Skip to content

Commit

Permalink
[efr32] dynamic multi-protocol support for MG12 and MG21 (#4321)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marven Gilhespie authored and jwhui committed Nov 13, 2019
1 parent 1626cc4 commit 3dbd91a
Show file tree
Hide file tree
Showing 14 changed files with 418 additions and 178 deletions.
15 changes: 15 additions & 0 deletions examples/Makefile-efr32mg12
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,21 @@ COMMONCFLAGS := \

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) \
Expand Down
15 changes: 15 additions & 0 deletions examples/Makefile-efr32mg21
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ COMMONCFLAGS := \

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) \
Expand Down
13 changes: 10 additions & 3 deletions examples/platforms/efr32mg12/Makefile.platform.am
Original file line number Diff line number Diff line change
Expand Up @@ -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)
9 changes: 8 additions & 1 deletion examples/platforms/efr32mg12/brd4161a/board_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
8 changes: 7 additions & 1 deletion examples/platforms/efr32mg12/brd4166a/board_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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__
11 changes: 9 additions & 2 deletions examples/platforms/efr32mg12/brd4170a/board_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
9 changes: 8 additions & 1 deletion examples/platforms/efr32mg12/brd4304a/board_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
15 changes: 15 additions & 0 deletions examples/platforms/efr32mg12/platform-band.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -61,11 +71,16 @@ typedef struct efr32RadioCounters
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;
Expand Down
88 changes: 80 additions & 8 deletions examples/platforms/efr32mg12/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,11 @@ static void efr32ConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAI
{
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;

Expand Down Expand Up @@ -357,7 +361,11 @@ static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAI
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:
Expand Down Expand Up @@ -494,7 +502,12 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
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);
Expand Down Expand Up @@ -541,18 +554,53 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
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)
Expand Down Expand Up @@ -646,7 +694,9 @@ static void processNextRxPacket(otInstance *aInstance)
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);
Expand Down Expand Up @@ -686,6 +736,7 @@ static void processNextRxPacket(otInstance *aInstance)
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])
Expand Down Expand Up @@ -795,6 +846,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
{
if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
{
RAIL_YieldRadio(aRailHandle);
sTransmitError = OT_ERROR_NONE;
sTransmitBusy = false;
}
Expand All @@ -804,6 +856,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
}
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
Expand All @@ -812,6 +865,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
}
else
{
RAIL_YieldRadio(aRailHandle);
sTransmitError = OT_ERROR_ABORT;
sTransmitBusy = false;
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
Expand All @@ -822,6 +876,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)

if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
{
RAIL_YieldRadio(aRailHandle);
sTransmitError = OT_ERROR_NO_ACK;
sTransmitBusy = false;
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
Expand Down Expand Up @@ -852,6 +907,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE)
{
const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle);
RAIL_YieldRadio(aRailHandle);

sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED;

Expand All @@ -872,15 +928,31 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
{
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;
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
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();
Expand Down
7 changes: 0 additions & 7 deletions examples/platforms/efr32mg21/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,8 @@ EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a
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) \
Expand Down
13 changes: 10 additions & 3 deletions examples/platforms/efr32mg21/Makefile.platform.am
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 3dbd91a

Please sign in to comment.