diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index 2e5298089..e05a6a46c 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -507,6 +507,7 @@ private: static void HandleCslTimer(Timer &aTimer); void HandleCslTimer(void); void GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter); + uint32_t GetNextCycleDrift(void); uint32_t GetLocalTime(void); bool IsCslEnabled(void) const { return mCslPeriod > 0; } #if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE diff --git a/src/core/mac/sub_mac_csl_receiver.cpp b/src/core/mac/sub_mac_csl_receiver.cpp index 01ab254eb..bec526301 100644 --- a/src/core/mac/sub_mac_csl_receiver.cpp +++ b/src/core/mac/sub_mac_csl_receiver.cpp @@ -184,7 +184,7 @@ void SubMac::HandleCslReceiveAt(uint32_t aTimeAhead, uint32_t aTimeAfter) uint32_t winStart; uint32_t winDuration; - mCslTimer.FireAt(mCslSampleTimeLocal - aTimeAhead + periodUs); + mCslTimer.FireAt(mCslSampleTimeLocal + periodUs - aTimeAhead - GetNextCycleDrift()); aTimeAhead -= kCslReceiveTimeAhead; winStart = mCslSampleTimeRadio - aTimeAhead; winDuration = aTimeAhead + aTimeAfter; @@ -221,7 +221,7 @@ void SubMac::HandleCslReceiveOrSleep(uint32_t aTimeAhead, uint32_t aTimeAfter) if (mIsCslSampling) { mIsCslSampling = false; - mCslTimer.FireAt(mCslSampleTimeLocal - aTimeAhead); + mCslTimer.FireAt(mCslSampleTimeLocal - aTimeAhead - GetNextCycleDrift()); if (mState == kStateRadioSample) { LogDebg("CSL sleep %lu", ToUlong(mCslTimer.GetNow().GetValue())); @@ -266,15 +266,23 @@ void SubMac::GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter) curTime = GetLocalTime(); elapsed = curTime - mCslLastSync.GetValue(); - semiWindow = - static_cast(static_cast(elapsed) * - (Get().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) / 1000000); + semiWindow = static_cast(static_cast(elapsed) * + (Get().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) / + Time::kOneSecondInUsec); semiWindow += mCslParentAccuracy.GetUncertaintyInMicrosec() + Get().GetCslUncertainty() * 10; aAhead = Min(semiPeriod, semiWindow + kMinReceiveOnAhead + kCslReceiveTimeAhead); aAfter = Min(semiPeriod, semiWindow + kMinReceiveOnAfter); } +uint32_t SubMac::GetNextCycleDrift(void) +{ + uint64_t periodUs = mCslPeriod * kUsPerTenSymbols; + + return static_cast(periodUs * (Get().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) / + Time::kOneSecondInUsec); +} + uint32_t SubMac::GetLocalTime(void) { uint32_t now;