Browse Source
Merge pull request #1 from polipl/feature/rtc-auto-sync-on-startup
Feature/rtc auto sync on startup
pull/2718/head
Paweł Małecki
1 week ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with
33 additions and
1 deletions
-
src/helpers/AutoDiscoverRTCClock.cpp
-
src/helpers/AutoDiscoverRTCClock.h
|
|
|
@ -26,6 +26,17 @@ bool AutoDiscoverRTCClock::i2c_probe(TwoWire& wire, uint8_t addr) { |
|
|
|
return (error == 0); |
|
|
|
} |
|
|
|
|
|
|
|
void AutoDiscoverRTCClock::syncSystemClock() { |
|
|
|
uint32_t hw_time = getCurrentTime(); |
|
|
|
if (hw_time <= 1704067200UL) return; // DS3231 not set or lost power (before 2024-01-01)
|
|
|
|
|
|
|
|
uint32_t sys_time = _fallback->getCurrentTime(); |
|
|
|
int32_t drift = (int32_t)(hw_time - sys_time); |
|
|
|
if (drift > 2 || drift < -2) { |
|
|
|
_fallback->setCurrentTime(hw_time); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void AutoDiscoverRTCClock::begin(TwoWire& wire) { |
|
|
|
if (i2c_probe(wire, DS3231_ADDRESS)) { |
|
|
|
ds3231_success = rtc_3231.begin(&wire); |
|
|
|
@ -49,6 +60,12 @@ void AutoDiscoverRTCClock::begin(TwoWire& wire) { |
|
|
|
rtc_8130_success = true; |
|
|
|
MESH_DEBUG_PRINTLN("RX8130CE: Initialized"); |
|
|
|
} |
|
|
|
|
|
|
|
_has_hw_rtc = ds3231_success || rv3028_success || rtc_8563_success || rtc_8130_success; |
|
|
|
if (_has_hw_rtc) { |
|
|
|
syncSystemClock(); |
|
|
|
_last_sync_ms = millis(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
uint32_t AutoDiscoverRTCClock::getCurrentTime() { |
|
|
|
|
|
|
|
@ -4,12 +4,20 @@ |
|
|
|
#include <Arduino.h> |
|
|
|
#include <Wire.h> |
|
|
|
|
|
|
|
#ifndef RTC_RESYNC_INTERVAL_MS |
|
|
|
#define RTC_RESYNC_INTERVAL_MS 3600000UL // re-sync system clock from hardware RTC once per hour
|
|
|
|
#endif |
|
|
|
|
|
|
|
class AutoDiscoverRTCClock : public mesh::RTCClock { |
|
|
|
mesh::RTCClock* _fallback; |
|
|
|
bool _has_hw_rtc; |
|
|
|
unsigned long _last_sync_ms; |
|
|
|
|
|
|
|
bool i2c_probe(TwoWire& wire, uint8_t addr); |
|
|
|
void syncSystemClock(); |
|
|
|
public: |
|
|
|
AutoDiscoverRTCClock(mesh::RTCClock& fallback) : _fallback(&fallback) { } |
|
|
|
AutoDiscoverRTCClock(mesh::RTCClock& fallback) |
|
|
|
: _fallback(&fallback), _has_hw_rtc(false), _last_sync_ms(0) { } |
|
|
|
|
|
|
|
void begin(TwoWire& wire); |
|
|
|
uint32_t getCurrentTime() override; |
|
|
|
@ -17,5 +25,12 @@ public: |
|
|
|
|
|
|
|
void tick() override { |
|
|
|
_fallback->tick(); // is typically VolatileRTCClock, which now needs tick()
|
|
|
|
if (_has_hw_rtc) { |
|
|
|
unsigned long now = millis(); |
|
|
|
if ((unsigned long)(now - _last_sync_ms) >= RTC_RESYNC_INTERVAL_MS) { |
|
|
|
syncSystemClock(); |
|
|
|
_last_sync_ms = now; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|