diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 036fddd60..dcd0f444b 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -394,13 +394,14 @@ void SubMac::StartCsmaBackoff(void) if (ShouldHandleTransmitTargetTime()) { - if (Time(static_cast(otPlatRadioGetNow(&GetInstance()))) < - Time(mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime) + mTransmitFrame.mInfo.mTxInfo.mTxDelay - - kCcaSampleInterval - kCslTransmitTimeAhead - kRadioHeaderShrDuration) + static constexpr uint32_t kAheadTime = kCcaSampleInterval + kCslTransmitTimeAhead + kRadioHeaderShrDuration; + Time txStartTime = Time(mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime); + + txStartTime += (mTransmitFrame.mInfo.mTxInfo.mTxDelay - kAheadTime); + + if (Time(static_cast(otPlatRadioGetNow(&GetInstance()))) < txStartTime) { - mTimer.StartAt(Time(mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime) - kCcaSampleInterval - - kCslTransmitTimeAhead - kRadioHeaderShrDuration, - mTransmitFrame.mInfo.mTxInfo.mTxDelay); + mTimer.FireAt(txStartTime); } else // Transmit without delay { @@ -444,11 +445,7 @@ void SubMac::StartTimerForBackoff(uint8_t aBackoffExponent) IgnoreError(Get().Sleep()); } -#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE - mTimer.Start(backoff); -#else - mTimer.Start(backoff / 1000UL); -#endif + StartTimer(backoff); #if OPENTHREAD_CONFIG_MAC_ADD_DELAY_ON_NO_ACK_ERROR_BEFORE_RETRY if (mState == kStateDelayBeforeRetx) @@ -501,11 +498,7 @@ void SubMac::HandleTransmitStarted(TxFrame &aFrame) { if (ShouldHandleAckTimeout() && aFrame.GetAckRequest()) { -#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE - mTimer.Start(kAckTimeout * 1000UL); -#else - mTimer.Start(kAckTimeout); -#endif + StartTimer(kAckTimeout); } } @@ -706,7 +699,7 @@ Error SubMac::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration) SetState(kStateEnergyScan); mEnergyScanMaxRssi = Radio::kInvalidRssi; mEnergyScanEndTime = TimerMilli::GetNow() + static_cast(aScanDuration); - mTimer.Start(0); + StartTimer(0); } else { @@ -733,11 +726,7 @@ void SubMac::SampleRssi(void) if (TimerMilli::GetNow() < mEnergyScanEndTime) { -#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE - mTimer.StartAt(mTimer.GetFireTime(), kEnergyScanRssiSampleInterval * 1000UL); -#else - mTimer.StartAt(mTimer.GetFireTime(), kEnergyScanRssiSampleInterval); -#endif + StartTimerAt(mTimer.GetFireTime(), kEnergyScanRssiSampleInterval); } else { @@ -978,6 +967,24 @@ exit: return; } +void SubMac::StartTimer(uint32_t aDelayUs) +{ +#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE + mTimer.Start(aDelayUs); +#else + mTimer.Start(aDelayUs / Time::kOneMsecInUsec); +#endif +} + +void SubMac::StartTimerAt(Time aStartTime, uint32_t aDelayUs) +{ +#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE + mTimer.StartAt(aStartTime, aDelayUs); +#else + mTimer.StartAt(aStartTime, aDelayUs / Time::kOneMsecInUsec); +#endif +} + // LCOV_EXCL_START const char *SubMac::StateToString(State aState) diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index 5bd43c25b..e334091da 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -532,16 +532,17 @@ private: static void HandleCslTimer(Timer &aTimer); void HandleCslTimer(void); void GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter); + uint32_t GetLocalTime(void); #if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE void LogReceived(RxFrame *aFrame); #endif #endif - static constexpr uint8_t kCsmaMinBe = 3; // macMinBE (IEEE 802.15.4-2006). - static constexpr uint8_t kCsmaMaxBe = 5; // macMaxBE (IEEE 802.15.4-2006). - static constexpr uint32_t kUnitBackoffPeriod = 20; // Number of symbols (IEEE 802.15.4-2006). - static constexpr uint32_t kAckTimeout = 16; // Timeout for waiting on an ACK (in msec). - static constexpr uint32_t kCcaSampleInterval = 128; // CCA sample interval, 128 usec. + static constexpr uint8_t kCsmaMinBe = 3; // macMinBE (IEEE 802.15.4-2006). + static constexpr uint8_t kCsmaMaxBe = 5; // macMaxBE (IEEE 802.15.4-2006). + static constexpr uint32_t kUnitBackoffPeriod = 20; // Number of symbols (IEEE 802.15.4-2006). + static constexpr uint32_t kAckTimeout = 16 * Time::kOneMsecInUsec; // Timeout for waiting on an ACK (in usec). + static constexpr uint32_t kCcaSampleInterval = 128; // CCA sample interval, 128 usec. #if OPENTHREAD_CONFIG_MAC_ADD_DELAY_ON_NO_ACK_ERROR_BEFORE_RETRY static constexpr uint8_t kRetxDelayMinBackoffExponent = OPENTHREAD_CONFIG_MAC_RETX_DELAY_MIN_BACKOFF_EXPONENT; @@ -549,9 +550,9 @@ private: #endif #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE - static constexpr uint32_t kEnergyScanRssiSampleInterval = 128; // RSSI sample interval for energy scan, 128 usec + static constexpr uint32_t kEnergyScanRssiSampleInterval = 128; // RSSI sample interval for energy scan, in usec #else - static constexpr uint32_t kEnergyScanRssiSampleInterval = 1; // RSSI sample interval during energy scan, 1 msec + static constexpr uint32_t kEnergyScanRssiSampleInterval = 1000; // RSSI sample interval for energy scan, in usec #endif enum State : uint8_t @@ -623,6 +624,8 @@ private: void StartTimerForBackoff(uint8_t aBackoffExponent); void BeginTransmit(void); void SampleRssi(void); + void StartTimer(uint32_t aDelayUs); + void StartTimerAt(Time aStartTime, uint32_t aDelayUs); void HandleReceiveDone(RxFrame *aFrame, Error aError); void HandleTransmitStarted(TxFrame &aFrame); @@ -667,10 +670,10 @@ private: SubMacTimer mTimer; #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - uint16_t mCslPeriod; // The CSL sample period, in units of 10 symbols (160 microseconds). - uint8_t mCslChannel : 7; // The CSL sample channel. - bool mIsCslSampling : 1; // Indicates that the radio is receiving in CSL state for platforms not supporting delayed - // reception. + uint16_t mCslPeriod; // The CSL sample period, in units of 10 symbols (160 microseconds). + uint8_t mCslChannel : 7; // The CSL sample channel. + bool mIsCslSampling : 1; // Indicates that the radio is receiving in CSL state for platforms not supporting + // delayed reception. uint16_t mCslPeerShort; // The CSL peer short address. TimeMicro mCslSampleTime; // The CSL sample time of the current period relative to the local radio clock. TimeMicro mCslLastSync; // The timestamp of the last successful CSL synchronization. diff --git a/src/core/mac/sub_mac_csl_receiver.cpp b/src/core/mac/sub_mac_csl_receiver.cpp index 74f15e2b3..85611f95b 100644 --- a/src/core/mac/sub_mac_csl_receiver.cpp +++ b/src/core/mac/sub_mac_csl_receiver.cpp @@ -62,11 +62,7 @@ void SubMac::UpdateCslLastSyncTimestamp(TxFrame &aFrame, RxFrame *aAckFrame) // Assuming the error here since it is bounded and has very small effect on the final window duration. if (aAckFrame != nullptr && aFrame.GetHeaderIe(CslIe::kHeaderIeId) != nullptr) { -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC - mCslLastSync = TimerMicro::GetNow(); -#else - mCslLastSync = TimeMicro(static_cast(otPlatRadioGetNow(&GetInstance()))); -#endif + mCslLastSync = TimeMicro(GetLocalTime()); } } @@ -237,12 +233,7 @@ void SubMac::GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter) uint32_t semiPeriod = mCslPeriod * kUsPerTenSymbols / 2; uint32_t curTime, elapsed, semiWindow; -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC - curTime = TimerMicro::GetNow().GetValue(); -#else - curTime = static_cast(otPlatRadioGetNow(&GetInstance())); -#endif - + curTime = GetLocalTime(); elapsed = curTime - mCslLastSync.GetValue(); semiWindow = @@ -254,6 +245,19 @@ void SubMac::GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter) aAfter = Min(semiPeriod, semiWindow + kMinReceiveOnAfter); } +uint32_t SubMac::GetLocalTime(void) +{ + uint32_t now; + +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC + now = TimerMicro::GetNow().GetValue(); +#else + now = static_cast(otPlatRadioGetNow(&GetInstance())); +#endif + + return now; +} + #if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE void SubMac::LogReceived(RxFrame *aFrame) {