mirror of
https://github.com/espressif/openthread.git
synced 2026-09-12 20:20:04 +00:00
[efr32] dynamic multi-protocol support for MG12 and MG21 (#4321)
This commit is contained in:
committed by
Jonathan Hui
parent
1626cc4013
commit
3dbd91aa2b
@@ -119,6 +119,21 @@ COMMONCFLAGS := \
|
|||||||
|
|
||||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
|
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 += \
|
CPPFLAGS += \
|
||||||
$(COMMONCFLAGS) \
|
$(COMMONCFLAGS) \
|
||||||
$(target_CPPFLAGS) \
|
$(target_CPPFLAGS) \
|
||||||
|
|||||||
@@ -105,6 +105,21 @@ COMMONCFLAGS := \
|
|||||||
|
|
||||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
|
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 += \
|
CPPFLAGS += \
|
||||||
$(COMMONCFLAGS) \
|
$(COMMONCFLAGS) \
|
||||||
$(target_CPPFLAGS) \
|
$(target_CPPFLAGS) \
|
||||||
|
|||||||
@@ -30,12 +30,19 @@
|
|||||||
# efr32mg12 platform-specific Makefile
|
# 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)/examples/platforms/efr32mg12/libopenthread-efr32mg12.a \
|
||||||
$(top_builddir)/third_party/silabs/libsilabs-efr32mg12-sdk.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)
|
$(NULL)
|
||||||
|
|
||||||
LDFLAGS_COMMON += \
|
LDFLAGS_COMMON += \
|
||||||
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
|
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|||||||
@@ -35,7 +35,14 @@
|
|||||||
#ifndef __BOARD_CONFIG_H__
|
#ifndef __BOARD_CONFIG_H__
|
||||||
#define __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
|
#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__
|
#endif // __BOARD_CONFIG_H__
|
||||||
|
|||||||
@@ -35,8 +35,14 @@
|
|||||||
#ifndef __BOARD_CONFIG_H__
|
#ifndef __BOARD_CONFIG_H__
|
||||||
#define __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.
|
||||||
#define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
|
|
||||||
|
|
||||||
|
#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__
|
#endif // __BOARD_CONFIG_H__
|
||||||
|
|||||||
@@ -35,8 +35,15 @@
|
|||||||
#ifndef __BOARD_CONFIG_H__
|
#ifndef __BOARD_CONFIG_H__
|
||||||
#define __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.
|
||||||
#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 915MHz 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
|
#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__
|
#endif // __BOARD_CONFIG_H__
|
||||||
|
|||||||
@@ -35,7 +35,14 @@
|
|||||||
#ifndef __BOARD_CONFIG_H__
|
#ifndef __BOARD_CONFIG_H__
|
||||||
#define __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
|
#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__
|
#endif // __BOARD_CONFIG_H__
|
||||||
|
|||||||
@@ -43,6 +43,16 @@
|
|||||||
|
|
||||||
#define RAIL_TX_FIFO_SIZE (OT_RADIO_FRAME_MAX_SIZE + 1)
|
#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
|
typedef struct efr32RadioCounters
|
||||||
{
|
{
|
||||||
uint64_t mRailPlatTxTriggered;
|
uint64_t mRailPlatTxTriggered;
|
||||||
@@ -61,11 +71,16 @@ typedef struct efr32RadioCounters
|
|||||||
uint64_t mRailEventNoAck;
|
uint64_t mRailEventNoAck;
|
||||||
uint64_t mRailEventTxAbort;
|
uint64_t mRailEventTxAbort;
|
||||||
uint64_t mRailEventSchedulerStatusError;
|
uint64_t mRailEventSchedulerStatusError;
|
||||||
|
uint64_t mRailEventsSchedulerStatusTransmitBusy;
|
||||||
|
uint32_t mRailEventsSchedulerStatusLastStatus;
|
||||||
} efr32RadioCounters;
|
} efr32RadioCounters;
|
||||||
|
|
||||||
typedef struct efr32CommonConfig
|
typedef struct efr32CommonConfig
|
||||||
{
|
{
|
||||||
RAIL_Config_t mRailConfig;
|
RAIL_Config_t mRailConfig;
|
||||||
|
#if RADIO_CONFIG_DMP_SUPPORT
|
||||||
|
RAILSched_Config_t railSchedState;
|
||||||
|
#endif
|
||||||
uint8_t
|
uint8_t
|
||||||
mRailTxFifo[RAIL_TX_FIFO_SIZE]; // must be 2 power between 64 and 4096, and bigger than OT_RADIO_FRAME_MAX_SIZE
|
mRailTxFifo[RAIL_TX_FIFO_SIZE]; // must be 2 power between 64 and 4096, and bigger than OT_RADIO_FRAME_MAX_SIZE
|
||||||
} efr32CommonConfig;
|
} efr32CommonConfig;
|
||||||
|
|||||||
@@ -263,7 +263,11 @@ static void efr32ConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAI
|
|||||||
{
|
{
|
||||||
sCommonConfig.mRailConfig.eventsCallback = aEventCallback;
|
sCommonConfig.mRailConfig.eventsCallback = aEventCallback;
|
||||||
sCommonConfig.mRailConfig.protocol = NULL; // only used by Bluetooth stack
|
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;
|
uint8_t index = 0;
|
||||||
|
|
||||||
@@ -357,7 +361,11 @@ static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAI
|
|||||||
sCurrentBandConfig = config;
|
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);
|
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -494,7 +502,12 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
|
|||||||
sCurrentBandConfig = config;
|
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);
|
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
|
||||||
|
|
||||||
otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL);
|
otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL);
|
||||||
@@ -541,18 +554,53 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
|
|||||||
RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true);
|
RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true);
|
||||||
RAIL_WriteTxFifo(gRailHandle, aFrame->mPsdu, frameLength - 2, false);
|
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)
|
if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST)
|
||||||
{
|
{
|
||||||
txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK;
|
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)
|
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
|
else
|
||||||
{
|
{
|
||||||
status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, NULL);
|
status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, &txSchedulerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == RAIL_STATUS_NO_ERROR)
|
if (status == RAIL_STATUS_NO_ERROR)
|
||||||
@@ -646,7 +694,9 @@ static void processNextRxPacket(otInstance *aInstance)
|
|||||||
uint16_t length;
|
uint16_t length;
|
||||||
|
|
||||||
packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo);
|
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);
|
packetHandle = RAIL_RX_PACKET_HANDLE_INVALID);
|
||||||
|
|
||||||
status = RAIL_GetRxPacketDetailsAlt(gRailHandle, packetHandle, &packetDetails);
|
status = RAIL_GetRxPacketDetailsAlt(gRailHandle, packetHandle, &packetDetails);
|
||||||
@@ -686,6 +736,7 @@ static void processNextRxPacket(otInstance *aInstance)
|
|||||||
assert((length == IEEE802154_ACK_LENGTH) &&
|
assert((length == IEEE802154_ACK_LENGTH) &&
|
||||||
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK);
|
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK);
|
||||||
|
|
||||||
|
RAIL_YieldRadio(gRailHandle);
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
|
|
||||||
if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])
|
if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])
|
||||||
@@ -795,6 +846,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
{
|
{
|
||||||
if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
|
if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_NONE;
|
sTransmitError = OT_ERROR_NONE;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
}
|
}
|
||||||
@@ -804,6 +856,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
}
|
}
|
||||||
else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY)
|
else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY)
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
|
sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
||||||
@@ -812,6 +865,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_ABORT;
|
sTransmitError = OT_ERROR_ABORT;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
||||||
@@ -822,6 +876,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
|
|
||||||
if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
|
if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_NO_ACK;
|
sTransmitError = OT_ERROR_NO_ACK;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
||||||
@@ -852,6 +907,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE)
|
if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE)
|
||||||
{
|
{
|
||||||
const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle);
|
const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle);
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
|
|
||||||
sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED;
|
sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED;
|
||||||
|
|
||||||
@@ -872,8 +928,12 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
{
|
{
|
||||||
RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle);
|
RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle);
|
||||||
|
|
||||||
if (status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL ||
|
assert(status != RAIL_SCHEDULER_STATUS_INTERNAL_ERROR);
|
||||||
(status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy))
|
|
||||||
|
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;
|
sTransmitError = OT_ERROR_ABORT;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
@@ -881,6 +941,18 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
sRailDebugCounters.mRailEventSchedulerStatusError++;
|
sRailDebugCounters.mRailEventSchedulerStatusError++;
|
||||||
#endif
|
#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();
|
otSysEventSignalPending();
|
||||||
|
|||||||
@@ -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
|
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6
|
||||||
|
|
||||||
libopenthread_efr32mg21_a_CPPFLAGS = \
|
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 \
|
-DEFR32_SERIES2_CONFIG1_MICRO \
|
||||||
-DNVIC_CONFIG=\"platform/base/hal/micro/cortexm3/efm32/nvic-config.h\" \
|
-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)/include \
|
||||||
-I$(top_srcdir)/examples/platforms \
|
-I$(top_srcdir)/examples/platforms \
|
||||||
-I$(top_srcdir)/examples/platforms/efr32mg21/$(EFR32_BOARD_DIR) \
|
-I$(top_srcdir)/examples/platforms/efr32mg21/$(EFR32_BOARD_DIR) \
|
||||||
|
|||||||
@@ -30,12 +30,19 @@
|
|||||||
# efr32mg21 platform-specific Makefile
|
# 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)/examples/platforms/efr32mg21/libopenthread-efr32mg21.a \
|
||||||
$(top_builddir)/third_party/silabs/libsilabs-efr32mg21-sdk.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)
|
$(NULL)
|
||||||
|
|
||||||
LDFLAGS_COMMON += \
|
LDFLAGS_COMMON += \
|
||||||
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/efr32mg21.ld \
|
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/efr32mg21.ld \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|||||||
@@ -35,7 +35,14 @@
|
|||||||
#ifndef __BOARD_CONFIG_H__
|
#ifndef __BOARD_CONFIG_H__
|
||||||
#define __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
|
#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__
|
#endif // __BOARD_CONFIG_H__
|
||||||
|
|||||||
@@ -43,6 +43,16 @@
|
|||||||
|
|
||||||
#define RAIL_TX_FIFO_SIZE (OT_RADIO_FRAME_MAX_SIZE + 1)
|
#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
|
typedef struct efr32RadioCounters
|
||||||
{
|
{
|
||||||
uint64_t mRailPlatTxTriggered;
|
uint64_t mRailPlatTxTriggered;
|
||||||
@@ -61,18 +71,17 @@ typedef struct efr32RadioCounters
|
|||||||
uint64_t mRailEventNoAck;
|
uint64_t mRailEventNoAck;
|
||||||
uint64_t mRailEventTxAbort;
|
uint64_t mRailEventTxAbort;
|
||||||
uint64_t mRailEventSchedulerStatusError;
|
uint64_t mRailEventSchedulerStatusError;
|
||||||
|
uint64_t mRailEventsSchedulerStatusTransmitBusy;
|
||||||
|
uint32_t mRailEventsSchedulerStatusLastStatus;
|
||||||
} efr32RadioCounters;
|
} 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
|
typedef struct efr32BandConfig
|
||||||
{
|
{
|
||||||
|
RAIL_Handle_t mRailHandle;
|
||||||
|
RAIL_Config_t mRailConfig;
|
||||||
|
RAILSched_Config_t mRailSchedState;
|
||||||
const RAIL_ChannelConfig_t *mChannelConfig;
|
const RAIL_ChannelConfig_t *mChannelConfig;
|
||||||
|
uint8_t mRailTxFifo[OT_RADIO_FRAME_MAX_SIZE + 1];
|
||||||
uint8_t mChannelMin;
|
uint8_t mChannelMin;
|
||||||
uint8_t mChannelMax;
|
uint8_t mChannelMax;
|
||||||
} efr32BandConfig;
|
} efr32BandConfig;
|
||||||
|
|||||||
@@ -46,10 +46,8 @@
|
|||||||
#include "utils/soft_source_match_table.h"
|
#include "utils/soft_source_match_table.h"
|
||||||
|
|
||||||
#include "board_config.h"
|
#include "board_config.h"
|
||||||
#include "em_cmu.h"
|
|
||||||
#include "em_core.h"
|
#include "em_core.h"
|
||||||
#include "em_system.h"
|
#include "em_system.h"
|
||||||
#include "hal-config.h"
|
|
||||||
#include "openthread-core-efr32-config.h"
|
#include "openthread-core-efr32-config.h"
|
||||||
#include "pa_conversions_efr32.h"
|
#include "pa_conversions_efr32.h"
|
||||||
#include "platform-band.h"
|
#include "platform-band.h"
|
||||||
@@ -72,6 +70,7 @@ enum
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
EFR32_RECEIVE_SENSITIVITY = -100, // dBm
|
EFR32_RECEIVE_SENSITIVITY = -100, // dBm
|
||||||
|
EFR32_RSSI_AVERAGING_TIME = 16, // us
|
||||||
EFR32_RSSI_AVERAGING_TIMEOUT = 300, // us
|
EFR32_RSSI_AVERAGING_TIMEOUT = 300, // us
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,8 +114,7 @@ static otRadioFrame sTransmitFrame;
|
|||||||
static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH];
|
static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH];
|
||||||
static volatile otError sTransmitError;
|
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
|
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
||||||
static efr32RadioCounters sRailDebugCounters;
|
static efr32RadioCounters sRailDebugCounters;
|
||||||
@@ -132,53 +130,75 @@ static energyScanMode sEnergyScanMode;
|
|||||||
static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents);
|
static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents);
|
||||||
|
|
||||||
static const RAIL_IEEE802154_Config_t sRailIeee802154Config = {
|
static const RAIL_IEEE802154_Config_t sRailIeee802154Config = {
|
||||||
.addresses = NULL,
|
NULL, // addresses
|
||||||
.ackConfig =
|
{
|
||||||
|
// ackConfig
|
||||||
|
true, // ackConfig.enable
|
||||||
|
894, // ackConfig.ackTimeout
|
||||||
{
|
{
|
||||||
.enable = true,
|
// ackConfig.rxTransitions
|
||||||
.ackTimeout = 894,
|
RAIL_RF_STATE_RX, // ackConfig.rxTransitions.success
|
||||||
.rxTransitions =
|
RAIL_RF_STATE_RX, // ackConfig.rxTransitions.error
|
||||||
{
|
|
||||||
.success = RAIL_RF_STATE_RX,
|
|
||||||
.error = RAIL_RF_STATE_RX,
|
|
||||||
},
|
|
||||||
.txTransitions =
|
|
||||||
{
|
|
||||||
.success = RAIL_RF_STATE_RX,
|
|
||||||
.error = RAIL_RF_STATE_RX,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
.timings =
|
|
||||||
{
|
{
|
||||||
.idleToRx = 100,
|
// ackConfig.txTransitions
|
||||||
.txToRx = 192 - 10,
|
RAIL_RF_STATE_RX, // ackConfig.txTransitions.success
|
||||||
.idleToTx = 100,
|
RAIL_RF_STATE_RX, // ackConfig.txTransitions.error
|
||||||
.rxToTx = 192,
|
|
||||||
.rxSearchTimeout = 0,
|
|
||||||
.txToRxSearchTimeout = 0,
|
|
||||||
},
|
},
|
||||||
.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;
|
RAIL_DECLARE_TX_POWER_VBAT_CURVES_ALT;
|
||||||
|
|
||||||
static int8_t sTxPowerDbm = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
|
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_Status_t status;
|
||||||
RAIL_Handle_t handle;
|
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);
|
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);
|
status = RAIL_ConfigCal(handle, RAIL_CAL_ALL);
|
||||||
assert(status == RAIL_STATUS_NO_ERROR);
|
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);
|
status = RAIL_IEEE802154_Init(handle, &sRailIeee802154Config);
|
||||||
assert(status == RAIL_STATUS_NO_ERROR);
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
|
|
||||||
@@ -197,39 +217,27 @@ static RAIL_Handle_t efr32RailInit(efr32CommonConfig *aCommonConfig)
|
|||||||
);
|
);
|
||||||
assert(status == RAIL_STATUS_NO_ERROR);
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
|
|
||||||
uint16_t actualLenth = RAIL_SetTxFifo(handle, aCommonConfig->mRailTxFifo, 0, sizeof(aCommonConfig->mRailTxFifo));
|
uint16_t actualLength = RAIL_SetTxFifo(handle, aBandConfig->mRailTxFifo, 0, sizeof(aBandConfig->mRailTxFifo));
|
||||||
assert(actualLenth == sizeof(aCommonConfig->mRailTxFifo));
|
assert(actualLength == sizeof(aBandConfig->mRailTxFifo));
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void efr32RailConfigLoad(efr32BandConfig *aBandConfig)
|
static void efr32RadioSetTxPower(RAIL_Handle_t aRailHandle,
|
||||||
{
|
const RAIL_ChannelConfig_t *aChannelConfig,
|
||||||
RAIL_Status_t status;
|
int8_t aPowerDbm)
|
||||||
#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)
|
|
||||||
{
|
{
|
||||||
RAIL_Status_t status;
|
RAIL_Status_t status;
|
||||||
const RAIL_TxPowerCurvesConfigAlt_t txPowerCurvesConfig = RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT;
|
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);
|
status = RAIL_InitTxPowerCurvesAlt(&txPowerCurvesConfig);
|
||||||
assert(status == RAIL_STATUS_NO_ERROR);
|
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);
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,56 +257,39 @@ static efr32BandConfig *efr32RadioGetBandConfig(uint8_t aChannel)
|
|||||||
return config;
|
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;
|
uint8_t index = 0;
|
||||||
|
|
||||||
#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
|
#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
|
||||||
sBandConfigs[index].mChannelConfig = NULL;
|
sBandConfigs[index].mRailConfig.eventsCallback = aEventCallback;
|
||||||
sBandConfigs[index].mChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN;
|
sBandConfigs[index].mRailConfig.protocol = NULL;
|
||||||
sBandConfigs[index].mChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
|
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++;
|
index++;
|
||||||
#endif
|
#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)
|
void efr32RadioInit(void)
|
||||||
{
|
{
|
||||||
RAIL_Status_t status;
|
efr32BandConfigInit(RAILCb_Generic);
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
sReceiveFrame.mLength = 0;
|
sReceiveFrame.mLength = 0;
|
||||||
sReceiveFrame.mPsdu = sReceivePsdu;
|
sReceiveFrame.mPsdu = sReceivePsdu;
|
||||||
sTransmitFrame.mLength = 0;
|
sTransmitFrame.mLength = 0;
|
||||||
sTransmitFrame.mPsdu = sTransmitPsdu;
|
sTransmitFrame.mPsdu = sTransmitPsdu;
|
||||||
|
|
||||||
sCurrentBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL);
|
sRxBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL);
|
||||||
assert(sCurrentBandConfig != NULL);
|
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;
|
sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
|
||||||
sTransmitError = OT_ERROR_NONE;
|
sTransmitError = OT_ERROR_NONE;
|
||||||
@@ -311,36 +302,37 @@ void efr32RadioDeinit(void)
|
|||||||
{
|
{
|
||||||
RAIL_Status_t status;
|
RAIL_Status_t status;
|
||||||
|
|
||||||
RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
|
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
|
||||||
status = RAIL_ConfigEvents(gRailHandle, RAIL_EVENTS_ALL, 0);
|
{
|
||||||
assert(status == RAIL_STATUS_NO_ERROR);
|
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)
|
static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAIL_Time_t aAveragingTimeUs)
|
||||||
{
|
{
|
||||||
RAIL_Status_t status;
|
RAIL_Status_t status;
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
efr32BandConfig *config = NULL;
|
|
||||||
|
|
||||||
otEXPECT_ACTION(sEnergyScanStatus == ENERGY_SCAN_STATUS_IDLE, error = OT_ERROR_BUSY);
|
otEXPECT_ACTION(sEnergyScanStatus == ENERGY_SCAN_STATUS_IDLE, error = OT_ERROR_BUSY);
|
||||||
|
|
||||||
sEnergyScanStatus = ENERGY_SCAN_STATUS_IN_PROGRESS;
|
sEnergyScanStatus = ENERGY_SCAN_STATUS_IN_PROGRESS;
|
||||||
sEnergyScanMode = aMode;
|
sEnergyScanMode = aMode;
|
||||||
|
|
||||||
RAIL_Idle(gRailHandle, RAIL_IDLE, true);
|
RAIL_Idle(sRxBandConfig->mRailHandle, RAIL_IDLE, true);
|
||||||
|
|
||||||
config = efr32RadioGetBandConfig(aChannel);
|
RAIL_SchedulerInfo_t scanSchedulerInfo = {.priority = RADIO_SCHEDULER_CHANNEL_SCAN_PRIORITY,
|
||||||
otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
|
.slipTime = RADIO_SCHEDULER_CHANNEL_SLIP_TIME,
|
||||||
|
.transactionTime = aAveragingTimeUs};
|
||||||
|
|
||||||
if (sCurrentBandConfig != config)
|
status = RAIL_StartAverageRssi(sRxBandConfig->mRailHandle, aChannel, aAveragingTimeUs, &scanSchedulerInfo);
|
||||||
{
|
|
||||||
efr32RailConfigLoad(config);
|
|
||||||
sCurrentBandConfig = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = RAIL_StartAverageRssi(gRailHandle, aChannel, aAveragingTimeUs, NULL);
|
|
||||||
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
|
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -375,7 +367,7 @@ void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
|
|||||||
|
|
||||||
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
|
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);
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,7 +383,7 @@ void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aA
|
|||||||
|
|
||||||
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
|
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);
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,7 +398,7 @@ void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
|
|||||||
|
|
||||||
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
|
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);
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -451,7 +443,10 @@ otError otPlatRadioSleep(otInstance *aInstance)
|
|||||||
|
|
||||||
otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL);
|
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;
|
sState = OT_RADIO_STATE_SLEEP;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -470,14 +465,18 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
|
|||||||
config = efr32RadioGetBandConfig(aChannel);
|
config = efr32RadioGetBandConfig(aChannel);
|
||||||
otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
|
otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
|
||||||
|
|
||||||
if (sCurrentBandConfig != config)
|
if (sRxBandConfig != config)
|
||||||
{
|
{
|
||||||
RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
|
RAIL_Idle(sRxBandConfig->mRailHandle, RAIL_IDLE, false);
|
||||||
efr32RailConfigLoad(config);
|
sRxBandConfig = config;
|
||||||
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(sRxBandConfig->mRailHandle, aChannel, &bgRxSchedulerInfo);
|
||||||
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
|
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
|
||||||
|
|
||||||
otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL);
|
otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL);
|
||||||
@@ -492,7 +491,7 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
|
|||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
RAIL_CsmaConfig_t csmaConfig = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA;
|
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;
|
efr32BandConfig * config;
|
||||||
RAIL_Status_t status;
|
RAIL_Status_t status;
|
||||||
uint8_t frameLength;
|
uint8_t frameLength;
|
||||||
@@ -513,29 +512,64 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
|
|||||||
sTransmitError = OT_ERROR_NONE;
|
sTransmitError = OT_ERROR_NONE;
|
||||||
sTransmitBusy = true;
|
sTransmitBusy = true;
|
||||||
|
|
||||||
if (sCurrentBandConfig != config)
|
if (sTxBandConfig != config)
|
||||||
{
|
{
|
||||||
RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
|
efr32RadioSetTxPower(config->mRailHandle, config->mChannelConfig, sTxPowerDbm);
|
||||||
efr32RailConfigLoad(config);
|
sTxBandConfig = config;
|
||||||
sCurrentBandConfig = config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frameLength = (uint8_t)aFrame->mLength;
|
frameLength = (uint8_t)aFrame->mLength;
|
||||||
RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true);
|
RAIL_WriteTxFifo(sTxBandConfig->mRailHandle, &frameLength, sizeof frameLength, true);
|
||||||
RAIL_WriteTxFifo(gRailHandle, aFrame->mPsdu, frameLength - 2, false);
|
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)
|
if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST)
|
||||||
{
|
{
|
||||||
txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK;
|
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)
|
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
|
else
|
||||||
{
|
{
|
||||||
status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, NULL);
|
status = RAIL_StartTx(sTxBandConfig->mRailHandle, aFrame->mChannel, txOptions, &txSchedulerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == RAIL_STATUS_NO_ERROR)
|
if (status == RAIL_STATUS_NO_ERROR)
|
||||||
@@ -567,19 +601,29 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
|||||||
|
|
||||||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
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);
|
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;
|
rssi = sEnergyScanResultDbm;
|
||||||
railRssi = RAIL_GetRssi(gRailHandle, true);
|
|
||||||
if (railRssi != RAIL_RSSI_INVALID)
|
|
||||||
{
|
|
||||||
rssi = railRssi / QUARTER_DBM_IN_DBM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
|
||||||
|
exit:
|
||||||
return rssi;
|
return rssi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,7 +651,7 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
|
|||||||
|
|
||||||
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
|
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);
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,7 +664,7 @@ void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
|
|||||||
sIsSrcMatchEnabled = aEnable;
|
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_RxPacketHandle_t packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
|
||||||
RAIL_RxPacketInfo_t packetInfo;
|
RAIL_RxPacketInfo_t packetInfo;
|
||||||
@@ -628,11 +672,15 @@ static void processNextRxPacket(otInstance *aInstance)
|
|||||||
RAIL_Status_t status;
|
RAIL_Status_t status;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
|
|
||||||
packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo);
|
packetHandle = RAIL_GetRxPacketInfo(aRailHandle, 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);
|
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);
|
otEXPECT(status == RAIL_STATUS_NO_ERROR);
|
||||||
|
|
||||||
length = packetInfo.packetBytes + 1;
|
length = packetInfo.packetBytes + 1;
|
||||||
@@ -656,7 +704,7 @@ static void processNextRxPacket(otInstance *aInstance)
|
|||||||
memcpy(sReceiveFrame.mPsdu + packetInfo.firstPortionBytes, packetInfo.lastPortionData,
|
memcpy(sReceiveFrame.mPsdu + packetInfo.firstPortionBytes, packetInfo.lastPortionData,
|
||||||
packetInfo.packetBytes - packetInfo.firstPortionBytes);
|
packetInfo.packetBytes - packetInfo.firstPortionBytes);
|
||||||
|
|
||||||
status = RAIL_ReleaseRxPacket(gRailHandle, packetHandle);
|
status = RAIL_ReleaseRxPacket(aRailHandle, packetHandle);
|
||||||
if (status == RAIL_STATUS_NO_ERROR)
|
if (status == RAIL_STATUS_NO_ERROR)
|
||||||
{
|
{
|
||||||
packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
|
packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
|
||||||
@@ -669,6 +717,7 @@ static void processNextRxPacket(otInstance *aInstance)
|
|||||||
assert((length == IEEE802154_ACK_LENGTH) &&
|
assert((length == IEEE802154_ACK_LENGTH) &&
|
||||||
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK);
|
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK);
|
||||||
|
|
||||||
|
RAIL_YieldRadio(gRailHandle);
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
|
|
||||||
if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])
|
if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])
|
||||||
@@ -725,7 +774,7 @@ exit:
|
|||||||
|
|
||||||
if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID)
|
if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID)
|
||||||
{
|
{
|
||||||
RAIL_ReleaseRxPacket(gRailHandle, packetHandle);
|
RAIL_ReleaseRxPacket(aRailHandle, packetHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,6 +827,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
{
|
{
|
||||||
if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
|
if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_NONE;
|
sTransmitError = OT_ERROR_NONE;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
}
|
}
|
||||||
@@ -787,6 +837,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
}
|
}
|
||||||
else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY)
|
else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY)
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
|
sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
||||||
@@ -795,6 +846,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_ABORT;
|
sTransmitError = OT_ERROR_ABORT;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
||||||
@@ -805,6 +857,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
|
|
||||||
if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
|
if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
|
||||||
{
|
{
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
sTransmitError = OT_ERROR_NO_ACK;
|
sTransmitError = OT_ERROR_NO_ACK;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
|
||||||
@@ -835,6 +888,7 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE)
|
if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE)
|
||||||
{
|
{
|
||||||
const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle);
|
const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle);
|
||||||
|
RAIL_YieldRadio(aRailHandle);
|
||||||
|
|
||||||
sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED;
|
sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED;
|
||||||
|
|
||||||
@@ -855,8 +909,12 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
{
|
{
|
||||||
RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle);
|
RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle);
|
||||||
|
|
||||||
if (status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL ||
|
assert(status != RAIL_SCHEDULER_STATUS_INTERNAL_ERROR);
|
||||||
(status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy))
|
|
||||||
|
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;
|
sTransmitError = OT_ERROR_ABORT;
|
||||||
sTransmitBusy = false;
|
sTransmitBusy = false;
|
||||||
@@ -864,6 +922,18 @@ static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
|
|||||||
sRailDebugCounters.mRailEventSchedulerStatusError++;
|
sRailDebugCounters.mRailEventSchedulerStatusError++;
|
||||||
#endif
|
#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();
|
otSysEventSignalPending();
|
||||||
@@ -919,7 +989,7 @@ void efr32RadioProcess(otInstance *aInstance)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
processNextRxPacket(aInstance);
|
processNextRxPacket(aInstance, sRxBandConfig->mRailHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
|
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
|
||||||
@@ -941,8 +1011,11 @@ otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
|
|||||||
|
|
||||||
RAIL_Status_t status;
|
RAIL_Status_t status;
|
||||||
|
|
||||||
status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aPower) * 10);
|
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
|
||||||
assert(status == RAIL_STATUS_NO_ERROR);
|
{
|
||||||
|
status = RAIL_SetTxPowerDbm(sBandConfigs[i].mRailHandle, ((RAIL_TxPower_t)aPower) * 10);
|
||||||
|
assert(status == RAIL_STATUS_NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
sTxPowerDbm = aPower;
|
sTxPowerDbm = aPower;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user