6 #ifndef ACE_TIME_SYSTEM_CLOCK_LOOP_H
7 #define ACE_TIME_SYSTEM_CLOCK_LOOP_H
10 #include <AceCommon.h>
11 #include "SystemClock.h"
13 class SystemClockLoopTest;
14 class SystemClockLoopTest_loop;
15 class SystemClockLoopTest_setup;
16 class SystemClockLoopTest_backupNow;
17 class SystemClockLoopTest_syncNow;
18 class SystemClockLoopTest_getNow;
47 template <
typename T_SCCI>
68 Clock* referenceClock ,
70 uint16_t syncPeriodSeconds = 3600,
71 uint16_t initialSyncPeriodSeconds = 5,
72 uint16_t requestTimeoutMillis = 1000,
73 ace_common::TimingStats* timingStats =
nullptr):
75 mSyncPeriodSeconds(syncPeriodSeconds),
76 mRequestTimeoutMillis(requestTimeoutMillis),
77 mTimingStats(timingStats),
78 mCurrentSyncPeriodSeconds(initialSyncPeriodSeconds) {}
96 switch (mRequestStatus) {
99 mRequestStartMillis = nowMillis;
100 mRequestStatus = kStatusSent;
103 + mCurrentSyncPeriodSeconds * (uint32_t) 1000);
107 uint32_t elapsedMillis = nowMillis - mRequestStartMillis;
108 if (mTimingStats) mTimingStats->update((uint16_t) elapsedMillis);
115 mRequestStatus = kStatusWaitForRetry;
120 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
121 mRequestStatus = this->kStatusOk;
126 if (elapsedMillis >= mRequestTimeoutMillis) {
127 mRequestStatus = this->kStatusWaitForRetry;
136 uint32_t elapsedMillis = nowMillis - mRequestStartMillis;
137 if (elapsedMillis >= mCurrentSyncPeriodSeconds * (uint32_t) 1000) {
138 mRequestStatus = kStatusReady;
146 case kStatusWaitForRetry: {
147 uint32_t elapsedMillis = nowMillis - mRequestStartMillis;
149 if (elapsedMillis >= mCurrentSyncPeriodSeconds * (uint32_t) 1000) {
150 if (mCurrentSyncPeriodSeconds >= mSyncPeriodSeconds / 2) {
151 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
153 mCurrentSyncPeriodSeconds *= 2;
155 mRequestStatus = kStatusReady;
171 friend class ::SystemClockLoopTest;
172 friend class ::SystemClockLoopTest_loop;
173 friend class ::SystemClockLoopTest_syncNow;
174 friend class ::SystemClockLoopTest_setup;
175 friend class ::SystemClockLoopTest_backupNow;
176 friend class ::SystemClockLoopTest_getNow;
179 static const uint8_t kStatusReady = 0;
182 static const uint8_t kStatusSent = 1;
185 static const uint8_t kStatusOk = 2;
188 static const uint8_t kStatusWaitForRetry = 3;
190 uint16_t
const mSyncPeriodSeconds = 3600;
191 uint16_t
const mRequestTimeoutMillis = 1000;
192 ace_common::TimingStats*
const mTimingStats =
nullptr;
194 uint32_t mRequestStartMillis;
195 uint16_t mCurrentSyncPeriodSeconds = 5;
196 uint8_t mRequestStatus = kStatusReady;
205 using SystemClockLoop = SystemClockLoopTemplate<hw::ClockInterface>;
Abstract base class for objects that provide and store time.
virtual void sendRequest() const
Send a time request asynchronously.
virtual acetime_t readResponse() const
Returns number of seconds since AceTime epoch (2000-01-01).
virtual bool isResponseReady() const
Return true if a response is ready.
static const acetime_t kInvalidSeconds
Error value returned by getNow() and other methods when this object is not yet initialized.
A subclass of SystemClock that sync with its mReferenceClock using the non-blocking Clock API of the ...
void loop()
Make a request to the referenceClock every syncPeriodSeconds seconds.
SystemClockLoopTemplate(Clock *referenceClock, Clock *backupClock, uint16_t syncPeriodSeconds=3600, uint16_t initialSyncPeriodSeconds=5, uint16_t requestTimeoutMillis=1000, ace_common::TimingStats *timingStats=nullptr)
Constructor.
SystemClockLoopTemplate()
Empty constructor used for testing.
A Clock that uses the Arduino millis() function to advance the time returned to the user.
static const uint8_t kSyncStatusError
Sync request failed.
void setSyncStatusCode(uint8_t code)
Set the status code of most recent sync attempt.
void setPrevSyncAttemptMillis(uint32_t ms)
Set the millis of prev sync attempt.
void keepAlive()
Call this (or getNow() every 65.535 seconds or faster to keep the internal counter in sync with milli...
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.
unsigned long clockMillis() const
Return the Arduino millis().
static const uint8_t kSyncStatusOk
Sync was successful.