From e668f0cc3ef79370966095a230241cfcbfdceb4d Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Tue, 9 Jan 2018 17:47:01 +0000 Subject: [PATCH] [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. --- examples/Makefile-efr32 | 10 +- examples/platforms/efr32/Makefile.am | 56 +- examples/platforms/efr32/Makefile.platform.am | 4 +- examples/platforms/efr32/README.md | 4 +- .../efr32/crypto/efr32-mbedtls-config.h | 1 + examples/platforms/efr32/hal-config.h | 388 ++++++++++ .../efr32/openthread-core-efr32-config.h | 16 +- examples/platforms/efr32/platform.c | 81 +-- examples/platforms/efr32/radio.c | 676 +++++++++--------- examples/platforms/efr32/rail_config.h | 9 + examples/platforms/efr32/uart.c | 208 +++--- third_party/mbedtls/Makefile.am | 7 +- 12 files changed, 893 insertions(+), 567 deletions(-) create mode 100644 examples/platforms/efr32/hal-config.h create mode 100644 examples/platforms/efr32/rail_config.h diff --git a/examples/Makefile-efr32 b/examples/Makefile-efr32 index 9f451e9d1..94a0f68ce 100644 --- a/examples/Makefile-efr32 +++ b/examples/Makefile-efr32 @@ -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 diff --git a/examples/platforms/efr32/Makefile.am b/examples/platforms/efr32/Makefile.am index 648407100..9d2e6663a 100644 --- a/examples/platforms/efr32/Makefile.am +++ b/examples/platforms/efr32/Makefile.am @@ -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 = \ diff --git a/examples/platforms/efr32/Makefile.platform.am b/examples/platforms/efr32/Makefile.platform.am index 066e9b77a..c2ecbae4e 100644 --- a/examples/platforms/efr32/Makefile.platform.am +++ b/examples/platforms/efr32/Makefile.platform.am @@ -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) diff --git a/examples/platforms/efr32/README.md b/examples/platforms/efr32/README.md index 6e8f2e309..3ac347cfa 100644 --- a/examples/platforms/efr32/README.md +++ b/examples/platforms/efr32/README.md @@ -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 diff --git a/examples/platforms/efr32/crypto/efr32-mbedtls-config.h b/examples/platforms/efr32/crypto/efr32-mbedtls-config.h index 00093a047..80ad4a07c 100644 --- a/examples/platforms/efr32/crypto/efr32-mbedtls-config.h +++ b/examples/platforms/efr32/crypto/efr32-mbedtls-config.h @@ -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 diff --git a/examples/platforms/efr32/hal-config.h b/examples/platforms/efr32/hal-config.h new file mode 100644 index 000000000..456c7cb34 --- /dev/null +++ b/examples/platforms/efr32/hal-config.h @@ -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 */ + diff --git a/examples/platforms/efr32/openthread-core-efr32-config.h b/examples/platforms/efr32/openthread-core-efr32-config.h index aa64191b7..6582a8afc 100644 --- a/examples/platforms/efr32/openthread-core-efr32-config.h +++ b/examples/platforms/efr32/openthread-core-efr32-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_ diff --git a/examples/platforms/efr32/platform.c b/examples/platforms/efr32/platform.c index d0f6e11bc..d3c452cf4 100644 --- a/examples/platforms/efr32/platform.c +++ b/examples/platforms/efr32/platform.c @@ -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(); -} diff --git a/examples/platforms/efr32/radio.c b/examples/platforms/efr32/radio.c index eff19fc06..fc27c58a8 100644 --- a/examples/platforms/efr32/radio.c +++ b/examples/platforms/efr32/radio.c @@ -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; } diff --git a/examples/platforms/efr32/rail_config.h b/examples/platforms/efr32/rail_config.h new file mode 100644 index 000000000..8b643556c --- /dev/null +++ b/examples/platforms/efr32/rail_config.h @@ -0,0 +1,9 @@ +#ifndef __RAIL_CONFIG_H__ +#define __RAIL_CONFIG_H__ + +#include +#include "rail_types.h" + +#define RADIO_CONFIG_XTAL_FREQUENCY 38400000UL + +#endif // __RAIL_CONFIG_H__ diff --git a/examples/platforms/efr32/uart.c b/examples/platforms/efr32/uart.c index f2642556f..ac91dee4d 100644 --- a/examples/platforms/efr32/uart.c +++ b/examples/platforms/efr32/uart.c @@ -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(); diff --git a/third_party/mbedtls/Makefile.am b/third_party/mbedtls/Makefile.am index 71f85017b..d5447305e 100644 --- a/third_party/mbedtls/Makefile.am +++ b/third_party/mbedtls/Makefile.am @@ -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 += \