[da15000] remove unsupported platform (#3827)

This commit is contained in:
Jonathan Hui
2019-05-16 21:37:19 -07:00
committed by GitHub
parent ed23f050ad
commit 7f0168cbc7
103 changed files with 3 additions and 55975 deletions
-22
View File
@@ -128,17 +128,6 @@ build_cc2652() {
arm-none-eabi-size output/cc2652/bin/ot-ncp-mtd || die
}
build_da15000() {
git checkout -- . || die
git clean -xfd || die
./bootstrap || die
COMMISSIONER=1 JOINER=1 SLAAC=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 DNS_CLIENT=1 make -f examples/Makefile-da15000 || die
arm-none-eabi-size output/da15000/bin/ot-cli-ftd || die
arm-none-eabi-size output/da15000/bin/ot-cli-mtd || die
arm-none-eabi-size output/da15000/bin/ot-ncp-ftd || die
arm-none-eabi-size output/da15000/bin/ot-ncp-mtd || die
}
build_emsk() {
export PATH=/tmp/arc_gnu_2017.03-rc2_prebuilt_elf32_le_linux_install/bin:$PATH || die
@@ -265,7 +254,6 @@ build_samr21() {
build_cc2538
build_cc2650
build_cc2652
build_da15000
build_kw41z
build_nrf52811
build_nrf52840
@@ -280,7 +268,6 @@ build_samr21() {
build_cc2538
build_cc2650
build_cc2652
build_da15000
build_kw41z
build_nrf52811
build_nrf52840
@@ -295,7 +282,6 @@ build_samr21() {
build_cc2538
build_cc2650
build_cc2652
build_da15000
build_kw41z
build_nrf52811
build_nrf52840
@@ -312,7 +298,6 @@ build_samr21() {
build_cc2538
build_cc2650
build_cc2652
build_da15000
build_kw41z
build_nrf52811
build_nrf52840
@@ -332,13 +317,6 @@ build_samr21() {
build_nrf52840
build_qpg6095
build_samr21
# DA15000 build failure:
#
# third_party/dialog/DialogSDK/bsp/peripherals/src/hw_aes_hash.c:399:99: \
# error: bitwise comparison always evaluates to false [-Werror=tautological-compare]
#
# build_da15000
}
[ $BUILD_TARGET != posix ] || {
+1 -1
View File
@@ -35,7 +35,7 @@ More information about Thread can be found at [threadgroup.org](http://threadgro
# Who supports OpenThread?
<a href="https://www.arm.com/"><img src="doc/images/ot-contrib-arm.png" alt="ARM" width="200px"></a><a href="https://www.cascoda.com/"><img src="doc/images/ot-contrib-cascoda.png" alt="Cascoda" width="200px"></a><a href="http://www.dialog-semiconductor.com/"><img src="doc/images/ot-contrib-dialog.png" alt="Dialog" width="200px"></a><a href="https://www.microsoft.com/en-us/"><img src="doc/images/ot-contrib-ms.png" alt="Microsoft" width="200px"></a><a href="https://nest.com/"><img src="doc/images/ot-contrib-nest.png" alt="Nest" width="200px"></a><a href="http://www.nordicsemi.com/"><img src="doc/images/ot-contrib-nordic.png" alt="Nordic" width="200px"></a><a href="http://www.nxp.com/"><img src="doc/images/ot-contrib-nxp.png" alt="NXP" width="200px"></a><a href="https://www.particle.io/"><img src="doc/images/ot-contrib-particle.png" alt="Particle" width="200px"></a><a href="http://www.qorvo.com/"><img src="doc/images/ot-contrib-qorvo.png" alt="Qorvo" width="200px"></a><a href="https://www.qualcomm.com/"><img src="doc/images/ot-contrib-qc.png" alt="Qualcomm" width="200px"></a><a href="https://www.st.com/"><img src="doc/images/ot-contrib-stm.png" alt="STMicroelectronics" width="200px"></a><a href="https://www.synopsys.com/"><img src="doc/images/ot-contrib-synopsys.png" alt="Synopsys" width="200px"></a><a href="https://www.ti.com/"><img src="doc/images/ot-contrib-ti.png" alt="Texas Instruments" width="200px"></a><a href="https://www.zephyrproject.org/"><img src="doc/images/ot-contrib-zephyr.png" alt="Zephyr Project" width="200px"></a>
<a href="https://www.arm.com/"><img src="doc/images/ot-contrib-arm.png" alt="ARM" width="200px"></a><a href="https://www.cascoda.com/"><img src="doc/images/ot-contrib-cascoda.png" alt="Cascoda" width="200px"></a><a href="https://www.microsoft.com/en-us/"><img src="doc/images/ot-contrib-ms.png" alt="Microsoft" width="200px"></a><a href="https://nest.com/"><img src="doc/images/ot-contrib-nest.png" alt="Nest" width="200px"></a><a href="http://www.nordicsemi.com/"><img src="doc/images/ot-contrib-nordic.png" alt="Nordic" width="200px"></a><a href="http://www.nxp.com/"><img src="doc/images/ot-contrib-nxp.png" alt="NXP" width="200px"></a><a href="https://www.particle.io/"><img src="doc/images/ot-contrib-particle.png" alt="Particle" width="200px"></a><a href="http://www.qorvo.com/"><img src="doc/images/ot-contrib-qorvo.png" alt="Qorvo" width="200px"></a><a href="https://www.qualcomm.com/"><img src="doc/images/ot-contrib-qc.png" alt="Qualcomm" width="200px"></a><a href="https://www.st.com/"><img src="doc/images/ot-contrib-stm.png" alt="STMicroelectronics" width="200px"></a><a href="https://www.synopsys.com/"><img src="doc/images/ot-contrib-synopsys.png" alt="Synopsys" width="200px"></a><a href="https://www.ti.com/"><img src="doc/images/ot-contrib-ti.png" alt="Texas Instruments" width="200px"></a><a href="https://www.zephyrproject.org/"><img src="doc/images/ot-contrib-zephyr.png" alt="Zephyr Project" width="200px"></a>
# Getting started
+2 -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, da15000, efr32, emsk, gp712, kw41z, nrf52811, nrf52840, qpg6095, samr21 @<:@default=none@:>@.])],
[Specify the examples from one of: none, posix, cc1352, cc2538, cc2650, cc2652, efr32, emsk, gp712, kw41z, nrf52811, nrf52840, qpg6095, samr21 @<:@default=none@:>@.])],
[
case "${with_examples}" in
none)
;;
posix|cc1352|cc2538|cc2650|cc2652|da15000|efr32|emsk|gp712|kw41z|nrf52811|nrf52840|qpg6095|samr21)
posix|cc1352|cc2538|cc2650|cc2652|efr32|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,11 +1737,6 @@ case ${with_examples} in
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_CC2652],[${OPENTHREAD_EXAMPLES_CC2652}],[Define to 1 if you want to use cc2652 examples])
;;
da15000)
OPENTHREAD_EXAMPLES_DA15000=1
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])
@@ -1806,9 +1801,6 @@ 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_DA15000)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_DA15000], [test "${with_examples}" = "da15000"])
AC_SUBST(OPENTHREAD_EXAMPLES_EFR32)
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32], [test "${with_examples}" = "efr32"])
@@ -1982,7 +1974,6 @@ examples/platforms/cc1352/Makefile
examples/platforms/cc2538/Makefile
examples/platforms/cc2650/Makefile
examples/platforms/cc2652/Makefile
examples/platforms/da15000/Makefile
examples/platforms/efr32/Makefile
examples/platforms/efr32/sleepy-demo/Makefile
examples/platforms/efr32/sleepy-demo/efr32-sleepy-demo-ftd/Makefile
-1
View File
@@ -34,7 +34,6 @@ EXTRA_DIST = \
$(srcdir)/images/Open-Thread-Logo-200x42.png \
$(srcdir)/images/openthread_logo.png \
$(srcdir)/images/ot-contrib-arm.png \
$(srcdir)/images/ot-contrib-dialog.png \
$(srcdir)/images/ot-contrib-ms.png \
$(srcdir)/images/ot-contrib-nest.png \
$(srcdir)/images/ot-contrib-nordic.png \
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

-283
View File
@@ -1,283 +0,0 @@
#
# Copyright (c) 2016, 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
AS = 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-ftd \
--enable-mtd \
--enable-ncp \
--with-ncp-bus=uart \
--enable-radio-only \
--enable-linker-map \
--with-examples=da15000 \
MBEDTLS_CPPFLAGS="$(DA15000_MBEDTLS_CPPFLAGS)" \
$(NULL)
ifneq ($(DISABLE_BUILTIN_MBEDTLS), 1)
configure_OPTIONS += MBEDTLS_CPPFLAGS="$(DA15000_MBEDTLS_CPPFLAGS)"
endif
TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
DA15000_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
DA15000_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"da15000-mbedtls-config.h\"'
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/examples/platforms/da15000/crypto
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/include
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/peripherals/include
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/adapters/include
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/memory/include
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/interfaces/ftdf/include
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/bsp/config
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/dialog/DialogSDK/interfaces/ftdf/src
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/mbedtls/repo/include
DA15000_MBEDTLS_CPPFLAGS += -I$(PWD)/third_party/mbedtls
DA15000_MBEDTLS_CPPFLAGS += -include$(PWD)/examples/platforms/da15000/custom_config_qspi.h
CONFIG_FILE = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-da15000-config.h\"'
CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/da15000/
COMMONCFLAGS := \
-fdata-sections \
-ffunction-sections \
-Os \
-g \
-D$(CONFIG_FILE) \
-I$(CONFIG_FILE_PATH) \
$(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 = da15000
ARCHS = cortex-m0
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-m0
#
cortex-m0_target_ABI = cortex-m0
cortex-m0_target_CPPFLAGS = -mcpu=cortex-m0 -mfloat-abi=soft -mthumb
cortex-m0_target_CFLAGS = -mcpu=cortex-m0 -mfloat-abi=soft -mthumb
cortex-m0_target_CXXFLAGS = -mcpu=cortex-m0 -mfloat-abi=soft -mthumb
cortex-m0_target_LDFLAGS = -mcpu=cortex-m0 -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) ""
-6
View File
@@ -35,7 +35,6 @@ DIST_SUBDIRS = \
cc2538 \
cc2650 \
cc2652 \
da15000 \
efr32 \
emsk \
gp712 \
@@ -70,10 +69,6 @@ if OPENTHREAD_EXAMPLES_CC2652
SUBDIRS += cc2652
endif
if OPENTHREAD_EXAMPLES_DA15000
SUBDIRS += da15000
endif
if OPENTHREAD_EXAMPLES_EFR32
SUBDIRS += efr32
endif
@@ -121,7 +116,6 @@ PRETTY_SUBDIRS = \
cc2538 \
cc2650 \
cc2652 \
da15000 \
efr32 \
emsk \
gp712 \
-4
View File
@@ -57,10 +57,6 @@ if OPENTHREAD_EXAMPLES_CC2652
include $(top_srcdir)/examples/platforms/cc2652/Makefile.platform.am
endif
if OPENTHREAD_EXAMPLES_DA15000
include $(top_srcdir)/examples/platforms/da15000/Makefile.platform.am
endif
if OPENTHREAD_EXAMPLES_EFR32
include $(top_srcdir)/examples/platforms/efr32/Makefile.platform.am
endif
-121
View File
@@ -1,121 +0,0 @@
#
# Copyright (c) 2016, 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-da15000.a
# Do not enable -pedantic-errors
override CFLAGS := $(filter-out -pedantic-errors,$(CFLAGS))
override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
libopenthread_da15000_a_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/examples/platforms/da15000 \
-I$(top_srcdir)/examples/platforms/da15000/crypto \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/config \
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/include \
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/memory/include \
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/osal \
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/peripherals/include \
-I$(top_srcdir)/third_party/dialog/DialogSDK/interfaces/ftdf/include \
-I$(top_srcdir)/third_party/dialog/DialogSDK/interfaces/ftdf/src \
-I$(top_srcdir)/third_party/mbedtls/repo/include \
-include$(top_srcdir)/examples/platforms/da15000/custom_config_qspi.h \
-Wno-sign-compare \
-Wno-unused-parameter \
-Wno-type-limits \
-Wno-unused-variable \
-Wno-missing-field-initializers \
-fno-strict-aliasing \
$(MBEDTLS_CPPFLAGS) \
$(NULL)
PLATFORM_SOURCES = \
alarm.c \
flash.c \
logging.c \
misc.c \
radio.c \
random.c \
system.c \
uart.c \
crypto/aes_alt.c \
$(NULL)
DIALOG_SOURCES = \
@top_builddir@/third_party/dialog/DialogSDK/bsp/memory/src/qspi_automode.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_aes_hash.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_cpm.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_crypto.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_dma.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_gpadc.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_gpio.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_hard_fault.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_otpc.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_qspi.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_rf.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_timer0.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_trng.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_uart.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_watchdog.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/sys_tcs.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/startup/config.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/startup/startup_ARMCM0.S \
@top_builddir@/third_party/dialog/DialogSDK/bsp/startup/system_ARMCM0.c \
@top_builddir@/third_party/dialog/DialogSDK/bsp/startup/vector_table.S \
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf.c \
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf_phy_api.c \
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/common.c \
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/data.c \
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/main.c \
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/power.c \
$(NULL)
libopenthread_da15000_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(DIALOG_SOURCES) \
$(NULL)
noinst_HEADERS = \
custom_config_qspi.h \
platform-da15000.h \
$(NULL)
PRETTY_FILES = \
$(PLATFORM_SOURCES) \
$(noinst_HEADERS) \
$(NULL)
Dash = -
libopenthread_da15000_a_LIBADD = \
$(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
@@ -1,39 +0,0 @@
#
# 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.
#
#
# da15000 platform-specific Makefile
#
LDADD_COMMON += \
$(top_builddir)/examples/platforms/da15000/libopenthread-da15000.a \
$(NULL)
LDFLAGS_COMMON += \
-T $(top_srcdir)/third_party/dialog/DialogSDK/bsp/ldfile/da15000.ld \
$(NULL)
-146
View File
@@ -1,146 +0,0 @@
# Dialog OpenThread DA15000 Example
This directory contains example platform drivers for the [Dialog Semiconductor DA15000][da15000]
[da15000]: https://support.dialog-semiconductor.com/connectivity/product/openthread-sandbox
**NOTE:** Each Thread node requires a unique EUI-64.
Please make sure all Thread nodes in your network have a unique EUI-64 by setting HARDCODED_NODE_ID in radio.c to a unique value.
**NOTE:** Current version works only with DA15000
## Toolchain
Download and install the [GNU toolchain for ARM
Cortex-M][gnu-toolchain].
[gnu-toolchain]: https://launchpad.net/gcc-arm-embedded
In a Bash terminal, follow these instructions to install the GNU toolchain and
other dependencies.
```bash
$ cd <path-to-openthread>
$ ./script/bootstrap
```
## Build Examples (How to build and flash):
```bash
$ cd <path-to-openthread>
$ ./bootstrap
$ make -f examples/Makefile-da15000 clean
$ make -f examples/Makefile-da15000
```
Execute script to prepare image for flashing:
**NOTE:** Script is based on Dialog Tools binaries compiled for x86 Linux.
```bash
$ cd ./third_party/dialog/DialogTools
$ ./imgprep.sh
```
Flash Binaries:
**NOTE:** Flashing process requires JLinkGDBServer. Please visit https://www.segger.com/jlink-gdb-server.html for details.
1. Open another terminal window in order to start gdb server. Write the command (Linux):
```bash
$ JLinkGDBServer -ir -if swd -speed auto -device Cortex-M0 -logtofile on -localhostonly
```
2. Return to previous terminal window and execute a command in order to flash the board:
```bash
$ ./cli_programmer gdbserver write_qspi_exec ../../../output/da15000/bin/ot-cli-ftd.bin
```
## Interact:
Board will indicate state of device according to LED blink speed.
| Frequency | Role |
| --- | --- |
| 5Hz | Leader |
| 2Hz | Router |
| 0.5Hz | End Device |
1. Open terminal to /dev/ttyACM0 (serial port settings: 115200 8-N-1).
2. Type help for list of commands
## Examples:
1. Create Topology and become Leader on channel 13.
```
> channel 13
Done
> panid 0xface
Done
> ifconfig up
Done
> thread start
Done
```
Wait and see that LED started to blink with 5Hz.
Check node state:
```
> state
Leader
```
2. Attach Router and ping Leader Mesh Local address.
Open terminal for second device /dev/ttyACM1 and issue commands:
```
> channel 13
Done
> panid 0xface
Done
> ifconfig up
Done
> thread start
```
Wait until LED start to blink. Should blink slower.
Check node state:
```
> state
Router
```
List addresses on terminal with Leader:
```
> ipaddr
fdde:ad00:beef:0:0:ff:fe00:4400
fdde:ad00:beef:0:92f5:9844:67ad:a0c9
fe80:0:0:0:2c11:aba1:ecc1:96da
```
Ping Leader from Router terminal:
```
> ping fdde:ad00:beef:0:92f5:9844:67ad:a0c9
16 bytes from fdde:ad00:beef:0:92f5:9844:67ad:a0c9: icmp_seq=2 hlim=64 time=359ms
```
## Remarks
* Validation
The DA15000 example has been validated by Dialog Semiconductor with commit 1f6528e included.
* Build environment
The DA15000 example code and all required dependencies have been complied with gcc version 5.4.0 (20160609).
## Troubleshooting
* Why cant I see the VCOM port?
The Segger Virtual COM port can be disabled by software configuration. If you can see the Segger
driver properly installed but the VCOM not showing up in the device manager, its probably disabled
by software. To re-enable it you have to run JLinkExe and issue the command ` vcom enable`.It is
required to power cycle the device to apply the change.
-96
View File
@@ -1,96 +0,0 @@
/*
* Copyright (c) 2016, 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 alarm.c
* Platform abstraction for the alarm
*/
#include <openthread/platform/alarm-milli.h>
#include "platform-da15000.h"
#include "hw_timer0.h"
static bool sIsRunning = false;
static uint32_t sAlarm = 0;
static uint32_t sCounter;
volatile bool sAlarmFired = false;
static void timer0_interrupt_cb(void)
{
sCounter++;
}
void da15000AlarmProcess(otInstance *aInstance)
{
if ((sIsRunning) && (sAlarm <= sCounter))
{
sIsRunning = false;
otPlatAlarmMilliFired(aInstance);
}
}
void da15000AlarmInit(void)
{
hw_timer0_init(NULL);
hw_timer0_set_clock_source(HW_TIMER0_CLK_SRC_FAST);
hw_timer0_set_pwm_mode(HW_TIMER0_MODE_PWM);
hw_timer0_set_fast_clock_div(HW_TIMER0_FAST_CLK_DIV_4);
hw_timer0_set_t0_reload(0x07D0, 0x07D0);
hw_timer0_register_int(timer0_interrupt_cb);
hw_timer0_set_on_clock_div(false);
}
uint32_t otPlatAlarmMilliGetNow(void)
{
return sCounter;
}
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
{
OT_UNUSED_VARIABLE(aInstance);
sAlarm = t0 + dt;
sIsRunning = true;
if (sCounter == 0)
{
hw_timer0_enable();
}
hw_timer0_unfreeze();
}
void otPlatAlarmMilliStop(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
sIsRunning = false;
hw_timer0_freeze();
}
-207
View File
@@ -1,207 +0,0 @@
/*
* 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 "aes_alt.h"
#ifdef MBEDTLS_AES_ALT
#include <stdint.h>
#include <string.h>
#include <openthread/platform/toolchain.h>
#include "hw_aes_hash.h"
#include <common/code_utils.hpp>
#include "mbedtls/aes.h"
static void mbedtls_zeroize(void *v, size_t n)
{
volatile unsigned char *p = (unsigned char *)v;
while (n--)
{
*p++ = 0;
}
}
void mbedtls_aes_init(mbedtls_aes_context *ctx)
{
memset(ctx, 0, sizeof(mbedtls_aes_context));
}
void mbedtls_aes_free(mbedtls_aes_context *ctx)
{
if (ctx == NULL)
{
return;
}
hw_aes_hash_disable_clock();
mbedtls_zeroize(ctx, sizeof(mbedtls_aes_context));
}
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
{
int retval = 0;
switch (keybits)
{
case 128:
ctx->hwKeyLen = HW_AES_128;
memcpy(ctx->aes_enc_key, key, 16);
break;
case 192:
ctx->hwKeyLen = HW_AES_192;
memcpy(ctx->aes_enc_key, key, 24);
break;
case 256:
ctx->hwKeyLen = HW_AES_256;
memcpy(ctx->aes_enc_key, key, 32);
break;
default:
retval = MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
break;
}
return retval;
}
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
{
int retval = 0;
switch (keybits)
{
case 128:
ctx->hwKeyLen = HW_AES_128;
memcpy(ctx->aes_dec_key, key, 16);
break;
case 192:
ctx->hwKeyLen = HW_AES_192;
memcpy(ctx->aes_enc_key, key, 24);
break;
case 256:
ctx->hwKeyLen = HW_AES_256;
memcpy(ctx->aes_enc_key, key, 32);
break;
default:
retval = MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
break;
}
return retval;
}
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16])
{
int retval = 0;
hw_aes_hash_enable_clock();
hw_aes_hash_mark_input_block_as_last();
hw_aes_hash_cfg_aes_ecb(ctx->hwKeyLen);
hw_aes_hash_store_keys(ctx->hwKeyLen, ctx->aes_enc_key, HW_AES_PERFORM_KEY_EXPANSION);
hw_aes_hash_cfg_dma((uint8_t *)input, (uint8_t *)output, 16);
switch (mode)
{
case MBEDTLS_AES_ENCRYPT:
hw_aes_hash_encrypt();
retval = 0;
break;
case MBEDTLS_AES_DECRYPT:
hw_aes_hash_decrypt();
retval = 0;
break;
default:
retval = -1;
break;
}
while (hw_aes_hash_is_active())
{
;
}
return retval;
}
int mbedtls_aes_self_test(int verbose)
{
OT_UNUSED_VARIABLE(verbose);
/* 128-bit Key 2b7e151628aed2a6abf7158809cf4f3c */
const uint8_t key_128b[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
int retval = 0;
mbedtls_aes_context aes;
uint8_t input[16] = {0};
uint8_t output[16] = {0};
uint8_t decrypt[16] = {0};
strcpy((char *)input, (const char *)"hw_aes_test");
mbedtls_aes_init(&aes);
retval = mbedtls_aes_setkey_enc(&aes, (const unsigned char *)key_128b, 128);
VerifyOrExit(retval != 0, retval = -1);
retval = mbedtls_aes_setkey_dec(&aes, (const unsigned char *)key_128b, 128);
VerifyOrExit(retval != 0, retval = -1);
retval = mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, input, output);
VerifyOrExit(retval != 0, retval = -1);
retval = mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_DECRYPT, output, decrypt);
VerifyOrExit(retval != 0, retval = -1);
mbedtls_aes_free(&aes);
exit:
return retval;
}
#endif /* MBEDTLS_AES_ALT */
-167
View File
@@ -1,167 +0,0 @@
/*
* 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 MBEDTLS_AES_ALT_H
#define MBEDTLS_AES_ALT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "da15000-mbedtls-config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#ifdef MBEDTLS_AES_ALT
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint8_t hwKeyLen;
unsigned char aes_enc_key[32]; /* Encryption key */
unsigned char aes_dec_key[32]; /* Decryption key */
} mbedtls_aes_context;
/**
* @brief Initialize AES context
*
* @param [in,out] ctx AES context to be initialized
*/
void mbedtls_aes_init(mbedtls_aes_context *ctx);
/**
* @brief Clear AES context
*
* \param ctx AES context to be cleared
*/
void mbedtls_aes_free(mbedtls_aes_context *ctx);
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits);
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits);
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16],
unsigned char output[16]);
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
*/
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
*
* \param ctx AES context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_AES_ALT */
#endif /* MBEDTLS_AES_ALT_H */
@@ -1,34 +0,0 @@
/*
* 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.
*/
#ifndef DA15000_MBEDTLS_CONFIG_H
#define DA15000_MBEDTLS_CONFIG_H
#define MBEDTLS_AES_ALT
#endif // DA15000_MBEDTLS_CONFIG_H
@@ -1,125 +0,0 @@
/*
* Copyright (c) 2016, 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 custom_config_qspi.h
* Board Support Package. User Configuration file for cached QSPI mode.
*/
#ifndef CUSTOM_CONFIG_QSPI_H_
#define CUSTOM_CONFIG_QSPI_H_
#include "bsp_definitions.h"
// clang-format off
#define dg_configBLACK_ORCA_IC_REV BLACK_ORCA_IC_REV_B
#define dg_configBLACK_ORCA_IC_STEP BLACK_ORCA_IC_STEP_B
#undef CONFIG_USE_BLE
#define CONFIG_USE_FTDF
#define __HEAP_SIZE 0x0600
#define __STACK_SIZE 0x0100
#define dg_configUSE_LP_CLK LP_CLK_32768
#define dg_configEXEC_MODE MODE_IS_CACHED
#define dg_configCODE_LOCATION NON_VOLATILE_IS_FLASH
#define dg_configEXT_CRYSTAL_FREQ EXT_CRYSTAL_IS_16M
#define dg_configIMAGE_SETUP DEVELOPMENT_MODE
#define dg_configEMULATE_OTP_COPY (0)
#define dg_configUSER_CAN_USE_TIMER1 (0)
#define dg_configUSE_WDOG (0)
#define dg_configFLASH_CONNECTED_TO (FLASH_CONNECTED_TO_1V8)
#define dg_configFLASH_POWER_DOWN (0)
#define dg_configPOWER_1V8_ACTIVE (1)
#define dg_configPOWER_1V8_SLEEP (1)
#define dg_configBATTERY_TYPE (BATTERY_TYPE_LIMN2O4)
#define dg_configBATTERY_CHARGE_CURRENT 2 // 30mA
#define dg_configBATTERY_PRECHARGE_CURRENT 20 // 2.1mA
#define dg_configBATTERY_CHARGE_NTC 1 // disabled
#define dg_configUSE_USB 0
#define dg_configUSE_USB_CHARGER 0
#define dg_configALLOW_CHARGING_NOT_ENUM 1
#define dg_configUSE_ProDK (1)
#define dg_configUSE_SW_CURSOR (1)
#define dg_configDISABLE_BACKGROUND_FLASH_OPS (1)
/*************************************************************************************************\
* Memory layout specific config
*/
#define dg_configQSPI_CODE_SIZE (512 * 1024)
/*************************************************************************************************\
* FTDF specific config
*/
#define FTDF_NO_CSL /* Define this to disable CSL mode */
#define FTDF_NO_TSCH /* Define this to disable TSCH mode */
#define FTDF_LITE /* Define this to enable LITE mode (only transparent mode enabled) */
#define FTDF_PHY_API /* Define this to enable PHY API mode (no FTDF adapter;
implies FTDF_LITE) */
#define FTDF_PASS_ACK_FRAME /* Define this to pass ACK frame */
/*************************************************************************************************\
* OS specific config
*/
#define OS_BAREMETAL
/*************************************************************************************************\
* Peripheral specific config
*/
#define dg_configRF_ENABLE_RECALIBRATION (0)
#define dg_configUSE_HW_AES_HASH (1)
#define dg_configUSE_HW_TIMER0 (1)
#define dg_configUSE_HW_TRNG (1)
#define dg_configFLASH_ADAPTER (0)
#define dg_configRF_ADAPTER (0)
#define dg_configUART_SOFTWARE_FIFO (1)
#define dg_configUART2_SOFTWARE_FIFO_SIZE (256)
#define dg_configNVMS_ADAPTER (0)
#define dg_configNVMS_VES (0)
/* Include bsp default values */
#include "bsp_defaults.h"
// clang-format on
#endif /* CUSTOM_CONFIG_QSPI_H_ */
-144
View File
@@ -1,144 +0,0 @@
/*
* Copyright (c) 2016, 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 "platform-da15000.h"
#include "qspi_automode.h"
#define FLASH_BUFFER_SIZE 0x2000
#define FLASH_SECTOR_SIZE 0x1000
#define FLASH_PAGE_SIZE 0x0100
/*
* In case that user tries to write data to flash passing as source QSPI mapped flash address
* data must be first copied to RAM as during write QSPI controller can't read flash.
* To achieve this, small on stack buffer will be used to copy data to RAM first.
* This define specifies how much stack can be used for this purpose.
*/
#define ON_STACK_BUFFER_SIZE 16
otError utilsFlashInit(void)
{
return OT_ERROR_NONE;
}
uint32_t utilsFlashGetSize(void)
{
return (uint32_t)FLASH_BUFFER_SIZE;
}
otError utilsFlashErasePage(uint32_t aAddress)
{
uint32_t flash_offset = aAddress & ~(FLASH_SECTOR_SIZE - 1);
qspi_automode_erase_flash_sector(flash_offset);
CACHE->CACHE_CTRL1_REG = CACHE_CACHE_CTRL1_REG_CACHE_FLUSH_Msk;
return OT_ERROR_NONE;
}
otError utilsFlashStatusWait(uint32_t aTimeout)
{
OT_UNUSED_VARIABLE(aTimeout);
return OT_ERROR_NONE;
}
static inline bool FlashQspiAddress(const void *aBuf)
{
if (((uint32_t)aBuf >= MEMORY_QSPIF_BASE) && ((uint32_t)aBuf < MEMORY_QSPIF_END))
{
return true;
}
return ((uint32_t)aBuf >= MEMORY_REMAPPED_BASE) && ((uint32_t)aBuf < MEMORY_REMAPPED_END) &&
(REG_GETF(CRG_TOP, SYS_CTRL_REG, REMAP_ADR0) == 2);
}
static size_t FlashWriteFromQspi(uint32_t aAddress, const uint8_t *aQspiBuf, size_t aSize)
{
size_t written;
size_t offset = 0;
uint8_t buf[ON_STACK_BUFFER_SIZE];
/*
* qspi_automode_write_flash_page can't write data if source address points to QSPI mapped
* memory. To write data from QSPI flash, it will be first copied to small on stack
* buffer. This buffer can be accessed when QSPI controller is working in manual mode.
*/
while (offset < aSize)
{
size_t chunk = sizeof(buf) > aSize - offset ? aSize - offset : sizeof(buf);
memcpy(buf, aQspiBuf + offset, chunk);
written = qspi_automode_write_flash_page(aAddress + offset, buf, chunk);
offset += written;
}
return offset;
}
uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
size_t written;
size_t offset = 0;
bool buf_from_flash = FlashQspiAddress(aData);
while (offset < aSize)
{
/*
* If buf is QSPI Flash memory, use function that will copy source data to RAM
* first.
*/
if (buf_from_flash)
{
written = FlashWriteFromQspi(aAddress + offset, aData + offset, aSize - offset);
}
else
{
/*
* Try write everything, lower driver will reduce this value to accommodate
* page boundary and and maximum write size limitation
*/
written = qspi_automode_write_flash_page(aAddress + offset, aData + offset, aSize - offset);
}
offset += written;
}
CACHE->CACHE_CTRL1_REG = CACHE_CACHE_CTRL1_REG_CACHE_FLUSH_Msk;
return aSize;
}
uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
return qspi_automode_read(aAddress, aData, aSize);
;
}
-48
View File
@@ -1,48 +0,0 @@
/*
* Copyright (c) 2016, 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/logging.h>
#include <openthread/platform/toolchain.h>
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
(OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
OT_UNUSED_VARIABLE(aFormat);
}
#endif
-53
View File
@@ -1,53 +0,0 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <openthread/platform/misc.h>
#include "platform-da15000.h"
#include "hw_cpm.h"
#include "sdk_defs.h"
void otPlatReset(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
hw_cpm_reboot_system();
}
otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return OT_PLAT_RESET_REASON_POWER_ON;
}
void otPlatWakeHost(void)
{
// TODO: implement an operation to wake the host from sleep state.
}
@@ -1,117 +0,0 @@
/*
* Copyright (c) 2016, 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 DA15000 compile-time configuration constants for OpenThread.
*/
#ifndef OPENTHREAD_CORE_DA15000_CONFIG_H_
#define OPENTHREAD_CORE_DA15000_CONFIG_H_
/**
* @def OPENTHREAD_CONFIG_PLATFORM_INFO
*
* The platform-specific string to insert into the OpenThread version string.
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_INFO "DA15000"
/**
* @def SETTINGS_CONFIG_BASE_ADDRESS
*
* The base address of the pages to be used for non-volatile-settings storage.
*/
#define SETTINGS_CONFIG_BASE_ADDRESS 0x7B000
/**
* @def SETTINGS_CONFIG_PAGE_SIZE
*
* The page size of settings.
*
*/
#define SETTINGS_CONFIG_PAGE_SIZE 0x1000
/**
* @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 0
/**
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
*
* Define to 1 if you want to enable software retransmission logic.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 0
/**
* @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 0
/**
* @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 OPENTHREAD_CONFIG_ADDRESS_CACHE_ENTRIES
*
* The number of EID-to-RLOC cache entries.
*
*/
#define OPENTHREAD_CONFIG_ADDRESS_CACHE_ENTRIES 20
/**
* @def OPENTHREAD_CONFIG_LOG_OUTPUT
*
* The DA15000 platform provides an otPlatLog() function.
*/
#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_APP
#endif
/**
* @def OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS
*
* The maximum number of state-changed callback handlers (set using `otSetStateChangedCallback()`).
*
*/
#define OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS 3
#endif // OPENTHREAD_CORE_DA15000_CONFIG_H_
@@ -1,77 +0,0 @@
/*
* Copyright (c) 2016, 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 PLATFORM_DA15000_H_
#define PLATFORM_DA15000_H_
#include <openthread-core-config.h>
#include <openthread/config.h>
#include <openthread/instance.h>
/**
* This function initializes the radio service used by OpenThread.
*
*/
void da15000RadioInit(void);
/**
* This function performs radio driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void da15000RadioProcess(otInstance *aInstance);
/**
* This function initializes the alarm service used by OpenThread.
*
*/
void da15000AlarmInit(void);
/**
* This function performs alarm driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void da15000AlarmProcess(otInstance *aInstance);
/**
* This function initializes the random number service used by OpenThread.
*
*/
void da15000RandomInit(void);
/**
* This function performs UART driver processing.
*
*/
void da15000UartProcess(void);
#endif /* PLATFORM_PLATFORM_DA15000_H_ */
-625
View File
@@ -1,625 +0,0 @@
/*
* Copyright (c) 2016, 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 radio.cpp
* Platform abstraction for radio communication.
*/
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>
#include <string.h>
#include "platform-da15000.h"
#include "common/logging.hpp"
#include "utils/code_utils.h"
#include "ad_ftdf.h"
#include "ad_ftdf_phy_api.h"
#include "hw_otpc.h"
#include "hw_rf.h"
#include "internal.h"
// clang-format off
#define FACTORY_TEST_TIMESTAMP (0x7F8EA08) // Register holds a timestamp of facotry test of a chip
#define FACTORY_TESTER_ID (0x7F8EA0C) // Register holds test machine ID used for factory test
#define RADIO_DEFAULT_CHANNEL (11)
#define RADIO_EUI64_TABLE_SIZE (8)
#define RADIO_FRAMES_BUFFER_SIZE (32)
// clang-format on
enum
{
DA15000_RECEIVE_SENSITIVITY = -100, // dBm
};
static ftdf_dbm sRssiReal = -100; // Initialize with the worst power
static otInstance * sThreadInstance;
static otRadioState sRadioState = OT_RADIO_STATE_DISABLED;
static otRadioFrame sReceiveFrame[RADIO_FRAMES_BUFFER_SIZE];
static otRadioFrame *sReceiveFrameAck;
static otRadioFrame sTransmitFrame;
static otError sTransmitStatus;
static bool sAckFrame = false;
static bool sDropFrame = false;
static bool sRadioPromiscuous = false;
static bool sTransmitDoneFrame = false;
static uint8_t sChannel = RADIO_DEFAULT_CHANNEL;
static uint8_t sEnableRX = 0;
static int8_t sTxPower = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
static uint8_t sReadFrame = 0;
static uint8_t sWriteFrame = 0;
static uint32_t sSleepInitDelay = 0;
static uint8_t sEui64[RADIO_EUI64_TABLE_SIZE];
static uint8_t sReceivePsdu[RADIO_FRAMES_BUFFER_SIZE][OT_RADIO_FRAME_MAX_SIZE];
static uint8_t sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE];
static void da15000OtpRead(void)
{
hw_otpc_init(); // Start clock.
hw_otpc_disable(); // Make sure it is in standby mode.
hw_otpc_init(); // Restart clock.
hw_otpc_manual_read_on(false);
__DMB();
uint32_t *factoryTestTimeStamp = (uint32_t *)FACTORY_TEST_TIMESTAMP;
uint32_t *factoryTestId = (uint32_t *)FACTORY_TESTER_ID;
__DMB();
sEui64[0] = 0x80; // 80-EA-CA is for Dialog Semiconductor
sEui64[1] = 0xEA;
sEui64[2] = 0xCA;
sEui64[3] = (*factoryTestId >> 8) & 0xff;
sEui64[4] = (*factoryTestTimeStamp >> 24) & 0xff;
sEui64[5] = (*factoryTestTimeStamp >> 16) & 0xff;
sEui64[6] = (*factoryTestTimeStamp >> 8) & 0xff;
sEui64[7] = *factoryTestTimeStamp & 0xff;
hw_otpc_manual_read_off();
hw_otpc_disable();
}
void da15000RadioInit(void)
{
uint16_t ptr;
/* Wake up power domains */
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP);
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP) == 0x0)
;
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
while (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_UP) == 0x0)
;
REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_ENABLE, 1);
REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_DIV, 0);
hw_rf_poweron();
hw_rf_system_init();
ad_ftdf_init_phy_api();
da15000OtpRead();
sChannel = RADIO_DEFAULT_CHANNEL;
sTransmitFrame.mPsdu = sTransmitPsdu;
for (ptr = 0; ptr != RADIO_FRAMES_BUFFER_SIZE; ptr++)
{
sReceiveFrame[ptr].mPsdu = &sReceivePsdu[ptr][0];
}
otLogInfoPlat(sThreadInstance, "Radio initialized", NULL);
}
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
OT_UNUSED_VARIABLE(aInstance);
memcpy(aIeeeEui64, sEui64, RADIO_EUI64_TABLE_SIZE);
}
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanid)
{
otLogInfoPlat("Set PanId: %X", aPanid);
ftdf_set_value(FTDF_PIB_PAN_ID, &aPanid);
}
void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
{
otLogInfoPlat("Set Extended Address: %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]);
ftdf_set_value(FTDF_PIB_EXTENDED_ADDRESS, aAddress->m8);
}
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
{
otLogInfoPlat("Set Short Address: %X", aAddress);
ftdf_set_value(FTDF_PIB_SHORT_ADDRESS, &aAddress);
}
otError otPlatRadioEnable(otInstance *aInstance)
{
ftdf_bitmap32_t options;
otError error = OT_ERROR_NONE;
uint8_t modeCCA;
otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
sThreadInstance = aInstance;
sEnableRX = 1;
ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
ftdf_set_value(FTDF_PIB_CURRENT_CHANNEL, &sChannel);
modeCCA = FTDF_CCA_MODE_2;
ftdf_set_value(FTDF_PIB_CCA_MODE, &modeCCA);
options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
options |= FTDF_TRANSPARENT_AUTO_ACK;
ftdf_enable_transparent_mode(FTDF_TRUE, options);
otPlatRadioSetPromiscuous(aInstance, false);
otLogDebgPlat("Radio state: OT_RADIO_STATE_SLEEP", NULL);
sRadioState = OT_RADIO_STATE_SLEEP;
exit:
return error;
}
otError otPlatRadioDisable(otInstance *aInstance)
{
sEnableRX = 0;
ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
ad_ftdf_sleep_when_possible(FTDF_TRUE);
ftdf_fppr_reset();
otLogDebgPlat("Radio state: OT_RADIO_STATE_DISABLED", NULL);
sRadioState = OT_RADIO_STATE_DISABLED;
return OT_ERROR_NONE;
}
bool otPlatRadioIsEnabled(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return (sRadioState != OT_RADIO_STATE_DISABLED);
}
otError otPlatRadioSleep(otInstance *aInstance)
{
otError error = OT_ERROR_NONE;
if (sRadioState == OT_RADIO_STATE_RECEIVE && sSleepInitDelay == 0)
{
sSleepInitDelay = otPlatAlarmMilliGetNow();
return OT_ERROR_NONE;
}
else if ((otPlatAlarmMilliGetNow() - sSleepInitDelay) < dg_configINITIAL_SLEEP_DELAY_TIME)
{
return OT_ERROR_NONE;
}
otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_RECEIVE, error = OT_ERROR_INVALID_STATE);
otLogDebgPlat("Radio state: OT_RADIO_STATE_SLEEP", NULL);
sRadioState = OT_RADIO_STATE_SLEEP;
sEnableRX = 0;
ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
ad_ftdf_sleep_when_possible(FTDF_TRUE);
exit:
return error;
}
otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(sRadioState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
ad_ftdf_wake_up();
sEnableRX = 0;
ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
sChannel = aChannel;
ftdf_set_value(FTDF_PIB_CURRENT_CHANNEL, &aChannel);
sEnableRX = 1;
ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
otLogDebgPlat("Radio state: OT_RADIO_STATE_RECEIVE", NULL);
sRadioState = OT_RADIO_STATE_RECEIVE;
exit:
return error;
}
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aEnable);
}
otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
otError error = OT_ERROR_NONE;
uint8_t entry;
uint8_t entryIdx;
// check if address already stored
otEXPECT(!ftdf_fppr_lookup_short_address(aShortAddress, &entry, &entryIdx));
otEXPECT_ACTION(ftdf_fppr_get_free_short_address(&entry, &entryIdx), error = OT_ERROR_NO_BUFS);
otLogDebgPlat("Add ShortAddress entry: %d", entry);
ftdf_fppr_set_short_address(entry, entryIdx, aShortAddress);
ftdf_fppr_set_short_address_valid(entry, entryIdx, FTDF_TRUE);
exit:
return error;
}
otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
otError error = OT_ERROR_NONE;
uint8_t entry;
ftdf_ext_address_t addr;
uint32_t addrL;
uint64_t addrH;
addrL =
(aExtAddress->m8[3] << 24) | (aExtAddress->m8[2] << 16) | (aExtAddress->m8[1] << 8) | (aExtAddress->m8[0] << 0);
addrH =
(aExtAddress->m8[7] << 24) | (aExtAddress->m8[6] << 16) | (aExtAddress->m8[5] << 8) | (aExtAddress->m8[4] << 0);
addr = addrL | (addrH << 32);
// check if address already stored
otEXPECT(!ftdf_fppr_lookup_ext_address(addr, &entry));
otEXPECT_ACTION(ftdf_fppr_get_free_ext_address(&entry), error = OT_ERROR_NO_BUFS);
otLogDebgPlat("Add ExtAddress entry: %d", entry);
ftdf_fppr_set_ext_address(entry, addr);
ftdf_fppr_set_ext_address_valid(entry, FTDF_TRUE);
exit:
return error;
}
otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
otError error = OT_ERROR_NONE;
uint8_t entry;
uint8_t entryIdx;
otEXPECT_ACTION(ftdf_fppr_lookup_short_address(aShortAddress, &entry, &entryIdx), error = OT_ERROR_NO_ADDRESS);
otLogDebgPlat("Clear ShortAddress entry: %d", entry);
ftdf_fppr_set_short_address(entry, entryIdx, 0);
ftdf_fppr_set_short_address_valid(entry, entryIdx, FTDF_FALSE);
exit:
return error;
}
otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
otError error = OT_ERROR_NONE;
uint8_t entry;
ftdf_ext_address_t addr;
uint32_t addrL;
uint64_t addrH;
addrL =
(aExtAddress->m8[3] << 24) | (aExtAddress->m8[2] << 16) | (aExtAddress->m8[1] << 8) | (aExtAddress->m8[0] << 0);
addrH =
(aExtAddress->m8[7] << 24) | (aExtAddress->m8[6] << 16) | (aExtAddress->m8[5] << 8) | (aExtAddress->m8[4] << 0);
addr = addrL | (addrH << 32);
otEXPECT_ACTION(ftdf_fppr_lookup_ext_address(addr, &entry), error = OT_ERROR_NO_ADDRESS);
otLogDebgPlat("Clear ExtAddress entry: %d", entry);
ftdf_fppr_set_ext_address(entry, 0);
ftdf_fppr_set_ext_address_valid(entry, FTDF_FALSE);
exit:
return error;
}
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
uint8_t i, j;
otLogDebgPlat("Clear ShortAddress entries", NULL);
for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
{
for (j = 0; j < 4; j++)
{
if (ftdf_fppr_get_short_address_valid(i, j))
{
ftdf_fppr_set_short_address_valid(i, j, FTDF_FALSE);
}
}
}
}
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
uint8_t i;
otLogDebgPlat("Clear ExtAddress entries", NULL);
for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
{
if (ftdf_fppr_get_ext_address_valid(i))
{
ftdf_fppr_set_ext_address_valid(i, FTDF_FALSE);
}
}
}
otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return &sTransmitFrame;
}
otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(sRadioState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
otLogDebgPlat("Radio start transmit: %d bytes on channel: %d", aFrame->mLength, aFrame->mChannel);
ad_ftdf_send_frame_simple(aFrame->mLength, aFrame->mPsdu, aFrame->mChannel, 0, FTDF_TRUE);
otLogDebgPlat("Radio state: OT_RADIO_STATE_TRANSMIT", NULL);
sRadioState = OT_RADIO_STATE_TRANSMIT;
otPlatRadioTxStarted(aInstance, aFrame);
exit:
return error;
}
int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return sRssiReal;
}
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
}
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return sRadioPromiscuous;
}
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
otLogInfoPlat("Set Promiscuous: %d", aEnable ? 1 : 0);
ftdf_set_value(FTDF_PIB_PROMISCUOUS_MODE, &aEnable);
sRadioPromiscuous = aEnable;
}
otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aScanChannel);
OT_UNUSED_VARIABLE(aScanDuration);
return OT_ERROR_NOT_IMPLEMENTED;
}
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 = sTxPower;
exit:
return error;
}
otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
otLogInfoPlat("Set DefaultTxPower: %d", aPower);
sTxPower = aPower;
ftdf_set_value(FTDF_PIB_TX_POWER, &aPower);
return OT_ERROR_NONE;
}
void da15000RadioProcess(otInstance *aInstance)
{
ftdf_frame_header_t frameHeader;
if (sReadFrame != sWriteFrame)
{
ftdf_get_frame_header(sReceiveFrame[sReadFrame].mPsdu, &frameHeader);
otLogDebgPlat("Radio received: %d bytes", sReceiveFrame[sReadFrame].mLength);
if (frameHeader.frame_type == FTDF_ACKNOWLEDGEMENT_FRAME)
{
sReceiveFrameAck = &sReceiveFrame[sReadFrame];
sAckFrame = true;
}
// TODO Set this flag only when the packet is really acknowledged with frame pending set.
// See https://github.com/openthread/openthread/pull/3785
sReceiveFrame[sReadFrame].mInfo.mRxInfo.mAckedWithFramePending = true;
otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame[sReadFrame], OT_ERROR_NONE);
sReadFrame = (sReadFrame + 1) % RADIO_FRAMES_BUFFER_SIZE;
sDropFrame = false;
}
if (sTransmitDoneFrame)
{
otLogDebgPlat("Radio transmit status: %s", otThreadErrorToString(sTransmitStatus));
ftdf_get_frame_header(sTransmitFrame.mPsdu, &frameHeader);
if ((frameHeader.options & FTDF_OPT_ACK_REQUESTED) == 0 || sTransmitStatus != OT_ERROR_NONE)
{
sRadioState = OT_RADIO_STATE_RECEIVE;
otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, NULL, sTransmitStatus);
}
else
{
otEXPECT(sAckFrame);
sRadioState = OT_RADIO_STATE_RECEIVE;
otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, sReceiveFrameAck, sTransmitStatus);
sAckFrame = false;
}
sTransmitDoneFrame = false;
otLogDebgPlat("Radio state: OT_RADIO_STATE_RECEIVE", NULL);
}
exit:
return;
}
void ftdf_send_frame_transparent_confirm(void *handle, ftdf_bitmap32_t status)
{
OT_UNUSED_VARIABLE(handle);
switch (status)
{
case FTDF_TRANSPARENT_SEND_SUCCESSFUL:
sTransmitStatus = OT_ERROR_NONE;
break;
case FTDF_TRANSPARENT_CSMACA_FAILURE:
sTransmitStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
break;
case FTDF_TRANSPARENT_NO_ACK:
sTransmitStatus = OT_ERROR_NO_ACK;
break;
default:
sTransmitStatus = OT_ERROR_ABORT;
break;
}
sTransmitDoneFrame = true;
}
static void radioRssiCalc(ftdf_link_quality_t link_quality)
{
sRssiReal = (ftdf_dbm)((0.5239 * (float)link_quality) - 114.8604);
}
void ftdf_rcv_frame_transparent(ftdf_data_length_t frame_length,
ftdf_octet_t * frame,
ftdf_bitmap32_t status,
ftdf_link_quality_t link_quality)
{
otEXPECT(frame_length <= OT_RADIO_FRAME_MAX_SIZE);
otEXPECT(sRadioState != OT_RADIO_STATE_DISABLED);
otEXPECT(!sDropFrame);
if (status == FTDF_TRANSPARENT_RCV_SUCCESSFUL)
{
radioRssiCalc(link_quality);
if (otPlatRadioGetPromiscuous(sThreadInstance))
{
// Timestamp
sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mMsec = otPlatAlarmMilliGetNow();
sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mUsec = 0; // Don't support microsecond timer for now.
}
sReceiveFrame[sWriteFrame].mChannel = sChannel;
sReceiveFrame[sWriteFrame].mLength = frame_length;
sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mLqi = OT_RADIO_LQI_NONE;
sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mRssi = otPlatRadioGetRssi(sThreadInstance);
memcpy(sReceiveFrame[sWriteFrame].mPsdu, frame, frame_length);
sWriteFrame = (sWriteFrame + 1) % RADIO_FRAMES_BUFFER_SIZE;
if (sWriteFrame == sReadFrame)
{
sDropFrame = true;
}
}
exit:
return;
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return DA15000_RECEIVE_SENSITIVITY;
}
-127
View File
@@ -1,127 +0,0 @@
/*
* Copyright (c) 2016, 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 true random number generator.
*/
#include <string.h>
#include <openthread/platform/random.h>
#include "platform-da15000.h"
#include "hw_trng.h"
#include "sdk_defs.h"
#define RANDOM_SIZE_OF_BUFFER 32
static uint32_t sRandomNumbers[RANDOM_SIZE_OF_BUFFER];
static uint8_t sRandomNextNumberIndex = 0;
static bool sRandomGeneratorStarted = false;
static void RandomCallback(void)
{
hw_trng_get_numbers(sRandomNumbers, RANDOM_SIZE_OF_BUFFER);
sRandomNextNumberIndex = 0;
hw_trng_stop();
hw_trng_disable_clk();
hw_trng_disable_interrupt();
sRandomGeneratorStarted = false;
}
static void StartGenerator(void)
{
hw_trng_enable(RandomCallback);
sRandomGeneratorStarted = true;
}
void da15000RandomInit(void)
{
StartGenerator();
}
uint32_t otPlatRandomGet(void)
{
uint32_t randomNumber;
bool randomGet = false;
do
{
GLOBAL_INT_DISABLE();
if (sRandomNextNumberIndex < RANDOM_SIZE_OF_BUFFER)
{
randomNumber = sRandomNumbers[sRandomNextNumberIndex++];
randomGet = true;
if (sRandomNextNumberIndex == RANDOM_SIZE_OF_BUFFER)
{
StartGenerator();
}
}
else if (hw_trng_get_fifo_level() > 0)
{
randomNumber = hw_trng_get_number();
randomGet = true;
}
else if (!sRandomGeneratorStarted)
{
StartGenerator();
}
GLOBAL_INT_RESTORE();
} while (!randomGet);
return randomNumber;
}
otError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength)
{
uint32_t randomNumber;
while (aOutputLength)
{
randomNumber = otPlatRandomGet();
if (aOutputLength < 4)
{
memcpy(aOutput, &randomNumber, aOutputLength);
aOutputLength = 0;
}
else
{
memcpy(aOutput, &randomNumber, 4);
aOutputLength -= 4;
aOutput += 4;
}
}
return OT_ERROR_NONE;
}
-297
View File
@@ -1,297 +0,0 @@
/*
* Copyright (c) 2016, 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.
*/
#include <openthread/commissioner.h>
#include <openthread/joiner.h>
#include <openthread/thread.h>
#include <openthread/platform/alarm-milli.h>
#include "platform-da15000.h"
#include "hw_cpm.h"
#include "hw_gpio.h"
#include "hw_qspi.h"
#include "hw_watchdog.h"
#include "sdk_defs.h"
static bool sBlink = false;
static int sMsCounterInit;
static int sMsCounter;
// clang-format off
#define ALIVE_LED_PERIOD (50000)
#define ALIVE_LED_DUTY (500)
#define LEADER_BLINK_TIME (200)
#define ROUTER_BLINK_TIME (500)
#define CHILD_BLINK_TIME (2000)
// clang-format on
static otInstance *sInstance = NULL;
/*
* Example function. Blink LED according to node state
* Leader - 5Hz
* Router - 2Hz
* Child - 0.5Hz
*/
static void ExampleProcess(otInstance *aInstance)
{
static int aliveLEDcounter = 0;
otDeviceRole devRole;
static int thrValue;
devRole = otThreadGetDeviceRole(aInstance);
if (sBlink == false && otPlatAlarmMilliGetNow() != 0)
{
sMsCounterInit = otPlatAlarmMilliGetNow();
sBlink = true;
}
sMsCounter = otPlatAlarmMilliGetNow() - sMsCounterInit;
switch (devRole)
{
case OT_DEVICE_ROLE_LEADER:
thrValue = LEADER_BLINK_TIME;
break;
case OT_DEVICE_ROLE_ROUTER:
thrValue = ROUTER_BLINK_TIME;
break;
case OT_DEVICE_ROLE_CHILD:
thrValue = CHILD_BLINK_TIME;
break;
default:
thrValue = 0x00;
}
if ((thrValue != 0x00) && (sMsCounter >= thrValue))
{
hw_gpio_toggle(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
sMsCounterInit = otPlatAlarmMilliGetNow();
}
if (thrValue == 0)
{
// No specific role, let's generate 'alive blink'
// to inform that we are running.
// Loop counter is used to run even if timers
// are not initialized yet.
aliveLEDcounter++;
if (aliveLEDcounter > ALIVE_LED_PERIOD)
{
aliveLEDcounter = 0;
hw_gpio_set_active(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
}
if (aliveLEDcounter > ALIVE_LED_DUTY)
{
hw_gpio_set_inactive(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
}
}
}
void otSysInit(int argc, char *argv[])
{
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
// Initialize Random number generator
da15000RandomInit();
// Initialize Alarm
da15000AlarmInit();
// Initialize Radio
da15000RadioInit();
}
bool otSysPseudoResetWasRequested(void)
{
return false;
}
#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && (OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_JOINER)
static sys_clk_t ClkGet(void)
{
sys_clk_t clk = sysclk_RC16;
uint32_t hw_clk = hw_cpm_get_sysclk();
switch (hw_clk)
{
case SYS_CLK_IS_RC16:
clk = sysclk_RC16;
break;
case SYS_CLK_IS_XTAL16M:
if (dg_configEXT_CRYSTAL_FREQ == EXT_CRYSTAL_IS_16M)
{
clk = sysclk_XTAL16M;
}
else
{
clk = sysclk_XTAL32M;
}
break;
case SYS_CLK_IS_PLL:
if (hw_cpm_get_pll_divider_status() == 1)
{
clk = sysclk_PLL48;
}
else
{
clk = sysclk_PLL96;
}
break;
case SYS_CLK_IS_LP:
// fall-through
default:
ASSERT_WARNING(0);
break;
}
return clk;
}
static void ClkSet(sys_clk_t clock)
{
switch (clock)
{
case sysclk_XTAL16M:
if (!hw_cpm_check_xtal16m_status()) // XTAL16M disabled
{
hw_cpm_enable_xtal16m(); // Enable XTAL16M
}
hw_cpm_set_sysclk(SYS_CLK_IS_XTAL16M); // Set XTAL16 as sys_clk
hw_watchdog_unfreeze(); // Start watchdog
while (!hw_cpm_is_xtal16m_started())
; // Block until XTAL16M starts
hw_qspi_set_div(HW_QSPI_DIV_1);
hw_watchdog_freeze(); // Stop watchdog
hw_cpm_set_hclk_div(0);
hw_cpm_set_pclk_div(0);
break;
case sysclk_PLL48:
if (hw_cpm_is_pll_locked() == 0)
{
hw_cpm_pll_sys_on(); // Turn on PLL
}
hw_cpm_enable_pll_divider(); // Enable divider (div by 2)
hw_qspi_set_div(HW_QSPI_DIV_1);
hw_cpm_set_sysclk(SYS_CLK_IS_PLL);
hw_cpm_set_hclk_div(0);
hw_cpm_set_pclk_div(0);
break;
case sysclk_PLL96:
if (hw_cpm_is_pll_locked() == 0)
{
hw_cpm_pll_sys_on(); // Turn on PLL
}
hw_cpm_disable_pll_divider(); // Disable divider (div by 1)
hw_qspi_set_div(HW_QSPI_DIV_2);
hw_cpm_set_sysclk(SYS_CLK_IS_PLL);
hw_cpm_set_hclk_div(0);
hw_cpm_set_pclk_div(0);
break;
default:
break;
}
}
static void ClkChange(sys_clk_t lastClock, sys_clk_t newClock)
{
if (ClkGet() == lastClock)
{
ClkSet(newClock);
}
}
static void StateChangedCallback(uint32_t aFlags, void *aContext)
{
if ((aFlags & OT_CHANGED_COMMISSIONER_STATE) != 0)
{
if (otCommissionerGetState(sInstance) == OT_COMMISSIONER_STATE_ACTIVE)
{
ClkChange(sysclk_XTAL16M, sysclk_PLL96);
}
else
{
ClkChange(sysclk_PLL96, sysclk_XTAL16M);
}
}
if ((aFlags & OT_CHANGED_JOINER_STATE) != 0)
{
if (otJoinerGetState(sInstance) != OT_JOINER_STATE_IDLE)
{
ClkChange(sysclk_XTAL16M, sysclk_PLL96);
}
else
{
ClkChange(sysclk_PLL96, sysclk_XTAL16M);
}
}
}
#endif // (OPENTHREAD_MTD || OPENTHREAD_FTD) && (OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_JOINER)
void otSysProcessDrivers(otInstance *aInstance)
{
if (sInstance == NULL)
{
sInstance = aInstance;
#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && (OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_JOINER)
otSetStateChangedCallback(aInstance, StateChangedCallback, 0);
#endif // (OPENTHREAD_MTD || OPENTHREAD_FTD) && (OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_JOINER)
}
da15000UartProcess();
da15000RadioProcess(aInstance);
da15000AlarmProcess(aInstance);
ExampleProcess(aInstance);
}
-119
View File
@@ -1,119 +0,0 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <openthread/platform/uart.h>
#include "platform-da15000.h"
#include "hw_gpio.h"
#include "hw_uart.h"
static bool sUartWriteDone = false;
static bool sUartReadDone = false;
static char * sInitBuf = NULL;
static uint8_t sUartBuf;
static void UartSignalWrite(void *p, uint16_t transferred)
{
if (transferred)
{
sUartWriteDone = true;
}
}
static void UartSignalRead(void *p, uint16_t transferred)
{
if (transferred)
{
sUartReadDone = true;
}
}
otError otPlatUartEnable(void)
{
// clang-format off
uart_config_ex uart_init =
{
.baud_rate = HW_UART_BAUDRATE_115200,
.data = HW_UART_DATABITS_8,
.parity = HW_UART_PARITY_NONE,
.stop = HW_UART_STOPBITS_1,
.auto_flow_control = 0,
.use_fifo = 1,
.use_dma = 1,
.tx_fifo_tr_lvl = 0,
.rx_fifo_tr_lvl = 0,
.tx_dma_channel = HW_DMA_CHANNEL_3,
.rx_dma_channel = HW_DMA_CHANNEL_2,
};
// clang-format on
hw_uart_init_ex(HW_UART2, &uart_init);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_UART2_TX);
hw_gpio_set_pin_function(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_UART2_RX);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_5, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO);
hw_uart_receive(HW_UART2, &sUartBuf, 1, UartSignalRead, NULL);
return OT_ERROR_NONE;
}
otError otPlatUartDisable(void)
{
return OT_ERROR_NONE;
}
void da15000UartProcess(void)
{
if (sUartReadDone)
{
otPlatUartReceived(&sUartBuf, 1);
sUartReadDone = false;
hw_uart_receive(HW_UART2, &sUartBuf, 1, UartSignalRead, NULL);
}
if (sUartWriteDone)
{
sUartWriteDone = false;
otPlatUartSendDone();
}
if (sInitBuf == NULL)
{
sInitBuf = "\n";
otPlatUartReceived((uint8_t *)sInitBuf, 1);
}
}
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
{
hw_uart_send(HW_UART2, aBuf, aBufLength, UartSignalWrite, NULL);
return OT_ERROR_NONE;
}
-1
View File
@@ -29,7 +29,6 @@
include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
EXTRA_DIST = \
dialog \
nxp \
nlbuild-autotools \
openthread-test-driver \
-26
View File
@@ -1,26 +0,0 @@
/* Copyright (c) 2009 - 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
-650
View File
@@ -1,650 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup BSP_CONFIG
* \{
* \addtogroup BSP_DEBUG
*
* \brief Doxygen documentation is not yet available for this module.
* Please check the source code file(s)
*
* \{
*/
/**
****************************************************************************************
*
* @file bsp_debug.h
*
* @brief Board Support Package. Debug Configuration.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 BSP_DEBUG_H_
#define BSP_DEBUG_H_
/* --------------------------------- DEBUG GPIO handling macros --------------------------------- */
#define DBG_CONFIGURE(flag, name, func) \
{ \
if (flag == 1) { \
name##_MODE_REG = 0x300 + func; \
} \
}
#define DBG_CONFIGURE_HIGH(flag, name) \
{ \
if (flag == 1) { \
name##_SET_REG = name##_PIN; \
name##_MODE_REG = 0x300; \
} \
}
#define DBG_CONFIGURE_LOW(flag, name) \
{ \
if (flag == 1) { \
name##_RESET_REG = name##_PIN; \
name##_MODE_REG = 0x300; \
} \
}
#define DBG_SET_HIGH(flag, name) \
{ \
if (flag == 1) { \
name##_SET_REG = name##_PIN; \
} \
}
#define DBG_SET_LOW(flag, name) \
{ \
if (flag == 1) { \
name##_RESET_REG = name##_PIN; \
} \
}
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------- HardFault or NMI event ------------------------------------ */
#ifndef EXCEPTION_DEBUG
#define EXCEPTION_DEBUG (0)
#endif
/* ---------------------------------------------------------------------------------------------- */
/* --------------------------------- Clock and Power Manager ------------------------------------ */
#ifndef CPM_DEBUG
#define CPM_DEBUG (0)
#endif
#ifndef CPM_USE_FUNCTIONAL_DEBUG
#define CPM_USE_FUNCTIONAL_DEBUG (0) // Requires GPIO config.
#endif
#ifndef CPM_USE_TIMING_DEBUG
#define CPM_USE_TIMING_DEBUG (0) // Requires GPIO config.
#endif
#ifndef CPM_USE_RCX_DEBUG
#define CPM_USE_RCX_DEBUG (0) // Requires logging.
#endif
/* Controls which RAM blocks will be retained when the MEASURE_SLEEP_CURRENT test mode is used
* (optional). */
#ifndef dg_configTESTMODE_RETAIN_RAM
#define dg_configTESTMODE_RETAIN_RAM (0x1F)
#endif
/* Controls whether the Cache will be retained when the MEASURE_SLEEP_CURRENT test mode is used
* (optional). */
#ifndef dg_configTESTMODE_RETAIN_CACHE
#define dg_configTESTMODE_RETAIN_CACHE (0)
#endif
/* Controls whether the ECC RAM will be retained when the MEASURE_SLEEP_CURRENT test mode is used
* (optional). */
#ifndef dg_config_TESTMODE_RETAIN_ECCRAM
#define dg_config_TESTMODE_RETAIN_ECCRAM (0)
#endif
/* ---------------------------------------------------------------------------------------------- */
/* --------------------------------------- USB Charger ------------------------------------------ */
#ifndef DEBUG_USB_CHARGER
#define DEBUG_USB_CHARGER (0)
#endif
#ifndef DEBUG_USB_CHARGER_FSM
#define DEBUG_USB_CHARGER_FSM (0)
#endif
#ifndef DEBUG_USB_CHARGER_PRINT
#define DEBUG_USB_CHARGER_PRINT (0)
#endif
#ifndef USB_CHARGER_TIMING_DEBUG
#define USB_CHARGER_TIMING_DEBUG (0)
#endif
/* ---------------------------------------------------------------------------------------------- */
/* ------------------------------------------- BLE ---------------------------------------------- */
#ifndef BLE_USE_TIMING_DEBUG
#define BLE_USE_TIMING_DEBUG (0) // Requires GPIO config.
#endif
#ifndef BLE_ADAPTER_DEBUG
#define BLE_ADAPTER_DEBUG (0) // Requires GPIO config.
#endif
#ifndef BLE_RX_EN_DEBUG
#define BLE_RX_EN_DEBUG (0) // Requires GPIO config.
#endif
#define BLE_RX_EN_FUNC (57)
#ifndef BLE_WINDOW_STATISTICS
#define BLE_WINDOW_STATISTICS (0)
#endif
#ifndef BLE_SLEEP_PERIOD_DEBUG
#define BLE_SLEEP_PERIOD_DEBUG (0) // Requires logging and window statistics.
#endif
#ifndef BLE_WAKEUP_MONITOR_PERIOD
#define BLE_WAKEUP_MONITOR_PERIOD (1024)
#endif
#ifndef BLE_MAX_MISSES_ALLOWED
#define BLE_MAX_MISSES_ALLOWED (0)
#endif
#ifndef BLE_MAX_DELAYS_ALLOWED
#define BLE_MAX_DELAYS_ALLOWED (0)
#endif
/* ---------------------------------------------------------------------------------------------- */
/* ------------------------------------------ Flash --------------------------------------------- */
#ifndef FLASH_DEBUG
#define FLASH_DEBUG (0) // Requires GPIO config.
#endif
#ifndef __DBG_QSPI_ENABLED
#define __DBG_QSPI_ENABLED (0)
#endif
/* ---------------------------------------------------------------------------------------------- */
/* ------------------------------------------ Common -------------------------------------------- */
#ifndef CMN_TIMING_DEBUG
#define CMN_TIMING_DEBUG (0) // Requires GPIO config.
#endif
/* ---------------------------------------------------------------------------------------------- */
/* -------------------------------------------- SPI --------------------------------------------- */
#ifndef SPI_TIMING_DEBUG
#define SPI_TIMING_DEBUG (0) // Requires GPIO config.
#endif
/* ---------------------------------------------------------------------------------------------- */
/* ------------------------------------ GPIO configuration -------------------------------------- */
/* Enable/Disable GPIO pin assignment conflict detection
*/
#define DEBUG_GPIO_ALLOC_MONITOR_ENABLED (0)
/* Exception handling debug configuration
*
*/
#if (EXCEPTION_DEBUG == 0)
// Exception occurred (initial configuration: low)
#define EXCEPTIONDBG_MODE_REG *(volatile int *)0x20000000
#define EXCEPTIONDBG_SET_REG *(volatile int *)0x20000000
#define EXCEPTIONDBG_RESET_REG *(volatile int *)0x20000000
#define EXCEPTIONDBG_PIN (0)
#else
// Tick (P3[0])
#define EXCEPTIONDBG_MODE_REG GPIO->P30_MODE_REG
#define EXCEPTIONDBG_SET_REG GPIO->P3_SET_DATA_REG
#define EXCEPTIONDBG_RESET_REG GPIO->P3_RESET_DATA_REG
#define EXCEPTIONDBG_PIN (1 << 0)
#endif
/* Functional debug configuration
*
* Note that GPIO overlapping is allowed if the tracked events are discrete and the initial GPIO
* configuration is the same! No checking is performed for erroneous configuration though!
*
*/
#if (CPM_USE_FUNCTIONAL_DEBUG == 0)
// Tick (initial configuration: low)
#define CPMDBG_TICK_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_TICK_SET_REG *(volatile int *)0x20000000
#define CPMDBG_TICK_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_TICK_PIN (0)
// External Wake-up (initial configuration: low)
#define CPMDBG_EXT_WKUP_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_EXT_WKUP_SET_REG *(volatile int *)0x20000000
#define CPMDBG_EXT_WKUP_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_EXT_WKUP_PIN (0)
// Active / Sleep (initial configuration: high)
#define CPMDBG_POWERUP_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_POWERUP_SET_REG *(volatile int *)0x20000000
#define CPMDBG_POWERUP_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_POWERUP_PIN (0)
#else
// Tick (P2[3])
#define CPMDBG_TICK_MODE_REG GPIO->P23_MODE_REG
#define CPMDBG_TICK_SET_REG GPIO->P2_SET_DATA_REG
#define CPMDBG_TICK_RESET_REG GPIO->P2_RESET_DATA_REG
#define CPMDBG_TICK_PIN (1 << 3)
// External Wake-up (P3[0])
#define CPMDBG_EXT_WKUP_MODE_REG GPIO->P30_MODE_REG
#define CPMDBG_EXT_WKUP_SET_REG GPIO->P3_SET_DATA_REG
#define CPMDBG_EXT_WKUP_RESET_REG GPIO->P3_RESET_DATA_REG
#define CPMDBG_EXT_WKUP_PIN (1 << 0)
// Active / Sleep (P1[4])
#define CPMDBG_POWERUP_MODE_REG GPIO->P14_MODE_REG
#define CPMDBG_POWERUP_SET_REG GPIO->P1_SET_DATA_REG
#define CPMDBG_POWERUP_RESET_REG GPIO->P1_RESET_DATA_REG
#define CPMDBG_POWERUP_PIN (1 << 4)
#endif
/* Timing debug configuration
*
* Note that in this mode the pad latches are removed immediately after the execution resumes from
* the __WFI(). Because of this, it is not advised to use this feature in projects that use GPIOS.
* Nevertheless, in case it is used, make sure that the "peripheral initialization" is also done
* at that point, modifying sys_power_mgr.c accordingly.
*
* Note also that GPIO overlapping is allowed if the tracked events are discrete and the initial
* GPIO configuration is the same! No checking is performed for erroneous configuration though!
*
*/
#if (CPM_USE_TIMING_DEBUG == 0)
// CPM: sleep or idle entry (until __WFI() is called) (initial configuration: high)
#define CPMDBG_SLEEP_ENTER_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_SLEEP_ENTER_SET_REG *(volatile int *)0x20000000
#define CPMDBG_SLEEP_ENTER_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_SLEEP_ENTER_PIN (0)
// CPM: sleep or idle exit (initial configuration: low)
#define CPMDBG_SLEEP_EXIT_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_SLEEP_EXIT_SET_REG *(volatile int *)0x20000000
#define CPMDBG_SLEEP_EXIT_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_SLEEP_EXIT_PIN (0)
// Low clocks (initial configuration: low)
#define CPMDBG_LOWER_CLOCKS_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_LOWER_CLOCKS_SET_REG *(volatile int *)0x20000000
#define CPMDBG_LOWER_CLOCKS_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_LOWER_CLOCKS_PIN (0)
// XTAL16M settling (initial configuration: low)
#define CPMDBG_XTAL16M_SETTLED_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_XTAL16M_SETTLED_SET_REG *(volatile int *)0x20000000
#define CPMDBG_XTAL16M_SETTLED_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_XTAL16M_SETTLED_PIN (0)
#else
// CPM: sleep or idle entry (until __WFI() is called) (P1[7])
#define CPMDBG_SLEEP_ENTER_MODE_REG GPIO->P17_MODE_REG
#define CPMDBG_SLEEP_ENTER_SET_REG GPIO->P1_SET_DATA_REG
#define CPMDBG_SLEEP_ENTER_RESET_REG GPIO->P1_RESET_DATA_REG
#define CPMDBG_SLEEP_ENTER_PIN (1 << 7)
// CPM: sleep or idle exit (P1[6])
#define CPMDBG_SLEEP_EXIT_MODE_REG GPIO->P16_MODE_REG
#define CPMDBG_SLEEP_EXIT_SET_REG GPIO->P1_SET_DATA_REG
#define CPMDBG_SLEEP_EXIT_RESET_REG GPIO->P1_RESET_DATA_REG
#define CPMDBG_SLEEP_EXIT_PIN (1 << 6)
// Low clocks (P1[5])
#define CPMDBG_LOWER_CLOCKS_MODE_REG GPIO->P15_MODE_REG
#define CPMDBG_LOWER_CLOCKS_SET_REG GPIO->P1_SET_DATA_REG
#define CPMDBG_LOWER_CLOCKS_RESET_REG GPIO->P1_RESET_DATA_REG
#define CPMDBG_LOWER_CLOCKS_PIN (1 << 5)
// XTAL16M settling (P1[4])
#define CPMDBG_XTAL16M_SETTLED_MODE_REG GPIO->P14_MODE_REG
#define CPMDBG_XTAL16M_SETTLED_SET_REG GPIO->P1_SET_DATA_REG
#define CPMDBG_XTAL16M_SETTLED_RESET_REG GPIO->P1_RESET_DATA_REG
#define CPMDBG_XTAL16M_SETTLED_PIN (1 << 4)
#endif
#if (BLE_USE_TIMING_DEBUG == 0)
// BLE LP & GEN irqs (initial configuration: low)
#define CPMDBG_BLE_IRQ_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_BLE_IRQ_SET_REG *(volatile int *)0x20000000
#define CPMDBG_BLE_IRQ_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_BLE_IRQ_PIN (0)
// BLE sleep prepare (final stage) (initial configuration: low)
#define CPMDBG_BLE_SLEEP_ENTRY_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_BLE_SLEEP_ENTRY_SET_REG *(volatile int *)0x20000000
#define CPMDBG_BLE_SLEEP_ENTRY_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_BLE_SLEEP_ENTRY_PIN (0)
// BLE LP irq signal (diagnostics) (initial configuration: unknown)
#define CPMDBG_BLE_LP_IRQ_MODE_REG *(volatile int *)0x20000000
#else
// BLE LP & GEN ISRs (P1[4])
#define CPMDBG_BLE_IRQ_MODE_REG GPIO->P14_MODE_REG
#define CPMDBG_BLE_IRQ_SET_REG GPIO->P1_SET_DATA_REG
#define CPMDBG_BLE_IRQ_RESET_REG GPIO->P1_RESET_DATA_REG
#define CPMDBG_BLE_IRQ_PIN (1 << 4)
// BLE sleep prepare (final stage) (P1[4])
#define CPMDBG_BLE_SLEEP_ENTRY_MODE_REG GPIO->P14_MODE_REG
#define CPMDBG_BLE_SLEEP_ENTRY_SET_REG GPIO->P1_SET_DATA_REG
#define CPMDBG_BLE_SLEEP_ENTRY_RESET_REG GPIO->P1_RESET_DATA_REG
#define CPMDBG_BLE_SLEEP_ENTRY_PIN (1 << 4)
// BLE LP irq signal (diagnostics) (P2[3])
#define CPMDBG_BLE_LP_IRQ_MODE_REG GPIO->P23_MODE_REG
#endif
#if (BLE_ADAPTER_DEBUG == 0)
#define BLEBDG_ADAPTER_MODE_REG *(volatile int *)0x20000000
#define BLEBDG_ADAPTER_SET_REG *(volatile int *)0x20000000
#define BLEBDG_ADAPTER_RESET_REG *(volatile int *)0x20000000
#define BLEBDG_ADAPTER_PIN (0)
#else
#define BLEBDG_ADAPTER_MODE_REG GPIO->P30_MODE_REG
#define BLEBDG_ADAPTER_SET_REG GPIO->P3_SET_DATA_REG
#define BLEBDG_ADAPTER_RESET_REG GPIO->P3_RESET_DATA_REG
#define BLEBDG_ADAPTER_PIN (1 << 0)
#endif
#if (BLE_RX_EN_DEBUG == 0)
#define BLEBDG_RXEN_MODE_REG *(volatile int *)0x20000000
#define BLEBDG_RXEN_SET_REG *(volatile int *)0x20000000
#define BLEBDG_RXEN_RESET_REG *(volatile int *)0x20000000
#define BLEBDG_RXEN_PIN (0)
#else
#define BLEBDG_RXEN_MODE_REG GPIO->P12_MODE_REG
#define BLEBDG_RXEN_SET_REG GPIO->P1_SET_DATA_REG
#define BLEBDG_RXEN_RESET_REG GPIO->P1_RESET_DATA_REG
#define BLEBDG_RXEN_PIN (1 << 2)
#endif
#if (USB_CHARGER_TIMING_DEBUG == 0)
// CHRG: Inside critical section (initial configuration: low)
#define CHRGDBG_CRITICAL_SECTION_MODE_REG *(volatile int *)0x20000000
#define CHRGDBG_CRITICAL_SECTION_SET_REG *(volatile int *)0x20000000
#define CHRGDBG_CRITICAL_SECTION_RESET_REG *(volatile int *)0x20000000
#define CHRGDBG_CRITICAL_SECTION_PIN (0)
// CHRG: FSM task (initial configuration: low)
#define CHRGDBG_FSM_TASK_MODE_REG *(volatile int *)0x20000000
#define CHRGDBG_FSM_TASK_SET_REG *(volatile int *)0x20000000
#define CHRGDBG_FSM_TASK_RESET_REG *(volatile int *)0x20000000
#define CHRGDBG_FSM_TASK_PIN (0)
// CHRG: Control task (initial configuration: low)
#define CPMDBG_CONTROL_TASK_MODE_REG *(volatile int *)0x20000000
#define CPMDBG_CONTROL_TASK_SET_REG *(volatile int *)0x20000000
#define CPMDBG_CONTROL_TASK_RESET_REG *(volatile int *)0x20000000
#define CPMDBG_CONTROL_TASK_PIN (0)
#else
// CHRG: Inside critical section (P3[2])
#define CHRGDBG_CRITICAL_SECTION_MODE_REG GPIO->P32_MODE_REG
#define CHRGDBG_CRITICAL_SECTION_SET_REG GPIO->P3_SET_DATA_REG
#define CHRGDBG_CRITICAL_SECTION_RESET_REG GPIO->P3_RESET_DATA_REG
#define CHRGDBG_CRITICAL_SECTION_PIN (1 << 2)
// CHRG: FSM task (P3[3])
#define CHRGDBG_FSM_TASK_MODE_REG GPIO->P33_MODE_REG
#define CHRGDBG_FSM_TASK_SET_REG GPIO->P3_SET_DATA_REG
#define CHRGDBG_FSM_TASK_RESET_REG GPIO->P3_RESET_DATA_REG
#define CHRGDBG_FSM_TASK_PIN (1 << 3)
// CHRG: Control task (P3[4])
#define CPMDBG_CONTROL_TASK_MODE_REG GPIO->P34_MODE_REG
#define CPMDBG_CONTROL_TASK_SET_REG GPIO->P3_SET_DATA_REG
#define CPMDBG_CONTROL_TASK_RESET_REG GPIO->P3_RESET_DATA_REG
#define CPMDBG_CONTROL_TASK_PIN (1 << 4)
#endif
#if (CMN_TIMING_DEBUG == 0)
// Common: Inside critical section (initial configuration: low)
#define CMNDBG_CRITICAL_SECTION_MODE_REG *(volatile int *)0x20000000
#define CMNDBG_CRITICAL_SECTION_SET_REG *(volatile int *)0x20000000
#define CMNDBG_CRITICAL_SECTION_RESET_REG *(volatile int *)0x20000000
#define CMNDBG_CRITICAL_SECTION_PIN (0)
#else
// Common: Inside critical section (P4[6])
#define CMNDBG_CRITICAL_SECTION_MODE_REG GPIO->P40_MODE_REG
#define CMNDBG_CRITICAL_SECTION_SET_REG GPIO->P4_SET_DATA_REG
#define CMNDBG_CRITICAL_SECTION_RESET_REG GPIO->P4_RESET_DATA_REG
#define CMNDBG_CRITICAL_SECTION_PIN (1 << 0)
#endif
/* Flash debug configuration
*
*/
#if (FLASH_DEBUG == 0)
// Write page (initial configuration: low)
#define FLASHDBG_PAGE_PROG_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_PIN (0)
// Program page wait loop (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_PIN (0)
// Program page wait loop - pending irq check (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_IRQ_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_IRQ_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_IRQ_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_IRQ_PIN (0)
// Suspend op (initial configuration: low)
#define FLASHDBG_SUSPEND_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_PIN (0)
// Erase sector cmd (initial configuration: low)
#define FLASHDBG_SECTOR_ERASE_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_SECTOR_ERASE_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_SECTOR_ERASE_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_SECTOR_ERASE_PIN (0)
// Notify task (initial configuration: low)
#define FLASHDBG_TASK_NOTIFY_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_TASK_NOTIFY_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_TASK_NOTIFY_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_TASK_NOTIFY_PIN (0)
// Suspend action (low level) (initial configuration: low)
#define FLASHDBG_SUSPEND_ACTION_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_ACTION_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_ACTION_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_ACTION_PIN (0)
// Resume op (initial configuration: low)
#define FLASHDBG_RESUME_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_RESUME_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_RESUME_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_RESUME_PIN (0)
#else
// Write page (initial configuration: low)
#define FLASHDBG_PAGE_PROG_MODE_REG GPIO->P30_MODE_REG
#define FLASHDBG_PAGE_PROG_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_PAGE_PROG_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_PAGE_PROG_PIN (1 << 0)
// Program page wait loop (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_MODE_REG GPIO->P31_MODE_REG
#define FLASHDBG_PAGE_PROG_WL_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_PIN (1 << 1)
// Program page wait loop - pending irq check (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_IRQ_MODE_REG GPIO->P32_MODE_REG
#define FLASHDBG_PAGE_PROG_WL_IRQ_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_IRQ_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_IRQ_PIN (1 << 2)
// Suspend op (initial configuration: low)
#define FLASHDBG_SUSPEND_MODE_REG GPIO->P33_MODE_REG
#define FLASHDBG_SUSPEND_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_SUSPEND_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_SUSPEND_PIN (1 << 3)
// Erase sector cmd (initial configuration: low)
#define FLASHDBG_SECTOR_ERASE_MODE_REG GPIO->P34_MODE_REG
#define FLASHDBG_SECTOR_ERASE_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_SECTOR_ERASE_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_SECTOR_ERASE_PIN (1 << 4)
// Notify task (initial configuration: low)
#define FLASHDBG_TASK_NOTIFY_MODE_REG GPIO->P35_MODE_REG
#define FLASHDBG_TASK_NOTIFY_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_TASK_NOTIFY_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_TASK_NOTIFY_PIN (1 << 5)
// Suspend action (low level) (initial configuration: low)
#define FLASHDBG_SUSPEND_ACTION_MODE_REG GPIO->P36_MODE_REG
#define FLASHDBG_SUSPEND_ACTION_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_SUSPEND_ACTION_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_SUSPEND_ACTION_PIN (1 << 6)
// Resume op (initial configuration: low)
#define FLASHDBG_RESUME_MODE_REG GPIO->P37_MODE_REG
#define FLASHDBG_RESUME_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_RESUME_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_RESUME_PIN (1 << 7)
#endif
/* Enables the logging of stack (RW) heap memories usage.
*
* The feature shall only be enabled in development/debug mode
*/
#ifndef dg_configLOG_BLE_STACK_MEM_USAGE
#define dg_configLOG_BLE_STACK_MEM_USAGE (0)
#endif
/**
* \brief Enables BLE diagnostic signals.
*
* There are 5 (4 plus the COEX mode, see next table) diagnostic signal configurations that
* user can choose from. To enable a specific configuration, simply define
* dg_configBLE_DIAGN_CONFIG with the perspective configuration ID. Configuration ID 0 disables
* BLE diagnostics.
*
* ------------------------------------------------------------------------------------------------------
* | Signal | Pin | Config 1 | Config 2 | Config 3 | Config 4 |
* ------------------------------------------------------------------------------------------------------
* | ble_diag0 | P2_0 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag1 | P2_1 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag2 | P2_2 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag3 | P1_0 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag4 | P1_1 | ble_slp_irq | radcntl_txen | radcntl_txen | radcntl_txen |
* ------------------------------------------------------------------------------------------------------
* | ble_diag5 | P1_2 | ble_cscnt_irq | radcntl_rxen | rf_tx_en | radcntl_rxen |
* ------------------------------------------------------------------------------------------------------
* | ble_diag6 | P1_3 | ble_finetgtim_irq | rf_rx_en | rf_tx_data | ble_rx_irq |
* ------------------------------------------------------------------------------------------------------
* | ble_diag7 | P2_3 | ble_event_irq | rf_rx_data | rf_tx_data_valid | ble_event_irq |
* ------------------------------------------------------------------------------------------------------
*
* Coex Mode Diagnostics: The COEX interface multiplexes its diagnostic pins on top of BLE
* diagnostics when option dg_configCOEX_ENABLE_DIAGS is set to 1. However, diagnostic signals
* ble_diag0 and ble_diag1 are unused by the COEX diagnostics and can be used for BLE. More
* specifically, Config 5 enables the following configuration, that can be used simultaneously
* with COEX diagnostics (dg_configCOEX_ENABLE_DIAGS == 1):
*
* ----------------------------------------------
* | Signal | Pin | Config 5 |
* ----------------------------------------------
* | ble_diag0 | P3_0 | radcntl_txen |
* ----------------------------------------------
* | ble_diag1 | P3_1 | radcntl_rxen |
* ----------------------------------------------
*
*/
#ifndef dg_configBLE_DIAGN_CONFIG
#define dg_configBLE_DIAGN_CONFIG (0)
#endif
#endif /* BSP_DEBUG_H_ */
/**
\}
\}
\}
*/
File diff suppressed because it is too large Load Diff
@@ -1,162 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup BSP_CONFIG
* \{
* \addtogroup BSP_CONFIG_DEFINITIONS
*
* \brief Doxygen documentation is not yet available for this module.
* Please check the source code file(s)
*
*\{
*/
/**
****************************************************************************************
*
* @file bsp_definitions.h
*
* @brief Board Support Package. System Configuration file definitions.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 BSP_DEFINITIONS_H_
#define BSP_DEFINITIONS_H_
/* ------------------------------------ Generic definitions ------------------------------------- */
#define LP_CLK_32000 0
#define LP_CLK_32768 1
#define LP_CLK_RCX 2
#define LP_CLK_ANY 3
#define LP_CLK_IS_ANALOG 0
#define LP_CLK_IS_DIGITAL 1
#define MODE_IS_MIRRORED 0
#define MODE_IS_CACHED 1
#define MODE_IS_RAM MODE_IS_MIRRORED
#define NON_VOLATILE_IS_OTP 0 // Code is in OTP
#define NON_VOLATILE_IS_FLASH 1 // Code is in QSPI Flash
#define NON_VOLATILE_IS_NONE 2 // Debug mode! Code is in RAM!
#define EXT_CRYSTAL_IS_16M 0
#define EXT_CRYSTAL_IS_32M 1
#define DEVELOPMENT_MODE 0 // Code is built for debugging
#define PRODUCTION_MODE 1 // Code is built for production
#define FLASH_IS_NOT_CONNECTED 0
#define FLASH_CONNECTED_TO_1V8 1
#define FLASH_CONNECTED_TO_1V8P 2
#define BATTERY_TYPE_2xNIMH 0
#define BATTERY_TYPE_3xNIMH 1
#define BATTERY_TYPE_LICOO2 2 // 2.5V discharge voltage, 4.20V charge voltage
#define BATTERY_TYPE_LIMN2O4 3 // 2.5V discharge voltage, 4.20V charge voltage
#define BATTERY_TYPE_NMC 4 // 2.5V discharge voltage, 4.20V charge voltage
#define BATTERY_TYPE_LIFEPO4 5 // 2.5V discharge voltage, 3.65V charge voltage
#define BATTERY_TYPE_LINICOAIO2 6 // 3.0V discharge voltage, 4.20V charge voltage
#define BATTERY_TYPE_CUSTOM 7
#define BATTERY_TYPE_NO_RECHARGE 8
#define BATTERY_TYPE_NO_BATTERY 9
#define BATTERY_TYPE_2xNIMH_ADC_VOLTAGE (2785)
#define BATTERY_TYPE_3xNIMH_ADC_VOLTAGE (4013)
#define BATTERY_TYPE_LICOO2_ADC_VOLTAGE (3440)
#define BATTERY_TYPE_LIMN2O4_ADC_VOLTAGE (3440)
#define BATTERY_TYPE_NMC_ADC_VOLTAGE (3440)
#define BATTERY_TYPE_LIFEPO4_ADC_VOLTAGE (2989)
#define BATTERY_TYPE_LINICOAIO2_ADC_VOLTAGE (3440)
/*
* The supported chip revisions.
*/
#define BLACK_ORCA_IC_REV_AUTO (-1)
#define BLACK_ORCA_IC_REV_A 0
#define BLACK_ORCA_IC_REV_B 1
/*
* The supported chip steppings.
*/
#define BLACK_ORCA_IC_STEP_AUTO (-1)
#define BLACK_ORCA_IC_STEP_A 0
#define BLACK_ORCA_IC_STEP_B 1
#define BLACK_ORCA_IC_STEP_C 2
#define BLACK_ORCA_IC_STEP_D 3
#define BLACK_ORCA_IC_STEP_E 7
/*
* Legacy DK motherboards, which are not supported by the SDK.
* The definitions exist just so that we don't break compilation of old projects.
*/
#define BLACK_ORCA_MB_REV_A 0
#define BLACK_ORCA_MB_REV_B 1
/*
* The supported DK motherboards.
*/
#define BLACK_ORCA_MB_REV_D 2
/*
* The cache associativity options.
*/
#define CACHE_ASSOC_AS_IS (-1) /// leave as set by the ROM booter
#define CACHE_ASSOC_DIRECT_MAP 0 /// direct-mapped
#define CACHE_ASSOC_2_WAY 1 /// 2-way set associative
#define CACHE_ASSOC_4_WAY 2 /// 4-way set associative
/*
* The cache line size options.
*/
#define CACHE_LINESZ_AS_IS (-1) /// leave as set by the ROM booter
#define CACHE_LINESZ_8_BYTES 0 /// 8 bytes
#define CACHE_LINESZ_16_BYTES 1 /// 16 bytes
#define CACHE_LINESZ_32_BYTES 2 /// 32 bytes
/*
* The supported RF Front-End Modules
*/
#define FEM_NOFEM 0
#define FEM_SKY66112_11 1
/*
* The BLE event notification user hook types
*/
#define BLE_EVENT_NOTIF_USER_ISR 0 /// User-defined hooks directly from ISR context
#define BLE_EVENT_NOTIF_USER_TASK 1 /// Notification of the user task, using task notifications.
#endif /* BSP_DEFINITIONS_H_ */
/**
\}
\}
\}
*/
-149
View File
@@ -1,149 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup BSP_CONFIG
* \{
* \addtogroup RF_FEM
*
* \brief RF Front-End module confguration
*
*\{
*/
/**
***************************************************************************************
*
* @file bsp_fem.h
*
* @brief Board Support Package. RF Front-End Module definitions.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 BSP_FEM_H_
#define BSP_FEM_H_
/* ------------------------------- RF FEM driver (SKY66112-11) configuration settings ----------- */
#ifdef dg_configFEM_DLG_REF_BOARD
#define dg_configFEM FEM_SKY66112_11
#if dg_configPOWER_1V8P == 0
#warning Setting dg_configPOWER_1V8P to 1 for FEM to work
#undef dg_configPOWER_1V8P
#define dg_configPOWER_1V8P 1
#endif
#define dg_configFEM_SKY66112_11_FEM_BIAS_V18P
#define dg_configFEM_SKY66112_11_FEM_BIAS2_V18
#ifndef dg_configFEM_SKY66112_11_CSD_PORT
#define dg_configFEM_SKY66112_11_CSD_PORT HW_GPIO_PORT_4
#endif
#ifndef dg_configFEM_SKY66112_11_CSD_PIN
#define dg_configFEM_SKY66112_11_CSD_PIN HW_GPIO_PIN_3
#endif
#ifndef dg_configFEM_SKY66112_11_CPS_PORT
#define dg_configFEM_SKY66112_11_CPS_PORT HW_GPIO_PORT_4
#endif
#ifndef dg_configFEM_SKY66112_11_CPS_PIN
#define dg_configFEM_SKY66112_11_CPS_PIN HW_GPIO_PIN_6
#endif
#ifndef dg_configFEM_SKY66112_11_CRX_PORT
#define dg_configFEM_SKY66112_11_CRX_PORT HW_GPIO_PORT_4
#endif
#ifndef dg_configFEM_SKY66112_11_CRX_PIN
#define dg_configFEM_SKY66112_11_CRX_PIN HW_GPIO_PIN_2
#endif
#ifndef dg_configFEM_SKY66112_11_CTX_PORT
#define dg_configFEM_SKY66112_11_CTX_PORT HW_GPIO_PORT_4
#endif
#ifndef dg_configFEM_SKY66112_11_CTX_PIN
#define dg_configFEM_SKY66112_11_CTX_PIN HW_GPIO_PIN_5
#endif
#ifndef dg_configFEM_SKY66112_11_CHL_PORT
#define dg_configFEM_SKY66112_11_CHL_PORT HW_GPIO_PORT_4
#endif
#ifndef dg_configFEM_SKY66112_11_CHL_PIN
#define dg_configFEM_SKY66112_11_CHL_PIN HW_GPIO_PIN_4
#endif
#ifndef dg_configFEM_SKY66112_11_ANTSEL_PORT
#define dg_configFEM_SKY66112_11_ANTSEL_PORT HW_GPIO_PORT_4
#endif
#ifndef dg_configFEM_SKY66112_11_ANTSEL_PIN
#define dg_configFEM_SKY66112_11_ANTSEL_PIN HW_GPIO_PIN_0
#endif
#endif /* dg_configFEM_DLG_REF_BOARD */
#ifndef dg_configFEM
#define dg_configFEM FEM_NOFEM
#endif
#if dg_configFEM == FEM_SKY66112_11
#ifndef dg_configFEM_SKY66112_11_CSD_USE_DCF
#define dg_configFEM_SKY66112_11_CSD_USE_DCF 1
#endif
#ifndef dg_configFEM_SKY66112_11_TXSET_DCF
#define dg_configFEM_SKY66112_11_TXSET_DCF 47
#endif
#ifndef dg_configFEM_SKY66112_11_TXRESET_DCF
#define dg_configFEM_SKY66112_11_TXRESET_DCF 0
#endif
#ifndef dg_configFEM_SKY66112_11_RXSET_DCF
#define dg_configFEM_SKY66112_11_RXSET_DCF 1
#endif
#ifndef dg_configFEM_SKY66112_11_RXRESET_DCF
#define dg_configFEM_SKY66112_11_RXRESET_DCF 20
#endif
#endif /* dg_configFEM == FEM_SKY66112_11 */
#endif /* BSP_FEM_H_ */
/**
\}
\}
\}
*/
-43
View File
@@ -1,43 +0,0 @@
/**************************************************************************//**
* @file ARMCM0.h
* @brief CMSIS Core Peripheral Access Layer Header File for
* ARMCM0 Device Series
* @version V3.00
* @date 16. October 2015
******************************************************************************/
/* Copyright (c) 2011 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 ARMCM0_H
#define ARMCM0_H
#include <core_cm0.h> /* Cortex-M0 processor and core peripherals */
#include "system_ARMCM0.h" /* System Header */
#endif /* ARMCM0_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-798
View File
@@ -1,798 +0,0 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex_M0
@{
*/
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000U
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
#include "sdk_defs.h" /* Declares IRQn_Type */
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
-87
View File
@@ -1,87 +0,0 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */
-87
View File
@@ -1,87 +0,0 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */
-151
View File
@@ -1,151 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup INTERRUPTS
*
* \brief Interrupt priority configuration
*
* \{
*/
/**
*****************************************************************************************
*
* @file interrupts.h
*
* @brief Interrupt priority configuration
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 INTERRUPTS_H_
#define INTERRUPTS_H_
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Setup interrupt priorities
*
* When CPU is reset all interrupts have some priority setup.
* Reset -3
* NMI -2
* HardFault -1
* All other interrupts have configurable priority that is set to 0.
* If some interrupts should have priority other then default, this function should be called.
* Argument \p prios can specify only those interrupts that need to have value other than default.
* For memory efficiency table with priorities for each interrupt consist of interrupt priority
* tag PRIORITY_x followed by interrupts that should have this priority, interrupts names are from
* enum IRQn_Type.
*
* \note If interrupt priorities do not need to be changed dynamically at runtime, best way to
* specify static configuration is to create table named __dialog_interrupt_priorities that will
* be used automatically at startup.
*
* Most convenient way to prepare such table is to use macros like in example below:
*
* \code{.c}
* INTERRUPT_PRIORITY_CONFIG_START(__dialog_interrupt_priorities)
* PRIORITY_0, // Start interrupts with priority 0 (highest)
* SVCall_IRQn,
* PendSV_IRQn,
* SysTick_IRQn,
* PRIORITY_1, // Start interrupts with priority 1
* BLE_WAKEUP_LP_IRQn,
* BLE_GEN_IRQn,
* FTDF_WAKEUP_IRQn,
* FTDF_GEN_IRQn,
* PRIORITY_2,
* SRC_IN_IRQn,
* SRC_OUT_IRQn,
* PRIORITY_3,
* UART_IRQn,
* UART2_IRQn,
* INTERRUPT_PRIORITY_CONFIG_END
* \endcode
*
* Table __dialog_interrupt_priorities can now be used to call this function.
* Table can specify all interrupts or only those that need to be changed.
*
* \param [in] prios table with interrupts and priorities to setup
*
*/
void set_interrupt_priorities(const int8_t prios[]);
/**
* \brief Check whether running in interrupt context.
*
* \return true if the CPU is serving an interrupt.
*/
static inline bool in_interrupt(void)
{
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0;
}
/**
* \brief Default interrupt priorities table.
*
*/
extern const int8_t __dialog_interrupt_priorities[];
#if (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A) && (dg_configUSE_AUTO_CHIP_DETECTION != 1)
#define LAST_IRQn PLL_LOCK_IRQn
#else
#define LAST_IRQn RESERVED31_IRQn
#endif
/*
* Following macros allow easy way to build table with interrupt priorities.
* See example in set_interrupt_priorities function description.
*/
#define INTERRUPT_PRIORITY_CONFIG_START(name) const int8_t name[] = {
#define PRIORITY_0 (LAST_IRQn + 1)
#define PRIORITY_1 (LAST_IRQn + 2)
#define PRIORITY_2 (LAST_IRQn + 3)
#define PRIORITY_3 (LAST_IRQn + 4)
#define PRIORITY_TABLE_END (LAST_IRQn + 5)
#define INTERRUPT_PRIORITY_CONFIG_END PRIORITY_TABLE_END };
#ifdef __cplusplus
}
#endif
#endif /* INTERRUPTS_H_ */
/**
* \}
* \}
* \}
*/
-812
View File
@@ -1,812 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup PLATFORM
*
* \brief Platform definitions
*
* \{
*/
/**
*****************************************************************************************
*
* @file sdk_defs.h
*
* @brief Central include header file with platform definitions.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 __SDK_DEFS_H__
#define __SDK_DEFS_H__
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
# define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
/* assert gcc version is at least 4.9.3 */
# if GCC_VERSION < 40903
# error "Please use gcc version 4.9.3 or newer!"
# endif
#endif
#if (dg_configUSE_AUTO_CHIP_DETECTION == 1)
/* use a register description that is generic enough for our needs */
# include "DA14680AE.h"
#else
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
# if dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_E
# include "DA14680AE.h"
# else
# error "Unknown chip stepping for revision A -- check the value of dg_configBLACK_ORCA_IC_STEP"
# endif
#elif dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B
# if dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_B
# include "DA14680BB.h"
# else
# error "Unknown chip stepping for revision B -- check the value of dg_configBLACK_ORCA_IC_STEP"
# endif
#else
# error "Unknown chip revision -- check the value of dg_configBLACK_ORCA_IC_REV"
#endif
#endif
#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */
#include "system_DA14680.h" /* DA14680AA System */
/************************
* Memory map
************************/
/**
* \brief Remapped device base address.
*/
#define MEMORY_REMAPPED_BASE 0x00000000UL
#define MEMORY_REMAPPED_END 0x04000000UL
/**
* \brief Remapped device memory size (64MiB).
*/
#define MEMORY_REMAPPED_SIZE (MEMORY_REMAPPED_END - MEMORY_REMAPPED_BASE)
/**
* \brief ROM base address.
*/
#define MEMORY_ROM_BASE 0x07F00000UL
#define MEMORY_ROM_END 0x07F40000UL
/**
* \brief ROM memory size (256KiB).
*/
#define MEMORY_ROM_SIZE (MEMORY_ROM_END - MEMORY_ROM_BASE)
/**
* \brief OTP Controller base address.
*/
#define MEMORY_OTPC_BASE 0x07F40000UL
#define MEMORY_OTPC_END 0x07F80000UL
/**
* \brief OTP memory base address.
*/
#define MEMORY_OTP_BASE 0x07F80000UL
#define MEMORY_OTP_END 0x07FC0000UL
/**
* \brief OTP memory size (256KiB).
*/
#define MEMORY_OTP_SIZE (MEMORY_OTP_END - MEMORY_OTP_BASE)
/**
* \brief SYSTEM RAM base address.
*/
#define MEMORY_SYSRAM_BASE 0x07FC0000UL
#define MEMORY_SYSRAM_END 0x07FE0000UL
/**
* \brief SYSTEM RAM size (128KiB).
*/
#define MEMORY_SYSRAM_SIZE (MEMORY_SYSRAM_END - MEMORY_SYSRAM_BASE)
/**
* \brief CACHE RAM base address.
*/
#define MEMORY_CACHERAM_BASE 0x07FE0000UL
#define MEMORY_CACHERAM_END 0x08000000UL
/**
* \brief CACHE RAM size (128KiB).
*/
#define MEMORY_CACHERAM_SIZE (MEMORY_CACHERAM_END - MEMORY_CACHERAM_BASE)
/**
* \brief QSPI Flash base address.
*/
#define MEMORY_QSPIF_BASE 0x08000000UL
#define MEMORY_QSPIF_END 0x0BF00000UL
/**
* \brief QSPI Flash memory size (63MiB).
*/
#define MEMORY_QSPIF_SIZE (MEMORY_QSPIF_END - MEMORY_QSPIF_BASE)
/**
* \brief QSPI Controller base address.
*/
#define MEMORY_QSPIC_BASE 0x0C000000UL
#define MEMORY_QSPIC_END 0x0C100000UL
/**
* \brief ECC engine microcode base address.
*/
#define MEMORY_ECC_UCODE_BASE 0x40030000UL
/**
* \brief TRNG FIFO address
*/
#define MEMORY_TRNG_FIFO 0x40040000UL
#define WITHIN_RANGE(_a, _s, _e) (((uint32_t)(_a) >= (uint32_t)(_s)) && ((uint32_t)(_a) < (uint32_t)(_e)))
/**
* \brief Address is in the remapped memory region
*/
#define IS_REMAPPED_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_REMAPPED_BASE, MEMORY_REMAPPED_END)
/**
* \brief Address is in the ROM region
*/
#define IS_ROM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_ROM_BASE, MEMORY_ROM_END)
/**
* \brief Address is in the OTP memory region
*/
#define IS_OTP_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_OTP_BASE, MEMORY_OTP_END)
/**
* \brief Address is in the OTP Controller memory region
*/
#define IS_OTPC_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_OTPC_BASE, MEMORY_OTPC_END)
/**
* \brief Address is in the SYSTEM RAM region
*/
#define IS_SYSRAM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_SYSRAM_BASE, MEMORY_SYSRAM_END)
/**
* \brief Address is in the CACHE RAM region
*/
#define IS_CACHERAM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_CACHERAM_BASE, MEMORY_CACHERAM_END)
/**
* \brief Address is in the QSPI Flash memory region
*/
#define IS_QSPIF_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_QSPIF_BASE, MEMORY_QSPIF_END)
/**
* \brief Address is in the QSPI Controller memory region
*/
#define IS_QSPIC_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_QSPIC_BASE, MEMORY_QSPIC_END)
#define _BLACK_ORCA_IC_VERSION(revision, stepping) \
(((revision) << 8) | (stepping))
/**
* \brief Convenience macro to create the full chip version from revision and stepping.
* It takes letters as arguments.
*/
#define BLACK_ORCA_IC_VERSION(revision, stepping) \
_BLACK_ORCA_IC_VERSION(BLACK_ORCA_IC_REV_##revision, \
BLACK_ORCA_IC_STEP_##stepping)
/**
* \brief The chip version that we compile for.
*/
#define BLACK_ORCA_TARGET_IC \
_BLACK_ORCA_IC_VERSION(dg_configBLACK_ORCA_IC_REV, dg_configBLACK_ORCA_IC_STEP)
/**
* \brief Zero-initialized data retained memory attribute
*/
#define __RETAINED __attribute__((section("retention_mem_zi"))) // RetRAM0
#define __RETAINED_1 __attribute__((section("retention_mem_1_zi"))) // RetRAM1
/**
* \brief Initialized data retained memory attribute
*/
#define __RETAINED_RW __attribute__((section("retention_mem_init")))
/**
* \brief Uninitialized data retained memory attribute
*/
#define __RETAINED_UNINIT __attribute__((section("retention_mem_uninit")))
/**
* \brief Constant data retained memory attribute
*/
#define __RETAINED_CONST_INIT __attribute__((section("retention_mem_const")))
/**
* \brief Text retained memory attribute
*/
#if ((dg_configCODE_LOCATION == NON_VOLATILE_IS_FLASH) && (dg_configEXEC_MODE == MODE_IS_CACHED))
#define __RETAINED_CODE __attribute__((section("text_retained"))) __attribute__((noinline)) __attribute__((optimize ("no-tree-switch-conversion")))
#else
#define __RETAINED_CODE
#endif
/**
* \brief Attribute to tell the compiler to consider a symbol as used
*/
#define __USED __attribute__((used))
/**
* \brief Attribute to tell the compiler to consider a symbol as externally visible (for LTO)
*/
#define __LTO_EXT __attribute__((externally_visible))
extern uint32_t black_orca_chip_version;
#define CHIP_IS_AE (black_orca_chip_version == BLACK_ORCA_IC_VERSION(A, E))
#define CHIP_IS_BB (black_orca_chip_version == BLACK_ORCA_IC_VERSION(B, B))
/**
* \brief Get the chip version of the system, at runtime.
*/
__STATIC_INLINE uint32_t black_orca_get_chip_version(void)
{
uint32_t rev = CHIP_VERSION->CHIP_REVISION_REG - 'A';
uint32_t step = CHIP_VERSION->CHIP_TEST1_REG;
return _BLACK_ORCA_IC_VERSION(rev, step);
}
// Forward declaration
__RETAINED_CODE void hw_cpm_assert_trigger_gpio(void);
/**
* \brief Assert as warning macro
*
* \note Active only while in development mode
*/
#define ASSERT_WARNING(a) \
{ \
if (!(a)) { \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
hw_cpm_assert_trigger_gpio(); \
do {} while(1); \
} \
} \
}
/**
* \brief Assert as error macro
*
*/
#define ASSERT_ERROR(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
hw_cpm_assert_trigger_gpio(); \
do {} while(1); \
} \
} \
else { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
__asm volatile ( " bkpt 2 " ); \
} \
} \
}
/**
* \brief Assert as warning macro when the system is still uninitialized
*
* \note Active only while in development mode. The SW cursor is not activated.
*/
#define ASSERT_WARNING_UNINIT(a) \
{ \
if (!(a)) { \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
do {} while(1); \
} \
} \
}
/**
* \brief Assert as error macro when the system is still uninitialized
*
* \note The SW cursor is not activated.
*/
#define ASSERT_ERROR_UNINIT(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
do {} while(1); \
} \
} \
else { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
__asm volatile ( " bkpt 2 " ); \
} \
} \
}
/**
* \brief Macro to disable all interrupts
*
* This macro must always be used with GLOBAL_INT_RESTORE(). E.g.
*
* \code{.c}
* GLOBAL_INT_DISABLE();
* ... code to be executed with interrupts disabled ...
* GLOBAL_INT_RESTORE();
* \endcode
*
* \sa GLOBAL_INT_RESTORE
*/
#define GLOBAL_INT_DISABLE() \
do { \
unsigned int __l_irq_rest; \
__asm volatile ("mrs %0, primask \n\t" \
"mov r1, $1 \n\t" \
"msr primask, r1 \n\t" \
: "=r" (__l_irq_rest) \
: \
: "r1" \
); \
DBG_CONFIGURE_HIGH(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION);
/**
* \brief Macro to restore all interrupts
*
* This macro must always be used after GLOBAL_INT_DISABLE(). E.g.
*
* \code{.c}
* GLOBAL_INT_DISABLE();
* ... code to be executed with interrupts disabled ...
* GLOBAL_INT_RESTORE();
* \endcode
*
* \sa GLOBAL_INT_DISABLE
*/
#define GLOBAL_INT_RESTORE() \
if (__l_irq_rest == 0) { \
DBG_CONFIGURE_LOW(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION); \
} \
__asm volatile ("msr primask, %0 \n\t" \
: \
: "r" (__l_irq_rest) \
: \
); \
} while(0)
#define containingoffset(address, type, field) ((type*)((uint8*)(address)-(size_t)(&((type*)0)->field)))
/**
* \brief Macro the minimum of two values
*
* \param[in] a First value
* \param[in] b Second value
*/
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
/**
* \brief Macro the maximum of two values
*
* \param[in] a First value
* \param[in] b Second value
*/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
/**
* \brief Macro to swap the bytes of a 16-bit variable
*
* \param[in] a The 16-bit variable
*/
#if defined(__GNUC__)
#define SWAP16(a) __builtin_bswap16(a)
#else
#define SWAP16(a) ((a<<8) | (a>>8))
#endif
/**
* \brief Macro to swap the bytes of a 32-bit variable
*
* \param[in] a The 32-bit variable
*/
#if defined(__GNUC__)
#define SWAP32(a) __builtin_bswap32(a)
#else
#define SWAP32(a) ((a>>24 & 0xff) | (a>>8 & 0xff00) | (a<<8 & 0xff0000) | (a<<24 & 0xff000000))
#endif
#if defined(__GNUC__)
#define DEPRECATED __attribute__ ((deprecated))
#else
#warning Deprecated macro must be implemented for this compiler
#define DEPRECATED
#endif
#if defined(__GNUC__)
#define DEPRECATED_MSG(msg) __attribute__ ((deprecated(msg)))
#else
#warning Deprecated macro must be implemented for this compiler
#define DEPRECATED_MSG(msg)
#endif
/* The following exist in ROM code */
void __aeabi_memcpy(void *dest, const void *src, size_t n);
void __aeabi_memmove(void *dest, const void *src, size_t n);
void __aeabi_memset(void *dest, size_t n, int c);
/**
* \brief Optimized memcpy
*/
#define OPT_MEMCPY __aeabi_memcpy
/**
* \brief Optimized memmove
*/
#define OPT_MEMMOVE __aeabi_memmove
/**
* \brief Optimized memset
*/
#define OPT_MEMSET(s, c, n) __aeabi_memset(s, n, c)
/**
* \brief Access register field mask.
*
* Returns a register field mask (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->SYS_STAT_REG;
*
* if (tmp & REG_MSK(CRG_TOP, SYS_STAT_REG, XTAL16_TRIM_READY)) {
* ...
* \endcode
*/
#define REG_MSK(base, reg, field) \
(base ## _ ## reg ## _ ## field ## _Msk)
/**
* \brief Access register field position.
*
* Returns a register field position (aimed to be used with local variables).
*/
#define REG_POS(base, reg, field) \
(base ## _ ## reg ## _ ## field ## _Pos)
/**
* \brief Access register field value.
*
* Returns a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
* int counter;
* tmp = CRG_TOP->TRIM_CTRL_REG;
* counter = REG_GET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp);
* ...
* \endcode
*/
#define REG_GET_FIELD(base, reg, field, var) \
((var & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Set register field value.
*
* Sets a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->TRIM_CTRL_REG;
* REG_SET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp, 10);
* REG_SET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_TRIM_SELECT, tmp, 2);
* CRG_TOP->TRIM_CTRL_REG = tmp;
* ...
* \endcode
*/
#define REG_SET_FIELD(base, reg, field, var, val) \
var = ((var & ~((base ## _ ## reg ## _ ## field ## _Msk))) | \
(((val) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
/**
* \brief Clear register field value.
*
* Clears a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->TRIM_CTRL_REG;
* REG_CLR_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp);
* REG_CLR_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_TRIM_SELECT, tmp);
* CRG_TOP->TRIM_CTRL_REG = tmp;
* ...
* \endcode
*/
#define REG_CLR_FIELD(base, reg, field, var) \
var &= ~(base ## _ ## reg ## _ ## field ## _Msk)
/**
* \brief Get the address of a register value by index (provided a register interval)
*
* \note The register interval should be an exact multiple of the register's base size. For example,
* if the register size is 32-bit, then the interval should be 0x4, 0x8, etc. Otherwise, the result
* will be undefined. The interval value must be in bytes. The index value (0,1,2...) is multiplied by
* the interval value (in bytes) to find the actual offset of the register.
*
* Returns a register address value by index
*/
#define REG_GET_ADDR_INDEXED(base, reg, interval, index) \
((&base->reg) + (((intptr_t) index) * ((interval) / sizeof(base->reg))))
/**
* \brief Return the value of a register field by index (provided a register interval).
*
* e.g.
* \code
* uint16_t val;
* uint16_t index = 2
*
* val = REG_GETF_INDEXED(FTDF, FTDF_LONG_ADDR_0_0_REG, REG_EXP_SA_L, 0x10, index)
*
* ...
* \endcode
*
* \note The register interval should be an exact multiple of the register's base size. For example,
* if the register size is 32-bit, then the interval should be 0x4, 0x8, etc. Otherwise, the result
* will be undefined. The interval value must be in bytes. The index value (0,1,2...) is multiplied by
* the interval value (in bytes) to find the actual offset of the register.
*
*/
#define REG_GETF_INDEXED(base, reg, field, interval, index) \
(((*REG_GET_ADDR_INDEXED(base, reg, interval, index)) & \
(base ## _ ## reg ## _ ## field ## _Msk)) >> (base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Return the value of a register field.
*
* e.g.
* \code
* uint16_t val;
*
* val = REG_GETF(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N);
* ...
* \endcode
*/
#define REG_GETF(base, reg, field) \
(((base->reg) & (base##_##reg##_##field##_Msk)) >> (base##_##reg##_##field##_Pos))
/**
* \brief Set the value of a register field.
*
* e.g.
* \code
*
* REG_SETF(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, new_value);
* ...
* \endcode
*/
#define REG_SETF(base, reg, field, new_val) \
base->reg = ((base->reg & ~(base##_##reg##_##field##_Msk)) | \
((base##_##reg##_##field##_Msk) & ((new_val) << (base##_##reg##_##field##_Pos))))
/**
* \brief Set a bit of a register.
*
* e.g.
* \code
*
* REG_SET_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
* ...
* \endcode
*/
#define REG_SET_BIT(base, reg, field) \
do { \
base->reg |= (1 << (base##_##reg##_##field##_Pos)); \
} while (0)
/**
* \brief Clear a bit of a register.
*
* e.g.
* \code
*
* REG_CLR_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
* ...
* \endcode
*/
#define REG_CLR_BIT(base, reg, field) \
do { \
base->reg &= ~(base##_##reg##_##field##_Msk); \
} while (0)
/**
* \brief Sets register bits, indicated by the mask, to a value.
*
* e.g.
* \code
* REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_5_REG, 0xFF00, 0x1818);
* \endcode
*/
#define REG_SET_MASKED(base, reg, mask, value) \
do { \
base->reg = (base->reg & ~(mask)) | ((value) & (mask)); \
} while (0)
/**
* \brief Sets 16-bit wide register bits, indicated by the field, to a value v.
*/
#define BITS16(base, reg, field, v) \
((uint16) (((uint16) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
/**
* \brief Sets 32-bit wide register bits, indicated by the field, to a value v.
*/
#define BITS32(base, reg, field, v) \
((uint32) (((uint32) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
/**
* \brief Reads 16-bit wide register bits, indicated by the field, to a variable v.
*/
#define GETBITS16(base, reg, v, field) \
((uint16) (((uint16) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Reads 32-bit wide register bits, indicated by the field, to a variable v.
*/
#define GETBITS32(base, reg, v, field) \
((uint32) (((uint32) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Macro to enable the debugger
*
*/
#define ENABLE_DEBUGGER \
do { \
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
} while(0)
/**
* \brief Macro to disable the debugger
*
*/
#define DISABLE_DEBUGGER \
do { \
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
} while(0)
/**
* \brief Macro to cause a software reset
*
*/
#define SWRESET \
do { \
REG_SET_BIT(GPREG, DEBUG_REG, SW_RESET); \
} while (0)
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
typedef unsigned char uint8; // 8 bits
typedef char int8; // 8 bits
typedef unsigned short uint16; // 16 bits
typedef short int16; // 16 bits
typedef unsigned long uint32; // 32 bits
typedef long int32; // 32 bits
typedef unsigned long long uint64; // 64 bits
typedef long long int64; // 64 bits
/* See also "Data Types" on pag. 21 of the (Doulos) Cortex-M0 / SoC 1.0 training documentation. */
typedef unsigned char BYTE; // 8 bits = Byte
typedef unsigned short HWORD; // 16 bits = Halfword
typedef unsigned long WORD; // 32 bits = Word
typedef long long DWORD; // 64 bits = Doubleword
#ifdef __cplusplus
}
#endif
#endif /* __SDK_DEFS_H__ */
/**
* \}
* \}
* \}
*/
-118
View File
@@ -1,118 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup SUOTA
*
* \brief SUOTA structure definitions
*
* \{
*/
/**
*****************************************************************************************
*
* @file suota.h
*
* @brief SUOTA structure definitions
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 SUOTA_H_
#define SUOTA_H_
#include <stdint.h>
#define SUOTA_VERSION_1_1 11
#define SUOTA_VERSION_1_2 12
#define SUOTA_VERSION_1_3 13
#ifndef SUOTA_VERSION
#define SUOTA_VERSION SUOTA_VERSION_1_3
#endif
#if SUOTA_PSM && (SUOTA_VERSION < SUOTA_VERSION_1_2)
# error "SUOTA_PSM is only applicable to SUOTA_VERSION >= 1.2"
#endif
/**
* \struct suota_1_1_product_header_t;
*
* \brief SUOTA 1.1 product header as defined by Dialog SUOTA specification.
*
* \note the same header is used for any SUOTA version newer than 1.1
*
*/
typedef struct {
uint8_t signature[2];
uint16_t flags;
uint32_t current_image_location;
uint32_t update_image_location;
uint8_t reserved[8];
} __attribute__((packed)) suota_1_1_product_header_t;
#define SUOTA_1_1_PRODUCT_HEADER_SIGNATURE_B1 0x70
#define SUOTA_1_1_PRODUCT_HEADER_SIGNATURE_B2 0x62
/**
* \struct suota_1_1_image_header_t
*
* \brief SUOTA 1.1 image header as defined by Dialog SUOTA specification.
*
* \note the same header is used for any SUOTA version newer than 1.1
*
*/
typedef struct {
uint8_t signature[2];
uint16_t flags;
uint32_t code_size;
uint32_t crc;
uint8_t version[16];
uint32_t timestamp;
uint32_t exec_location;
} __attribute__((packed)) suota_1_1_image_header_t;
#define SUOTA_1_1_IMAGE_HEADER_SIGNATURE_B1 0x70
#define SUOTA_1_1_IMAGE_HEADER_SIGNATURE_B2 0x61
#define SUOTA_1_1_IMAGE_FLAG_FORCE_CRC 0x01
#define SUOTA_1_1_IMAGE_FLAG_VALID 0x02
#define SUOTA_1_1_IMAGE_FLAG_RETRY1 0x04
#define SUOTA_1_1_IMAGE_FLAG_RETRY2 0x08
typedef suota_1_1_image_header_t suota_image_header_t;
#endif /* SUOTA_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,64 +0,0 @@
/**************************************************************************//**
* @file system_ARMCM0.h
* @brief CMSIS Device System Header File for
* ARMCM0 Device Series
* @version V2.00
* @date 18. August 2015
******************************************************************************/
/* Copyright (c) 2011 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 SYSTEM_ARMCM0_H
#define SYSTEM_ARMCM0_H
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/** @brief Setup the microcontroller system.
Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/** \brief Update SystemCoreClock variable.
Updates the SystemCoreClock with current core Clock
retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_ARMCM0_H */
@@ -1,91 +0,0 @@
/**************************************************************************//**
* @file system_DA14680.h
* @brief CMSIS Cortex-M0 Device Peripheral Access Layer Header File for
* Device DA14680
* @version V3.10
* @date 23. November 2012
*
* @note
*
******************************************************************************/
/* Copyright (c) 2012 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 SYSTEM_DA14680_H
#define SYSTEM_DA14680_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
/**
* \brief Convert a CPU address to a physical address
*
* To calculate the physical address, the current remapping (SYS_CTRL_REG.REMAP_ADR0)
* is used.
*
* \param [in] addr address seen by CPU
*
* \return physical address (for DMA, AES/HASH etc.) -- can be same or different as addr
*
*/
extern uint32_t DA15000_phy_addr(uint32_t addr);
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_DA14680_H */
-237
View File
@@ -1,237 +0,0 @@
/**
****************************************************************************************
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
MEMORY
{
ROM (rx) : ORIGIN = (0x8000000 + (0)), LENGTH = (512 * 1024)
RetRAM0 (rwx): ORIGIN = (0x7FC0000) + (( 64 * 1024) + ( 0 * 1024)), LENGTH = (( 24 * 1024))
RetRAM1 (rwx): ORIGIN = (0), LENGTH = 0
RAM (rw) : ORIGIN = (0x7FC0000) + ((0x200)), LENGTH = (( 64 * 1024) - (0x200))
}
ENTRY(Reset_Handler)
SECTIONS
{
.init_text :
{
KEEP(*(.isr_vector))
. = 0xC0;
KEEP(*(.patch_table))
. = 0x100;
KEEP(*(.patch_table_flash))
. = 0x130;
KEEP(*(.default_patch_code_handler_section))
. = 0x200;
*(text_reset*)
} > ROM
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext + (__data_end__ - __data_start__))
LONG (__RetRAM0_code_start__)
LONG (__RetRAM0_code_end__ - __RetRAM0_code_start__)
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
__copy_table_end__ = .;
. = ALIGN(16);
} > ROM
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__RetRAM0_data_start)
LONG (__RetRAM0_size)
LONG (__RetRAM1_start__)
LONG (__RetRAM1_end__ - __RetRAM1_start__)
__zero_table_end__ = .;
. = ALIGN(16);
} > ROM
PROVIDE_HIDDEN (__stext = .);
.text :
{
*(EXCLUDE_FILE(*libnosys.a:sbrk.o
*libgcc.a:_aeabi_uldivmod.o
*libgcc.a:_muldi3.o
*libgcc.a:_dvmd_tls.o
*libgcc.a:bpabi.o
*libgcc.a:_udivdi3.o
*libgcc.a:_clzdi2.o
*libgcc.a:_clzsi2.o) .text*)
. = ALIGN(4);
__start_adapter_init_section = .;
*(adapter_init_section)
__stop_adapter_init_section = .;
__start_bus_init_section = .;
*(bus_init_section)
__stop_bus_init_section = .;
__start_device_init_section = .;
*(device_init_section)
__stop_device_init_section = .;
KEEP(*(.init))
KEEP(*(.fini))
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
*(.rodata*)
KEEP(*(.eh_frame*))
} > ROM
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > ROM
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > ROM
__exidx_end = .;
.align_s :
{
. = ALIGN(16);
} > ROM
__etext = .;
.data : AT (__etext)
{
. = ALIGN(16);
__data_start__ = .;
*(vtable)
*(EXCLUDE_FILE(*\libg_nano.a:* *\libnosys.a:*) .data*)
. = ALIGN(4);
KEEP(*(.jcr*))
. = ALIGN(16);
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(32);
__bss_start__ = .;
*(.bss.ecc_buffer)
*(EXCLUDE_FILE(*\libg_nano.a:* *\libnosys.a:*) .bss*)
*(COMMON)
. = ALIGN(32);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
RETENTION_INIT0 : AT (__etext + (__data_end__ - __data_start__))
{
. = ALIGN(16);
__RetRAM0_code_start__ = .;
*(text_retained)
*libgcc.a:_aeabi_uldivmod.o (.text*)
*libgcc.a:_muldi3.o (.text*)
*libgcc.a:_dvmd_tls.o (.text*)
*libgcc.a:bpabi.o (.text*)
*libgcc.a:_udivdi3.o (.text*)
*libgcc.a:_clzdi2.o (.text*)
*libgcc.a:_clzsi2.o (.text*)
. = ALIGN(4);
*(retention_mem_init)
*(retention_mem_const)
*(privileged_data_init)
*(.retention)
*\libg_nano.a:* (.data*)
*\libnosys.a:* (.data*)
. = ALIGN(16);
__RetRAM0_code_end__ = .;
. = ALIGN(4);
} > RetRAM0
RETENTION_RAM0 (COPY) :
{
. = ALIGN(4);
__RetRAM0_start = .;
*(nmi_info)
*(hard_fault_info)
*(retention_mem_uninit)
. = ALIGN(32);
__RetRAM0_data_start = .;
*\libg_nano.a:* (.bss*)
*\libnosys.a:* (.bss*)
*(privileged_data_zi)
*(retention_mem_zi)
*(os_heap)
. = ALIGN(32);
__RetRAM0_data_end__ = .;
} > RetRAM0
RETENTION_RAM1 (COPY) :
{
. = ALIGN(32);
__RetRAM1_start__ = .;
*(privileged_data_1_zi)
*(retention_mem_1_zi)
. = ALIGN(32);
__RetRAM1_end__ = .;
} > RetRAM1
__RetRAM0_size = (__RetRAM0_data_end__ - __RetRAM0_data_start);
__image_size = __etext + (__data_end__ - __data_start__)
+ (__RetRAM0_code_end__ - __RetRAM0_code_start__)
- ORIGIN(ROM);
__mirrored_image_size = __etext + (__data_end__ - __data_start__) - ORIGIN(ROM);
}
@@ -1,305 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \{
*/
/**
****************************************************************************************
*
* @file qspi_automode.h
*
* @brief Access QSPI flash when running in auto mode
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 QSPI_AUTOMODE_H_
#define QSPI_AUTOMODE_H_
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sdk_defs.h>
#include <hw_qspi.h>
#include "hw_cpm.h"
/*
* Debug options
*/
#if __DBG_QSPI_ENABLED
#define __DBG_QSPI_VOLATILE__ volatile
#pragma message "Automode: Debugging is on!"
#else
#define __DBG_QSPI_VOLATILE__
#endif
/*
* Defines (generic)
*/
/* Macros to put functions that need to be copied to ram in one section (retained) */
typedef struct qspi_ucode_s {
const uint32_t *code;
uint8_t size;
} qspi_ucode_t;
/*
* Flash specific defines
*/
/**
* \brief SUS bit delay after SUSPEND command (in μsec)
*
*/
#define FLASH_SUS_DELAY (20)
/**
* \brief Get size of RAM buffer needed for code to modify QSPI flash.
*
* Called must allocate buffer at least of this size and pass it qspi_set_code_buffer() to allow
* flash modification.
*
* \return size of buffer needed
*
*/
DEPRECATED
uint32_t qspi_automode_get_code_buffer_size(void);
/**
* \brief Set buffer that will be used for code that modifies flash.
*
* This function should be called with buffer allocated for flash manipulation code.
* Size of this buffer should be at least the value returned from qspi_get_code_buffer_size().
* If function is called with NULL all further calls to qspi_write_flash_page() or
* qspi_erase_flash_sector() will crash.
* To preserve memory it is quite wise to allocate buffer before erase/write, update flash and
* then call this function with NULL and free memory.
*
* \param [in] ram buffer for code that will be used for erase and write.
*
*/
DEPRECATED_MSG("Function does not need to be called")
void qspi_automode_set_code_buffer(void *ram);
/**
* \brief Write flash memory
*
* This function allows to write up to page size of data to flash.
* If size is greater than page size, flash can wrap data and overwrite content of page.
* It's possible to write less then page size.
* Memory should be erased before.
*
* \note: Do not pass buf pointing to QSPI mapped memory.
*
* \param [in] addr offset in flash to write data to
* \param [in] buf pointer to data to write
* \param [in] size number of bytes to write
*
* return number of bytes written
*
*/
size_t qspi_automode_write_flash_page(uint32_t addr, const uint8_t *buf, size_t size);
/**
* \brief Erase flash sector
*
* \param [in] addr starting offset of sector
*/
void qspi_automode_erase_flash_sector(uint32_t addr);
/**
* \brief Erase whole chip
*/
void qspi_automode_erase_chip(void);
/**
* \brief Read flash memory
*
* \param [in] addr starting offset
* \param [out] buf buffer to read data to
* \param [in] len number of bytes to read
*
* \returns number of bytes read
*/
size_t qspi_automode_read(uint32_t addr, uint8_t *buf, size_t len);
/**
* \brief Get address of flash
*
* \param [in] addr starting offset
*
* \returns address in CPU address space where data is located
*/
static inline const void *qspi_automode_addr(uint32_t addr) __attribute__((always_inline));
static inline const void *qspi_automode_addr(uint32_t addr)
{
return (const void *) (MEMORY_QSPIF_BASE + addr);
}
/**
* \brief Power up flash
*/
__RETAINED_CODE void qspi_automode_flash_power_up(void);
/**
* \brief Set QSPI Flash into power down mode
*/
__RETAINED_CODE void qspi_automode_flash_power_down(void);
/**
* \brief Init QSPI controller
*/
__RETAINED_CODE bool qspi_automode_init(void);
#if (dg_configDISABLE_BACKGROUND_FLASH_OPS == 0)
/**
* \brief Check if a program or sector erase operation is in progress
*
* \return bool True if the BUSY bit is set else false.
*
* \warning This function checks the value of the BUSY bit in the Status Register 1 of the Flash. It
* is the responsibility of the caller to call the function in the right context. The
* function must be called with interrupts disabled.
*
*/
__RETAINED_CODE bool qspi_check_program_erase_in_progress(void);
/**
* \brief Suspend a Flash program or erase operation
*
* \details This function will try to suspend an ongoing program or erase procedure. The SUS bit is
* checked and the actual status is returned to the caller. Note that the program or erase
* procedure may have been completed before the suspend command is processed by the Flash. In
* this case the SUS bit will be left to 0.
*
* \return bool True if the procedure has been suspended. False if the procedure was not suspended
* successfully or had finished before the suspend command was processed by the Flash.
*
* \warning After the call to this function, the QSPI controller is set to auto mode and the Flash
* access to quad mode (if QUAD_MODE is 1). The function must be called with interrupts
* disabled.
*
*/
__RETAINED_CODE bool qspi_check_and_suspend(void);
/**
* \brief Resume a Flash program or sector erase operation
*
* \warning After the call to this function, the QSPI controller is set to manual mode and the Flash
* access to single mode. The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE void qspi_resume(void);
/**
* \brief Erase a sector of the Flash in manual mode
*
* \param[in] addr The address of the sector to be erased.
*
* \warning This function does not block until the Flash has processed the command! The QSPI
* controller is left to manual mode after the call to this function. The function must be
* called with interrupts disabled.
*
*/
__RETAINED_CODE void flash_erase_sector_manual_mode(uint32_t addr);
/**
* \brief Program data into a page of the Flash in manual mode
*
* \param[in] addr The address of the Flash where the data will be written. It may be anywhere in a
* page.
* \param[in] buf Pointer to the beginning of the buffer that contains the data to be written.
* \param[in] len The number of bytes to be written.
*
* \return size_t The number of bytes written.
*
* \warning The boundary of the page where addr belongs to, will not be crossed! The caller should
* issue another flash_program_page_manual_mode() call in order to write the remaining data
* to the next page. The QSPI controller is left to manual mode after the call to this
* function. The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE size_t flash_program_page_manual_mode(uint32_t addr, const uint8_t *buf,
uint16_t len);
#endif
/**
* \brief Activate Flash command entry mode
*
* \note After the call to this function, the QSPI controller is set to manual mode and the Flash
* access to single mode.
*
* \warning The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE void flash_activate_command_entry_mode(void);
/**
* \brief Deactivate Flash command entry mode
*
* \note After the call to this function, the QSPI controller is set to auto mode and the Flash
* access to quad mode (if QUAD_MODE is 1).
*
* \warning The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE void flash_deactivate_command_entry_mode(void);
/**
* \brief Configure Flash and QSPI controller for system clock frequency
*
* This function is used to change the Flash configuration of the QSPI controller
* to work with the system clock frequency defined in sys_clk. Dummy clock
* cycles could be changed here to support higher clock frequencies.
* QSPI controller clock divider could also be changed if the Flash
* maximum frequency is smaller than the system clock frequency.
* This function must be called before changing system clock frequency.
*
* \param [in] sys_clk System clock frequency
*
*/
__RETAINED_CODE void qspi_automode_sys_clock_cfg(sys_clk_t sys_clk);
/**
* \brief Get ucode required for wake-up sequence
* \return qspi_ucode_t Pointer to the structure containing the ucode and ucode size
*/
const qspi_ucode_t *qspi_automode_get_ucode(void);
#endif /* QSPI_AUTOMODE_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,174 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \brief QSPI flash driver framework
* \{
*/
/**
****************************************************************************************
*
* @file qspi_common.h
*
* @brief QSPI flash driver common definitions
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 _QSPI_COMMON_H_
#define _QSPI_COMMON_H_
#include "qspi_automode.h"
/*
* Flash Commands
*
* Note: Default command issuing mode is single mode! If commands specific to other modes have to be
* issued then the mode must be changed!
*/
#define CMD_WRITE_STATUS_REGISTER 0x01
#define CMD_WRITE_DISABLE 0x04
#define CMD_READ_STATUS_REGISTER 0x05
#define CMD_WRITE_ENABLE 0x06
#define CMD_SECTOR_ERASE 0x20
#define CMD_QUAD_PAGE_PROGRAM 0x32
#define CMD_QUAD_IO_PAGE_PROGRAM 0x38
#define CMD_BLOCK_ERASE 0x52
#define CMD_CHIP_ERASE 0xC7
#define CMD_FAST_READ_QUAD 0xEB
#define CMD_READ_JEDEC_ID 0x9F
#define CMD_EXIT_CONTINUOUS_MODE 0xFF
#define CMD_RELEASE_POWER_DOWN 0xAB
#define CMD_ENTER_POWER_DOWN 0xB9
#define CMD_FAST_READ_QUAD_4B 0xEC
#define CMD_SECTOR_ERASE_4B 0x21
#define CMD_QUAD_PAGE_PROGRAM_4B 0x34
#define CMD_QUAD_IO_PAGE_PROGRAM_4B 0x3E
/* Erase/Write in progress */
#define FLASH_STATUS_BUSY_BIT 0
#define FLASH_STATUS_BUSY_MASK (1 << FLASH_STATUS_BUSY_BIT)
/* WE Latch bit */
#define FLASH_STATUS_WEL_BIT 1
#define FLASH_STATUS_WEL_MASK (1 << FLASH_STATUS_WEL_BIT)
typedef bool (*is_suspended_cb_t)(void);
typedef void (*initialize_cb_t)(uint8_t device_type, uint8_t device_density);
typedef void (*deactivate_command_entry_mode_cb_t)(void);
typedef void (*sys_clk_cfg_cb_t)(sys_clk_t type);
typedef uint8_t (*get_dummy_bytes_cb_t)(void);
/**
* \brief QSPI Flash configuration structure
*
* This struct is used to define a driver for a specific QSPI flash.
*
* \note The struct instance must be declared as static const for this to work
*/
typedef struct qspi_flash_config {
// Function pointers
initialize_cb_t initialize; /**< Flash-specific initialization */
is_suspended_cb_t is_suspended; /**< Check if flash is in erase/program
suspend state */
deactivate_command_entry_mode_cb_t
deactivate_command_entry_mode; /**< Perform extra steps needed when command
entry mode is deactivated */
sys_clk_cfg_cb_t sys_clk_cfg; /**< Perform Flash configuration when system clock
is changed (e.g. change dummy bytes or QSPIC
clock divider */
get_dummy_bytes_cb_t get_dummy_bytes; /**< Return the number of dummy bytes currently
needed (they may e.g. change when the clock
changes) */
uint8_t manufacturer_id; /**< The Flash JEDEC vendor ID (Cmd 0x9F, 1st byte)
This (and the device_type/device_density)
are needed for flash autodetection */
uint8_t device_type; /**< The Flash JEDEC device type (Cmd 0x9F, 2nd byte) */
uint8_t device_density; /**< The Flash JEDEC device type (Cmd 0x9F, 3rd byte) */
uint8_t erase_opcode; /**< The Flash erase opcode to use */
uint8_t erase_suspend_opcode; /**< The Flash erase suspend opcode to use */
uint8_t erase_resume_opcode; /**< The Flash erase resume opcode to use */
uint8_t page_program_opcode; /**< The Flash page program opcode to use */
bool quad_page_program_address; /**< If true, the address will be transmitted in
QUAD mode when writing a page. Otherwise, it
will be transmitted in single mode */
uint8_t read_erase_progress_opcode; /**< The opcode to use to check if erase is in progress
(Usually the Read Status Reg opcode (0x5)) */
uint8_t erase_in_progress_bit; /**< The bit to check when reading the erase progress */
bool erase_in_progress_bit_high_level; /**< The active state (true: high, false: low) of the bit
above */
uint8_t send_once; /**< If set to 1, the "Performance mode" (or burst, or
continuous; differs per vendor) will be used for read
accesses. In this mode, the read opcode is only sent
once, and subsequent accesses only transfer the address */
uint8_t extra_byte; /**< The extra byte to transmit, when in "Performance mode"
(send once is 1), that tells the flash that it should
stay in this continuous, performance mode */
HW_QSPI_ADDR_SIZE address_size; /**< Whether the flash works in 24- or 32-bit addressing mode */
HW_QSPI_BREAK_SEQ_SIZE break_seq_size; /**< Whether the break sequence, that puts flash out of the
continuous mode, is one or two bytes long (the break byte is
0xFF) */
qspi_ucode_t ucode_wakeup; /**< The QSPIC microcode to use to setup the flash on wakeup. This
is automatically used by the QSPI Controller after wakeup, and
before CPU starts code execution. This is different based on
whether flash was active, in deep power down or completely off
while the system was sleeping */
uint16_t power_down_delay; /**< This is the time, in usec, needed for the flash to go to power
down, after the Power Down command is issued */
uint16_t release_power_down_delay; /**< This is the time, in usec, needed for the flash to exit the power
down mode, after the Release Power Down command is issued */
} qspi_flash_config_t;
extern const qspi_flash_config_t* flash_config_init;
#if (FLASH_AUTODETECT == 1)
extern qspi_flash_config_t *flash_config;
#else
extern const qspi_flash_config_t * const flash_config;
#endif
static void qspi_write(const uint8_t *wbuf, size_t wlen);
static void qspi_transact(const uint8_t *wbuf, size_t wlen, uint8_t *rbuf, size_t rlen);
static uint8_t flash_read_status_register(void);
static void flash_write_status_register(uint8_t value);
static void flash_write_enable(void);
static void qspi_automode_set_dummy_bytes_count(uint8_t count);
static inline bool flash_erase_program_in_progress(void) __attribute__((always_inline));
static inline bool flash_is_busy(void) __attribute__((always_inline));
#endif /* _QSPI_COMMON_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,115 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \{
*/
/**
****************************************************************************************
*
* @file qspi_w25q80ew.h
*
* @brief QSPI flash driver for the Winbond W25Q80EW
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 _QSPI_W32Q80EW_H_
#define _QSPI_W32Q80EW_H_
#ifndef WINBOND_ID
#define WINBOND_ID 0xEF
#endif
// Device type using command 0x9F
#define W25Q80EW 0x60
#ifndef W25Q_8Mb_SIZE
#define W25Q_8Mb_SIZE 0x14
#endif
#if (FLASH_AUTODETECT == 1) || (dg_configFLASH_MANUFACTURER_ID == WINBOND_ID && \
dg_configFLASH_DEVICE_TYPE == W25Q80EW && dg_configFLASH_DENSITY == W25Q_8Mb_SIZE)
#include "qspi_common.h"
#include "qspi_winbond.h"
static void flash_w25q80ew_sys_clock_cfg(sys_clk_t sys_clk);
static uint8_t flash_w25q80ew_get_dummy_bytes(void);
static const qspi_flash_config_t flash_w25q80ew_config = {
.manufacturer_id = WINBOND_ID,
.device_type = W25Q80EW,
.device_density = W25Q_8Mb_SIZE,
.is_suspended = flash_w25q_is_suspended,
.initialize = flash_w25q_initialize,
.deactivate_command_entry_mode = flash_w25q_deactivate_command_entry_mode,
.sys_clk_cfg = flash_w25q80ew_sys_clock_cfg,
.get_dummy_bytes = flash_w25q80ew_get_dummy_bytes,
.break_seq_size = HW_QSPI_BREAK_SEQ_SIZE_1B,
.address_size = HW_QSPI_ADDR_SIZE_24,
.page_program_opcode = CMD_QUAD_PAGE_PROGRAM,
.quad_page_program_address = false,
.erase_opcode = CMD_SECTOR_ERASE,
.erase_suspend_opcode = W25Q_ERASE_PROGRAM_SUSPEND,
.erase_resume_opcode = W25Q_ERASE_PROGRAM_RESUME,
.read_erase_progress_opcode = CMD_READ_STATUS_REGISTER,
.erase_in_progress_bit = FLASH_STATUS_BUSY_BIT,
.erase_in_progress_bit_high_level = true,
.send_once = 1,
.extra_byte = 0xA0,
.ucode_wakeup = {w25q_ucode_wakeup, sizeof(w25q_ucode_wakeup)},
.power_down_delay = W25Q_POWER_DOWN_DELAY_US,
.release_power_down_delay = W25Q_RELEASE_POWER_DOWN_DELAY_US,
};
#if (FLASH_AUTODETECT == 0)
const qspi_flash_config_t* const flash_config = &flash_w25q80ew_config;
#endif
__RETAINED_CODE static void flash_w25q80ew_sys_clock_cfg(sys_clk_t sys_clk)
{
}
__RETAINED_CODE static uint8_t flash_w25q80ew_get_dummy_bytes(void)
{
return 2;
}
#endif
#endif /* _QSPI_W32Q80EW_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,241 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \{
*/
/**
****************************************************************************************
*
* @file qspi_winbond.h
*
* @brief QSPI flash driver for Winbond flashes - common code
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 _QSPI_WINBOND_H_
#define _QSPI_WINBOND_H_
#define WINBOND_ID 0xEF
#if (FLASH_AUTODETECT == 1) || (dg_configFLASH_MANUFACTURER_ID == WINBOND_ID)
#include "qspi_common.h"
#define W25Q_ERASE_PROGRAM_SUSPEND 0x75
#define W25Q_ERASE_PROGRAM_RESUME 0x7A
#define W25Q_WRITE_STATUS_REGISTER2 0x31
#define W25Q_PAGE_PROGRAM 0x02
#define W25Q_WRITE_ENABLE_NON_VOL 0x50
#define W25Q_READ_STATUS_REGISTER2 0x35
#define W25Q_BLOCK_ERASE_64K 0xD8
#define W25Q_FAST_READ_QPI 0x0B
#define W25Q_READ_DEVICE_ID_SINGLE 0x90 // Requires single mode for the command entry!
#define W25Q_READ_DEVICE_ID_DUAL 0x92 // Requires dual mode for the command entry!
#define W25Q_READ_DEVICE_ID_QUAD 0x94
#define W25Q_READ_UNIQUE_ID 0x4B // Requires single mode for the command entry!
#define W25Q_READ_SFDP_REG 0x5A // Requires single mode for the command entry!
#define W25Q_ERASE_SECURITY_REGS 0x44 // Requires single mode for the command entry!
#define W25Q_PROGR_SECURITY_REGS 0x42 // Requires single mode for the command entry!
#define W25Q_READ_SECURITY_REGS 0x48 // Requires single mode for the command entry!
#define W25Q_ENTER_QPI_MODE 0x38 // Requires single mode for the command entry!
#define W25Q_EXIT_QPI_MODE 0xFF // Requires quad mode for the command entry!
/* Suspend */
#define W25Q_STATUS2_SUS_BIT 7
#define W25Q_STATUS2_SUS_MASK (1 << W25Q_STATUS2_SUS_BIT)
/* QPI Enable */
#define W25Q_STATUS2_QE_BIT 1
#define W25Q_STATUS2_QE_MASK (1 << W25Q_STATUS2_QE_BIT)
// Flash power up/down timings
#define W25Q_POWER_DOWN_DELAY_US 3
#define W25Q_RELEASE_POWER_DOWN_DELAY_US 3
#define W25Q_POWER_UP_DELAY_US 10
#if (dg_configFLASH_POWER_OFF == 1)
/**
* \brief uCode for handling the QSPI FLASH activation from power off.
*/
/*
* Should work with all Winbond flashes -- verified with W25Q80EW.
*
* Delay 10usec
* 0x01 // CMD_NBYTES = 0, CMD_TX_MD = 0 (Single), CMD_VALID = 1
* 0xA0 // CMD_WT_CNT_LS = 160 --> 10000 / 62.5 = 160 = 10usec
* 0x00 // CMD_WT_CNT_MS = 0
* Exit from Fast Read mode
* 0x09 // CMD_NBYTES = 1, CMD_TX_MD = 0 (Single), CMD_VALID = 1
* 0x00 // CMD_WT_CNT_LS = 0
* 0x00 // CMD_WT_CNT_MS = 0
* 0xFF // Enable Reset
* (up to 16 words)
*/
const uint32_t w25q_ucode_wakeup[] = {
0x09000001 | (((uint16_t)(W25Q_POWER_UP_DELAY_US*1000/62.5) & 0xFFFF) << 8),
0x00FF0000,
};
#elif (dg_configFLASH_POWER_DOWN == 1)
/**
* \brief uCode for handling the QSPI FLASH release from power-down.
*/
/*
* Should work with all Winbond flashes -- verified with W25Q80EW.
*
* 0x09 // CMD_NBYTES = 1, CMD_TX_MD = 0 (Single), CMD_VALID = 1
* 0x30 // CMD_WT_CNT_LS = 3000 / 62.5 = 48 // 3usec
* 0x00 // CMD_WT_CNT_MS = 0
* 0xAB // Release Power Down
* (up to 16 words)
*/
const uint32_t w25q_ucode_wakeup[] = {
0xAB000009 | (((uint16_t)(W25Q_RELEASE_POWER_DOWN_DELAY_US*1000/62.5) & 0xFFFF) << 8),
};
#else
/**
* \brief uCode for handling the QSPI FLASH exit from the "Continuous Read Mode".
*/
/*
* Should work with all Winbond flashes -- verified with W25Q80EW.
*
* 0x25 // CMD_NBYTES = 4, CMD_TX_MD = 2 (Quad), CMD_VALID = 1
* 0x00 // CMD_WT_CNT_LS = 0
* 0x00 // CMD_WT_CNT_MS = 0
* 0x55 // Clocks 0-1 (A23-16)
* 0x55 // Clocks 2-3 (A15-8)
* 0x55 // Clocks 4-5 (A7-0)
* 0x55 // Clocks 6-7 (M7-0) : M5-4 != '10' ==> Disable "Continuous Read Mode"
* (up to 16 words)
*/
const uint32_t w25q_ucode_wakeup[] = {
0x55000025,
0x00555555,
};
#endif
static bool flash_w25q_is_suspended(void);
static void flash_w25q_initialize(uint8_t device_type, uint8_t device_density);
static void flash_w25q_deactivate_command_entry_mode(void);
/**
* \brief Enable volatile writes to Status Register bits
* \details When this command is issued, any writes to any of the Status Registers of the Flash are
* done as volatile writes. This command is valid only when the Write Status Register command
* follows.
*
* \note This function blocks until the Flash has processed the command.
*/
static inline void flash_w25q_wre_volatile(void) __attribute__((always_inline)) __attribute__((unused));
static inline void flash_w25q_wre_volatile(void)
{
uint8_t cmd[] = { W25Q_WRITE_ENABLE_NON_VOL };
qspi_write(cmd, 1);
/* Verify */
while (flash_is_busy());
}
static inline uint8_t flash_w25q_read_status_register_2(void) __attribute__((always_inline));
static inline uint8_t flash_w25q_read_status_register_2(void)
{
__DBG_QSPI_VOLATILE__ uint8_t status;
uint8_t cmd[] = { W25Q_READ_STATUS_REGISTER2 };
qspi_transact(cmd, 1, &status, 1);
return status;
}
/**
* \brief Write the Status Register 2 of the Flash
*
* \param[in] value The value to be written.
*
* \note This function blocks until the Flash has processed the command. No verification that the
* value has been actually written is done though. It is up to the caller to decide whether
* such verification is needed or not and execute it on its own.
*/
static inline void flash_w25q_write_status_register_2(uint8_t value) __attribute__((always_inline));
static inline void flash_w25q_write_status_register_2(uint8_t value)
{
uint8_t cmd[] = { W25Q_WRITE_STATUS_REGISTER2, value };
qspi_write(cmd, 2);
/* Wait for the Flash to process the command */
while (flash_is_busy());
}
static inline void flash_w25q_enable_quad_mode(void) __attribute__((always_inline));
static inline void flash_w25q_enable_quad_mode(void)
{
uint8_t status;
status = flash_w25q_read_status_register_2();
if (!(status & W25Q_STATUS2_QE_MASK)) {
flash_write_enable();
flash_w25q_write_status_register_2(status | W25Q_STATUS2_QE_MASK);
}
}
__RETAINED_CODE static bool flash_w25q_is_suspended(void)
{
__DBG_QSPI_VOLATILE__ uint8_t status;
status = flash_w25q_read_status_register_2();
return (status & W25Q_STATUS2_SUS_MASK) != 0;
}
__RETAINED_CODE static void flash_w25q_initialize(uint8_t device_type, uint8_t device_density)
{
flash_activate_command_entry_mode();
flash_w25q_enable_quad_mode();
flash_deactivate_command_entry_mode();
}
__RETAINED_CODE static void flash_w25q_deactivate_command_entry_mode(void)
{
}
#endif
#endif /* _QSPI_WINBOND_H_ */
/**
* \}
* \}
* \}
*/
File diff suppressed because it is too large Load Diff
-95
View File
@@ -1,95 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup OSAL
*
* \brief OS Abstraction Layer
*
* \{
*/
/**
****************************************************************************************
*
* @file osal.h
*
* @brief OS abstraction layer API
*
* @brief Access QSPI flash when running in auto mode
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 OSAL_H_
#define OSAL_H_
#if defined OS_BAREMETAL
#include <sdk_defs.h>
/*
* Basic set of macros that can be used in non OS environment.
*/
# define PRIVILEGED_DATA
# define OS_MALLOC malloc
# define OS_FREE free
# ifndef RELEASE_BUILD
# define OS_ASSERT(a) do { if (!(a)) {__BKPT(0);} } while (0)
# else
# define OS_ASSERT(a) ((void) (a))
# endif
#endif
/**
* \brief Cast any pointer to unsigned int value
*/
#define OS_PTR_TO_UINT(p) ((unsigned) (void *) (p))
/**
* \brief Cast any pointer to signed int value
*/
#define OS_PTR_TO_INT(p) ((int) (void *) (p))
/**
* \brief Cast any unsigned int value to pointer
*/
#define OS_UINT_TO_PTR(u) ((void *) (unsigned) (u))
/**
* \brief Cast any signed int value to pointer
*/
#define OS_INT_TO_PTR(i) ((void *) (int) (i))
#endif /* OSAL_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,767 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup AES_HASH
* \{
* \brief AES/Hash Engine
*/
/**
****************************************************************************************
*
* @file hw_aes_hash.h
*
* @brief Definition of API for the AES/HASH Engine Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_AES_HASH_H_
#define HW_AES_HASH_H_
#if dg_configUSE_HW_AES_HASH
#include <stdbool.h>
#include "sdk_defs.h"
/**
* \brief AES/Hash callback
*
* This function is called by the AES/Hash driver when the interrupt is fired.
*
*/
typedef void (*hw_aes_hash_cb)(void);
/**
* \brief AES key sizes. Possible values: HW_AES_128, HW_AES_192, HW_AES_256.
*/
typedef enum {
HW_AES_128 = 0,
HW_AES_192 = 1,
HW_AES_256 = 2
} hw_aes_key_size;
/**
* \brief AES direction. Possible values: HW_AES_DECRYPT, HW_AES_ENCRYPT.
*/
typedef enum {
HW_AES_DECRYPT = 0,
HW_AES_ENCRYPT = 1
} hw_aes_direction;
/**
* \brief AES/Hash modes. Possible values: HW_AES_ECB, HW_AES_CBC, HW_AES_CTR, HW_HASH_MD5,
* HW_AES_SHA_1, HW_AES_SHA_256_224, HW_AES_SHA_256, HW_AES_SHA_384, HW_AES_SHA_512,
* HW_AES_SHA_512_224, HW_AES_SHA_512_256.
*/
typedef enum {
HW_AES_ECB,
HW_AES_CBC,
HW_AES_CTR,
HW_HASH_MD5,
HW_HASH_SHA_1,
HW_HASH_SHA_256_224,
HW_HASH_SHA_256,
HW_HASH_SHA_384,
HW_HASH_SHA_512,
HW_HASH_SHA_512_224,
HW_HASH_SHA_512_256
} hw_aes_hash_mode;
/**
* \brief Key expansion modes.
* Possible values HW_AES_PERFORM_KEY_EXPANSION, HW_AES_DO_NOT_PERFORM_KEY_EXPANSION
*/
typedef enum {
HW_AES_PERFORM_KEY_EXPANSION = 0, /**< Key expansion is performed by the engine */
HW_AES_DO_NOT_PERFORM_KEY_EXPANSION /**< Key expansion is performed by the software */
} hw_aes_hash_key_exp_t;
/**
\brief AES/Hash setup structure.
*/
typedef struct {
hw_aes_hash_mode mode; /**< AES/Hash mode. */
hw_aes_direction aesDirection; /**< AES direction. Only used when the mode is an AES mode.*/
hw_aes_key_size aesKeySize; /**< AES key size. Only used when the mode is an AES mode. */
bool aesKeyExpand; /**< When true the key expansion process is execute. When false the key
expansion process is not executed. The user should write the AES keys in CRYPTO_RAM.
Only used when the mode is an AES mode. */
uint32 aesKeys; /**< The start address of the buffer containing the AES key. */
uint32 aesIvCtrblk_0_31; /**< In CBC mode IV[31:0] and in CTR mode the initial value of the
32 bits counter. Only used when the mode is an AES CBC/CTR mode. */
uint32 aesIvCtrblk_32_63; /**< In CBC mode IV[63:32] and in CTR[63:32].
Only used when the mode is an AES CBC/CTR mode. */
uint32 aesIvCtrblk_64_95; /**< In CBC mode IV[95:64] and in CTR[95:64].
Only used when the mode is an AES CBC/CTR mode. */
uint32 aesIvCtrblk_96_127; /**< In CBC mode IV[127:96] and in CTR[127:96].
Only used when the mode is an AES CBC/CTR mode. */
bool aesWriteBackAll; /**< When true all the AES resulting data is written to memory.
When false only the final block of the AES resulting data is written to memory.
Only used when the mode is an AES mode. */
uint8 hashOutLength; /**< The number of bytes of the hash result to be saved to memory.
Only used when mode is a Hash mode. */
bool moreDataToCome; /**< When false this is the last data block. When true more data is to
come. */
uint32 sourceAddress; /**< The physical address of the input data that needs to be processed. */
uint32 destinationAddress; /**< The physical address (RAM only) where the resulting data needs
to be written. If NULL the register is not written.*/
uint32 dataSize; /**< The number of bytes that need to be processed. If this number is not
a multiple of a block size, the data is automatically extended with zeros. */
bool enableInterrupt; /**< When true the callback function is called after the operation
has ended. */
hw_aes_hash_cb callback; /**< The callback function that is called when enable interrupt
is true. */
} hw_aes_hash_setup;
/**
* \brief Enable AES/HASH engine clock
*
* This function enables the AES/HASH engine clock.
*/
__STATIC_INLINE void hw_aes_hash_enable_clock(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
* \brief Disable AES/HASH engine clock
*
* This function disables the AES/HASH engine clock.
*/
__STATIC_INLINE void hw_aes_hash_disable_clock(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
* \brief Check if AES/HASH engine clock is enabled
*
* \return Non-zero value if enabled, 0 otherwise
*/
__STATIC_INLINE int hw_aes_hash_clock_is_enabled(void)
{
return (CRG_TOP->CLK_AMBA_REG) & (CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk);
}
/**
* \brief AES/Hash enable.
*
* This function sets up and starts a AES/HASH engine operation. All the
* configuration details are included in the setup input structure.
*
* \param [in] setup The setup structure with setup values.
*
* \deprecated You can use hw_aes_hash_init with hw_aes_hash_start instead.
*
* \sa hw_aes_hash_init
* \sa hw_aes_hash_start
*
*/
void hw_aes_hash_enable(const hw_aes_hash_setup setup) DEPRECATED;
/**
* \brief AES/Hash initialize.
*
* This function sets up a AES/HASH engine operation. All the configuration details
* are included in the setup input structure. The operation can then start by calling
* hw_aes_hash_start
*
* \param [in] setup The setup structure with setup values.
*
* \note There are some restrictions in the value of dataSize of the setup structure depending on
* the mode. This function will do appropriate checking using assertions. The following
* table shows what the value of dataSize should be:
*
* mode | moreDataToCome = true | moreDataToCome = false
* ------------------- | --------------------- | ----------------------
* HW_AES_ECB | multiple of 16 | multiple of 16
* HW_AES_CBC | multiple of 16 | no restrictions
* HW_AES_CTR | multiple of 16 | no restrictions
* HW_HASH_MD5 | multiple of 8 | no restrictions
* HW_HASH_SHA_1 | multiple of 8 | no restrictions
* HW_HASH_SHA_256_224 | multiple of 8 | no restrictions
* HW_HASH_SHA_256 | multiple of 8 | no restrictions
* HW_HASH_SHA_384 | multiple of 8 | no restrictions
* HW_HASH_SHA_512 | multiple of 8 | no restrictions
* HW_HASH_SHA_512_224 | multiple of 8 | no restrictions
* HW_HASH_SHA_512_256 | multiple of 8 | no restrictions
*
* \sa hw_aes_hash_start
*
*/
void hw_aes_hash_init(hw_aes_hash_setup *setup);
/**
* \brief AES/Hash restart.
*
* This function restarts the AES/Hash engine. This function can be used when the engine waits for
* more input data.
*
* \param [in] sourceAddress The start address of the data that needs to be processed.
* \param [in] dataSize The number of bytes that need to be processed. If this number is not
* a multiple of a block size, the data is automatically extended with zeros.
* \param [in] moreDataToCome When false this is the last data block. When true more data is to
* come.
*
*/
void hw_aes_hash_restart(const uint32 sourceAddress, const uint32 dataSize,
const bool moreDataToCome);
/**
* \brief AES/Hash is active.
*
* This function tells if the AES/Hash engine is active or not.
*
* \return True if the AES/Hash engine is active and false when it is inactive.
*
*/
bool hw_aes_hash_is_active();
/**
* \brief AES/Hash is waiting for more data.
*
* This function tells if the AES/Hash engine is waiting for more data or not.
*
* \return True if the AES/Hash engine is waiting more data and false when it is not.
*
*/
bool hw_aes_hash_wait_for_in();
/**
* \brief AES/Hash disable.
*
* This function disables the AES/HASH engine and its interrupt request signal.
*
* \param [in] waitTillInactive When true the AES/HASH engine is disabled after any pending operation
* finishes. When false the AES/Hash is disabled immediately.
*
*/
void hw_aes_hash_disable(const bool waitTillInactive);
/**
* \brief Mark next input block as being last
*
* This function is used to configure the engine so as to consider the next input block
* as the last of the operation. When the operation finishes, the engine's status
* becomes "inactive".
*/
__STATIC_INLINE void hw_aes_hash_mark_input_block_as_last(void)
{
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN);
}
/**
* \brief Mark next input block as not being last
*
* This function is used to configure the engine so as to expect more input blocks
* after the operation. When the operation finishes, the engine's status
* becomes "waiting for input".
*/
__STATIC_INLINE void hw_aes_hash_mark_input_block_as_not_last(void)
{
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN);
}
/**
* \brief Configure engine for AES ECB encryption/decryption
*
* This function configures the engine for AES ECB encryption/decryption
*
* \param[in] key_size The size of the key used in the encryption/decryption
*
* \warning AES ECB is not recommended for use in cryptographic protocols.
*/
__STATIC_INLINE void hw_aes_hash_cfg_aes_ecb(hw_aes_key_size key_size)
{
uint32 crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg, key_size);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for AES CTR encryption/decryption
*
* This function configures the engine for AES CTR encryption/decryption
*
* \param[in] key_size The size of the key used in the encryption/decryption
*/
__STATIC_INLINE void hw_aes_hash_cfg_aes_ctr(hw_aes_key_size key_size)
{
uint32 crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 2);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg, key_size);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for AES CBC encryption/decryption
*
* This function configures the engine for AES CBC encryption/decryption
*
* \param[in] key_size The size of the key used in the encryption/decryption
*/
__STATIC_INLINE void hw_aes_hash_cfg_aes_cbc(hw_aes_key_size key_size)
{
uint32 crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 3);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg, key_size);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for MD5 hash
*
* This function configures the engine to perform MD5 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 16. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_md5(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 16)? 15: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for SHA1 hash
*
* This function configures the engine to perform SHA1 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 20. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_sha1(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 20)? 19: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 1);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for SHA-224 hash
*
* This function configures the engine to perform SHA-224 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 28. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_sha_224(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 28)? 27: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 2);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for SHA-256 hash
*
* This function configures the engine to perform SHA-256 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 32. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_sha_256(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 32)? 31: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 3);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for SHA-384 hash
*
* This function configures the engine to perform SHA-384 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 48. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_sha_384(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 48)? 47: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 0);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for SHA-512 hash
*
* This function configures the engine to perform SHA-512 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 64. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_sha_512(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 64)? 63: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 1);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for SHA-512/224 hash
*
* This function configures the engine to perform SHA-512/224 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 28. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_sha_512_224(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 28)? 27: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 2);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Configure engine for SHA-512/256 hash
*
* This function configures the engine to perform SHA-512/256 hashing
*
* \param[in] result_size The size in bytes of the result that the engine will write
* to the output memory. Accepted values are 1 to 32. Out of
* range values are adjusted to the closest limit.
*/
__STATIC_INLINE void hw_aes_hash_cfg_sha_512_256(unsigned int result_size)
{
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(result_size > 32)? 31: (result_size == 0)? 0 : (result_size - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypto_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypto_ctrl_reg, 3);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
}
/**
* \brief Store initialization vector in AES/HASH engine memory
*
* This function stores the initialization vector (IV) that is necessary for AES CBC
* mode.
*
*
* \sa hw_aes_store_ic
*
* \param[in] iv The address of the buffer containing the initialization vector
*/
void hw_aes_hash_store_iv(const uint8 *iv);
/**
* \brief Store counter initialization in AES/HASH engine memory
*
* This function stores the counter initialization that is necessary for AES CTR
* mode.
*
*
* \sa hw_aes_store_iv
*
* \param[in] ic The address of the buffer containing the counter initialization
*/
void hw_aes_hash_store_ic(const uint8 *ic);
/**
* \brief Store AES keys in AES/HASH engine memory
*
* This function stores the keys used for AES encryption/decryption in AES/HASH engine memory.
* If key expansion is performed by the engine, then aes_keys should contain only the base
* key. Otherwise it should contain all the expanded keys.
*
* \note
* After an AES operation with a certain key, further operations using the same key do not
* need storing it to the AES/HASH memory again.
*
* \param[in] key_size The size of the key used in the encryption/decryption
* \param[in] aes_keys The address of the buffer containing the keys
* \param[in] key_exp Define if key expansion will be performed by hw or sw
*/
void hw_aes_hash_store_keys(hw_aes_key_size key_size, const uint8 *aes_keys, hw_aes_hash_key_exp_t key_exp);
/**
* \brief Configure DMA for data manipulation
*
* This function configures the DMA machine with the source and destination buffers.
*
* \param[in] src The physical address of the buffer containing the input data for the operation
* \param[in] dst The physical address (RAM or Cache RAM only) of the buffer where the output of the
* operation will be stored. The dst address must be NULL when configuring the DMA
* while the engine is waiting for more input data.
* \param[in] len The length of the input data
*/
void hw_aes_hash_cfg_dma(const uint8 *src, uint8 *dst, unsigned int len);
/**
* \brief Start AES/HASH engine operation
*
* This function starts a AES/HASH operation. The operation depends on the configuration that
* has been applied before calling this function
*
* \sa hw_aes_hash_init
*
*/
__STATIC_INLINE void hw_aes_hash_start(void)
{
AES_HASH->CRYPTO_START_REG = 1;
}
/**
* \brief Start AES encryption
*
* This function starts an AES encryption. AES mode, key and input/output data should be configured
* before calling this function.
*
* \sa hw_aes_hash_init
* \sa hw_aes_hash_cfg_aes_ecb
* \sa hw_aes_hash_cfg_aes_ctr
* \sa hw_aes_hash_cfg_aes_cbc
* \sa hw_aes_hash_store_keys
* \sa hw_aes_hash_cfg_dma
*/
__STATIC_INLINE void hw_aes_hash_encrypt(void)
{
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC);
AES_HASH->CRYPTO_START_REG = 1;
}
/**
* \brief Start AES decryption
*
* This function starts an AES decryption. AES mode, key and input/output data should be configured
* before calling this function.
*
* \sa hw_aes_hash_init
* \sa hw_aes_hash_cfg_aes_ecb
* \sa hw_aes_hash_cfg_aes_ctr
* \sa hw_aes_hash_cfg_aes_cbc
* \sa hw_aes_hash_store_keys
* \sa hw_aes_hash_cfg_dma
*/
__STATIC_INLINE void hw_aes_hash_decrypt(void)
{
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC);
AES_HASH->CRYPTO_START_REG = 1;
}
/**
* \brief Enable AES/HASH engine interrupt
*
* This function enables the AES/HASH engine interrupt and sets a callback function
* to be called when the interrupt occurs.
*
* \param[in] cb The callback function for the interrupt
*
* \deprecated Consider using hw_crypto API along with hw_aes_hash_enable_interrupt_source()
*/
DEPRECATED_MSG("consider using hw_crypto API along with hw_aes_hash_enable_interrupt_source")
void hw_aes_hash_enable_interrupt(hw_aes_hash_cb cb);
/**
* \brief Disable AES/HASH engine interrupt
*
* This function disables the AES/HASH engine interrupt.
*
* \deprecated Consider using hw_crypto API along with hw_aes_hash_disable_interrupt_source()
*/
DEPRECATED_MSG("consider using hw_crypto API along with hw_aes_hash_disable_interrupt_source")
void hw_aes_hash_disable_interrupt(void);
/**
* \brief Enable AES/HASH engine interrupt source
*
* This function enables AES/HASH engine interrupt source.
*
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
* function does not enable the CRYPTO interrupt itself. Use hw_crypto_enable_aes_hash_interrupt()
* in addition, in order to enable the CRYPTO interrupt.
*/
static inline void hw_aes_hash_enable_interrupt_source(void)
{
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
}
/**
* \brief Disable AES/HASH engine interrupt source
*
* This function disables AES/HASH engine interrupt source.
*
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
* function does not disable the CRYPTO interrupt itself. Use hw_crypto_disable_aes_hash_interrupt()
* in order to disable the CRYPTO interrupt.
*/
static inline void hw_aes_hash_disable_interrupt_source(void)
{
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
}
/**
* \brief Clear AES/HASH engine pending interrupt
*
* This function clears AES/HASH engine pending interrupt request.
*
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
* function does not clear pending CRYPTO interrupt. Use hw_crypto_clear_pending_interrupt()
* in order to clear pending CRYPTO interrupt.
*/
static inline void hw_aes_hash_clear_interrupt_req(void)
{
AES_HASH->CRYPTO_CLRIRQ_REG = 0x1;
}
/**
* \brief Set output mode to write all
*
* This function configures the AES/HASH engine to write back to memory all the
* resulting data.
*
* \note
* Only applicable to AES operations.
*/
__STATIC_INLINE void hw_aes_hash_output_mode_write_all(void)
{
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD);
}
/**
* \brief Set output mode to write final
*
* This function configures the AES/HASH engine to write back to memory only the
* the last block of the resulting data.
*
* \note
* Only applicable to AES operations.
*/
__STATIC_INLINE void hw_aes_hash_output_mode_write_final(void)
{
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD);
}
/**
* \brief Check input data size restriction
*
* This function checks the restrictions of input data length. It returns 0 if the restrictions are not
* violated, -1 otherwise. It checks the configured values at the time it is called so it should be
* used just before starting an operation. The function can be useful for debugging. The following
* table summarizes the restrictions for the input data length.
*
* ALGORITHM | NOT LAST DATA BLOCK | LAST DATA BLOCK
* ------------------- | --------------------- | ----------------
* HW_AES_ECB | multiple of 16 | multiple of 16
* HW_AES_CBC | multiple of 16 | no restrictions
* HW_AES_CTR | multiple of 16 | no restrictions
* HW_HASH_MD5 | multiple of 8 | no restrictions
* HW_HASH_SHA_1 | multiple of 8 | no restrictions
* HW_HASH_SHA_256_224 | multiple of 8 | no restrictions
* HW_HASH_SHA_256 | multiple of 8 | no restrictions
* HW_HASH_SHA_384 | multiple of 8 | no restrictions
* HW_HASH_SHA_512 | multiple of 8 | no restrictions
* HW_HASH_SHA_512_224 | multiple of 8 | no restrictions
* HW_HASH_SHA_512_256 | multiple of 8 | no restrictions
*
*/
int hw_aes_hash_check_restrictions(void);
#endif /* dg_configUSE_HW_AES_HASH */
#endif /* HW_AES_HASH_H_ */
/**
* \}
* \}
* \}
*/
File diff suppressed because it is too large Load Diff
@@ -1,108 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup CRYPTO
* \{
* \brief Interrupt handling for the crypto engines (AES/HASH, ECC)
*/
/**
****************************************************************************************
*
* @file hw_crypto.h
*
* @brief Interrupt handling API for the AES/Hash and ECC Engines.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC)
#include "sdk_defs.h"
/**
* \brief Crypto engines callback
*
* This function type is used for callbacks called when the crypto engines (AES/HASH, ECC)
* generate an interrupt.
*
* \param [in] status The status register (either AES/HASH or ECC) at the time of the interrupt.
*
*/
typedef void (*hw_crypto_cb)(unsigned int status);
/**
* \brief Enable interrupt for AES/HASH crypto engine.
*
* \param [in] cb A callback to be called when interrupt occurs. It must always be provided.
*
* \note AES/HASH engine and ECC engine are common sources of CRYPTO system interrupt. This
* function only enables CRYPTO interrupt itself and registers a callback for AES/HASH
* related CRYPTO interrupts. In order to fully enable AES/HASH interrupts
* hw_aes_hash_enable_interrupt_source() must also be called
*/
void hw_crypto_enable_aes_hash_interrupt(hw_crypto_cb cb);
/**
* \brief Enable interrupt for ECC crypto engine.
*
* \param [in] cb A callback to be called when interrupt occurs. It must always be provided.
*/
void hw_crypto_enable_ecc_interrupt(hw_crypto_cb cb);
/**
* \brief Disable interrupt for AES/HASH crypto engine.
*/
void hw_crypto_disable_aes_hash_interrupt(void);
/**
* \brief Disable interrupt for ECC crypto engine.
*/
void hw_crypto_disable_ecc_interrupt(void);
/**
* \brief Clear pending interrupt from AES/HASH and ECC crypto engines.
*
* \note This function clears the pending CRYPTO interrupt only on the NVI Controller.
* Use hw_aes_hash_clear_interrupt_req() and hw_ecc_clear_interrupt_source() to clear the
* source of CRYPTO interrupt on the AES/HASH and ECC engines respectively.
*/
static inline void hw_crypto_clear_pending_interrupt(void)
{
NVIC_ClearPendingIRQ(CRYPTO_IRQn);
}
#endif /* (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC) */
/**
* \}
* \}
* \}
*/
@@ -1,382 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup DMA
* \{
* \brief DMA Controller
*/
/**
****************************************************************************************
*
* @file hw_dma.h
*
* @brief Definition of API for the DMA Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_DMA_H_
#define HW_DMA_H_
#if dg_configUSE_HW_DMA
#include <stdint.h>
#include <sdk_defs.h>
/*
* ENUMERATION DEFINITIONS
*****************************************************************************************
*/
/**
* \brief DMA channel number
*
*/
typedef enum {
HW_DMA_CHANNEL_0 = 0, /**< Channel number 0 */
HW_DMA_CHANNEL_1 = 1, /**< Channel number 1 */
HW_DMA_CHANNEL_2 = 2, /**< Channel number 2 */
HW_DMA_CHANNEL_3 = 3, /**< Channel number 3 */
HW_DMA_CHANNEL_4 = 4, /**< Channel number 4 */
HW_DMA_CHANNEL_5 = 5, /**< Channel number 5 */
HW_DMA_CHANNEL_6 = 6, /**< Channel number 6 */
HW_DMA_CHANNEL_7 = 7, /**< Channel number 7 */
HW_DMA_CHANNEL_INVALID = 8 /**< Invalid Channel number */
} HW_DMA_CHANNEL;
/**
* \brief DMA channel enable/disable
*
*/
typedef enum {
HW_DMA_STATE_DISABLED = 0x0, /**< DMA disabled */
HW_DMA_STATE_ENABLED = 0x1 /**< DMA enabled */
} HW_DMA_STATE;
/**
* \brief DMA channel bus width transfer
*
*/
typedef enum {
HW_DMA_BW_BYTE = 0x0, /**< Byte */
HW_DMA_BW_HALFWORD = 0x2, /**< Halfword */
HW_DMA_BW_WORD = 0x4 /**< Word */
} HW_DMA_BW;
/**
* \brief DMA channel interrupt enable/disable
*
*/
typedef enum {
HW_DMA_IRQ_STATE_DISABLED = 0x0, /**< Disable interrupt on this channel */
HW_DMA_IRQ_STATE_ENABLED = 0x8 /**< Enable interrupt on this channel */
} HW_DMA_IRQ_STATE;
/**
* \brief DMA request input multiplexer controlled
*
*/
typedef enum {
HW_DMA_DREQ_START = 0x0, /**< DMA channel starts immediately */
HW_DMA_DREQ_TRIGGERED = 0x10 /**< DMA channel must be triggered by peripheral DMA request */
} HW_DMA_DREQ;
/**
* \brief Increment destination address mode
*
*/
typedef enum {
HW_DMA_BINC_FALSE = 0x0, /**< Do not increment */
HW_DMA_BINC_TRUE = 0x20 /**< Increment according value of BW */
} HW_DMA_BINC;
/**
* \brief Increment of source address mode
*
*/
typedef enum {
HW_DMA_AINC_FALSE = 0x0, /**< Do not increment */
HW_DMA_AINC_TRUE = 0x40 /**< Increment according value of BW */
} HW_DMA_AINC;
/**
* \brief Channel mode
*
* In normal mode the DMA transfer stops the transfer after
* length DMAx_LEN_REG.
* In circular mode the DMA channel repeats the transfer
* after length DMAx_LEN_REG with the initial register values
* DMAx_A_START_REG, DMAx_B_START_REG, DMAx_LEN_REG, DMAx_INT_REG.
*
* \note only works if DREQ_MODE = 1
*
*/
typedef enum {
HW_DMA_MODE_NORMAL = 0x0, /**< Normal mode */
HW_DMA_MODE_CIRCULAR = 0x80 /**< Circular mode */
} HW_DMA_MODE;
/**
* \brief Channel priority
*
* Set priority level of DMA channel to determine which DMA
* channel will be activated in case more than one DMA channel
* requests DMA.
*
*/
typedef enum {
HW_DMA_PRIO_0 = 0x000, /**< Lowest priority */
HW_DMA_PRIO_1 = 0x100, /**< .. */
HW_DMA_PRIO_2 = 0x200, /**< .. */
HW_DMA_PRIO_3 = 0x300, /**< .. */
HW_DMA_PRIO_4 = 0x400, /**< .. */
HW_DMA_PRIO_5 = 0x500, /**< .. */
HW_DMA_PRIO_6 = 0x600, /**< .. */
HW_DMA_PRIO_7 = 0x700 /**< Highest priority */
} HW_DMA_PRIO;
/**
* \brief DMA idle mode
*
* In blocking mode the DMA performs a fast back-to-back
* copy, disabling bus access for any bus master with lower priority.
* In interrupting mode the DMA inserts a wait cycle after each
* store allowing the CR16 to steal cycles or cache to perform a
* burst read.
*
* \note if DREQ_MODE = 1, DMA_IDLE does not have any effect
*
*/
typedef enum {
HW_DMA_IDLE_BLOCKING_MODE = 0x000, /**< Blocking mode */
HW_DMA_IDLE_INTERRUPTING_MODE = 0x800 /**< Interrupting mode */
} HW_DMA_IDLE;
/**
* \brief DMA init mode
*
*/
typedef enum {
HW_DMA_INIT_AX_BX_AY_BY = 0x0000, /**< DMA performs copy A1 to B1, A2 to B2 */
HW_DMA_INIT_AX_BX_BY = 0x1000 /**< DMA performs copy A1 to B1, B2 */
} HW_DMA_INIT;
/**
* \brief Channel request trigger
*
*/
typedef enum {
HW_DMA_TRIG_SPI_RXTX = 0x0,
HW_DMA_TRIG_SPI2_RXTX = 0x1,
HW_DMA_TRIG_UART_RXTX = 0x2,
HW_DMA_TRIG_UART2_RXTX = 0x3,
HW_DMA_TRIG_I2C_RXTX = 0x4,
HW_DMA_TRIG_I2C2_RXTX = 0x5,
HW_DMA_TRIG_USB_RXTX = 0x6,
HW_DMA_TRIG_I2S_LEFTRIGHT = 0x8,
HW_DMA_TRIG_PDM_LEFTRIGHT = 0x9,
HW_DMA_TRIG_FTDF_RXTX = 0xA,
HW_DMA_TRIG_ECC_RXTX = 0xB,
HW_DMA_TRIG_ADC = 0xC,
HW_DMA_TRIG_NONE = 0xF
} HW_DMA_TRIG;
/**
* \brief DMA channel transfer callback
*
* This function is called by the DMA driver when the
* interrupt is fired.
*
* \param [in] user_data transfered data
* \param [in] len length of transfered data
*
*/
typedef void (*hw_dma_transfer_cb)(void *user_data, uint16_t len);
/**
* \brief DMA parameters structure
*
*/
typedef struct {
HW_DMA_CHANNEL channel_number; /**< DMA Channel Number to be used */
HW_DMA_BW bus_width; /**< Transfer Bus width: 8, 16 or 32 bits */
HW_DMA_IRQ_STATE irq_enable; /**< Enable or disable IRQ generation */
uint16 irq_nr_of_trans; /**< Number of transfers before IRQ generation
set to 0 to fire IRQ after transfer ends */
HW_DMA_DREQ dreq_mode; /**< Start DMA immediately or triggered by peripheral */
HW_DMA_AINC a_inc; /**< Increment of source address */
HW_DMA_BINC b_inc; /**< Increment of destination address */
HW_DMA_MODE circular; /**< Select normal or circular operation */
HW_DMA_PRIO dma_prio; /**< Channel priority from 0 to 7 */
HW_DMA_IDLE dma_idle; /**< Idle mode: blocking or interrupting */
HW_DMA_INIT dma_init; /**< Copy mode: block copy or mem init */
HW_DMA_TRIG dma_req_mux; /**< DMA trigger */
uint32 src_address; /**< Source address */
uint32 dest_address; /**< Destination address */
uint16 length; /**< Number of DMA transfers */
hw_dma_transfer_cb callback; /**< Function to call after irq_nr_of_trans transfers */
void *user_data; /**< Data to pass to Callback */
} DMA_setup;
/*
* API FUNCTIONS DEFINITIONS
*****************************************************************************************
*/
/**
* \brief Initialize DMA Channel
*
* \param [in] channel_setup pointer to struct of type DMA_Setup
*
*/
void hw_dma_channel_initialization(DMA_setup *channel_setup);
/**
* \brief Update DMA source address and length
*
* When DMA is configured for some peripheral, it could be enough to setup only source address
* and data length. Other parameters most likely do not change for same type of transmission
* for values that ware specified in \p hw_dma_channel_initialization().
* This function should speed up DMA start time when only address and size changes from previous
* transmission.
*
* \param [in] channel DMA channel number to modify
* \param [in] addr new source address
* \param [in] length new data transfer length
* \param [in] cb function to call after transmission finishes
*
*/
void hw_dma_channel_update_source(HW_DMA_CHANNEL channel, void* addr, uint16_t length,
hw_dma_transfer_cb cb);
/**
* \brief Update DMA destination address and length
*
* When DMA is configured for some peripheral, it could be enough to setup only destination address
* and data length. Other parameters most likely do not change for same type of transmission
* for values that ware specified in \p hw_dma_channel_initialization().
* This function should speed up DMA start time when only address and size changes from previous
* transmission.
*
* \param [in] channel DMA channel number to modify
* \param [in] addr new source address
* \param [in] length new data transfer length
* \param [in] cb function to call after transmission finishes
*
*/
void hw_dma_channel_update_destination(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
hw_dma_transfer_cb cb);
/**
* \brief Update DMA interrupt trigger index
*
* DMA channel can trigger an interrupt after arbitrary transfer has finished.
* Usually interrupt is triggered after transmission finishes but for cyclic mode,
* where DMA never stops, it is convenient trigger interrupt at other times.
* This function allows to specify the number of transfers after which the interrupt is triggered.
*
* \param [in] channel DMA channel number to modify
* \param [in] int_ix Number of transfers until the interrupt is triggered
*
*/
void hw_dma_channel_update_int_ix(HW_DMA_CHANNEL channel, uint16_t int_ix);
/**
* \brief Enable or disable a DMA channel
*
* \param [in] channel_number DMA Channel Number to start/stop
* \param [in] dma_on enable/disable DMA channel
*
*/
void hw_dma_channel_enable(HW_DMA_CHANNEL channel_number, HW_DMA_STATE dma_on);
/**
* \brief Stop DMA channel if operation is in progress
*
* If no transfer is in progress nothing happens.
* If there is outstanding DMA transfer it will be stopped and
* callback will be called with count of data already transfered
*
* \param [in] channel_number DMA channel number to stop
*
*/
void hw_dma_channel_stop(HW_DMA_CHANNEL channel_number);
/**
* \brief Read number of transmitted bytes so far
*
* Use this function to see how many bytes were transfered
* via DMA channel so far. This number can changed very soon.
*
* \param [in] channel_number DMA channel number
*
* \return number of bytes already transfered (when transfer is in progress),
* 0 - if transfer is already finished,
* undefined if called or not started channel
*
*/
uint16_t hw_dma_transfered_bytes(HW_DMA_CHANNEL channel_number);
/**
* \brief Freeze DMA
*
*/
static inline void hw_dma_freeze(void)
{
GPREG->SET_FREEZE_REG = REG_MSK(GPREG, SET_FREEZE_REG, FRZ_DMA);
}
/**
* \brief Unfreeze DMA
*
*/
static inline void hw_dma_unfreeze(void)
{
GPREG->RESET_FREEZE_REG = REG_MSK(GPREG, RESET_FREEZE_REG, FRZ_DMA);
}
/**
* \brief Check if any DMA channel is active.
*
* \return true, if a channel is active else false.
*/
bool hw_dma_channel_active(void);
#endif /* dg_configUSE_HW_DMA */
#endif /* HW_DMA_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,767 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup GPADC
* \{
* \brief General Purpose ADC
*/
/**
*****************************************************************************************
*
* @file hw_gpadc.h
*
* @brief Definition of API for the GPADC Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_GPADC_H
#define HW_GPADC_H
#if dg_configUSE_HW_GPADC
#include <stdbool.h>
#include <stdint.h>
#include <sdk_defs.h>
extern int16_t hw_gpadc_differential_gain_error;
extern int16_t hw_gpadc_single_ended_gain_error;
/**
* \brief ADC input mode
*
*/
typedef enum {
HW_GPADC_INPUT_MODE_DIFFERENTIAL = 0, /**< differential mode (default) */
HW_GPADC_INPUT_MODE_SINGLE_ENDED = 1 /**< single ended mode */
} HW_GPADC_INPUT_MODE;
/**
* \brief ADC clock source
*
*/
typedef enum {
HW_GPADC_CLOCK_INTERNAL = 0, /**< internal high-speed clock (default) */
HW_GPADC_CLOCK_DIGITAL = 1 /**< digital clock (16/96MHz) */
} HW_GPADC_CLOCK;
/**
* \brief ADC input
*
* \p GPADC_INPUT_SE_* values should be used only in single ended mode
* \p GPADC_INPUT_DIFF_* values should be used only in differential mode
*
*/
typedef enum {
HW_GPADC_INPUT_SE_P12 = 0, /**< GPIO 1.2 */
HW_GPADC_INPUT_SE_P14 = 1, /**< GPIO 1.4 */
HW_GPADC_INPUT_SE_P13 = 2, /**< GPIO 1.3 */
HW_GPADC_INPUT_SE_P07 = 3, /**< GPIO 0.7 */
HW_GPADC_INPUT_SE_AVS = 4, /**< analog ground level */
HW_GPADC_INPUT_SE_VDD = 5,
HW_GPADC_INPUT_SE_VDCDC = 6,
HW_GPADC_INPUT_SE_V33 = 7,
HW_GPADC_INPUT_SE_VBAT = 9, /**< battery */
HW_GPADC_INPUT_SE_TEMPSENS = 14, /**< temperature sensor */
HW_GPADC_INPUT_SE_P06 = 16, /**< GPIO 0.6 */
HW_GPADC_INPUT_SE_P10 = 17, /**< GPIO 1.0 */
HW_GPADC_INPUT_SE_P15 = 18, /**< GPIO 1.5 */
HW_GPADC_INPUT_SE_P24 = 19, /**< GPIO 2.4 */
HW_GPADC_INPUT_DIFF_P12_P14 = 0, /**< GPIO 1.2 vs 1.4 */
HW_GPADC_INPUT_DIFF_P13_P07 = 1, /**< GPIO 1.3 vs 0.7 */
} HW_GPADC_INPUT;
/**
* \brief ADC interrupt handler
*
*/
typedef void (*hw_gpadc_interrupt_cb)(void);
/**
* \brief ADC configuration
*
*/
typedef struct {
HW_GPADC_CLOCK clock; /**< clock source */
HW_GPADC_INPUT_MODE input_mode; /**< input mode */
HW_GPADC_INPUT input; /**< ADC input */
uint8_t sample_time; /**< sample time */
bool continous; /**< continous mode state */
uint8_t interval; /**< interval between conversions in continous mode */
bool input_attenuator; /**< input attenuator state */
bool chopping; /**< chopping state */
uint8_t oversampling; /**< oversampling value */
} gpadc_config;
/**
* \brief Initialize ADC
*
* \p cfg can be NULL - no configuration is performed in such case.
*
* \param [in] cfg configuration
*
*/
void hw_gpadc_init(const gpadc_config *cfg);
/**
* \brief Configure ADC
*
* Shortcut to call appropriate configuration function. If \p cfg is NULL, this function does
* nothing.
*
* \param [in] cfg configuration
*
*/
void hw_gpadc_configure(const gpadc_config *cfg);
/**
* \brief Reset ADC to its default values without disabling the LDO.
*
*/
void hw_gpadc_reset(void);
/**
* \brief Register interrupt handler
*
* Interrupt is enabled after calling this function. Application is responsible for clearing
* interrupt using hw_gpadc_clear_interrupt(). If no callback is specified interrupt is cleared by
* driver.
*
* \param [in] cb callback fired on interrupt
*
* \sa hw_gpadc_clear_interrupt
*
*/
void hw_gpadc_register_interrupt(hw_gpadc_interrupt_cb cb);
/**
* \brief Unregister interrupt handler
*
* Interrupt is disabled after calling this function.
*
*/
void hw_gpadc_unregister_interrupt(void);
/**
* \brief Clear interrupt
*
* Application should call this in interrupt handler to clear interrupt.
*
* \sa hw_gpadc_register_interrupt
*
*/
static inline void hw_gpadc_clear_interrupt(void)
{
GPADC->GP_ADC_CLEAR_INT_REG = 1;
}
/**
* \brief Enable ADC
*
* Sampling is started after calling this function, to start conversion application should call
* hw_gpadc_start().
*
* \sa hw_gpadc_start
*
*/
static inline void hw_gpadc_enable(void)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_EN, 1);
}
/**
* \brief Disable ADC
*
* Application should wait for conversion to be completed before disabling ADC. In case of
* continuous mode, application should disable continuous mode and then wait for conversion to be
* completed in order to have ADC in defined state.
*
* \sa hw_gpadc_in_progress
* \sa hw_gpadc_set_continuous
*
*/
static inline void hw_gpadc_disable(void)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_EN, 0);
}
/**
* \brief Set the delay required to enable the ADC_LDO.
*
* param [in] LDO enable delay
*
*/
static inline void hw_gpadc_set_ldo_delay(uint32_t delay)
{
REG_SETF(GPADC, GP_ADC_CTRL3_REG, GP_ADC_EN_DEL, delay);
}
/** \brief Perform ADC calibration
*
* Calibration is performed. The input mode must be HW_GPADC_INPUT_SE_VDD (1.2V).
* LDO constant and dynamic currents may be on. The input mode must be Single Ended. The calibration
* is performed only once.
*
* \sa hw_gpadc_set_input_mode
*
*/
void hw_gpadc_calibrate(void);
/**
* \brief Start conversion
*
* Application should not call this function while conversion is still in progress.
*
* \sa hw_gpadc_in_progress
*
*/
static inline void hw_gpadc_start(void)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_START, 1);
}
/**
* \brief Check if conversion is in progress
*
* \return conversion state
*
*/
static inline bool hw_gpadc_in_progress(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_START);
}
/**
* \brief Set continuous mode
*
* With continuous mode enabled ADC will automatically restart conversion once completed. It's still
* required to start 1st conversion using hw_gpadc_start(). Interval between subsequent conversions
* can be adjusted using hw_gpadc_set_interval().
*
* \param [in] enabled continuous mode state
*
* \sa hw_gpadc_start
* \sa hw_gpadc_set_interval
*
*/
static inline void hw_gpadc_set_continuous(bool enabled)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CONT, !!enabled);
}
/**
* \brief Get continuous mode state
*
* \return continuous mode state
*
*/
static inline bool hw_gpadc_get_continuous(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CONT);
}
/**
* \brief Set input channel
*
* Application is responsible for using proper input symbols depending on whether single ended or
* differential mode is used.
*
* \param [in] input input channel
*
* \sa hw_gpadc_set_input_mode
* \sa GPADC_INPUT_MODE
*
*/
static inline void hw_gpadc_set_input(HW_GPADC_INPUT input)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SEL, input);
}
/**
* \brief Get current input channel
*
* \return input channel
*
*/
static inline HW_GPADC_INPUT hw_gpadc_get_input(void)
{
return (HW_GPADC_INPUT) REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SEL);
}
/**
* \brief Set input mode
*
* \param [in] mode input mode
*
*/
static inline void hw_gpadc_set_input_mode(HW_GPADC_INPUT_MODE mode)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SE, mode);
}
/**
* \brief Get current input mode
*
* return input mode
*
*/
static inline HW_GPADC_INPUT_MODE hw_gpadc_get_input_mode(void)
{
return (HW_GPADC_INPUT_MODE) REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SE);
}
/**
* \brief Set clock source
*
* \param [in] clock clock source
*
*/
static inline void hw_gpadc_set_clock(HW_GPADC_CLOCK clock)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CLK_SEL, clock);
}
/**
* \brief Get current clock source
*
* \return clock source
*
*/
static inline HW_GPADC_CLOCK hw_gpadc_get_clock(void)
{
return (HW_GPADC_CLOCK) REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CLK_SEL);
}
/**
* \brief Set oversampling
*
* With oversampling enabled multiple successive conversions will be executed and results are added
* together to increase effective number of bits in result.
*
* Number of samples taken is 2<sup>\p n_samples</sup>. Valid values for \p n_samples are 0-7 thus
* at most 128 samples can be taken. In this case 17bits of result are generated with the least
* significant bit being discarded.
*
* \param [in] n_samples number of samples to be taken
*
* \sa hw_gpadc_get_raw_value
*
*/
static inline void hw_gpadc_set_oversampling(uint8_t n_samples)
{
REG_SETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_CONV_NRS, n_samples);
}
/**
* \brief Get current oversampling
*
* \return number of samples to be taken
*
* \sa hw_gpadc_set_oversampling
*
*/
static inline uint8_t hw_gpadc_get_oversampling(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_CONV_NRS);
}
/**
* \brief Set sample time
*
* Sample time is \p mult x 32 clock cycles or 1 clock cycle when \p mult is 0. Valid values are
* 0-15.
*
* \param [in] mult multiplier
*
*/
static inline void hw_gpadc_set_sample_time(uint8_t mult)
{
REG_SETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_SMPL_TIME, mult);
}
/**
* \brief Get current sample time
*
* \return multiplier
*
* \sa hw_gpadc_set_sample_time
*
*/
static inline uint8_t hw_gpadc_get_sample_time(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_SMPL_TIME);
}
/**
* \brief Set state of input attenuator
*
* Enabling internal attenuator scales input voltage by factor of 3 thus increasing effective input
* scale from 0-1.2V to 0-3.6V in single ended mode or from -1.2-1.2V to -3.6-3.6V in differential
* mode.
*
* \param [in] enabled attenuator state
*
*/
static inline void hw_gpadc_set_input_attenuator_state(bool enabled)
{
REG_SETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_ATTN3X, !!enabled);
}
/**
* \brief Get current state of input attenuator
*
* \return attenuator state
*
*/
static inline bool hw_gpadc_get_input_attenuator_state(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_ATTN3X);
}
/**
* \brief Set input mute state
*
* Once enabled, samples are taken at mid-scale to determine internal offset and/or notice of the
* ADC with regards to VDD_REF.
*
* \param [in] enabled mute state
*
* \sa hw_gpadc_calibrate
*
*/
static inline void hw_gpadc_set_mute(bool enabled)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_MUTE, !!enabled);
}
/**
* \brief Get current input mute state
*
* \return mute state
*
* \sa hw_gpadc_set_mute
*
*/
static inline bool hw_gpadc_get_mute(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_MUTE);
}
/**
* \brief Set input and output sign change
*
* Once enabled, sign of ADC input and output is changed.
*
* \param [in] enabled sign change state
*
*/
static inline void hw_gpadc_set_sign_change(bool enabled)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SIGN, !!enabled);
}
/**
* \brief Set input and output sign change
*
* \return sign change state
*
*/
static inline bool hw_gpadc_get_sign_change(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SIGN);
}
/**
* \brief Set chopping state
*
* Once enabled, two samples with opposite polarity are taken to cancel offset.
*
* \param [in] enabled chopping state
*
*/
static inline void hw_gpadc_set_chopping(bool enabled)
{
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CHOP, !!enabled);
}
/**
* \brief Get current chopping state
*
* \return chopping state
*
*/
static inline bool hw_gpadc_get_chopping(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CHOP);
}
/**
* \brief Set state of constant 20uA load current on ADC LDO output
*
* Constant 20uA load current on LDO output can be enabled so that the current will not drop to 0.
*
* \param [in] enabled load current state
*
*/
static inline void hw_gpadc_set_ldo_constant_current(bool enabled)
{
REG_SETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_I20U, !!enabled);
}
/**
* \brief Get current state of constant 20uA load current on ADC LDO output
*
* \return load current current state
*
* \sa hw_gpadc_set_ldo_constant_current
*
*/
static inline bool hw_gpadc_get_ldo_constant_current(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_I20U);
}
/**
* \brief Set state of dynamic 10uA load current on ADC LDO output
*
* 10uA load current on LDO output can be enabled during sample phase so that the load current
* during sampling and conversion phase becomes approximately the same.
*
* \param [in] enabled load current state
*
*/
static inline void hw_gpadc_set_ldo_dynamic_current(bool enabled)
{
REG_SETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_IDYN, !!enabled);
}
/**
* \brief Get current state of dynamic 10uA load current on ADC LDO output
*
* \return load current current state
*
* \sa hw_gpadc_set_ldo_dynamic_current
*
*/
static inline bool hw_gpadc_get_ldo_dynamic_current(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL2_REG, GP_ADC_IDYN);
}
/**
* \brief Set interval between conversions in continuous mode
*
* Interval time is \p mult x 1.024ms. Valid values are 0-255.
*
* \param [in] mult multiplier
*
* \sa hw_gpadc_set_continuous
*
*/
static inline void hw_gpadc_set_interval(uint8_t mult)
{
REG_SETF(GPADC, GP_ADC_CTRL3_REG, GP_ADC_INTERVAL, mult);
}
/**
* \brief Get current interval between conversions in continuous mode
*
* \return multiplier
*
* \sa hw_gpadc_set_interval
*
*/
static inline uint8_t hw_gpadc_get_interval(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL3_REG, GP_ADC_INTERVAL);
}
/**
* \brief Set offset adjustment for positive ADC array
*
* \param [in] offset offset value
*
* \sa hw_gpadc_calibrate
* \sa hw_gpadc_set_negative_offset
*
*/
static inline void hw_gpadc_set_offset_positive(uint16_t offset)
{
GPADC->GP_ADC_OFFP_REG = offset & REG_MSK(GPADC, GP_ADC_OFFP_REG, GP_ADC_OFFP);
}
/**
* \brief Get current offset adjustment for positive ADC array
*
* \return offset value
*
*/
static inline uint16_t hw_gpadc_get_offset_positive(void)
{
return GPADC->GP_ADC_OFFP_REG & REG_MSK(GPADC, GP_ADC_OFFP_REG, GP_ADC_OFFP);
}
/**
* \brief Set offset adjustment for negative ADC array
*
* \param [in] offset offset value
*
* \sa hw_gpadc_calibrate
* \sa hw_gpadc_set_positive_offset
*
*/
static inline void hw_gpadc_set_offset_negative(uint16_t offset)
{
GPADC->GP_ADC_OFFN_REG = offset & REG_MSK(GPADC, GP_ADC_OFFN_REG, GP_ADC_OFFN);
}
/**
* \brief Get current offset adjustment for negative ADC array
*
* \return offset value
*
*/
static inline uint16_t hw_gpadc_get_offset_negative(void)
{
return GPADC->GP_ADC_OFFN_REG & REG_MSK(GPADC, GP_ADC_OFFN_REG, GP_ADC_OFFN);
}
/**
* \brief Store Single Ended ADC Gain Error
*
* \param [in] single ADC Single Ended Gain Error
*
*/
static inline void hw_gpadc_store_se_gain_error(int16_t single)
{
hw_gpadc_single_ended_gain_error = single;
}
/**
* \brief Store Differential ADC Gain Error
*
* \param [in] diff ADC Differential Gain Error
*
*/
static inline void hw_gpadc_store_diff_gain_error(int16_t diff)
{
hw_gpadc_differential_gain_error = diff;
}
/**
* \brief Check the availability of ADC Gain Error
*
* \return ADC Gain Error availability
*
*/
static inline bool hw_gpadc_pre_check_for_gain_error(void)
{
if (dg_configUSE_ADC_GAIN_ERROR_CORRECTION == 1) {
return (hw_gpadc_single_ended_gain_error && hw_gpadc_differential_gain_error);
}
return false;
}
/**
* \brief Get raw conversion result value
*
* Upper 10 bits are always valid, lower 6 bits are only valid in case oversampling is enabled.
*
* \return conversion result value
*
* \sa hw_gpadc_start
* \sa hw_gpadc_set_oversampling
* \sa hw_gpadc_get_value
*
*/
uint16_t hw_gpadc_get_raw_value(void);
/**
* \brief Get conversion result value
*
* Invalid bits are discarded from result, i.e. oversampling is taken into account when calculating
* value.
*
* \return conversion result value
*
* \sa hw_gpadc_set_oversampling
* \sa hw_gpadc_get_raw_value
*
*/
static inline uint16_t hw_gpadc_get_value(void)
{
return hw_gpadc_get_raw_value() >> (6 - MIN(6, hw_gpadc_get_oversampling()));
}
/**
* \brief Get conversion result value without gain compensation and over sampling.
*
* \return conversion result value
*
*/
static inline uint16_t hw_gpadc_get_value_without_gain(void)
{
uint16_t adc_raw_res = GPADC->GP_ADC_RESULT_REG;
return adc_raw_res;
}
/**
* \brief Start a measurement and wait for the result.
*
* \sa hw_gpadc_start
* \sa hw_gpadc_in_progress
* \sa hw_gpadc_clear_interrupt
*
*/
void hw_gpadc_adc_measure(void);
/**
* \brief Take measurements using the ADC and evaluate the results.
*
* \sa hw_gpadc_adc_measure
* \sa hw_gpadc_get_raw_value
*
*/
void hw_gpadc_test_measurements(void);
#endif /* dg_configUSE_HW_GPADC */
#endif /* HW_GPADC_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,495 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup GPIO
* \{
* \brief GPIO Control
*/
/**
*****************************************************************************************
*
* @file hw_gpio.h
*
* @brief Definition of API for the GPIO Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_GPIO_H_
#define HW_GPIO_H_
#if dg_configUSE_HW_GPIO
#include <stdbool.h>
#include <stdint.h>
#include <sdk_defs.h>
/* GPIO layout definitions */
/** Number of GPIO ports available */
#define HW_GPIO_NUM_PORTS (5)
/** Number of GPIO pins available (cumulative) */
#define HW_GPIO_NUM_PINS (HW_GPIO_PORT_0_NUM_PINS + HW_GPIO_PORT_1_NUM_PINS + \
HW_GPIO_PORT_2_NUM_PINS + HW_GPIO_PORT_3_NUM_PINS + \
HW_GPIO_PORT_4_NUM_PINS)
/** Number of GPIO pins available in port 0 */
#define HW_GPIO_PORT_0_NUM_PINS (8)
/** Number of GPIO pins available in port 1 */
#define HW_GPIO_PORT_1_NUM_PINS (8)
/** Number of GPIO pins available in port 2 */
#define HW_GPIO_PORT_2_NUM_PINS (5)
/** Number of GPIO pins available in port 3 */
#define HW_GPIO_PORT_3_NUM_PINS (8)
/** Number of GPIO pins available in port 4 */
#define HW_GPIO_PORT_4_NUM_PINS (8)
/** Number of pins in each GPIO port */
extern const uint8_t hw_gpio_port_num_pins[HW_GPIO_NUM_PORTS];
/**
* \brief GPIO input/output mode
*
*/
typedef enum {
HW_GPIO_MODE_INPUT = 0, /**< GPIO as an input */
HW_GPIO_MODE_INPUT_PULLUP = 0x100, /**< GPIO as an input with pull-up */
HW_GPIO_MODE_INPUT_PULLDOWN = 0x200, /**< GPIO as an input with pull-down */
HW_GPIO_MODE_OUTPUT = 0x300, /**< GPIO as an (implicitly push-pull) output */
HW_GPIO_MODE_OUTPUT_PUSH_PULL = 0x300, /**< GPIO as an (explicitly push-pull) output */
HW_GPIO_MODE_OUTPUT_OPEN_DRAIN = 0x700, /**< GPIO as an open-drain output */
} HW_GPIO_MODE;
/**
* \brief GPIO power source
*
*/
typedef enum {
HW_GPIO_POWER_V33 = 0, /**< V33 (3.3 V) power rail */
HW_GPIO_POWER_VDD1V8P = 1, /**< VDD1V8P (1.8 V) power rail */
} HW_GPIO_POWER;
/**
* \brief GPIO port number
*
*/
typedef enum {
HW_GPIO_PORT_0 = 0, /**< GPIO Port 0 */
HW_GPIO_PORT_1 = 1, /**< GPIO Port 1 */
HW_GPIO_PORT_2 = 2, /**< GPIO Port 2 */
HW_GPIO_PORT_3 = 3, /**< GPIO Port 3 */
HW_GPIO_PORT_4 = 4 /**< GPIO Port 4 */
} HW_GPIO_PORT;
/**
* \brief GPIO pin number
*
*/
typedef enum {
HW_GPIO_PIN_0 = 0, /**< GPIO Pin 0 */
HW_GPIO_PIN_1 = 1, /**< GPIO Pin 1 */
HW_GPIO_PIN_2 = 2, /**< GPIO Pin 2 */
HW_GPIO_PIN_3 = 3, /**< GPIO Pin 3 */
HW_GPIO_PIN_4 = 4, /**< GPIO Pin 4 */
HW_GPIO_PIN_5 = 5, /**< GPIO Pin 5 */
HW_GPIO_PIN_6 = 6, /**< GPIO Pin 6 */
HW_GPIO_PIN_7 = 7, /**< GPIO Pin 7 */
} HW_GPIO_PIN;
/**
* \brief GPIO function
*
*/
typedef enum {
HW_GPIO_FUNC_GPIO = 0, /**< GPIO */
HW_GPIO_FUNC_UART_RX = 1, /**< GPIO as UART RX */
HW_GPIO_FUNC_UART_TX = 2, /**< GPIO as UART TX */
HW_GPIO_FUNC_UART_IRDA_RX = 3, /**< GPIO as UART IRDA RX */
HW_GPIO_FUNC_UART_IRDA_TX = 4, /**< GPIO as UART IRDA TX */
HW_GPIO_FUNC_UART2_RX = 5, /**< GPIO as UART2 RX */
HW_GPIO_FUNC_UART2_TX = 6, /**< GPIO as UART2 TX */
HW_GPIO_FUNC_UART2_IRDA_RX = 7, /**< GPIO as UART2 IRDA RX */
HW_GPIO_FUNC_UART2_IRDA_TX = 8, /**< GPIO as UART2 IRDA TX */
HW_GPIO_FUNC_UART2_CTSN = 9, /**< GPIO as UART2 CTSN */
HW_GPIO_FUNC_UART2_RTSN = 10, /**< GPIO as UART2 RTSN */
HW_GPIO_FUNC_SPI_DI = 11, /**< GPIO as SPI DI */
HW_GPIO_FUNC_SPI_DO = 12, /**< GPIO as SPI DO */
HW_GPIO_FUNC_SPI_CLK = 13, /**< GPIO as SPI CLK */
HW_GPIO_FUNC_SPI_EN = 14, /**< GPIO as SPI EN */
HW_GPIO_FUNC_SPI2_DI = 15, /**< GPIO as SPI2 DI */
HW_GPIO_FUNC_SPI2_DO = 16, /**< GPIO as SPI2 DO */
HW_GPIO_FUNC_SPI2_CLK = 17, /**< GPIO as SPI2 CLK */
HW_GPIO_FUNC_SPI2_EN = 18, /**< GPIO as SPI2 EN */
HW_GPIO_FUNC_I2C_SCL = 19, /**< GPIO as I2C SCL */
HW_GPIO_FUNC_I2C_SDA = 20, /**< GPIO as I2C SDA */
HW_GPIO_FUNC_I2C2_SCL = 21, /**< GPIO as I2C2 SCL */
HW_GPIO_FUNC_I2C2_SDA = 22, /**< GPIO as I2C2 SDA */
HW_GPIO_FUNC_PWM0 = 23, /**< GPIO as PWM0 */
HW_GPIO_FUNC_PWM1 = 24, /**< GPIO as PWM1 */
HW_GPIO_FUNC_PWM2 = 25, /**< GPIO as PWM2 */
HW_GPIO_FUNC_PWM3 = 26, /**< GPIO as PWM3 */
HW_GPIO_FUNC_PWM4 = 27, /**< GPIO as PWM4 */
HW_GPIO_FUNC_BLE_DIAG = 28, /**< GPIO as BLE DIAG */
HW_GPIO_FUNC_FTDF_DIAG = 29, /**< GPIO as FTDF DIAG */
HW_GPIO_FUNC_PCM_DI = 30, /**< GPIO as PCM DI */
HW_GPIO_FUNC_PCM_DO = 31, /**< GPIO as PCM DO */
HW_GPIO_FUNC_PCM_FSC = 32, /**< GPIO as PCM FSC */
HW_GPIO_FUNC_PCM_CLK = 33, /**< GPIO as PCM CLK */
HW_GPIO_FUNC_PDM_DI = 34, /**< GPIO as PDM DI */
HW_GPIO_FUNC_PDM_DO = 35, /**< GPIO as PDM DO */
HW_GPIO_FUNC_PDM_CLK = 36, /**< GPIO as PDM CLK */
HW_GPIO_FUNC_USB_SOF = 37, /**< GPIO as USB SOF */
HW_GPIO_FUNC_ADC = 38, /**< GPIO as ADC */
HW_GPIO_FUNC_USB = 38, /**< GPIO as USB */
HW_GPIO_FUNC_QSPI = 38, /**< GPIO as QSPI */
HW_GPIO_FUNC_XTAL32 = 38, /**< GPIO as XTAL32 */
HW_GPIO_FUNC_QUADEC_XA = 39, /**< GPIO as QUADEC XA */
HW_GPIO_FUNC_QUADEC_XB = 40, /**< GPIO as QUADEC XB */
HW_GPIO_FUNC_QUADEC_YA = 41, /**< GPIO as QUADEC YA */
HW_GPIO_FUNC_QUADEC_YB = 42, /**< GPIO as QUADEC YB */
HW_GPIO_FUNC_QUADEC_ZA = 43, /**< GPIO as QUADEC ZA */
HW_GPIO_FUNC_QUADEC_ZB = 44, /**< GPIO as QUADEC ZB */
HW_GPIO_FUNC_IR_OUT = 45, /**< GPIO as IR OUT */
HW_GPIO_FUNC_BREATH = 46, /**< GPIO as BREATH */
HW_GPIO_FUNC_KB_ROW = 47, /**< GPIO as KB ROW */
HW_GPIO_FUNC_COEX_EXT_ACT0 = 48, /**< GPIO as COEX EXT ACT0 */
HW_GPIO_FUNC_COEX_EXT_ACT1 = 49, /**< GPIO as COEX EXT ACT1 */
HW_GPIO_FUNC_COEX_SMART_ACT = 50, /**< GPIO as COEX SMART ACT */
HW_GPIO_FUNC_COEX_SMART_PRI = 51, /**< GPIO as COEX SMART PRI */
HW_GPIO_FUNC_CLOCK = 52, /**< GPIO as CLOCK */
HW_GPIO_FUNC_ONESHOT = 53, /**< GPIO as ONESHOT */
HW_GPIO_FUNC_PWM5 = 54, /**< GPIO as PWM5 */
HW_GPIO_FUNC_PORT0_DCF = 55, /**< GPIO as PORT0 DCF */
HW_GPIO_FUNC_PORT1_DCF = 56, /**< GPIO as PORT1 DCF */
HW_GPIO_FUNC_PORT2_DCF = 57, /**< GPIO as PORT2 DCF */
HW_GPIO_FUNC_PORT3_DCF = 58, /**< GPIO as PORT3 DCF */
HW_GPIO_FUNC_PORT4_DCF = 59, /**< GPIO as PORT4 DCF */
HW_GPIO_FUNC_RF_ANT_TRIM0 = 60, /**< GPIO as RF ANT TRIM0 */
HW_GPIO_FUNC_RF_ANT_TRIM1 = 61, /**< GPIO as RF ANT TRIM1 */
HW_GPIO_FUNC_RF_ANT_TRIM2 = 62 /**< GPIO as RF ANT TRIM2 */
} HW_GPIO_FUNC;
/**
* \brief GPIO pin configuration
*
* It's recommended to use \p HW_GPIO_PINCONFIG and \p HW_GPIO_PINCONFIG_RESERVE to set pin entries.
* Each configuration must be terminated using \p HW_GPIO_PINCONFIG_END macro.
*
*/
typedef struct {
uint8_t pin; /**< pin name, high-nibble is port number and low-nibble is pin */
HW_GPIO_MODE mode; /**< pin mode */
HW_GPIO_FUNC func; /**< pin function */
bool high; /**< initial pin state, true for high and false for low */
bool reserve; /*<< true if pin should be also reserved */
} __attribute__((packed)) gpio_config;
/**
* \brief GPIO pin configuration for \p gpio_config
*
* \p xport and \p xpin are specified as symbols from \p HW_GPIO_PORT and \p HW_GPIO_PIN enums
* respectively or more conveniently as plain numeric values.
* \p xmode and \p xfunc have the same values as defined in \p HW_GPIO_MODE and \p HW_GPIO_FUNC enums
* respectively, except they have prefix stripped.
*
* \param [in] xport port number
* \param [in] xpin pin number
* \param [in] xmode pin mode
* \param [in] xfunc pin function
* \param [in] xhigh true for high state, false otherwise
*
*/
#define HW_GPIO_PINCONFIG(xport, xpin, xmode, xfunc, xhigh) \
{ \
.pin = (xport << 4) | (xpin & 0x0F), \
.mode = HW_GPIO_MODE_ ## xmode, \
.func = HW_GPIO_FUNC_ ## xfunc, \
.high = xhigh, \
.reserve = false, \
}
/**
* \brief GPIO pin configuration and reservation for \p gpio_config
*
* This macro is virtually identical to \p HW_GPIO_PINCONFIG, except it also reserves pin.
*
* \param [in] xport port number
* \param [in] xpin pin number
* \param [in] xmode pin mode
* \param [in] xfunc pin function
* \param [in] xhigh true for high state, false otherwise
*
* \sa HW_GPIO_PINCONFIG
*
*/
#define HW_GPIO_PINCONFIG_RESERVE(xport, xpin, xmode, xfunc, xhigh) \
{ \
.pin = (xport << 4) | (xpin & 0x0F), \
.mode = HW_GPIO_MODE_ ## xmode, \
.func = HW_GPIO_FUNC_ ## xfunc, \
.high = xhigh, \
.reserve = true, \
}
/**
* \brief Macro to properly terminate array of \p gpio_config definition
*
*/
#define HW_GPIO_PINCONFIG_END \
{ \
.pin = 0xFF, \
}
/**
* \brief GPIO configuration
*
* This is a shortcut to configure multiple GPIOs in one call.
* \p cfg is an array of GPIO pins configuration, it should be terminated by dummy element with
* \p pin member set to 0xFF (macro \p HW_GPIO_PINCONFIG can be used for this purpose).
*
* \param [in] cfg GPIO pins configuration
*
* \sa hw_gpio_configure_pin
* \sa hw_gpio_set_pin_function
*
*/
void hw_gpio_configure(const gpio_config cfg[]);
/**
* \brief Reserve GPIO pin
*
* Reserve pin for exclusive usage.
* This macro can be used in application peripheral_setup function to detect
* usage of same GPIO pin by different applications.
*
* \param [in] port GPIO port number
* \param [in] pin GPIO pin number
*
* \return true if pin was successfully reserved and setup, false if pin was already reserved
*
*/
bool hw_gpio_reserve_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin);
/**
* \brief Reserve GPIO pin and set pin function
*
* Reserve pin and set up it function. If pin was already reserved do nothing.
*
* \param [in] port GPIO port number
* \param [in] pin GPIO pin number
* \param [in] mode GPIO access mode
* \param [in] function GPIO function
* \param [in] high in case of PID_GPIO and OUTPUT value to set on pin
*
* \return true if pin was successfully reserved and setup, false if pin was already reserved
*
*/
bool hw_gpio_reserve_and_configure_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE mode,
HW_GPIO_FUNC function, bool high);
/**
* \brief Unreserve GPIO pin
*
* Free reserved pin. If pin was not reserved do nothing.
* Configuration of pin does not change just reservation.
*
* \note If pin was reserved using RESERVE_GPIO it will also be unreserved.
* If RESERVE_GPIO was not enabled by compile time flags call to this function
* may cause unexpected result.
*
* \param [in] port GPIO port number
* \param [in] pin GPIO pin number
*
* \sa hw_gpio_reserve_and_configure_pin
* \sa hw_gpio_reserve_pin
* \sa RESERVE_GPIO
*
*/
void hw_gpio_unreserve_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin);
#if (DEBUG_GPIO_ALLOC_MONITOR_ENABLED == 1)
/**
* \brief Reserve GPIO pin
*
* Reserve pin for exclusive usage. If pin is already allocated trigger breakpoint.
* This macro should be used in application peripheral_setup function to detect
* usage of same GPIO pin by different applications.
*
* If runtime GPIO reservation is needed, use hw_gpio_reserve_pin,
* hw_gpio_reserve_and_configure_pin and hw_gpio_unreserve_pin instead.
*
* \param [in] name parameter ignored, used for debug only
* \param [in] port GPIO port number
* \param [in] pin GPIO pin number
* \param [in] func parameter ignored (for compatibility)
*
* \sa hw_gpio_reserve_pin
* \sa hw_gpio_reserve_and_configure_pin
* \sa hw_gpio_unreserve_pin instead
*
*/
#define RESERVE_GPIO(name, port, pin, func) \
do { \
if (!hw_gpio_reserve_pin((port), (pin))) { \
/* If debugger stops at this line, there is configuration problem */ \
/* pin is used without being reserved first */ \
__BKPT(0); /* this pin has not been previously reserved! */ \
} \
} while (0)
#else
#define RESERVE_GPIO( name, port, pin, func ) \
do { \
\
} while (0)
#endif // (DEBUG_GPIO_ALLOC_MONITOR_ENABLED == 1)
/**
* \brief Set the pin type and mode
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
* \param [in] mode GPIO pin mode
* \param [in] function GPIO pin usage
*
*/
void hw_gpio_set_pin_function(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE mode,
HW_GPIO_FUNC function);
/**
* \brief Get the pin type and mode
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
* \param [out] mode GPIO pin mode
* \param [out] function GPIO pin usage
*
*/
void hw_gpio_get_pin_function(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE* mode,
HW_GPIO_FUNC* function);
/**
* \brief Combined function to set the state and the type and mode of the GPIO pin
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
* \param [in] mode GPIO pin mode
* \param [in] function GPIO pin usage
* \param [in] high set to TRUE to set the pin into high else low
*
*/
void hw_gpio_configure_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE mode,
HW_GPIO_FUNC function, const bool high);
/**
* \brief Configure power source for pin output
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
* \param [in] power GPIO power source
*
*/
void hw_gpio_configure_pin_power(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_POWER power);
/**
* \brief Set a GPIO in high state
*
* The GPIO should have been previously configured as an output!
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
*
*/
void hw_gpio_set_active(HW_GPIO_PORT port, HW_GPIO_PIN pin);
/**
* \brief Set a GPIO in low state
*
* The GPIO should have been previously configured as an output!
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
*
*/
void hw_gpio_set_inactive(HW_GPIO_PORT port, HW_GPIO_PIN pin);
/**
* \brief Get the GPIO status
*
* The GPIO should have been previously configured as input!
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
*
* \return true if the pin is high, false if low
*
*/
bool hw_gpio_get_pin_status(HW_GPIO_PORT port, HW_GPIO_PIN pin);
/**
* \brief Toggle GPIO pin state
*
* \param [in] port GPIO port
* \param [in] pin GPIO pin
*
*/
void hw_gpio_toggle(HW_GPIO_PORT port, HW_GPIO_PIN pin);
/**
* \brief Find pins with specific function
*
* Function searches for pins configured for specific function.
* If buf is not NULL and buf_size is greater than 0 pins are stored in buf
* high-nibble is port number and low-nibble is pin.
* If number of pins found is greater then buf_size only buf_size entries are filled, though
* the returned number of found pins is correct.
*
* \param [in] func function to lookup
* \param [out] buf buffer for port-pin pairs that are configured for specific function
* \param [in] buf_size size of buf
*
* \return number of pins with specific function put in buf
* 0 - no pin is configured for this function
*
*/
int hw_gpio_get_pins_with_function(HW_GPIO_FUNC func, uint8_t *buf, int buf_size);
#endif /* dg_configUSE_HW_GPIO */
#endif /* HW_GPIO_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,72 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup Exception_Handlers
* \{
* \brief Generic Exception Handlers
*/
/**
*****************************************************************************************
*
* @file hw_hard_fault.h
*
* @brief Hard-Fault Handler include file.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_HARD_FAULT_H_
#define HW_HARD_FAULT_H_
#include <stdbool.h>
#include <stdint.h>
#include <sdk_defs.h>
#define HARDFAULT_MAGIC_NUMBER 0xBADC0FFE
/**
* \brief Holds the stack contents when a hard-fault occurs.
*
* \details The stack contents are copied at this variable when a hard-fault occurs. The first
* position is marked with a special "flag" (0xBADC0FFE) to indicate that the data that
* follow are valid.
*/
extern uint32_t hardfault_event_data[9];
#endif /* HW_HARD_FAULT_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,152 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup LED
* \{
* \brief LED Controller
*/
/**
*****************************************************************************************
*
* @file hw_led.h
*
* @brief Definition of API for the LED Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_LED_H_
#define HW_LED_H_
#include <sdk_defs.h>
/**
* \brief Source for LED1
*/
typedef enum {
HW_LED_SRC1_PWM2 = 0, /**< LED1 controlled by PWM2 */
HW_LED_SRC1_BREATH = 1 /**< LED1 controlled by Breath Timer */
} HW_LED_SRC1;
/**
* \brief Source for LED2
*/
typedef enum {
HW_LED_SRC2_PWM3 = 0, /**< LED2 controlled by PWM3 */
HW_LED_SRC2_BREATH = 1 /**< LED2 controlled by Breath Timer */
} HW_LED_SRC2;
/**
* \brief Source for LED3
*/
typedef enum {
HW_LED_SRC3_PWM4 = 0, /**< LED3 controlled by PWM4 */
HW_LED_SRC3_BREATH = 1 /**< LED3 controlled by Breath Timer */
} HW_LED_SRC3;
/**
* \brief Set the source that controls LED1
*
* \param [in] src the source that controls LED1
*
* \sa HW_LED_SRC1
*/
__STATIC_INLINE void hw_led_set_led1_src(HW_LED_SRC1 src)
{
REG_SETF(GPREG, LED_CONTROL_REG, LED1_SRC_SEL, src);
}
/**
* \brief Set the source that controls LED2
*
* \param [in] src the source that controls LED2
*
* \sa HW_LED_SRC2
*/
__STATIC_INLINE void hw_led_set_led2_src(HW_LED_SRC2 src)
{
REG_SETF(GPREG, LED_CONTROL_REG, LED2_SRC_SEL, src);
}
/**
* \brief Set the source that controls LED3
*
* \param [in] src the source that controls LED3
*
* \sa HW_LED_SRC3
*/
__STATIC_INLINE void hw_led_set_led3_src(HW_LED_SRC3 src)
{
REG_SETF(GPREG, LED_CONTROL_REG, LED3_SRC_SEL, src);
}
/**
* \brief Enable or disable LED1
*
* \param [in] state true to enable LED1, or false to disable it
*
*/
__STATIC_INLINE void hw_led_enable_led1(bool state)
{
REG_SETF(GPREG, LED_CONTROL_REG, LED1_EN, state);
}
/**
* \brief Enable or disable LED2
*
* \param [in] state true to enable LED2, or false to disable it
*
*/
__STATIC_INLINE void hw_led_enable_led2(bool state)
{
REG_SETF(GPREG, LED_CONTROL_REG, LED2_EN, state);
}
/**
* \brief Enable or disable LED3
*
* \param [in] state true to enable LED3, or false to disable it
*
*/
__STATIC_INLINE void hw_led_enable_led3(bool state)
{
REG_SETF(GPREG, LED_CONTROL_REG, LED3_EN, state);
}
#endif /* HW_LED_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,576 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup OTPC
* \{
* \brief OTP Memory Controller
*/
/**
****************************************************************************************
*
* @file hw_otpc.h
*
* @brief Definition of API for the OTP Controller driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_OTPC_H_
#define HW_OTPC_H_
#if dg_configUSE_HW_OTPC
#include <stdbool.h>
#include <stdint.h>
#include <sdk_defs.h>
/**
* \brief Get the mask of a field of an OTPC register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to access
*
*/
#define HW_OTPC_REG_FIELD_MASK(reg, field) \
(OTPC_OTPC_##reg##_REG_##OTPC_##reg##_##field##_Msk)
/**
* \brief Get the bit position of a field of an OTPC register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to access
*
*/
#define HW_OTPC_REG_FIELD_POS(reg, field) \
(OTPC_OTPC_##reg##_REG_##OTPC_##reg##_##field##_Pos)
/**
* \brief Prepare (i.e. shift and mask) a value to be used for an OTPC register field.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to access
* \param [in] val is the value to prepare
*
*/
#define HW_OTPC_FIELD_VAL(reg, field, val) \
(((val) << HW_OTPC_REG_FIELD_POS(reg, field)) & HW_OTPC_REG_FIELD_MASK(reg, field))
/**
* \brief Get the value of a field of an OTPC register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to write
*
* \return the value of the register field
*
*/
#define HW_OTPC_REG_GETF(reg, field) \
((OTPC->OTPC_##reg##_REG & (OTPC_OTPC_##reg##_REG_##OTPC_##reg##_##field##_Msk)) >> (OTPC_OTPC_##reg##_REG_##OTPC_##reg##_##field##_Pos))
/**
* \brief Set the value of a field of an OTPC register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to write
* \param [in] new_val is the value to write
*
*/
#define HW_OTPC_REG_SETF(reg, field, new_val) \
OTPC->OTPC_##reg##_REG = ((OTPC->OTPC_##reg##_REG & ~(OTPC_OTPC_##reg##_REG_##OTPC_##reg##_##field##_Msk)) | \
((OTPC_OTPC_##reg##_REG_##OTPC_##reg##_##field##_Msk) & ((new_val) << (OTPC_OTPC_##reg##_REG_##OTPC_##reg##_##field##_Pos))))
/**
* \brief OTP Controller mode
*/
typedef enum {
HW_OTPC_MODE_STBY = 0,
HW_OTPC_MODE_MREAD = 1,
HW_OTPC_MODE_MPROG = 2,
HW_OTPC_MODE_AREAD = 3,
HW_OTPC_MODE_APROG = 4,
HW_OTPC_MODE_TBLANK = 5,
HW_OTPC_MODE_TDEC = 6,
HW_OTPC_MODE_TWR = 7
} HW_OTPC_MODE;
#define MAX_RR_AVAIL (8)
#define OTP_CLK_IS_16M (0)
#define OTP_CLK_IS_32M (1)
#define OTP_CLK_IS_48M (2)
/**
* \brief Word inside cell to program/read
*
* Cell contents in memory starts with low word (i.e. to program/read both words in cell at once,
* HW_OTPC_WORD_LOW should be used for addressing).
*
*/
typedef enum {
HW_OTPC_WORD_LOW = 0,
HW_OTPC_WORD_HIGH = 1
} HW_OTPC_WORD;
/**
* \brief System clock frequency in MHz
*
*/
typedef enum {
HW_OTPC_SYS_CLK_FREQ_1 = 0,
HW_OTPC_SYS_CLK_FREQ_2 = 1,
HW_OTPC_SYS_CLK_FREQ_3 = 2,
HW_OTPC_SYS_CLK_FREQ_4 = 3,
HW_OTPC_SYS_CLK_FREQ_6 = 4,
HW_OTPC_SYS_CLK_FREQ_8 = 5,
HW_OTPC_SYS_CLK_FREQ_12 = 6,
HW_OTPC_SYS_CLK_FREQ_16 = 7,
HW_OTPC_SYS_CLK_FREQ_24 = 8,
HW_OTPC_SYS_CLK_FREQ_32 = 9,
HW_OTPC_SYS_CLK_FREQ_48 = 10
} HW_OTPC_SYS_CLK_FREQ;
/*
* Reset values of OTPC registers
*/
#define OTPC_MODE_REG_RESET (0x00000000)
#define OTPC_PCTRL_REG_RESET (0x00000000)
#define OTPC_STAT_REG_RESET (0x00000051)
#define OTPC_AHBADR_REG_RESET (0x07FC0000)
#define OTPC_CELADR_REG_RESET (0x00000000)
#define OTPC_NWORDS_REG_RESET (0x00000000)
#define OTPC_FFPRT_REG_RESET (0x00000000)
#define OTPC_FFRD_REG_RESET (0x00000000)
#define OTPC_PWORDL_REG_RESET (0x00000000)
#define OTPC_PWORDH_REG_RESET (0x00000000)
#define OTPC_TIM1_REG_RESET (0x1A104F20)
#define OTPC_TIM2_REG_RESET (0x00010000)
/**
* \brief Convert system clock frequency expressed in MHz to equivalent HW_OTPC_SYS_CLK_FREQ value
*
* \sa HW_OTPC_SYS_CLK_FREQ
*/
__RETAINED_CODE HW_OTPC_SYS_CLK_FREQ hw_otpc_convert_sys_clk_mhz(uint32_t clk_freq);
/**
* \brief Initialize the OTP Controller.
*
* \warning The AHB clock must be up to 48MHz! It is a responsibility of the caller to check this!
*
*/
static inline void hw_otpc_init(void)
{
GLOBAL_INT_DISABLE();
if ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE))) {
/*
* Reset OTP controller
*/
OTPC->OTPC_MODE_REG = HW_OTPC_MODE_STBY; // Set OTPC to standby
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, OTPC_RESET_REQ); // Reset the OTPC
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, OTPC_RESET_REQ); // Get the OTPC out of Reset
/*
* Initialize the POR registers
*/
OTPC->OTPC_NWORDS_REG = OTPC_NWORDS_REG_RESET;
OTPC->OTPC_TIM1_REG = OTPC_TIM1_REG_RESET;
OTPC->OTPC_TIM2_REG = OTPC_TIM2_REG_RESET;
}
/*
* Enable OTPC clock
*/
CRG_TOP->CLK_AMBA_REG |= 1 << REG_POS(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
* \brief Close the OTP Controller.
*
*/
static inline void hw_otpc_close(void)
{
/*
* Disable OTPC clock
*/
GLOBAL_INT_DISABLE();
CRG_TOP->CLK_AMBA_REG &= ~REG_MSK(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
* \brief Check if the OTP Cotnroller is active.
*
* \return 1 if it is active, else 0.
*
*/
static inline uint32_t hw_otpc_is_active(void) __attribute__((always_inline));
static inline uint32_t hw_otpc_is_active(void)
{
/*
* Check if the OTPC clock is enabled
*/
return !!(CRG_TOP->CLK_AMBA_REG & REG_MSK(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE));
}
/**
* \brief Put the OTP Controller in STBY mode and turn-off clock.
*
*/
void hw_otpc_disable(void);
/**
* \brief Set the access speed of the OTP Controller based on the system clock.
*
* \details Switch from PLL to XTAL : call function after clock switch with high_clk_speed == false
* Switch from XTAL to PLL : call function before clock switch with high_clk_speed == true
*
* \param [in] clk_speed The frequency of the system clock: 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 and 48.
*
* \warning The OTP clock must have been enabled (OTP_ENABLE == 1).
* (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
__RETAINED_CODE void hw_otpc_set_speed(HW_OTPC_SYS_CLK_FREQ clk_speed);
/**
* \brief Set or reset the power saving mode of the OTP Controller.
*
* \param [in] inactivity_period The number of HCLK cycles to remain powered while no access is made.
* If set to 0, this feature is disabled.
*
* \warning The hw_otpc_init() and hw_otpc_set_speed() must have been called.
* (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*/
void hw_otpc_power_save(uint32_t inactivity_period);
/**
* \brief Get the number of the Repair Records.
*
* \return The number of used Repair Records.
*
* \warning The hw_otpc_init() and hw_otpc_set_speed() must have been called. The OTPC mode will be reset.
* (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*/
uint32_t hw_otpc_num_of_rr(void);
/**
* \brief Program manually an OTP entry.
*
* \param [in] cell_offset Cell offset to be programmed.
*
* \param [in] pword_l The low 32-bits of the 64-bit word to be written.
*
* \param [in] pword_h The high 32-bits of the 64-bit word to be written.
*
* \param [in] use_rr Use a Repair Record if writing fails when true.
*
* \return true for success, false for failure
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
bool hw_otpc_manual_word_prog(uint32_t cell_offset, uint32_t pword_l, uint32_t pword_h, bool use_rr);
/**
* \brief Program manually an OTP block.
*
* \param [in] p_data The start address of the data to copy from.
*
* \param [in] cell_offset Cell offset to start programming from.
*
* \param [in] cell_word Word inside cell to start programming from.
*
* \param [in] num_of_words The actual number of the words to be written.
*
* \param [in] use_rr true to use Repair Records if writing fails
*
* \return true for success, false for failure
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
bool hw_otpc_manual_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
uint32_t num_of_words, bool use_rr);
/**
* \brief Put the OTP in manual read mode.
*
* \details In manual read mode the OTP is memory mapped to the address MEMORY_OTP_BASE. So, any
* access to this memory space results into reading from the OTP. The caller must make sure
* that the function hw_otpc_manual_read_off() is called when reading from the OTP is
* finished.
*
* \param [in] spare_rows true to access the spare rows area, false to access normal memory cell
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
void hw_otpc_manual_read_on(bool spare_rows);
/**
* \brief Take the OTP out of manual read mode and put it in STBY.
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
void hw_otpc_manual_read_off(void);
/**
* \brief Program manually a Repair Record in the OTP's spare area.
*
* \param [in] cell_offset The address programmed with errors.
* \param [in] pword_l The low 32-bits of the 64-bit word to be written.
* \param [in] pword_h The high 32-bits of the 64-bit word to be written.
* \return true for success, false for failure
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
bool hw_otpc_write_rr(uint32_t cell_offset, uint32_t pword_l, uint32_t pword_h);
/**
* \brief Program OTP via DMA.
*
* \param [in] p_data The start address of the data in RAM.
*
* \param [in] cell_offset Cell offset to be programmed.
*
* \param [in] cell_word Word inside cell to be programmed.
*
* \param [in] num_of_words The actual number of the words to be written. The driver will write this
* value minus 1 to the specific register.
*
* \param [in] spare_rows true to access the spare rows area, false to access normal memory cell
*
* \return true for success, false for failure (the programming should be retried or fixed!)
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
bool hw_otpc_dma_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
uint32_t num_of_words, bool spare_rows);
/**
* \brief Read OTP via DMA.
*
* \param [in] p_data The address in RAM to write the data to.
*
* \param [in] cell_offset Cell offset to be programmed.
*
* \param [in] cell_word Word inside cell to be programmed.
*
* \param [in] num_of_words The actual number of the words to be read. The driver will write this
* value minus 1 to the specific register.
*
* \param [in] spare_rows true to access the spare rows area, false to access normal memory cell
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
void hw_otpc_dma_read(uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
uint32_t num_of_words, bool spare_rows);
/**
* \brief Program OTP via FIFO (Auto mode).
*
* \param [in] p_data The start address of the data in RAM.
*
* \param [in] cell_offset Cell offset to be programmed.
*
* \param [in] cell_word Word inside cell to be programmed.
*
* \param [in] num_of_words The actual number of the words to be written. The driver will write this
* value minus 1 to the specific register.
*
* \param [in] spare_rows true to access the spare rows area, false to access normal memory cell
*
* \return true for success, false for failure
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
bool hw_otpc_fifo_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
uint32_t num_of_words, bool spare_rows);
/**
* \brief Read OTP via FIFO.
*
* \param [in] p_data The address in RAM to write the data to.
*
* \param [in] cell_offset Cell offset to be programmed.
*
* \param [in] cell_word Word inside cell to be programmed.
*
* \param [in] num_of_words The actual number of the words to be read. The driver will write this
* value minus 1 to the specific register.
*
* \param [in] spare_rows true to access the spare rows area, false to access normal memory cell
*
* \return true for success, false for failure
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
bool hw_otpc_fifo_read(uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
uint32_t num_of_words, bool spare_rows);
/**
* \brief Prepare OTPC to execute an OTP copy after wakeup.
*
* \param [in] num_of_bytes The actual number of the bytes to be copied. The driver will write the
* proper value to the specific register.
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
void hw_otpc_prepare(uint32_t num_of_bytes);
/**
* \brief Cancel any previous preparations of the OTPC for executing an OTP copy after wakeup.
*
* \warning The hw_otpc_init() and the hw_otpc_set_speed() must have been called and the mode must
* be STBY. (Note: the hw_otpc_set_speed() must be called only once when the PLL is used or
* during each clock switch when both PLL and XTAL16 are used, since the register bits it
* modifies are retained.)
*
*/
void hw_otpc_cancel_prepare(void);
/**
* \brief Get cell memory address
*
* Returns mapped memory address for given cell, can be used for e.g. manual reading.
*
* \param [in] cell_offset cell offset
*
* \return cell memory address
*
* \sa hw_otpc_manual_read_on
*
*/
static inline void *hw_otpc_cell_to_mem(uint32_t cell_offset)
{
return (void *) (MEMORY_OTP_BASE + (cell_offset << 3)); // cell size is 8 bytes
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// TEST FUNCTIONALITY
////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* \brief Execution of the BLANK test.
*
* \return The test result.
* <ul>
* <li> 0, if the test succeeded
* <li> 1, if the test 1 failed
* </ul>
*
*/
int hw_otpc_blank(void);
/**
* \brief Execution of the TDEC test.
*
* \return The test result.
* <ul>
* <li> 0, if the test succeeded
* <li> 1, if the test 1 failed
* </ul>
*
*/
int hw_otpc_tdec(void);
/**
* \brief Execution of the TWR test.
*
* \return The test result.
* <ul>
* <li> 0, if the test succeeded
* <li> 1, if the test 1 failed
* </ul>
*
*/
int hw_otpc_twr(void);
#endif /* dg_configUSE_HW_OTPC */
#endif /* HW_OTPC_H_ */
/**
\}
\}
\}
*/
File diff suppressed because it is too large Load Diff
@@ -1,331 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup RF
* \{
* \brief Radio Control
*/
/**
*****************************************************************************************
*
* @file hw_rf.h
*
* @brief Radio module (RF) Low Level Driver API.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_RF_H_
#define HW_RF_H_
#if dg_configUSE_HW_RF
#include <stdbool.h>
#include "sdk_defs.h"
#include "hw_cpm.h"
#if dg_configFEM == FEM_SKY66112_11
#include "hw_fem_sky66112-11.h"
#endif
typedef struct __attribute__ ((__packed__)) {
uint8_t tx_power_ble: 4;
uint8_t tx_power_ftdf: 4;
} hw_rf_tx_power_luts_t;
extern hw_rf_tx_power_luts_t rf_tx_power_luts;
/**
* \brief Power LUT setting
*
*/
typedef enum {
HW_RF_PWR_LUT_0dbm = 0, /**< TX PWR attenuation 0 dbm */
HW_RF_PWR_LUT_m1dbm = 1, /**< TX PWR attenuation -1 dbm */
HW_RF_PWR_LUT_m2dbm = 2, /**< TX PWR attenuation -2 dbm */
HW_RF_PWR_LUT_m3dbm = 3, /**< TX PWR attenuation -3 dbm */
HW_RF_PWR_LUT_m4dbm = 4, /**< TX PWR attenuation -4 dbm */
} HW_RF_PWR_LUT_SETTING;
/**
* \brief Initializes RF system, and performs the initial calibration
*
* \note The RF PD must be on before this is called
*
* \return True, if iff calib is successful, false otherwise
*/
bool hw_rf_system_init(void);
/**
* \brief Sets parameters according to their recommended values.
*/
void hw_rf_set_recommended_settings(void);
/**
* \brief (Re)calibrates RF DC offset.
*/
void hw_rf_dc_offset_calibration(void);
/**
* \brief (Re)calibrates modulation gain.
*/
void hw_rf_modulation_gain_calibration(bool);
/**
* \brief Convenience function to (re)calibrate all RF related modules.
*
* \return True if calibration (specifically, the iff calibration part)
* succeeds, false if not
*/
bool hw_rf_calibration(void);
/**
* \brief Start Calibration procedure and return.
*
* This will block for some time in order to perform
* the first part of calibration (IFF, DC offset and the start of gain calib).
* Interrupts must be disabled by the caller.
*
* \return True if calibration was successful, false if not (i.e. iff calib hang)
*
*/
bool hw_rf_start_calibration(void);
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
/**
* \brief Set TX Power
*
* This actually sets the index of the RF_TX_PWER_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \warning Do not call this function before recommended settings are applied
*/
void hw_rf_set_tx_power(HW_RF_PWR_LUT_SETTING lut);
#else
#ifdef CONFIG_USE_BLE
/**
* \brief Set TX Power for BLE
*
* This actually sets the index of the RF_TX_PWR_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \warning Do not call this function before recommended settings are applied
*/
void hw_rf_set_tx_power_ble(HW_RF_PWR_LUT_SETTING lut);
#endif
#ifdef CONFIG_USE_FTDF
/**
* \brief Set TX Power for FTDF
*
* This actually sets the index of the RF_TX_PWR_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \warning Do not call this function before recommended settings are applied
*/
void hw_rf_set_tx_power_ftdf(HW_RF_PWR_LUT_SETTING lut);
#endif
/**
* \brief Set TX Power
*
* This actually sets the index of the RF_TX_PWR_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \deprecated This function is deprecated since it can only set
* BLE and FTDF TX power with the same value. Use hw_rf_set_tx_power_ble()
* and hw_rf_set_tx_power_ftdf() instead.
*
* \warning Do not call this function before recommended settings are applied
*/
static inline void hw_rf_set_tx_power(HW_RF_PWR_LUT_SETTING lut)
{
#ifdef CONFIG_USE_BLE
hw_rf_set_tx_power_ble(lut);
#endif
#ifdef CONFIG_USE_FTDF
hw_rf_set_tx_power_ftdf(lut);
#endif
}
#endif
/**
* \brief Turns on RF module.
*/
static inline void hw_rf_poweron(void) __attribute__((always_inline));
static inline void hw_rf_poweron(void)
{
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_deactivate_bod_protection();
}
/* If PD_RAD is up, make sure to power it down to issue a reset */
if (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_UP)) {
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_delay_usec(30);
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
GLOBAL_INT_RESTORE();
while (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_DOWN) == 0x0);
}
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
GLOBAL_INT_RESTORE();
while (!REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_UP));
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_delay_usec(30);
hw_cpm_activate_bod_protection();
}
// Enable the PLLdig/RFCU clock
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_RADIO_REG, RFCU_ENABLE);
REG_SETF(CRG_TOP, CLK_RADIO_REG, RFCU_DIV, 1);
GLOBAL_INT_RESTORE();
#if dg_configFEM == FEM_SKY66112_11
hw_fem_start();
#endif
}
/**
* \brief Turns off RF module.
*/
static inline void hw_rf_poweroff()
{
#if dg_configFEM == FEM_SKY66112_11
hw_fem_stop();
#endif
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_deactivate_bod_protection();
hw_cpm_delay_usec(30);
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
GLOBAL_INT_RESTORE();
while (!REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_DOWN));
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_delay_usec(30);
hw_cpm_activate_bod_protection();
}
}
/**
* \brief Sets parameters according to their recommended values, taking RF state into account.
*
* Acts like \ref hw_rf_set_recommended_settings but makes sure that the RF power domain is on and
* unconfigured.
* Interrupts must be disabled by the caller.
*
*/
void hw_rf_request_recommended_settings(void);
/**
* \brief Requests that the RF is turned on
*
* Requests that the RF is turned on, if not already on.
* Interrupts must be disabled by the caller.
*
* \param [in] mode_ble True, if the rf is needed for ble
*/
__RETAINED_CODE void hw_rf_request_on(bool mode_ble);
/**
* \brief Requests that the RF is turned off
*
* Requests that the RF is turned off, if not already off.
* The RF will be turned off only if there are no more
* requests (ie. all requesters have called hw_rf_request_off())
* Interrupts must be disabled by the caller.
*
* \param [in] mode_ble True, if the rf was needed for ble
*/
void hw_rf_request_off(bool mode_ble);
/**
* \brief Start transmitting a continuous wave (unmodulated transmission)
*
* \param [in] mode is the mode to use. 1: BLE, 2 or 3: FTDF (0: Normal, use hw_rf_stop_*)
*
* \param [in] ch is the Channel to transmit on, calculated as:
* (mode is BLE) ch = (F 2402) / 2, where F ranges from 2402 MHz to 2480 MHz.
* Range: 0x00 0x27.
* (mode is FTDF) ch = (F 2405) / 5, where F ranges from 2405 MHz to 2480 MHz.
* Range: 0x00 0xf.
*/
void hw_rf_start_continuous_wave(uint8_t mode, uint8_t ch);
/**
* \brief Start reception of a continuous wave (unmodulated reception)
*
* \param [in] mode is the mode to use. 1: BLE, 2 or 3: FTDF (0: Normal, use hw_rf_stop_*)
*
* \param [in] ch is the Channel to receive on, calculated as:
* (mode is BLE) ch = (F 2402) / 2, where F ranges from 2402 MHz to 2480 MHz.
* Range: 0x00 0x27.
* (mode is FTDF) ch = (F 2405) / 5, where F ranges from 2405 MHz to 2480 MHz.
* Range: 0x00 0xf.
*/
void hw_rf_start_continuous_wave_rx(uint8_t mode, uint8_t ch);
/**
* \brief Stop transmitting a continuous wave (unmodulated transmission)
*
*/
void hw_rf_stop_continuous_wave(void);
#endif /* dg_configUSE_HW_RF */
#endif /* HW_RF_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,385 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup Timer0
* \{
* \brief Timer0
*/
/**
*****************************************************************************************
*
* @file hw_timer0.h
*
* @brief Definition of API for the Timer0 Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_TIMER0_H_
#define HW_TIMER0_H_
#if dg_configUSE_HW_TIMER0
#include <stdbool.h>
#include <stdint.h>
#include <sdk_defs.h>
/**
* \brief Get the mask of a field of an TIMER0 register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to access
*
*/
#define HW_TIMER0_REG_FIELD_MASK(reg, field) \
(GP_TIMERS_TIMER0_##reg##_REG_##field##_Msk)
/**
* \brief Get the bit position of a field of an TIMER0 register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to access
*
*/
#define HW_TIMER0_REG_FIELD_POS(reg, field) \
(GP_TIMERS_TIMER0_##reg##_REG_##field##_Pos)
/**
* \brief Get the value of a field of an TIMER0 register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to write
*
* \return the value of the register field
*
*/
#define HW_TIMER0_REG_GETF(reg, field) \
((GP_TIMERS->TIMER0_##reg##_REG & (GP_TIMERS_TIMER0_##reg##_REG_##field##_Msk)) >> (GP_TIMERS_TIMER0_##reg##_REG_##field##_Pos))
/**
* \brief Set the value of a field of an TIMER0 register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to write
* \param [in] new_val is the value to write
*
*/
#define HW_TIMER0_REG_SETF(reg, field, new_val) \
GP_TIMERS->TIMER0_##reg##_REG = ((GP_TIMERS->TIMER0_##reg##_REG & ~(GP_TIMERS_TIMER0_##reg##_REG_##field##_Msk)) | \
((GP_TIMERS_TIMER0_##reg##_REG_##field##_Msk) & ((new_val) << (GP_TIMERS_TIMER0_##reg##_REG_##field##_Pos))))
/**
* \brief Clock source for timer
*
*/
typedef enum {
HW_TIMER0_CLK_SRC_SLOW = 0, /**< 32kHz (slow) clock */
HW_TIMER0_CLK_SRC_FAST = 1 /**< 2/4/8/16MHz (fast) clock */
} HW_TIMER0_CLK_SRC;
/**
* \brief Fast clock division factor
*
*/
typedef enum {
HW_TIMER0_FAST_CLK_DIV_1 = 0, /**< divide by 1 */
HW_TIMER0_FAST_CLK_DIV_2, /**< divide by 2 */
HW_TIMER0_FAST_CLK_DIV_4, /**< divide by 4 */
HW_TIMER0_FAST_CLK_DIV_8, /**< divide by 8 */
} HW_TIMER0_FAST_CLK_DIV;
/**
* \brief PWM mode
*
*/
typedef enum {
HW_TIMER0_MODE_PWM = 0, /**< PWM signal is '1' during high state */
HW_TIMER0_MODE_CLOCK = 1 /**< PWM signal is clock divided by 2 during high state */
} HW_TIMER0_MODE;
/**
* \brief Timer interrupt callback
*
*/
typedef void (*hw_timer0_interrupt_cb)(void);
/*
* \brief Timer configuration
*
*/
typedef struct {
HW_TIMER0_CLK_SRC clk_src; /**< clock source */
HW_TIMER0_FAST_CLK_DIV fast_clk_div; /**< clock division factor (only applicable when fast clock is selected as source) */
bool on_clock_div; /**< enable ON-counter clock divider (clock for ON-counter is divided by 10) */
uint16_t on_reload; /**< reload value for ON-counter */
uint16_t t0_reload_m; /**< reload value for T0-counter M-register */
uint16_t t0_reload_n; /**< reload value for T0-counter N-register */
} timer0_config;
/**
* \brief Initialize the timer
*
* Turn on clock for timer and configure timer. After initialization both timer and its interrupt
* are disabled. \p cfg can be NULL - no configuration is performed in such case.
*
* \param [in] cfg configuration
*
*/
void hw_timer0_init(const timer0_config *cfg);
/**
* \brief Timer configuration
*
* Shortcut to call appropriate configuration function. If \p cfg is NULL, this function does
* nothing.
*
* \param [in] cfg configuration
*
*/
void hw_timer0_configure(const timer0_config *cfg);
/**
* \brief Register an interrupt handler
*
* \param [in] handler Function pointer to call when timer interrupt occurs
*
*/
void hw_timer0_register_int(hw_timer0_interrupt_cb handler);
/**
* \brief Unregister an interrupt handler
*
*/
void hw_timer0_unregister_int(void);
/**
* \brief Enable the timer
*
*/
static inline void hw_timer0_enable(void)
{
HW_TIMER0_REG_SETF(CTRL, TIM0_CTRL, 1);
}
/**
* \brief Disable the timer
*
*/
static inline void hw_timer0_disable(void)
{
HW_TIMER0_REG_SETF(CTRL, TIM0_CTRL, 0);
}
/**
* \brief Set clock source for timer
*
* \param [in] clk_src clock source
*
* \sa TIMER0_CLK_SRC
*
*/
static inline void hw_timer0_set_clock_source(HW_TIMER0_CLK_SRC clk_src)
{
HW_TIMER0_REG_SETF(CTRL, TIM0_CLK_SEL, clk_src);
}
/**
* \brief Get current clock source for timer
*
* \return clock source
*
*/
static inline HW_TIMER0_CLK_SRC hw_timer0_get_clock_source(void)
{
return HW_TIMER0_REG_GETF(CTRL, TIM0_CLK_SEL);
}
/**
* \brief Set fast clock division factor
*
* \param [in] div division factor
*
* \sa TIMER0_FAST_CLK_DIV
*
*/
static inline void hw_timer0_set_fast_clock_div(HW_TIMER0_FAST_CLK_DIV div)
{
GLOBAL_INT_DISABLE();
REG_SETF(CRG_TOP, CLK_TMR_REG, TMR0_DIV, div);
GLOBAL_INT_RESTORE();
}
/**
* \brief Get current fast clock division factor
*
* \return division factor
*
*/
static inline HW_TIMER0_FAST_CLK_DIV hw_timer0_get_fast_clock_div(void)
{
return REG_GETF(CRG_TOP, CLK_TMR_REG, TMR0_DIV);
}
/**
* \brief Set state of clock divider for ON-counter
*
* Once enabled, ON-counter clock will be divided by 10.
*
* \param [in] enabled clock divider status
*
*/
static inline void hw_timer0_set_on_clock_div(bool enabled)
{
HW_TIMER0_REG_SETF(CTRL, TIM0_CLK_DIV, !enabled);
}
/**
* \brief Get current state of clock divider for ON-counter
*
* \return clock divider status
*
*/
static inline bool hw_timer0_get_on_clock_div(void)
{
return !HW_TIMER0_REG_GETF(CTRL, TIM0_CLK_DIV);
}
/**
* \brief Set PWM mode for timer
*
* \param [in] mode PWM mode
*
* \sa TIMER0_MODE
*
*/
static inline void hw_timer0_set_pwm_mode(HW_TIMER0_MODE mode)
{
HW_TIMER0_REG_SETF(CTRL, PWM_MODE, mode);
}
/**
* \brief Get current PWM mode for timer
*
* \return PWM mode
*
*/
static inline HW_TIMER0_MODE hw_timer0_get_pwm_mode(void)
{
return HW_TIMER0_REG_GETF(CTRL, PWM_MODE);
}
/**
* \brief Set reload value for T0-counter
*
* T0 counter value is decremented on each clock cycle. At the beginning it's loaded from M-register
* and then, once reached zero, loaded from N-register (and then M and N again).
*
* PWM0 is high when counting down M-register and low when counting down N-register.
* For PWM1 is the opposite.
*
* \param [in] m_value M-register reload value
* \param [in] n_value N-register reload value
*
*/
static inline void hw_timer0_set_t0_reload(uint16_t m_value, uint16_t n_value)
{
GP_TIMERS->TIMER0_RELOAD_M_REG = m_value;
GP_TIMERS->TIMER0_RELOAD_N_REG = n_value;
}
/**
* \brief Set reload value for ON-counter
*
* ON counter value is decremented on each clock cycle. Once ON reaches zero it will remain zero
* until T0 counter completes decrementing N-register value. When this happens, interrupt is
* generated.
*
* \param [in] value reload value
*
* \sa hw_timer0_set_on_clock_div
*
*/
static inline void hw_timer0_set_on_reload(uint16_t value)
{
GP_TIMERS->TIMER0_ON_REG = value;
}
/**
* \brief Get T0-counter value
*
* \return counter value
*
*/
static inline uint16_t hw_timer0_get_t0(void)
{
return (GP_TIMERS->TIMER0_RELOAD_M_REG);
}
/**
* \brief Get ON-counter value
*
* \return counter value
*
*/
static inline uint16_t hw_timer0_get_on(void)
{
return (GP_TIMERS->TIMER0_ON_REG);
}
/**
* \brief Freeze timer
*
*/
static inline void hw_timer0_freeze(void)
{
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SWTIM0_Msk;
}
/**
* \brief Unfreeze timer
*
*/
static inline void hw_timer0_unfreeze(void)
{
GPREG->RESET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SWTIM0_Msk;
}
#endif /* dg_configUSE_HW_TIMER0 */
#endif /* HW_TIMER0_H_ */
/**
* \}
* \}
* \}
*/
File diff suppressed because it is too large Load Diff
@@ -1,145 +0,0 @@
/**
*****************************************************************************************
*
* @file hw_trng.h
*
* @brief Definition of API for the True Random Number Generator Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_TRNG_H_
#define HW_TRNG_H_
#if dg_configUSE_HW_TRNG
#include <sdk_defs.h>
/**
* \brief TRNG callback.
*
* This function is called by the TRNG driver when the interrupt is fired.
*
* \note If the TRNG is not needed anymore the hw_trng_disable function should be called in the
* callback function to save power.
*
*/
typedef void (*hw_trng_cb)(void);
/**
* \brief TRNG enable.
*
* This function enables the TRNG. If callback is not NULL it will be called when a TRNG interrupt
* occurs. The interrupt is triggered when the TRNG FIFO is full.
*
* \param [in] callback The callback function that is called when a TRNG interrupt occurs.
*
* \note If the amount of random numbers needed is less than the contents of the FIFO it is faster
* and more power efficient to use a wait loop in combination with the hw_trng_get_fifo_level
* function. If the FIFO has the required level use the hw_trng_get_numbers function to get the
* random numbers.
*
*/
void hw_trng_enable(hw_trng_cb callback);
/**
* \brief Get a random number from TRNG.
*
* This function reads a random number from the TRNG FIFO.
*
* \return A 32-bit unsigned random number.
*
* \warning This function does not check for number availability in the FIFO
*
*/
__attribute__((always_inline)) static inline uint32_t hw_trng_get_number(void)
{
return *((volatile uint32_t *)MEMORY_TRNG_FIFO);
}
/**
* \brief Get random numbers from TRNG.
*
* This function fills a buffer with random numbers read from the TRNG FIFO.
*
* \param [in] buffer The buffer to write the numbers to.
* \param [in] size The size of the buffer (max 32).
*
* \note Do not forget to disable the TRNG after reading the amount of numbers needed to save
* power.
*
* \warning This function does not check for number availability in the FIFO
*
*/
void hw_trng_get_numbers(uint32_t* buffer, uint8_t size);
/**
* \brief TRNG get FIFO level.
*
* This function returns the current level of the TRNG FIFO.
*
* \return The current level of the TRNG FIFO.
*
*/
__RETAINED_CODE uint8_t hw_trng_get_fifo_level(void);
/**
* \brief TRNG disable.
*
* This function stops TRNG, disables its clock and its interrupt.
*
*/
void hw_trng_disable(void);
/**
* \brief Stop TRNG operation.
*/
static inline void hw_trng_stop(void)
{
REG_CLR_BIT(TRNG, TRNG_CTRL_REG, TRNG_ENABLE);
}
/**
* \brief Disable TRNG clock.
*/
void hw_trng_disable_clk(void);
/**
* \brief Disable TRNG interrupt.
*/
void hw_trng_disable_interrupt(void);
/**
* \brief Clear TRNG pending interrupt.
*/
void hw_trng_clear_pending(void);
#endif /* dg_configUSE_HW_TRNG */
#endif /* HW_TRNG_H_ */
File diff suppressed because it is too large Load Diff
@@ -1,188 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup Watchdog_Timer
* \{
* \brief Watchdog Timer
*/
/**
*****************************************************************************************
*
* @file hw_watchdog.h
*
* @brief Definition of API for the Watchdog timer Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_WATCHDOG_H_
#define HW_WATCHDOG_H_
#include <stdbool.h>
#include <stdint.h>
#include <sdk_defs.h>
#define NMI_MAGIC_NUMBER 0xDEADBEEF
/**
* \brief Holds the stack contents when an NMI occurs.
*
* \details The stack contents are copied at this variable when an NMI occurs. The first position is
* marked with a special "flag" (0xDEADBEEF) to indicate that the data that follow are valid.
*/
extern uint32_t nmi_event_data[9];
/**
* \brief Types of generated states if reload value is 0
*
* Generate NMI (non-maskable interrupt) or RST (reset of the system)
*
*/
typedef enum {
HW_WDG_RESET_NMI = 0, /**< Generate NMI if the watchdog reaches 0 and WDOG reset if the counter become less or equal to -16 */
HW_WDG_RESET_RST = 1 /**< Generate WDOG reset it the counter becomes less or equal than 0 */
} HW_WDG_RESET;
/**
* \brief Watchdog timer interrupt callback
*
* \param [in] hardfault_args pointer to call stack
*
*/
typedef void (*hw_watchdog_interrupt_cb)(unsigned long *exception_args);
/**
* \brief Freeze the watchdog
*
* \return true if operation is allowed, else false
*
*/
__RETAINED_CODE bool hw_watchdog_freeze(void);
/**
* \brief Unfreeze the watchdog
*
*/
__RETAINED_CODE void hw_watchdog_unfreeze(void);
/**
* \brief Set positive reload value of the watchdog timer
*
* \param [in] value reload value from 0 (0x00) to 255 (0xFF)
*
*/
static inline void hw_watchdog_set_pos_val(uint8_t value) __attribute__((always_inline));
static inline void hw_watchdog_set_pos_val(uint8_t value)
{
WDOG->WATCHDOG_REG = (uint16_t)value;
}
/**
* \brief Set negative reload value of the watchdog timer
*
* \param [in] value reload value from -16 (0x1FF) to 0 (0x00)
*
*/
static inline void hw_watchdog_set_neg_val(uint8_t value)
{
WDOG->WATCHDOG_REG = WDOG_WATCHDOG_REG_WDOG_VAL_NEG_Msk | (uint16_t)value;
}
/**
* \brief Get reload value of the watchdog timer
*
*/
static inline uint16_t hw_watchdog_get_val(void)
{
return REG_GETF(WDOG, WATCHDOG_REG, WDOG_VAL);
}
/**
* \brief Generate a reset signal of the system if reload value reaches 0
*
*/
static inline void hw_watchdog_gen_RST(void) __attribute__((always_inline));
static inline void hw_watchdog_gen_RST(void)
{
REG_SET_BIT(WDOG, WATCHDOG_CTRL_REG, NMI_RST);
}
/**
* \brief Register an interrupt handler
*
* \param [in] handler function pointer to handler to call when an interrupt occurs
*
*/
void hw_watchdog_register_int(hw_watchdog_interrupt_cb handler);
/**
* \brief Unregister an interrupt handler
*
*/
__RETAINED_CODE void hw_watchdog_unregister_int(void);
/**
* \brief Handle NMI interrupt.
*
* \param [in] hardfault_args pointer to call stack
*
*/
__RETAINED_CODE void hw_watchdog_handle_int(unsigned long *hardfault_args);
/**
* \brief Check whether the timer has expired
*
* \return true, if the timer has expired, false otherwise
*
*/
bool hw_watchdog_is_timer_expired(void);
/**
* \brief Check what is generated when watchdog reaches 0 value
*
* If it is NMI (interrupt) or RST (system/wdog reset).
*
* \return HW_WDG_RESET_NMI if NMI interrupt is generated, otherwise HW_WDG_RESET_RST
*
*/
HW_WDG_RESET hw_watchdog_is_irq_or_rst_gen(void);
#endif /* HW_WATCHDOG_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,600 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup Wakeup_Timer
* \{
* \brief Wakeup Timer
*/
/**
*****************************************************************************************
*
* @file hw_wkup.h
*
* @brief Definition of API for the Wakeup timer Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 HW_WKUP_H_
#define HW_WKUP_H_
#if dg_configUSE_HW_WKUP
#include <stdbool.h>
#include <stdint.h>
#include <sdk_defs.h>
#include "hw_gpio.h"
#if (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
#define WKUP_SEL_P0_BASE_REG (volatile uint16_t *)(&WAKEUP->WKUP_SEL_GPIO_P0_REG)
#else
#define WKUP_SEL_P0_BASE_REG (volatile uint16_t *)(&WAKEUP->WKUP_SELECT_P0_REG)
#endif
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
/**
* \brief Wakeup timer configuration
*
*/
typedef struct {
uint8_t pin_state[HW_GPIO_NUM_PORTS]; /**< pin states in each port, 1: enabled, 0: disabled */
uint8_t pin_trigger[HW_GPIO_NUM_PORTS]; /**< pin triggers in each port, 1: low, 0: high */
} wkup_pin_config_t;
extern volatile wkup_pin_config_t wkup_pin_config; /**< stores wkup pin configuration */
extern volatile uint8_t wkup_status[HW_GPIO_NUM_PORTS]; /**< stores wakeup sources */
#endif
/**
* \brief Get the mask of a field of an WKUP register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to access
*
*/
#define HW_WKUP_REG_FIELD_MASK(reg, field) \
(WAKEUP_WKUP_##reg##_REG_##field##_Msk)
/**
* \brief Get the bit position of a field of an WKUP register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to access
*
*/
#define HW_WKUP_REG_FIELD_POS(reg, field) \
(WAKEUP_WKUP_##reg##_REG_##field##_Pos)
/**
* \brief Get the value of a field of an WKUP register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to write
*
* \return the value of the register field
*
*/
#define HW_WKUP_REG_GETF(reg, field) \
((WAKEUP->WKUP_##reg##_REG & (WAKEUP_WKUP_##reg##_REG_##field##_Msk)) >> (WAKEUP_WKUP_##reg##_REG_##field##_Pos))
/**
* \brief Set the value of a field of an WKUP register.
*
* \param [in] reg is the register to access
* \param [in] field is the register field to write
* \param [in] new_val is the value to write
*
*/
#define HW_WKUP_REG_SETF(reg, field, new_val) \
WAKEUP->WKUP_##reg##_REG = ((WAKEUP->WKUP_##reg##_REG & ~(WAKEUP_WKUP_##reg##_REG_##field##_Msk)) | \
((WAKEUP_WKUP_##reg##_REG_##field##_Msk) & ((new_val) << (WAKEUP_WKUP_##reg##_REG_##field##_Pos))))
/**
* \brief Pin state which increments event counter
*
*/
typedef enum {
HW_WKUP_PIN_STATE_HIGH = 0,
HW_WKUP_PIN_STATE_LOW = 1
} HW_WKUP_PIN_STATE;
/**
* \brief Wakeup timer configuration
*
*/
typedef struct {
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
/**
* counter threshold
*
* \warning Supported only in DA14680/1 chips
*/
uint8_t threshold;
#endif
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
uint8_t debounce; /**< debounce time in ms */
#endif
uint8_t pin_state[HW_GPIO_NUM_PORTS]; /**< pin states in each port, see hw_wkup_configure_port */
uint8_t pin_trigger[HW_GPIO_NUM_PORTS]; /**< pin triggers in each port, see hw_wkup_configure_port */
} wkup_config;
typedef void (*hw_wkup_interrupt_cb)(void);
/**
* \brief Initialize peripheral
*
* Resets Wakeup Timer to initial state, i.e. interrupt is disabled and all pin triggers are
* disabled.
*
* \p cfg can be NULL - no configuration is performed in such case.
*
* \param [in] cfg configuration
*
*/
void hw_wkup_init(const wkup_config *cfg);
/**
* \brief Configure peripheral
*
* Shortcut to call appropriate configuration function. If \p cfg is NULL, this function does
* nothing.
*
* \param [in] cfg configuration
*
*/
void hw_wkup_configure(const wkup_config *cfg);
/**
* \brief Register interrupt handler
*
* Callback function is called when interrupt is generated, i.e. event counter reaches configured
* value. Interrupt is automatically enabled after calling this function. Application should reset
* interrupt in callback function using hw_wkup_reset_interrupt(). If no callback is specified,
* interrupt will be automatically cleared by the driver.
*
* \param [in] cb callback function
* \param [in] prio the priority of the interrupt
*
* \sa hw_wkup_unregister_interrupt
* \sa hw_wkup_clear_interrupt
* \sa hw_wkup_set_counter_threshold
* \sa hw_wkup_get_counter
*
*/
void hw_wkup_register_interrupt(hw_wkup_interrupt_cb cb, uint32_t prio);
/**
* \brief Unregister interrupt handler
*
* Interrupt is automatically disabled after calling this function.
*
*/
void hw_wkup_unregister_interrupt(void);
/**
* \brief Reset interrupt
*
* This function MUST be called by any user-specified interrupt callback, to clear the interrupt.
*
*/
static inline void hw_wkup_reset_interrupt(void)
{
WAKEUP->WKUP_RESET_IRQ_REG = 1;
}
/**
* \brief Interrupt handler
*
*/
void hw_wkup_handler(void);
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
/**
* \brief Set debounce time
*
* Setting debounce time to 0 will disable hardware debouncing. Maximum debounce time is 63ms.
*
* \param [in] time_ms debounce time in milliseconds
*
*/
static inline void hw_wkup_set_debounce_time(uint8_t time_ms)
{
HW_WKUP_REG_SETF(CTRL, WKUP_DEB_VALUE, time_ms);
}
#endif //!((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
/**
* \brief Get current debounce time
*
* \return debounce time in milliseconds
*
*/
static inline uint8_t hw_wkup_get_debounce_time(void)
{
return HW_WKUP_REG_GETF(CTRL, WKUP_DEB_VALUE);
}
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
/**
* \brief Set threshold for event counter
*
* Interrupt is generated after event counter reaches configured value.
*
* \param [in] level number of events
*
* \warning Supported only in DA14680/1 chips
* \sa hw_wkup_register_interrupt
* \sa hw_wkup_get_counter
*
*/
static inline void hw_wkup_set_counter_threshold(uint8_t level)
{
HW_WKUP_REG_SETF(COMPARE, COMPARE, level);
}
/**
* \brief Get threshold for event counter
*
* \return number of events
*
* \warning Supported only in DA14680/1 chips
*/
static inline uint8_t hw_wkup_get_counter_threshold(void)
{
return HW_WKUP_REG_GETF(COMPARE, COMPARE);
}
/**
* \brief Get current value of event counter
*
* Number of events counted so far. Can be reset using hw_wkup_reset_counter().
*
* \return number of events
*
* \note The counter is automatically reset by the hardware when the interrupt is generated.
*
* \warning Supported only in DA14680/1 chips
*
* \sa hw_wkup_reset_counter
*
*/
static inline uint8_t hw_wkup_get_counter(void)
{
return HW_WKUP_REG_GETF(COUNTER, EVENT_VALUE);
}
/**
* \brief Reset event counter
*
* There is no need to reset counter manually in interrupt callback - it's reset automatically by
* hardware.
*
* \warning Supported only in DA14680/1 chips
*/
static inline void hw_wkup_reset_counter(void)
{
WAKEUP->WKUP_RESET_CNTR_REG = 1;
}
#endif
/**
* \brief Set GPIO pin event counting state
*
* Once enabled, state changes on pin will increment event counter. State which triggers event can
* be set using hw_wkup_set_pin_trigger().
*
* \param [in] port port number
* \param [in] pin pin number
* \param [in] enabled pin event counting state
*
* \sa hw_wkup_set_pin_trigger
* \sa hw_wkup_configure_pin
* \sa hw_wkup_configure_port
*
*/
static inline void hw_wkup_set_pin_state(HW_GPIO_PORT port, HW_GPIO_PIN pin, bool enabled)
{
volatile uint16_t *wkup_pin_enable_reg = WKUP_SEL_P0_BASE_REG + port;
uint16_t wkup_pin_enable_val = *wkup_pin_enable_reg;
wkup_pin_enable_val &= ~(1 << pin);
wkup_pin_enable_val |= (!!enabled) << pin;
*wkup_pin_enable_reg = wkup_pin_enable_val;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
wkup_pin_config.pin_state[port] = wkup_pin_enable_val;
#endif
}
/** \brief Get GPIO pin event counting state
*
* \param [in] port port number
* \param [in] pin pin number
*
* \return pin event counting state
*
* \sa hw_wkup_set_pin_state
*
*/
static inline bool hw_wkup_get_pin_state(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
uint16_t wkup_pin_enable_val = *(WKUP_SEL_P0_BASE_REG + port);
return (wkup_pin_enable_val & (1 << pin)) >> pin;
}
/**
* \brief Set GPIO pin state which triggers event
*
* Pin event counting should be enabled for this setting to have any effect.
*
* \param [in] port port number
* \param [in] pin pin number
* \param [in] state pin state
*
* \sa hw_wkup_set_pin_counter_state
* \sa hw_wkup_configure_pin
* \sa hw_wkup_configure_port
*
*/
static inline void hw_wkup_set_pin_trigger(HW_GPIO_PORT port, HW_GPIO_PIN pin,
HW_WKUP_PIN_STATE state)
{
uint16_t pol_rx_reg = *((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port);
pol_rx_reg &= ~(1 << pin);
pol_rx_reg |= (!!state) << pin;
*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port) = pol_rx_reg;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
wkup_pin_config.pin_trigger[port] = pol_rx_reg;
#endif
}
/** \brief Get GPIO pin state which triggers event
*
* \param [in] port port number
* \param [in] pin pin number
*
* \return pin state
*
* \sa hw_wkup_set_pin_trigger
*
*/
static inline HW_WKUP_PIN_STATE hw_wkup_get_pin_trigger(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
uint16_t pol_rx_reg = *((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port);
return (pol_rx_reg & (1 << pin)) >> pin;
}
/**
* \brief Set GPIO pin event counting and triggered state
*
* Effectively, this is shortcut for calling hw_wkup_set_pin_state() and hw_wkup_set_pin_trigger().
*
* \param [in] port port number
* \param [in] pin pin number
* \param [in] enabled pin event counting state
* \param [in] state pin state
*
* \sa hw_wkup_set_pin_counter_state
* \sa hw_wkup_set_pin_trigger
* \sa hw_wkup_configure_port
*
*/
static inline void hw_wkup_configure_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin, bool enabled,
HW_WKUP_PIN_STATE state)
{
// first set up the proper polarity...
hw_wkup_set_pin_trigger(port, pin, state);
// ...then enable counting on the specific GPIO
hw_wkup_set_pin_state(port, pin, enabled);
}
/**
* \brief Configure event counting and triggering state for whole GPIO port
*
* In \p enabled and \p state bitmasks each bit describes state of corresponding pin in port.
* For \p enabled 0 means disabled and 1 means enabled.
* For \p state 0 means event is triggered on low state and 1 means trigger is on high state.
*
* \param [in] port port number
* \param [in] enabled pin event counting bitmask
* \param [in] state pin state bitmask
*
* \sa hw_wkup_set_pin_counter_state
* \sa hw_wkup_set_pin_trigger
* \sa hw_wkup_configure_pin
*
*/
static inline void hw_wkup_configure_port(HW_GPIO_PORT port, uint8_t enabled, uint8_t state)
{
*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port) = ~state; // register has inverted logic than state bitmask
*(WKUP_SEL_P0_BASE_REG + port) = enabled;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
wkup_pin_config.pin_state[port] = enabled;
wkup_pin_config.pin_trigger[port] = ~state;
#endif
}
/**
* \brief Get state (enabled/disabled) of all pins in GPIO port
*
* Meaning of bits in returned bitmask is the same as in hw_wkup_configure_port().
*
* \return port pin event counter state bitmask
*
* \sa hw_wkup_configure_port
*
*/
static inline uint8_t hw_wkup_get_port_state(HW_GPIO_PORT port)
{
#if dg_configLATCH_WKUP_SOURCE
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
return wkup_pin_config.pin_state[port];
#else
return *((volatile uint16_t *)(&WAKEUP->WKUP_SEL_GPIO_P0_REG) + port);
#endif
#else
return *((volatile uint16_t *)(&WAKEUP->WKUP_SELECT_P0_REG) + port);
#endif
}
/**
* \brief Get event triggering state for all pins in GPIO port
*
* Meaning of bits in returned bitmask is the same as in hw_wkup_configure_port().
*
* \return port pin event triggering state bitmask
*
* \sa hw_wkup_configure_port
*
*/
static inline uint8_t hw_wkup_get_port_trigger(HW_GPIO_PORT port)
{
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
return wkup_pin_config.pin_trigger[port];
#else
return ~(*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port)); // register has inverted logic that returned bitmask
#endif
}
/**
* \brief Emulate key hit
*
* Event counter will be increased with debounce time taken into account (if enabled).
*
*/
static inline void hw_wkup_emulate_key_hit(void)
{
HW_WKUP_REG_SETF(CTRL, WKUP_SFT_KEYHIT, 1);
HW_WKUP_REG_SETF(CTRL, WKUP_SFT_KEYHIT, 0);
}
/**
* \brief Freeze wakeup timer
*
*/
static inline void hw_wkup_freeze(void)
{
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WKUPTIM_Msk;
}
/**
* \brief Unfreeze wakeup timer
*
*/
static inline void hw_wkup_unfreeze(void)
{
GPREG->RESET_FREEZE_REG = GPREG_RESET_FREEZE_REG_FRZ_WKUPTIM_Msk;
}
/**
* \brief Get port status on last wake up
*
* Meaning of bits in returned bitmask is the same as in hw_wkup_configure_port().
*
* \return port pin event counter state bitmask
*
* \sa hw_wkup_configure_port
*
*/
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
static inline uint8_t hw_wkup_get_status(HW_GPIO_PORT port)
{
return wkup_status[port];
}
#elif dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
static inline uint8_t hw_wkup_get_status(HW_GPIO_PORT port)
{
switch (port) {
case HW_GPIO_PORT_0:
return HW_WKUP_REG_GETF(STATUS_0, WKUP_STAT_P0);
case HW_GPIO_PORT_1:
return HW_WKUP_REG_GETF(STATUS_0, WKUP_STAT_P1);
case HW_GPIO_PORT_2:
return HW_WKUP_REG_GETF(STATUS_1, WKUP_STAT_P2);
case HW_GPIO_PORT_3:
return HW_WKUP_REG_GETF(STATUS_2, WKUP_STAT_P3);
case HW_GPIO_PORT_4:
return HW_WKUP_REG_GETF(STATUS_2, WKUP_STAT_P4);
default:
ASSERT_WARNING(0);//Invalid argument
}
}
#endif
/**
* \brief Clear latch status
*
* This function MUST be called by any user-specified interrupt callback,
* to clear the interrupt latch status.
*
* \param [in] port port number
* \param [in] status pin status bitmask
*
* \sa hw_wkup_get_status
*/
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
static inline void hw_wkup_clear_status(HW_GPIO_PORT port, uint8_t status)
{
ASSERT_WARNING((port>=HW_GPIO_PORT_0) && (port<=HW_GPIO_PORT_4))
wkup_status[port] &= ~status;
}
#elif dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
static inline void hw_wkup_clear_status(HW_GPIO_PORT port, uint8_t status)
{
switch (port) {
case HW_GPIO_PORT_0:
HW_WKUP_REG_SETF(CLEAR_0, WKUP_CLEAR_P0, status);
break;
case HW_GPIO_PORT_1:
HW_WKUP_REG_SETF(CLEAR_0, WKUP_CLEAR_P1, status);
break;
case HW_GPIO_PORT_2:
HW_WKUP_REG_SETF(CLEAR_1, WKUP_CLEAR_P2, status);
break;
case HW_GPIO_PORT_3:
HW_WKUP_REG_SETF(CLEAR_2, WKUP_CLEAR_P3, status);
break;
case HW_GPIO_PORT_4:
HW_WKUP_REG_SETF(CLEAR_2, WKUP_CLEAR_P4, status);
break;
default:
ASSERT_WARNING(0);//Invalid argument
}
}
#endif
#endif /* dg_configUSE_HW_WKUP */
#endif /* HW_WKUP_H_ */
/**
* \}
* \}
* \}
*/
@@ -1,123 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup TCS_HANDLER
*
* \brief TCS Handler
*
* \{
*/
/**
****************************************************************************************
*
* @file sys_tcs.h
*
* @brief TCS Handler header file.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 SYS_TCS_H_
#define SYS_TCS_H_
#include <stdint.h>
#include "sdk_defs.h"
typedef enum sys_tcs_area_type {
#ifdef CONFIG_USE_BLE
tcs_ble,
#endif
#ifdef CONFIG_USE_FTDF
tcs_ftdf,
#endif
tcs_radio,
tcs_charger,
tcs_audio,
tcs_system, /* Last area. Add any missing areas above this! */
} sys_tcs_area_t;
/**
* \brief Flag to check whether the TCS is written or not.
* \details true, the TCS is written (the BANDGAP_REG value exists in the TCS)
* false, the TCS is empty
*/
extern bool sys_tcs_is_calibrated_chip;
/**
* \brief The XTAL16M settling time (in TCS).
* \details XTAL32K, the settling time is expressed in clock cycles
* RCX, not applicable; the SDK hard-coded value is used
* If it is zero, the hard-coded value (dg_configXTAL16_SETTLE_TIME) is applied.
*/
extern uint16_t sys_tcs_xtal16m_settling_time;
/**
* \brief Initialize the variables used from the TCS handling module.
*
*/
void sys_tcs_init(void);
/**
* \brief Store TCS <address, value> pair in the Global TCS array if it points to a register
* that is not in the AON power dowmain or is not retained, else it applies the vaule to
* the register.
*
* \param [in] address the address of the register
* \param [in] value the value for this register
*
* \return true if the chip is calibrated (the BANDGAP setting has been applied), else false.
*
* \warning When this function is called, the RC16 must have been set as the system clock!
*
*/
bool sys_tcs_store_pair(uint32_t address, uint32_t value);
/**
* \brief Sort the registers of the registers in the Memory Map of the chip to a different "classes"
* in the TCS array.
*
*/
void sys_tcs_sort_array(void);
/**
* \brief Apply the <address, value> pairs located in a "class" of the TCS array. This is done only
* for calibrated chips!
*
*/
void sys_tcs_apply(sys_tcs_area_t area);
#endif /* SYS_TCS_H_ */
/**
\}
\}
\}
*/
@@ -1,414 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup AES_HASH
* \{
*/
/**
****************************************************************************************
*
* @file hw_aes_hash.c
*
* @brief Implementation of the AES/Hash Engine Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_AES_HASH
#include <hw_aes_hash.h>
#include <hw_crypto.h>
#define MODE_IS_AES(m) (m <= HW_AES_CTR)
static void hw_aes_hash_wait_on_inactive(void)
{
while (!REG_GETF(AES_HASH, CRYPTO_STATUS_REG, CRYPTO_INACTIVE)) {
;
};
}
static void hw_aes_hash_set_mode(const hw_aes_hash_setup* setup)
{
uint32_t crypt0_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
switch (setup->mode) {
case HW_AES_ECB:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
break;
case HW_AES_CBC:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 3);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
AES_HASH->CRYPTO_MREG0_REG = setup->aesIvCtrblk_0_31;
AES_HASH->CRYPTO_MREG1_REG = setup->aesIvCtrblk_32_63;
AES_HASH->CRYPTO_MREG2_REG = setup->aesIvCtrblk_64_95;
AES_HASH->CRYPTO_MREG3_REG = setup->aesIvCtrblk_96_127;
break;
case HW_AES_CTR:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 2);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
AES_HASH->CRYPTO_MREG0_REG = setup->aesIvCtrblk_0_31;
AES_HASH->CRYPTO_MREG1_REG = setup->aesIvCtrblk_32_63;
AES_HASH->CRYPTO_MREG2_REG = setup->aesIvCtrblk_64_95;
AES_HASH->CRYPTO_MREG3_REG = setup->aesIvCtrblk_96_127;
break;
case HW_HASH_MD5:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
break;
case HW_HASH_SHA_1:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 1);
break;
case HW_HASH_SHA_256_224:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 2);
break;
case HW_HASH_SHA_256:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 0);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 3);
break;
case HW_HASH_SHA_384:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 0);
break;
case HW_HASH_SHA_512:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 1);
break;
case HW_HASH_SHA_512_224:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 2);
break;
case HW_HASH_SHA_512_256:
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_SEL, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG_MD, crypt0_ctrl_reg, 1);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ALG, crypt0_ctrl_reg, 3);
break;
}
AES_HASH->CRYPTO_CTRL_REG = crypt0_ctrl_reg;
}
static void hw_aes_hash_check_data_size(const hw_aes_hash_setup* setup)
{
switch (setup->mode) {
case HW_AES_ECB:
// In ECB mode the dataSize needs to be a multiple of 16.
ASSERT_ERROR(setup->dataSize % 0x10 == 0);
break;
case HW_AES_CBC:
case HW_AES_CTR:
// If more data is to come in CBC or CTR mode the dataSize needs to be a multiple of 16.
if (setup->moreDataToCome) {
ASSERT_ERROR(setup->dataSize % 0x10 == 0);
}
break;
case HW_HASH_MD5:
case HW_HASH_SHA_1:
case HW_HASH_SHA_256_224:
case HW_HASH_SHA_256:
case HW_HASH_SHA_384:
case HW_HASH_SHA_512:
case HW_HASH_SHA_512_224:
case HW_HASH_SHA_512_256:
// If more data is to come in hash mode the dataSize needs to be a multiple of 8.
if (setup->moreDataToCome) {
ASSERT_ERROR(setup->dataSize % 0x8 == 0);
}
break;
}
}
hw_aes_hash_cb hw_aes_hash_old_style_cb = NULL;
static void hw_aes_hash_old_cb_style_support(unsigned int status)
{
if (hw_aes_hash_old_style_cb) {
hw_aes_hash_old_style_cb();
}
}
void hw_aes_hash_enable_interrupt(hw_aes_hash_cb cb)
{
hw_aes_hash_old_style_cb = cb;
hw_crypto_enable_aes_hash_interrupt(hw_aes_hash_old_cb_style_support);
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
}
void hw_aes_hash_disable_interrupt(void)
{
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_IRQ_EN);
hw_crypto_disable_aes_hash_interrupt();
}
static inline uint32 hw_aes_hash_construct_word(const uint8 *data)
{
if ((uint32)data & 0x3) {
uint32 internal_buf;
uint8 *p = (uint8 *)&internal_buf + 3;
unsigned int i;
for (i = 0; i < 4; i++) {
*(p--) = *(data++);
}
return internal_buf;
}
else {
return SWAP32(*(uint32 *)data);
}
}
void hw_aes_hash_store_keys(hw_aes_key_size key_size, const uint8 *aes_keys, hw_aes_hash_key_exp_t key_exp)
{
volatile uint32 *kmem_ptr = &AES_HASH->CRYPTO_KEYS_START;
unsigned int key_wrds;
if (key_exp == HW_AES_DO_NOT_PERFORM_KEY_EXPANSION) {
/* Key expansion is provided by the software */
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP);
key_wrds = (key_size == HW_AES_256) ? 60 : (key_size == HW_AES_192) ? 52 : 44;
}
else {
/* Key expansion needs to be performed by the engine */
REG_SET_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP);
key_wrds = (key_size == HW_AES_256) ? 8 : (key_size == HW_AES_192) ? 6 : 4;
}
do {
*(kmem_ptr++) = hw_aes_hash_construct_word(aes_keys);
aes_keys += 4;
key_wrds--;
} while (key_wrds > 0);
}
void hw_aes_hash_enable(const hw_aes_hash_setup setup)
{
hw_aes_hash_check_data_size(&setup);
hw_aes_hash_enable_clock();
hw_aes_hash_set_mode(&setup);
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN, crypto_ctrl_reg,
setup.moreDataToCome);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(setup.hashOutLength - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC, crypto_ctrl_reg,
setup.aesDirection);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP, crypto_ctrl_reg,
setup.aesKeyExpand);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg,
setup.aesKeySize);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD, crypto_ctrl_reg,
!setup.aesWriteBackAll);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
if (MODE_IS_AES(setup.mode)) {
hw_aes_hash_store_keys(setup.aesKeySize, (uint8 *)setup.aesKeys, !setup.aesKeyExpand);
}
hw_aes_hash_cfg_dma((const uint8 *)setup.sourceAddress, (uint8 *)setup.destinationAddress,
(unsigned int)setup.dataSize);
if (setup.enableInterrupt) {
hw_aes_hash_old_style_cb = setup.callback;
hw_aes_hash_enable_interrupt_source();
hw_crypto_enable_aes_hash_interrupt(hw_aes_hash_old_cb_style_support);
}
else {
hw_aes_hash_disable_interrupt_source();
hw_crypto_disable_aes_hash_interrupt();
}
hw_aes_hash_start();
}
void hw_aes_hash_init(hw_aes_hash_setup *setup)
{
hw_aes_hash_check_data_size(setup);
hw_aes_hash_enable_clock();
hw_aes_hash_set_mode(setup);
uint32_t crypto_ctrl_reg = AES_HASH->CRYPTO_CTRL_REG;
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN, crypto_ctrl_reg,
setup->moreDataToCome);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_HASH_OUT_LEN, crypto_ctrl_reg,
(setup->hashOutLength - 1));
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_ENCDEC, crypto_ctrl_reg,
setup->aesDirection);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEXP, crypto_ctrl_reg,
setup->aesKeyExpand);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_AES_KEY_SZ, crypto_ctrl_reg,
setup->aesKeySize);
REG_SET_FIELD(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_OUT_MD, crypto_ctrl_reg,
!setup->aesWriteBackAll);
AES_HASH->CRYPTO_CTRL_REG = crypto_ctrl_reg;
if (MODE_IS_AES(setup->mode)) {
hw_aes_hash_store_keys(setup->aesKeySize, (uint8 *)setup->aesKeys, !setup->aesKeyExpand);
}
hw_aes_hash_cfg_dma((const uint8 *)setup->sourceAddress, (uint8 *)setup->destinationAddress,
(unsigned int)setup->dataSize);
if (setup->enableInterrupt) {
hw_aes_hash_old_style_cb = setup->callback;
hw_aes_hash_enable_interrupt_source();
hw_crypto_enable_aes_hash_interrupt(hw_aes_hash_old_cb_style_support);
}
else {
hw_aes_hash_disable_interrupt_source();
hw_crypto_disable_aes_hash_interrupt();
}
}
void hw_aes_hash_restart(const uint32 sourceAddress, const uint32 dataSize,
const bool moreDataToCome)
{
hw_aes_hash_cfg_dma((const uint8 *)sourceAddress, NULL, (unsigned int)dataSize);
REG_SETF(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN, moreDataToCome);
hw_aes_hash_start();
}
bool hw_aes_hash_is_active()
{
return REG_GETF(AES_HASH, CRYPTO_STATUS_REG, CRYPTO_INACTIVE) == 0;
}
bool hw_aes_hash_wait_for_in()
{
return REG_GETF(AES_HASH, CRYPTO_STATUS_REG, CRYPTO_WAIT_FOR_IN) == 1;
}
void hw_aes_hash_disable(const bool waitOnFinish)
{
if (waitOnFinish)
hw_aes_hash_wait_on_inactive();
hw_aes_hash_disable_interrupt_source();
AES_HASH->CRYPTO_CLRIRQ_REG = 1;
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE);
GLOBAL_INT_RESTORE();
REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN);
}
void hw_aes_hash_cfg_dma(const uint8 *src, uint8 *dst, unsigned int len)
{
/* Source address setting */
AES_HASH->CRYPTO_FETCH_ADDR_REG = DA15000_phy_addr((uint32)src);
/* Destination address setting */
if (dst) {
unsigned int remap_type = REG_GETF(CRG_TOP, SYS_CTRL_REG, REMAP_ADR0);
if (IS_SYSRAM_ADDRESS(dst) ||
(IS_REMAPPED_ADDRESS(dst) && (remap_type == 0x3))) {
AES_HASH->CRYPTO_DEST_ADDR_REG = DA15000_phy_addr((uint32)dst);
#if dg_configEXEC_MODE != MODE_IS_CACHED
} else if (IS_CACHERAM_ADDRESS(dst)) {
AES_HASH->CRYPTO_DEST_ADDR_REG = DA15000_phy_addr((uint32)dst);
#endif
} else {
/*
* Destination address can only reside in RAM or Cache RAM, but in case of remapped
* address, REMAP_ADR0 cannot be 0x6 (Cache Data RAM)
*/
ASSERT_ERROR(0);
}
}
/* Data length setting */
AES_HASH->CRYPTO_LEN_REG = (uint32)len;
}
static void hw_aes_hash_store_in_mode_dependent_regs(const uint8 *buf)
{
AES_HASH->CRYPTO_MREG0_REG = hw_aes_hash_construct_word(buf + 12);
AES_HASH->CRYPTO_MREG1_REG = hw_aes_hash_construct_word(buf + 8);
AES_HASH->CRYPTO_MREG2_REG = hw_aes_hash_construct_word(buf + 4);
AES_HASH->CRYPTO_MREG3_REG = hw_aes_hash_construct_word(buf + 0);
}
void hw_aes_hash_store_iv(const uint8 *iv)
{
hw_aes_hash_store_in_mode_dependent_regs(iv);
}
void hw_aes_hash_store_ic(const uint8 *ic)
{
hw_aes_hash_store_in_mode_dependent_regs(ic);
}
int hw_aes_hash_check_restrictions(void)
{
unsigned int is_hash = AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_HASH_SEL_Msk;
unsigned int more_in = AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_MORE_IN_Msk;
if (is_hash) {
if (more_in && (AES_HASH->CRYPTO_LEN_REG & 0x7)) {
return -1;
}
}
else {
unsigned int is_ecb = (((AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk) == 0) |
((AES_HASH->CRYPTO_CTRL_REG & AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Msk) == 0x0100));
if ((is_ecb || more_in) && (AES_HASH->CRYPTO_LEN_REG & 0x15)) {
return -1;
}
}
return 0;
}
#endif /* dg_configUSE_HW_AES_HASH */
/**
* \}
* \}
* \}
*/
@@ -1,856 +0,0 @@
/**
\addtogroup BSP
\{
\addtogroup DEVICES
\{
\addtogroup CPM
\{
*/
/**
****************************************************************************************
*
* @file hw_cpm.c
*
* @brief Clock and Power Manager Driver
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_CPM
#include <stdint.h>
#include "hw_cpm.h"
#include "hw_watchdog.h"
/*
* These variables should be defined and initialized by the framework/sdk used
*/
extern sys_clk_t cm_sysclk;
extern ahb_div_t cm_ahbclk;
/*
* Global variables
*/
__RETAINED_UNINIT uint16_t hw_cpm_bod_enabled_in_tcs;
#if (dg_configPOWER_1V8_ACTIVE == 1)
__RETAINED_RW static bool cpm_1v8_state = true;
#else
static const bool cpm_1v8_state = false;
#endif
/*
* Local variables
*/
/*
* Forward declarations
*/
/*
* Function definitions
*/
uint32_t hw_cpm_sysclk_is_rc16(void)
{
uint32_t ret = 0;
if (REG_GETF(CRG_TOP, CLK_CTRL_REG, SYS_CLK_SEL) == SYS_CLK_IS_RC16) {
ret = 1;
}
return ret;
}
uint32_t hw_cpm_sysclk_is_xtal16m(void)
{
uint32_t ret = 0;
if (REG_GETF(CRG_TOP, CLK_CTRL_REG, SYS_CLK_SEL) == SYS_CLK_IS_XTAL16M) {
ret = 1;
}
return ret;
}
void hw_cpm_set_divn(bool freq)
{
uint32_t regval;
int val;
if (freq) {
val = 1;
}
else {
val = 0;
}
regval = CRG_TOP->CLK_CTRL_REG;
REG_SET_FIELD(CRG_TOP, CLK_CTRL_REG, DIVN_XTAL32M_MODE, regval, val);
REG_SET_FIELD(CRG_TOP, CLK_CTRL_REG, XTAL32M_MODE, regval, val);
CRG_TOP->CLK_CTRL_REG = regval;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
CRG_TOP->DIVN_SYNC_REG = val;
#endif
}
bool hw_cpm_is_rc16_allowed(void)
{
bool ret = false;
uint32_t tmp;
do {
tmp = CRG_TOP->SYS_STAT_REG;
#ifdef CONFIG_USE_FTDF
// Check FTDF
if (tmp & REG_MSK(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP)) {
break;
}
#endif
#ifdef CONFIG_USE_BLE
// Check BLE
if (tmp & REG_MSK(CRG_TOP, SYS_STAT_REG, BLE_IS_UP)) {
break;
}
#endif
// Check APHY/DPHY & COEX
if (tmp & REG_MSK(CRG_TOP, SYS_STAT_REG, RAD_IS_UP)) {
break;
}
if (tmp & REG_MSK(CRG_TOP, SYS_STAT_REG, PER_IS_UP)) {
// Check SRC
if (REG_GETF(APU, SRC1_CTRL_REG, SRC_EN) == 1) {
break;
}
// Check PDM
if (REG_GETF(CRG_PER, PDM_DIV_REG, CLK_PDM_EN) == 1) {
break;
}
// Check USB
if (REG_GETF(USB, USB_MCTRL_REG, USBEN) == 1) {
break;
}
tmp = CRG_PER->CLK_PER_REG;
// Check UART1/2
if (tmp & REG_MSK(CRG_PER, CLK_PER_REG, UART_ENABLE)) {
break;
}
/* -------------------------------------------------------------------------------*/
// Check ADC clock
if (REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_EN) &&
(!(tmp & REG_MSK(CRG_PER, CLK_PER_REG, ADC_CLK_SEL)))) {
break;
}
// Check I2C clock
if ((tmp & REG_MSK(CRG_PER, CLK_PER_REG, I2C_ENABLE)) &&
(!(tmp & REG_MSK(CRG_PER, CLK_PER_REG, I2C_CLK_SEL)))) {
break;
}
// Check SPI clock
if ((tmp & REG_MSK(CRG_PER, CLK_PER_REG, SPI_ENABLE)) &&
(!(tmp & REG_MSK(CRG_PER, CLK_PER_REG, SPI_CLK_SEL)))) {
break;
}
// Check PCM clock
tmp = CRG_PER->PCM_DIV_REG;
if ((tmp & REG_MSK(CRG_PER, PCM_DIV_REG, CLK_PCM_EN)) &&
(!(tmp & REG_MSK(CRG_PER, PCM_DIV_REG, PCM_SRC_SEL)))) {
break;
}
/* KBSCN and QUAD are not seriously affected by the clock switch and, thus,
* they cannot block it!
*/
}
tmp = CRG_TOP->CLK_TMR_REG;
// Check Timer0 clock
if ((tmp & REG_MSK(CRG_TOP, CLK_TMR_REG, TMR0_ENABLE)) &&
(!(tmp & REG_MSK(CRG_TOP, CLK_TMR_REG, TMR0_CLK_SEL)))) {
break;
}
// Check Timer2 clock
if ((tmp & REG_MSK(CRG_TOP, CLK_TMR_REG, TMR2_ENABLE)) &&
(!(tmp & REG_MSK(CRG_TOP, CLK_TMR_REG, TMR2_CLK_SEL)))) {
break;
}
/* Breathe, SOC and WDOG are not seriously affected by the clock switch and, thus,
* they cannot block it!
*/
ret = true;
} while (0);
return ret;
}
void hw_cpm_set_sysclk(uint32_t mode)
{
/* Make sure a valid sys clock is requested */
ASSERT_WARNING(mode <= SYS_CLK_IS_PLL);
REG_SETF(CRG_TOP, CLK_CTRL_REG, SYS_CLK_SEL, mode);
// Wait until the switch is done!
switch (mode) {
case SYS_CLK_IS_XTAL16M:
while (REG_GETF(CRG_TOP, CLK_CTRL_REG, RUNNING_AT_XTAL16M) == 0) {}
break;
case SYS_CLK_IS_RC16:
while (REG_GETF(CRG_TOP, CLK_CTRL_REG, RUNNING_AT_RC16M) == 0) {}
break;
case SYS_CLK_IS_LP:
while (REG_GETF(CRG_TOP, CLK_CTRL_REG, RUNNING_AT_32K) == 0) {}
break;
case SYS_CLK_IS_PLL:
while (REG_GETF(CRG_TOP, CLK_CTRL_REG, RUNNING_AT_PLL96M) == 0) {}
break;
default:
ASSERT_WARNING(0);
break;
}
}
void hw_cpm_short_delay(void)
{
volatile int i;
for (i = 0; i < 20; i++);
}
void hw_cpm_pll_sys_on(void)
{
/* Before enabling the PLL LDO, the 1.4V voltage needs to be present; in real-life this
* is achieved by first turning on the 1.4V ACORE LDO, then the DCDC converter to take over
* the generation of 1.4V and finally turning off the ACORE LDO.
*/
/* LDO PLL enable. */
REG_SET_BIT(GPREG, PLL_SYS_CTRL1_REG, LDO_PLL_ENABLE);
/* Configure system PLL. */
REG_SETF(GPREG, PLL_SYS_CTRL1_REG, PLL_R_DIV, 1); /* Default/reset value. */
/* Program N-divider and DEL_SEL. */
REG_SET_BIT(GPREG, PLL_SYS_CTRL2_REG, PLL_SEL_MIN_CUR_INT); // Last review date: Feb 15, 2016 - 12:25:47
/* Now turn on PLL. */
REG_SET_BIT(GPREG, PLL_SYS_CTRL1_REG, PLL_EN);
while ((GPREG->PLL_SYS_STATUS_REG & REG_MSK(GPREG, PLL_SYS_STATUS_REG, LDO_PLL_OK)) == 0) {}
/* And wait until lock. */
while ((GPREG->PLL_SYS_STATUS_REG & REG_MSK(GPREG, PLL_SYS_STATUS_REG, PLL_LOCK_FINE)) == 0) {}
}
void hw_cpm_pll_sys_off(void)
{
// The PLL is not the system clk.
while ((CRG_TOP->CLK_CTRL_REG & REG_MSK(CRG_TOP, CLK_CTRL_REG, RUNNING_AT_PLL96M)) != 0);
GPREG->PLL_SYS_CTRL1_REG = 0x0000; // Switch off the PLL.
}
__RETAINED_CODE void hw_cpm_start_calibration(cal_clk_t clk_type, uint32_t cycles)
{
ASSERT_WARNING(REG_GETF(ANAMISC, CLK_REF_SEL_REG, REF_CAL_START) == 0); // Must be disabled
ANAMISC->CLK_REF_CNT_REG = cycles; // # of cal clock cycles
REG_SETF(ANAMISC, CLK_REF_SEL_REG, REF_CLK_SEL, clk_type);
REG_SET_BIT(ANAMISC, CLK_REF_SEL_REG, REF_CAL_START);
}
uint32_t hw_cpm_get_calibration_data(void)
{
uint32_t high;
uint32_t low;
uint32_t value;
while (REG_GETF(ANAMISC, CLK_REF_SEL_REG, REF_CAL_START) == 1); // Wait until it's finished
high = ANAMISC->CLK_REF_VAL_H_REG;
low = ANAMISC->CLK_REF_VAL_L_REG;
value = ( high << 16 ) + low;
return value;
}
void hw_cpm_dcdc_config(void)
{
uint32_t reg;
/*
* Preferred settings section
* Last review date: January 03, 2017 - 16:26:35
*/
REG_CLR_BIT(DCDC, DCDC_CTRL_0_REG, DCDC_FW_ENABLE);
reg = DCDC->DCDC_IRQ_MASK_REG;
REG_SET_FIELD(DCDC, DCDC_IRQ_MASK_REG, DCDC_V18P_TIMEOUT_IRQ_MASK, reg, 1);
REG_SET_FIELD(DCDC, DCDC_IRQ_MASK_REG, DCDC_VDD_TIMEOUT_IRQ_MASK, reg, 1);
REG_SET_FIELD(DCDC, DCDC_IRQ_MASK_REG, DCDC_V18_TIMEOUT_IRQ_MASK, reg, 1);
REG_SET_FIELD(DCDC, DCDC_IRQ_MASK_REG, DCDC_V14_TIMEOUT_IRQ_MASK, reg, 1);
DCDC->DCDC_IRQ_MASK_REG = reg;
REG_SET_BIT(DCDC, DCDC_TRIM_REG, DCDC_P_COMP_MAN_TRIM);
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
DCDC->DCDC_V14_0_REG &= ~(REG_MSK(DCDC, DCDC_V14_0_REG, DCDC_V14_CUR_LIM_MIN) |
REG_MSK(DCDC, DCDC_V14_0_REG, DCDC_V14_FAST_RAMPING));
DCDC->DCDC_V18_0_REG &= ~(REG_MSK(DCDC, DCDC_V18_0_REG, DCDC_V18_CUR_LIM_MIN) |
REG_MSK(DCDC, DCDC_V18_0_REG, DCDC_V18_FAST_RAMPING));
DCDC->DCDC_V18P_0_REG &= ~(REG_MSK(DCDC, DCDC_V18P_0_REG, DCDC_V18P_CUR_LIM_MIN) |
REG_MSK(DCDC, DCDC_V18P_0_REG, DCDC_V18P_FAST_RAMPING));
DCDC->DCDC_VDD_0_REG &= ~(REG_MSK(DCDC, DCDC_VDD_0_REG, DCDC_VDD_CUR_LIM_MIN) |
REG_MSK(DCDC, DCDC_VDD_0_REG, DCDC_VDD_FAST_RAMPING));
#else
DCDC->DCDC_V14_0_REG &= ~REG_MSK(DCDC, DCDC_V14_0_REG, DCDC_V14_FAST_RAMPING);
DCDC->DCDC_V18_0_REG &= ~REG_MSK(DCDC, DCDC_V18_0_REG, DCDC_V18_FAST_RAMPING);
DCDC->DCDC_V18P_0_REG &= ~REG_MSK(DCDC, DCDC_V18P_0_REG, DCDC_V18P_FAST_RAMPING);
DCDC->DCDC_VDD_0_REG &= ~REG_MSK(DCDC, DCDC_VDD_0_REG, DCDC_VDD_FAST_RAMPING);
reg = DCDC->DCDC_CTRL_2_REG;
REG_SET_FIELD(DCDC, DCDC_CTRL_2_REG, DCDC_LSSUP_TRIM, reg, 0);
REG_SET_FIELD(DCDC, DCDC_CTRL_2_REG, DCDC_HSGND_TRIM, reg, 0);
DCDC->DCDC_CTRL_2_REG = reg;
#endif
REG_SETF(DCDC, DCDC_VDD_1_REG, DCDC_VDD_CUR_LIM_MAX_LV, 0xD);
REG_SETF(DCDC, DCDC_V14_0_REG, DCDC_V14_VOLTAGE, 0x8);
if (dg_configPOWER_1V8_ACTIVE == 1) {
REG_SETF(DCDC, DCDC_V18_0_REG, DCDC_V18_VOLTAGE, 0x16);
}
if (dg_configPOWER_1V8P == 1) {
REG_SETF(DCDC, DCDC_V18P_0_REG, DCDC_V18P_VOLTAGE, 0x16);
}
// End of preferred settings
DCDC->DCDC_VDD_1_REG |= ((1 << REG_POS(DCDC, DCDC_VDD_1_REG, DCDC_VDD_ENABLE_HV)) |
(1 << REG_POS(DCDC, DCDC_VDD_1_REG, DCDC_VDD_ENABLE_LV)));
if ((dg_configPOWER_1V8_ACTIVE == 1) && cpm_1v8_state) {
DCDC->DCDC_V18_1_REG |= (1 << REG_POS(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_HV));
DCDC->DCDC_V18_1_REG &= ~REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_LV);
}
else {
DCDC->DCDC_V18_1_REG &= ~(REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_HV) |
REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_LV));
}
if (dg_configPOWER_1V8P == 1) {
DCDC->DCDC_V18P_1_REG |= (1 << REG_POS(DCDC, DCDC_V18P_1_REG, DCDC_V18P_ENABLE_HV));
DCDC->DCDC_V18P_1_REG &= ~REG_MSK(DCDC, DCDC_V18P_1_REG, DCDC_V18P_ENABLE_LV);
}
else {
DCDC->DCDC_V18P_1_REG &= ~(REG_MSK(DCDC, DCDC_V18P_1_REG, DCDC_V18P_ENABLE_HV) |
REG_MSK(DCDC, DCDC_V18P_1_REG, DCDC_V18P_ENABLE_LV));
}
}
void hw_cpm_dcdc_on(void)
{
DCDC->DCDC_V14_1_REG |= ((1 << REG_POS(DCDC, DCDC_V14_1_REG, DCDC_V14_ENABLE_HV)) |
(1 << REG_POS(DCDC, DCDC_V14_1_REG, DCDC_V14_ENABLE_LV)));
REG_SETF(DCDC, DCDC_VDD_0_REG, DCDC_VDD_VOLTAGE, 0x10); // 1.2 V
REG_SETF(DCDC, DCDC_CTRL_0_REG, DCDC_MODE, 1);
// Trim the LDOs down to lowest possible voltage so DCDC can take over
CRG_TOP->LDO_CTRL1_REG &= ~REG_MSK(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_SETVDD);
REG_SETF(CRG_TOP, LDO_CTRL1_REG, LDO_CORE_SETVDD, 0x2);
// Turn off LDOs
CRG_TOP->LDO_CTRL1_REG &= ~REG_MSK(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_ENABLE);
CRG_TOP->LDO_CTRL2_REG &= ~(REG_MSK(CRG_TOP, LDO_CTRL2_REG, LDO_1V2_ON) |
REG_MSK(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_ON) |
REG_MSK(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_PA_ON));
// Trim the LDOs back to normal levels
hw_cpm_reset_radio_vdd();
CRG_TOP->LDO_CTRL1_REG &= ~REG_MSK(CRG_TOP, LDO_CTRL1_REG, LDO_CORE_SETVDD);
}
void hw_cpm_set_preferred_values(void)
{
uint32_t reg;
reg = CRG_TOP->CLK_16M_REG;
REG_SET_FIELD(CRG_TOP, CLK_16M_REG, XTAL16_HPASS_FLT_EN, reg, 1); // Last review date: Feb 15, 2016 - 12:25:47
REG_SET_FIELD(CRG_TOP, CLK_16M_REG, XTAL16_AMP_TRIM, reg, 5);
REG_SET_FIELD(CRG_TOP, CLK_16M_REG, XTAL16_CUR_SET, reg, 5);
CRG_TOP->CLK_16M_REG = reg;
REG_SETF(CRG_TOP, BANDGAP_REG, LDO_SLEEP_TRIM, 0x8);
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
REG_SETF(CRG_TOP, BANDGAP_REG, BYPASS_COLD_BOOT_DISABLE, 1); // Last review date: Feb 15, 2016 - 12:25:47
#else
/* Hardcoding this since this will be used in AUTO mode as well (uartboot), where
* the AE datasheet is included (it doesn't contain this reg)
*/
volatile uint16_t *xtal16m_ctrl_reg = (volatile uint16_t *)0x50000056;
/* The following code corresponds to (in BB):
REG_SET_FIELD(CRG_TOP, XTAL16M_CTRL_REG, XTAL16M_ENABLE_ZERO, reg, 1);
REG_SET_FIELD(CRG_TOP, XTAL16M_CTRL_REG, XTAL16M_AMP_REG_SIG_SEL, reg, 1);
*/
*xtal16m_ctrl_reg |= 0x100UL | 0x8UL;
/* The following corresponds to
REG_SETF(CRG_TOP, BANDGAP_REG, LDO_SUPPLY_USE_BGREF, 1);
*/
CRG_TOP->BANDGAP_REG |= 0x4000UL;
#endif
}
void hw_cpm_configure_xtal32k_pins(void)
{
GPIO->P20_MODE_REG = 0x26;
GPIO->P21_MODE_REG = 0x26;
}
void hw_cpm_configure_ext32k_pins(void)
{
GPIO->P20_MODE_REG = 0x0;
}
void hw_cpm_trigger_sw_cursor(void)
{
if (dg_configUSE_SW_CURSOR == 1) {
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_D) {
SW_CURSOR_SET = 1 << SW_CURSOR_PIN;
}
else {
SW_CURSOR_RESET = 1 << SW_CURSOR_PIN;
}
SW_CURSOR_GPIO = 0x300;
hw_cpm_delay_usec(50);
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_D) {
SW_CURSOR_RESET = 1 << SW_CURSOR_PIN;
}
hw_cpm_setup_sw_cursor();
}
}
void hw_cpm_reset_system(void)
{
__asm volatile ( " cpsid i " );
hw_watchdog_unregister_int();
hw_watchdog_set_pos_val(1);
hw_watchdog_unfreeze();
while (1);
}
void hw_cpm_reboot_system(void)
{
__asm volatile ( " cpsid i " );
hw_watchdog_gen_RST();
hw_watchdog_set_pos_val(1);
hw_watchdog_unfreeze();
while (1);
}
void hw_cpm_assert_trigger_gpio(void)
{
if (EXCEPTION_DEBUG == 1) {
if (dg_configLP_CLK_SOURCE == LP_CLK_IS_DIGITAL) {
hw_cpm_configure_ext32k_pins();
} else if ((dg_configUSE_LP_CLK == LP_CLK_32000)
|| (dg_configUSE_LP_CLK == LP_CLK_32768)) {
hw_cpm_configure_xtal32k_pins();
}
hw_cpm_power_up_per_pd();
hw_cpm_deactivate_pad_latches();
DBG_SET_HIGH(EXCEPTION_DEBUG, EXCEPTIONDBG);
}
}
#define HW_CPM_ACTIVATE_BOD_PROTECTION \
do { \
uint16_t val = 0; \
\
REG_SETF(CRG_TOP, BOD_CTRL_REG, BOD_VDD_LVL, 1); /* VDD Level (700mV) */ \
\
if (hw_cpm_bod_enabled_in_tcs == 0) { \
val = 0; \
/* VBAT enable */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_VBAT_EN, val, 1); \
/* 1V8 Flash enable */ \
if ((dg_configPOWER_1V8_ACTIVE == 1) && (dg_configPOWER_1V8_SLEEP == 1)) { \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN, val, 1); \
} \
/* 1V8P enable */ \
if (dg_configPOWER_1V8P == 1) { \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN, val, 1); \
} \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_VDD_EN, val, 1); /* VDD enable */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_RESET_EN, val, 1); /* Reset enable */\
CRG_TOP->BOD_CTRL2_REG = val; \
} \
else { \
CRG_TOP->BOD_CTRL2_REG = hw_cpm_bod_enabled_in_tcs; \
} \
} while (0);
void hw_cpm_activate_bod_protection(void)
{
HW_CPM_ACTIVATE_BOD_PROTECTION
}
void hw_cpm_activate_bod_protection_at_init(void)
{
HW_CPM_ACTIVATE_BOD_PROTECTION
}
void hw_cpm_configure_bod_protection(void)
{
REG_SETF(CRG_TOP, BOD_CTRL_REG, BOD_VDD_LVL, 1); /* VDD Level (700mV) */
if (hw_cpm_bod_enabled_in_tcs == 0) {
/* VBAT enable */
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_VBAT_EN);
/* 1V8 Flash enable */
if ((dg_configPOWER_1V8_ACTIVE == 1) && (dg_configPOWER_1V8_SLEEP == 1)) {
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN);
} else {
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN);
}
/* 1V8P enable */
if (dg_configPOWER_1V8P == 1) {
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN);
} else {
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN);
}
/* Generate Reset on a BOD event */
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_RESET_EN);
}
else {
CRG_TOP->BOD_CTRL2_REG = hw_cpm_bod_enabled_in_tcs;
}
}
void hw_cpm_set_1v8_state(bool state)
{
if ((dg_configPOWER_1V8_ACTIVE == 1) && (cpm_1v8_state != state)) {
uint32_t reg;
uint32_t dcdc_state;
GLOBAL_INT_DISABLE();
reg = CRG_TOP->LDO_CTRL2_REG;
dcdc_state = (uint32_t)REG_GETF(DCDC, DCDC_CTRL_0_REG, DCDC_MODE);
#if (dg_configPOWER_1V8_ACTIVE == 1)
cpm_1v8_state = state;
#endif
if (!cpm_1v8_state) {
// Disable BOD for the 1V8 rail
if (dg_configUSE_BOD == 1) {
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN);
}
// Deactivate 1V8 rail in LDOs
REG_CLR_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_ON, reg);
if (dg_configPOWER_1V8_SLEEP == 1) {
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_RET_DISABLE,
reg, 1);
}
CRG_TOP->LDO_CTRL2_REG = reg;
// Deactivate 1V8 rail in DCDC
if (dg_configUSE_DCDC == 1) {
// Disable DCDC to apply change
REG_SETF(DCDC, DCDC_CTRL_0_REG, DCDC_MODE, 0);
DCDC->DCDC_V18_1_REG &=
~(REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_HV) |
REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_LV));
// Restore DCDC
REG_SETF(DCDC, DCDC_CTRL_0_REG, DCDC_MODE, dcdc_state);
}
} else {
// Restore 1V8 rail in LDOs
/* But not when DCDC is running... */
if (dcdc_state != 1) {
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_ON,
reg, 1);
}
if (dg_configPOWER_1V8_SLEEP == 1) {
REG_CLR_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_RET_DISABLE,
reg);
}
CRG_TOP->LDO_CTRL2_REG = reg;
// Restore 1V8 rail in DCDC
if (dg_configUSE_DCDC == 1) {
DCDC->DCDC_V18_1_REG |= (1 << REG_POS(DCDC, DCDC_V18_1_REG,
DCDC_V18_ENABLE_HV));
DCDC->DCDC_V18_1_REG &= ~REG_MSK(DCDC, DCDC_V18_1_REG,
DCDC_V18_ENABLE_LV);
}
// Restore BOD setup
if (dg_configUSE_BOD == 1) {
hw_cpm_delay_usec(200);
hw_cpm_configure_bod_protection();
}
}
GLOBAL_INT_RESTORE();
}
}
bool hw_cpm_get_1v8_state(void)
{
return cpm_1v8_state;
}
void hw_cpm_delay_usec(uint32_t usec)
{
sys_clk_t sclk;
ahb_div_t hclk;
uint8_t freq;
sclk = cm_sysclk;
hclk = cm_ahbclk;
freq = 16 >> hclk;
/* Requested delay time must be > 0 usec */
ASSERT_WARNING(usec != 0);
/*
* ldr r3, [pc, #148] 2 cycles
* push {r4, lr} 2 cycles
* ldrb r1, [r3, #17] 2 cycles
* ldrb r2, [r3, #8] 2 cycles
* movs r3, #16 1 cycle
* asrs r3, r2 1 cycle
* uxtb r3, r2 1 cycle
* ----------
* cmp r0, #0 4 cycles overhead in total
* bne.n 0x8003106 <hw_cpm_delay_usec+30>
* cpsid i
* bkpt 0x0002
*
* Total: 11 cycles
*/
__asm volatile( " cmp %[sclk], #1 \n" // 1 cycle : 1 (sysclk_RC16, sysclk_XTAL16M)
" ble start \n" // 1 or 3 cycles: 2/4
" cmp %[sclk], #3 \n" // 1 cycle : 3 (sysclk_PLL48)
" bgt s96M \n" // 1 or 3 cycles: 4/6
" blt s32M \n" // 1 or 3 cycles: 5/7
"s48M: add r4, %[freq], %[freq] \n" // 1 cycle : 6
" add %[freq], r4, %[freq] \n" // 1 cycle : 7
" b start \n" // 3 cycles : 10
"s96M: add r4, %[freq], %[freq] \n" // 1 cycle : 7
" add %[freq], r4, %[freq] \n" // 1 cycle : 8
" lsl %[freq], %[freq], #1 \n" // 1 cycle : 9
" b start \n" // 3 cycles : 12
"s32M: lsl %[freq], %[freq], #1 \n" // 1 cycle : 8
/* -----------------------------------------------------*/
/* Overhead up to this point:
* sysclk_RC16 : 15 cycles (error: 15/16 - 15 usec)
* sysclk_XTAL16M : 15 cycles (error: 15/16 - 15 usec)
* sysclk_XTAL32M : 19 cycles (error: 19/32 - 19/2 usec)
* sysclk_PLL48 : 21 cycles (error: 21/48 - 21/3 usec)
* sysclk_PLL96 : 23 cycles (error: 23/96 - 23/6 usec)
*/
"start: cmp %[freq], #16 \n" // 1 cycle : 1
" bgt high \n" // 1 or 3 cycles: 2/4
" blt low \n" // 1 or 3 cycles: 3/5
" mov %[sclk], #4 \n" // 1 cycle : 4
" b calc \n" // 3 cycles : 7
"high: cmp %[freq], #24 \n" // 1 cycle : 5
" bne c32M \n" // 1 or 3 cycles: 6/8
" mov %[sclk], #6 \n" // 1 cycle : 7
" b calc \n" // 3 cycles : 10
"c32M: cmp %[freq], #32 \n" // 1 cycle : 9
" bne c48M \n" // 1 or 3 cycles: 10/12
" mov %[sclk], #8 \n" // 1 cycle : 11
" b calc \n" // 3 cycles : 12
"c48M: cmp %[freq], #48 \n" // 1 cycle : 13
" bne c96M \n" // 1 or 3 cycles: 14/16
" mov %[sclk], #12 \n" // 1 cycle : 15
" b calc \n" // 3 cycles : 18
"c96M: mov %[sclk], #24 \n" // 1 cycle : 17
" b calc \n" // 3 cycles : 20
"low: cmp %[freq], #1 \n" // 1 cycle : 6
" bgt c2M \n" // 1 or 3 cycles: 7/9
" lsr %[usec], %[usec], #2 \n" // 1 cycle : 8
" b loop \n" // 3 cycles : 11
"c2M: cmp %[freq], #2 \n" // 1 cycle : 10
" bgt c3M \n" // 1 or 3 cycles: 11/13
" lsr %[usec], %[usec], #1 \n" // 1 cycle : 12
" b loop \n" // 3 cycles : 15
"c3M: cmp %[freq], #3 \n" // 1 cycle : 14
" bgt c4M \n" // 1 or 3 cycles: 15/17
" lsr %[usec], %[usec], #1 \n" // 1 cycle : 16
" b loop1 \n" // 3 cycles : 19
"c4M: cmp %[freq], #4 \n" // 1 cycle : 18
" bgt c6M \n" // 1 or 3 cycles: 19/21
" b loop \n" // 3 cycles : 22
"c6M: cmp %[freq],#6 \n" // 1 cycle : 22
" bgt c8M \n" // 1 or 3 cycles: 23/25
" b loop1 \n" // 3 cycles : 26
"c8M: cmp %[freq], #8 \n" // 1 cycle : 26
" bgt c12M \n" // 1 or 3 cycles: 27/29
" mov %[sclk], #2 \n" // 1 cycle : 28
" b calc \n" // 3 cycles : 31
"c12M: mov %[sclk], #2 \n" // 1 cycle : 30
" mul %[usec], %[sclk], %[usec] \n" // 1 cycle : 31
/* Error:
* 1MHz: 11 cycles, 11usec
* 2MHz: 15 cycles, 7.5usec
* 3MHz: 19 cycles, 6.33usec
* 4MHz: 22 cycles, 5.5usec
* 6MHz: 26 cycles, 4.33usec
* 8MHz: 31 cycles, 3.875usec
* 12MHz: 31 cycles, 2.584usec
* 16MHz: 8 cycles, 0.5usec
* 24MHz: 11 cycles, 0.459usec
* 32MHz: 13 cycles, 0.406usec
* 48MHz: 19 cycles, 0.396usec
* 96MHz: 21 cycles, 0.219usec
*
* 1 loop of 4 cycles is --- 1 usec is # loops
* 1MHz: 4usec --- divide (usec) by 4 (up to 5usec error)
* 2MHz: 2usec --- divide (usec) by 2 (up to 2usec error)
* 4MHz: 1usec --- 1 loop ( 0*4 + 1*2, 0.5000usec error)
* 8MHz: 500nsec --- 2 loops ( 1*4 + 1*2, 0.2500usec error)
* 16MHz: 250nsec --- 4 loops ( 3*4 + 1*2, 0.5000usec error)
* 24MHz: 167nsec --- 6 loops ( 5*4 + 1*2, 0.0830usec error)
* 32MHz: 125nsec --- 8 loops ( 7*4 + 1*2, 0.0625usec error)
* 48MHz: 84nsec --- 12 loops (11*4 + 1*2, 0.0420usec error)
* 96MHz: 42nsec --- 24 loops (23*4 + 1*2, 0.0210usec error)
*
* 1 loop of 6 cycles is --- 1 usec is # loops
* 3MHz: 2usec --- divide (usec) by 2 (up to 3usec error)
* 6MHz: 1usec --- 1 loop ( 0*6 + 1*7, 0.1670usec error)
* 12MHz: 0.5usec --- 2 loops ( 1*6 + 1*7, 0.0830usec error)
*
* Cumulative error is:
* 1MHz: 11 + 5 = 16usec
* 2MHz: 7.5 + 2 = 9.5usec
* 3MHz: 6.33 + 3 = 9.33usec
* 4MHz: 5.5 + 0.5 = 6usec
* 6MHz: 4.33 + 0.167 = 4.5usec
* 8MHz: 3.875 + 0.25 = 4.125usec
* 12MHz: 2.584 + 0.083 = 2.67usec
* 16MHz: 0.5 + 0.5 = 1usec
* 24MHz: 0.459 + 0.083 = 0.541usec
* 32MHz: 0.406 + 0.0625 = 0.469usec
* 48MHz: 0.396 + 0.042 = 0.438usec
* 96MHz: 0.219 + 0.021 = 0.429usec
*/
"loop1: sub %[usec], %[usec], #1 \n" // 1 cycle
" nop \n" // 1 cycle
" nop \n" // 1 cycle
" bne loop1 \n" // 3 cycles except for the last one which is 1
" b exit \n" // 3 cycles
"calc: mul %[usec], %[sclk], %[usec] \n" // 1 cycle
"loop: sub %[usec], %[usec], #1 \n" // 1 cycle
" bne loop \n" // 3 cycles except for the last one which is 1
"exit: \n"
:
: /* output */
[usec] "r" (usec), [freq] "r" (freq), [sclk] "r" (sclk) : /* inputs (%0, %1, %2) */
"r4"); /* registers that are destroyed */
}
#endif /* dg_configUSE_HW_CPM */
/**
\}
\}
\}
*/
@@ -1,126 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup CRYPTO
* \{
*/
/**
****************************************************************************************
*
* @file hw_crypto.c
*
* @brief Implementation of interrupt handling for the AES/Hash and ECC Engines.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC)
#include "hw_crypto.h"
#if (dg_configSYSTEMVIEW)
# include "SEGGER_SYSVIEW_FreeRTOS.h"
#else
# define SEGGER_SYSTEMVIEW_ISR_ENTER()
# define SEGGER_SYSTEMVIEW_ISR_EXIT()
#endif
__RETAINED static hw_crypto_cb hw_crypto_aes_hash_cb;
__RETAINED static hw_crypto_cb hw_crypto_ecc_cb;
void hw_crypto_enable_aes_hash_interrupt(hw_crypto_cb cb)
{
/* A callback for the interrupt must be provided */
ASSERT_ERROR(cb);
hw_crypto_aes_hash_cb = cb;
NVIC_EnableIRQ(CRYPTO_IRQn);
}
void hw_crypto_enable_ecc_interrupt(hw_crypto_cb cb)
{
/* A callback for the interrupt must be provided */
ASSERT_ERROR(cb);
hw_crypto_ecc_cb = cb;
NVIC_EnableIRQ(CRYPTO_IRQn);
}
void hw_crypto_disable_aes_hash_interrupt(void)
{
hw_crypto_aes_hash_cb = NULL;
if (!hw_crypto_ecc_cb) {
NVIC_DisableIRQ(CRYPTO_IRQn);
}
}
void hw_crypto_disable_ecc_interrupt(void)
{
hw_crypto_ecc_cb = NULL;
if (!hw_crypto_aes_hash_cb) {
NVIC_DisableIRQ(CRYPTO_IRQn);
}
}
void CRYPTO_Handler(void)
{
SEGGER_SYSTEMVIEW_ISR_ENTER();
uint32_t status = AES_HASH->CRYPTO_STATUS_REG;
/* In case both AES/HASH and ECC have triggered an interrupt, first the AES/HASH
will be served, and then the ISR will be called again since the ECC interrupt
source is only cleared by reading its status register */
if (status & AES_HASH_CRYPTO_STATUS_REG_CRYPTO_IRQ_ST_Msk) {
/* Clear AES/HASH interrupt source */
AES_HASH->CRYPTO_CLRIRQ_REG = 0x1;
if (hw_crypto_aes_hash_cb != NULL) {
hw_crypto_aes_hash_cb(status);
}
} else {
/* Clear ECC interrupt source */
status = ECC->ECC_STATUS_REG;
if (hw_crypto_ecc_cb != NULL) {
hw_crypto_ecc_cb(status);
}
}
SEGGER_SYSTEMVIEW_ISR_EXIT();
}
#endif /* (dg_configUSE_HW_AES_HASH || dg_configUSE_HW_ECC) */
/**
* \}
* \}
* \}
*/
@@ -1,425 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup DMA
* \{
*/
/**
****************************************************************************************
*
* @file hw_dma.c
*
* @brief Implementation of the DMA Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_DMA
#include <hw_gpio.h>
#include <hw_dma.h>
#if (dg_configSYSTEMVIEW)
# include "SEGGER_SYSVIEW_FreeRTOS.h"
#else
# define SEGGER_SYSTEMVIEW_ISR_ENTER()
# define SEGGER_SYSTEMVIEW_ISR_EXIT()
#endif
static struct hw_dma_callback_data {
hw_dma_transfer_cb callback;
void *user_data;
} dma_callbacks_user_data[8];
#define DMA_CHN_REG(reg, chan) ((volatile uint16 *)(&(reg)) + ((chan) * 8))
/**
* \brief Initialize DMA Channel
*
* \param [in] channel_setup pointer to struct of type DMA_Setup
*
*/
void hw_dma_channel_initialization(DMA_setup *channel_setup)
{
volatile uint16 *dma_x_ctrl_reg;
volatile uint16 *dma_x_a_start_low_reg;
volatile uint16 *dma_x_a_start_high_reg;
volatile uint16 *dma_x_b_start_low_reg;
volatile uint16 *dma_x_b_start_high_reg;
volatile uint16 *dma_x_len_reg;
volatile uint16 *dma_x_int_reg;
uint32 src_address;
uint32 dest_address;
/* Make sure the DMA channel length is not zero */
ASSERT_WARNING(channel_setup->length > 0);
// Look up DMAx_CTRL_REG address
dma_x_ctrl_reg = DMA_CHN_REG(DMA->DMA0_CTRL_REG, channel_setup->channel_number);
// Look up DMAx_A_STARTL_REG address
dma_x_a_start_low_reg = DMA_CHN_REG(DMA->DMA0_A_STARTL_REG, channel_setup->channel_number);
// Look up DMAx_A_STARTH_REG address
dma_x_a_start_high_reg = DMA_CHN_REG(DMA->DMA0_A_STARTH_REG, channel_setup->channel_number);
// Look up DMAx_B_STARTL_REG address
dma_x_b_start_low_reg = DMA_CHN_REG(DMA->DMA0_B_STARTL_REG, channel_setup->channel_number);
// Look up DMAx_B_STARTH_REG address
dma_x_b_start_high_reg = DMA_CHN_REG(DMA->DMA0_B_STARTH_REG, channel_setup->channel_number);
// Look up DMAX_LEN_REG address
dma_x_len_reg = DMA_CHN_REG(DMA->DMA0_LEN_REG, channel_setup->channel_number);
// Look up DMAX_INT
dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, channel_setup->channel_number);
// Make sure DMA channel is disabled first
REG_SET_FIELD(DMA, DMA0_CTRL_REG, DMA_ON, *dma_x_ctrl_reg, HW_DMA_STATE_DISABLED);
// Set DMAx_CTRL_REG width provided settings, but do not start the channel.
// Start the channel with the "dma_channel_enable" function separately.
*dma_x_ctrl_reg =
channel_setup->bus_width |
channel_setup->irq_enable |
channel_setup->dreq_mode |
channel_setup->b_inc |
channel_setup->a_inc |
channel_setup->circular |
channel_setup->dma_prio |
channel_setup->dma_idle |
channel_setup->dma_init;
// Set DMA_REQ_MUX_REG for the requested channel / trigger combination
if (channel_setup->dma_req_mux != HW_DMA_TRIG_NONE) {
switch (channel_setup->channel_number) {
case HW_DMA_CHANNEL_0:
case HW_DMA_CHANNEL_1:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA01_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
case HW_DMA_CHANNEL_2:
case HW_DMA_CHANNEL_3:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA23_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
case HW_DMA_CHANNEL_4:
case HW_DMA_CHANNEL_5:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA45_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
case HW_DMA_CHANNEL_6:
case HW_DMA_CHANNEL_7:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA67_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
default:
break;
}
#if dg_configDMA_DYNAMIC_MUX || (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
/*
* When different DMA channels are used for same device it is important
* that only one trigger is set for specific device at a time.
* Having same trigger for different channels can cause unpredictable results.
* Following code also should help when SPI1 is assigned to non 0 channel.
*/
GLOBAL_INT_DISABLE();
switch (channel_setup->channel_number) {
case HW_DMA_CHANNEL_6:
case HW_DMA_CHANNEL_7:
if (REG_GETF(DMA, DMA_REQ_MUX_REG, DMA45_SEL) == channel_setup->dma_req_mux) {
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA45_SEL, HW_DMA_TRIG_NONE);
}
/* no break */
case HW_DMA_CHANNEL_4:
case HW_DMA_CHANNEL_5:
if (REG_GETF(DMA, DMA_REQ_MUX_REG, DMA23_SEL) == channel_setup->dma_req_mux) {
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA23_SEL, HW_DMA_TRIG_NONE);
}
/* no break */
case HW_DMA_CHANNEL_2:
case HW_DMA_CHANNEL_3:
if (REG_GETF(DMA, DMA_REQ_MUX_REG, DMA01_SEL) == channel_setup->dma_req_mux) {
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA01_SEL, HW_DMA_TRIG_NONE);
}
break;
case HW_DMA_CHANNEL_0:
case HW_DMA_CHANNEL_1:
default:
break;
}
GLOBAL_INT_RESTORE();
#endif
}
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B)
//Set REQ_SENSE bit of i2c, USB and Uart peripherals TX path
if (((channel_setup->dma_req_mux == HW_DMA_TRIG_UART_RXTX) ||
(channel_setup->dma_req_mux == HW_DMA_TRIG_UART2_RXTX) ||
(channel_setup->dma_req_mux == HW_DMA_TRIG_I2C_RXTX) ||
(channel_setup->dma_req_mux == HW_DMA_TRIG_I2C2_RXTX) ||
(channel_setup->dma_req_mux == HW_DMA_TRIG_USB_RXTX)) &&
(channel_setup->channel_number & 1)) {//odd channels used for TX
REG_SET_FIELD(DMA, DMA0_CTRL_REG, REQ_SENSE, *dma_x_ctrl_reg, 1);
}
#endif
src_address = DA15000_phy_addr(channel_setup->src_address);
dest_address = DA15000_phy_addr(channel_setup->dest_address);
// Set source address registers
*dma_x_a_start_low_reg = (src_address & 0xffff);
*dma_x_a_start_high_reg = (src_address >> 16);
// Set destination address registers
*dma_x_b_start_low_reg = (dest_address & 0xffff);
*dma_x_b_start_high_reg = (dest_address >> 16);
// Set IRQ number of transfers
if (channel_setup->irq_nr_of_trans > 0) {
// If user explicitly set this number use it
*dma_x_int_reg = channel_setup->irq_nr_of_trans - 1;
} else {
// If user passed 0, use transfer length to fire interrupt after transfer ends
*dma_x_int_reg = channel_setup->length - 1;
}
// Set the transfer length
*dma_x_len_reg = (channel_setup->length) - 1;
if (channel_setup->irq_enable)
dma_callbacks_user_data[channel_setup->channel_number].callback = channel_setup->callback;
else
dma_callbacks_user_data[channel_setup->channel_number].callback = NULL;
dma_callbacks_user_data[channel_setup->channel_number].user_data = channel_setup->user_data;
}
void hw_dma_channel_update_source(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
hw_dma_transfer_cb cb)
{
uint32_t phy_addr = DA15000_phy_addr((uint32_t) addr);
dma_callbacks_user_data[channel].callback = cb;
// Look up DMAx_A_STARTL_REG address
volatile uint16 *dma_x_a_start_low_reg = DMA_CHN_REG(DMA->DMA0_A_STARTL_REG, channel);
// Look up DMAx_A_STARTH_REG address
volatile uint16 *dma_x_a_start_high_reg = DMA_CHN_REG(DMA->DMA0_A_STARTH_REG, channel);
// Look up DMAX_LEN_REG address
volatile uint16 *dma_x_len_reg = DMA_CHN_REG(DMA->DMA0_LEN_REG, channel);
volatile uint16 *dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, channel);
// Set source address registers
*dma_x_a_start_low_reg = (phy_addr & 0xffff);
*dma_x_a_start_high_reg = (phy_addr >> 16);
*dma_x_int_reg = length - 1;
// Set the transfer length
*dma_x_len_reg = length - 1;
}
void hw_dma_channel_update_destination(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
hw_dma_transfer_cb cb)
{
uint32_t phy_addr = DA15000_phy_addr((uint32_t) addr);
dma_callbacks_user_data[channel].callback = cb;
// Look up DMAx_B_STARTL_REG address
volatile uint16 *dma_x_b_start_low_reg = DMA_CHN_REG(DMA->DMA0_B_STARTL_REG, channel);
// Look up DMAx_B_STARTH_REG address
volatile uint16 *dma_x_b_start_high_reg = DMA_CHN_REG(DMA->DMA0_B_STARTH_REG, channel);
// Look up DMAX_LEN_REG address
volatile uint16 *dma_x_len_reg = DMA_CHN_REG(DMA->DMA0_LEN_REG, channel);
volatile uint16 *dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, channel);
// Set destination address registers
*dma_x_b_start_low_reg = (phy_addr & 0xffff);
*dma_x_b_start_high_reg = (phy_addr >> 16);
*dma_x_int_reg = length - 1;
// Set the transfer length
*dma_x_len_reg = length - 1;
}
void hw_dma_channel_update_int_ix(HW_DMA_CHANNEL channel, uint16_t int_ix)
{
volatile uint16 *dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, channel);
*dma_x_int_reg = int_ix;
}
/**
* \brief Enable or disable a DMA channel
*
* \param [in] channel_number DMA channel number to start/stop
* \param [in] dma_on enable/disable DMA channel
*
*/
void hw_dma_channel_enable(HW_DMA_CHANNEL channel_number, HW_DMA_STATE dma_on)
{
volatile uint16 *dma_x_ctrl_reg;
// Look up DMAx_CTRL_REG address
dma_x_ctrl_reg = DMA_CHN_REG(DMA->DMA0_CTRL_REG, channel_number);
if (dma_on == HW_DMA_STATE_ENABLED) {
uint16_t dma_ctrl = *dma_x_ctrl_reg;
REG_SET_FIELD(DMA, DMA0_CTRL_REG, DMA_ON, dma_ctrl, 1);
if (dma_callbacks_user_data[channel_number].callback) {
REG_SET_FIELD(DMA, DMA0_CTRL_REG, IRQ_ENABLE, dma_ctrl, 1);
}
// Start the chosen DMA channel
*dma_x_ctrl_reg = dma_ctrl;
NVIC_EnableIRQ(DMA_IRQn);
} else {
// Stop the chosen DMA channel
REG_SET_FIELD(DMA, DMA0_CTRL_REG, DMA_ON, *dma_x_ctrl_reg, 0);
REG_SET_FIELD(DMA, DMA0_CTRL_REG, IRQ_ENABLE, *dma_x_ctrl_reg, 0);
}
}
static inline void dma_helper(HW_DMA_CHANNEL channel_number, uint16_t len, bool stop_dma)
{
hw_dma_transfer_cb cb;
NVIC_DisableIRQ(DMA_IRQn);
cb = dma_callbacks_user_data[channel_number].callback;
if (stop_dma) {
dma_callbacks_user_data[channel_number].callback = NULL;
hw_dma_channel_enable(channel_number, HW_DMA_STATE_DISABLED);
}
if (cb) {
cb(dma_callbacks_user_data[channel_number].user_data, len);
}
NVIC_EnableIRQ(DMA_IRQn);
}
bool hw_dma_channel_active(void)
{
int dma_on;
dma_on = REG_GETF(DMA, DMA0_CTRL_REG, DMA_ON);
dma_on |= REG_GETF(DMA, DMA1_CTRL_REG, DMA_ON);
dma_on |= REG_GETF(DMA, DMA2_CTRL_REG, DMA_ON);
dma_on |= REG_GETF(DMA, DMA3_CTRL_REG, DMA_ON);
dma_on |= REG_GETF(DMA, DMA4_CTRL_REG, DMA_ON);
dma_on |= REG_GETF(DMA, DMA5_CTRL_REG, DMA_ON);
dma_on |= REG_GETF(DMA, DMA6_CTRL_REG, DMA_ON);
dma_on |= REG_GETF(DMA, DMA7_CTRL_REG, DMA_ON);
return (dma_on == 1);
}
/**
* \brief Capture DMA Interrupt Handler
*
* Calls user interrupt handler
*
*/
void DMA_Handler(void)
{
SEGGER_SYSTEMVIEW_ISR_ENTER();
uint16_t risen;
uint16_t i;
volatile uint16 *dma_x_len_reg;
volatile uint16 *dma_x_int_reg;
volatile uint16 *dma_x_ctrl_reg;
risen = DMA->DMA_INT_STATUS_REG;
for (i = 0; risen != 0 && i < 8; ++i, risen >>= 1) {
if (risen & 1) {
bool stop;
/*
* DMAx_INT_REG shows after how many transfers the interrupt
* is generated
*/
dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, i);
/*
* DMAx_LEN_REG shows the length of the DMA transfer
*/
dma_x_len_reg = DMA_CHN_REG(DMA->DMA0_LEN_REG, i);
dma_x_ctrl_reg = DMA_CHN_REG(DMA->DMA0_CTRL_REG, i);
/*
* Stop DMA if:
* - transfer is completed
* - mode is not circular
*/
stop = (*dma_x_int_reg == *dma_x_len_reg)
&& (!REG_GET_FIELD(DMA, DMA0_CTRL_REG, CIRCULAR, *dma_x_ctrl_reg));
DMA->DMA_CLEAR_INT_REG = 1 << i;
dma_helper(i, *dma_x_int_reg + 1, stop);
}
}
SEGGER_SYSTEMVIEW_ISR_EXIT();
}
void hw_dma_channel_stop(HW_DMA_CHANNEL channel_number)
{
// Stopping DMA will clear DMAx_IDX_REG so read it before
volatile uint16 *dma_x_idx_reg = DMA_CHN_REG(DMA->DMA0_IDX_REG, channel_number);
dma_helper(channel_number, *dma_x_idx_reg, true);
}
uint16_t hw_dma_transfered_bytes(HW_DMA_CHANNEL channel_number)
{
volatile uint16 *dma_x_int_reg = dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_IDX_REG, channel_number);
return *dma_x_int_reg;
}
#endif /* dg_configUSE_HW_DMA */
/**
* \}
* \}
* \}
*/
@@ -1,301 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup GPADC
* \{
*/
/**
****************************************************************************************
*
* @file hw_gpadc.c
*
* @brief Implementation of the GPADC Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_GPADC
#include <stdio.h>
#include <string.h>
#include <hw_gpadc.h>
#if (dg_configSYSTEMVIEW)
# include "SEGGER_SYSVIEW_FreeRTOS.h"
#else
# define SEGGER_SYSTEMVIEW_ISR_ENTER()
# define SEGGER_SYSTEMVIEW_ISR_EXIT()
#endif
static hw_gpadc_interrupt_cb intr_cb = NULL;
int16_t hw_gpadc_differential_gain_error __RETAINED;
int16_t hw_gpadc_single_ended_gain_error __RETAINED;
void hw_gpadc_init(const gpadc_config *cfg)
{
GPADC->GP_ADC_CTRL_REG = 0;
GPADC->GP_ADC_CTRL2_REG = 0;
GPADC->GP_ADC_CTRL3_REG = 0x40; // default value for GP_ADDC_EN_DEL
NVIC_DisableIRQ(ADC_IRQn);
hw_gpadc_configure(cfg);
}
void hw_gpadc_reset(void)
{
GPADC->GP_ADC_CTRL_REG = REG_MSK(GPADC, GP_ADC_CTRL_REG, GP_ADC_EN);
GPADC->GP_ADC_CTRL2_REG = 0;
GPADC->GP_ADC_CTRL3_REG = 0x40; // default value for GP_ADDC_EN_DEL
NVIC_DisableIRQ(ADC_IRQn);
}
void hw_gpadc_configure(const gpadc_config *cfg)
{
if (cfg) {
hw_gpadc_set_clock(cfg->clock);
hw_gpadc_set_input_mode(cfg->input_mode);
hw_gpadc_set_input(cfg->input);
hw_gpadc_set_sample_time(cfg->sample_time);
hw_gpadc_set_continuous(cfg->continous);
hw_gpadc_set_interval(cfg->interval);
hw_gpadc_set_input_attenuator_state(cfg->input_attenuator);
hw_gpadc_set_chopping(cfg->chopping);
hw_gpadc_set_oversampling(cfg->oversampling);
}
}
void hw_gpadc_register_interrupt(hw_gpadc_interrupt_cb cb)
{
intr_cb = cb;
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_MINT, 1);
NVIC_EnableIRQ(ADC_IRQn);
}
void hw_gpadc_unregister_interrupt(void)
{
NVIC_DisableIRQ(ADC_IRQn);
REG_SETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_MINT, 0);
intr_cb = NULL;
}
void hw_gpadc_adc_measure(void)
{
hw_gpadc_start();
while (hw_gpadc_in_progress());
hw_gpadc_clear_interrupt();
}
void hw_gpadc_calibrate(void)
{
uint16_t adc_off_p, adc_off_n;
uint32_t diff;
int i;
for (i = 0; i < 5; i++) { // Try up to five times to calibrate correctly.
hw_gpadc_set_offset_positive(0x200);
hw_gpadc_set_offset_negative(0x200);
hw_gpadc_set_mute(true);
if (dg_configUSE_SOC == 1) {
hw_gpadc_set_oversampling(4);
}
hw_gpadc_set_sign_change(false);
hw_gpadc_adc_measure();
if (dg_configUSE_SOC == 1) {
adc_off_p = ((hw_gpadc_get_value_without_gain() >> 6) - 0x200);
} else {
adc_off_p = hw_gpadc_get_value() - 0x200;
}
hw_gpadc_set_sign_change(true);
hw_gpadc_adc_measure();
if (dg_configUSE_SOC == 1) {
adc_off_n = ((hw_gpadc_get_value_without_gain() >> 6) - 0x200);
} else {
adc_off_n = hw_gpadc_get_value() - 0x200;
}
if (hw_gpadc_get_input_mode() == HW_GPADC_INPUT_MODE_SINGLE_ENDED) {
hw_gpadc_set_offset_positive(0x200 - 2 * adc_off_p);
hw_gpadc_set_offset_negative(0x200 - 2 * adc_off_n);
} else {
hw_gpadc_set_offset_positive(0x200 - adc_off_p);
hw_gpadc_set_offset_negative(0x200 - adc_off_n);
}
hw_gpadc_set_sign_change(false);
// Verify calibration result
hw_gpadc_adc_measure();
if (dg_configUSE_SOC == 1) {
adc_off_n = (hw_gpadc_get_value_without_gain() >> 6);
} else {
adc_off_n = hw_gpadc_get_value();
}
if (adc_off_n > 0x200) {
diff = adc_off_n - 0x200;
}
else {
diff = 0x200 - adc_off_n;
}
if (diff < 0x8) {
break;
}
else if (i == 4) {
ASSERT_WARNING(0); // Calibration does not converge.
}
}
hw_gpadc_set_mute(false);
}
void ADC_Handler(void)
{
SEGGER_SYSTEMVIEW_ISR_ENTER();
if (intr_cb) {
intr_cb();
} else {
hw_gpadc_clear_interrupt();
}
SEGGER_SYSTEMVIEW_ISR_EXIT();
}
void hw_gpadc_test_measurements(void)
{
uint32_t val[16];
uint32_t mid = 0, diff_n = 0, diff_p = 0;
volatile bool loop = true;
if (hw_gpadc_get_input_mode() != HW_GPADC_INPUT_MODE_SINGLE_ENDED) {
hw_gpadc_set_input_mode(HW_GPADC_INPUT_MODE_SINGLE_ENDED);
hw_gpadc_set_ldo_constant_current(true);
hw_gpadc_set_ldo_dynamic_current(true);
hw_gpadc_calibrate();
}
hw_gpadc_reset();
hw_gpadc_set_input_mode(HW_GPADC_INPUT_MODE_SINGLE_ENDED);
hw_gpadc_set_ldo_constant_current(true);
hw_gpadc_set_ldo_dynamic_current(true);
hw_gpadc_set_sample_time(15);
hw_gpadc_set_chopping(true);
hw_gpadc_set_input(HW_GPADC_INPUT_SE_VBAT);
// hw_gpadc_set_oversampling(1); // 2 samples
hw_gpadc_set_oversampling(2); // 4 samples
while (loop) {
for (volatile int i = 0; i < 4; i++); // wait ~1.5usec
for (int j = 0; j < 16; j++) {
hw_gpadc_adc_measure();
// val[j] = hw_gpadc_get_raw_value() >> 4; // 2 samples
val[j] = hw_gpadc_get_raw_value() >> 3; // 4 samples
if (j == 0) {
mid = 0;
diff_p = 0;
diff_n = 0;
}
mid += val[j];
if (j == 15) {
mid /= 16;
for (int k = 0; k < 16; k++) {
if ((mid > val[k]) && (diff_p < mid - val[k])) {
diff_p = mid - val[k];
}
if ((mid < val[k]) && (diff_n < val[k] - mid)) {
diff_n = val[k] - mid;
}
}
}
}
}
}
uint16_t hw_gpadc_get_raw_value(void)
{
uint16_t adc_raw_res = GPADC->GP_ADC_RESULT_REG;
int32_t res = adc_raw_res;
if (dg_configUSE_ADC_GAIN_ERROR_CORRECTION == 1) {
if (hw_gpadc_pre_check_for_gain_error()) {
int16_t gain_trim;
const HW_GPADC_INPUT_MODE input_mode = hw_gpadc_get_input_mode();
if (input_mode == HW_GPADC_INPUT_MODE_SINGLE_ENDED) {
gain_trim = hw_gpadc_single_ended_gain_error;
/* Gain correction */
res = 0xFFFFU * adc_raw_res / (0xFFFFU + gain_trim);
/* Boundary check */
if ((uint32_t)res > UINT16_MAX) {
return UINT16_MAX;
}
} else if (input_mode == HW_GPADC_INPUT_MODE_DIFFERENTIAL) {
gain_trim = hw_gpadc_differential_gain_error;
res = (int16_t)(adc_raw_res ^ 0x8000);
/* Gain correction */
res = 0xFFFF * res / (0xFFFF + gain_trim);
/* Boundary check for lower limit */
if (res < INT16_MIN) {
return 0; /* INT16_MIN ^ 0x8000 */
}
/* Boundary check for upper limit */
if (res > INT16_MAX) {
return UINT16_MAX; /* INT16_MAX ^ 0x8000 */
}
res ^= 0x8000;
}
}
}
return res;
}
#endif /* dg_configUSE_HW_GPADC */
/**
* \}
* \}
* \}
*/
@@ -1,302 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup GPIO
* \{
*/
/**
****************************************************************************************
*
* @file hw_gpio.c
*
* @brief Implementation of the GPIO Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_GPIO
#include <stdint.h>
#include <hw_gpio.h>
/* Register adresses */
#define PX_DATA_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_DATA_REG)) + _port)
#define PX_DATA_REG(_port) *PX_DATA_REG_ADDR(_port)
#define PX_SET_DATA_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_SET_DATA_REG)) + _port)
#define PX_SET_DATA_REG(_port) *PX_SET_DATA_REG_ADDR(_port)
#define PX_RESET_DATA_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_RESET_DATA_REG)) + _port)
#define PX_RESET_DATA_REG(_port) *PX_RESET_DATA_REG_ADDR(_port)
#define PXX_MODE_REG_ADDR(_port, _pin) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P00_MODE_REG)) + (_port * 8) + _pin)
#define PXX_MODE_REG(_port, _pin) *PXX_MODE_REG_ADDR(_port, _pin)
#define PX_PADPWR_CTRL_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_PADPWR_CTRL_REG)) + _port)
#define PX_PADPWR_CTRL_REG(_port) *PX_PADPWR_CTRL_REG_ADDR(_port)
/* on FPGA we cannot read the state of an output GPIO */
#ifdef FPGA_PAD_LOOPBACK_BROKEN
static uint16_t Px_DATA_REG_cache[5];
#endif
#if (dg_configIMAGE_SETUP == PRODUCTION_MODE) && (DEBUG_GPIO_ALLOC_MONITOR_ENABLED == 1)
#warning "GPIO assignment monitoring is active in PRODUCTION build!"
#endif
static volatile uint8_t GPIO_status[HW_GPIO_NUM_PORTS] = { 0 };
const uint8_t hw_gpio_port_num_pins[HW_GPIO_NUM_PORTS] = {
HW_GPIO_PORT_0_NUM_PINS, HW_GPIO_PORT_1_NUM_PINS,
HW_GPIO_PORT_2_NUM_PINS, HW_GPIO_PORT_3_NUM_PINS,
HW_GPIO_PORT_4_NUM_PINS };
/*
* Global Functions
****************************************************************************************
*/
void hw_gpio_configure(const gpio_config cfg[])
{
#if dg_configIMAGE_SETUP == DEVELOPMENT_MODE
int num_pins = 0;
uint8_t set_mask[HW_GPIO_NUM_PORTS] = { 0 };
#endif
if (!cfg) {
return;
}
while (cfg->pin != 0xFF) {
uint8_t port = cfg->pin >> 4;
uint8_t pin = cfg->pin & 0x0F;
#if dg_configIMAGE_SETUP == DEVELOPMENT_MODE
if (port >= HW_GPIO_NUM_PORTS || pin >= hw_gpio_port_num_pins[port]) {
/*
* invalid port or pin number specified, it was either incorrectly specified
* of cfg was not terminated properly using HW_GPIO_PINCONFIG_END so we're
* reading garbage
*/
__BKPT(0);
}
if (++num_pins > HW_GPIO_NUM_PINS) {
/*
* trying to set more pins than available, perhaps cfg was not terminated
* properly using HW_GPIO_PINCONFIG_END?
*/
__BKPT(0);
}
if (set_mask[port] & (1 << pin)) {
/*
* trying to set pin which has been already set by this call which means
* there is duplicated pin in configuration - does not make sense
*/
__BKPT(0);
}
set_mask[port] |= (1 << pin);
#endif
if (cfg->reserve) {
hw_gpio_reserve_and_configure_pin(port, pin, cfg->mode, cfg->func, cfg->high);
} else {
hw_gpio_configure_pin(port, pin, cfg->mode, cfg->func, cfg->high);
}
cfg++;
}
}
bool hw_gpio_reserve_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
if ((GPIO_status[port] & (1 << pin))) {
return false;
}
GPIO_status[port] |= (1 << pin);
return true;
}
bool hw_gpio_reserve_and_configure_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE mode,
HW_GPIO_FUNC function, bool high)
{
if (!hw_gpio_reserve_pin(port, pin)) {
return false;
}
hw_gpio_configure_pin(port, pin, mode, function, high);
return true;
}
void hw_gpio_unreserve_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
GPIO_status[port] &= ~(1 << pin);
}
static void hw_gpio_verify_reserved(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
#if (DEBUG_GPIO_ALLOC_MONITOR_ENABLED == 1)
if (!(GPIO_status[port] & (1 << pin))) {
// If debugger stops at this line, there is configuration problem
// pin is used without being reserved first
__BKPT(0); /* this pin has not been previously reserved! */
}
#endif // (DEBUG_GPIO_ALLOC_MONITOR_ENABLED == 1)
}
void hw_gpio_set_pin_function(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE mode,
HW_GPIO_FUNC function)
{
hw_gpio_verify_reserved(port, pin);
PXX_MODE_REG(port, pin) = mode | function;
}
void hw_gpio_get_pin_function(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE* mode,
HW_GPIO_FUNC* function)
{
uint16_t val;
hw_gpio_verify_reserved(port, pin);
val = PXX_MODE_REG(port, pin);
*mode = val & 0x0700;
*function = val & 0x00ff;
}
void hw_gpio_configure_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_MODE mode,
HW_GPIO_FUNC function, const bool high)
{
hw_gpio_verify_reserved(port, pin);
if (high)
hw_gpio_set_active(port, pin);
else
hw_gpio_set_inactive(port, pin);
hw_gpio_set_pin_function(port, pin, mode, function);
}
void hw_gpio_configure_pin_power(HW_GPIO_PORT port, HW_GPIO_PIN pin, HW_GPIO_POWER power)
{
uint16_t padpwr;
padpwr = PX_PADPWR_CTRL_REG(port);
padpwr &= ~(1 << pin);
if (power == HW_GPIO_POWER_VDD1V8P) {
padpwr |= (1 << pin);
}
PX_PADPWR_CTRL_REG(port) = padpwr;
}
void hw_gpio_set_active(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
hw_gpio_verify_reserved(port, pin);
PX_SET_DATA_REG(port) = 1 << pin;
#ifdef FPGA_PAD_LOOPBACK_BROKEN
Px_DATA_REG_cache[port] |= 1 << pin;
#endif
}
void hw_gpio_set_inactive(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
hw_gpio_verify_reserved(port, pin);
PX_RESET_DATA_REG(port) = 1 << pin;
#ifdef FPGA_PAD_LOOPBACK_BROKEN
Px_DATA_REG_cache[port] &= ~(1 << pin);
#endif
}
bool hw_gpio_get_pin_status(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
#ifdef FPGA_PAD_LOOPBACK_BROKEN
HW_GPIO_MODE mode;
HW_GPIO_FUNC function;
#endif
hw_gpio_verify_reserved(port, pin);
#ifdef FPGA_PAD_LOOPBACK_BROKEN
hw_gpio_get_pin_function(port, pin, &mode, &function);
if (mode != HW_GPIO_MODE_OUTPUT)
return !!(PX_DATA_REG(port) & (1 << pin));
else
return !!(Px_DATA_REG_cache[port] & (1 << pin));
#else
return ( (PX_DATA_REG(port) & (1 << pin)) != 0 );
#endif
}
void hw_gpio_toggle(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
hw_gpio_verify_reserved(port, pin);
if (hw_gpio_get_pin_status(port, pin))
hw_gpio_set_inactive(port, pin);
else
hw_gpio_set_active(port, pin);
}
int hw_gpio_get_pins_with_function(HW_GPIO_FUNC func, uint8_t *buf, int buf_size)
{
int count = 0;
int port;
int pin;
HW_GPIO_MODE mode;
HW_GPIO_FUNC pin_func;
for (port = 0; port < HW_GPIO_NUM_PORTS; ++port) {
for (pin = 0; pin < hw_gpio_port_num_pins[port]; ++pin) {
hw_gpio_get_pin_function(port, pin, &mode, &pin_func);
if (pin_func != func) {
continue;
}
if (count < buf_size && buf != NULL) {
buf[count] = (uint8_t) ((port << 4) | pin);
}
count++;
}
}
return count;
}
#endif /* dg_configUSE_HW_GPIO */
/**
* \}
* \}
* \}
*/
@@ -1,172 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup Exception_Handlers
* \{
*/
/**
****************************************************************************************
*
* @file hw_hard_fault.c
*
* @brief HardFault handler.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 <stdint.h>
#include <stdio.h>
#include "sdk_defs.h"
#include "hw_hard_fault.h"
#include "hw_watchdog.h"
#include "hw_cpm.h"
/*
* Global variables
*/
uint32_t hardfault_event_data[9] __attribute__((section("hard_fault_info")));
/*
* Local variables
*/
/*
* This is the base address in Retention RAM where the stacked information will be copied.
*/
#define STATUS_BASE (0x7FC5600)
/*
* Compilation switch to enable verbose output on HardFault
*/
#ifndef VERBOSE_HARDFAULT
# define VERBOSE_HARDFAULT 0
#endif
/*
* Function definitions
*/
/**
* \brief HardFault handler implementation. During development it will copy the system's status
* to a predefined location in memory. In release mode, it will cause a system reset.
*
* \param [in] hardfault_args The system's status when the HardFault event occurred.
*
* \return void
*
*/
#if (dg_configCODE_LOCATION == NON_VOLATILE_IS_FLASH)
__attribute__((section("text_retained")))
#endif
void HardFault_HandlerC(unsigned long *hardfault_args)
{
// Stack frame contains:
// r0, r1, r2, r3, r12, r14, the return address and xPSR
// - Stacked R0 = hf_args[0]
// - Stacked R1 = hf_args[1]
// - Stacked R2 = hf_args[2]
// - Stacked R3 = hf_args[3]
// - Stacked R12 = hf_args[4]
// - Stacked LR = hf_args[5]
// - Stacked PC = hf_args[6]
// - Stacked xPSR= hf_args[7]
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) {
hw_watchdog_freeze(); // Stop WDOG
ENABLE_DEBUGGER;
*(volatile unsigned long *)(STATUS_BASE ) = hardfault_args[0]; // R0
*(volatile unsigned long *)(STATUS_BASE + 0x04) = hardfault_args[1]; // R1
*(volatile unsigned long *)(STATUS_BASE + 0x08) = hardfault_args[2]; // R2
*(volatile unsigned long *)(STATUS_BASE + 0x0C) = hardfault_args[3]; // R3
*(volatile unsigned long *)(STATUS_BASE + 0x10) = hardfault_args[4]; // R12
*(volatile unsigned long *)(STATUS_BASE + 0x14) = hardfault_args[5]; // LR
*(volatile unsigned long *)(STATUS_BASE + 0x18) = hardfault_args[6]; // PC
*(volatile unsigned long *)(STATUS_BASE + 0x1C) = hardfault_args[7]; // PSR
*(volatile unsigned long *)(STATUS_BASE + 0x20) = (unsigned long)hardfault_args; // Stack Pointer
*(volatile unsigned long *)(STATUS_BASE + 0x24) = (*((volatile unsigned long *)(0xE000ED28))); // CFSR
*(volatile unsigned long *)(STATUS_BASE + 0x28) = (*((volatile unsigned long *)(0xE000ED2C))); // HFSR
*(volatile unsigned long *)(STATUS_BASE + 0x2C) = (*((volatile unsigned long *)(0xE000ED30))); // DFSR
*(volatile unsigned long *)(STATUS_BASE + 0x30) = (*((volatile unsigned long *)(0xE000ED3C))); // AFSR
*(volatile unsigned long *)(STATUS_BASE + 0x34) = (*((volatile unsigned long *)(0xE000ED34))); // MMAR
*(volatile unsigned long *)(STATUS_BASE + 0x38) = (*((volatile unsigned long *)(0xE000ED38))); // BFAR
if (VERBOSE_HARDFAULT) {
printf("HardFault Handler:\r\n");
printf("- R0 = 0x%08lx\r\n", hardfault_args[0]);
printf("- R1 = 0x%08lx\r\n", hardfault_args[1]);
printf("- R2 = 0x%08lx\r\n", hardfault_args[2]);
printf("- R3 = 0x%08lx\r\n", hardfault_args[3]);
printf("- R12 = 0x%08lx\r\n", hardfault_args[4]);
printf("- LR = 0x%08lx\r\n", hardfault_args[5]);
printf("- PC = 0x%08lx\r\n", hardfault_args[6]);
printf("- xPSR= 0x%08lx\r\n", hardfault_args[7]);
}
hw_cpm_assert_trigger_gpio();
while (1);
}
else {
# ifdef PRODUCTION_DEBUG_OUTPUT
# if (USE_WDOG)
WDOG->WATCHDOG_REG = 0xC8; // Reset WDOG! 200 * 10.24ms active time for UART to finish printing!
# endif
dbg_prod_output(1, hardfault_args);
# endif // PRODUCTION_DEBUG_OUTPUT
hardfault_event_data[0] = HARDFAULT_MAGIC_NUMBER;
hardfault_event_data[1] = hardfault_args[0]; // R0
hardfault_event_data[2] = hardfault_args[1]; // R1
hardfault_event_data[3] = hardfault_args[2]; // R2
hardfault_event_data[4] = hardfault_args[3]; // R3
hardfault_event_data[5] = hardfault_args[4]; // R12
hardfault_event_data[6] = hardfault_args[5]; // LR
hardfault_event_data[7] = hardfault_args[6]; // PC
hardfault_event_data[8] = hardfault_args[7]; // PSR
hw_cpm_reboot_system(); // Force reset
while (1);
}
}
/**
* \}
* \}
* \}
* */
File diff suppressed because it is too large Load Diff
@@ -1,177 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup QSPI
* \{
*/
/**
****************************************************************************************
*
* @file hw_qspi.c
*
* @brief Implementation of the QSPI Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_QSPI
#include <stdint.h>
#include "hw_qspi.h"
__RETAINED_RW uint8_t dummy_num[] = { 0, 1, 2, 0, 3 };
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
#endif
void hw_qspi_set_bus_mode(HW_QSPI_BUS_MODE mode)
{
switch (mode) {
case HW_QSPI_BUS_MODE_SINGLE:
QSPIC->QSPIC_CTRLBUS_REG = REG_MSK(QSPIC, QSPIC_CTRLBUS_REG, QSPIC_SET_SINGLE);
break;
case HW_QSPI_BUS_MODE_DUAL:
QSPIC->QSPIC_CTRLBUS_REG = REG_MSK(QSPIC, QSPIC_CTRLBUS_REG, QSPIC_SET_DUAL);
break;
case HW_QSPI_BUS_MODE_QUAD:
QSPIC->QSPIC_CTRLBUS_REG = REG_MSK(QSPIC, QSPIC_CTRLBUS_REG, QSPIC_SET_QUAD);
hw_qspi_set_io2_output(false);
hw_qspi_set_io3_output(false);
break;
}
}
__attribute__((section("text_retained"))) void hw_qspi_set_automode(bool automode)
{
if (automode) {
const uint32_t burst_cmd_a = QSPIC->QSPIC_BURSTCMDA_REG;
const uint32_t burst_cmd_b = QSPIC->QSPIC_BURSTCMDB_REG;
const uint32_t status_cmd = QSPIC->QSPIC_STATUSCMD_REG;
const uint32_t erase_cmd_b = QSPIC->QSPIC_ERASECMDB_REG;
const uint32_t burstbrk = QSPIC->QSPIC_BURSTBRK_REG;
if (GETBITS32(QSPIC, QSPIC_BURSTCMDA_REG, burst_cmd_a, QSPIC_INST_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_BURSTCMDA_REG, burst_cmd_a, QSPIC_ADR_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_BURSTCMDA_REG, burst_cmd_a, QSPIC_DMY_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_BURSTCMDA_REG, burst_cmd_a, QSPIC_EXT_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_BURSTCMDB_REG, burst_cmd_b, QSPIC_DAT_RX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_BURSTCMDB_REG, burst_cmd_b, QSPIC_DAT_RX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_STATUSCMD_REG, status_cmd, QSPIC_RSTAT_RX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_STATUSCMD_REG, status_cmd, QSPIC_RSTAT_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_ERASECMDB_REG, erase_cmd_b, QSPIC_ERS_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_ERASECMDB_REG, erase_cmd_b, QSPIC_WEN_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_ERASECMDB_REG, erase_cmd_b, QSPIC_SUS_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_ERASECMDB_REG, erase_cmd_b, QSPIC_RES_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_ERASECMDB_REG, erase_cmd_b, QSPIC_EAD_TX_MD) == HW_QSPI_BUS_MODE_QUAD ||
GETBITS32(QSPIC, QSPIC_BURSTBRK_REG, burstbrk, QSPIC_BRK_TX_MD) == HW_QSPI_BUS_MODE_QUAD) {
hw_qspi_set_io2_output(false);
hw_qspi_set_io3_output(false);
}
}
HW_QSPIC_REG_SETF(CTRLMODE, AUTO_MD, automode);
}
void hw_qspi_set_wrapping_burst_instruction(uint8_t inst, HW_QSPI_WRAP_LEN len,
HW_QSPI_WRAP_SIZE size)
{
HW_QSPIC_REG_SETF(BURSTCMDA, INST_WB, inst);
QSPIC->QSPIC_BURSTCMDB_REG =
(QSPIC->QSPIC_BURSTCMDB_REG &
~(REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_WRAP_SIZE) |
REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_WRAP_LEN))) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_WRAP_SIZE, size) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_WRAP_LEN, len) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_WRAP_MD, 1);
}
void hw_qspi_set_dummy_bytes_count(uint8_t count)
{
if (count == 3) {
HW_QSPIC_REG_SETF(BURSTCMDB, DMY_FORCE, 1);
} else {
QSPIC->QSPIC_BURSTCMDB_REG =
(QSPIC->QSPIC_BURSTCMDB_REG &
~(REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_FORCE) |
REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_NUM))) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_NUM,
dummy_num[count]);
}
}
void hw_qspi_erase_block(uint32_t addr)
{
if (!hw_qspi_get_automode()) {
hw_qspi_set_automode(true);
}
// Wait for previous erase to end
while (hw_qspi_get_erase_status() != 0) {
}
if (hw_qspi_get_address_size() == HW_QSPI_ADDR_SIZE_32) {
addr >>= 12;
} else {
addr >>= 4;
}
// Setup erase block page
HW_QSPIC_REG_SETF(ERASECTRL, ERS_ADDR, addr);
// Fire erase
HW_QSPIC_REG_SETF(ERASECTRL, ERASE_EN, 1);
}
void hw_qspi_set_pads(HW_QSPI_SLEW_RATE rate, HW_QSPI_DRIVE_CURRENT current)
{
QSPIC->QSPIC_GP_REG =
BITS16(QSPIC, QSPIC_GP_REG, QSPIC_PADS_SLEW, rate) |
BITS16(QSPIC, QSPIC_GP_REG, QSPIC_PADS_DRV, current);
}
void hw_qspi_init(const qspi_config *cfg)
{
hw_qspi_enable_clock();
hw_qspi_set_automode(false);
hw_qspi_set_bus_mode(HW_QSPI_BUS_MODE_SINGLE);
hw_qspi_set_io2_output(true);
hw_qspi_set_io2(1);
hw_qspi_set_io3_output(true);
hw_qspi_set_io3(1);
if (cfg) {
hw_qspi_set_address_size(cfg->address_size);
hw_qspi_set_clock_mode(cfg->idle_clock);
hw_qspi_set_read_sampling_edge(cfg->sampling_edge);
}
}
#endif /* dg_configUSE_HW_QSPI */
/**
* \}
* \}
* \}
*/
File diff suppressed because it is too large Load Diff
@@ -1,122 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup Timer0
* \{
*/
/**
****************************************************************************************
*
* @file hw_timer0.c
*
* @brief Implementation of the Timer0 Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_TIMER0
#include <stdio.h>
#include <sdk_defs.h>
#include <hw_timer0.h>
#if (dg_configSYSTEMVIEW)
# include "SEGGER_SYSVIEW_FreeRTOS.h"
#else
# define SEGGER_SYSTEMVIEW_ISR_ENTER()
# define SEGGER_SYSTEMVIEW_ISR_EXIT()
#endif
static hw_timer0_interrupt_cb intr_cb;
void hw_timer0_init(const timer0_config *cfg)
{
/* Enable clock for peripheral */
GLOBAL_INT_DISABLE();
uint32_t clk_tmr_reg = CRG_TOP->CLK_TMR_REG;
clk_tmr_reg &= ~CRG_TOP_CLK_TMR_REG_TMR0_DIV_Msk;
clk_tmr_reg &= ~CRG_TOP_CLK_TMR_REG_TMR0_CLK_SEL_Msk;
clk_tmr_reg |= CRG_TOP_CLK_TMR_REG_TMR0_ENABLE_Msk;
CRG_TOP->CLK_TMR_REG = clk_tmr_reg ;
GLOBAL_INT_RESTORE();
/* Reset control register, i.e. disable timer */
GP_TIMERS->TIMER0_CTRL_REG = 0x0;
/* Disable NVIC interrupt */
NVIC_DisableIRQ(SWTIM0_IRQn);
intr_cb = NULL;
hw_timer0_configure(cfg);
}
void hw_timer0_configure(const timer0_config *cfg)
{
if (cfg) {
hw_timer0_set_clock_source(cfg->clk_src);
hw_timer0_set_fast_clock_div(cfg->fast_clk_div);
hw_timer0_set_on_clock_div(cfg->on_clock_div);
hw_timer0_set_on_reload(cfg->on_reload);
hw_timer0_set_t0_reload(cfg->t0_reload_m, cfg->t0_reload_n);
}
}
void hw_timer0_register_int(hw_timer0_interrupt_cb handler)
{
intr_cb = handler;
NVIC_EnableIRQ(SWTIM0_IRQn);
}
void hw_timer0_unregister_int(void)
{
NVIC_DisableIRQ(SWTIM0_IRQn);
intr_cb = NULL;
}
void SWTIM0_Handler(void)
{
SEGGER_SYSTEMVIEW_ISR_ENTER();
if (intr_cb) {
intr_cb();
}
SEGGER_SYSTEMVIEW_ISR_EXIT();
}
#endif /* dg_configUSE_HW_TIMER0 */
/**
* \}
* \}
* \}
*/
@@ -1,125 +0,0 @@
/**
****************************************************************************************
*
* @file hw_trng.c
*
* @brief Implementation of the True Random Number Generator Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_TRNG
#include <hw_trng.h>
#if (dg_configSYSTEMVIEW)
# include "SEGGER_SYSVIEW_FreeRTOS.h"
#else
# define SEGGER_SYSTEMVIEW_ISR_ENTER()
# define SEGGER_SYSTEMVIEW_ISR_EXIT()
#endif
#define HW_TRNG_FIFO_DEPTH (32)
static hw_trng_cb trng_cb;
void hw_trng_disable_clk(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE);
GLOBAL_INT_RESTORE();
}
void hw_trng_clear_pending(void)
{
uint32_t dummy __attribute__((unused));
/* read TRNG_FIFOLVL_REG to clear level-sensitive source. */
dummy = TRNG->TRNG_FIFOLVL_REG;
NVIC_ClearPendingIRQ(TRNG_IRQn);
}
void hw_trng_enable(hw_trng_cb callback)
{
if (callback != NULL) {
trng_cb = callback;
hw_trng_clear_pending();
NVIC_EnableIRQ(TRNG_IRQn);
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE);
GLOBAL_INT_RESTORE();
REG_SET_BIT(TRNG, TRNG_CTRL_REG, TRNG_ENABLE);
}
void hw_trng_get_numbers(uint32_t* buffer, uint8_t size)
{
if (size > HW_TRNG_FIFO_DEPTH)
size = HW_TRNG_FIFO_DEPTH;
for (int i = 0; i < size ; i++) {
buffer[i] = hw_trng_get_number();
}
}
__RETAINED_CODE uint8_t hw_trng_get_fifo_level(void)
{
return (TRNG->TRNG_FIFOLVL_REG) & (REG_MSK(TRNG, TRNG_FIFOLVL_REG, TRNG_FIFOLVL) |
REG_MSK(TRNG, TRNG_FIFOLVL_REG, TRNG_FIFOFULL));
}
void hw_trng_disable_interrupt(void)
{
NVIC_DisableIRQ(TRNG_IRQn);
trng_cb = NULL;
}
void hw_trng_disable(void)
{
hw_trng_stop();
hw_trng_disable_interrupt();
hw_trng_clear_pending();
hw_trng_disable_clk();
}
void TRNG_Handler(void)
{
uint32_t dummy __attribute__((unused));
SEGGER_SYSTEMVIEW_ISR_ENTER();
if (trng_cb != NULL)
trng_cb();
/* read TRNG_FIFOLVL_REG to clear level-sensitive source. */
dummy = TRNG->TRNG_FIFOLVL_REG;
SEGGER_SYSTEMVIEW_ISR_EXIT();
}
#endif /* dg_configUSE_HW_TRNG */
File diff suppressed because it is too large Load Diff
@@ -1,172 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup Watchdog_Timer
* \{
*/
/**
****************************************************************************************
*
* @file hw_watchdog.c
*
* @brief Implementation of the Watchdog timer Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 <stdio.h>
#include "hw_watchdog.h"
#include "hw_cpm.h"
/*
* Global variables
*/
uint32_t nmi_event_data[9] __attribute__((section("nmi_info")));
/*
* Local variables
*/
static hw_watchdog_interrupt_cb int_handler __RETAINED = NULL;
/*
* This is the base address in Retention RAM where the stacked information will be copied.
*/
#define STATUS_BASE (0x7FC5600)
bool hw_watchdog_freeze(void)
{
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk;
return !REG_GETF(WDOG, WATCHDOG_CTRL_REG, NMI_RST);
}
void hw_watchdog_unfreeze(void)
{
GPREG->RESET_FREEZE_REG = GPREG_RESET_FREEZE_REG_FRZ_WDOG_Msk;
}
HW_WDG_RESET hw_watchdog_is_irq_or_rst_gen(void)
{
if (REG_GETF(WDOG, WATCHDOG_CTRL_REG, NMI_RST)) {
return HW_WDG_RESET_RST;
}
return HW_WDG_RESET_NMI;
}
void hw_watchdog_register_int(hw_watchdog_interrupt_cb handler)
{
int_handler = handler;
}
void hw_watchdog_unregister_int(void)
{
int_handler = NULL;
}
__RETAINED_CODE void hw_watchdog_handle_int(unsigned long *exception_args)
{
// Reached this point due to a WDOG timeout
uint16_t pmu_ctrl_reg = CRG_TOP->PMU_CTRL_REG;
pmu_ctrl_reg |= ((1 << CRG_TOP_PMU_CTRL_REG_BLE_SLEEP_Pos) | /* turn off BLE */
(1 << CRG_TOP_PMU_CTRL_REG_FTDF_SLEEP_Pos) | /* turn off FTDF */
(1 << CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Pos) | /* turn off radio PD */
(1 << CRG_TOP_PMU_CTRL_REG_PERIPH_SLEEP_Pos)); /* turn off peripheral power domain */
CRG_TOP->PMU_CTRL_REG = pmu_ctrl_reg;
REG_SET_BIT(CRG_TOP, CLK_RADIO_REG, BLE_LP_RESET); /* reset the BLE LP timer */
#if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE)
hw_watchdog_freeze(); // Stop WDOG
ENABLE_DEBUGGER;
if (exception_args != NULL) {
*(volatile unsigned long *)(STATUS_BASE ) = exception_args[0]; // R0
*(volatile unsigned long *)(STATUS_BASE + 0x04) = exception_args[1]; // R1
*(volatile unsigned long *)(STATUS_BASE + 0x08) = exception_args[2]; // R2
*(volatile unsigned long *)(STATUS_BASE + 0x0C) = exception_args[3]; // R3
*(volatile unsigned long *)(STATUS_BASE + 0x10) = exception_args[4]; // R12
*(volatile unsigned long *)(STATUS_BASE + 0x14) = exception_args[5]; // LR
*(volatile unsigned long *)(STATUS_BASE + 0x18) = exception_args[6]; // PC
*(volatile unsigned long *)(STATUS_BASE + 0x1C) = exception_args[7]; // PSR
*(volatile unsigned long *)(STATUS_BASE + 0x20) = (unsigned long)exception_args; // Stack Pointer
*(volatile unsigned long *)(STATUS_BASE + 0x24) = (*((volatile unsigned long *)(0xE000ED28))); // CFSR
*(volatile unsigned long *)(STATUS_BASE + 0x28) = (*((volatile unsigned long *)(0xE000ED2C))); // HFSR
*(volatile unsigned long *)(STATUS_BASE + 0x2C) = (*((volatile unsigned long *)(0xE000ED30))); // DFSR
*(volatile unsigned long *)(STATUS_BASE + 0x30) = (*((volatile unsigned long *)(0xE000ED3C))); // AFSR
*(volatile unsigned long *)(STATUS_BASE + 0x34) = (*((volatile unsigned long *)(0xE000ED34))); // MMAR
*(volatile unsigned long *)(STATUS_BASE + 0x38) = (*((volatile unsigned long *)(0xE000ED38))); // BFAR
}
hw_cpm_assert_trigger_gpio();
if (REG_GETF(CRG_TOP, SYS_STAT_REG, DBG_IS_ACTIVE)) {
__BKPT(0);
}
else {
while (1);
}
#else // dg_configIMAGE_SETUP == DEVELOPMENT_MODE
if (exception_args != NULL) {
nmi_event_data[0] = NMI_MAGIC_NUMBER;
nmi_event_data[1] = exception_args[0]; // R0
nmi_event_data[2] = exception_args[1]; // R1
nmi_event_data[3] = exception_args[2]; // R2
nmi_event_data[4] = exception_args[3]; // R3
nmi_event_data[5] = exception_args[4]; // R12
nmi_event_data[6] = exception_args[5]; // LR
nmi_event_data[7] = exception_args[6]; // PC
nmi_event_data[8] = exception_args[7]; // PSR
}
// Wait for the reset to occur
while (1);
#endif // dg_configIMAGE_SETUP == DEVELOPMENT_MODE
}
__RETAINED_CODE void NMI_HandlerC(unsigned long *exception_args);
void NMI_HandlerC(unsigned long *exception_args)
{
if (int_handler) {
int_handler(exception_args);
}
else {
hw_watchdog_handle_int(exception_args);
}
}
/**
* \}
* \}
* \}
*/
@@ -1,209 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \{
* \addtogroup Wakeup_Timer
* \{
*/
/**
****************************************************************************************
*
* @file hw_wkup.c
*
* @brief Implementation of the Wakeup timer Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_WKUP
#include <stdio.h>
#include <string.h>
#include <hw_wkup.h>
static hw_wkup_interrupt_cb intr_cb __RETAINED /* = NULL*/;
#if ((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A))
#define PX_DATA_REG_ADDR(_port) ((uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_DATA_REG)) + _port)
#define PX_DATA_REG(_port) *PX_DATA_REG_ADDR(_port)
#define BF_GET(_var, _pos) ((_var>>_pos) & 1)
__RETAINED volatile wkup_pin_config_t wkup_pin_config;
volatile uint8_t wkup_status[HW_GPIO_NUM_PORTS];
static bool hw_wkup_update_status(void)
{
uint8_t i, j, enable_loop_cnt = 0;
uint8_t pol_rx_reg;
bool wkup_status_updated = false;
uint8_t cur_port_data[HW_GPIO_NUM_PORTS];
for (i = 0; i < HW_GPIO_NUM_PORTS; i++) {
wkup_status[i] = 0;
if (wkup_pin_config.pin_state[i]) {
//read port status
cur_port_data[i] = PX_DATA_REG(i);
//read trigger polarity
pol_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 10 + i);
for (j = 0; j < 8; j++) {
if ((wkup_pin_config.pin_state[i] & (1 << j)) &&
(BF_GET(pol_rx_reg, j)
== BF_GET(~cur_port_data[i], j))) {
//invert trigger polarity
pol_rx_reg ^= (1 << j);
if (BF_GET(wkup_pin_config.pin_trigger[i], j)
== BF_GET(~cur_port_data[i], j)) {
wkup_status[i] |= (1 << j);
wkup_status_updated = true;
}
}
}
//update trigger polarity
*((volatile uint16_t *)WAKEUP_BASE + 10 + i) = pol_rx_reg;
}
}
return wkup_status_updated;
}
#endif /* dg_configLATCH_WKUP_SOURCE */
void hw_wkup_init(const wkup_config *cfg)
{
unsigned int i;
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_TMR_REG, WAKEUPCT_ENABLE);
GLOBAL_INT_RESTORE();
/* reset configuration */
WAKEUP->WKUP_CTRL_REG = 0;
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
WAKEUP->WKUP_COMPARE_REG = 0;
#endif
/* disable all pins */
for (i = 0; i < HW_GPIO_NUM_PORTS; i++) {
*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + i) = 0;
*((volatile uint16_t *)(&WAKEUP->WKUP_SELECT_P0_REG) + i) = 0;
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
*((volatile uint16_t *)(&WAKEUP-> WKUP_SEL_GPIO_P0_REG) + i) = 0;
#endif
#if dg_configLATCH_WKUP_SOURCE
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
wkup_pin_config.pin_state[i] = 0;
wkup_pin_config.pin_trigger[i] = 0;
wkup_status[i] = 0;
hw_wkup_clear_status(i, 0xFF);
#endif
#endif //dg_configLATCH_WKUP_SOURCE
}
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
WAKEUP->WKUP_CLEAR_0_REG = WAKEUP->WKUP_CLEAR_1_REG = WAKEUP->WKUP_CLEAR_2_REG = 0xFFFF;
#endif
NVIC_DisableIRQ(WKUP_GPIO_IRQn);
hw_wkup_configure(cfg);
}
void hw_wkup_configure(const wkup_config *cfg)
{
int i;
if (!cfg) {
return;
}
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
hw_wkup_set_counter_threshold(cfg->threshold);
#endif
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
hw_wkup_set_debounce_time(cfg->debounce);
#endif
for (i = 0; i < HW_GPIO_NUM_PORTS; i++) {
hw_wkup_configure_port(i, cfg->pin_state[i], cfg->pin_trigger[i]);
}
}
void hw_wkup_register_interrupt(hw_wkup_interrupt_cb cb, uint32_t prio)
{
intr_cb = cb;
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
HW_WKUP_REG_SETF(CTRL, WKUP_ENABLE_IRQ, 1);
#endif
NVIC_ClearPendingIRQ(WKUP_GPIO_IRQn);
NVIC_SetPriority(WKUP_GPIO_IRQn, prio);
NVIC_EnableIRQ(WKUP_GPIO_IRQn);
}
void hw_wkup_unregister_interrupt(void)
{
intr_cb = NULL;
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
HW_WKUP_REG_SETF(CTRL, WKUP_ENABLE_IRQ, 0);
#endif
NVIC_DisableIRQ(WKUP_GPIO_IRQn);
}
void hw_wkup_handler(void)
{
#if ((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A))
if (intr_cb && hw_wkup_update_status()) {
#else
if (intr_cb) {
#endif
intr_cb();
}
else {
hw_wkup_reset_interrupt();
#if dg_configLATCH_WKUP_SOURCE
hw_wkup_clear_status(HW_GPIO_PORT_0, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_1, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_2, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_3, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_4, 0xFF);
#endif
}
}
#ifdef OS_BAREMETAL
void WKUP_GPIO_Handler(void)
{
hw_wkup_handler();
}
#endif
#endif /* dg_configUSE_HW_WKUP */
/**
* \}
* \}
* \}
*/
@@ -1,454 +0,0 @@
/**
\addtogroup BSP
\{
\addtogroup SYSTEM
\{
\addtogroup TCS_Handling
\{
*/
/**
****************************************************************************************
*
* @file sys_tcs.c
*
* @brief TCS HAndler
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 <stdint.h>
#include "hw_cpm.h"
#include "sys_tcs.h"
#include "hw_gpadc.h"
#define APPEND_TCS_LENGTH (0)
#define RADIO_AREA_SIZE (0x1000)
#define PERIPHERAL_AREA_SIZE (0xC4A)
#define IS_IN_AREA(addr, base, size) ((addr >= base) && (addr <= (base + size)))
#define ADC_SE_GAIN_ERROR(value) ((value) & 0x0000FFFF)
#define ADC_DIFF_GAIN_ERROR(value) (((value) & 0xFFFF0000) >> 16)
/*
* Global and / or retained variables
*/
uint32_t tcs_data[24 * 2 + APPEND_TCS_LENGTH] __RETAINED_UNINIT;
uint8_t tcs_length __RETAINED_UNINIT;
uint8_t area_offset[tcs_system + 1] __RETAINED;
uint8_t area_size_global[tcs_system + 1] __RETAINED;
uint16_t sys_tcs_xtal16m_settling_time __RETAINED;
const uint32_t *tcs_ptr __RETAINED;
bool sys_tcs_is_calibrated_chip __RETAINED_UNINIT; // Initial value: false
/*
* Local variables
*/
static const uint32_t uncalibrated_tcs_data[] = {
/* BANDGAP_REG: (offset 0)
* [14]: BYPASS_COLD_BOOT_DISABLE = 0
* [13:10]: LDO_SLEEP_TRIM = 0x4
* [9:5]: BGR_ITRIM = 0x00
* [4:0]: BGR_TRIM = 0x13 (change until V12 is 1.2V)
*
* Especially for this register, merge the trimmed and preferred settings.
*/
(uint32_t)&CRG_TOP->BANDGAP_REG, 0x1013,
/* CLK_FREQ_TRIM_REG: (offset 2)
* [10:8]: COARSE_ADJ = 0x4
* [7:0]: FINE_ADJ = 0x60
*/
(uint32_t)&CRG_TOP->CLK_FREQ_TRIM_REG, 0x0460,
/* CLK_16M_REG: (offset 4)
* [15]: RC16M_STARTUP_DISABLE = 0
* [14]: XTAL16_HPASS_FLT_EN = 0
* [13]: XTAL16_SPIKE_FLT_BYPASS = 0
* [12:10]: XTAL16_AMP_TRIM = 0x5
* [9]: XTAL16_EXT_CLK_ENABLE = 0
* [8]: XTAL16_MAX_CURRENT = 0
* [7:5]: XTAL16_CUR_SET = 0x5
* [4:1]: RC16M_TRIM = 0x9
* [0]: RC16M_ENABLE = 0
*
* Apply the trimmed and a default preferred value. The correct one is applied
* later.
*/
(uint32_t)&CRG_TOP->CLK_16M_REG, 0x14B2,
/* CLK_32K_REG: (offset 6)
* [15:13]: 0
* [12]: XTAL32K_DISABLE_AMPREG0 = 0
* [11:8]: RC32K_TRIM = 0x07
* [7]: RC32K_ENABLE = 0x1 (reset value)
* [6:3]: XTAL32K_CUR = 0x3 (reset value)
* [2:1]: XTAL32K_RBIAS = 0x2 (reset value)
* [0]: XTAL32K_ENABLE = 0
*/
(uint32_t)&CRG_TOP->CLK_32K_REG, 0x79C,
/* CHARGER_CTRL2_REG: (offset 8)
* [15:13]: 0
* [12:8]: CURRENT_OFFSET_TRIM = 0x0C
* [7:4]: CHARGER_VFLOAT_ADJ = 0x5
* [3:0]: CURRENT_GAIN_TRIM = 0xA
*/
(uint32_t)&ANAMISC->CHARGER_CTRL2_REG, 0x0C5A,
};
#define UNCALIBRATED_DATA_NON_RETAINED_OFFSET (8)
#ifdef CONFIG_USE_BLE
#define UNCALIBRATED_DATA_BLE_SIZE (0)
#define UNCALIBRATED_DATA_BLE_OFFSET (0)
#endif
#ifdef CONFIG_USE_FTDF
#define UNCALIBRATED_DATA_FTDF_SIZE (0)
#define UNCALIBRATED_DATA_FTDF_OFFSET (0)
#endif
#define UNCALIBRATED_DATA_RADIO_SIZE (0)
#define UNCALIBRATED_DATA_RADIO_OFFSET (0)
#define UNCALIBRATED_DATA_CHARGER_SIZE (1 * 2)
#define UNCALIBRATED_DATA_CHARGER_OFFSET (8)
#define UNCALIBRATED_DATA_AUDIO_SIZE (0)
#define UNCALIBRATED_DATA_AUDIO_OFFSET (0)
#define UNCALIBRATED_DATA_SYSTEM_SIZE (0)
#define UNCALIBRATED_DATA_SYSTEM_OFFSET (0)
/*
* Forward declarations
*/
/*
* Function definitions
*/
/**
* \brief Apply a TCS <address, value> pair.
*
* \param [in] address the address of the register
* \param [in] value the value for this register
*
*/
static void apply_pair(uint32_t address, uint32_t value)
{
if (address & 0x2) {
*(volatile uint16_t *)address = value;
}
else {
*(volatile uint32_t *)address = value;
}
}
/**
* \brief Apply a TCS <address, value> entry of the TCS array.
*
* \param [in] address the address of the register
* \param [in] value the value for this register
*
*/
static void apply_entry(uint8_t index)
{
uint32_t address = tcs_ptr[index];
uint32_t value = tcs_ptr[index + 1];
if (address & 0x2) {
*(volatile uint16_t *)address = value;
}
else {
*(volatile uint32_t *)address = value;
}
}
/**
* \brief Store TCS <address, value> pair in the Global TCS array.
*
* \param [in] address the address of the register
* \param [in] value the value for this register
*
*/
static void store_in_array(uint32_t address, uint32_t value)
{
tcs_data[tcs_length] = address;
tcs_length++;
tcs_data[tcs_length] = value;
tcs_length++;
}
/**
* \brief Swaps the contents of two entries in the TCS array.
*
* \param [in] address the address of the register
* \param [in] value the value for this register
*
* \warning When this function is called, the RC16 must have been set as the system clock!
*
*/
static void swap_entries(uint32_t first_pos, uint32_t second_pos)
{
uint32_t address_stored;
uint32_t value_stored;
address_stored = tcs_data[second_pos];
value_stored = tcs_data[second_pos + 1];
tcs_data[second_pos] = tcs_data[first_pos];
tcs_data[second_pos + 1] = tcs_data[first_pos + 1];
tcs_data[first_pos] = address_stored;
tcs_data[first_pos + 1] = value_stored;
}
/**
* \brief Sort the registers of a specific Memory Map area of the chip to a continuous region in the
* TCS array.
*
* \param [in] area_base the base address of the Memory Map area
* \param [in] area_size the size of the Memory Map region in bytes
* \param [in] array_ptr the current position in the TCS array to start reading from (all previous
* positions have been sorted)
* \param [out] ptr the offset of the beginning of the sorted region in the TCS array
* \param [out] size the size of the sorted region in bytes
*
* \return The updated position in the TCS array to start reading next time
*/
static int sys_tcs_sort_area(uint32_t area_base, uint32_t area_size, uint32_t array_ptr, uint8_t *ptr, uint8_t *size)
{
uint32_t i = array_ptr;
uint32_t sort_start;
uint32_t sort_end;
if (array_ptr == tcs_length) {
return array_ptr; // Nothing else is left in the array or tcs_length is zero
}
sort_start = array_ptr;
sort_end = array_ptr;
/* Make sure that the values in TCS don't overflow the allocated array */
ASSERT_WARNING(tcs_length <= sizeof(tcs_data)/sizeof(tcs_data[0]));
while (i < (tcs_length - 1)) {
if (IS_IN_AREA(tcs_data[i], area_base, area_size)) {
if (i == array_ptr) {
if (sort_start == array_ptr) {
sort_start = array_ptr;
sort_end = sort_start + 2;
}
}
else {
// Copy it to the proper place.
if (i != sort_end) {
swap_entries(sort_end, i);
}
sort_end += 2;
}
}
i += 2;
}
*ptr = sort_start;
*size = sort_end - sort_start;
return sort_end;
}
void sys_tcs_init(void)
{
tcs_length = 0;
sys_tcs_is_calibrated_chip = false;
hw_cpm_bod_enabled_in_tcs = 0;
}
bool sys_tcs_store_pair(uint32_t address, uint32_t value)
{
// If it stops here then tcs_length must become uint16_t.
ASSERT_WARNING( (256 * sizeof(tcs_length)) >= (24 * 2 + APPEND_TCS_LENGTH) );
// Check if the address is in Always-ON or of a retained register and apply it.
if (IS_IN_AREA(address, CRG_TOP_BASE, sizeof(CRG_TOP_Type))
|| IS_IN_AREA(address, TIMER1_BASE, sizeof(TIMER1_Type))
|| IS_IN_AREA(address, WAKEUP_BASE, sizeof(WAKEUP_Type))
|| IS_IN_AREA(address, DCDC_BASE, sizeof(DCDC_Type))
|| IS_IN_AREA(address, QSPIC_BASE, sizeof(QSPIC_Type))
|| IS_IN_AREA(address, CACHE_BASE, sizeof(CACHE_Type))
|| IS_IN_AREA(address, OTPC_BASE, sizeof(OTPC_Type))) {
if (address == (uint32_t)&CRG_TOP->BANDGAP_REG) {
sys_tcs_is_calibrated_chip = true;
} else if (address == (uint32_t)&CRG_TOP->CLK_16M_REG) {
value |= CRG_TOP_CLK_16M_REG_RC16M_ENABLE_Msk; // Make sure that RC16 is enabled!
} else if (address == (uint32_t)&CRG_TOP->XTALRDY_CTRL_REG) {
sys_tcs_xtal16m_settling_time = value;
} else if (address == (uint32_t)&CRG_TOP->BOD_CTRL2_REG) {
hw_cpm_bod_enabled_in_tcs = value;
/*
* Read the ADC Gain Error. Given that the Chip Configuration Section
* (CCS) of OTP is out of space, the values are stored in the TCS section
* using as address the read-only register SYS_STAT_REG.
* The 16 LSB of the 32bit data-value is the single ended gain error.
* The 16 MSB of the 32bit data-value is the differential gain error.
* Both gain error values should be interpreted as signed 16bit integers.
*/
} else if (dg_configUSE_ADC_GAIN_ERROR_CORRECTION == 1) {
if (address == (uint32_t)&CRG_TOP->SYS_STAT_REG) {
hw_gpadc_store_se_gain_error(ADC_SE_GAIN_ERROR(value));
hw_gpadc_store_diff_gain_error(ADC_DIFF_GAIN_ERROR(value));
}
}
apply_pair(address, value);
} else {
store_in_array(address, value);
}
return sys_tcs_is_calibrated_chip;
}
void sys_tcs_sort_array(void)
{
int entry_ptr = 0;
int i;
/*
* Apply a default value to CLK_FREQ_TRIM_REG, if not set in TCS.
* [10:8]: COARSE_ADJ = 0x4
* [7:0]: FINE_ADJ = 0x60
*/
if (CRG_TOP->CLK_FREQ_TRIM_REG == 0) {
CRG_TOP->CLK_FREQ_TRIM_REG = 0x0460;
}
if (sys_tcs_is_calibrated_chip) {
#ifdef CONFIG_USE_BLE
entry_ptr = sys_tcs_sort_area(BLE_BASE, sizeof(BLE_Type), entry_ptr,
&area_offset[tcs_ble], &area_size_global[tcs_ble]);
#endif
#ifdef CONFIG_USE_FTDF
entry_ptr = sys_tcs_sort_area(FTDF_BASE, sizeof(FTDF_Type), entry_ptr,
&area_offset[tcs_ftdf], &area_size_global[tcs_ftdf]);
#endif
entry_ptr = sys_tcs_sort_area(RFCU_BASE, RADIO_AREA_SIZE, entry_ptr,
&area_offset[tcs_radio], &area_size_global[tcs_radio]);
entry_ptr = sys_tcs_sort_area((uint32_t)&ANAMISC->CHARGER_CTRL2_REG, 1, entry_ptr,
&area_offset[tcs_charger], &area_size_global[tcs_charger]);
entry_ptr = sys_tcs_sort_area(APU_BASE, sizeof(APU_Type), entry_ptr,
&area_offset[tcs_audio], &area_size_global[tcs_audio]);
// The rest should be System. Assert if not!
for (i = entry_ptr; i < tcs_length; i += 2) {
if (IS_IN_AREA(tcs_data[i], UART_BASE, PERIPHERAL_AREA_SIZE)) {
ASSERT_WARNING(0);
}
if (IS_IN_AREA(tcs_data[i], CRG_TOP_BASE, 0x6100)) {
// It is ok (most probably).
}
else {
ASSERT_WARNING(0);
}
}
area_offset[tcs_system] = entry_ptr;
area_size_global[tcs_system] = tcs_length - entry_ptr;
tcs_ptr = tcs_data;
}
else {
tcs_ptr = uncalibrated_tcs_data;
for (i = 0; i < UNCALIBRATED_DATA_NON_RETAINED_OFFSET; i += 2) {
apply_pair(tcs_ptr[i], tcs_ptr[i + 1]);
}
#ifdef CONFIG_USE_BLE
if (UNCALIBRATED_DATA_BLE_SIZE > 0) {
area_offset[tcs_ble] = UNCALIBRATED_DATA_BLE_OFFSET;
area_size_global[tcs_ble] = UNCALIBRATED_DATA_BLE_SIZE;
}
#endif
#ifdef CONFIG_USE_FTDF
if (UNCALIBRATED_DATA_FTDF_SIZE > 0) {
area_offset[tcs_ftdf] = UNCALIBRATED_DATA_FTDF_OFFSET;
area_size_global[tcs_ftdf] = UNCALIBRATED_DATA_FTDF_SIZE;
}
#endif
if (UNCALIBRATED_DATA_RADIO_SIZE > 0) {
area_offset[tcs_radio] = UNCALIBRATED_DATA_RADIO_OFFSET;
area_size_global[tcs_radio] = UNCALIBRATED_DATA_RADIO_SIZE;
}
if (UNCALIBRATED_DATA_CHARGER_SIZE > 0) {
area_offset[tcs_charger] = UNCALIBRATED_DATA_CHARGER_OFFSET;
area_size_global[tcs_charger] = UNCALIBRATED_DATA_CHARGER_SIZE;
}
if (UNCALIBRATED_DATA_AUDIO_SIZE > 0) {
area_offset[tcs_audio] = UNCALIBRATED_DATA_AUDIO_OFFSET;
area_size_global[tcs_audio] = UNCALIBRATED_DATA_AUDIO_SIZE;
}
if (UNCALIBRATED_DATA_SYSTEM_SIZE > 0) {
area_offset[tcs_system] = UNCALIBRATED_DATA_SYSTEM_OFFSET;
area_size_global[tcs_system] = UNCALIBRATED_DATA_SYSTEM_SIZE;
}
}
}
void sys_tcs_apply(sys_tcs_area_t area)
{
int i;
for (i = area_offset[area]; i < (area_offset[area] + area_size_global[area]); i += 2) {
apply_entry(i);
}
}
/**
\}
\}
\}
*/
-143
View File
@@ -1,143 +0,0 @@
/**
****************************************************************************************
*
* @file config.c
*
* @brief Configure system.
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
/**
\addtogroup BSP
\{
\addtogroup SYSTEM
\{
\addtogroup Start-up
\{
*/
#include <stdbool.h>
#include <stdio.h>
#include "sdk_defs.h"
#include "interrupts.h"
/*
* Dialog default priority configuration table.
*
* Content of this table will be applied at system start.
*
* \note If interrupt priorities provided by Dialog need to be changed, do not modify this file.
* Create similar table with SAME name instead somewhere inside code without week attribute,
* and it will be used instead of table below.
*/
#pragma weak __dialog_interrupt_priorities
INTERRUPT_PRIORITY_CONFIG_START(__dialog_interrupt_priorities)
PRIORITY_0, /* Start interrupts with priority 0 (highest) */
SVCall_IRQn,
PendSV_IRQn,
XTAL16RDY_IRQn,
PRIORITY_1, /* Start interrupts with priority 1 */
BLE_WAKEUP_LP_IRQn,
BLE_GEN_IRQn,
FTDF_WAKEUP_IRQn,
FTDF_GEN_IRQn,
RFCAL_IRQn,
COEX_IRQn,
CRYPTO_IRQn,
RF_DIAG_IRQn,
PRIORITY_2, /* Start interrupts with priority 2 */
DMA_IRQn,
I2C_IRQn,
I2C2_IRQn,
SPI_IRQn,
SPI2_IRQn,
ADC_IRQn,
SRC_IN_IRQn,
SRC_OUT_IRQn,
TRNG_IRQn,
LAST_IRQn,
PRIORITY_3, /* Start interrupts with priority 3 (lowest) */
SysTick_IRQn,
UART_IRQn,
UART2_IRQn,
MRM_IRQn,
KEYBRD_IRQn,
IRGEN_IRQn,
WKUP_GPIO_IRQn,
SWTIM0_IRQn,
SWTIM1_IRQn,
QUADEC_IRQn,
USB_IRQn,
PCM_IRQn,
VBUS_IRQn,
DCDC_IRQn,
INTERRUPT_PRIORITY_CONFIG_END
void set_interrupt_priorities(const int8_t prios[])
{
uint32_t old_primask, iser;
int i = 0;
uint32_t prio = 0;
/*
* We shouldn't change the priority of an enabled interrupt.
* 1. Globally disable interrupts, saving the global interrupts disable state.
* 2. Explicitly disable all interrupts, saving the individual interrupt enable state.
* 3. Set interrupt priorities.
* 4. Restore individual interrupt enables.
* 5. Restore global interrupt enable state.
*/
old_primask = __get_PRIMASK();
__disable_irq();
iser = NVIC->ISER[0];
NVIC->ICER[0] = iser;
for (i = 0; prios[i] != PRIORITY_TABLE_END; ++i) {
switch (prios[i]) {
case PRIORITY_0:
case PRIORITY_1:
case PRIORITY_2:
case PRIORITY_3:
prio = prios[i] - PRIORITY_0;
break;
default:
NVIC_SetPriority(prios[i], prio);
break;
}
}
NVIC->ISER[0] = iser;
__set_PRIMASK(old_primask);
}
/**
\}
\}
\}
*/
@@ -1,367 +0,0 @@
/* File: startup_ARMCM0.S
* Purpose: startup file for Cortex-M0 devices. Should use with
* GCC for ARM Embedded Processors
* Version: V2.0
* Date: 16 August 2013
*/
/* Copyright (c) 2011 - 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
.syntax unified
.arch armv6-m
.section text_reset
.thumb
.thumb_func
.align 1
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
#if (dg_configSKIP_MAGIC_CHECK_AT_START == 0)
/* If the Magic Word {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEAD10CC} is found at 0x7fd0000 then the
* execution will block for a while in order to give time to a debugger to attach. */
ldr r4, =0x7fd0000
ldmia r4!, {r0-r3}
ldr r4, =0xDEADBEEF
cmp r0, r4
bne .code_starts
cmp r1, r4
bne .code_starts
cmp r2, r4
bne .code_starts
ldr r4, =0xDEAD10CC
cmp r3, r4
bne .code_starts
/* Enable debugger */
ldr r4, =0x50000012
ldrh r5, [r4]
mov r6, r5
movs r1, #128
orrs r5, r5, r1
strh r5, [r4]
/* Block for 2'' */
ldr r0, =0x150000
.delay_loop:
subs r0, #1
bgt .delay_loop
/* Make sure that this will happen only once! */
ldr r4, =0x7fd0000
movs r0, #0
str r0, [r4]
/* Restore debugger setting */
ldr r4, =0x50000012
strh r6, [r4]
.code_starts:
#endif
/* RAM shuffling configuration should be determined from the image in the QSPI Flash or OTP
* and must be applied at the beginning of the Reset Vector. The interrupt vector table must
* be copied to the RAM base after the shuffling is done.
* NOTE: Even though there is an OTP field specifically for the shuffling configuration
* we must bypass it here since the shuffling might change between different
* QSPI FLASH image versions. For OTP images RAM shuffling configuration will never change,
* but we also apply it to ignore the OTP field in any case. */
ldr r4, =0x50000012
movs r0, #0
ldrh r0, [r4]
movs r1, #0x18
bics r0, r0, r1
movs r1, #dg_configSHUFFLING_MODE<<3
orrs r0, r0, r1
/* Update SYS_CTRL_REG. */
strh r0, [r4]
/* Copy ISR VT from from QSPI Flash/OTP to RAM. This must be done
* after applying shuffling mode. */
# if (dg_configIMAGE_FLASH_OFFSET == 0)
ldr r1, =0x8000008
# else
ldr r1, =(0x8000000 + dg_configIMAGE_FLASH_OFFSET)
# endif
ldr r2, =0x7FC0000
ldr r3, =0x7FC00C0
/* Block should be a multiple of 16 to traverse correctly L_loopIV */
subs r3, r2
ble .L_loopIV_done
.L_loopIV:
ldmia r1!, {r4-r7}
stmia r2!, {r4-r7}
subs r3, #16
bgt .L_loopIV
.L_loopIV_done:
bl SystemInitPre
bl SystemInit
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#define __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r0, =__copy_table_end__
.L_loop0:
cmp r4, r0
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
push {r4}
.L_loop0_0:
subs r3, #16
blt .L_loop0_0_done
ldmia r1!, {r4-r7}
stmia r2!, {r4-r7}
b .L_loop0_0
.L_loop0_0_done:
pop {r4}
adds r4, #12
b .L_loop0
.L_loop0_done:
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#define __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r0, =__zero_table_end__
movs r4, 0
movs r5, r4
mov r6, r4
mov r7, r4
.L_loop2:
cmp r3, r0
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
.L_loop2_0:
subs r2, #32 // Requires 32-byte alignment!
blt .L_loop2_0_done
stmia r1!, {r4-r7}
stmia r1!, {r4-r7}
b .L_loop2_0
.L_loop2_0_done:
adds r3, #8
b .L_loop2
.L_loop2_done:
/* Copy the address of the retained NMI and HardFault handlers to the vector table. */
ldr r0, =0x7FC0008
ldr r1, =NMI_Handler
str r1, [r0, #0]
ldr r1, =HardFault_Handler
str r1, [r0, #4]
bl SystemInitPost
bl main
.pool
.size Reset_Handler, . - Reset_Handler
.text
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
/*
* enable debugger:
* CRG_TOP->SYS_CTRL_REG_b.DEBUGGER_ENABLE = 1;
*/
movs r1, #0x50
lsls r1, #24
ldrh r2, [r1, #0x12]
movs r3, #0x80
orrs r2, r2, r3
strh r2, [r1, #0x12]
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
.thumb
.thumb_func
.align 1
.weak SVC_Handler
.type SVC_Handler, %function
SVC_Handler:
b .
.size SVC_Handler, . - SVC_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler BLE_WAKEUP_LP_Handler
def_irq_handler BLE_GEN_Handler
def_irq_handler FTDF_WAKEUP_Handler
def_irq_handler FTDF_GEN_Handler
def_irq_handler RFCAL_Handler
def_irq_handler COEX_Handler
def_irq_handler CRYPTO_Handler
def_irq_handler MRM_Handler
def_irq_handler UART_Handler
def_irq_handler UART2_Handler
def_irq_handler I2C_Handler
def_irq_handler I2C2_Handler
def_irq_handler SPI_Handler
def_irq_handler SPI2_Handler
def_irq_handler ADC_Handler
def_irq_handler KEYBRD_Handler
def_irq_handler IRGEN_Handler
def_irq_handler WKUP_GPIO_Handler
def_irq_handler SWTIM0_Handler
def_irq_handler SWTIM1_Handler
def_irq_handler QUADEC_Handler
def_irq_handler USB_Handler
def_irq_handler PCM_Handler
def_irq_handler SRC_IN_Handler
def_irq_handler SRC_OUT_Handler
def_irq_handler VBUS_Handler
def_irq_handler DMA_Handler
def_irq_handler RF_DIAG_Handler
def_irq_handler TRNG_Handler
def_irq_handler DCDC_Handler
def_irq_handler XTAL16RDY_Handler
def_irq_handler RESERVED31_Handler
.section text_retained
.align 1
.thumb
.thumb_func
.globl NMI_Handler
.type NMI_Handler, %function
NMI_Handler:
ldr r1, =NMI_HandlerC
movs r0, #4
mov r2, lr
tst r0, r2
beq NMI_stacking_using_MSP
mrs r0, psp
b stack_check
NMI_stacking_using_MSP:
mrs r0, msp
b stack_check
.size NMI_Handler, . - NMI_Handler
.align 1
.thumb
.thumb_func
.globl HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
ldr r1, =HardFault_HandlerC
movs r0, #4
mov r2, lr
tst r0, r2
beq HF_stacking_using_MSP
mrs r0, psp
b stack_check
HF_stacking_using_MSP:
mrs r0, msp
stack_check:
/* 0x7FC0000 is start of RAM */
ldr r2, =0x7FC0000
cmp r0, r2
blt Wrong_SP
/* Check SYS_CTRL_REG:CACHERAM_MUX */
ldr r2, =0x50000012
ldrh r2, [r2]
movs r3, #1
lsls r3, r3, #10
ands r2, r2, r3
bne cache_is_on
/* 0x7FE4000 marks end of RAM (assuming that the CACHE is used as RAM) */
ldr r2, =0x7FE4000-32
b check_end_of_ram
cache_is_on:
/* 0x7FE0000 marks end of RAM */
ldr r2, =0x7FE0000-32
check_end_of_ram:
cmp r0, r2
bgt Wrong_SP
bx r1
Wrong_SP:
/* Freeze WDog at all times */
ldr r0, =0x50003300
ldr r1, =8
strh r1, [r0, #0]
/* Enable debugger at all times */
ldr r4, =0x50000012
ldrh r0, [r4, #0]
movs r1, #0x80
orrs r0, r0, r1
/* Update SYS_CTRL_REG */
strh r0, [r4, #0]
/* Wait for the WDog to hit or a debug session to start */
b .
.size HardFault_Handler, . - HardFault_Handler
.end
-571
View File
@@ -1,571 +0,0 @@
/**************************************************************************//**
* @file system_ARMCM0.c
* @brief CMSIS Device System Source File for
* ARMCM0 Device Series
* @version V2.00
* @date 18. August 2015
******************************************************************************/
/* Copyright (c) 2011 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/errno.h>
#include "sdk_defs.h"
#include "interrupts.h"
#include "hw_cpm.h"
#include "hw_otpc.h"
#include "hw_qspi.h"
#include "hw_watchdog.h"
#include "sys_tcs.h"
#include "qspi_automode.h"
/*
* This is just so that compilation doesn't break for RAM builds.
* The code that uses it is optimized out in RAM builds.
*/
extern uint32_t NVMS_PARAM_PART_end;
/*
* TCS Offsets
*/
#define OTP_HEADER_BASE_ADDR_IN_OTP (0x7F8E9C0)
#define TCS_SECTION_OFFSET (184) /* 0x7F8EA78 - 0x7F8E9C0 */
#define TCS_SECTION_LENGTH (24) /* 24 entries, 16 bytes each for OTP */
#ifndef __SYSTEM_CLOCK
# define __SYSTEM_CLOCK (16000000UL) /* 16 MHz */
#endif
#if (dg_configUSE_LP_CLK == LP_CLK_32000)
# define LP_CLK_FREQ (32000)
#elif (dg_configUSE_LP_CLK == LP_CLK_32768)
# define LP_CLK_FREQ (32768)
#elif (dg_configUSE_LP_CLK == LP_CLK_RCX)
# define LP_CLK_FREQ (0)
#else
# error "dg_configUSE_LP_CLK is not defined or has an unknown value!"
#endif
/*
* Linker symbols
*
* Note: if any of them is missing, please correct your linker script. Please refer to the linker
* script of pxp_reporter.
*/
extern uint32_t __copy_table_start__;
extern uint32_t __copy_table_end__;
extern uint32_t __zero_table_start__;
extern uint32_t __zero_table_end__;
extern uint8_t end;
extern uint8_t __HeapLimit;
/*
* Global variables
*/
__RETAINED_RW static uint8_t *heapend = &end;
__RETAINED_UNINIT __attribute__((unused)) uint32_t black_orca_chip_version;
uint32_t SystemCoreClock __RETAINED = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/
uint32_t SystemLPClock __RETAINED = LP_CLK_FREQ; /*!< System Low Power Clock Frequency (LP Clock)*/
/**
* @brief Memory safe implementation of newlib's _sbrk().
*
*/
__LTO_EXT
void *_sbrk(int incr)
{
uint8_t *newheapstart;
if (heapend + incr > &__HeapLimit) {
/* Hitting this, means that the value of _HEAP_SIZE is too small.
* The value of incr is in stored_incr at this point. By checking the equation
* above, it is straightforward to determine the missing space.
*/
volatile int stored_incr __attribute__((unused));
stored_incr = incr;
ASSERT_ERROR(0);
errno = ENOMEM;
return (void *)-1;
}
newheapstart = heapend;
heapend += incr;
return newheapstart;
}
/**
* Apply trim values from OTP.
*
* @brief Writes the trim values located in the OTP to the corresponding system registers.
*
* @param[out] tcs_array The valid <address, value> pairs are placed in this buffer.
* @param[out] valid_entries The number of valid pairs.
*
* @return True if at least one trim value has been applied, else false.
*
*/
static bool apply_trim_values_from_otp(uint32_t *tcs_array, uint32_t *valid_entries)
{
uint32_t address;
uint32_t inverted_address;
uint32_t value;
uint32_t inverted_value;
uint32_t *p;
int i;
int index = 0;
int vdd = 0;
int retries = 0;
bool forward_reading = true;
bool res = false;
p = (uint32_t *)(OTP_HEADER_BASE_ADDR_IN_OTP + TCS_SECTION_OFFSET);
for (i = 0; i < TCS_SECTION_LENGTH; i++) {
do {
address = *p;
p++;
inverted_address = *p;
p++;
value = *p;
p++;
inverted_value = *p;
p++;
if ((address == 0) && (value == 0)) {
break;
}
// Check validity
if ((address != ~inverted_address) || (value != ~inverted_value)) {
// Change LDO core voltage level and retry
vdd++;
vdd &= 0x3;
REG_SETF(CRG_TOP, LDO_CTRL1_REG, LDO_CORE_SETVDD, vdd);
// Wait for the voltage to settle...
SysTick->CTRL = 0;
SysTick->LOAD = 500; // 500 * (62.5 * 4) = 125usec
SysTick->VAL = 0;
SysTick->CTRL = 0x5; // Start using system clock
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {}
// Adjust the read pointer
p -= 4;
}
retries++;
if (retries == 32) {
// Unrecoverable problem! Assert in development mode
ASSERT_WARNING(0);
// Unrecoverable problem! Issue a HW reset.
hw_cpm_reset_system();
}
} while ((address != ~inverted_address) || (value != ~inverted_value));
retries = 0;
// Read the complete TCS area but skip empty entries.
if ((address == 0) && (value == 0)) {
if ((BLACK_ORCA_TARGET_IC >= BLACK_ORCA_IC_VERSION(A, E))
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1)
&& (CHIP_IS_AE || CHIP_IS_BB))) {
if (!forward_reading) {
break;
}
forward_reading = false;
p = (uint32_t *)(OTP_HEADER_BASE_ADDR_IN_OTP + TCS_SECTION_OFFSET);
p += (TCS_SECTION_LENGTH - 1) * 4;
}
else {
(void)forward_reading;
}
continue;
}
if (!forward_reading) {
p -= 8;
}
sys_tcs_store_pair(address, value);
tcs_array[(index * 2) + 0] = address;
tcs_array[(index * 2) + 1] = value;
*valid_entries = index + 1;
index++;
res = true;
}
return res;
}
/**
* Check whether the code has been compiled for a chip version that is compatible with the chip
* it runs on.
*/
static bool is_compatible_chip_version(void)
{
const uint32_t ver = black_orca_get_chip_version();
/* Oldest supported version is AE. */
if ((ver < BLACK_ORCA_IC_VERSION(A, E)) && (dg_configUSE_AUTO_CHIP_DETECTION == 0)) {
return false;
}
if ((ver == BLACK_ORCA_TARGET_IC) || (dg_configUSE_AUTO_CHIP_DETECTION == 1)) {
return true;
}
return false;
}
#ifdef OS_BAREMETAL
static volatile bool nortos_xtal16m_settled = false;
void XTAL16RDY_Handler(void)
{
nortos_xtal16m_settled = true;
}
/* carry out clock initialization sequence */
static void nortos_clk_setup(void)
{
// Setup DIVN
if (dg_configEXT_CRYSTAL_FREQ == EXT_CRYSTAL_IS_16M) {
hw_cpm_set_divn(false); // External crystal is 16MHz
}
else {
hw_cpm_set_divn(true); // External crystal is 32MHz
}
hw_cpm_enable_rc32k();
hw_cpm_lp_set_rc32k();
NVIC_ClearPendingIRQ(XTAL16RDY_IRQn);
nortos_xtal16m_settled = false;
NVIC_EnableIRQ(XTAL16RDY_IRQn); // Activate XTAL16 Ready IRQ
hw_cpm_set_xtal16m_settling_time(dg_configXTAL16_SETTLE_TIME_RC32K);
hw_cpm_enable_xtal16m(); // Enable XTAL16M
hw_watchdog_unfreeze(); // Start watchdog
while(!hw_cpm_is_xtal16m_started()); // Block until XTAL16M starts
/* Wait for XTAL16M to settle */
while(!nortos_xtal16m_settled);
hw_watchdog_freeze(); // Stop watchdog
hw_cpm_set_sysclk(SYS_CLK_IS_XTAL16M);
}
#endif /* OS_BAREMETAL */
static __RETAINED_CODE void configure_cache(void)
{
bool flush = false;
GLOBAL_INT_DISABLE();
if (dg_configCACHEABLE_QSPI_AREA_LEN != -1) {
uint32_t cache_len;
/* dg_configCACHEABLE_QSPI_AREA_LEN must be 64KB-aligned */
ASSERT_WARNING((dg_configCACHEABLE_QSPI_AREA_LEN & 0xFFFF) == 0);
/*
* dg_configCACHEABLE_QSPI_AREA_LEN shouldn't set any bits that do not fit in
* CACHE_CTRL2_REG.CACHE_LEN (9 bits wide) after shifting out the lower 16 bits
*/
ASSERT_WARNING((dg_configCACHEABLE_QSPI_AREA_LEN & 0x1FF0000)
== dg_configCACHEABLE_QSPI_AREA_LEN);
/*
* set cacheable area
*
* setting CACHE_CTRL2_REG.CACHE_LEN to N, actually sets the size of the cacheable
* area to (N + 1) * 64KB
* special cases:
* N == 0 --> no caching
* N == 1 --> 128KB are cached, i.e. no way to cache only 64KB
*/
cache_len = dg_configCACHEABLE_QSPI_AREA_LEN >> 16;
/* cannot cache only 64KB! */
ASSERT_WARNING(cache_len != 1);
if (cache_len > 1) {
cache_len--;
}
REG_SETF(CACHE, CACHE_CTRL2_REG, CACHE_LEN, cache_len);
}
if (dg_configCACHE_ASSOCIATIVITY != CACHE_ASSOC_AS_IS) {
if (CACHE->CACHE_ASSOCCFG_REG != dg_configCACHE_ASSOCIATIVITY) {
/* override the set associativity setting */
CACHE->CACHE_ASSOCCFG_REG = dg_configCACHE_ASSOCIATIVITY;
flush = true;
}
}
if (dg_configCACHE_LINESZ != CACHE_LINESZ_AS_IS) {
if (CACHE->CACHE_LNSIZECFG_REG != dg_configCACHE_LINESZ) {
/* override the cache line setting */
CACHE->CACHE_LNSIZECFG_REG = dg_configCACHE_LINESZ;
flush = true;
}
}
if (flush && (REG_GETF(CACHE, CACHE_CTRL2_REG, CACHE_LEN) > 0)) {
/* flush cache */
REG_SET_BIT(CACHE, CACHE_CTRL1_REG, CACHE_FLUSH);
}
GLOBAL_INT_RESTORE();
}
/**
* Basic system setup
*
* @brief Setup the AMBA clocks. Ensure proper alignment of copy and zero table entries.
*/
void SystemInitPre(void) __attribute__((section("text_reset")));
void SystemInitPre(void)
{
/*
* Enable debugger.
*/
if (dg_configENABLE_DEBUGGER) {
ENABLE_DEBUGGER;
}
/*
* Bandgap has already been set by the bootloader.
* Use fast clocks from now on.
*/
hw_cpm_set_hclk_div(0);
hw_cpm_set_pclk_div(0);
/*
* Ensure 16-byte alignment for all elements of each entry in the Copy Table. This is
* a requirement imposed by the fast start-up code! If any of the assertions below hits,
* please correct your linker script file accordingly!
*/
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) {
uint32_t *p;
for (p = &__copy_table_start__; p < &__copy_table_end__; p += 3) {
ASSERT_WARNING_UNINIT( (p[0] & 0xF) == 0 ); // from
ASSERT_WARNING_UNINIT( (p[1] & 0xF) == 0 ); // to
ASSERT_WARNING_UNINIT( (p[2] & 0xF) == 0 ); // size
}
}
/*
* Ensure 32-byte alignment for all elements of each entry in the Data Table. This is
* a requirement imposed by the fast start-up code! If any of the assertions below hits,
* please correct your linker script file accordingly!
*/
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) {
uint32_t *p;
for (p = &__zero_table_start__; p < &__zero_table_end__; p += 2) {
ASSERT_WARNING_UNINIT( (p[0] & 0x1F) == 0 ); // start at
ASSERT_WARNING_UNINIT( (p[1] & 0x1F) == 0 ); // size
}
}
}
/**
* Initialize the system
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit(void)
{
/*
* Make sure we are running on a chip version that the code has been built for.
*/
ASSERT_WARNING_UNINIT(is_compatible_chip_version());
/*
* Detect chip version (optionally).
*/
if (dg_configUSE_AUTO_CHIP_DETECTION == 1) {
black_orca_chip_version = black_orca_get_chip_version();
if (!CHIP_IS_AE && !CHIP_IS_BB) {
// Oldest supported version is AE.
ASSERT_WARNING_UNINIT(0);
}
}
/*
* Initialize UNINIT variables.
*/
sys_tcs_init();
/*
* BOD protection
*/
if (dg_configUSE_BOD == 1) {
/* BOD has already been enabled at this point but it must be reconfigured */
hw_cpm_configure_bod_protection();
} else {
hw_cpm_deactivate_bod_protection();
}
/*
* Apply default priorities to interrupts.
*/
set_interrupt_priorities(__dialog_interrupt_priorities);
/*
* If we are executing from RAM, make sure that code written in Flash won't have left the
* system in "unknown" state.
*/
if (dg_configCODE_LOCATION == NON_VOLATILE_IS_NONE) {
GLOBAL_INT_DISABLE();
CRG_TOP->PMU_CTRL_REG |= 0xE;
CRG_TOP->PMU_CTRL_REG &= ~1;
GLOBAL_INT_RESTORE();
}
/*
* Switch to RC16.
*/
hw_cpm_set_sysclk(SYS_CLK_IS_RC16); // Use RC16
hw_cpm_disable_xtal16m(); // Disable XTAL16M
/*
* Set highest access speed for QSPI Flash.
*/
if (dg_configFLASH_CONNECTED_TO != FLASH_IS_NOT_CONNECTED) {
hw_qspi_set_div(HW_QSPI_DIV_1);
}
}
/**
* Process the TCS
*
* @brief Process the TCS section.
*/
void SystemInitPost(void)
{
SystemCoreClock = __SYSTEM_CLOCK;
SystemLPClock = LP_CLK_FREQ;
uint32_t tcs_pairs[TCS_SECTION_LENGTH * 2];
uint32_t valid_tcs_pairs = 0;
hw_cpm_start_ldos(); // Make sure all LDOs are as expected
hw_cpm_reset_radio_vdd(); // Set Radio voltage to 1.40V
/*
* Initialize Flash
*/
if (dg_configFLASH_CONNECTED_TO != FLASH_IS_NOT_CONNECTED) {
qspi_automode_init(); // The bootloader may have left the Flash in wrong mode...
}
/*
* Retrieve trim values from OTP.
*/
hw_otpc_init(); // Start clock.
hw_otpc_disable(); // Make sure it is in standby mode.
hw_otpc_init(); // Restart clock.
hw_otpc_manual_read_on(false);
/*
* Apply trim values from OTP.
*/
apply_trim_values_from_otp(tcs_pairs, &valid_tcs_pairs);
if (dg_configIMAGE_SETUP == PRODUCTION_MODE) {
ASSERT_ERROR(sys_tcs_is_calibrated_chip); // Uncalibrated chip!!!
}
hw_otpc_manual_read_off();
hw_otpc_disable();
if (dg_configFLASH_CONNECTED_TO != FLASH_IS_NOT_CONNECTED) {
hw_cpm_enable_qspi_init(); // Enable QSPI init after wakeup
hw_qspi_set_read_pipe_clock_delay(6); // Set read pipe clock delay to 6 (Last review date: Feb 15, 2016 - 12:25:47)
}
/*
* All trim values have been loaded from TCS or defaults are used.
*/
sys_tcs_sort_array();
sys_tcs_apply(tcs_system);
hw_cpm_set_preferred_values();
#ifdef OS_BAREMETAL
/* perform clock initialization here, as there is no CPM to do it later for us */
nortos_clk_setup();
#endif
configure_cache();
}
uint32_t DA15000_phy_addr(uint32_t addr)
{
static const uint32 remap[] = {
MEMORY_ROM_BASE,
MEMORY_OTP_BASE,
MEMORY_QSPIF_BASE,
MEMORY_SYSRAM_BASE,
MEMORY_QSPIF_BASE,
MEMORY_OTP_BASE,
MEMORY_CACHERAM_BASE,
0
};
if (addr >= MEMORY_REMAPPED_END)
return addr;
return addr + remap[REG_GETF(CRG_TOP, SYS_CTRL_REG, REMAP_ADR0)];
}
__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); }
-178
View File
@@ -1,178 +0,0 @@
/**
****************************************************************************************
*
* @file vector_table.S
*
* @brief Interrupt Vector Table and Patch Table
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
.syntax unified
.arch armv6-m
.section .stack
.align 3
.equ Stack_Size, __STACK_SIZE
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
.equ Heap_Size, __HEAP_SIZE
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .isr_vector, "a"
.align 2
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long Default_Handler /* replaced by NMI_Handler after the ISR is copied to retRAM*/
.long Default_Handler /* replaced by HardFault_Handler after the ISR is copied to retRAM */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long BLE_WAKEUP_LP_Handler /* 0 */
.long BLE_GEN_Handler /* 1 */
.long FTDF_WAKEUP_Handler /* 2 */
.long FTDF_GEN_Handler /* 3 */
.long RFCAL_Handler /* 4 */
.long COEX_Handler /* 5 */
.long CRYPTO_Handler /* 6 */
.long MRM_Handler /* 7 */
.long UART_Handler /* 8 */
.long UART2_Handler /* 9 */
.long I2C_Handler /* 10 */
.long I2C2_Handler /* 11 */
.long SPI_Handler /* 12 */
.long SPI2_Handler /* 13 */
.long ADC_Handler /* 14 */
.long KEYBRD_Handler /* 15 */
.long IRGEN_Handler /* 16 */
.long WKUP_GPIO_Handler /* 17 */
.long SWTIM0_Handler /* 18 */
.long SWTIM1_Handler /* 19 */
.long QUADEC_Handler /* 20 */
.long USB_Handler /* 21 */
.long PCM_Handler /* 22 */
.long SRC_IN_Handler /* 23 */
.long SRC_OUT_Handler /* 24 */
.long VBUS_Handler /* 25 */
.long DMA_Handler /* 26 */
.long RF_DIAG_Handler /* 27 */
.long TRNG_Handler /* 28 */
.long DCDC_Handler /* 29 */
.long XTAL16RDY_Handler /* 30 */
.long RESERVED31_Handler /* 31 */
.size __isr_vector, . - __isr_vector
/*
* Patch Table
* Notice: it crosses the 0x100 boundary
* in cached mode, the first entries will be copied to
* (and accessed from) RAM and others will only lie on
* QSPI flash or OTP.
*
* In C declare: extern uint32_t __patch_table_start[];
*/
.section .patch_table, "a"
.align 4
.globl __patch_table_start
__patch_table_start:
/*
* 28 32-bit entries, initialized to "pointer to Default_Patch_Code"
*
* NOTE: we assume that SYS_CTRL_REG.REMAP_INTVECT == 1
*/
.long Default_Patch_Code_Handler /* 0, in RAM */
.long Default_Patch_Code_Handler /* 1, in RAM */
.long Default_Patch_Code_Handler /* 2, in RAM */
.long Default_Patch_Code_Handler /* 3, in RAM */
.long Default_Patch_Code_Handler /* 4, in RAM */
.long Default_Patch_Code_Handler /* 5, in RAM */
.long Default_Patch_Code_Handler /* 6, in RAM */
.long Default_Patch_Code_Handler /* 7, in RAM */
.long Default_Patch_Code_Handler /* 8, in RAM */
.long Default_Patch_Code_Handler /* 9, in RAM */
.long Default_Patch_Code_Handler /* 10, in RAM */
.long Default_Patch_Code_Handler /* 11, in RAM */
/*
* Chip version: AD
* Entries 12, 13, 14 and 15 are unusable and skipped in the QSPI image,
* to account for the overhead of the QSPI header (16 bytes).
*
* Chip version: AA, AC, AE
* Entries 14 and 15 are unusable and skipped in the QSPI image,
* to account for the overhead of the QSPI header (8 bytes).
*
* The mkimage tool is responsible for stripping the proper entries from the QSPI image.
*/
.long Default_Patch_Code_Handler /* 12 */
.long Default_Patch_Code_Handler /* 13 */
.long 0xDEADBEEF /* 14 */
.long 0xDEADBEEF /* 15 */
.size __patch_table_start, . - __patch_table_start
__patch_table_end:
.section .default_patch_code_handler_section, "a"
.globl Default_Patch_Code_Handler
.align 1
.thumb
.thumb_func
.type Default_Patch_Code_Handler, %function
Default_Patch_Code_Handler:
bkpt #0
bkpt #0
@@ -1,118 +0,0 @@
/**
\addtogroup INTERFACES
\{
\addtogroup FTDF
\{
*/
/**
****************************************************************************************
*
* @file ad_ftdf_config.h
*
* @brief FTDF Adapter API
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 AD_FTDF_CONFIG_H
#define AD_FTDF_CONFIG_H
#ifndef FTDF_PHY_API
#include "queue.h"
#endif
#include "ftdf.h"
/**
* \brief Sleep When Idle
*
* If set, the block will sleep when Idle
*
*/
#define AD_FTDF_SLEEP_WHEN_IDLE 1
/**
* \brief Idle Timeout
*
* Idle Timeout, in OS scheduler ticks, after which, if still Idle, FTDF will
* be put to sleep. Only applicable if AD_FTDF_SLEEP_WHEN_IDLE 1
*
*/
#define AD_FTDF_IDLE_TIMEOUT 1
/**
* \brief UP Queue size
*
* Defines the UP (UMAC to client app) Queue length, in number of messages
*
*/
#define AD_FTDF_UP_QUEUE_LENGTH 16
/**
* \brief DOWN Queue size
*
* Defines the DOWN (client app to UMAC) Queue length, in number of messages
*
*/
#define AD_FTDF_DOWN_QUEUE_LENGTH 16
/**
* \brief Low Power Clock cycle
*
* Defines the Low Power clock cycle in pico secs. Used for computation needed
* for sleeping / waking up FTDF
*
*/
#define AD_FTDF_LP_CLOCK_CYCLE 30517578
/**
* \brief Wake Up Latency
*
* Defines the Wake Up Latency expressed in Low Power clock cycles, that is
* the number of LP clock cycles needed for the FTDF to be fully operational
* (calculations and FTDF timer synchronization)
*
*/
#define AD_FTDF_WUP_LATENCY 10
/**
* \brief Sleep value compensation
*
* Defines the sleep value compensation expressed in microseconds. This value
* is subtracted from the sleep time returned by ftdf_can_sleep()
*/
#define AD_FTDF_SLEEP_COMPENSATION 1500
#endif /* AD_FTDF_CONFIG_H */
/**
\}
\}
\}
*/
@@ -1,143 +0,0 @@
/**
\addtogroup INTERFACES
\{
\addtogroup FTDF
\{
*/
/**
****************************************************************************************
*
* @file ad_ftdf_phy_api.h
*
* @brief FTDF PHY Adapter API
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 AD_FTDF_PHY_API_H
#define AD_FTDF_PHY_API_H
#include "ftdf.h"
#include "ad_ftdf_config.h"
/**
* \brief Initialize adapter - create queues
*
*/
void ad_ftdf_init(void);
/**
* \brief Set Extended Address
*
* Sets interface extended address. This is thread safe.
*
* \param[in] address - The extended address to set
*/
void ad_ftdf_set_ext_address(ftdf_ext_address_t address);
/**
* \brief Get Extended Address
*
* Gets interface extended address. This is thread safe.
*
* \returns The extended address of the interface
*/
ftdf_ext_address_t ad_ftdf_get_ext_address(void);
/**
* \brief Transmits a frame
*
* Transmits a frame. Params:
*
* \param[in] frame_length - The total length of the frame passed in bytes
* \param[in] frame - a pointer to the passed frame buffer
* \param[in] channel - The channel to use for transmission in [11, 26]
* \param[in] csma_suppress - If true, csma protocol (i.e. CCA) will not be performed
* \param[in] pti - Packet Traffic Information that will be used for this transaction.
*/
ftdf_status_t ad_ftdf_send_frame_simple(ftdf_data_length_t frame_length,
ftdf_octet_t* frame,
ftdf_channel_number_t channel,
ftdf_pti_t pti,
ftdf_boolean_t csma_suppress);
/**
* \brief Instructs the MAC and PHY to go to sleep
*
* \param[in] allow_deferred_sleep - If true, then if the MAC cannot go to sleep immediately
* (e.g. a transmission is pending), the MAC will go to sleep
* as soon as possible. If false, and the MAC cannot go to sleep
* immediately, sleep will be aborted.
*/
void ad_ftdf_sleep_when_possible(ftdf_boolean_t allow_deferred_sleep);
/**
* \brief Instructs the MAC and PHY to wakeup, if sleeping
*
*/
void ad_ftdf_wake_up(void);
#if FTDF_DBG_BUS_ENABLE
/**
* \brief Configures GPIO pins for the FTDF debug bus
*
* if FTDF_DBG_BUS_USE_PORT_4 == 0, the FTDF debug bus uses the following (fixed) GPIO pins,
*
* bit 0: HW_GPIO_PORT_1, HW_GPIO_PIN_4
* bit 1: HW_GPIO_PORT_1, HW_GPIO_PIN_5
* bit 2: HW_GPIO_PORT_1, HW_GPIO_PIN_6
* bit 3: HW_GPIO_PORT_1, HW_GPIO_PIN_7
* bit 4: HW_GPIO_PORT_0, HW_GPIO_PIN_6
* bit 5: HW_GPIO_PORT_0, HW_GPIO_PIN_7
* bit 6: HW_GPIO_PORT_1, HW_GPIO_PIN_3
* bit 7: HW_GPIO_PORT_2, HW_GPIO_PIN_3
*
* if FTDF_DBG_BUS_USE_PORT_4 == 1, the FTDF debug bus uses the following pins:
*
* bit 0: HW_GPIO_PORT_4, HW_GPIO_PIN_0
* bit 1: HW_GPIO_PORT_4, HW_GPIO_PIN_1
* bit 2: HW_GPIO_PORT_4, HW_GPIO_PIN_2
* bit 3: HW_GPIO_PORT_4, HW_GPIO_PIN_3
* bit 4: HW_GPIO_PORT_4, HW_GPIO_PIN_4
* bit 5: HW_GPIO_PORT_4, HW_GPIO_PIN_5
* bit 6: HW_GPIO_PORT_4, HW_GPIO_PIN_6
* bit 7: HW_GPIO_PORT_4, HW_GPIO_PIN_7
*
*/
void ad_ftdf_dbg_bus_gpio_config(void);
#endif /* FTDF_DBG_BUS_ENABLE */
#endif /* AD_FTDF_PHY_API_H */
/**
\}
\}
\}
*/
File diff suppressed because it is too large Load Diff
@@ -1,192 +0,0 @@
/**
****************************************************************************************
*
* @file ftdf_config_phy_api.h
*
* @brief FTDF PHY API configuration template file
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 FTDF_CONFIG_PHY_API_H_
#define FTDF_CONFIG_PHY_API_H_
#include "osal.h" // OS_FREERTOS macro is checked within the header file.
/**
* \remark phy configuration values in microseconds
*/
#define FTDF_PHYTXSTARTUP 0x4c
#define FTDF_PHYTXLATENCY 0x02
#define FTDF_PHYTXFINISH 0x00
#define FTDF_PHYTRXWAIT 0x22
#define FTDF_PHYRXSTARTUP 0x54
#define FTDF_PHYRXLATENCY 0
#define FTDF_PHYENABLE 0x20
#ifndef FTDF_LITE
#define FTDF_LITE
#endif
/**
* \remark See FTDF_GET_MSG_BUFFER in ftdf.h
*/
#define FTDF_GET_MSG_BUFFER ad_ftdf_get_msg_buffer
/**
* \remark See FTDF_REL_MSG_BUFFER in ftdf.h
*/
#define FTDF_REL_MSG_BUFFER ad_ftdf_rel_msg_buffer
/**
* \remark See FTDF_REC_MSG in ftdf.h
*/
#define FTDF_RCV_MSG ad_ftdf_rcv_msg
/**
* \remark See FTDF_GET_DATA_BUFFER in ftdf.h
*/
#define FTDF_GET_DATA_BUFFER ad_ftdf_get_data_buffer
/**
* \remark See FTDF_REL_DATA_BUFFER in ftdf.h
*/
#define FTDF_REL_DATA_BUFFER ad_ftdf_rel_data_buffer
/**
* \remark See FTDF_GET_EXT_ADDRESS in ftdf.h
*/
#define FTDF_GET_EXT_ADDRESS ad_ftdf_get_ext_address
/**
* \remark See FTDF_RCV_FRAME_TRANSPARENT in ftdf.h
*/
#define FTDF_RCV_FRAME_TRANSPARENT ftdf_rcv_frame_transparent
/**
* \remark See FTDF_SEND_FRAME_TRANSPARENT_CONFIRM in ftdf.h
*/
#define FTDF_SEND_FRAME_TRANSPARENT_CONFIRM ftdf_send_frame_transparent_confirm
/**
* \remark See FTDF_WAKE_UP_READY in ftdf.h
*/
#define FTDF_WAKE_UP_READY ad_ftdf_wake_up_ready
/**
* \remark See FTDF_SLEEP_CALLBACK in ftdf.h
*/
#define FTDF_SLEEP_CALLBACK ad_ftdf_sleep_cb
/* Forward declaration */
void sleep_when_possible(uint8_t explicit_request, uint32_t sleep_time);
#define FTDF_LMACREADY4SLEEP_CB sleep_when_possible
#ifndef OS_FREERTOS
#define portDISABLE_INTERRUPTS() \
do { \
__asm volatile (" cpsid i "); \
DBG_CONFIGURE_HIGH(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION); \
} while (0)
#define portENABLE_INTERRUPTS() \
do { \
DBG_CONFIGURE_LOW(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION); \
__asm volatile (" cpsie i "); \
} while (0)
void vPortEnterCritical(void);
void vPortExitCritical(void);
#define OS_ENTER_CRITICAL_SECTION vPortEnterCritical
#define OS_LEAVE_CRITICAL_SECTION vPortExitCritical
#endif
/**
* \remark Critical section
*/
#define ftdf_critical_var( )
#define ftdf_enter_critical( ) OS_ENTER_CRITICAL_SECTION()
#define ftdf_exit_critical( ) OS_LEAVE_CRITICAL_SECTION()
#ifndef FTDF_DBG_BUS_ENABLE
/**
* \brief Whether FTDF debug bus will be available or not.
*
* Define to 0 for production software.
*
* Refer to \ref ad_ftdf_dbgBusGpioConfig for the GPIO pins used for the debug bus.
*/
#define FTDF_DBG_BUS_ENABLE 0
#endif
#if FTDF_DBG_BUS_ENABLE
#define FTDF_DBG_BUS_GPIO_CONFIG ad_ftdf_dbg_bus_gpio_config
#ifndef FTDF_DBG_BUS_USE_GPIO_P1_3_P2_2
/**
* \brief Enables FTDF diagnostics on diagnostic pins 6 and 7 on GPIO P1_3 and P2_3.
*
* When enabled, UART must use pins other than the default P1_3, P2_3.
*/
#define FTDF_DBG_BUS_USE_GPIO_P1_3_P2_2 (0)
#endif
#ifndef FTDF_DBG_BUS_USE_SWDIO_PIN
/**
* \brief Enables diagnostics on diagnostic pin 4 on GPIO P0_6.
*
* When enabled, the debugger must be disabled since SWD uses the same pin for SWDIO.
*/
#define FTDF_DBG_BUS_USE_SWDIO_PIN (0)
#endif
#ifndef FTDF_DBG_BUS_USE_PORT_4
/**
* \brief Uses Port 4 (instead of GPIOs at Ports 0, 1 and 2) for diagnostics
*
* When enabled, FTDF diagnostics pins uses P4_0 to P4_7
*/
#define FTDF_DBG_BUS_USE_PORT_4 (0)
#endif
#endif /* FTDF_DBG_BUS_ENABLE */
#ifndef FTDF_USE_AUTO_PTI
#define FTDF_USE_AUTO_PTI 0
#endif
#ifndef FTDF_USE_FP_PROCESSING_RAM
/**
* \brief Whether to use HW acceleration for indirect sending.
*
*/
#define FTDF_USE_FP_PROCESSING_RAM 1
#endif /* FTDF_USE_FP_PROCESSING_RAM */
#endif /* FTDF_CONFIG_PHY_API_H_ */
@@ -1,341 +0,0 @@
/**
****************************************************************************************
*
* @file ad_ftdf.c
*
* @brief FTDF FreeRTOS Adapter
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#ifdef CONFIG_USE_FTDF
#include <string.h>
#include <stdbool.h>
#ifndef FTDF_PHY_API
#include "osal.h"
#include "queue.h"
#include "sys_power_mgr.h"
#endif
#if dg_configRF_ADAPTER
#include "ad_rf.h"
#else
#include "hw_rf.h"
#endif
#include "sys_tcs.h"
#include "sdk_defs.h"
#include "ad_ftdf.h"
#include "internal.h"
#if FTDF_DBG_BUS_ENABLE
#include "hw_gpio.h"
#endif /* FTDF_DBG_BUS_ENABLE */
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
#include "hw_gpio.h"
#endif
#if dg_configUSE_FTDF_DDPHY == 1
#include "radio.h"
#endif
#define WUP_LATENCY (AD_FTDF_LP_CLOCK_CYCLE * AD_FTDF_WUP_LATENCY)
#ifdef FTDF_PHY_API
#ifndef PRIVILEGED_DATA
#define PRIVILEGED_DATA __attribute__((section("privileged_data_zi")))
#endif
#ifndef INITIALIZED_PRIVILEGED_DATA
#define INITIALIZED_PRIVILEGED_DATA __attribute__((section("privileged_data_init")))
#endif
#endif
PRIVILEGED_DATA ftdf_boolean_t explicit_sleep; /* = FTDF_FALSE; */
PRIVILEGED_DATA sleep_status_t sleep_status;
PRIVILEGED_DATA ftdf_ext_address_t u_ext_address;
static void ad_ftdf_sleep(void)
{
ftdf_critical_var();
ftdf_enter_critical();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP); // go sleep
ftdf_exit_critical();
// don't go-go before I sleep
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_DOWN) == 0x0) {
}
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
hw_gpio_set_inactive(FTDF_DBG_BLOCK_SLEEP_GPIO_PORT, FTDF_DBG_BLOCK_SLEEP_GPIO_PIN);
#endif
}
void ad_ftdf_wake_up_internal(bool sync)
{
if ( sleep_status != BLOCK_SLEEPING ) {
return;
}
ftdf_critical_var();
ftdf_enter_critical();
/* Wake up power domains */
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP); // go wake up
ftdf_exit_critical();
// don't go-go before I sleep
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP) == 0x0) {
}
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
hw_gpio_configure_pin(FTDF_DBG_BLOCK_SLEEP_GPIO_PORT, FTDF_DBG_BLOCK_SLEEP_GPIO_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, true);
#endif
/* Power on and configure RF */
#if dg_configRF_ADAPTER
ad_rf_request_on(false);
#else
hw_rf_request_on(false);
#endif
/* Apply trim values */
sys_tcs_apply(tcs_ftdf);
#if dg_configRF_ADAPTER
ad_rf_request_recommended_settings();
#else
hw_rf_request_recommended_settings();
#endif
if (sync) {
ftdf_init_lmac( );
sleep_status = BLOCK_ACTIVE;
} else {
/* Wake up FTDF block */
sleep_status = BLOCK_WAKING_UP;
ftdf_wakeup();
#if defined(FTDF_NO_CSL) && defined(FTDF_NO_TSCH)
ad_ftdf_wake_up_ready();
#endif
}
}
void ad_ftdf_wake_up_async(void)
{
ad_ftdf_wake_up_internal(false);
}
void ad_ftdf_wake_up_sync(void)
{
ad_ftdf_wake_up_internal(true);
}
void sleep_when_possible(uint8_t explicit_request, uint32_t sleep_time )
{
ftdf_boolean_t block_sleep = FTDF_FALSE;
if ((!AD_FTDF_SLEEP_WHEN_IDLE && !explicit_request) || sleep_status != BLOCK_ACTIVE) {
return;
}
ftdf_usec_t us;
ftdf_critical_var();
ftdf_enter_critical();
#ifdef FTDF_PHY_API
if (explicit_request && (REG_GETF(FTDF, FTDF_LMAC_CONTROL_STATUS_REG, LMACREADY4SLEEP) == 0)) {
/* clear a previous interrupt */
FTDF->FTDF_LMAC_CONTROL_DELTA_REG = REG_MSK(FTDF, FTDF_LMAC_CONTROL_DELTA_REG, LMACREADY4SLEEP_D);
/* Enable (unmask) interrupt */
REG_SET_BIT(FTDF, FTDF_LMAC_CONTROL_MASK_REG, LMACREADY4SLEEP_M);
us = 0;
} else {
us = ftdf_can_sleep();
}
#else
us = ftdf_can_sleep();
#endif
/* Try to sleep as much as needed (if sleep_time is 0, then sleep as much as possible).
* Otherwise, sleep as much as possible. */
if ( explicit_request == FTDF_TRUE ) {
if (sleep_time && us > sleep_time)
us = sleep_time;
}
if (us > ( WUP_LATENCY / 1000000) + AD_FTDF_SLEEP_COMPENSATION) {
// Subtract sleep compensation from the sleep time, compensating for delays
us -= AD_FTDF_SLEEP_COMPENSATION;
block_sleep = ftdf_prepare_for_sleep(us);
if (block_sleep) {
// FTDF ready to sleep, disable clocks
sleep_status = BLOCK_SLEEPING;
explicit_sleep = explicit_request;
#if FTDF_USE_SLEEP_DURING_BACKOFF
ftdf_sdb_fsm_sleep();
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
#if dg_configUSE_FTDF_DDPHY == 1
ftdf_ddphy_save();
#endif /* dg_configUSE_FTDF_DDPHY */
ad_ftdf_sleep();
} else {
#if FTDF_USE_SLEEP_DURING_BACKOFF
ftdf_sdb_fsm_abort_sleep();
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
}
}
ftdf_exit_critical();
if (block_sleep) {
#if dg_configRF_ADAPTER
ad_rf_request_off(false);
#else
hw_rf_request_off(false);
#endif
}
}
/**
* @brief Initialization function of FTDF adapter
*/
void ad_ftdf_init(void)
{
/* Wake up power domains */
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP); // go wake up
GLOBAL_INT_RESTORE();
// don't go-go before I sleep
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP) == 0x0) {
}
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
hw_gpio_configure_pin(FTDF_DBG_BLOCK_SLEEP_GPIO_PORT, FTDF_DBG_BLOCK_SLEEP_GPIO_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, true);
#endif
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_ENABLE); // on
REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_DIV, 0); // divide by 1
GLOBAL_INT_RESTORE();
/* Power on and configure RF */
#if dg_configRF_ADAPTER
ad_rf_request_on(false);
#else
hw_rf_request_on(false);
#endif
/* Apply trim values */
sys_tcs_apply(tcs_ftdf);
#if dg_configRF_ADAPTER
ad_rf_request_recommended_settings();
#else
hw_rf_request_recommended_settings();
#endif
ftdf_set_sleep_attributes( AD_FTDF_LP_CLOCK_CYCLE, AD_FTDF_WUP_LATENCY );
#ifdef FTDF_PHY_API
ad_ftdf_init_phy_api();
#else
ad_ftdf_init_mac_api();
#endif
}
void ad_ftdf_sleep_cb(ftdf_usec_t sleep_time )
{
sleep_when_possible( FTDF_TRUE, sleep_time );
}
#if FTDF_DBG_BUS_ENABLE
void ad_ftdf_dbg_bus_gpio_config(void)
{
#if FTDF_DBG_BUS_USE_PORT_4 == 1
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_0, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_1, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_2, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_4, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_5, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_6, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_4, HW_GPIO_PIN_7, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#else
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_4, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_5, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_6, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_7, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#if FTDF_DBG_BUS_USE_SWDIO_PIN
/*
* Note that this pin has a conflict with SWD. Disable the debugger in order to use this
* pin.
*/
hw_gpio_set_pin_function(HW_GPIO_PORT_0, HW_GPIO_PIN_6, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#endif
hw_gpio_set_pin_function(HW_GPIO_PORT_0, HW_GPIO_PIN_7, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#if FTDF_DBG_BUS_USE_GPIO_P1_3_P2_2
/*
* Note that these pins have a conflict with the pins used for UART by default. Configure
* UART on different pins if you would like to use the pins below for diagnostics.
*/
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#endif
#endif /* FTDF_DBG_BUS_USE_PORT_4 == 1 */
}
#endif /* FTDF_DBG_BUS_ENABLE */
#endif
@@ -1,94 +0,0 @@
/**
\addtogroup INTERFACES
\{
\addtogroup FTDF
\{
*/
/**
****************************************************************************************
*
* @file ad_ftdf.h
*
* @brief FTDF Adapter internal header file
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 AD_FTDF_H
#define AD_FTDF_H
#ifndef FTDF_PHY_API
#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"
#endif
#include "ftdf.h"
#include "ad_ftdf_config.h"
typedef enum {
BLOCK_ACTIVE = 0, BLOCK_SLEEPING, BLOCK_WAKING_UP
} sleep_status_t;
extern sleep_status_t sleep_status;
extern ftdf_ext_address_t u_ext_address;
extern ftdf_boolean_t explicit_sleep;
void ad_ftdf_init_mac_api(void);
void ad_ftdf_init_phy_api(void);
void ad_ftdf_wake_up_async(void);
void ad_ftdf_wake_up_sync(void);
void sleep_when_possible( uint8_t explicit_request, uint32_t sleep_time );
#if FTDF_DBG_BUS_ENABLE
/**
* \brief Configures GPIO pins for the FTDF debug bus
*
* Debug bus uses the following (fixed) GPIO pins:
*
* bit 0: HW_GPIO_PORT_1, HW_GPIO_PIN_4
* bit 1: HW_GPIO_PORT_1, HW_GPIO_PIN_5
* bit 2: HW_GPIO_PORT_1, HW_GPIO_PIN_6
* bit 3: HW_GPIO_PORT_1, HW_GPIO_PIN_7
* bit 4: HW_GPIO_PORT_0, HW_GPIO_PIN_6
* bit 5: HW_GPIO_PORT_0, HW_GPIO_PIN_7
* bit 6: HW_GPIO_PORT_1, HW_GPIO_PIN_3
* bit 7: HW_GPIO_PORT_2, HW_GPIO_PIN_3
*/
void ad_ftdf_dbg_bus_gpio_config(void);
#endif /* FTDF_DBG_BUS_ENABLE */
#endif /* AD_FTDF_H */
/**
\}
\}
\}
*/
@@ -1,164 +0,0 @@
/**
****************************************************************************************
*
* @file ad_ftdf_phy_api.c
*
* @brief FTDF FreeRTOS Adapter
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#ifdef CONFIG_USE_FTDF
#ifdef FTDF_PHY_API
#include <string.h>
#include <stdbool.h>
#include "sdk_defs.h"
#include "ad_ftdf.h"
#include "ad_ftdf_phy_api.h"
#include "internal.h"
#if FTDF_DBG_BUS_ENABLE
#include "hw_gpio.h"
#endif /* FTDF_DBG_BUS_ENABLE */
#ifndef OS_FREERTOS
static unsigned long uxCriticalNesting = 0xaaaaaaaa;
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
__asm volatile( "dsb" );
__asm volatile( "isb" );
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
uxCriticalNesting--;
if ( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
#endif /* !OS_FREERTOS */
/**
* @brief ftdf_gen_irq interrupt service routine
*/
void FTDF_GEN_Handler( void)
{
ftdf_confirm_lmac_interrupt();
ftdf_event_handler();
}
/**
* @brief ftdf_wakup_irq interrupt service routine
*/
void FTDF_WAKEUP_Handler( void)
{
ad_ftdf_wake_up_async();
}
void ad_ftdf_set_ext_address( ftdf_ext_address_t address)
{
u_ext_address = address;
}
ftdf_ext_address_t ad_ftdf_get_ext_address( void)
{
return u_ext_address;
}
void ad_ftdf_wake_up_ready( void)
{
}
ftdf_status_t ad_ftdf_send_frame_simple( ftdf_data_length_t frameLength,
ftdf_octet_t *frame,
ftdf_channel_number_t channel,
ftdf_pti_t pti,
ftdf_boolean_t csmaSuppress)
{
ftdf_critical_var();
ftdf_enter_critical();
if (ftdf_tx_in_progress == FTDF_TRUE) {
ftdf_exit_critical();
return FTDF_TRANSPARENT_OVERFLOW;
}
ftdf_tx_in_progress = FTDF_TRUE;
ftdf_exit_critical();
if (sleep_status == BLOCK_SLEEPING) {
/* Wake-up the block */
ad_ftdf_wake_up_async();
#if FTDF_DBG_BUS_ENABLE
ftdf_check_dbg_mode();
#endif /* FTDF_DBG_BUS_ENABLE */
sleep_status = BLOCK_ACTIVE;
}
return ftdf_send_frame_simple(frameLength, frame, channel, pti, csmaSuppress);
}
void ad_ftdf_sleep_when_possible( ftdf_boolean_t allow_deferred_sleep)
{
sleep_when_possible(allow_deferred_sleep, 0);
}
void ad_ftdf_wake_up(void)
{
if (sleep_status == BLOCK_SLEEPING) {
/* Wake-up the block */
ad_ftdf_wake_up_async();
#if FTDF_DBG_BUS_ENABLE
ftdf_check_dbg_mode();
#endif /* FTDF_DBG_BUS_ENABLE */
sleep_status = BLOCK_ACTIVE;
}
}
void ad_ftdf_init_phy_api(void)
{
NVIC_ClearPendingIRQ(FTDF_WAKEUP_IRQn);
NVIC_EnableIRQ(FTDF_WAKEUP_IRQn);
NVIC_ClearPendingIRQ(FTDF_GEN_IRQn);
NVIC_EnableIRQ(FTDF_GEN_IRQn);
sleep_status = BLOCK_ACTIVE;
#ifndef OS_FREERTOS
uxCriticalNesting = 0;
#endif
ftdf_reset(1);
}
#endif /* FTDF_PHY_API */
#endif
File diff suppressed because it is too large Load Diff
-621
View File
@@ -1,621 +0,0 @@
/**
****************************************************************************************
*
* @file data.c
*
* @brief FTDF data send/receive functions
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 <stdlib.h>
#include <ftdf.h>
#include "internal.h"
#ifdef CONFIG_USE_FTDF
#ifndef FTDF_LITE
void ftdf_process_data_request(ftdf_data_request_t *data_request)
{
#ifndef FTDF_NO_TSCH
if (ftdf_pib.tsch_enabled && ftdf_tsch_slot_link->request != data_request) {
ftdf_status_t status;
if ((data_request->dst_addr_mode == FTDF_SHORT_ADDRESS) && !data_request->indirect_tx) {
status = ftdf_schedule_tsch((ftdf_msg_buffer_t*) data_request);
if (status == FTDF_SUCCESS) {
return;
}
} else {
status = FTDF_INVALID_PARAMETER;
}
ftdf_send_data_confirm(data_request, status, 0, 0, 0, NULL);
return;
}
#endif /* FTDF_NO_TSCH */
int queue;
ftdf_address_mode_t dst_addr_mode = data_request->dst_addr_mode;
ftdf_pan_id_t dst_pan_id = data_request->dst_pan_id;
ftdf_address_t dst_addr = data_request->dst_addr;
/* Search for an existing indirect queue */
for (queue = 0; queue < FTDF_NR_OF_REQ_BUFFERS; queue++) {
if (dst_addr_mode == FTDF_SHORT_ADDRESS) {
if ((ftdf_tx_pending_list[queue].addr_mode == dst_addr_mode) &&
(ftdf_tx_pending_list[queue].addr.short_address == dst_addr.short_address)) {
break;
}
} else if (dst_addr_mode == FTDF_EXTENDED_ADDRESS) {
if ((ftdf_tx_pending_list[queue].addr_mode == dst_addr_mode) &&
(ftdf_tx_pending_list[queue].addr.ext_address == dst_addr.ext_address)) {
break;
}
}
}
if (data_request->indirect_tx) {
ftdf_status_t status = FTDF_SUCCESS;
if (queue < FTDF_NR_OF_REQ_BUFFERS) {
/* Queue request in existing queue */
status = ftdf_queue_req_head((ftdf_msg_buffer_t*) data_request,
&ftdf_tx_pending_list[queue].queue);
if (status == FTDF_SUCCESS) {
ftdf_add_tx_pending_timer((ftdf_msg_buffer_t*) data_request, queue,
(ftdf_pib.transaction_persistence_time *
FTDF_BASE_SUPERFRAME_DURATION),
ftdf_send_transaction_expired);
return;
}
}
if ((dst_addr_mode != FTDF_EXTENDED_ADDRESS) && (dst_addr_mode != FTDF_SHORT_ADDRESS)) {
status = FTDF_INVALID_PARAMETER;
}
if (status != FTDF_SUCCESS) {
/* Queueing of indirect transfer was not successful */
ftdf_send_data_confirm(data_request, status, 0, 0, 0, NULL);
return;
}
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
uint8_t entry, short_addr_idx;
if (dst_addr_mode == FTDF_SHORT_ADDRESS) {
if (ftdf_fppr_get_free_short_address(&entry, &short_addr_idx) == FTDF_FALSE) {
goto transaction_overflow;
}
} else if (dst_addr_mode == FTDF_EXTENDED_ADDRESS) {
if (ftdf_fppr_get_free_ext_address(&entry) == FTDF_FALSE) {
goto transaction_overflow;
}
} else {
status = FTDF_INVALID_PARAMETER;
}
#endif
/* Search for an empty indirect queue */
for (queue = 0; queue < FTDF_NR_OF_REQ_BUFFERS; queue++) {
if (ftdf_tx_pending_list[queue].addr_mode == FTDF_NO_ADDRESS) {
ftdf_tx_pending_list[queue].addr_mode = dst_addr_mode;
ftdf_tx_pending_list[queue].pan_id = dst_pan_id;
ftdf_tx_pending_list[queue].addr = dst_addr;
status = ftdf_queue_req_head((ftdf_msg_buffer_t*) data_request,
&ftdf_tx_pending_list[queue].queue);
if (status == FTDF_SUCCESS) {
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
if (dst_addr_mode == FTDF_SHORT_ADDRESS) {
ftdf_fppr_set_short_address(entry, short_addr_idx, dst_addr.short_address);
ftdf_fppr_set_short_address_valid(entry, short_addr_idx, FTDF_TRUE);
} else if (dst_addr_mode == FTDF_EXTENDED_ADDRESS) {
ftdf_fppr_set_ext_address(entry, dst_addr.short_address);
ftdf_fppr_set_ext_address_valid(entry, FTDF_TRUE);
} else {
ASSERT_WARNING(0);
}
#endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */
ftdf_add_tx_pending_timer((ftdf_msg_buffer_t*) data_request,
queue,
(ftdf_pib.transaction_persistence_time *
FTDF_BASE_SUPERFRAME_DURATION),
ftdf_send_transaction_expired);
return;
} else {
break;
}
}
}
/* Did not find an existing or an empty queue */
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
transaction_overflow:
#endif
ftdf_send_data_confirm(data_request, FTDF_TRANSACTION_OVERFLOW, 0, 0, 0, NULL);
return;
}
if (ftdf_req_current == NULL) {
ftdf_req_current = (ftdf_msg_buffer_t*) data_request;
} else {
if (ftdf_queue_req_head((ftdf_msg_buffer_t*) data_request, &ftdf_req_queue) ==
FTDF_TRANSACTION_OVERFLOW) {
ftdf_send_data_confirm(data_request, FTDF_TRANSACTION_OVERFLOW, 0, 0, 0, NULL);
}
return;
}
ftdf_frame_header_t *frame_header = &ftdf_fh;
ftdf_security_header *security_header = &ftdf_sh;
frame_header->frame_type = data_request->send_multi_purpose ? FTDF_MULTIPURPOSE_FRAME : FTDF_DATA_FRAME;
ftdf_boolean_t frame_pending;
if (queue < FTDF_NR_OF_REQ_BUFFERS) {
frame_pending = FTDF_TRUE;
} else {
frame_pending = FTDF_FALSE;
}
frame_header->options =
(data_request->security_level > 0 ? FTDF_OPT_SECURITY_ENABLED : 0) |
(data_request->ack_tx ? FTDF_OPT_ACK_REQUESTED : 0) |
(frame_pending ? FTDF_OPT_FRAME_PENDING : 0) |
((data_request->frame_control_options & FTDF_PAN_ID_PRESENT) ? FTDF_OPT_PAN_ID_PRESENT : 0) |
((data_request->frame_control_options & FTDF_IES_INCLUDED) ? FTDF_OPT_IES_PRESENT : 0) |
((data_request->frame_control_options & FTDF_SEQ_NR_SUPPRESSED) ? FTDF_OPT_SEQ_NR_SUPPRESSED : 0);
if (ftdf_pib.le_enabled || ftdf_pib.tsch_enabled) {
frame_header->options |= FTDF_OPT_ENHANCED;
}
frame_header->src_addr_mode = data_request->src_addr_mode;
frame_header->src_pan_id = ftdf_pib.pan_id;
frame_header->dst_addr_mode = data_request->dst_addr_mode;
frame_header->dst_pan_id = data_request->dst_pan_id;
frame_header->dst_addr = data_request->dst_addr;
security_header->security_level = data_request->security_level;
security_header->key_id_mode = data_request->key_id_mode;
security_header->key_index = data_request->key_index;
security_header->key_source = data_request->key_source;
security_header->frame_counter = ftdf_pib.frame_counter;
security_header->frame_counter_mode = ftdf_pib.frame_counter_mode;
#ifndef FTDF_NO_TSCH
if (ftdf_pib.tsch_enabled) {
frame_header->sn = ftdf_process_tsch_sn((ftdf_msg_buffer_t*)data_request,
ftdf_pib.dsn,
&data_request->requestSN);
} else
#endif /* FTDF_NO_TSCH */
{
frame_header->sn = ftdf_pib.dsn;
}
ftdf_octet_t *tx_ptr = (ftdf_octet_t*) &FTDF->FTDF_TX_FIFO_0_0_REG +
(FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
/* Skip PHY header (= MAC length) */
tx_ptr++;
ftdf_data_length_t msdu_length = data_request->msdu_length;
tx_ptr = ftdf_add_frame_header(tx_ptr, frame_header, msdu_length);
tx_ptr = ftdf_add_security_header(tx_ptr, security_header);
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
if (data_request->frame_control_options & FTDF_IES_INCLUDED) {
tx_ptr = ftdf_add_ies(tx_ptr,
data_request->header_ie_list,
data_request->payload_ie_list,
data_request->msdu_length);
}
#endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */
ftdf_status_t status = ftdf_send_frame(ftdf_pib.current_channel,
frame_header,
security_header,
tx_ptr,
data_request->msdu_length,
data_request->msdu);
if (status != FTDF_SUCCESS) {
ftdf_send_data_confirm(data_request, status, 0, 0, 0, NULL);
ftdf_req_current = NULL;
return;
}
ftdf_nr_of_retries = 0;
if (frame_header->sn == ftdf_pib.dsn) {
ftdf_pib.dsn++;
}
}
void ftdf_send_data_confirm(ftdf_data_request_t *data_request,
ftdf_status_t status,
ftdf_time_t timestamp,
ftdf_sn_t dsn,
ftdf_num_of_backoffs_t num_of_backoffs,
ftdf_ie_list_t *ack_payload)
{
FTDF_REL_DATA_BUFFER(data_request->msdu);
ftdf_data_confirm_t *data_confirm =
(ftdf_data_confirm_t*) FTDF_GET_MSG_BUFFER(sizeof(ftdf_data_confirm_t));
data_confirm->msg_id = FTDF_DATA_CONFIRM;
data_confirm->msdu_handle = data_request->msdu_handle;
data_confirm->status = status;
data_confirm->timestamp = timestamp;
data_confirm->num_of_backoffs = num_of_backoffs;
data_confirm->dsn = dsn;
data_confirm->ack_payload = ack_payload;
if (ftdf_req_current == (ftdf_msg_buffer_t*)data_request) {
ftdf_req_current = NULL;
}
FTDF_REL_MSG_BUFFER((ftdf_msg_buffer_t*) data_request);
FTDF_RCV_MSG((ftdf_msg_buffer_t*) data_confirm);
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
ftdf_fp_fsm_clear_pending();
#endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */
ftdf_process_next_request();
}
void ftdf_send_data_indication(ftdf_frame_header_t *frame_header,
ftdf_security_header *security_header,
ftdf_ie_list_t *payload_ie_list,
ftdf_data_length_t msdu_length,
ftdf_octet_t *msdu,
ftdf_link_quality_t mpdu_link_quality,
ftdf_time_t timestamp)
{
ftdf_data_indication_t *data_indication =
(ftdf_data_indication_t*) FTDF_GET_MSG_BUFFER(sizeof(ftdf_data_indication_t));
ftdf_octet_t *msdu_buf = FTDF_GET_DATA_BUFFER(msdu_length);
ftdf_octet_t *buf_ptr = msdu_buf;
int n;
for (n = 0; n < msdu_length; n++) {
*msdu_buf++ = *msdu++;
}
data_indication->msg_id = FTDF_DATA_INDICATION;
data_indication->src_addr_mode = frame_header->src_addr_mode;
data_indication->src_pan_id = frame_header->src_pan_id;
data_indication->src_addr = frame_header->src_addr;
data_indication->dst_addr_mode = frame_header->dst_addr_mode;
data_indication->dst_pan_id = frame_header->dst_pan_id;
data_indication->dst_addr = frame_header->dst_addr;
data_indication->msdu_length = msdu_length;
data_indication->msdu = buf_ptr;
data_indication->mpdu_link_quality = mpdu_link_quality;
data_indication->dsn = frame_header->sn;
data_indication->timestamp = timestamp;
data_indication->security_level = security_header->security_level;
data_indication->key_id_mode = security_header->key_id_mode;
data_indication->key_index = security_header->key_index;
data_indication->payload_ie_list = payload_ie_list;
if (data_indication->key_id_mode == 0x2) {
for (n = 0; n < 4; n++) {
data_indication->key_source[n] = security_header->key_source[n];
}
} else if (data_indication->key_id_mode == 0x3) {
for (n = 0; n < 8; n++) {
data_indication->key_source[n] = security_header->key_source[n];
}
}
FTDF_RCV_MSG((ftdf_msg_buffer_t*) data_indication);
}
void ftdf_process_poll_request(ftdf_poll_request_t *poll_request)
{
if (ftdf_req_current == NULL) {
ftdf_req_current = (ftdf_msg_buffer_t*) poll_request;
} else {
if (ftdf_queue_req_head((ftdf_msg_buffer_t*) poll_request, &ftdf_req_queue) ==
FTDF_TRANSACTION_OVERFLOW) {
ftdf_send_poll_confirm(poll_request, FTDF_TRANSACTION_OVERFLOW);
}
return;
}
ftdf_frame_header_t *frame_header = &ftdf_fh;
ftdf_security_header *security_header = &ftdf_sh;
frame_header->frame_type = FTDF_MAC_COMMAND_FRAME;
frame_header->options =
(poll_request->security_level > 0 ? FTDF_OPT_SECURITY_ENABLED : 0) | FTDF_OPT_ACK_REQUESTED;
if (ftdf_pib.short_address < 0xfffe) {
frame_header->src_addr_mode = FTDF_SHORT_ADDRESS;
frame_header->src_addr.short_address = ftdf_pib.short_address;
} else {
frame_header->src_addr_mode = FTDF_EXTENDED_ADDRESS;
frame_header->src_addr.ext_address = ftdf_pib.ext_address;
}
frame_header->src_pan_id = ftdf_pib.pan_id;
frame_header->dst_addr_mode = poll_request->coord_addr_mode;
frame_header->dst_pan_id = poll_request->coord_pan_id;
frame_header->dst_addr = poll_request->coord_addr;
security_header->security_level = poll_request->security_level;
security_header->key_id_mode = poll_request->key_id_mode;
security_header->key_index = poll_request->key_index;
security_header->key_source = poll_request->key_source;
security_header->frame_counter = ftdf_pib.frame_counter;
security_header->frame_counter_mode = ftdf_pib.frame_counter_mode;
ftdf_octet_t *tx_ptr = (ftdf_octet_t*) &FTDF->FTDF_TX_FIFO_0_0_REG + (FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
/* Skip PHY header (= MAC length) */
tx_ptr++;
frame_header->sn = ftdf_pib.dsn;
tx_ptr = ftdf_add_frame_header(tx_ptr, frame_header, 1);
tx_ptr = ftdf_add_security_header(tx_ptr, security_header);
*tx_ptr++ = FTDF_COMMAND_DATA_REQUEST;
ftdf_status_t status = ftdf_send_frame(ftdf_pib.current_channel,
frame_header,
security_header,
tx_ptr,
0,
NULL);
if (status != FTDF_SUCCESS) {
ftdf_send_poll_confirm(poll_request, status);
return;
}
ftdf_nr_of_retries = 0;
ftdf_pib.dsn++;
}
void ftdf_send_poll_confirm(ftdf_poll_request_t *poll_request, ftdf_status_t status)
{
ftdf_poll_confirm_t *poll_confirm = (ftdf_poll_confirm_t*) FTDF_GET_MSG_BUFFER(sizeof(ftdf_poll_confirm_t));
poll_confirm->msg_id = FTDF_POLL_CONFIRM;
poll_confirm->status = status;
if (ftdf_req_current == (ftdf_msg_buffer_t*)poll_request) {
ftdf_req_current = NULL;
}
FTDF_REL_MSG_BUFFER((ftdf_msg_buffer_t*) poll_request);
FTDF_RCV_MSG((ftdf_msg_buffer_t*) poll_confirm);
ftdf_process_next_request();
}
void ftdf_process_purge_request(ftdf_purge_request_t *purge_request)
{
ftdf_handle_t msdu_handle = purge_request->msdu_handle;
ftdf_status_t status = FTDF_INVALID_HANDLE;
int n;
for (n = 0; n < FTDF_NR_OF_REQ_BUFFERS; n++) {
ftdf_msg_buffer_t *request =
ftdf_dequeue_by_handle(msdu_handle, &ftdf_tx_pending_list[n].queue);
if (request) {
ftdf_data_request_t *data_request = (ftdf_data_request_t*) request;
if (data_request->indirect_tx == FTDF_TRUE) {
ftdf_remove_tx_pending_timer(request);
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
if (ftdf_tx_pending_list[n].addr_mode == FTDF_SHORT_ADDRESS) {
uint8_t entry, shortAddrIdx;
ftdf_boolean_t found = ftdf_fppr_lookup_short_address(
ftdf_tx_pending_list[n].addr.short_address, &entry,
&shortAddrIdx);
ASSERT_WARNING(found);
ftdf_fppr_set_short_address_valid(entry, shortAddrIdx, FTDF_FALSE);
} else if (ftdf_tx_pending_list[n].addr_mode == FTDF_EXTENDED_ADDRESS) {
uint8_t entry;
ftdf_boolean_t found = ftdf_fppr_lookup_ext_address(
ftdf_tx_pending_list[n].addr.ext_address, &entry);
ASSERT_WARNING(found);
ftdf_fppr_set_ext_address_valid(entry, FTDF_FALSE);
} else {
ASSERT_WARNING(0);
}
#endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */
if (ftdf_is_queue_empty(&ftdf_tx_pending_list[n].queue)) {
ftdf_tx_pending_list[n].addr_mode = FTDF_NO_ADDRESS;
}
}
FTDF_REL_DATA_BUFFER(data_request->msdu);
FTDF_REL_MSG_BUFFER((ftdf_msg_buffer_t*) data_request);
status = FTDF_SUCCESS;
break;
}
}
ftdf_purge_confirm_t *purge_confirm =
(ftdf_purge_confirm_t*) FTDF_GET_MSG_BUFFER(sizeof(ftdf_purge_confirm_t));
purge_confirm->msg_id = FTDF_PURGE_CONFIRM;
purge_confirm->msdu_handle = msdu_handle;
purge_confirm->status = status;
FTDF_REL_MSG_BUFFER((ftdf_msg_buffer_t*) purge_request);
FTDF_RCV_MSG((ftdf_msg_buffer_t*) purge_confirm);
}
#endif /* !FTDF_LITE */
#ifdef FTDF_PHY_API
ftdf_status_t ftdf_send_frame_simple(ftdf_data_length_t frame_length,
ftdf_octet_t *frame,
ftdf_channel_number_t channel,
ftdf_pti_t pti,
ftdf_boolean_t csma_suppress)
{
ftdf_octet_t *fp = frame;
if ((frame_length > 127) || (ftdf_transparent_mode != FTDF_TRUE)) {
return FTDF_INVALID_PARAMETER;
}
ftdf_octet_t *tx_ptr =
(ftdf_octet_t*) &FTDF->FTDF_TX_FIFO_0_0_REG + (FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
/* This data copy could/should be optimized using DMA */
*tx_ptr++ = frame_length;
int n;
for (n = 0; n < frame_length; n++) {
*tx_ptr++ = *fp++;
}
ftdf_critical_var();
ftdf_enter_critical();
ftdf_nr_of_retries = 0;
ftdf_exit_critical();
ftdf_send_transparent_frame(frame_length,
frame,
channel,
pti,
csma_suppress);
return FTDF_SUCCESS;
}
#else /* !FTDF_PHY_API */
void ftdf_process_transparent_request(ftdf_transparent_request_t *transparent_request)
{
ftdf_data_length_t frame_length = transparent_request->frame_length;
if ((frame_length > 127) || (ftdf_transparent_mode != FTDF_TRUE)) {
FTDF_SEND_FRAME_TRANSPARENT_CONFIRM(transparent_request->handle,
FTDF_INVALID_PARAMETER);
FTDF_REL_MSG_BUFFER((ftdf_msg_buffer_t*) transparent_request);
return;
}
if (ftdf_req_current == NULL) {
ftdf_req_current = (ftdf_msg_buffer_t*) transparent_request;
} else {
#ifndef FTDF_LITE
if (ftdf_queue_req_head((ftdf_msg_buffer_t*) transparent_request, &ftdf_req_queue) ==
FTDF_TRANSACTION_OVERFLOW) {
#endif /* !FTDF_LITE */
FTDF_SEND_FRAME_TRANSPARENT_CONFIRM(transparent_request->handle,
FTDF_TRANSPARENT_OVERFLOW);
FTDF_REL_MSG_BUFFER((ftdf_msg_buffer_t*) transparent_request);
#ifndef FTDF_LITE
}
#endif /* !FTDF_LITE */
return;
}
ftdf_octet_t *tx_ptr =
(ftdf_octet_t*) &FTDF->FTDF_TX_FIFO_0_0_REG + (FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
*tx_ptr++ = frame_length;
ftdf_octet_t *frame = transparent_request->frame;
int n;
for (n = 0; n < frame_length; n++) {
*tx_ptr++ = *frame++;
}
ftdf_send_transparent_frame(frame_length,
transparent_request->frame,
transparent_request->channel,
transparent_request->pti,
transparent_request->cmsa_suppress);
ftdf_nr_of_retries = 0;
}
void ftdf_send_frame_transparent(ftdf_data_length_t frame_length,
ftdf_octet_t *frame,
ftdf_channel_number_t channel,
ftdf_pti_t pti,
ftdf_boolean_t cmsa_suppress,
void *handle)
{
ftdf_transparent_request_t *transparent_request =
(ftdf_transparent_request_t*) FTDF_GET_MSG_BUFFER(sizeof(ftdf_transparent_request_t));
transparent_request->msg_id = FTDF_TRANSPARENT_REQUEST;
transparent_request->frame_length = frame_length;
transparent_request->frame = frame;
transparent_request->channel = channel;
transparent_request->pti = pti;
transparent_request->cmsa_suppress = cmsa_suppress;
transparent_request->handle = handle;
ftdf_process_transparent_request(transparent_request);
}
#endif /* FTDF_PHY_API */
#endif /* CONFIG_USE_FTDF */
@@ -1,15 +0,0 @@
#ifndef FTDFINFO_H_
#define FTDFINFO_H_
/*
* The FTDF release name (version) is listed below, and manually maintained.
* The build time is automatically generated.
*/
#define FTDF_ARCHITECTURE_VERSION 1
#define FTDF_BRANCH_VERSION 0
#define FTDF_LOAD_VERSION 32
const char *ftdf_get_umac_rel_name( void );
const char *ftdf_get_umac_build_time( void );
#endif /* FTDFINFO_H_ */
@@ -1,723 +0,0 @@
/**
****************************************************************************************
*
* @file internal.h
*
* @brief Internal header file
*
* Copyright (c) 2016, Dialog Semiconductor
* 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.
*
*
****************************************************************************************
*/
#define FTDF_TBD 0
#define FTDF_FCS_LENGTH 2
#define FTDF_BUFFER_LENGTH 128
#ifndef FTDF_NR_OF_REQ_BUFFERS
#define FTDF_NR_OF_REQ_BUFFERS 96
#endif
#define FTDF_NR_OF_RX_BUFFERS 8
#define FTDF_NR_OF_CHANNELS 16
#define FTDF_NR_OF_SCAN_RESULTS 16
#define FTDF_NR_OF_CSL_PEERS 16
#define FTDF_MAX_HEADER_IES 8
#define FTDF_MAX_PAYLOAD_IES 4
#define FTDF_MAX_SUB_IES 8
#define FTDF_MAX_IE_CONTENT 128
#define FTDF_NR_OF_RX_ADDRS 16
#define FTDF_NR_OF_NEIGHBORS 16
#define FTDF_TX_DATA_BUFFER 0
#define FTDF_TX_WAKEUP_BUFFER 1
#define FTDF_TX_ACK_BUFFER 2
#define FTDF_OPT_SECURITY_ENABLED 0x01
#define FTDF_OPT_FRAME_PENDING 0x02
#define FTDF_OPT_SEQ_NR_SUPPRESSED 0x04
#define FTDF_OPT_ACK_REQUESTED 0x08
#define FTDF_OPT_IES_PRESENT 0x10
#define FTDF_OPT_PAN_ID_PRESENT 0x20
#define FTDF_OPT_ENHANCED 0x40
#define FTDF_MSK_RX_CE 0x00000002
#define FTDF_MSK_SYMBOL_TMR_CE 0x00000008
#define FTDF_MSK_TX_CE 0x00000010
#define FTDF_TX_FLAG_CLEAR_M_0_REG_INTV 0x20
#define FTDF_TX_FLAG_CLEAR_E_0_REG_INTV 0x20
#define FTDF_TX_PRIORITY_0_REG_INTV 0x20
#define FTDF_RX_META_1_0_REG_INTV 0x10
#define FTDF_TX_FLAG_S_0_REG_INTV 0x20
#define FTDF_TX_RETURN_STATUS_1_0_REG_INTV 0x10
#define FTDF_TX_META_DATA_0_0_REG_INTV 0x10
#define FTDF_TX_RETURN_STATUS_1_0_REG_INTV 0x10
#define FTDF_TX_META_DATA_1_0_REG_INTV 0x10
// The maximum time in symbols that is takes to process request. After succesful
// processing a request the TX buffer is fully initialized and ready to be sent.
#define FTDF_TSCH_MAX_PROCESS_REQUEST_TIME 35
// The maximum time in symbols needed to search for the next slot for which a
// TX or RX needs to be done
#define FTDF_TSCH_MAX_SCHEDULE_TIME 30
#define ftdf_process_request ftdf_snd_msg
typedef struct {
ftdf_ext_address_t ext_address;
ftdf_period_t ack_wait_duration;
#ifndef FTDF_LITE
ftdf_boolean_t associated_pan_coord;
ftdf_boolean_t association_permit;
ftdf_boolean_t auto_request;
ftdf_boolean_t batt_life_ext;
ftdf_num_of_backoffs_t batt_life_ext_periods;
ftdf_octet_t beacon_payload[FTDF_MAX_BEACON_PAYLOAD_LENGTH];
ftdf_size_t beacon_payload_length;
ftdf_order_t beacon_order;
ftdf_time_t beacon_tx_time;
ftdf_sn_t bsn;
ftdf_ext_address_t coord_ext_address;
ftdf_short_address_t coord_short_address;
ftdf_sn_t dsn;
ftdf_boolean_t gts_permit;
#endif /* !FTDF_LITE */
ftdf_be_exponent_t max_be;
ftdf_size_t max_csma_backoffs;
ftdf_period_t max_frame_total_wait_time;
ftdf_size_t max_frame_retries;
ftdf_be_exponent_t min_be;
#ifndef FTDF_LITE
ftdf_period_t lifs_period;
ftdf_period_t sifs_period;
#endif /* !FTDF_LITE */
ftdf_pan_id_t pan_id;
#ifndef FTDF_LITE
ftdf_boolean_t promiscuous_mode; /* Not supported. Use transparent mode instead */
ftdf_size_t response_wait_time;
#endif /* !FTDF_LITE */
ftdf_boolean_t rx_on_when_idle;
#ifndef FTDF_LITE
ftdf_boolean_t security_enabled;
#endif /* !FTDF_LITE */
ftdf_short_address_t short_address;
#ifndef FTDF_LITE
ftdf_size_t superframe_order;
ftdf_period_t sync_symbol_offset;
ftdf_boolean_t timestamp_supported;
ftdf_period_t transaction_persistence_time;
ftdf_period_t enh_ack_wait_duration;
ftdf_boolean_t implicit_broadcast;
ftdf_simple_address_t simple_address;
ftdf_period_t disconnect_time;
ftdf_priority_t join_priority;
ftdf_asn_t asn;
ftdf_boolean_t no_hl_buffers;
ftdf_slotframe_table_t slotframe_table;
FTDF_LinkTable link_table;
ftdf_timeslot_template_t timeslot_template;
ftdf_hopping_sequence_id_t hopping_sequence_id;
ftdf_channel_page_t channel_page;
ftdf_channel_number_t number_of_channels;
ftdf_bitmap32_t phy_configuration;
ftdf_bitmap8_t extended_bitmap;
ftdf_length_t hopping_sequence_length;
ftdf_channel_number_t hopping_sequence_list[FTDF_MAX_HOPPING_SEQUENCE_LENGTH];
ftdf_length_t current_hop;
ftdf_period_t dwell_time;
ftdf_period_t csl_period;
ftdf_period_t csl_max_period;
ftdf_bitmap32_t csl_channel_mask;
ftdf_period_t csl_frame_pending_wait;
ftdf_boolean_t low_energy_superframe_supported;
ftdf_boolean_t low_energy_superframe_sync_interval;
#endif /* !FTDF_LITE */
ftdf_performance_metrics_t performance_metrics;
#ifndef FTDF_LITE
ftdf_boolean_t use_enhanced_becaon;
ftdf_ie_list_t eb_ie_list;
ftdf_boolean_t eb_filtering_enabled;
ftdf_sn_t eb_sn;
ftdf_auto_sa_t eb_auto_sa;
ftdf_ie_list_t e_ack_ie_list;
ftdf_boolean_t tsch_enabled;
ftdf_boolean_t le_enabled;
#endif /* !FTDF_LITE */
ftdf_channel_number_t current_channel;
ftdf_tx_power_tolerance_t tx_power_tolerance;
ftdf_dbm tx_power;
ftdf_cca_mode_t cca_mode;
#ifndef FTDF_LITE
ftdf_channel_page_t current_page;
ftdf_period_t max_frame_duration;
ftdf_period_t shr_duration;
ftdf_key_table_t key_table;
ftdf_device_table_t device_table;
ftdf_security_level_table_t security_level_table;
ftdf_frame_counter_t frame_counter;
ftdf_security_level_t mt_data_security_level;
ftdf_key_id_mode_t mt_data_key_id_mode;
ftdf_octet_t mt_data_key_source[8];
ftdf_key_index_t mt_data_key_index;
ftdf_octet_t default_key_source[8];
ftdf_ext_address_t pan_coord_ext_address;
ftdf_short_address_t pan_coord_short_address;
ftdf_frame_counter_mode_t frame_counter_mode;
ftdf_period_t csl_sync_tx_margin;
ftdf_period_t csl_max_age_remote_info;
#endif /* !FTDF_LITE */
ftdf_traffic_counters_t traffic_counters;
#ifndef FTDF_LITE
ftdf_boolean_t le_capable;
ftdf_boolean_t ll_capable;
ftdf_boolean_t dsme_capable;
ftdf_boolean_t rfid_capable;
ftdf_boolean_t amca_capable;
#endif /* !FTDF_LITE */
ftdf_boolean_t metrics_capable;
#ifndef FTDF_LITE
ftdf_boolean_t ranging_supported;
#endif /* !FTDF_LITE */
ftdf_boolean_t keep_phy_enabled;
ftdf_boolean_t metrics_enabled;
#ifndef FTDF_LITE
ftdf_boolean_t beacon_auto_respond;
ftdf_boolean_t tsch_capable;
ftdf_period_t ts_sync_correct_threshold;
#endif /* !FTDF_LITE */
ftdf_nr_backoff_periods_t bo_irq_threshold;
ftdf_pti_config_t pti_config;
ftdf_link_quality_mode_t link_quality_mode;
} ftdf_pib_t;
typedef uint8_t ftdf_frame_version_t;
#define FTDF_FRAME_VERSION_2003 0
#define FTDF_FRAME_VERSION_2011 1
#define FTDF_FRAME_VERSION_E 2
#define FTDF_FRAME_VERSION_NOT_SUPPORTED 3
typedef struct {
ftdf_frame_type_t frame_type;
ftdf_frame_version_t frame_version;
ftdf_bitmap8_t options;
ftdf_sn_t sn;
ftdf_address_mode_t src_addr_mode;
ftdf_pan_id_t src_pan_id;
ftdf_address_t src_addr;
ftdf_address_mode_t dst_addr_mode;
ftdf_pan_id_t dst_pan_id;
ftdf_address_t dst_addr;
ftdf_command_frame_id_t command_frame_id;
} ftdf_frame_header_t;
typedef struct {
ftdf_security_level_t security_level;
ftdf_key_id_mode_t key_id_mode;
ftdf_key_index_t key_index;
ftdf_frame_counter_mode_t frame_counter_mode;
ftdf_octet_t *key_source;
ftdf_frame_counter_t frame_counter;
} ftdf_security_header;
typedef struct {
ftdf_boolean_t fast_a;
ftdf_boolean_t data_r;
} ftdf_assoc_admin_t;
typedef uint8_t ftdf_sn_sel;
#define FTDF_SN_SEL_DSN 0
#define FTDF_SN_SEL_BSN 1
#define FTDF_SN_SEL_EBSN 2
typedef struct {
ftdf_address_mode_t addr_mode;
ftdf_address_t addr;
ftdf_time_t timestamp;
ftdf_boolean_t dsn_valid;
ftdf_sn_t dsn;
ftdf_boolean_t bsn_valid;
ftdf_sn_t bsn;
ftdf_boolean_t ebsn_valid;
ftdf_sn_t eb_sn;
} ftdf_rx_address_admin_t;
struct ftdf_buffer_;
typedef struct {
struct ftdf_buffer_ *next;
struct ftdf_buffer_ *prev;
} ftdf_buffer_header_t;
typedef struct ftdf_buffer_ {
ftdf_buffer_header_t header;
ftdf_msg_buffer_t *request;
} ftdf_buffer_t;
typedef struct {
ftdf_buffer_header_t head;
ftdf_buffer_header_t tail;
} ftdf_queue_t;
typedef struct {
ftdf_address_t addr;
ftdf_address_mode_t addr_mode;
ftdf_pan_id_t pan_id;
ftdf_queue_t queue;
} ftdf_pending_t;
typedef struct _ftdf_pending_tl_ {
struct _ftdf_pending_tl_ *next;
ftdf_boolean_t free;
ftdf_msg_buffer_t *request;
ftdf_time_t delta;
uint8_t pend_list_nr;
void (* func)(struct _ftdf_pending_tl_*);
} ftdf_pending_tl_t;
typedef uint8_t ftdf_remote_id;
#define FTDF_REMOTE_DATA_REQUEST 0
#define FTDF_REMOTE_PAN_ID_CONFLICT_NOTIFICATION 1
#define FTDF_REMOTE_BEACON 2
#define FTDF_REMOTE_KEEP_ALIVE 3
typedef struct {
ftdf_msg_id_t msg_id;
ftdf_remote_id remote_id;
ftdf_short_address_t dst_addr;
} ftdf_remote_request_t;
#ifndef FTDF_NO_CSL
typedef struct {
ftdf_short_address_t addr;
ftdf_time_t time;
ftdf_period_t period;
} ftdf_peer_csl_timing_t;
#endif /* FTDF_NO_CSL */
typedef uint8_t FTDF_State;
#define FTDF_STATE_UNINITIALIZED 0
#define FTDF_STATE_IDLE 1
#define FTDF_STATE_DATA_REQUEST 2
#define FTDF_STATE_POLL_REQUEST 3
#define FTDF_STATE_SCANNING 4
#ifndef FTDF_NO_TSCH
typedef struct {
ftdf_short_address_t nodeAddr;
ftdf_size_t nr_of_retries;
ftdf_size_t nr_of_cca_retries;
ftdf_be_exponent_t BE;
} ftdf_tsch_retry_t;
typedef struct {
ftdf_short_address_t dst_addr;
ftdf_keep_alive_period_t period;
ftdf_remote_request_t msg;
} FTDF_NeighborEntry;
#endif /* FTDF_NO_TSCH */
typedef struct {
ftdf_count_t fcs_error_cnt;
ftdf_count_t tx_std_ack_cnt;
ftdf_count_t rx_std_ack_cnt;
} ftdf_lmac_counters_t;
extern ftdf_pib_t ftdf_pib;
extern FTDF_State *FTDF_state;
extern ftdf_boolean_t ftdf_transparent_mode;
extern ftdf_bitmap32_t ftdf_transparent_mode_options;
extern ftdf_queue_t ftdf_req_queue;
extern ftdf_queue_t ftdf_freeQueue;
extern ftdf_pending_t ftdf_tx_pending_list[FTDF_NR_OF_REQ_BUFFERS];
extern ftdf_pending_tl_t ftdf_tx_pending_timer_list[FTDF_NR_OF_REQ_BUFFERS];
extern ftdf_pending_tl_t *ftdf_tx_pending_timer_head;
extern ftdf_time_t ftdf_tx_pending_timer_lt;
extern ftdf_time_t ftdf_tx_pending_timer_time;
extern ftdf_msg_buffer_t *ftdf_req_current;
extern ftdf_size_t ftdf_nr_of_retries;
extern ftdf_boolean_t ftdf_is_pan_coordinator;
extern ftdf_slotframe_entry_t ftdf_slotframe_table[FTDF_MAX_SLOTFRAMES];
extern ftdf_link_entry_t ftdf_link_table[FTDF_MAX_LINKS];
#ifndef FTDF_NO_TSCH
extern ftdf_link_entry_t *ftdf_start_links[FTDF_MAX_SLOTFRAMES];
extern ftdf_link_entry_t *ftdf_end_links[FTDF_MAX_SLOTFRAMES];
extern FTDF_NeighborEntry ftdf_neighbor_table[FTDF_NR_OF_NEIGHBORS];
extern ftdf_boolean_t ftdf_wake_up_enable_tsch;
#endif /* FTDF_NO_TSCH */
#ifndef FTDF_NO_CSL
extern ftdf_boolean_t ftdf_wake_up_enable_le;
#endif /* FTDF_NO_CSL */
extern ftdf_lmac_counters_t ftdf_lmac_counters;
extern ftdf_frame_header_t ftdf_fh;
extern ftdf_security_header ftdf_sh;
extern ftdf_assoc_admin_t ftdf_aa;
extern ftdf_boolean_t ftdf_tx_in_progress;
#ifndef FTDF_NO_CSL
extern ftdf_time_t ftdf_rz_time;
extern ftdf_short_address_t ftdf_send_frame_pending;
#endif /* FTDF_NO_CSL */
extern ftdf_time_t ftdf_start_csl_sample_time;
#ifndef FTDF_NO_TSCH
extern ftdf_link_entry_t *ftdf_tsch_slot_link;
extern ftdf_time64_t ftdf_tsch_slot_time;
extern ftdf_asn_t ftdf_tsch_slot_asn;
#endif /* FTDF_NO_TSCH */
void ftdf_process_data_request(ftdf_data_request_t *req);
void ftdf_process_purge_request(ftdf_purge_request_t *req);
void ftdf_process_associate_request(ftdf_associate_request_t *req);
void ftdf_process_associate_response(ftdf_associate_response_t *req);
void ftdf_process_disassociate_request(ftdf_disassociate_request_t *req);
void ftdf_process_get_request(ftdf_get_request_t *req);
void ftdf_process_set_request(ftdf_set_request_t *req);
void ftdf_process_orphan_response(ftdf_orphan_response_t *req);
void ftdf_process_reset_request(ftdf_reset_request_t *req);
void ftdf_process_rx_enable_request(ftdf_rx_enable_request_t *req);
void ftdf_process_scan_request(ftdf_scan_request_t *req);
void ftdf_process_start_request(ftdf_start_request_t *req);
void ftdf_process_poll_request(ftdf_poll_request_t *req);
#ifndef FTDF_NO_TSCH
void ftdf_process_set_slotframe_request(ftdf_set_slotframe_request_t *req);
void ftdf_process_set_link_request(ftdf_set_link_request_t *req);
void ftdf_process_tsch_mode_request(ftdf_tsch_mode_request_t *req);
void ftdf_process_keep_alive_request(ftdf_keep_alive_request_t *req);
#endif /* FTDF_NO_TSCH */
void ftdf_process_beacon_request(ftdf_beacon_request_t *req);
void ftdf_process_transparent_request(ftdf_transparent_request_t *req);
void ftdf_process_remote_request(ftdf_remote_request_t *req);
void ftdf_process_next_request(void);
void ftdf_process_rx_event(void);
void ftdf_process_tx_event(void);
void ftdf_process_symbol_timer_event(void);
void ftdf_send_data_confirm(ftdf_data_request_t *data_request,
ftdf_status_t status,
ftdf_time_t timestamp,
ftdf_sn_t dsn,
ftdf_num_of_backoffs_t num_of_backoffs,
ftdf_ie_list_t *ack_payload);
void ftdf_send_data_indication(ftdf_frame_header_t *frame_header,
ftdf_security_header *security_header,
ftdf_ie_list_t *payload_ie_list,
ftdf_data_length_t msdu_length,
ftdf_octet_t *msdu,
ftdf_link_quality_t mpdu_link_quality,
ftdf_time_t timestamp);
void ftdf_send_poll_confirm(ftdf_poll_request_t *poll_request, ftdf_status_t status);
void ftdf_send_scan_confirm(ftdf_scan_request_t *scan_request, ftdf_status_t status);
void ftdf_send_beacon_notify_indication(ftdf_pan_descriptor_t *pan_descriptor);
void ftdf_send_beacon_confirm(ftdf_beacon_request_t *beacon_request, ftdf_status_t status);
void ftdf_send_associate_confirm(ftdf_associate_request_t *associate_request,
ftdf_status_t status,
ftdf_short_address_t assoc_short_addr);
void ftdf_send_associate_data_request(void);
void ftdf_send_disassociate_confirm(ftdf_disassociate_request_t *dis_req, ftdf_status_t status);
void ftdf_send_sync_loss_indication(ftdf_loss_reason_t loss_reason, ftdf_security_header *security_header);
void ftdf_sendpan_id_conflict_notification(ftdf_frame_header_t *frame_header, ftdf_security_header *security_header);
void ftdf_send_comm_status_indication(ftdf_msg_buffer_t *request,
ftdf_status_t status,
ftdf_pan_id_t pan_Id,
ftdf_address_mode_t src_addr_mode,
ftdf_address_t src_addr,
ftdf_address_mode_t dst_addr_mode,
ftdf_address_t dst_addr,
ftdf_security_level_t security_level,
ftdf_key_id_mode_t key_id_mode,
ftdf_octet_t *key_source,
ftdf_key_index_t key_index);
void ftdf_start_timer(ftdf_period_t period, void (* timer_func)(void *params), void *params);
ftdf_octet_t *ftdf_get_tx_buf_ptr(ftdf_buffer_t *tx_buffer);
void ftdf_set_tx_meta_data(ftdf_buffer_t *tx_buffer,
ftdf_data_length_t frame_length,
ftdf_channel_number_t channel,
ftdf_frame_type_t frame_type,
ftdf_boolean_t ack_tx,
ftdf_sn_t sn);
ftdf_status_t ftdf_send_frame(ftdf_channel_number_t channel,
ftdf_frame_header_t *frame_header,
ftdf_security_header *security_header,
ftdf_octet_t *tx_ptr,
ftdf_data_length_t payload_size,
ftdf_octet_t *payload);
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
ftdf_status_t ftdf_send_ack_frame(ftdf_frame_header_t *frame_header,
ftdf_security_header *security_header,
ftdf_octet_t *tx_ptr);
#endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */
void ftdf_send_transparent_frame(ftdf_data_length_t frame_length,
ftdf_octet_t *frame,
ftdf_channel_number_t channel,
ftdf_pti_t pti,
ftdf_boolean_t cmsa_suppress);
ftdf_octet_t *ftdf_get_rx_buffer(void);
void ftdf_process_rx_event(void);
ftdf_octet_t *ftdf_add_frame_header(ftdf_octet_t *tx_ptr,
ftdf_frame_header_t *frame_header,
ftdf_data_length_t msdu_length);
ftdf_octet_t *ftdf_get_frame_header(ftdf_octet_t *rx_ptr, ftdf_frame_header_t *frame_header);
ftdf_data_length_t ftdf_get_mic_length(ftdf_security_level_t security_level);
ftdf_octet_t *ftdf_get_security_header(ftdf_octet_t *rx_ptr,
uint8_t frame_version,
ftdf_security_header *security_header);
ftdf_octet_t *ftdf_add_security_header(ftdf_octet_t *tx_ptr,
ftdf_security_header *security_header);
ftdf_status_t ftdf_secure_frame(ftdf_octet_t *buf_ptr,
ftdf_octet_t *priv_ptr,
ftdf_frame_header_t *frame_header,
ftdf_security_header *security_header);
ftdf_status_t ftdf_unsecure_frame(ftdf_octet_t *buf_ptr,
ftdf_octet_t *priv_ptr,
ftdf_frame_header_t *frame_header,
ftdf_security_header *security_header);
ftdf_key_descriptor_t *ftdf_lookup_key(ftdf_address_mode_t dev_addr_mode,
ftdf_pan_id_t dev_pan_id,
ftdf_address_t dev_addr,
ftdf_frame_type_t frame_type,
ftdf_key_id_mode_t key_id_mode,
ftdf_key_index_t key_index,
ftdf_octet_t *key_source);
ftdf_device_descriptor_t *ftdf_lookup_device(ftdf_size_t nr_of_device_descriptor_handles,
ftdf_device_descriptor_handle_t *device_descriptor_handles,
ftdf_address_mode_t dev_addr_mode,
ftdf_pan_id_t dev_pan_id,
ftdf_address_t dev_addr);
ftdf_security_level_descriptor_t *ftdf_get_security_level_descr(ftdf_frame_type_t frame_type,
ftdf_command_frame_id_t command_frame_id);
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
ftdf_octet_t *ftdf_add_ies(ftdf_octet_t *tx_ptr,
ftdf_ie_list_t *header_ie_list,
ftdf_ie_list_t *payload_ie_list,
ftdf_boolean_t with_termination_ie);
ftdf_octet_t *ftdf_get_ies(ftdf_octet_t *rx_ptr,
ftdf_octet_t *frame_end_ptr,
ftdf_ie_list_t **header_ie_list,
ftdf_ie_list_t **payload_ie_list);
#endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */
#ifndef FTDF_NO_CSL
void ftdf_set_peer_csl_timing(ftdf_ie_list_t *header_ie_list, ftdf_time_t timeStamp);
void ftdf_set_csl_sample_time(void);
void ftdf_get_wakeup_params(ftdf_short_address_t dst_addr,
ftdf_time_t *wakeup_start_time,
ftdf_period_t *wakeup_period);
#endif /* FTDF_NO_CSL */
void ftdf_get_ext_address(void);
void ftdf_set_ext_address(void);
void ftdf_get_ack_wait_duration(void);
void ftdf_get_enh_ack_wait_duration(void);
void ftdf_set_enh_ack_wait_duration(void);
void ftdf_get_implicit_broadcast(void);
void ftdf_set_implicit_broadcast(void);
void ftdf_set_short_address(void);
void ftdf_set_simple_address(void);
void ftdf_get_rx_on_when_idle(void);
void ftdf_set_rx_on_when_idle(void);
void ftdf_getpan_id(void);
void ftdf_setpan_id(void);
void ftdf_get_current_channel(void);
void ftdf_set_current_channel(void);
void FTDF_setTXPower( void );
void ftdf_get_max_frame_total_wait_time(void);
void ftdf_set_max_frame_total_wait_time(void);
#ifndef FTDF_NO_CSL
void ftdf_set_le_enabled(void);
void ftdf_get_csl_frame_pending_wait(void);
void ftdf_set_csl_frame_pending_wait(void);
#endif /* FTDF_NO_CSL */
void ftdf_get_lmac_pm_data(void);
void ftdf_get_lmac_traffic_counters(void);
void ftdf_set_max_csma_backoffs(void);
void ftdf_set_max_be(void);
void ftdf_set_min_be(void);
void ftdf_get_keep_phy_enabled(void);
void ftdf_set_keep_phy_enabled(void);
void ftdf_set_bo_irq_threshold(void);
void ftdf_get_bo_irq_threshold(void);
void ftdf_set_pti_config(void);
#ifndef FTDF_NO_TSCH
void ftdf_set_timeslot_template(void);
#endif /* FTDF_NO_TSCH */
void ftdf_init_lmac(void);
void ftdf_init_queues(void);
void ftdf_init_queue(ftdf_queue_t *queue);
void ftdf_queue_buffer_head(ftdf_buffer_t *buffer, ftdf_queue_t *queue);
ftdf_status_t ftdf_queue_req_head(ftdf_msg_buffer_t *request, ftdf_queue_t *queue);
ftdf_buffer_t *ftdf_dequeue_buffer_tail(ftdf_queue_t *queue);
ftdf_msg_buffer_t *ftdf_dequeue_req_tail(ftdf_queue_t *queue);
ftdf_msg_buffer_t *ftdf_dequeue_by_handle(ftdf_handle_t handle, ftdf_queue_t *queue);
ftdf_buffer_t *ftdf_dequeue_by_buffer(ftdf_buffer_t *buffer, ftdf_queue_t *queue);
ftdf_boolean_t ftdf_is_queue_empty(ftdf_queue_t *queue);
void ftdf_add_tx_pending_timer(ftdf_msg_buffer_t *request,
uint8_t pend_list_nr,
ftdf_time_t delta,
void (* func)(ftdf_pending_tl_t*));
void ftdf_remove_tx_pending_timer(ftdf_msg_buffer_t *request);
void ftdf_restore_tx_pending_timer(void);
ftdf_boolean_t ftdf_get_tx_pending_timer_head(ftdf_time_t *time);
void ftdf_send_transaction_expired(ftdf_pending_tl_t *ptr);
#ifndef FTDF_NO_TSCH
void ftdf_process_keep_alive_timer_exp(ftdf_pending_tl_t *ptr);
void ftdf_reset_keep_alive_timer(ftdf_short_address_t dst_addr);
#endif /* FTDF_NO_TSCH */
void ftdf_process_tx_pending(ftdf_frame_header_t *frame_hader, ftdf_security_header *security_header);
void ftdf_process_command_frame(ftdf_octet_t *rx_buffer,
ftdf_frame_header_t *frame_header,
ftdf_security_header *security_header,
ftdf_ie_list_t *payload_ie_list);
void ftdf_scan_ready(ftdf_scan_request_t*);
void ftdf_add_pan_descriptor(ftdf_pan_descriptor_t*);
void ftdf_send_beacon_request(ftdf_channel_number_t channel);
void ftdf_send_beacon_request_indication(ftdf_frame_header_t *frame_header, ftdf_ie_list_t *payload_ie_list);
void ftdf_send_orphan_notification(ftdf_channel_number_t channel);
#ifndef FTDF_NO_TSCH
void ftdf_set_tsch_enabled(void);
ftdf_status_t ftdf_schedule_tsch(ftdf_msg_buffer_t *request);
void ftdf_tsch_process_request(void);
ftdf_size_t ftdf_get_tsch_sync_sub_ie(void);
ftdf_octet_t *ftdf_add_tsch_sync_sub_ie(ftdf_octet_t *tx_ptr);
ftdf_short_address_t ftdf_get_request_address(ftdf_msg_buffer_t *request);
ftdf_msg_buffer_t *ftdf_tsch_get_pending(ftdf_msg_buffer_t *request);
ftdf_octet_t *ftdf_add_corr_time_ie(ftdf_octet_t *tx_ptr, ftdf_time_t rx_timestamp);
void ftdf_correct_slot_time(ftdf_time_t rx_timestamp);
void ftdf_correct_slot_time_from_ack(ftdf_ie_list_t *header_ie_list);
void ftdf_init_tsch_retries(void);
ftdf_tsch_retry_t *ftdf_get_tsch_retry(ftdf_short_address_t node_addr);
ftdf_num_of_backoffs_t ftdf_get_num_of_backoffs(ftdf_be_exponent_t be);
void ftdf_init_backoff(void);
ftdf_sn_t ftdf_process_tsch_sn(ftdf_msg_buffer_t *msg, ftdf_sn_t sn, uint8_t *priv);
#endif /* FTDF_NO_TSCH */
ftdf_time64_t ftdf_get_cur_time64(void);
void ftdf_init_cur_time64(void);
#if FTDF_USE_SLEEP_DURING_BACKOFF
typedef enum
{
FTDF_SDB_STATE_INIT = 0,
FTDF_SDB_STATE_BACKING_OFF,
FTDF_SDB_STATE_WAITING_WAKE_UP_IRQ,
FTDF_SDB_STATE_RESUMING,
} ftdf_sdb_state_t;
typedef struct
{
ftdf_sdb_state_t state;
ftdf_size_t nr_of_backoffs;
ftdf_time_t cca_retry_time;
ftdf_octet_t buffer[FTDF_BUFFER_LENGTH];
uint32_t metadata_0;
uint32_t metadata_1;
uint32_t phy_csma_ca_attr;
} ftdf_sdb_t;
void ftdf_sdb_fsm_reset(void);
void ftdf_sdb_fsm_backoff_irq(void);
void ftdf_sdb_fsm_sleep(void);
void ftdf_sdb_fsm_abort_sleep(void);
void ftdf_sdb_fsm_wake_up_irq(void);
void ftdf_sdb_fsm_wake_up(void);
void ftdf_sdb_fsm_tx_irq(void);
ftdf_usec_t ftdf_sdb_get_sleep_time(void);
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
static inline void ftdf_set_link_quality_mode(void)
{
#ifdef FTDF_PIB_LINK_QUALITY_MODE
REG_SETF(FTDF, FTDF_LMAC_CONTROL_1_REG, PHYRXATTR_DEM_PTI,
(ftdf_pib.link_quality_mode == FTDF_LINK_QUALITY_MODE_RSSI) ? 0x8 : 0);
REG_SETF(DEM, RF_FTDF_CTRL4_REG, LQI_SCALE, 0);
if (ftdf_pib.link_quality_mode == FTDF_LINK_QUALITY_MODE_RSSI) {
REG_SETF(DEM, RF_FTDF_CTRL4_REG, LQI_PREAMBLE_EN, 0);
REG_SETF(DEM, RF_FTDF_CTRL4_REG, LQI_CORRTH_EN, 1);
} else {
REG_SETF(DEM, RF_FTDF_CTRL4_REG, LQI_PREAMBLE_EN, 1);
REG_SETF(DEM, RF_FTDF_CTRL4_REG, LQI_CORRTH_EN, 0);
}
#endif
}
#if dg_configUSE_FTDF_DDPHY == 1
void ftdf_ddphy_restore(void);
void ftdf_ddphy_save(void);
#endif
-292
View File
@@ -1,292 +0,0 @@
/**
****************************************************************************************
*
* @file main.c
*
* @brief Main FTDF functions
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 <ftdf.h>
#include <string.h>
#include "internal.h"
#include "ftdfInfo.h"
void ftdf_get_release_info(char **lmac_rel_name, char **lmac_build_time, char **umac_rel_name,
char **umac_build_time)
{
static char lrel_name[16];
static char lbld_time[16];
static char urel_name[16];
static char ubld_time[16];
uint8_t i;
volatile uint32_t *ptr = &FTDF->FTDF_REL_NAME_0_REG;
uint32_t *chr_ptr = (uint32_t*)lrel_name;
for (i = 0; i < 4; i++) {
*chr_ptr++ = *ptr++;
}
ptr = &FTDF->FTDF_BUILDTIME_0_REG;
chr_ptr = (uint32_t*)lbld_time;
for (i = 0; i < 4; i++) {
*chr_ptr++ = *ptr++;
}
const char* umac_v_ptr = ftdf_get_umac_rel_name();
for (i = 0; i < 16; i++) {
urel_name[i] = umac_v_ptr[i];
if (umac_v_ptr[i] == '\0') {
break;
}
}
umac_v_ptr = ftdf_get_umac_build_time();
for (i = 0; i < 16; i++) {
ubld_time[i] = umac_v_ptr[i];
if (umac_v_ptr[i] == '\0') {
break;
}
}
lrel_name[15] = '\0';
lbld_time[15] = '\0';
urel_name[15] = '\0';
ubld_time[15] = '\0';
*lmac_rel_name = lrel_name;
*lmac_build_time = lbld_time;
*umac_rel_name = urel_name;
*umac_build_time = ubld_time;
}
void ftdf_confirm_lmac_interrupt(void)
{
REG_SETF(FTDF, FTDF_FTDF_CM_REG, FTDF_CM, 0);
}
void ftdf_event_handler(void)
{
volatile uint32_t ftdf_ce = FTDF->FTDF_FTDF_CE_REG;
if (ftdf_ce & FTDF_MSK_RX_CE) {
ftdf_process_rx_event();
}
if (ftdf_ce & FTDF_MSK_TX_CE) {
ftdf_process_tx_event();
}
if (ftdf_ce & FTDF_MSK_SYMBOL_TMR_CE) {
ftdf_process_symbol_timer_event();
}
#ifndef FTDF_LITE
#ifndef FTDF_NO_CSL
if (ftdf_pib.le_enabled) {
ftdf_time_t cur_time = REG_GETF(FTDF, FTDF_SYMBOLTIMESNAPSHOTVAL_REG,
SYMBOLTIMESNAPSHOTVAL);
ftdf_time_t delta = cur_time - ftdf_rz_time;
if (delta < 0x80000000) {
/* RZ has passed check if a send frame is pending */
if (ftdf_send_frame_pending != 0xfffe) {
ftdf_time_t wakeup_start_time;
ftdf_period_t wakeup_period;
ftdf_critical_var();
ftdf_enter_critical();
ftdf_get_wakeup_params(ftdf_send_frame_pending, &wakeup_start_time,
&wakeup_period);
ftdf_tx_in_progress = FTDF_TRUE;
REG_SETF(FTDF, FTDF_LMAC_CONTROL_8_REG, MACCSLSTARTSAMPLETIME,
wakeup_start_time);
REG_SETF(FTDF, FTDF_LMAC_CONTROL_7_REG, MACWUPERIOD, wakeup_period);
REG_SETF(FTDF, FTDF_TX_SET_OS_REG, TX_FLAG_SET,
((1 << FTDF_TX_DATA_BUFFER) |
(1 << FTDF_TX_WAKEUP_BUFFER)));
ftdf_send_frame_pending = 0xfffe;
ftdf_exit_critical();
}
if (ftdf_tx_in_progress == FTDF_FALSE) {
ftdf_set_csl_sample_time();
}
}
}
#endif /* FTDF_NO_CSL */
#endif /* !FTDF_LITE */
REG_SETF(FTDF, FTDF_FTDF_CM_REG, FTDF_CM,
(FTDF_MSK_TX_CE | FTDF_MSK_RX_CE | FTDF_MSK_SYMBOL_TMR_CE));
}
#ifndef FTDF_PHY_API
void ftdf_snd_msg(ftdf_msg_buffer_t* msg_buf)
{
switch (msg_buf->msg_id) {
#ifndef FTDF_LITE
case FTDF_DATA_REQUEST:
ftdf_process_data_request((ftdf_data_request_t*)msg_buf);
break;
case FTDF_PURGE_REQUEST:
ftdf_process_purge_request((ftdf_purge_request_t*)msg_buf);
break;
case FTDF_ASSOCIATE_REQUEST:
ftdf_process_associate_request((ftdf_associate_request_t*)msg_buf);
break;
case FTDF_ASSOCIATE_RESPONSE:
ftdf_process_associate_response((ftdf_associate_response_t*)msg_buf);
break;
case FTDF_DISASSOCIATE_REQUEST:
ftdf_process_disassociate_request((ftdf_disassociate_request_t*)msg_buf);
break;
#endif /* !FTDF_LITE */
case FTDF_GET_REQUEST:
ftdf_process_get_request((ftdf_get_request_t*)msg_buf);
break;
case FTDF_SET_REQUEST:
ftdf_process_set_request((ftdf_set_request_t*)msg_buf);
break;
#ifndef FTDF_LITE
case FTDF_ORPHAN_RESPONSE:
ftdf_process_orphan_response((ftdf_orphan_response_t*)msg_buf);
break;
#endif /* !FTDF_LITE */
case FTDF_RESET_REQUEST:
ftdf_process_reset_request((ftdf_reset_request_t*)msg_buf);
break;
case FTDF_RX_ENABLE_REQUEST:
ftdf_process_rx_enable_request((ftdf_rx_enable_request_t*)msg_buf);
break;
#ifndef FTDF_LITE
case FTDF_SCAN_REQUEST:
ftdf_process_scan_request((ftdf_scan_request_t*)msg_buf);
break;
case FTDF_START_REQUEST:
ftdf_process_start_request((ftdf_start_request_t*)msg_buf);
break;
case FTDF_POLL_REQUEST:
ftdf_process_poll_request((ftdf_poll_request_t*)msg_buf);
break;
#ifndef FTDF_NO_TSCH
case FTDF_SET_SLOTFRAME_REQUEST:
ftdf_process_set_slotframe_request((ftdf_set_slotframe_request_t*)msg_buf);
break;
case FTDF_SET_LINK_REQUEST:
ftdf_process_set_link_request((ftdf_set_link_request_t*)msg_buf);
break;
case FTDF_TSCH_MODE_REQUEST:
ftdf_process_tsch_mode_request((ftdf_tsch_mode_request_t*)msg_buf);
break;
case FTDF_KEEP_ALIVE_REQUEST:
ftdf_process_keep_alive_request((ftdf_keep_alive_request_t*)msg_buf);
break;
#endif /* FTDF_NO_TSCH */
case FTDF_BEACON_REQUEST:
ftdf_process_beacon_request((ftdf_beacon_request_t*)msg_buf);
break;
#endif /* !FTDF_LITE */
case FTDF_TRANSPARENT_ENABLE_REQUEST:
ftdf_enable_transparent_mode(((ftdf_transparent_enable_request_t*)msg_buf)->enable,
((ftdf_transparent_enable_request_t*)msg_buf)->options);
FTDF_REL_MSG_BUFFER(msg_buf);
break;
case FTDF_TRANSPARENT_REQUEST:
ftdf_process_transparent_request((ftdf_transparent_request_t*)msg_buf);
break;
case FTDF_SLEEP_REQUEST:
FTDF_SLEEP_CALLBACK(((ftdf_sleep_request_t*)msg_buf)->sleep_time);
FTDF_REL_MSG_BUFFER(msg_buf);
break;
#ifndef FTDF_LITE
case FTDF_REMOTE_REQUEST:
ftdf_process_remote_request((ftdf_remote_request_t*)msg_buf);
break;
#endif /* !FTDF_LITE */
#if FTDF_DBG_BUS_ENABLE
case FTDF_DBG_MODE_SET_REQUEST:
ftdf_set_dbg_mode(((ftdf_dbg_mode_set_request_t *) msg_buf)->dbg_mode);
FTDF_REL_MSG_BUFFER(msg_buf);
break;
#endif /* FTDF_DBG_BUS_ENABLE */
case FTDF_FPPR_MODE_SET_REQUEST:
ftdf_fppr_set_mode(((ftdf_fppr_mode_set_request_t *) msg_buf)->match_fp,
((ftdf_fppr_mode_set_request_t *) msg_buf)->fp_override,
((ftdf_fppr_mode_set_request_t *) msg_buf)->fp_force);
FTDF_REL_MSG_BUFFER(msg_buf);
break;
default:
// Silenty release the message buffer
FTDF_REL_MSG_BUFFER(msg_buf);
break;
}
}
void ftdf_send_frame_transparent_confirm(void *handle, ftdf_bitmap32_t status)
{
ftdf_transparent_confirm_t* confirm =
(ftdf_transparent_confirm_t*) FTDF_GET_MSG_BUFFER(
sizeof(ftdf_transparent_confirm_t));
confirm->msg_id = FTDF_TRANSPARENT_CONFIRM;
confirm->handle = handle;
confirm->status = status;
FTDF_RCV_MSG((ftdf_msg_buffer_t*)confirm);
}
void ftdf_rcv_frame_transparent(ftdf_data_length_t frame_length, ftdf_octet_t *frame,
ftdf_bitmap32_t status, ftdf_link_quality_t link_quality)
{
ftdf_transparent_indication_t *indication =
(ftdf_transparent_indication_t*) FTDF_GET_MSG_BUFFER(
sizeof(ftdf_transparent_indication_t));
indication->msg_id = FTDF_TRANSPARENT_INDICATION;
indication->frame_length = frame_length;
indication->status = status;
indication->frame = FTDF_GET_DATA_BUFFER(frame_length);
memcpy(indication->frame, frame, frame_length);
FTDF_RCV_MSG((ftdf_msg_buffer_t*)indication);
}
#endif /* !FTDF_PHY_API */
-327
View File
@@ -1,327 +0,0 @@
/**
****************************************************************************************
*
* @file power.c
*
* @brief FTDF power on/off functions
*
* Copyright (c) 2016, Dialog Semiconductor
* 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 <stdlib.h>
#include <ftdf.h>
#include "internal.h"
#include "sdk_defs.h"
#ifdef CONFIG_USE_FTDF
static ftdf_psec_t ftdf_low_power_clock_cycle __attribute__ ((section(".retention")));
static ftdf_psec_t ftdf_wake_up_latency __attribute__ ((section(".retention")));
/* Pre-calculated value for optimization. */
static ftdf_usec_t ftdf_low_power_clock_cycle_u_sec __attribute__ ((section(".retention")));
/* Pre-calculated value for optimization. */
static ftdf_usec_t ftdf_wake_up_latency_u_sec __attribute__ ((section(".retention")));
/* Pre-calculated value for optimization. */
static ftdf_nr_low_power_clock_cycles_t ftdf_csmaca_wakeup_thr __attribute__ ((section(".retention")));
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
static uint32_t ftdf_event_curr_val __attribute__ ((section(".retention")));
static uint32_t ftdf_time_stamp_curr_val __attribute__ ((section(".retention")));
static uint32_t ftdf_time_stamp_curr_phase_val __attribute__ ((section(".retention")));
#endif
#ifndef FTDF_NO_CSL
ftdf_boolean_t ftdf_wake_up_enable_le __attribute__ ((section(".retention")));
#endif /* FTDF_NO_CSL */
#ifndef FTDF_NO_TSCH
ftdf_boolean_t ftdf_wake_up_enable_tsch;
#endif /* FTDF_NO_TSCH */
void ftdf_set_sleep_attributes(ftdf_psec_t low_power_clock_cycle,
ftdf_nr_low_power_clock_cycles_t wake_up_latency)
{
ftdf_low_power_clock_cycle = low_power_clock_cycle;
ftdf_wake_up_latency = (ftdf_psec_t)wake_up_latency * low_power_clock_cycle;
ftdf_low_power_clock_cycle_u_sec = ftdf_low_power_clock_cycle / 1000000;
ftdf_wake_up_latency_u_sec = ftdf_wake_up_latency / 1000000;
ftdf_csmaca_wakeup_thr = (ftdf_nr_low_power_clock_cycles_t)
(((ftdf_psec_t) 0xffffffff * 1000000 - ftdf_wake_up_latency) / ftdf_low_power_clock_cycle);
}
ftdf_usec_t ftdf_can_sleep(void)
{
#ifdef FTDF_PHY_API
if (ftdf_tx_in_progress || ftdf_pib.keep_phy_enabled) {
return 0;
}
#else
#if FTDF_USE_SLEEP_DURING_BACKOFF
if (ftdf_pib.keep_phy_enabled)
#else
if (ftdf_req_current || ftdf_pib.keep_phy_enabled)
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
{
return 0;
}
#endif
#if FTDF_USE_SLEEP_DURING_BACKOFF
if (REG_GETF(FTDF, FTDF_SECURITY_STATUS_REG, SECBUSY) == 1)
#else /* FTDF_USE_SLEEP_DURING_BACKOFF */
if ((REG_GETF(FTDF, FTDF_LMAC_CONTROL_STATUS_REG, LMACREADY4SLEEP) == 0) ||
(REG_GETF(FTDF, FTDF_SECURITY_STATUS_REG, SECBUSY) == 1))
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
{
return 0;
}
#ifndef FTDF_NO_CSL
if (ftdf_pib.le_enabled) {
#if FTDF_USE_SLEEP_DURING_BACKOFF
/* Abort sleep when LMAC is busy. */
if (REG_GETF(FTDF, FTDF_LMAC_CONTROL_STATUS_REG, LMACREADY4SLEEP) == 0) {
return 0;
}
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
if (ftdf_tx_in_progress == FTDF_FALSE) {
ftdf_time_t cur_time = REG_GETF(FTDF, FTDF_SYMBOLTIMESNAPSHOTVAL_REG,
SYMBOLTIMESNAPSHOTVAL);
ftdf_time_t delta = cur_time - ftdf_start_csl_sample_time;
/* A delta larger than 0x80000000 is assumed to be negative */
/* Do not return a sleep value when CSL sample time is in the past */
if (delta < 0x80000000) {
return 0;
}
return (ftdf_start_csl_sample_time - cur_time) * 16;
} else {
return 0;
}
}
#endif /* FTDF_NO_CSL */
#ifndef FTDF_NO_TSCH
if (ftdf_pib.tsch_enabled) {
#if FTDF_USE_SLEEP_DURING_BACKOFF
/* Abort sleep when LMAC is busy. */
if (REG_GETF(FTDF, FTDF_LMAC_CONTROL_STATUS_REG, LMACREADY4SLEEP) == 0) {
return 0;
}
#endif
ftdf_time64_t curTime64 = ftdf_get_cur_time64();
ftdf_time64_t delta = curTime64 - ftdf_tsch_slot_time;
/* A delta larger than 0x8000000000000000 is assumed to be negative */
/* Do not return a sleep value when TSCH slot time is in the past */
if (delta < 0x8000000000000000ULL) {
return 0;
}
ftdf_usec_t sleep_time = (ftdf_usec_t)(ftdf_tsch_slot_time - curTime64);
ftdf_time_t pend_list_time;
ftdf_time_t curTime = REG_GETF(FTDF, FTDF_SYMBOLTIMESNAPSHOTVAL_REG, SYMBOLTIMESNAPSHOTVAL);
ftdf_boolean_t pending = ftdf_get_tx_pending_timer_head(&pend_list_time);
if (pending) {
/* A delta larger than 0x80000000 is assumed to be negative */
/* Do not return a sleep value when pending timer time is in the past */
if (curTime - pend_list_time < 0x80000000) {
return 0;
}
ftdf_usec_t tmp_sleep_time = (ftdf_usec_t)(pend_list_time - curTime);
if (tmp_sleep_time < sleep_time) {
sleep_time = tmp_sleep_time;
}
}
if (sleep_time < FTDF_TSCH_MAX_PROCESS_REQUEST_TIME + FTDF_TSCH_MAX_SCHEDULE_TIME) {
return 0;
}
return (sleep_time - (FTDF_TSCH_MAX_PROCESS_REQUEST_TIME + FTDF_TSCH_MAX_SCHEDULE_TIME)) * 16;
}
#endif /* FTDF_NO_TSCH */
#ifndef FTDF_LITE
/* Normal mode */
int n;
for (n = 0; n < FTDF_NR_OF_REQ_BUFFERS; n++) {
if (ftdf_tx_pending_list[n].addr_mode != FTDF_NO_ADDRESS) {
return 0;
}
}
#endif /* !FTDF_LITE */
#if FTDF_USE_SLEEP_DURING_BACKOFF
return ftdf_sdb_get_sleep_time();
#else /* FTDF_USE_SLEEP_DURING_BACKOFF */
return 0xffffffff;
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
}
ftdf_boolean_t ftdf_prepare_for_sleep(ftdf_usec_t sleep_time)
{
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
if (ftdf_pib.le_enabled || ftdf_pib.tsch_enabled) {
if (sleep_time < (2 * ftdf_low_power_clock_cycle_u_sec)) {
return FTDF_FALSE;
}
// Correct sleeptime with the inaccuracy of this function
sleep_time -= (2 * ftdf_low_power_clock_cycle_u_sec);
if (sleep_time < (ftdf_wake_up_latency_u_sec + 500)) {
return FTDF_FALSE;
}
}
#endif
ftdf_critical_var();
ftdf_enter_critical();
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
/* Capture the current value of both the event generator and the timestamp generator
and phase on the rising edge of LP_CLK */
REG_SETF(FTDF, FTDF_LMAC_CONTROL_OS_REG, GETGENERATORVAL, 1);
#endif
/* Save current LMAC PM counters */
ftdf_lmac_counters.fcs_error_cnt += REG_GETF(FTDF, FTDF_MACFCSERRORCOUNT_REG, MACFCSERRORCOUNT);
ftdf_lmac_counters.tx_std_ack_cnt += REG_GETF(FTDF, FTDF_MACTXSTDACKFRMCNT_REG, MACTXSTDACKFRMCNT);
ftdf_lmac_counters.rx_std_ack_cnt += REG_GETF(FTDF, FTDF_MACRXSTDACKFRMOKCNT_REG, MACRXSTDACKFRMOKCNT);
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
/* Wait until data is ready */
while (REG_GETF(FTDF, FTDF_LMAC_CONTROL_DELTA_REG, GETGENERATORVAL_E) == 0) {}
ftdf_event_curr_val = REG_GETF(FTDF, FTDF_EVENTCURRVAL_REG, EVENTCURRVAL);
ftdf_time_stamp_curr_val = REG_GETF(FTDF, FTDF_TIMESTAMPCURRVAL_REG, TIMESTAMPCURRVAL);
ftdf_time_stamp_curr_phase_val = REG_GETF(FTDF, FTDF_TIMESTAMPCURRPHASEVAL_REG, TIMESTAMPCURRPHASEVAL);
#ifdef SIMULATOR
REG_CLR_FIELD(FTDF, FTDF_LMAC_CONTROL_DELTA_REG, GETGENERATORVAL_E, FTDF->FTDF_LMAC_CONTROL_DELTA_REG);
#else
FTDF->FTDF_LMAC_CONTROL_DELTA_REG = REG_MSK(FTDF, FTDF_LMAC_CONTROL_DELTA_REG, GETGENERATORVAL_E);
#endif
uint64_t next_wake_up_thr;
#if FTDF_USE_SLEEP_DURING_BACKOFF
uint64_t pico_sleep_time = (uint64_t)sleep_time * 1000000;
next_wake_up_thr = ( pico_sleep_time - ftdf_wake_up_latency ) / ftdf_low_power_clock_cycle;
#else /* FTDF_USE_SLEEP_DURING_BACKOFF */
if (ftdf_pib.le_enabled || ftdf_pib.tsch_enabled) {
uint64_t picoSleepTime = (uint64_t)sleep_time * 1000000;
next_wake_up_thr = (picoSleepTime - ftdf_wake_up_latency) / ftdf_low_power_clock_cycle;
} else {
next_wake_up_thr = ftdf_csmaca_wakeup_thr;
}
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
/* Set wake up threshold */
uint32_t wake_up_int_thr = ftdf_event_curr_val + next_wake_up_thr;
/* Note that for IC revs other than A the size of WAKEUPINTTHR is 25 bits. */
REG_SETF(FTDF, FTDF_WAKEUP_CONTROL_REG, WAKEUPINTTHR, wake_up_int_thr);
REG_SETF(FTDF, FTDF_WAKEUP_CONTROL_REG, WAKEUPENABLE, 1);
#endif
ftdf_exit_critical();
return FTDF_TRUE;
}
void ftdf_wakeup(void)
{
#ifndef FTDF_PHY_API
ftdf_critical_var();
ftdf_enter_critical();
REG_SETF(FTDF, FTDF_WAKEUP_CONTROL_REG, WAKEUPENABLE, 0);
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
/* Capture the current value of both the event generator and the timestamp generator
and phase on the rising edge of LP_CLK */
REG_SETF(FTDF, FTDF_LMAC_CONTROL_OS_REG, GETGENERATORVAL, 1);
/* Wait until data is ready */
while (REG_GETF(FTDF, FTDF_LMAC_CONTROL_DELTA_REG, GETGENERATORVAL_E) == 0) {}
uint32_t event_new_curr_val = REG_GETF(FTDF, FTDF_EVENTCURRVAL_REG, EVENTCURRVAL);
#ifdef SIMULATOR
REG_CLR_FIELD(FTDF, FTDF_LMAC_CONTROL_DELTA_REG, GETGENERATORVAL_E);
#else
FTDF->FTDF_LMAC_CONTROL_DELTA_REG = REG_MSK(FTDF, FTDF_LMAC_CONTROL_DELTA_REG, GETGENERATORVAL_E);
#endif
/* Backward calculate the time slept */
/* ftdf_psec_t sleep_time = ((uint64_t)(event_new_curr_val - ftdf_event_curr_val) *
ftdf_low_power_clock_cycle) + ftdf_wake_up_latency; */
ftdf_psec_t sleep_time;
if (event_new_curr_val >= ftdf_event_curr_val) { /* Check for wraps. */
sleep_time = (event_new_curr_val - ftdf_event_curr_val) * ftdf_low_power_clock_cycle +
ftdf_wake_up_latency;
} else {
sleep_time = (event_new_curr_val +
(REG_MSK(FTDF, FTDF_EVENTCURRVAL_REG, EVENTCURRVAL) - ftdf_event_curr_val)) *
ftdf_low_power_clock_cycle + ftdf_wake_up_latency;
}
/* Calculate sync values */
uint64_t new_sync_vals = ((uint64_t)ftdf_time_stamp_curr_val << 8) |
(ftdf_time_stamp_curr_phase_val & 0xff);
new_sync_vals += (sleep_time / 62500) + 1;
uint32_t sync_timestamp_thr = ftdf_event_curr_val + (sleep_time / ftdf_low_power_clock_cycle);
uint32_t sync_timestamp_val = (new_sync_vals & 0xffffffff00) >> 8;
uint32_t sync_timestamp_phase_val = (new_sync_vals & 0xff);
/* Set values */
REG_SETF(FTDF, FTDF_SYNCTIMESTAMPTHR_REG, SYNCTIMESTAMPTHR, sync_timestamp_thr);
REG_SETF(FTDF, FTDF_SYNCTIMESTAMPVAL_REG, SYNCTIMESTAMPVAL, sync_timestamp_val);
REG_SETF(FTDF, FTDF_SYNCTIMESTAMPPHASEVAL_REG, SYNCTIMESTAMPPHASEVAL, sync_timestamp_phase_val);
REG_SETF(FTDF, FTDF_TIMER_CONTROL_1_REG, SYNCTIMESTAMPENA, 1);
#endif
ftdf_exit_critical();
#ifndef FTDF_NO_CSL
ftdf_wake_up_enable_le = ftdf_pib.le_enabled;
ftdf_pib.le_enabled = FTDF_FALSE;
#endif /* FTDF_NO_CSL */
#ifndef FTDF_NO_TSCH
ftdf_wake_up_enable_tsch = ftdf_pib.tsch_enabled;
ftdf_pib.tsch_enabled = FTDF_FALSE;
#endif /* FTDF_NO_TSCH */
#endif /* ! FTDF_PHY_API */
/* Init LMAC */
ftdf_init_lmac();
}
#endif /* CONFIG_USE_FTDF */

Some files were not shown because too many files have changed in this diff Show More