diff --git a/etc/cmake/options.cmake b/etc/cmake/options.cmake index 227e0faa1..6d3bd5c75 100644 --- a/etc/cmake/options.cmake +++ b/etc/cmake/options.cmake @@ -188,6 +188,7 @@ ot_option(OT_COMMISSIONER OPENTHREAD_CONFIG_COMMISSIONER_ENABLE "commissioner") ot_option(OT_CSL_AUTO_SYNC OPENTHREAD_CONFIG_MAC_CSL_AUTO_SYNC_ENABLE "data polling based on csl") ot_option(OT_CSL_DEBUG OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE "csl debug") ot_option(OT_CSL_RECEIVER OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE "csl receiver") +ot_option(OT_CSL_RECEIVER_LOCAL_TIME_SYNC OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC "use local time for csl elapsed sync time") ot_option(OT_DATASET_UPDATER OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE "dataset updater") ot_option(OT_DEVICE_PROP_LEADER_WEIGHT OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE "device prop for leader weight") ot_option(OT_DHCP6_CLIENT OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE "DHCP6 client") diff --git a/src/core/config/mac.h b/src/core/config/mac.h index 2694e0dc8..5cb1982cd 100644 --- a/src/core/config/mac.h +++ b/src/core/config/mac.h @@ -425,6 +425,28 @@ #define OPENTHREAD_CONFIG_MAC_CSL_AUTO_SYNC_ENABLE OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #endif +/** + * @def OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC + * + * This setting configures the usage of local time rather than radio time for calculating the + * elapsed time since last CSL synchronization event in order to schedule the duration of the + * CSL receive window. + * + * This is done at expense of too short or too long receive windows depending on the drift + * between the two clocks within the CSL timeout period. In order to compensate for a too + * short receive window, CSL uncertainty can be increased. + * + * This setting can be useful for platforms in which is important to reduce the number of + * radio API calls, for instance when they are costly. One typical situation is a multicore + * chip architecture in which different instances of current time are being kept in host and + * radio cores. In this case, accessing the radio core current time API requires serialization + * and it is more costly than just accessing local host time. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC +#define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC 0 +#endif + /** * @def OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD * diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 86e58c276..fb1695687 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -352,7 +352,11 @@ void SubMac::HandleReceiveDone(RxFrame *aFrame, Error aError) // Assuming the risk of the parent missing the Enh-ACK in favor of smaller CSL receive window if ((mCslPeriod > 0) && aFrame->mInfo.mRxInfo.mAckedWithSecEnhAck) { +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC + mCslLastSync = TimerMicro::GetNow(); +#else mCslLastSync = TimeMicro(static_cast(aFrame->mInfo.mRxInfo.mTimestamp)); +#endif } } #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE @@ -613,9 +617,13 @@ void SubMac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aErro #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE // Actual synchronization timestamp should be from the sent frame instead of the current time. // Assuming the error here since it is bounded and has very small effect on the final window duration. - if (mCslPeriod > 0) + 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 } #endif break; @@ -1232,9 +1240,13 @@ void SubMac::HandleCslTimer(void) void SubMac::GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter) { uint32_t semiPeriod = mCslPeriod * kUsPerTenSymbols / 2; - uint32_t curTime = static_cast(otPlatRadioGetNow(&GetInstance())); - uint32_t elapsed; - uint32_t semiWindow; + uint32_t curTime, elapsed, semiWindow; + +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_LOCAL_TIME_SYNC + curTime = TimerMicro::GetNow(); +#else + curTime = static_cast(otPlatRadioGetNow(&GetInstance())); +#endif elapsed = curTime - mCslLastSync.GetValue();