mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[csl] account for accuracy drift for next CSL window (#11602)
This commit improves the accuracy of CSL timer fire time by taking into account the accuracy drift introduced between the current CSL window and next CSL window. Original implementation: - calculate CSL window edges based on current elapsed time - CSL window edges used to obtain next CSL timer fireAt time - does not account for additional drift due to accuracy from now until next CSL window - undesired outcome: if CSL period is large (e.g. 10s) and accuracy is poor (e.g. 200ppm), then the additional accuracy drift could be significant (e.g. 2ms) and the SSED may wake up too late Suggested implementation: - calculate the additional expected drift between now and next CSL window (i.e. periodUs) and account for this difference by setting CSL timer to fireAt earlier
This commit is contained in:
@@ -507,6 +507,7 @@ private:
|
|||||||
static void HandleCslTimer(Timer &aTimer);
|
static void HandleCslTimer(Timer &aTimer);
|
||||||
void HandleCslTimer(void);
|
void HandleCslTimer(void);
|
||||||
void GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter);
|
void GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter);
|
||||||
|
uint32_t GetNextCycleDrift(void);
|
||||||
uint32_t GetLocalTime(void);
|
uint32_t GetLocalTime(void);
|
||||||
bool IsCslEnabled(void) const { return mCslPeriod > 0; }
|
bool IsCslEnabled(void) const { return mCslPeriod > 0; }
|
||||||
#if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE
|
#if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ void SubMac::HandleCslReceiveAt(uint32_t aTimeAhead, uint32_t aTimeAfter)
|
|||||||
uint32_t winStart;
|
uint32_t winStart;
|
||||||
uint32_t winDuration;
|
uint32_t winDuration;
|
||||||
|
|
||||||
mCslTimer.FireAt(mCslSampleTimeLocal - aTimeAhead + periodUs);
|
mCslTimer.FireAt(mCslSampleTimeLocal + periodUs - aTimeAhead - GetNextCycleDrift());
|
||||||
aTimeAhead -= kCslReceiveTimeAhead;
|
aTimeAhead -= kCslReceiveTimeAhead;
|
||||||
winStart = mCslSampleTimeRadio - aTimeAhead;
|
winStart = mCslSampleTimeRadio - aTimeAhead;
|
||||||
winDuration = aTimeAhead + aTimeAfter;
|
winDuration = aTimeAhead + aTimeAfter;
|
||||||
@@ -221,7 +221,7 @@ void SubMac::HandleCslReceiveOrSleep(uint32_t aTimeAhead, uint32_t aTimeAfter)
|
|||||||
if (mIsCslSampling)
|
if (mIsCslSampling)
|
||||||
{
|
{
|
||||||
mIsCslSampling = false;
|
mIsCslSampling = false;
|
||||||
mCslTimer.FireAt(mCslSampleTimeLocal - aTimeAhead);
|
mCslTimer.FireAt(mCslSampleTimeLocal - aTimeAhead - GetNextCycleDrift());
|
||||||
if (mState == kStateRadioSample)
|
if (mState == kStateRadioSample)
|
||||||
{
|
{
|
||||||
LogDebg("CSL sleep %lu", ToUlong(mCslTimer.GetNow().GetValue()));
|
LogDebg("CSL sleep %lu", ToUlong(mCslTimer.GetNow().GetValue()));
|
||||||
@@ -266,15 +266,23 @@ void SubMac::GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter)
|
|||||||
curTime = GetLocalTime();
|
curTime = GetLocalTime();
|
||||||
elapsed = curTime - mCslLastSync.GetValue();
|
elapsed = curTime - mCslLastSync.GetValue();
|
||||||
|
|
||||||
semiWindow =
|
semiWindow = static_cast<uint32_t>(static_cast<uint64_t>(elapsed) *
|
||||||
static_cast<uint32_t>(static_cast<uint64_t>(elapsed) *
|
(Get<Radio>().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) /
|
||||||
(Get<Radio>().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) / 1000000);
|
Time::kOneSecondInUsec);
|
||||||
semiWindow += mCslParentAccuracy.GetUncertaintyInMicrosec() + Get<Radio>().GetCslUncertainty() * 10;
|
semiWindow += mCslParentAccuracy.GetUncertaintyInMicrosec() + Get<Radio>().GetCslUncertainty() * 10;
|
||||||
|
|
||||||
aAhead = Min(semiPeriod, semiWindow + kMinReceiveOnAhead + kCslReceiveTimeAhead);
|
aAhead = Min(semiPeriod, semiWindow + kMinReceiveOnAhead + kCslReceiveTimeAhead);
|
||||||
aAfter = Min(semiPeriod, semiWindow + kMinReceiveOnAfter);
|
aAfter = Min(semiPeriod, semiWindow + kMinReceiveOnAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SubMac::GetNextCycleDrift(void)
|
||||||
|
{
|
||||||
|
uint64_t periodUs = mCslPeriod * kUsPerTenSymbols;
|
||||||
|
|
||||||
|
return static_cast<uint32_t>(periodUs * (Get<Radio>().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) /
|
||||||
|
Time::kOneSecondInUsec);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t SubMac::GetLocalTime(void)
|
uint32_t SubMac::GetLocalTime(void)
|
||||||
{
|
{
|
||||||
uint32_t now;
|
uint32_t now;
|
||||||
|
|||||||
Reference in New Issue
Block a user