[efr32] add mg21 support and changes to mg12 radio inteface code (#3922)

* renamed efr32 in two for mg12 and mg21 and radio changes for mg12

Change to radio interface code, check the txBusy flag before
attempting to transmit a packet Cleaner auto state transition code and
safer event handling Use HAL_PA_VOLTAGE in all hal-config.h files

* uart flow control mode is configured from board /hal-config.h

Allows a different flow control mode for each EFR32 board as
necessary.  (hw flow control is not presently implemented on
Thunderboard Sense so HAL_USART_FLOW_CONTROL_NONE mode should be used
for BRD4166A, other boards use HAL_USART_FLOW_CONTROL_HWUART)
This commit is contained in:
Marven Gilhespie
2019-07-02 18:43:28 +02:00
committed by Jonathan Hui
parent af46ffa53b
commit 0bb0b7424d
62 changed files with 3736 additions and 193 deletions
+21 -11
View File
@@ -1691,12 +1691,12 @@ AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_ECDSA], [${OPENTHREAD_ENABLE_ECDSA}], [Def
AC_ARG_WITH(examples,
[AS_HELP_STRING([--with-examples=TARGET],
[Specify the examples from one of: none, posix, cc1352, cc2538, cc2650, cc2652, efr32, emsk, gp712, kw41z, nrf52811, nrf52840, qpg6095, samr21 @<:@default=none@:>@.])],
[Specify the examples from one of: none, posix, cc1352, cc2538, cc2650, cc2652, efr32mg12, efr32mg21, emsk, gp712, kw41z, nrf52811, nrf52840, qpg6095, samr21 @<:@default=none@:>@.])],
[
case "${with_examples}" in
none)
;;
posix|cc1352|cc2538|cc2650|cc2652|efr32|emsk|gp712|kw41z|nrf52811|nrf52840|qpg6095|samr21)
posix|cc1352|cc2538|cc2650|cc2652|efr32mg12|efr32mg21|emsk|gp712|kw41z|nrf52811|nrf52840|qpg6095|samr21)
if test ${enable_posix_app} = "yes"; then
AC_MSG_ERROR([--with-examples must be none when POSIX apps are enabled by --enable-posix-app])
fi
@@ -1737,9 +1737,14 @@ case ${with_examples} in
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_CC2652],[${OPENTHREAD_EXAMPLES_CC2652}],[Define to 1 if you want to use cc2652 examples])
;;
efr32)
OPENTHREAD_EXAMPLES_EFR32=1
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_EFR32],[${OPENTHREAD_EXAMPLES_EFR32}],[Define to 1 if you want to use efr32 examples])
efr32mg12)
OPENTHREAD_EXAMPLES_EFR32MG12=1
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_EFR32MG12],[${OPENTHREAD_EXAMPLES_EFR32MG12}],[Define to 1 if you want to use efr32mg12 examples])
;;
efr32mg21)
OPENTHREAD_EXAMPLES_EFR32MG21=1
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_EFR32MG21],[${OPENTHREAD_EXAMPLES_EFR32MG21}],[Define to 1 if you want to use efr32mg21 examples])
;;
emsk)
@@ -1801,8 +1806,11 @@ AM_CONDITIONAL([OPENTHREAD_EXAMPLES_CC2650], [test "${with_examples}" = "cc2650"
AC_SUBST(OPENTHREAD_EXAMPLES_CC2652)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_CC2652], [test "${with_examples}" = "cc2652"])
AC_SUBST(OPENTHREAD_EXAMPLES_EFR32)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32], [test "${with_examples}" = "efr32"])
AC_SUBST(OPENTHREAD_EXAMPLES_EFR32MG12)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32MG12], [test "${with_examples}" = "efr32mg12"])
AC_SUBST(OPENTHREAD_EXAMPLES_EFR32MG21)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32MG21], [test "${with_examples}" = "efr32mg21"])
AC_SUBST(OPENTHREAD_EXAMPLES_EMSK)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EMSK], [test "${with_examples}" = "emsk"])
@@ -1965,6 +1973,7 @@ third_party/Makefile
third_party/jlink/Makefile
third_party/mbedtls/Makefile
third_party/NordicSemiconductor/Makefile
third_party/silabs/Makefile
examples/Makefile
examples/apps/Makefile
examples/apps/cli/Makefile
@@ -1974,10 +1983,11 @@ examples/platforms/cc1352/Makefile
examples/platforms/cc2538/Makefile
examples/platforms/cc2650/Makefile
examples/platforms/cc2652/Makefile
examples/platforms/efr32/Makefile
examples/platforms/efr32/sleepy-demo/Makefile
examples/platforms/efr32/sleepy-demo/efr32-sleepy-demo-ftd/Makefile
examples/platforms/efr32/sleepy-demo/efr32-sleepy-demo-mtd/Makefile
examples/platforms/efr32mg12/Makefile
examples/platforms/efr32mg12/sleepy-demo/Makefile
examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-ftd/Makefile
examples/platforms/efr32mg12/sleepy-demo/sleepy-demo-mtd/Makefile
examples/platforms/efr32mg21/Makefile
examples/platforms/emsk/Makefile
examples/platforms/gp712/Makefile
examples/platforms/kw41z/Makefile
@@ -50,7 +50,7 @@ configure_OPTIONS = \
--with-ncp-bus=uart \
--enable-radio-only \
--enable-linker-map \
--with-examples=efr32 \
--with-examples=efr32mg12 \
MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)" \
$(NULL)
@@ -90,19 +90,19 @@ endif
EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"efr32-mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -D$(MCU)
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/crypto
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.5/util/third_party/mbedtls/configs
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.5/platform/CMSIS/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.5/util/third_party/mbedtls/sl_crypto/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.5/platform/Device/SiliconLabs/EFR32MG12P/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/inc
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.5/platform/radio/rail_lib/chip/efr32/efr32xg1x
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32mg12/crypto
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/util/third_party/mbedtls/configs
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/CMSIS/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG12P/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/emlib/inc
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/chip/efr32/efr32xg1x
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls
CONFIG_FILE = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-efr32-config.h\"'
CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32/
CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32mg12/
HAL_CONF_DIR = $(CONFIG_FILE_PATH)/$(shell echo $(BOARD) | tr A-Z a-z)
COMMONCFLAGS := \
@@ -161,7 +161,7 @@ ResultPath = output
TopResultDir = $(ResultPath)
AbsTopResultDir = $(PWD)/$(TopResultDir)
TargetTuple = efr32
TargetTuple = efr32mg12
ARCHS = cortex-m4
+298
View File
@@ -0,0 +1,298 @@
#
# Copyright (c) 2019, 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.
#
.NOTPARALLEL:
AR = arm-none-eabi-ar
CCAS = arm-none-eabi-as
CPP = arm-none-eabi-cpp
CC = arm-none-eabi-gcc
CXX = arm-none-eabi-g++
LD = arm-none-eabi-ld
STRIP = arm-none-eabi-strip
NM = arm-none-eabi-nm
RANLIB = arm-none-eabi-ranlib
OBJCOPY = arm-none-eabi-objcopy
BuildJobs ?= 10
configure_OPTIONS = \
--enable-cli \
--enable-diag \
--enable-ftd \
--enable-mtd \
--enable-ncp \
--with-ncp-bus=uart \
--enable-radio-only \
--enable-linker-map \
--with-examples=efr32mg21 \
MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)" \
$(NULL)
ifneq ($(DISABLE_BUILTIN_MBEDTLS), 1)
configure_OPTIONS += MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)"
endif
TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
#
# Differentiate between boards
# - BRD4180A / SLWSTK6000B / Wireless Starter Kit / 2.4GHz@20dBm
#
ifeq ($(BOARD),BRD4180A)
MCU = EFR32MG21A020F1024IM32
else
$(error Please provide a value for BOARD variable e.g BOARD=BRD4180A (currently supported BRD4180A))
endif
EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"efr32-mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -D$(MCU)
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32mg21/crypto
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/util/third_party/mbedtls/configs
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/CMSIS/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG21/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/emlib/inc
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/chip/efr32/efr32xg2x
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v2.6/hardware/kit/common/drivers
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/mbedtls/repo/include/mbedtls
CONFIG_FILE = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-efr32-config.h\"'
CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/efr32mg21/
HAL_CONF_DIR = $(CONFIG_FILE_PATH)/$(shell echo $(BOARD) | tr A-Z a-z)
COMMONCFLAGS := \
-fdata-sections \
-ffunction-sections \
-Os \
-g \
-D$(CONFIG_FILE) \
-I$(CONFIG_FILE_PATH) \
-I$(HAL_CONF_DIR) \
-D$(MCU) \
$(NULL)
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
CPPFLAGS += \
$(COMMONCFLAGS) \
$(target_CPPFLAGS) \
$(NULL)
CFLAGS += \
$(COMMONCFLAGS) \
$(target_CFLAGS) \
$(NULL)
CXXFLAGS += \
$(COMMONCFLAGS) \
$(target_CXXFLAGS) \
-fno-exceptions \
-fno-rtti \
$(NULL)
LDFLAGS += \
$(COMMONCFLAGS) \
$(target_LDFLAGS) \
-nostartfiles \
-specs=nano.specs \
-specs=nosys.specs \
-Wl,--gc-sections \
$(NULL)
ECHO := @echo
MAKE := make
MKDIR_P := mkdir -p
LN_S := ln -s
RM_F := rm -f
INSTALL := /usr/bin/install
INSTALLFLAGS := -p
BuildPath = build
TopBuildDir = $(BuildPath)
AbsTopBuildDir = $(PWD)/$(TopBuildDir)
ResultPath = output
TopResultDir = $(ResultPath)
AbsTopResultDir = $(PWD)/$(TopResultDir)
TargetTuple = efr32mg21
ARCHS = cortex-m33
TopTargetLibDir = $(TopResultDir)/$(TargetTuple)/lib
ifndef BuildJobs
BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
endif
JOBSFLAG := -j$(BuildJobs)
#
# configure-arch <arch>
#
# Configure OpenThread for the specified architecture.
#
# arch - The architecture to configure.
#
define configure-arch
$(ECHO) " CONFIG $(TargetTuple)..."
(cd $(BuildPath)/$(TargetTuple) && $(AbsTopSourceDir)/configure \
INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
CPP="$(CPP)" CC="$(CC)" CXX="$(CXX)" OBJC="$(OBJC)" OBJCXX="$(OBJCXX)" AR="$(AR)" RANLIB="$(RANLIB)" NM="$(NM)" STRIP="$(STRIP)" CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
--host=arm-none-eabi \
--prefix=/ \
--exec-prefix=/$(TargetTuple) \
$(configure_OPTIONS))
endef # configure-arch
#
# build-arch <arch>
#
# Build the OpenThread intermediate build products for the specified
# architecture.
#
# arch - The architecture to build.
#
define build-arch
$(ECHO) " BUILD $(TargetTuple)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
all
endef # build-arch
#
# stage-arch <arch>
#
# Stage (install) the OpenThread final build products for the specified
# architecture.
#
# arch - The architecture to stage.
#
define stage-arch
$(ECHO) " STAGE $(TargetTuple)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(TargetTuple) --no-print-directory \
DESTDIR=$(AbsTopResultDir) \
install
endef # stage-arch
#
# ARCH_template <arch>
#
# Define macros, targets and rules to configure, build, and stage the
# OpenThread for a single architecture.
#
# arch - The architecture to instantiate the template for.
#
define ARCH_template
CONFIGURE_TARGETS += configure-$(1)
BUILD_TARGETS += do-build-$(1)
STAGE_TARGETS += stage-$(1)
BUILD_DIRS += $(BuildPath)/$(TargetTuple)
DIRECTORIES += $(BuildPath)/$(TargetTuple)
configure-$(1): target_CPPFLAGS=$($(1)_target_CPPFLAGS)
configure-$(1): target_CFLAGS=$($(1)_target_CFLAGS)
configure-$(1): target_CXXFLAGS=$($(1)_target_CXXFLAGS)
configure-$(1): target_LDFLAGS=$($(1)_target_LDFLAGS)
configure-$(1): $(BuildPath)/$(TargetTuple)/config.status
$(BuildPath)/$(TargetTuple)/config.status: | $(BuildPath)/$(TargetTuple)
$$(call configure-arch,$(1))
do-build-$(1): configure-$(1)
do-build-$(1):
+$$(call build-arch,$(1))
stage-$(1): do-build-$(1)
stage-$(1): | $(TopResultDir)
$$(call stage-arch,$(1))
$(1): stage-$(1)
endef # ARCH_template
.DEFAULT_GOAL := all
all: stage
#
# cortex-m33
#
cortex-m33_target_ABI = cortex-m33
cortex-m33_target_CPPFLAGS = -mcpu=cortex-m33 -mthumb -fmessage-length=0 -ffunction-sections -fdata-sections -mfpu=fpv5-sp-d16 -mfloat-abi=hard
cortex-m33_target_CFLAGS = -mcpu=cortex-m33 -mthumb -fmessage-length=0 -ffunction-sections -fdata-sections -mfpu=fpv5-sp-d16 -mfloat-abi=hard
cortex-m33_target_CXXFLAGS = -mcpu=cortex-m33 -mthumb -fmessage-length=0 -ffunction-sections -fdata-sections -mfpu=fpv5-sp-d16 -mfloat-abi=hard
cortex-m33_target_LDFLAGS = -mcpu=cortex-m33 -mthumb -fmessage-length=0 -ffunction-sections -fdata-sections -mfpu=fpv5-sp-d16 -mfloat-abi=hard
# Instantiate an architecture-specific build template for each target
# architecture.
$(foreach arch,$(ARCHS),$(eval $(call ARCH_template,$(arch))))
#
# Common / Finalization
#
configure: $(CONFIGURE_TARGETS)
build: $(BUILD_TARGETS)
stage: $(STAGE_TARGETS)
DIRECTORIES = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
CLEAN_DIRS = $(TopResultDir) $(BUILD_DIRS)
all: stage
$(DIRECTORIES):
$(ECHO) " MKDIR $@"
@$(MKDIR_P) "$@"
clean:
$(ECHO) " CLEAN"
@$(RM_F) -r $(CLEAN_DIRS)
help:
$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
$(ECHO) "architectures: "
$(ECHO) ""
$(ECHO) " $(ARCHS)"
$(ECHO) ""
$(ECHO) "To build only a particular architecture, specify: "
$(ECHO) ""
$(ECHO) " make -f $(firstword $(MAKEFILE_LIST)) <architecture>"
$(ECHO) ""
+10 -4
View File
@@ -35,7 +35,8 @@ DIST_SUBDIRS = \
cc2538 \
cc2650 \
cc2652 \
efr32 \
efr32mg12 \
efr32mg21 \
emsk \
gp712 \
kw41z \
@@ -69,8 +70,12 @@ if OPENTHREAD_EXAMPLES_CC2652
SUBDIRS += cc2652
endif
if OPENTHREAD_EXAMPLES_EFR32
SUBDIRS += efr32
if OPENTHREAD_EXAMPLES_EFR32MG12
SUBDIRS += efr32mg12
endif
if OPENTHREAD_EXAMPLES_EFR32MG21
SUBDIRS += efr32mg21
endif
if OPENTHREAD_EXAMPLES_EMSK
@@ -116,7 +121,8 @@ PRETTY_SUBDIRS = \
cc2538 \
cc2650 \
cc2652 \
efr32 \
efr32mg12 \
efr32mg21 \
emsk \
gp712 \
kw41z \
+6 -2
View File
@@ -57,8 +57,12 @@ if OPENTHREAD_EXAMPLES_CC2652
include $(top_srcdir)/examples/platforms/cc2652/Makefile.platform.am
endif
if OPENTHREAD_EXAMPLES_EFR32
include $(top_srcdir)/examples/platforms/efr32/Makefile.platform.am
if OPENTHREAD_EXAMPLES_EFR32MG12
include $(top_srcdir)/examples/platforms/efr32mg12/Makefile.platform.am
endif
if OPENTHREAD_EXAMPLES_EFR32MG21
include $(top_srcdir)/examples/platforms/efr32mg21/Makefile.platform.am
endif
if OPENTHREAD_EXAMPLES_EMSK
@@ -28,7 +28,7 @@
include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
lib_LIBRARIES = libopenthread-efr32.a
lib_LIBRARIES = libopenthread-efr32mg12.a
# Do not enable -Wconversion for rail
override CFLAGS := $(filter-out -Wconversion,$(CFLAGS))
@@ -40,12 +40,12 @@ override CXXFLAGS := $(filter-out -pedantic-errors,$(
EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a-z)
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.5
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6
libopenthread_efr32_a_CPPFLAGS = \
libopenthread_efr32mg12_a_CPPFLAGS = \
-D__START=main \
-D__STARTUP_CLEAR_BSS \
-DPLATFORM_HEADER=\"@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/base/hal/micro/cortexm3/compiler/gcc.h\" \
-DPLATFORM_HEADER=\"@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.6/platform/base/hal/micro/cortexm3/compiler/gcc.h\" \
-Wno-sign-compare \
-DCORTEXM3 \
-DPHY=EMBER_PHY_RAIL \
@@ -54,7 +54,7 @@ libopenthread_efr32_a_CPPFLAGS =
-DPLAT=EMBER_PLATFORM_CORTEXM3 \
-I$(top_srcdir)/include \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/examples/platforms/efr32/$(EFR32_BOARD_DIR) \
-I$(top_srcdir)/examples/platforms/efr32mg12/$(EFR32_BOARD_DIR) \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/third_party/silabs/rail_config \
-I$(EFR32MG_SDK_SRCDIR) \
@@ -107,42 +107,12 @@ PLATFORM_SOURCES =
uart.c \
$(NULL)
nodist_libopenthread_efr32_a_SOURCES = \
@top_builddir@/third_party/silabs/rail_config/rail_config.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/hardware/kit/common/bsp/bsp_bcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/hardware/kit/common/bsp/bsp_init.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/hardware/kit/common/bsp/bsp_stk.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/hardware/kit/common/bsp/bsp_stk_leds.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emdrv/dmadrv/src/dmadrv.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emdrv/rtcdrv/src/rtcdriver.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emdrv/uartdrv/src/uartdrv.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emdrv/ustimer/src/ustimer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_adc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_cmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_core.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_crypto.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_emu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_gpio.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_ldma.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_leuart.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_msc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_rmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_rtcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_system.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_timer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/emlib/src/em_usart.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/radio/rail_lib/hal/efr32/hal_efr.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/radio/rail_lib/hal/hal_common.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/util/third_party/mbedtls/library/ecp.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/util/third_party/mbedtls/sl_crypto/src/crypto_aes.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/util/third_party/mbedtls/sl_crypto/src/crypto_ecp.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/util/third_party/mbedtls/sl_crypto/src/crypto_management.c \
noinst_HEADERS = \
platform-efr32.h \
platform-band.h \
$(NULL)
libopenthread_efr32_a_SOURCES = \
libopenthread_efr32mg12_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NULL)
@@ -151,7 +121,7 @@ PRETTY_FILES =
$(NULL)
Dash = -
libopenthread_efr32_a_LIBADD = \
libopenthread_efr32mg12_a_LIBADD = \
$(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o") \
$(shell find $(top_builddir)/third_party/jlink/SEGGER_RTT_V640/RTT $(Dash)type f $(Dash)name "*.o")
@@ -27,14 +27,15 @@
#
#
# efr32 platform-specific Makefile
# efr32mg12 platform-specific Makefile
#
LDADD_COMMON += \
$(top_builddir)/examples/platforms/efr32/libopenthread-efr32.a \
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.5/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \
$(top_builddir)/examples/platforms/efr32mg12/libopenthread-efr32mg12.a \
$(top_builddir)/third_party/silabs/libsilabs-efr32mg12-sdk.a \
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \
$(NULL)
LDFLAGS_COMMON += \
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.5/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
$(NULL)
@@ -1,6 +1,6 @@
# OpenThread on EFR32 Example
# OpenThread on EFR32MG12 Example
This directory contains example platform drivers for the [Silicon Labs EFR32][efr32mg]
This directory contains example platform drivers for the [Silicon Labs EFR32MG12][efr32mg12]
based on [EFR32™ Mighty Gecko Wireless Starter Kit][SLWSTK6000B] or [Thunderboard™ Sense 2 Sensor-to-Cloud Advanced IoT Development Kit][SLTB004A].
[efr32mg]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc
@@ -10,11 +10,11 @@ based on [EFR32™ Mighty Gecko Wireless Starter Kit][SLWSTK6000B] or [Thunderbo
The example platform drivers are intended to present the minimal code
necessary to support OpenThread. [EFR32MG12P SoC][efr32mg12p]
has rich memory and peripheral resources which can support all OpenThread
capabilities. See the "Run the example with EFR32 boards" section below
capabilities. See the "Run the example with EFR32MG12 boards" section below
for an example using basic OpenThread capabilities.
See [sleepy-demo/README.md](sleepy-demo/README.md) for instructions for an example that uses the low-energy
modes of the EFR32 when running as a Sleepy End Device.
modes of the EFR32MG12 when running as a Sleepy End Device.
[efr32mg12p]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc/device.EFR32MG12P432F1024GL125
@@ -22,7 +22,7 @@ modes of the EFR32 when running as a Sleepy End Device.
Download and install the [GNU toolchain for ARM Cortex-M][gnu-toolchain].
[gnu-toolchain]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm
[gnu-toolchain]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
In a Bash terminal, follow these instructions to install the GNU toolchain and
other dependencies.
@@ -40,14 +40,15 @@ $ ./script/bootstrap
2. Install Flex (Gecko) SDK including RAIL Library from Simplicity Studio.
- Connect EFR32MG12P Wireless Starter Kit to Simplicity Studio.
- Find Flex SDK v2.5 in the Software Update page and click Install.
- Flex SDK v2.5 will be installed in the path: `/SimplicityStudio_v4/developer/sdks/gecko_sdk_suite`.
- Find Flex SDK v2.6 in the Software Update page and click Install.
- Flex SDK v2.6 will be installed in the path: `/SimplicityStudio_v4/developer/sdks/gecko_sdk_suite`.
For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32)
portfolio using RAIL, see [Getting Started with RAIL Library quick start guide][QSG121]. For more information
portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the
Wireless Gecko (EFR32™) Portfolio][QSG138]. For more information
on RAIL, see [Radio Abstraction Interface Layer][rail].
[QSG121]: http://www.silabs.com/documents/public/quick-start-guides/QSG121-EFR32-RAIL.pdf
[QSG138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
[rail]: http://www.silabs.com/products/development-tools/software/radio-abstraction-interface-layer-sdk
3. Configure the path to Flex SDK source code.
@@ -70,18 +71,18 @@ $ ln -s <path-to-Simplicity-Studio>/developer/sdks/gecko_sdk_suite silabs/gecko_
$ cd <path-to-openthread>
$ ./bootstrap
```
For EFR32™ Mighty Gecko Wireless Starter Kit:
For EFR32MG12™ Mighty Gecko Wireless Starter Kit:
```bash
$ make -f examples/Makefile-efr32 BOARD=BRD4161A
$ make -f examples/Makefile-efr32mg12 BOARD=BRD4161A
```
or alternatively for the Thunderboard™ Sense 2:
```bash
$ make -f examples/Makefile-efr32 BOARD=BRD4166A
$ make -f examples/Makefile-efr32mg12 BOARD=BRD4166A
```
After a successful build, the `elf` files are found in
`<path-to-openthread>/output/efr32/bin`.
`<path-to-openthread>/output/efr32mg12/bin`.
## Flash Binaries
@@ -109,7 +110,7 @@ Compiled binaries also may be flashed onto the specified EFR32 dev board using [
[j-link-commander]: https://www.segger.com/products/debug-probes/j-link/tools/j-link-commander/
```bash
$ cd <path-to-openthread>/output/efr32/bin
$ cd <path-to-openthread>/output/efr32mg12/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
$ JLinkExe -device EFR32MG12PxxxF1024 -speed 4000 -if SWD -autoconnect 1 -SelectEmuBySN <SerialNo>
$ J-Link>loadfile ot-cli-ftd.hex
@@ -126,7 +127,7 @@ $ JLinkExe
Alternatively Simplicity Commander provides a graphical interface for J-Link Commander.
```bash
$ cd <path-to-openthread>/output/efr32/bin
$ cd <path-to-openthread>/output/efr32mg12/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.ihex
$ <path-to-simplicity-studio>/developer/adapter_packs/commander/commander
```
@@ -137,7 +138,7 @@ Click on the Flash icon on the left side of the window to switch to the flash pa
In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button.
Click the Flash button located under the Browse... button.
## Run the example with EFR32 boards
## Run the example with EFR32MG12 boards
1. Flash two EFR32 boards with the `CLI example` firmware (as shown above).
2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1).
Type `help` for a list of commands.
@@ -251,7 +252,7 @@ joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compilin
```bash
$ cd <path-to-openthread>
$ ./bootstrap
$ make -f examples/Makefile-efr32 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
$ make -f examples/Makefile-efr32mg12 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
```
For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
@@ -264,4 +265,4 @@ The following toolchain has been used for testing and verification:
- gcc version 7.3.1
The EFR32 example has been verified with following Flex SDK/RAIL Library version:
- Flex SDK version 2.5.1.0
- Flex SDK version 2.6.0.0
@@ -247,7 +247,7 @@
#define HAL_SERIAL_APP_RXSTOP (16)
#define HAL_SERIAL_APP_RXSTART (16)
#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128)
#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
// [SERIAL]$
// $[SPIDISPLAY]
@@ -145,7 +145,7 @@
#define HAL_PA_RAMP (10UL)
#define HAL_PA_2P4_LOWPOWER (0)
#define HAL_PA_POWER (252U)
#define BSP_PA_VOLTAGE (3300U)
#define HAL_PA_VOLTAGE (3300U)
#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
// [PA]$
@@ -223,7 +223,7 @@
#define HAL_SERIAL_APP_RXSTOP (16UL)
#define HAL_SERIAL_APP_RXSTART (16UL)
#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128UL)
#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_NONE)
#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
// [SERIAL]$
// $[SPIDISPLAY]
@@ -159,7 +159,7 @@
#define HAL_PA_RAMP (10UL)
#define HAL_PA_2P4_LOWPOWER (0)
#define HAL_PA_POWER (252U)
#define BSP_PA_VOLTAGE (3300U)
#define HAL_PA_VOLTAGE (3300U)
#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
// [PA]$
@@ -29,5 +29,5 @@
#include "hal-config.h"
#if (HAL_FEM_ENABLE)
#include "../../../third_party/silabs/gecko_sdk_suite/v2.5/util/plugin/plugin-common/fem-control/fem-control.c"
#include "../../../third_party/silabs/gecko_sdk_suite/v2.6/util/plugin/plugin-common/fem-control/fem-control.c"
#endif
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2018, 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 defines the frequency band configuration structure for efr32.
*
*/
#ifndef PLATFORM_BAND_H_
#define PLATFORM_BAND_H_
#include <openthread/platform/radio.h>
#include "rail.h"
#include "rail_config.h"
#include "rail_ieee802154.h"
#define RAIL_TX_FIFO_SIZE (OT_RADIO_FRAME_MAX_SIZE + 1)
typedef struct efr32CommonConfig
{
RAIL_Config_t mRailConfig;
uint8_t
mRailTxFifo[RAIL_TX_FIFO_SIZE]; // must be 2 power between 64 and 4096, and bigger than OT_RADIO_FRAME_MAX_SIZE
} efr32CommonConfig;
typedef struct efr32BandConfig
{
const RAIL_ChannelConfig_t *mChannelConfig;
uint8_t mChannelMin;
uint8_t mChannelMax;
} efr32BandConfig;
#endif // PLATFORM_BAND_H_
+880
View File
@@ -0,0 +1,880 @@
/*
* Copyright (c) 2019, 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 implements the OpenThread platform abstraction for radio communication.
*
*/
#include <assert.h>
#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#include <openthread/platform/radio.h>
#include "common/logging.hpp"
#include "utils/code_utils.h"
#include "utils/soft_source_match_table.h"
#include "board_config.h"
#include "em_cmu.h"
#include "em_core.h"
#include "em_system.h"
#include "hal-config.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"
#include "rtcdriver.h"
enum
{
IEEE802154_MIN_LENGTH = 5,
IEEE802154_MAX_LENGTH = 127,
IEEE802154_ACK_LENGTH = 5,
IEEE802154_FRAME_TYPE_MASK = 0x7,
IEEE802154_FRAME_TYPE_ACK = 0x2,
IEEE802154_FRAME_PENDING = 1 << 4,
IEEE802154_ACK_REQUEST = 1 << 5,
IEEE802154_DSN_OFFSET = 2,
};
enum
{
EFR32_RECEIVE_SENSITIVITY = -100, // dBm
EFR32_RSSI_AVERAGING_TIMEOUT = 300, // us
};
enum
{
EFR32_SCHEDULER_SAMPLE_RSSI_PRIORITY = 10, // High priority
EFR32_SCHEDULER_TX_PRIORITY = 10, // High priority
EFR32_SCHEDULER_RX_PRIORITY = 20, // Low priority
};
enum
{
#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT && RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
EFR32_NUM_BAND_CONFIGS = 2,
#else
EFR32_NUM_BAND_CONFIGS = 1,
#endif
};
typedef enum
{
ENERGY_SCAN_STATUS_IDLE,
ENERGY_SCAN_STATUS_IN_PROGRESS,
ENERGY_SCAN_STATUS_COMPLETED
} energyScanStatus;
typedef enum
{
ENERGY_SCAN_MODE_SYNC,
ENERGY_SCAN_MODE_ASYNC
} energyScanMode;
RAIL_Handle_t gRailHandle;
static volatile bool sTransmitBusy = false;
static bool sPromiscuous = false;
static bool sIsSrcMatchEnabled = false;
static otRadioState sState = OT_RADIO_STATE_DISABLED;
static uint8_t sReceivePsdu[IEEE802154_MAX_LENGTH];
static otRadioFrame sReceiveFrame;
static otError sReceiveError;
static otRadioFrame sTransmitFrame;
static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH];
static volatile otError sTransmitError;
static efr32CommonConfig sCommonConfig;
static efr32BandConfig sBandConfigs[EFR32_NUM_BAND_CONFIGS];
static volatile energyScanStatus sEnergyScanStatus;
static volatile int8_t sEnergyScanResultDbm;
static energyScanMode sEnergyScanMode;
#define QUARTER_DBM_IN_DBM 4
#define US_IN_MS 1000
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 = 894,
.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,
};
RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp);
static int8_t sTxPowerDbm = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
static efr32BandConfig *sCurrentBandConfig = NULL;
static RAIL_Handle_t efr32RailInit(efr32CommonConfig *aCommonConfig)
{
RAIL_Status_t status;
RAIL_Handle_t handle;
handle = RAIL_Init(&aCommonConfig->mRailConfig, NULL);
assert(handle != NULL);
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 //
);
assert(status == RAIL_STATUS_NO_ERROR);
uint16_t actualLenth = RAIL_SetTxFifo(handle, aCommonConfig->mRailTxFifo, 0, sizeof(aCommonConfig->mRailTxFifo));
assert(actualLenth == sizeof(aCommonConfig->mRailTxFifo));
return handle;
}
static void efr32RailConfigLoad(efr32BandConfig *aBandConfig)
{
RAIL_Status_t status;
#if HAL_PA_2P4_LOWPOWER == 1
RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_LP, HAL_PA_VOLTAGE, 10};
#else
RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, HAL_PA_VOLTAGE, 10};
#endif
if (aBandConfig->mChannelConfig != NULL)
{
uint16_t firstChannel = RAIL_ConfigChannels(gRailHandle, aBandConfig->mChannelConfig, NULL);
assert(firstChannel == aBandConfig->mChannelMin);
txPowerConfig.mode = RAIL_TX_POWER_MODE_SUBGIG;
}
else
{
status = RAIL_IEEE802154_Config2p4GHzRadio(gRailHandle);
assert(status == RAIL_STATUS_NO_ERROR);
}
status = RAIL_ConfigTxPower(gRailHandle, &txPowerConfig);
assert(status == RAIL_STATUS_NO_ERROR);
}
static void efr32RadioSetTxPower(uint8_t aPowerDbm)
{
RAIL_Status_t status;
RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = {curves24Hp, curvesSg, curves24Lp, piecewiseSegments};
status = RAIL_InitTxPowerCurves(&txPowerCurvesConfig);
assert(status == RAIL_STATUS_NO_ERROR);
status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aPowerDbm) * 10);
assert(status == RAIL_STATUS_NO_ERROR);
}
static efr32BandConfig *efr32RadioGetBandConfig(uint8_t aChannel)
{
efr32BandConfig *config = NULL;
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
{
if ((sBandConfigs[i].mChannelMin <= aChannel) && (aChannel <= sBandConfigs[i].mChannelMax))
{
config = &sBandConfigs[i];
break;
}
}
return config;
}
static void efr32ConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle, RAIL_Events_t events))
{
sCommonConfig.mRailConfig.eventsCallback = aEventCallback;
sCommonConfig.mRailConfig.protocol = NULL; // only used by Bluetooth stack
sCommonConfig.mRailConfig.scheduler = NULL; // only needed for DMP
uint8_t index = 0;
#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;
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;
#endif
gRailHandle = efr32RailInit(&sCommonConfig);
assert(gRailHandle != NULL);
efr32RailConfigLoad(&(sBandConfigs[0]));
}
void efr32RadioInit(void)
{
RAIL_Status_t status;
// check if RAIL_TX_FIFO_SIZE is power of two..
assert((RAIL_TX_FIFO_SIZE & (RAIL_TX_FIFO_SIZE - 1)) == 0);
// check the limits of the RAIL_TX_FIFO_SIZE.
assert((RAIL_TX_FIFO_SIZE >= 64) || (RAIL_TX_FIFO_SIZE <= 4096));
efr32ConfigInit(RAILCb_Generic);
CMU_ClockEnable(cmuClock_PRS, true);
RTCDRV_Init();
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;
sCurrentBandConfig = efr32RadioGetBandConfig(OPENTHREAD_CONFIG_DEFAULT_CHANNEL);
assert(sCurrentBandConfig != NULL);
efr32RadioSetTxPower(sTxPowerDbm);
sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
sTransmitError = OT_ERROR_NONE;
sTransmitBusy = false;
otLogInfoPlat("Initialized", NULL);
}
void efr32RadioDeinit(void)
{
RAIL_Status_t status;
RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
status = RAIL_ConfigEvents(gRailHandle, RAIL_EVENTS_ALL, 0);
assert(status == RAIL_STATUS_NO_ERROR);
sCurrentBandConfig = NULL;
}
static otError efr32StartEnergyScan(energyScanMode aMode, uint16_t aChannel, RAIL_Time_t aAveragingTimeUs)
{
RAIL_Status_t status;
otError error = OT_ERROR_NONE;
efr32BandConfig *config = NULL;
otEXPECT_ACTION(sEnergyScanStatus == ENERGY_SCAN_STATUS_IDLE, error = OT_ERROR_BUSY);
sEnergyScanStatus = ENERGY_SCAN_STATUS_IN_PROGRESS;
sEnergyScanMode = aMode;
RAIL_Idle(gRailHandle, RAIL_IDLE, true);
config = efr32RadioGetBandConfig(aChannel);
otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
if (sCurrentBandConfig != config)
{
efr32RailConfigLoad(config);
sCurrentBandConfig = config;
}
status = RAIL_StartAverageRssi(gRailHandle, aChannel, aAveragingTimeUs, NULL);
otEXPECT_ACTION(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
exit:
return error;
}
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
OT_UNUSED_VARIABLE(aInstance);
uint64_t eui64;
uint8_t *eui64Ptr = NULL;
eui64 = SYSTEM_GetUnique();
eui64Ptr = (uint8_t *)&eui64;
for (uint8_t i = 0; i < OT_EXT_ADDRESS_SIZE; i++)
{
aIeeeEui64[i] = eui64Ptr[(OT_EXT_ADDRESS_SIZE - 1) - i];
}
}
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
otLogInfoPlat("PANID=%X", aPanId);
utilsSoftSrcMatchSetPanId(aPanId);
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
{
status = RAIL_IEEE802154_SetPanId(gRailHandle, aPanId, 0);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
otLogInfoPlat("ExtAddr=%X%X%X%X%X%X%X%X", aAddress->m8[7], aAddress->m8[6], aAddress->m8[5], aAddress->m8[4],
aAddress->m8[3], aAddress->m8[2], aAddress->m8[1], aAddress->m8[0]);
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
{
status = RAIL_IEEE802154_SetLongAddress(gRailHandle, (uint8_t *)aAddress->m8, 0);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
otLogInfoPlat("ShortAddr=%X", aAddress);
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
{
status = RAIL_IEEE802154_SetShortAddress(gRailHandle, aAddress, 0);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
bool otPlatRadioIsEnabled(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return (sState != OT_RADIO_STATE_DISABLED);
}
otError otPlatRadioEnable(otInstance *aInstance)
{
otEXPECT(!otPlatRadioIsEnabled(aInstance));
otLogInfoPlat("State=OT_RADIO_STATE_SLEEP", NULL);
sState = OT_RADIO_STATE_SLEEP;
exit:
return OT_ERROR_NONE;
}
otError otPlatRadioDisable(otInstance *aInstance)
{
otEXPECT(otPlatRadioIsEnabled(aInstance));
otLogInfoPlat("State=OT_RADIO_STATE_DISABLED", NULL);
sState = OT_RADIO_STATE_DISABLED;
exit:
return OT_ERROR_NONE;
}
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_ABORT, true); // abort packages under reception
sState = OT_RADIO_STATE_SLEEP;
exit:
return error;
}
otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
otError error = OT_ERROR_NONE;
RAIL_Status_t status;
efr32BandConfig *config;
OT_UNUSED_VARIABLE(aInstance);
otEXPECT_ACTION(sState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
config = efr32RadioGetBandConfig(aChannel);
otEXPECT_ACTION(config != NULL, error = OT_ERROR_INVALID_ARGS);
if (sCurrentBandConfig != config)
{
RAIL_Idle(gRailHandle, RAIL_IDLE_ABORT, true);
efr32RailConfigLoad(config);
sCurrentBandConfig = config;
}
status = RAIL_StartRx(gRailHandle, aChannel, NULL);
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;
exit:
return error;
}
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;
assert(sTransmitBusy == false);
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_ABORT, true);
efr32RailConfigLoad(config);
sCurrentBandConfig = config;
}
otEXPECT(aFrame->mLength >= IEEE802154_MIN_LENGTH && aFrame->mLength <= IEEE802154_MAX_LENGTH);
frameLength = (uint8_t)aFrame->mLength;
RAIL_WriteTxFifo(gRailHandle, &frameLength, sizeof frameLength, true);
RAIL_WriteTxFifo(gRailHandle, aFrame->mPsdu, frameLength - 2, false);
if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST)
{
txOptions |= RAIL_TX_OPTION_WAIT_FOR_ACK;
}
if (aFrame->mInfo.mTxInfo.mCsmaCaEnabled)
{
status = RAIL_StartCcaCsmaTx(gRailHandle, aFrame->mChannel, txOptions, &csmaConfig, NULL);
}
else
{
status = RAIL_StartTx(gRailHandle, aFrame->mChannel, txOptions, NULL);
}
assert(status == RAIL_STATUS_NO_ERROR);
otPlatRadioTxStarted(aInstance, aFrame);
exit:
return error;
}
otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return &sTransmitFrame;
}
int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
int8_t rssi = OT_RADIO_RSSI_INVALID;
OT_UNUSED_VARIABLE(aInstance);
if ((RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX))
{
int16_t railRssi = RAIL_RSSI_INVALID;
railRssi = RAIL_GetRssi(gRailHandle, true);
if (railRssi != RAIL_RSSI_INVALID)
{
rssi = railRssi / QUARTER_DBM_IN_DBM;
}
}
return rssi;
}
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN;
}
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return sPromiscuous;
}
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
sPromiscuous = aEnable;
for (uint8_t i = 0; i < EFR32_NUM_BAND_CONFIGS; i++)
{
status = RAIL_IEEE802154_SetPromiscuousMode(gRailHandle, aEnable);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
OT_UNUSED_VARIABLE(aInstance);
// set Frame Pending bit for all outgoing ACKs if aEnable is false
sIsSrcMatchEnabled = aEnable;
}
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;
packetHandle = RAIL_GetRxPacketInfo(gRailHandle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo);
otEXPECT_ACTION(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
otEXPECT(length == packetInfo.firstPortionData[0]);
// check the length validity of recv packet
otEXPECT(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH);
otLogInfoPlat("Received data:%d", length);
// skip length byte
assert(packetInfo.firstPortionBytes > 0);
packetInfo.firstPortionData++;
packetInfo.firstPortionBytes--;
packetInfo.packetBytes--;
// read packet
memcpy(sReceiveFrame.mPsdu, packetInfo.firstPortionData, packetInfo.firstPortionBytes);
memcpy(sReceiveFrame.mPsdu + packetInfo.firstPortionBytes, packetInfo.lastPortionData,
packetInfo.packetBytes - packetInfo.firstPortionBytes);
status = RAIL_ReleaseRxPacket(gRailHandle, packetHandle);
if (status == RAIL_STATUS_NO_ERROR)
{
packetHandle = RAIL_RX_PACKET_HANDLE_INVALID;
}
sReceiveFrame.mLength = length;
if (packetDetails.isAck)
{
assert((length == IEEE802154_ACK_LENGTH) &&
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK);
sTransmitBusy = false;
if (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])
{
sTransmitError = OT_ERROR_NONE;
}
else
{
sTransmitError = OT_ERROR_NO_ACK;
}
}
else
{
otEXPECT(length != IEEE802154_ACK_LENGTH);
sReceiveError = OT_ERROR_NONE;
sReceiveFrame.mInfo.mRxInfo.mRssi = packetDetails.rssi;
sReceiveFrame.mInfo.mRxInfo.mLqi = packetDetails.lqi;
// TODO: grab timestamp and handle conversion to msec/usec and RAIL_GetRxTimeSyncWordEndAlt
// sReceiveFrame.mInfo.mRxInfo.mMsec = packetDetails.packetTime;
// sReceiveFrame.mInfo.mRxInfo.mUsec = packetDetails.packetTime;
// TODO Set this flag only when the packet is really acknowledged with frame pending set.
// See https://github.com/openthread/openthread/pull/3785
sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
}
else
#endif
{
// signal MAC layer for each received frame if promiscous is enabled
// otherwise only signal MAC layer for non-ACK frame
if (sPromiscuous || sReceiveFrame.mLength > IEEE802154_ACK_LENGTH)
{
otLogInfoPlat("Received %d bytes", sReceiveFrame.mLength);
otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
}
}
}
exit:
if (packetHandle != RAIL_RX_PACKET_HANDLE_INVALID)
{
RAIL_ReleaseRxPacket(gRailHandle, packetHandle);
}
}
static void ieee802154DataRequestCommand(RAIL_Handle_t aRailHandle)
{
RAIL_Status_t status;
if (sIsSrcMatchEnabled)
{
RAIL_IEEE802154_Address_t sourceAddress;
status = RAIL_IEEE802154_GetAddress(aRailHandle, &sourceAddress);
assert(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);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
else
{
status = RAIL_IEEE802154_SetFramePending(aRailHandle);
assert(status == RAIL_STATUS_NO_ERROR);
}
}
static void RAILCb_Generic(RAIL_Handle_t aRailHandle, RAIL_Events_t aEvents)
{
if (aEvents & RAIL_EVENT_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)
{
sTransmitError = OT_ERROR_NONE;
sTransmitBusy = false;
}
}
else if (aEvents & RAIL_EVENT_TX_CHANNEL_BUSY)
{
sTransmitError = OT_ERROR_CHANNEL_ACCESS_FAILURE;
sTransmitBusy = false;
}
else
{
sTransmitError = OT_ERROR_ABORT;
sTransmitBusy = false;
}
}
if (aEvents & RAIL_EVENT_RX_ACK_TIMEOUT)
{
sTransmitError = OT_ERROR_NO_ACK;
sTransmitBusy = false;
}
if (aEvents & RAIL_EVENT_RX_PACKET_RECEIVED)
{
RAIL_HoldRxPacket(aRailHandle);
}
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 (aEvents & RAIL_EVENT_RSSI_AVERAGE_DONE)
{
const int16_t energyScanResultQuarterDbm = RAIL_GetAverageRssi(aRailHandle);
sEnergyScanStatus = ENERGY_SCAN_STATUS_COMPLETED;
if (energyScanResultQuarterDbm == RAIL_RSSI_INVALID)
{
sEnergyScanResultDbm = OT_RADIO_RSSI_INVALID;
}
else
{
sEnergyScanResultDbm = energyScanResultQuarterDbm / QUARTER_DBM_IN_DBM;
}
}
}
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)
{
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_ENABLE_DIAG
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);
}
}
else if (sEnergyScanMode == ENERGY_SCAN_MODE_ASYNC && sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
{
sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
otPlatRadioEnergyScanDone(aInstance, sEnergyScanResultDbm);
}
processNextRxPacket(aInstance);
}
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS);
*aPower = sTxPowerDbm;
exit:
return error;
}
otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aPower) * 10);
assert(status == RAIL_STATUS_NO_ERROR);
sTxPowerDbm = aPower;
return OT_ERROR_NONE;
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return EFR32_RECEIVE_SENSITIVITY;
}
@@ -31,8 +31,8 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
# Always package (e.g. for 'make dist') these subdirectories.
DIST_SUBDIRS = \
efr32-sleepy-demo-mtd \
efr32-sleepy-demo-ftd \
sleepy-demo-mtd \
sleepy-demo-ftd \
$(NULL)
# Always build (e.g. for 'make all') these subdirectories.
@@ -41,14 +41,14 @@ SUBDIRS = \
$(NULL)
if OPENTHREAD_ENABLE_EXECUTABLE
SUBDIRS += efr32-sleepy-demo-mtd efr32-sleepy-demo-ftd
SUBDIRS += sleepy-demo-mtd sleepy-demo-ftd
endif
# Always pretty (e.g. for 'make pretty') these subdirectories.
PRETTY_SUBDIRS = \
efr32-sleepy-demo-mtd \
efr32-sleepy-demo-ftd \
sleepy-demo-mtd \
sleepy-demo-ftd \
$(NULL)
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
@@ -1,11 +1,11 @@
# EFR32 Sleepy Demo Example
# EFR32MG12 Sleepy Demo Example
The EFR32 Sleepy applications demonstrates Sleepy End Device behaviour using
the EFR32's low power EM2 mode. The steps below will take you through the
process of building and running the demo
For setting up the build environment refer to [examples/platforms/efr32/README.md](../README.md).
For setting up the build environment refer to [examples/platforms/efr32mg12/README.md](../README.md).
## 1. Build
@@ -13,21 +13,21 @@ For setting up the build environment refer to [examples/platforms/efr32/README.m
```bash
$ cd <path-to-openthread>
$ ./bootstrap
$ make -f examples/Makefile-efr32 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 BOARD=BRD4161A
$ make -f examples/Makefile-efr32mg12 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 BOARD=BRD4161A
```
Convert the resulting executables into S-Record format and append a s37 suffix.
```bash
$ cd output/efr32/bin
$ arm-none-eabi-objcopy -O srec efr32-sleepy-demo-mtd efr32-sleepy-demo-mtd.s37
$ arm-none-eabi-objcopy -O srec efr32-sleepy-demo-ftd efr32-sleepy-demo-ftd.s37
$ cd output/efr32mg12/bin
$ arm-none-eabi-objcopy -O srec sleepy-demo-mtd sleepy-demo-mtd.s37
$ arm-none-eabi-objcopy -O srec sleepy-demo-ftd sleepy-demo-ftd.s37
```
In Silicon Labs Simplicity Studio flash one device with the efr32-sleepy-demo-mtd.s37
image and the other device with the efr32-sleepy-demo-ftd.s37 image.
In Silicon Labs Simplicity Studio flash one device with the sleepy-demo-mtd.s37
image and the other device with the sleepy-demo-ftd.s37 image.
For instructions on flashing firmware see [examples/platforms/efr32/README.md](../README.md#flash-binaries)
For instructions on flashing firmware see [examples/platforms/efr32mg12/README.md](../README.md#flash-binaries)
## 2. Starting nodes
@@ -37,14 +37,14 @@ The devices start Thread and form a network within a few seconds of powering on.
application the devices should implement and go through a commissioning process to create
a network and add devices.
When the efr32-sleepy-demo-ftd device is started in the CLI the user shall see:
When the sleepy-demo-ftd device is started in the CLI the user shall see:
```
efr32-sleepy-demo-ftd started
efr32-sleepy-demo-ftd changed to leader
sleepy-demo-ftd started
sleepy-demo-ftd changed to leader
```
When the efr32-sleepy-demo-mtd device starts it joins the preconfigured Thread network
When the sleepy-demo-mtd device starts it joins the preconfigured Thread network
before disabling Rx-On-Idle to become a Sleepy-End-Device.
Use the command "child table" in the FTD console and observe the R flag of the child is 0.
@@ -33,10 +33,10 @@ override CFLAGS := $(filter-out -Wconversion,$(CFLA
override CXXFLAGS := $(filter-out -Wconversion,$(CXXFLAGS))
EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a-z)
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.5
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6
$(top_builddir)/examples/platforms/efr32/libopenthread-efr32.a:
(cd $(top_builddir)/examples/platforms/efr32/ && $(MAKE) $(AM_MAKEFLAGS) libopenthread-efr32.a )
$(top_builddir)/examples/platforms/efr32mg12/libopenthread-efr32mg12.a:
(cd $(top_builddir)/examples/platforms/efr32mg12/ && $(MAKE) $(AM_MAKEFLAGS) libopenthread-efr32mg12.a )
bin_PROGRAMS = \
$(NULL)
@@ -45,7 +45,7 @@ CPPFLAGS_COMMON += \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/examples/platforms \
-DPLATFORM_HEADER=\"@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/base/hal/micro/cortexm3/compiler/gcc.h\" \
-DPLATFORM_HEADER=\"@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.6/platform/base/hal/micro/cortexm3/compiler/gcc.h\" \
-Wno-sign-compare \
-DCORTEXM3 \
-D__START=main \
@@ -119,15 +119,15 @@ endif # OPENTHREAD_ENABLE_DIAG
if OPENTHREAD_ENABLE_EXECUTABLE
bin_PROGRAMS += \
efr32-sleepy-demo-ftd \
sleepy-demo-ftd \
$(NULL)
endif
efr32_sleepy_demo_ftd_CPPFLAGS = \
sleepy_demo_ftd_CPPFLAGS = \
$(CPPFLAGS_COMMON) \
$(NULL)
efr32_sleepy_demo_ftd_LDADD = \
sleepy_demo_ftd_LDADD = \
$(top_builddir)/src/cli/libopenthread-cli-ftd.a \
$(top_builddir)/src/core/libopenthread-ftd.a \
$(LDADD_COMMON) \
@@ -135,20 +135,20 @@ efr32_sleepy_demo_ftd_LDADD = \
$(LDADD_COMMON) \
$(NULL)
efr32_sleepy_demo_ftd_LDFLAGS = \
sleepy_demo_ftd_LDFLAGS = \
$(LDFLAGS_COMMON) \
$(NULL)
efr32_sleepy_demo_ftd_LIBTOOLFLAGS = \
sleepy_demo_ftd_LIBTOOLFLAGS = \
$(LIBTOOLFLAGS_COMMON) \
$(NULL)
efr32_sleepy_demo_ftd_SOURCES = \
sleepy_demo_ftd_SOURCES = \
$(SOURCES_COMMON) \
$(NULL)
if OPENTHREAD_ENABLE_LINKER_MAP
efr32_sleepy_demo_ftd_LDFLAGS += -Wl,-Map=efr32-sleepy-demo-ftd.map
sleepy_demo_ftd_LDFLAGS += -Wl,-Map=sleepy-demo-ftd.map
endif
if OPENTHREAD_BUILD_COVERAGE
@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
assert(instance);
otCliUartInit(instance);
otCliOutputFormat("efr32-sleepy-demo-ftd started\r\n");
otCliOutputFormat("sleepy-demo-ftd started\r\n");
setNetworkConfiguration(instance);
otSetStateChangedCallback(instance, handleNetifStateChanged, instance);
@@ -190,10 +190,10 @@ void handleNetifStateChanged(uint32_t aFlags, void *aContext)
switch (changedRole)
{
case OT_DEVICE_ROLE_LEADER:
otCliOutputFormat("efr32-sleepy-demo-ftd changed to leader\r\n");
otCliOutputFormat("sleepy-demo-ftd changed to leader\r\n");
break;
case OT_DEVICE_ROLE_ROUTER:
otCliOutputFormat("efr32-sleepy-demo-ftd changed to router\r\n");
otCliOutputFormat("sleepy-demo-ftd changed to router\r\n");
break;
case OT_DEVICE_ROLE_CHILD:
@@ -33,10 +33,10 @@ override CFLAGS := $(filter-out -Wconversion,$(CFLA
override CXXFLAGS := $(filter-out -Wconversion,$(CXXFLAGS))
EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a-z)
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.5
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6
$(top_builddir)/examples/platforms/efr32/libopenthread-efr32.a:
(cd $(top_builddir)/examples/platforms/efr32/ && $(MAKE) $(AM_MAKEFLAGS) libopenthread-efr32.a )
$(top_builddir)/examples/platforms/efr32mg12/libopenthread-efr32mg12.a:
(cd $(top_builddir)/examples/platforms/efr32mg12/ && $(MAKE) $(AM_MAKEFLAGS) libopenthread-efr32mg12.a )
bin_PROGRAMS = \
$(NULL)
@@ -45,7 +45,7 @@ CPPFLAGS_COMMON += \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/examples/platforms \
-DPLATFORM_HEADER=\"@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.5/platform/base/hal/micro/cortexm3/compiler/gcc.h\" \
-DPLATFORM_HEADER=\"@top_builddir@/third_party/silabs/gecko_sdk_suite/v2.6/platform/base/hal/micro/cortexm3/compiler/gcc.h\" \
-Wno-sign-compare \
-DCORTEXM3 \
-D__START=main \
@@ -119,15 +119,15 @@ endif # OPENTHREAD_ENABLE_DIAG
if OPENTHREAD_ENABLE_EXECUTABLE
bin_PROGRAMS += \
efr32-sleepy-demo-mtd \
sleepy-demo-mtd \
$(NULL)
endif
efr32_sleepy_demo_mtd_CPPFLAGS = \
sleepy_demo_mtd_CPPFLAGS = \
$(CPPFLAGS_COMMON) \
$(NULL)
efr32_sleepy_demo_mtd_LDADD = \
sleepy_demo_mtd_LDADD = \
$(top_builddir)/src/cli/libopenthread-cli-mtd.a \
$(top_builddir)/src/core/libopenthread-mtd.a \
$(LDADD_COMMON) \
@@ -135,20 +135,20 @@ efr32_sleepy_demo_mtd_LDADD = \
$(LDADD_COMMON) \
$(NULL)
efr32_sleepy_demo_mtd_LDFLAGS = \
sleepy_demo_mtd_LDFLAGS = \
$(LDFLAGS_COMMON) \
$(NULL)
efr32_sleepy_demo_mtd_LIBTOOLFLAGS = \
sleepy_demo_mtd_LIBTOOLFLAGS = \
$(LIBTOOLFLAGS_COMMON) \
$(NULL)
efr32_sleepy_demo_mtd_SOURCES = \
sleepy_demo_mtd_SOURCES = \
$(SOURCES_COMMON) \
$(NULL)
if OPENTHREAD_ENABLE_LINKER_MAP
efr32_sleepy_demo_mtd_LDFLAGS += -Wl,-Map=efr32_sleepy_demo_mtd_.map
sleepy_demo_mtd_LDFLAGS += -Wl,-Map=sleepy-demo-mtd.map
endif
if OPENTHREAD_BUILD_COVERAGE
@@ -125,6 +125,7 @@ void efr32Sleep(void)
EMU_EnterEM2(true);
}
CORE_EXIT_ATOMIC();
// TODO OT will handle an interrupt here and it mustn't call any RAIL APIs
while (RAIL_Wake(0) != RAIL_STATUS_NO_ERROR)
{
@@ -64,7 +64,7 @@ enum
(USART_Parity_TypeDef)USART_FRAME_PARITY_NONE, /* Parity */ \
(USART_OVS_TypeDef)USART_CTRL_OVS_X16, /* Oversampling mode*/ \
false, /* Majority vote disable */ \
uartdrvFlowControlHwUart, /* Flow control */ \
HAL_SERIAL_APP_FLOW_CONTROL, /* Flow control */ \
BSP_SERIAL_APP_CTS_PORT, /* CTS port number */ \
BSP_SERIAL_APP_CTS_PIN, /* CTS pin number */ \
BSP_SERIAL_APP_RTS_PORT, /* RTS port number */ \
+113
View File
@@ -0,0 +1,113 @@
#
# Copyright (c) 2019, 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 $(abs_top_nlbuild_autotools_dir)/automake/pre.am
lib_LIBRARIES = libopenthread-efr32mg21.a
# Do not enable -Wconversion for rail
override CFLAGS := $(filter-out -Wconversion,$(CFLAGS))
override CXXFLAGS := $(filter-out -Wconversion,$(CXXFLAGS))
# Do not enable -pedantic-errors for rail
override CFLAGS := $(filter-out -pedantic-errors,$(CFLAGS))
override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a-z)
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6
libopenthread_efr32mg21_a_CPPFLAGS = \
-D__START=main \
-D__STARTUP_CLEAR_BSS \
-I$(top_srcdir)/include \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/examples/platforms/efr32mg21/$(EFR32_BOARD_DIR) \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/third_party/silabs/rail_config \
-I$(EFR32MG_SDK_SRCDIR) \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/common \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/chip/efr32 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/protocol/ieee802154 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/chip/efr32/rf/common/cortex \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/hal \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/hal/efr32 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/plugin/pa-conversions \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/common/bsp \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/EFR32MG21_$(BOARD)/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/CMSIS/Include \
-I$(EFR32MG_SDK_SRCDIR)/platform/Device/SiliconLabs/EFR32MG21/Include \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/common/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/gpiointerrupt/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/uartdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/uartdrv/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/ustimer/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/dmadrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/dmadrv/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/rtcdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emlib/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/halconfig/inc/hal-config \
-I$(EFR32MG_SDK_SRCDIR)/util/plugin/plugin-common/fem-control \
-Wno-unused-parameter \
-Wno-missing-field-initializers \
$(NULL)
PLATFORM_SOURCES = \
alarm.c \
diag.c \
entropy.c \
fem-control.c \
flash.c \
logging.c \
misc.c \
radio.c \
startup-gcc.c \
system.c \
uart.c \
$(NULL)
noinst_HEADERS = \
platform-efr32.h \
platform-band.h \
$(NULL)
libopenthread_efr32mg21_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NULL)
PRETTY_FILES = \
$(PLATFORM_SOURCES) \
$(noinst_HEADERS) \
$(NULL)
Dash = -
libopenthread_efr32mg21_a_LIBADD = \
$(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o") \
$(shell find $(top_builddir)/third_party/jlink/SEGGER_RTT_V640/RTT $(Dash)type f $(Dash)name "*.o")
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
@@ -0,0 +1,41 @@
#
# Copyright (c) 2019, 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.
#
#
# efr32mg21 platform-specific Makefile
#
LDADD_COMMON += \
$(top_builddir)/examples/platforms/efr32mg21/libopenthread-efr32mg21.a \
$(top_builddir)/third_party/silabs/libsilabs-efr32mg21-sdk.a \
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg21_gcc_release.a \
$(NULL)
LDFLAGS_COMMON += \
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/efr32mg21.ld \
$(NULL)
+216
View File
@@ -0,0 +1,216 @@
# OpenThread on EFR32MG21 Example
This directory contains example platform drivers for the [Silicon Labs EFR32MG21][efr32mg]
based on [EFR32™ Mighty Gecko Wireless Starter Kit][SLWSTK6000B]
[efr32mg]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc
[SLWSTK6000B]: http://www.silabs.com/products/development-tools/wireless/mesh-networking/mighty-gecko-starter-kit
The example platform drivers are intended to present the minimal code
necessary to support OpenThread. [EFR32MG21 SoC][efr32mg21]
has rich memory and peripheral resources which can support all OpenThread
capabilities. See the "Run the example with EFR32 boards" section below
for an example using basic OpenThread capabilities.
[efr32mg21]: https://www.silabs.com/products/wireless/mesh-networking/series-2-efr32-mighty-gecko-zigbee-thread-soc/device.efr32mg21a020f768im32
## Toolchain
Download and install the [GNU toolchain for ARM Cortex-M][gnu-toolchain].
[gnu-toolchain]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
In a Bash terminal, follow these instructions to install the GNU toolchain and
other dependencies.
```bash
$ cd <path-to-openthread>
$ ./script/bootstrap
```
## Build Examples
1. Download and install the [Simplicity Studio][simplicity_studio].
[simplicity_studio]: http://www.silabs.com/products/development-tools/software/simplicity-studio
2. Install Flex (Gecko) SDK including RAIL Library from Simplicity Studio.
- Connect EFR32MG21 Wireless Starter Kit to Simplicity Studio.
- Find Flex SDK v2.6 in the Software Update page and click Install.
- Flex SDK v2.6 will be installed in the path: `/SimplicityStudio_v4/developer/sdks/gecko_sdk_suite`.
For more information on configuring, building, and installing applications for the Wireless Gecko (EFR32)
portfolio using FLEX, see [Getting Started with the Silicon Labs Flex Software Development Kit for the
Wireless Gecko (EFR32™) Portfolio][QSG138]. For more information
on RAIL, see [Radio Abstraction Interface Layer][rail].
[QSG138]: https://www.silabs.com/documents/public/quick-start-guides/qsg138-flex-efr32.pdf
[rail]: http://www.silabs.com/products/development-tools/software/radio-abstraction-interface-layer-sdk
3. Configure the path to Flex SDK source code.
```bash
$ cd <path-to-Simplicity-Studio>/developer/sdks
$ cp -rf gecko_sdk_suite <path-to-openthread>/third_party/silabs/
```
Alternatively create a symbolic link to the Flex SDK source code.
```bash
$ cd <path-to-openthread>/third_party
$ ln -s <path-to-Simplicity-Studio>/developer/sdks/gecko_sdk_suite silabs/gecko_sdk_suite
```
Note: Due to an error in the core_cm33.h file provided by ARM, the compiler will throw an error when pedantic
option is used on the builds. To avoid this, please add the following lines of code at the top of the
file core_cm33.h:
```
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
```
core_cm33.h can be found at:
```
<path-to-Simplicity-Studio>/developer/sdks/gecko_sdk_suite/v2.6/platform/CMSIS/Include
```
4. Build OpenThread Firmware (CLI example) on EFR32 platform.
```bash
$ cd <path-to-openthread>
$ ./bootstrap
```
For EFR32MG21™ Mighty Gecko Wireless Starter Kit:
```bash
$ make -f examples/Makefile-efr32mg21 BOARD=BRD4180A
```
After a successful build, the `elf` files are found in
`<path-to-openthread>/output/efr32mg21/bin`.
## Flash Binaries
Simplicity Commander provides a graphical interface for J-Link Commander.
```bash
$ cd <path-to-openthread>/output/efr32mg21/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
$ <path-to-simplicity-studio>/developer/adapter_packs/commander/commander
```
In the J-Link Device drop-down list select the serial number of the device to flash. Click the Adapter Connect button.
Esnure the Debug Interface drop-down list is set to SWD and click the Target Connect button.
Click on the Flash icon on the left side of the window to switch to the flash page.
In the Flash MCU pane enter the path of the ot-cli-ftd.s37 file or choose the file with the Browse... button.
Click the Flash button located under the Browse... button.
## Run the example with EFR32MG21 boards
1. Flash two EFR32 boards with the `CLI example` firmware (as shown above).
2. Open terminal to first device `/dev/ttyACM0` (serial port settings: 115200 8-N-1).
Type `help` for a list of commands.
```bash
> help
help
channel
childtimeout
contextreusedelay
extaddr
extpanid
ipaddr
keysequence
leaderweight
masterkey
mode
netdataregister
networkidtimeout
networkname
panid
ping
prefix
releaserouterid
rloc16
route
routerupgradethreshold
scan
start
state
stop
whitelist
```
3. Start a Thread network as Leader.
```bash
> panid 0xface
Done
> ifconfig up
Done
> thread start
Done
wait a couple of seconds...
> state
leader
Done
```
4. Open terminal to second device `/dev/ttyACM1` (serial port settings: 115200 8-N-1)
and attach it to the Thread network as a Router.
```bash
> panid 0xface
Done
> routerselectionjitter 1
Done
> ifconfig up
Done
> thread start
Done
wait a couple of seconds...
> state
router
Done
```
5. List all IPv6 addresses of Leader.
```bash
> ipaddr
fdde:ad00:beef:0:0:ff:fe00:fc00
fdde:ad00:beef:0:0:ff:fe00:800
fdde:ad00:beef:0:5b:3bcd:deff:7786
fe80:0:0:0:6447:6e10:cf7:ee29
Done
```
6. Send an ICMPv6 ping to Leader's Mesh-EID IPv6 address.
```bash
> ping fdde:ad00:beef:0:5b:3bcd:deff:7786
8 bytes from fdde:ad00:beef:0:5b:3bcd:deff:7786: icmp_seq=1 hlim=64 time=24ms
```
The above example demonstrates basic OpenThread capabilities. Enable more features/roles (e.g. commissioner,
joiner, DHCPv6 Server/Client, etc.) by assigning compile-options before compiling.
```bash
$ cd <path-to-openthread>
$ ./bootstrap
$ make -f examples/Makefile-efr32mg21 COMMISSIONER=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1
```
For a list of all available commands, visit [OpenThread CLI Reference README.md][CLI].
[CLI]: https://github.com/openthread/openthread/blob/master/src/cli/README.md
## Verification
The following toolchain has been used for testing and verification:
- gcc version 7.3.1
The EFR32 example has been verified with following Flex SDK/RAIL Library version:
- Flex SDK version 2.6.0.0
+152
View File
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2019, 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 implements the OpenThread platform abstraction for the alarm.
*
*/
#include <stdbool.h>
#include <stdint.h>
#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#include "utils/code_utils.h"
#include "em_core.h"
#include "rail.h"
#define XTAL_ACCURACY 200
#define US_IN_MS 1000
static uint32_t sTimerHi = 0;
static uint32_t sTimerLo = 0;
static uint32_t sAlarmT0 = 0;
static uint32_t sAlarmDt = 0;
static bool sIsRunning = false;
void efr32AlarmInit(void)
{
}
uint64_t otPlatTimeGet(void)
{
uint32_t timer_lo;
uint64_t timer_us;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
timer_lo = RAIL_GetTime();
if (timer_lo < sTimerLo)
{
sTimerHi++;
}
sTimerLo = timer_lo;
timer_us = (((uint64_t)sTimerHi << 32) | sTimerLo);
CORE_EXIT_CRITICAL();
return timer_us;
}
uint32_t otPlatAlarmMilliGetNow(void)
{
return otPlatTimeGet() / US_IN_MS;
}
uint32_t otPlatTimeGetXtalAccuracy(void)
{
return XTAL_ACCURACY;
}
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
{
OT_UNUSED_VARIABLE(aInstance);
sAlarmT0 = t0;
sAlarmDt = dt;
sIsRunning = true;
}
void otPlatAlarmMilliStop(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
sIsRunning = false;
}
void efr32AlarmProcess(otInstance *aInstance)
{
uint32_t now = otPlatAlarmMilliGetNow();
uint32_t expires;
bool fire = false;
otEXPECT(sIsRunning);
expires = sAlarmT0 + sAlarmDt;
if (sAlarmT0 <= now)
{
fire = (expires >= sAlarmT0 && expires <= now);
}
else
{
fire = (expires >= sAlarmT0 || expires <= now);
}
if (fire)
{
sIsRunning = false;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagAlarmFired(aInstance);
}
else
#endif
{
otPlatAlarmMilliFired(aInstance);
}
}
exit:
return;
}
void RAILCb_TimerExpired(void)
{
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2019, 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 includes dev borad compile-time configuration constants for efr32.
*
*/
#ifndef __BOARD_CONFIG_H__
#define __BOARD_CONFIG_H__
#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 ///< Dev board suppports OQPSK modulation in 2.4GHz band.
#endif // __BOARD_CONFIG_H__
@@ -0,0 +1,260 @@
#ifndef HAL_CONFIG_H
#define HAL_CONFIG_H
#include "em_device.h"
#include "hal-config-types.h"
// This file is auto-generated by Hardware Configurator in Simplicity Studio.
// Any content between $[ and ]$ will be replaced whenever the file is regenerated.
// Content outside these regions will be preserved.
// $[ACMP0]
// [ACMP0]$
// $[ACMP1]
// [ACMP1]$
// $[ADC0]
// [ADC0]$
// $[ANTDIV]
// [ANTDIV]$
// $[BATTERYMON]
// [BATTERYMON]$
// $[BTL_BUTTON]
// [BTL_BUTTON]$
// $[BULBPWM]
// [BULBPWM]$
// $[BULBPWM_COLOR]
// [BULBPWM_COLOR]$
// $[BUTTON]
// [BUTTON]$
// $[CMU]
#define HAL_CLK_HFCLK_SOURCE (HAL_CLK_HFCLK_SOURCE_HFXO)
#define BSP_CLK_LFXO_PRESENT (1)
#define HAL_CLK_EM4CLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
#define HAL_CLK_EM23CLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
#define BSP_CLK_HFXO_PRESENT (1)
#define BSP_CLK_LFXO_INIT CMU_LFXOINIT_DEFAULT
#define BSP_CLK_LFXO_CTUNE (79U)
#define HAL_CLK_RTCCCLK_SOURCE (HAL_CLK_LFCLK_SOURCE_LFRCO)
#define BSP_CLK_LFXO_FREQ (32768U)
#define BSP_CLK_HFXO_FREQ (38400000UL)
#define BSP_CLK_HFXO_CTUNE (129)
#define BSP_CLK_HFXO_INIT CMU_HFXOINIT_DEFAULT
// [CMU]$
// $[COEX]
// [COEX]$
// $[EMU]
// [EMU]$
// $[EXTFLASH]
// [EXTFLASH]$
// $[EZRADIOPRO]
// [EZRADIOPRO]$
// $[GPIO]
#define PORTIO_GPIO_SWV_PIN (3U)
#define PORTIO_GPIO_SWV_PORT (gpioPortA)
#define BSP_TRACE_SWO_PIN (3U)
#define BSP_TRACE_SWO_PORT (gpioPortA)
// [GPIO]$
// $[I2C0]
// [I2C0]$
// $[I2C1]
// [I2C1]$
// $[I2CSENSOR]
// [I2CSENSOR]$
// $[IADC0]
// [IADC0]$
// $[IOEXP]
// [IOEXP]$
// $[LED]
#define BSP_LED_PRESENT (1)
#define BSP_LED0_PIN (0U)
#define BSP_LED0_PORT (gpioPortB)
#define BSP_LED1_PIN (1U)
#define BSP_LED1_PORT (gpioPortB)
#define HAL_LED_ENABLE { 0, 1 }
#define BSP_LED_POLARITY (1)
#define HAL_LED_COUNT (2U)
#define BSP_LED_COUNT (2U)
#define BSP_LED_INIT { { BSP_LED0_PORT, BSP_LED0_PIN }, { BSP_LED1_PORT, BSP_LED1_PIN } }
// [LED]$
// $[LETIMER0]
// [LETIMER0]$
// $[LFXO]
// [LFXO]$
// $[MODEM]
// [MODEM]$
// $[PA]
#define HAL_PA_ENABLE (1)
#define HAL_PA_RAMP (10UL)
#define HAL_PA_SELECTION (HAL_PA_SELECTION_2P4_HP)
#define HAL_PA_POWER (252U)
#define HAL_PA_VOLTAGE (3300U)
#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h"
// [PA]$
// $[PORTIO]
// [PORTIO]$
// $[PRS]
// [PRS]$
// $[PTI]
#define PORTIO_PTI_DFRAME_PIN (5U)
#define PORTIO_PTI_DFRAME_PORT (gpioPortC)
#define PORTIO_PTI_DOUT_PIN (4U)
#define PORTIO_PTI_DOUT_PORT (gpioPortC)
#define HAL_PTI_ENABLE (1)
#define BSP_PTI_DFRAME_PIN (5U)
#define BSP_PTI_DFRAME_PORT (gpioPortC)
#define BSP_PTI_DOUT_PIN (4U)
#define BSP_PTI_DOUT_PORT (gpioPortC)
#define HAL_PTI_MODE (HAL_PTI_MODE_UART)
#define HAL_PTI_BAUD_RATE (1600000UL)
// [PTI]$
// $[SERIAL]
#define HAL_SERIAL_USART0_ENABLE (0)
#define HAL_SERIAL_LEUART0_ENABLE (0)
#define HAL_SERIAL_USART1_ENABLE (0)
#define HAL_SERIAL_USART2_ENABLE (0)
#define HAL_SERIAL_USART3_ENABLE (0)
#define HAL_SERIAL_RXWAKE_ENABLE (0)
#define BSP_SERIAL_APP_CTS_PIN (4U)
#define BSP_SERIAL_APP_CTS_PORT (gpioPortA)
#define BSP_SERIAL_APP_RX_PIN (6U)
#define BSP_SERIAL_APP_RX_PORT (gpioPortA)
#define BSP_SERIAL_APP_TX_PIN (5U)
#define BSP_SERIAL_APP_TX_PORT (gpioPortA)
#define BSP_SERIAL_APP_RTS_PIN (1U)
#define BSP_SERIAL_APP_RTS_PORT (gpioPortC)
#define HAL_SERIAL_APP_RX_QUEUE_SIZE (128UL)
#define HAL_SERIAL_APP_BAUD_RATE (115200UL)
#define HAL_SERIAL_APP_RXSTOP (16UL)
#define HAL_SERIAL_APP_RXSTART (16UL)
#define HAL_SERIAL_APP_TX_QUEUE_SIZE (128UL)
#define HAL_SERIAL_APP_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
// [SERIAL]$
// $[SPIDISPLAY]
// [SPIDISPLAY]$
// $[SPINCP]
// [SPINCP]$
// $[TIMER0]
// [TIMER0]$
// $[TIMER1]
// [TIMER1]$
// $[TIMER2]
// [TIMER2]$
// $[TIMER3]
// [TIMER3]$
// $[UARTNCP]
// [UARTNCP]$
// $[USART0]
#define PORTIO_USART0_CTS_PIN (4U)
#define PORTIO_USART0_CTS_PORT (gpioPortA)
#define PORTIO_USART0_RTS_PIN (1U)
#define PORTIO_USART0_RTS_PORT (gpioPortC)
#define PORTIO_USART0_RX_PIN (6U)
#define PORTIO_USART0_RX_PORT (gpioPortA)
#define PORTIO_USART0_TX_PIN (5U)
#define PORTIO_USART0_TX_PORT (gpioPortA)
#define HAL_USART0_ENABLE (1)
#define BSP_USART0_CTS_PIN (4U)
#define BSP_USART0_CTS_PORT (gpioPortA)
#define BSP_USART0_RX_PIN (6U)
#define BSP_USART0_RX_PORT (gpioPortA)
#define BSP_USART0_TX_PIN (5U)
#define BSP_USART0_TX_PORT (gpioPortA)
#define BSP_USART0_RTS_PIN (1U)
#define BSP_USART0_RTS_PORT (gpioPortC)
#define HAL_USART0_RX_QUEUE_SIZE (128UL)
#define HAL_USART0_BAUD_RATE (115200UL)
#define HAL_USART0_RXSTOP (16UL)
#define HAL_USART0_RXSTART (16UL)
#define HAL_USART0_TX_QUEUE_SIZE (128UL)
#define HAL_USART0_FLOW_CONTROL (HAL_USART_FLOW_CONTROL_HWUART)
// [USART0]$
// $[USART1]
// [USART1]$
// $[USART2]
// [USART2]$
// $[VCOM]
#define HAL_VCOM_ENABLE (1)
#define BSP_VCOM_ENABLE_PIN (4U)
#define BSP_VCOM_ENABLE_PORT (gpioPortD)
// [VCOM]$
// $[VUART]
// [VUART]$
// $[WDOG]
#define HAL_WDOG_ENABLE (0)
// [WDOG]$
#if defined(_SILICON_LABS_MODULE)
#include "sl_module.h"
#endif
#endif /* HAL_CONFIG_H */
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2019, 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.
*/
#ifndef EFR32_MBEDTLS_CONFIG_H
#define EFR32_MBEDTLS_CONFIG_H
#include "em_device.h"
#include "em_se.h"
/**
* \def MBEDTLS_AES_ALT
*
* Enable hardware acceleration for the AES block cipher
*
* Module: sl_crypto/src/crypto_aes.c for devices with CRYPTO
* sl_crypto/src/aes_aes.c for devices with AES
*
* See MBEDTLS_AES_C for more information.
*/
#define MBEDTLS_AES_ALT
/**
* \def MBEDTLS_ENTROPY_HARDWARE_ALT
*
* Integrate the provided default entropy source into the mbed
* TLS entropy infrastructure.
*
*/
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_SHA256_C
/**
* \def MBEDTLS_ECP_INTERNAL_ALT
* \def ECP_SHORTWEIERSTRASS
* \def MBEDTLS_ECP_ADD_MIXED_ALT
* \def MBEDTLS_ECP_DOUBLE_JAC_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
*
* Enable hardware acceleration for the elliptic curve over GF(p) library.
*
* Module: sl_crypto/src/crypto_ecp.c
* Caller: library/ecp.c
*
* Requires: MBEDTLS_BIGNUM_C, MBEDTLS_ECP_C and at least one
* MBEDTLS_ECP_DP_XXX_ENABLED and (CRYPTO_COUNT > 0)
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_ECP_INTERNAL_ALT
#define ECP_SHORTWEIERSTRASS
#define MBEDTLS_ECP_ADD_MIXED_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
#endif
/**
* \def MBEDTLS_SHA256_ALT
*
* Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
* hash algorithms.
*
* Module: sl_crypto/src/crypto_sha.c
* Caller: library/entropy.c
* library/mbedtls_md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
*
* Requires: MBEDTLS_SHA256_C and (CRYPTO_COUNT > 0)
* See MBEDTLS_SHA256_C for more information.
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
//#define MBEDTLS_SHA256_ALT
#endif
#endif // EFR32_MBEDTLS_CONFIG_H
+95
View File
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2019, 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 implements the OpenThread platform abstraction for the diagnostics.
*
*/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>
#include "platform-efr32.h"
#if OPENTHREAD_ENABLE_DIAG
/**
* Diagnostics mode variables.
*
*/
static bool sDiagMode = false;
void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(argc);
// Add more platform specific diagnostics features here.
snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
}
void otPlatDiagModeSet(bool aMode)
{
sDiagMode = aMode;
}
bool otPlatDiagModeGet()
{
return sDiagMode;
}
void otPlatDiagChannelSet(uint8_t aChannel)
{
OT_UNUSED_VARIABLE(aChannel);
}
void otPlatDiagTxPowerSet(int8_t aTxPower)
{
OT_UNUSED_VARIABLE(aTxPower);
}
void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aFrame);
OT_UNUSED_VARIABLE(aError);
}
void otPlatDiagAlarmCallback(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
}
#endif // #if OPENTHREAD_ENABLE_DIAG
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2019, 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 implements the OpenThread platform abstraction for random number generator.
*
*/
#include <openthread/platform/entropy.h>
#include "mbedtls/entropy_poll.h"
#include "utils/code_utils.h"
static uint32_t randomUint32Get(void)
{
uint32_t random = 0;
size_t ouputLen = 0;
mbedtls_hardware_poll(NULL, (unsigned char *)&random, sizeof(random), &ouputLen);
return random;
}
otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(aOutput, error = OT_ERROR_INVALID_ARGS);
for (uint16_t length = 0; length < aOutputLength; length++)
{
aOutput[length] = (uint8_t)randomUint32Get();
}
exit:
return error;
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2019, 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 "hal-config.h"
#if (HAL_FEM_ENABLE)
#include "../../../third_party/silabs/gecko_sdk_suite/v2.6/util/plugin/plugin-common/fem-control/fem-control.c"
#endif
+144
View File
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2019, 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 implements the OpenThread platform abstraction for the non-volatile storage.
*/
#include <openthread-core-config.h>
#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include "utils/code_utils.h"
#include "utils/flash.h"
#include "em_msc.h"
// clang-format off
#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM))
// clang-format on
static inline uint32_t mapAddress(uint32_t aAddress)
{
return aAddress + FLASH_DATA_START_ADDR;
}
static otError returnTypeConvert(int32_t aStatus)
{
otError error = OT_ERROR_NONE;
switch (aStatus)
{
case mscReturnOk:
error = OT_ERROR_NONE;
break;
case mscReturnInvalidAddr:
case mscReturnUnaligned:
error = OT_ERROR_INVALID_ARGS;
break;
default:
error = OT_ERROR_FAILED;
}
return error;
}
otError utilsFlashInit(void)
{
MSC_Init();
return OT_ERROR_NONE;
}
uint32_t utilsFlashGetSize(void)
{
return FLASH_DATA_END_ADDR - FLASH_DATA_START_ADDR;
}
otError utilsFlashErasePage(uint32_t aAddress)
{
int32_t status;
status = MSC_ErasePage((uint32_t *)mapAddress(aAddress));
return returnTypeConvert(status);
}
otError utilsFlashStatusWait(uint32_t aTimeout)
{
otError error = OT_ERROR_BUSY;
uint32_t start = otPlatAlarmMilliGetNow();
do
{
if (MSC->STATUS & MSC_STATUS_WDATAREADY)
{
error = OT_ERROR_NONE;
break;
}
} while (aTimeout && ((otPlatAlarmMilliGetNow() - start) < aTimeout));
return error;
}
uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t rval = aSize;
int32_t status;
otEXPECT_ACTION(aData, rval = 0);
otEXPECT_ACTION(((aAddress + aSize) < utilsFlashGetSize()) && (!(aAddress & 3)) && (!(aSize & 3)), rval = 0);
status = MSC_WriteWord((uint32_t *)mapAddress(aAddress), aData, aSize);
otEXPECT_ACTION(returnTypeConvert(status) == OT_ERROR_NONE, rval = 0);
exit:
return rval;
}
uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t rval = aSize;
uint32_t pAddress = mapAddress(aAddress);
uint8_t *byte = aData;
otEXPECT_ACTION(aData, rval = 0);
otEXPECT_ACTION((aAddress + aSize) < utilsFlashGetSize(), rval = 0);
while (aSize--)
{
*byte++ = (*(uint8_t *)(pAddress++));
}
exit:
return rval;
}
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2019, 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 logging.c
* Platform abstraction for the logging
*
*/
#include <openthread-core-config.h>
#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/logging.h>
#include <utils/logging_rtt.h>
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
(OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
void efr32LogInit(void)
{
utilsLogRttInit();
}
void efr32LogDeinit(void)
{
utilsLogRttDeinit();
}
OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
va_list ap;
va_start(ap, aFormat);
utilsLogRttOutput(aLogLevel, aLogRegion, aFormat, ap);
va_end(ap);
}
#endif
+99
View File
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2019, 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 implements the OpenThread platform abstraction for miscellaneous behaviors.
*/
#include <openthread/platform/misc.h>
#include "em_rmu.h"
#include "platform-efr32.h"
static uint32_t sResetCause;
void efr32MiscInit(void)
{
// Read the cause of last reset.
sResetCause = RMU_ResetCauseGet();
// Clear the register, as the causes cumulate over resets.
RMU_ResetCauseClear();
}
void otPlatReset(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
NVIC_SystemReset();
}
otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
otPlatResetReason reason;
if (sResetCause & EMU_RSTCAUSE_POR)
{
reason = OT_PLAT_RESET_REASON_POWER_ON;
}
else if (sResetCause & EMU_RSTCAUSE_SYSREQ)
{
reason = OT_PLAT_RESET_REASON_SOFTWARE;
}
else if ((sResetCause & EMU_RSTCAUSE_WDOG0) || (sResetCause & EMU_RSTCAUSE_WDOG1))
{
reason = OT_PLAT_RESET_REASON_WATCHDOG;
}
else if (sResetCause & EMU_RSTCAUSE_PIN)
{
reason = OT_PLAT_RESET_REASON_EXTERNAL;
}
else if (sResetCause & EMU_RSTCAUSE_LOCKUP)
{
reason = OT_PLAT_RESET_REASON_FAULT;
}
else if ((sResetCause & EMU_RSTCAUSE_AVDDBOD) || (sResetCause & EMU_RSTCAUSE_DECBOD) ||
(sResetCause & EMU_RSTCAUSE_DVDDBOD) || (sResetCause & EMU_RSTCAUSE_DVDDLEBOD) ||
(sResetCause & EMU_RSTCAUSE_EM4))
{
reason = OT_PLAT_RESET_REASON_ASSERT;
}
else
{
reason = OT_PLAT_RESET_REASON_UNKNOWN;
}
return reason;
}
void otPlatWakeHost(void)
{
// TODO: implement an operation to wake the host from sleep state.
}
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2019, 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 includes efr32 compile-time configuration constants
* for OpenThread.
*/
#include "board_config.h"
#include "em_msc.h"
#ifndef OPENTHREAD_CORE_EFR32_CONFIG_H_
#define OPENTHREAD_CORE_EFR32_CONFIG_H_
/**
* @def OPENTHREAD_CONFIG_LOG_OUTPUT
*
* The efr32 platform provides an otPlatLog() function.
*/
#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
#endif
/*
* @def OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
*
* We dont support sub-gig frequencies on MG21.
*
*/
#define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 0
/*
* @def OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
*
* Define to 1 if you want to enable physical layer to support OQPSK modulation in 2.4GHz band.
*
*/
#ifdef RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
#define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 1
#else
#define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 0
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_INFO
*
* The platform-specific string to insert into the OpenThread version string.
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
/*
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
*
* Define to 1 if you want to enable software retransmission logic.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1
/**
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF
*
* Define to 1 if you want to enable software CSMA-CA backoff logic.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 1
/**
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN
*
* Define to 1 if you want to enable software energy scanning logic.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN 1
/**
* @def SETTINGS_CONFIG_BASE_ADDRESS
*
* The base address of settings.
*
*/
#define SETTINGS_CONFIG_BASE_ADDRESS 0
/**
* @def SETTINGS_CONFIG_PAGE_SIZE
*
* The page size of settings.
*
*/
#define SETTINGS_CONFIG_PAGE_SIZE FLASH_PAGE_SIZE
/**
* @def SETTINGS_CONFIG_PAGE_NUM
*
* The page number of settings.
*
*/
#define SETTINGS_CONFIG_PAGE_NUM 4
/**
* @def RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
*
* The number of short source address table entries.
*
*/
#define RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM 6
/**
* @def RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
*
* The number of extended source address table entries.
*
*/
#define RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM 6
#endif // OPENTHREAD_CORE_EFR32_CONFIG_H_
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2019, 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 includes the platform-specific initializers.
*
*/
#ifndef PLATFORM_EFR32_H_
#define PLATFORM_EFR32_H_
#include <openthread/instance.h>
#include "em_device.h"
#include "em_system.h"
#include "core_cm33.h"
// Global OpenThread instance structure
extern otInstance *sInstance;
/**
* This function initializes the alarm service used by OpenThread.
*
*/
void efr32AlarmInit(void);
/**
* This function performs alarm driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void efr32AlarmProcess(otInstance *aInstance);
/**
* This function initializes the radio service used by OpenThead.
*
*/
void efr32RadioInit(void);
/**
* This function deinitializes the radio service used by OpenThead.
*
*/
void efr32RadioDeinit(void);
/**
* This function performs radio driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void efr32RadioProcess(otInstance *aInstance);
/**
* This function performs UART driver processing.
*
*/
void efr32UartProcess(void);
/**
* Initialization of Misc module.
*
*/
void efr32MiscInit(void);
/**
* Initialization of ADC module for random number generator.
*
*/
void efr32RandomInit(void);
/**
* Initialization of Logger driver.
*
*/
void efr32LogInit(void);
/**
* Deinitialization of Logger driver.
*
*/
void efr32LogDeinit(void);
#endif // PLATFORM_EFR32_H_
@@ -45,7 +45,6 @@
#include "utils/soft_source_match_table.h"
#include "board_config.h"
#include "em_cmu.h"
#include "em_core.h"
#include "em_system.h"
#include "openthread-core-efr32-config.h"
@@ -54,7 +53,6 @@
#include "rail.h"
#include "rail_config.h"
#include "rail_ieee802154.h"
#include "rtcdriver.h"
enum
{
@@ -84,11 +82,7 @@ enum
enum
{
#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT && RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
EFR32_NUM_BAND_CONFIGS = 2,
#else
EFR32_NUM_BAND_CONFIGS = 1,
#endif
};
typedef enum
@@ -104,8 +98,6 @@ typedef enum
ENERGY_SCAN_MODE_ASYNC
} energyScanMode;
RAIL_Handle_t gRailHandle;
static volatile bool sTransmitBusy = false;
static bool sPromiscuous = false;
static bool sIsSrcMatchEnabled = false;
@@ -161,7 +153,7 @@ static const RAIL_IEEE802154_Config_t sRailIeee802154Config = {
false, // isPanCoordinator
};
RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp);
RAIL_DECLARE_TX_POWER_VBAT_CURVES_ALT;
static int8_t sTxPowerDbm = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
@@ -182,11 +174,6 @@ static RAIL_Handle_t efr32RailConfigInit(efr32BandConfig *aBandConfig)
handle = RAIL_Init(&aBandConfig->mRailConfig, NULL);
assert(handle != NULL);
if (gRailHandle == NULL)
{
gRailHandle = handle;
}
status = RAIL_ConfigData(handle, &railDataConfig);
assert(status == RAIL_STATUS_NO_ERROR);
@@ -232,16 +219,11 @@ static void efr32RadioSetTxPower(RAIL_Handle_t aRailHandle,
const RAIL_ChannelConfig_t *aChannelConfig,
uint8_t aPowerDbm)
{
RAIL_Status_t status;
RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = {curves24Hp, curvesSg, curves24Lp, piecewiseSegments};
RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, 3300, 10};
RAIL_Status_t status;
const RAIL_TxPowerCurvesConfigAlt_t txPowerCurvesConfig = RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT;
RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, 3300, 10};
if ((aChannelConfig != NULL) && (aChannelConfig->configs[0].baseFrequency < 1000000000UL))
{
txPowerConfig.mode = RAIL_TX_POWER_MODE_SUBGIG;
}
status = RAIL_InitTxPowerCurves(&txPowerCurvesConfig);
status = RAIL_InitTxPowerCurvesAlt(&txPowerCurvesConfig);
assert(status == RAIL_STATUS_NO_ERROR);
status = RAIL_ConfigTxPower(aRailHandle, &txPowerConfig);
@@ -282,30 +264,12 @@ static void efr32BandConfigInit(void (*aEventCallback)(RAIL_Handle_t railHandle,
assert((sBandConfigs[index].mRailHandle = efr32RailConfigInit(&sBandConfigs[index])) != NULL);
index++;
#endif
#if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
sBandConfigs[index].mRailConfig.eventsCallback = aEventCallback;
sBandConfigs[index].mRailConfig.protocol = NULL;
sBandConfigs[index].mRailConfig.scheduler = &sBandConfigs[index].mRailSchedState;
sBandConfigs[index].mChannelConfig = channelConfigs[0];
sBandConfigs[index].mChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
sBandConfigs[index].mChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX;
assert((sBandConfigs[index].mRailHandle = efr32RailConfigInit(&sBandConfigs[index])) != NULL);
#endif
}
void efr32RadioInit(void)
{
RAIL_Status_t status;
efr32BandConfigInit(RAILCb_Generic);
CMU_ClockEnable(cmuClock_PRS, true);
RTCDRV_Init();
status = RAIL_ConfigSleep(gRailHandle, RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED);
assert(status == RAIL_STATUS_NO_ERROR);
sReceiveFrame.mLength = 0;
sReceiveFrame.mPsdu = sReceivePsdu;
sTransmitFrame.mLength = 0;
@@ -512,6 +476,7 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
RAIL_SchedulerInfo_t schedulerInfo = {.priority = EFR32_SCHEDULER_TX_PRIORITY};
efr32BandConfig * config;
RAIL_Status_t status;
uint8_t frameLength;
otEXPECT_ACTION((sState != OT_RADIO_STATE_DISABLED) && (sState != OT_RADIO_STATE_TRANSMIT),
error = OT_ERROR_INVALID_STATE);
@@ -529,8 +494,10 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
sTxBandConfig = config;
}
RAIL_WriteTxFifo(sTxBandConfig->mRailHandle, &aFrame->mLength, sizeof(aFrame->mLength), true);
RAIL_WriteTxFifo(sTxBandConfig->mRailHandle, aFrame->mPsdu, aFrame->mLength - 2, false);
otEXPECT(aFrame->mLength >= IEEE802154_MIN_LENGTH && aFrame->mLength <= IEEE802154_MAX_LENGTH);
frameLength = (uint8_t)aFrame->mLength;
RAIL_WriteTxFifo(sTxBandConfig->mRailHandle, &frameLength, sizeof frameLength, true);
RAIL_WriteTxFifo(sTxBandConfig->mRailHandle, aFrame->mPsdu, frameLength - 2, false);
if (aFrame->mPsdu[0] & IEEE802154_ACK_REQUEST)
{
@@ -696,10 +663,6 @@ static void processNextRxPacket(otInstance *aInstance, RAIL_Handle_t aRailHandle
sReceiveError = OT_ERROR_NONE;
// TODO Set this flag only when the packet is really acknowledged with frame pending set.
// See https://github.com/openthread/openthread/pull/3785
sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
@@ -0,0 +1,10 @@
#ifndef __RAIL_CONFIG_H__
#define __RAIL_CONFIG_H__
#include <stdint.h>
#include "rail_types.h"
#include "board_config.h"
#define RADIO_CONFIG_XTAL_FREQUENCY 38400000UL
#endif // __RAIL_CONFIG_H__
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2019, 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 implements gcc-specific startup code for the efr32.
*/
__extension__ typedef int __guard __attribute__((mode(__DI__)));
int __cxa_guard_acquire(__guard *g)
{
return !*(char *)(g);
}
void __cxa_guard_release(__guard *g)
{
*(char *)g = 1;
}
void __cxa_guard_abort(__guard *g)
{
(void)g;
}
void __cxa_pure_virtual(void)
{
while (1)
;
}
+109
View File
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2019, 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
* @brief
* This file includes the platform-specific initializers.
*/
#include <string.h>
#include <openthread/platform/uart.h>
#include "common/logging.hpp"
#include "bsp.h"
#include "em_chip.h"
#include "hal_common.h"
#include "openthread-core-efr32-config.h"
#include "platform-efr32.h"
#include "hal-config.h"
#if (HAL_FEM_ENABLE)
#include "fem-control.h"
#endif
#define USE_EFR32_LOG \
((OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
(OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL))
void halInitChipSpecific(void);
otInstance *sInstance;
void otSysInit(int argc, char *argv[])
{
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
CHIP_Init();
halInitChipSpecific();
BSP_Init(BSP_INIT_BCC);
#if (HAL_FEM_ENABLE)
initFem();
wakeupFem();
#endif
#if USE_EFR32_LOG
efr32LogInit();
#endif
efr32RadioInit();
efr32AlarmInit();
efr32MiscInit();
}
bool otSysPseudoResetWasRequested(void)
{
return false;
}
void otSysDeinit(void)
{
efr32RadioDeinit();
#if USE_EFR32_LOG
efr32LogDeinit();
#endif
}
void otSysProcessDrivers(otInstance *aInstance)
{
sInstance = aInstance;
// should sleep and wait for interrupts here
efr32UartProcess();
efr32RadioProcess(aInstance);
efr32AlarmProcess(aInstance);
}
+318
View File
@@ -0,0 +1,318 @@
/*
* Copyright (c) 2019, 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 implements the OpenThread platform abstraction for UART communication.
*
*/
#include <stddef.h>
#include <openthread/platform/uart.h>
#include "utils/code_utils.h"
#include "em_core.h"
#include "uartdrv.h"
#include <assert.h>
#include <string.h>
#include "hal-config.h"
enum
{
kReceiveFifoSize = 128,
kDmaBlockSize = 64
};
#define USART_PORT USART0
#define USART_PORT_RX_IRQn USART0_RX_IRQn
#define USART_INIT \
{ \
USART_PORT, /* USART port */ \
115200, /* Baud rate */ \
BSP_SERIAL_APP_TX_PORT, /* USART Tx port number */ \
BSP_SERIAL_APP_RX_PORT, /* USART Rx port number */ \
BSP_SERIAL_APP_TX_PIN, /* USART Tx pin number */ \
BSP_SERIAL_APP_RX_PIN, /* USART Rx pin number */ \
0, /* UART instance number */ \
(USART_Stopbits_TypeDef)USART_FRAME_STOPBITS_ONE, /* Stop bits */ \
(USART_Parity_TypeDef)USART_FRAME_PARITY_NONE, /* Parity */ \
(USART_OVS_TypeDef)USART_CTRL_OVS_X16, /* Oversampling mode*/ \
false, /* Majority vote disable */ \
HAL_SERIAL_APP_FLOW_CONTROL, /* Flow control */ \
BSP_SERIAL_APP_CTS_PORT, /* CTS port number */ \
BSP_SERIAL_APP_CTS_PIN, /* CTS pin number */ \
BSP_SERIAL_APP_RTS_PORT, /* RTS port number */ \
BSP_SERIAL_APP_RTS_PIN, /* RTS pin number */ \
(UARTDRV_Buffer_FifoQueue_t *)&sUartRxQueue, /* RX operation queue */ \
(UARTDRV_Buffer_FifoQueue_t *)&sUartTxQueue, /* TX operation queue */ \
}
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS, sUartRxQueue);
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS, sUartTxQueue);
static CORE_DECLARE_NVIC_MASK(sRxNvicMask);
static UARTDRV_HandleData_t sUartHandleData;
static UARTDRV_Handle_t sUartHandle = &sUartHandleData;
static const uint8_t * sTransmitBuffer;
static volatile uint16_t sTransmitLength;
static volatile bool sReceiveDeferred;
// Using unwrapped indexes allows buffer full and buffer empty conditions to be easily distinguished.
// These values will eventually wrap themselves (due to an integer overflow). They should always be wrapped
// using %kReceiveFifoSize at the point of use, except if testing for a buffer empty condition (mReadEnd == mReadStart).
// kReceiveFifoSize must therefore also be specified to a length of a power of 2.
typedef struct ReceiveFifo_t
{
// The data buffer
uint8_t mBuffer[kReceiveFifoSize];
// The offset of the first item to be read from the list (unwrapped)
uint16_t mReadStart;
// The offset of the last item to be read plus one (unwrapped)
volatile uint16_t mReadEnd;
// The offset of first unused item (unwrapped)
volatile uint16_t mWrite;
} ReceiveFifo_t;
static ReceiveFifo_t sReceiveFifo;
static bool enqueueNextReceive(void);
static void updateReceiveProgress(uint8_t *aData, UARTDRV_Count_t aCount)
{
assert(aData != NULL);
const uint16_t blockStartWrapped = aData - sReceiveFifo.mBuffer;
const uint16_t readEndWrapped = sReceiveFifo.mReadEnd % kReceiveFifoSize;
// Check readEndWrapped is within range of the current block. Required when mReadEnd was set to the end of
// the buffer on a previous call and readEndWrapped now wraps to 0.
if (readEndWrapped >= blockStartWrapped && readEndWrapped < blockStartWrapped + kDmaBlockSize)
{
sReceiveFifo.mReadEnd += blockStartWrapped + aCount - readEndWrapped;
}
}
static void receiveDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
{
updateReceiveProgress(aData, aCount);
if (!enqueueNextReceive())
{
// A failure to enqueue the next receive is due to no free blocks remaining in the buffer. Defer enqueueing
// the next receive operation to processReceive() (running in the main execution context) where the
// contents of the buffer shall firstly be emptied. In the mean time, flow control RTS will be deasserted.
assert(sReceiveDeferred == false);
sReceiveDeferred = true;
}
}
static inline bool isBufferEmpty(uint16_t unwrappedReadStart, uint16_t unwrappedReadEnd)
{
return (unwrappedReadStart == unwrappedReadEnd);
}
static bool enqueueNextReceive(void)
{
bool result;
const uint16_t wrappedWrite = sReceiveFifo.mWrite % kReceiveFifoSize;
const uint16_t wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
Ecode_t status;
if (isBufferEmpty(sReceiveFifo.mReadStart, sReceiveFifo.mReadEnd))
{
// Buffer is completely empty
result = true;
}
else if (wrappedReadStart == wrappedWrite)
{
// Buffer is completely full because it isn't empty and wrappedReadStart == wrappedWrite
result = false;
}
else if (wrappedReadStart > wrappedWrite)
{
// Read wrappedReadStart is ahead of wrappedWrite: the next block may or may not be fully vacant
result = (wrappedReadStart - wrappedWrite >= kDmaBlockSize);
}
else
{
// Read wrappedReadStart is behind wrappedWrite, so therefore there is at least one block free
result = true;
}
otEXPECT(result);
status = UARTDRV_Receive(sUartHandle, sReceiveFifo.mBuffer + wrappedWrite, kDmaBlockSize, receiveDone);
otEXPECT_ACTION(ECODE_OK == status, result = false);
sReceiveFifo.mWrite += kDmaBlockSize;
exit:
return result;
}
static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
{
sTransmitLength = 0;
}
static void processReceive(void)
{
uint16_t readEnd;
uint8_t * buffer;
UARTDRV_Count_t itemsReceived;
UARTDRV_Count_t itemsRemaining;
uint16_t wrappedReadStart;
uint16_t wrappedReadEnd;
uint16_t readLength;
CORE_DECLARE_NVIC_STATE;
CORE_ENTER_NVIC(&sRxNvicMask);
UARTDRV_GetReceiveStatus(sUartHandle, &buffer, &itemsReceived, &itemsRemaining);
if (buffer != NULL)
{
// Only update the receive progress if a current receive is in progress (buffer not NULL)
updateReceiveProgress(buffer, itemsReceived);
}
readEnd = sReceiveFifo.mReadEnd;
CORE_EXIT_NVIC();
wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
wrappedReadEnd = readEnd % kReceiveFifoSize;
if (!isBufferEmpty(sReceiveFifo.mReadStart, readEnd))
{
if (wrappedReadStart >= wrappedReadEnd)
{
// The buffer isn't empty, and wrappedReadStart >= wrappedReadEnd. Firstly, data needs to be read
// from wrappedReadStart to the end of the buffer. Subsequently, data can then be read from the start
// of the buffer to wrappedReadEnd.
readLength = kReceiveFifoSize - wrappedReadStart;
otPlatUartReceived(sReceiveFifo.mBuffer + wrappedReadStart, readLength);
// Move the read start index by the amount of data read
sReceiveFifo.mReadStart += readLength;
}
// mReadStart may have been modified above, so recalculate wrappedReadStart
wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
if (!isBufferEmpty(sReceiveFifo.mReadStart, readEnd))
{
// There is still data in the buffer (i.e. wrappedReadStart < wrappedReadEnd)
readLength = wrappedReadEnd - wrappedReadStart;
otPlatUartReceived(sReceiveFifo.mBuffer + wrappedReadStart, readLength);
// All data has been read
sReceiveFifo.mReadStart = readEnd;
}
}
CORE_ENTER_NVIC(&sRxNvicMask);
// The buffer has been emptied, but it may have since filled up again just before entering this critical section.
// Attempt to enqueue any receive operations that previously failed to enqueue due to a full buffer.
if (sReceiveDeferred)
{
sReceiveDeferred = !enqueueNextReceive();
}
CORE_EXIT_NVIC();
}
static void processTransmit(void)
{
if (sTransmitBuffer != NULL && sTransmitLength == 0)
{
sTransmitBuffer = NULL;
otPlatUartSendDone();
}
}
otError otPlatUartEnable(void)
{
otError error = OT_ERROR_NONE;
UARTDRV_Init_t uartInit = USART_INIT;
bool enqueuedReceive;
memset(&sRxNvicMask, 0, sizeof(sRxNvicMask));
CORE_NvicMaskSetIRQ(LDMA_IRQn, &sRxNvicMask);
CORE_NvicMaskSetIRQ(USART_PORT_RX_IRQn, &sRxNvicMask);
sReceiveFifo.mReadStart = 0;
sReceiveFifo.mReadEnd = 0;
sReceiveFifo.mWrite = 0;
sTransmitLength = 0;
sTransmitBuffer = NULL;
otEXPECT_ACTION(ECODE_OK == UARTDRV_Init(sUartHandle, &uartInit), error = OT_ERROR_FAILED);
CORE_DECLARE_NVIC_STATE;
CORE_ENTER_NVIC(&sRxNvicMask);
enqueuedReceive = enqueueNextReceive();
CORE_EXIT_NVIC();
otEXPECT_ACTION(enqueuedReceive, error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatUartDisable(void)
{
return OT_ERROR_NOT_IMPLEMENTED;
}
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
{
otError error = OT_ERROR_NONE;
Ecode_t status;
otEXPECT_ACTION(sTransmitBuffer == NULL, error = OT_ERROR_BUSY);
sTransmitBuffer = aBuf;
sTransmitLength = aBufLength;
status = UARTDRV_Transmit(sUartHandle, (uint8_t *)sTransmitBuffer, sTransmitLength, transmitDone);
otEXPECT_ACTION(ECODE_OK == status, error = OT_ERROR_FAILED);
exit:
return error;
}
void efr32UartProcess(void)
{
processReceive();
processTransmit();
}
+10 -7
View File
@@ -33,15 +33,10 @@ EXTRA_DIST = \
nlbuild-autotools \
openthread-test-driver \
NordicSemiconductor \
silabs \
synopsys \
$(NULL)
if OPENTHREAD_EXAMPLES_EFR32
EXTRA_DIST += \
silabs \
$(NULL)
endif
# Always package (e.g. for 'make dist') these subdirectories.
DIST_SUBDIRS = \
@@ -51,8 +46,16 @@ DIST_SUBDIRS = \
SUBDIRS =
if OPENTHREAD_EXAMPLES_EFR32
if OPENTHREAD_EXAMPLES_EFR32MG12
SUBDIRS += \
silabs \
jlink \
$(NULL)
endif
if OPENTHREAD_EXAMPLES_EFR32MG21
SUBDIRS += \
silabs \
jlink \
$(NULL)
endif
+3 -1
View File
@@ -80,11 +80,13 @@ libmbedcrypto_a_SOURCES = \
repo/library/x509_crt.c \
$(NULL)
if !OPENTHREAD_EXAMPLES_EFR32
if !OPENTHREAD_EXAMPLES_EFR32MG12
if !OPENTHREAD_EXAMPLES_EFR32MG21
libmbedcrypto_a_SOURCES += \
repo/library/ecp.c \
$(NULL)
endif
endif
if OPENTHREAD_BUILD_COVERAGE
Dash = -
+172
View File
@@ -0,0 +1,172 @@
#
# Copyright (c) 2019, 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 $(abs_top_nlbuild_autotools_dir)/automake/pre.am
if OPENTHREAD_EXAMPLES_EFR32MG12
lib_LIBRARIES = \
libsilabs-efr32mg12-sdk.a \
$(NULL)
endif
if OPENTHREAD_EXAMPLES_EFR32MG21
lib_LIBRARIES = \
libsilabs-efr32mg21-sdk.a \
$(NULL)
endif
# Do not enable -Wconversion for Silicon Labs SDK sources
override CFLAGS := $(filter-out -Wconversion,$(CFLAGS))
override CXXFLAGS := $(filter-out -Wconversion,$(CXXFLAGS))
# Do not enable -pedantic-errors for Silicon Labs SDK sources
override CFLAGS := $(filter-out -pedantic-errors,$(CFLAGS))
override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
# Do not enable -Wshadow for Silicon Labs SDK sources
override CFLAGS := $(filter-out -Wshadow,$(CFLAGS))
override CXXFLAGS := $(filter-out -Wshadow,$(CXXFLAGS))
EFR32_BOARD_DIR = $(shell echo $(BOARD) | tr A-Z a-z)
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v2.6
COMMONCPPFLAGS = \
-D__START=main \
-D__STARTUP_CLEAR_BSS \
-I$(srcdir) \
-I$(top_srcdir)/include \
-I$(top_srcdir)/third_party/silabs/rail_config \
-I$(top_srcdir)/examples/platforms/efr32mg21/$(EFR32_BOARD_DIR) \
-I$(EFR32MG_SDK_SRCDIR) \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/common \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/chip/efr32 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/protocol/ieee802154 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/chip/efr32/rf/common/cortex \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/hal \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/hal/efr32 \
-I$(EFR32MG_SDK_SRCDIR)/platform/radio/rail_lib/plugin/pa-conversions \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/common/bsp \
-I$(EFR32MG_SDK_SRCDIR)/platform/CMSIS/Include \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/common/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/gpiointerrupt/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/uartdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/uartdrv/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/ustimer/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/dmadrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/dmadrv/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/rtcdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emlib/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/halconfig/inc/hal-config \
-I$(EFR32MG_SDK_SRCDIR)/util/plugin/plugin-common/fem-control \
-Wno-unused-parameter \
-Wno-missing-field-initializers \
$(NULL)
SILABS_EFR32MG12_CPPFLAGS = \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/EFR32MG12_$(BOARD)/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/Device/SiliconLabs/EFR32MG12P/Include \
$(NULL)
SILABS_EFR32MG21_CPPFLAGS = \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/EFR32MG21_$(BOARD)/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/Device/SiliconLabs/EFR32MG21P/Include \
$(NULL)
SILABS_COMMON_SOURCES = \
rail_config/rail_config.c \
gecko_sdk_suite/v2.6/hardware/kit/common/bsp/bsp_bcc.c \
gecko_sdk_suite/v2.6/hardware/kit/common/bsp/bsp_init.c \
gecko_sdk_suite/v2.6/hardware/kit/common/bsp/bsp_stk.c \
gecko_sdk_suite/v2.6/hardware/kit/common/bsp/bsp_stk_leds.c \
gecko_sdk_suite/v2.6/platform/emdrv/dmadrv/src/dmadrv.c \
gecko_sdk_suite/v2.6/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c \
gecko_sdk_suite/v2.6/platform/emdrv/rtcdrv/src/rtcdriver.c \
gecko_sdk_suite/v2.6/platform/emdrv/uartdrv/src/uartdrv.c \
gecko_sdk_suite/v2.6/platform/emdrv/ustimer/src/ustimer.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_adc.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_cmu.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_core.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_crypto.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_emu.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_gpio.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_ldma.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_leuart.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_msc.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_rmu.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_rtcc.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_system.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_timer.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_usart.c \
gecko_sdk_suite/v2.6/platform/radio/rail_lib/hal/efr32/hal_efr.c \
gecko_sdk_suite/v2.6/platform/radio/rail_lib/hal/hal_common.c \
gecko_sdk_suite/v2.6/util/third_party/mbedtls/library/ecp.c \
gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/src/crypto_aes.c \
gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/src/crypto_ecp.c \
gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/src/crypto_management.c \
$(NULL)
SILABS_EFR32MG12_SOURCES = \
gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \
gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \
$(NULL)
SILABS_EFR32MG21_SOURCES = \
gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG21/Source/system_efr32mg21.c \
gecko_sdk_suite/v2.6/platform/Device/SiliconLabs/EFR32MG21/Source/GCC/startup_efr32mg21.c \
gecko_sdk_suite/v2.6/platform/emlib/src/em_se.c \
gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/src/se_trng.c \
gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/src/se_aes.c \
gecko_sdk_suite/v2.6/util/third_party/mbedtls/sl_crypto/src/se_management.c \
$(NULL)
libsilabs_efr32mg12_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(SILABS_EFR32MG12_CPPFLAGS) \
$(NULL)
libsilabs_efr32mg12_sdk_a_SOURCES = \
$(SILABS_COMMON_SOURCES) \
$(SILABS_EFR32MG12_SOURCES) \
$(NULL)
libsilabs_efr32mg21_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(SILABS_EFR32MG21_CPPFLAGS) \
$(NULL)
libsilabs_efr32mg21_sdk_a_SOURCES = \
$(SILABS_COMMON_SOURCES) \
$(SILABS_EFR32MG21_SOURCES) \
$(NULL)
noinst_HEADERS = \
$(NULL)
include $(abs_top_nlbuild_autotools_dir)/automake/post.am