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;
}
1.7.1