wall clock More...
#include "config.h"
#include <stdio.h>
#include <avr/pgmspace.h>
#include <clock.h>
#include <rtc.h>
Data Structures | |
struct | adjbuf_s |
adjustment buffer | |
Defines | |
#define | ADJ_BUFFER_SIZE (1) |
number of entries in adjustment buffer | |
Functions | |
void | clock_adjust (uint16_t ticks, uint8_t t2_val, clock_adj_source_t src, const clock_time_t *time) |
post adjustment to clock | |
clock_status_t | clock_get_time (clock_time_t *time) |
get current time (UTC) |
wall clock
For a short explanation, see Time Handling.
void clock_adjust | ( | uint16_t | ticks, | |
uint8_t | t2_val, | |||
clock_adj_source_t | src, | |||
const clock_time_t * | time | |||
) |
post adjustment to clock
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_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; }