@ -197,19 +197,30 @@ public:
}
}
} ;
} ;
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 {
class ESP32RTCClock : public mesh : : RTCClock {
public :
public :
ESP32RTCClock ( ) { }
ESP32RTCClock ( ) { }
void begin ( ) {
void begin ( ) {
esp_reset_reason_t reason = esp_reset_reason ( ) ;
esp_reset_reason_t reason = esp_reset_reason ( ) ;
if ( reason = = ESP_RST_POWERON ) {
if ( reason = = ESP_RST_DEEPSLEEP ) {
// start with some date/time in the recent past
return ; // ESP-IDF preserves system time across deep sleep
struct timeval tv ;
}
tv . tv_sec = 1715770351 ; // 15 May 2024, 8:50pm
// 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 ;
tv . tv_usec = 0 ;
settimeofday ( & tv , NULL ) ;
settimeofday ( & tv , NULL ) ;
}
}
}
uint32_t getCurrentTime ( ) override {
uint32_t getCurrentTime ( ) override {
time_t _now ;
time_t _now ;
time ( & _now ) ;
time ( & _now ) ;
@ -220,6 +231,16 @@ public:
tv . tv_sec = time ;
tv . tv_sec = time ;
tv . tv_usec = 0 ;
tv . tv_usec = 0 ;
settimeofday ( & tv , NULL ) ;
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 ;
}
}
}
} ;
} ;