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