timekeeper fixes
This commit is contained in:
parent
c20ef02ce8
commit
6ab4a0bd9f
@ -17,10 +17,9 @@
|
|||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern QueueHandle_t LoraSendQueue;
|
extern QueueHandle_t LoraSendQueue;
|
||||||
|
|
||||||
|
esp_err_t lora_stack_init();
|
||||||
void onEvent(ev_t ev);
|
void onEvent(ev_t ev);
|
||||||
void gen_lora_deveui(uint8_t *pdeveui);
|
void gen_lora_deveui(uint8_t *pdeveui);
|
||||||
void RevBytes(unsigned char *b, size_t c);
|
void RevBytes(unsigned char *b, size_t c);
|
||||||
@ -36,7 +35,7 @@ void lora_queuereset(void);
|
|||||||
void lora_housekeeping(void);
|
void lora_housekeeping(void);
|
||||||
void user_request_network_time_callback(void *pVoidUserUTCTime,
|
void user_request_network_time_callback(void *pVoidUserUTCTime,
|
||||||
int flagSuccess);
|
int flagSuccess);
|
||||||
|
time_t set_loratime(time_t t);
|
||||||
esp_err_t lora_stack_init();
|
time_t get_loratime(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -20,13 +20,12 @@ void clock_init(void);
|
|||||||
void clock_loop(void *pvParameters);
|
void clock_loop(void *pvParameters);
|
||||||
void time_sync(void);
|
void time_sync(void);
|
||||||
void timepulse_start(void);
|
void timepulse_start(void);
|
||||||
uint8_t wait_for_pulse(void);
|
uint8_t syncTime(getExternalTime getTimeFunction, timesource_t const caller);
|
||||||
uint8_t syncTime(time_t const t, timesource_t const caller);
|
|
||||||
uint8_t timepulse_init(void);
|
uint8_t timepulse_init(void);
|
||||||
uint8_t TimeIsValid(time_t const t);
|
uint8_t TimeIsValid(time_t const t);
|
||||||
time_t syncProvider_CB(void);
|
time_t syncProvider_CB(void);
|
||||||
time_t compiledUTC(void);
|
time_t compiledUTC(void);
|
||||||
time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh,
|
time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, uint8_t mm,
|
||||||
uint8_t mm, uint8_t ss);
|
uint8_t ss);
|
||||||
|
|
||||||
#endif // _timekeeper_H
|
#endif // _timekeeper_H
|
@ -75,9 +75,6 @@ void gps_read() {
|
|||||||
|
|
||||||
// function to fetch current time from gps
|
// function to fetch current time from gps
|
||||||
time_t get_gpstime(void) {
|
time_t get_gpstime(void) {
|
||||||
// !! never call now() or delay in this function, this would break this
|
|
||||||
// function to be used as SyncProvider for Time.h
|
|
||||||
|
|
||||||
time_t t = 0;
|
time_t t = 0;
|
||||||
|
|
||||||
if ((gps.time.age() < 950) && (gps.time.isValid())) {
|
if ((gps.time.age() < 950) && (gps.time.isValid())) {
|
||||||
@ -87,11 +84,11 @@ time_t get_gpstime(void) {
|
|||||||
|
|
||||||
// use recent gps time
|
// use recent gps time
|
||||||
t = tmConvert(gps.date.year(), gps.date.month(), gps.date.day(),
|
t = tmConvert(gps.date.year(), gps.date.month(), gps.date.day(),
|
||||||
gps.time.hour(), gps.time.minute(), gps.time.second());
|
gps.time.hour(), gps.time.minute(), gps.time.second());
|
||||||
|
|
||||||
ESP_LOGD(TAG, "GPS time: %02d.%02d.%04d %02d:%02d:%02d", gps.date.day(),
|
// ESP_LOGD(TAG, "GPS time: %02d.%02d.%04d %02d:%02d:%02d", gps.date.day(),
|
||||||
gps.date.month(), gps.date.year(), gps.time.hour(),
|
// gps.date.month(), gps.date.year(), gps.time.hour(),
|
||||||
gps.time.minute(), gps.time.second());
|
// gps.time.minute(), gps.time.second());
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
} // get_gpstime()
|
} // get_gpstime()
|
||||||
|
@ -472,9 +472,19 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
|
|||||||
*pUserUTCTime += requestDelaySec;
|
*pUserUTCTime += requestDelaySec;
|
||||||
|
|
||||||
// Update system time with time read from the network
|
// Update system time with time read from the network
|
||||||
if (syncTime(*pUserUTCTime, _lora)) { // have we got a valid time?
|
set_loratime(*pUserUTCTime); // store time in time sync provider function
|
||||||
ESP_LOGI(TAG, "LORA has set the system time");
|
if (syncTime(get_loratime, _lora))
|
||||||
} else
|
ESP_LOGI(TAG, "Received recent time from LoRa");
|
||||||
ESP_LOGI(TAG, "Unable to sync system time with LORA");
|
else
|
||||||
|
ESP_LOGI(TAG, "Invalid time received from LoRa");
|
||||||
#endif // HAS_LORA
|
#endif // HAS_LORA
|
||||||
} // user_request_network_time_callback
|
} // user_request_network_time_callback
|
||||||
|
|
||||||
|
time_t set_loratime(time_t t) {
|
||||||
|
static time_t loratime = 0; // stores time for retrieval
|
||||||
|
if (t > loratime)
|
||||||
|
loratime = t; // store time if it is recent
|
||||||
|
return loratime;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t get_loratime(void) { return set_loratime(0); }
|
||||||
|
@ -59,8 +59,6 @@ uint8_t set_rtctime(time_t t) { // t is UTC in seconds epoch time
|
|||||||
} // set_rtctime()
|
} // set_rtctime()
|
||||||
|
|
||||||
time_t get_rtctime(void) {
|
time_t get_rtctime(void) {
|
||||||
// !! never call now() or delay in this function, this would break this
|
|
||||||
// function to be used as SyncProvider for Time.h
|
|
||||||
time_t t = 0;
|
time_t t = 0;
|
||||||
if (I2C_MUTEX_LOCK()) {
|
if (I2C_MUTEX_LOCK()) {
|
||||||
if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) {
|
if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) {
|
||||||
|
@ -6,23 +6,24 @@ static const char TAG[] = "main";
|
|||||||
// symbol to display current time source
|
// symbol to display current time source
|
||||||
const char timeSetSymbols[] = {'G', 'R', 'L', '?'};
|
const char timeSetSymbols[] = {'G', 'R', 'L', '?'};
|
||||||
|
|
||||||
|
getExternalTime TimeSourcePtr; // pointer to time source function
|
||||||
|
|
||||||
void time_sync() {
|
void time_sync() {
|
||||||
// synchonization of systime with external time source (GPS/LORA)
|
// check synchonization of systime, called by cyclic.cpp
|
||||||
// frequently called from cyclic.cpp
|
|
||||||
|
|
||||||
#ifdef TIME_SYNC_INTERVAL
|
#ifdef TIME_SYNC_INTERVAL
|
||||||
|
|
||||||
if (timeStatus() == timeSet)
|
if (timeStatus() == timeSet) // timeStatus() is flipped in Time.h
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
if (syncTime(get_gpstime(), _gps))
|
if (syncTime(get_gpstime, _gps))
|
||||||
return; // attempt sync with GPS time
|
return; // attempt sync with GPS time
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// no GPS -> fallback to RTC time while trying lora sync
|
// no GPS -> fallback to RTC time while trying lora sync
|
||||||
#ifdef HAS_RTC
|
#ifdef HAS_RTC
|
||||||
if (!syncTime(get_rtctime(), _rtc)) // sync with RTC time
|
if (!syncTime(get_rtctime, _rtc)) // sync with RTC time
|
||||||
ESP_LOGW(TAG, "no confident RTC time");
|
ESP_LOGW(TAG, "no confident RTC time");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -34,43 +35,50 @@ void time_sync() {
|
|||||||
#endif // TIME_SYNC_INTERVAL
|
#endif // TIME_SYNC_INTERVAL
|
||||||
} // time_sync()
|
} // time_sync()
|
||||||
|
|
||||||
// sync time on start of next second
|
// sync time on start of next second from GPS or RTC
|
||||||
uint8_t syncTime(time_t const t, timesource_t const caller) {
|
uint8_t syncTime(getExternalTime getTimeFunction, timesource_t const caller) {
|
||||||
|
|
||||||
|
TimeSourcePtr = getTimeFunction;
|
||||||
|
time_t t;
|
||||||
|
|
||||||
|
if (!TimeSourcePtr)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if ((caller == _gps || caller == _rtc)) // ticking timesource?
|
||||||
|
xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)); // then wait on pps
|
||||||
|
|
||||||
|
t = TimeSourcePtr(); // get time from given timesource
|
||||||
|
|
||||||
if (TimeIsValid(t)) {
|
if (TimeIsValid(t)) {
|
||||||
uint8_t const TimeIsPulseSynced =
|
if (caller == _gps) // gps time concerns past second
|
||||||
wait_for_pulse(); // wait for next 1pps timepulse
|
t++;
|
||||||
setTime(t); // sync time and reset timeStatus() to timeSet
|
setTime(t); // flips timeStatus() in Time.h
|
||||||
adjustTime(1); // forward time to next second
|
|
||||||
timeSource = caller;
|
timeSource = caller;
|
||||||
ESP_LOGD(TAG, "Time source %c set time to %02d:%02d:%02d",
|
ESP_LOGD(TAG, "Time source %c set time to %02d:%02d:%02d",
|
||||||
timeSetSymbols[timeSource], hour(t), minute(t), second(t));
|
timeSetSymbols[timeSource], hour(t), minute(t), second(t));
|
||||||
#ifdef HAS_RTC
|
|
||||||
if ((TimeIsPulseSynced) && (caller != _rtc))
|
|
||||||
set_rtctime(now());
|
|
||||||
#endif
|
|
||||||
return 1; // success
|
|
||||||
|
|
||||||
} else {
|
#ifdef HAS_RTC
|
||||||
ESP_LOGD(TAG, "Time source %c sync attempt failed", timeSetSymbols[caller]);
|
if (caller != _rtc)
|
||||||
timeSource = _unsynced;
|
set_rtctime(t);
|
||||||
return 0; // failure
|
#endif
|
||||||
|
|
||||||
|
return 1; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
ESP_LOGD(TAG, "Time source %c sync attempt failed", timeSetSymbols[caller]);
|
||||||
|
timeSource = _unsynced;
|
||||||
|
return 0; // failure
|
||||||
|
|
||||||
} // syncTime()
|
} // syncTime()
|
||||||
|
|
||||||
|
|
||||||
// callback function called by Time.h in interval set in main.cpp
|
// callback function called by Time.h in interval set in main.cpp
|
||||||
time_t syncProvider_CB(void) {
|
time_t syncProvider_CB(void) {
|
||||||
timeSource = _unsynced;
|
timeSource = _unsynced;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function to sync moment on timepulse
|
|
||||||
uint8_t wait_for_pulse(void) {
|
|
||||||
// sync on top of next second with 1pps timepulse
|
|
||||||
if (xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1010)) == pdTRUE)
|
|
||||||
return 1; // success
|
|
||||||
ESP_LOGD(TAG, "Missing timepulse");
|
|
||||||
return 0; // failure
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function to setup a pulse per second for time synchronisation
|
// helper function to setup a pulse per second for time synchronisation
|
||||||
uint8_t timepulse_init() {
|
uint8_t timepulse_init() {
|
||||||
@ -209,7 +217,8 @@ void clock_loop(void *pvParameters) { // ClockTask
|
|||||||
xTaskNotifyWait(0x00, ULONG_MAX, &wakeTime,
|
xTaskNotifyWait(0x00, ULONG_MAX, &wakeTime,
|
||||||
portMAX_DELAY); // wait for timepulse
|
portMAX_DELAY); // wait for timepulse
|
||||||
|
|
||||||
if (timeStatus() == timeNotSet) // no confident time -> no output to clock
|
// no confident time -> suppress clock output
|
||||||
|
if (timeStatus() == timeNotSet)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
t = now(); // payload to send to clock
|
t = now(); // payload to send to clock
|
||||||
|
Loading…
Reference in New Issue
Block a user