mirror of
https://github.com/espressif/openthread.git
synced 2026-08-19 00:49:53 +00:00
[csl] take into account radio header for aiming at the CSL phase (#8743)
This commit fixes CSL operations timing taking into account that the CSL phase should refer to the beginning of the SHR. On the CSL transmitter, corrects the transmission delay timing taking into account that the timestamp of the received frame from the CSL receiver refers to the start of the PHR. On the CSL receiver, no changes are needed assuming the platform injects the proper CSL phase value.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (305)
|
||||
#define OPENTHREAD_API_VERSION (306)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -466,6 +466,18 @@
|
||||
#define OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_CSL_TRANSMIT_TIME_AHEAD
|
||||
*
|
||||
* Transmission scheduling and ramp up time needed for the CSL transmitter to be ready, in units of microseconds.
|
||||
* This time must include at least the radio's turnaround time between end of CCA and start of preamble transmission.
|
||||
* To avoid early CSL transmission it also must not be configured higher than the actual scheduling and ramp up time.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_CSL_TRANSMIT_TIME_AHEAD
|
||||
#define OPENTHREAD_CONFIG_CSL_TRANSMIT_TIME_AHEAD 40
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD
|
||||
*
|
||||
|
||||
@@ -419,9 +419,10 @@ void SubMac::StartCsmaBackoff(void)
|
||||
{
|
||||
if (Time(static_cast<uint32_t>(otPlatRadioGetNow(&GetInstance()))) <
|
||||
Time(mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime) + mTransmitFrame.mInfo.mTxInfo.mTxDelay -
|
||||
kCcaSampleInterval)
|
||||
kCcaSampleInterval - kCslTransmitTimeAhead)
|
||||
{
|
||||
mTimer.StartAt(Time(mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime) - kCcaSampleInterval,
|
||||
mTimer.StartAt(Time(mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime) - kCcaSampleInterval -
|
||||
kCslTransmitTimeAhead,
|
||||
mTransmitFrame.mInfo.mTxInfo.mTxDelay);
|
||||
}
|
||||
else // Transmit without delay
|
||||
@@ -1187,10 +1188,10 @@ void SubMac::GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter)
|
||||
semiWindow =
|
||||
static_cast<uint32_t>(static_cast<uint64_t>(elapsed) *
|
||||
(Get<Radio>().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) / 1000000);
|
||||
semiWindow += mCslParentAccuracy.GetUncertaintyInMicrosec();
|
||||
semiWindow += mCslParentAccuracy.GetUncertaintyInMicrosec() + Get<Radio>().GetCslUncertainty() * 10;
|
||||
|
||||
aAhead = (semiWindow + kCslReceiveTimeAhead > semiPeriod) ? semiPeriod : semiWindow + kCslReceiveTimeAhead;
|
||||
aAfter = (semiWindow + kMinCslWindow > semiPeriod) ? semiPeriod : semiWindow + kMinCslWindow;
|
||||
aAhead = Min(semiPeriod, semiWindow + kCslReceiveTimeAhead);
|
||||
aAfter = Min(semiPeriod, semiWindow + kMinCslWindow);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
|
||||
@@ -571,6 +571,13 @@ private:
|
||||
static constexpr uint32_t kCslReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
|
||||
// CSL transmitter would schedule delayed transmission `kCslTransmitTimeAhead` earlier
|
||||
// than expected delayed transmit time. The value is in usec.
|
||||
// Only for radios not supporting OT_RADIO_CAPS_TRANSMIT_TIMING.
|
||||
static constexpr uint32_t kCslTransmitTimeAhead = OPENTHREAD_CONFIG_CSL_TRANSMIT_TIME_AHEAD;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method initializes the states of the sub-MAC layer.
|
||||
*
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
namespace ot {
|
||||
|
||||
static constexpr uint32_t kUsPerTenSymbols = OT_US_PER_TEN_SYMBOLS; ///< Time for 10 symbols in units of microseconds
|
||||
static constexpr uint32_t kRadioHeaderShrDuration = 160; ///< Duration of SHR in us
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
/**
|
||||
@@ -483,7 +484,7 @@ public:
|
||||
uint8_t GetCslAccuracy(void);
|
||||
|
||||
/**
|
||||
* Get the fixed uncertainty of the Device for scheduling CSL Transmissions in units of 10 microseconds.
|
||||
* Get the fixed uncertainty of the Device for scheduling CSL operations in units of 10 microseconds.
|
||||
*
|
||||
* @returns The CSL Uncertainty in units of 10 us.
|
||||
*
|
||||
|
||||
@@ -156,10 +156,11 @@ uint32_t CslTxScheduler::GetNextCslTransmissionDelay(const Child &aChild,
|
||||
uint32_t &aDelayFromLastRx,
|
||||
uint32_t aAheadUs) const
|
||||
{
|
||||
uint64_t radioNow = otPlatRadioGetNow(&GetInstance());
|
||||
uint32_t periodInUs = aChild.GetCslPeriod() * kUsPerTenSymbols;
|
||||
uint64_t firstTxWindow = aChild.GetLastRxTimestamp() + aChild.GetCslPhase() * kUsPerTenSymbols;
|
||||
uint64_t nextTxWindow = radioNow - (radioNow % periodInUs) + (firstTxWindow % periodInUs);
|
||||
uint64_t radioNow = otPlatRadioGetNow(&GetInstance());
|
||||
uint32_t periodInUs = aChild.GetCslPeriod() * kUsPerTenSymbols;
|
||||
uint64_t firstTxWindow =
|
||||
aChild.GetLastRxTimestamp() - kRadioHeaderShrDuration + aChild.GetCslPhase() * kUsPerTenSymbols;
|
||||
uint64_t nextTxWindow = radioNow - (radioNow % periodInUs) + (firstTxWindow % periodInUs);
|
||||
|
||||
while (nextTxWindow < radioNow + aAheadUs)
|
||||
{
|
||||
|
||||
@@ -1315,9 +1315,9 @@ public:
|
||||
void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; }
|
||||
|
||||
/**
|
||||
* This method returns the Clock Accuracy value.
|
||||
* This method returns the Clock Uncertainty value.
|
||||
*
|
||||
* @returns The Clock Accuracy value.
|
||||
* @returns The Clock Uncertainty value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetCslUncertainty(void) const { return mCslUncertainty; }
|
||||
|
||||
Reference in New Issue
Block a user