1#include "main-header.h"
6#define TIME_REQUEST_SYNC_INTERVAL 300
8#define TIME_MAX_AGE_NO_SYNC (60 * 60 * 24 * 2)
10static long appstarted;
11static uint8_t daytime;
12static uint32_t last_time_stamp;
13static uint32_t last_date_stamp;
14static uint32_t last_time_sync_req = 0;
15static uint32_t last_time_sync = 0;
17static uint32_t old_last_time_sync = 0;
18static uint32_t old_last_time_stamp;
19static uint32_t old_last_date_stamp;
20static int32_t old_last_drift;
21static struct sctime old_time;
22static uint32_t last_published_time = 0;
23static int adj_time = 0;
24static uint32_t ltd = 0;
27static int get_time_as_struct(
struct sctime *time, uint32_t l_time_sync, uint32_t l_time_stamp, uint32_t l_date_stamp);
29static void time_set_new_from_sync(uint32_t received, uint32_t bcdtime, uint32_t bcddate, uint32_t temp_override);
30static void add_seconds_to_timestruct(
struct sctime *nt, uint32_t add_secs);
34void check_time_on_loop() {
35 uint32_t now = mculib_get_seconds_since_boot();
37 if (last_time_sync == 0) {
38 if (get_seconds_since_start() < 60) {
43 if ((now - last_time_sync < TIME_REQUEST_SYNC_INTERVAL) && (now >= last_time_sync)) {
48 if ((now - last_time_sync_req <= 5) && (now >= last_time_sync_req)) {
51 send_clock_sync_request();
55static int sync_disabled() {
56 if ((last_time_sync != 0) && (config_get_flag(CONFIG_FLAGS_CLOCKSYNC_DISABLED))) {
61void send_clock_sync_request() {
62 if (sync_disabled()) {
65 uint32_t now = mculib_get_seconds_since_boot();
67 printf(
"[time] sending sync request...\r\n");
73 com->target = CLOUD_SERVER;
75 last_time_sync_req = now;
80 time_add_debug_to_command(
com);
85 printf(
"[time] failed to send sync request: %i\r\n", n);
91static void time_set_new_from_sync(uint32_t received, uint32_t bcdtime, uint32_t bcddate, uint32_t temp_override) {
93 int n = get_localtime_as_struct(&nt1);
94 uint32_t lt1 = last_time_sync;
96 if ((temp_override) || (!sync_disabled())) {
97 last_time_sync = received;
98 last_time_stamp = bcdtime;
99 last_date_stamp = bcddate;
103 if ((old_last_time_sync == 0) || ((received - old_last_time_sync) > 60 * 60 * 4)) {
104 old_last_time_sync = received;
105 old_last_time_stamp = bcdtime;
106 old_last_date_stamp = bcddate;
108 uint32_t lt2 = received;
111 printf(
"[time] not calculating drift because cannot calc time on old time\r\n");
115 n = get_time_as_struct(&nt2, received, bcdtime, bcddate);
117 printf(
"[time] not calculating drift because cannot calc time on new time\r\n");
120 if ((nt1.month != nt2.month) || (nt1.month != nt2.month)) {
123 printf(
"[time] not calculating drift across two different dates\r\n");
127 uint32_t ne1 = nt1.second + (nt1.minute * 60) + (nt1.hour * 60 * 60);
128 uint32_t ne2 = nt2.second + (nt2.minute * 60) + (nt2.hour * 60 * 60);
130 adj_time = ne2 - ne1;
134 if (old_last_time_sync < received) {
135 convert_timestamps_to_time(old_last_time_stamp, old_last_date_stamp, &old_time);
136 add_seconds_to_timestruct(&old_time, received - old_last_time_sync);
137 if ((nt2.month == old_time.month) && (nt2.month == old_time.month)) {
138 old_last_drift = old_time.second + (old_time.minute * 60) + (old_time.hour * 60 * 60) - ne2;
143 printf(
"[time] set time diff: %i@%i, %i@%i (%i/%i)\r\n", ne1, lt1, ne2, lt2, adj_time, ltd);
151int time_command_received(
struct command *com) {
154 uint32_t now = mculib_get_seconds_since_boot();
167 config_set_clock_mul(dm);
173 config_set_clock_div(dm);
179 printf(
"[time] clock-info did not include bcdtime - ignored\r\n");
185 printf(
"[time] clock-info did not include bcddate - ignored\r\n");
194 config_set_timezone(tz);
195 printf(
"[time] set new timezone %i\r\n");
203 printf(
"[time] clock-info did not include timezone - ignored\r\n");
206 if (tz != config_get_timezone()) {
207 printf(
"[time] received for time %i, but we are in %i - ignored\r\n", tz, config_get_timezone());
213 time_set_new_from_sync(now, p1, p2, res);
216 if (sync_disabled()) {
250 printf(
"[time] failed to forward sync request: %i\r\n", n);
257static uint32_t max_date_for_month(uint32_t month) {
258 if ((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12)) {
271static void add_seconds_to_timestruct(
struct sctime *nt, uint32_t add_secs) {
272 uint32_t add_wdays = 0;
273 uint32_t days = add_secs / (60 * 60 * 24);
275 nt->day = nt->day + days;
276 add_wdays = add_wdays + days;
277 add_secs = add_secs - (days * 60 * 60 * 24);
279 uint32_t hours = add_secs / (60 * 60);
281 nt->hour = nt->hour + hours;
282 add_secs = add_secs - (hours * 60 * 60);
284 uint32_t secs = add_secs % 60;
286 nt->second = nt->second + secs;
287 if (nt->second >= 60) {
289 nt->second = nt->second - 60;
291 uint32_t mins = ((add_secs - (secs)) / 60) % 3600;
293 nt->minute = nt->minute + mins;
294 if (nt->minute >= 60) {
296 nt->minute = nt->minute - 60;
298 if (nt->hour >= 24) {
301 nt->hour = nt->hour - 24;
303 uint32_t mdm = max_date_for_month(nt->month);
307 nt->day = nt->day - mdm;
309 nt->weekday = nt->weekday + (add_wdays % 7);
310 if (nt->weekday > 7) {
311 nt->weekday = nt->weekday - 7;
315uint32_t convert_time_to_timestamp(
struct sctime *time) {
318 res |= time->hour << 24;
319 res |= time->minute << 16;
320 res |= time->second << 8;
321 res |= time->weekday;
330static uint8_t compare_time(
struct sctime *time1,
struct sctime *time2) {
331 if (time1->year > time2->year) {
334 if (time1->year < time2->year) {
337 if (time1->month > time2->month) {
340 if (time1->month < time2->month) {
343 if (time1->day > time2->day) {
346 if (time1->day < time2->day) {
349 if (time1->hour > time2->hour) {
352 if (time1->hour < time2->hour) {
355 if (time1->minute > time2->minute) {
358 if (time1->minute < time2->minute) {
361 if (time1->second > time2->second) {
364 if (time1->second < time2->second) {
369int diff_time(
struct sctime *time1,
struct sctime *time2) {
370 uint8_t reverse_sign = 0;
378 int r = compare_time(larger, smaller);
389 if (larger->month != smaller->month) {
390 m_days = max_date_for_month(larger->month);
392 diff = diff + (m_days + smaller->day - larger->day) * 60 * 60 * 24;
393 diff = diff + (smaller->hour - larger->hour) * 60 * 60;
394 diff = diff + (smaller->minute - larger->minute) * 60;
395 diff = diff + (smaller->second - larger->second);
402void convert_timestamps_to_time(uint32_t bcdtime, uint32_t bcddate,
struct sctime *time) {
403 time->hour = ((bcdtime >> 24) & 0xFF);
404 time->minute = ((bcdtime >> 16) & 0xFF);
405 time->second = ((bcdtime >> 8) & 0xFF);
406 time->weekday = ((bcdtime) & 0xFF);
407 time->year = ((bcddate >> 16) & 0xFFFF);
408 time->month = ((bcddate >> 8) & 0xFF);
409 time->day = ((bcddate) & 0xFF);
410 time->timestamp = bcdtime;
411 uint32_t now = mculib_get_seconds_since_boot();
412 uint32_t since = now - last_time_sync;
414 time->secs_since_last_sync = since;
415 time->daytime = daytime;
417static int get_time_as_struct(
struct sctime *time, uint32_t l_time_sync, uint32_t l_time_stamp, uint32_t l_date_stamp) {
418 if (l_time_sync == 0) {
422 uint32_t now = mculib_get_seconds_since_boot();
424 if ((now < last_published_time) && (last_published_time - now < 50)) {
425 now = last_published_time;
427 last_published_time = now;
429 uint32_t since = now - l_time_sync;
431 if (since > TIME_MAX_AGE_NO_SYNC) {
434 if (l_time_sync > now) {
437 convert_timestamps_to_time(l_time_stamp, l_date_stamp, time);
441 if (config_get_clock_mul() != 0) {
442 since = since * config_get_clock_mul();
444 if (config_get_clock_div() != 0) {
445 since = since / config_get_clock_div();
447 add_seconds_to_timestruct(time, since);
451int get_localtime_as_struct(
struct sctime *time) {
452 return get_time_as_struct(time, last_time_sync, last_time_stamp, last_date_stamp);
455void clocksync_enable(uint8_t e) {
457 printf(
"clocksync enabled\r\n");
458 config_set_flag(CONFIG_FLAGS_CLOCKSYNC_DISABLED, 0);
460 printf(
"clocksync disabled\r\n");
461 config_set_flag(CONFIG_FLAGS_CLOCKSYNC_DISABLED, 1);
465void time_add_debug_to_command(
struct command *com) {
467 int n = get_localtime_as_struct(<);
476 uint32_t *CNWRTC_BASE_TR = (uint32_t *)0x40002800;
478 uint32_t stupidcal = (*CNWRTC_BASE_TR);
481 CNWRTC_BASE_TR = (uint32_t *)0x40002804;
483 stupidcal = (*CNWRTC_BASE_TR);
487 command_add_arg(com,
"f=%i/%i", config_get_clock_mul(), config_get_clock_div());
493 appstarted = mculib_get_seconds_since_boot();
495uint32_t get_seconds_since_start() {
496 return mculib_get_seconds_since_boot() - appstarted;
498void clocksync_help() {
499 uint32_t now = mculib_get_seconds_since_boot();
501 int n = get_localtime_as_struct(&nt);
503 printf(
"Clocksync help:\r\n");
504 printf(
"Now (boot): %i\r\n", now);
505 printf(
"Now (strt): %i\r\n", (now - appstarted));
506 printf(
"Multiplier: %i\r\n", config_get_clock_mul());
507 printf(
"Divisor : %i\r\n", config_get_clock_div());
508 printf(
"ltd : %i\r\n", ltd);
509 printf(
"adj_time : %i\r\n", adj_time);
510 printf(
"last sync : %i (%i)\r\n", last_time_sync, (now - last_time_sync));
512 printf(
"Time : %i:%i:%i (%s)\r\n", nt.hour, nt.minute, nt.second, (nt.daytime ?
"day":
"night"));
514 printf(
"Time : unavailable (%i)\r\n", n);
516 printf(
"Timezone : %i\r\n", config_get_timezone());
517 printf(
"Enabled : %s\r\n", (sync_disabled() ?
"No" :
"Yes"));
int send_command(struct command *com)
send a command to another module (or broadcast)
void free_command(struct command *com)
free a command
void command_add_arg(struct command *com, const char *format,...)
adds an arg to a partially initialised command structure
int namedarg_uint32(struct command *com, const char *name, uint32_t *value)
get a named arg (key-value pair), parsed as integer. result in "value". if return value == 0 ,...
struct command * alloc_command()
allocate a free command