diff --git a/README.md b/README.md index 997a51d0..a9f2ebed 100644 --- a/README.md +++ b/README.md @@ -405,11 +405,11 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. bytes 1..4 = time/date in UTC epoch seconds (LSB) byte 5 = time source & status, see below - bits 0..3 time source + bits 0..3 last seen time source 0x00 = GPS 0x01 = RTC 0x02 = LORA - 0x03 = unsynched + 0x03 = unsynched (never synched) bits 4..7 time status 0x00 = timeNotSet (never synched) diff --git a/include/timekeeper.h b/include/timekeeper.h index 87f999c0..6239f082 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -26,7 +26,7 @@ void timepulse_start(void); void timeSync(void); uint8_t timepulse_init(void); time_t timeIsValid(time_t const t); -time_t timeProvider(void); +void calibrateTime(void); time_t compiledUTC(void); TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPins); diff --git a/include/timesync.h b/include/timesync.h index 94ec86bb..498952c1 100644 --- a/include/timesync.h +++ b/include/timesync.h @@ -15,6 +15,6 @@ void send_timesync_req(void); int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len); void process_timesync_req(void *taskparameter); void store_time_sync_req(uint32_t t_millisec); -void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec); +void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t timesource); #endif \ No newline at end of file diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index 62cf1007..cb5de1ec 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -59,9 +59,7 @@ void irqHandler(void *pvParameters) { // is time to be synced? if (InterruptStatus & TIMESYNC_IRQ) { now(); // ensure sysTime is recent - time_t t = timeProvider(); - if (timeIsValid(t)) - setTime(t); + calibrateTime(); } #endif diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 333218dd..e82ac1f5 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -464,11 +464,6 @@ void lora_enqueuedata(MessageBuffer_t *message, sendprio_t prio) { void lora_queuereset(void) { xQueueReset(LoraSendQueue); } -void lora_housekeeping(void) { - // ESP_LOGD(TAG, "loraloop %d bytes left", - // uxTaskGetStackHighWaterMark(LoraTask)); -} - #if (TIME_SYNC_LORAWAN) void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, int flagSuccess) { @@ -510,7 +505,7 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, time_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000; // Update system time with time read from the network - setMyTime(*pUserUTCTime + requestDelaySec, 0); + setMyTime(*pUserUTCTime + requestDelaySec, 0, _lora); finish: // end of time critical section: release app irq lock @@ -523,7 +518,7 @@ finish: void lmictask(void *pvParameters) { configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check - os_init(); // initialize lmic run-time environment on core 1 + os_init(); // initialize lmic run-time environment LMIC_reset(); // initialize lmic MAC LMIC_setLinkCheckMode(0); // This tells LMIC to make the receive windows bigger, in case your clock is diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 646069c2..a3c14829 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -22,9 +22,10 @@ Ticker timesyncer; void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } -time_t timeProvider(void) { +void calibrateTime(void) { time_t t = 0; + timesource_t timeSource; #if (HAS_GPS) // fetch recent time from last NMEA record @@ -34,9 +35,7 @@ time_t timeProvider(void) { set_rtctime(t); // calibrate RTC #endif timeSource = _gps; - timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat - ESP_LOGD(TAG, "GPS time = %d", t); - return t; + goto finish; } #endif @@ -45,8 +44,7 @@ time_t timeProvider(void) { t = get_rtctime(); if (t) { timeSource = _rtc; - timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); // short retry - ESP_LOGD(TAG, "RTC time = %d", t); + goto finish } #endif @@ -58,14 +56,17 @@ time_t timeProvider(void) { LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); #endif - if (!t) { - timeSource = _unsynced; - timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); // short retry +finish: + + if (t) { // sync successful + setMyTime(t, 0, timeSource); // set time + timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); + ESP_LOGD(TAG, "time = %d | source: %c", t, timeSetSymbols[timeSource]); + } else { // sync failed, we want to retry shortly + timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); } - return t; - -} // timeProvider() +} // calibrateTime() // helper function to setup a pulse per second for time synchronisation uint8_t timepulse_init() { diff --git a/src/timesync.cpp b/src/timesync.cpp index 95515ec9..f8ba0157 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -128,7 +128,7 @@ void process_timesync_req(void *taskparameter) { // calculate fraction milliseconds time_to_set_fraction_msec = (uint16_t)(time_offset_ms.count() % 1000); - setMyTime(time_to_set, time_to_set_fraction_msec); + setMyTime(time_to_set, time_to_set_fraction_msec, _lora); finish: // end of time critical section: release app irq lock @@ -208,7 +208,8 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { } // adjust system time, calibrate RTC and RTC_INT pps -void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) { +void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, + timesource_t timesource) { time_t time_to_set = (time_t)(t_sec + 1); @@ -218,7 +219,8 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) { if (timeIsValid(time_to_set)) { // wait until top of second with millisecond precision - vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); + if (t_msec) + vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); // set RTC time and calibrate RTC_INT pulse on top of second #ifdef HAS_RTC @@ -233,7 +235,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) { setTime(time_to_set); // set the time on top of second - timeSource = _lora; + timeSource = timesource; timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was adjusted", millis() / 1000.0);