Add support for SiLabs EFR32. (#1592)

* Add support for SiLabs EFR32.
This commit is contained in:
Xiao Ma
2017-04-24 10:48:18 -07:00
committed by Jonathan Hui
parent 739006be37
commit b83f644cb3
24 changed files with 2852 additions and 6 deletions
+11 -2
View File
@@ -957,11 +957,11 @@ AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_RAW_LINK_API],[${OPENTHREAD_ENABLE_RAW_LIN
AC_ARG_WITH(examples,
[AS_HELP_STRING([--with-examples=TARGET],
[Specify the examples from one of: none, posix, cc2538, cc2650, da15000, nrf52840 @<:@default=none@:>@.])],
[Specify the examples from one of: none, posix, cc2538, cc2650, da15000, efr32, nrf52840 @<:@default=none@:>@.])],
[
case "${with_examples}" in
none|posix|cc2538|cc2650|da15000|nrf52840)
none|posix|cc2538|cc2650|da15000|efr32|nrf52840)
;;
*)
AC_MSG_ERROR([Invalid value ${with_examples} for --with-examples])
@@ -994,6 +994,11 @@ case ${with_examples} in
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_DA15000],[${OPENTHREAD_EXAMPLES_DA15000}],[Define to 1 if you want to use da15000 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])
;;
nrf52840)
OPENTHREAD_EXAMPLES_NRF52840=1
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_NRF52840],[${OPENTHREAD_EXAMPLES_NRF52840}],[Define to 1 if you want to use nrf52840 examples])
@@ -1020,6 +1025,9 @@ AM_CONDITIONAL([OPENTHREAD_EXAMPLES_CC2650], [test "${OPENTHREAD_EXAMPLES}" = "c
AC_SUBST(OPENTHREAD_EXAMPLES_DA15000)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_DA15000], [test "${OPENTHREAD_EXAMPLES}" = "da15000"])
AC_SUBST(OPENTHREAD_EXAMPLES_EFR32)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32], [test "${OPENTHREAD_EXAMPLES}" = "efr32"])
AC_SUBST(OPENTHREAD_EXAMPLES_NRF52840)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_NRF52840], [test "${OPENTHREAD_EXAMPLES}" = "nrf52840"])
@@ -1180,6 +1188,7 @@ examples/platforms/Makefile
examples/platforms/cc2538/Makefile
examples/platforms/cc2650/Makefile
examples/platforms/da15000/Makefile
examples/platforms/efr32/Makefile
examples/platforms/nrf52840/Makefile
examples/platforms/posix/Makefile
examples/platforms/utils/Makefile
+303
View File
@@ -0,0 +1,303 @@
#
# Copyright (c) 2017, 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-app=all \
--enable-ncp-app=all \
--with-ncp-bus=uart \
--enable-diag \
--enable-default-logging \
--with-examples=efr32 \
--with-platform-info=EFR32 \
MBEDTLS_CPPFLAGS="$(EFR32_MBEDTLS_CPPFLAGS)" \
$(NULL)
ifeq ($(CERT_LOG),1)
configure_OPTIONS += --enable-cert-log
endif
ifeq ($(COMMISSIONER),1)
configure_OPTIONS += --enable-commissioner
endif
ifeq ($(JOINER),1)
configure_OPTIONS += --enable-joiner
endif
ifeq ($(DHCP6_SERVER),1)
configure_OPTIONS += --enable-dhcp6-server
endif
ifeq ($(DHCP6_CLIENT),1)
configure_OPTIONS += --enable-dhcp6-client
endif
ifeq ($(JAM_DETECTION),1)
configure_OPTIONS += --enable-jam-detection
endif
ifeq ($(DNS_CLIENT),1)
configure_OPTIONS += --enable-dns-client
endif
TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"efr32-mbedtls-config.h\"'
EFR32_MBEDTLS_CPPFLAGS += -DEFR32MG12P432F1024GL125
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/examples/platforms/efr32/crypto
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.0/util/third_party/mbedtls/configs
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/CMSIS/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.0/util/third_party/mbedtls/sl_crypto/include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Include
EFR32_MBEDTLS_CPPFLAGS += -I$(AbsTopSourceDir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/inc
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/
COMMONCFLAGS := \
-fdata-sections \
-ffunction-sections \
-Os \
-g \
-D$(CONFIG_FILE) \
-I$(CONFIG_FILE_PATH) \
$(NULL)
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 \
-Wl,-Map=map.map \
$(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 = efr32
ARCHS = cortex-m4
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-m4
#
cortex-m4_target_ABI = cortex-m4
cortex-m4_target_CPPFLAGS = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
cortex-m4_target_CFLAGS = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
cortex-m4_target_CXXFLAGS = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
cortex-m4_target_LDFLAGS = -mcpu=cortex-m4 -mfloat-abi=soft -mthumb
# 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) ""
+11
View File
@@ -102,6 +102,17 @@ LDFLAGS_COMMON += \
$(NULL)
endif # OPENTHREAD_EXAMPLES_DA15000
if OPENTHREAD_EXAMPLES_EFR32
LDADD_COMMON += \
$(top_builddir)/examples/platforms/efr32/libopenthread-efr32.a \
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \
$(NULL)
LDFLAGS_COMMON += \
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
$(NULL)
endif # OPENTHREAD_EXAMPLES_EFR32
if OPENTHREAD_EXAMPLES_NRF52840
LDADD_COMMON += \
$(top_builddir)/examples/platforms/nrf52840/libopenthread-nrf52840.a \
+11
View File
@@ -102,6 +102,17 @@ LDFLAGS_COMMON += \
$(NULL)
endif # OPENTHREAD_EXAMPLES_DA15000
if OPENTHREAD_EXAMPLES_EFR32
LDADD_COMMON += \
$(top_builddir)/examples/platforms/efr32/libopenthread-efr32.a \
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \
$(NULL)
LDFLAGS_COMMON += \
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
$(NULL)
endif # OPENTHREAD_EXAMPLES_EFR32
if OPENTHREAD_EXAMPLES_NRF52840
LDADD_COMMON += \
$(top_builddir)/examples/platforms/nrf52840/libopenthread-nrf52840.a \
+6
View File
@@ -34,6 +34,7 @@ DIST_SUBDIRS = \
cc2538 \
cc2650 \
da15000 \
efr32 \
nrf52840 \
posix \
utils \
@@ -57,6 +58,10 @@ if OPENTHREAD_EXAMPLES_DA15000
SUBDIRS += da15000
endif
if OPENTHREAD_EXAMPLES_EFR32
SUBDIRS += efr32
endif
if OPENTHREAD_EXAMPLES_NRF52840
SUBDIRS += nrf52840
endif
@@ -71,6 +76,7 @@ PRETTY_SUBDIRS = \
cc2538 \
cc2650 \
da15000 \
efr32 \
nrf52840 \
posix \
utils \
+123
View File
@@ -0,0 +1,123 @@
#
# Copyright (c) 2017, 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-efr32.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))
EFR32MG_SDK_SRCDIR = $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.0
libopenthread_efr32_a_CPPFLAGS = \
-DEFR32MG12P432F1024GL125 \
-D__START=main \
-D__STARTUP_CLEAR_BSS \
-I$(top_srcdir)/include \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/src/core \
-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/efr32 \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/common/bsp \
-I$(EFR32MG_SDK_SRCDIR)/hardware/kit/EFR32MG12_BRD4161A/config \
-I$(EFR32MG_SDK_SRCDIR)/platform/CMSIS/Include \
-I$(EFR32MG_SDK_SRCDIR)/platform/Device/SiliconLabs/EFR32MG12P/Include \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/common/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/uartdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/ustimer/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/dmadrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emdrv/rtcdrv/inc \
-I$(EFR32MG_SDK_SRCDIR)/platform/emlib/inc \
-Wno-unused-parameter \
$(NULL)
PLATFORM_SOURCES = \
alarm.c \
flash.c \
logging.c \
misc.c \
platform.c \
radio.c \
random.c \
startup-gcc.c \
uart.c \
$(NULL)
if OPENTHREAD_ENABLE_DIAG
PLATFORM_SOURCES += \
diag.c \
$(NULL)
endif
nodist_libopenthread_efr32_a_SOURCES = \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/hardware/kit/common/bsp/bsp_bcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/hardware/kit/common/bsp/bsp_stk.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emdrv/rtcdrv/src/rtcdriver.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emdrv/ustimer/src/ustimer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_adc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_cmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_core.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_emu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_gpio.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_rmu.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_rtcc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_system.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_timer.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_usart.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_msc.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/emlib/src/em_crypto.c \
$(NULL)
noinst_HEADERS = \
platform-efr32.h \
$(NULL)
libopenthread_efr32_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NULL)
PRETTY_FILES = \
$(PLATFORM_SOURCES) \
$(NULL)
Dash = -
libopenthread_efr32_a_LIBADD = \
$(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
+187
View File
@@ -0,0 +1,187 @@
# OpenThread on EFR32 Example
This directory contains example platform drivers for the [Silicon Labs EFR32][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. [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
for an example using basic OpenThread capabilities.
[efr32mg12p]: http://www.silabs.com/products/wireless/mesh-networking/efr32mg-mighty-gecko-zigbee-thread-soc/device.EFR32MG12P432F1024GL125
## Toolchain
Download and install the [GNU toolchain for ARM Cortex-M][gnu-toolchain].
[gnu-toolchain]: https://launchpad.net/gcc-arm-embedded
## 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 EFR32MG12P Wireless Starter Kit to Simplicity Studio.
- Find the latest Flex SDK in the Software Update page and click Install.
- Flex SDK 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
on RAIL, see [Radio Abstraction Interface Layer][rail].
[QSG121]: http://www.silabs.com/documents/public/quick-start-guides/QSG121-EFR32-RAIL.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-openthread>/third_party
$ mkdir silabs
$ cd <path-to-Simplicity-Studio>/developer/sdks
$ cp -rf gecko_sdk_suite <path-to-openthread>/third_party/silabs/
```
4. Build OpenThread Firmware (CLI example) on EFR32 platform.
```bash
$ cd <path-to-openthread>
$ ./bootstrap
$ make -f examples/Makefile-efr32
```
After a successful build, the `elf` files are found in
`<path-to-openthread>/output/efr32/bin`.
## Flash Binaries
Compiled binaries may be flashed onto the EFR32 using [JLinkGDBServer][jlinkgdbserver].
EFR32 Starter kit mainboard integrates an on-board SEGGER J-Link debugger.
[jlinkgdbserver]: https://www.segger.com/jlink-gdb-server.html
```bash
$ cd <path-to-JLinkGDBServer>
$ sudo ./JLinkGDBServer -if swd -device EFR32MG1PxxxF256
$ cd <path-to-openthread>/output/efr32/bin
$ arm-none-eabi-gdb ot-cli-ftd
$ (gdb) target remote 127.0.0.1:2331
$ (gdb) load
$ (gdb) monitor reset
$ (gdb) c
```
## Run the example with EFR32 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-efr32 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 4.9.3
The EFR32 example has been verified with following Flex SDK/RAIL Library version:
- Flex SDK version 1.1.1.0
- RAIL Library version 1.5.2.2
+128
View File
@@ -0,0 +1,128 @@
/*
* Copyright (c) 2017, 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 <utils/code_utils.h>
#include <openthread/platform/platform.h>
#include <openthread/platform/alarm.h>
#include <openthread/platform/diag.h>
#include "rail.h"
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)
{
}
uint32_t otPlatAlarmGetNow(void)
{
uint32_t timer_lo;
timer_lo = RAIL_GetTime();
if (timer_lo < sTimerLo)
{
sTimerHi++;
}
sTimerLo = timer_lo;
return (((uint64_t)sTimerHi << 32) | sTimerLo) / 1000;
}
void otPlatAlarmStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
{
(void)aInstance;
sAlarmT0 = t0;
sAlarmDt = dt;
sIsRunning = true;
}
void otPlatAlarmStop(otInstance *aInstance)
{
(void)aInstance;
sIsRunning = false;
}
void efr32AlarmProcess(otInstance *aInstance)
{
uint32_t now = otPlatAlarmGetNow();
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
{
otPlatAlarmFired(aInstance);
}
}
exit:
return;
}
void RAILCb_TimerExpired(void)
{
}
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2017, 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"
/**
* \def MBEDTLS_AES_ALT
*
* Enable hardware acceleration for the AES block cipher
*
* Module: sl_crypto/src/sl_aes.c
* or
* sl_crypto/src/slcl_aes.c if MBEDTLS_SLCL_PLUGINS is defined.
*
* See MBEDTLS_AES_C for more information.
*/
#define MBEDTLS_AES_ALT
/**
* \def MBEDTLS_ECP_DEVICE_ALT
* \def MBEDTLS_ECP_DEVICE_ALT
* \def MBEDTLS_ECP_DOUBLE_JAC_ALT
* \def MBEDTLS_ECP_DEVICE_ADD_MIXED_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
* \def MBEDTLS_MPI_MODULAR_DIVISION_ALT
*
* Enable hardware acceleration for the elliptic curve over GF(p) library.
*
* Module: sl_crypto/src/sl_ecp.c
* or
* sl_crypto/src/slcl_ecp.c if MBEDTLS_SLCL_PLUGINS is defined.
* Caller: library/ecp.c
* library/ecdh.c
* library/ecdsa.c
* library/ecjpake.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_DEVICE_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_DEVICE_ADD_MIXED_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
#define MBEDTLS_MPI_MODULAR_DIVISION_ALT
#endif
/**
* \def MBEDTLS_SHA256_ALT
*
* Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
* hash algorithms.
*
* Module: sl_crypto/src/sl_sha256.c
* or
* sl_crypto/src/slcl_sha256.c if MBEDTLS_SLCL_PLUGINS is defined.
* 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
+89
View File
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2017, 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.h>
#include <openthread/platform/radio.h>
#include "platform-efr32.h"
/**
* Diagnostics mode variables.
*
*/
static bool sDiagMode = false;
void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
// Add more plarform specific diagnostics features here.
snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
(void) argc;
(void) aInstance;
}
void otPlatDiagModeSet(bool aMode)
{
sDiagMode = aMode;
}
bool otPlatDiagModeGet()
{
return sDiagMode;
}
void otPlatDiagChannelSet(uint8_t aChannel)
{
(void) aChannel;
}
void otPlatDiagTxPowerSet(int8_t aTxPower)
{
(void) aTxPower;
}
void otPlatDiagRadioReceived(otInstance *aInstance, RadioPacket *aFrame, ThreadError aError)
{
(void) aInstance;
(void) aFrame;
(void) aError;
}
void otPlatDiagAlarmCallback(otInstance *aInstance)
{
(void) aInstance;
}
+142
View File
@@ -0,0 +1,142 @@
/*
* Copyright (c) 2017, 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-config.h>
#include <openthread/platform/alarm.h>
#include <utils/flash.h>
#include <utils/code_utils.h>
#include "em_msc.h"
#define FLASH_DATA_USED_PAGES 10
#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * FLASH_DATA_USED_PAGES))
static inline uint32_t mapAddress(uint32_t aAddress)
{
return aAddress + FLASH_DATA_START_ADDR;
}
static ThreadError returnTypeConvert(int32_t aStatus)
{
ThreadError error = kThreadError_None;
switch (aStatus)
{
case mscReturnOk:
error = kThreadError_None;
break;
case mscReturnInvalidAddr:
case mscReturnUnaligned:
error = kThreadError_InvalidArgs;
break;
default:
error = kThreadError_Failed;
}
return error;
}
ThreadError utilsFlashInit(void)
{
MSC_Init();
return kThreadError_None;
}
uint32_t utilsFlashGetSize(void)
{
return FLASH_DATA_END_ADDR - FLASH_DATA_START_ADDR;
}
ThreadError utilsFlashErasePage(uint32_t aAddress)
{
int32_t status;
status = MSC_ErasePage((uint32_t *)mapAddress(aAddress));
return returnTypeConvert(status);
}
ThreadError utilsFlashStatusWait(uint32_t aTimeout)
{
ThreadError error = kThreadError_Busy;
uint32_t start = otPlatAlarmGetNow();
do
{
if (MSC->STATUS & MSC_STATUS_WDATAREADY)
{
error = kThreadError_None;
break;
}
}
while (aTimeout && ((otPlatAlarmGetNow() - 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) == kThreadError_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;
}
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2017, 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 logging.
*
*/
#ifdef OPENTHREAD_CONFIG_FILE
#include OPENTHREAD_CONFIG_FILE
#else
#include <openthread-config.h>
#endif
#include <openthread/platform/logging.h>
#if OPENTHREAD_ENABLE_CLI_LOGGING
#include <ctype.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <utils/code_utils.h>
#include <cli.h>
#endif
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
#if OPENTHREAD_ENABLE_CLI_LOGGING
va_list args;
va_start(args, aFormat);
otCliLog(aLogLevel, aLogRegion, aFormat, args);
va_end(args);
#else
(void)aLogLevel;
(void)aLogRegion;
(void)aFormat;
#endif // OPENTHREAD_ENABLE_CLI_LOGGING
}
+95
View File
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2017, 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/types.h>
#include <openthread/platform/misc.h>
#include "platform-efr32.h"
#include "em_rmu.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)
{
(void)aInstance;
NVIC_SystemReset();
}
otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
{
(void)aInstance;
otPlatResetReason reason;
if (sResetCause & RMU_RSTCAUSE_PORST)
{
reason = kPlatResetReason_PowerOn;
}
else if (sResetCause & RMU_RSTCAUSE_SYSREQRST)
{
reason = kPlatResetReason_Software;
}
else if (sResetCause & RMU_RSTCAUSE_WDOGRST)
{
reason = kPlatResetReason_Watchdog;
}
else if (sResetCause & RMU_RSTCAUSE_EXTRST)
{
reason = kPlatResetReason_External;
}
else if (sResetCause & RMU_RSTCAUSE_LOCKUPRST)
{
reason = kPlatResetReason_Fault;
}
else if ((sResetCause & RMU_RSTCAUSE_AVDDBOD) ||
(sResetCause & RMU_RSTCAUSE_DECBOD) ||
(sResetCause & RMU_RSTCAUSE_DVDDBOD) ||
(sResetCause & RMU_RSTCAUSE_EM4RST))
{
reason = kPlatResetReason_Assert;
}
else
{
reason = kPlatResetReason_Unknown;
}
return reason;
}
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2017, 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.
*/
#ifndef OPENTHREAD_CORE_EFR32_CONFIG_H_
#define OPENTHREAD_CORE_EFR32_CONFIG_H_
/**
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT
*
* Define to 1 if you want to enable software ACK timeout logic.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT 1
/**
* @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_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 0x800
/**
* @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
/**
* @def RADIO_CONFIG_XXX
*
* The Radio configuration Auto-generated by Simplicity Studio (rail_config.h).
*
*/
#define RADIO_CONFIG_BASE_FREQUENCY 2450000000UL
#define RADIO_CONFIG_XTAL_FREQUENCY 38400000UL
#define RADIO_CONFIG_BITRATE "2.4kbps"
#define RADIO_CONFIG_MODULATION_TYPE "FSK2"
#define RADIO_CONFIG_DEVIATION "1.2kHz"
#endif // OPENTHREAD_CORE_EFR32_CONFIG_H_
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2017, 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 "em_device.h"
#include "em_system.h"
#include "core_cm4.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 EFR32 Hardware Abstract Layer.
*
*/
void efr32HalInit(void);
#endif // PLATFORM_EFR32_H_
+147
View File
@@ -0,0 +1,147 @@
/*
* Copyright (c) 2017, 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 "pa.h"
#include "pti.h"
#include "bsp.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "em_chip.h"
#include "platform-efr32.h"
#include "rail.h"
#include "rail_ieee802154.h"
#include "openthread-core-efr32-config.h"
otInstance *sInstance;
void PlatformInit(int argc, char *argv[])
{
(void)argc;
(void)argv;
CHIP_Init();
efr32HalInit();
BSP_Init(BSP_INIT_BCC);
otPlatUartEnable();
RAIL_Init_t railInitParams =
{
128, // maxPacketLength: UNUSED
RADIO_CONFIG_XTAL_FREQUENCY,
0
};
RAIL_RfInit(&railInitParams);
RAIL_RfIdle();
efr32AlarmInit();
efr32RadioInit();
efr32MiscInit();
efr32RandomInit();
}
void PlatformDeinit(void)
{
efr32RadioDeinit();
}
void PlatformProcessDrivers(otInstance *aInstance)
{
sInstance = aInstance;
// should sleep and wait for interrupts here
efr32UartProcess();
efr32RadioProcess(aInstance);
efr32AlarmProcess(aInstance);
}
void halInitChipSpecific(void)
{
CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_WSTK_DEFAULT;
RADIO_PTIInit_t ptiInit = RADIO_PTI_INIT;
RADIO_PAInit_t paInit;
SYSTEM_ChipRevision_TypeDef chipRev;
SYSTEM_ChipRevisionGet(&chipRev);
// Init DCDC regulator and HFXO with WSTK radio board specific parameters
// from s025_sw\kits\SLWSTK6100A_EFR32MG\config\bspconfig.h
#ifdef EMU_DCDCINIT_WSTK_DEFAULT
EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_WSTK_DEFAULT;
EMU_DCDCInit(&dcdcInit);
#else
EMU_DCDCPowerOff();
#endif
CMU_HFXOInit(&hfxoInit);
SystemHFXOClockSet(RADIO_CONFIG_XTAL_FREQUENCY);
// Initialize the Packet Trace Interface (PTI) to match the configuration in
// the board header
RADIO_PTI_Init(&ptiInit);
/* Switch HFCLK to HFXO and disable HFRCO */
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
// Initialize the PA now that the HFXO is up and the timing is correct
#if (RADIO_CONFIG_BASE_FREQUENCY < 1000000000UL)
paInit = (RADIO_PAInit_t) RADIO_PA_SUBGIG_INIT;
#else
paInit = (RADIO_PAInit_t) RADIO_PA_2P4_INIT;
#endif
if (!RADIO_PA_Init(&paInit))
{
// Error: The PA could not be initialized due to an improper configuration.
// Please ensure your configuration is valid for the selected part.
while (1);
}
// Initialize other chip clocks
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFRCO);
CMU_ClockEnable(cmuClock_CORELE, true);
}
void efr32HalInit(void)
{
halInitChipSpecific();
}
+844
View File
@@ -0,0 +1,844 @@
/*
* Copyright (c) 2017, 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/types.h>
#include <openthread-config.h>
#include <common/logging.hpp>
#include <utils/code_utils.h>
#include <openthread/platform/platform.h>
#include <openthread/platform/radio.h>
#include <openthread/platform/diag.h>
#include "em_core.h"
#include "em_system.h"
#include "rail.h"
#include "rail_ieee802154.h"
#include "openthread-core-efr32-config.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,
};
static uint16_t sPanId = 0;
static uint8_t sChannel = 0;
static bool sTransmitBusy = false;
static bool sPromiscuous = false;
static bool sIsReceiverEnabled = false;
static bool sIsSrcMatchEnabled = false;
static PhyState sState = kStateDisabled;
static uint8_t sReceiveBuffer[IEEE802154_MAX_LENGTH + 1 + sizeof(RAIL_RxPacketInfo_t)];
static uint8_t sReceivePsdu[IEEE802154_MAX_LENGTH];
static RadioPacket sReceiveFrame;
static ThreadError sReceiveError;
static RadioPacket sTransmitFrame;
static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH];
static ThreadError sTransmitError;
typedef struct srcMatchEntry
{
uint16_t checksum;
bool allocated;
} sSrcMatchEntry;
static sSrcMatchEntry srcMatchShortEntry[RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM];
static sSrcMatchEntry srcMatchExtEntry[RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM];
void efr32RadioInit(void)
{
// Data Management
RAIL_DataConfig_t railDataConfig =
{
TX_PACKET_DATA,
RX_PACKET_DATA,
PACKET_MODE,
PACKET_MODE,
};
RAIL_DataConfig(&railDataConfig);
// 802.15.4 configuration
RAIL_IEEE802154_Config_t config =
{
false, // promiscuousMode
false, // isPanCoordinator
RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, // framesMask
RAIL_RF_STATE_RX, // defaultState
100, // idleTime
192, // turnaroundTime
894, // ackTimeout
NULL // addresses
};
sReceiveFrame.mLength = 0;
sReceiveFrame.mPsdu = sReceivePsdu;
sTransmitFrame.mLength = 0;
sTransmitFrame.mPsdu = sTransmitPsdu;
if (RAIL_IEEE802154_2p4GHzRadioConfig())
{
assert(false);
}
if (RAIL_IEEE802154_Init(&config))
{
assert(false);
}
RAIL_TxPowerSet(0);
otLogInfoPlat(sInstance, "Initialized", NULL);
}
void efr32RadioDeinit(void)
{
RAIL_RfIdle();
RAIL_IEEE802154_Deinit();
}
void setChannel(uint8_t channel)
{
bool enabled = false;
otEXPECT(sChannel != channel);
if (sIsReceiverEnabled)
{
RAIL_RfIdle();
enabled = true;
sIsReceiverEnabled = false;
}
otLogInfoPlat(sInstance, "Channel=%d", channel);
sChannel = channel;
if (enabled)
{
if (RAIL_RxStart(channel))
{
assert(false);
}
sIsReceiverEnabled = true;
}
exit:
return;
}
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
uint64_t eui64;
uint8_t *eui64Ptr = NULL;
(void)aInstance;
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)
{
(void)aInstance;
otLogInfoPlat(sInstance, "PANID=%X", aPanId);
sPanId = aPanId;
RAIL_IEEE802154_SetPanId(aPanId);
}
void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *aAddress)
{
(void)aInstance;
otLogInfoPlat(sInstance, "ExtAddr=%X%X%X%X%X%X%X%X",
aAddress[7], aAddress[6], aAddress[5], aAddress[4],
aAddress[3], aAddress[2], aAddress[1], aAddress[0]);
RAIL_IEEE802154_SetLongAddress(aAddress);
}
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
{
(void)aInstance;
otLogInfoPlat(sInstance, "ShortAddr=%X", aAddress);
RAIL_IEEE802154_SetShortAddress(aAddress);
}
bool otPlatRadioIsEnabled(otInstance *aInstance)
{
(void)aInstance;
return (sState != kStateDisabled);
}
ThreadError otPlatRadioEnable(otInstance *aInstance)
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT(!otPlatRadioIsEnabled(aInstance));
otLogInfoPlat(sInstance, "State=kStateSleep", NULL);
sState = kStateSleep;
exit:
CORE_EXIT_CRITICAL();
return kThreadError_None;
}
ThreadError otPlatRadioDisable(otInstance *aInstance)
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT(otPlatRadioIsEnabled(aInstance));
otLogInfoPlat(sInstance, "State=kStateDisabled", NULL);
sState = kStateDisabled;
exit:
CORE_EXIT_CRITICAL();
return kThreadError_None;
}
ThreadError otPlatRadioSleep(otInstance *aInstance)
{
ThreadError error = kThreadError_None;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT_ACTION((sState != kStateTransmit) && (sState != kStateDisabled),
error = kThreadError_InvalidState);
otLogInfoPlat(sInstance, "State=kStateSleep", NULL);
sState = kStateSleep;
if (sIsReceiverEnabled)
{
RAIL_RfIdleExt(RAIL_IDLE, true);
sIsReceiverEnabled = false;
}
exit:
CORE_EXIT_CRITICAL();
return error;
}
ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
ThreadError error = kThreadError_None;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT_ACTION(sState != kStateDisabled, error = kThreadError_InvalidState);
otLogInfoPlat(sInstance, "State=kStateReceive", NULL);
sState = kStateReceive;
setChannel(aChannel);
sReceiveFrame.mChannel = aChannel;
if (!sIsReceiverEnabled)
{
if (RAIL_RxStart(aChannel))
{
assert(false);
}
sIsReceiverEnabled = true;
}
exit:
CORE_EXIT_CRITICAL();
return error;
}
ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket)
{
ThreadError error = kThreadError_None;
RAIL_CsmaConfig_t csmaConfig = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA;
RAIL_TxData_t tx_data;
uint8_t frame[IEEE802154_MAX_LENGTH + 1];
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT_ACTION((sState != kStateDisabled) && (sState != kStateTransmit),
error = kThreadError_InvalidState);
sState = kStateTransmit;
sTransmitError = kThreadError_None;
sTransmitBusy = true;
frame[0] = aPacket->mLength;
memcpy(frame + 1, aPacket->mPsdu, aPacket->mLength);
tx_data.dataPtr = frame;
tx_data.dataLength = aPacket->mLength - 1;
setChannel(aPacket->mChannel);
RAIL_RfIdleExt(RAIL_IDLE, true);
if (RAIL_TxDataLoad(&tx_data))
{
assert(false);
}
if (RAIL_TxStart(aPacket->mChannel, RAIL_CcaCsma, &csmaConfig))
{
assert(false);
}
exit:
CORE_EXIT_CRITICAL();
return error;
}
RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
(void)aInstance;
return &sTransmitFrame;
}
int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
(void)aInstance;
return (uint8_t)(RAIL_RxGetRSSI() >> 2);
}
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
(void)aInstance;
return kRadioCapsNone;
}
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
(void)aInstance;
return sPromiscuous;
}
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
(void)aInstance;
sPromiscuous = aEnable;
RAIL_IEEE802154_SetPromiscuousMode(aEnable);
}
int8_t findSrcMatchAvailEntry(bool aShortAddress)
{
int8_t entry = -1;
if (aShortAddress)
{
for (uint8_t i = 0; i < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM; i++)
{
if (!srcMatchShortEntry[i].allocated)
{
entry = i;
break;
}
}
}
else
{
for (uint8_t i = 0; i < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM; i++)
{
if (!srcMatchExtEntry[i].allocated)
{
entry = i;
break;
}
}
}
return entry;
}
int8_t findSrcMatchShortEntry(const uint16_t aShortAddress)
{
int8_t entry = -1;
uint16_t checksum = aShortAddress + sPanId;
for (uint8_t i = 0; i < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM; i++)
{
if (checksum == srcMatchShortEntry[i].checksum &&
srcMatchShortEntry[i].allocated)
{
entry = i;
break;
}
}
return entry;
}
int8_t findSrcMatchExtEntry(const uint8_t *aExtAddress)
{
int8_t entry = -1;
uint16_t checksum = sPanId;
checksum += (uint16_t)aExtAddress[0] | (uint16_t)(aExtAddress[1] << 8);
checksum += (uint16_t)aExtAddress[2] | (uint16_t)(aExtAddress[3] << 8);
checksum += (uint16_t)aExtAddress[4] | (uint16_t)(aExtAddress[5] << 8);
checksum += (uint16_t)aExtAddress[6] | (uint16_t)(aExtAddress[7] << 8);
for (uint8_t i = 0; i < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM; i++)
{
if (checksum == srcMatchExtEntry[i].checksum &&
srcMatchExtEntry[i].allocated)
{
entry = i;
break;
}
}
return entry;
}
void addToSrcMatchShortIndirect(uint8_t entry, const uint16_t aShortAddress)
{
uint16_t checksum = aShortAddress + sPanId;
srcMatchShortEntry[entry].checksum = checksum;
srcMatchShortEntry[entry].allocated = true;
}
void addToSrcMatchExtIndirect(uint8_t entry, const uint8_t *aExtAddress)
{
uint16_t checksum = sPanId;
checksum += (uint16_t)aExtAddress[0] | (uint16_t)(aExtAddress[1] << 8);
checksum += (uint16_t)aExtAddress[2] | (uint16_t)(aExtAddress[3] << 8);
checksum += (uint16_t)aExtAddress[4] | (uint16_t)(aExtAddress[5] << 8);
checksum += (uint16_t)aExtAddress[6] | (uint16_t)(aExtAddress[7] << 8);
srcMatchExtEntry[entry].checksum = checksum;
srcMatchExtEntry[entry].allocated = true;
}
void removeFromSrcMatchShortIndirect(uint8_t entry)
{
srcMatchShortEntry[entry].allocated = false;
memset(&srcMatchShortEntry[entry].checksum, 0, sizeof(uint16_t));
}
void removeFromSrcMatchExtIndirect(uint8_t entry)
{
srcMatchExtEntry[entry].allocated = false;
memset(&srcMatchExtEntry[entry].checksum, 0, sizeof(uint16_t));
}
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
// set Frame Pending bit for all outgoing ACKs if aEnable is false
sIsSrcMatchEnabled = aEnable;
CORE_EXIT_CRITICAL();
}
ThreadError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
(void)aInstance;
ThreadError error = kThreadError_None;
int8_t entry = -1;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchAvailEntry(true);
otLogDebgPlat(sInstance, "Add ShortAddr entry: %d", entry);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM,
error = kThreadError_NoBufs);
addToSrcMatchShortIndirect(entry, aShortAddress);
exit:
CORE_EXIT_CRITICAL();
return error;
}
ThreadError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
{
ThreadError error = kThreadError_None;
int8_t entry = -1;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchAvailEntry(false);
otLogDebgPlat(sInstance, "Add ExtAddr entry: %d", entry);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM,
error = kThreadError_NoBufs);
addToSrcMatchExtIndirect(entry, aExtAddress);
exit:
CORE_EXIT_CRITICAL();
return error;
}
ThreadError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
ThreadError error = kThreadError_None;
int8_t entry = -1;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchShortEntry(aShortAddress);
otLogDebgPlat(sInstance, "Clear ShortAddr entry: %d", entry);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM,
error = kThreadError_NoAddress);
removeFromSrcMatchShortIndirect(entry);
exit:
CORE_EXIT_CRITICAL();
return error;
}
ThreadError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
{
ThreadError error = kThreadError_None;
int8_t entry = -1;
(void)aInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
entry = findSrcMatchExtEntry(aExtAddress);
otLogDebgPlat(sInstance, "Clear ExtAddr entry: %d", entry);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM,
error = kThreadError_NoAddress);
removeFromSrcMatchExtIndirect(entry);
exit:
CORE_EXIT_CRITICAL();
return error;
}
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
(void)aInstance;
otLogDebgPlat(sInstance, "Clear ShortAddr entries", NULL);
memset(srcMatchShortEntry, 0, sizeof(srcMatchShortEntry));
}
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
(void)aInstance;
otLogDebgPlat(sInstance, "Clear ExtAddr entries", NULL);
memset(srcMatchExtEntry, 0, sizeof(srcMatchExtEntry));
}
void RAILCb_IEEE802154_DataRequestCommand(RAIL_IEEE802154_Address_t *aAddress)
{
if (sIsSrcMatchEnabled)
{
if ((aAddress->length == RAIL_IEEE802154_LongAddress &&
findSrcMatchExtEntry(aAddress->longAddress) >= 0) ||
(aAddress->length == RAIL_IEEE802154_ShortAddress &&
findSrcMatchShortEntry(aAddress->shortAddress) >= 0))
{
RAIL_IEEE802154_SetFramePending();
}
}
else
{
(void)aAddress;
RAIL_IEEE802154_SetFramePending();
}
}
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
{
(void)aInstance;
(void)aScanChannel;
(void)aScanDuration;
return kThreadError_NotImplemented;
}
void RAILCb_TxRadioStatus(uint8_t aStatus)
{
switch (aStatus)
{
case RAIL_TX_CONFIG_CHANNEL_BUSY:
sTransmitError = kThreadError_ChannelAccessFailure;
sTransmitBusy = false;
break;
case RAIL_TX_CONFIG_TX_ABORTED:
sTransmitError = kThreadError_Abort;
sTransmitBusy = false;
break;
default:
break;
}
}
void RAILCb_TxPacketSent(RAIL_TxPacketInfo_t *aTxPacketInfo)
{
(void)aTxPacketInfo;
sTransmitError = kThreadError_None;
sTransmitBusy = false;
}
void RAILCb_RxPacketReceived(void *aRxPacketHandle)
{
RAIL_RxPacketInfo_t *rxPacketInfo;
uint8_t length;
rxPacketInfo = (RAIL_RxPacketInfo_t *)aRxPacketHandle;
// check recv packet appended info
otEXPECT(rxPacketInfo != NULL &&
rxPacketInfo->appendedInfo.crcStatus &&
rxPacketInfo->appendedInfo.frameCodingStatus);
length = rxPacketInfo->dataLength + 1;
// check the length in recv packet info structure
otEXPECT(length == rxPacketInfo->dataPtr[0]);
// check the lenght validity of recv packet
otEXPECT(length >= IEEE802154_MIN_LENGTH && length <= IEEE802154_MAX_LENGTH);
memcpy(sReceiveFrame.mPsdu, rxPacketInfo->dataPtr + 1, rxPacketInfo->dataLength);
sReceiveFrame.mPower = rxPacketInfo->appendedInfo.rssiLatch;
sReceiveFrame.mLqi = rxPacketInfo->appendedInfo.lqi;
sReceiveFrame.mLength = length;
sReceiveError = kThreadError_None;
exit:
return;
}
void efr32RadioProcess(otInstance *aInstance)
{
// ensure process would not be broken by
// the incoming interrupt with higher priority
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
if ((sState == kStateReceive && sReceiveFrame.mLength > 0) ||
(sState == kStateTransmit && sReceiveFrame.mLength > IEEE802154_ACK_LENGTH))
{
#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(sInstance, "Received %d bytes", sReceiveFrame.mLength);
otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError);
}
}
}
if (sState == kStateTransmit && sTransmitBusy == false)
{
if (sTransmitError != kThreadError_None || (sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0)
{
if (sTransmitError != kThreadError_None)
{
otLogDebgPlat(sInstance, "Transmit failed ErrorCode=%d", sTransmitError);
}
sState = kStateReceive;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, false, sTransmitError);
}
else
#endif
{
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, sTransmitError);
}
}
else if (sReceiveFrame.mLength == IEEE802154_ACK_LENGTH &&
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK &&
(sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET]))
{
sState = kStateReceive;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame,
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0,
sTransmitError);
}
else
#endif
{
otLogInfoPlat(sInstance, "Received ACK:%d", sReceiveFrame.mLength);
otPlatRadioTransmitDone(aInstance, &sTransmitFrame,
(sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0,
sTransmitError);
}
}
}
sReceiveFrame.mLength = 0;
CORE_EXIT_CRITICAL();
}
void RAILCb_RfReady(void)
{
}
void RAILCb_CalNeeded(void)
{
}
void RAILCb_RxAckTimeout(void)
{
}
void RAILCb_RxRadioStatus(uint8_t aStatus)
{
(void)aStatus;
}
void RAILCb_RadioStateChanged(uint8_t aState)
{
(void)aState;
}
void RAILCb_RssiAverageDone(int16_t avgRssi)
{
(void)avgRssi;
}
void RAILCb_RxFifoAlmostFull(uint16_t bytesAvailable)
{
(void)bytesAvailable;
}
void RAILCb_TxFifoAlmostEmpty(uint16_t spaceAvailable)
{
(void)spaceAvailable;
}
void *RAILCb_AllocateMemory(uint32_t size)
{
uint8_t *pointer = NULL;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
otEXPECT(size <= (IEEE802154_MAX_LENGTH + 1 + sizeof(RAIL_RxPacketInfo_t)));
pointer = sReceiveBuffer;
exit:
CORE_EXIT_CRITICAL();
return pointer;
}
void *RAILCb_BeginWriteMemory(void *handle, uint32_t offset,
uint32_t *available)
{
(void)available;
return ((uint8_t *)handle) + offset;
}
void RAILCb_EndWriteMemory(void *handle, uint32_t offset, uint32_t size)
{
(void)handle;
(void)offset;
(void)size;
}
void RAILCb_FreeMemory(void *handle)
{
(void)handle;
}
void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower)
{
(void)aInstance;
RAIL_TxPowerSet(aPower);
}
+108
View File
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2017, 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 <utils/code_utils.h>
#include <openthread/types.h>
#include <openthread/platform/random.h>
#include "em_adc.h"
#include "em_cmu.h"
enum
{
EFR32_ADC_REF_CLOCK = 7000000,
};
void efr32RandomInit(void)
{
/* Enable ADC Clock */
CMU_ClockEnable(cmuClock_ADC0, true);
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
/* Initialize the ADC with the required values */
init.timebase = ADC_TimebaseCalc(0);
init.prescale = ADC_PrescaleCalc(EFR32_ADC_REF_CLOCK, 0);
ADC_Init(ADC0, &init);
/* Initialize for single conversion specific to RNG */
singleInit.reference = adcRefVEntropy;
singleInit.diff = true;
singleInit.posSel = adcPosSelVSS;
singleInit.negSel = adcNegSelVSS;
ADC_InitSingle(ADC0, &singleInit);
/* Set VINATT to maximum value and clear FIFO */
ADC0->SINGLECTRLX |= _ADC_SINGLECTRLX_VINATT_MASK;
ADC0->SINGLEFIFOCLEAR = ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
}
uint32_t otPlatRandomGet(void)
{
uint8_t tmp = 0;
uint32_t random = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
ADC_Start(ADC0, adcStartSingle);
while ((ADC0->IF & ADC_IF_SINGLE) == 0);
tmp |= ((ADC_DataSingleGet(ADC0) & 0x07) << (j * 3));
}
random |= (tmp & 0xff) << (i * 8);
}
return random;
}
ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength)
{
ThreadError error = kThreadError_None;
otEXPECT_ACTION(aOutput && aOutputLength, error = kThreadError_InvalidArgs);
for (uint16_t length = 0; length < aInputLength; length++)
{
aOutput[length] = (uint8_t)otPlatRandomGet();
}
*aOutputLength = aInputLength;
exit:
return error;
}
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2017, 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); }
+196
View File
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2017, 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 <utils/code_utils.h>
#include <openthread/types.h>
#include <openthread/platform/uart.h>
#include "bspconfig.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
enum
{
kPlatformClock = 32000000,
kBaudRate = 115200,
kReceiveBufferSize = 128,
};
static void processReceive(void);
static void processTransmit(void);
static const uint8_t *sTransmitBuffer = NULL;
static uint16_t sTransmitLength = 0;
typedef struct RecvBuffer
{
// The data buffer
uint8_t mBuffer[kReceiveBufferSize];
// The offset of the first item written to the list.
uint16_t mHead;
// The offset of the next item to be written to the list.
uint16_t mTail;
} RecvBuffer;
static RecvBuffer sReceive;
ThreadError otPlatUartEnable(void)
{
USART_TypeDef *usart = USART0;
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
sReceive.mHead = 0;
sReceive.mTail = 0;
/* Enable peripheral clocks */
CMU_ClockEnable(cmuClock_HFPER, true);
/* Configure GPIO pins */
CMU_ClockEnable(cmuClock_GPIO, true);
/* Configure GPIO pin for UART TX */
/* To avoid false start, configure output as high. */
GPIO_PinModeSet(BSP_BCC_TXPORT, BSP_BCC_TXPIN, gpioModePushPull, 1u);
/* Configure GPIO pin for UART RX */
GPIO_PinModeSet(BSP_BCC_RXPORT, BSP_BCC_RXPIN, gpioModeInput, 1u);
/* Enable the switch that enables UART communication. */
GPIO_PinModeSet(BSP_BCC_ENABLE_PORT, BSP_BCC_ENABLE_PIN, gpioModePushPull, 1u);
CMU_ClockEnable(cmuClock_USART0, true);
/* Configure USART for basic async operation */
init.enable = usartDisable;
USART_InitAsync(usart, &init);
/* Enable pins at correct UART/USART location. */
usart->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN;
usart->ROUTELOC0 = (usart->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK))
| (_USART_ROUTELOC0_TXLOC_LOC0 << _USART_ROUTELOC0_TXLOC_SHIFT)
| (_USART_ROUTELOC0_RXLOC_LOC0 << _USART_ROUTELOC0_RXLOC_SHIFT);
/* Clear previous RX interrupts */
USART_IntClear(usart, USART_IF_RXDATAV);
NVIC_ClearPendingIRQ(USART0_RX_IRQn);
/* Enable RX interrupts */
USART_IntEnable(usart, USART_IF_RXDATAV);
NVIC_EnableIRQ(USART0_RX_IRQn);
/* Finally enable it */
USART_Enable(usart, usartEnable);
return kThreadError_None;
}
void USART0_RX_IRQHandler(void)
{
if (USART0->STATUS & USART_STATUS_RXDATAV)
{
uint8_t byte = USART_Rx(USART0);
// We can only write if incrementing mTail doesn't equal mHead
if (sReceive.mHead != (sReceive.mTail + 1) % kReceiveBufferSize)
{
sReceive.mBuffer[sReceive.mTail] = byte;
sReceive.mTail = (sReceive.mTail + 1) % kReceiveBufferSize;
}
}
}
ThreadError otPlatUartDisable(void)
{
return kThreadError_NotImplemented;
}
ThreadError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
{
ThreadError error = kThreadError_None;
otEXPECT_ACTION(sTransmitBuffer == NULL, error = kThreadError_Busy);
sTransmitBuffer = aBuf;
sTransmitLength = aBufLength;
exit:
return error;
}
void processReceive(void)
{
// Copy tail to prevent multiple reads
uint16_t tail = sReceive.mTail;
// If the data wraps around, process the first part
if (sReceive.mHead > tail)
{
otPlatUartReceived(sReceive.mBuffer + sReceive.mHead, kReceiveBufferSize - sReceive.mHead);
// Reset the buffer mHead back to zero.
sReceive.mHead = 0;
}
// For any data remaining, process it
if (sReceive.mHead != tail)
{
otPlatUartReceived(sReceive.mBuffer + sReceive.mHead, tail - sReceive.mHead);
// Set mHead to the local tail we have cached
sReceive.mHead = tail;
}
}
void processTransmit(void)
{
otEXPECT(sTransmitBuffer != NULL);
for (; sTransmitLength > 0; sTransmitLength--)
{
USART_Tx(USART0, *sTransmitBuffer++);
}
sTransmitBuffer = NULL;
otPlatUartSendDone();
exit:
return;
}
void efr32UartProcess(void)
{
processReceive();
processTransmit();
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Nest Labs, Inc.
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+6
View File
@@ -35,6 +35,12 @@ EXTRA_DIST = \
NordicSemiconductor \
$(NULL)
if OPENTHREAD_EXAMPLES_EFR32
EXTRA_DIST += \
silabs \
$(NULL)
endif
# Always package (e.g. for 'make dist') these subdirectories.
DIST_SUBDIRS = \
+21 -2
View File
@@ -42,7 +42,6 @@ libmbedcrypto_a_CPPFLAGS = \
libmbedcrypto_a_SOURCES = \
hardware_entropy.c \
repo/library/aes.c \
repo/library/md.c \
repo/library/md_wrap.c \
repo/library/memory_buffer_alloc.c \
@@ -50,6 +49,16 @@ libmbedcrypto_a_SOURCES = \
repo/library/sha256.c \
$(NULL)
if OPENTHREAD_EXAMPLES_EFR32
nodist_libmbedcrypto_a_SOURCES = \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/util/third_party/mbedtls/sl_crypto/src/sl_aes.c \
$(NULL)
else
libmbedcrypto_a_SOURCES += \
repo/library/aes.c \
$(NULL)
endif # OPENTHREAD_EXAMPLES_EFR32
if OPENTHREAD_ENABLE_DTLS
libmbedcrypto_a_SOURCES += \
repo/library/bignum.c \
@@ -60,7 +69,6 @@ libmbedcrypto_a_SOURCES += \
repo/library/ctr_drbg.c \
repo/library/debug.c \
repo/library/ecjpake.c \
repo/library/ecp.c \
repo/library/ecp_curves.c \
repo/library/entropy.c \
repo/library/entropy_poll.c \
@@ -72,6 +80,17 @@ libmbedcrypto_a_SOURCES += \
repo/library/ssl_tls.c \
$(NULL)
if OPENTHREAD_EXAMPLES_EFR32
nodist_libmbedcrypto_a_SOURCES += \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/util/third_party/mbedtls/library/ecp.c \
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/util/third_party/mbedtls/sl_crypto/src/sl_ecp.c \
$(NULL)
else
libmbedcrypto_a_SOURCES += \
repo/library/ecp.c \
$(NULL)
endif # OPENTHREAD_EXAMPLES_EFR32
#
# mbedtls patches
#
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2016 Nest Labs Inc. All Rights Reserved.
* Copyright 2016 The OpenThread Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.