From 6fa97e98784a60e088d7c2c5a1c216abc5a74b69 Mon Sep 17 00:00:00 2001 From: Mason Tran Date: Wed, 10 Feb 2021 13:55:24 -0500 Subject: [PATCH] [efr32] update for compatibility with Gecko SDK 3.1.1 (#6154) This commit updates the EFR32 platform-abstraction layer to work with GSDK 3.1.1. - memory.c - Implemented otPlatCAlloc() and otPlatFree() to handle #6123 - GSDK mbedtls was updated and moved to util/third_party/crypto/mbedtls - mbedtls_config_autogen.h was regenerated - system.c - NVIC initialization is now done via a simple call to sl_device_init_nvic() - alarm.c - Stubs for 1.2 related platform timing functions in alarm.c - ieee802154mac.h - Standardization of 802.15.4 header values and constants - uart.c - Reduce the number of vulnerable windows where interrupts disabled by RAIL will cause dropped characters. The OpenThread task now polls the UART buffer for arrived data and reads it out. The USART0 IRQ handler takes care of waking up the task when data has arrived. - radio.c - Implementation of Wi-Fi coexistence and antenna diversity features, and corresponding updates to run-time phy select configurations. - Support for enhanced frame pending and early frame pending for Thread 1.2 low power features (temporarily disabled until 1.2 support is available) - Implementation of enhanced ACKs with IEs for CSL. - Remove FIFO queue that was maintaining unique identifiers (contents of received packet: PHR+MAC header) This was being used to tell the upper MAC whether the frame pending bit was set in an ACK for a received packet. Changed the implementation so we save the state to a reserved bit in the held packet (in the MAC header) within the receive completion ISR, and retrieve the value in processNextRxPacket() to pass to where the upper MAC expects it. --- examples/Makefile-efr32mg1 | 22 +- examples/Makefile-efr32mg12 | 38 +- examples/Makefile-efr32mg13 | 40 +- examples/Makefile-efr32mg21 | 40 +- examples/platforms/efr32/Makefile.platform.am | 2 +- .../platforms/efr32/efr32_platform_defs.am | 10 +- .../efr32/efr32mg1/Makefile.platform.am | 2 +- examples/platforms/efr32/efr32mg1/README.md | 6 +- .../efr32mg1/crypto/mbedtls_config_autogen.h | 12 +- .../efr32/efr32mg12/Makefile.platform.am | 2 +- examples/platforms/efr32/efr32mg12/README.md | 6 +- .../efr32mg12/crypto/mbedtls_config_autogen.h | 15 +- .../efr32/efr32mg13/Makefile.platform.am | 2 +- examples/platforms/efr32/efr32mg13/README.md | 6 +- .../efr32mg13/crypto/mbedtls_config_autogen.h | 16 +- .../efr32/efr32mg21/Makefile.platform.am | 2 +- examples/platforms/efr32/efr32mg21/README.md | 6 +- .../efr32mg21/crypto/mbedtls_config_autogen.h | 12 +- examples/platforms/efr32/src/alarm.c | 21 + examples/platforms/efr32/src/ieee802154mac.h | 194 ++ examples/platforms/efr32/src/memory.c | 46 + .../efr32/src/openthread-core-efr32-config.h | 40 +- examples/platforms/efr32/src/radio.c | 2645 +++++++++++++---- examples/platforms/efr32/src/system.c | 17 +- examples/platforms/efr32/src/uart.c | 61 +- third_party/silabs/Makefile.am | 323 +- 26 files changed, 2728 insertions(+), 858 deletions(-) create mode 100644 examples/platforms/efr32/src/ieee802154mac.h create mode 100644 examples/platforms/efr32/src/memory.c diff --git a/examples/Makefile-efr32mg1 b/examples/Makefile-efr32mg1 index 4fc7590f9..705afe3ba 100644 --- a/examples/Makefile-efr32mg1 +++ b/examples/Makefile-efr32mg1 @@ -73,15 +73,19 @@ EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls_config.h\"' EFR32_MBEDTLS_CPPFLAGS += -D$(MCU) EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/src EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/$(PLATFORM_LOWERCASE)/crypto -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/configs -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include/mbedtls -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/CMSIS/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG1P/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emlib/inc -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/radio/rail_lib/chip/efr32/efr32xg1x -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/silicon_labs/silabs_core/memory_manager +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include/mbedtls +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/config +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc/configs +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/CMSIS/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG1P/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emlib/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/radio/rail_lib/chip/efr32/efr32xg1x +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/silicon_labs/silabs_core/memory_manager CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32/ HAL_CONF_DIR = $(CONFIG_FILE_PATH)/$(EFR32_PLATFORM)/$(BOARD_LOWERCASE) diff --git a/examples/Makefile-efr32mg12 b/examples/Makefile-efr32mg12 index 02a8d3b32..16461a2e9 100644 --- a/examples/Makefile-efr32mg12 +++ b/examples/Makefile-efr32mg12 @@ -43,14 +43,14 @@ EFR32_PLATFORM = efr32mg12 PLATFORM_LOWERCASE = $(shell echo $(EFR32_PLATFORM) | tr A-Z a-z) BOARD_LOWERCASE = $(shell echo $(BOARD) | tr A-Z a-z) -configure_OPTIONS = \ - --enable-cli \ - --enable-ftd \ - --enable-mtd \ - --enable-ncp \ - --enable-radio-only \ - --enable-linker-map \ - --enable-builtin-mbedtls=no \ +configure_OPTIONS = \ + --enable-cli \ + --enable-ftd \ + --enable-mtd \ + --enable-ncp \ + --enable-radio-only \ + --enable-linker-map \ + --enable-builtin-mbedtls=no \ --with-examples=$(EFR32_PLATFORM) \ MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)" \ $(NULL) @@ -91,15 +91,19 @@ EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls_config.h\"' EFR32_MBEDTLS_CPPFLAGS += -D$(MCU) EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/src EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/$(PLATFORM_LOWERCASE)/crypto -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/configs -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include/mbedtls -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/CMSIS/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG12P/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emlib/inc -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/radio/rail_lib/chip/efr32/efr32xg1x -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/silicon_labs/silabs_core/memory_manager +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include/mbedtls +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/config +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc/configs +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/CMSIS/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG12P/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emlib/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/radio/rail_lib/chip/efr32/efr32xg1x +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/silicon_labs/silabs_core/memory_manager CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32/ HAL_CONF_DIR = $(CONFIG_FILE_PATH)/$(EFR32_PLATFORM)/$(BOARD_LOWERCASE) diff --git a/examples/Makefile-efr32mg13 b/examples/Makefile-efr32mg13 index 00828d9cf..5cbcc93a4 100644 --- a/examples/Makefile-efr32mg13 +++ b/examples/Makefile-efr32mg13 @@ -43,14 +43,14 @@ EFR32_PLATFORM = efr32mg13 PLATFORM_LOWERCASE = $(shell echo $(EFR32_PLATFORM) | tr A-Z a-z) BOARD_LOWERCASE = $(shell echo $(BOARD) | tr A-Z a-z) -configure_OPTIONS = \ - --enable-cli \ - --enable-ftd \ - --enable-mtd \ - --enable-ncp \ - --enable-radio-only \ - --enable-linker-map \ - --enable-builtin-mbedtls=no \ +configure_OPTIONS = \ + --enable-cli \ + --enable-ftd \ + --enable-mtd \ + --enable-ncp \ + --enable-radio-only \ + --enable-linker-map \ + --enable-builtin-mbedtls=no \ --with-examples=$(EFR32_PLATFORM) \ MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)" \ $(NULL) @@ -76,16 +76,20 @@ endif EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls_config.h\"' EFR32_MBEDTLS_CPPFLAGS += -D$(MCU) EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/src -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/efr32mg13/crypto -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/configs -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include/mbedtls -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/CMSIS/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG13P/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emlib/inc -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/radio/rail_lib/chip/efr32/efr32xg1x -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/silicon_labs/silabs_core/memory_manager +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/$(PLATFORM_LOWERCASE)/crypto +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include/mbedtls +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/config +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc/configs +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/CMSIS/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG13P/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emlib/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/radio/rail_lib/chip/efr32/efr32xg1x +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/silicon_labs/silabs_core/memory_manager CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32/ HAL_CONF_DIR = $(CONFIG_FILE_PATH)/$(EFR32_PLATFORM)/$(BOARD_LOWERCASE) diff --git a/examples/Makefile-efr32mg21 b/examples/Makefile-efr32mg21 index c2987aa33..80db2a686 100644 --- a/examples/Makefile-efr32mg21 +++ b/examples/Makefile-efr32mg21 @@ -43,14 +43,14 @@ EFR32_PLATFORM = efr32mg21 PLATFORM_LOWERCASE = $(shell echo $(EFR32_PLATFORM) | tr A-Z a-z) BOARD_LOWERCASE = $(shell echo $(BOARD) | tr A-Z a-z) -configure_OPTIONS = \ - --enable-cli \ - --enable-ftd \ - --enable-mtd \ - --enable-ncp \ - --enable-radio-only \ - --enable-linker-map \ - --enable-builtin-mbedtls=no \ +configure_OPTIONS = \ + --enable-cli \ + --enable-ftd \ + --enable-mtd \ + --enable-ncp \ + --enable-radio-only \ + --enable-linker-map \ + --enable-builtin-mbedtls=no \ --with-examples=$(EFR32_PLATFORM) \ MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)" \ $(NULL) @@ -81,15 +81,21 @@ EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls_config.h\"' EFR32_MBEDTLS_CPPFLAGS += -D$(MCU) EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/src EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/$(PLATFORM_LOWERCASE)/crypto -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/configs -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/include/mbedtls -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/CMSIS/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG21/Include -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emlib/inc -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/radio/rail_lib/chip/efr32/efr32xg2x -EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.0/util/silicon_labs/silabs_core/memory_manager +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/include/mbedtls +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/config +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/inc/configs +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/CMSIS/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG21/Include +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emlib/inc +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/radio/rail_lib/chip/efr32/efr32xg2x +EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v3.1/util/silicon_labs/silabs_core/memory_manager EFR32_MBEDTLS_CPPFLAGS += -Wno-unused-function EFR32_MBEDTLS_CPPFLAGS += -Wno-unused-parameter diff --git a/examples/platforms/efr32/Makefile.platform.am b/examples/platforms/efr32/Makefile.platform.am index 1d53802c4..b1a4afba9 100644 --- a/examples/platforms/efr32/Makefile.platform.am +++ b/examples/platforms/efr32/Makefile.platform.am @@ -55,7 +55,7 @@ fi; ) LDADD_COMMON += \ $(top_builddir)/examples/platforms/efr32/libopenthread-$(PLATFORM_LOWERCASE).a \ $(top_builddir)/third_party/silabs/libsilabs-$(PLATFORM_LOWERCASE)-sdk.a \ - $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \ + $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/radio/rail_lib/autogen/librail_release/$(LIBRAIL) \ $(NULL) LDFLAGS_COMMON += \ diff --git a/examples/platforms/efr32/efr32_platform_defs.am b/examples/platforms/efr32/efr32_platform_defs.am index 68d7da63b..223a08b3b 100644 --- a/examples/platforms/efr32/efr32_platform_defs.am +++ b/examples/platforms/efr32/efr32_platform_defs.am @@ -30,7 +30,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am # ============================================================================== # General variables # ============================================================================== -SDK_SRC_DIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.0 +SDK_SRC_DIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.1 EFR32_PLATFORM = $(subst /,,$(exec_prefix)) # NOTE: This is a work-around that sets EFR32_PLATFORM to the correct platform name. @@ -67,6 +67,8 @@ override CXXFLAGS := $(filter-out -Wundef,$(CXXFLAGS)) # ============================================================================== SILABS_GSDK_CPPFLAGS = \ -I$(SDK_SRC_DIR) \ + -I$(SDK_SRC_DIR)/hardware/board/config/$(BOARD_LOWERCASE)_brd4001a \ + -I$(SDK_SRC_DIR)/hardware/board/config/$(BOARD_LOWERCASE) \ -I$(SDK_SRC_DIR)/hardware/kit/$(PLATFORM_UPPERCASE)_$(BOARD_UPPERCASE)/config \ -I$(SDK_SRC_DIR)/hardware/kit/common/bsp \ -I$(SDK_SRC_DIR)/hardware/kit/common/drivers \ @@ -98,9 +100,6 @@ SILABS_GSDK_CPPFLAGS = -I$(SDK_SRC_DIR)/platform/service/sleeptimer/config \ -I$(SDK_SRC_DIR)/platform/service/sleeptimer/inc \ -I$(SDK_SRC_DIR)/util/plugin/plugin-common/fem-control \ - -I$(SDK_SRC_DIR)/util/third_party/mbedtls/configs \ - -I$(SDK_SRC_DIR)/util/third_party/mbedtls/include \ - -I$(SDK_SRC_DIR)/util/third_party/mbedtls/sl_crypto/include \ $(NULL) @@ -117,6 +116,8 @@ SILABS_EFR32MG2X_CPPFLAGS = -I$(SDK_SRC_DIR)/platform/emdrv/nvm3/config/s2 \ -I$(SDK_SRC_DIR)/platform/radio/rail_lib/chip/efr32/efr32xg2x \ -I$(SDK_SRC_DIR)/platform/radio/rail_lib/plugin/pa-conversions/efr32xg21/config \ + -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/se_manager/inc \ + -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/se_manager/src \ $(NULL) @@ -130,6 +131,7 @@ PLATFORM_COMMON_SOURCES_LIST = src/fem-control.c \ src/flash.c \ src/logging.c \ + src/memory.c \ src/misc.c \ src/openthread-core-efr32-config-check.h \ src/openthread-core-efr32-config.h \ diff --git a/examples/platforms/efr32/efr32mg1/Makefile.platform.am b/examples/platforms/efr32/efr32mg1/Makefile.platform.am index c3977f3d0..22912f675 100644 --- a/examples/platforms/efr32/efr32mg1/Makefile.platform.am +++ b/examples/platforms/efr32/efr32mg1/Makefile.platform.am @@ -31,5 +31,5 @@ # LDADD_COMMON += \ - $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \ + $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \ $(NULL) diff --git a/examples/platforms/efr32/efr32mg1/README.md b/examples/platforms/efr32/efr32mg1/README.md index 0aa543e05..e4af6401a 100644 --- a/examples/platforms/efr32/efr32mg1/README.md +++ b/examples/platforms/efr32/efr32mg1/README.md @@ -28,8 +28,8 @@ $ ./script/bootstrap 2. Install Flex (Gecko) SDK including RAIL Library from Simplicity Studio. - Connect EFR32MG1P Wireless Starter Kit to Simplicity Studio. - - Find Flex SDK v3.0 in the Software Update page and click Install. - - Flex SDK v3.0 will be installed in the path: + - Find Flex SDK v3.1 in the Software Update page and click Install. + - Flex SDK v3.1 will be installed in the path: - Mac - `/Applications/Simplicity\ Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite` - Windows @@ -244,4 +244,4 @@ The following toolchain has been used for testing and verification: The EFR32 example has been verified with following Flex SDK/RAIL Library version: -- Flex SDK version 3.0.x +- Flex SDK v3.1.x diff --git a/examples/platforms/efr32/efr32mg1/crypto/mbedtls_config_autogen.h b/examples/platforms/efr32/efr32mg1/crypto/mbedtls_config_autogen.h index 0104fdfcd..5f839fd1f 100644 --- a/examples/platforms/efr32/efr32mg1/crypto/mbedtls_config_autogen.h +++ b/examples/platforms/efr32/efr32mg1/crypto/mbedtls_config_autogen.h @@ -24,10 +24,10 @@ #define MBEDTLS_ECP_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_ECDH_C +#define MBEDTLS_ECDH_LEGACY_CONTEXT #define MBEDTLS_ECDSA_C #define MBEDTLS_ENTROPY_ADC_C -#define MBEDTLS_ENTROPY_RAIL_C -#define MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL +#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_MD_C #define MBEDTLS_ECJPAKE_C #define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED @@ -37,14 +37,12 @@ #define MBEDTLS_ENTROPY_FORCE_SHA256 #define MBEDTLS_ENTROPY_MAX_SOURCES 2 #define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_SHA1_C #define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C #define MBEDTLS_SSL_TLS_C #define MBEDTLS_SSL_CLI_C #define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE #define MBEDTLS_SSL_SRV_C #define MBEDTLS_X509_USE_C #define MBEDTLS_X509_CRT_PARSE_C @@ -53,13 +51,17 @@ #define MBEDTLS_OID_C #define MBEDTLS_PK_C #define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PSA_CRYPTO_DRIVERS #include "config-device-acceleration.h" +#if !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) #include "sl_malloc.h" #define MBEDTLS_PLATFORM_FREE_MACRO sl_free #define MBEDTLS_PLATFORM_CALLOC_MACRO sl_calloc +#endif + #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_PLATFORM_C diff --git a/examples/platforms/efr32/efr32mg12/Makefile.platform.am b/examples/platforms/efr32/efr32mg12/Makefile.platform.am index 3b4799aab..df29d3f8e 100644 --- a/examples/platforms/efr32/efr32mg12/Makefile.platform.am +++ b/examples/platforms/efr32/efr32mg12/Makefile.platform.am @@ -31,5 +31,5 @@ # LDADD_COMMON += \ - $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \ + $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \ $(NULL) diff --git a/examples/platforms/efr32/efr32mg12/README.md b/examples/platforms/efr32/efr32mg12/README.md index 1facf1fa7..25bd53ed0 100644 --- a/examples/platforms/efr32/efr32mg12/README.md +++ b/examples/platforms/efr32/efr32mg12/README.md @@ -33,8 +33,8 @@ $ ./script/bootstrap 2. Install Flex (Gecko) SDK including RAIL Library from Simplicity Studio. - Connect EFR32MG12P Wireless Starter Kit to Simplicity Studio. - - Find Flex SDK v3.0 in the Software Update page and click Install. - - Flex SDK v3.0 will be installed in the path: + - Find Flex SDK v3.1 in the Software Update page and click Install. + - Flex SDK v3.1 will be installed in the path: - Mac - `/Applications/Simplicity\ Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite` - Windows @@ -257,4 +257,4 @@ The following toolchain has been used for testing and verification: The EFR32 example has been verified with following Flex SDK/RAIL Library version: -- Flex SDK version 3.0.x +- Flex SDK v3.1.x diff --git a/examples/platforms/efr32/efr32mg12/crypto/mbedtls_config_autogen.h b/examples/platforms/efr32/efr32mg12/crypto/mbedtls_config_autogen.h index 42240ccc7..5f839fd1f 100644 --- a/examples/platforms/efr32/efr32mg12/crypto/mbedtls_config_autogen.h +++ b/examples/platforms/efr32/efr32mg12/crypto/mbedtls_config_autogen.h @@ -24,9 +24,10 @@ #define MBEDTLS_ECP_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_ECDH_C +#define MBEDTLS_ECDH_LEGACY_CONTEXT #define MBEDTLS_ECDSA_C #define MBEDTLS_ENTROPY_ADC_C -#define MBEDTLS_ENTROPY_RAIL_C +#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_MD_C #define MBEDTLS_ECJPAKE_C #define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED @@ -36,14 +37,12 @@ #define MBEDTLS_ENTROPY_FORCE_SHA256 #define MBEDTLS_ENTROPY_MAX_SOURCES 2 #define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_SHA1_C #define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C #define MBEDTLS_SSL_TLS_C #define MBEDTLS_SSL_CLI_C #define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE #define MBEDTLS_SSL_SRV_C #define MBEDTLS_X509_USE_C #define MBEDTLS_X509_CRT_PARSE_C @@ -52,17 +51,17 @@ #define MBEDTLS_OID_C #define MBEDTLS_PK_C #define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PSA_CRYPTO_DRIVERS #include "config-device-acceleration.h" -#if defined(MBEDTLS_TRNG_PRESENT) -#define MBEDTLS_TRNG_C -#endif - +#if !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) #include "sl_malloc.h" #define MBEDTLS_PLATFORM_FREE_MACRO sl_free #define MBEDTLS_PLATFORM_CALLOC_MACRO sl_calloc +#endif + #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_PLATFORM_C diff --git a/examples/platforms/efr32/efr32mg13/Makefile.platform.am b/examples/platforms/efr32/efr32mg13/Makefile.platform.am index 47b48a4b7..f45ce083e 100644 --- a/examples/platforms/efr32/efr32mg13/Makefile.platform.am +++ b/examples/platforms/efr32/efr32mg13/Makefile.platform.am @@ -31,5 +31,5 @@ # LDADD_COMMON += \ - $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \ + $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a \ $(NULL) diff --git a/examples/platforms/efr32/efr32mg13/README.md b/examples/platforms/efr32/efr32mg13/README.md index d38af3f97..eace8e906 100644 --- a/examples/platforms/efr32/efr32mg13/README.md +++ b/examples/platforms/efr32/efr32mg13/README.md @@ -32,8 +32,8 @@ $ ./script/bootstrap 2. Install Flex (Gecko) SDK including RAIL Library from Simplicity Studio. - Connect EFR32MG13P Wireless Starter Kit to Simplicity Studio. - - Find Flex SDK v3.0 in the Software Update page and click Install. - - Flex SDK v3.0 will be installed in the path: + - Find Flex SDK v3.1 in the Software Update page and click Install. + - Flex SDK v3.1 will be installed in the path: - Mac - `/Applications/Simplicity\ Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite` - Windows @@ -250,4 +250,4 @@ The following toolchain has been used for testing and verification: The EFR32 example has been verified with following Flex SDK/RAIL Library version: -- Flex SDK version 3.0.x +- Flex SDK v3.1.x diff --git a/examples/platforms/efr32/efr32mg13/crypto/mbedtls_config_autogen.h b/examples/platforms/efr32/efr32mg13/crypto/mbedtls_config_autogen.h index c0a738c94..5f839fd1f 100644 --- a/examples/platforms/efr32/efr32mg13/crypto/mbedtls_config_autogen.h +++ b/examples/platforms/efr32/efr32mg13/crypto/mbedtls_config_autogen.h @@ -24,10 +24,10 @@ #define MBEDTLS_ECP_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_ECDH_C +#define MBEDTLS_ECDH_LEGACY_CONTEXT #define MBEDTLS_ECDSA_C #define MBEDTLS_ENTROPY_ADC_C -#define MBEDTLS_ENTROPY_RAIL_C -#define MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL +#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_MD_C #define MBEDTLS_ECJPAKE_C #define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED @@ -37,14 +37,12 @@ #define MBEDTLS_ENTROPY_FORCE_SHA256 #define MBEDTLS_ENTROPY_MAX_SOURCES 2 #define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_SHA1_C #define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C #define MBEDTLS_SSL_TLS_C #define MBEDTLS_SSL_CLI_C #define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE #define MBEDTLS_SSL_SRV_C #define MBEDTLS_X509_USE_C #define MBEDTLS_X509_CRT_PARSE_C @@ -53,17 +51,17 @@ #define MBEDTLS_OID_C #define MBEDTLS_PK_C #define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PSA_CRYPTO_DRIVERS #include "config-device-acceleration.h" -#if defined(MBEDTLS_TRNG_PRESENT) -#define MBEDTLS_TRNG_C -#endif - +#if !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) #include "sl_malloc.h" #define MBEDTLS_PLATFORM_FREE_MACRO sl_free #define MBEDTLS_PLATFORM_CALLOC_MACRO sl_calloc +#endif + #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_PLATFORM_C diff --git a/examples/platforms/efr32/efr32mg21/Makefile.platform.am b/examples/platforms/efr32/efr32mg21/Makefile.platform.am index f91e03aea..8193b737d 100644 --- a/examples/platforms/efr32/efr32mg21/Makefile.platform.am +++ b/examples/platforms/efr32/efr32mg21/Makefile.platform.am @@ -31,5 +31,5 @@ # LDADD_COMMON += \ - $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.0/platform/emdrv/nvm3/lib/libnvm3_CM33_gcc.a \ + $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v3.1/platform/emdrv/nvm3/lib/libnvm3_CM33_gcc.a \ $(NULL) diff --git a/examples/platforms/efr32/efr32mg21/README.md b/examples/platforms/efr32/efr32mg21/README.md index b3457a297..9075d932c 100644 --- a/examples/platforms/efr32/efr32mg21/README.md +++ b/examples/platforms/efr32/efr32mg21/README.md @@ -30,8 +30,8 @@ $ ./script/bootstrap 2. Install Flex (Gecko) SDK including RAIL Library from Simplicity Studio. - Connect EFR32MG21 Wireless Starter Kit to Simplicity Studio. - - Find Flex SDK v3.0 in the Software Update page and click Install. - - Flex SDK v3.0 will be installed in the path: + - Find Flex SDK v3.1 in the Software Update page and click Install. + - Flex SDK v3.1 will be installed in the path: - Mac - `/Applications/Simplicity\ Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite` - Windows @@ -193,4 +193,4 @@ The following toolchain has been used for testing and verification: The EFR32 example has been verified with following Flex SDK/RAIL Library version: -- Flex SDK version 3.0.x +- Flex SDK v3.1.x diff --git a/examples/platforms/efr32/efr32mg21/crypto/mbedtls_config_autogen.h b/examples/platforms/efr32/efr32mg21/crypto/mbedtls_config_autogen.h index 7f02e60d1..e55f74a5c 100644 --- a/examples/platforms/efr32/efr32mg21/crypto/mbedtls_config_autogen.h +++ b/examples/platforms/efr32/efr32mg21/crypto/mbedtls_config_autogen.h @@ -24,8 +24,9 @@ #define MBEDTLS_ECP_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_ECDH_C +#define MBEDTLS_ECDH_LEGACY_CONTEXT #define MBEDTLS_ECDSA_C -#define MBEDTLS_ENTROPY_RAIL_C +#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_MD_C #define MBEDTLS_ECJPAKE_C #define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED @@ -35,14 +36,12 @@ #define MBEDTLS_ENTROPY_FORCE_SHA256 #define MBEDTLS_ENTROPY_MAX_SOURCES 2 #define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_ENTROPY_HARDWARE_ALT #define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_SHA1_C #define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C #define MBEDTLS_SSL_TLS_C #define MBEDTLS_SSL_CLI_C #define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE #define MBEDTLS_SSL_SRV_C #define MBEDTLS_X509_USE_C #define MBEDTLS_X509_CRT_PARSE_C @@ -51,13 +50,18 @@ #define MBEDTLS_OID_C #define MBEDTLS_PK_C #define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PSA_CRYPTO_DRIVERS +#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS #include "config-device-acceleration.h" +#if !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC) #include "sl_malloc.h" #define MBEDTLS_PLATFORM_FREE_MACRO sl_free #define MBEDTLS_PLATFORM_CALLOC_MACRO sl_calloc +#endif + #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_PLATFORM_C diff --git a/examples/platforms/efr32/src/alarm.c b/examples/platforms/efr32/src/alarm.c index 6caa1efee..842823f8c 100644 --- a/examples/platforms/efr32/src/alarm.c +++ b/examples/platforms/efr32/src/alarm.c @@ -38,6 +38,7 @@ #include "openthread-system.h" #include +#include #include #include #include "common/logging.hpp" @@ -145,3 +146,23 @@ void efr32AlarmProcess(otInstance *aInstance) } } } + +uint32_t otPlatAlarmMicroGetNow(void) +{ + // TODO microsecond support + return otPlatAlarmMilliGetNow(); +} + +void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt) +{ + // TODO microsecond support + return otPlatAlarmMilliStartAt(aInstance, aT0, aDt); +} + +void otPlatAlarmMicroStop(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + sl_sleeptimer_stop_timer(&sl_handle); + sIsRunning = false; +} diff --git a/examples/platforms/efr32/src/ieee802154mac.h b/examples/platforms/efr32/src/ieee802154mac.h new file mode 100644 index 000000000..178dfee02 --- /dev/null +++ b/examples/platforms/efr32/src/ieee802154mac.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2020, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file holds required 802.15.4 definitions + * + */ + +#ifndef __IEEE802154IEEE802154_H__ +#define __IEEE802154IEEE802154_H__ + +#define IEEE802154_MIN_LENGTH \ + 4 // Technically, a version 2 packet / ACK + // can be 4 bytes with seq# suppression +#define IEEE802154_MAX_LENGTH 127 +#define IEEE802154_ACK_LENGTH 5 + +// FCF + DSN + dest PANID + dest addr + src PANID + src addr (without security header) +#define IEEE802154_MAX_MHR_LENGTH (2 + 1 + 2 + 8 + 2 + 8) + +#define IEEE802154_DSN_OFFSET 2 +#define IEEE802154_FCF_OFFSET 0 + +//------------------------------------------------------------------------ +// 802.15.4 Frame Control Field definitions for Beacon, Ack, Data, Command + +#define IEEE802154_FRAME_TYPE_MASK ((uint16_t)0x0007U) // Bits 0..2 +#define IEEE802154_FRAME_TYPE_BEACON ((uint16_t)0x0000U) // Beacon +#define IEEE802154_FRAME_TYPE_DATA ((uint16_t)0x0001U) // Data +#define IEEE802154_FRAME_TYPE_ACK ((uint16_t)0x0002U) // ACK +#define IEEE802154_FRAME_TYPE_COMMAND ((uint16_t)0x0003U) // Command +#define IEEE802154_FRAME_TYPE_CONTROL IEEE802154_FRAME_TYPE_COMMAND // (synonym) +#define IEEE802154_FRAME_TYPE_RESERVED_MASK ((uint16_t)0x0004U) // Versions 0/1 +// 802.15.4E-2012 introduced MultiPurpose with different Frame Control Field +// layout described in the MultiPurpose section below. +#define IEEE802154_FRAME_TYPE_MULTIPURPOSE ((uint16_t)0x0005U) // MultiPurpose + +#define IEEE802154_FRAME_FLAG_SECURITY_ENABLED ((uint16_t)0x0008U) // Bit 3 +#define IEEE802154_FRAME_FLAG_FRAME_PENDING ((uint16_t)0x0010U) // Bit 4 +#define IEEE802154_FRAME_FLAG_ACK_REQUIRED ((uint16_t)0x0020U) // Bit 5 +#define IEEE802154_FRAME_FLAG_INTRA_PAN ((uint16_t)0x0040U) // Bit 6 +// 802.15.4-2006 renamed the Intra-Pan flag PanId-Compression +#define IEEE802154_FRAME_FLAG_PANID_COMPRESSION IEEE802154_FRAME_FLAG_INTRA_PAN +#define IEEE802154_FRAME_FLAG_RESERVED ((uint16_t)0x0080U) // Bit 7 reserved +// Use the reserved flag internally to check whether frame pending bit was set in outgoing ACK +#define IEEE802154_FRAME_PENDING_SET_IN_OUTGOING_ACK IEEE802154_FRAME_FLAG_RESERVED +// 802.15.4E-2012 introduced these flags for Frame Version 2 frames +// which are reserved bit positions in earlier Frame Version frames: +#define IEEE802154_FRAME_FLAG_SEQ_SUPPRESSION ((uint16_t)0x0100U) // Bit 8 +#define IEEE802154_FRAME_FLAG_IE_LIST_PRESENT ((uint16_t)0x0200U) // Bit 9 + +#define IEEE802154_FRAME_DESTINATION_MODE_MASK ((uint16_t)0x0C00U) // Bits 10..11 +#define IEEE802154_FRAME_DESTINATION_MODE_NONE ((uint16_t)0x0000U) // Mode 0 +#define IEEE802154_FRAME_DESTINATION_MODE_RESERVED ((uint16_t)0x0400U) // Mode 1 +#define IEEE802154_FRAME_DESTINATION_MODE_SHORT ((uint16_t)0x0800U) // Mode 2 +#define IEEE802154_FRAME_DESTINATION_MODE_LONG ((uint16_t)0x0C00U) // Mode 3 +// 802.15.4e-2012 only (not adopted into 802.15.4-2015) +#define IEEE802154_FRAME_DESTINATION_MODE_BYTE IEEE802154_FRAME_DESTINATION_MODE_RESERVED + +#define IEEE802154_FRAME_VERSION_MASK ((uint16_t)0x3000U) // Bits 12..13 +#define IEEE802154_FRAME_VERSION_2003 ((uint16_t)0x0000U) // Version 0 +#define IEEE802154_FRAME_VERSION_2006 ((uint16_t)0x1000U) // Version 1 +// In 802.15.4-2015, Version 2 is just called "IEEE STD 802.15.4" +// which can be rather confusing. It was introduced in 802.15.4E-2012. +#define IEEE802154_FRAME_VERSION_2012 ((uint16_t)0x2000U) // Version 2 +#define IEEE802154_FRAME_VERSION_2015 ((uint16_t)0x2000U) // Version 2 +#define IEEE802154_FRAME_VERSION_RESERVED ((uint16_t)0x3000U) // Version 3 + +#define IEEE802154_FRAME_SOURCE_MODE_MASK ((uint16_t)0xC000U) // Bits 14..15 +#define IEEE802154_FRAME_SOURCE_MODE_NONE ((uint16_t)0x0000U) // Mode 0 +#define IEEE802154_FRAME_SOURCE_MODE_RESERVED ((uint16_t)0x4000U) // Mode 1 +#define IEEE802154_FRAME_SOURCE_MODE_SHORT ((uint16_t)0x8000U) // Mode 2 +#define IEEE802154_FRAME_SOURCE_MODE_LONG ((uint16_t)0xC000U) // Mode 3 +// 802.15.4e-2012 only (not adopted into 802.15.4-2015) +#define IEEE802154_FRAME_SOURCE_MODE_BYTE IEEE802154_FRAME_SOURCE_MODE_RESERVED + +//------------------------------------------------------------------------ +// 802.15.4E-2012 Frame Control Field definitions for MultiPurpose + +#define IEEE802154_MP_FRAME_TYPE_MASK IEEE802154_FRAME_TYPE_MASK // Bits 0..2 +#define IEEE802154_MP_FRAME_TYPE_MULTIPURPOSE IEEE802154_FRAME_TYPE_MULTIPURPOSE + +#define IEEE802154_MP_FRAME_FLAG_LONG_FCF ((uint16_t)0x0008U) // Bit 3 + +#define IEEE802154_MP_FRAME_DESTINATION_MODE_MASK ((uint16_t)0x0030U) // Bits 4..5 +#define IEEE802154_MP_FRAME_DESTINATION_MODE_NONE ((uint16_t)0x0000U) // Mode 0 +#define IEEE802154_MP_FRAME_DESTINATION_MODE_RESERVED ((uint16_t)0x0010U) // Mode 1 +#define IEEE802154_MP_FRAME_DESTINATION_MODE_SHORT ((uint16_t)0x0020U) // Mode 2 +#define IEEE802154_MP_FRAME_DESTINATION_MODE_LONG ((uint16_t)0x0030U) // Mode 3 +// 802.15.4e-2012 only (not adopted into 802.15.4-2015) +#define IEEE802154_MP_FRAME_DESTINATION_MODE_BYTE IEEE802154_MP_FRAME_DESTINATION_MODE_RESERVED + +#define IEEE802154_MP_FRAME_SOURCE_MODE_MASK ((uint16_t)0x00C0U) // Bits 6..7 +#define IEEE802154_MP_FRAME_SOURCE_MODE_NONE ((uint16_t)0x0000U) // Mode 0 +#define IEEE802154_MP_FRAME_SOURCE_MODE_RESERVED ((uint16_t)0x0040U) // Mode 1 +#define IEEE802154_MP_FRAME_SOURCE_MODE_SHORT ((uint16_t)0x0080U) // Mode 2 +#define IEEE802154_MP_FRAME_SOURCE_MODE_LONG ((uint16_t)0x00C0U) // Mode 3 +// 802.15.4e-2012 only (not adopted into 802.15.4-2015) +#define IEEE802154_MP_FRAME_SOURCE_MODE_BYTE IEEE802154_MP_FRAME_SOURCE_MODE_RESERVED + +#define IEEE802154_MP_FRAME_FLAG_PANID_PRESENT ((uint16_t)0x0100U) // Bit 8 +#define IEEE802154_MP_FRAME_FLAG_SECURITY_ENABLED ((uint16_t)0x0200U) // Bit 9 +#define IEEE802154_MP_FRAME_FLAG_SEQ_SUPPRESSION ((uint16_t)0x0400U) // Bit 10 +#define IEEE802154_MP_FRAME_FLAG_FRAME_PENDING ((uint16_t)0x0800U) // Bit 11 + +#define IEEE802154_MP_FRAME_VERSION_MASK IEEE802154_FRAME_VERSION_MASK // Bits 12..13 +#define IEEE802154_MP_FRAME_VERSION_2012 ((uint16_t)0x0000U) // Zeroed out +#define IEEE802154_MP_FRAME_VERSION_2015 ((uint16_t)0x0000U) // Zeroed out +// All other MultiPurpose Frame Versions are reserved + +#define IEEE802154_MP_FRAME_FLAG_ACK_REQUIRED ((uint16_t)0x4000U) // Bit 14 +#define IEEE802154_MP_FRAME_FLAG_IE_LIST_PRESENT ((uint16_t)0x8000U) // Bit 15 + +//------------------------------------------------------------------------ +// Information Elements fields + +#define IEEE802154_KEYID_MODE_0 ((uint8_t)0x0000U) +#define IEEE802154_KEYID_MODE_0_SIZE 0 + +#define IEEE802154_KEYID_MODE_1 ((uint8_t)0x0008U) +#define IEEE802154_KEYID_MODE_1_SIZE 0 + +#define IEEE802154_KEYID_MODE_2 ((uint8_t)0x0010U) +#define IEEE802154_KEYID_MODE_2_SIZE 4 + +#define IEEE802154_KEYID_MODE_3 ((uint8_t)0x0018U) +#define IEEE802154_KEYID_MODE_3_SIZE 8 + +#define IEEE802154_KEYID_MODE_MASK ((uint8_t)0x0018U) + +//------------------------------------------------------------------------ +// Information Elements fields + +// There are Header IEs and Payload IEs. Header IEs are authenticated +// if MAC Security is enabled. Payload IEs are both authenticated and +// encrypted if MAC security is enabled. + +// Header and Payload IEs have slightly different formats and different +// contents based on the 802.15.4 spec. + +// Both are actually a list of IEs that continues until a termination +// IE is seen. + +#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_LENGTH_MASK 0x007F // bits 0-6 +#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_ID_MASK 0x7F80 // bits 7-14 +#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_TYPE_MASK 0x8000 // bit 15 + +#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_ID_SHIFT 7 + +#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_LENGTH_MASK 0x07FF // bits 0 -10 +#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_GROUP_ID_MASK 0x7800 // bits 11-14 +#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_TYPE_MASK 0x8000 // bit 15 + +#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_ID_SHIFT 11 + +// This "type" field indicates header vs. payload IE. However there is +// also a Header IE List terminator which would imply the IE list +// that follows is only payload IEs. +#define IEEE802154_FRAME_INFO_ELEMENT_TYPE_MASK 0x8000 + +// Header Termination ID 1 is used when there are Payload IEs that follow. +// Header Termination ID 2 is used when there are no Payload IEs and the +// next field is the MAC payload. +#define IEEE802154_FRAME_HEADER_TERMINATION_ID_1 0x7E +#define IEEE802154_FRAME_HEADER_TERMINATION_ID_2 0x7F +#define IEEE802154_FRAME_PAYLOAD_TERMINATION_ID 0x0F + +#endif //__IEEE802154IEEE802154_H__ diff --git a/examples/platforms/efr32/src/memory.c b/examples/platforms/efr32/src/memory.c new file mode 100644 index 000000000..1f4899450 --- /dev/null +++ b/examples/platforms/efr32/src/memory.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "openthread-core-efr32-config.h" +#include "platform-efr32.h" + +#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE +#include + +#include "sl_malloc.h" + +void *otPlatCAlloc(size_t aNum, size_t aSize) +{ + return sl_calloc(aNum, aSize); +} + +void otPlatFree(void *aPtr) +{ + sl_free(aPtr); +} +#endif diff --git a/examples/platforms/efr32/src/openthread-core-efr32-config.h b/examples/platforms/efr32/src/openthread-core-efr32-config.h index d1cbde654..2a81b0cc7 100644 --- a/examples/platforms/efr32/src/openthread-core-efr32-config.h +++ b/examples/platforms/efr32/src/openthread-core-efr32-config.h @@ -101,7 +101,17 @@ * Define to 1 if you want to enable software transmission security logic. * */ -#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE \ + (OPENTHREAD_RADIO && (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)) + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE + * + * Define to 1 to enable software transmission target time logic. + * + */ +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE \ + (OPENTHREAD_RADIO && (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)) /** * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE @@ -111,6 +121,15 @@ */ #define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0 +/** + * @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE + * + * Define to 1 if you want to support microsecond timer in platform. + * + */ +#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE \ + (OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE && (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)) + /** * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE * @@ -129,4 +148,23 @@ */ #define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +/** + * @def OPENTHREAD_CONFIG_MIN_SLEEP_DURATION_MS + * + * Minimum duration in ms below which the platform will not + * enter a deep sleep (EM2) mode. + * + */ +#define OPENTHREAD_CONFIG_MIN_SLEEP_DURATION_MS 5 + +/** + * @def OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE + * + * Enable the external heap. + * + */ +#ifndef OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE +#define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 0 +#endif + #endif // OPENTHREAD_CORE_EFR32_CONFIG_H_ diff --git a/examples/platforms/efr32/src/radio.c b/examples/platforms/efr32/src/radio.c index 44e8380de..d04d30129 100644 --- a/examples/platforms/efr32/src/radio.c +++ b/examples/platforms/efr32/src/radio.c @@ -32,65 +32,89 @@ * */ -#include -#include - #include #include "openthread-system.h" #include +#include +#include #include #include #include #include "common/logging.hpp" #include "utils/code_utils.h" +#include "utils/mac_frame.h" #include "utils/soft_source_match_table.h" #include "antenna.h" #include "board_config.h" -#include "em_cmu.h" #include "em_core.h" #include "em_system.h" -#include "hal-config.h" +#include "ieee802154mac.h" +#include "openthread-core-efr32-config.h" #include "pa_conversions_efr32.h" #include "platform-band.h" #include "rail.h" #include "rail_config.h" #include "rail_ieee802154.h" -#define IEEE802154_MIN_LENGTH (5u) -#define IEEE802154_MAX_LENGTH (127u) -#define IEEE802154_ACK_LENGTH (5u) +#ifdef SL_COMPONENT_CATALOG_PRESENT +#include "sl_component_catalog.h" +#endif // SL_COMPONENT_CATALOG_PRESENT -// FCF + DSN + dest PANID + dest addr + src PANID + src addr (without security header) -#define IEEE802154_MAX_MHR_LENGTH (2u + 1u + 2u + 8u + 2u + 8u) +#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT +#include "sl_rail_util_ant_div.h" +#include "sl_rail_util_ant_div_config.h" +#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT -#define IEEE802154_FRAME_TYPE_MASK (0x07u) -#define IEEE802154_FRAME_TYPE_ACK (0x02u) -#define IEEE802154_FRAME_TYPE_MAC_COMMAND (0x03u) -#define IEEE802154_ACK_REQUEST (1u << 5) -#define IEEE802154_DSN_OFFSET (2u) -#define IEEE802154_FCF_OFFSET (0u) +#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT +#include "coexistence-802154.h" +#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT -#define EFR32_RECEIVE_SENSITIVITY (-100) // dBm -#define EFR32_RSSI_AVERAGING_TIME (16u) // us -#define EFR32_RSSI_AVERAGING_TIMEOUT (300u) // us +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT +#include "sl_rail_util_ieee802154_stack_event.h" +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT -#define EFR32_SCHEDULER_SAMPLE_RSSI_PRIORITY (10u) // High priority -#define EFR32_SCHEDULER_TX_PRIORITY (10u) // High priority -#define EFR32_SCHEDULER_RX_PRIORITY (20u) // Low priority +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT +#include "sl_rail_util_ieee802154_phy_select.h" +#endif // #ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT +//------------------------------------------------------------------------------ +// Enums, macros and static variables -enum -{ -#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT && RADIO_CONFIG_915MHZ_OQPSK_SUPPORT - EFR32_NUM_BAND_CONFIGS = 2, -#else - EFR32_NUM_BAND_CONFIGS = 1, -#endif -}; +#define LOW_BYTE(n) ((uint8_t)((n)&0xFF)) +#define HIGH_BYTE(n) ((uint8_t)(LOW_BYTE((n) >> 8))) +#define EFR32_RECEIVE_SENSITIVITY -100 // dBm +#define EFR32_RSSI_AVERAGING_TIME 16 // us +#define EFR32_RSSI_AVERAGING_TIMEOUT 300 // us + +// Internal flags +#define FLAG_RADIO_INIT_DONE 0x0001 +#define FLAG_ONGOING_TX_DATA 0x0002 +#define FLAG_ONGOING_TX_ACK 0x0004 +#define FLAG_WAITING_FOR_ACK 0x0008 +#define FLAG_SYMBOL_TIMER_RUNNING 0x0010 // Not used +#define FLAG_CURRENT_TX_USE_CSMA 0x0020 +#define FLAG_DATA_POLL_FRAME_PENDING_SET 0x0040 +#define FLAG_CALIBRATION_NEEDED 0x0080 // Not used +#define FLAG_IDLE_PENDING 0x0100 // Not used + +#define TX_COMPLETE_RESULT_SUCCESS 0x00 // Not used +#define TX_COMPLETE_RESULT_CCA_FAIL 0x01 +#define TX_COMPLETE_RESULT_OTHER_FAIL 0x02 +#define TX_COMPLETE_RESULT_NONE 0xFF // Not used + +#define TX_WAITING_FOR_ACK 0x00 +#define TX_NO_ACK 0x01 + +#define ONGOING_TX_FLAGS (FLAG_ONGOING_TX_DATA | FLAG_ONGOING_TX_ACK) + +#define QUARTER_DBM_IN_DBM 4 +#define US_IN_MS 1000 + +// Energy Scan typedef enum { ENERGY_SCAN_STATUS_IDLE, @@ -104,87 +128,323 @@ typedef enum ENERGY_SCAN_MODE_ASYNC } energyScanMode; -RAIL_Handle_t gRailHandle; +static volatile energyScanStatus sEnergyScanStatus; +static volatile int8_t sEnergyScanResultDbm; +static energyScanMode sEnergyScanMode; -static volatile bool sTransmitBusy = false; -static bool sPromiscuous = false; -static otRadioState sState = OT_RADIO_STATE_DISABLED; - -enum -{ - ACKED_WITH_FP_MATCH_LENGTH = 1 + IEEE802154_MAX_MHR_LENGTH, // PHR and MHR - ACKED_WITH_FP_SLOTS = 32, // maximum number of Data Request packets in the RX FIFO. Length should be a power of 2. -}; - -typedef struct efr32AckedWithFP -{ - uint8_t mLength; - uint8_t mPacket[ACKED_WITH_FP_MATCH_LENGTH]; -} efr32AckedWithFP; -static bool sIsSrcMatchEnabled = false; -static efr32AckedWithFP sAckedWithFPFifo[ACKED_WITH_FP_SLOTS]; -static uint32_t sAckedWithFPReadIndex; -static volatile uint32_t sAckedWithFPWriteIndex; +static bool sIsSrcMatchEnabled = false; +// Receive static uint8_t sReceivePsdu[IEEE802154_MAX_LENGTH]; +static uint8_t sReceiveAckPsdu[IEEE802154_ACK_LENGTH]; static otRadioFrame sReceiveFrame; +static otRadioFrame sReceiveAckFrame; static otError sReceiveError; +// Transmit static otRadioFrame sTransmitFrame; static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH]; static volatile otError sTransmitError; +static volatile bool sTransmitBusy = false; +static otRadioFrame * sTxFrame = NULL; + +// Radio +#define CCA_THRESHOLD_UNINIT 127 +#define CCA_THRESHOLD_DEFAULT -75 // dBm - default for 2.4GHz 802.15.4 + +static bool sPromiscuous = false; +static otRadioState sState = OT_RADIO_STATE_DISABLED; static efr32CommonConfig sCommonConfig; -static efr32BandConfig sBandConfigs[EFR32_NUM_BAND_CONFIGS]; +static efr32BandConfig sBandConfig; +static efr32BandConfig * sCurrentBandConfig = NULL; + +static int8_t sCcaThresholdDbm = CCA_THRESHOLD_DEFAULT; #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT static efr32RadioCounters sRailDebugCounters; #endif -static volatile energyScanStatus sEnergyScanStatus; -static volatile int8_t sEnergyScanResultDbm; -static energyScanMode sEnergyScanMode; +// RAIL +RAIL_Handle_t emPhyRailHandle; +#define gRailHandle emPhyRailHandle -#define QUARTER_DBM_IN_DBM 4 -#define US_IN_MS 1000 +static const RAIL_IEEE802154_Config_t sRailIeee802154Config = { + NULL, // addresses + { + // ackConfig + true, // ackConfig.enable + 672, // 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 + false, // defaultFramePendingInOutgoingAcks +}; + +// Misc +static volatile uint16_t miscInternalFlags = 0; +static bool emPendingData = false; + +#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT +enum +{ + RHO_INACTIVE = 0, + RHO_EXT_ACTIVE, + RHO_INT_ACTIVE, // Not used + RHO_BOTH_ACTIVE, +}; + +static uint8_t rhoActive = RHO_INACTIVE; +static bool ptaGntEventReported; +static bool sRadioCoexEnabled = true; + +#if SL_OPENTHREAD_COEX_COUNTER_ENABLE +static uint32_t sCoexCounters[SL_RAIL_UTIL_COEX_EVENT_COUNT] = {0}; +#endif // SL_OPENTHREAD_COEX_COUNTER_ENABLE + +#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT + +// Enhanced Acks and CSL +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT +static otExtAddress sExtAddress; +static otRadioIeInfo sTransmitIeInfo; +#endif + +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +static uint8_t sAckIeData[OT_ACK_IE_MAX_SIZE]; +static uint8_t sAckIeDataLength = 0; + +static uint32_t sCslPeriod; +static uint32_t sCslSampleTime; +static const uint8_t sCslIeHeader[OT_IE_HEADER_SIZE] = {CSL_IE_HEADER_BYTES_LO, CSL_IE_HEADER_BYTES_HI}; + +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + +static uint32_t sMacFrameCounter; +static uint8_t sKeyId; +static struct otMacKey sPrevKey; +static struct otMacKey sCurrKey; +static struct otMacKey sNextKey; +static bool sAckedWithSecEnhAck; +static uint32_t sAckFrameCounter; +static uint8_t sAckKeyId; + +static void processSecurityForEnhancedAck(uint8_t *aAckFrame) +{ + otRadioFrame ackFrame; + struct otMacKey *key = NULL; + uint8_t keyId; + + sAckedWithSecEnhAck = false; + otEXPECT(aAckFrame[1] & IEEE802154_FRAME_FLAG_SECURITY_ENABLED); + + memset(&ackFrame, 0, sizeof(ackFrame)); + ackFrame.mPsdu = &aAckFrame[1]; + ackFrame.mLength = aAckFrame[0]; + + keyId = otMacFrameGetKeyId(&ackFrame); + + otEXPECT(otMacFrameIsKeyIdMode1(&ackFrame) && keyId != 0); + + if (keyId == sKeyId) + { + key = &sCurrKey; + } + else if (keyId == sKeyId - 1) + { + key = &sPrevKey; + } + else if (keyId == sKeyId + 1) + { + key = &sNextKey; + } + else + { + otEXPECT(false); + } + + sAckFrameCounter = sMacFrameCounter; + sAckKeyId = keyId; + sAckedWithSecEnhAck = true; + + ackFrame.mInfo.mTxInfo.mAesKey = key; + + otMacFrameSetKeyId(&ackFrame, keyId); + otMacFrameSetFrameCounter(&ackFrame, sMacFrameCounter++); + + // Perform AES-CCM encryption on the frame which is going to be sent. + otMacFrameProcessTransmitAesCcm(&ackFrame, &sExtAddress); + +exit: + return; +} +#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +//------------------------------------------------------------------------------ +// Forward Declarations static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents); -static const RAIL_IEEE802154_Config_t sRailIeee802154Config = { - .addresses = NULL, - .ackConfig = - { - .enable = true, - .ackTimeout = 672, - .rxTransitions = - { - .success = RAIL_RF_STATE_RX, - .error = RAIL_RF_STATE_RX, - }, - .txTransitions = - { - .success = RAIL_RF_STATE_RX, - .error = RAIL_RF_STATE_RX, - }, - }, - .timings = - { - .idleToRx = 100, - .txToRx = 192 - 10, - .idleToTx = 100, - .rxToTx = 192, - .rxSearchTimeout = 0, - .txToRxSearchTimeout = 0, - }, - .framesMask = RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, - .promiscuousMode = false, - .isPanCoordinator = false, - .defaultFramePendingInOutgoingAcks = false, -}; +static void efr32PhyStackInit(void); -static int8_t sCcaThresholdDbm = -75; // default -75dBm energy detect threshold +#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT +static void efr32CoexInit(void); +// Try to transmit the current outgoing frame subject to MAC-level PTA +static void tryTxCurrentPacket(void); +#else +// Transmit the current outgoing frame. +void txCurrentPacket(void); +#define tryTxCurrentPacket txCurrentPacket +#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT -static efr32BandConfig *sCurrentBandConfig = NULL; +static void txFailedCallback(bool isAck, uint8_t status); + +static bool validatePacketDetails(RAIL_RxPacketHandle_t packetHandle, + RAIL_RxPacketDetails_t *pPacketDetails, + RAIL_RxPacketInfo_t * pPacketInfo, + uint16_t * packetLength); +static bool validatePacketTimestamp(RAIL_RxPacketDetails_t *pPacketDetails, uint16_t packetLength); +static void updateRxFrameDetails(RAIL_RxPacketDetails_t *pPacketDetails, bool framePendingSetInOutgoingAck); + +//------------------------------------------------------------------------------ +// Helper Functions + +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + +static bool phyStackEventIsEnabled(void) +{ + bool result = false; + +#if (defined(SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT) && SL_RAIL_UTIL_ANT_DIV_RX_RUNTIME_PHY_SELECT) + result = true; +#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + +#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT + result |= (sl_rail_util_coex_is_enabled() && sRadioCoexEnabled); +#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT + + return result; +} + +static RAIL_Events_t currentEventConfig = RAIL_EVENTS_NONE; +static void updateEvents(RAIL_Events_t mask, RAIL_Events_t values) +{ + RAIL_Status_t status; + RAIL_Events_t newEventConfig = (currentEventConfig & ~mask) | (values & mask); + if (newEventConfig != currentEventConfig) + { + currentEventConfig = newEventConfig; + status = RAIL_ConfigEvents(gRailHandle, mask, values); + assert(status == RAIL_STATUS_NO_ERROR); + } +} + +static sl_rail_util_ieee802154_stack_event_t handlePhyStackEvent(sl_rail_util_ieee802154_stack_event_t stackEvent, + uint32_t supplement) +{ + return (phyStackEventIsEnabled() ? sl_rail_util_ieee802154_on_event(stackEvent, supplement) : 0); +} +#else +static void updateEvents(RAIL_Events_t mask, RAIL_Events_t values) +{ + RAIL_Status_t status; + status = RAIL_ConfigEvents(gRailHandle, mask, values); + assert(status == RAIL_STATUS_NO_ERROR); +} + +#define handlePhyStackEvent(event, supplement) 0 +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + +// Set or clear the passed flag. +static inline void setInternalFlag(uint16_t flag, bool val) +{ + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + miscInternalFlags = (val ? (miscInternalFlags | flag) : (miscInternalFlags & ~flag)); + CORE_EXIT_ATOMIC(); +} +// Returns true if the passed flag is set, false otherwise. +static inline bool getInternalFlag(uint16_t flag) +{ + return ((miscInternalFlags & flag) != 0); +} + +static inline bool txWaitingForAck(void) +{ + return (sTransmitBusy == true && ((sTransmitFrame.mPsdu[0] & IEEE802154_FRAME_FLAG_ACK_REQUIRED) != 0)); +} + +static bool txIsDataRequest(void) +{ + uint16_t fcf = sTransmitFrame.mPsdu[IEEE802154_FCF_OFFSET] | (sTransmitFrame.mPsdu[IEEE802154_FCF_OFFSET + 1] << 8); + + return (sTransmitBusy == true && (fcf & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_COMMAND); +} + +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT +static inline bool isReceivingFrame(void) +{ + return (RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX_ACTIVE) == RAIL_RF_STATE_RX_ACTIVE; +} +#endif + +static void radioSetIdle(void) +{ + if (RAIL_GetRadioState(gRailHandle) != RAIL_RF_STATE_IDLE) + { + RAIL_Idle(gRailHandle, RAIL_IDLE, true); + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_IDLED, 0U); + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_IDLED, 0U); + } + RAIL_YieldRadio(gRailHandle); + sState = OT_RADIO_STATE_SLEEP; +} + +static otError radioSetRx(uint8_t aChannel) +{ + otError error = OT_ERROR_NONE; + RAIL_Status_t status; + + RAIL_SchedulerInfo_t bgRxSchedulerInfo = { + .priority = RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY, + // sliptime/transaction time is not used for bg rx + }; + + status = RAIL_StartRx(gRailHandle, aChannel, &bgRxSchedulerInfo); + otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED); + + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_LISTEN, 0U); + sState = OT_RADIO_STATE_RECEIVE; + + otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL); +exit: + return error; +} + +//------------------------------------------------------------------------------ +// Radio Initialization static RAIL_Handle_t efr32RailInit(efr32CommonConfig *aCommonConfig) { @@ -194,29 +454,33 @@ static RAIL_Handle_t efr32RailInit(efr32CommonConfig *aCommonConfig) handle = RAIL_Init(&aCommonConfig->mRailConfig, NULL); assert(handle != NULL); +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) + status = RAIL_InitPowerManager(); + assert(status == RAIL_STATUS_NO_ERROR); +#endif // SL_CATALOG_POWER_MANAGER_PRESENT + status = RAIL_ConfigCal(handle, RAIL_CAL_ALL); assert(status == RAIL_STATUS_NO_ERROR); status = RAIL_IEEE802154_Init(handle, &sRailIeee802154Config); assert(status == RAIL_STATUS_NO_ERROR); - status = RAIL_ConfigEvents(handle, RAIL_EVENTS_ALL, - RAIL_EVENT_RX_ACK_TIMEOUT | // - RAIL_EVENTS_TX_COMPLETION | // - RAIL_EVENT_RX_PACKET_RECEIVED | // - RAIL_EVENT_RSSI_AVERAGE_DONE | // - RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND | // - RAIL_EVENT_CAL_NEEDED | // -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT || RADIO_CONFIG_DMP_SUPPORT - RAIL_EVENT_CONFIG_SCHEDULED | // - RAIL_EVENT_CONFIG_UNSCHEDULED | // -#endif - RAIL_EVENT_SCHEDULER_STATUS // - ); - assert(status == RAIL_STATUS_NO_ERROR); +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + // Enhanced Frame Pending + // status = RAIL_IEEE802154_EnableEarlyFramePending(handle, true); + // assert(status == RAIL_STATUS_NO_ERROR); - uint16_t actualLength = RAIL_SetTxFifo(handle, aCommonConfig->mRailTxFifo, 0, sizeof(aCommonConfig->mRailTxFifo)); - assert(actualLength == sizeof(aCommonConfig->mRailTxFifo)); + // status = RAIL_IEEE802154_EnableDataFramePending(handle, true); + // assert(status == RAIL_STATUS_NO_ERROR); + + // Enhanced ACKs (only on platforms that support it, so error checking is disabled) + // RAIL_IEEE802154_ConfigEOptions(handle, + // (RAIL_IEEE802154_E_OPTION_GB868 | RAIL_IEEE802154_E_OPTION_ENH_ACK), + // (RAIL_IEEE802154_E_OPTION_GB868 | RAIL_IEEE802154_E_OPTION_ENH_ACK)); +#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + + uint16_t actualLenth = RAIL_SetTxFifo(handle, aCommonConfig->mRailTxFifo, 0, sizeof(aCommonConfig->mRailTxFifo)); + assert(actualLenth == sizeof(aCommonConfig->mRailTxFifo)); return handle; } @@ -226,18 +490,20 @@ static void efr32RailConfigLoad(efr32BandConfig *aBandConfig) RAIL_Status_t status; RAIL_TxPowerConfig_t txPowerConfig = {SL_RAIL_UTIL_PA_SELECTION_2P4GHZ, SL_RAIL_UTIL_PA_VOLTAGE_MV, 10}; -#if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT if (aBandConfig->mChannelConfig != NULL) { uint16_t firstChannel = RAIL_ConfigChannels(gRailHandle, aBandConfig->mChannelConfig, NULL); assert(firstChannel == aBandConfig->mChannelMin); - txPowerConfig.mode = RAIL_TX_POWER_MODE_SUBGIG; + // txPowerConfig.mode = RAIL_TX_POWER_MODE_SUBGIG; TO DO:Check this macro } else -#endif // RADIO_CONFIG_915MHZ_OQPSK_SUPPORT { +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT + status = sl_rail_util_plugin_config_2p4ghz_radio(gRailHandle); +#else status = RAIL_IEEE802154_Config2p4GHzRadio(gRailHandle); +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT assert(status == RAIL_STATUS_NO_ERROR); } @@ -258,13 +524,9 @@ static efr32BandConfig *efr32RadioGetBandConfig(uint8_t aChannel) { efr32BandConfig *config = NULL; - for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++) + if ((sBandConfig.mChannelMin <= aChannel) && (aChannel <= sBandConfig.mChannelMax)) { - if ((sBandConfigs[i].mChannelMin <= aChannel) && (aChannel <= sBandConfigs[i].mChannelMax)) - { - config = &sBandConfigs[i]; - break; - } + config = &sBandConfig; } return config; @@ -280,20 +542,17 @@ static void efr32ConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAI sCommonConfig.mRailConfig.scheduler = NULL; // only needed for DMP #endif - uint8_t index = 0; - #if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT - sBandConfigs[index].mChannelConfig = NULL; - sBandConfigs[index].mChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN; - sBandConfigs[index].mChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX; + sBandConfig.mChannelConfig = NULL; + sBandConfig.mChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN; + sBandConfig.mChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX; - index++; #endif #if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT - sBandConfigs[index].mChannelConfig = channelConfigs[0]; - sBandConfigs[index].mChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN; - sBandConfigs[index].mChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX; + sBandConfig.mChannelConfig = channelConfigs[0]; // TO DO: channel config?? + sBandConfig.mChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN; + sBandConfig.mChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX; #endif #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT @@ -302,11 +561,24 @@ static void efr32ConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAI gRailHandle = efr32RailInit(&sCommonConfig); assert(gRailHandle != NULL); - efr32RailConfigLoad(&(sBandConfigs[0])); + + updateEvents(RAIL_EVENTS_ALL, + (0 | RAIL_EVENT_RX_ACK_TIMEOUT | RAIL_EVENT_RX_PACKET_RECEIVED | RAIL_EVENTS_TXACK_COMPLETION | + RAIL_EVENTS_TX_COMPLETION | RAIL_EVENT_RSSI_AVERAGE_DONE | RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT || RADIO_CONFIG_DMP_SUPPORT + | RAIL_EVENT_CONFIG_SCHEDULED | RAIL_EVENT_CONFIG_UNSCHEDULED | RAIL_EVENT_SCHEDULER_STATUS +#endif + | RAIL_EVENT_CAL_NEEDED)); + + efr32RailConfigLoad(&(sBandConfig)); } void efr32RadioInit(void) { + if (getInternalFlag(FLAG_RADIO_INIT_DONE)) + { + return; + } RAIL_Status_t status; // check if RAIL_TX_FIFO_SIZE is power of two.. @@ -316,24 +588,33 @@ void efr32RadioInit(void) assert((RAIL_TX_FIFO_SIZE >= 64) || (RAIL_TX_FIFO_SIZE <= 4096)); efr32ConfigInit(RAILCb_Generic); + setInternalFlag(FLAG_RADIO_INIT_DONE, true); status = RAIL_ConfigSleep(gRailHandle, RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED); assert(status == RAIL_STATUS_NO_ERROR); - sReceiveFrame.mLength = 0; - sReceiveFrame.mPsdu = sReceivePsdu; - sTransmitFrame.mLength = 0; - sTransmitFrame.mPsdu = sTransmitPsdu; + sReceiveFrame.mLength = 0; + sReceiveFrame.mPsdu = sReceivePsdu; + sReceiveAckFrame.mLength = 0; + sReceiveAckFrame.mPsdu = sReceiveAckPsdu; + sTransmitFrame.mLength = 0; + sTransmitFrame.mPsdu = sTransmitPsdu; + +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + sTransmitFrame.mInfo.mTxInfo.mIeInfo = &sTransmitIeInfo; +#endif +#endif sCurrentBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL); assert(sCurrentBandConfig != NULL); - memset(sAckedWithFPFifo, 0, sizeof(sAckedWithFPFifo)); - sAckedWithFPWriteIndex = 0; - sAckedWithFPReadIndex = 0; - efr32RadioSetTxPower(OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER); + assert(RAIL_ConfigRxOptions(gRailHandle, RAIL_RX_OPTION_TRACK_ABORTED_FRAMES, + RAIL_RX_OPTION_TRACK_ABORTED_FRAMES) == RAIL_STATUS_NO_ERROR); + efr32PhyStackInit(); + sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE; sTransmitError = OT_ERROR_NONE; sTransmitBusy = false; @@ -352,6 +633,15 @@ void efr32RadioDeinit(void) sCurrentBandConfig = NULL; } +//------------------------------------------------------------------------------ +// Energy Scan support + +static void energyScanComplete(int8_t scanResultDbm) +{ + sEnergyScanResultDbm = scanResultDbm; + sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED; +} + static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAIL_Time_t aAveragingTimeUs) { RAIL_Status_t status = RAIL_STATUS_NO_ERROR; @@ -382,9 +672,66 @@ static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAI otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED); exit: + if (status != RAIL_STATUS_NO_ERROR) + { + energyScanComplete(OT_RADIO_RSSI_INVALID); + } return error; } +//------------------------------------------------------------------------------ +// Enhanced Acks and CSL support + +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + +static uint16_t getCslPhase() +{ + uint32_t curTime = otPlatAlarmMicroGetNow(); + uint32_t cslPeriodInUs = sCslPeriod * OT_US_PER_TEN_SYMBOLS; + uint32_t diff = ((sCslSampleTime % cslPeriodInUs) - (curTime % cslPeriodInUs) + cslPeriodInUs) % cslPeriodInUs; + + return (uint16_t)(diff / OT_US_PER_TEN_SYMBOLS); +} + +static void updateIeData(void) +{ + // The CSL IE Content field: + // ___________________________________________________ + // | Octets: 2 | Octets: 2 | Octets: 0/2 | + // |______________|______________|_____________________| + // | CSL Phase | CSL Period | Rendezvous time | + // |______________|______________|_____________________| + // + // Note: The rendezvous time is included right when sending the packet, + // (in txCurrentPacket), before updating the 802.15.4 header with CSL IEs. + // The tx frame is modified at the right offset (see mInfo.mTxInfo.mIeInfo->mTimeIeOffset) + + int8_t offset = 0; + if (sCslPeriod > 0) + { + uint8_t *finger = sAckIeData; + memcpy(finger, sCslIeHeader, OT_IE_HEADER_SIZE); + finger += OT_IE_HEADER_SIZE; + + uint16_t cslPhase = getCslPhase(); + *finger++ = HIGH_BYTE(cslPhase); + *finger++ = LOW_BYTE(cslPhase); + + *finger++ = HIGH_BYTE((uint16_t)sCslPeriod); + *finger++ = LOW_BYTE((uint16_t)sCslPeriod); + + offset = finger - sAckIeData; + } + + sAckIeDataLength = offset; +} +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +//------------------------------------------------------------------------------ +// Stack support + void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) { OT_UNUSED_VARIABLE(aInstance); @@ -418,6 +765,14 @@ void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId) void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress) { OT_UNUSED_VARIABLE(aInstance); +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + for (size_t i = 0; i < sizeof(*aAddress); i++) + { + sExtAddress.m8[i] = aAddress->m8[sizeof(*aAddress) - 1 - i]; + } +#endif +#endif RAIL_Status_t status; @@ -472,18 +827,13 @@ exit: otError otPlatRadioSleep(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - otError error = OT_ERROR_NONE; otEXPECT_ACTION((sState != OT_RADIO_STATE_TRANSMIT) && (sState != OT_RADIO_STATE_DISABLED), error = OT_ERROR_INVALID_STATE); otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL); - - RAIL_Idle(gRailHandle, RAIL_IDLE, true); - RAIL_YieldRadio(gRailHandle); - sState = OT_RADIO_STATE_SLEEP; - + radioSetIdle(); exit: return error; } @@ -507,17 +857,11 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) sCurrentBandConfig = config; } - RAIL_SchedulerInfo_t bgRxSchedulerInfo = { - .priority = RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY, - // sliptime/transaction time is not used for bg rx - }; - - status = RAIL_StartRx(gRailHandle, aChannel, &bgRxSchedulerInfo); + status = radioSetRx(aChannel); otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED); - otLogInfoPlat("State=OT_RADIO_STATE_RECEIVE", NULL); - sState = OT_RADIO_STATE_RECEIVE; - sReceiveFrame.mChannel = aChannel; + sReceiveFrame.mChannel = aChannel; + sReceiveAckFrame.mChannel = aChannel; exit: return error; @@ -525,29 +869,14 @@ exit: 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_TxOptions_t txOptions = RAIL_TX_OPTIONS_DEFAULT; - efr32BandConfig * config; - RAIL_Status_t status; - uint8_t frameLength; - -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailPlatTxTriggered++; -#endif - - assert(sTransmitBusy == false); + otError error = OT_ERROR_NONE; + efr32BandConfig *config; otEXPECT_ACTION((sState != OT_RADIO_STATE_DISABLED) && (sState != OT_RADIO_STATE_TRANSMIT), error = OT_ERROR_INVALID_STATE); config = efr32RadioGetBandConfig(aFrame->mChannel); otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS); - - sState = OT_RADIO_STATE_TRANSMIT; - sTransmitError = OT_ERROR_NONE; - sTransmitBusy = true; - if (sCurrentBandConfig != config) { RAIL_Idle(gRailHandle, RAIL_IDLE, true); @@ -555,9 +884,57 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) sCurrentBandConfig = config; } - frameLength = (uint8_t)aFrame->mLength; + assert(sTransmitBusy == false); + sState = OT_RADIO_STATE_TRANSMIT; + sTransmitError = OT_ERROR_NONE; + sTransmitBusy = true; + sTxFrame = aFrame; + + setInternalFlag(FLAG_CURRENT_TX_USE_CSMA, aFrame->mInfo.mTxInfo.mCsmaCaEnabled); + + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + setInternalFlag(FLAG_ONGOING_TX_DATA, true); + tryTxCurrentPacket(); + CORE_EXIT_ATOMIC(); + + if (sTransmitError == OT_ERROR_NONE) + { + otPlatRadioTxStarted(aInstance, aFrame); + } +exit: + return error; +} + +void txCurrentPacket(void) +{ + assert(getInternalFlag(FLAG_ONGOING_TX_DATA)); + assert(sTxFrame != NULL); + + RAIL_CsmaConfig_t csmaConfig = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA; + RAIL_TxOptions_t txOptions = RAIL_TX_OPTIONS_DEFAULT; + RAIL_Status_t status; + uint8_t frameLength; + bool ackRequested; + +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailPlatTxTriggered++; +#endif + + // signalling this event earlier, as this event can assert REQ (expecially for a + // non-CSMA transmit) giving the Coex master a little more time to grant or deny. + if (getInternalFlag(FLAG_CURRENT_TX_USE_CSMA)) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_PENDED_PHY, (uint32_t) true); + } + else + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_PENDED_PHY, (uint32_t) false); + } + + frameLength = (uint8_t)sTxFrame->mLength; RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true); - RAIL_WriteTxFifo(gRailHandle, aFrame->mPsdu, frameLength - 2, false); + RAIL_WriteTxFifo(gRailHandle, sTxFrame->mPsdu, frameLength - 2, false); RAIL_SchedulerInfo_t txSchedulerInfo = { .priority = RADIO_SCHEDULER_TX_PRIORITY, @@ -565,7 +942,36 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) .transactionTime = 0, // will be calculated later if DMP is used }; - if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST) +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + // Update IE data in the 802.15.4 header with the newest CSL period / phase + if (sCslPeriod > 0) + { + otMacFrameSetCslIe(sTxFrame, (uint16_t)sCslPeriod, getCslPhase()); + } +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + // Seek the time sync offset and update the rendezvous time + if (aFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0) + { + uint8_t *timeIe = aFrame->mPsdu + aFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset; + uint64_t time = otPlatTimeGet() + aFrame->mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset; + + *timeIe = aFrame->mInfo.mTxInfo.mIeInfo->mTimeSyncSeq; + + *(++timeIe) = (uint8_t)(time & 0xff); + for (uint8_t i = 1; i < sizeof(uint64_t); i++) + { + time = time >> 8; + *(++timeIe) = (uint8_t)(time & 0xff); + } + } +#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE +#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + + ackRequested = (sTxFrame->mPsdu[0] & IEEE802154_FRAME_FLAG_ACK_REQUIRED); + if (ackRequested) { txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK; @@ -582,6 +988,18 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) #endif } +#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + // Update Tx options to use currently-selected antenna. + // If antenna diverisity on Tx is disabled, leave both options 0 + // so Tx antenna tracks Rx antenna. + if (sl_rail_util_ant_div_get_antenna_mode() != SL_RAIL_UTIL_ANT_DIV_DISABLED) + { + txOptions |= ((sl_rail_util_ant_div_get_antenna_selected() == SL_RAIL_UTIL_ANTENNA_SELECT_ANTENNA1) + ? RAIL_TX_OPTION_ANTENNA0 + : RAIL_TX_OPTION_ANTENNA1); + } +#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + #if RADIO_CONFIG_DMP_SUPPORT // time needed for the frame itself // 4B preamble, 1B SFD, 1B PHR is not counted in frameLength @@ -595,42 +1013,40 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) } #endif - if (aFrame->mInfo.mTxInfo.mCsmaCaEnabled) + if (getInternalFlag(FLAG_CURRENT_TX_USE_CSMA)) { #if RADIO_CONFIG_DMP_SUPPORT // time needed for CSMA/CA txSchedulerInfo.transactionTime += RADIO_TIMING_CSMA_OVERHEAD_US; #endif - csmaConfig.csmaTries = aFrame->mInfo.mTxInfo.mMaxCsmaBackoffs; + csmaConfig.csmaTries = sTxFrame->mInfo.mTxInfo.mMaxCsmaBackoffs; csmaConfig.ccaThreshold = sCcaThresholdDbm; - - status = RAIL_StartCcaCsmaTx(gRailHandle, aFrame->mChannel, txOptions, &csmaConfig, &txSchedulerInfo); + status = RAIL_StartCcaCsmaTx(gRailHandle, sTxFrame->mChannel, txOptions, &csmaConfig, &txSchedulerInfo); } else { - status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, &txSchedulerInfo); + status = RAIL_StartTx(gRailHandle, sTxFrame->mChannel, txOptions, &txSchedulerInfo); + if (status == RAIL_STATUS_NO_ERROR) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_STARTED, 0U); + } } - if (status == RAIL_STATUS_NO_ERROR) { #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT sRailDebugCounters.mRailTxStarted++; #endif - otPlatRadioTxStarted(aInstance, aFrame); } else { #if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT sRailDebugCounters.mRailTxStartFailed++; #endif - // Tx started at an invalid time or an invalid paramter has been passed. - sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE; - sTransmitBusy = false; + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_BLOCKED, (uint32_t)ackRequested); + txFailedCallback(false, TX_COMPLETE_RESULT_OTHER_FAIL); + otSysEventSignalPending(); } - -exit: - return error; } otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance) @@ -672,7 +1088,17 @@ otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN; + otRadioCaps capabilities = (OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN); + +#if OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + capabilities |= OT_RADIO_CAPS_TRANSMIT_SEC; +#endif + +#if OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE + capabilities |= OT_RADIO_CAPS_TRANSMIT_TIMING; +#endif + + return capabilities; } bool otPlatRadioGetPromiscuous(otInstance *aInstance) @@ -702,420 +1128,6 @@ void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable) sIsSrcMatchEnabled = aEnable; } -static bool sAckedWithFPFifoIsFull(void) -{ - return (uint32_t)(sAckedWithFPWriteIndex - sAckedWithFPReadIndex) == otARRAY_LENGTH(sAckedWithFPFifo); -} - -static bool sAckedWithFPFifoIsEmpty(void) -{ - return (uint32_t)(sAckedWithFPWriteIndex - sAckedWithFPReadIndex) == 0; -} - -static efr32AckedWithFP *sAckedWithFPFifoGetWriteSlot(void) -{ - uint32_t idx = sAckedWithFPWriteIndex & (otARRAY_LENGTH(sAckedWithFPFifo) - 1); - return &sAckedWithFPFifo[idx]; -} - -static const efr32AckedWithFP *sAckedWithFPFifoGetReadSlot(void) -{ - uint32_t idx = sAckedWithFPReadIndex & (otARRAY_LENGTH(sAckedWithFPFifo) - 1); - return &sAckedWithFPFifo[idx]; -} - -static void insertIeee802154DataRequestCommand(RAIL_Handle_t aRailHandle) -{ - assert(!sAckedWithFPFifoIsFull()); - efr32AckedWithFP *const slot = sAckedWithFPFifoGetWriteSlot(); - - RAIL_RxPacketInfo_t packetInfo; - - RAIL_GetRxIncomingPacketInfo(aRailHandle, &packetInfo); - assert(packetInfo.packetBytes >= 4); // PHR + FCF + DSN - - if (packetInfo.packetBytes > sizeof(slot->mPacket)) - { - packetInfo.packetBytes = sizeof(slot->mPacket); - if (packetInfo.firstPortionBytes >= sizeof(slot->mPacket)) - { - packetInfo.firstPortionBytes = sizeof(slot->mPacket); - packetInfo.lastPortionData = NULL; - } - } - slot->mLength = packetInfo.packetBytes; - RAIL_CopyRxPacket(slot->mPacket, &packetInfo); - - ++sAckedWithFPWriteIndex; -} - -static bool wasAckedWithFramePending(const uint8_t *aPsdu, uint8_t aPsduLength) -{ - bool ackedWithFramePending = false; - uint16_t fcf = aPsdu[IEEE802154_FCF_OFFSET] | (aPsdu[IEEE802154_FCF_OFFSET + 1] << 8); - - otEXPECT((fcf & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_MAC_COMMAND); - - while (!(ackedWithFramePending || sAckedWithFPFifoIsEmpty())) - { - const efr32AckedWithFP *const slot = sAckedWithFPFifoGetReadSlot(); - if ((slot->mPacket[0] == aPsduLength) && (memcmp(slot->mPacket + 1, aPsdu, slot->mLength - 1) == 0)) - { - ackedWithFramePending = true; - } - ++sAckedWithFPReadIndex; - } - -exit: - return ackedWithFramePending; -} - -static void processNextRxPacket(otInstance *aInstance) -{ - RAIL_RxPacketHandle_t packetHandle = RAIL_RX_PACKET_HANDLE_INVALID; - RAIL_RxPacketInfo_t packetInfo; - RAIL_RxPacketDetails_t packetDetails; - RAIL_Status_t status; - uint16_t length; - bool framePending = false; - - packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo); - - otEXPECT_ACTION(packetHandle != RAIL_RX_PACKET_HANDLE_INVALID && - packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS, - packetHandle = RAIL_RX_PACKET_HANDLE_INVALID); - - status = RAIL_GetRxPacketDetailsAlt(gRailHandle, packetHandle, &packetDetails); - otEXPECT(status == RAIL_STATUS_NO_ERROR); - - length = packetInfo.packetBytes + 1; - - // check the length in recv packet info structure; RAIL should take care of this. - otEXPECT(length == packetInfo.firstPortionData[0]); - - // check the length validity of recv packet; RAIL should take care of this. - otEXPECT(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH); - - otLogInfoPlat("Received data:%d", length); - - // skip length byte - otEXPECT(packetInfo.firstPortionBytes > 0); - packetInfo.firstPortionData++; - packetInfo.firstPortionBytes--; - packetInfo.packetBytes--; - - // read packet - RAIL_CopyRxPacket(sReceiveFrame.mPsdu, &packetInfo); - - status = RAIL_ReleaseRxPacket(gRailHandle, packetHandle); - if (status == RAIL_STATUS_NO_ERROR) - { - packetHandle = RAIL_RX_PACKET_HANDLE_INVALID; - } - - sReceiveFrame.mLength = length; - - sReceiveFrame.mInfo.mRxInfo.mRssi = packetDetails.rssi; - sReceiveFrame.mInfo.mRxInfo.mLqi = packetDetails.lqi; - - // Get the timestamp when the SFD was received - assert(packetDetails.timeReceived.timePosition != RAIL_PACKET_TIME_INVALID); - packetDetails.timeReceived.totalPacketBytes = length + 1; - - status = RAIL_GetRxTimeSyncWordEndAlt(gRailHandle, &packetDetails); - assert(status == RAIL_STATUS_NO_ERROR); - sReceiveFrame.mInfo.mRxInfo.mTimestamp = packetDetails.timeReceived.packetTime; - - if (packetDetails.isAck) - { - otEXPECT((length == IEEE802154_ACK_LENGTH) && - (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK); - - sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = false; - - RAIL_YieldRadio(gRailHandle); - sTransmitBusy = false; - - if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET]) - { - sTransmitError = OT_ERROR_NONE; - } - else - { - sTransmitError = OT_ERROR_NO_ACK; - } - } - else - { - // signal MAC layer for each received frame if promiscuous is enabled - // otherwise only signal MAC layer for non-ACK frame - otEXPECT(sPromiscuous || (length != IEEE802154_ACK_LENGTH)); - - sReceiveError = OT_ERROR_NONE; - - // Set this flag only when the packet is really acknowledged with frame pending set. - framePending = wasAckedWithFramePending(sReceiveFrame.mPsdu, sReceiveFrame.mLength); - sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = framePending; - -#if OPENTHREAD_CONFIG_DIAG_ENABLE - - if (otPlatDiagModeGet()) - { - otPlatDiagRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError); - } - else -#endif - { - otLogInfoPlat("Received %d bytes", sReceiveFrame.mLength); - otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError); -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailPlatRadioReceiveDoneCbCount++; -#endif - } - if (!framePending) - { - RAIL_YieldRadio(gRailHandle); - } - } - otSysEventSignalPending(); - -exit: - - if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID) - { - RAIL_ReleaseRxPacket(gRailHandle, packetHandle); - } -} - -static void ieee802154DataRequestCommand(RAIL_Handle_t aRailHandle) -{ - RAIL_Status_t status = RAIL_STATUS_NO_ERROR; - - if (sIsSrcMatchEnabled) - { - RAIL_IEEE802154_Address_t sourceAddress; - - status = RAIL_IEEE802154_GetAddress(aRailHandle, &sourceAddress); - otEXPECT(status == RAIL_STATUS_NO_ERROR); - - if ((sourceAddress.length == RAIL_IEEE802154_LongAddress && - utilsSoftSrcMatchExtFindEntry((otExtAddress *)sourceAddress.longAddress) >= 0) || - (sourceAddress.length == RAIL_IEEE802154_ShortAddress && - utilsSoftSrcMatchShortFindEntry(sourceAddress.shortAddress) >= 0)) - { - status = RAIL_IEEE802154_SetFramePending(aRailHandle); - otEXPECT(status == RAIL_STATUS_NO_ERROR); - insertIeee802154DataRequestCommand(aRailHandle); - } - } - else - { - status = RAIL_IEEE802154_SetFramePending(aRailHandle); - otEXPECT(status == RAIL_STATUS_NO_ERROR); - insertIeee802154DataRequestCommand(aRailHandle); - } - -exit: - if (status == RAIL_STATUS_INVALID_STATE) - { - otLogWarnPlat("Too late to modify outgoing FP"); - } - else - { - assert(status == RAIL_STATUS_NO_ERROR); - } -} - -static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents) -{ -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - if (aEvents & RAIL_EVENT_CONFIG_SCHEDULED) - { - sRailDebugCounters.mRailEventConfigScheduled++; - } - if (aEvents & RAIL_EVENT_CONFIG_UNSCHEDULED) - { - sRailDebugCounters.mRailEventConfigUnScheduled++; - } -#endif - if (aEvents & RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND) - { - ieee802154DataRequestCommand(aRailHandle); - } - - if (aEvents & RAIL_EVENTS_TX_COMPLETION) - { - if (aEvents & RAIL_EVENT_TX_PACKET_SENT) - { - if ((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) - { - RAIL_YieldRadio(aRailHandle); - sTransmitError = OT_ERROR_NONE; - sTransmitBusy = false; - } -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventPacketSent++; -#endif - } - else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY) - { - RAIL_YieldRadio(aRailHandle); - sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE; - sTransmitBusy = false; -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventChannelBusy++; -#endif - } - else - { - RAIL_YieldRadio(aRailHandle); - sTransmitError = OT_ERROR_ABORT; - sTransmitBusy = false; -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventTxAbort++; -#endif - } - } - - if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT) - { - RAIL_YieldRadio(aRailHandle); - sTransmitError = OT_ERROR_NO_ACK; - sTransmitBusy = false; -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventNoAck++; -#endif - } - - if (aEvents & RAIL_EVENT_RX_PACKET_RECEIVED) - { - RAIL_HoldRxPacket(aRailHandle); -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventPacketReceived++; -#endif - } - - 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); - -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventCalNeeded++; -#endif - } - - if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE) - { - const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle); - RAIL_YieldRadio(aRailHandle); - - sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED; - - if (energyScanResultQuarterDbm == RAIL_RSSI_INVALID) - { - sEnergyScanResultDbm = OT_RADIO_RSSI_INVALID; - } - else - { - sEnergyScanResultDbm = energyScanResultQuarterDbm / QUARTER_DBM_IN_DBM; - } - -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailPlatRadioEnergyScanDoneCbCount++; -#endif - } - if (aEvents & RAIL_EVENT_SCHEDULER_STATUS) - { - RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle); - - assert(status != RAIL_SCHEDULER_STATUS_INTERNAL_ERROR); - - if (status == RAIL_SCHEDULER_STATUS_CCA_CSMA_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || - status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL || - (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy) || - (status == RAIL_SCHEDULER_STATUS_EVENT_INTERRUPTED && sTransmitBusy)) - { - sTransmitError = OT_ERROR_ABORT; - sTransmitBusy = false; -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventSchedulerStatusError++; -#endif - } - else if (status == RAIL_SCHEDULER_STATUS_AVERAGE_RSSI_FAIL) - { - sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED; - sEnergyScanResultDbm = OT_RADIO_RSSI_INVALID; - } -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - else if (sTransmitBusy) - { - sRailDebugCounters.mRailEventsSchedulerStatusLastStatus = status; - sRailDebugCounters.mRailEventsSchedulerStatusTransmitBusy++; - } -#endif - } - - otSysEventSignalPending(); -} - -otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration) -{ - OT_UNUSED_VARIABLE(aInstance); - - return efr32StartEnergyScan(ENERGY_SCAN_MODE_ASYNC, aScanChannel, (RAIL_Time_t)aScanDuration * US_IN_MS); -} - -void efr32RadioProcess(otInstance *aInstance) -{ - // We should process the received packet first. Adding it at the end of this function, - // will delay the stack notification until the next call to efr32RadioProcess() - processNextRxPacket(aInstance); - - if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false) - { - if (sTransmitError != OT_ERROR_NONE) - { - otLogDebgPlat("Transmit failed ErrorCode=%d", sTransmitError); - } - - sState = OT_RADIO_STATE_RECEIVE; -#if OPENTHREAD_CONFIG_DIAG_ENABLE - if (otPlatDiagModeGet()) - { - otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, sTransmitError); - } - else -#endif - if (((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) || (sTransmitError != OT_ERROR_NONE)) - { - otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, sTransmitError); - } - else - { - otPlatRadioTxDone(aInstance, &sTransmitFrame, &sReceiveFrame, sTransmitError); - } - -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailPlatRadioTxDoneCbCount++; -#endif - - otSysEventSignalPending(); - } - else if (sEnergyScanMode == ENERGY_SCAN_MODE_ASYNC && sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED) - { - sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE; - otPlatRadioEnergyScanDone(aInstance, sEnergyScanResultDbm); - otSysEventSignalPending(); - -#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT - sRailDebugCounters.mRailEventEnergyScanCompleted++; -#endif - } -} - otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower) { OT_UNUSED_VARIABLE(aInstance); @@ -1123,7 +1135,6 @@ otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower) otError error = OT_ERROR_NONE; otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS); - // RAIL_GetTxPowerDbm() returns power in deci-dBm (0.1dBm) // Divide by 10 because aPower is supposed be in units dBm *aPower = RAIL_GetTxPowerDbm(gRailHandle) / 10; @@ -1175,6 +1186,1448 @@ int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) return EFR32_RECEIVE_SENSITIVITY; } +otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration) +{ + OT_UNUSED_VARIABLE(aInstance); + + return efr32StartEnergyScan(ENERGY_SCAN_MODE_ASYNC, aScanChannel, (RAIL_Time_t)aScanDuration * US_IN_MS); +} + +//------------------------------------------------------------------------------ +// Enhanced Acks and CSL support + +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +void otPlatRadioSetMacKey(otInstance * aInstance, + uint8_t aKeyIdMode, + uint8_t aKeyId, + const otMacKey *aPrevKey, + const otMacKey *aCurrKey, + const otMacKey *aNextKey) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aKeyIdMode); + + assert(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL); + + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + + sKeyId = aKeyId; + memcpy(sPrevKey.m8, aPrevKey->m8, OT_MAC_KEY_SIZE); + memcpy(sCurrKey.m8, aCurrKey->m8, OT_MAC_KEY_SIZE); + memcpy(sNextKey.m8, aNextKey->m8, OT_MAC_KEY_SIZE); + + CORE_EXIT_ATOMIC(); +} + +void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter) +{ + OT_UNUSED_VARIABLE(aInstance); + + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + + sMacFrameCounter = aMacFrameCounter; + + CORE_EXIT_ATOMIC(); +} + +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, const otExtAddress *aExtAddr) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aExtAddr); + + sCslPeriod = aCslPeriod; + updateIeData(); + + return OT_ERROR_NONE; +} + +void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime) +{ + OT_UNUSED_VARIABLE(aInstance); + + sCslSampleTime = aCslSampleTime; +} +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE +otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled) +{ + OT_UNUSED_VARIABLE(aInstance); + + if (aEnabled && !sl_rail_util_coex_is_enabled()) + { + otLogInfoPlat("Coexistence GPIO configurations not set"); + return OT_ERROR_FAILED; + } + sRadioCoexEnabled = aEnabled; + return OT_ERROR_NONE; +} + +bool otPlatRadioIsCoexEnabled(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return (sRadioCoexEnabled && sl_rail_util_coex_is_enabled()); +} + +otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics) +{ + OT_UNUSED_VARIABLE(aInstance); + otError error = OT_ERROR_NONE; + + otEXPECT_ACTION(aCoexMetrics != NULL, error = OT_ERROR_INVALID_ARGS); + + memset(aCoexMetrics, 0, sizeof(otRadioCoexMetrics)); + // TO DO: + // Tracking coex metrics with detailed granularity currently + // not implemented. + // memcpy(aCoexMetrics, &sCoexMetrics, sizeof(otRadioCoexMetrics)); +exit: + return error; +} +#endif // OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE + +//------------------------------------------------------------------------------ + +// Return false if enhanced ACK is not required +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +static uint8_t getKeySourceLength(uint8_t keyIdMode) +{ + uint8_t len = 0; + + switch (keyIdMode) + { + case IEEE802154_KEYID_MODE_0: + len = IEEE802154_KEYID_MODE_0_SIZE; + break; + + case IEEE802154_KEYID_MODE_1: + len = IEEE802154_KEYID_MODE_1_SIZE; + break; + + case IEEE802154_KEYID_MODE_2: + len = IEEE802154_KEYID_MODE_2_SIZE; + break; + + case IEEE802154_KEYID_MODE_3: + len = IEEE802154_KEYID_MODE_3_SIZE; + break; + } + + return len; +} + +static bool writeIeee802154EnhancedAck(RAIL_Handle_t aRailHandle, const uint8_t *aIeData, uint8_t aIeLength) +{ + // This table is derived from 802.15.4-2015 Section 7.2.1.5 PAN ID + // Compression field and Table 7-2 for both 2003/2006 and 2015 + // frame versions. It is indexed by 6 bits of the MacFCF: + // SrcAdrMode FrameVer DstAdrMode PanIdCompression + // and each address' length is encoded in a nibble: + // 15:12 11:8 7:4 3:0 + // SrcAdr SrcPan DstAdr DstPan + // Illegal combinations are indicated by 0xFFFFU. + +#define ADDRSIZE_DST_PAN_SHIFT 0 +#define ADDRSIZE_DST_PAN_MASK (0x0FU << ADDRSIZE_DST_PAN_SHIFT) +#define ADDRSIZE_DST_ADR_SHIFT 4 +#define ADDRSIZE_DST_ADR_MASK (0x0FU << ADDRSIZE_DST_ADR_SHIFT) +#define ADDRSIZE_SRC_PAN_SHIFT 8 +#define ADDRSIZE_SRC_PAN_MASK (0x0FU << ADDRSIZE_SRC_PAN_SHIFT) +#define ADDRSIZE_SRC_ADR_SHIFT 12 +#define ADDRSIZE_SRC_ADR_MASK (0x0FU << ADDRSIZE_SRC_ADR_SHIFT) + + static const uint16_t ieee802154Table7p2[64] = { + 0x0000U, 0x0000U, 0xFFFFU, 0xFFFFU, 0x0022U, 0x0022U, 0x0082U, 0x0082U, 0x0000U, 0x0002U, 0xFFFFU, + 0xFFFFU, 0x0022U, 0x0020U, 0x0082U, 0x0080U, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, + 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0x2200U, + 0x2200U, 0xFFFFU, 0xFFFFU, 0x2222U, 0x2022U, 0x2282U, 0x2082U, 0x2200U, 0x2000U, 0xFFFFU, 0xFFFFU, + 0x2222U, 0x2022U, 0x2282U, 0x2082U, 0x8200U, 0x8200U, 0xFFFFU, 0xFFFFU, 0x8222U, 0x8022U, 0x8282U, + 0x8082U, 0x8200U, 0x8000U, 0xFFFFU, 0xFFFFU, 0x8222U, 0x8022U, 0x8082U, 0x8080U, + }; + + // For an Enhanced ACK, we need to generate that ourselves; + // RAIL will generate an Immediate ACK for us, though we can + // tell it to go out with its FramePending bit set. + // An 802.15.4 packet from RAIL should look like: + // 1/2 | 1/2 | 0/1 | 0/2 | 0/2/8 | 0/2 | 0/2/8 | 14 + // PHR | MacFCF | Seq# | DstPan | DstAdr | SrcPan | SrcAdr | SecHdr + + // With RAIL_IEEE802154_EnableEarlyFramePending(), RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND + // is triggered after receiving through the SrcAdr field of the packet, + // not the SecHdr which hasn't been received yet. + +#define EARLY_FRAME_PENDING_EXPECTED_BYTES (2U + 2U + 1U + 2U + 8U + 2U + 8U) +#define MAX_SECURED_EXPECTED_RECEIVED_BYTES (EARLY_FRAME_PENDING_EXPECTED_BYTES + 14U) +#define FINAL_PACKET_LENGTH_WITH_IE (MAX_SECURED_EXPECTED_RECEIVED_BYTES + aIeLength) + + RAIL_RxPacketInfo_t packetInfo; + uint8_t pkt[FINAL_PACKET_LENGTH_WITH_IE]; + + // TODO, in the original prototype for this code, this check was made to + // determine the PHY header length. + // When we add Sub-Ghz support, and we call RAIL_IEEE802154_ConfigGOptions, + // we should check for a 2-byte PHR. + // #if ("mac has channel pages" && IEEE802154_GB868_SUPPORTED) + // #define PHRLen ((emRadioChannelPageInUse == 0) ? 1 : 2) + // #else + // #define PHRLen 1 + uint8_t PHRLen = 1; + + uint8_t pktOffset = PHRLen; // No need to parse the PHR byte(s) + RAIL_GetRxIncomingPacketInfo(gRailHandle, &packetInfo); + + // Check if packetinfo.packetBytes includes the info we want, + // and if not, spin-wait calling RAIL_GetRxIncomingPacketInfo() + // until it has arrived + uint32_t startMs = otPlatAlarmMilliGetNow(); + while (packetInfo.packetBytes < MAX_SECURED_EXPECTED_RECEIVED_BYTES) + { + RAIL_GetRxIncomingPacketInfo(gRailHandle, &packetInfo); + if (otPlatAlarmMilliGetNow() - startMs > 100u) + { + // More than 100 ms. has elapsed. + break; + } + } + + if (packetInfo.packetBytes < (pktOffset + 2U)) + { + return false; + } + + // Only extract what we care about + if (packetInfo.packetBytes > MAX_SECURED_EXPECTED_RECEIVED_BYTES) + { + packetInfo.packetBytes = MAX_SECURED_EXPECTED_RECEIVED_BYTES; + if (packetInfo.firstPortionBytes >= MAX_SECURED_EXPECTED_RECEIVED_BYTES) + { + packetInfo.firstPortionBytes = MAX_SECURED_EXPECTED_RECEIVED_BYTES; + packetInfo.lastPortionData = NULL; + } + } + + RAIL_CopyRxPacket(pkt, &packetInfo); + uint16_t macFcf = pkt[pktOffset++]; + + if ((macFcf & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_MULTIPURPOSE) + { + // Multipurpose frames have an arcane FCF structure + if ((macFcf & IEEE802154_MP_FRAME_FLAG_LONG_FCF) != 0U) + { + macFcf |= (pkt[pktOffset++] << 8); + } + + // Map Multipurpose FCF to a 'normal' Version FCF as best we can. + macFcf = + (IEEE802154_FRAME_TYPE_MULTIPURPOSE | + ((macFcf & (IEEE802154_MP_FRAME_FLAG_SECURITY_ENABLED | IEEE802154_MP_FRAME_FLAG_IE_LIST_PRESENT)) >> 6) | + ((macFcf & IEEE802154_MP_FRAME_FLAG_FRAME_PENDING) >> 7) | + ((macFcf & IEEE802154_MP_FRAME_FLAG_ACK_REQUIRED) >> 9) | + ((macFcf & (IEEE802154_MP_FRAME_FLAG_PANID_PRESENT | IEEE802154_MP_FRAME_FLAG_SEQ_SUPPRESSION)) >> 2) | + ((macFcf & IEEE802154_MP_FRAME_DESTINATION_MODE_MASK) << 6) | IEEE802154_MP_FRAME_VERSION_2015 | + ((macFcf & IEEE802154_MP_FRAME_SOURCE_MODE_MASK) << 8)); + + // MultiPurpose's PANID_PRESENT is not equivalent to 2012/5's + // PANID_COMPRESSION so we map it best we can by flipping it + // in the following address-combination situations: + uint16_t addrCombo = (macFcf & (IEEE802154_FRAME_SOURCE_MODE_MASK | IEEE802154_FRAME_DESTINATION_MODE_MASK)); + if ((addrCombo == (IEEE802154_FRAME_SOURCE_MODE_NONE | IEEE802154_FRAME_DESTINATION_MODE_NONE)) || + (addrCombo == (IEEE802154_FRAME_SOURCE_MODE_SHORT | IEEE802154_FRAME_DESTINATION_MODE_SHORT)) || + (addrCombo == (IEEE802154_FRAME_SOURCE_MODE_SHORT | IEEE802154_FRAME_DESTINATION_MODE_LONG)) || + (addrCombo == (IEEE802154_FRAME_SOURCE_MODE_LONG | IEEE802154_FRAME_DESTINATION_MODE_SHORT))) + { + // 802.15.4-2015 PANID_COMPRESSION = MP PANID_PRESENT + } + else + { + // 802.15.4-2015 PANID_COMPRESSION = !MP PANID_PRESENT + macFcf ^= IEEE802154_FRAME_FLAG_PANID_COMPRESSION; // Flip it + } + } + else + { + macFcf |= (pkt[pktOffset++] << 8); + } + + bool enhAck = ((macFcf & IEEE802154_FRAME_VERSION_MASK) == IEEE802154_FRAME_VERSION_2015); + if (!enhAck) + { + return false; + } + + // Compress MAC FCF to index into 64-entry address-length table: + // SrcAdrMode FrameVer DstAdrMode PanIdCompression + // + // Note: Use IEEE802154_FRAME_VERSION_2012 rather than _MASK so the + // low-order bit of the version field isn't used in deriving the index. + uint16_t index = (((macFcf & (IEEE802154_FRAME_SOURCE_MODE_MASK | IEEE802154_FRAME_VERSION_2012)) >> 10) | + ((macFcf & IEEE802154_FRAME_DESTINATION_MODE_MASK) >> 9) | + ((macFcf & IEEE802154_FRAME_FLAG_PANID_COMPRESSION) >> 6)); + + uint16_t addrSizes = ieee802154Table7p2[index]; + // Illegal combinations mean illegal packets which we ignore + if (addrSizes == 0xFFFFU) + { + return false; + } + + uint8_t seqNo = + ((enhAck && ((macFcf & IEEE802154_FRAME_FLAG_SEQ_SUPPRESSION) != 0U)) ? 0U : pkt[pktOffset++]); // Seq# + + // Start writing the enhanced ACK -- we need to construct it since RAIL cannot. + + // First extract addresses from incoming packet since we may + // need to reflect them in a different order in the outgoing ACK. + // Use byte[0] to hold each one's length. + uint8_t dstPan[3] = { + 0, + }; // Initialized only to eliminate false gcc warning + dstPan[0] = ((addrSizes & ADDRSIZE_DST_PAN_MASK) >> ADDRSIZE_DST_PAN_SHIFT); + if ((dstPan[0] + pktOffset) > packetInfo.packetBytes) + { + return false; + } + + if (dstPan[0] > 0U) + { + dstPan[1] = pkt[pktOffset++]; + dstPan[2] = pkt[pktOffset++]; + } + + uint8_t dstAdr[9]; + dstAdr[0] = ((addrSizes & ADDRSIZE_DST_ADR_MASK) >> ADDRSIZE_DST_ADR_SHIFT); + if ((dstAdr[0] + pktOffset) > packetInfo.packetBytes) + { + return false; + } + + for (uint8_t i = 1U; i <= dstAdr[0]; i++) + { + dstAdr[i] = pkt[pktOffset++]; + } + + uint8_t srcPan[3]; + srcPan[0] = ((addrSizes & ADDRSIZE_SRC_PAN_MASK) >> ADDRSIZE_SRC_PAN_SHIFT); + if ((srcPan[0] + pktOffset) > packetInfo.packetBytes) + { + return false; + } + + if (srcPan[0] > 0U) + { + srcPan[1] = pkt[pktOffset++]; + srcPan[2] = pkt[pktOffset++]; + } + + uint8_t srcAdr[9]; + srcAdr[0] = ((addrSizes & ADDRSIZE_SRC_ADR_MASK) >> ADDRSIZE_SRC_ADR_SHIFT); + if ((srcAdr[0] + pktOffset) > packetInfo.packetBytes) + { + return false; + } + + for (uint8_t i = 1U; i <= srcAdr[0]; i++) + { + srcAdr[i] = pkt[pktOffset++]; + } + + // Once done with address fields, pick the security control (if present) + uint8_t securityHeader[1 + 4 + 8 + 1]; // max len: control + fc + key source + key ID + uint8_t securityHeaderLength = 0; + + if (macFcf & IEEE802154_FRAME_FLAG_SECURITY_ENABLED) + { + uint8_t securityControl = pkt[pktOffset]; + // Then the key ID + uint8_t keySourceLength = getKeySourceLength(securityControl & IEEE802154_KEYID_MODE_MASK); + securityHeaderLength += (sizeof(uint8_t) /* security control */ + + sizeof(uint32_t) /* frame counter */ + + keySourceLength + sizeof(uint8_t)); /* key ID */ + memcpy(securityHeader, pkt + pktOffset, securityHeaderLength); + pktOffset += securityHeaderLength; + } + + // Reuse packet[] buffer for outgoing Enhanced ACK. + // Phr1 Phr2 FcfL FcfH [Seq#] [DstPan] [DstAdr] [SrcPan] [SrcAdr] + // Will fill in PHR later. + // MAC Fcf: + // - Frame Type = ACK + // - Security Enabled, as appropriate + // - Frame Pending = 0 or as appropriate + // - ACK Request = 0 + // - PanId compression = incoming packet's + // - Seq# suppression = incoming packet's + // - IE Present = 0 in this implementation + // - DstAdrMode = SrcAdrMode of incoming packet's + // - Frame Version = 2 (154E) + // - SrcAdrMode = DstAdrMode of incoming packet's (for convenience) + uint16_t ackFcf = + (IEEE802154_FRAME_TYPE_ACK | (macFcf & IEEE802154_FRAME_FLAG_PANID_COMPRESSION) | + (macFcf & IEEE802154_FRAME_FLAG_SEQ_SUPPRESSION) | (macFcf & IEEE802154_FRAME_FLAG_SECURITY_ENABLED) | + IEEE802154_FRAME_VERSION_2015 | ((macFcf & IEEE802154_FRAME_SOURCE_MODE_MASK) >> 4) | + ((macFcf & IEEE802154_FRAME_DESTINATION_MODE_MASK) << 4)); + + // Do frame-pending check now + if (sIsSrcMatchEnabled) + { + bool setFramePending = true; + if (srcAdr[0] > 0U) + { + if (srcAdr[0] == 8U) + { + setFramePending = (utilsSoftSrcMatchExtFindEntry((otExtAddress *)&srcAdr[1]) >= 0); + } + else + { + uint16_t srcAdrShort = srcAdr[1] | (srcAdr[2] << 8); + setFramePending = (utilsSoftSrcMatchShortFindEntry(srcAdrShort) >= 0); + } + } + if (setFramePending) + { + ackFcf |= IEEE802154_FRAME_FLAG_FRAME_PENDING; + } + } + + pktOffset = PHRLen; + pkt[pktOffset++] = (uint8_t)ackFcf; + pkt[pktOffset++] = (uint8_t)(ackFcf >> 8); + + if ((macFcf & IEEE802154_FRAME_FLAG_SEQ_SUPPRESSION) == 0U) + { + pkt[pktOffset++] = seqNo; + } + + // Determine outgoing ACK's address field sizes + index = (((ackFcf & (IEEE802154_FRAME_SOURCE_MODE_MASK | IEEE802154_FRAME_VERSION_2012)) >> 10) | + ((ackFcf & IEEE802154_FRAME_DESTINATION_MODE_MASK) >> 9) | + ((ackFcf & IEEE802154_FRAME_FLAG_PANID_COMPRESSION) >> 6)); + + addrSizes = ieee802154Table7p2[index]; + if (addrSizes == 0xFFFFU) + { + // Uh-oh! Enh-ACK would be malformed?! Something funky happened! + // Possibly a latency-induced issue. + return false; + } + + // DstPan = SrcPan of incoming if avail otherwise DstPan of incoming + if ((addrSizes & ADDRSIZE_DST_PAN_MASK) != 0U) + { + if (srcPan[0] > 0U) + { + pkt[pktOffset++] = srcPan[1]; + pkt[pktOffset++] = srcPan[2]; + } + else if (dstPan[0] > 0U) + { + pkt[pktOffset++] = dstPan[1]; + pkt[pktOffset++] = dstPan[2]; + } + else + { + // Uh-oh! Outgoing packet needs a DstPanId but incoming had neither! + // Possibly a latency-induced issue. + return false; + } + } + + // DstAdr = SrcAdr of incoming packet -- their sizes should match + if ((addrSizes & ADDRSIZE_DST_ADR_MASK) != 0U) + { + for (uint8_t i = 1U; i <= srcAdr[0]; i++) + { + pkt[pktOffset++] = srcAdr[i]; + } + } + + // SrcPan = DstPan of incoming if avail otherwise SrcPan of incoming + if ((addrSizes & ADDRSIZE_SRC_PAN_MASK) != 0U) + { + if (dstPan[0] > 0U) + { + pkt[pktOffset++] = dstPan[1]; + pkt[pktOffset++] = dstPan[2]; + } + else if (srcPan[0] > 0U) + { + pkt[pktOffset++] = srcPan[1]; + pkt[pktOffset++] = srcPan[2]; + } + else + { + // Uh-oh! Outgoing packet needs a SrcPanId but incoming had neither! + // Possibly a latency-induced issue. + return false; + } + } + + // SrcAdr = DstAdr of incoming packet -- their sizes should match + if ((addrSizes & ADDRSIZE_SRC_ADR_MASK) != 0U) + { + for (uint8_t i = 1U; i <= dstAdr[0]; i++) + { + pkt[pktOffset++] = dstAdr[i]; + } + } + + if (ackFcf & IEEE802154_FRAME_FLAG_SECURITY_ENABLED) + { + memcpy(pkt + pktOffset, securityHeader, securityHeaderLength); + pktOffset += securityHeaderLength; + } + + // Now add the IE data + memcpy(pkt + pktOffset, aIeData, aIeLength); + pktOffset += aIeLength; + + // Fill in PHR now that we know Enh-ACK's length + if (PHRLen == 2U) // Not true till SubGhz implementation is in place + { + pkt[0] = (0x08U /*FCS=2byte*/ | 0x10U /*Whiten=enabled*/); + pkt[1] = (uint8_t)(__RBIT(pktOffset - 2U /*PHRLen*/ + 2U /*FCS*/) >> 24); + } + else + { + pkt[0] = (pktOffset - 1U /*PHRLen*/ + 2U /*FCS*/); + } + + processSecurityForEnhancedAck(pkt); + + return (RAIL_IEEE802154_WriteEnhAck(aRailHandle, pkt, pktOffset) == RAIL_STATUS_NO_ERROR); +} +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +//------------------------------------------------------------------------------ +// RAIL callbacks + +static void dataRequestCommandCallback(RAIL_Handle_t aRailHandle) +{ + // This callback occurs after the address fields of an incoming + // ACK-requesting CMD or DATA frame have been received and we + // can do a frame pending check. We must also figure out what + // kind of ACK is being requested -- Immediate or Enhanced. + +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 && OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE) + // Check if we need to write an enhanced ACK. + if (writeIeee802154EnhancedAck(aRailHandle, sAckIeData, sAckIeDataLength)) + { + return; + } +#endif + + // If not, RAIL will send an immediate ACK, but we need to do FP lookup. + RAIL_Status_t status = RAIL_STATUS_NO_ERROR; + + bool framePendingSet = false; + + if (sIsSrcMatchEnabled) + { + RAIL_IEEE802154_Address_t sourceAddress; + + status = RAIL_IEEE802154_GetAddress(aRailHandle, &sourceAddress); + otEXPECT(status == RAIL_STATUS_NO_ERROR); + + if ((sourceAddress.length == RAIL_IEEE802154_LongAddress && + utilsSoftSrcMatchExtFindEntry((otExtAddress *)sourceAddress.longAddress) >= 0) || + (sourceAddress.length == RAIL_IEEE802154_ShortAddress && + utilsSoftSrcMatchShortFindEntry(sourceAddress.shortAddress) >= 0)) + { + status = RAIL_IEEE802154_SetFramePending(aRailHandle); + otEXPECT(status == RAIL_STATUS_NO_ERROR); + framePendingSet = true; + } + } + else + { + status = RAIL_IEEE802154_SetFramePending(aRailHandle); + otEXPECT(status == RAIL_STATUS_NO_ERROR); + framePendingSet = true; + } + + if (framePendingSet) + { + // Store whether frame pending was set in the outgoing ACK in a reserved + // bit of the MAC header. + RAIL_RxPacketInfo_t packetInfo; + RAIL_GetRxIncomingPacketInfo(gRailHandle, &packetInfo); + + // skip length byte + otEXPECT(packetInfo.firstPortionBytes > 0); + packetInfo.firstPortionData++; + packetInfo.firstPortionBytes--; + packetInfo.packetBytes--; + + uint8_t *macFcfPointer = ((packetInfo.firstPortionBytes == 0) ? (uint8_t *)packetInfo.lastPortionData + : (uint8_t *)packetInfo.firstPortionData); + *macFcfPointer |= IEEE802154_FRAME_PENDING_SET_IN_OUTGOING_ACK; + } + +exit: + if (status == RAIL_STATUS_INVALID_STATE) + { + otLogWarnPlat("Too late to modify outgoing FP"); + } + else + { + assert(status == RAIL_STATUS_NO_ERROR); + } +} + +static void packetReceivedCallback(RAIL_RxPacketHandle_t packetHandle) +{ + RAIL_RxPacketInfo_t packetInfo; + RAIL_RxPacketDetails_t packetDetails; + uint16_t length; + bool framePendingInAck = false; + bool rxCorrupted = false; + + packetHandle = RAIL_GetRxPacketInfo(gRailHandle, packetHandle, &packetInfo); + otEXPECT_ACTION( + (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID && packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS), + rxCorrupted = true); + + otEXPECT_ACTION(validatePacketDetails(packetHandle, &packetDetails, &packetInfo, &length), rxCorrupted = true); + + // skip length byte + otEXPECT_ACTION(packetInfo.firstPortionBytes > 0, rxCorrupted = true); + packetInfo.firstPortionData++; + packetInfo.firstPortionBytes--; + packetInfo.packetBytes--; + + uint8_t macFcf = + ((packetInfo.firstPortionBytes == 0) ? packetInfo.lastPortionData[0] : packetInfo.firstPortionData[0]); + + if (packetDetails.isAck) + { + otEXPECT_ACTION( + (length == IEEE802154_ACK_LENGTH && (macFcf & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK), + rxCorrupted = true); + + // read packet + RAIL_CopyRxPacket(sReceiveAckFrame.mPsdu, &packetInfo); + sReceiveAckFrame.mLength = length; + + // Releasing the ACK frames here, ensures that the main thread (processNextRxPacket) + // is not wasting cycles, releasing the ACK frames from the Rx FIFO queue. + RAIL_ReleaseRxPacket(gRailHandle, packetHandle); + + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ENDED, (uint32_t)isReceivingFrame()); + + if (txWaitingForAck() && + (sReceiveAckFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])) + { + otEXPECT_ACTION(validatePacketTimestamp(&packetDetails, length), rxCorrupted = true); + updateRxFrameDetails(&packetDetails, false); + + // Processing the ACK frame in ISR context avoids the Tx state to be messed up, + // in case the Rx FIFO queue gets wiped out in a DMP situation. + sTransmitBusy = false; + sTransmitError = OT_ERROR_NONE; + setInternalFlag(FLAG_WAITING_FOR_ACK, false); + + framePendingInAck = ((macFcf & IEEE802154_FRAME_FLAG_FRAME_PENDING) != 0); + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_ACK_RECEIVED, (uint32_t)framePendingInAck); + + if (txIsDataRequest() && framePendingInAck) + { + emPendingData = true; + } + } + // Yield the radio upon receiving an ACK as long as it is not related to + // a data request. + if (!txIsDataRequest()) + { + RAIL_YieldRadio(gRailHandle); + } + } + else + { + otEXPECT_ACTION(sPromiscuous || (length != IEEE802154_ACK_LENGTH), rxCorrupted = true); + + if (macFcf & IEEE802154_FRAME_FLAG_ACK_REQUIRED) + { + (void)handlePhyStackEvent((RAIL_IsRxAutoAckPaused(gRailHandle) + ? SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ACK_BLOCKED + : SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ACKING), + (uint32_t)isReceivingFrame()); + setInternalFlag(FLAG_ONGOING_TX_ACK, true); + } + else + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ENDED, (uint32_t)isReceivingFrame()); + // We received a frame that does not require an ACK as result of a data + // poll: we yield the radio here. + if (emPendingData) + { + RAIL_YieldRadio(gRailHandle); + emPendingData = false; + } + } + } +exit: + if (rxCorrupted) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_CORRUPTED, (uint32_t)isReceivingFrame()); + } +} + +static void packetSentCallback(bool isAck) +{ + if (isAck) + { + // We successfully sent out an ACK. + setInternalFlag(FLAG_ONGOING_TX_ACK, false); + // We acked the packet we received after a poll: we can yield now. + if (emPendingData) + { + RAIL_YieldRadio(gRailHandle); + emPendingData = false; + } + } + else if (getInternalFlag(FLAG_ONGOING_TX_DATA)) + { + setInternalFlag(FLAG_ONGOING_TX_DATA, false); + + if (txWaitingForAck()) + { + setInternalFlag(FLAG_WAITING_FOR_ACK, true); + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_ACK_WAITING, 0U); + } + else + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_ENDED, 0U); + RAIL_YieldRadio(gRailHandle); + sTransmitError = OT_ERROR_NONE; + sTransmitBusy = false; + } +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventPacketSent++; +#endif + } +} + +static void txFailedCallback(bool isAck, uint8_t status) +{ + if (isAck) + { + setInternalFlag(FLAG_ONGOING_TX_ACK, false); + } + else if (getInternalFlag(FLAG_ONGOING_TX_DATA)) + { + if (status == TX_COMPLETE_RESULT_CCA_FAIL) + { + sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE; + setInternalFlag(FLAG_CURRENT_TX_USE_CSMA, false); +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventChannelBusy++; +#endif + } + else + { + sTransmitError = OT_ERROR_ABORT; +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventTxAbort++; +#endif + } + setInternalFlag(FLAG_ONGOING_TX_DATA, false); + RAIL_YieldRadio(gRailHandle); + sTransmitBusy = false; + } +} + +static void ackTimeoutCallback(void) +{ + assert(txWaitingForAck()); + assert(getInternalFlag(FLAG_WAITING_FOR_ACK)); + + sTransmitError = OT_ERROR_NO_ACK; + sTransmitBusy = false; +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventNoAck++; +#endif + +#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + // If antenna diversity is enabled toggle the selected antenna. + sl_rail_util_ant_div_toggle_antenna(); +#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + // TO DO: Check if we have an OT function that + // provides the number of mac retry attempts left + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_ACK_TIMEDOUT, 0); + + setInternalFlag(FLAG_WAITING_FOR_ACK, false); + RAIL_YieldRadio(gRailHandle); + emPendingData = false; +} + +static void schedulerEventCallback(RAIL_Handle_t aRailHandle) +{ + RAIL_SchedulerStatus_t status = RAIL_GetSchedulerStatus(aRailHandle); + assert(status != RAIL_SCHEDULER_STATUS_INTERNAL_ERROR); + + if (status == RAIL_SCHEDULER_STATUS_CCA_CSMA_TX_FAIL || status == RAIL_SCHEDULER_STATUS_SINGLE_TX_FAIL || + status == RAIL_SCHEDULER_STATUS_SCHEDULED_TX_FAIL || + (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sTransmitBusy) || + (status == RAIL_SCHEDULER_STATUS_EVENT_INTERRUPTED && sTransmitBusy)) + { + if (getInternalFlag(FLAG_ONGOING_TX_ACK)) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ACK_ABORTED, (uint32_t)isReceivingFrame()); + txFailedCallback(true, 0xFF); + } + // We were in the process of TXing a data frame, treat it as a CCA_FAIL. + if (getInternalFlag(FLAG_ONGOING_TX_DATA)) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_BLOCKED, (uint32_t)txWaitingForAck()); + txFailedCallback(false, TX_COMPLETE_RESULT_CCA_FAIL); + } + +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventSchedulerStatusError++; +#endif + } + else if (status == RAIL_SCHEDULER_STATUS_AVERAGE_RSSI_FAIL || + (status == RAIL_SCHEDULER_STATUS_SCHEDULE_FAIL && sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS)) + { + energyScanComplete(OT_RADIO_RSSI_INVALID); + } +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + else if (sTransmitBusy) + { + sRailDebugCounters.mRailEventsSchedulerStatusLastStatus = status; + sRailDebugCounters.mRailEventsSchedulerStatusTransmitBusy++; + } +#endif +} + +static void configUnscheduledCallback(void) +{ + // We are waiting for an ACK: we will never get the ACK we were waiting for. + // We want to call ackTimeoutCallback() only if the PACKET_SENT event + // already fired (which would clear the FLAG_ONGOING_TX_DATA flag). + if (getInternalFlag(FLAG_WAITING_FOR_ACK)) + { + ackTimeoutCallback(); + } + + // We are about to send an ACK, which it won't happen. + if (getInternalFlag(FLAG_ONGOING_TX_ACK)) + { + txFailedCallback(true, 0xFF); + } +} + +static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents) +{ +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + if (aEvents & (RAIL_EVENT_RX_SYNC1_DETECT | RAIL_EVENT_RX_SYNC2_DETECT)) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_STARTED, (uint32_t)isReceivingFrame()); + } +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + + if ((aEvents & RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND) +#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT + && !RAIL_IsRxAutoAckPaused(aRailHandle) +#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT + ) + { + dataRequestCommandCallback(aRailHandle); + } + +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + if (aEvents & RAIL_EVENT_RX_FILTER_PASSED) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ACCEPTED, (uint32_t)isReceivingFrame()); + } +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + + if (aEvents & RAIL_EVENT_TX_PACKET_SENT) + { + packetSentCallback(false); + } + else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_BLOCKED, (uint32_t)txWaitingForAck()); + txFailedCallback(false, TX_COMPLETE_RESULT_CCA_FAIL); + } + else if (aEvents & RAIL_EVENT_TX_BLOCKED) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_BLOCKED, (uint32_t)txWaitingForAck()); + txFailedCallback(false, TX_COMPLETE_RESULT_OTHER_FAIL); + } + else if (aEvents & (RAIL_EVENT_TX_UNDERFLOW | RAIL_EVENT_TX_ABORTED)) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_ABORTED, (uint32_t)txWaitingForAck()); + txFailedCallback(false, TX_COMPLETE_RESULT_OTHER_FAIL); + } + else + { + // Pre-completion aEvents are processed in their logical order: +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + if (aEvents & RAIL_EVENT_TX_START_CCA) + { + // We are starting RXWARM for a CCA check + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_CCA_SOON, 0U); + } + if (aEvents & RAIL_EVENT_TX_CCA_RETRY) + { + // We failed a CCA check and need to retry + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_CCA_BUSY, 0U); + } + if (aEvents & RAIL_EVENT_TX_CHANNEL_CLEAR) + { + // We're going on-air + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_STARTED, 0U); + } +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + } + + if (aEvents & RAIL_EVENT_RX_PACKET_RECEIVED) + { + packetReceivedCallback(RAIL_HoldRxPacket(aRailHandle)); +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventPacketReceived++; +#endif + } + +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + if (aEvents & RAIL_EVENT_RX_FRAME_ERROR) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_CORRUPTED, (uint32_t)isReceivingFrame()); + } + // The following 3 events cause us to not receive a packet + if (aEvents & (RAIL_EVENT_RX_PACKET_ABORTED | RAIL_EVENT_RX_ADDRESS_FILTERED | RAIL_EVENT_RX_FIFO_OVERFLOW)) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_FILTERED, (uint32_t)isReceivingFrame()); + } +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + + if (aEvents & RAIL_EVENT_TXACK_PACKET_SENT) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ACK_SENT, (uint32_t)isReceivingFrame()); + packetSentCallback(true); + } + if (aEvents & (RAIL_EVENT_TXACK_ABORTED | RAIL_EVENT_TXACK_UNDERFLOW)) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ACK_ABORTED, (uint32_t)isReceivingFrame()); + txFailedCallback(true, 0xFF); + } + if (aEvents & RAIL_EVENT_TXACK_BLOCKED) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_ACK_BLOCKED, (uint32_t)isReceivingFrame()); + txFailedCallback(true, 0xFF); + } + // Deal with ACK timeout after possible RX completion in case RAIL + // notifies us of the ACK and the timeout simultaneously -- we want + // the ACK to win over the timeout. + if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT) + { + if (getInternalFlag(FLAG_WAITING_FOR_ACK)) + { + ackTimeoutCallback(); + } + } + + if (aEvents & RAIL_EVENT_CONFIG_UNSCHEDULED) + { + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_RX_IDLED, 0U); + configUnscheduledCallback(); +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventConfigUnScheduled++; +#endif + } + + if (aEvents & RAIL_EVENT_CONFIG_SCHEDULED) + { +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventConfigScheduled++; +#endif + } + + if (aEvents & RAIL_EVENT_SCHEDULER_STATUS) + { + schedulerEventCallback(aRailHandle); + } + + if (aEvents & RAIL_EVENT_CAL_NEEDED) + { + RAIL_Status_t status; + + status = RAIL_Calibrate(aRailHandle, NULL, RAIL_CAL_ALL_PENDING); + // TODO: Non-RTOS DMP case fails +#if (!defined(SL_CATALOG_BLUETOOTH_PRESENT) || defined(SL_CATALOG_KERNEL_PRESENT)) + assert(status == RAIL_STATUS_NO_ERROR); +#endif + +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventCalNeeded++; +#endif + } + + if (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE) + { + const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle); + RAIL_YieldRadio(aRailHandle); + + energyScanComplete(energyScanResultQuarterDbm == RAIL_RSSI_INVALID + ? OT_RADIO_RSSI_INVALID + : (energyScanResultQuarterDbm / QUARTER_DBM_IN_DBM)); +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailPlatRadioEnergyScanDoneCbCount++; +#endif + } + + otSysEventSignalPending(); +} + +//------------------------------------------------------------------------------ +// Main thread packet handling + +static bool validatePacketDetails(RAIL_RxPacketHandle_t packetHandle, + RAIL_RxPacketDetails_t *pPacketDetails, + RAIL_RxPacketInfo_t * pPacketInfo, + uint16_t * packetLength) +{ + bool pktValid = true; + + otEXPECT_ACTION((RAIL_GetRxPacketDetailsAlt(gRailHandle, packetHandle, pPacketDetails) == RAIL_STATUS_NO_ERROR), + pktValid = false); + + // RAIL's packetBytes includes the 1-byte PHY header but not the 2-byte CRC + // We want *packetLength to match the PHY header length so we add 2 for CRC + // and subtract 1 for PHY header. + *packetLength = pPacketInfo->packetBytes + 1; + + // check the length in recv packet info structure; RAIL should take care of this. + otEXPECT_ACTION(*packetLength == pPacketInfo->firstPortionData[0], pktValid = false); + + // check the length validity of recv packet; RAIL should take care of this. + otEXPECT_ACTION((*packetLength >= IEEE802154_MIN_LENGTH && *packetLength <= IEEE802154_MAX_LENGTH), + pktValid = false); +exit: + return pktValid; +} + +static bool validatePacketTimestamp(RAIL_RxPacketDetails_t *pPacketDetails, uint16_t packetLength) +{ + bool rxTimestampValid = true; + + // Get the timestamp when the SFD was received + otEXPECT_ACTION(pPacketDetails->timeReceived.timePosition != RAIL_PACKET_TIME_INVALID, rxTimestampValid = false); + + // + 1 for the 1-byte PHY header + pPacketDetails->timeReceived.totalPacketBytes = packetLength + 1; + + otEXPECT_ACTION((RAIL_GetRxTimeSyncWordEndAlt(gRailHandle, pPacketDetails) == RAIL_STATUS_NO_ERROR), + rxTimestampValid = false); +exit: + return rxTimestampValid; +} + +static void updateRxFrameDetails(RAIL_RxPacketDetails_t *pPacketDetails, bool framePendingSetInOutgoingAck) +{ + assert(pPacketDetails != NULL); + + if (pPacketDetails->isAck) + { + sReceiveAckFrame.mInfo.mRxInfo.mRssi = pPacketDetails->rssi; + sReceiveAckFrame.mInfo.mRxInfo.mLqi = pPacketDetails->lqi; + sReceiveAckFrame.mInfo.mRxInfo.mTimestamp = pPacketDetails->timeReceived.packetTime; + } + else + { + sReceiveFrame.mInfo.mRxInfo.mRssi = pPacketDetails->rssi; + sReceiveFrame.mInfo.mRxInfo.mLqi = pPacketDetails->lqi; + sReceiveFrame.mInfo.mRxInfo.mTimestamp = pPacketDetails->timeReceived.packetTime; + // Set this flag only when the packet is really acknowledged with frame pending set. + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = framePendingSetInOutgoingAck; + } +} + +static void processNextRxPacket(otInstance *aInstance) +{ + RAIL_RxPacketHandle_t packetHandle = RAIL_RX_PACKET_HANDLE_INVALID; + RAIL_RxPacketInfo_t packetInfo; + RAIL_RxPacketDetails_t packetDetails; + RAIL_Status_t status; + uint16_t length; + bool rxProcessDone = false; + + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + + packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE, &packetInfo); + otEXPECT_ACTION( + (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID && packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS), + packetHandle = RAIL_RX_PACKET_HANDLE_INVALID); + + otEXPECT(validatePacketDetails(packetHandle, &packetDetails, &packetInfo, &length)); + + // skip length byte + otEXPECT(packetInfo.firstPortionBytes > 0); + packetInfo.firstPortionData++; + packetInfo.firstPortionBytes--; + packetInfo.packetBytes--; + + // As received ACK frames are already processed in packetReceivedCallback, + // we only need to read and process the non-ACK frames here. + otEXPECT(sPromiscuous || (!packetDetails.isAck && (length != IEEE802154_ACK_LENGTH))); + + // read packet + RAIL_CopyRxPacket(sReceiveFrame.mPsdu, &packetInfo); + sReceiveFrame.mLength = length; + + uint8_t *macFcfPointer = sReceiveFrame.mPsdu; + + // Check the reserved bit in the MAC header to see whether the frame pending + // bit was set in the outgoing ACK + // Then, clear it. + bool framePendingSetInOutgoingAck = ((*macFcfPointer & IEEE802154_FRAME_PENDING_SET_IN_OUTGOING_ACK) != 0); + *macFcfPointer &= ~IEEE802154_FRAME_PENDING_SET_IN_OUTGOING_ACK; + + status = RAIL_ReleaseRxPacket(gRailHandle, packetHandle); + if (status == RAIL_STATUS_NO_ERROR) + { + packetHandle = RAIL_RX_PACKET_HANDLE_INVALID; + } + + otEXPECT(validatePacketTimestamp(&packetDetails, length)); + updateRxFrameDetails(&packetDetails, framePendingSetInOutgoingAck); + rxProcessDone = true; + +exit: + if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID) + { + RAIL_ReleaseRxPacket(gRailHandle, packetHandle); + } + CORE_EXIT_ATOMIC(); + + // signal MAC layer + if (rxProcessDone) + { + sReceiveError = OT_ERROR_NONE; + +#if OPENTHREAD_CONFIG_DIAG_ENABLE + if (otPlatDiagModeGet()) + { + otPlatDiagRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError); + } + else +#endif + { + otLogInfoPlat("Received %d bytes", sReceiveFrame.mLength); + otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError); +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailPlatRadioReceiveDoneCbCount++; +#endif + } + otSysEventSignalPending(); + } +} + +static void processTxComplete(otInstance *aInstance) +{ + if (sState == OT_RADIO_STATE_TRANSMIT && sTransmitBusy == false) + { + if (sTransmitError != OT_ERROR_NONE) + { + otLogDebgPlat("Transmit failed ErrorCode=%d", sTransmitError); + } + + sState = OT_RADIO_STATE_RECEIVE; +#if OPENTHREAD_CONFIG_DIAG_ENABLE + if (otPlatDiagModeGet()) + { + otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, sTransmitError); + } + else +#endif + if (((sTransmitFrame.mPsdu[0] & IEEE802154_FRAME_FLAG_ACK_REQUIRED) == 0) || + (sTransmitError != OT_ERROR_NONE)) + { + otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, sTransmitError); + } + else + { + otPlatRadioTxDone(aInstance, &sTransmitFrame, &sReceiveAckFrame, sTransmitError); + } + +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailPlatRadioTxDoneCbCount++; +#endif + otSysEventSignalPending(); + } +} + +void efr32RadioProcess(otInstance *aInstance) +{ + (void)handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TICK, 0U); + + // We should process the received packet first. Adding it at the end of this function, + // will delay the stack notification until the next call to efr32RadioProcess() + processNextRxPacket(aInstance); + processTxComplete(aInstance); + + if (sEnergyScanMode == ENERGY_SCAN_MODE_ASYNC && sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED) + { + sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE; + otPlatRadioEnergyScanDone(aInstance, sEnergyScanResultDbm); + otSysEventSignalPending(); + +#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT + sRailDebugCounters.mRailEventEnergyScanCompleted++; +#endif + } +} + +//------------------------------------------------------------------------------ +// Antenn Diveristy, Wifi coexistence and Run time PHY select support + +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT + +otError setRadioState(otRadioState state) +{ + otError error = OT_ERROR_NONE; + + // Defer idling the radio if we have an ongoing TX task + otEXPECT_ACTION((!getInternalFlag(ONGOING_TX_FLAGS)), error = OT_ERROR_FAILED); + + switch (state) + { + case OT_RADIO_STATE_RECEIVE: + otEXPECT_ACTION(radioSetRx(sReceiveFrame.mChannel) == OT_ERROR_NONE, error = OT_ERROR_FAILED); + break; + case OT_RADIO_STATE_SLEEP: + radioSetIdle(); + break; + default: + error = OT_ERROR_FAILED; + } +exit: + return error; +} + +void sl_ot_update_active_radio_config(void) +{ + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + + // Proceed with PHY selection only if 2.4 GHz band is used + otEXPECT(sBandConfig.mChannelConfig == NULL); + + otRadioState currentState = sState; + otEXPECT(setRadioState(OT_RADIO_STATE_SLEEP) == OT_ERROR_NONE); + sl_rail_util_plugin_config_2p4ghz_radio(gRailHandle); + otEXPECT(setRadioState(currentState) == OT_ERROR_NONE); + +exit: + CORE_EXIT_ATOMIC(); + return; +} +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT + +#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT +void efr32AntennaConfigInit(void) +{ + RAIL_Status_t status; + sl_rail_util_ant_div_init(); + status = sl_rail_util_ant_div_update_antenna_config(); + assert(status == RAIL_STATUS_NO_ERROR); +} +#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + +static void changeDynamicEvents(void) +{ + const RAIL_Events_t eventMask = + RAIL_EVENTS_NONE | RAIL_EVENT_RX_SYNC1_DETECT | RAIL_EVENT_RX_SYNC2_DETECT | RAIL_EVENT_RX_FRAME_ERROR | + RAIL_EVENT_RX_FIFO_OVERFLOW | RAIL_EVENT_RX_ADDRESS_FILTERED | RAIL_EVENT_RX_PACKET_ABORTED | + RAIL_EVENT_RX_FILTER_PASSED | RAIL_EVENT_TX_CHANNEL_CLEAR | RAIL_EVENT_TX_CCA_RETRY | RAIL_EVENT_TX_START_CCA; + RAIL_Events_t eventValues = RAIL_EVENTS_NONE; + + if (phyStackEventIsEnabled()) + { + eventValues |= eventMask; + } + updateEvents(eventMask, eventValues); +} +#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + +static void efr32PhyStackInit(void) +{ +#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + efr32AntennaConfigInit(); +#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT + +#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT + efr32CoexInit(); +#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT + +#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_STACK_EVENT_PRESENT + changeDynamicEvents(); +#endif +} + +#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT + +static void emRadioEnableAutoAck(void) +{ + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + + if (getInternalFlag(FLAG_RADIO_INIT_DONE)) + { + if ((rhoActive >= RHO_INT_ACTIVE) // Internal always holds ACKs + || ((rhoActive > RHO_INACTIVE) && ((sl_rail_util_coex_get_options() & SL_RAIL_UTIL_COEX_OPT_ACK_HOLDOFF) != + SL_RAIL_UTIL_COEX_OPT_DISABLED))) + { + RAIL_PauseRxAutoAck(gRailHandle, true); + } + else + { + RAIL_PauseRxAutoAck(gRailHandle, false); + } + } + CORE_EXIT_ATOMIC(); +} + +static void emRadioEnablePta(bool enable) +{ + halInternalInitPta(); + + // When PTA is enabled, we want to negate PTA_REQ as soon as an incoming + // frame is aborted, e.g. due to filtering. To do that we must turn off + // the TRACKABFRAME feature that's normally on to benefit sniffing on PTI. + assert(RAIL_ConfigRxOptions(gRailHandle, RAIL_RX_OPTION_TRACK_ABORTED_FRAMES, + (enable ? RAIL_RX_OPTIONS_NONE : RAIL_RX_OPTION_TRACK_ABORTED_FRAMES)) == + RAIL_STATUS_NO_ERROR); +} + +static void efr32CoexInit(void) +{ + sl_rail_util_coex_options_t coexOptions = sl_rail_util_coex_get_options(); + +#if SL_OPENTHREAD_COEX_MAC_HOLDOFF_ENABLE + coexOptions |= SL_RAIL_UTIL_COEX_OPT_MAC_HOLDOFF; +#endif // SL_OPENTHREAD_COEX_MAC_HOLDOFF_ENABLE + + sl_rail_util_coex_set_options(coexOptions); + + emRadioEnableAutoAck(); // Might suspend AutoACK if RHO already in effect + emRadioEnablePta(sl_rail_util_coex_is_enabled()); +} + +// Managing radio transmission +static void onPtaGrantTx(sl_rail_util_coex_req_t ptaStatus) +{ + // Only pay attention to first PTA Grant callback, ignore any further ones + if (ptaGntEventReported) + { + return; + } + ptaGntEventReported = true; + + assert(ptaStatus == SL_RAIL_UTIL_COEX_REQCB_GRANTED); + // PTA is telling us we've gotten GRANT and should send ASAP *without* CSMA + setInternalFlag(FLAG_CURRENT_TX_USE_CSMA, false); + txCurrentPacket(); +} + +static void tryTxCurrentPacket(void) +{ + assert(getInternalFlag(FLAG_ONGOING_TX_DATA)); + + ptaGntEventReported = false; + sl_rail_util_ieee802154_stack_event_t ptaStatus = + handlePhyStackEvent(SL_RAIL_UTIL_IEEE802154_STACK_EVENT_TX_PENDED_MAC, (uint32_t)&onPtaGrantTx); + if (ptaStatus == SL_RAIL_UTIL_IEEE802154_STACK_STATUS_SUCCESS) + { + // Normal case where PTA allows us to start the (CSMA) transmit below + txCurrentPacket(); + } + else if (ptaStatus == SL_RAIL_UTIL_IEEE802154_STACK_STATUS_CB_PENDING) + { + // onPtaGrantTx() callback will take over (and might already have) + } + else if (ptaStatus == SL_RAIL_UTIL_IEEE802154_STACK_STATUS_HOLDOFF) + { + txFailedCallback(false, TX_COMPLETE_RESULT_OTHER_FAIL); + } +} + +// Managing CCA Threshold +static void setCcaThreshold(void) +{ + if (sCcaThresholdDbm == CCA_THRESHOLD_UNINIT) + { + sCcaThresholdDbm = CCA_THRESHOLD_DEFAULT; + } + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + int8_t thresholddBm = sCcaThresholdDbm; + + if (getInternalFlag(FLAG_RADIO_INIT_DONE)) + { + if (rhoActive > RHO_INACTIVE) + { + thresholddBm = RAIL_RSSI_INVALID_DBM; + } + assert(RAIL_SetCcaThreshold(gRailHandle, thresholddBm) == RAIL_STATUS_NO_ERROR); + } + CORE_EXIT_ATOMIC(); +} + +static void emRadioHoldOffInternalIsr(uint8_t active) +{ + if (active != rhoActive) + { + rhoActive = active; // Update rhoActive early + if (getInternalFlag(FLAG_RADIO_INIT_DONE)) + { + setCcaThreshold(); + emRadioEnableAutoAck(); + } + } +} + +// External API used by Coex Component +void emRadioHoldOffIsr(bool active) +{ + emRadioHoldOffInternalIsr((uint8_t)active | (rhoActive & ~RHO_EXT_ACTIVE)); +} + +#if SL_OPENTHREAD_COEX_COUNTER_ENABLE + +void sl_rail_util_coex_counter_on_event(sl_rail_util_coex_event_t event) +{ + otEXPECT(event < SL_RAIL_UTIL_COEX_EVENT_COUNT); + sCoexCounters[event] += 1; +exit: + return; +} + +void efr32RadioGetCoexCounters(uint32_t (*aCoexCounters)[SL_RAIL_UTIL_COEX_EVENT_COUNT]) +{ + memset((void *)aCoexCounters, 0, sizeof(*aCoexCounters)); + memcpy(aCoexCounters, sCoexCounters, sizeof(*aCoexCounters)); +} + +void efr32RadioClearCoexCounters(void) +{ + memset((void *)sCoexCounters, 0, sizeof(sCoexCounters)); +} + +#endif // SL_OPENTHREAD_COEX_COUNTER_ENABLE +#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT + RAIL_AntennaConfig_t halAntennaConfig; void initAntenna(void) diff --git a/examples/platforms/efr32/src/system.c b/examples/platforms/efr32/src/system.c index 493cc6740..4b9baced6 100644 --- a/examples/platforms/efr32/src/system.c +++ b/examples/platforms/efr32/src/system.c @@ -55,15 +55,11 @@ #include "em_system.h" #include "hal-config.h" #include "hal_common.h" +#include "platform-efr32.h" #include "rail.h" +#include "sl_device_init_nvic.h" #include "sl_mpu.h" #include "sl_sleeptimer.h" -#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE -#include "sl_malloc.h" -#include "openthread/heap.h" -#endif - -#include "platform-efr32.h" #if (HAL_FEM_ENABLE) #include "fem-control.h" @@ -170,15 +166,8 @@ void otSysInit(int argc, char *argv[]) __disable_irq(); -#undef FIXED_EXCEPTION -#define FIXED_EXCEPTION(vectorNumber, functionName, deviceIrqn, deviceIrqHandler) -#define EXCEPTION(vectorNumber, functionName, deviceIrqn, deviceIrqHandler, priorityLevel, subpriority) \ - NVIC_SetPriority(deviceIrqn, NVIC_EncodePriority(PRIGROUP_POSITION - 1, priorityLevel, subpriority)); -#include NVIC_CONFIG -#undef EXCEPTION - - NVIC_SetPriorityGrouping(PRIGROUP_POSITION - 1); CHIP_Init(); + sl_device_init_nvic(); halInitChipSpecific(); BSP_Init(BSP_INIT_BCC); diff --git a/examples/platforms/efr32/src/uart.c b/examples/platforms/efr32/src/uart.c index 0ba169fca..9769577da 100644 --- a/examples/platforms/efr32/src/uart.c +++ b/examples/platforms/efr32/src/uart.c @@ -33,6 +33,7 @@ */ #include +#include #include "openthread-system.h" #include @@ -43,6 +44,15 @@ #include "uartdrv.h" #include "hal-config.h" +#include "sl_uartdrv_usart_vcom_config.h" + +#define HELPER1(x) USART##x##_RX_IRQn +#define HELPER2(x) HELPER1(x) +#define USART_IRQ HELPER2(SL_UARTDRV_USART_VCOM_PERIPHERAL_NO) + +#define HELPER3(x) USART##x##_RX_IRQHandler +#define HELPER4(x) HELPER3(x) +#define USART_IRQHandler HELPER4(SL_UARTDRV_USART_VCOM_PERIPHERAL_NO) enum { @@ -89,9 +99,15 @@ static const UARTDRV_InitUart_t USART_INIT = { static UARTDRV_HandleData_t sUartHandleData; static UARTDRV_Handle_t sUartHandle = &sUartHandleData; -static uint8_t sReceiveBuffer[2]; -static const uint8_t * sTransmitBuffer = NULL; -static volatile uint16_t sTransmitLength = 0; + +// In order to reduce the probability of data loss due to disabled interrupts, we use +// two duplicate receive buffers so we can always have one "active" receive request. +#define RECEIVE_BUFFER_SIZE 128 +static uint8_t sReceiveBuffer1[RECEIVE_BUFFER_SIZE]; +static uint8_t sReceiveBuffer2[RECEIVE_BUFFER_SIZE]; +static const uint8_t * sTransmitBuffer = NULL; +static volatile uint16_t sTransmitLength = 0; +static uint8_t lastCount = 0; typedef struct ReceiveFifo_t { @@ -109,14 +125,17 @@ static void processReceive(void); static void receiveDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount) { + OT_UNUSED_VARIABLE(aStatus); + // We can only write if incrementing mTail doesn't equal mHead - if (sReceiveFifo.mHead != (sReceiveFifo.mTail + 1) % kReceiveFifoSize) + if (sReceiveFifo.mHead != (sReceiveFifo.mTail + aCount - lastCount) % kReceiveFifoSize) { - sReceiveFifo.mBuffer[sReceiveFifo.mTail] = aData[0]; - sReceiveFifo.mTail = (sReceiveFifo.mTail + 1) % kReceiveFifoSize; + memcpy(sReceiveFifo.mBuffer + sReceiveFifo.mTail, aData + lastCount, aCount - lastCount); + sReceiveFifo.mTail = (sReceiveFifo.mTail + aCount - lastCount) % kReceiveFifoSize; + lastCount = 0; } - UARTDRV_Receive(aHandle, aData, 1, receiveDone); + UARTDRV_Receive(aHandle, aData, aCount, receiveDone); otSysEventSignalPending(); } @@ -133,6 +152,16 @@ static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aDa static void processReceive(void) { + uint8_t * aData; + UARTDRV_Count_t aCount, remaining; + CORE_ATOMIC_SECTION(UARTDRV_GetReceiveStatus(sUartHandle, &aData, &aCount, &remaining); + + if (aCount > lastCount) { + memcpy(sReceiveFifo.mBuffer + sReceiveFifo.mTail, aData + lastCount, aCount - lastCount); + sReceiveFifo.mTail = (sReceiveFifo.mTail + aCount - lastCount) % kReceiveFifoSize; + lastCount = aCount; + }) + // Copy tail to prevent multiple reads uint16_t tail = sReceiveFifo.mTail; @@ -169,6 +198,11 @@ static void processTransmit(void) } } +void USART_IRQHandler(void) +{ + otSysEventSignalPending(); +} + otError otPlatUartEnable(void) { UARTDRV_InitUart_t uartInit = USART_INIT; @@ -178,10 +212,15 @@ otError otPlatUartEnable(void) UARTDRV_Init(sUartHandle, &uartInit); - for (uint8_t i = 0; i < sizeof(sReceiveBuffer); i++) - { - UARTDRV_Receive(sUartHandle, &sReceiveBuffer[i], sizeof(sReceiveBuffer[i]), receiveDone); - } + // When one receive request is completed, the other buffer is used for a separate receive request, issued + // immediately. + UARTDRV_Receive(sUartHandle, sReceiveBuffer1, RECEIVE_BUFFER_SIZE, receiveDone); + UARTDRV_Receive(sUartHandle, sReceiveBuffer2, RECEIVE_BUFFER_SIZE, receiveDone); + + // Enable USART0 interrupt to wake OT task when data arrives + NVIC_ClearPendingIRQ(USART_IRQ); + NVIC_EnableIRQ(USART_IRQ); + USART_IntEnable(SL_UARTDRV_USART_VCOM_PERIPHERAL, USART_IF_RXDATAV); return OT_ERROR_NONE; } diff --git a/third_party/silabs/Makefile.am b/third_party/silabs/Makefile.am index 1a4830452..ae8eb643e 100644 --- a/third_party/silabs/Makefile.am +++ b/third_party/silabs/Makefile.am @@ -29,6 +29,9 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am include $(top_srcdir)/examples/platforms/efr32/efr32_platform_defs.am +# ============================================================================== +# Which libraries to build +# ============================================================================== lib_LIBRARIES = $(NULL) if !OPENTHREAD_ENABLE_BUILTIN_MBEDTLS @@ -61,6 +64,9 @@ lib_LIBRARIES += $(NULL) endif +# ============================================================================== +# Compiler flags +# ============================================================================== # Do not enable -Wshadow for Silicon Labs SDK sources override CFLAGS := $(filter-out -Wshadow,$(CFLAGS)) @@ -70,87 +76,77 @@ override CXXFLAGS := $(filter-out -Wshadow,$(CXXFLAGS)) override CFLAGS := $(filter-out -Wcast-align,$(CFLAGS)) override CXXFLAGS := $(filter-out -Wcast-align,$(CXXFLAGS)) -# ============================================================================= -SILABS_MBEDTLS_DIR = $(SDK_SRC_DIR)/util/third_party/mbedtls +# ============================================================================== +# Silabs Gecko SDK mbedtls +# ============================================================================== -SILABS_MBEDTLS_CPPFLAGS = \ - $(MBEDTLS_CPPFLAGS) \ - -I$(SILABS_MBEDTLS_DIR)/configs \ - -I$(SILABS_MBEDTLS_DIR)/include \ - -I$(SILABS_MBEDTLS_DIR)/sl_crypto/include \ - -I$(SDK_SRC_DIR)/platform/radio/rail_lib/common \ - -I$(SDK_SRC_DIR)/util/silicon_labs/silabs_core/memory_manager \ - -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/se_manager/inc/ \ - -I$(SDK_SRC_DIR)/platform/common/inc/ \ +SILABS_MBEDTLS_DIR = $(SDK_SRC_DIR)/util/third_party/crypto/mbedtls + +SILABS_MBEDTLS_CPPFLAGS = \ + $(MBEDTLS_CPPFLAGS) \ + -I$(SILABS_MBEDTLS_DIR)/include \ + -I$(SILABS_MBEDTLS_DIR)/include/mbedtls \ + -I$(SILABS_MBEDTLS_DIR)/library \ + -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/sl_alt/include \ + -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/sl_mbedtls_support/config \ + -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/sl_mbedtls_support/inc \ + -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/sl_mbedtls_support/inc/configs \ + -I$(SDK_SRC_DIR)/util/third_party/crypto/sl_component/sl_psa_driver/inc \ + -I$(SDK_SRC_DIR)/util/silicon_labs/silabs_core/memory_manager \ + -I$(SDK_SRC_DIR)/platform/CMSIS/Include \ + -I$(SDK_SRC_DIR)/platform/common/inc/ \ + -I$(SDK_SRC_DIR)/platform/emlib/inc \ + -I$(SDK_SRC_DIR)/platform/radio/rail_lib/common \ $(NULL) -SILABS_MBEDTLS_SOURCES = \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_crypto.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/aes.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/asn1parse.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/asn1write.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/base64.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/bignum.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ccm.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/cipher_wrap.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/cipher.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/cmac.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ctr_drbg.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/des.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ecdh.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ecdsa.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ecjpake.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ecp_curves.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ecp.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/entropy.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/error.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/md_wrap.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/md.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/oid.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/pem.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/pk_wrap.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/pk.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/pkparse.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/platform_util.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/rsa_internal.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/rsa.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/sha1.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/sha256.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/sha512.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ssl_cache.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ssl_ciphersuites.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ssl_cli.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ssl_cookie.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ssl_srv.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ssl_ticket.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ssl_tls.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/threading.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/x509_create.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/x509_crl.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/x509_crt.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/x509_csr.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/x509.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/x509write_crt.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/x509write_csr.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_aes.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_ecp.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_management.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_sha.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/entropy_adc.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/entropy_rail.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_aes.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_ccm.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_cmac.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_ecp.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_jpake.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_management.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_sha.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/se_trng.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/shax.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/sl_mbedtls.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/trng.c \ - gecko_sdk_suite/v3.0/util/silicon_labs/silabs_core/memory_manager/sl_malloc.c \ +SILABS_MBEDTLS_SOURCES = \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/aes.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/asn1parse.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/asn1write.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/base64.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/bignum.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ccm.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/cipher_wrap.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/cipher.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/cmac.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ctr_drbg.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/des.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ecdh.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ecdsa.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ecjpake.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ecp_curves.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ecp.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/entropy.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/error.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/md.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/oid.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/pem.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/pk_wrap.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/pk.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/pkparse.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/platform_util.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/platform.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/rsa_internal.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/rsa.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/sha256.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_cache.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_ciphersuites.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_cli.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_cookie.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_msg.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_srv.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_ticket.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/ssl_tls.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/threading.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/x509_create.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/x509_crl.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/x509_crt.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/x509_csr.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/x509.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/x509write_crt.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/mbedtls/library/x509write_csr.c \ + gecko_sdk_suite/v3.1/util/silicon_labs/silabs_core/memory_manager/sl_malloc.c \ $(NULL) libsilabs_mbedtls_a_CPPFLAGS = \ @@ -162,7 +158,9 @@ libsilabs_mbedtls_a_SOURCES = $(NULL) -# ============================================================================= +# ============================================================================== +# Gecko SDK +# ============================================================================== COMMONCPPFLAGS = \ -I$(srcdir) \ @@ -179,70 +177,136 @@ COMMONCPPFLAGS = -Wno-missing-field-initializers \ $(NULL) -SILABS_COMMON_SOURCES = \ - rail_config/rail_config.c \ - gecko_sdk_suite/v3.0/hardware/kit/common/bsp/bsp_bcc.c \ - gecko_sdk_suite/v3.0/hardware/kit/common/bsp/bsp_init.c \ - gecko_sdk_suite/v3.0/hardware/kit/common/bsp/bsp_stk.c \ - gecko_sdk_suite/v3.0/hardware/kit/common/bsp/bsp_stk_leds.c \ - gecko_sdk_suite/v3.0/platform/emdrv/dmadrv/src/dmadrv.c \ - gecko_sdk_suite/v3.0/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c \ - gecko_sdk_suite/v3.0/platform/emdrv/nvm3/src/nvm3_default_common_linker.c \ - gecko_sdk_suite/v3.0/platform/emdrv/nvm3/src/nvm3_hal_flash.c \ - gecko_sdk_suite/v3.0/platform/emdrv/nvm3/src/nvm3_lock.c \ - gecko_sdk_suite/v3.0/platform/emdrv/uartdrv/src/uartdrv.c \ - gecko_sdk_suite/v3.0/platform/emdrv/ustimer/src/ustimer.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_adc.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_cmu.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_core.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_emu.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_gpio.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_ldma.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_leuart.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_msc.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_rmu.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_rtcc.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_system.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_timer.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_usart.c \ - gecko_sdk_suite/v3.0/platform/radio/rail_lib/hal/efr32/hal_efr.c \ - gecko_sdk_suite/v3.0/platform/radio/rail_lib/hal/hal_common.c \ - gecko_sdk_suite/v3.0/platform/radio/rail_lib/plugin/pa-conversions/pa_conversions_efr32.c \ - gecko_sdk_suite/v3.0/platform/service/mpu/src/sl_mpu.c \ - gecko_sdk_suite/v3.0/platform/service/sleeptimer/src/sl_sleeptimer.c \ - gecko_sdk_suite/v3.0/platform/service/sleeptimer/src/sl_sleeptimer_hal_rtcc.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/library/ecp.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_aes.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_ecp.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_management.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/crypto_sha.c \ - gecko_sdk_suite/v3.0/util/third_party/mbedtls/sl_crypto/src/shax.c \ +SILABS_COMMON_SOURCES = \ + rail_config/rail_config.c \ + gecko_sdk_suite/v3.1/hardware/kit/common/bsp/bsp_bcc.c \ + gecko_sdk_suite/v3.1/hardware/kit/common/bsp/bsp_init.c \ + gecko_sdk_suite/v3.1/hardware/kit/common/bsp/bsp_stk.c \ + gecko_sdk_suite/v3.1/hardware/kit/common/bsp/bsp_stk_leds.c \ + gecko_sdk_suite/v3.1/platform/emdrv/dmadrv/src/dmadrv.c \ + gecko_sdk_suite/v3.1/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c \ + gecko_sdk_suite/v3.1/platform/emdrv/nvm3/src/nvm3_default_common_linker.c \ + gecko_sdk_suite/v3.1/platform/emdrv/nvm3/src/nvm3_hal_flash.c \ + gecko_sdk_suite/v3.1/platform/emdrv/nvm3/src/nvm3_lock.c \ + gecko_sdk_suite/v3.1/platform/emdrv/uartdrv/src/uartdrv.c \ + gecko_sdk_suite/v3.1/platform/emdrv/ustimer/src/ustimer.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_cmu.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_core.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_emu.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_gpio.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_ldma.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_msc.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_rmu.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_rtcc.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_system.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_timer.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_usart.c \ + gecko_sdk_suite/v3.1/platform/radio/rail_lib/hal/efr32/hal_efr.c \ + gecko_sdk_suite/v3.1/platform/radio/rail_lib/hal/hal_common.c \ + gecko_sdk_suite/v3.1/platform/radio/rail_lib/plugin/pa-conversions/pa_conversions_efr32.c \ + gecko_sdk_suite/v3.1/platform/service/mpu/src/sl_mpu.c \ + gecko_sdk_suite/v3.1/platform/service/device_init/src/sl_device_init_nvic.c \ + gecko_sdk_suite/v3.1/platform/service/sleeptimer/src/sl_sleeptimer.c \ + gecko_sdk_suite/v3.1/platform/service/sleeptimer/src/sl_sleeptimer_hal_rtcc.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/source/sl_entropy.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/source/sl_mbedtls.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/mbedtls_sha.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_psa_driver_init.c \ $(NULL) + +# ============================================================================== +# Series-level _SOURCES +# ============================================================================== +SILABS_EFR32MG1X_SOURCES = \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_adc.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_crypto.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_leuart.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/crypto_aes.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/crypto_ecp.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/crypto_management.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_aead.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_cipher.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_hash.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_mac.c \ + $(NULL) + +SILABS_EFR32MG2X_SOURCES = \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_burtc.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_prs.c \ + gecko_sdk_suite/v3.1/platform/emlib/src/em_se.c \ + gecko_sdk_suite/v3.1/platform/service/sleeptimer/src/sl_sleeptimer_hal_burtc.c \ + gecko_sdk_suite/v3.1/platform/service/sleeptimer/src/sl_sleeptimer_hal_prortc.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_attestation.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_cipher.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_entropy.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_hash.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_key_derivation.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_key_handling.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_signature.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager_util.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/se_manager/src/sl_se_manager.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/source/sl_se_management.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/mbedtls_cmac.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/mbedtls_ecdsa_ecdh.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/se_aes.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/se_ccm.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_mbedtls_support/src/se_jpake.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_driver_aead.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_driver_builtin_keys.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_driver_cipher.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_driver_key_derivation.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_driver_key_management.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_driver_mac.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_driver_signature.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_opaque_driver_aead.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_opaque_driver_cipher.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_opaque_driver_mac.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_opaque_key_derivation.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_transparent_driver_aead.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_transparent_driver_cipher.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_transparent_driver_hash.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_transparent_driver_mac.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_psa_driver/src/sli_se_transparent_key_derivation.c \ + $(NULL) + + +# ============================================================================== +# Platform-level _SOURCES +# ============================================================================== + SILABS_EFR32MG1_SOURCES = \ - gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG1P/Source/system_efr32mg1p.c \ - gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG1P/Source/GCC/startup_efr32mg1p.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG1P/Source/system_efr32mg1p.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG1P/Source/GCC/startup_efr32mg1p.c \ + gecko_sdk_suite/v3.1/util/third_party/crypto/sl_component/sl_alt/source/sl_entropy_adc.c \ + $(SILABS_EFR32MG1X_SOURCES) \ $(NULL) SILABS_EFR32MG12_SOURCES = \ - gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \ - gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \ + $(SILABS_EFR32MG1X_SOURCES) \ $(NULL) -SILABS_EFR32MG13_SOURCES = \ - gecko_sdk_suite/v3.0/hardware/kit/common/drivers/mx25flash_spi.c \ - gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG13P/Source/system_efr32mg13p.c \ - gecko_sdk_suite/v3.0//platform/Device/SiliconLabs/EFR32MG13P/Source/GCC/startup_efr32mg13p.c \ +SILABS_EFR32MG13_SOURCES = \ + gecko_sdk_suite/v3.1/hardware/kit/common/drivers/mx25flash_spi.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG13P/Source/system_efr32mg13p.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG13P/Source/GCC/startup_efr32mg13p.c \ + $(SILABS_EFR32MG1X_SOURCES) \ $(NULL) SILABS_EFR32MG21_SOURCES = \ - gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG21/Source/system_efr32mg21.c \ - gecko_sdk_suite/v3.0/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/startup_efr32mg21.c \ - gecko_sdk_suite/v3.0/platform/emlib/src/em_se.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG21/Source/system_efr32mg21.c \ + gecko_sdk_suite/v3.1/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/startup_efr32mg21.c \ + $(SILABS_EFR32MG2X_SOURCES) $(NULL) + +# ============================================================================== + libsilabs_efr32mg1_sdk_a_CPPFLAGS = \ $(SILABS_EFR32MG1_CPPFLAGS) \ + $(SILABS_MBEDTLS_CPPFLAGS) \ $(COMMONCPPFLAGS) \ $(NULL) @@ -253,6 +317,7 @@ libsilabs_efr32mg1_sdk_a_SOURCES libsilabs_efr32mg12_sdk_a_CPPFLAGS = \ $(SILABS_EFR32MG12_CPPFLAGS) \ + $(SILABS_MBEDTLS_CPPFLAGS) \ $(COMMONCPPFLAGS) \ $(NULL) @@ -263,6 +328,7 @@ libsilabs_efr32mg12_sdk_a_SOURCES libsilabs_efr32mg13_sdk_a_CPPFLAGS = \ $(SILABS_EFR32MG13_CPPFLAGS) \ + $(SILABS_MBEDTLS_CPPFLAGS) \ $(COMMONCPPFLAGS) \ $(NULL) @@ -273,6 +339,7 @@ libsilabs_efr32mg13_sdk_a_SOURCES libsilabs_efr32mg21_sdk_a_CPPFLAGS = \ $(SILABS_EFR32MG21_CPPFLAGS) \ + $(SILABS_MBEDTLS_CPPFLAGS) \ $(COMMONCPPFLAGS) \ $(NULL) @@ -282,7 +349,7 @@ libsilabs_efr32mg21_sdk_a_SOURCES $(NULL) noinst_HEADERS = \ - $(NULL) + $(NULL) include $(abs_top_nlbuild_autotools_dir)/automake/post.am