[efr32] dynamic multi-protocol support for MG12 and MG21 (#4321)
diff --git a/examples/Makefile-efr32mg12 b/examples/Makefile-efr32mg12 index 4298d0f..673c96a 100644 --- a/examples/Makefile-efr32mg12 +++ b/examples/Makefile-efr32mg12
@@ -119,6 +119,21 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk +# +# Platform-Specific switches +# + +DMP ?= 0 +RADIODEBUG ?= 0 + +ifeq ($(DMP),1) +COMMONCFLAGS += -DRADIO_CONFIG_DMP_SUPPORT=1 +endif + +ifeq ($(RADIODEBUG),1) +COMMONCFLAGS += -DRADIO_CONFIG_DEBUG_COUNTERS_SUPPORT=1 +endif + CPPFLAGS += \ $(COMMONCFLAGS) \ $(target_CPPFLAGS) \
diff --git a/examples/Makefile-efr32mg21 b/examples/Makefile-efr32mg21 index f50ef7f..af2c122 100644 --- a/examples/Makefile-efr32mg21 +++ b/examples/Makefile-efr32mg21
@@ -105,6 +105,21 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk +# +# Platform-Specific switches +# + +DMP ?= 0 +RADIODEBUG ?= 0 + +ifeq ($(DMP),1) +COMMONCFLAGS += -DRADIO_CONFIG_DMP_SUPPORT=1 +endif + +ifeq ($(RADIODEBUG),1) +COMMONCFLAGS += -DRADIO_CONFIG_DEBUG_COUNTERS_SUPPORT=1 +endif + CPPFLAGS += \ $(COMMONCFLAGS) \ $(target_CPPFLAGS) \
diff --git a/examples/platforms/efr32mg12/Makefile.platform.am b/examples/platforms/efr32mg12/Makefile.platform.am index 15ee454..44fe782 100644 --- a/examples/platforms/efr32mg12/Makefile.platform.am +++ b/examples/platforms/efr32mg12/Makefile.platform.am
@@ -30,12 +30,19 @@ # efr32mg12 platform-specific Makefile # -LDADD_COMMON += \ +LIBRAIL = $(shell \ +if [ "$(DMP)" = "1" ]; then \ + echo "librail_multiprotocol_efr32xg12_gcc_release.a"; \ +else \ + echo "librail_efr32xg12_gcc_release.a"; \ +fi ) + +LDADD_COMMON += \ $(top_builddir)/examples/platforms/efr32mg12/libopenthread-efr32mg12.a \ $(top_builddir)/third_party/silabs/libsilabs-efr32mg12-sdk.a \ - $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \ + $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \ $(NULL) -LDFLAGS_COMMON += \ +LDFLAGS_COMMON += \ -T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \ $(NULL)
diff --git a/examples/platforms/efr32mg12/brd4161a/board_config.h b/examples/platforms/efr32mg12/brd4161a/board_config.h index f24cfef..1aee7a1 100644 --- a/examples/platforms/efr32mg12/brd4161a/board_config.h +++ b/examples/platforms/efr32mg12/brd4161a/board_config.h
@@ -35,7 +35,14 @@ #ifndef __BOARD_CONFIG_H__ #define __BOARD_CONFIG_H__ -#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 2.4GHz band. +#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band. + +#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c +#endif + +#ifndef RADIO_CONFIG_DMP_SUPPORT +#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c +#endif #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/brd4166a/board_config.h b/examples/platforms/efr32mg12/brd4166a/board_config.h index 41f3282..1aee7a1 100644 --- a/examples/platforms/efr32mg12/brd4166a/board_config.h +++ b/examples/platforms/efr32mg12/brd4166a/board_config.h
@@ -35,8 +35,14 @@ #ifndef __BOARD_CONFIG_H__ #define __BOARD_CONFIG_H__ -#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 2.4GHz band. -#define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c +#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band. +#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT +#define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c +#endif + +#ifndef RADIO_CONFIG_DMP_SUPPORT +#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c +#endif #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/brd4170a/board_config.h b/examples/platforms/efr32mg12/brd4170a/board_config.h index 31f0ba0..c40f4a4 100644 --- a/examples/platforms/efr32mg12/brd4170a/board_config.h +++ b/examples/platforms/efr32mg12/brd4170a/board_config.h
@@ -35,8 +35,15 @@ #ifndef __BOARD_CONFIG_H__ #define __BOARD_CONFIG_H__ -#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 2.4GHz band. -#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 915MHz band. +#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band. +#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 915MHz band. + +#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c +#endif + +#ifndef RADIO_CONFIG_DMP_SUPPORT +#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c +#endif #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/brd4304a/board_config.h b/examples/platforms/efr32mg12/brd4304a/board_config.h index f24cfef..1aee7a1 100644 --- a/examples/platforms/efr32mg12/brd4304a/board_config.h +++ b/examples/platforms/efr32mg12/brd4304a/board_config.h
@@ -35,7 +35,14 @@ #ifndef __BOARD_CONFIG_H__ #define __BOARD_CONFIG_H__ -#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 2.4GHz band. +#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band. + +#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c +#endif + +#ifndef RADIO_CONFIG_DMP_SUPPORT +#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c +#endif #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg12/platform-band.h b/examples/platforms/efr32mg12/platform-band.h index 6145f70..cba0a64 100644 --- a/examples/platforms/efr32mg12/platform-band.h +++ b/examples/platforms/efr32mg12/platform-band.h
@@ -43,6 +43,16 @@ #define RAIL_TX_FIFO_SIZE (OT_RADIO_FRAME_MAX_SIZE + 1) +#define RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY 255 +#define RADIO_SCHEDULER_CHANNEL_SCAN_PRIORITY 255 +#define RADIO_SCHEDULER_CHANNEL_SLIP_TIME 500000UL +#define RADIO_SCHEDULER_TX_PRIORITY 100 +#define RADIO_SCHEDULER_TX_SLIP_TIME 500000UL + +#define RADIO_TIMING_CSMA_OVERHEAD_US 500 +#define RADIO_TIMING_DEFAULT_BYTETIME_US 32 // only used if RAIL_GetBitRate returns 0 +#define RADIO_TIMING_DEFAULT_SYMBOLTIME_US 16 // only used if RAIL_GetSymbolRate returns 0 + typedef struct efr32RadioCounters { uint64_t mRailPlatTxTriggered; @@ -61,11 +71,16 @@ uint64_t mRailEventNoAck; uint64_t mRailEventTxAbort; uint64_t mRailEventSchedulerStatusError; + uint64_t mRailEventsSchedulerStatusTransmitBusy; + uint32_t mRailEventsSchedulerStatusLastStatus; } efr32RadioCounters; typedef struct efr32CommonConfig { RAIL_Config_t mRailConfig; +#if RADIO_CONFIG_DMP_SUPPORT + RAILSched_Config_t railSchedState; +#endif uint8_t mRailTxFifo[RAIL_TX_FIFO_SIZE]; // must be 2 power between 64 and 4096, and bigger than OT_RADIO_FRAME_MAX_SIZE } efr32CommonConfig;
diff --git a/examples/platforms/efr32mg12/radio.c b/examples/platforms/efr32mg12/radio.c index 00dfc6a..48aa066 100644 --- a/examples/platforms/efr32mg12/radio.c +++ b/examples/platforms/efr32mg12/radio.c
@@ -263,7 +263,11 @@ { sCommonConfig.mRailConfig.eventsCallback = aEventCallback; sCommonConfig.mRailConfig.protocol = NULL; // only used by Bluetooth stack - sCommonConfig.mRailConfig.scheduler = NULL; // only needed for DMP +#if RADIO_CONFIG_DMP_SUPPORT + sCommonConfig.mRailConfig.scheduler = &(sCommonConfig.railSchedState); +#else + sCommonConfig.mRailConfig.scheduler = NULL; // only needed for DMP +#endif uint8_t index = 0; @@ -357,7 +361,11 @@ sCurrentBandConfig = config; } - status = RAIL_StartAverageRssi(gRailHandle, aChannel, aAveragingTimeUs, NULL); + RAIL_SchedulerInfo_t scanSchedulerInfo = {.priority = RADIO_SCHEDULER_CHANNEL_SCAN_PRIORITY, + .slipTime = RADIO_SCHEDULER_CHANNEL_SLIP_TIME, + .transactionTime = aAveragingTimeUs}; + + status = RAIL_StartAverageRssi(gRailHandle, aChannel, aAveragingTimeUs, &scanSchedulerInfo); otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED); exit: @@ -494,7 +502,12 @@ sCurrentBandConfig = config; } - status = RAIL_StartRx(gRailHandle, aChannel, NULL); + RAIL_SchedulerInfo_t bgRxSchedulerInfo = { + .priority = RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY, + // sliptime/transaction time is not used for bg rx + }; + + status = RAIL_StartRx(gRailHandle, aChannel, &bgRxSchedulerInfo); otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED); otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL); @@ -541,18 +554,53 @@ RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true); RAIL_WriteTxFifo(gRailHandle, aFrame->mPsdu, frameLength - 2, false); + RAIL_SchedulerInfo_t txSchedulerInfo = { + .priority = RADIO_SCHEDULER_TX_PRIORITY, + .slipTime = RADIO_SCHEDULER_CHANNEL_SLIP_TIME, + .transactionTime = 0, // will be calculated later if DMP is used + }; + if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST) { txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK; + +#if RADIO_CONFIG_DMP_SUPPORT + // time we wait for ACK + if (RAIL_GetSymbolRate(gRailHandle) > 0) + { + txSchedulerInfo.transactionTime += 12 * 1e6 / RAIL_GetSymbolRate(gRailHandle); + } + else + { + txSchedulerInfo.transactionTime += 12 * RADIO_TIMING_DEFAULT_SYMBOLTIME_US; + } +#endif } +#if RADIO_CONFIG_DMP_SUPPORT + // time needed for the frame itself + // 4B preamble, 1B SFD, 1B PHR is not counted in frameLength + if (RAIL_GetBitRate(gRailHandle) > 0) + { + txSchedulerInfo.transactionTime = (frameLength + 4 + 1 + 1) * 8 * 1e6 / RAIL_GetBitRate(gRailHandle); + } + else + { // assume 250kbps + txSchedulerInfo.transactionTime = (frameLength + 4 + 1 + 1) * RADIO_TIMING_DEFAULT_BYTETIME_US; + } +#endif + if (aFrame->mInfo.mTxInfo.mCsmaCaEnabled) { - status = RAIL_StartCcaCsmaTx(gRailHandle, aFrame->mChannel, txOptions, &csmaConfig, NULL); +#if RADIO_CONFIG_DMP_SUPPORT + // time needed for CSMA/CA + txSchedulerInfo.transactionTime += RADIO_TIMING_CSMA_OVERHEAD_US; +#endif + status = RAIL_StartCcaCsmaTx(gRailHandle, aFrame->mChannel, txOptions, &csmaConfig, &txSchedulerInfo); } else { - status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, NULL); + status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, &txSchedulerInfo); } if (status == RAIL_STATUS_NO_ERROR) @@ -646,7 +694,9 @@ uint16_t length; packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo); - otEXPECT_ACTION(packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS, + + otEXPECT_ACTION(packetHandle != RAIL_RX_PACKET_HANDLE_INVALID && + packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS, packetHandle = RAIL_RX_PACKET_HANDLE_INVALID); status = RAIL_GetRxPacketDetailsAlt(gRailHandle, packetHandle, &packetDetails); @@ -686,6 +736,7 @@ assert((length == IEEE802154_ACK_LENGTH) && (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK); + RAIL_YieldRadio(gRailHandle); sTransmitBusy = false; if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET]) @@ -795,6 +846,7 @@ { if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_NONE; sTransmitBusy = false; } @@ -804,6 +856,7 @@ } else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY) { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE; sTransmitBusy = false; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT @@ -812,6 +865,7 @@ } else { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_ABORT; sTransmitBusy = false; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT @@ -822,6 +876,7 @@ if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT) { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_NO_ACK; sTransmitBusy = false; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT @@ -852,6 +907,7 @@ if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE) { const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle); + RAIL_YieldRadio(aRailHandle); sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED; @@ -872,8 +928,12 @@ { RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle); - if (status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL || - (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy)) + assert(status != RAIL_SCHEDULER_STATUS_INTERNAL_ERROR); + + if (status == RAIL_SCHEDULER_STATUS_CCA_CSMA_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || + status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL || + (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy) || + (status == RAIL_SCHEDULER_STATUS_EVENT_INTERRUPTED && sTransmitBusy)) { sTransmitError = OT_ERROR_ABORT; sTransmitBusy = false; @@ -881,6 +941,18 @@ sRailDebugCounters.mRailEventSchedulerStatusError++; #endif } + else if (status == RAIL_SCHEDULER_STATUS_AVERAGE_RSSI_FAIL) + { + sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED; + sEnergyScanResultDbm = OT_RADIO_RSSI_INVALID; + } +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + else if (sTransmitBusy) + { + sRailDebugCounters.mRailEventsSchedulerStatusLastStatus = status; + sRailDebugCounters.mRailEventsSchedulerStatusTransmitBusy++; + } +#endif } otSysEventSignalPending();
diff --git a/examples/platforms/efr32mg21/Makefile.am b/examples/platforms/efr32mg21/Makefile.am index da76e07..7283d89 100644 --- a/examples/platforms/efr32mg21/Makefile.am +++ b/examples/platforms/efr32mg21/Makefile.am
@@ -43,15 +43,8 @@ EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6 libopenthread_efr32mg21_a_CPPFLAGS = \ - -DPLATFORM_HEADER=\"@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.6/platform/base/hal/micro/cortexm3/compiler/gcc.h\" \ -DEFR32_SERIES2_CONFIG1_MICRO \ -DNVIC_CONFIG=\"platform/base/hal/micro/cortexm3/efm32/nvic-config.h\" \ - -Wno-sign-compare \ - -DCORTEXM3 \ - -DPHY=EMBER_PHY_RAIL \ - -DMICRO=EMBER_MICRO_CORTEXM3_EFR32 \ - -DCORTEXM3_EFM32_MICRO \ - -DPLAT=EMBER_PLATFORM_CORTEXM3 \ -I$(top_srcdir)/include \ -I$(top_srcdir)/examples/platforms \ -I$(top_srcdir)/examples/platforms/efr32mg21/$(EFR32_BOARD_DIR) \
diff --git a/examples/platforms/efr32mg21/Makefile.platform.am b/examples/platforms/efr32mg21/Makefile.platform.am index a626d88..6187f98 100644 --- a/examples/platforms/efr32mg21/Makefile.platform.am +++ b/examples/platforms/efr32mg21/Makefile.platform.am
@@ -30,12 +30,19 @@ # efr32mg21 platform-specific Makefile # -LDADD_COMMON += \ +LIBRAIL = $(shell \ +if [ "$(DMP)" = "1" ]; then \ + echo "librail_multiprotocol_efr32xg21_gcc_release.a"; \ +else \ + echo "librail_efr32xg21_gcc_release.a"; \ +fi ) + +LDADD_COMMON += \ $(top_builddir)/examples/platforms/efr32mg21/libopenthread-efr32mg21.a \ $(top_builddir)/third_party/silabs/libsilabs-efr32mg21-sdk.a \ - $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg21_gcc_release.a \ + $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \ $(NULL) -LDFLAGS_COMMON += \ +LDFLAGS_COMMON += \ -T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/efr32mg21.ld \ $(NULL)
diff --git a/examples/platforms/efr32mg21/brd4180a/board_config.h b/examples/platforms/efr32mg21/brd4180a/board_config.h index 8865142..ee009f6 100644 --- a/examples/platforms/efr32mg21/brd4180a/board_config.h +++ b/examples/platforms/efr32mg21/brd4180a/board_config.h
@@ -35,7 +35,14 @@ #ifndef __BOARD_CONFIG_H__ #define __BOARD_CONFIG_H__ -#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 2.4GHz band. +#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Dev board suppports OQPSK modulation in 2.4GHz band. + +#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT #define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c +#endif + +#ifndef RADIO_CONFIG_DMP_SUPPORT +#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c +#endif #endif // __BOARD_CONFIG_H__
diff --git a/examples/platforms/efr32mg21/platform-band.h b/examples/platforms/efr32mg21/platform-band.h index 6145f70..fb82093 100644 --- a/examples/platforms/efr32mg21/platform-band.h +++ b/examples/platforms/efr32mg21/platform-band.h
@@ -43,6 +43,16 @@ #define RAIL_TX_FIFO_SIZE (OT_RADIO_FRAME_MAX_SIZE + 1) +#define RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY 255 +#define RADIO_SCHEDULER_CHANNEL_SCAN_PRIORITY 255 +#define RADIO_SCHEDULER_CHANNEL_SLIP_TIME 500000UL +#define RADIO_SCHEDULER_TX_PRIORITY 100 +#define RADIO_SCHEDULER_TX_SLIP_TIME 500000UL + +#define RADIO_TIMING_CSMA_OVERHEAD_US 500 +#define RADIO_TIMING_DEFAULT_BYTETIME_US 32 // only used if RAIL_GetBitRate returns 0 +#define RADIO_TIMING_DEFAULT_SYMBOLTIME_US 16 // only used if RAIL_GetSymbolRate returns 0 + typedef struct efr32RadioCounters { uint64_t mRailPlatTxTriggered; @@ -61,18 +71,17 @@ uint64_t mRailEventNoAck; uint64_t mRailEventTxAbort; uint64_t mRailEventSchedulerStatusError; + uint64_t mRailEventsSchedulerStatusTransmitBusy; + uint32_t mRailEventsSchedulerStatusLastStatus; } efr32RadioCounters; -typedef struct efr32CommonConfig -{ - RAIL_Config_t mRailConfig; - uint8_t - mRailTxFifo[RAIL_TX_FIFO_SIZE]; // must be 2 power between 64 and 4096, and bigger than OT_RADIO_FRAME_MAX_SIZE -} efr32CommonConfig; - typedef struct efr32BandConfig { + RAIL_Handle_t mRailHandle; + RAIL_Config_t mRailConfig; + RAILSched_Config_t mRailSchedState; const RAIL_ChannelConfig_t *mChannelConfig; + uint8_t mRailTxFifo[OT_RADIO_FRAME_MAX_SIZE + 1]; uint8_t mChannelMin; uint8_t mChannelMax; } efr32BandConfig;
diff --git a/examples/platforms/efr32mg21/radio.c b/examples/platforms/efr32mg21/radio.c index 3074fb2..1b55bbb 100644 --- a/examples/platforms/efr32mg21/radio.c +++ b/examples/platforms/efr32mg21/radio.c
@@ -46,10 +46,8 @@ #include "utils/soft_source_match_table.h" #include "board_config.h" -#include "em_cmu.h" #include "em_core.h" #include "em_system.h" -#include "hal-config.h" #include "openthread-core-efr32-config.h" #include "pa_conversions_efr32.h" #include "platform-band.h" @@ -72,6 +70,7 @@ enum { EFR32_RECEIVE_SENSITIVITY = -100, // dBm + EFR32_RSSI_AVERAGING_TIME = 16, // us EFR32_RSSI_AVERAGING_TIMEOUT = 300, // us }; @@ -115,8 +114,7 @@ static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH]; static volatile otError sTransmitError; -static efr32CommonConfig sCommonConfig; -static efr32BandConfig sBandConfigs[EFR32_NUM_BAND_CONFIGS]; +static efr32BandConfig sBandConfigs[EFR32_NUM_BAND_CONFIGS]; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT static efr32RadioCounters sRailDebugCounters; @@ -132,53 +130,75 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents); static const RAIL_IEEE802154_Config_t sRailIeee802154Config = { - .addresses = NULL, - .ackConfig = + NULL, // addresses + { + // ackConfig + true, // ackConfig.enable + 894, // ackConfig.ackTimeout { - .enable = true, - .ackTimeout = 894, - .rxTransitions = - { - .success = RAIL_RF_STATE_RX, - .error = RAIL_RF_STATE_RX, - }, - .txTransitions = - { - .success = RAIL_RF_STATE_RX, - .error = RAIL_RF_STATE_RX, - }, + // ackConfig.rxTransitions + RAIL_RF_STATE_RX, // ackConfig.rxTransitions.success + RAIL_RF_STATE_RX, // ackConfig.rxTransitions.error }, - .timings = { - .idleToRx = 100, - .txToRx = 192 - 10, - .idleToTx = 100, - .rxToTx = 192, - .rxSearchTimeout = 0, - .txToRxSearchTimeout = 0, + // ackConfig.txTransitions + RAIL_RF_STATE_RX, // ackConfig.txTransitions.success + RAIL_RF_STATE_RX, // ackConfig.txTransitions.error }, - .framesMask = RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, - .promiscuousMode = false, - .isPanCoordinator = false, + }, + { + // timings + 100, // timings.idleToRx + 192 - 10, // timings.txToRx + 100, // timings.idleToTx + 192, // timings.rxToTx + 0, // timings.rxSearchTimeout + 0, // timings.txToRxSearchTimeout + }, + RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, // framesMask + false, // promiscuousMode + false, // isPanCoordinator }; RAIL_DECLARE_TX_POWER_VBAT_CURVES_ALT; static int8_t sTxPowerDbm = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER; -static efr32BandConfig *sCurrentBandConfig = NULL; +static efr32BandConfig *sTxBandConfig = NULL; +static efr32BandConfig *sRxBandConfig = NULL; -static RAIL_Handle_t efr32RailInit(efr32CommonConfig *aCommonConfig) +static RAIL_Handle_t efr32RailConfigInit(efr32BandConfig *aBandConfig) { - RAIL_Status_t status; - RAIL_Handle_t handle; + RAIL_Status_t status; + RAIL_Handle_t handle; + RAIL_DataConfig_t railDataConfig = { + TX_PACKET_DATA, + RX_PACKET_DATA, + PACKET_MODE, + PACKET_MODE, + }; - handle = RAIL_Init(&aCommonConfig->mRailConfig, NULL); + handle = RAIL_Init(&aBandConfig->mRailConfig, NULL); assert(handle != NULL); + status = RAIL_ConfigData(handle, &railDataConfig); + assert(status == RAIL_STATUS_NO_ERROR); + + RAIL_Idle(handle, RAIL_IDLE, true); + status = RAIL_ConfigCal(handle, RAIL_CAL_ALL); assert(status == RAIL_STATUS_NO_ERROR); + if (aBandConfig->mChannelConfig != NULL) + { + RAIL_ConfigChannels(handle, aBandConfig->mChannelConfig, NULL); + } + else + { + status = RAIL_IEEE802154_Config2p4GHzRadio(handle); + assert(status == RAIL_STATUS_NO_ERROR); + } + status = RAIL_IEEE802154_Init(handle, &sRailIeee802154Config); assert(status == RAIL_STATUS_NO_ERROR); @@ -197,39 +217,27 @@ ); assert(status == RAIL_STATUS_NO_ERROR); - uint16_t actualLenth = RAIL_SetTxFifo(handle, aCommonConfig->mRailTxFifo, 0, sizeof(aCommonConfig->mRailTxFifo)); - assert(actualLenth == sizeof(aCommonConfig->mRailTxFifo)); + uint16_t actualLength = RAIL_SetTxFifo(handle, aBandConfig->mRailTxFifo, 0, sizeof(aBandConfig->mRailTxFifo)); + assert(actualLength == sizeof(aBandConfig->mRailTxFifo)); return handle; } -static void efr32RailConfigLoad(efr32BandConfig *aBandConfig) -{ - RAIL_Status_t status; -#if HAL_PA_2P4_LOWPOWER == 1 - RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_LP, HAL_PA_VOLTAGE, 10}; -#else - RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, HAL_PA_VOLTAGE, 10}; -#endif - - (void)aBandConfig; - - status = RAIL_IEEE802154_Config2p4GHzRadio(gRailHandle); - assert(status == RAIL_STATUS_NO_ERROR); - - status = RAIL_ConfigTxPower(gRailHandle, &txPowerConfig); - assert(status == RAIL_STATUS_NO_ERROR); -} - -static void efr32RadioSetTxPower(int8_t aPowerDbm) +static void efr32RadioSetTxPower(RAIL_Handle_t aRailHandle, + const RAIL_ChannelConfig_t *aChannelConfig, + int8_t aPowerDbm) { RAIL_Status_t status; const RAIL_TxPowerCurvesConfigAlt_t txPowerCurvesConfig = RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT; + RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, 3300, 10}; status = RAIL_InitTxPowerCurvesAlt(&txPowerCurvesConfig); assert(status == RAIL_STATUS_NO_ERROR); - status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aPowerDbm) * 10); + status = RAIL_ConfigTxPower(aRailHandle, &txPowerConfig); + assert(status == RAIL_STATUS_NO_ERROR); + + status = RAIL_SetTxPowerDbm(aRailHandle, ((RAIL_TxPower_t)aPowerDbm) * 10); assert(status == RAIL_STATUS_NO_ERROR); } @@ -249,56 +257,39 @@ return config; } -static void efr32ConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAIL_Events_t events)) +static void efr32BandConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAIL_Events_t events)) { - sCommonConfig.mRailConfig.eventsCallback = aEventCallback; - sCommonConfig.mRailConfig.protocol = NULL; // only used by Bluetooth stack - sCommonConfig.mRailConfig.scheduler = NULL; // only needed for DMP - uint8_t index = 0; #if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT - sBandConfigs[index].mChannelConfig = NULL; - sBandConfigs[index].mChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN; - sBandConfigs[index].mChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX; + sBandConfigs[index].mRailConfig.eventsCallback = aEventCallback; + sBandConfigs[index].mRailConfig.protocol = NULL; + sBandConfigs[index].mRailConfig.scheduler = &sBandConfigs[index].mRailSchedState; + sBandConfigs[index].mChannelConfig = NULL; + sBandConfigs[index].mChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN; + sBandConfigs[index].mChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX; + assert((sBandConfigs[index].mRailHandle = efr32RailConfigInit(&sBandConfigs[index])) != NULL); index++; #endif - -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - memset(&sRailDebugCounters, 0x00, sizeof(efr32RadioCounters)); -#endif - - gRailHandle = efr32RailInit(&sCommonConfig); - assert(gRailHandle != NULL); - efr32RailConfigLoad(&(sBandConfigs[0])); } void efr32RadioInit(void) { - RAIL_Status_t status; - - // check if RAIL_TX_FIFO_SIZE is power of two.. - assert((RAIL_TX_FIFO_SIZE & (RAIL_TX_FIFO_SIZE - 1)) == 0); - - // check the limits of the RAIL_TX_FIFO_SIZE. - assert((RAIL_TX_FIFO_SIZE >= 64) || (RAIL_TX_FIFO_SIZE <= 4096)); - - efr32ConfigInit(RAILCb_Generic); - - CMU_ClockEnable(cmuClock_PRS, true); - status = RAIL_ConfigSleep(gRailHandle, RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED); - assert(status == RAIL_STATUS_NO_ERROR); + efr32BandConfigInit(RAILCb_Generic); sReceiveFrame.mLength = 0; sReceiveFrame.mPsdu = sReceivePsdu; sTransmitFrame.mLength = 0; sTransmitFrame.mPsdu = sTransmitPsdu; - sCurrentBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL); - assert(sCurrentBandConfig != NULL); + sRxBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL); + assert(sRxBandConfig != NULL); - efr32RadioSetTxPower(sTxPowerDbm); + sTxBandConfig = sRxBandConfig; + efr32RadioSetTxPower(sTxBandConfig->mRailHandle, sTxBandConfig->mChannelConfig, sTxPowerDbm); + + gRailHandle = sTxBandConfig->mRailHandle; // global handle for alarms. sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE; sTransmitError = OT_ERROR_NONE; @@ -311,36 +302,37 @@ { RAIL_Status_t status; - RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true); - status = RAIL_ConfigEvents(gRailHandle, RAIL_EVENTS_ALL, 0); - assert(status == RAIL_STATUS_NO_ERROR); + for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) + { + RAIL_Idle(sBandConfigs[i].mRailHandle, RAIL_IDLE_FORCE_SHUTDOWN_CLEAR_FLAGS, true); - sCurrentBandConfig = NULL; + status = RAIL_IEEE802154_Deinit(sBandConfigs[i].mRailHandle); + assert(status == RAIL_STATUS_NO_ERROR); + + sBandConfigs[i].mRailHandle = NULL; + } + + sTxBandConfig = NULL; + sRxBandConfig = NULL; } static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAIL_Time_t aAveragingTimeUs) { - RAIL_Status_t status; - otError error = OT_ERROR_NONE; - efr32BandConfig *config = NULL; + RAIL_Status_t status; + otError error = OT_ERROR_NONE; otEXPECT_ACTION(sEnergyScanStatus == ENERGY_SCAN_STATUS_IDLE, error = OT_ERROR_BUSY); sEnergyScanStatus = ENERGY_SCAN_STATUS_IN_PROGRESS; sEnergyScanMode = aMode; - RAIL_Idle(gRailHandle, RAIL_IDLE, true); + RAIL_Idle(sRxBandConfig->mRailHandle, RAIL_IDLE, true); - config = efr32RadioGetBandConfig(aChannel); - otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS); + RAIL_SchedulerInfo_t scanSchedulerInfo = {.priority = RADIO_SCHEDULER_CHANNEL_SCAN_PRIORITY, + .slipTime = RADIO_SCHEDULER_CHANNEL_SLIP_TIME, + .transactionTime = aAveragingTimeUs}; - if (sCurrentBandConfig != config) - { - efr32RailConfigLoad(config); - sCurrentBandConfig = config; - } - - status = RAIL_StartAverageRssi(gRailHandle, aChannel, aAveragingTimeUs, NULL); + status = RAIL_StartAverageRssi(sRxBandConfig->mRailHandle, aChannel, aAveragingTimeUs, &scanSchedulerInfo); otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED); exit: @@ -375,7 +367,7 @@ for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) { - status = RAIL_IEEE802154_SetPanId(gRailHandle, aPanId, 0); + status = RAIL_IEEE802154_SetPanId(sBandConfigs[i].mRailHandle, aPanId, 0); assert(status == RAIL_STATUS_NO_ERROR); } } @@ -391,7 +383,7 @@ for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) { - status = RAIL_IEEE802154_SetLongAddress(gRailHandle, (uint8_t *)aAddress->m8, 0); + status = RAIL_IEEE802154_SetLongAddress(sBandConfigs[i].mRailHandle, (uint8_t *)aAddress->m8, 0); assert(status == RAIL_STATUS_NO_ERROR); } } @@ -406,7 +398,7 @@ for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) { - status = RAIL_IEEE802154_SetShortAddress(gRailHandle, aAddress, 0); + status = RAIL_IEEE802154_SetShortAddress(sBandConfigs[i].mRailHandle, aAddress, 0); assert(status == RAIL_STATUS_NO_ERROR); } } @@ -451,7 +443,10 @@ otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL); - RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true); // abort packages under reception + for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) + { + RAIL_Idle(sBandConfigs[i].mRailHandle, RAIL_IDLE, true); + } sState = OT_RADIO_STATE_SLEEP; exit: @@ -470,14 +465,18 @@ config = efr32RadioGetBandConfig(aChannel); otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS); - if (sCurrentBandConfig != config) + if (sRxBandConfig != config) { - RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true); - efr32RailConfigLoad(config); - sCurrentBandConfig = config; + RAIL_Idle(sRxBandConfig->mRailHandle, RAIL_IDLE, false); + sRxBandConfig = config; } - status = RAIL_StartRx(gRailHandle, aChannel, NULL); + RAIL_SchedulerInfo_t bgRxSchedulerInfo = { + .priority = RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY, + // sliptime/transaction time is not used for bg rx + }; + + status = RAIL_StartRx(sRxBandConfig->mRailHandle, aChannel, &bgRxSchedulerInfo); otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED); otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL); @@ -492,7 +491,7 @@ { otError error = OT_ERROR_NONE; RAIL_CsmaConfig_t csmaConfig = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA; - RAIL_TxOptions_t txOptions = RAIL_TX_OPTIONS_DEFAULT; + RAIL_TxOptions_t txOptions = RAIL_TX_OPTIONS_NONE; efr32BandConfig * config; RAIL_Status_t status; uint8_t frameLength; @@ -513,29 +512,64 @@ sTransmitError = OT_ERROR_NONE; sTransmitBusy = true; - if (sCurrentBandConfig != config) + if (sTxBandConfig != config) { - RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true); - efr32RailConfigLoad(config); - sCurrentBandConfig = config; + efr32RadioSetTxPower(config->mRailHandle, config->mChannelConfig, sTxPowerDbm); + sTxBandConfig = config; } frameLength = (uint8_t)aFrame->mLength; - RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true); - RAIL_WriteTxFifo(gRailHandle, aFrame->mPsdu, frameLength - 2, false); + RAIL_WriteTxFifo(sTxBandConfig->mRailHandle, &frameLength, sizeof frameLength, true); + RAIL_WriteTxFifo(sTxBandConfig->mRailHandle, aFrame->mPsdu, frameLength - 2, false); + + RAIL_SchedulerInfo_t txSchedulerInfo = { + .priority = RADIO_SCHEDULER_TX_PRIORITY, + .slipTime = RADIO_SCHEDULER_CHANNEL_SLIP_TIME, + .transactionTime = 0, // will be calculated later if DMP is used + }; if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST) { txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK; + +#if RADIO_CONFIG_DMP_SUPPORT + // time we wait for ACK + if (RAIL_GetSymbolRate(gRailHandle) > 0) + { + txSchedulerInfo.transactionTime += 12 * 1e6 / RAIL_GetSymbolRate(gRailHandle); + } + else + { + txSchedulerInfo.transactionTime += 12 * RADIO_TIMING_DEFAULT_SYMBOLTIME_US; + } +#endif } +#if RADIO_CONFIG_DMP_SUPPORT + // time needed for the frame itself + // 4B preamble, 1B SFD, 1B PHR is not counted in frameLength + if (RAIL_GetBitRate(gRailHandle) > 0) + { + txSchedulerInfo.transactionTime = (frameLength + 4 + 1 + 1) * 8 * 1e6 / RAIL_GetBitRate(gRailHandle); + } + else + { // assume 250kbps + txSchedulerInfo.transactionTime = (frameLength + 4 + 1 + 1) * RADIO_TIMING_DEFAULT_BYTETIME_US; + } +#endif + if (aFrame->mInfo.mTxInfo.mCsmaCaEnabled) { - status = RAIL_StartCcaCsmaTx(gRailHandle, aFrame->mChannel, txOptions, &csmaConfig, NULL); +#if RADIO_CONFIG_DMP_SUPPORT + // time needed for CSMA/CA + txSchedulerInfo.transactionTime += RADIO_TIMING_CSMA_OVERHEAD_US; +#endif + status = + RAIL_StartCcaCsmaTx(sTxBandConfig->mRailHandle, aFrame->mChannel, txOptions, &csmaConfig, &txSchedulerInfo); } else { - status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, NULL); + status = RAIL_StartTx(sTxBandConfig->mRailHandle, aFrame->mChannel, txOptions, &txSchedulerInfo); } if (status == RAIL_STATUS_NO_ERROR) @@ -567,19 +601,29 @@ int8_t otPlatRadioGetRssi(otInstance *aInstance) { - int8_t rssi = OT_RADIO_RSSI_INVALID; + otError error; + uint32_t start; + int8_t rssi = OT_RADIO_RSSI_INVALID; + OT_UNUSED_VARIABLE(aInstance); - if ((RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX)) + error = efr32StartEnergyScan(ENERGY_SCAN_MODE_SYNC, sReceiveFrame.mChannel, EFR32_RSSI_AVERAGING_TIME); + otEXPECT(error == OT_ERROR_NONE); + + start = RAIL_GetTime(); + + // waiting for the event RAIL_EVENT_RSSI_AVERAGE_DONE + while (sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS && + ((RAIL_GetTime() - start) < EFR32_RSSI_AVERAGING_TIMEOUT)) + ; + + if (sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED) { - int16_t railRssi = RAIL_RSSI_INVALID; - railRssi = RAIL_GetRssi(gRailHandle, true); - if (railRssi != RAIL_RSSI_INVALID) - { - rssi = railRssi / QUARTER_DBM_IN_DBM; - } + rssi = sEnergyScanResultDbm; } + sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE; +exit: return rssi; } @@ -607,7 +651,7 @@ for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) { - status = RAIL_IEEE802154_SetPromiscuousMode(gRailHandle, aEnable); + status = RAIL_IEEE802154_SetPromiscuousMode(sBandConfigs[i].mRailHandle, aEnable); assert(status == RAIL_STATUS_NO_ERROR); } } @@ -620,7 +664,7 @@ sIsSrcMatchEnabled = aEnable; } -static void processNextRxPacket(otInstance *aInstance) +static void processNextRxPacket(otInstance *aInstance, RAIL_Handle_t aRailHandle) { RAIL_RxPacketHandle_t packetHandle = RAIL_RX_PACKET_HANDLE_INVALID; RAIL_RxPacketInfo_t packetInfo; @@ -628,11 +672,15 @@ RAIL_Status_t status; uint16_t length; - packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo); - otEXPECT_ACTION(packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS, + packetHandle = RAIL_GetRxPacketInfo(aRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo); + + otEXPECT_ACTION(packetHandle != RAIL_RX_PACKET_HANDLE_INVALID && + packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS, packetHandle = RAIL_RX_PACKET_HANDLE_INVALID); - status = RAIL_GetRxPacketDetailsAlt(gRailHandle, packetHandle, &packetDetails); + packetDetails.timeReceived.timePosition = RAIL_PACKET_TIME_INVALID; + packetDetails.timeReceived.totalPacketBytes = 0; + status = RAIL_GetRxPacketDetails(aRailHandle, packetHandle, &packetDetails); otEXPECT(status == RAIL_STATUS_NO_ERROR); length = packetInfo.packetBytes + 1; @@ -656,7 +704,7 @@ memcpy(sReceiveFrame.mPsdu + packetInfo.firstPortionBytes, packetInfo.lastPortionData, packetInfo.packetBytes - packetInfo.firstPortionBytes); - status = RAIL_ReleaseRxPacket(gRailHandle, packetHandle); + status = RAIL_ReleaseRxPacket(aRailHandle, packetHandle); if (status == RAIL_STATUS_NO_ERROR) { packetHandle = RAIL_RX_PACKET_HANDLE_INVALID; @@ -669,6 +717,7 @@ assert((length == IEEE802154_ACK_LENGTH) && (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK); + RAIL_YieldRadio(gRailHandle); sTransmitBusy = false; if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET]) @@ -725,7 +774,7 @@ if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID) { - RAIL_ReleaseRxPacket(gRailHandle, packetHandle); + RAIL_ReleaseRxPacket(aRailHandle, packetHandle); } } @@ -778,6 +827,7 @@ { if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_NONE; sTransmitBusy = false; } @@ -787,6 +837,7 @@ } else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY) { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE; sTransmitBusy = false; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT @@ -795,6 +846,7 @@ } else { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_ABORT; sTransmitBusy = false; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT @@ -805,6 +857,7 @@ if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT) { + RAIL_YieldRadio(aRailHandle); sTransmitError = OT_ERROR_NO_ACK; sTransmitBusy = false; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT @@ -835,6 +888,7 @@ if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE) { const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle); + RAIL_YieldRadio(aRailHandle); sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED; @@ -855,8 +909,12 @@ { RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle); - if (status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL || - (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy)) + assert(status != RAIL_SCHEDULER_STATUS_INTERNAL_ERROR); + + if (status == RAIL_SCHEDULER_STATUS_CCA_CSMA_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || + status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL || + (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy) || + (status == RAIL_SCHEDULER_STATUS_EVENT_INTERRUPTED && sTransmitBusy)) { sTransmitError = OT_ERROR_ABORT; sTransmitBusy = false; @@ -864,6 +922,18 @@ sRailDebugCounters.mRailEventSchedulerStatusError++; #endif } + else if (status == RAIL_SCHEDULER_STATUS_AVERAGE_RSSI_FAIL) + { + sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED; + sEnergyScanResultDbm = OT_RADIO_RSSI_INVALID; + } +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + else if (sTransmitBusy) + { + sRailDebugCounters.mRailEventsSchedulerStatusLastStatus = status; + sRailDebugCounters.mRailEventsSchedulerStatusTransmitBusy++; + } +#endif } otSysEventSignalPending(); @@ -919,7 +989,7 @@ #endif } - processNextRxPacket(aInstance); + processNextRxPacket(aInstance, sRxBandConfig->mRailHandle); } otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower) @@ -941,8 +1011,11 @@ RAIL_Status_t status; - status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aPower) * 10); - assert(status == RAIL_STATUS_NO_ERROR); + for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) + { + status = RAIL_SetTxPowerDbm(sBandConfigs[i].mRailHandle, ((RAIL_TxPower_t)aPower) * 10); + assert(status == RAIL_STATUS_NO_ERROR); + } sTxPowerDbm = aPower;