wall clock More...
Go to the source code of this file.
Data Structures | |
struct | clock_status_s |
status of clock More... | |
struct | clock_time_s |
wall clock time (and date) More... | |
Typedefs | |
typedef struct clock_status_s | clock_status_t |
status of clock | |
typedef struct clock_time_s | clock_time_t |
wall clock time (and date) | |
Enumerations | |
enum | clock_adj_source_t { CLOCKADJ_NONE, CLOCKADJ_GPS_MOD, CLOCKADJ_GPS_EXT, CLOCKADJ_USER } |
adjustment sources More... | |
Functions | |
clock_status_t | clock_get_time (clock_time_t *time) |
get current time (UTC) | |
void | clock_adjust (uint16_t ticks, uint8_t t2_val, clock_adj_source_t src, const clock_time_t *time) |
post adjustment to clock |
wall clock
For a short explanation, see Time Handling.
enum clock_adj_source_t |
void clock_adjust | ( | uint16_t | ticks, | |
uint8_t | t2_val, | |||
clock_adj_source_t | src, | |||
const clock_time_t * | time | |||
) |
post adjustment to clock
For clock_get_time() to be able to return a valid time, clock_adjust() has to be called at least once before (e.g. from the GPS code). clock_adjust() records the offset to the internal timer built around the 32 kHz oscillator.
ticks | tick count when time has been recorded | |
t2_val | value of the T2 register when time has been recorded | |
src | source of time value | |
time | pointer to structure containing the time |
It is assumed that clock_adjust() will be called shortly after the time value has been determined so that the ticks value has not made a full "rotation", and preferrably has not wrapped around.
The current implementation records only the last adjustment values.
{ if (ADJ_BUFFER_SIZE >= 1) { hl_time_t curr_time = hl_get_current_time (); if (curr_time.ticks < ticks) /* there was a wrap-around, computation is too complicated * here at the moment */ return; /* just store it away */ adjust_buffer[0].uptime.seconds = curr_time.seconds; adjust_buffer[0].uptime.ticks = ticks; adjust_buffer[0].uptime.t2_val = t2_val; adjust_buffer[0].walltime.time = *time; adjust_buffer[0].source = src; } }
clock_status_t clock_get_time | ( | clock_time_t * | time | ) |
get current time (UTC)
clock_get_time() will return the current wall clock time.
time | pointer to a struct clock_time_s which should be filled with the current time. If it is NULL, clock_get_time() will just return the clock status. |
{ clock_status_t retval = { .is_set = 0, .valid_time = 0, .valid_date = 0, .valid_century = 0, }; if (ADJ_BUFFER_SIZE >= 1) { #ifdef DEBUG printf_P (PSTR("last seconds=%ld tick=%d\r\n"), adjust_buffer[0].uptime.seconds, adjust_buffer[0].uptime.ticks); #endif if (adjust_buffer[0].uptime.ticks || adjust_buffer[0].uptime.seconds) { /* clock_adjust() has already been called, so we can return data */ struct adjbuf_s * buf = &adjust_buffer[0]; retval.is_set = 1; retval.valid_time = 1; retval.valid_date = buf->walltime.time.day && buf->walltime.time.month; retval.valid_century = buf->walltime.time.year >= 100; if (time) { /* The caller has requested to get the data and not just the status */ hl_time_t curr_time = hl_get_current_time (); /* time elapsed since last call to clock_adjust(), * will be (very) near 0 when GPS reception is OK. */ int32_t offset = curr_time.seconds - buf->uptime.seconds; ldiv_t d; #ifdef DEBUG printf_P (PSTR("time offset=%ld\r\n"), offset); #endif /* if we did not reach the saved tick value, the real second * tick did not occur yet */ if (curr_time.ticks < buf->uptime.ticks) { offset--; } *time = buf->walltime.time; if (offset == 0) goto out; /* do corrections */ /* seconds */ d = ldiv(offset + buf->walltime.time.sec, 60L); time->sec = d.rem; offset = d.quot; if (offset == 0) goto out; /* minutes */ d = ldiv(offset + buf->walltime.time.min, 60L); time->min = d.rem; offset = d.quot; if (offset == 0) goto out; /* hours */ d = ldiv(offset + buf->walltime.time.hour, 24L); time->hour = d.rem; offset = d.quot; /* now offset is in days * --- we don't expect a very long time between adjustments */ while (offset) { uint8_t mdays = month_days (time->year, time->month); if (offset > (int8_t)(mdays - time->day)) { /* advance to first day of next month */ offset -= mdays - time->day + 1; time->day = 1; if (++time->month > 12) { time->month = 1; time->year++; } } else { time->day += offset; offset = 0; } } out:; /* now offset is 0, so *time contains the current time */ #ifdef DEBUG printf_P (PSTR("%04u-%02u-%02u %02u:%02u:%02u\r\n"), time->year, time->month, time->day, time->hour, time->min, time->sec); #endif } } } return retval; }