[efr32] update to RAIL 2.x (#2401)

This update also makes the following changes:
- Initialize chip using `halInitChipSpecific()` provided by RAIL HAL.
- Use `RAIL_HoldRxPacket()` to move rx processing out of interrupt context
- Eliminate critical sections from `otPlatRadio*` APIs.
- Use UART driver provided by Gecko SDK.
This commit is contained in:
Jonathan Hui
2018-01-09 17:47:01 +00:00
committed by GitHub
parent e27cb115a5
commit e668f0cc3e
12 changed files with 893 additions and 567 deletions
+5 -5
View File
@@ -58,11 +58,11 @@ EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"efr32-mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -DEFR32MG12P432F1024GL125
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/crypto
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.1/util/third_party/mbedtls/configs
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.1/platform/CMSIS/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.1/util/third_party/mbedtls/sl_crypto/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.1/platform/Device/SiliconLabs/EFR32MG12P/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/inc
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.0/util/third_party/mbedtls/configs
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.0/platform/CMSIS/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.0/util/third_party/mbedtls/sl_crypto/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.0/platform/Device/SiliconLabs/EFR32MG12P/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/inc
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo.patched/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo.patched/include/mbedtls
+37 -19
View File
@@ -38,7 +38,7 @@ override CXXFLAGS := $(filter-out -Wconversion,$(CXXF
override CFLAGS := $(filter-out -pedantic-errors,$(CFLAGS))
override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.1
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.0
libopenthread_efr32_a_CPPFLAGS = \
-DEFR32MG12P432F1024GL125 \
@@ -51,17 +51,25 @@ libopenthread_efr32_a_CPPFLAGS =
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/chip/efr32 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/protocol/ieee802154 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/chip/efr32/rf/common/cortex \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/hal \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/hal/efr32 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/plugin/pa-conversions \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/common/bsp \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/common/drivers \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/common/halconfig \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/EFR32MG12_BRD4161A/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/CMSIS/Include \
-I$(EFR32MG_SDK_SRCDIR)/platform/Device/SiliconLabs/EFR32MG12P/Include \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/common/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/gpiointerrupt/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/uartdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/uartdrv/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/ustimer/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/dmadrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/dmadrv/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/rtcdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emlib/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/halconfig/inc/hal-config \
-Wno-unused-parameter \
$(NULL)
@@ -84,24 +92,34 @@ PLATFORM_SOURCES +=
endif
nodist_libopenthread_efr32_a_SOURCES = \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/hardware/kit/common/bsp/bsp_bcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/hardware/kit/common/bsp/bsp_stk.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emdrv/rtcdrv/src/rtcdriver.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emdrv/ustimer/src/ustimer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_adc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_cmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_core.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_emu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_gpio.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_rmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_rtcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_system.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_timer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_usart.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_msc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/platform/emlib/src/em_crypto.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/hardware/kit/common/bsp/bsp_bcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/hardware/kit/common/bsp/bsp_init.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/hardware/kit/common/bsp/bsp_stk.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/hardware/kit/common/bsp/bsp_stk_leds.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/hardware/kit/common/drivers/retargetserial.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emdrv/dmadrv/src/dmadrv.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emdrv/rtcdrv/src/rtcdriver.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emdrv/uartdrv/src/uartdrv.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emdrv/ustimer/src/ustimer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_adc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_cmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_core.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_crypto.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_emu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_gpio.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_ldma.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_leuart.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_msc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_rmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_rtcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_system.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_timer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/emlib/src/em_usart.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/radio/rail_lib/hal/efr32/hal_efr.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/platform/radio/rail_lib/hal/hal_common.c \
$(NULL)
noinst_HEADERS = \
@@ -32,9 +32,9 @@
LDADD_COMMON += \
$(top_builddir)/examples/platforms/efr32/libopenthread-efr32.a \
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.1/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.0/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \
$(NULL)
LDFLAGS_COMMON += \
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.1/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
$(NULL)
+2 -2
View File
@@ -191,7 +191,7 @@ For a list of all available commands, visit [OpenThread CLI Reference README.md]
The following toolchain has been used for testing and verification:
- gcc version 4.9.3
- gcc version 5.4.1
The EFR32 example has been verified with following Flex SDK/RAIL Library version:
- Flex SDK version 1.1.1.0, RAIL Library version 1.5.2
- Flex SDK version 1.2.0.0, RAIL Library version 1.6.0
- Flex SDK version 2.0.0.0
@@ -67,6 +67,7 @@
* MBEDTLS_ECP_DP_XXX_ENABLED and (CRYPTO_COUNT > 0)
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_ECP_INTERNAL_ALT
#define MBEDTLS_ECP_DEVICE_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_DEVICE_ADD_MIXED_ALT
+388
View File
@@ -0,0 +1,388 @@
#ifndef HAL_CONFIG_H
#define HAL_CONFIG_H
#include "em_device.h"
#include "hal-config-types.h"
// This file is auto-generated by Hardware Configurator in Simplicity Studio.
// Any content between $[ and ]$ will be replaced whenever the file is regenerated.
// Content outside these regions will be preserved.
// $[ACMP0]
// [ACMP0]$
// $[ACMP1]
// [ACMP1]$
// $[ADC0]
// [ADC0]$
// $[ANTDIV]
// [ANTDIV]$
// $[BATTERYMON]
// [BATTERYMON]$
// $[BTL_BUTTON]
// [BTL_BUTTON]$
// $[BULBPWM]
// [BULBPWM]$
// $[BULBPWM_COLOR]
// [BULBPWM_COLOR]$
// $[BUTTON]
// [BUTTON]$
// $[CMU]
#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
#define HAL_CLK_LFECLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
#define HAL_CLK_LFBCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
#define BSP_CLK_LFXO_PRESENT (1)
#define BSP_CLK_HFXO_PRESENT (1)
#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
#define BSP_CLK_LFXO_CTUNE (0)
#define BSP_CLK_LFXO_FREQ (32768)
#define HAL_CLK_LFACLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
#define BSP_CLK_HFXO_FREQ (38400000)
#define BSP_CLK_HFXO_CTUNE (338)
#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
#define BSP_CLK_HFXO_CTUNE_TOKEN (0)
#define HAL_CLK_HFXO_AUTOSTART (HAL_CLK_HFXO_AUTOSTART_NONE)
// [CMU]$
// $[COEX]
// [COEX]$
// $[CS5463]
// [CS5463]$
// $[CSEN0]
// [CSEN0]$
// $[DCDC]
#define BSP_DCDC_PRESENT (1)
#define HAL_DCDC_BYPASS (0)
#define BSP_DCDC_INIT EMU_DCDCINIT_DEFAULT
// [DCDC]$
// $[EMU]
// [EMU]$
// $[EXTFLASH]
// [EXTFLASH]$
// $[EZRADIOPRO]
// [EZRADIOPRO]$
// $[GPIO]
#define PORTIO_GPIO_SWCLKTCK_PIN (0)
#define PORTIO_GPIO_SWCLKTCK_PORT (gpioPortF)
#define PORTIO_GPIO_DBGROUTE_LOC (0)
#define PORTIO_GPIO_SWDIOTMS_PIN (1)
#define PORTIO_GPIO_SWDIOTMS_PORT (gpioPortF)
#define PORTIO_GPIO_SWV_PIN (2)
#define PORTIO_GPIO_SWV_PORT (gpioPortF)
#define PORTIO_GPIO_SWV_LOC (0)
#define PORTIO_GPIO_TCLK_PIN (8)
#define PORTIO_GPIO_TCLK_PORT (gpioPortF)
#define PORTIO_GPIO_TCLK_LOC (0)
#define PORTIO_GPIO_TD0_PIN (9)
#define PORTIO_GPIO_TD0_PORT (gpioPortF)
#define PORTIO_GPIO_TD0_LOC (0)
#define PORTIO_GPIO_TD1_PIN (10)
#define PORTIO_GPIO_TD1_PORT (gpioPortF)
#define PORTIO_GPIO_TD1_LOC (0)
#define PORTIO_GPIO_TD2_PIN (11)
#define PORTIO_GPIO_TD2_PORT (gpioPortF)
#define PORTIO_GPIO_TD2_LOC (0)
#define PORTIO_GPIO_TD3_PIN (12)
#define PORTIO_GPIO_TD3_PORT (gpioPortF)
#define PORTIO_GPIO_TD3_LOC (0)
// [GPIO]$
// $[I2C0]
#define PORTIO_I2C0_SCL_PIN (10)
#define PORTIO_I2C0_SCL_PORT (gpioPortC)
#define PORTIO_I2C0_SCL_LOC (14)
#define PORTIO_I2C0_SDA_PIN (11)
#define PORTIO_I2C0_SDA_PORT (gpioPortC)
#define PORTIO_I2C0_SDA_LOC (16)
// [I2C0]$
// $[I2C1]
// [I2C1]$
// $[I2CSENSOR]
// [I2CSENSOR]$
// $[IDAC0]
// [IDAC0]$
// $[IOEXP]
// [IOEXP]$
// $[LED]
#define BSP_LED_PRESENT (1)
#define BSP_LED0_PIN (4)
#define BSP_LED0_PORT (gpioPortF)
#define BSP_LED1_PIN (5)
#define BSP_LED1_PORT (gpioPortF)
#define HAL_LED_ENABLE { 0, 1 }
#define HAL_LED_COUNT (2)
#define BSP_LED_COUNT (2)
#define BSP_LED_INIT { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
// [LED]$
// $[LESENSE]
// [LESENSE]$
// $[LETIMER0]
// [LETIMER0]$
// $[LEUART0]
// [LEUART0]$
// $[LFXO]
// [LFXO]$
// $[LNA]
// [LNA]$
// $[PA]
#define HAL_PA_ENABLE (1)
#define HAL_PA_RAMP (10)
#define HAL_PA_2P4_LOWPOWER (0)
#define HAL_PA_POWER (252)
#define HAL_PA_VOLTAGE (3300)
#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
// [PA]$
// $[PCNT0]
// [PCNT0]$
// $[PCNT1]
// [PCNT1]$
// $[PCNT2]
// [PCNT2]$
// $[PORTIO]
// [PORTIO]$
// $[PRS]
#define PORTIO_PRS_CH4_PIN (13)
#define PORTIO_PRS_CH4_PORT (gpioPortD)
#define PORTIO_PRS_CH4_LOC (4)
// [PRS]$
// $[PTI]
#define PORTIO_PTI_DFRAME_PIN (13)
#define PORTIO_PTI_DFRAME_PORT (gpioPortB)
#define PORTIO_PTI_DFRAME_LOC (6)
#define PORTIO_PTI_DOUT_PIN (12)
#define PORTIO_PTI_DOUT_PORT (gpioPortB)
#define PORTIO_PTI_DOUT_LOC (6)
#define HAL_PTI_ENABLE (1)
#define BSP_PTI_DFRAME_PIN (13)
#define BSP_PTI_DFRAME_PORT (gpioPortB)
#define BSP_PTI_DFRAME_LOC (6)
#define BSP_PTI_DOUT_PIN (12)
#define BSP_PTI_DOUT_PORT (gpioPortB)
#define BSP_PTI_DOUT_LOC (6)
#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
#define HAL_PTI_BAUD_RATE (1600000)
// [PTI]$
// $[PYD1698]
// [PYD1698]$
// $[SERIAL]
#define HAL_SERIAL_USART0_ENABLE (0)
#define BSP_SERIAL_APP_PORT (HAL_SERIAL_PORT_USART0)
#define HAL_SERIAL_LEUART0_ENABLE (0)
#define HAL_SERIAL_USART1_ENABLE (0)
#define HAL_SERIAL_USART2_ENABLE (0)
#define HAL_SERIAL_USART3_ENABLE (0)
#define HAL_SERIAL_RXWAKE_ENABLE (0)
#define BSP_SERIAL_APP_CTS_PIN (2)
#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
#define BSP_SERIAL_APP_CTS_LOC (30)
#define BSP_SERIAL_APP_RX_PIN (1)
#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
#define BSP_SERIAL_APP_RX_LOC (0)
#define BSP_SERIAL_APP_TX_PIN (0)
#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
#define BSP_SERIAL_APP_TX_LOC (0)
#define BSP_SERIAL_APP_RTS_PIN (3)
#define BSP_SERIAL_APP_RTS_PORT (gpioPortA)
#define BSP_SERIAL_APP_RTS_LOC (30)
#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128)
#define HAL_SERIAL_APP_BAUD_RATE (115200)
#define HAL_SERIAL_APP_RXSTOP (16)
#define HAL_SERIAL_APP_RXSTART (16)
#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128)
#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
// [SERIAL]$
// $[SPIDISPLAY]
// [SPIDISPLAY]$
// $[SPINCP]
// [SPINCP]$
// $[TIMER0]
// [TIMER0]$
// $[TIMER1]
// [TIMER1]$
// $[UARTNCP]
// [UARTNCP]$
// $[USART0]
#define PORTIO_USART0_CTS_PIN (2)
#define PORTIO_USART0_CTS_PORT (gpioPortA)
#define PORTIO_USART0_CTS_LOC (30)
#define PORTIO_USART0_RTS_PIN (3)
#define PORTIO_USART0_RTS_PORT (gpioPortA)
#define PORTIO_USART0_RTS_LOC (30)
#define PORTIO_USART0_RX_PIN (1)
#define PORTIO_USART0_RX_PORT (gpioPortA)
#define PORTIO_USART0_RX_LOC (0)
#define PORTIO_USART0_TX_PIN (0)
#define PORTIO_USART0_TX_PORT (gpioPortA)
#define PORTIO_USART0_TX_LOC (0)
#define HAL_USART0_ENABLE (1)
#define BSP_USART0_CTS_PIN (2)
#define BSP_USART0_CTS_PORT (gpioPortA)
#define BSP_USART0_CTS_LOC (30)
#define BSP_USART0_RX_PIN (1)
#define BSP_USART0_RX_PORT (gpioPortA)
#define BSP_USART0_RX_LOC (0)
#define BSP_USART0_TX_PIN (0)
#define BSP_USART0_TX_PORT (gpioPortA)
#define BSP_USART0_TX_LOC (0)
#define BSP_USART0_RTS_PIN (3)
#define BSP_USART0_RTS_PORT (gpioPortA)
#define BSP_USART0_RTS_LOC (30)
#define HAL_USART0_RX_QUEUE_SIZE (128)
#define HAL_USART0_BAUD_RATE (115200)
#define HAL_USART0_RXSTOP (16)
#define HAL_USART0_RXSTART (16)
#define HAL_USART0_TX_QUEUE_SIZE (128)
#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
// [USART0]$
// $[USART1]
#define PORTIO_USART1_CLK_PIN (8)
#define PORTIO_USART1_CLK_PORT (gpioPortC)
#define PORTIO_USART1_CLK_LOC (11)
#define PORTIO_USART1_CS_PIN (9)
#define PORTIO_USART1_CS_PORT (gpioPortC)
#define PORTIO_USART1_CS_LOC (11)
#define PORTIO_USART1_RX_PIN (7)
#define PORTIO_USART1_RX_PORT (gpioPortC)
#define PORTIO_USART1_RX_LOC (11)
#define PORTIO_USART1_TX_PIN (6)
#define PORTIO_USART1_TX_PORT (gpioPortC)
#define PORTIO_USART1_TX_LOC (11)
// [USART1]$
// $[USART2]
#define PORTIO_USART2_CLK_PIN (8)
#define PORTIO_USART2_CLK_PORT (gpioPortA)
#define PORTIO_USART2_CLK_LOC (1)
#define PORTIO_USART2_CS_PIN (9)
#define PORTIO_USART2_CS_PORT (gpioPortA)
#define PORTIO_USART2_CS_LOC (1)
#define PORTIO_USART2_RX_PIN (7)
#define PORTIO_USART2_RX_PORT (gpioPortA)
#define PORTIO_USART2_RX_LOC (1)
#define PORTIO_USART2_TX_PIN (6)
#define PORTIO_USART2_TX_PORT (gpioPortA)
#define PORTIO_USART2_TX_LOC (1)
// [USART2]$
// $[USART3]
#define PORTIO_USART3_CTS_PIN (8)
#define PORTIO_USART3_CTS_PORT (gpioPortD)
#define PORTIO_USART3_CTS_LOC (28)
#define PORTIO_USART3_RTS_PIN (9)
#define PORTIO_USART3_RTS_PORT (gpioPortD)
#define PORTIO_USART3_RTS_LOC (28)
#define PORTIO_USART3_RX_PIN (7)
#define PORTIO_USART3_RX_PORT (gpioPortB)
#define PORTIO_USART3_RX_LOC (10)
#define PORTIO_USART3_TX_PIN (6)
#define PORTIO_USART3_TX_PORT (gpioPortB)
#define PORTIO_USART3_TX_LOC (10)
// [USART3]$
// $[VCOM]
// [VCOM]$
// $[VDAC0]
// [VDAC0]$
// $[VUART]
// [VUART]$
// $[WDOG]
// [WDOG]$
// $[WTIMER0]
// [WTIMER0]$
// $[WTIMER1]
// [WTIMER1]$
#endif /* HAL_CONFIG_H */
@@ -41,7 +41,7 @@
* The efr32 platform provides an otPlatLog() function.
*/
#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
#endif
/**
@@ -50,7 +50,7 @@
* The platform-specific string to insert into the OpenThread version string.
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
#define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
/*
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
@@ -108,16 +108,4 @@
*/
#define RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM 6
/**
* @def RADIO_CONFIG_XXX
*
* The Radio configuration Auto-generated by Simplicity Studio (rail_config.h).
*
*/
#define RADIO_CONFIG_BASE_FREQUENCY 2450000000UL
#define RADIO_CONFIG_XTAL_FREQUENCY 38400000UL
#define RADIO_CONFIG_BITRATE "2.4kbps"
#define RADIO_CONFIG_MODULATION_TYPE "FSK2"
#define RADIO_CONFIG_DEVIATION "1.2kHz"
#endif // OPENTHREAD_CORE_EFR32_CONFIG_H_
+8 -73
View File
@@ -38,20 +38,16 @@
#include "common/logging.hpp"
#include "pa.h"
#include "pti.h"
#include "bsp.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "em_chip.h"
#include "hal_common.h"
#include "platform-efr32.h"
#include "rail.h"
#include "rail_ieee802154.h"
#include "openthread-core-efr32-config.h"
otInstance *sInstance;
void halInitChipSpecific(void);
void HAL_Init(void);
otInstance *sInstance;
void PlatformInit(int argc, char *argv[])
{
@@ -59,20 +55,13 @@ void PlatformInit(int argc, char *argv[])
(void)argv;
CHIP_Init();
HAL_Init();
halInitChipSpecific();
BSP_Init(BSP_INIT_BCC);
RAIL_Init_t railInitParams =
{
128, // maxPacketLength: UNUSED
RADIO_CONFIG_XTAL_FREQUENCY,
0
};
RAIL_RfInit(&railInitParams);
RAIL_RfIdle();
efr32AlarmInit();
efr32RadioInit();
efr32AlarmInit();
efr32MiscInit();
efr32RandomInit();
}
@@ -92,57 +81,3 @@ void PlatformProcessDrivers(otInstance *aInstance)
efr32RadioProcess(aInstance);
efr32AlarmProcess(aInstance);
}
void halInitChipSpecific(void)
{
CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_WSTK_DEFAULT;
RADIO_PTIInit_t ptiInit = RADIO_PTI_INIT;
RADIO_PAInit_t paInit;
SYSTEM_ChipRevision_TypeDef chipRev;
SYSTEM_ChipRevisionGet(&chipRev);
// Init DCDC regulator and HFXO with WSTK radio board specific parameters
// from s025_sw\kits\SLWSTK6100A_EFR32MG\config\bspconfig.h
#ifdef EMU_DCDCINIT_WSTK_DEFAULT
EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_WSTK_DEFAULT;
EMU_DCDCInit(&dcdcInit);
#else
EMU_DCDCPowerOff();
#endif
CMU_HFXOInit(&hfxoInit);
SystemHFXOClockSet(RADIO_CONFIG_XTAL_FREQUENCY);
// Initialize the Packet Trace Interface (PTI) to match the configuration in
// the board header
RADIO_PTI_Init(&ptiInit);
/* Switch HFCLK to HFXO and disable HFRCO */
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
// Initialize the PA now that the HFXO is up and the timing is correct
#if (RADIO_CONFIG_BASE_FREQUENCY < 1000000000UL)
paInit = (RADIO_PAInit_t) RADIO_PA_SUBGIG_INIT;
#else
paInit = (RADIO_PAInit_t) RADIO_PA_2P4_INIT;
#endif
if (!RADIO_PA_Init(&paInit))
{
// Error: The PA could not be initialized due to an improper configuration.
// Please ensure your configuration is valid for the selected part.
while (1);
}
// Initialize other chip clocks
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFRCO);
CMU_ClockEnable(cmuClock_CORELE, true);
}
void HAL_Init(void)
{
halInitChipSpecific();
}
+336 -340
View File
@@ -46,7 +46,9 @@
#include "em_core.h"
#include "em_system.h"
#include "pa_conversions_efr32.h"
#include "rail.h"
#include "rail_config.h"
#include "rail_ieee802154.h"
#include "openthread-core-efr32-config.h"
@@ -68,14 +70,11 @@ enum
};
static uint16_t sPanId = 0;
static uint8_t sChannel = 0;
static bool sTransmitBusy = false;
static bool sPromiscuous = false;
static bool sIsReceiverEnabled = false;
static bool sIsSrcMatchEnabled = false;
static otRadioState sState = OT_RADIO_STATE_DISABLED;
static uint8_t sReceiveBuffer[IEEE802154_MAX_LENGTH + 1 + sizeof(RAIL_RxPacketInfo_t)];
static uint8_t sReceivePsdu[IEEE802154_MAX_LENGTH];
static otRadioFrame sReceiveFrame;
static otError sReceiveError;
@@ -93,9 +92,60 @@ typedef struct srcMatchEntry
static sSrcMatchEntry srcMatchShortEntry[RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM];
static sSrcMatchEntry srcMatchExtEntry[RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM];
static uint8_t sRailTxFifo[1 + IEEE802154_MAX_LENGTH];
static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents);
static RAIL_Config_t sRailConfig =
{
.eventsCallback = &RAILCb_Generic,
.protocol = NULL,
.scheduler = NULL,
};
static const RAIL_IEEE802154_Config_t sRailIeee802154Config =
{
NULL, // addresses
{
// ackConfig
true, // ackConfig.enable
894, // ackConfig.ackTimeout
{
// ackConfig.rxTransitions
RAIL_RF_STATE_RX, // ackConfig.rxTransitions.success
RAIL_RF_STATE_RX, // ackConfig.rxTransitions.error
},
{
// ackConfig.txTransitions
RAIL_RF_STATE_RX, // ackConfig.txTransitions.success
RAIL_RF_STATE_RX, // ackConfig.txTransitions.error
},
},
{
// 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
};
static RAIL_Handle_t sRailHandle = NULL;
RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp);
void efr32RadioInit(void)
{
// Data Management
RAIL_Status_t status;
sRailHandle = RAIL_Init(&sRailConfig, NULL);
assert(sRailHandle != NULL);
RAIL_DataConfig_t railDataConfig =
{
TX_PACKET_DATA,
@@ -104,76 +154,60 @@ void efr32RadioInit(void)
PACKET_MODE,
};
RAIL_DataConfig(&railDataConfig);
status = RAIL_ConfigData(sRailHandle, &railDataConfig);
assert(status == RAIL_STATUS_NO_ERROR);
// 802.15.4 configuration
RAIL_IEEE802154_Config_t config =
{
false, // promiscuousMode
false, // isPanCoordinator
RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, // framesMask
RAIL_RF_STATE_RX, // defaultState
100, // idleTime
192, // turnaroundTime
894, // ackTimeout
NULL // addresses
};
status = RAIL_ConfigCal(sRailHandle, RAIL_CAL_ALL);
assert(status == RAIL_STATUS_NO_ERROR);
status = RAIL_IEEE802154_Config2p4GHzRadio(sRailHandle);
assert(status == RAIL_STATUS_NO_ERROR);
status = RAIL_IEEE802154_Init(sRailHandle, &sRailIeee802154Config);
assert(status == RAIL_STATUS_NO_ERROR);
status = RAIL_ConfigEvents(sRailHandle, RAIL_EVENTS_ALL,
RAIL_EVENT_RX_ACK_TIMEOUT |
RAIL_EVENT_TX_PACKET_SENT |
RAIL_EVENT_RX_PACKET_RECEIVED |
RAIL_EVENT_TX_CHANNEL_BUSY |
RAIL_EVENT_TX_ABORTED |
RAIL_EVENT_TX_BLOCKED |
RAIL_EVENT_TX_UNDERFLOW |
RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND |
RAIL_EVENT_CAL_NEEDED
);
assert(status == RAIL_STATUS_NO_ERROR);
RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = { curves24Hp, curvesSg, curves24Lp, piecewiseSegments };
status = RAIL_InitTxPowerCurves(&txPowerCurvesConfig);
assert(status == RAIL_STATUS_NO_ERROR);
RAIL_TxPowerConfig_t txPowerConfig = { RAIL_TX_POWER_MODE_2P4_HP, 3300, 10 };
status = RAIL_ConfigTxPower(sRailHandle, &txPowerConfig);
assert(status == RAIL_STATUS_NO_ERROR);
status = RAIL_SetTxPowerDbm(sRailHandle, ((RAIL_TxPower_t)OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER) * 10);
assert(status == RAIL_STATUS_NO_ERROR);
RAIL_SetTxFifo(sRailHandle, sRailTxFifo, 0, sizeof(sRailTxFifo));
sReceiveFrame.mLength = 0;
sReceiveFrame.mPsdu = sReceivePsdu;
sTransmitFrame.mLength = 0;
sTransmitFrame.mPsdu = sTransmitPsdu;
if (RAIL_IEEE802154_2p4GHzRadioConfig())
{
assert(false);
}
if (RAIL_IEEE802154_Init(&config))
{
assert(false);
}
RAIL_TxPowerSet(((int32_t)OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER) * 10);
otLogInfoPlat(sInstance, "Initialized", NULL);
}
void efr32RadioDeinit(void)
{
RAIL_RfIdle();
RAIL_IEEE802154_Deinit();
}
RAIL_Status_t status;
void setChannel(uint8_t aChannel)
{
bool enabled = false;
RAIL_Idle(sRailHandle, RAIL_IDLE_FORCE_SHUTDOWN_CLEAR_FLAGS, true);
otEXPECT(sChannel != aChannel);
if (sIsReceiverEnabled)
{
RAIL_RfIdle();
enabled = true;
sIsReceiverEnabled = false;
}
otLogInfoPlat(sInstance, "Channel=%d", aChannel);
sChannel = aChannel;
if (enabled)
{
if (RAIL_RxStart(aChannel))
{
assert(false);
}
sIsReceiverEnabled = true;
}
exit:
return;
status = RAIL_IEEE802154_Deinit(sRailHandle);
assert(status == RAIL_STATUS_NO_ERROR);
}
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
@@ -193,32 +227,41 @@ void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
{
RAIL_Status_t status;
(void)aInstance;
otLogInfoPlat(sInstance, "PANID=%X", aPanId);
sPanId = aPanId;
RAIL_IEEE802154_SetPanId(aPanId);
status = RAIL_IEEE802154_SetPanId(sRailHandle, aPanId, 0);
assert(status == RAIL_STATUS_NO_ERROR);
}
void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
{
RAIL_Status_t status;
(void)aInstance;
otLogInfoPlat(sInstance, "ExtAddr=%X%X%X%X%X%X%X%X",
aAddress->m8[7], aAddress->m8[6], aAddress->m8[5], aAddress->m8[4],
aAddress->m8[3], aAddress->m8[2], aAddress->m8[1], aAddress->m8[0]);
RAIL_IEEE802154_SetLongAddress((uint8_t *)aAddress->m8);
status = RAIL_IEEE802154_SetLongAddress(sRailHandle, (uint8_t *)aAddress->m8, 0);
assert(status == RAIL_STATUS_NO_ERROR);
}
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
{
RAIL_Status_t status;
(void)aInstance;
otLogInfoPlat(sInstance, "ShortAddr=%X", aAddress);
RAIL_IEEE802154_SetShortAddress(aAddress);
status = RAIL_IEEE802154_SetShortAddress(sRailHandle, aAddress, 0);
assert(status == RAIL_STATUS_NO_ERROR);
}
bool otPlatRadioIsEnabled(otInstance *aInstance)
@@ -229,31 +272,23 @@ bool otPlatRadioIsEnabled(otInstance *aInstance)
otError otPlatRadioEnable(otInstance *aInstance)
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT(!otPlatRadioIsEnabled(aInstance));
otLogInfoPlat(sInstance, "State=OT_RADIO_STATE_SLEEP", NULL);
sState = OT_RADIO_STATE_SLEEP;
exit:
CORE_EXIT_CRITICAL();
return OT_ERROR_NONE;
}
otError otPlatRadioDisable(otInstance *aInstance)
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT(otPlatRadioIsEnabled(aInstance));
otLogInfoPlat(sInstance, "State=OT_RADIO_STATE_DISABLED", NULL);
sState = OT_RADIO_STATE_DISABLED;
exit:
CORE_EXIT_CRITICAL();
return OT_ERROR_NONE;
}
@@ -262,50 +297,34 @@ otError otPlatRadioSleep(otInstance *aInstance)
otError error = OT_ERROR_NONE;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT_ACTION((sState != OT_RADIO_STATE_TRANSMIT) && (sState != OT_RADIO_STATE_DISABLED),
error = OT_ERROR_INVALID_STATE);
otLogInfoPlat(sInstance, "State=OT_RADIO_STATE_SLEEP", NULL);
sState = OT_RADIO_STATE_SLEEP;
if (sIsReceiverEnabled)
{
RAIL_RfIdleExt(RAIL_IDLE, true);
sIsReceiverEnabled = false;
}
RAIL_Idle(sRailHandle, RAIL_IDLE, true);
exit:
CORE_EXIT_CRITICAL();
return error;
}
otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
otError error = OT_ERROR_NONE;
RAIL_Status_t status;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT_ACTION(sState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
status = RAIL_StartRx(sRailHandle, aChannel, NULL);
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
otLogInfoPlat(sInstance, "State=OT_RADIO_STATE_RECEIVE", NULL);
sState = OT_RADIO_STATE_RECEIVE;
setChannel(aChannel);
sReceiveFrame.mChannel = aChannel;
if (!sIsReceiverEnabled)
{
otEXPECT_ACTION(RAIL_RxStart(aChannel) == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
sIsReceiverEnabled = true;
}
exit:
CORE_EXIT_CRITICAL();
return error;
}
@@ -313,14 +332,10 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
{
otError error = OT_ERROR_NONE;
RAIL_CsmaConfig_t csmaConfig = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA;
RAIL_TxData_t txData;
RAIL_TxOptions_t txOption;
uint8_t frame[IEEE802154_MAX_LENGTH + 1];
RAIL_TxOptions_t txOptions = RAIL_TX_OPTIONS_NONE;
RAIL_Status_t status;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT_ACTION((sState != OT_RADIO_STATE_DISABLED) && (sState != OT_RADIO_STATE_TRANSMIT),
error = OT_ERROR_INVALID_STATE);
@@ -328,27 +343,20 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
sTransmitError = OT_ERROR_NONE;
sTransmitBusy = true;
frame[0] = aFrame->mLength;
memcpy(frame + 1, aFrame->mPsdu, aFrame->mLength);
txData.dataPtr = frame;
txData.dataLength = aFrame->mLength - 1;
RAIL_WriteTxFifo(sRailHandle, &aFrame->mLength, sizeof(aFrame->mLength), true);
RAIL_WriteTxFifo(sRailHandle, aFrame->mPsdu, aFrame->mLength - 2, false);
txOption.waitForAck = (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST) ? true : false;
txOption.removeCrc = false;
txOption.syncWordId = 0;
if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST)
{
txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK;
}
setChannel(aFrame->mChannel);
RAIL_RfIdleExt(RAIL_IDLE, true);
otEXPECT_ACTION(RAIL_TxDataLoad(&txData) == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
otEXPECT_ACTION(RAIL_TxStartWithOptions(aFrame->mChannel, &txOption, RAIL_CcaCsma, &csmaConfig) == RAIL_STATUS_NO_ERROR,
error = OT_ERROR_FAILED);
status = RAIL_StartCcaCsmaTx(sRailHandle, aFrame->mChannel, txOptions, &csmaConfig, NULL);
assert(status == RAIL_STATUS_NO_ERROR);
otPlatRadioTxStarted(aInstance, aFrame);
exit:
CORE_EXIT_CRITICAL();
return error;
}
@@ -361,13 +369,13 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
(void)aInstance;
return (uint8_t)(RAIL_RxGetRSSI() >> 2);
return (int8_t)(RAIL_GetAverageRssi(sRailHandle) >> 2);
}
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
(void)aInstance;
return OT_RADIO_CAPS_ACK_TIMEOUT;
return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF;
}
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
@@ -378,10 +386,13 @@ bool otPlatRadioGetPromiscuous(otInstance *aInstance)
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
RAIL_Status_t status;
(void)aInstance;
sPromiscuous = aEnable;
RAIL_IEEE802154_SetPromiscuousMode(aEnable);
status = RAIL_IEEE802154_SetPromiscuousMode(sRailHandle, aEnable);
assert(status == RAIL_STATUS_NO_ERROR);
}
int8_t findSrcMatchAvailEntry(bool aShortAddress)
@@ -492,13 +503,8 @@ void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
// set Frame Pending bit for all outgoing ACKs if aEnable is false
sIsSrcMatchEnabled = aEnable;
CORE_EXIT_CRITICAL();
}
otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
@@ -507,9 +513,6 @@ otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t a
otError error = OT_ERROR_NONE;
int8_t entry = -1;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchAvailEntry(true);
otLogDebgPlat(sInstance, "Add ShortAddr entry: %d", entry);
@@ -519,7 +522,6 @@ otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t a
addToSrcMatchShortIndirect(entry, aShortAddress);
exit:
CORE_EXIT_CRITICAL();
return error;
}
@@ -529,9 +531,6 @@ otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress
int8_t entry = -1;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchAvailEntry(false);
otLogDebgPlat(sInstance, "Add ExtAddr entry: %d", entry);
@@ -541,7 +540,6 @@ otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress
addToSrcMatchExtIndirect(entry, aExtAddress);
exit:
CORE_EXIT_CRITICAL();
return error;
}
@@ -551,9 +549,6 @@ otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t
int8_t entry = -1;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchShortEntry(aShortAddress);
otLogDebgPlat(sInstance, "Clear ShortAddr entry: %d", entry);
@@ -563,7 +558,6 @@ otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t
removeFromSrcMatchShortIndirect(entry);
exit:
CORE_EXIT_CRITICAL();
return error;
}
@@ -573,9 +567,6 @@ otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddre
int8_t entry = -1;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchExtEntry(aExtAddress);
otLogDebgPlat(sInstance, "Clear ExtAddr entry: %d", entry);
@@ -585,7 +576,6 @@ otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddre
removeFromSrcMatchExtIndirect(entry);
exit:
CORE_EXIT_CRITICAL();
return error;
}
@@ -607,22 +597,207 @@ void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
memset(srcMatchExtEntry, 0, sizeof(srcMatchExtEntry));
}
void RAILCb_IEEE802154_DataRequestCommand(RAIL_IEEE802154_Address_t *aAddress)
static void checkForAck(RAIL_Handle_t aRailHandle)
{
RAIL_RxPacketHandle_t packetHandle;
RAIL_RxPacketInfo_t packetInfo;
RAIL_RxPacketDetails_t packetDetails;
RAIL_Status_t status;
uint8_t frame[IEEE802154_ACK_LENGTH];
uint16_t length;
packetHandle = RAIL_GetRxPacketInfo(aRailHandle, RAIL_RX_PACKET_HANDLE_NEWEST, &packetInfo);
assert(packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS);
status = RAIL_GetRxPacketDetails(aRailHandle, packetHandle, &packetDetails);
assert(status == RAIL_STATUS_NO_ERROR);
otEXPECT(packetDetails.isAck);
sTransmitBusy = false;
length = packetInfo.packetBytes + 1;
assert(length == IEEE802154_ACK_LENGTH && length == packetInfo.firstPortionData[0]);
// skip length byte
assert(packetInfo.firstPortionBytes > 0);
packetInfo.firstPortionData++;
packetInfo.firstPortionBytes--;
packetInfo.packetBytes--;
// read packet
memcpy(frame, packetInfo.firstPortionData, packetInfo.firstPortionBytes);
memcpy(frame + packetInfo.firstPortionBytes,
packetInfo.lastPortionData,
packetInfo.packetBytes - packetInfo.firstPortionBytes);
assert((frame[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK);
if (frame[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])
{
sTransmitError = OT_ERROR_NONE;
}
else
{
sTransmitError = OT_ERROR_NO_ACK;
}
status = RAIL_ReleaseRxPacket(aRailHandle, packetHandle);
assert(status == RAIL_STATUS_NO_ERROR);
exit:
return;
}
static void processNextRxPacket(otInstance *aInstance, RAIL_Handle_t aRailHandle)
{
RAIL_RxPacketHandle_t packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
RAIL_RxPacketInfo_t packetInfo;
RAIL_RxPacketDetails_t packetDetails;
RAIL_Status_t status;
uint16_t length;
otEXPECT(sState == OT_RADIO_STATE_RECEIVE);
packetHandle = RAIL_GetRxPacketInfo(aRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo);
otEXPECT_ACTION(packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS,
packetHandle = RAIL_RX_PACKET_HANDLE_INVALID);
status = RAIL_GetRxPacketDetails(aRailHandle, packetHandle, &packetDetails);
assert(status == RAIL_STATUS_NO_ERROR);
length = packetInfo.packetBytes + 1;
assert(!packetDetails.isAck);
assert(length != IEEE802154_ACK_LENGTH);
// check the length in recv packet info structure
assert(length == packetInfo.firstPortionData[0]);
// check the length validity of recv packet
otEXPECT(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH);
otLogInfoPlat(aInstance, "Received data:%d", length);
// skip length byte
assert(packetInfo.firstPortionBytes > 0);
packetInfo.firstPortionData++;
packetInfo.firstPortionBytes--;
packetInfo.packetBytes--;
// read packet
memcpy(sReceiveFrame.mPsdu, packetInfo.firstPortionData, packetInfo.firstPortionBytes);
memcpy(sReceiveFrame.mPsdu + packetInfo.firstPortionBytes,
packetInfo.lastPortionData,
packetInfo.packetBytes - packetInfo.firstPortionBytes);
sReceiveFrame.mLength = length;
sReceiveFrame.mRssi = packetDetails.rssi;
sReceiveFrame.mLqi = packetDetails.lqi;
// TODO: grab timestamp and handle conversion to msec/usec
// sReceiveFrame.mMsec = packetDetails.packetTime;
// sReceiveFrame.mUsec = packetDetails.packetTime;
sReceiveError = OT_ERROR_NONE;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
}
else
#endif
{
// signal MAC layer for each received frame if promiscous is enabled
// otherwise only signal MAC layer for non-ACK frame
if (sPromiscuous || sReceiveFrame.mLength > IEEE802154_ACK_LENGTH)
{
otLogInfoPlat(aInstance, "Received %d bytes", sReceiveFrame.mLength);
otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
}
}
exit:
if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID)
{
RAIL_ReleaseRxPacket(aRailHandle, packetHandle);
}
}
static void ieee802154DataRequestCommand(RAIL_Handle_t aRailHandle)
{
RAIL_Status_t status;
if (sIsSrcMatchEnabled)
{
if ((aAddress->length == RAIL_IEEE802154_LongAddress &&
findSrcMatchExtEntry((otExtAddress *)aAddress->longAddress) >= 0) ||
(aAddress->length == RAIL_IEEE802154_ShortAddress &&
findSrcMatchShortEntry(aAddress->shortAddress) >= 0))
RAIL_IEEE802154_Address_t sourceAddress;
status = RAIL_IEEE802154_GetAddress(aRailHandle, &sourceAddress);
assert(status == RAIL_STATUS_NO_ERROR);
if ((sourceAddress.length == RAIL_IEEE802154_LongAddress &&
findSrcMatchExtEntry((otExtAddress *)sourceAddress.longAddress) >= 0) ||
(sourceAddress.length == RAIL_IEEE802154_ShortAddress &&
findSrcMatchShortEntry(sourceAddress.shortAddress) >= 0))
{
RAIL_IEEE802154_SetFramePending();
status = RAIL_IEEE802154_SetFramePending(aRailHandle);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
else
{
(void)aAddress;
RAIL_IEEE802154_SetFramePending();
status = RAIL_IEEE802154_SetFramePending(aRailHandle);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
{
if (aEvents & (RAIL_EVENT_TX_ABORTED | RAIL_EVENT_TX_BLOCKED | RAIL_EVENT_TX_UNDERFLOW))
{
sTransmitError = OT_ERROR_ABORT;
sTransmitBusy = false;
}
if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
{
sTransmitError = OT_ERROR_NO_ACK;
sTransmitBusy = false;
}
if (aEvents & RAIL_EVENT_RX_PACKET_RECEIVED)
{
RAIL_HoldRxPacket(aRailHandle);
checkForAck(aRailHandle);
}
if (aEvents & RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND)
{
ieee802154DataRequestCommand(aRailHandle);
}
if (aEvents & RAIL_EVENT_TX_PACKET_SENT)
{
if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
{
sTransmitError = OT_ERROR_NONE;
sTransmitBusy = false;
}
}
if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY)
{
sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
sTransmitBusy = false;
}
if (aEvents & RAIL_EVENT_CAL_NEEDED)
{
RAIL_Status_t status;
status = RAIL_Calibrate(aRailHandle, NULL, RAIL_CAL_ALL_PENDING);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
@@ -634,213 +809,31 @@ otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint1
return OT_ERROR_NOT_IMPLEMENTED;
}
void RAILCb_TxRadioStatus(uint8_t aStatus)
{
switch (aStatus)
{
case RAIL_TX_CONFIG_CHANNEL_BUSY:
sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
sTransmitBusy = false;
break;
case RAIL_TX_CONFIG_TX_ABORTED:
sTransmitError = OT_ERROR_ABORT;
sTransmitBusy = false;
break;
case RAIL_TX_CONFIG_BUFFER_UNDERFLOW:
sTransmitError = OT_ERROR_ABORT;
sTransmitBusy = false;
break;
default:
break;
}
}
void RAILCb_TxPacketSent(RAIL_TxPacketInfo_t *aTxPacketInfo)
{
(void)aTxPacketInfo;
sTransmitError = OT_ERROR_NONE;
sTransmitBusy = false;
}
void RAILCb_RxPacketReceived(void *aRxPacketHandle)
{
RAIL_RxPacketInfo_t *rxPacketInfo;
uint8_t length;
rxPacketInfo = (RAIL_RxPacketInfo_t *)aRxPacketHandle;
// check recv packet appended info
otEXPECT(rxPacketInfo != NULL &&
rxPacketInfo->appendedInfo.crcStatus &&
rxPacketInfo->appendedInfo.frameCodingStatus);
length = rxPacketInfo->dataLength + 1;
// check the length in recv packet info structure
otEXPECT(length == rxPacketInfo->dataPtr[0]);
// check the lenght validity of recv packet
otEXPECT(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH);
otLogInfoPlat(sInstance, "Received data:%d", rxPacketInfo->dataLength);
#if OPENTHREAD_ENABLE_RAW_LINK_API
// Timestamp
sReceiveFrame.mMsec = otPlatAlarmMilliGetNow();
sReceiveFrame.mUsec = 0; // Don't support microsecond timer for now.
#endif
memcpy(sReceiveFrame.mPsdu, rxPacketInfo->dataPtr + 1, rxPacketInfo->dataLength);
sReceiveFrame.mRssi = rxPacketInfo->appendedInfo.rssiLatch;
sReceiveFrame.mLqi = rxPacketInfo->appendedInfo.lqi;
sReceiveFrame.mLength = length;
sReceiveError = OT_ERROR_NONE;
exit:
return;
}
void efr32RadioProcess(otInstance *aInstance)
{
// ensure process would not be broken by
// the incoming interrupt with higher priority
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
if ((sState == OT_RADIO_STATE_RECEIVE && sReceiveFrame.mLength > 0) ||
(sState == OT_RADIO_STATE_TRANSMIT && sReceiveFrame.mLength > IEEE802154_ACK_LENGTH))
if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false)
{
if (sTransmitError != OT_ERROR_NONE)
{
otLogDebgPlat(sInstance, "Transmit failed ErrorCode=%d", sTransmitError);
}
sState = OT_RADIO_STATE_RECEIVE;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, sTransmitError);
}
else
#endif
{
// signal MAC layer for each received frame if promiscous is enabled
// otherwise only signal MAC layer for non-ACK frame
if (sPromiscuous || sReceiveFrame.mLength > IEEE802154_ACK_LENGTH)
{
otLogInfoPlat(sInstance, "Received %d bytes", sReceiveFrame.mLength);
otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
}
otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, sTransmitError);
}
}
if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false)
{
if (sTransmitError != OT_ERROR_NONE || (sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
{
if (sTransmitError != OT_ERROR_NONE)
{
otLogDebgPlat(sInstance, "Transmit failed ErrorCode=%d", sTransmitError);
}
sState = OT_RADIO_STATE_RECEIVE;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, sTransmitError);
}
else
#endif
{
otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, sTransmitError);
}
}
else if (sReceiveFrame.mLength == IEEE802154_ACK_LENGTH &&
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK &&
(sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET]))
{
sState = OT_RADIO_STATE_RECEIVE;
otLogInfoPlat(sInstance, "Received ACK:%d", sReceiveFrame.mLength);
otPlatRadioTxDone(aInstance, &sTransmitFrame, &sReceiveFrame, sTransmitError);
}
}
sReceiveFrame.mLength = 0;
CORE_EXIT_CRITICAL();
}
void RAILCb_RxAckTimeout(void)
{
sTransmitError = OT_ERROR_NO_ACK;
}
void RAILCb_RfReady(void)
{
}
void RAILCb_CalNeeded(void)
{
}
void RAILCb_RxRadioStatus(uint8_t aStatus)
{
(void)aStatus;
}
void RAILCb_RadioStateChanged(uint8_t aState)
{
(void)aState;
}
void RAILCb_RssiAverageDone(int16_t avgRssi)
{
(void)avgRssi;
}
void RAILCb_RxFifoAlmostFull(uint16_t aBytesAvailable)
{
(void)aBytesAvailable;
}
void RAILCb_TxFifoAlmostEmpty(uint16_t aSpaceAvailable)
{
(void)aSpaceAvailable;
}
void *RAILCb_AllocateMemory(uint32_t aSize)
{
uint8_t *pointer = NULL;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT(aSize <= (IEEE802154_MAX_LENGTH + 1 + sizeof(RAIL_RxPacketInfo_t)));
pointer = sReceiveBuffer;
exit:
CORE_EXIT_CRITICAL();
return pointer;
}
void *RAILCb_BeginWriteMemory(void *aHandle, uint32_t aOffset,
uint32_t *available)
{
(void)available;
return ((uint8_t *)aHandle) + aOffset;
}
void RAILCb_EndWriteMemory(void *aHandle, uint32_t aOffset, uint32_t aSize)
{
(void)aHandle;
(void)aOffset;
(void)aSize;
}
void RAILCb_FreeMemory(void *aHandle)
{
(void)aHandle;
processNextRxPacket(aInstance, sRailHandle);
}
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
@@ -849,7 +842,7 @@ otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
(void)aInstance;
otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS);
*aPower = (int8_t)(RAIL_TxPowerGet() / 10);
*aPower = (int8_t)(RAIL_GetTxPowerDbm(sRailHandle) / 10);
exit:
return error;
@@ -857,8 +850,11 @@ exit:
otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
RAIL_Status_t status;
(void)aInstance;
RAIL_TxPowerSet(((int32_t)aPower) * 10);
status = RAIL_SetTxPowerDbm(sRailHandle, ((RAIL_TxPower_t)aPower) * 10);
assert(status == RAIL_STATUS_NO_ERROR);
return OT_ERROR_NONE;
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef __RAIL_CONFIG_H__
#define __RAIL_CONFIG_H__
#include <stdint.h>
#include "rail_types.h"
#define RADIO_CONFIG_XTAL_FREQUENCY 38400000UL
#endif // __RAIL_CONFIG_H__
+99 -109
View File
@@ -39,99 +39,127 @@
#include "utils/code_utils.h"
#include "bspconfig.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "em_core.h"
#include "uartdrv.h"
#include "retargetserialhalconfig.h"
enum
{
kPlatformClock = 32000000,
kBaudRate = 115200,
kReceiveBufferSize = 128,
kReceiveFifoSize = 128,
};
static void processReceive(void);
static void processTransmit(void);
#define USART_INIT \
{ \
RETARGET_UART, /* USART port */ \
115200, /* Baud rate */ \
RETARGET_TX_LOCATION, /* USART Tx pin location number */ \
RETARGET_RX_LOCATION, /* USART Rx pin location number */ \
(USART_Stopbits_TypeDef)USART_FRAME_STOPBITS_ONE, /* Stop bits */ \
(USART_Parity_TypeDef)USART_FRAME_PARITY_NONE, /* Parity */ \
(USART_OVS_TypeDef)USART_CTRL_OVS_X16, /* Oversampling mode*/ \
false, /* Majority vote disable */ \
uartdrvFlowControlHwUart, /* Flow control */ \
RETARGET_CTSPORT, /* CTS port number */ \
RETARGET_CTSPIN, /* CTS pin number */ \
RETARGET_RTSPORT, /* RTS port number */ \
RETARGET_RTSPIN, /* RTS pin number */ \
(UARTDRV_Buffer_FifoQueue_t *)&sUartRxQueue, /* RX operation queue */ \
(UARTDRV_Buffer_FifoQueue_t *)&sUartTxQueue, /* TX operation queue */ \
RETARGET_CTS_LOCATION, /* CTS location */ \
RETARGET_RTS_LOCATION /* RTS location */ \
}
static const uint8_t *sTransmitBuffer = NULL;
static uint16_t sTransmitLength = 0;
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS, sUartRxQueue);
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS, sUartTxQueue);
typedef struct RecvBuffer
static UARTDRV_HandleData_t sUartHandleData;
static UARTDRV_Handle_t sUartHandle = &sUartHandleData;
static uint8_t sReceiveBuffer[2];
static const uint8_t *sTransmitBuffer = NULL;
static uint16_t sTransmitLength = 0;
typedef struct ReceiveFifo_t
{
// The data buffer
uint8_t mBuffer[kReceiveBufferSize];
uint8_t mBuffer[kReceiveFifoSize];
// The offset of the first item written to the list.
uint16_t mHead;
// The offset of the next item to be written to the list.
uint16_t mTail;
} RecvBuffer;
} ReceiveFifo_t;
static RecvBuffer sReceive;
static ReceiveFifo_t sReceiveFifo;
static void processReceive(void);
static void receiveDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
{
// We can only write if incrementing mTail doesn't equal mHead
if (sReceiveFifo.mHead != (sReceiveFifo.mTail + 1) % kReceiveFifoSize)
{
sReceiveFifo.mBuffer[sReceiveFifo.mTail] = aData[0];
sReceiveFifo.mTail = (sReceiveFifo.mTail + 1) % kReceiveFifoSize;
}
UARTDRV_Receive(aHandle, aData, 1, receiveDone);
}
static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
{
sTransmitLength = 0;
}
static void processReceive(void)
{
// Copy tail to prevent multiple reads
uint16_t tail = sReceiveFifo.mTail;
// If the data wraps around, process the first part
if (sReceiveFifo.mHead > tail)
{
otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, kReceiveFifoSize - sReceiveFifo.mHead);
// Reset the buffer mHead back to zero.
sReceiveFifo.mHead = 0;
}
// For any data remaining, process it
if (sReceiveFifo.mHead != tail)
{
otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, tail - sReceiveFifo.mHead);
// Set mHead to the local tail we have cached
sReceiveFifo.mHead = tail;
}
}
static void processTransmit(void)
{
if (sTransmitBuffer != NULL && sTransmitLength == 0)
{
sTransmitBuffer = NULL;
otPlatUartSendDone();
}
}
otError otPlatUartEnable(void)
{
USART_TypeDef *usart = USART0;
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
UARTDRV_Init_t uartInit = USART_INIT;
sReceive.mHead = 0;
sReceive.mTail = 0;
sReceiveFifo.mHead = 0;
sReceiveFifo.mTail = 0;
/* Enable peripheral clocks */
CMU_ClockEnable(cmuClock_HFPER, true);
/* Configure GPIO pins */
CMU_ClockEnable(cmuClock_GPIO, true);
UARTDRV_Init(sUartHandle, &uartInit);
/* Configure GPIO pin for UART TX */
/* To avoid false start, configure output as high. */
GPIO_PinModeSet(BSP_BCC_TXPORT, BSP_BCC_TXPIN, gpioModePushPull, 1u);
/* Configure GPIO pin for UART RX */
GPIO_PinModeSet(BSP_BCC_RXPORT, BSP_BCC_RXPIN, gpioModeInput, 1u);
/* Enable the switch that enables UART communication. */
GPIO_PinModeSet(BSP_BCC_ENABLE_PORT, BSP_BCC_ENABLE_PIN, gpioModePushPull, 1u);
CMU_ClockEnable(cmuClock_USART0, true);
/* Configure USART for basic async operation */
init.enable = usartDisable;
USART_InitAsync(usart, &init);
/* Enable pins at correct UART/USART location. */
usart->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN;
usart->ROUTELOC0 = (usart->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK))
| (_USART_ROUTELOC0_TXLOC_LOC0 << _USART_ROUTELOC0_TXLOC_SHIFT)
| (_USART_ROUTELOC0_RXLOC_LOC0 << _USART_ROUTELOC0_RXLOC_SHIFT);
/* Clear previous RX interrupts */
USART_IntClear(usart, USART_IF_RXDATAV);
NVIC_ClearPendingIRQ(USART0_RX_IRQn);
/* Enable RX interrupts */
USART_IntEnable(usart, USART_IF_RXDATAV);
NVIC_EnableIRQ(USART0_RX_IRQn);
/* Finally enable it */
USART_Enable(usart, usartEnable);
for (uint8_t i = 0; i < sizeof(sReceiveBuffer); i++)
{
UARTDRV_Receive(sUartHandle, &sReceiveBuffer[i], sizeof(sReceiveBuffer[i]), receiveDone);
}
return OT_ERROR_NONE;
}
void USART0_RX_IRQHandler(void)
{
if (USART0->STATUS & USART_STATUS_RXDATAV)
{
uint8_t byte = USART_Rx(USART0);
// We can only write if incrementing mTail doesn't equal mHead
if (sReceive.mHead != (sReceive.mTail + 1) % kReceiveBufferSize)
{
sReceive.mBuffer[sReceive.mTail] = byte;
sReceive.mTail = (sReceive.mTail + 1) % kReceiveBufferSize;
}
}
}
otError otPlatUartDisable(void)
{
return OT_ERROR_NOT_IMPLEMENTED;
@@ -146,50 +174,12 @@ otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
sTransmitBuffer = aBuf;
sTransmitLength = aBufLength;
UARTDRV_Transmit(sUartHandle, (uint8_t *)sTransmitBuffer, sTransmitLength, transmitDone);
exit:
return error;
}
void processReceive(void)
{
// Copy tail to prevent multiple reads
uint16_t tail = sReceive.mTail;
// If the data wraps around, process the first part
if (sReceive.mHead > tail)
{
otPlatUartReceived(sReceive.mBuffer + sReceive.mHead, kReceiveBufferSize - sReceive.mHead);
// Reset the buffer mHead back to zero.
sReceive.mHead = 0;
}
// For any data remaining, process it
if (sReceive.mHead != tail)
{
otPlatUartReceived(sReceive.mBuffer + sReceive.mHead, tail - sReceive.mHead);
// Set mHead to the local tail we have cached
sReceive.mHead = tail;
}
}
void processTransmit(void)
{
otEXPECT(sTransmitBuffer != NULL);
for (; sTransmitLength > 0; sTransmitLength--)
{
USART_Tx(USART0, *sTransmitBuffer++);
}
sTransmitBuffer = NULL;
otPlatUartSendDone();
exit:
return;
}
void efr32UartProcess(void)
{
processReceive();
+4 -3
View File
@@ -50,7 +50,8 @@ libmbedcrypto_a_SOURCES = \
if OPENTHREAD_EXAMPLES_EFR32
nodist_libmbedcrypto_a_SOURCES = \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/util/third_party/mbedtls/sl_crypto/src/sl_aes.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/util/third_party/mbedtls/sl_crypto/src/crypto_aes.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/util/third_party/mbedtls/sl_crypto/src/crypto_management.c \
$(NULL)
else
libmbedcrypto_a_SOURCES += \
@@ -81,8 +82,8 @@ libmbedcrypto_a_SOURCES += \
if OPENTHREAD_EXAMPLES_EFR32
nodist_libmbedcrypto_a_SOURCES += \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/util/third_party/mbedtls/library/ecp.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.1/util/third_party/mbedtls/sl_crypto/src/sl_ecp.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/util/third_party/mbedtls/library/ecp.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.0/util/third_party/mbedtls/sl_crypto/src/crypto_ecp.c \
$(NULL)
else
libmbedcrypto_a_SOURCES += \