[radio] introduce dedicated RadioTime types to clarify clock domain (#13268)

This commit introduces dedicated type definitions `otRadioTime64`
(`RadioTime64`) and `otRadioTime32` (`RadioTime32`) to represent radio
hardware microsecond timestamps.

Key benefits and changes:
- Self-Documenting Clock Domain: Transceiver hardware clocks operate in a
  distinct clock domain (`otPlatRadioGetNow()`) from core system timers
  (`TimerMilli::GetNow()`, `TimerMicro::GetNow()`). Using dedicated
  types prevents developers from accidentally passing core system time
  into radio scheduling APIs.
- Explicit Rollover Handling: Introduced `IsRadioTimeStrictlyBefore()` to
  compare 32-bit radio timestamps using modulo serial arithmetic, cleanly
  accounting for `uint32_t` microsecond counter wrap-around.
- Core Module Adoption: Updated `otRadioFrame::mTxInfo` / `mRxInfo`,
  `otPlatRadioGetNow()`, `otPlatRadioReceiveAt()`, `SubMac`, and
  `CslTxScheduler` to adopt the new radio time types.
This commit is contained in:
Abtin Keshavarzian
2026-07-03 12:32:11 -07:00
committed by GitHub
parent 593fc53fcf
commit 4c44ff1edb
26 changed files with 259 additions and 90 deletions
+2 -2
View File
@@ -1041,7 +1041,7 @@ exit:
} }
#endif #endif
uint64_t otPlatRadioGetNow(otInstance *aInstance) otRadioTime64 otPlatRadioGetNow(otInstance *aInstance)
{ {
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
@@ -1109,7 +1109,7 @@ otError otPlatRadioResetCsl(otInstance *aInstance)
return OT_ERROR_NONE; return OT_ERROR_NONE;
} }
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime) void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, otRadioTime32 aCslSampleTime)
{ {
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
+1 -1
View File
@@ -345,7 +345,7 @@ typedef struct otRadioContext
otExtAddress mExtAddress; ///< In little-endian byte order. otExtAddress mExtAddress; ///< In little-endian byte order.
uint32_t mMacFrameCounter; uint32_t mMacFrameCounter;
uint32_t mPrevMacFrameCounter; uint32_t mPrevMacFrameCounter;
uint32_t mCslSampleTime; ///< The sample time based on the microsecond timer. otRadioTime32 mCslSampleTime; ///< The sample time based on the microsecond timer.
uint16_t mCslPeriod; ///< In unit of 10 symbols. uint16_t mCslPeriod; ///< In unit of 10 symbols.
otShortAddress mCslShortAddress; ///< The short address of the CSL receiver's peer. otShortAddress mCslShortAddress; ///< The short address of the CSL receiver's peer.
otExtAddress mCslExtAddress; ///< The extended address of the CSL receiver's peer. otExtAddress mCslExtAddress; ///< The extended address of the CSL receiver's peer.
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
* *
* @note This number versions both OpenThread platform and user APIs. * @note This number versions both OpenThread platform and user APIs.
*/ */
#define OPENTHREAD_API_VERSION (609) #define OPENTHREAD_API_VERSION (610)
/** /**
* @addtogroup api-instance * @addtogroup api-instance
+25 -6
View File
@@ -183,6 +183,25 @@ struct otExtAddress
*/ */
typedef struct otExtAddress otExtAddress; typedef struct otExtAddress otExtAddress;
/**
* Represents a 64-bit radio time in microseconds referenced to a continuous monotonic local radio clock.
*
* This type is returned by `otPlatRadioGetNow()` and is used as the timestamp field (`mTimestamp`) in radio frames
* (`otRadioFrame`).
*/
typedef uint64_t otRadioTime64;
/**
* Represents a 32-bit radio time in microseconds.
*
* This type holds the lower 32 bits (least significant bits) of a full 64-bit radio time (`otRadioTime64`).
*
* It is used in APIs such as `otPlatRadioReceiveAt()` and `otPlatRadioUpdateCslSampleTime()` and as the transmission
* delay base time (`mTxDelayBaseTime`) in `otRadioFrame`. It is important for radio platform implementations to
* correctly account for its roll-over.
*/
typedef uint32_t otRadioTime32;
#define OT_MAC_KEY_SIZE 16 ///< Size of the MAC Key in bytes. #define OT_MAC_KEY_SIZE 16 ///< Size of the MAC Key in bytes.
/** /**
@@ -273,7 +292,7 @@ typedef struct otRadioFrame
* *
* This field does not affect CCA behavior which is controlled by `mCsmaCaEnabled`. * This field does not affect CCA behavior which is controlled by `mCsmaCaEnabled`.
*/ */
uint32_t mTxDelayBaseTime; otRadioTime32 mTxDelayBaseTime;
/** /**
* The delay time in microseconds for this transmission referenced * The delay time in microseconds for this transmission referenced
@@ -381,7 +400,7 @@ typedef struct otRadioFrame
* *
* The platform should update this field before otPlatRadioTxStarted() is fired for each transmit attempt. * The platform should update this field before otPlatRadioTxStarted() is fired for each transmit attempt.
*/ */
uint64_t mTimestamp; otRadioTime64 mTimestamp;
} mTxInfo; } mTxInfo;
/** /**
@@ -393,7 +412,7 @@ typedef struct otRadioFrame
* The time of the local radio clock in microseconds when the end of * The time of the local radio clock in microseconds when the end of
* the SFD was present at the local antenna. * the SFD was present at the local antenna.
*/ */
uint64_t mTimestamp; otRadioTime64 mTimestamp;
uint32_t mAckFrameCounter; ///< ACK security frame counter (applicable when `mAckedWithSecEnhAck` is set). uint32_t mAckFrameCounter; ///< ACK security frame counter (applicable when `mAckedWithSecEnhAck` is set).
uint8_t mAckKeyId; ///< ACK security key index (applicable when `mAckedWithSecEnhAck` is set). uint8_t mAckKeyId; ///< ACK security key index (applicable when `mAckedWithSecEnhAck` is set).
@@ -765,7 +784,7 @@ void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacF
* @returns The current time in microseconds. UINT64_MAX when platform does not * @returns The current time in microseconds. UINT64_MAX when platform does not
* support or radio time is not ready. * support or radio time is not ready.
*/ */
uint64_t otPlatRadioGetNow(otInstance *aInstance); otRadioTime64 otPlatRadioGetNow(otInstance *aInstance);
/** /**
* Get the bus speed in bits/second between the host and the radio chip. * Get the bus speed in bits/second between the host and the radio chip.
@@ -894,7 +913,7 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel);
* @retval OT_ERROR_NONE Successfully scheduled receive window. * @retval OT_ERROR_NONE Successfully scheduled receive window.
* @retval OT_ERROR_FAILED The receive window could not be scheduled. For example, if @p aStart is in the past. * @retval OT_ERROR_FAILED The receive window could not be scheduled. For example, if @p aStart is in the past.
*/ */
otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration); otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, otRadioTime32 aStart, uint32_t aDuration);
/** /**
* The radio driver calls this function to notify OpenThread of a received frame. * The radio driver calls this function to notify OpenThread of a received frame.
@@ -1225,7 +1244,7 @@ otError otPlatRadioResetCsl(otInstance *aInstance);
* the time when the first symbol of the MHR of * the time when the first symbol of the MHR of
* the frame is expected. * the frame is expected.
*/ */
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime); void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, otRadioTime32 aCslSampleTime);
/** /**
* Get the current estimated worst case accuracy (maximum ± deviation from the * Get the current estimated worst case accuracy (maximum ± deviation from the
+3
View File
@@ -663,6 +663,8 @@ openthread_core_files = [
"radio/radio.hpp", "radio/radio.hpp",
"radio/radio_callbacks.cpp", "radio/radio_callbacks.cpp",
"radio/radio_platform.cpp", "radio/radio_platform.cpp",
"radio/radio_types.cpp",
"radio/radio_types.hpp",
"radio/trel_interface.cpp", "radio/trel_interface.cpp",
"radio/trel_interface.hpp", "radio/trel_interface.hpp",
"radio/trel_link.cpp", "radio/trel_link.cpp",
@@ -857,6 +859,7 @@ openthread_radio_sources = [
"radio/radio.cpp", "radio/radio.cpp",
"radio/radio_callbacks.cpp", "radio/radio_callbacks.cpp",
"radio/radio_platform.cpp", "radio/radio_platform.cpp",
"radio/radio_types.cpp",
"thread/link_quality.cpp", "thread/link_quality.cpp",
"utils/parse_cmdline.cpp", "utils/parse_cmdline.cpp",
"utils/power_calibration.cpp", "utils/power_calibration.cpp",
+2
View File
@@ -224,6 +224,7 @@ set(COMMON_SOURCES
radio/radio.cpp radio/radio.cpp
radio/radio_callbacks.cpp radio/radio_callbacks.cpp
radio/radio_platform.cpp radio/radio_platform.cpp
radio/radio_types.cpp
radio/trel_interface.cpp radio/trel_interface.cpp
radio/trel_link.cpp radio/trel_link.cpp
radio/trel_packet.cpp radio/trel_packet.cpp
@@ -339,6 +340,7 @@ set(RADIO_COMMON_SOURCES
radio/radio.cpp radio/radio.cpp
radio/radio_callbacks.cpp radio/radio_callbacks.cpp
radio/radio_platform.cpp radio/radio_platform.cpp
radio/radio_types.cpp
thread/link_quality.cpp thread/link_quality.cpp
utils/otns.cpp utils/otns.cpp
utils/parse_cmdline.cpp utils/parse_cmdline.cpp
+6 -6
View File
@@ -2498,7 +2498,7 @@ void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr)
neighbor->SetCslLastHeard(TimerMilli::GetNow()); neighbor->SetCslLastHeard(TimerMilli::GetNow());
neighbor->SetLastRxTimestamp(aFrame.GetTimestamp()); neighbor->SetLastRxTimestamp(aFrame.GetTimestamp());
LogDebg("Timestamp=%lu Sequence=%u CslPeriod=%u CslPhase=%u TransmitPhase=%u", LogDebg("Timestamp=%lu Sequence=%u CslPeriod=%u CslPhase=%u TransmitPhase=%u",
ToUlong(static_cast<uint32_t>(aFrame.GetTimestamp())), aFrame.GetSequence(), csl->GetPeriod(), ToUlong(ConvertRadioTime64To32(aFrame.GetTimestamp())), aFrame.GetSequence(), csl->GetPeriod(),
csl->GetPhase(), neighbor->GetCslPhase()); csl->GetPhase(), neighbor->GetCslPhase());
#if OPENTHREAD_FTD #if OPENTHREAD_FTD
@@ -2622,9 +2622,9 @@ Error Mac::HandleWakeupFrame(const RxFrame &aFrame)
const ConnectionIe *connectionIe; const ConnectionIe *connectionIe;
Address srcAddress; Address srcAddress;
WakeupInfo wakeupInfo; WakeupInfo wakeupInfo;
uint32_t rvTimeUs; RadioTime32 rvTimeUs;
uint64_t rvTimestampUs; RadioTime64 rvTimestampUs;
uint64_t radioNowUs; RadioTime64 radioNowUs;
VerifyOrExit(mWakeupListenEnabled && aFrame.IsWakeupFrame()); VerifyOrExit(mWakeupListenEnabled && aFrame.IsWakeupFrame());
@@ -2637,13 +2637,13 @@ Error Mac::HandleWakeupFrame(const RxFrame &aFrame)
wakeupInfo.mRetryCount = connectionIe->GetRetryCount(); wakeupInfo.mRetryCount = connectionIe->GetRetryCount();
VerifyOrExit(wakeupInfo.mRetryInterval > 0 && wakeupInfo.mRetryCount > 0, error = kErrorInvalidArgs); VerifyOrExit(wakeupInfo.mRetryInterval > 0 && wakeupInfo.mRetryCount > 0, error = kErrorInvalidArgs);
radioNowUs = otPlatRadioGetNow(&GetInstance()); radioNowUs = Get<Radio>().GetNow();
rvTimeUs = aFrame.Find<RendezvousTimeIe>()->GetRendezvousTime() * kUsPerTenSymbols; rvTimeUs = aFrame.Find<RendezvousTimeIe>()->GetRendezvousTime() * kUsPerTenSymbols;
rvTimestampUs = aFrame.GetTimestamp() + kRadioHeaderPhrDuration + aFrame.GetLength() * kOctetDuration + rvTimeUs; rvTimestampUs = aFrame.GetTimestamp() + kRadioHeaderPhrDuration + aFrame.GetLength() * kOctetDuration + rvTimeUs;
if (rvTimestampUs > radioNowUs + kCslRequestAhead) if (rvTimestampUs > radioNowUs + kCslRequestAhead)
{ {
wakeupInfo.mAttachDelayMs = static_cast<uint32_t>(rvTimestampUs - radioNowUs - kCslRequestAhead); wakeupInfo.mAttachDelayMs = ConvertRadioTime64To32(rvTimestampUs - radioNowUs - kCslRequestAhead);
wakeupInfo.mAttachDelayMs = wakeupInfo.mAttachDelayMs / Time::kOneMsecInUsec; wakeupInfo.mAttachDelayMs = wakeupInfo.mAttachDelayMs / Time::kOneMsecInUsec;
} }
else else
+17 -2
View File
@@ -43,6 +43,7 @@
#include "mac/mac_header_ie.hpp" #include "mac/mac_header_ie.hpp"
#include "mac/mac_types.hpp" #include "mac/mac_types.hpp"
#include "meshcop/network_name.hpp" #include "meshcop/network_name.hpp"
#include "radio/radio_types.hpp"
namespace ot { namespace ot {
namespace Mac { namespace Mac {
@@ -945,7 +946,7 @@ public:
* *
* @returns The timestamp in microseconds. * @returns The timestamp in microseconds.
*/ */
const uint64_t &GetTimestamp(void) const { return mInfo.mRxInfo.mTimestamp; } const RadioTime64 &GetTimestamp(void) const { return mInfo.mRxInfo.mTimestamp; }
/** /**
* Performs AES CCM on the frame which is received. * Performs AES CCM on the frame which is received.
@@ -1283,6 +1284,13 @@ public:
#endif #endif
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
/**
* Gets the TX delay field for the frame.
*
* @returns The delay time for the TX frame in microseconds.
*/
uint32_t GetTxDelay(void) const { return mInfo.mTxInfo.mTxDelay; }
/** /**
* Set TX delay field for the frame. * Set TX delay field for the frame.
* *
@@ -1290,12 +1298,19 @@ public:
*/ */
void SetTxDelay(uint32_t aTxDelay) { mInfo.mTxInfo.mTxDelay = aTxDelay; } void SetTxDelay(uint32_t aTxDelay) { mInfo.mTxInfo.mTxDelay = aTxDelay; }
/**
* Gets the TX delay base time field for the frame.
*
* @returns The delay base time for the TX frame as a `RadioTime32`.
*/
RadioTime32 GetTxDelayBaseTime(void) const { return mInfo.mTxInfo.mTxDelayBaseTime; }
/** /**
* Set TX delay base time field for the frame. * Set TX delay base time field for the frame.
* *
* @param[in] aTxDelayBaseTime The delay base time for the TX frame. * @param[in] aTxDelayBaseTime The delay base time for the TX frame.
*/ */
void SetTxDelayBaseTime(uint32_t aTxDelayBaseTime) { mInfo.mTxInfo.mTxDelayBaseTime = aTxDelayBaseTime; } void SetTxDelayBaseTime(RadioTime32 aTxDelayBaseTime) { mInfo.mTxInfo.mTxDelayBaseTime = aTxDelayBaseTime; }
#endif #endif
}; };
+9 -12
View File
@@ -427,32 +427,29 @@ void SubMac::StartCsmaBackoff(void)
uint8_t backoffExponent = kCsmaMinBe + mCsmaBackoffs; uint8_t backoffExponent = kCsmaMinBe + mCsmaBackoffs;
#if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
if (mTransmitFrame.mInfo.mTxInfo.mTxDelay != 0 || mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime != 0) if (mTransmitFrame.GetTxDelay() != 0 || mTransmitFrame.GetTxDelayBaseTime() != 0)
{ {
SetState(kStateCslTransmit); SetState(kStateCslTransmit);
if (ShouldHandleTransmitTargetTime()) if (ShouldHandleTransmitTargetTime())
{ {
static constexpr uint32_t kAheadTime = kCcaSampleInterval + kCslTransmitTimeAhead + kRadioHeaderShrDuration; static constexpr uint32_t kAheadTime = kCcaSampleInterval + kCslTransmitTimeAhead + kRadioHeaderShrDuration;
Time txStartTime = Time(mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime);
Time radioNow = Time(static_cast<uint32_t>(Get<Radio>().GetNow())); RadioTime32 radioNow = Get<Radio>().GetNowAsRadioTime32();
RadioTime32 txStartTime = mTransmitFrame.GetTxDelayBaseTime();
txStartTime += (mTransmitFrame.mInfo.mTxInfo.mTxDelay - kAheadTime); txStartTime += (mTransmitFrame.mInfo.mTxInfo.mTxDelay - kAheadTime);
if (radioNow < txStartTime) if (IsRadioTimeStrictlyBefore(radioNow, txStartTime))
{ {
StartTimer(txStartTime - radioNow); StartTimer(txStartTime - radioNow);
ExitNow();
} }
else // Transmit without delay
{ // Transmit without delay
BeginTransmit();
}
}
else
{
BeginTransmit();
} }
BeginTransmit();
ExitNow(); ExitNow();
} }
#endif // !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #endif // !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
+10 -10
View File
@@ -677,7 +677,7 @@ private:
bool mIsCslSampling : 1; // Indicates that the current time is in CSL sample window bool mIsCslSampling : 1; // Indicates that the current time is in CSL sample window
// for platforms not supporting `Radio::ReceiveAt()`. // for platforms not supporting `Radio::ReceiveAt()`.
uint16_t mCslPeerShort; // The CSL peer short address. uint16_t mCslPeerShort; // The CSL peer short address.
uint32_t mCslSampleTimeRadio; // The CSL sample time of the current period based on radio time (lower 32-bit). RadioTime32 mCslSampleTimeRadio; // The CSL sample time of the current period based on radio time (lower 32-bit).
TimeMicro mCslSampleTimeLocal; // The CSL sample time of the current period based on local time. TimeMicro mCslSampleTimeLocal; // The CSL sample time of the current period based on local time.
TimeMicro mCslLastSync; // The timestamp of the last successful CSL synchronization. TimeMicro mCslLastSync; // The timestamp of the last successful CSL synchronization.
CslAccuracy mCslParentAccuracy; // The parent's CSL accuracy (clock accuracy and uncertainty). CslAccuracy mCslParentAccuracy; // The parent's CSL accuracy (clock accuracy and uncertainty).
@@ -685,15 +685,15 @@ private:
#endif #endif
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
bool mIsWedSampling : 1; // Indicates that the current time is in WED's sample window bool mIsWedSampling : 1; // Indicates that the current time is in WED's sample window
// for platforms not supporting `Radio::ReceiveAt()`. // for platforms not supporting `Radio::ReceiveAt()`.
bool mIsWedEnabled : 1; // Indicates if the WED is enabled. bool mIsWedEnabled : 1; // Indicates if the WED is enabled.
uint32_t mWakeupListenInterval; // The wake-up listen interval, in microseconds. uint32_t mWakeupListenInterval; // The wake-up listen interval, in microseconds.
uint32_t mWakeupListenDuration; // The wake-up listen duration, in microseconds. uint32_t mWakeupListenDuration; // The wake-up listen duration, in microseconds.
uint8_t mWakeupChannel; // The wake-up sample channel. uint8_t mWakeupChannel; // The wake-up sample channel.
TimeMicro mWedSampleTime; // The WED sample time of the current interval in local time. TimeMicro mWedSampleTime; // The WED sample time of the current interval in local time.
uint64_t mWedSampleTimeRadio; // The WED sample time of the current interval in radio time. RadioTime64 mWedSampleTimeRadio; // The WED sample time of the current interval in radio time.
TimerMicro mWedTimer; TimerMicro mWedTimer;
#endif #endif
}; };
+8 -9
View File
@@ -99,7 +99,7 @@ void SubMac::UpdateCslLastSyncTimestamp(RxFrame *aFrame, Error aError)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC
mCslLastSync = TimerMicro::GetNow(); mCslLastSync = TimerMicro::GetNow();
#else #else
mCslLastSync = TimeMicro(static_cast<uint32_t>(aFrame->mInfo.mRxInfo.mTimestamp)); mCslLastSync = TimeMicro(ConvertRadioTime64To32(aFrame->GetTimestamp()));
#endif #endif
} }
@@ -129,7 +129,7 @@ void SubMac::SetCslParams(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShor
mCslTimer.Stop(); mCslTimer.Stop();
if (mCslPeriod > 0) if (mCslPeriod > 0)
{ {
mCslSampleTimeRadio = static_cast<uint32_t>(Get<Radio>().GetNow()); mCslSampleTimeRadio = Get<Radio>().GetNowAsRadioTime32();
mCslSampleTimeLocal = TimerMicro::GetNow(); mCslSampleTimeLocal = TimerMicro::GetNow();
// Update CSL sync time whenever CSL parameters are re-initialized. // Update CSL sync time whenever CSL parameters are re-initialized.
mCslLastSync = mCslSampleTimeLocal; mCslLastSync = mCslSampleTimeLocal;
@@ -180,9 +180,9 @@ void SubMac::HandleCslReceiveAt(uint32_t aTimeAhead, uint32_t aTimeAfter)
* x-|------------|-------------------------------------x-|------------|---------------------------------------| * x-|------------|-------------------------------------x-|------------|---------------------------------------|
* sample sleep sample sleep * sample sleep sample sleep
*/ */
uint32_t periodUs = mCslPeriod * kUsPerTenSymbols; uint32_t periodUs = mCslPeriod * kUsPerTenSymbols;
uint32_t winStart; RadioTime32 winStart;
uint32_t winDuration; uint32_t winDuration;
mCslTimer.FireAt(mCslSampleTimeLocal + periodUs - aTimeAhead - GetNextCycleDrift()); mCslTimer.FireAt(mCslSampleTimeLocal + periodUs - aTimeAhead - GetNextCycleDrift());
aTimeAhead -= kCslReceiveTimeAhead; aTimeAhead -= kCslReceiveTimeAhead;
@@ -290,7 +290,7 @@ uint32_t SubMac::GetLocalTime(void)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC
now = TimerMicro::GetNow().GetValue(); now = TimerMicro::GetNow().GetValue();
#else #else
now = static_cast<uint32_t>(Get<Radio>().GetNow()); now = Get<Radio>().GetNowAsRadioTime32();
#endif #endif
return now; return now;
@@ -321,8 +321,7 @@ void SubMac::LogReceived(RxFrame *aFrame)
(dst.GetType() == Address::kTypeExtended && dst.GetExtended() == GetExtAddress())); (dst.GetType() == Address::kTypeExtended && dst.GetExtended() == GetExtAddress()));
LogDebg("Received frame in state (SubMac %s, CSL %s), timestamp %lu", StateToString(mState), LogDebg("Received frame in state (SubMac %s, CSL %s), timestamp %lu", StateToString(mState),
mIsCslSampling ? "CslSample" : "CslSleep", mIsCslSampling ? "CslSample" : "CslSleep", ToUlong(ConvertRadioTime64To32(aFrame->GetTimestamp())));
ToUlong(static_cast<uint32_t>(aFrame->mInfo.mRxInfo.mTimestamp)));
VerifyOrExit(mState == kStateRadioSample); VerifyOrExit(mState == kStateRadioSample);
@@ -330,7 +329,7 @@ void SubMac::LogReceived(RxFrame *aFrame)
ahead -= kMinReceiveOnAhead + kCslReceiveTimeAhead; ahead -= kMinReceiveOnAhead + kCslReceiveTimeAhead;
sampleTime = mCslSampleTimeRadio - mCslPeriod * kUsPerTenSymbols; sampleTime = mCslSampleTimeRadio - mCslPeriod * kUsPerTenSymbols;
deviation = static_cast<uint32_t>(aFrame->mInfo.mRxInfo.mTimestamp) + kRadioHeaderPhrDuration - sampleTime; deviation = ConvertRadioTime64To32(aFrame->GetTimestamp()) + kRadioHeaderPhrDuration - sampleTime;
// This logs three values (all in microseconds): // This logs three values (all in microseconds):
// - Absolute sample time in which the CSL receiver expected the MHR of the received frame. // - Absolute sample time in which the CSL receiver expected the MHR of the received frame.
+1 -1
View File
@@ -96,7 +96,7 @@ void SubMac::HandleWedReceiveAt(void)
if (mState != kStateDisabled) if (mState != kStateDisabled)
{ {
IgnoreError( IgnoreError(
Get<Radio>().ReceiveAt(mWakeupChannel, static_cast<uint32_t>(mWedSampleTimeRadio), mWakeupListenDuration)); Get<Radio>().ReceiveAt(mWakeupChannel, ConvertRadioTime64To32(mWedSampleTimeRadio), mWakeupListenDuration));
} }
} }
+1 -1
View File
@@ -100,7 +100,7 @@ Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &aTxFrames)
VerifyOrExit(frame->GenerateWakeupFrame(Get<Mac::Mac>().GetPanId(), mWakeupRequest, source) == kErrorNone, VerifyOrExit(frame->GenerateWakeupFrame(Get<Mac::Mac>().GetPanId(), mWakeupRequest, source) == kErrorNone,
frame = nullptr); frame = nullptr);
frame->SetTxDelayBaseTime(static_cast<uint32_t>(Get<Radio>().GetNow())); frame->SetTxDelayBaseTime(Get<Radio>().GetNowAsRadioTime32());
frame->SetTxDelay(radioTxDelay); frame->SetTxDelay(radioTxDelay);
frame->SetCsmaCaEnabled(kWakeupFrameTxCca); frame->SetCsmaCaEnabled(kWakeupFrameTxCca);
frame->SetMaxCsmaBackoffs(0); frame->SetMaxCsmaBackoffs(0);
+2
View File
@@ -128,6 +128,8 @@ Error Radio::Transmit(Mac::TxFrame &aFrame)
} }
#endif // OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE #endif // OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
//---------------------------------------------------------------------------------------------------------------------
#if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD) #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
inline uint64_t UintSafeMinus(uint64_t aLhs, uint64_t aRhs) { return aLhs > aRhs ? (aLhs - aRhs) : 0; } inline uint64_t UintSafeMinus(uint64_t aLhs, uint64_t aRhs) { return aLhs > aRhs ? (aLhs - aRhs) : 0; }
+16 -8
View File
@@ -46,6 +46,7 @@
#include "common/numeric_limits.hpp" #include "common/numeric_limits.hpp"
#include "common/time.hpp" #include "common/time.hpp"
#include "mac/mac_frame.hpp" #include "mac/mac_frame.hpp"
#include "radio/radio_types.hpp"
namespace ot { namespace ot {
@@ -523,7 +524,7 @@ public:
* @retval kErrorNone Successfully scheduled receive window. * @retval kErrorNone Successfully scheduled receive window.
* @retval kErrorFailed The receive window could not be scheduled. * @retval kErrorFailed The receive window could not be scheduled.
*/ */
Error ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration); Error ReceiveAt(uint8_t aChannel, RadioTime32 aStart, uint32_t aDuration);
#endif #endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
@@ -532,7 +533,7 @@ public:
* *
* @param[in] aCslSampleTime The CSL sample time. * @param[in] aCslSampleTime The CSL sample time.
*/ */
void UpdateCslSampleTime(uint32_t aCslSampleTime); void UpdateCslSampleTime(RadioTime32 aCslSampleTime);
/** /**
* Enables CSL sampling in radio. * Enables CSL sampling in radio.
@@ -567,7 +568,14 @@ public:
* *
* @returns The current radio clock time. * @returns The current radio clock time.
*/ */
uint64_t GetNow(void); RadioTime64 GetNow(void);
/**
* Get the current radio time in microseconds as a 32-bit value (lower 32 bits of the full radio time).
*
* @returns The current radio clock time as a `RadioTime32`.
*/
RadioTime32 GetNowAsRadioTime32(void) { return ConvertRadioTime64To32(GetNow()); }
/** /**
* Get the current accuracy, in units of ± ppm, of the clock used for scheduling CSL operations. * Get the current accuracy, in units of ± ppm, of the clock used for scheduling CSL operations.
@@ -984,7 +992,7 @@ inline Error Radio::Receive(uint8_t aChannel)
} }
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
inline Error Radio::ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration) inline Error Radio::ReceiveAt(uint8_t aChannel, RadioTime32 aStart, uint32_t aDuration)
{ {
Error error = otPlatRadioReceiveAt(GetInstancePtr(), aChannel, aStart, aDuration); Error error = otPlatRadioReceiveAt(GetInstancePtr(), aChannel, aStart, aDuration);
#if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD) #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
@@ -998,7 +1006,7 @@ inline Error Radio::ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDurat
#endif #endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
inline void Radio::UpdateCslSampleTime(uint32_t aCslSampleTime) inline void Radio::UpdateCslSampleTime(RadioTime32 aCslSampleTime)
{ {
otPlatRadioUpdateCslSampleTime(GetInstancePtr(), aCslSampleTime); otPlatRadioUpdateCslSampleTime(GetInstancePtr(), aCslSampleTime);
} }
@@ -1013,7 +1021,7 @@ inline Error Radio::ResetCsl(void) { return otPlatRadioResetCsl(GetInstancePtr()
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE || \ #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE || \
OPENTHREAD_CONFIG_TIME_SYNC_ENABLE OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
inline uint64_t Radio::GetNow(void) { return otPlatRadioGetNow(GetInstancePtr()); } inline RadioTime64 Radio::GetNow(void) { return otPlatRadioGetNow(GetInstancePtr()); }
inline uint8_t Radio::GetCslAccuracy(void) { return otPlatRadioGetCslAccuracy(GetInstancePtr()); } inline uint8_t Radio::GetCslAccuracy(void) { return otPlatRadioGetCslAccuracy(GetInstancePtr()); }
@@ -1112,7 +1120,7 @@ inline Error Radio::ReceiveAt(uint8_t, uint32_t, uint32_t) { return kErrorNone;
#endif #endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
inline void Radio::UpdateCslSampleTime(uint32_t) {} inline void Radio::UpdateCslSampleTime(RadioTime32) {}
inline Error Radio::EnableCsl(uint32_t, Mac::ShortAddress, const Mac::ExtAddress &) { return kErrorNotImplemented; } inline Error Radio::EnableCsl(uint32_t, Mac::ShortAddress, const Mac::ExtAddress &) { return kErrorNotImplemented; }
@@ -1121,7 +1129,7 @@ inline Error Radio::ResetCsl(void) { return kErrorNotImplemented; }
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE || \ #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE || \
OPENTHREAD_CONFIG_TIME_SYNC_ENABLE OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
inline uint64_t Radio::GetNow(void) { return NumericLimits<uint64_t>::kMax; } inline RadioTime64 Radio::GetNow(void) { return NumericLimits<uint64_t>::kMax; }
inline uint8_t Radio::GetCslAccuracy(void) { return NumericLimits<uint8_t>::kMax; } inline uint8_t Radio::GetCslAccuracy(void) { return NumericLimits<uint8_t>::kMax; }
+5 -5
View File
@@ -281,7 +281,7 @@ extern "C" OT_TOOL_WEAK void otPlatRadioSetMacFrameCounterIfLarger(otInstance *a
extern "C" OT_TOOL_WEAK uint64_t otPlatTimeGet(void) { return UINT64_MAX; } extern "C" OT_TOOL_WEAK uint64_t otPlatTimeGet(void) { return UINT64_MAX; }
extern "C" OT_TOOL_WEAK uint64_t otPlatRadioGetNow(otInstance *aInstance) extern "C" OT_TOOL_WEAK otRadioTime64 otPlatRadioGetNow(otInstance *aInstance)
{ {
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
@@ -366,10 +366,10 @@ extern "C" OT_TOOL_WEAK otError otPlatRadioGetRegion(otInstance *aInstance, uint
return kErrorNotImplemented; return kErrorNotImplemented;
} }
extern "C" OT_TOOL_WEAK otError otPlatRadioReceiveAt(otInstance *aInstance, extern "C" OT_TOOL_WEAK otError otPlatRadioReceiveAt(otInstance *aInstance,
uint8_t aChannel, uint8_t aChannel,
uint32_t aStart, otRadioTime32 aStart,
uint32_t aDuration) uint32_t aDuration)
{ {
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aChannel); OT_UNUSED_VARIABLE(aChannel);
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2026, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes implementation of OpenThread radio types.
*/
#include "radio_types.hpp"
#include "common/time.hpp"
namespace ot {
bool IsRadioTimeStrictlyBefore(RadioTime32 aFirstTime, RadioTime32 aSecondTime)
{
Time firstTime(aFirstTime);
Time secondTime(aSecondTime);
return (firstTime < secondTime);
}
} // namespace ot
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2026, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for OpenThread radio types.
*/
#ifndef OT_CORE_RADIO_RADIO_TYPES_HPP_
#define OT_CORE_RADIO_RADIO_TYPES_HPP_
#include "openthread-core-config.h"
#include <openthread/platform/radio.h>
namespace ot {
/**
* Represents a 64-bit radio time in microseconds referenced to a continuous monotonic local radio clock.
*/
typedef otRadioTime64 RadioTime64;
/**
* Represents a 32-bit radio time in microseconds (holds the lower 32 bits of a `RadioTime64`).
*/
typedef otRadioTime32 RadioTime32;
/**
* Converts a 64-bit radio time to a 32-bit radio time.
*
* @param[in] aRadioTime64 The 64-bit radio time to convert.
*
* @returns The converted 32-bit radio time (lower 32 bits of @p aRadioTime64).
*/
inline RadioTime32 ConvertRadioTime64To32(RadioTime64 aRadioTime64) { return static_cast<RadioTime32>(aRadioTime64); }
/**
* Indicates whether a given 32-bit radio time is strictly before another 32-bit radio time.
*
* This function correctly accounts for 32-bit microsecond counter roll-over.
*
* @param[in] aFirstTime The first 32-bit radio time to compare.
* @param[in] aSecondTime The second 32-bit radio time to compare.
*
* @retval TRUE @p aFirstTime is strictly before @p aSecondTime.
* @retval FALSE @p aFirstTime is not strictly before @p aSecondTime.
*/
bool IsRadioTimeStrictlyBefore(RadioTime32 aFirstTime, RadioTime32 aSecondTime);
} // namespace ot
#endif // OT_CORE_RADIO_RADIO_TYPES_HPP_
+6 -7
View File
@@ -135,12 +135,12 @@ uint32_t CslTxScheduler::GetNextCslTransmissionDelay(const CslNeighbor &aCslNeig
uint32_t &aDelayFromLastRx, uint32_t &aDelayFromLastRx,
uint32_t aAheadUs) const uint32_t aAheadUs) const
{ {
uint64_t radioNow = Get<Radio>().GetNow(); // See CslTxScheduler::NeighborInfo::mCslPhase
uint32_t periodInUs = aCslNeighbor.GetCslPeriod() * kUsPerTenSymbols;
/* see CslTxScheduler::NeighborInfo::mCslPhase */ RadioTime64 radioNow = Get<Radio>().GetNow();
uint64_t firstTxWindow = aCslNeighbor.GetLastRxTimestamp() + aCslNeighbor.GetCslPhase() * kUsPerTenSymbols; uint32_t periodInUs = aCslNeighbor.GetCslPeriod() * kUsPerTenSymbols;
uint64_t nextTxWindow = radioNow - (radioNow % periodInUs) + (firstTxWindow % periodInUs); RadioTime64 firstTxWindow = aCslNeighbor.GetLastRxTimestamp() + aCslNeighbor.GetCslPhase() * kUsPerTenSymbols;
RadioTime64 nextTxWindow = radioNow - (radioNow % periodInUs) + (firstTxWindow % periodInUs);
while (nextTxWindow < radioNow + aAheadUs) while (nextTxWindow < radioNow + aAheadUs)
{ {
@@ -222,8 +222,7 @@ Mac::TxFrame *CslTxScheduler::HandleFrameRequest(Mac::TxFrames &aTxFrames)
VerifyOrExit(delay <= mCslFrameRequestAheadUs + kFramePreparationGuardInterval, frame = nullptr); VerifyOrExit(delay <= mCslFrameRequestAheadUs + kFramePreparationGuardInterval, frame = nullptr);
frame->SetTxDelay(txDelay); frame->SetTxDelay(txDelay);
frame->SetTxDelayBaseTime( frame->SetTxDelayBaseTime(ConvertRadioTime64To32(mCslTxNeighbor->GetLastRxTimestamp()));
static_cast<uint32_t>(mCslTxNeighbor->GetLastRxTimestamp())); // Only LSB part of the time is required.
frame->SetCsmaCaEnabled(true); frame->SetCsmaCaEnabled(true);
exit: exit:
+2 -2
View File
@@ -95,8 +95,8 @@ public:
TimeMilli GetCslLastHeard(void) const { return mCslLastHeard; } TimeMilli GetCslLastHeard(void) const { return mCslLastHeard; }
void SetCslLastHeard(TimeMilli aCslLastHeard) { mCslLastHeard = aCslLastHeard; } void SetCslLastHeard(TimeMilli aCslLastHeard) { mCslLastHeard = aCslLastHeard; }
uint64_t GetLastRxTimestamp(void) const { return mLastRxTimestamp; } RadioTime64 GetLastRxTimestamp(void) const { return mLastRxTimestamp; }
void SetLastRxTimestamp(uint64_t aLastRxTimestamp) { mLastRxTimestamp = aLastRxTimestamp; } void SetLastRxTimestamp(RadioTime64 aLastRxTimestamp) { mLastRxTimestamp = aLastRxTimestamp; }
private: private:
uint8_t mCslTxAttempts : 7; ///< Number of CSL triggered tx attempts. uint8_t mCslTxAttempts : 7; ///< Number of CSL triggered tx attempts.
+9 -9
View File
@@ -1627,15 +1627,15 @@ otError RadioSpinel::Transmit(otRadioFrame &aFrame)
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (mTransmitFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0) if (mTransmitFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0)
{ {
uint64_t netRadioTime = otPlatRadioGetNow(mInstance); otRadioTime64 netRadioTime = otPlatRadioGetNow(mInstance);
uint64_t netSyncTime; otRadioTime64 netSyncTime;
uint8_t *timeIe = mTransmitFrame->mPsdu + mTransmitFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset; uint8_t *timeIe = mTransmitFrame->mPsdu + mTransmitFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset;
if (netRadioTime == UINT64_MAX) if (netRadioTime == UINT64_MAX)
{ {
// If we can't get the radio time, get the platform time // If we can't get the radio time, get the platform time
netSyncTime = static_cast<uint64_t>(static_cast<int64_t>(otPlatTimeGet()) + netSyncTime = static_cast<otRadioTime64>(static_cast<int64_t>(otPlatTimeGet()) +
mTransmitFrame->mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset); mTransmitFrame->mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset);
} }
else else
{ {
@@ -1644,16 +1644,16 @@ otError RadioSpinel::Transmit(otRadioFrame &aFrame)
// If supported, add a delay and transmit the network time at a precise moment // If supported, add a delay and transmit the network time at a precise moment
#if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
transmitDelay = kTxWaitUs / 10; transmitDelay = kTxWaitUs / 10;
mTransmitFrame->mInfo.mTxInfo.mTxDelayBaseTime = static_cast<uint32_t>(netRadioTime); mTransmitFrame->mInfo.mTxInfo.mTxDelayBaseTime = static_cast<otRadioTime32>(netRadioTime);
mTransmitFrame->mInfo.mTxInfo.mTxDelay = transmitDelay; mTransmitFrame->mInfo.mTxInfo.mTxDelay = transmitDelay;
#endif #endif
netSyncTime = static_cast<uint64_t>(static_cast<int64_t>(netRadioTime) + transmitDelay + netSyncTime = static_cast<otRadioTime64>(static_cast<int64_t>(netRadioTime) + transmitDelay +
mTransmitFrame->mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset); mTransmitFrame->mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset);
} }
*(timeIe++) = mTransmitFrame->mInfo.mTxInfo.mIeInfo->mTimeSyncSeq; *(timeIe++) = mTransmitFrame->mInfo.mTxInfo.mIeInfo->mTimeSyncSeq;
for (uint8_t i = 0; i < sizeof(uint64_t); i++) for (uint8_t i = 0; i < sizeof(otRadioTime64); i++)
{ {
*(timeIe++) = static_cast<uint8_t>(netSyncTime & 0xff); *(timeIe++) = static_cast<uint8_t>(netSyncTime & 0xff);
netSyncTime = netSyncTime >> 8; netSyncTime = netSyncTime >> 8;
+2 -2
View File
@@ -1709,8 +1709,8 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_RX_AT>(void)
SuccessOrExit(error = mDecoder.ReadUint8(channel)); SuccessOrExit(error = mDecoder.ReadUint8(channel));
{ {
uint64_t now = otPlatRadioGetNow(mInstance); otRadioTime64 now = otPlatRadioGetNow(mInstance);
uint32_t start; uint32_t start;
VerifyOrExit(when > now && (when - now) < UINT32_MAX, error = OT_ERROR_INVALID_ARGS); VerifyOrExit(when > now && (when - now) < UINT32_MAX, error = OT_ERROR_INVALID_ARGS);
+2 -2
View File
@@ -978,7 +978,7 @@ void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacF
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
} }
uint64_t otPlatRadioGetNow(otInstance *aInstance) otRadioTime64 otPlatRadioGetNow(otInstance *aInstance)
{ {
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
return GetRadioSpinel().GetNow(); return GetRadioSpinel().GetNow();
@@ -1097,7 +1097,7 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance,
} }
#endif #endif
otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration) otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, otRadioTime32 aStart, uint32_t aDuration)
{ {
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aChannel); OT_UNUSED_VARIABLE(aChannel);
+1 -1
View File
@@ -385,7 +385,7 @@ otError otPlatRadioSleep(otInstance *) { return OT_ERROR_NONE; }
otError otPlatRadioReceive(otInstance *, uint8_t aChannel) { return FakePlatform::CurrentPlatform().Receive(aChannel); } otError otPlatRadioReceive(otInstance *, uint8_t aChannel) { return FakePlatform::CurrentPlatform().Receive(aChannel); }
otError otPlatRadioReceiveAt(otInstance *, uint8_t aChannel, uint32_t aStart, uint32_t aDuration) otError otPlatRadioReceiveAt(otInstance *, uint8_t aChannel, otRadioTime32 aStart, uint32_t aDuration)
{ {
return FakePlatform::CurrentPlatform().ReceiveAt(aChannel, aStart, aDuration); return FakePlatform::CurrentPlatform().ReceiveAt(aChannel, aStart, aDuration);
} }
+2 -2
View File
@@ -156,7 +156,7 @@ exit:
return error; return error;
} }
uint64_t otPlatRadioGetNow(otInstance *aInstance) otRadioTime64 otPlatRadioGetNow(otInstance *aInstance)
{ {
OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aInstance);
@@ -332,7 +332,7 @@ otError otPlatRadioResetCsl(otInstance *aInstance)
return kErrorNone; return kErrorNone;
} }
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime) void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, otRadioTime32 aCslSampleTime)
{ {
AsNode(aInstance).mRadio.mRadioContext.mCslSampleTime = aCslSampleTime; AsNode(aInstance).mRadio.mRadioContext.mCslSampleTime = aCslSampleTime;
} }
+1 -1
View File
@@ -457,7 +457,7 @@ OT_TOOL_WEAK otError otPlatRadioEnableCsl(otInstance *, uint32_t, otShortAddress
OT_TOOL_WEAK otError otPlatRadioResetCsl(otInstance *) { return OT_ERROR_NONE; } OT_TOOL_WEAK otError otPlatRadioResetCsl(otInstance *) { return OT_ERROR_NONE; }
OT_TOOL_WEAK void otPlatRadioUpdateCslSampleTime(otInstance *, uint32_t) {} OT_TOOL_WEAK void otPlatRadioUpdateCslSampleTime(otInstance *, otRadioTime32) {}
OT_TOOL_WEAK uint8_t otPlatRadioGetCslAccuracy(otInstance *) OT_TOOL_WEAK uint8_t otPlatRadioGetCslAccuracy(otInstance *)
{ {