From 5f0c67c287ee56f10e68df4e3b03c574f53bd247 Mon Sep 17 00:00:00 2001 From: Wessel Nieboer Date: Mon, 2 Mar 2026 10:11:51 +0100 Subject: [PATCH 1/2] Fix 1970 date after crash/watchdog/brownout reset on ESP32 Currently, time is only set to ~2024 when it powers on cleanly. When time is lost, this results in time dropping to 1970. Save time as backup to RTC slow memory. Should fix time staying accurate during brownouts etc. --- src/helpers/ESP32Board.h | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/helpers/ESP32Board.h b/src/helpers/ESP32Board.h index d7eb5fee26..27d429b3fa 100644 --- a/src/helpers/ESP32Board.h +++ b/src/helpers/ESP32Board.h @@ -197,19 +197,30 @@ class ESP32Board : public mesh::MainBoard { } }; +static RTC_NOINIT_ATTR uint32_t _rtc_backup_time; +static RTC_NOINIT_ATTR uint32_t _rtc_backup_magic; +#define RTC_BACKUP_MAGIC 0xAA55CC33 +#define RTC_TIME_MIN 1772323200 // 1 Mar 2026 + class ESP32RTCClock : public mesh::RTCClock { public: ESP32RTCClock() { } void begin() { esp_reset_reason_t reason = esp_reset_reason(); - if (reason == ESP_RST_POWERON) { - // start with some date/time in the recent past - struct timeval tv; - tv.tv_sec = 1715770351; // 15 May 2024, 8:50pm + if (reason == ESP_RST_DEEPSLEEP) { + return; // ESP-IDF preserves system time across deep sleep + } + // All other resets (power-on, crash, WDT, brownout) lose system time. + // Restore from RTC backup if valid, otherwise use hardcoded seed. + struct timeval tv; + if (_rtc_backup_magic == RTC_BACKUP_MAGIC && _rtc_backup_time > RTC_TIME_MIN) { + tv.tv_sec = _rtc_backup_time; + } else { + tv.tv_sec = 1772323200; // 1 Mar 2026 + } tv.tv_usec = 0; settimeofday(&tv, NULL); } - } uint32_t getCurrentTime() override { time_t _now; time(&_now); @@ -220,6 +231,16 @@ class ESP32RTCClock : public mesh::RTCClock { tv.tv_sec = time; tv.tv_usec = 0; settimeofday(&tv, NULL); + _rtc_backup_time = time; + _rtc_backup_magic = RTC_BACKUP_MAGIC; + } + void tick() override { + time_t now; + time(&now); + if (now > RTC_TIME_MIN && (uint32_t)now != _rtc_backup_time) { + _rtc_backup_time = (uint32_t)now; + _rtc_backup_magic = RTC_BACKUP_MAGIC; + } } }; From bf4d877e8bd074ced67f64aa16579c61b01c4656 Mon Sep 17 00:00:00 2001 From: Wessel Date: Fri, 5 Jun 2026 19:00:33 +0200 Subject: [PATCH 2/2] Update src/helpers/ESP32Board.h Co-authored-by: Dan McGee --- src/helpers/ESP32Board.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/ESP32Board.h b/src/helpers/ESP32Board.h index 27d429b3fa..511bd1fe63 100644 --- a/src/helpers/ESP32Board.h +++ b/src/helpers/ESP32Board.h @@ -216,7 +216,7 @@ class ESP32RTCClock : public mesh::RTCClock { if (_rtc_backup_magic == RTC_BACKUP_MAGIC && _rtc_backup_time > RTC_TIME_MIN) { tv.tv_sec = _rtc_backup_time; } else { - tv.tv_sec = 1772323200; // 1 Mar 2026 + tv.tv_sec = RTC_TIME_MIN; } tv.tv_usec = 0; settimeofday(&tv, NULL);