timemanager fixes
This commit is contained in:
parent
60467ca195
commit
feda8dd938
@ -114,7 +114,7 @@ extern SemaphoreHandle_t I2Caccess, TimePulse;
|
|||||||
extern TaskHandle_t irqHandlerTask, ClockTask;
|
extern TaskHandle_t irqHandlerTask, ClockTask;
|
||||||
extern TimerHandle_t WifiChanTimer;
|
extern TimerHandle_t WifiChanTimer;
|
||||||
extern Timezone myTZ;
|
extern Timezone myTZ;
|
||||||
extern time_t LastSyncTime, userUTCTime;
|
extern time_t lastSyncTime, userUTCTime;
|
||||||
|
|
||||||
// application includes
|
// application includes
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
|
@ -20,7 +20,6 @@ void clock_loop(void *pvParameters);
|
|||||||
void time_sync(void);
|
void time_sync(void);
|
||||||
int wait_for_pulse(void);
|
int wait_for_pulse(void);
|
||||||
int syncTime(time_t const t, uint8_t const timesource);
|
int syncTime(time_t const t, uint8_t const timesource);
|
||||||
int syncTime(uint32_t const t, uint8_t const timesource);
|
|
||||||
void IRAM_ATTR CLOCKIRQ(void);
|
void IRAM_ATTR CLOCKIRQ(void);
|
||||||
int timepulse_init(void);
|
int timepulse_init(void);
|
||||||
void timepulse_start(void);
|
void timepulse_start(void);
|
||||||
|
@ -89,16 +89,19 @@ HardwareSerial IF482(2); // use UART #2 (note: #1 may be in use for serial GPS)
|
|||||||
// triggered by timepulse to ticker out DCF signal
|
// triggered by timepulse to ticker out DCF signal
|
||||||
void IF482_Pulse(time_t t) {
|
void IF482_Pulse(time_t t) {
|
||||||
|
|
||||||
|
static const TickType_t txDelay =
|
||||||
|
pdMS_TO_TICKS(IF482_PULSE_LENGTH) - tx_Ticks(HAS_IF482);
|
||||||
|
|
||||||
TickType_t startTime = xTaskGetTickCount();
|
TickType_t startTime = xTaskGetTickCount();
|
||||||
static const TickType_t txDelay = pdMS_TO_TICKS(IF482_PULSE_LENGTH) - tx_Ticks(HAS_IF482);
|
|
||||||
vTaskDelayUntil(&startTime, txDelay);
|
vTaskDelayUntil(&startTime, txDelay); // wait until moment to fire
|
||||||
IF482.print(IF482_Frame(t+1)); // note: if482 telegram for *next* second
|
IF482.print(IF482_Frame(t + 1)); // note: if482 telegram for *next* second
|
||||||
}
|
}
|
||||||
|
|
||||||
String IRAM_ATTR IF482_Frame(time_t startTime) {
|
String IRAM_ATTR IF482_Frame(time_t startTime) {
|
||||||
|
|
||||||
time_t t = myTZ.toLocal(startTime);
|
time_t t = myTZ.toLocal(startTime);
|
||||||
char mon, buf[14], out[IF482_FRAME_SIZE];
|
char mon, out[IF482_FRAME_SIZE];
|
||||||
|
|
||||||
switch (timeStatus()) { // indicates if time has been set and recently synced
|
switch (timeStatus()) { // indicates if time has been set and recently synced
|
||||||
case timeSet: // time is set and is synced
|
case timeSet: // time is set and is synced
|
||||||
@ -113,9 +116,10 @@ String IRAM_ATTR IF482_Frame(time_t startTime) {
|
|||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
// generate IF482 telegram
|
// generate IF482 telegram
|
||||||
snprintf(buf, sizeof(buf), "%02u%02u%02u%1u%02u%02u%02u", year(t) - 2000,
|
snprintf(out, sizeof(out), "O%cL%02u%02u%02u%1u%02u%02u%02u\r", mon,
|
||||||
month(t), day(t), weekday(t), hour(t), minute(t), second(t));
|
year(t) - 2000, month(t), day(t), weekday(t), hour(t), minute(t),
|
||||||
snprintf(out, sizeof(out), "O%cL%s\r", mon, buf);
|
second(t));
|
||||||
|
|
||||||
ESP_LOGD(TAG, "IF482 = %s", out);
|
ESP_LOGD(TAG, "IF482 = %s", out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -124,13 +128,13 @@ String IRAM_ATTR IF482_Frame(time_t startTime) {
|
|||||||
TickType_t tx_Ticks(unsigned long baud, uint32_t config, int8_t rxPin,
|
TickType_t tx_Ticks(unsigned long baud, uint32_t config, int8_t rxPin,
|
||||||
int8_t txPins) {
|
int8_t txPins) {
|
||||||
|
|
||||||
uint32_t datenbits = ((config & 0x0c) >> 2) + 5;
|
uint32_t databits = ((config & 0x0c) >> 2) + 5;
|
||||||
uint32_t stopbits = ((config & 0x20) >> 5) + 1;
|
uint32_t stopbits = ((config & 0x20) >> 5) + 1;
|
||||||
uint32_t tx_delay =
|
uint32_t txTime =
|
||||||
(2 + datenbits + stopbits) * IF482_FRAME_SIZE * 1000.0 / baud;
|
(databits + stopbits + 2) * IF482_FRAME_SIZE * 1000.0 / baud;
|
||||||
// +2 ms margin for the startbit and the clock's processing time
|
// +2 ms margin for the startbit and the clock's processing time
|
||||||
|
|
||||||
return pdMS_TO_TICKS(round(tx_delay));
|
return pdMS_TO_TICKS(round(txTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_IF482
|
#endif // HAS_IF482
|
@ -443,7 +443,7 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
|
|||||||
int flagSuccess) {
|
int flagSuccess) {
|
||||||
#ifdef HAS_LORA
|
#ifdef HAS_LORA
|
||||||
// Explicit conversion from void* to uint32_t* to avoid compiler errors
|
// Explicit conversion from void* to uint32_t* to avoid compiler errors
|
||||||
uint32_t *pUserUTCTime = (uint32_t *)pVoidUserUTCTime;
|
time_t *pUserUTCTime = (time_t *)pVoidUserUTCTime;
|
||||||
lmic_time_reference_t lmicTimeReference;
|
lmic_time_reference_t lmicTimeReference;
|
||||||
|
|
||||||
if (flagSuccess != 1) {
|
if (flagSuccess != 1) {
|
||||||
@ -468,11 +468,11 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
|
|||||||
ostime_t ticksRequestSent = lmicTimeReference.tLocal;
|
ostime_t ticksRequestSent = lmicTimeReference.tLocal;
|
||||||
// Add the delay between the instant the time was transmitted and
|
// Add the delay between the instant the time was transmitted and
|
||||||
// the current time
|
// the current time
|
||||||
uint32_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000;
|
time_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000;
|
||||||
*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)) { // do we have a valid time?
|
if (syncTime(*pUserUTCTime, lora)) { // have we got a valid time?
|
||||||
#ifdef HAS_RTC
|
#ifdef HAS_RTC
|
||||||
if (TimeIsSynced)
|
if (TimeIsSynced)
|
||||||
set_rtctime(now()); // UTC time
|
set_rtctime(now()); // UTC time
|
||||||
|
@ -72,7 +72,7 @@ TaskHandle_t irqHandlerTask, ClockTask;
|
|||||||
SemaphoreHandle_t I2Caccess, TimePulse;
|
SemaphoreHandle_t I2Caccess, TimePulse;
|
||||||
bool volatile TimePulseTick = false;
|
bool volatile TimePulseTick = false;
|
||||||
bool TimeIsSynced = false;
|
bool TimeIsSynced = false;
|
||||||
time_t LastSyncTime = 0, userUTCTime = 0;
|
time_t lastSyncTime = 0, userUTCTime = 0;
|
||||||
|
|
||||||
// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
|
// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
|
||||||
// if present
|
// if present
|
||||||
|
@ -9,17 +9,21 @@ void time_sync() {
|
|||||||
|
|
||||||
#ifdef TIME_SYNC_INTERVAL
|
#ifdef TIME_SYNC_INTERVAL
|
||||||
|
|
||||||
time_t lastTimeSync = now() - LastSyncTime; // check if a sync is due
|
static time_t ageOfTime = 0;
|
||||||
|
|
||||||
|
ageOfTime = now() - lastSyncTime; // check if a sync is due
|
||||||
|
|
||||||
|
// is it time to sync with external source or did we never sync yet?
|
||||||
|
if ((ageOfTime >= (TIME_SYNC_INTERVAL * 60000)) || !lastSyncTime) {
|
||||||
|
|
||||||
if ((lastTimeSync >= (TIME_SYNC_INTERVAL * 60000)) || !LastSyncTime) {
|
|
||||||
// is it time to sync with external source?
|
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
if (syncTime(get_gpstime(), pps)) // attempt sync with GPS time
|
syncTime(get_gpstime(), pps); // attempt sync with GPS time
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined HAS_LORA && defined TIME_SYNC_LORA
|
#if defined HAS_LORA && defined TIME_SYNC_LORA
|
||||||
if (!TimeIsSynced) // no GPS sync -> try lora sync
|
if (!TimeIsSynced) // no GPS sync -> try lora sync
|
||||||
LMIC_requestNetworkTime(user_request_network_time_callback,
|
LMIC_requestNetworkTime(user_request_network_time_callback,
|
||||||
&userUTCTime);
|
&userUTCTime);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,10 +31,11 @@ void time_sync() {
|
|||||||
if (TimeIsSynced) { // recalibrate RTC, if we have one
|
if (TimeIsSynced) { // recalibrate RTC, if we have one
|
||||||
set_rtctime(now());
|
set_rtctime(now());
|
||||||
} else { // we switch to fallback time after a while
|
} else { // we switch to fallback time after a while
|
||||||
if ((lastTimeSync >= (TIME_SYNC_TIMEOUT * 60000)) ||
|
if ((ageOfTime >= (TIME_SYNC_TIMEOUT * 60000)) ||
|
||||||
!LastSyncTime) { // sync is still due -> use RTC as fallback source
|
!lastSyncTime) { // sync is still due -> use RTC as fallback source
|
||||||
if (syncTime(get_rtctime(), rtc)) // sync with RTC time
|
if (!syncTime(get_rtctime(), rtc)) // sync with RTC time
|
||||||
TimeIsSynced = false;
|
ESP_LOGW(TAG, "no valid time");
|
||||||
|
TimeIsSynced = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -42,30 +47,26 @@ void time_sync() {
|
|||||||
int syncTime(time_t const t, uint8_t const timesource) {
|
int syncTime(time_t const t, uint8_t const timesource) {
|
||||||
|
|
||||||
// symbol to display current time source
|
// symbol to display current time source
|
||||||
const char timeSetSymbols[] = {'G', 'R', 'L', '~' };
|
const char timeSetSymbols[] = {'G', 'R', 'L', '~'};
|
||||||
|
|
||||||
if (TimeIsValid(t)) {
|
if (TimeIsValid(t)) {
|
||||||
TimeIsSynced = wait_for_pulse(); // wait for next 1pps timepulse
|
TimeIsSynced = wait_for_pulse(); // wait for next 1pps timepulse
|
||||||
setTime(t);
|
setTime(t);
|
||||||
adjustTime(1); // forward time to next second
|
adjustTime(1); // forward time to next second
|
||||||
LastSyncTime = now(); // store time of this sync
|
lastSyncTime = now(); // store time of this sync
|
||||||
timeSource = timeSetSymbols[timesource];
|
timeSource = timeSetSymbols[timesource];
|
||||||
ESP_LOGD(TAG, "Time was set to %02d:%02d:%02d", hour(t), minute(t),
|
ESP_LOGD(TAG, "Time source %c set time to %02d:%02d:%02d", timeSource,
|
||||||
second(t));
|
hour(t), minute(t), second(t));
|
||||||
return 1; // success
|
return 1; // success
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(TAG, "Time sync attempt failed");
|
|
||||||
timeSource = timeSetSymbols[unsynced];
|
timeSource = timeSetSymbols[unsynced];
|
||||||
TimeIsSynced = false;
|
TimeIsSynced = false;
|
||||||
|
ESP_LOGD(TAG, "Time source %c sync attempt failed", timeSource);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// failure
|
// failure
|
||||||
}
|
}
|
||||||
|
|
||||||
int syncTime(uint32_t const t, uint8_t const timesource) { // t is UTC time in seconds epoch
|
|
||||||
return syncTime(static_cast<time_t>(t), timesource);
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function to sync moment on timepulse
|
// helper function to sync moment on timepulse
|
||||||
int wait_for_pulse(void) {
|
int wait_for_pulse(void) {
|
||||||
// sync on top of next second with 1pps timepulse
|
// sync on top of next second with 1pps timepulse
|
||||||
@ -153,8 +154,8 @@ time_t compiledUTC(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// helper function to convert gps date/time into time_t
|
// helper function to convert gps date/time into time_t
|
||||||
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) {
|
||||||
tmElements_t tm;
|
tmElements_t tm;
|
||||||
tm.Year = CalendarYrToTm(YYYY); // year offset from 1970 in time.h
|
tm.Year = CalendarYrToTm(YYYY); // year offset from 1970 in time.h
|
||||||
tm.Month = MM;
|
tm.Month = MM;
|
||||||
|
Loading…
Reference in New Issue
Block a user