6 #ifndef ACE_TIME_SYSTEM_CLOCK_H
7 #define ACE_TIME_SYSTEM_CLOCK_H
11 #include "../hw/ClockInterface.h"
13 class SystemClockCoroutineTest;
14 class SystemClockLoopTest;
15 class SystemClockLoopTest_loop;
16 class SystemClockLoopTest_setup;
17 class SystemClockLoopTest_backupNow;
18 class SystemClockLoopTest_syncNow;
19 class SystemClockLoopTest_getNow;
59 template <
typename T_CI>
76 if (mBackupClock !=
nullptr) {
108 while ((uint16_t) ((uint16_t)
clockMillis() - mPrevKeepAliveMillis)
110 mPrevKeepAliveMillis += 1000;
114 return mEpochSeconds;
123 void setNow(acetime_t epochSeconds)
override {
127 if (mReferenceClock !=
nullptr) {
128 mReferenceClock->
setNow(epochSeconds);
146 if (mReferenceClock) {
147 acetime_t nowSeconds = mReferenceClock->
getNow();
157 return mLastSyncTime;
177 return (int32_t) (
clockMillis() - mPrevSyncAttemptMillis) / 1000;
187 return (int32_t) (mNextSyncAttemptMillis -
clockMillis()) / 1000;
208 friend class ::SystemClockLoopTest;
209 friend class ::SystemClockCoroutineTest;
210 friend class ::SystemClockLoopTest_loop;
211 friend class ::SystemClockLoopTest_syncNow;
212 friend class ::SystemClockLoopTest_setup;
213 friend class ::SystemClockLoopTest_backupNow;
214 friend class ::SystemClockLoopTest_getNow;
238 Clock* referenceClock ,
241 mReferenceClock(referenceClock),
242 mBackupClock(backupClock) {}
252 Clock* referenceClock ,
255 mReferenceClock = referenceClock;
256 mBackupClock = backupClock;
259 mPrevSyncAttemptMillis = 0;
260 mNextSyncAttemptMillis = 0;
261 mPrevKeepAliveMillis = 0;
292 if (mBackupClock !=
nullptr) {
293 mBackupClock->
setNow(nowSeconds);
323 mLastSyncTime = epochSeconds;
324 acetime_t skew = mEpochSeconds - epochSeconds;
326 if (skew == 0)
return;
328 mEpochSeconds = epochSeconds;
332 if (mBackupClock != mReferenceClock) {
339 mNextSyncAttemptMillis = ms;
344 mPrevSyncAttemptMillis = ms;
349 mSyncStatusCode = code;
353 Clock* mReferenceClock;
358 uint32_t mPrevSyncAttemptMillis = 0;
359 uint32_t mNextSyncAttemptMillis = 0;
360 mutable uint16_t mPrevKeepAliveMillis = 0;
361 int16_t mClockSkew = 0;
362 bool mIsInit =
false;
367 using SystemClock = SystemClockTemplate<hw::ClockInterface>;
Abstract base class for objects that provide and store time.
virtual acetime_t getNow() const =0
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
virtual void setNow(acetime_t)
Set the time to the indicated seconds.
static const acetime_t kInvalidSeconds
Error value returned by getNow() and other methods when this object is not yet initialized.
A Clock that uses the Arduino millis() function to advance the time returned to the user.
int32_t getSecondsToSyncAttempt() const
Return the number of seconds until the next syncNow() attempt.
uint8_t getSyncStatusCode() const
Get sync status code.
static const uint8_t kSyncStatusError
Sync request failed.
void setup()
Attempt to retrieve the time from the backupClock if it exists.
void forceSync()
Manually force a sync with the referenceClock if it exists.
SystemClockTemplate()
Empty constructor primarily for tests.
void initSystemClock(Clock *referenceClock, Clock *backupClock)
Same as constructor but allows delayed initialization, e.g.
void backupNow(acetime_t nowSeconds)
Write the nowSeconds to the backupClock (which can be an RTC that has non-volatile memory).
void setSyncStatusCode(uint8_t code)
Set the status code of most recent sync attempt.
void setNow(acetime_t epochSeconds) override
Set the time to the indicated seconds.
void setPrevSyncAttemptMillis(uint32_t ms)
Set the millis of prev sync attempt.
SystemClockTemplate(Clock *referenceClock, Clock *backupClock)
Constructor.
void keepAlive()
Call this (or getNow() every 65.535 seconds or faster to keep the internal counter in sync with milli...
acetime_t getNow() const override
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
bool isInit() const
Return true if initialized by setNow() or syncNow().
int32_t getSecondsSinceSyncAttempt() const
Return the number of seconds since the previous sync attempt, successful or not.
void syncNow(acetime_t epochSeconds)
Set the current mEpochSeconds to the given epochSeconds.
Clock * getReferenceClock() const
Get referenceClock.
static const uint8_t kSyncStatusTimedOut
Sync request timed out.
void setNextSyncAttemptMillis(uint32_t ms)
Set the millis to next sync attempt.
int16_t getClockSkew() const
Difference between this clock compared to reference at last sync.
static const uint8_t kSyncStatusUnknown
Sync was never done.
unsigned long clockMillis() const
Return the Arduino millis().
acetime_t getLastSyncTime() const
Return the time (seconds since Epoch) of the last successful syncNow() call.
static const uint8_t kSyncStatusOk
Sync was successful.