mirror of
https://github.com/espressif/openthread.git
synced 2026-09-13 04:30:08 +00:00
Added support for DA15000. (#919)
This commit is contained in:
committed by
Jonathan Hui
parent
a360f2e46e
commit
9c12733366
+11
-2
@@ -812,11 +812,11 @@ AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_APPLICATION_COAP],[${OPENTHREAD_ENABLE_APP
|
||||
|
||||
AC_ARG_WITH(examples,
|
||||
[AS_HELP_STRING([--with-examples=TARGET],
|
||||
[Specify the examples from one of: none, posix, cc2538 @<:@default=none@:>@.])],
|
||||
[Specify the examples from one of: none, posix, cc2538, da15000 @<:@default=none@:>@.])],
|
||||
[
|
||||
case "${with_examples}" in
|
||||
|
||||
none|posix|cc2538)
|
||||
none|posix|cc2538|da15000)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid value ${with_examples} for --with-examples])
|
||||
@@ -839,6 +839,10 @@ case ${with_examples} in
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_CC2538],[${OPENTHREAD_EXAMPLES_CC2538}],[Define to 1 if you want to use cc2538 examples])
|
||||
;;
|
||||
|
||||
da15000)
|
||||
OPENTHREAD_EXAMPLES_DA15000=1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
AC_MSG_RESULT(${OPENTHREAD_EXAMPLES})
|
||||
@@ -872,6 +876,10 @@ if test "$PLATFORM_INFO" != "none"; then
|
||||
AC_DEFINE_UNQUOTED([PLATFORM_INFO],["${PLATFORM_INFO}"],[OpenThread platform information])
|
||||
fi
|
||||
|
||||
AC_SUBST(OPENTHREAD_EXAMPLES_DA15000)
|
||||
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_DA15000], [test "${OPENTHREAD_EXAMPLES}" = "da15000"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_DA15000],[${OPENTHREAD_EXAMPLES_DA15000}],[Define to 1 if you want to use da15000 examples])
|
||||
|
||||
#
|
||||
# Tools
|
||||
#
|
||||
@@ -988,6 +996,7 @@ examples/apps/cli/Makefile
|
||||
examples/apps/ncp/Makefile
|
||||
examples/platforms/Makefile
|
||||
examples/platforms/cc2538/Makefile
|
||||
examples/platforms/da15000/Makefile
|
||||
examples/platforms/posix/Makefile
|
||||
examples/platforms/utils/Makefile
|
||||
tools/Makefile
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
configure_OPTIONS = \
|
||||
--enable-cli \
|
||||
--enable-ncp \
|
||||
--with-examples=da15000 \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(CLI_LOGGING),1)
|
||||
configure_OPTIONS += --enable-cli-logging
|
||||
endif
|
||||
|
||||
ifeq ($(CERT_LOG),1)
|
||||
configure_OPTIONS += --enable-cert-log
|
||||
endif
|
||||
|
||||
ifeq ($(COMMISSIONER),1)
|
||||
configure_OPTIONS += --enable-commissioner
|
||||
endif
|
||||
|
||||
ifeq ($(JOINER),1)
|
||||
configure_OPTIONS += --enable-joiner
|
||||
endif
|
||||
|
||||
ifeq ($(DHCP6_SERVER),1)
|
||||
configure_OPTIONS += --enable-dhcp6-server
|
||||
endif
|
||||
|
||||
ifeq ($(DHCP6_CLIENT),1)
|
||||
configure_OPTIONS += --enable-dhcp6-client
|
||||
endif
|
||||
|
||||
COMMONCFLAGS = \
|
||||
-fdata-sections \
|
||||
-ffunction-sections \
|
||||
-Os \
|
||||
-g \
|
||||
$(NULL)
|
||||
|
||||
CPPFLAGS = \
|
||||
$(COMMONCFLAGS) \
|
||||
$(target_CPPFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
CFLAGS = \
|
||||
$(COMMONCFLAGS) \
|
||||
$(target_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
CXXFLAGS = \
|
||||
$(COMMONCFLAGS) \
|
||||
$(target_CXXFLAGS) \
|
||||
-fno-exceptions \
|
||||
-fno-rtti \
|
||||
$(NULL)
|
||||
|
||||
LDFLAGS = \
|
||||
$(COMMONCFLAGS) \
|
||||
$(target_LDFLAGS) \
|
||||
-nostartfiles \
|
||||
-specs=nano.specs \
|
||||
-specs=nosys.specs \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,-Map=map.map \
|
||||
$(NULL)
|
||||
|
||||
ECHO := @echo
|
||||
MAKE := make
|
||||
MKDIR_P := mkdir -p
|
||||
LN_S := ln -s
|
||||
RM_F := rm -f
|
||||
|
||||
INSTALL := /usr/bin/install
|
||||
INSTALLFLAGS := -p
|
||||
|
||||
TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
|
||||
AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
|
||||
|
||||
BuildPath = build
|
||||
TopBuildDir = $(BuildPath)
|
||||
AbsTopBuildDir = $(PWD)/$(TopBuildDir)
|
||||
|
||||
ResultPath = output
|
||||
TopResultDir = $(ResultPath)
|
||||
AbsTopResultDir = $(PWD)/$(TopResultDir)
|
||||
|
||||
TargetTuple = arm-none-eabi
|
||||
|
||||
ARCHS = cortex-m0
|
||||
|
||||
TopTargetLibDir = $(TopResultDir)/$(if $(1),$(1)-,)$(TargetTuple)/lib
|
||||
|
||||
#
|
||||
# configure-arch <arch>
|
||||
#
|
||||
# Configure OpenThread for the specified architecture.
|
||||
#
|
||||
# arch - The architecture to configure.
|
||||
#
|
||||
define configure-arch
|
||||
$(ECHO) " CONFIG $(1)-$(TargetTuple)..."
|
||||
(cd $(BuildPath)/$(1)-$(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 \
|
||||
--target=arm-none-eabi \
|
||||
--prefix=/ \
|
||||
$(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 $(1)-$(TargetTuple)"
|
||||
$(MAKE) -C $(BuildPath)/$(1)-$(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 $(1)-$(TargetTuple)"
|
||||
$(MAKE) -C $(BuildPath)/$(1)-$(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)/$(1)-$(TargetTuple)
|
||||
DIRECTORIES += $(BuildPath)/$(1)-$(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)/$(1)-$(TargetTuple)/config.status
|
||||
|
||||
$(BuildPath)/$(1)-$(TargetTuple)/config.status: | $(BuildPath)/$(1)-$(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) ""
|
||||
@@ -78,6 +78,17 @@ LDFLAGS_COMMON += \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_EXAMPLES_CC2538
|
||||
|
||||
|
||||
if OPENTHREAD_EXAMPLES_DA15000
|
||||
LDADD_COMMON += \
|
||||
$(top_builddir)/examples/platforms/da15000/libopenthread-da15000.a \
|
||||
$(NULL)
|
||||
|
||||
LDFLAGS_COMMON += \
|
||||
-T $(top_srcdir)/examples/platforms/da15000/da15000.ld \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ot_cli_ftd_CPPFLAGS = \
|
||||
$(CPPFLAGS_COMMON) \
|
||||
$(NULL)
|
||||
|
||||
@@ -75,6 +75,16 @@ ot_ncp_LDFLAGS += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
if OPENTHREAD_EXAMPLES_DA15000
|
||||
ot_ncp_LDADD += \
|
||||
$(top_builddir)/examples/platforms/da15000/libopenthread-da15000.a \
|
||||
$(NULL)
|
||||
|
||||
ot_ncp_LDFLAGS += \
|
||||
-T $(top_srcdir)/examples/platforms/da15000/da15000.ld \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ot_ncp_SOURCES = \
|
||||
main.c \
|
||||
$(NULL)
|
||||
|
||||
@@ -32,6 +32,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
cc2538 \
|
||||
da15000 \
|
||||
posix \
|
||||
utils \
|
||||
$(NULL)
|
||||
@@ -50,10 +51,15 @@ if OPENTHREAD_EXAMPLES_CC2538
|
||||
SUBDIRS += cc2538
|
||||
endif
|
||||
|
||||
if OPENTHREAD_EXAMPLES_DA15000
|
||||
SUBDIRS = da15000
|
||||
endif
|
||||
|
||||
# Always pretty (e.g. for 'make pretty') these subdirectories.
|
||||
|
||||
PRETTY_SUBDIRS = \
|
||||
cc2538 \
|
||||
da15000 \
|
||||
posix \
|
||||
utils \
|
||||
$(NULL)
|
||||
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
libopenthread_da15000_a_CPPFLAGS = \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/examples/platforms \
|
||||
-I$(top_srcdir)/src/core \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/include \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/peripherals/include \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/adapters/include \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/memory/include \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/interfaces/ftdf/include \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/bsp/config \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK \
|
||||
-I$(top_srcdir)/third_party/dialog/DialogSDK/interfaces/ftdf/src \
|
||||
-include$(top_srcdir)/examples/platforms/da15000/custom_config_qspi.h \
|
||||
-Wno-unknown-pragmas \
|
||||
-Wno-sign-compare \
|
||||
-Wno-unused-function \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-shadow \
|
||||
-Wno-type-limits \
|
||||
-Wno-unused-variable \
|
||||
-Wno-missing-field-initializers \
|
||||
-fno-strict-aliasing \
|
||||
$(NULL)
|
||||
|
||||
|
||||
libopenthread_da15000_settings.cpp: $(srcdir)/../utils/settings.cpp
|
||||
cp $? $@
|
||||
|
||||
CLEANFILES = libopenthread_da15000_settings.cpp
|
||||
|
||||
libopenthread_da15000_a_SOURCES = \
|
||||
alarm.c \
|
||||
flash.c \
|
||||
logging.c \
|
||||
platform.c \
|
||||
radio.c \
|
||||
random.c \
|
||||
vector.c \
|
||||
cstartup.c \
|
||||
uart.c \
|
||||
cortex-m_cstartup.c \
|
||||
startup-gcc.c \
|
||||
libopenthread_da15000_settings.cpp \
|
||||
clock.c \
|
||||
misc.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/memory/src/qspi_automode.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_qspi.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_timer0.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_gpio.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_cpm.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_trng.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_rf.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_hard_fault.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/peripherals/src/hw_uart.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_otpc.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_fem_sky66112-11.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/bsp/peripherals/src/hw_dma.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/common.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/power.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/data.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf_phy_api.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/ad_ftdf.c \
|
||||
@top_builddir@/third_party/dialog/DialogSDK/interfaces/ftdf/src/main.c \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
platform-da15000.h \
|
||||
$(NULL)
|
||||
|
||||
if OPENTHREAD_BUILD_COVERAGE
|
||||
CLEANFILES += $(wildcard *.gcda *.gcno)
|
||||
endif # OPENTHREAD_BUILD_COVERAGE
|
||||
|
||||
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
# 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 NODE_ID in radio.c to a unique value.
|
||||
|
||||
## 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 -b uartboot.bin gdbserver write_qspi 0x0 ../../../output/bin/arm-none-eabi-ot-cli-ftd.img
|
||||
```
|
||||
|
||||
## 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: 9600 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
|
||||
```
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <platform/alarm.h>
|
||||
#include "hw_timer0.h"
|
||||
#include "hw_gpio.h"
|
||||
#include "platform-da15000.h"
|
||||
|
||||
static bool s_is_running = false;
|
||||
static uint32_t s_alarm = 0;
|
||||
static uint32_t s_counter;
|
||||
volatile bool s_alarm_fired = false;
|
||||
|
||||
static void timer0_interrupt_cb(void)
|
||||
{
|
||||
s_counter++;
|
||||
}
|
||||
|
||||
void da15000AlarmProcess(otInstance *aInstance)
|
||||
{
|
||||
if ((s_is_running) && (s_alarm <= s_counter))
|
||||
{
|
||||
s_is_running = false;
|
||||
otPlatAlarmFired(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 otPlatAlarmGetNow(void)
|
||||
{
|
||||
return s_counter;
|
||||
}
|
||||
|
||||
void otPlatAlarmStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
|
||||
{
|
||||
(void)aInstance;
|
||||
s_alarm = t0 + dt;
|
||||
s_is_running = true;
|
||||
|
||||
if (s_counter == 0)
|
||||
{
|
||||
hw_timer0_enable();
|
||||
}
|
||||
|
||||
|
||||
if (s_is_running == false)
|
||||
{
|
||||
s_is_running = true;
|
||||
}
|
||||
|
||||
hw_timer0_unfreeze();
|
||||
}
|
||||
|
||||
void otPlatAlarmStop(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
s_is_running = false;
|
||||
hw_timer0_freeze();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 clock.c
|
||||
* Clock init for Dialog da15000.
|
||||
*
|
||||
*/
|
||||
#include "global_io.h"
|
||||
#include "hw_cpm.h"
|
||||
#include "hw_watchdog.h"
|
||||
|
||||
volatile uint8_t xtal16_settled = 0;
|
||||
|
||||
extern void XTAL16RDY_Handler(void);
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions.
|
||||
DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT
|
||||
THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower
|
||||
numeric values on an ARM Cortex-M). */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1
|
||||
|
||||
void switch_to_rc16(void)
|
||||
{
|
||||
if (!hw_cpm_check_rc16_status()) // RC16 is disabled
|
||||
{
|
||||
hw_cpm_enable_rc16(); // Enable RC16
|
||||
hw_cpm_short_delay(); // Wait until it is stable
|
||||
}
|
||||
|
||||
// fast --> slow clock switch
|
||||
hw_cpm_set_sysclk(SYS_CLK_IS_RC16); // Set RC16 as sys_clk
|
||||
//cm_adjust_otp_access_timings(); // Adjust OTP timings
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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 cortex-m_cstartup.c
|
||||
* ARM Cortex-M generic cstartup.
|
||||
*
|
||||
* Setup RAM as needed based on GCC linker script sections.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
//#include <tool.h>
|
||||
#define __NAKED __attribute__((naked))
|
||||
#define __USED __attribute__((used))
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
// forward declaration
|
||||
extern void main(void);
|
||||
extern void __cpu_startup(void);
|
||||
extern void __gcc_program_start(void);
|
||||
|
||||
extern uint32_t __rwdata_start__; // End of .text region in FLASH
|
||||
extern uint32_t _sdata; // Start of .data region in RAM
|
||||
extern uint32_t _edata; // End of .data region in RAM
|
||||
|
||||
extern uint32_t __bss_start__;
|
||||
extern uint32_t __bss_end__;
|
||||
|
||||
extern uint32_t __init_array_start;
|
||||
extern uint32_t __init_array_end;
|
||||
|
||||
/********************************************************************/
|
||||
void cstartup_rwdata()
|
||||
{
|
||||
|
||||
// Get the addresses for the .data section (initialized data section)
|
||||
uint32_t *data_rom = (uint32_t *) &__rwdata_start__;
|
||||
uint32_t *data_ram = (uint32_t *) &_sdata;
|
||||
uint32_t *data_ram_end = (uint32_t *) &_edata;
|
||||
|
||||
// Copy initialized data from ROM to RAM
|
||||
while (data_ram < data_ram_end)
|
||||
{
|
||||
*data_ram++ = *data_rom++;
|
||||
}
|
||||
}
|
||||
|
||||
void cstartup_bss()
|
||||
{
|
||||
|
||||
/* Clear the zero-initialized data section */
|
||||
uint32_t *bss_start = (uint32_t *) &__bss_start__;
|
||||
uint32_t *bss_end = (uint32_t *) &__bss_end__;
|
||||
|
||||
while (bss_start < bss_end)
|
||||
{
|
||||
*bss_start++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cstartup(void)
|
||||
{
|
||||
cstartup_rwdata();
|
||||
cstartup_bss();
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/**
|
||||
* ARM Cortex-M Start
|
||||
*
|
||||
* This function calls all of the needed startup routines and then
|
||||
* branches to the main process.
|
||||
*
|
||||
* This contains the very first instructions that are run on boot.
|
||||
*/
|
||||
void __USED __NAKED __NO_RETURN __gcc_program_start(void)
|
||||
{
|
||||
// early platform initialization - configure clocks, etc.
|
||||
__cpu_startup();
|
||||
|
||||
// C/C++ runtime initialization (BSS, Data, relocation, etc.)
|
||||
cstartup();
|
||||
|
||||
// TBD we should pass parameters here.
|
||||
main();
|
||||
|
||||
// No actions to perform after this so wait forever
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 cstartup.c
|
||||
* cstartup for Dialog da15000.
|
||||
* Called by __BOOT_STARTUP to initialize the processor on boot.
|
||||
* The caller is aliased in tool.h to a compiler dependant value:
|
||||
* IAR: __low_level_init
|
||||
* GCC: __gcc_program_start
|
||||
*
|
||||
* For Cortex-M cores, called from cpu/arm/cortex-m/boot/cstartup.c.
|
||||
*/
|
||||
|
||||
#include "global_io.h"
|
||||
#include "bsp/include/black_orca.h"
|
||||
#include "bsp/include/core_cm0.h"
|
||||
|
||||
void __cpu_startup(void)
|
||||
{
|
||||
// SetWord16(CLK_AMBA_REG, 0x00); // set clocks (hclk and pclk ) 16MHz
|
||||
// SetWord16(SET_FREEZE_REG,FRZ_WDOG); // stop watchdog
|
||||
// SetBits16(SYS_CTRL_REG,PAD_LATCH_EN,1); // enable pads
|
||||
ENABLE_DEBUGGER; // enable debugger
|
||||
// SetBits16(PMU_CTRL_REG, PERIPH_SLEEP,0); // exit peripheral power down
|
||||
// SetBits16(PMU_CTRL_REG, RETAIN_RAM, dg_configMEM_RETENTION_MODE);
|
||||
// SetBits16(AON_SPARE_REG, EN_BATSYS_RET, 1); // Power GPIOs during sleep
|
||||
}
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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
|
||||
* Custom configuration file for FreeRTOS applications executing from QSPI.
|
||||
*/
|
||||
|
||||
#ifndef CUSTOM_CONFIG_QSPI_H_
|
||||
#define CUSTOM_CONFIG_QSPI_H_
|
||||
|
||||
#include "bsp_definitions.h"
|
||||
|
||||
#undef CONFIG_USE_BLE
|
||||
#define CONFIG_USE_FTDF
|
||||
|
||||
#define __HEAP_SIZE 0x0600
|
||||
#define __STACK_SIZE 0x0100
|
||||
|
||||
#define CONFIG_RETARGET
|
||||
#define CONFIG_RETARGET_UART HW_UART1
|
||||
|
||||
#define dg_configPOWER_CONFIG (POWER_CONFIGURATION_2)
|
||||
|
||||
#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_configMEM_RETENTION_MODE (0x1F)
|
||||
#define dg_configMEM_RETENTION_MODE_PRESERVE_IMAGE (0x1F)
|
||||
#define dg_configSHUFFLING_MODE (0x3)
|
||||
|
||||
#define dg_configUSE_WDOG (0)
|
||||
|
||||
#define dg_configUSE_DCDC (1)
|
||||
|
||||
#define dg_configPOWER_FLASH (1)
|
||||
#define dg_configFLASH_POWER_DOWN (0)
|
||||
#define dg_configFLASH_POWER_OFF (0)
|
||||
|
||||
#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_configCACHEABLE_QSPI_AREA_LEN NVMS_PARAM_PART_start
|
||||
|
||||
#define dg_configFEM_DLG_REF_BOARD (1)
|
||||
#define dg_configUSE_HW_TRNG (1)
|
||||
|
||||
#define dg_configUSE_HW_TIMER0 (1)
|
||||
|
||||
|
||||
/*************************************************************************************************\
|
||||
* OS specific config
|
||||
*/
|
||||
#define OS_BAREMETAL
|
||||
#define CPU_DA15000 (1)
|
||||
|
||||
/*************************************************************************************************\
|
||||
* Peripheral specific config
|
||||
*/
|
||||
#define FTDF_PHY_API
|
||||
#define dg_configUSE_HW_RF (1)
|
||||
#define dg_configRF_ENABLE_RECALIBRATION (0)
|
||||
#define FTDF_NO_CSL
|
||||
#define FTDF_NO_TSCH
|
||||
#define FTDF_LITE
|
||||
|
||||
#define dg_configFLASH_ADAPTER (0)
|
||||
#define dg_configNVMS_ADAPTER (0)
|
||||
#define dg_configNVMS_VES (0)
|
||||
#define dg_configUSE_WDOG (0)
|
||||
/* Include bsp default values */
|
||||
#include "bsp_defaults.h"
|
||||
|
||||
#endif /* CUSTOM_CONFIG_QSPI_H_ */
|
||||
Executable
+205
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Peripheral memory map */
|
||||
/******************************************************************************/
|
||||
_BOOTLOADER_SIZE = 0 ;
|
||||
_QSPI_SIZE = 2048K ; /* ld doesn't allow defines to be used for MEMORY */
|
||||
_EXE_SIZE = 108K ; /* In RAM config, reserve space for the executable... */
|
||||
_TEXT_START = 0x140 ;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
vector (rx) : ORIGIN = 0x00000000, LENGTH = 0x0C0
|
||||
magic (r) : ORIGIN = 0x000000C0, LENGTH = 0x080 /* patch table */
|
||||
flash (rx) : ORIGIN = 0x00000140, LENGTH = 2048K
|
||||
rom (rx) : ORIGIN = 0x07F00000, LENGTH = 256K
|
||||
otp (rx) : ORIGIN = 0x07F80000, LENGTH = 256K
|
||||
ram (rwx) : ORIGIN = 0x07FC0000+0x140, LENGTH = 128K-0x140
|
||||
cacheram (rwx) : ORIGIN = 0x07FE0000, LENGTH = 16K
|
||||
qspi (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
|
||||
}
|
||||
|
||||
/**
|
||||
* GCC linker script for ARM Cortex-M microcontrollers.
|
||||
*/
|
||||
|
||||
/*
|
||||
ENTRY(_start)
|
||||
*/
|
||||
ENTRY(__gcc_program_start)
|
||||
|
||||
/*
|
||||
* Reserve memory for heap and stack. The linker will issue an error if there
|
||||
* is not enough memory.
|
||||
*
|
||||
* NOTE: The reserved heap and stack will be added to the bss column of the
|
||||
* binutils size command.
|
||||
*/
|
||||
_heap_size = 0x0; /* required amount of heap */
|
||||
_stack_size = 0x0; /* required amount of stack */
|
||||
|
||||
/*
|
||||
* The stack starts at the end of RAM and grows downwards. Full-descending
|
||||
* stack; decrement first, then store.
|
||||
*/
|
||||
__stack_start__ = ORIGIN(ram) + LENGTH(ram);
|
||||
__stack_end__ = __stack_start__ - _stack_size;
|
||||
|
||||
EXTERN(__vector_table)
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Reset and ISR vectors */
|
||||
.isr_vector :
|
||||
{
|
||||
__isr_vector_start__ = .;
|
||||
__cs3_interrupt_vector = __vector_table;
|
||||
KEEP(*(.isr_vector))
|
||||
ASSERT(. != __isr_vector_start__, "The .isr_vector section is empty");
|
||||
} >vector
|
||||
|
||||
/* Special configuration section for some processors */
|
||||
.magic :
|
||||
{
|
||||
KEEP(*(.magic))
|
||||
} >magic
|
||||
|
||||
/* Text section (code and read-only data) */
|
||||
.text :
|
||||
{
|
||||
. = _TEXT_START;
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
*(.text*) /* code */
|
||||
_etext = .;
|
||||
|
||||
__rodata_start__ = .;
|
||||
*(.rodata*) /* read only data */
|
||||
|
||||
/*
|
||||
* Note: No ARM/Thumb interworking, so no .glue_7 or .glue_7t sections
|
||||
*/
|
||||
*(.ctors)
|
||||
*(.dtors)
|
||||
|
||||
/* Static constructors and destructors */
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
} >flash
|
||||
|
||||
|
||||
/*
|
||||
* Stack unwinding and exception handling sections.
|
||||
*
|
||||
* ARM compilers emit object files with .ARM.extab and .ARM.exidx sections
|
||||
* when using C++ exceptions. Also, at least GCC emits those sections when
|
||||
* dividing large numbers (64-bit) in C. So we have to handle them.
|
||||
*
|
||||
* (ARM uses .ARM.extab and .ARM.exidx instead of the .eh_frame section
|
||||
* used on x86.)
|
||||
*/
|
||||
.ARM.extab : /* exception unwinding information */
|
||||
{
|
||||
*(.ARM.extab*)
|
||||
} >flash
|
||||
.ARM.exidx : /* index entries for section unwinding */
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >flash
|
||||
|
||||
|
||||
/*
|
||||
* Initialized data section. This section is programmed into FLASH (LMA
|
||||
* address) and copied to RAM (VMA address) in startup code.
|
||||
*/
|
||||
. = ALIGN(4);
|
||||
__rwdata_start__ = .; /* LMA address is _sidata (in FLASH) */
|
||||
.data : AT(__rwdata_start__)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* data section VMA address */
|
||||
*(text_retained)
|
||||
. = ALIGN(4);
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >ram
|
||||
|
||||
|
||||
/* Uninitialized data section (zeroed out by startup code) */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
__end__ = .;
|
||||
} >ram
|
||||
|
||||
|
||||
/*
|
||||
* Reserve memory for heap and stack. The linker will issue an error if
|
||||
* there is not enough memory.
|
||||
*/
|
||||
._heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sheap = .;
|
||||
. = . + _heap_size;
|
||||
. = ALIGN(4);
|
||||
_eheap = .;
|
||||
} >ram
|
||||
|
||||
._stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. = . + _stack_size;
|
||||
. = ALIGN(4);
|
||||
} >ram
|
||||
|
||||
}
|
||||
|
||||
/* Nice to have */
|
||||
__isr_vector_size__ = SIZEOF(.isr_vector);
|
||||
__text_size__ = SIZEOF(.text);
|
||||
__data_size__ = SIZEOF(.data);
|
||||
__bss_size__ = SIZEOF(.bss);
|
||||
|
||||
PROVIDE (end = .);
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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-types.h>
|
||||
#include "hw_qspi.h"
|
||||
#include "qspi_automode.h"
|
||||
#include "platform/alarm.h"
|
||||
#include "openthread-config.h"
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
#define FLASH_PAGE_SIZE 0x0100
|
||||
#define FLASH_BUFFER_SIZE 0x2000 // 8kB
|
||||
#define FLASH_OFFSET 0x7B000 // Flash memory size is 512kB (0x7D000) and starts from 0x8000000. Offset point to 500kB position
|
||||
|
||||
#define W25Q_READ_STATUS_REGISTER1 0x05
|
||||
|
||||
/* Erase/Write in progress */
|
||||
#define W25Q_STATUS1_BUSY_BIT 0
|
||||
#define W25Q_STATUS1_BUSY_MASK (1 << W25Q_STATUS1_BUSY_BIT)
|
||||
|
||||
static uint32_t wait_status_timeout;
|
||||
|
||||
#define QSPI_SECTION __attribute__ ((section ("text_retained")))
|
||||
|
||||
QSPI_SECTION static inline uint8_t qspi_get_erase_status(void)
|
||||
{
|
||||
QSPIC->QSPIC_CHCKERASE_REG = 0;
|
||||
return HW_QSPIC_REG_GETF(ERASECTRL, ERS_STATE);
|
||||
}
|
||||
|
||||
// Erase QSPI memory section as non-blocking function. Remember to check utilsFlashStatusWait before write or read!!
|
||||
ThreadError utilsFlashErasePage(uint32_t aAddress)
|
||||
{
|
||||
|
||||
uint32_t flash_offset = (aAddress + FLASH_OFFSET) & ~(FLASH_SECTOR_SIZE - 1);
|
||||
|
||||
if (aAddress > FLASH_BUFFER_SIZE)
|
||||
{
|
||||
return kThreadError_InvalidArgs;
|
||||
}
|
||||
|
||||
/* Setup erase block page */
|
||||
HW_QSPIC_REG_SETF(ERASECTRL, ERS_ADDR, (flash_offset >>= 4));
|
||||
/* Fire erase */
|
||||
HW_QSPIC_REG_SETF(ERASECTRL, ERASE_EN, 1);
|
||||
|
||||
CACHE->CACHE_CTRL1_REG = CACHE_CACHE_CTRL1_REG_CACHE_FLUSH_Msk;
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
|
||||
uint32_t utilsFlashGetSize(void)
|
||||
{
|
||||
|
||||
return (uint32_t)FLASH_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
ThreadError utilsFlashStatusWait(uint32_t aTimeout)
|
||||
{
|
||||
|
||||
wait_status_timeout = otPlatAlarmGetNow();
|
||||
|
||||
while (qspi_get_erase_status() && ((otPlatAlarmGetNow() - wait_status_timeout) < aTimeout));
|
||||
|
||||
if (qspi_get_erase_status())
|
||||
{
|
||||
return kThreadError_Busy;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ThreadError utilsFlashInit(void)
|
||||
{
|
||||
|
||||
qspi_automode_init();
|
||||
qspi_automode_flash_power_up();
|
||||
|
||||
utilsFlashErasePage(0);
|
||||
utilsFlashErasePage(0x1000);
|
||||
|
||||
if (utilsFlashStatusWait(1000) == kThreadError_Busy)
|
||||
{
|
||||
return kThreadError_Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kThreadError_None;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
|
||||
{
|
||||
uint32_t flash_offset = (aAddress + FLASH_OFFSET);
|
||||
return flash_offset;
|
||||
}
|
||||
|
||||
|
||||
uint32_t utilsFlashWrite2(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
|
||||
{
|
||||
|
||||
uint32_t flash_offset = (aAddress + FLASH_OFFSET);
|
||||
size_t offset = 0;
|
||||
size_t written;
|
||||
|
||||
while (flash_offset < (aAddress + FLASH_OFFSET) + aSize)
|
||||
{
|
||||
qspi_automode_erase_flash_sector(flash_offset);
|
||||
flash_offset += FLASH_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
flash_offset = (aAddress + FLASH_OFFSET);
|
||||
|
||||
while (offset < aSize)
|
||||
{
|
||||
written = qspi_automode_write_flash_page(flash_offset + offset, aData + offset,
|
||||
aSize - offset);
|
||||
offset += written;
|
||||
}
|
||||
|
||||
return flash_offset;
|
||||
}
|
||||
|
||||
uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
|
||||
{
|
||||
|
||||
size_t written = 0;
|
||||
size_t offset = 0;
|
||||
uint32_t flash_offset = (aAddress + FLASH_OFFSET);
|
||||
|
||||
memcpy(aData, (void *)(MEMORY_QSPIF_BASE + flash_offset), aSize);
|
||||
|
||||
return aSize;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 <platform/logging.h>
|
||||
|
||||
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
|
||||
{
|
||||
(void)aLogLevel;
|
||||
(void)aLogRegion;
|
||||
(void)aFormat;
|
||||
}
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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/misc.h>
|
||||
#include <openthread-types.h>
|
||||
#include "black_orca.h"
|
||||
|
||||
void otPlatReset(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
WDOG->WATCHDOG_CTRL_REG |= (1 << (WDOG_WATCHDOG_CTRL_REG_NMI_RST_Pos));
|
||||
}
|
||||
|
||||
otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return kPlatResetReason_PowerOn;
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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-types.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_ */
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread.h>
|
||||
#include "platform/alarm.h"
|
||||
#include <openthread-types.h>
|
||||
#include "platform-da15000.h"
|
||||
#include "black_orca.h"
|
||||
#include "hw_cpm.h"
|
||||
#include "hw_watchdog.h"
|
||||
#include "ftdf.h"
|
||||
#include "hw_gpio.h"
|
||||
#include "platform/uart.h"
|
||||
|
||||
static bool blink = false;
|
||||
static int mscounter_init;
|
||||
static int mscounter;
|
||||
|
||||
#define LEADER_BLINK_TIME (200)
|
||||
#define ROUTER_BLINK_TIME (500)
|
||||
#define CHILD_BLINK_TIME (2000)
|
||||
|
||||
|
||||
otInstance *sInstance;
|
||||
|
||||
|
||||
void ClkInit(void)
|
||||
{
|
||||
|
||||
NVIC_ClearPendingIRQ(XTAL16RDY_IRQn);
|
||||
NVIC_EnableIRQ(XTAL16RDY_IRQn); // Activate XTAL16 Ready IRQ
|
||||
hw_cpm_set_divn(false); // External crystal is 16MHz
|
||||
hw_cpm_enable_rc32k();
|
||||
hw_cpm_lp_set_rc32k();
|
||||
hw_cpm_set_xtal16m_settling_time(dg_configXTAL16_SETTLE_TIME_RC32K);
|
||||
hw_cpm_enable_xtal16m(); // Enable XTAL16M
|
||||
hw_cpm_configure_xtal32k_pins(); // Configure XTAL32K pins
|
||||
hw_cpm_configure_xtal32k(); // Configure XTAL32K
|
||||
hw_cpm_enable_xtal32k(); // Enable XTAL32K
|
||||
hw_watchdog_unfreeze(); // Start watchdog
|
||||
|
||||
while (!hw_cpm_is_xtal16m_started()); // Block until XTAL16M starts
|
||||
|
||||
hw_watchdog_freeze(); // Stop watchdog
|
||||
hw_cpm_set_recharge_period((uint16_t)dg_configSET_RECHARGE_PERIOD);
|
||||
hw_cpm_set_sysclk(SYS_CLK_IS_XTAL16M);
|
||||
hw_cpm_set_hclk_div(0);
|
||||
hw_cpm_set_pclk_div(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Example function. Blink LED according to node state
|
||||
* Leader - 5Hz
|
||||
* Router - 2Hz
|
||||
* Child - 0.5Hz
|
||||
*/
|
||||
|
||||
void ExampleProcess(otInstance *aInstance)
|
||||
{
|
||||
otDeviceRole devRole;
|
||||
static int thrValue;
|
||||
|
||||
devRole = otGetDeviceRole(aInstance);
|
||||
|
||||
if (blink == false && otPlatAlarmGetNow() != 0)
|
||||
{
|
||||
mscounter_init = otPlatAlarmGetNow();
|
||||
blink = true;
|
||||
}
|
||||
|
||||
mscounter = otPlatAlarmGetNow() - mscounter_init;
|
||||
|
||||
switch (devRole)
|
||||
{
|
||||
case kDeviceRoleLeader:
|
||||
thrValue = LEADER_BLINK_TIME;
|
||||
break;
|
||||
|
||||
case kDeviceRoleRouter:
|
||||
thrValue = ROUTER_BLINK_TIME;
|
||||
break;
|
||||
|
||||
case kDeviceRoleChild:
|
||||
thrValue = CHILD_BLINK_TIME;
|
||||
break;
|
||||
|
||||
default:
|
||||
thrValue = 0x00;
|
||||
}
|
||||
|
||||
if ((thrValue != 0x00) && (mscounter >= thrValue))
|
||||
{
|
||||
hw_gpio_toggle(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
|
||||
mscounter_init = otPlatAlarmGetNow();
|
||||
}
|
||||
|
||||
if (thrValue == 0)
|
||||
{
|
||||
hw_gpio_set_inactive(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PlatformInit(int argc, char *argv[])
|
||||
{
|
||||
// Initialize System Clock
|
||||
ClkInit();
|
||||
// Initialize Random number generator
|
||||
da15000RandomInit();
|
||||
// Initialize Alarm
|
||||
da15000AlarmInit();
|
||||
// Initialize Radio
|
||||
da15000RadioInit();
|
||||
// Initialize UART
|
||||
otPlatUartEnable();
|
||||
// enable interrupts
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
}
|
||||
|
||||
|
||||
void PlatformProcessDrivers(otInstance *aInstance)
|
||||
{
|
||||
sInstance = aInstance;
|
||||
|
||||
da15000AlarmProcess(aInstance);
|
||||
da15000UartProcess();
|
||||
da15000RadioProcess(aInstance);
|
||||
ExampleProcess(aInstance);
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
* 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 <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <common/code_utils.hpp>
|
||||
#include <platform/alarm.h>
|
||||
#include <platform/radio.h>
|
||||
#include <openthread.h>
|
||||
#include "platform-da15000.h"
|
||||
|
||||
#define DEBUG_LOG_ENABLE (0)
|
||||
|
||||
#include <ftdf.h>
|
||||
#include <ad_ftdf.h>
|
||||
#include "ad_ftdf_phy_api.h"
|
||||
#include "hw_rf.h"
|
||||
#include <global_io.h>
|
||||
#include <regmap.h>
|
||||
#include "black_orca.h"
|
||||
#include "core_cm0.h"
|
||||
#include "internal.h"
|
||||
#include <hw_uart.h>
|
||||
|
||||
typedef struct __attribute__((packed)) RadioMessage
|
||||
{
|
||||
uint8_t mChannel;
|
||||
uint8_t mPsdu[kMaxPHYPacketSize];
|
||||
} RadioMessage;
|
||||
|
||||
static PhyState s_state = kStateDisabled;
|
||||
static RadioMessage s_receive_message;
|
||||
static RadioMessage s_transmit_message;
|
||||
static RadioMessage s_ack_message;
|
||||
static RadioPacket s_receive_frame;
|
||||
static RadioPacket s_transmit_frame;
|
||||
static RadioPacket s_ack_frame;
|
||||
static bool s_data_pending = false;
|
||||
static bool SendFrameDone = false;
|
||||
static uint8_t s_extended_address[OT_EXT_ADDRESS_SIZE];
|
||||
static uint16_t s_short_address;
|
||||
static uint16_t s_panid;
|
||||
|
||||
//static int s_sockfd;
|
||||
|
||||
static bool s_promiscuous = false;
|
||||
|
||||
static uint8_t sleep_init_delay = 0;
|
||||
static bool SED = false;
|
||||
static uint32_t sleep_const_delay;
|
||||
|
||||
static otInstance *First_Instace;
|
||||
uint32_t NODE_ID = 1;
|
||||
|
||||
#define DEFAULT_CHANNEL (11)
|
||||
#define FTDF_OFFSET_CHANNEL (11)
|
||||
|
||||
void disable_interrupt()
|
||||
{
|
||||
NVIC_DisableIRQ(FTDF_GEN_IRQn);
|
||||
}
|
||||
|
||||
void enable_interrupt()
|
||||
{
|
||||
NVIC_ClearPendingIRQ(FTDF_GEN_IRQn);
|
||||
NVIC_EnableIRQ(FTDF_GEN_IRQn);
|
||||
}
|
||||
|
||||
|
||||
void phy_power_init()
|
||||
{
|
||||
// Set the radio_ldo voltage to 1.4 Volts
|
||||
REG_SETF(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_SETVDD, 2);
|
||||
// Switch on the RF LDO
|
||||
REG_SETF(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_ENABLE, 1);
|
||||
hw_rf_poweron();
|
||||
}
|
||||
|
||||
|
||||
void ad_ftdf_init_phy_api_V2(void)
|
||||
{
|
||||
NVIC_ClearPendingIRQ(FTDF_WAKEUP_IRQn);
|
||||
NVIC_EnableIRQ(FTDF_WAKEUP_IRQn);
|
||||
|
||||
NVIC_ClearPendingIRQ(FTDF_GEN_IRQn);
|
||||
NVIC_EnableIRQ(FTDF_GEN_IRQn);
|
||||
|
||||
volatile uint32_t *lmacReset = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMACRESET);
|
||||
*lmacReset = MSK_R_FTDF_ON_OFF_REGMAP_LMACRESET;
|
||||
|
||||
volatile uint32_t *controlStatus = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_STATUS);
|
||||
|
||||
while ((*controlStatus & MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP) == 0) {}
|
||||
|
||||
volatile uint32_t *wakeupTimerEnableStatus = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS);
|
||||
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPTIMERENABLE, 0);
|
||||
|
||||
while (*wakeupTimerEnableStatus & MSK_F_FTDF_ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS) {}
|
||||
|
||||
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPTIMERENABLE, 1);
|
||||
|
||||
while ((*wakeupTimerEnableStatus & MSK_F_FTDF_ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS) == 0) {}
|
||||
}
|
||||
|
||||
void ad_ftdf_init_lmac()
|
||||
{
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_CCAIDLEWAIT, 192);
|
||||
volatile uint32_t *txFlagClear = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_CLEAR);
|
||||
*txFlagClear = MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR;
|
||||
|
||||
volatile uint32_t *phyParams = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_PHY_PARAMETERS_2);
|
||||
*phyParams = (FTDF_PHYTXSTARTUP << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXSTARTUP) |
|
||||
(FTDF_PHYTXLATENCY << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXLATENCY) |
|
||||
(FTDF_PHYTXFINISH << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXFINISH) |
|
||||
(FTDF_PHYTRXWAIT << OFF_F_FTDF_ON_OFF_REGMAP_PHYTRXWAIT);
|
||||
|
||||
phyParams = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_PHY_PARAMETERS_3);
|
||||
*phyParams = (FTDF_PHYRXSTARTUP << OFF_F_FTDF_ON_OFF_REGMAP_PHYRXSTARTUP) |
|
||||
(FTDF_PHYRXLATENCY << OFF_F_FTDF_ON_OFF_REGMAP_PHYRXLATENCY) |
|
||||
(FTDF_PHYENABLE << OFF_F_FTDF_ON_OFF_REGMAP_PHYENABLE);
|
||||
|
||||
volatile uint32_t *ftdfCm = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CM);
|
||||
*ftdfCm = FTDF_MSK_TX_CE | FTDF_MSK_RX_CE | FTDF_MSK_SYMBOL_TMR_CE;
|
||||
|
||||
volatile uint32_t *rxMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_RX_MASK);
|
||||
*rxMask = MSK_R_FTDF_ON_OFF_REGMAP_RX_MASK;
|
||||
|
||||
volatile uint32_t *lmacMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_MASK);
|
||||
*lmacMask = MSK_F_FTDF_ON_OFF_REGMAP_RXTIMEREXPIRED_M;
|
||||
|
||||
volatile uint32_t *lmacCtrlMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_MASK);
|
||||
*lmacCtrlMask = MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIMETHR_M |
|
||||
MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIME2THR_M |
|
||||
MSK_F_FTDF_ON_OFF_REGMAP_SYNCTIMESTAMP_M;
|
||||
|
||||
volatile uint32_t *txFlagClearM;
|
||||
txFlagClearM = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_M, FTDF_TX_DATA_BUFFER);
|
||||
*txFlagClearM |= MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_M;
|
||||
txFlagClearM = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_M, FTDF_TX_WAKEUP_BUFFER);
|
||||
*txFlagClearM |= MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_M;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
s_panid = panid;
|
||||
FTDF_setValue(FTDF_PIB_PAN_ID, &panid);
|
||||
}
|
||||
|
||||
void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *address)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
for (unsigned i = 0; i < sizeof(s_extended_address); i++)
|
||||
{
|
||||
s_extended_address[i] = address[i];
|
||||
}
|
||||
|
||||
FTDF_setValue(FTDF_PIB_EXTENDED_ADDRESS, s_extended_address);
|
||||
}
|
||||
|
||||
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
s_short_address = address;
|
||||
FTDF_setValue(FTDF_PIB_SHORT_ADDRESS, &address);
|
||||
}
|
||||
|
||||
|
||||
void da15000RadioInit(void)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
phy_power_init();
|
||||
hw_rf_system_init();
|
||||
hw_rf_set_recommended_settings();
|
||||
hw_rf_iff_calibration();
|
||||
|
||||
hw_rf_modulation_gain_calibration(0); //RF MODE 0
|
||||
hw_rf_dc_offset_calibration();
|
||||
|
||||
// ad_ftdf_init_phy_api();
|
||||
FTDF_pib.CCAMode = 2;
|
||||
ad_ftdf_init_phy_api_V2();
|
||||
ad_ftdf_init_lmac();
|
||||
}
|
||||
|
||||
|
||||
ThreadError otPlatRadioEnable(otInstance *aInstance)
|
||||
{
|
||||
First_Instace = aInstance;
|
||||
(void)aInstance;
|
||||
ThreadError error = kThreadError_None;
|
||||
uint16_t DefaultChannel = DEFAULT_CHANNEL;
|
||||
uint8_t value = 1;
|
||||
|
||||
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &value); //Wake();
|
||||
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &DefaultChannel); //SetChannel(channel);
|
||||
|
||||
uint32_t max_retries = 0;
|
||||
FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &max_retries);
|
||||
|
||||
FTDF_Bitmap32 options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
|
||||
options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
|
||||
options |= FTDF_TRANSPARENT_AUTO_ACK;
|
||||
|
||||
FTDF_enableTransparentMode(FTDF_TRUE, options);
|
||||
otPlatRadioSetPromiscuous(aInstance, false);
|
||||
|
||||
s_receive_frame.mPsdu = s_receive_message.mPsdu;
|
||||
s_transmit_frame.mPsdu = s_transmit_message.mPsdu;
|
||||
s_ack_frame.mPsdu = s_ack_message.mPsdu;
|
||||
s_state = kStateReceive;
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioDisable(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
s_state = kStateDisabled;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
bool otPlatRadioIsEnabled(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return (s_state != kStateDisabled);
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioSleep(otInstance *aInstance)
|
||||
{
|
||||
ThreadError error = kThreadError_Busy;
|
||||
(void)aInstance;
|
||||
|
||||
|
||||
if (s_state == kStateReceive && sleep_init_delay == 0)
|
||||
{
|
||||
sleep_init_delay = otPlatAlarmGetNow();
|
||||
return kThreadError_None; //error;
|
||||
}
|
||||
else if ((otPlatAlarmGetNow() - sleep_init_delay) < 3000)
|
||||
{
|
||||
return kThreadError_None; //error;
|
||||
}
|
||||
|
||||
if (s_state == kStateSleep || s_state == kStateReceive)
|
||||
{
|
||||
error = kThreadError_None;
|
||||
SED = true;
|
||||
sleep_const_delay = otPlatAlarmGetNow();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
(void)aInstance;
|
||||
|
||||
#if DEBUG_LOG_ENABLE
|
||||
hw_uart_write_buffer(HW_UART1, "\nR", 2);
|
||||
#endif
|
||||
VerifyOrExit(s_state != kStateDisabled, error = kThreadError_Busy);
|
||||
s_state = kStateReceive;
|
||||
s_receive_frame.mChannel = aChannel;
|
||||
|
||||
uint32_t phyAckAttr;
|
||||
phyAckAttr = 0x08 | ((aChannel - FTDF_OFFSET_CHANNEL) & 0xf) << 4;
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_PHYRXATTR, (((aChannel - FTDF_OFFSET_CHANNEL) & 0xf) << 4));
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_PHYACKATTR, phyAckAttr);
|
||||
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_RXALWAYSON, 1);
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 1);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return &s_transmit_frame;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
(void)aInstance;
|
||||
|
||||
FTDF_Boolean csmaSuppress = 0;
|
||||
VerifyOrExit(s_state == kStateReceive, error = kThreadError_Busy);
|
||||
|
||||
ad_ftdf_send_frame_simple(aPacket->mLength, aPacket->mPsdu, aPacket->mChannel, 0, csmaSuppress); //Prio 0 for all.
|
||||
s_state = kStateTransmit;
|
||||
s_data_pending = false;
|
||||
#if DEBUG_LOG_ENABLE
|
||||
hw_uart_write_buffer(HW_UART1, "\nT", 2);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return 0;
|
||||
}
|
||||
|
||||
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return kRadioCapsNone;
|
||||
}
|
||||
|
||||
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
(void)aInstance;
|
||||
uint8_t value;
|
||||
value = aEnable;
|
||||
FTDF_setValue(FTDF_PIB_PROMISCUOUS_MODE, &value);
|
||||
s_promiscuous = aEnable;
|
||||
}
|
||||
|
||||
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return s_promiscuous;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioHandleTransmitDone(bool *rxPending)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
VerifyOrExit(s_state == kStateTransmit, error = kThreadError_InvalidState);
|
||||
|
||||
s_state = kStateReceive;
|
||||
|
||||
if (rxPending != NULL)
|
||||
{
|
||||
*rxPending = s_data_pending;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status)
|
||||
{
|
||||
(void)handle;
|
||||
(void)status;
|
||||
volatile uint32_t *txStatus = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_RETURN_STATUS_1, FTDF_TX_DATA_BUFFER);
|
||||
|
||||
SendFrameDone = true;
|
||||
|
||||
#if DEBUG_LOG_ENABLE
|
||||
hw_uart_write_buffer(HW_UART1, "\nTD", 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void da15000RadioProcess(otInstance *aInstance)
|
||||
{
|
||||
bool rxPending;
|
||||
uint8_t bufferForFTDFconfigValue = 0;
|
||||
|
||||
if (SendFrameDone)
|
||||
{
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 1);
|
||||
otPlatRadioHandleTransmitDone(&rxPending);
|
||||
otPlatRadioTransmitDone(aInstance, &s_transmit_frame, false, kThreadError_None);
|
||||
SendFrameDone = false;
|
||||
}
|
||||
|
||||
if ((SED) && ((otPlatAlarmGetNow() - sleep_const_delay) > 100))
|
||||
{
|
||||
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &bufferForFTDFconfigValue);
|
||||
s_state = kStateSleep;
|
||||
SED = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
|
||||
FTDF_Octet *frame,
|
||||
FTDF_Bitmap32 status,
|
||||
FTDF_LinkQuality lqi)
|
||||
{
|
||||
(void)status;
|
||||
RadioPacket otRadioPacket;
|
||||
|
||||
#if DEBUG_LOG_ENABLE
|
||||
char buff[10];
|
||||
sprintf(buff, "\nlq:%d", lqi);
|
||||
hw_uart_write_buffer(HW_UART1, buff, 5);
|
||||
#endif
|
||||
|
||||
otRadioPacket.mPower = kPhyInvalidRssi;
|
||||
otRadioPacket.mLqi = lqi;
|
||||
|
||||
if (s_receive_frame.mChannel == 0)
|
||||
{
|
||||
s_receive_frame.mChannel = DEFAULT_CHANNEL;
|
||||
}
|
||||
|
||||
otRadioPacket.mChannel = s_receive_frame.mChannel;
|
||||
otRadioPacket.mLength = frameLength;
|
||||
otRadioPacket.mPsdu = frame;
|
||||
|
||||
otPlatRadioReceiveDone(First_Instace, &otRadioPacket, kThreadError_None);
|
||||
|
||||
if (s_state != kStateDisabled)
|
||||
{
|
||||
s_state = kStateReceive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
|
||||
{
|
||||
(void)aInstance;
|
||||
aIeeeEui64[0] = 0x80; //80-EA-CA is for Dialog Semiconductor
|
||||
aIeeeEui64[1] = 0xEA;
|
||||
aIeeeEui64[2] = 0xCA;
|
||||
aIeeeEui64[3] = 0x00;
|
||||
aIeeeEui64[4] = (NODE_ID >> 24) & 0xff;
|
||||
aIeeeEui64[5] = (NODE_ID >> 16) & 0xff;
|
||||
aIeeeEui64[6] = (NODE_ID >> 8) & 0xff;
|
||||
aIeeeEui64[7] = NODE_ID & 0xff;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
|
||||
{
|
||||
ThreadError error = kThreadError_NotImplemented;
|
||||
(void)aInstance;
|
||||
(void)aScanChannel;
|
||||
(void)aScanDuration;
|
||||
return error;
|
||||
}
|
||||
|
||||
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
|
||||
(void)aInstance;
|
||||
(void)aEnable;
|
||||
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
||||
{
|
||||
|
||||
ThreadError error = kThreadError_NotImplemented;
|
||||
(void)aInstance;
|
||||
(void)aShortAddress;
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
||||
{
|
||||
|
||||
ThreadError error = kThreadError_NotImplemented;
|
||||
(void)aInstance;
|
||||
(void)aExtAddress;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
||||
{
|
||||
|
||||
ThreadError error = kThreadError_NotImplemented;
|
||||
(void)aInstance;
|
||||
(void)aShortAddress;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
||||
{
|
||||
|
||||
ThreadError error = kThreadError_NotImplemented;
|
||||
(void)aExtAddress;
|
||||
(void)aInstance;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
|
||||
{
|
||||
|
||||
(void)aInstance;
|
||||
}
|
||||
|
||||
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
|
||||
{
|
||||
|
||||
(void)aInstance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 a pseudo-random number generator.
|
||||
*
|
||||
* @warning
|
||||
* This implementation is not a true random number generator and does @em satisfy the Thread requirements.
|
||||
*/
|
||||
|
||||
#include <platform/random.h>
|
||||
#include "platform-da15000.h"
|
||||
#include "black_orca.h"
|
||||
#include "hw_trng.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
#define HW_TRNG_RAM (0x40040000)
|
||||
|
||||
static uint32_t s_state = 1;
|
||||
static uint32_t seed;
|
||||
|
||||
int zhal_get_entropy(uint8_t *outEntropy, size_t inSize)
|
||||
{
|
||||
uint32_t randword;
|
||||
unsigned char *pbuf = outEntropy;
|
||||
const size_t req_words = inSize >> 2;
|
||||
const unsigned char *pbuf_end = outEntropy + inSize;
|
||||
const unsigned char *preq_words_end = (unsigned char *)(((uint32_t *)outEntropy) + req_words);
|
||||
ptrdiff_t remainder_bytes = pbuf_end - preq_words_end;
|
||||
|
||||
hw_trng_enable(NULL);
|
||||
|
||||
for (pbuf = outEntropy; pbuf < preq_words_end; pbuf += 4)
|
||||
{
|
||||
/* Wait for a random word to become available in the TRNG FIFO. */
|
||||
while ((TRNG->TRNG_FIFOLVL_REG & TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOLVL_Msk) == 0);
|
||||
|
||||
randword = *((volatile uint32_t *)HW_TRNG_RAM);
|
||||
memcpy(pbuf, &randword, 4);
|
||||
}
|
||||
|
||||
if (remainder_bytes)
|
||||
{
|
||||
while ((TRNG->TRNG_FIFOLVL_REG & TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOLVL_Msk) == 0);
|
||||
|
||||
randword = *((volatile uint32_t *)HW_TRNG_RAM);
|
||||
memcpy(pbuf, &randword, remainder_bytes);
|
||||
}
|
||||
|
||||
hw_trng_disable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void da15000RandomInit(void)
|
||||
{
|
||||
zhal_get_entropy((uint8_t *)&seed, sizeof(seed));
|
||||
s_state = seed;
|
||||
}
|
||||
|
||||
uint32_t otPlatRandomGet(void)
|
||||
{
|
||||
uint32_t mlcg;
|
||||
zhal_get_entropy((uint8_t *)&mlcg, sizeof(mlcg));
|
||||
return mlcg;
|
||||
}
|
||||
|
||||
ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength)
|
||||
{
|
||||
|
||||
for (uint16_t length = 0; length < aInputLength; length++)
|
||||
{
|
||||
aOutput[length] = (uint8_t)otPlatRandomGet();
|
||||
}
|
||||
|
||||
*aOutputLength = aInputLength;
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Stubs out exception handling and general C++ bloat
|
||||
* for suitability for embedded environments.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
__extension__ typedef int __guard __attribute__((mode(__DI__)));
|
||||
extern int __cxa_guard_acquire(__guard *g);
|
||||
extern void __cxa_guard_release(__guard *g);
|
||||
extern void __cxa_guard_abort(__guard *g);
|
||||
extern void __cxa_pure_virtual(void);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void *__dso_handle;
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <hw_uart.h>
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <platform/uart.h>
|
||||
#include "hw_gpio.h"
|
||||
#include "platform-da15000.h"
|
||||
|
||||
static int s_in_fd;
|
||||
static int s_out_fd;
|
||||
void UartBuffClear(void);
|
||||
|
||||
ThreadError otPlatUartEnable(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uart_config uart_init =
|
||||
{
|
||||
.baud_rate = HW_UART_BAUDRATE_9600,
|
||||
.data = HW_UART_DATABITS_8,
|
||||
.stop = HW_UART_STOPBITS_1,
|
||||
.parity = HW_UART_PARITY_NONE,
|
||||
.use_dma = 0,
|
||||
.use_fifo = 1,
|
||||
.rx_dma_channel = HW_DMA_CHANNEL_0,
|
||||
.tx_dma_channel = HW_DMA_CHANNEL_1,
|
||||
};
|
||||
|
||||
hw_uart_init(CONFIG_RETARGET_UART, &uart_init);
|
||||
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_3,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_UART_TX);
|
||||
hw_gpio_set_pin_function(HW_GPIO_PORT_2, HW_GPIO_PIN_3,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_UART_RX);
|
||||
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_5, HW_GPIO_MODE_OUTPUT,
|
||||
HW_GPIO_FUNC_GPIO);
|
||||
UartBuffClear();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError otPlatUartDisable(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
close(s_in_fd);
|
||||
close(s_out_fd);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void da15000UartProcess(void)
|
||||
{
|
||||
uint8_t aBuf;
|
||||
|
||||
// Wait until received data are available
|
||||
if (hw_uart_read_buf_empty(HW_UART1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Read element from the receive FIFO
|
||||
aBuf = UBA(HW_UART1)->UART2_RBR_THR_DLL_REG;
|
||||
otPlatUartReceived(&aBuf, 1);
|
||||
}
|
||||
|
||||
|
||||
void UartBuffClear(void)
|
||||
{
|
||||
|
||||
volatile uint8_t aBuf;
|
||||
|
||||
while (hw_uart_read_buf_empty(HW_UART1) == 0)
|
||||
{
|
||||
aBuf += UBA(HW_UART1)->UART2_RBR_THR_DLL_REG;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ThreadError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
hw_uart_write_buffer(HW_UART1, aBuf, aBufLength);
|
||||
|
||||
otPlatUartSendDone();
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* 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 cpu/dialog/da15000/boot/vector.c
|
||||
* CpuIrq_da15x -- IRQ driver for ARM Cortex-M series cores.
|
||||
*
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
#pragma location=".isr_vector"
|
||||
|
||||
#define __WEAK __attribute__((weak))
|
||||
#define __USED __attribute__((used))
|
||||
#define __BOOT_VECTOR __attribute__ ((section(".isr_vector")))
|
||||
#define __BOOT_STACK &__stack_start__
|
||||
#define __BOOT_STARTUP __gcc_program_start
|
||||
|
||||
typedef void (*irq_handler_t)(void);
|
||||
extern unsigned int __stack_start__[];
|
||||
extern void __gcc_program_start(void);
|
||||
|
||||
/// Declaration of default interrupt service routine
|
||||
static void halt_isr(void)
|
||||
{
|
||||
__asm("BKPT 255");
|
||||
|
||||
while (1);
|
||||
}
|
||||
static void default_isr(void)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* The kernel interrupts - in their CMSIS form.
|
||||
These must be implemented locally, or compiler will
|
||||
give conflicting definition for __vector_table.
|
||||
*/
|
||||
__WEAK void NMI_Handler() { }
|
||||
__WEAK void HardFault_Handler()
|
||||
{
|
||||
halt_isr();
|
||||
}
|
||||
__WEAK void SVC_Handler()
|
||||
{
|
||||
halt_isr();
|
||||
}
|
||||
__WEAK void PendSV_Handler()
|
||||
{
|
||||
halt_isr();
|
||||
}
|
||||
__WEAK void SysTick_Handler()
|
||||
{
|
||||
halt_isr();
|
||||
}
|
||||
|
||||
__WEAK void MemManage_Handler()
|
||||
{
|
||||
halt_isr();
|
||||
}
|
||||
__WEAK void DebugMon_Handler()
|
||||
{
|
||||
halt_isr();
|
||||
}
|
||||
__WEAK void BusFault_Handler()
|
||||
{
|
||||
halt_isr();
|
||||
}
|
||||
|
||||
/* Default handlers for other DA15X peripheral interrupts. */
|
||||
__WEAK void DEBUG_IRQHandler()
|
||||
{
|
||||
default_isr();
|
||||
}
|
||||
|
||||
|
||||
__WEAK void BLE_WAKEUP_LP_Handler()
|
||||
{
|
||||
default_isr(); /* 0 */
|
||||
}
|
||||
__WEAK void BLE_GEN_Handler()
|
||||
{
|
||||
default_isr(); /* 1 */
|
||||
}
|
||||
__WEAK void FTDF_WAKEUP_Handler()
|
||||
{
|
||||
default_isr(); /* 2 */
|
||||
}
|
||||
__WEAK void FTDF_GEN_Handler()
|
||||
{
|
||||
default_isr(); /* 3 */
|
||||
}
|
||||
__WEAK void RFCAL_Handler()
|
||||
{
|
||||
default_isr(); /* 4 */
|
||||
}
|
||||
__WEAK void COEX_Handler()
|
||||
{
|
||||
default_isr(); /* 5 */
|
||||
}
|
||||
__WEAK void CRYPTO_Handler()
|
||||
{
|
||||
default_isr(); /* 6 */
|
||||
}
|
||||
__WEAK void MRM_Handler()
|
||||
{
|
||||
default_isr(); /* 7 */
|
||||
}
|
||||
__WEAK void UART_Handler()
|
||||
{
|
||||
default_isr(); /* 8 */
|
||||
}
|
||||
__WEAK void UART2_Handler()
|
||||
{
|
||||
default_isr(); /* 9 */
|
||||
}
|
||||
__WEAK void I2C_Handler()
|
||||
{
|
||||
default_isr(); /* 10 */
|
||||
}
|
||||
__WEAK void I2C2_Handler()
|
||||
{
|
||||
default_isr(); /* 11 */
|
||||
}
|
||||
__WEAK void SPI_Handler()
|
||||
{
|
||||
default_isr(); /* 12 */
|
||||
}
|
||||
__WEAK void SPI2_Handler()
|
||||
{
|
||||
default_isr(); /* 13 */
|
||||
}
|
||||
__WEAK void ADC_Handler()
|
||||
{
|
||||
default_isr(); /* 14 */
|
||||
}
|
||||
__WEAK void KEYBRD_Handler()
|
||||
{
|
||||
default_isr(); /* 15 */
|
||||
}
|
||||
__WEAK void IRGEN_Handler()
|
||||
{
|
||||
default_isr(); /* 16 */
|
||||
}
|
||||
__WEAK void WKUP_GPIO_Handler()
|
||||
{
|
||||
default_isr(); /* 17 */
|
||||
}
|
||||
__WEAK void SWTIM0_Handler()
|
||||
{
|
||||
default_isr(); /* 18 */
|
||||
}
|
||||
__WEAK void SWTIM1_Handler()
|
||||
{
|
||||
default_isr(); /* 19 */
|
||||
}
|
||||
__WEAK void QUADEC_Handler()
|
||||
{
|
||||
default_isr(); /* 20 */
|
||||
}
|
||||
__WEAK void USB_Handler()
|
||||
{
|
||||
default_isr(); /* 21 */
|
||||
}
|
||||
__WEAK void PCM_Handler()
|
||||
{
|
||||
default_isr(); /* 22 */
|
||||
}
|
||||
__WEAK void SRC_IN_Handler()
|
||||
{
|
||||
default_isr(); /* 23 */
|
||||
}
|
||||
__WEAK void SRC_OUT_Handler()
|
||||
{
|
||||
default_isr(); /* 24 */
|
||||
}
|
||||
__WEAK void VBUS_Handler()
|
||||
{
|
||||
default_isr(); /* 25 */
|
||||
}
|
||||
__WEAK void DMA_Handler()
|
||||
{
|
||||
default_isr(); /* 26 */
|
||||
}
|
||||
__WEAK void RF_DIAG_Handler()
|
||||
{
|
||||
default_isr(); /* 27 */
|
||||
}
|
||||
__WEAK void TRNG_Handler()
|
||||
{
|
||||
default_isr(); /* 28 */
|
||||
}
|
||||
__WEAK void DCDC_Handler()
|
||||
{
|
||||
default_isr(); /* 29 */
|
||||
}
|
||||
__WEAK void XTAL16RDY_Handler()
|
||||
{
|
||||
default_isr(); /* 30 */
|
||||
}
|
||||
__WEAK void RESERVED31_Handler()
|
||||
{
|
||||
default_isr(); /* 31 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
__BOOT_VECTOR __USED
|
||||
const irq_handler_t __vector_table[] =
|
||||
{
|
||||
// Cortex-M vector table
|
||||
(irq_handler_t)__BOOT_STACK, //INT_Initial_Stack_Pointer = 0, // Initial Stack Pointer
|
||||
(irq_handler_t)__BOOT_STARTUP, //INT_Initial_Program_Counter = 1, // Initial Program Counter
|
||||
NMI_Handler, //INT_NMI = 2, // Non-maskable Interrupt (NMI)
|
||||
HardFault_Handler, //INT_Hard_Fault = 3, // Hard Fault
|
||||
MemManage_Handler, //INT_Mem_Manage_Fault = 4, // MemManage Fault
|
||||
BusFault_Handler, //INT_Bus_Fault = 5, // Bus Fault
|
||||
default_isr, //INT_Usage_Fault = 6, // Usage Fault
|
||||
default_isr, //INT_Reserved7 = 7, // Reserved interrupt 7
|
||||
default_isr, //INT_Reserved8 = 8, // Reserved interrupt 8
|
||||
default_isr, //INT_Reserved9 = 9, // Reserved interrupt 9
|
||||
default_isr, //INT_Reserved10 = 10, // Reserved interrupt 10
|
||||
SVC_Handler, //INT_SVCall = 11, // Supervisor call (SVCall)
|
||||
DebugMon_Handler, //INT_DebugMonitor = 12, // Debug Monitor
|
||||
default_isr, //INT_Reserved13 = 13, // Reserved interrupt 13
|
||||
PendSV_Handler, //INT_PendableSrvReq = 14, // Pendable request for system service (PendableSrvReq)
|
||||
SysTick_Handler, //INT_SysTick = 15, // SysTick Interrupt
|
||||
|
||||
// Dialog DA15000 vector table
|
||||
BLE_WAKEUP_LP_Handler, //BLE_WAKEUP_LP_IRQn = 0, // Wakeup from Sleep by BLE Interrupt request.
|
||||
BLE_GEN_Handler, //BLE_GEN_IRQn = 1, // BLE Interrupt request. Sources:
|
||||
FTDF_WAKEUP_Handler, //FTDF_WAKEUP_IRQn = 2, // Wakeup from Sleep by FTDF Interrupt request.
|
||||
FTDF_GEN_Handler, //FTDF_GEN_IRQn = 3, // FTDF Interrupt request. Sources:
|
||||
RFCAL_Handler, //RFCAL_IRQn = 4, // RF Calibration Interrupt request. Generated by the DPHY.
|
||||
COEX_Handler, //COEX_IRQn = 5, // Coex Interrupt request.
|
||||
CRYPTO_Handler, //CRYPTO_IRQn = 6, // Crypto Interrupt request. Sources:
|
||||
MRM_Handler, //MRM_IRQn = 7, // Cache Miss Rate Monitor Interrupt request.
|
||||
UART_Handler, //UART_IRQn = 8, // UART Interrupt request.
|
||||
UART2_Handler, //UART2_IRQn = 9, // UART2 Interrupt request.
|
||||
I2C_Handler, //I2C_IRQn = 10, // I2C Interrupt request.
|
||||
I2C2_Handler, //I2C2_IRQn = 11, // I2C2 Interrupt request.
|
||||
SPI_Handler, //SPI_IRQn = 12, // SPI Interrupt request.
|
||||
SPI2_Handler, //SPI2_IRQn = 13, // SPI2 Interrupt request.
|
||||
ADC_Handler, //ADC_IRQn = 14, // Analog-Digital Converter Interrupt request.
|
||||
KEYBRD_Handler, //KEYBRD_IRQn = 15, // Keyboard scanner Interrupt request.
|
||||
IRGEN_Handler, //IRGEN_IRQn = 16, // InfraRed Generator Interrupt request.
|
||||
WKUP_GPIO_Handler, //WKUP_GPIO_IRQn = 17, // Wakeup with/without debouncing Interrupt request (when system
|
||||
SWTIM0_Handler, //SWTIM0_IRQn = 18, // SW Timer Interrupt request (Timer0).
|
||||
SWTIM1_Handler, //SWTIM1_IRQn = 19, // SW Timer Interrupt request (Timer1).
|
||||
QUADEC_Handler, //QUADEC_IRQn = 20, // Quadrature Decoder Interrupt request.
|
||||
USB_Handler, //USB_IRQn = 21, // USB device FS Interrupt request.
|
||||
PCM_Handler, //PCM_IRQn = 22, // PCM Interrupt request.
|
||||
SRC_IN_Handler, //SRC_IN_IRQn = 23, // Sample Rate Converter Input Interrupt request.
|
||||
SRC_OUT_Handler, //SRC_OUT_IRQn = 24, // Sample Rate Converter Output Interrupt request.
|
||||
VBUS_Handler, //VBUS_IRQn = 25, // VBUS presence Interrupt request.
|
||||
DMA_Handler, //DMA_IRQn = 26, // DMA Interrupt request.
|
||||
RF_DIAG_Handler, //RF_DIAG_IRQn = 27, // Baseband or Radio Diagnostics Interrupt request.
|
||||
TRNG_Handler, //TRNG_IRQn = 28, // True Random Number Generation Interrupt request.
|
||||
DCDC_Handler, //DCDC_IRQn = 29, // DCDC Interrupt request. Generated upon time out threshold reach.
|
||||
XTAL16RDY_Handler, //XTAL16RDY_IRQn = 30, // Indicates that XTAL16 oscillator is trimmed and settled and can
|
||||
DEBUG_IRQHandler, //RESERVED31_IRQn = 31, // RESERVED31 Interrupt request.
|
||||
};
|
||||
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup ADAPTERS
|
||||
* \{
|
||||
* \addtogroup RF_ADAPTER
|
||||
*
|
||||
* \brief RF adapter
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @brief Radio module access 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_RF_H_
|
||||
#define AD_RF_H_
|
||||
|
||||
#if dg_configRF_ADAPTER
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
//#include "platform_devices.h"
|
||||
|
||||
#include "hw_rf.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Performs RF adapter initialization
|
||||
*/
|
||||
void ad_rf_init(void);
|
||||
|
||||
/**
|
||||
* \brief Retry a failed calibration
|
||||
*
|
||||
* This will power-cycle RF, reapply tcs and recommended settings, and
|
||||
* retry calibration. If calibration fails again, it will reset the system
|
||||
* (using the wdog)
|
||||
*/
|
||||
void ad_rf_retry_calibration();
|
||||
|
||||
/**
|
||||
* \brief Start Calibration procedure and check if it succeeds
|
||||
*
|
||||
* This will start the calibration procedure, and check if the calibration initial
|
||||
* part (the iff calibration) succeeds. If not, it will reset the RF block and retry.
|
||||
* If the calibration still fails after the second attempt, it will trigger a
|
||||
* watchdog reset
|
||||
*
|
||||
*/
|
||||
static inline void ad_rf_start_and_check_calibration()
|
||||
{
|
||||
if (!hw_rf_start_calibration())
|
||||
ad_rf_retry_calibration();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Perform RF system initialization.
|
||||
*
|
||||
* This will preform a full RF system init, and check if the
|
||||
* calibration initial part (the iff calibration) succeeds. If not, it will
|
||||
* reset the RF block and retry.
|
||||
* If the calibration still fails after the second attempt, it will trigger a
|
||||
* watchdog reset
|
||||
*
|
||||
*/
|
||||
static inline void ad_rf_system_init()
|
||||
{
|
||||
if (!hw_rf_system_init())
|
||||
ad_rf_retry_calibration();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Start Calibration procedure and return.
|
||||
*
|
||||
* This will block for some time (with interrupts disabled) in order to perform
|
||||
* The first part of calibration (IFF, DC offset and the start of gain calib).
|
||||
*
|
||||
*/
|
||||
static inline void ad_rf_start_calibration()
|
||||
{
|
||||
// OS_ENTER_CRITICAL_SECTION();
|
||||
ad_rf_start_and_check_calibration();
|
||||
// OS_LEAVE_CRITICAL_SECTION();
|
||||
}
|
||||
|
||||
/**
|
||||
* \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. Disables interrupts.
|
||||
*
|
||||
*/
|
||||
static inline void ad_rf_request_recommended_settings(void)
|
||||
{
|
||||
// OS_ENTER_CRITICAL_SECTION();
|
||||
hw_rf_request_recommended_settings();
|
||||
// OS_LEAVE_CRITICAL_SECTION();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Requests that the RF is turned on
|
||||
*
|
||||
* Requests that the RF is turned on, if not already on. Disables interrupts.
|
||||
*
|
||||
* \param [in] mode_ble True, if the rf is needed for ble
|
||||
*
|
||||
*/
|
||||
static inline void ad_rf_request_on(bool mode_ble)
|
||||
{
|
||||
// OS_ENTER_CRITICAL_SECTION();
|
||||
hw_rf_request_on(mode_ble);
|
||||
// OS_LEAVE_CRITICAL_SECTION();
|
||||
}
|
||||
|
||||
/**
|
||||
* \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 ad_rf_request_off())
|
||||
* Disables interrupts
|
||||
*
|
||||
* \param [in] mode_ble True, if the rf was needed for ble
|
||||
*/
|
||||
static inline void ad_rf_request_off(bool mode_ble)
|
||||
{
|
||||
// ad_gpadc_acquire();
|
||||
// OS_ENTER_CRITICAL_SECTION();
|
||||
hw_rf_request_off(mode_ble);
|
||||
// OS_LEAVE_CRITICAL_SECTION();
|
||||
// ad_gpadc_release();
|
||||
}
|
||||
|
||||
#endif /* dg_configRF_ADAPTER */
|
||||
|
||||
#endif /* AD_RF_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/* 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.
|
||||
---------------------------------------------------------------------------*/
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 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
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------------------ Common -------------------------------------------- */
|
||||
#ifndef CMN_TIMING_DEBUG
|
||||
#define CMN_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
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
#endif /* BSP_DEBUG_H_ */
|
||||
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
+1434
File diff suppressed because it is too large
Load Diff
+114
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 POWER_CONFIGURATION_1 0
|
||||
#define POWER_CONFIGURATION_2 1
|
||||
#define POWER_CONFIGURATION_3 2
|
||||
|
||||
#define LP_CLK_32000 0
|
||||
#define LP_CLK_32768 1
|
||||
#define LP_CLK_RCX 2
|
||||
|
||||
#define MODE_IS_MIRRORED 0
|
||||
#define MODE_IS_CACHED 1
|
||||
#define MODE_IS_RAM MODE_IS_CACHED
|
||||
|
||||
#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 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 (2784)
|
||||
#define BATTERY_TYPE_3xNIMH_ADC_VOLTAGE (4013)
|
||||
#define BATTERY_TYPE_LICOO2_ADC_VOLTAGE (3439)
|
||||
#define BATTERY_TYPE_LIMN2O4_ADC_VOLTAGE (3439)
|
||||
#define BATTERY_TYPE_NMC_ADC_VOLTAGE (3439)
|
||||
#define BATTERY_TYPE_LIFEPO4_ADC_VOLTAGE (2947)
|
||||
#define BATTERY_TYPE_LINICOAIO2_ADC_VOLTAGE (3439)
|
||||
|
||||
|
||||
/*
|
||||
* The supported chip revisions.
|
||||
*/
|
||||
#define BLACK_ORCA_IC_REV_A 0
|
||||
|
||||
/*
|
||||
* The supported chip steppings.
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
* The supported DK motherboards.
|
||||
*/
|
||||
#define BLACK_ORCA_MB_REV_A 0
|
||||
#define BLACK_ORCA_MB_REV_B 1
|
||||
|
||||
/*
|
||||
* The supported RF Front-End Modules
|
||||
*/
|
||||
#define FEM_NOFEM 0
|
||||
#define FEM_SKY66112_11 1
|
||||
|
||||
#endif /* BSP_DEFINITIONS_H_ */
|
||||
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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
|
||||
|
||||
#undef dg_configBLACK_ORCA_IC_STEP
|
||||
#define dg_configBLACK_ORCA_IC_STEP BLACK_ORCA_IC_STEP_D
|
||||
|
||||
#define dg_configFEM FEM_SKY66112_11
|
||||
|
||||
#ifndef dg_configPOWER_EXT_1V8_PERIPHERALS
|
||||
#if dg_configPOWER_EXT_1V8_PERIPHERALS == 0
|
||||
#warning Setting dg_configPOWER_EXT_1V8_PERIPHERALS to 1 for FEM to work
|
||||
#define dg_configPOWER_EXT_1V8_PERIPHERALS 1
|
||||
#endif
|
||||
#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_2
|
||||
#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_7
|
||||
#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_4
|
||||
#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_6
|
||||
#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_5
|
||||
#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_3
|
||||
#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_ */
|
||||
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/**************************************************************************//**
|
||||
* @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 "global_io.h"
|
||||
/*
|
||||
* ==========================================================================
|
||||
* ---------- Interrupt Number Definition -----------------------------------
|
||||
* ==========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* ==========================================================================
|
||||
* ----------- Processor and Core Peripheral Section ------------------------
|
||||
* ==========================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include <core_cm0.h> /* Cortex-M0 processor and core peripherals */
|
||||
#include "system_ARMCM0.h" /* System Header */
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Device Specific Peripheral registers structures */
|
||||
/******************************************************************************/
|
||||
|
||||
/*--------------------- General Purpose Input and Ouptut ---------------------*/
|
||||
typedef union
|
||||
{
|
||||
__IO uint32_t WORD;
|
||||
__IO uint8_t BYTE[4];
|
||||
} GPIO_Data_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GPIO_Data_TypeDef DATA[256];
|
||||
__O uint32_t DIR;
|
||||
uint32_t RESERVED[3];
|
||||
__O uint32_t IE;
|
||||
} ARM_GPIO_TypeDef;
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Peripheral memory map */
|
||||
/******************************************************************************/
|
||||
/* Peripheral and SRAM base address */
|
||||
#define ARM_SRAM_BASE (( uint32_t)0x20000000UL)
|
||||
#define ARM_PERIPH_BASE (( uint32_t)0x40000000UL)
|
||||
|
||||
/* Peripheral memory map */
|
||||
#define ARM_GPIO_BASE ARM_PERIPH_BASE
|
||||
|
||||
#define ARM_GPIO0_BASE (ARM_GPIO_BASE)
|
||||
#define ARM_GPIO1_BASE (ARM_GPIO_BASE + 0x0800UL)
|
||||
#define ARM_GPIO2_BASE (ARM_GPIO_BASE + 0x1000UL)
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Peripheral declaration */
|
||||
/******************************************************************************/
|
||||
#define ARM_GPIO0 ((ARM_GPIO_TypeDef *) ARM_GPIO0_BASE)
|
||||
#define ARM_GPIO1 ((ARM_GPIO_TypeDef *) ARM_GPIO1_BASE)
|
||||
#define ARM_GPIO2 ((ARM_GPIO_TypeDef *) ARM_GPIO2_BASE)
|
||||
|
||||
|
||||
#endif /* ARMCM0_H */
|
||||
+11935
File diff suppressed because it is too large
Load Diff
+287
@@ -0,0 +1,287 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup SYSTEM
|
||||
* \{
|
||||
* \addtogroup PLATFORM
|
||||
*
|
||||
* \brief Black Orca Platform definitions
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file black_orca.h
|
||||
*
|
||||
* @brief Central include header file for the Dialog Black Orca platform.
|
||||
*
|
||||
* @version 1.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.
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __BLACK_ORCA_H__
|
||||
#define __BLACK_ORCA_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
|
||||
|
||||
#include "global_io.h"
|
||||
|
||||
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
|
||||
# if dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_D
|
||||
# include "DA14680AD.h"
|
||||
# elif dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_C
|
||||
# include "DA14680AC.h"
|
||||
# elif dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_A
|
||||
# include "DA14680AA.h"
|
||||
# else
|
||||
# error "Unknown chip stepping for revision A -- 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
|
||||
|
||||
#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */
|
||||
#include "system_DA14680.h" /* DA14680AA System */
|
||||
|
||||
|
||||
/************************
|
||||
* Black Orca Memory map
|
||||
************************/
|
||||
|
||||
/**
|
||||
* \brief Remapped device address range.
|
||||
*/
|
||||
#define MEMORY_REMAPPED_BASE 0x00000000
|
||||
#define MEMORY_REMAPPED_END 0x04000000
|
||||
|
||||
/**
|
||||
* \brief Remapped device memory size (64MiB).
|
||||
*/
|
||||
#define MEMORY_REMAPPED_SIZE (MEMORY_REMAPPED_END - MEMORY_REMAPPED_BASE)
|
||||
|
||||
/**
|
||||
* \brief ROM address range.
|
||||
*/
|
||||
#define MEMORY_ROM_BASE 0x07F00000
|
||||
#define MEMORY_ROM_END 0x07F40000
|
||||
|
||||
/**
|
||||
* \brief ROM memory size (256KiB).
|
||||
*/
|
||||
#define MEMORY_ROM_SIZE (MEMORY_ROM_END - MEMORY_ROM_BASE)
|
||||
|
||||
/**
|
||||
* \brief OTP Controller address range.
|
||||
*/
|
||||
#define MEMORY_OTPC_BASE 0x07F40000
|
||||
#define MEMORY_OTPC_END 0x07F80000
|
||||
|
||||
/**
|
||||
* \brief OTP memory address range.
|
||||
*/
|
||||
#define MEMORY_OTP_BASE 0x07F80000
|
||||
#define MEMORY_OTP_END 0x07FC0000
|
||||
|
||||
/**
|
||||
* \brief OTP memory size (256KiB).
|
||||
*/
|
||||
#define MEMORY_OTP_SIZE (MEMORY_OTP_END - MEMORY_OTP_BASE)
|
||||
|
||||
/**
|
||||
* \brief SYSTEM RAM address range.
|
||||
*/
|
||||
#define MEMORY_SYSRAM_BASE 0x07FC0000
|
||||
#define MEMORY_SYSRAM_END 0x07FE0000
|
||||
|
||||
/**
|
||||
* \brief SYSTEM RAM size (128KiB).
|
||||
*/
|
||||
#define MEMORY_SYSRAM_SIZE (MEMORY_SYSRAM_END - MEMORY_SYSRAM_BASE)
|
||||
|
||||
/**
|
||||
* \brief CACHE RAM address range.
|
||||
*/
|
||||
#define MEMORY_CACHERAM_BASE 0x07FE0000
|
||||
#define MEMORY_CACHERAM_END 0x08000000
|
||||
|
||||
/**
|
||||
* \brief CACHE RAM size (128KiB).
|
||||
*/
|
||||
#define MEMORY_CACHERAM_SIZE (MEMORY_CACHERAM_END - MEMORY_CACHERAM_BASE)
|
||||
|
||||
/**
|
||||
* \brief QSPI Flash address range.
|
||||
*/
|
||||
#define MEMORY_QSPIF_BASE 0x08000000
|
||||
#define MEMORY_QSPIF_END 0x0BF00000
|
||||
|
||||
/**
|
||||
* \brief QSPI Flash memory size (63MiB).
|
||||
*/
|
||||
#define MEMORY_QSPIF_SIZE (MEMORY_QSPIF_END - MEMORY_QSPIF_BASE)
|
||||
|
||||
/**
|
||||
* \brief QSPI Controller address range.
|
||||
*/
|
||||
#define MEMORY_QSPIC_BASE 0x0C000000
|
||||
#define MEMORY_QSPIC_END 0x0C100000
|
||||
|
||||
#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) \
|
||||
((((uint32_t)(revision)) << 8) | ((uint32_t)(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 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);
|
||||
|
||||
#define ASSERT(a) { if (!(a)) while (1); }
|
||||
|
||||
#define ASSERT_WARNING(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); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#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 " ); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BLACK_ORCA_H__ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+691
@@ -0,0 +1,691 @@
|
||||
/** \addtogroup ARM
|
||||
* \brief ARM core documentation
|
||||
* \{
|
||||
*/
|
||||
/**************************************************************************//**
|
||||
* @file core_cm0.h
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||
* @version V3.20
|
||||
* @date 25. February 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* 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.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM0_H_GENERIC
|
||||
#define __CORE_CM0_H_GENERIC
|
||||
|
||||
/** \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 (0x03) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0x00) /*!< 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 ( __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 ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU 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
|
||||
|
||||
#endif
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#warning "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
|
||||
#endif
|
||||
|
||||
#include <stdint.h> /* standard types definitions */
|
||||
#include <core_cmInstr.h> /* Core Instruction Access */
|
||||
#include <core_cmFunc.h> /* Core Function Access */
|
||||
|
||||
#endif /* __CORE_CM0_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM0_H_DEPENDANT
|
||||
#define __CORE_CM0_H_DEPENDANT
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM0_REV
|
||||
#define __CM0_REV 0x0000
|
||||
#warning "__CM0_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0
|
||||
#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 */
|
||||
|
||||
/*@} 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
|
||||
{
|
||||
#if (__CORTEX_M != 0x04)
|
||||
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
|
||||
#else
|
||||
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
|
||||
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
|
||||
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
|
||||
#endif
|
||||
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
|
||||
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;
|
||||
|
||||
|
||||
/** \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;
|
||||
|
||||
|
||||
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
#if (__CORTEX_M != 0x04)
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
#else
|
||||
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
|
||||
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
|
||||
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
|
||||
#endif
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
|
||||
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
|
||||
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;
|
||||
|
||||
|
||||
/** \brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
|
||||
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/*@} 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
|
||||
{
|
||||
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31];
|
||||
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31];
|
||||
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31];
|
||||
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31];
|
||||
uint32_t RESERVED4[64];
|
||||
__IO uint32_t IP[8]; /*!< 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
|
||||
{
|
||||
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
uint32_t RESERVED0;
|
||||
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< 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 16 /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< 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 4 /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< 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 15 /*!< 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
|
||||
{
|
||||
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_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_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 "black_orca.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)(IRQn) ) & 0x03) * 8 )
|
||||
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
|
||||
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
|
||||
|
||||
|
||||
/** \brief Enable External Interrupt
|
||||
|
||||
The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable External Interrupt
|
||||
|
||||
The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Pending Interrupt
|
||||
|
||||
The function 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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Pending Interrupt
|
||||
|
||||
The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Clear Pending Interrupt
|
||||
|
||||
The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Interrupt Priority
|
||||
|
||||
The function 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(IRQn < 0) {
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
|
||||
else {
|
||||
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Interrupt Priority
|
||||
|
||||
The function 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(IRQn < 0) {
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
|
||||
else {
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
|
||||
}
|
||||
|
||||
|
||||
/** \brief System Reset
|
||||
|
||||
The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
while(1); /* wait until reset */
|
||||
}
|
||||
|
||||
/*@} 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 == 0)
|
||||
|
||||
/** \brief System Tick Configuration
|
||||
|
||||
The function 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 - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
|
||||
|
||||
SysTick->LOAD = ticks - 1; /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0; /* 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 (0); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\} end of ARM group
|
||||
*/
|
||||
|
||||
+645
@@ -0,0 +1,645 @@
|
||||
/** \addtogroup ARM
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**************************************************************************//**
|
||||
* @file core_cmFunc.h
|
||||
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||
* @version V3.20
|
||||
* @date 25. February 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* 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.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __CORE_CMFUNC_H
|
||||
#define __CORE_CMFUNC_H
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* intrinsic void __enable_irq(); */
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get IPSR Register
|
||||
|
||||
This function returns the content of the IPSR Register.
|
||||
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief Enable IRQ Interrupts
|
||||
|
||||
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie i" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable IRQ Interrupts
|
||||
|
||||
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid i" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get IPSR Register
|
||||
|
||||
This function returns the content of the IPSR Register.
|
||||
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie f" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid f" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
uint32_t result;
|
||||
|
||||
/* Empty asm statement works as a scheduling barrier */
|
||||
__ASM volatile ("");
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
__ASM volatile ("");
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
/* Empty asm statement works as a scheduling barrier */
|
||||
__ASM volatile ("");
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
|
||||
__ASM volatile ("");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all instrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CMFUNC_H */
|
||||
|
||||
/**
|
||||
\} end of ARM group
|
||||
*/
|
||||
|
||||
+697
@@ -0,0 +1,697 @@
|
||||
/** \addtogroup ARM
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V3.20
|
||||
* @date 05. March 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* 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.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() __isb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() __dsb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() __dmb(0xF)
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __rbit
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/* Define macros for porting to both thumb1 and thumb2.
|
||||
* For thumb1, use low register (r0-r7), specified by constrant "l"
|
||||
* Otherwise, use general registers, specified by constrant "r" */
|
||||
#if defined (__thumb__) && !defined (__thumb2__)
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||
#else
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||
#endif
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
return __builtin_bswap32(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
return (short)__builtin_bswap16(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << (32 - op2));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex" ::: "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
||||
|
||||
/**
|
||||
\} end of ARM group
|
||||
*/
|
||||
|
||||
+362
@@ -0,0 +1,362 @@
|
||||
#ifndef IO_H_INCLUDED
|
||||
#define IO_H_INCLUDED
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* Description : IO, data type definitions and memory map selector.
|
||||
*
|
||||
* Remark(s) : None.
|
||||
*
|
||||
*----------------------------------------------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Synchronicity keywords:
|
||||
*
|
||||
* Id : $Id: global_io.h.rca 1.1 Wed Oct 24 09:42:42 2012 wroovers Experimental wroovers $
|
||||
* Source : $Source: /services/syncdata/hazelaar/8500/server_vault/applab/14580/sw/keil/keil_full_emb_SWHL6V16LL6V32_24okt_crosstest_OK_fpga14b/src/inc/global_io.h.rca $
|
||||
*
|
||||
*----------------------------------------------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Synchronicity history:
|
||||
*
|
||||
* Log : $Log: global_io.h.rca $
|
||||
* Log :
|
||||
* Log : Revision: 1.1 Mon Oct 1 11:08:33 2012 wroovers
|
||||
* Log : First Working set
|
||||
* Log :
|
||||
* Log : Revision: 1.2 Mon Mar 19 11:52:13 2012 snijders
|
||||
* Log : Updated the '*int*' typedef's. Put the 'bool' (C++ only) typedef in comment, see comment.
|
||||
* Log : Added typedef HWORD and updated the already existing WORD and DWORD (according to the ARM data type definitions).
|
||||
* Log : Removed the IAR depending '__far' and 'inline' defines (obsolete).
|
||||
* Log : Removed the CR16C_SW_V4 depending '__far' define (obsolete).
|
||||
* Log : Removed the 'NULL' define (most probably also obsolete).
|
||||
* Log :
|
||||
* Log : Revision: 1.1 Tue Mar 6 11:00:42 2012 snijders
|
||||
* Log : Initial check in for Project bbtester. Copied from "../sitel_io.h" and renamed to "global_io.h".
|
||||
* Log : Updated the header, no further changes yet.
|
||||
*
|
||||
*----------------------------------------------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* sc14580a
|
||||
* --------
|
||||
* 19-mar-2012/HS: Updated the '*int*' typedef's. Put the 'bool' (C++ only) typedef in comment, see comment.
|
||||
* Added typedef HWORD and updated the already existing WORD and DWORD (according to the ARM data type definitions).
|
||||
* Removed the IAR depending '__far' and 'inline' defines (obsolete).
|
||||
* Removed the CR16C_SW_V4 depending '__far' define (obsolete).
|
||||
* Removed the 'NULL' define (most probably also obsolete).
|
||||
* 06-mar-2012/HS: Initial check in for Project bbtester. Copied from "../sitel_io.h" and renamed to "global_io.h".
|
||||
* Updated the header, no further changes yet.
|
||||
*
|
||||
*----------------------------------------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
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
|
||||
|
||||
// Retention memory attributes
|
||||
#define __RETAINED __attribute__((section("retention_mem_zi")))
|
||||
#define __RETAINED_RW __attribute__((section("retention_mem_rw")))
|
||||
#define __RETAINED_UNINIT __attribute__((section("retention_mem_uninit")))
|
||||
#if ((dg_configCODE_LOCATION == NON_VOLATILE_IS_FLASH) && (dg_configEXEC_MODE == MODE_IS_CACHED))
|
||||
#define __RETAINED_CODE __attribute__((section("text_retained"))) __attribute__((noinline))
|
||||
#else
|
||||
#define __RETAINED_CODE
|
||||
#endif
|
||||
|
||||
// Interrupt macros
|
||||
#define GLOBAL_INT_DISABLE() \
|
||||
do { \
|
||||
uint32 __l_irq_rest = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1); \
|
||||
DBG_CONFIGURE_HIGH(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION);
|
||||
|
||||
|
||||
#define GLOBAL_INT_RESTORE() \
|
||||
if (__l_irq_rest == 0) { \
|
||||
DBG_CONFIGURE_LOW(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION); \
|
||||
__set_PRIMASK(0); \
|
||||
} \
|
||||
else { \
|
||||
__set_PRIMASK(1); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
|
||||
#ifndef offsetof
|
||||
#if defined(__GNUC__)
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
#else
|
||||
#define offsetof(type,member) ((size_t)(&((type *)0)->member))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define containingoffset(address, type, field) ((type*)((uint8*)(address)-(size_t)(&((type*)0)->field)))
|
||||
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#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
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define SWAP16(a) __builtin_bswap16(a)
|
||||
#define SWAP32(a) __builtin_bswap32(a)
|
||||
#else
|
||||
#define SWAP16(a) ((a<<8) | (a>>8))
|
||||
#define SWAP32(a) ((a>>24 & 0xff) | (a>>8 & 0xff00) | (a<<8 & 0xff0000) | (a<<24 & 0xff000000))
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define DEPRECATED __attribute__ ((deprecated))
|
||||
#define DEPRECATED_MSG(msg) __attribute__ ((deprecated(msg)))
|
||||
#else
|
||||
#warning Deprecated macro must be implemented for this compiler
|
||||
#define DEPRECATED
|
||||
#define DEPRECATED_MSG(msg)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \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 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)
|
||||
|
||||
#define ENABLE_DEBUGGER \
|
||||
do { \
|
||||
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
|
||||
} while(0)
|
||||
|
||||
#define DISABLE_DEBUGGER \
|
||||
do { \
|
||||
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define SWRESET \
|
||||
do { \
|
||||
REG_SET_BIT(GPREG, DEBUG_REG, SW_RESET); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* \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[];
|
||||
|
||||
/*
|
||||
* 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 (RESERVED31_IRQn + 1)
|
||||
#define PRIORITY_1 (RESERVED31_IRQn + 2)
|
||||
#define PRIORITY_2 (RESERVED31_IRQn + 3)
|
||||
#define PRIORITY_3 (RESERVED31_IRQn + 4)
|
||||
#define PRIORITY_TABLE_END (RESERVED31_IRQn + 5)
|
||||
#define INTERRUPT_PRIORITY_CONFIG_END PRIORITY_TABLE_END };
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern }
|
||||
#endif
|
||||
|
||||
#endif /* INTERRUPTS_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* \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_0 10
|
||||
#define SUOTA_VERSION_1_1 11
|
||||
|
||||
#ifndef SUOTA_VERSION
|
||||
#define SUOTA_VERSION SUOTA_VERSION_1_1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \struct suota_1_1_product_header_t;
|
||||
*
|
||||
* \brief SUOTA 1.1 product header as defined by Dialog SUOTA specification.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t signature[2];
|
||||
uint16_t flags;
|
||||
uint32_t current_image_location;
|
||||
uint32_t update_image_location;
|
||||
uint8_t reserved[8];
|
||||
} suota_1_1_product_header_t;
|
||||
|
||||
#define SUOTA_1_1_PRODUCT_HEADER_SIGNATURE_B1 0x70
|
||||
#define SUOTA_1_1_PRODUCT_HEADER_SIGNATURE_B2 0x62
|
||||
|
||||
#define SUOTA_1_0_PRODUCT_HEADER_SIGNATURE_B1 0x70
|
||||
#define SUOTA_1_0_PRODUCT_HEADER_SIGNATURE_B2 0x52
|
||||
|
||||
/**
|
||||
* \struct suota_1_0_image_header_t
|
||||
*
|
||||
* \brief SUOTA 1.0 image header as defined by Dialog SUOTA specification.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t signature[2];
|
||||
uint8_t valid_flag;
|
||||
uint8_t image_id;
|
||||
uint32_t code_size;
|
||||
uint32_t crc;
|
||||
uint8_t version[16];
|
||||
uint32_t timestamp;
|
||||
uint8_t encryption;
|
||||
uint8_t reserved[31];
|
||||
} suota_1_0_image_header_t;
|
||||
|
||||
/**
|
||||
* \struct suota_1_1_image_header_t
|
||||
*
|
||||
* \brief SUOTA 1.1 image header as defined by Dialog SUOTA specification.
|
||||
*
|
||||
*/
|
||||
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;
|
||||
} 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_0_IMAGE_HEADER_SIGNATURE_B1 0x70
|
||||
#define SUOTA_1_0_IMAGE_HEADER_SIGNATURE_B2 0x51
|
||||
|
||||
#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
|
||||
|
||||
#if (SUOTA_VERSION == SUOTA_VERSION_1_0)
|
||||
typedef suota_1_0_image_header_t suota_image_header_t;
|
||||
#else
|
||||
typedef suota_1_1_image_header_t suota_image_header_t;
|
||||
#endif
|
||||
|
||||
#endif /* SUOTA_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**************************************************************************//**
|
||||
* @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 */
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/**************************************************************************//**
|
||||
* @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 black_orca_phy_addr(uint32_t addr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_DA14680_H */
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup SYSTEM
|
||||
* \{
|
||||
* \addtogroup MEMORY
|
||||
*
|
||||
* \brief QSPI flash access when running in auto mode
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 <black_orca.h>
|
||||
#include <hw_qspi.h>
|
||||
|
||||
/**
|
||||
* QSPI controller allows to execute code directly from QSPI flash.
|
||||
* When code is executing from flash there is no possibility to reprogram it.
|
||||
* To be able to modify flash memory while it is used for code execution it must me assured that
|
||||
* for time needed for erase/write no code is running from flash.
|
||||
* To achieve this code in this file allows to copy programming functions to RAM and execute it
|
||||
* from there.
|
||||
* Great flexibility is achieved by putting all code needed for flash modification in one section
|
||||
* that will be copied to RAM.
|
||||
* Code in this section will not access any other functions or constant variables (that could reside
|
||||
* in flash).
|
||||
*/
|
||||
|
||||
/**
|
||||
* \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 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)
|
||||
{
|
||||
return (const void *) (MEMORY_QSPIF_BASE + addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Power up flash
|
||||
*/
|
||||
void qspi_automode_flash_power_up(void);
|
||||
|
||||
/**
|
||||
* \brief Init QSPI controller
|
||||
*/
|
||||
bool qspi_automode_init(void);
|
||||
|
||||
#endif /* QSPI_AUTOMODE_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,680 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file qspi_automode.c
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <black_orca.h>
|
||||
#include <hw_qspi.h>
|
||||
|
||||
/*
|
||||
* QSPI controller allows to execute code directly from QSPI flash.
|
||||
* When code is executing from flash there is no possibility to reprogram it.
|
||||
* To be able to modify flash memory while it is used for code execution it must me assured that
|
||||
* for time needed for erase/write no code is running from flash.
|
||||
* To achieve this code in this file allows to copy programming functions to RAM and execute it
|
||||
* from there.
|
||||
* Great flexibility is achieved by putting all code needed for flash modification in one section
|
||||
* that will be copied to RAM.
|
||||
* Code in this section will not access any other functions or constant variables (that could reside
|
||||
* in flash).
|
||||
*/
|
||||
|
||||
/* Erase/Write in progress */
|
||||
#define W25Q_STATUS1_BUSY_BIT 0
|
||||
#define W25Q_STATUS1_BUSY_MASK (1 << W25Q_STATUS1_BUSY_BIT)
|
||||
|
||||
#define W25Q_STATUS1_WEL_BIT 1
|
||||
#define W25Q_STATUS1_WEL_MASK (1 << W25Q_STATUS1_WEL_BIT)
|
||||
|
||||
#define W25Q_WRITE_STATUS_REGISTER 0x01
|
||||
#define W25Q_PAGE_PROGRAM 0x02
|
||||
#define W25Q_WRITE_DISABLE 0x04
|
||||
#define W25Q_READ_STATUS_REGISTER1 0x05
|
||||
#define W25Q_WRITE_ENABLE 0x06
|
||||
#define W25Q_SECTOR_ERASE 0x20
|
||||
#define W25Q_QUAD_PAGE_PROGRAM 0x32
|
||||
#define W25Q_READ_STATUS_REGISTER2 0x35
|
||||
#define W25Q_BLOCK_ERASE 0x52
|
||||
#define W25Q_ERASE_PROGRAM_SUSPEND 0x75
|
||||
#define W25Q_ERASE_PROGRAM_RESUME 0x7A
|
||||
#define W25Q_BLOCK_ERASE_64K 0xD8
|
||||
#define W25Q_CHIP_ERASE 0xC7
|
||||
#define W25Q_RELEASE_POWER_DOWN 0xAB
|
||||
#define W25Q_FAST_READ_QUAD 0xEB
|
||||
|
||||
#define FLASH_MAX_WRITE_SIZE dg_configFLASH_MAX_WRITE_SIZE
|
||||
|
||||
/*
|
||||
* Use QUAD mode for page write.
|
||||
* If flash does not support QUAD mode or it is not connected for QUAD mode set it to 0.
|
||||
*/
|
||||
#ifndef QUAD_MODE
|
||||
#define QUAD_MODE 1
|
||||
#endif
|
||||
|
||||
#ifndef ERASE_IN_AUTOMODE
|
||||
#define ERASE_IN_AUTOMODE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros to put functions that need to be copied to ram in one section.
|
||||
*/
|
||||
#define QSPI_SECTION __attribute__ ((section ("text_retained")))
|
||||
#define QSPI_SECTION_NOINLINE __attribute__ ((section ("text_retained"), noinline))
|
||||
|
||||
QSPI_SECTION static uint8_t flash_read_status_register_1(void);
|
||||
|
||||
/*
|
||||
* Set bus mode to single or QUAD mode.
|
||||
* Flash does not support DUAL page program so it is not supported here.
|
||||
*/
|
||||
QSPI_SECTION static inline void qspi_set_bus_mode(HW_QSPI_BUS_MODE mode)
|
||||
{
|
||||
if (mode == HW_QSPI_BUS_MODE_SINGLE)
|
||||
{
|
||||
QSPIC->QSPIC_CTRLBUS_REG = REG_MSK(QSPIC, QSPIC_CTRLBUS_REG, QSPIC_SET_SINGLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if QUAD_MODE
|
||||
QSPIC->QSPIC_CTRLBUS_REG = REG_MSK(QSPIC, QSPIC_CTRLBUS_REG, QSPIC_SET_QUAD);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable CS
|
||||
*/
|
||||
QSPI_SECTION static inline void qspi_cs_enable(void)
|
||||
{
|
||||
QSPIC->QSPIC_CTRLBUS_REG = QSPIC_QSPIC_CTRLBUS_REG_QSPIC_EN_CS_Msk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable CS
|
||||
*/
|
||||
QSPI_SECTION static inline void qspi_cs_disable(void)
|
||||
{
|
||||
QSPIC->QSPIC_CTRLBUS_REG = QSPIC_QSPIC_CTRLBUS_REG_QSPIC_DIS_CS_Msk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write 8 bits to QSPI bus.
|
||||
*/
|
||||
QSPI_SECTION static inline void qspi_write8(uint8_t data)
|
||||
{
|
||||
*((volatile uint8_t *) & (QSPIC->QSPIC_WRITEDATA_REG)) = data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write 32 bits to QSPI bus.
|
||||
* It creates more efficient transmission then 8 bits write.
|
||||
*/
|
||||
QSPI_SECTION static inline void qspi_write32(uint32_t data)
|
||||
{
|
||||
QSPIC->QSPIC_WRITEDATA_REG = data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read byte from QSPI bus.
|
||||
*/
|
||||
QSPI_SECTION static inline uint8_t qspi_read8(void)
|
||||
{
|
||||
return *((volatile uint8_t *) & (QSPIC->QSPIC_READDATA_REG));
|
||||
}
|
||||
|
||||
/*
|
||||
* Escape continues read mode that could be programmed in auto mode.
|
||||
* Without this when controller is switched to manual mode it could treat incoming
|
||||
* commands as addresses.
|
||||
*/
|
||||
QSPI_SECTION static inline void flash_reset_continuous_mode(void)
|
||||
{
|
||||
qspi_cs_enable();
|
||||
qspi_write8(0xFF);
|
||||
qspi_cs_disable();
|
||||
}
|
||||
|
||||
QSPI_SECTION uint8_t flash_release_power_down(void)
|
||||
{
|
||||
uint8_t id;
|
||||
|
||||
qspi_cs_enable();
|
||||
qspi_write32(0x000000AB);
|
||||
id = qspi_read8();
|
||||
qspi_cs_disable();
|
||||
|
||||
while (flash_read_status_register_1() & W25Q_STATUS1_BUSY_MASK);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get auto mode state of controller.
|
||||
*/
|
||||
QSPI_SECTION static inline bool qspi_get_automode(void)
|
||||
{
|
||||
return REG_GETF(QSPIC, QSPIC_CTRLMODE_REG, QSPIC_AUTO_MD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set auto or manual mode
|
||||
*/
|
||||
QSPI_SECTION static inline void qspi_set_automode(bool automode)
|
||||
{
|
||||
REG_SETF(QSPIC, QSPIC_CTRLMODE_REG, QSPIC_AUTO_MD, automode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write bytes on QSPI bus.
|
||||
*/
|
||||
QSPI_SECTION static void qspi_write(const uint8_t *wbuf, size_t wlen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
qspi_cs_enable();
|
||||
|
||||
for (i = 0; i < wlen; ++i)
|
||||
{
|
||||
qspi_write8(wbuf[i]);
|
||||
}
|
||||
|
||||
qspi_cs_disable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Do write then read transaction on QSPI bus.
|
||||
*/
|
||||
QSPI_SECTION static void qspi_transact(const uint8_t *wbuf, size_t wlen, uint8_t *rbuf,
|
||||
size_t rlen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
qspi_cs_enable();
|
||||
|
||||
for (i = 0; i < wlen; ++i)
|
||||
{
|
||||
qspi_write8(wbuf[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < rlen; ++i)
|
||||
{
|
||||
rbuf[i] = qspi_read8();
|
||||
}
|
||||
|
||||
qspi_cs_disable();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable write to flash.
|
||||
* Must be called before every write and erase.
|
||||
*/
|
||||
QSPI_SECTION static void flash_write_enable(void)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t cmd[] = { W25Q_WRITE_ENABLE };
|
||||
|
||||
do
|
||||
{
|
||||
qspi_write(cmd, 1);
|
||||
|
||||
do
|
||||
{
|
||||
status = flash_read_status_register_1();
|
||||
}
|
||||
while (status & W25Q_STATUS1_BUSY_MASK);
|
||||
}
|
||||
while (!(status & W25Q_STATUS1_WEL_MASK));
|
||||
}
|
||||
|
||||
QSPI_SECTION static size_t flash_write_page(uint32_t addr, const uint8_t *buf, uint16_t size)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t odd = ((uint32_t) buf) & 3;
|
||||
|
||||
flash_write_enable();
|
||||
|
||||
qspi_cs_enable();
|
||||
|
||||
qspi_write32((QUAD_MODE ? W25Q_QUAD_PAGE_PROGRAM : W25Q_PAGE_PROGRAM) |
|
||||
((addr >> 8) & 0xFF00) | ((addr << 8) & 0xFF0000) | (addr << 24));
|
||||
|
||||
/* Reduce max write size, that can reduce interrupt latency time */
|
||||
if (size > FLASH_MAX_WRITE_SIZE)
|
||||
{
|
||||
size = FLASH_MAX_WRITE_SIZE;
|
||||
}
|
||||
|
||||
/* Make sure write will not cross page boundary */
|
||||
if ((addr & 0xFF) + size > 256)
|
||||
{
|
||||
size = 256 - ((addr + 256) & 0xFF);
|
||||
}
|
||||
|
||||
#if QUAD_MODE
|
||||
qspi_set_bus_mode(HW_QSPI_BUS_MODE_QUAD);
|
||||
#endif
|
||||
|
||||
if (odd)
|
||||
{
|
||||
odd = 4 - odd;
|
||||
|
||||
for (i = 0; i < odd && i < size; ++i)
|
||||
{
|
||||
qspi_write8(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (; i + 3 < size; i += 4)
|
||||
{
|
||||
qspi_write32(*((uint32_t *) &buf[i]));
|
||||
}
|
||||
|
||||
for (; i < size; i++)
|
||||
{
|
||||
qspi_write8(*((uint8_t *) &buf[i]));
|
||||
}
|
||||
|
||||
#if QUAD_MODE
|
||||
qspi_set_bus_mode(HW_QSPI_BUS_MODE_SINGLE);
|
||||
#endif
|
||||
|
||||
qspi_cs_disable();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read flash status register.
|
||||
* It is important not to go to auto mode before flash finishes write or erase.
|
||||
*/
|
||||
QSPI_SECTION static uint8_t flash_read_status_register_1(void)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t cmd[] = { W25Q_READ_STATUS_REGISTER1 };
|
||||
|
||||
qspi_transact(cmd, 1, &status, 1);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#if !ERASE_IN_AUTOMODE
|
||||
/*
|
||||
* Erase flash sector 4KB command.
|
||||
*/
|
||||
QSPI_SECTION static void flash_erase_sector(uint32_t addr)
|
||||
{
|
||||
uint8_t cmd[4] = { W25Q_SECTOR_ERASE, addr >> 16, addr >> 8, addr };
|
||||
|
||||
flash_write_enable();
|
||||
|
||||
qspi_write(cmd, 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
QSPI_SECTION static inline uint8_t qspi_get_erase_status(void)
|
||||
{
|
||||
QSPIC->QSPIC_CHCKERASE_REG = 0;
|
||||
return HW_QSPIC_REG_GETF(ERASECTRL, ERS_STATE);
|
||||
}
|
||||
|
||||
QSPI_SECTION static inline HW_QSPI_ADDR_SIZE qspi_get_address_size(void)
|
||||
{
|
||||
return (HW_QSPI_ADDR_SIZE)HW_QSPIC_REG_GETF(CTRLMODE, USE_32BA);
|
||||
}
|
||||
|
||||
QSPI_SECTION_NOINLINE static bool qspi_writable(void)
|
||||
{
|
||||
bool am = qspi_get_automode();
|
||||
bool writable;
|
||||
|
||||
/*
|
||||
* From now on QSPI may not be available, turn of interrupts.
|
||||
*/
|
||||
GLOBAL_INT_DISABLE();
|
||||
|
||||
/*
|
||||
* Turn off auto mode to allow write.
|
||||
*/
|
||||
qspi_set_automode(false);
|
||||
|
||||
/*
|
||||
* Set default mode for commands.
|
||||
*/
|
||||
qspi_set_bus_mode(HW_QSPI_BUS_MODE_SINGLE);
|
||||
|
||||
/*
|
||||
* Exit continues mode, after this flash will interpret commands again.
|
||||
*/
|
||||
flash_reset_continuous_mode();
|
||||
|
||||
/*
|
||||
* Check if flash is ready.
|
||||
*/
|
||||
writable = !(flash_read_status_register_1() & W25Q_STATUS1_BUSY_MASK);
|
||||
|
||||
/*
|
||||
* Restore auto mode.
|
||||
*/
|
||||
qspi_set_automode(am);
|
||||
|
||||
/*
|
||||
* Let other code to be executed including QSPI one.
|
||||
*/
|
||||
GLOBAL_INT_RESTORE();
|
||||
|
||||
return writable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase sector using QSPI controller.
|
||||
*/
|
||||
QSPI_SECTION static void qspi_erase_sector(uint32_t addr)
|
||||
{
|
||||
/* Wait for previous erase to end */
|
||||
while (qspi_get_erase_status() != 0)
|
||||
{
|
||||
}
|
||||
|
||||
if (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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write page to flash.
|
||||
* This function blocks interrupts switches to manual mode, writes page (or less) of data.
|
||||
* Then it waits for flash to become ready before switching back to auto mode.
|
||||
* Make sure that buf does not point to QSPI mapped memory.
|
||||
*/
|
||||
QSPI_SECTION_NOINLINE static size_t write_page(uint32_t addr, const uint8_t *buf, uint16_t size)
|
||||
{
|
||||
bool am = qspi_get_automode();
|
||||
size_t written;
|
||||
|
||||
/*
|
||||
* From now on QSPI may not be available, turn of interrupts.
|
||||
*/
|
||||
GLOBAL_INT_DISABLE();
|
||||
|
||||
/*
|
||||
* Turn off auto mode to allow write.
|
||||
*/
|
||||
qspi_set_automode(false);
|
||||
|
||||
/*
|
||||
* Set default mode for commands.
|
||||
*/
|
||||
qspi_set_bus_mode(HW_QSPI_BUS_MODE_SINGLE);
|
||||
|
||||
/*
|
||||
* Exit continues mode, after this flash will interpret commands again.
|
||||
*/
|
||||
flash_reset_continuous_mode();
|
||||
|
||||
while (flash_read_status_register_1() & W25Q_STATUS1_BUSY_MASK);
|
||||
|
||||
/*
|
||||
* Write page of data.
|
||||
*/
|
||||
written = flash_write_page(addr, buf, size);
|
||||
|
||||
/*
|
||||
* Wait for flash to become ready again.
|
||||
*/
|
||||
while (flash_read_status_register_1() & W25Q_STATUS1_BUSY_MASK);
|
||||
|
||||
/*
|
||||
* Restore auto mode.
|
||||
*/
|
||||
qspi_set_automode(am);
|
||||
|
||||
/*
|
||||
* Let other code to be executed including QSPI one.
|
||||
*/
|
||||
GLOBAL_INT_RESTORE();
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase flash sector.
|
||||
* This function blocks interrupts switches to manual mode, erases sector.
|
||||
* Then it waits for flash to become ready before switching back to auto mode.
|
||||
*/
|
||||
QSPI_SECTION_NOINLINE static void erase_sector(uint32_t addr)
|
||||
{
|
||||
#if ERASE_IN_AUTOMODE
|
||||
/*
|
||||
* Erase sector in automode
|
||||
*/
|
||||
qspi_erase_sector(addr);
|
||||
|
||||
/*
|
||||
* Wait for erase to finish
|
||||
*/
|
||||
while (qspi_get_erase_status())
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
bool am = qspi_get_automode();
|
||||
|
||||
/*
|
||||
* From now on QSPI may not be available, turn of interrupts.
|
||||
*/
|
||||
GLOBAL_INT_DISABLE();
|
||||
|
||||
/*
|
||||
* Turn off auto mode to allow write.
|
||||
*/
|
||||
qspi_set_automode(false);
|
||||
|
||||
/*
|
||||
* Set default mode for commands.
|
||||
*/
|
||||
qspi_set_bus_mode(HW_QSPI_BUS_MODE_SINGLE);
|
||||
|
||||
flash_release_power_down();
|
||||
|
||||
/*
|
||||
* Exit continues mode, after this flash will interpret commands again.
|
||||
*/
|
||||
flash_reset_continuous_mode();
|
||||
|
||||
while (flash_read_status_register_1() & W25Q_STATUS1_BUSY_MASK);
|
||||
|
||||
/*
|
||||
* Execute erase command.
|
||||
*/
|
||||
flash_erase_sector(addr);
|
||||
|
||||
/*
|
||||
* Wait for flash to become ready again.
|
||||
*/
|
||||
while (flash_read_status_register_1() & W25Q_STATUS1_BUSY_MASK);
|
||||
|
||||
/*
|
||||
* Restore auto mode.
|
||||
*/
|
||||
qspi_set_automode(am);
|
||||
|
||||
/*
|
||||
* Let other code to be executed including QSPI one.
|
||||
*/
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t qspi_automode_get_code_buffer_size(void)
|
||||
{
|
||||
/* Return 1 in case some code will pass this value to memory allocation function */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void qspi_automode_set_code_buffer(void *ram)
|
||||
{
|
||||
(void) ram; /* Unused */
|
||||
}
|
||||
|
||||
bool qspi_automode_writable(void)
|
||||
{
|
||||
return qspi_writable();
|
||||
}
|
||||
|
||||
size_t qspi_automode_write_flash_page(uint32_t addr, const uint8_t *buf, size_t size)
|
||||
{
|
||||
while (!qspi_automode_writable())
|
||||
{
|
||||
}
|
||||
|
||||
return write_page(addr, buf, size);
|
||||
}
|
||||
|
||||
void qspi_automode_erase_flash_sector(uint32_t addr)
|
||||
{
|
||||
while (!qspi_automode_writable())
|
||||
{
|
||||
}
|
||||
|
||||
erase_sector(addr);
|
||||
}
|
||||
|
||||
size_t qspi_automode_read(uint32_t addr, uint8_t *buf, size_t len)
|
||||
{
|
||||
memcpy(buf, (void *)(MEMORY_QSPIF_BASE + addr), len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void qspi_automode_flash_power_up(void)
|
||||
{
|
||||
if (dg_configCODE_LOCATION != NON_VOLATILE_IS_FLASH)
|
||||
{
|
||||
bool am = qspi_get_automode();
|
||||
|
||||
/*
|
||||
* Turn off auto mode to allow write.
|
||||
*/
|
||||
qspi_set_automode(false);
|
||||
|
||||
/*
|
||||
* Set default mode for commands.
|
||||
*/
|
||||
qspi_set_bus_mode(HW_QSPI_BUS_MODE_SINGLE);
|
||||
|
||||
flash_release_power_down();
|
||||
|
||||
/*
|
||||
* Restore auto mode.
|
||||
*/
|
||||
qspi_set_automode(am);
|
||||
}
|
||||
}
|
||||
|
||||
static const qspi_config qspi_cfg =
|
||||
{
|
||||
HW_QSPI_ADDR_SIZE_24, HW_QSPI_POL_HIGH, HW_QSPI_SAMPLING_EDGE_NEGATIVE
|
||||
};
|
||||
|
||||
bool qspi_automode_init(void)
|
||||
{
|
||||
hw_qspi_enable_clock();
|
||||
|
||||
/*
|
||||
* Setup erase instruction that will be sent by QSPI controller to erase sector in automode.
|
||||
*/
|
||||
hw_qspi_set_erase_instruction(W25Q_SECTOR_ERASE, HW_QSPI_BUS_MODE_SINGLE,
|
||||
HW_QSPI_BUS_MODE_SINGLE, 8, 5);
|
||||
/*
|
||||
* Setup instruction pair that will temporarily suspend erase operation to allow read.
|
||||
*/
|
||||
hw_qspi_set_suspend_resume_instructions(W25Q_ERASE_PROGRAM_SUSPEND, HW_QSPI_BUS_MODE_SINGLE,
|
||||
W25Q_ERASE_PROGRAM_RESUME, HW_QSPI_BUS_MODE_SINGLE, 7);
|
||||
|
||||
/*
|
||||
* QSPI controller must send write enable before erase, this sets it up.
|
||||
*/
|
||||
hw_qspi_set_write_enable_instruction(W25Q_WRITE_ENABLE, HW_QSPI_BUS_MODE_SINGLE);
|
||||
|
||||
/*
|
||||
* Setup instruction that will be used to periodically check erase operation status.
|
||||
* Check LSB which is 1 when erase is in progress.
|
||||
*/
|
||||
hw_qspi_set_read_status_instruction(W25Q_READ_STATUS_REGISTER1, HW_QSPI_BUS_MODE_SINGLE,
|
||||
HW_QSPI_BUS_MODE_SINGLE, W25Q_STATUS1_BUSY_BIT, 1, 20, 0);
|
||||
|
||||
/*
|
||||
* This sequence is necessary if flash is working in continuous read mode, when instruction
|
||||
* is not sent on every read access just address. Sending 0xFFFF will exit this mode.
|
||||
* This sequence is sent only when QSPI is working in automode and decides to send one of
|
||||
* instructions above.
|
||||
* If flash is working in DUAL bus mode sequence should be 0xFFFF and size should be
|
||||
* HW_QSPI_BREAK_SEQ_SIZE_2B.
|
||||
*/
|
||||
hw_qspi_set_break_sequence(0xFFFF, HW_QSPI_BUS_MODE_SINGLE, HW_QSPI_BREAK_SEQ_SIZE_1B, 0);
|
||||
|
||||
/*
|
||||
* If application starts from FLASH then bootloader must have set read instruction.
|
||||
*/
|
||||
if (dg_configCODE_LOCATION != NON_VOLATILE_IS_FLASH)
|
||||
{
|
||||
hw_qspi_init(&qspi_cfg);
|
||||
hw_qspi_set_div(HW_QSPI_DIV_1);
|
||||
flash_reset_continuous_mode();
|
||||
hw_qspi_set_read_instruction(W25Q_FAST_READ_QUAD, 1, 2, HW_QSPI_BUS_MODE_SINGLE,
|
||||
HW_QSPI_BUS_MODE_QUAD, HW_QSPI_BUS_MODE_QUAD,
|
||||
HW_QSPI_BUS_MODE_QUAD);
|
||||
|
||||
hw_qspi_set_extra_byte(0xA0, HW_QSPI_BUS_MODE_QUAD, 1);
|
||||
|
||||
hw_qspi_set_automode(true);
|
||||
}
|
||||
|
||||
HW_QSPIC_REG_SETF(BURSTCMDB, CS_HIGH_MIN, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
+1275
File diff suppressed because it is too large
Load Diff
+330
@@ -0,0 +1,330 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup DMA
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 <black_orca.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 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_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup FEM
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @brief FEM Driver for SKYWORKS SKY66112-11 Low Level Driver API.
|
||||
*
|
||||
* GPIOs used for controlling the FEM are configured using the following macros, that should be placed
|
||||
* in custom_config.h:
|
||||
*
|
||||
* CSD : dg_configFEM_SKY66112_11_CSD_PORT/PIN
|
||||
* CPS : dg_configFEM_SKY66112_11_CPS_PORT/PIN
|
||||
* CRX : dg_configFEM_SKY66112_11_CRX_PORT/PIN
|
||||
* CTX : dg_configFEM_SKY66112_11_CTX_PORT/PIN
|
||||
* CHL : dg_configFEM_SKY66112_11_CHL_PORT/PIN
|
||||
* ANTSEL: dg_configFEM_SKY66112_11_ANTSEL_PORT/PIN
|
||||
*
|
||||
* FEM BIAS Voltage control is enabled by the following macros:
|
||||
*
|
||||
* V18 : dg_configFEM_SKY66112_11_FEM_BIAS_V18
|
||||
* V18P : dg_configFEM_SKY66112_11_FEM_BIAS_V18P
|
||||
*
|
||||
* If none of them is set, FEM BIAS will not be controlled by this 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_FEM_H_
|
||||
#define HW_FEM_H_
|
||||
|
||||
#if dg_configFEM == FEM_SKY66112_11
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(dg_configFEM_SKY66112_11_FEM_BIAS_V18) && defined(dg_configFEM_SKY66112_11_FEM_BIAS_V18P)
|
||||
#error Only one of dg_configFEM_SKY66112_11_FEM_BIAS_V18 and dg_configFEM_SKY66112_11_FEM_BIAS_V18P can be set at a time
|
||||
#endif
|
||||
|
||||
/* Configuration/state structure (actually just a byte) */
|
||||
typedef struct __attribute__ ((__packed__)) {
|
||||
uint8_t tx_power: 1;
|
||||
uint8_t tx_bypass: 1;
|
||||
uint8_t rx_bypass: 1;
|
||||
uint8_t antsel: 1;
|
||||
uint8_t started: 1;
|
||||
} hw_fem_config;
|
||||
|
||||
/**
|
||||
* \brief Configures FEM TX Power
|
||||
*
|
||||
* \param [in] high Set true to enable high TX power
|
||||
*
|
||||
*/
|
||||
void hw_fem_set_txpower(bool high);
|
||||
|
||||
/**
|
||||
* \brief Configures FEM Antenna to use
|
||||
*
|
||||
* \param [in] one false: antenna 0, true: antenna 1
|
||||
*
|
||||
*/
|
||||
void hw_fem_set_antenna(bool one);
|
||||
|
||||
/**
|
||||
* \brief Configures FEM TX bypass mode
|
||||
*
|
||||
* \param [in] enable false: Use PA, true: bypass
|
||||
*
|
||||
*/
|
||||
void hw_fem_set_tx_bypass(bool enable);
|
||||
|
||||
/**
|
||||
* \brief Configures FEM RX bypass mode
|
||||
*
|
||||
* \param [in] enable false: Use LNA, true: bypass
|
||||
*
|
||||
*/
|
||||
void hw_fem_set_rx_bypass(bool enable);
|
||||
|
||||
/**
|
||||
* \brief Gets the TX Power setting
|
||||
*
|
||||
* \return true, if TX Power is high, false if low
|
||||
*
|
||||
*/
|
||||
bool hw_fem_get_txpower(void);
|
||||
|
||||
/**
|
||||
* \brief Gets the selected antenna
|
||||
*
|
||||
* \return false: antenna 1, true: antenna 2
|
||||
*
|
||||
*/
|
||||
bool hw_fem_get_antenna(void);
|
||||
|
||||
/**
|
||||
* \brief Gets the TX bypass mode
|
||||
*
|
||||
* \return false: No TX bypass, true: TX bypass
|
||||
*
|
||||
*/
|
||||
bool hw_fem_get_tx_bypass(void);
|
||||
|
||||
/**
|
||||
* \brief Gets the RX bypass mode
|
||||
*
|
||||
* \return false: No RX bypass, true: RX bypass
|
||||
*
|
||||
*/
|
||||
bool hw_fem_get_rx_bypass(void);
|
||||
|
||||
/**
|
||||
* \brief Sets the FEM Bias
|
||||
*
|
||||
* \param [in] voltage The voltage to set the FEM Bias to (mV)
|
||||
*
|
||||
* \return 0: success, -1: Out of range value entered, -2: FEM BIAS not supported on this board
|
||||
*
|
||||
*/
|
||||
int hw_fem_set_bias(uint16_t voltage);
|
||||
|
||||
/**
|
||||
* \brief Sets the 2nd FEM Bias
|
||||
*
|
||||
* \param [in] voltage The voltage to set the 2nd FEM Bias to (mV)
|
||||
*
|
||||
* \return 0: success, -1: Out of range value entered, -2: 2nd FEM BIAS not supported on this board
|
||||
*
|
||||
*/
|
||||
int hw_fem_set_bias2(uint16_t voltage);
|
||||
|
||||
/**
|
||||
* \brief Starts and configures FEM.
|
||||
*
|
||||
* Configures and sets GPIOs according to configuration set by hw_fem_set_config(). Also configures
|
||||
* DCF Timers.
|
||||
*
|
||||
*
|
||||
* \note To be called by the RF driver when RF is powered on
|
||||
*
|
||||
*/
|
||||
void hw_fem_start(void);
|
||||
|
||||
/**
|
||||
* \brief Stops FEM.
|
||||
*
|
||||
* Stops DCF timers and sets all FEM control signals to 0 to achieve the lowest possible power
|
||||
*
|
||||
* \note To be called by the RF driver when RF is powered off
|
||||
*
|
||||
*/
|
||||
void hw_fem_stop(void);
|
||||
|
||||
#endif /* dg_configFEM == FEM_SKY66112_11 */
|
||||
#endif /* HW_FEM_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+716
@@ -0,0 +1,716 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup GPADC
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @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 <black_orca.h>
|
||||
|
||||
/**
|
||||
* \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 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 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 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 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
|
||||
*
|
||||
*/
|
||||
static inline uint16_t hw_gpadc_get_raw_value(void)
|
||||
{
|
||||
return GPADC->GP_ADC_RESULT_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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 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_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+493
@@ -0,0 +1,493 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup GPIO
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @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 <black_orca.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_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup 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 <black_orca.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_ */
|
||||
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup LED
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @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 <black_orca.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_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+568
@@ -0,0 +1,568 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup OTPC
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 <black_orca.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)
|
||||
{
|
||||
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|
||||
/*
|
||||
* 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 OTP Controller
|
||||
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, OTPC_RESET_REQ);// Get the OTP Controller 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;
|
||||
#endif
|
||||
/*
|
||||
* Enable OTPC clock
|
||||
*/
|
||||
CRG_TOP->CLK_AMBA_REG |= 1 << REG_POS(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Close the OTP Controller.
|
||||
*
|
||||
*/
|
||||
static inline void hw_otpc_close(void)
|
||||
{
|
||||
/*
|
||||
* Disable OTPC clock
|
||||
*/
|
||||
CRG_TOP->CLK_AMBA_REG &= ~REG_MSK(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \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)
|
||||
{
|
||||
/*
|
||||
* Disable OTPC clock
|
||||
*/
|
||||
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_ */
|
||||
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
+998
@@ -0,0 +1,998 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup QSPI
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file hw_qspi.h
|
||||
*
|
||||
* @brief Definition of API for 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.
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef HW_QSPI_H_
|
||||
#define HW_QSPI_H_
|
||||
|
||||
#if dg_configUSE_HW_QSPI
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <black_orca.h>
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the mask of a field of an QSPIC register.
|
||||
*
|
||||
* \param [in] reg is the register to access
|
||||
* \param [in] field is the register field to access
|
||||
*
|
||||
*/
|
||||
#define HW_QSPIC_REG_FIELD_MASK(reg, field) \
|
||||
(QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Msk)
|
||||
|
||||
/**
|
||||
* \brief Get the bit position of a field of an QSPIC register.
|
||||
*
|
||||
* \param [in] reg is the register to access
|
||||
* \param [in] field is the register field to access
|
||||
*
|
||||
*/
|
||||
#define HW_QSPIC_REG_FIELD_POS(reg, field) \
|
||||
(QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Pos)
|
||||
|
||||
/**
|
||||
* \brief Get the value of a field of an QSPIC 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_QSPIC_REG_GETF(reg, field) \
|
||||
((QSPIC->QSPIC_##reg##_REG & (QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Msk)) >> (QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Pos))
|
||||
|
||||
/**
|
||||
* \brief Set the value of a field of an QSPIC 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_QSPIC_REG_SETF(reg, field, new_val) \
|
||||
QSPIC->QSPIC_##reg##_REG = ((QSPIC->QSPIC_##reg##_REG & ~(QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Msk)) | \
|
||||
((QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Msk) & ((new_val) << (QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Pos))))
|
||||
|
||||
|
||||
/*
|
||||
* ENUMERATION DEFINITIONS
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Bus mode
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_BUS_MODE_SINGLE, /**< Bus mode in single mode */
|
||||
HW_QSPI_BUS_MODE_DUAL, /**< Bus mode in dual mode */
|
||||
HW_QSPI_BUS_MODE_QUAD /**< Bus mode in quad mode */
|
||||
} HW_QSPI_BUS_MODE;
|
||||
|
||||
/**
|
||||
* \brief Flash memory address size
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_ADDR_SIZE_24, /**< QSPI flash memory uses 24 bits address */
|
||||
HW_QSPI_ADDR_SIZE_32 /**< QSPI flash memory uses 32 bits address */
|
||||
} HW_QSPI_ADDR_SIZE;
|
||||
|
||||
/**
|
||||
* \brief Idle clock state
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_POL_LOW = 0, /**< SPI clock will be low at idle */
|
||||
HW_QSPI_POL_HIGH = 1 /**< SPI clock will be high at idle */
|
||||
} HW_QSPI_POL;
|
||||
|
||||
/**
|
||||
* \brief Type of QSPI_CLK edge for sampling received data
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_SAMPLING_EDGE_POSITIVE = 0, /**< Sample the received data with the positive edge of the QSPI_SCK */
|
||||
HW_QSPI_SAMPLING_EDGE_NEGATIVE = 1 /**< Sample the received data with the negative edge of the QSPI_SCK */
|
||||
} HW_QSPI_SAMPLING_EDGE;
|
||||
|
||||
/**
|
||||
* \brief Selected data size of a wrapping burst
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_WRAP_SIZE_8BITS = 0, /**< Byte access (8-bits) */
|
||||
HW_QSPI_WRAP_SIZE_16BITS = 1, /**< Half word access (8-bits) */
|
||||
HW_QSPI_WRAP_SIZE_32BITS = 2, /**< Word access (8-bits) */
|
||||
} HW_QSPI_WRAP_SIZE;
|
||||
|
||||
/**
|
||||
* \brief Selected data length of a wrapping burst
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_WRAP_LEN_4BEAT = 0, /**< 4 beat wrapping burst */
|
||||
HW_QSPI_WRAP_LEN_8BEAT = 1, /**< 8 beat wrapping burst */
|
||||
HW_QSPI_WRAP_LEN_16BEAT = 2, /**< 16 beat wrapping burst */
|
||||
} HW_QSPI_WRAP_LEN;
|
||||
|
||||
/**
|
||||
* \brief Size of Burst Break Sequence
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_BREAK_SEQ_SIZE_1B = 0, /**< One byte */
|
||||
HW_QSPI_BREAK_SEQ_SIZE_2B = 1 /**< Two bytes */
|
||||
} HW_QSPI_BREAK_SEQ_SIZE;
|
||||
|
||||
/**
|
||||
* \brief QSPI pads slew rate control
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_SLEW_RATE_0, /**< xx V/ns (weak) */
|
||||
HW_QSPI_SLEW_RATE_1, /**< xx V/ns */
|
||||
HW_QSPI_SLEW_RATE_2, /**< xx V/ns */
|
||||
HW_QSPI_SLEW_RATE_3 /**< xx V/ns (strong) */
|
||||
} HW_QSPI_SLEW_RATE;
|
||||
|
||||
/**
|
||||
* \brief QSPI pads drive current
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_DRIVE_CURRENT_4, /**< 4 mA */
|
||||
HW_QSPI_DRIVE_CURRENT_8, /**< 8 mA */
|
||||
HW_QSPI_DRIVE_CURRENT_12, /**< 12 mA */
|
||||
HW_QSPI_DRIVE_CURRENT_16, /**< 16 mA */
|
||||
} HW_QSPI_DRIVE_CURRENT;
|
||||
|
||||
/**
|
||||
* \brief QSPI clock divider setting
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_QSPI_DIV_1 = 0, /**< divide by 1 */
|
||||
HW_QSPI_DIV_2 = 1, /**< divide by 2 */
|
||||
HW_QSPI_DIV_4 = 2, /**< divide by 4 */
|
||||
HW_QSPI_DIV_8 = 3 /**< divide by 8 */
|
||||
} HW_QSPI_DIV;
|
||||
|
||||
/**
|
||||
* \brief QSPI configuration
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
HW_QSPI_ADDR_SIZE address_size;
|
||||
HW_QSPI_POL idle_clock;
|
||||
HW_QSPI_SAMPLING_EDGE sampling_edge;
|
||||
} qspi_config;
|
||||
|
||||
/**
|
||||
* \brief Enable CS on QSPI bus
|
||||
*
|
||||
* Use this in manual mode.
|
||||
*
|
||||
*/
|
||||
#if (dg_configFLASH_POWER_DOWN == 1)
|
||||
__attribute__((section("text_retained")))
|
||||
#endif
|
||||
static inline void hw_qspi_cs_enable(void)
|
||||
{
|
||||
QSPIC->QSPIC_CTRLBUS_REG = QSPIC_QSPIC_CTRLBUS_REG_QSPIC_EN_CS_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable CS on QSPI bus
|
||||
*
|
||||
* Use this in manual mode.
|
||||
*
|
||||
*/
|
||||
#if (dg_configFLASH_POWER_DOWN == 1)
|
||||
__attribute__((section("text_retained")))
|
||||
#endif
|
||||
static inline void hw_qspi_cs_disable(void)
|
||||
{
|
||||
QSPIC->QSPIC_CTRLBUS_REG = QSPIC_QSPIC_CTRLBUS_REG_QSPIC_DIS_CS_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Select QSPI bus mode
|
||||
*
|
||||
* Use this in manual mode.
|
||||
*
|
||||
* \note Selecting QUAD mode will automatically configure pins IO2 and IO3 to input.
|
||||
*
|
||||
* \param [in] mode selects single/dual/quad mode for QSPI bus
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_bus_mode(HW_QSPI_BUS_MODE mode);
|
||||
|
||||
/**
|
||||
* \brief Check is SPI Bus is busy
|
||||
*
|
||||
* \return 0 - SPI Bus is idle,
|
||||
* 1 - SPI Bus is active. ReadData, WriteData or DummyData activity is in progress
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_is_busy(void)
|
||||
{
|
||||
return (uint8_t) QSPIC->QSPIC_STATUS_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 32 bits read transfer on QSPI bus
|
||||
*
|
||||
* The data is transferred using the selected mode of the SPI bus (SPI, Dual
|
||||
* SPI, Quad SPI).
|
||||
*
|
||||
* \return data read during read transfer
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_qspi_read32(void)
|
||||
{
|
||||
return QSPIC->QSPIC_READDATA_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 16 bits read transfer on QSPI bus
|
||||
*
|
||||
* The data is transferred using the selected mode of the SPI bus (SPI, Dual
|
||||
* SPI, Quad SPI).
|
||||
*
|
||||
* \return data read during read transfer
|
||||
*
|
||||
*/
|
||||
static inline uint16_t hw_qspi_read16(void)
|
||||
{
|
||||
return *((volatile uint16_t *) &(QSPIC->QSPIC_READDATA_REG));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 8 bits read transfer on QSPI bus
|
||||
*
|
||||
* The data is transferred using the selected mode of the SPI bus (SPI, Dual
|
||||
* SPI, Quad SPI).
|
||||
*
|
||||
* \return data read during read transfer
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_read8(void)
|
||||
{
|
||||
return *((volatile uint8_t *) &(QSPIC->QSPIC_READDATA_REG));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 32 bits write transfer on QSPI bus
|
||||
*
|
||||
* The data is transferred using the selected mode of the SPI bus (SPI, Dual
|
||||
* SPI, Quad SPI).
|
||||
*
|
||||
* param [in] data data to transfer
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_write32(uint32_t data)
|
||||
{
|
||||
QSPIC->QSPIC_WRITEDATA_REG = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 16 bits write transfer on QSPI bus
|
||||
*
|
||||
* The data is transferred using the selected mode of the SPI bus (SPI, Dual
|
||||
* SPI, Quad SPI).
|
||||
*
|
||||
* param [in] data data to transfer
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_write16(uint16_t data)
|
||||
{
|
||||
*((volatile uint16_t *) &(QSPIC->QSPIC_WRITEDATA_REG)) = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate 8 bits write transfer on QSPI bus
|
||||
*
|
||||
* The data is transferred using the selected mode of the SPI bus (SPI, Dual
|
||||
* SPI, Quad SPI).
|
||||
*
|
||||
* param [in] data data to transfer
|
||||
*
|
||||
*/
|
||||
#if (dg_configFLASH_POWER_DOWN == 1)
|
||||
__attribute__((section("text_retained")))
|
||||
#endif
|
||||
static inline void hw_qspi_write8(uint8_t data)
|
||||
{
|
||||
*((volatile uint8_t *) &(QSPIC->QSPIC_WRITEDATA_REG)) = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate a clock pulses to the SPI bus for 32 bits transfer
|
||||
*
|
||||
* During this activity in the SPI bus, the QSPI_IOx data pads are in hi-z state.
|
||||
* Number of pulses depends on selected mode of the SPI bus (SPI, Dual SPI, Quad SPI).
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_dummy32(void)
|
||||
{
|
||||
QSPIC->QSPIC_DUMMYDATA_REG = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate a clock pulses to the SPI bus for 16 bits transfer
|
||||
*
|
||||
* During this activity in the SPI bus, the QSPI_IOx data pads are in hi-z state.
|
||||
* Number of pulses depends on selected mode of the SPI bus (SPI, Dual SPI, Quad SPI).
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_dummy16(void)
|
||||
{
|
||||
*((volatile uint16_t *) &(QSPIC->QSPIC_DUMMYDATA_REG)) = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate a clock pulses to the SPI bus for 8 bits transfer
|
||||
*
|
||||
* During this activity in the SPI bus, the QSPI_IOx data pads are in hi-z state.
|
||||
* Number of pulses depends on selected mode of the SPI bus (SPI, Dual SPI, Quad SPI).
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_dummy8(void)
|
||||
{
|
||||
*((volatile uint8_t *) &(QSPIC->QSPIC_DUMMYDATA_REG)) = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Specifies address with that flash memory uses
|
||||
*
|
||||
* The controller uses 32 of 24 bits for address during Auto mode transfer.
|
||||
*
|
||||
* \param [in] size selects 32 or 24 address size
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_set_address_size(HW_QSPI_ADDR_SIZE size)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, USE_32BA, (size == HW_QSPI_ADDR_SIZE_32 ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get address size that flash memory uses
|
||||
*
|
||||
* The controller uses 32 of 24 bits for address during Auto mode transfer.
|
||||
*
|
||||
* \return currently selected address size
|
||||
*
|
||||
* \sa hw_qspi_set_address_size
|
||||
*
|
||||
*/
|
||||
static inline HW_QSPI_ADDR_SIZE hw_qspi_get_address_size(void)
|
||||
{
|
||||
return (HW_QSPI_ADDR_SIZE) HW_QSPIC_REG_GETF(CTRLMODE, USE_32BA);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Controls translation of burst accesses form AMBA bus to the QSPI bus
|
||||
*
|
||||
* \param [in] force 0 - controller translates a burst access on the AMBA bus
|
||||
* to a burst access on the QSPI bus. That results to a minimum
|
||||
* command/address phases, but the QSPI_CS is low for as
|
||||
* long as the access occures,
|
||||
* 1 - controller will split a burst access on the AMBA bus
|
||||
* into single accesses on the qspi bus. This results to a separate
|
||||
* read command to the FLASH memory foreach data
|
||||
* required. A 4-beat word incremental AMBA access will be
|
||||
* split into 4 different sequences of reading (command/address/
|
||||
* extra clock/read data). QSPI_CS will be only high while a qspi
|
||||
* access occures. This results to lower power dissipation with
|
||||
* respect to QSPIC_FORCENSEQ_EN=0 at cost of performance
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_force_nseq(uint8_t force)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, FORCENSEQ_EN, force);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable or disable auto mode on QSPI
|
||||
*
|
||||
* \note Selecting auto mode when any command previously configured has chosen
|
||||
* QUAD mode for any phase will automatically configure pins IO2 and IO3 to input.
|
||||
*
|
||||
* \param [in] automode true auto mode selected,
|
||||
* false manual mode selected
|
||||
*
|
||||
* \sa hw_qspi_set_read_instruction
|
||||
* \sa hw_qspi_set_read_status_instruction
|
||||
* \sa hw_qspi_set_suspend_resume_instructions
|
||||
* \sa hw_qspi_set_write_enable_instruction
|
||||
* \sa hw_qspi_set_extra_byte
|
||||
* \sa hw_qspi_set_erase_instruction
|
||||
* \sa hw_qspi_set_break_sequence
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_automode(bool automode);
|
||||
|
||||
/**
|
||||
* \brief Read automode state
|
||||
*
|
||||
* \return true auto mode is selected,
|
||||
* false manual mode is selected
|
||||
*
|
||||
*/
|
||||
static inline bool hw_qspi_get_automode(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, AUTO_MD);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get read pipe clock delay
|
||||
*
|
||||
* \return read pipe clock delay relative to the falling edge of QSPI_SCK
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_get_read_pipe_clock_delay(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, PCLK_MD);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set read pipe clock delay
|
||||
*
|
||||
* \param [in] delay read pipe clock delay relative to the falling edge of QSPI_SCK
|
||||
* value should be in range 0..7
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_set_read_pipe_clock_delay(uint8_t delay)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, PCLK_MD, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if read pipe is enabled
|
||||
*
|
||||
* \return 1 if read pipe is enabled, 0 otherwise
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_is_read_pipe_clock_enabled(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, RPIPE_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable read pipe
|
||||
*
|
||||
* \param [in] enable 1 enable read pipe,
|
||||
* 0 disable read pipe
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_enable_readpipe(uint8_t enable)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, RPIPE_EN, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get read sampling edge
|
||||
*
|
||||
* \return type of QSPI_CLK edge for sampling received data
|
||||
*
|
||||
*/
|
||||
static inline HW_QSPI_SAMPLING_EDGE hw_qspi_get_read_sampling_edge(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, RXD_NEG);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set read sampling edge
|
||||
*
|
||||
* \param [in] edge sets whether read samples or taken on rising or falling edge
|
||||
* of QSPI_SCK
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_set_read_sampling_edge(HW_QSPI_SAMPLING_EDGE edge)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, RXD_NEG, edge);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if hready signal is used
|
||||
*
|
||||
* \return 0 - when wait states are not added via hready signal during access to
|
||||
* QSPIC_WRITEDATA, QSPIC_READDATA and QSPIC_DUMMYDATA registers,
|
||||
* 1 - when wait states are added via hready signal during access to
|
||||
* QSPIC_WRITEDATA, QSPIC_READDATA and QSPIC_DUMMYDATA registers.
|
||||
* In this case read read QSPI_STATUS register to check the end of
|
||||
* activity at the SPI bus
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_is_hready_enabled(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, HRDY_MD);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable/disable adding wait states during register access
|
||||
*
|
||||
* \param [in] enable 0 - wait states will be added in hready signal during access to
|
||||
* QSPIC_WRITEDATA, QSPIC_READDATA and QSPIC_DUMMYDATA registers
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_enable_hready(uint8_t enable)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, HRDY_MD, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get clock mode
|
||||
*
|
||||
* \return 0 - SPI mode 0 is used for QSPI_CLK, the QSPI_SCK is low when QSPI_CS is high (idle),
|
||||
* 1 - SPI mode 3 is used for QSPI_CLK, the QSPI_SCK is high when QSPI_CS is high (idle)
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_get_clock_mode(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, CLK_MD);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set clock mode
|
||||
*
|
||||
* \param [in] mode HW_SPI_POL_LOW - SPI mode 0 is used for QSPI_CLK,
|
||||
* The QSPI_SCK is low when QSPI_CS is high (idle),
|
||||
* HW_SPI_POL_HIGH - SPI mode 3 is used for QSPI_CLK,
|
||||
* The QSPI_SCK is high when QSPI_CS is high (idle)
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_set_clock_mode(HW_QSPI_POL mode)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, CLK_MD, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set IO2 direction
|
||||
*
|
||||
* \param [in] output QSPI_IO2 output enable. Use this only in SPI or Dual SPI
|
||||
* mode to control /WP signal. When the Auto Mode is selected
|
||||
* and the QUAD SPI is used, set this to false.
|
||||
* false: The QSPI_IO2 pad is input
|
||||
* true: The QSPI_IO2 pad is output
|
||||
*
|
||||
*/
|
||||
#if (dg_configFLASH_POWER_DOWN == 1)
|
||||
__attribute__((section("text_retained")))
|
||||
#endif
|
||||
static inline void hw_qspi_set_io2_output(bool output)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, IO2_OEN, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set IO3 direction
|
||||
*
|
||||
* \param [in] output Use this only in SPI or Dual SPI mode to control /HOLD signal.
|
||||
* When the Auto Mode is selected and the QUAD SPI is used,
|
||||
* set this to false.
|
||||
* false: The QSPI_IO3 pad is input,
|
||||
* true: The QSPI_IO3 pad is output
|
||||
*
|
||||
*/
|
||||
#if (dg_configFLASH_POWER_DOWN == 1)
|
||||
__attribute__((section("text_retained")))
|
||||
#endif
|
||||
static inline void hw_qspi_set_io3_output(bool output)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, IO3_OEN, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set state for IO2 when it's configured as output
|
||||
*
|
||||
* \param [in] val QSPI_IO2 value to set (0 or 1)
|
||||
*
|
||||
* \sa hw_qspi_set_io2_direction
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_set_io2(uint8_t val)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, IO2_DAT, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set state for IO3 when it's configured as output
|
||||
*
|
||||
* \param [in] val QSPI_IO3 value to set (0 or 1)
|
||||
*
|
||||
* \sa hw_qspi_set_io3_direction
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_set_io3(uint8_t val)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(CTRLMODE, IO3_DAT, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read state of IO2 when not in QUAD mode
|
||||
*
|
||||
* \return value of IO2 pin (0 or 1)
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_get_io2(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, IO2_DAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read state of IO3 when not in QUAD mode
|
||||
*
|
||||
* \return value of IO3 pin (0 or 1)
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_get_io3(void)
|
||||
{
|
||||
return HW_QSPIC_REG_GETF(CTRLMODE, IO3_DAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set read instructions for QSPI flash
|
||||
*
|
||||
* This function sets up instruction to be sent to flash memory when data is requested
|
||||
* on AHB bus.
|
||||
*
|
||||
* \param [in] inst instruction for Incremental Burst or Single read access.
|
||||
* This value is the selected instruction at the cases of incremental
|
||||
* burst or single read access. Also this value is used when a wrapping
|
||||
* burst is not supported.
|
||||
* \param [in] send_once 0 - transmit instruction at any burst access,
|
||||
* 1 - transmit instruction only in the first access after the
|
||||
* selection of Auto Mode.
|
||||
* \param [in] dummy_count number of dummy bytes to send 0..4
|
||||
* \param [in] inst_phase describes the mode of the SPI bus during the instruction phase
|
||||
* \param [in] addr_phase describes the mode of the SPI bus during the address phase
|
||||
* \param [in] dummy_phase describes the mode of the SPI bus during the dummy phase
|
||||
* \param [in] data_phase describes the mode of the SPI bus during the data phase
|
||||
*
|
||||
* \sa hw_qspi_set_extra_byte
|
||||
* \sa hw_qspi_set_wrapping_burst_instruction
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_read_instruction(uint8_t inst, uint8_t send_once, uint8_t dummy_count,
|
||||
HW_QSPI_BUS_MODE inst_phase,
|
||||
HW_QSPI_BUS_MODE addr_phase,
|
||||
HW_QSPI_BUS_MODE dummy_phase,
|
||||
HW_QSPI_BUS_MODE data_phase);
|
||||
|
||||
/**
|
||||
* \brief Set wrapping burst read instructions for QSPI flash
|
||||
*
|
||||
* Calling this function will set up wrapping burst instruction to use.
|
||||
* Use this feature only when the serial FLASH memory supports a special
|
||||
* instruction for wrapping burst access.
|
||||
*
|
||||
* \param [in] inst instruction for Wrapping Burst
|
||||
* \param [in] len describes the selected length of a wrapping burst
|
||||
* \param [in] size describes the selected data size of a wrapping burst
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_wrapping_burst_instruction(uint8_t inst, HW_QSPI_WRAP_LEN len,
|
||||
HW_QSPI_WRAP_SIZE size);
|
||||
|
||||
/**
|
||||
* \brief Set extra byte to use in read instruction
|
||||
*
|
||||
* \param [in] extra_byte the value of an extra byte which will be transferred after
|
||||
* address. This byte is used for telling memory if it should stay
|
||||
* in continuous read mode or wait for normal instruction after CS
|
||||
* goes inactive
|
||||
* \param [in] bus_mode describes the mode of the SPI bus during the extra byte phase.
|
||||
* \param [in] half_disable_out 1 - disable (hi-z) output during the transmission
|
||||
* of bits [3:0] of extra byte
|
||||
*
|
||||
* \sa hw_qspi_set_read_instruction
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_extra_byte(uint8_t extra_byte, HW_QSPI_BUS_MODE bus_mode,
|
||||
uint8_t half_disable_out);
|
||||
|
||||
/**
|
||||
* \brief Set dummy byte count
|
||||
*
|
||||
* Number of dummy bytes to send when read instruction is executed.
|
||||
*
|
||||
* \param [in] count number of dummy bytes to send 0..4
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_dummy_bytes_count(uint8_t count);
|
||||
|
||||
/**
|
||||
* \brief Set number of clock when CS stays high
|
||||
*
|
||||
* \param [in] clock_count between the transmission of two different instructions to the
|
||||
* flash memory, the qspi bus stays in idle state (QSPI_CS high)
|
||||
* for at least this number of spi clock cycles. See the QSPIC_ERS_CS_HI
|
||||
* register for an exception
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_set_min_cs_high(uint8_t clock_count)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(BURSTCMDB, CS_HIGH_MIN, clock_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set up erase instructions
|
||||
*
|
||||
* Instruction will be send after call to hw_qspi_erase_block.
|
||||
*
|
||||
* \param [in] inst code value of the erase instruction
|
||||
* \param [in] inst_phase mode of the QSPI Bus during the instruction phase of the erase instruction
|
||||
* \param [in] addr_phase the mode of the QSPI Bus during the address phase of the erase instruction
|
||||
* \param [in] hclk_cycles the controller must stay without flash memory reading
|
||||
* requests for this number of AMBA AHB hclk cycles, before
|
||||
* performs the command of erase or resume 15 - 0
|
||||
* \param [in] cs_hi_cycles after the execution of instructions: write enable, erase, erase
|
||||
* suspend and erase resume, the QSPI_CS remains high for at
|
||||
* least this number of qspi bus clock cycles
|
||||
*
|
||||
* \sa hw_qspi_erase_block
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_erase_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
|
||||
HW_QSPI_BUS_MODE addr_phase, uint8_t hclk_cycles, uint8_t cs_hi_cycles);
|
||||
|
||||
/**
|
||||
* \brief Set up write enable instruction
|
||||
*
|
||||
* Instruction setup by this function will be executed before erase.
|
||||
*
|
||||
* \param [in] write_enable code value of the write enable instruction
|
||||
* \param [in] inst_phase mode of the QSPI Bus during the instruction phase
|
||||
*
|
||||
* \sa hw_qspi_erase_block
|
||||
* \sa hw_qspi_set_erase_instruction
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_write_enable_instruction(uint8_t write_enable, HW_QSPI_BUS_MODE inst_phase);
|
||||
|
||||
/**
|
||||
* \brief Set up erase suspend/resume instructions
|
||||
*
|
||||
* \param [in] erase_suspend_inst code value of the erase suspend instruction.
|
||||
* \param [in] suspend_inst_phase mode of the QSPI Bus during the instruction phase
|
||||
* of the suspend instruction
|
||||
* \param [in] erase_resume_inst code value of the erase resume instruction.
|
||||
* \param [in] resume_inst_phase mode of the QSPI Bus during the instruction phase
|
||||
* of the resume instruction
|
||||
* \param [in] minimum_delay defines the minimum time distance between the instruction
|
||||
* erase suspend and the previous instruction erase resume.
|
||||
* This delay will be also applied after the Erase command.
|
||||
* 0 - don't wait. The controller starts the erase suspend procedure
|
||||
* immediately,
|
||||
* 1..63 - controller waits at least this number of 288kHz clock cycles
|
||||
* before the suspension of erasing. Time starts counting after
|
||||
* the end of the previous erase resume
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_suspend_resume_instructions(uint8_t erase_suspend_inst,
|
||||
HW_QSPI_BUS_MODE suspend_inst_phase,
|
||||
uint8_t erase_resume_inst,
|
||||
HW_QSPI_BUS_MODE resume_inst_phase,
|
||||
uint8_t minimum_delay);
|
||||
|
||||
/**
|
||||
* \brief Set status command
|
||||
*
|
||||
* This command will be send by QSPI controller when it needs to check status of flash memory.
|
||||
* This command is also send indirectly when hw_qspi_get_erase_status is called.
|
||||
*
|
||||
* \param [in] inst instruction for read status
|
||||
* \param [in] inst_phase mode of the QSPI Bus during the instruction phase of the read
|
||||
* status instruction
|
||||
* \param [in] receive_phase mode of the QSPI Bus during the receive status phase of
|
||||
* the read status instruction
|
||||
* \param [in] busy_pos it describes which bit from the bits of status represents
|
||||
* the Busy bit (7 - 0)
|
||||
* \param [in] busy_val defines the value of the Busy bit which means that the flash is busy
|
||||
* 0 - flash is busy when the Busy bit is equal to 0,
|
||||
* 1 - flash is busy when the Busy bit is equal to 1
|
||||
* \param [in] read_delay defines the minimum time distance between the instruction
|
||||
* read status register and previous instructions like erase or
|
||||
* resume. The same delay will be also applied after the Erase command.
|
||||
* 0 - don't wait. The controller starts to read the Flash memory
|
||||
* status register immediately.
|
||||
* 1..63 - controller waits at least the number of QSPI_CLK
|
||||
* cycles and afterwards it starts to read the Flash memory status
|
||||
* register. Time starts counting after the end of the previous
|
||||
* erase/resume.
|
||||
* \param [in] sts_delay defines the register to count the delay to wait for the FLASH Status
|
||||
* Register read after an erase or erase/ resume command.
|
||||
* 0 - delay is controlled by the \p read_dealy (QSPIC_RESSTS_DLY)
|
||||
* which counts on the qspi clock,
|
||||
* 1 - delay is controlled by the \p minimum_delay value passed to
|
||||
* hw_qspi_set_suspend_resume_instructions (QSPIC_RESSUS_DLY) which
|
||||
* counts on the 288 kHz clock
|
||||
*
|
||||
* \sa hw_qspi_set_suspend_resume_instructions
|
||||
* \sa hw_qspi_get_erase_status
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_read_status_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
|
||||
HW_QSPI_BUS_MODE receive_phase,
|
||||
uint8_t busy_pos,
|
||||
uint8_t busy_val,
|
||||
uint8_t read_delay,
|
||||
uint8_t sts_delay);
|
||||
|
||||
/**
|
||||
* \brief Erase block/sector of flash memory
|
||||
*
|
||||
* For this function to work, erase instructions must be set up
|
||||
* with hw_qspi_set_erase_instruction.
|
||||
* User should call hw_qspi_get_erase_status to check if block erased.
|
||||
*
|
||||
* \note If user doesn't call hw_qspi_get_erase_status that returns status 0
|
||||
* QSPI controller will not be able to switch to manual mode.
|
||||
*
|
||||
* \param [in] addr memory address of block/sector thats is requested to be erased
|
||||
* for 24 bits addressing, bits [23:12] determine the block/sector
|
||||
* address bits. Bits [11:0] are ignored by the controller.
|
||||
* For 32 bits addressing, bits [31:12] determine the block/sectors
|
||||
* address bits. Bits [11:0] are ignored by the controller
|
||||
*
|
||||
* \sa hw_qspi_set_erase_instruction
|
||||
* \sa hw_qspi_get_erase_status
|
||||
* \sa hw_qspi_set_automode
|
||||
*
|
||||
*/
|
||||
void hw_qspi_erase_block(uint32_t addr);
|
||||
|
||||
/**
|
||||
* \brief Get erase status
|
||||
*
|
||||
* \return progress of sector/block erasing
|
||||
* 0 = no erase,
|
||||
* 1 = pending erase request,
|
||||
* 2 = erase procedure is running,
|
||||
* 3 = suspended erase procedure,
|
||||
* 4 = finishing the erase procedure
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_qspi_get_erase_status(void)
|
||||
{
|
||||
QSPIC->QSPIC_CHCKERASE_REG = 0;
|
||||
return HW_QSPIC_REG_GETF(ERASECTRL, ERS_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set burst break sequence
|
||||
*
|
||||
* \param [in] sequence value will be transmitted as the burst break sequence
|
||||
* \param [in] mode mode of the QSPI Bus during the transmission of the burst break sequence
|
||||
* \param [in] size size of Burst Break Sequence
|
||||
* \param [in] dis_out disable output during the transmission of the second half (sequence[3:0]).
|
||||
* Setting this bit is only useful if size = 1.
|
||||
* 0 - controller drives the QSPI bus during the transmission
|
||||
* of the sequence[3:0],
|
||||
* 1 - controller leaves the QSPI bus in Hi-Z during the transmission
|
||||
* of the sequence[3:0]
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_break_sequence(uint16_t sequence, HW_QSPI_BUS_MODE mode,
|
||||
HW_QSPI_BREAK_SEQ_SIZE size, uint8_t dis_out);
|
||||
|
||||
/**
|
||||
* \brief Disable burst break sequence
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_disable_burst_break_sequence(void)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(BURSTBRK, BRK_EN, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set configuration of QSPI pads
|
||||
*
|
||||
* \param [in] rate QSPI pads slew rate control
|
||||
* \param [in] current QSPI pads drive current
|
||||
*
|
||||
*/
|
||||
void hw_qspi_set_pads(HW_QSPI_SLEW_RATE rate, HW_QSPI_DRIVE_CURRENT current);
|
||||
|
||||
/**
|
||||
* \brief QSPI controller initialization
|
||||
*
|
||||
* This function will enable QSPI controller in manual mode.
|
||||
*
|
||||
* \note This function doesn't change QSPI_DIV
|
||||
*
|
||||
*/
|
||||
void hw_qspi_init(const qspi_config *cfg);
|
||||
|
||||
/**
|
||||
* \brief Enable QSPI controller clock
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_enable_clock(void)
|
||||
{
|
||||
CRG_TOP->CLK_AMBA_REG |= 1 << REG_POS(CRG_TOP, CLK_AMBA_REG, QSPI_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable QSPI controller clock
|
||||
*
|
||||
*/
|
||||
static inline void hw_qspi_disable_clock(void)
|
||||
{
|
||||
CRG_TOP->CLK_AMBA_REG &= ~REG_MSK(CRG_TOP, CLK_AMBA_REG, QSPI_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the QSPI clock divider
|
||||
*
|
||||
* \param [in] div QSPI clock divider
|
||||
*
|
||||
* \sa HW_QSPI_DIV
|
||||
*/
|
||||
void hw_qspi_set_div(HW_QSPI_DIV div);
|
||||
|
||||
/**
|
||||
* \brief Get the QSPI clock divider
|
||||
*
|
||||
* \return the QSPI clock divider setting
|
||||
*
|
||||
* \sa HW_QSPI_DIV
|
||||
*/
|
||||
static inline HW_QSPI_DIV hw_qspi_get_div(void)
|
||||
{
|
||||
return REG_GETF(CRG_TOP, CLK_AMBA_REG, QSPI_DIV);
|
||||
}
|
||||
|
||||
#endif /* dg_configUSE_HW_QSPI */
|
||||
|
||||
#endif /* HW_QSPI_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup RF
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file hw_rf.h
|
||||
*
|
||||
* @brief Radio module (RF) Low Level Driver API.
|
||||
*
|
||||
* @note The following recalibration-related weak functions can be overridden, if needed,
|
||||
* to provide additional functionality
|
||||
*
|
||||
* @note
|
||||
* ~~~{.c}
|
||||
* bool hw_rf_preoff_cb(void)
|
||||
* ~~~
|
||||
*
|
||||
* @note Called before actually shutting down the RF PD. If this returns true, the PD
|
||||
* will NOT be shutdown, but will stay on. This function can be used to decide
|
||||
* whether an RF recalibration is needed and to start the respective operation.
|
||||
* The default implementation (if an explicit implementation is omitted) returns
|
||||
* false (i.e. the RF PD shuts off immediately).
|
||||
*
|
||||
* @note
|
||||
* ~~~{.c}
|
||||
* void hw_rf_postconf_cb(void)
|
||||
* ~~~
|
||||
*
|
||||
* @note Called after the RF recommended settings are applied, or after the
|
||||
* recalibration procedure is completed. Can be used to start/reset a
|
||||
* recalibration timer, in case periodic recalibration is enabled using
|
||||
* dg_configRF_RECALIBRATION_TIMER_TIMEOUT
|
||||
*
|
||||
* @note
|
||||
* ~~~{.c}
|
||||
* void hw_rf_precalib_cb(void)
|
||||
* void hw_rf_postcalib_cb(void):
|
||||
* ~~~
|
||||
*
|
||||
* @note Called when the re-calibration (not the initial calibration) procedure
|
||||
* starts/ends. Can be used to instruct the system not to go to sleep during
|
||||
* this time.
|
||||
*
|
||||
* @note
|
||||
* ~~~{.c}
|
||||
* void hw_rf_apply_tcs_cb(void)
|
||||
* ~~~
|
||||
*
|
||||
* @note Called before applying the rf recommended settings. The implementation should
|
||||
* apply the TCS values
|
||||
*
|
||||
* @note
|
||||
* ~~~{.c}
|
||||
* uint32_t hw_rf_get_start_iff_time(void)
|
||||
* ~~~
|
||||
*
|
||||
* @note Called to get the time when IFF calibration starts
|
||||
*
|
||||
* @note
|
||||
* ~~~{.c}
|
||||
* bool hw_rf_check_iff_timeout(uint32_t start_time)
|
||||
* ~~~
|
||||
*
|
||||
* @note Called to check if IFF calibration has timed-out (i.e. took too long). It takes argument the
|
||||
* IFF calib start_time, as return by hw_rf_get_start_iff_time(). It should normally check against
|
||||
* config macro dg_configRF_IFF_CALIBRATION_TIMEOUT.
|
||||
*
|
||||
* @warning All the above functions are called in a critical section. They should not block.
|
||||
*
|
||||
* 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 "black_orca.h"
|
||||
|
||||
#include "hw_cpm.h"
|
||||
|
||||
#if dg_configFEM == FEM_SKY66112_11
|
||||
#include "hw_fem_sky66112-11.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \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 Intermediate Frequency Filter (IFF).
|
||||
*/
|
||||
bool hw_rf_iff_calibration(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();
|
||||
|
||||
/**
|
||||
* \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_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
|
||||
hw_cpm_deactivate_bod_protection();
|
||||
#endif
|
||||
|
||||
/* 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_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
|
||||
hw_cpm_delay_usec(30);
|
||||
#endif
|
||||
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
|
||||
while (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_DOWN) == 0x0);
|
||||
}
|
||||
|
||||
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
|
||||
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_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
|
||||
hw_cpm_delay_usec(30);
|
||||
hw_cpm_activate_bod_protection();
|
||||
#endif
|
||||
|
||||
// Enable the PLLdig/RFCU clock
|
||||
REG_SET_BIT(CRG_TOP, CLK_RADIO_REG, RFCU_ENABLE);
|
||||
REG_SETF(CRG_TOP, CLK_RADIO_REG, RFCU_DIV, 1);
|
||||
|
||||
#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_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
|
||||
hw_cpm_deactivate_bod_protection();
|
||||
hw_cpm_delay_usec(30);
|
||||
#endif
|
||||
|
||||
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
|
||||
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_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
|
||||
hw_cpm_delay_usec(30);
|
||||
hw_cpm_activate_bod_protection();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \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 Stop transmitting a continuous wave (unmodulated transmission)
|
||||
*
|
||||
*/
|
||||
void hw_rf_stop_continuous_wave(void);
|
||||
|
||||
/*
|
||||
* \brief Set TX Power
|
||||
*
|
||||
* This actually sets the index of the RF_TX_PWER_LUT_X_REG to use.
|
||||
*
|
||||
* \param [in] lut The index of the LUT to use. 0 disables this functionality.
|
||||
* 1: 0dbm, 2: -1dbm, 3: -2dbm, 4: -3dbm, 5: -4dbm
|
||||
*/
|
||||
static inline void hw_rf_set_tx_power(uint8_t lut)
|
||||
{
|
||||
RFCU->RF_TX_PWR_REG = lut;
|
||||
}
|
||||
|
||||
|
||||
#endif /* dg_configUSE_HW_RF */
|
||||
|
||||
#endif /* HW_RF_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+381
@@ -0,0 +1,381 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup 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 <black_orca.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)
|
||||
{
|
||||
REG_SETF(CRG_TOP, CLK_TMR_REG, TMR0_DIV, div);
|
||||
}
|
||||
|
||||
/**
|
||||
* \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_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+955
@@ -0,0 +1,955 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup Timer1
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file hw_timer1.h
|
||||
*
|
||||
* @brief Definition of API for the Timer1 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_TIMER1_H_
|
||||
#define HW_TIMER1_H_
|
||||
|
||||
#if dg_configUSE_HW_TIMER1
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <black_orca.h>
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the mask of a field of an TIMER1 register.
|
||||
*
|
||||
* \param [in] reg is the register to access
|
||||
* \param [in] field is the register field to access
|
||||
*
|
||||
*/
|
||||
#define HW_TIMER1_REG_FIELD_MASK(reg, field) \
|
||||
(TIMER1_CAPTIM_##reg##_REG_##field##_Msk)
|
||||
|
||||
/**
|
||||
* \brief Get the bit position of a field of an TIMER1 register.
|
||||
*
|
||||
* \param [in] reg is the register to access
|
||||
* \param [in] field is the register field to access
|
||||
*
|
||||
*/
|
||||
#define HW_TIMER1_REG_FIELD_POS(reg, field) \
|
||||
(TIMER1_CAPTIM_##reg##_REG_##field##_Pos)
|
||||
|
||||
/**
|
||||
* \brief Get the value of a field of an TIMER1 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_TIMER1_REG_GETF(reg, field) \
|
||||
((TIMER1->CAPTIM_##reg##_REG & (TIMER1_CAPTIM_##reg##_REG_##field##_Msk)) >> (TIMER1_CAPTIM_##reg##_REG_##field##_Pos))
|
||||
|
||||
/**
|
||||
* \brief Set the value of a field of an TIMER1 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_TIMER1_REG_SETF(reg, field, new_val) \
|
||||
TIMER1->CAPTIM_##reg##_REG = ((TIMER1->CAPTIM_##reg##_REG & ~(TIMER1_CAPTIM_##reg##_REG_##field##_Msk)) | \
|
||||
((TIMER1_CAPTIM_##reg##_REG_##field##_Msk) & ((new_val) << (TIMER1_CAPTIM_##reg##_REG_##field##_Pos))))
|
||||
|
||||
|
||||
#define EXT_CLK 16 // 16 MHz
|
||||
#define INT_CLK 32 // 32 kHz
|
||||
|
||||
/**
|
||||
* \brief Mode of operation
|
||||
*
|
||||
* PWM is enabled in both modes.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_TIMER1_MODE_TIMER = 0, /**< timer/capture mode */
|
||||
HW_TIMER1_MODE_ONESHOT = 1 /**< one-shot mode */
|
||||
} HW_TIMER1_MODE;
|
||||
|
||||
/**
|
||||
* \brief Clock source for timer
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_TIMER1_CLK_SRC_INT = 0, /**< Internal clock 32 kHz (slow) */
|
||||
HW_TIMER1_CLK_SRC_EXT = 1 /**< External clock 2/4/8/16 MHz (fast) */
|
||||
} HW_TIMER1_CLK_SRC;
|
||||
|
||||
/**
|
||||
* \brief Counting direction
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_TIMER1_DIR_UP = 0, /**< Timer counts up (counter is incremented) */
|
||||
HW_TIMER1_DIR_DOWN = 1 /**< Timer counts down (counter is decremented) */
|
||||
} HW_TIMER1_DIR;
|
||||
|
||||
/**
|
||||
* \brief Type of triggering events
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_TIMER1_TRIGGER_RISING = 0, /**< Event activated rising edge */
|
||||
HW_TIMER1_TRIGGER_FALLING = 1 /**< Event activated falling edge */
|
||||
} HW_TIMER1_TRIGGER;
|
||||
|
||||
/**
|
||||
* \brief One shot mode phases
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_TIMER1_ONESHOT_WAIT = 0, /**< Wait for the event */
|
||||
HW_TIMER1_ONESHOT_DELAY = 1, /**< Delay before started */
|
||||
HW_TIMER1_ONESHOT_STARTED = 2, /**< Start shot */
|
||||
HW_TIMER1_ONESHOT_ACTIVE = 3 /**< Shot is active */
|
||||
} HW_TIMER1_ONESHOT;
|
||||
|
||||
/**
|
||||
* \brief GPIOs for timer1
|
||||
*
|
||||
* Mainly use for mark which GPIO will triggers timer counting.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
HW_TIMER1_GPIO_NONE = 0, /**< None of GPIO */
|
||||
/* port 0 */
|
||||
HW_TIMER1_GPIO_P00 = 1, /**< Port 0, pin 0 */
|
||||
HW_TIMER1_GPIO_P01 = 2, /**< Port 0, pin 1 */
|
||||
HW_TIMER1_GPIO_P02 = 3, /**< Port 0, pin 2 */
|
||||
HW_TIMER1_GPIO_P03 = 4, /**< Port 0, pin 3 */
|
||||
HW_TIMER1_GPIO_P04 = 5, /**< Port 0, pin 4 */
|
||||
HW_TIMER1_GPIO_P05 = 6, /**< Port 0, pin 5 */
|
||||
HW_TIMER1_GPIO_P06 = 7, /**< Port 0, pin 6 */
|
||||
HW_TIMER1_GPIO_P07 = 8, /**< Port 0, pin 7 */
|
||||
/* port 1 */
|
||||
HW_TIMER1_GPIO_P10 = 9, /**< Port 1, pin 0 */
|
||||
HW_TIMER1_GPIO_P11 = 10, /**< Port 1, pin 1 */
|
||||
HW_TIMER1_GPIO_P12 = 11, /**< Port 1, pin 2 */
|
||||
HW_TIMER1_GPIO_P13 = 12, /**< Port 1, pin 3 */
|
||||
HW_TIMER1_GPIO_P14 = 13, /**< Port 1, pin 4 */
|
||||
HW_TIMER1_GPIO_P15 = 14, /**< Port 1, pin 5 */
|
||||
HW_TIMER1_GPIO_P16 = 15, /**< Port 1, pin 6 */
|
||||
HW_TIMER1_GPIO_P17 = 16, /**< Port 1, pin 7 */
|
||||
/* port 2 */
|
||||
HW_TIMER1_GPIO_P20 = 17, /**< Port 2, pin 0 */
|
||||
HW_TIMER1_GPIO_P21 = 18, /**< Port 2, pin 1 */
|
||||
HW_TIMER1_GPIO_P22 = 19, /**< Port 2, pin 2 */
|
||||
HW_TIMER1_GPIO_P23 = 20, /**< Port 2, pin 3 */
|
||||
HW_TIMER1_GPIO_P24 = 21, /**< Port 2, pin 4 */
|
||||
/* port 3 */
|
||||
HW_TIMER1_GPIO_P30 = 22, /**< Port 3, pin 0 */
|
||||
HW_TIMER1_GPIO_P31 = 23, /**< Port 3, pin 1 */
|
||||
HW_TIMER1_GPIO_P32 = 24, /**< Port 3, pin 2 */
|
||||
HW_TIMER1_GPIO_P33 = 25, /**< Port 3, pin 3 */
|
||||
HW_TIMER1_GPIO_P34 = 26, /**< Port 3, pin 4 */
|
||||
HW_TIMER1_GPIO_P35 = 27, /**< Port 3, pin 5 */
|
||||
HW_TIMER1_GPIO_P36 = 28, /**< Port 3, pin 6 */
|
||||
HW_TIMER1_GPIO_P37 = 29, /**< Port 3, pin 7 */
|
||||
/* port 4 */
|
||||
HW_TIMER1_GPIO_P40 = 30, /**< Port 4, pin 0 */
|
||||
HW_TIMER1_GPIO_P41 = 31, /**< Port 4, pin 1 */
|
||||
HW_TIMER1_GPIO_P42 = 32, /**< Port 4, pin 2 */
|
||||
HW_TIMER1_GPIO_P43 = 33, /**< Port 4, pin 3 */
|
||||
HW_TIMER1_GPIO_P44 = 34, /**< Port 4, pin 4 */
|
||||
HW_TIMER1_GPIO_P45 = 35, /**< Port 4, pin 5 */
|
||||
HW_TIMER1_GPIO_P46 = 36, /**< Port 4, pin 6 */
|
||||
HW_TIMER1_GPIO_P47 = 37, /**< Port 4, pin 7 */
|
||||
} HW_TIMER1_GPIO;
|
||||
|
||||
/**
|
||||
* \brief Timer interrupt callback
|
||||
*
|
||||
*/
|
||||
typedef void (*hw_timer1_handler_cb)(void);
|
||||
|
||||
/*
|
||||
* \brief Timer configuration for timer/capture mode
|
||||
*
|
||||
* \sa timer1_config
|
||||
* \sa hw_timer1_configure_timer
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
HW_TIMER1_DIR direction; /**< counting direction */
|
||||
uint32_t reload_val; /**< reload value */
|
||||
bool free_run; /**< free-running mode state */
|
||||
|
||||
HW_TIMER1_GPIO gpio1; /**< 1st GPIO for capture mode */
|
||||
HW_TIMER1_TRIGGER trigger1; /**< 1st GPIO capture trigger */
|
||||
HW_TIMER1_GPIO gpio2; /**< 2nd GPIO for capture mode */
|
||||
HW_TIMER1_TRIGGER trigger2; /**< 2nd GPIO capture trigger */
|
||||
} timer1_config_timer_capture;
|
||||
|
||||
/*
|
||||
* \brief Timer configuration for oneshot mode
|
||||
*
|
||||
* \sa timer1_config
|
||||
* \sa hw_timer1_configure_oneshot
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t delay; /**< delay (ticks) between GPIO event and output pulse */
|
||||
uint32_t shot_width; /**< width (ticks) of generated pulse */
|
||||
HW_TIMER1_GPIO gpio; /**< GPIO to wait for event */
|
||||
HW_TIMER1_TRIGGER trigger; /**< GPIO trigger */
|
||||
} timer1_config_oneshot;
|
||||
|
||||
/*
|
||||
* \brief Timer PWM configuration
|
||||
*
|
||||
* \sa timer1_config
|
||||
* \sa hw_timer1_configure_pwm
|
||||
* \sa hw_timer1_set_pwm_freq
|
||||
* \sa hw_timer1_set_pwm_duty_cycle
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t frequency; /**< frequency */
|
||||
uint16_t duty_cycle; /**< duty cycle */
|
||||
} timer1_config_pwm;
|
||||
|
||||
/*
|
||||
* \brief Timer configuration
|
||||
*
|
||||
* Only one of \p timer and \p oneshot configuration can be set since they are stored in the same
|
||||
* union (and will overwrite each other). Proper configuration structure is selected depending on
|
||||
* timer mode set.
|
||||
*
|
||||
* \sa timer1_config_timer_capture
|
||||
* \sa timer1_config_oneshot
|
||||
* \sa timer1_config_pwm
|
||||
* \sa hw_timer1_configure
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
HW_TIMER1_CLK_SRC clk_src; /**< clock source */
|
||||
uint16_t prescaler; /**< clock prescaler */
|
||||
|
||||
timer1_config_timer_capture timer; /**< configuration for timer/capture mode */
|
||||
timer1_config_oneshot oneshot; /**< configuration for oneshot mode */
|
||||
|
||||
timer1_config_pwm pwm; /**< PWM configuration */
|
||||
} timer1_config;
|
||||
|
||||
|
||||
#if dg_configUSER_CAN_USE_TIMER1 == 1
|
||||
|
||||
/**
|
||||
* \brief Timer initialization
|
||||
*
|
||||
* 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] mode timer mode
|
||||
* \param [in] cfg configuration
|
||||
*
|
||||
*/
|
||||
void hw_timer1_init(HW_TIMER1_MODE mode, const timer1_config *cfg);
|
||||
|
||||
/**
|
||||
* \brief Timer configuration
|
||||
*
|
||||
* Shortcut to call appropriate configuration function. If \p cfg is NULL, this function does
|
||||
* nothing except switching timer to selected mode.
|
||||
*
|
||||
* \param [in] mode timer mode
|
||||
* \param [in] cfg configuration
|
||||
*
|
||||
*/
|
||||
void hw_timer1_configure(HW_TIMER1_MODE mode, const timer1_config *cfg);
|
||||
|
||||
/**
|
||||
* \brief Timer configuration for timer/capture mode
|
||||
*
|
||||
* Shortcut to call appropriate configuration function. This does not switch timer to timer/capture
|
||||
* mode, it should be done separately using hw_timer1_set_mode().
|
||||
*
|
||||
* \param [in] cfg configuration
|
||||
*
|
||||
*/
|
||||
void hw_timer1_configure_timer(const timer1_config_timer_capture *cfg);
|
||||
|
||||
/**
|
||||
* \brief Timer configuration for oneshot mode
|
||||
*
|
||||
* Shortcut to call appropriate configuration function. This does not switch timer to oneshot
|
||||
* mode, it should be done separately using hw_timer1_set_mode().
|
||||
*
|
||||
* \param [in] cfg configuration
|
||||
*
|
||||
*/
|
||||
void hw_timer1_configure_oneshot(const timer1_config_oneshot *cfg);
|
||||
|
||||
/**
|
||||
* \brief Set clock source of the timer
|
||||
*
|
||||
* \param [in] clk clock source of the timer, external or internal
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_clk(HW_TIMER1_CLK_SRC clk)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_SYS_CLK_EN, clk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set timer clock prescaler
|
||||
*
|
||||
* Actual timer frequency is \p timer_freq = \p freq_clock / (\p value + 1)
|
||||
*
|
||||
* \param [in] value prescaler
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_prescaler(uint16_t value)
|
||||
{
|
||||
TIMER1->CAPTIM_PRESCALER_REG = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set timer reload value
|
||||
*
|
||||
* \note This changes the same register value as hw_timer1_set_oneshot_delay() since both parameters
|
||||
* share the same register (value is interpreted differently depending on timer mode).
|
||||
*
|
||||
* \param [in] value reload value
|
||||
*
|
||||
* \sa hw_timer1_set_oneshot_delay
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_reload(uint32_t value)
|
||||
{
|
||||
TIMER1->CAPTIM_RELOAD_REG = (uint16_t) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set pulse delay in oneshot mode
|
||||
*
|
||||
* \note This changes the same register value as hw_timer1_set_reload() since both parameters share
|
||||
* the same register (value is interpreted differently depending on timer mode).
|
||||
*
|
||||
* \param [in] delay delay (ticks)
|
||||
*
|
||||
* \sa hw_timer1_set_reload
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_oneshot_delay(uint32_t delay)
|
||||
{
|
||||
TIMER1->CAPTIM_RELOAD_REG = (uint16_t) delay;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set shot width
|
||||
*
|
||||
* This applies only to one-shot mode.
|
||||
*
|
||||
* \param [in] duration shot phase duration
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_shot_width(uint32_t duration)
|
||||
{
|
||||
TIMER1->CAPTIM_SHOTWIDTH_REG = (uint16_t) duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn on free run mode of the timer
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_freerun(bool enabled)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_FREE_RUN_MODE_EN, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set a type of the edge which triggers event1
|
||||
*
|
||||
* \param [in] edge type of edge, rising or falling
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_event1_trigger(HW_TIMER1_TRIGGER edge)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_IN1_EVENT_FALL_EN, edge);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set a type of the edge which triggers event2
|
||||
*
|
||||
* \param [in] edge type of edge, rising or falling
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_event2_trigger(HW_TIMER1_TRIGGER edge)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_IN2_EVENT_FALL_EN, edge);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set a GPIO input which triggers event1
|
||||
*
|
||||
* \param [in] gpio GPIO input
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_event1_gpio(HW_TIMER1_GPIO gpio)
|
||||
{
|
||||
TIMER1->CAPTIM_GPIO1_CONF_REG = gpio;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set a GPIO input which triggers event2
|
||||
*
|
||||
* \param [in] gpio GPIO input
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_event2_gpio(HW_TIMER1_GPIO gpio)
|
||||
{
|
||||
TIMER1->CAPTIM_GPIO2_CONF_REG = gpio;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get clock source of the timer
|
||||
*
|
||||
* \return clock source
|
||||
*
|
||||
*/
|
||||
static inline HW_TIMER1_CLK_SRC hw_timer1_get_clk(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(CTRL, CAPTIM_SYS_CLK_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get timer clock prescaler
|
||||
*
|
||||
* Actual timer frequency is \p timer_freq = \p freq_clock / (\p retval + 1)
|
||||
*
|
||||
* \return prescaler value
|
||||
*
|
||||
* \sa hw_timer1_get_prescaler_val
|
||||
*
|
||||
*/
|
||||
static inline uint16_t hw_timer1_get_prescaler(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_PRESCALER_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get timer reload value
|
||||
*
|
||||
* \return reload value
|
||||
*
|
||||
* \sa hw_timer1_set_reload
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_reload(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_RELOAD_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get pulse delay in oneshot mode
|
||||
*
|
||||
* \return delay (ticks)
|
||||
*
|
||||
* \sa hw_timer1_get_oneshot_delay
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_oneshot_delay(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_RELOAD_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get shot width
|
||||
*
|
||||
* This applies only to one-shot mode.
|
||||
*
|
||||
* \return shot width value
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_shot_width(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_SHOTWIDTH_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get free-running mode state
|
||||
*
|
||||
* \return free-running mode state
|
||||
*
|
||||
*/
|
||||
static inline bool hw_timer1_get_freerun(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(CTRL, CAPTIM_FREE_RUN_MODE_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get a type of the edge which triggers event1
|
||||
*
|
||||
* \return edge type
|
||||
*
|
||||
*/
|
||||
static inline HW_TIMER1_TRIGGER hw_timer1_get_event1_trigger(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(CTRL, CAPTIM_IN1_EVENT_FALL_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get a type of the edge which triggers event2
|
||||
*
|
||||
* \return edge type
|
||||
*
|
||||
*/
|
||||
static inline HW_TIMER1_TRIGGER hw_timer1_get_event2_trigger(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(CTRL, CAPTIM_IN2_EVENT_FALL_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get a GPIO input which triggers event1
|
||||
*
|
||||
* \return GPIO input
|
||||
*
|
||||
*/
|
||||
static inline HW_TIMER1_GPIO hw_timer1_get_event1_gpio(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_GPIO1_CONF_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get a GPIO input which triggers event2
|
||||
*
|
||||
* \return GPIO input
|
||||
*
|
||||
*/
|
||||
static inline HW_TIMER1_GPIO hw_timer1_get_event2_gpio(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_GPIO2_CONF_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the capture time for event on GPIO1
|
||||
*
|
||||
* \return time for event on GPIO1
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_capture1(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_CAPTURE_GPIO1_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the capture time for event on GPIO2
|
||||
*
|
||||
* \return time for event on GPIO2
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_capture2(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_CAPTURE_GPIO2_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the direction of timer counting
|
||||
*
|
||||
* \param [in] dir counting direction of the timer, up or down
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_direction(HW_TIMER1_DIR dir)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_COUNT_DOWN_EN, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn on one shot mode
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_mode(HW_TIMER1_MODE mode)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_ONESHOT_MODE_EN, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn on capture mode
|
||||
*
|
||||
*/
|
||||
static inline HW_TIMER1_MODE hw_timer1_get_mode(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(CTRL, CAPTIM_ONESHOT_MODE_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the tick count of the timer
|
||||
*
|
||||
* \return current value of the timer ticks
|
||||
*
|
||||
* \sa hw_timer1_get_prescaler_val
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_count(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_TIMER_VAL_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current phase of the one shot mode
|
||||
*
|
||||
* \return current phase of the one shot mode
|
||||
*
|
||||
*/
|
||||
static inline HW_TIMER1_ONESHOT hw_timer1_get_oneshot_phase(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(STATUS, CAPTIM_ONESHOT_PHASE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current state of IN1
|
||||
*
|
||||
* \return current logic level of IN1
|
||||
*
|
||||
*/
|
||||
static inline bool hw_timer1_get_gpio1_state(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(STATUS, CAPTIM_IN1_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current state of IN2
|
||||
*
|
||||
* \return current logic level of IN2
|
||||
*
|
||||
*/
|
||||
static inline bool hw_timer1_get_gpio2_state(void)
|
||||
{
|
||||
return HW_TIMER1_REG_GETF(STATUS, CAPTIM_IN2_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current prescaler counter value
|
||||
*
|
||||
* This is value of internal counter used for prescaling. It can be used to have finer granularity
|
||||
* when reading timer value.
|
||||
*
|
||||
* For reading current setting of prescaler, see hw_timer1_get_prescaler().
|
||||
*
|
||||
* \return current prescaler counter value
|
||||
*
|
||||
* \sa hw_timer1_get_count
|
||||
* \sa hw_timer1_get_prescaler
|
||||
*
|
||||
*/
|
||||
static inline uint16_t hw_timer1_get_prescaler_val(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_PRESCALER_VAL_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Register an interrupt handler.
|
||||
*
|
||||
* \param [in] handler function pointer to handler to call when an interrupt occurs
|
||||
*
|
||||
*/
|
||||
void hw_timer1_register_int(hw_timer1_handler_cb handler);
|
||||
|
||||
/**
|
||||
* \brief Unregister an interrupt handler
|
||||
*
|
||||
*/
|
||||
void hw_timer1_unregister_int(void);
|
||||
|
||||
/**
|
||||
* \brief Freeze timer
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_freeze(void)
|
||||
{
|
||||
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SWTIM1_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Unfreeze timer
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_unfreeze(void)
|
||||
{
|
||||
GPREG->RESET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SWTIM1_Msk;
|
||||
}
|
||||
|
||||
|
||||
#else // (dg_configUSER_CAN_USE_TIMER1 == 0)
|
||||
|
||||
|
||||
#define LP_CNT_REG_RANGE ( 16 )
|
||||
#define LP_CNT_MAX_VALUE ( (1 << LP_CNT_REG_RANGE) - 1 )
|
||||
#define LP_CNT_PRESCALED_MASK ( LP_CNT_MAX_VALUE )
|
||||
#define LP_CNT_NATIVE_MASK ( (1 << (LP_CNT_REG_RANGE + dg_configTim1PrescalerBitRange)) - 1 )
|
||||
|
||||
/**
|
||||
* \brief Configure timer as tick timer
|
||||
*
|
||||
* \details Setup Timer1 for use as a tick timer:
|
||||
* <ul>
|
||||
* <li> use LP clock and prescaler (if configured)
|
||||
* <li> free running mode
|
||||
* <li> IRQ masked
|
||||
* <li> up counter
|
||||
* <li> timer mode
|
||||
* <li> disabled
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
void hw_timer1_lp_clk_init(void);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Enable interrupt
|
||||
*
|
||||
* \return void
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_int_enable(void)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_IRQ_EN, 1);
|
||||
NVIC_ClearPendingIRQ(SWTIM1_IRQn);
|
||||
NVIC_EnableIRQ(SWTIM1_IRQn);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Disable interrupt
|
||||
*
|
||||
* \return void
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_int_disable(void)
|
||||
{
|
||||
NVIC_DisableIRQ(SWTIM1_IRQn);
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_IRQ_EN, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get counter's value
|
||||
*
|
||||
* \return The current value of the counter (prescaled).
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_value(void) __attribute__((always_inline));
|
||||
|
||||
static inline uint32_t hw_timer1_get_value(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_TIMER_VAL_REG;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Macro to get the current value of the timer, both prescaled and in LP clock cycles.
|
||||
*
|
||||
* \details Special care is needed when a prescaler is used. In this case, the
|
||||
* counting sequence is the following (assuminga prescaler of 3):
|
||||
* prescaler: 0 1 2 3 0 1 2 3 0
|
||||
* counter: 0 1 2
|
||||
*
|
||||
* If not implemented properly then the following may happen:
|
||||
* - let's assume that we are at the end of the {0, 3} period
|
||||
* - the counter's value is read and the result is 0
|
||||
* - at that moment, the counter increases it's prescaler value (and the counter's value
|
||||
* respectively), so the time becomes {1, 0}
|
||||
* - the reading of the prescaler's value will give 0 but {0, 0} is earlier than {0, 3} (when
|
||||
* the operation started) and this may result in errors in time computations.
|
||||
*
|
||||
*/
|
||||
#define HW_TIMER1_GET_INSTANT(prescaled, fine) \
|
||||
do { \
|
||||
if (dg_configTim1Prescaler != 0) { \
|
||||
uint32_t prescaler_v; \
|
||||
\
|
||||
do { \
|
||||
prescaler_v = TIMER1->CAPTIM_PRESCALER_VAL_REG; \
|
||||
prescaled = TIMER1->CAPTIM_TIMER_VAL_REG; \
|
||||
} while (prescaler_v != TIMER1->CAPTIM_PRESCALER_VAL_REG); \
|
||||
\
|
||||
fine = ( (uint32_t)prescaled * (1 + dg_configTim1Prescaler) + prescaler_v); \
|
||||
} \
|
||||
else { \
|
||||
prescaled = TIMER1->CAPTIM_TIMER_VAL_REG; \
|
||||
fine = prescaled; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* \brief Macro to set the trigger value. The previous trigger value is returned to the caller.
|
||||
*
|
||||
*/
|
||||
#define HW_TIMER1_SET_TRIGGER(value, last_value) \
|
||||
do { \
|
||||
last_value = TIMER1->CAPTIM_RELOAD_REG; \
|
||||
TIMER1->CAPTIM_RELOAD_REG = value; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get trigger value
|
||||
*
|
||||
* \return The current value of the trigger (prescaled).
|
||||
*
|
||||
*/
|
||||
static inline uint32_t hw_timer1_get_trigger(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_RELOAD_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set an "invalid" trigger value, which refers far away in the future
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_invalidate_trigger(void) __attribute__((always_inline));
|
||||
|
||||
static inline void hw_timer1_invalidate_trigger(void)
|
||||
{
|
||||
uint32_t lp_current_time; // prescaled
|
||||
uint32_t trigger;
|
||||
uint32_t dummy __attribute__((unused));
|
||||
|
||||
lp_current_time = hw_timer1_get_value(); // Get current time
|
||||
trigger = (lp_current_time - 1) & LP_CNT_PRESCALED_MASK; // Get an "invalid" trigger
|
||||
HW_TIMER1_SET_TRIGGER(trigger, dummy); // Move trigger too far in the future so
|
||||
// that no interrupt from the timer arrives.
|
||||
}
|
||||
|
||||
#endif // dg_configUSER_CAN_USE_TIMER1
|
||||
|
||||
|
||||
/**
|
||||
* \brief Enable the timer
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_enable(void)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_EN, 1);
|
||||
REG_SET_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable the timer
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_disable(void)
|
||||
{
|
||||
HW_TIMER1_REG_SETF(CTRL, CAPTIM_EN, 0);
|
||||
REG_CLR_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Timer PWM configuration
|
||||
*
|
||||
* Shortcut to call appropriate configuration function.
|
||||
*
|
||||
* \param [in] cfg configuration
|
||||
*
|
||||
*/
|
||||
void hw_timer1_configure_pwm(const timer1_config_pwm *cfg);
|
||||
|
||||
/**
|
||||
* \brief Set PWM frequency prescaler
|
||||
*
|
||||
* Actual PWM frequency is \p pwm_freq = \p timer_freq / (\p value + 1)
|
||||
*
|
||||
* \param [in] value PWM frequency defined as above
|
||||
*
|
||||
* \sa hw_timer1_set_prescaler
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_pwm_freq(uint16_t value)
|
||||
{
|
||||
TIMER1->CAPTIM_PWM_FREQ_REG = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set PWM duty cycle
|
||||
*
|
||||
* Actualy PWM duty cycle is \p pwm_dc = \p value / (\p pwm_freq + 1)
|
||||
*
|
||||
* \param [in] value PWM duty cycle defined as above
|
||||
*
|
||||
* \sa hw_timer1_set_pwm_freq
|
||||
*
|
||||
*/
|
||||
static inline void hw_timer1_set_pwm_duty_cycle(uint16_t value)
|
||||
{
|
||||
TIMER1->CAPTIM_PWM_DC_REG = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get PWM frequency prescaler
|
||||
*
|
||||
* Actual PWM frequency is \p pwm_freq = \p timer_freq / (\p retval + 1)
|
||||
*
|
||||
* \return PWM frequency as defined above
|
||||
*
|
||||
*/
|
||||
static inline uint16_t hw_timer1_get_pwm_freq(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_PWM_FREQ_REG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get PWM duty cycle
|
||||
*
|
||||
* Actualy PWM duty cycle is \p pwm_dc = \p retval / (\p pwm_freq + 1)
|
||||
*
|
||||
* \return PWM duty cycle as defined above
|
||||
*
|
||||
*/
|
||||
static inline uint16_t hw_timer1_get_pwm_duty_cycle(void)
|
||||
{
|
||||
return TIMER1->CAPTIM_PWM_DC_REG;
|
||||
}
|
||||
|
||||
#endif /* dg_configUSE_HW_TIMER1 */
|
||||
|
||||
#endif /* HW_TIMER1_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
#if dg_configUSE_HW_TRNG
|
||||
|
||||
#include <black_orca.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 TRNG get numbers.
|
||||
*
|
||||
* This function reads the random number 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.
|
||||
*
|
||||
*/
|
||||
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.
|
||||
*
|
||||
*/
|
||||
uint8_t hw_trng_get_fifo_level(void);
|
||||
|
||||
/**
|
||||
* \brief TRNG disable.
|
||||
*
|
||||
* This function disables the TRNG and its interrupt.
|
||||
*
|
||||
*/
|
||||
void hw_trng_disable(void);
|
||||
|
||||
#endif /* dg_configUSE_HW_TRNG */
|
||||
+1173
File diff suppressed because it is too large
Load Diff
+186
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup 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 <black_orca.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_ */
|
||||
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+462
@@ -0,0 +1,462 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup 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_USB_WKUP
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <black_orca.h>
|
||||
#include "hw_gpio.h"
|
||||
|
||||
|
||||
/**
|
||||
* \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 {
|
||||
uint8_t threshold; /**< counter threshold */
|
||||
uint8_t debounce; /**< debounce time in ms */
|
||||
|
||||
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 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);
|
||||
|
||||
/**
|
||||
* \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 miliseconds
|
||||
*
|
||||
*/
|
||||
static inline void hw_wkup_set_debounce_time(uint8_t time_ms)
|
||||
{
|
||||
HW_WKUP_REG_SETF(CTRL, WKUP_DEB_VALUE, time_ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get current debounce time
|
||||
*
|
||||
* \return debounce time in miliseconds
|
||||
*
|
||||
*/
|
||||
static inline uint8_t hw_wkup_get_debounce_time(void)
|
||||
{
|
||||
return HW_WKUP_REG_GETF(CTRL, WKUP_DEB_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set threshold for event counter
|
||||
*
|
||||
* Interrupt is generated after event counter reaches configured value.
|
||||
*
|
||||
* \param [in] level number of events
|
||||
*
|
||||
* \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
|
||||
*
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
*/
|
||||
static inline void hw_wkup_reset_counter(void)
|
||||
{
|
||||
WAKEUP->WKUP_RESET_CNTR_REG = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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)
|
||||
{
|
||||
uint16_t sel_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 5 + port);
|
||||
sel_rx_reg &= ~(1 << pin);
|
||||
sel_rx_reg |= (!!enabled) << pin;
|
||||
*((volatile uint16_t *)WAKEUP_BASE + 5 + port) = sel_rx_reg;
|
||||
}
|
||||
|
||||
/** \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 sel_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 5 + port);
|
||||
return (sel_rx_reg & (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_BASE + 10 + port);
|
||||
pol_rx_reg &= ~(1 << pin);
|
||||
pol_rx_reg |= (!!state) << pin;
|
||||
*((volatile uint16_t *)WAKEUP_BASE + 10 + port) = pol_rx_reg;
|
||||
}
|
||||
|
||||
/** \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_BASE + 10 + 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_BASE + 10 + port) = ~state; // register has inverted logic than state bitmask
|
||||
*((volatile uint16_t *)WAKEUP_BASE + 5 + port) = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get event counting state 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)
|
||||
{
|
||||
return *((volatile uint16_t *)WAKEUP_BASE + 5 + port);
|
||||
}
|
||||
|
||||
/**
|
||||
* \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)
|
||||
{
|
||||
return ~(*((volatile uint16_t *)WAKEUP_BASE + 10 + port)); // register has inverted logic that returned bitmask
|
||||
}
|
||||
|
||||
/**
|
||||
* \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;
|
||||
}
|
||||
|
||||
#endif /* dg_configUSE_HW_USB_WKUP */
|
||||
|
||||
#endif /* HW_WKUP_H_ */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* \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 "black_orca.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;
|
||||
|
||||
extern bool is_calibrated_chip;
|
||||
|
||||
|
||||
/**
|
||||
* \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_ */
|
||||
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
@@ -0,0 +1,743 @@
|
||||
/**
|
||||
\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;
|
||||
\
|
||||
|
||||
/*
|
||||
* 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;
|
||||
CRG_TOP->DIVN_SYNC_REG = val;
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
|
||||
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: Feb 15, 2016 - 12:25:47
|
||||
*/
|
||||
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);
|
||||
|
||||
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));
|
||||
|
||||
REG_SETF(DCDC, DCDC_VDD_1_REG, DCDC_VDD_CUR_LIM_MAX_LV, 0xD);
|
||||
// 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)));
|
||||
|
||||
REG_SETF(DCDC, DCDC_V14_0_REG, DCDC_V14_VOLTAGE, 0x7);
|
||||
|
||||
if (dg_configPOWER_FLASH == 1)
|
||||
{
|
||||
REG_SETF(DCDC, DCDC_V18_0_REG, DCDC_V18_VOLTAGE, 0x16);
|
||||
}
|
||||
|
||||
if (dg_configPOWER_EXT_1V8_PERIPHERALS == 1)
|
||||
{
|
||||
REG_SETF(DCDC, DCDC_V18P_0_REG, DCDC_V18P_VOLTAGE, 0x16);
|
||||
}
|
||||
|
||||
if (dg_configPOWER_FLASH == 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);
|
||||
}
|
||||
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_EXT_1V8_PERIPHERALS == 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 (BLACK_ORCA_TARGET_IC >= BLACK_ORCA_IC_VERSION(A, C))
|
||||
{
|
||||
REG_SETF(CRG_TOP, BANDGAP_REG, BYPASS_COLD_BOOT_DISABLE, 1); // Last review date: Feb 15, 2016 - 12:25:47
|
||||
}
|
||||
}
|
||||
|
||||
void hw_cpm_configure_xtal32k_pins(void)
|
||||
{
|
||||
GPIO->P20_MODE_REG = 0x26;
|
||||
GPIO->P21_MODE_REG = 0x26;
|
||||
}
|
||||
|
||||
void hw_cpm_trigger_sw_cursor(void)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
if (dg_configUSE_SW_CURSOR == 1)
|
||||
{
|
||||
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_B)
|
||||
{
|
||||
SW_CURSOR_SET = 1 << SW_CURSOR_PIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
SW_CURSOR_RESET = 1 << SW_CURSOR_PIN;
|
||||
}
|
||||
|
||||
SW_CURSOR_GPIO = 0x300;
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
}
|
||||
|
||||
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_B)
|
||||
{
|
||||
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_configUSE_LP_CLK != LP_CLK_RCX)
|
||||
{
|
||||
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_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_VDD_LVL, val, 1); /* VDD Level (700mV) */ \
|
||||
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_V33_TRIM, val, 2); /* V33 trim */ \
|
||||
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_1V8_PA_TRIM, val, 2); /* 1V8P trim */ \
|
||||
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_1V8_FLASH_TRIM, val, 2); /* 1V8 trim */ \
|
||||
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_VDD_TRIM, val, 2); /* VDD trim */ \
|
||||
CRG_TOP->BOD_CTRL_REG = val; \
|
||||
\
|
||||
val = 0; \
|
||||
/* 1V8 Flash enable */ \
|
||||
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_VBAT_EN, val, 1); \
|
||||
/* 1V8 Flash enable */ \
|
||||
if ((dg_configPOWER_FLASH == 1) && (dg_configFLASH_POWER_OFF == 0)) { \
|
||||
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN, val, 1); \
|
||||
} \
|
||||
/* 1V8P enable */ \
|
||||
if (dg_configPOWER_EXT_1V8_PERIPHERALS == 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; \
|
||||
} 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_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 */
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
@@ -0,0 +1,337 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup SYSTEM
|
||||
* \{
|
||||
* \addtogroup DMA
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file hw_dma.c
|
||||
*
|
||||
* 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 <global_io.h>
|
||||
#include <core_cm0.h>
|
||||
#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) ((uint16 *) (((int) &(reg)) + ((chan) << 4)))
|
||||
|
||||
/**
|
||||
* \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:
|
||||
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA01_SEL, channel_setup->dma_req_mux);
|
||||
break;
|
||||
|
||||
case HW_DMA_CHANNEL_2:
|
||||
case HW_DMA_CHANNEL_3:
|
||||
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA23_SEL, channel_setup->dma_req_mux);
|
||||
break;
|
||||
|
||||
case HW_DMA_CHANNEL_4:
|
||||
case HW_DMA_CHANNEL_5:
|
||||
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA45_SEL, channel_setup->dma_req_mux);
|
||||
break;
|
||||
|
||||
case HW_DMA_CHANNEL_6:
|
||||
case HW_DMA_CHANNEL_7:
|
||||
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA67_SEL, channel_setup->dma_req_mux);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
src_address = black_orca_phy_addr(channel_setup->src_address);
|
||||
dest_address = black_orca_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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 Timer 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
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,395 @@
|
||||
/**
|
||||
* \addtogroup BSP
|
||||
* \{
|
||||
* \addtogroup DEVICES
|
||||
* \{
|
||||
* \addtogroup FEM
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @brief FEM Driver for SKYWORKS SKY66112-11 Radio module
|
||||
*
|
||||
* 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_configFEM == FEM_SKY66112_11
|
||||
#include "stdint.h"
|
||||
|
||||
#include "black_orca.h"
|
||||
#include "hw_gpio.h"
|
||||
#include "hw_fem_sky66112-11.h"
|
||||
|
||||
static hw_fem_config fem_config __RETAINED;
|
||||
|
||||
#if !defined(dg_configFEM_SKY66112_11_CTX_PORT) || !defined(dg_configFEM_SKY66112_11_CTX_PIN)
|
||||
#error FEM CTX GPIO must be defined!!
|
||||
#endif
|
||||
|
||||
#if !defined(dg_configFEM_SKY66112_11_CRX_PORT) || !defined(dg_configFEM_SKY66112_11_CRX_PIN)
|
||||
#error FEM CRX GPIO must be defined!!
|
||||
#endif
|
||||
|
||||
|
||||
int hw_fem_set_bias(uint16_t voltage)
|
||||
{
|
||||
uint16_t value;
|
||||
|
||||
if (voltage < 1200 || voltage > 1975)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (voltage - 1200) / 27.5;
|
||||
|
||||
// /* Value is actually one lower than computed */
|
||||
// if (value > 0)
|
||||
// value--;
|
||||
|
||||
#ifdef dg_configFEM_SKY66112_11_FEM_BIAS_V18P
|
||||
REG_SETF(DCDC, DCDC_V18P_0_REG, DCDC_V18P_VOLTAGE, value);
|
||||
return 0;
|
||||
#elif defined(dg_configFEM_SKY66112_11_FEM_BIAS_V18)
|
||||
REG_SETF(DCDC, DCDC_V18_0_REG, DCDC_V18_VOLTAGE, value);
|
||||
return 0;
|
||||
#else
|
||||
return -2;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int hw_fem_set_bias2(uint16_t voltage)
|
||||
{
|
||||
uint16_t value;
|
||||
|
||||
if (voltage < 1200 || voltage > 1975)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (voltage - 1200) / 27.5;
|
||||
|
||||
// /* Value is actually one lower than computed */
|
||||
// if (value > 0)
|
||||
// value--;
|
||||
|
||||
#ifdef dg_configFEM_SKY66112_11_FEM_BIAS2_V18P
|
||||
REG_SETF(DCDC, DCDC_V18P_0_REG, DCDC_V18P_VOLTAGE, value);
|
||||
#elif defined(dg_configFEM_SKY66112_11_FEM_BIAS2_V18)
|
||||
REG_SETF(DCDC, DCDC_V18_0_REG, DCDC_V18_VOLTAGE, value);
|
||||
#else
|
||||
return -2;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hw_fem_set_txpower(bool high)
|
||||
{
|
||||
#if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN)
|
||||
GLOBAL_INT_DISABLE();
|
||||
fem_config.tx_power = high;
|
||||
|
||||
if (fem_config.started)
|
||||
{
|
||||
if (high == false)
|
||||
{
|
||||
/* TX Power low. Stop DCF, set GPIO to low */
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CHL_PORT,
|
||||
dg_configFEM_SKY66112_11_CHL_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
REG_SET_MASKED(RFCU_POWER, RF_PORT_EN_REG,
|
||||
RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_RX_Msk |
|
||||
RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_TX_Msk, 0);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TX Power high. Configure GPIO for DCF. Enable DCF on TX. */
|
||||
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CHL_PORT,
|
||||
dg_configFEM_SKY66112_11_CHL_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT4_DCF);
|
||||
REG_SET_MASKED(RFCU_POWER, RF_PORT_EN_REG,
|
||||
RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_RX_Msk |
|
||||
RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_TX_Msk,
|
||||
RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_TX_Msk);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_bypass(void)
|
||||
{
|
||||
uint16_t m = 0;
|
||||
|
||||
if (fem_config.tx_bypass)
|
||||
{
|
||||
m = RFCU_POWER_RF_PORT_EN_REG_RF_PORT3_TX_Msk;
|
||||
}
|
||||
|
||||
if (fem_config.rx_bypass)
|
||||
{
|
||||
m |= RFCU_POWER_RF_PORT_EN_REG_RF_PORT3_RX_Msk;
|
||||
}
|
||||
|
||||
REG_SET_MASKED(RFCU_POWER, RF_PORT_EN_REG,
|
||||
RFCU_POWER_RF_PORT_EN_REG_RF_PORT3_RX_Msk |
|
||||
RFCU_POWER_RF_PORT_EN_REG_RF_PORT3_TX_Msk, m);
|
||||
|
||||
if (m == 0)
|
||||
{
|
||||
/* No RX/TX bypass. Drive the interface line to low */
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CPS_PORT,
|
||||
dg_configFEM_SKY66112_11_CPS_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* At least one of TX/RX needs bypass */
|
||||
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CPS_PORT,
|
||||
dg_configFEM_SKY66112_11_CPS_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT3_DCF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hw_fem_set_tx_bypass(bool enable)
|
||||
{
|
||||
#if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN)
|
||||
GLOBAL_INT_DISABLE();
|
||||
fem_config.tx_bypass = enable;
|
||||
|
||||
if (fem_config.started)
|
||||
{
|
||||
set_bypass();
|
||||
}
|
||||
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void hw_fem_set_rx_bypass(bool enable)
|
||||
{
|
||||
#if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN)
|
||||
GLOBAL_INT_DISABLE();
|
||||
fem_config.rx_bypass = enable;
|
||||
|
||||
if (fem_config.started)
|
||||
{
|
||||
set_bypass();
|
||||
}
|
||||
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void hw_fem_set_antenna(bool one)
|
||||
{
|
||||
#if defined(dg_configFEM_SKY66112_11_ANTSEL_PORT) && defined(dg_configFEM_SKY66112_11_ANTSEL_PIN)
|
||||
GLOBAL_INT_DISABLE();
|
||||
fem_config.antsel = one;
|
||||
|
||||
if (fem_config.started)
|
||||
{
|
||||
/* Antenna selection */
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANTSEL_PORT,
|
||||
dg_configFEM_SKY66112_11_ANTSEL_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, fem_config.antsel);
|
||||
}
|
||||
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool hw_fem_get_txpower(void)
|
||||
{
|
||||
return fem_config.tx_power;
|
||||
}
|
||||
|
||||
bool hw_fem_get_antenna(void)
|
||||
{
|
||||
return fem_config.antsel;
|
||||
}
|
||||
|
||||
bool hw_fem_get_tx_bypass(void)
|
||||
{
|
||||
return fem_config.tx_bypass;
|
||||
}
|
||||
|
||||
bool hw_fem_get_rx_bypass(void)
|
||||
{
|
||||
return fem_config.rx_bypass;
|
||||
}
|
||||
|
||||
void hw_fem_start(void)
|
||||
{
|
||||
GLOBAL_INT_DISABLE();
|
||||
fem_config.started = true;
|
||||
|
||||
uint8_t set_delay;
|
||||
uint8_t reset_delay;
|
||||
uint16_t rf_port_en;
|
||||
|
||||
/******************************************************
|
||||
* Setup GPIOs
|
||||
*/
|
||||
|
||||
/* CSD GPIO Config */
|
||||
#if defined(dg_configFEM_SKY66112_11_CSD_PORT) && defined(dg_configFEM_SKY66112_11_CSD_PIN)
|
||||
# if dg_configFEM_SKY66112_11_CSD_USE_DCF == 0
|
||||
/* Manually set CSD (Enable FEM) */
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CSD_PORT, dg_configFEM_SKY66112_11_CSD_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, true);
|
||||
# else
|
||||
/* Use DCF for CSD */
|
||||
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CSD_PORT, dg_configFEM_SKY66112_11_CSD_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT2_DCF);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Timer 27 GPIO (DCF Port 0). Used for TX EN */
|
||||
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CTX_PORT, dg_configFEM_SKY66112_11_CTX_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT0_DCF);
|
||||
|
||||
/* Timer 28 (DCF Port 1). Used for RX EN */
|
||||
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CRX_PORT, dg_configFEM_SKY66112_11_CRX_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT1_DCF);
|
||||
|
||||
/* Antenna selection */
|
||||
#if defined(dg_configFEM_SKY66112_11_ANTSEL_PORT) && defined(dg_configFEM_SKY66112_11_ANTSEL_PIN)
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANTSEL_PORT, dg_configFEM_SKY66112_11_ANTSEL_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, fem_config.antsel);
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Setup DCFs
|
||||
*/
|
||||
|
||||
/* assign values to the timer registers for CTX/CRX (in usec) */
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_27_REG, SET_OFFSET, dg_configFEM_SKY66112_11_TXSET_DCF);
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_27_REG, RESET_OFFSET, dg_configFEM_SKY66112_11_TXRESET_DCF);
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_28_REG, SET_OFFSET, dg_configFEM_SKY66112_11_RXSET_DCF);
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_28_REG, RESET_OFFSET, dg_configFEM_SKY66112_11_RXRESET_DCF);
|
||||
|
||||
rf_port_en = 0x6; /* Start with Port 0: TX, Port 1: RX */
|
||||
|
||||
/* Compute set/reset delays to use for CSD, CPS, CHL DCFs: For setting delay,
|
||||
* smaller of TXSET, RXSET, and for resetting delay, larger of TXSET, RXSET
|
||||
*/
|
||||
#if dg_configFEM_SKY66112_11_RXSET_DCF > dg_configFEM_SKY66112_11_TXSET_DCF
|
||||
set_delay = dg_configFEM_SKY66112_11_TXSET_DCF;
|
||||
#else
|
||||
set_delay = dg_configFEM_SKY66112_11_RXSET_DCF;
|
||||
#endif
|
||||
|
||||
#if dg_configFEM_SKY66112_11_RXRESET_DCF > dg_configFEM_SKY66112_11_TXRESET_DCF
|
||||
reset_delay = dg_configFEM_SKY66112_11_RXRESET_DCF;
|
||||
#else
|
||||
reset_delay = dg_configFEM_SKY66112_11_TXRESET_DCF;
|
||||
#endif
|
||||
|
||||
/* CSD DCF (if enabled) configuration */
|
||||
#if defined(dg_configFEM_SKY66112_11_CSD_PORT) && defined(dg_configFEM_SKY66112_11_CSD_PIN)
|
||||
# if dg_configFEM_SKY66112_11_CSD_USE_DCF != 0
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_29_REG, SET_OFFSET, set_delay);
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_29_REG, RESET_OFFSET, reset_delay);
|
||||
|
||||
/* enable DCF Signals for Port 2 (CSD) for both rx/tx */
|
||||
rf_port_en |= 0x30;
|
||||
|
||||
# endif /* dg_configFEM_SKY66112_11_CSD_USE_DCF != 0 */
|
||||
#endif
|
||||
|
||||
/* Set bypass (CPS) DCF timers (but don't enable yet) */
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_30_REG, SET_OFFSET, set_delay);
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_30_REG, RESET_OFFSET, reset_delay);
|
||||
|
||||
/* Set TX Power (CHL) DCF timers (but don't enable yet) */
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_31_REG, SET_OFFSET, dg_configFEM_SKY66112_11_TXSET_DCF);
|
||||
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_31_REG, RESET_OFFSET, dg_configFEM_SKY66112_11_TXRESET_DCF);
|
||||
|
||||
/* Enable DCFs */
|
||||
RFCU_POWER->RF_PORT_EN_REG = rf_port_en;
|
||||
|
||||
hw_fem_set_txpower(fem_config.tx_power);
|
||||
set_bypass();
|
||||
|
||||
GLOBAL_INT_RESTORE();
|
||||
}
|
||||
|
||||
void hw_fem_stop(void)
|
||||
{
|
||||
GLOBAL_INT_DISABLE();
|
||||
fem_config.started = false;
|
||||
|
||||
/* Stop DCF Timers */
|
||||
RFCU_POWER->RF_PORT_EN_REG = 0x0;
|
||||
|
||||
/* Set all FEM interface outputs to GPIO mode, and value 0, in order to get the minimum
|
||||
* possible power consumption from FEM
|
||||
*/
|
||||
#if defined(dg_configFEM_SKY66112_11_CSD_PORT) && defined(dg_configFEM_SKY66112_11_CSD_PIN)
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CSD_PORT, dg_configFEM_SKY66112_11_CSD_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
#endif
|
||||
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CTX_PORT, dg_configFEM_SKY66112_11_CTX_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
|
||||
#if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN)
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CHL_PORT, dg_configFEM_SKY66112_11_CHL_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
#endif
|
||||
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CRX_PORT, dg_configFEM_SKY66112_11_CRX_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
|
||||
#if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN)
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CPS_PORT, dg_configFEM_SKY66112_11_CPS_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
#endif
|
||||
|
||||
#if defined(dg_configFEM_SKY66112_11_ANTSEL_PORT) && defined(dg_configFEM_SKY66112_11_ANTSEL_PIN)
|
||||
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANTSEL_PORT, dg_configFEM_SKY66112_11_ANTSEL_PIN,
|
||||
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
|
||||
#endif
|
||||
|
||||
GLOBAL_INT_RESTORE();
|
||||
}
|
||||
#endif /* dg_configFEM == FEM_SKY66112_11 */
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,342 @@
|
||||
/**
|
||||
* \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) ((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) ((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) ((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) ((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) ((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]; // = { };
|
||||
#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 */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* \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 "black_orca.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:\n\r");
|
||||
printf("- R0 = 0x%08lx\n\r", hardfault_args[0]);
|
||||
printf("- R1 = 0x%08lx\n\r", hardfault_args[1]);
|
||||
printf("- R2 = 0x%08lx\n\r", hardfault_args[2]);
|
||||
printf("- R3 = 0x%08lx\n\r", hardfault_args[3]);
|
||||
printf("- R12 = 0x%08lx\n\r", hardfault_args[4]);
|
||||
printf("- LR = 0x%08lx\n\r", hardfault_args[5]);
|
||||
printf("- PC = 0x%08lx\n\r", hardfault_args[6]);
|
||||
printf("- xPSR= 0x%08lx\n\r", 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
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* \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>
|
||||
|
||||
#define BITS16(base, reg, field, v) \
|
||||
((uint16) (((uint16) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
|
||||
(base ## _ ## reg ## _ ## field ## _Msk)))
|
||||
|
||||
#define BITS32(base, reg, field, v) \
|
||||
((uint32) (((uint32) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
|
||||
(base ## _ ## reg ## _ ## field ## _Msk)))
|
||||
|
||||
#define GETBITS16(base, reg, v, field) \
|
||||
((uint16) (((uint16) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
|
||||
(base ## _ ## reg ## _ ## field ## _Pos))
|
||||
|
||||
#define GETBITS32(base, reg, v, field) \
|
||||
((uint32) (((uint32) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
|
||||
(base ## _ ## reg ## _ ## field ## _Pos))
|
||||
|
||||
static const 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;
|
||||
}
|
||||
}
|
||||
|
||||
#if (dg_configFLASH_POWER_DOWN == 1)
|
||||
__attribute__((section("text_retained")))
|
||||
#endif
|
||||
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_read_instruction(uint8_t inst, uint8_t send_once, uint8_t dummy_count,
|
||||
HW_QSPI_BUS_MODE inst_phase,
|
||||
HW_QSPI_BUS_MODE addr_phase,
|
||||
HW_QSPI_BUS_MODE dummy_phase,
|
||||
HW_QSPI_BUS_MODE data_phase)
|
||||
{
|
||||
QSPIC->QSPIC_BURSTCMDA_REG =
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_INST, inst) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_INST_TX_MD, inst_phase) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_ADR_TX_MD, addr_phase) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_DMY_TX_MD, dummy_phase);
|
||||
|
||||
QSPIC->QSPIC_BURSTCMDB_REG =
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DAT_RX_MD, data_phase) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_INST_MD, send_once) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_FORCE, (dummy_count == 3 ? 1 : 0)) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_NUM, dummy_num[dummy_count]);
|
||||
}
|
||||
|
||||
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_extra_byte(uint8_t extra_byte, HW_QSPI_BUS_MODE bus_mode, uint8_t half_disable_out)
|
||||
{
|
||||
QSPIC->QSPIC_BURSTCMDA_REG =
|
||||
(QSPIC->QSPIC_BURSTCMDA_REG &
|
||||
~(REG_MSK(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_BYTE) |
|
||||
REG_MSK(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_TX_MD))) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_BYTE, extra_byte) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_TX_MD, bus_mode);
|
||||
|
||||
QSPIC->QSPIC_BURSTCMDB_REG =
|
||||
(QSPIC->QSPIC_BURSTCMDB_REG &
|
||||
~(REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_BYTE_EN) |
|
||||
REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_HF_DS))) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_BYTE_EN, 1) |
|
||||
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_HF_DS, half_disable_out ? 1 : 0);
|
||||
}
|
||||
|
||||
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_set_read_status_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
|
||||
HW_QSPI_BUS_MODE receive_phase,
|
||||
uint8_t busy_pos,
|
||||
uint8_t busy_val,
|
||||
uint8_t reset_delay,
|
||||
uint8_t sts_delay)
|
||||
{
|
||||
QSPIC->QSPIC_STATUSCMD_REG =
|
||||
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_BUSY_VAL, busy_val) |
|
||||
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_BUSY_POS , busy_pos) |
|
||||
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_RX_MD, receive_phase) |
|
||||
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_TX_MD, inst_phase) |
|
||||
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_INST, inst) |
|
||||
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_STSDLY_SEL, sts_delay) |
|
||||
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RESSTS_DLY, reset_delay);
|
||||
}
|
||||
|
||||
void hw_qspi_set_erase_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
|
||||
HW_QSPI_BUS_MODE addr_phase, uint8_t hclk_cycles,
|
||||
uint8_t cs_hi_cycles)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(ERASECMDA, ERS_INST, inst);
|
||||
QSPIC->QSPIC_ERASECMDB_REG =
|
||||
(QSPIC->QSPIC_ERASECMDB_REG &
|
||||
~(REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_TX_MD) |
|
||||
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_EAD_TX_MD) |
|
||||
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERSRES_HLD) |
|
||||
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_CS_HI))) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_TX_MD, inst_phase) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_EAD_TX_MD, addr_phase) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERSRES_HLD, hclk_cycles) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_CS_HI, cs_hi_cycles);
|
||||
}
|
||||
|
||||
void hw_qspi_set_write_enable_instruction(uint8_t write_enable, HW_QSPI_BUS_MODE inst_phase)
|
||||
{
|
||||
HW_QSPIC_REG_SETF(ERASECMDA, WEN_INST, write_enable);
|
||||
HW_QSPIC_REG_SETF(ERASECMDB, WEN_TX_MD, inst_phase);
|
||||
}
|
||||
|
||||
void hw_qspi_set_suspend_resume_instructions(uint8_t erase_suspend_inst,
|
||||
HW_QSPI_BUS_MODE suspend_inst_phase,
|
||||
uint8_t erase_resume_inst,
|
||||
HW_QSPI_BUS_MODE resume_inst_phase,
|
||||
uint8_t minimum_delay)
|
||||
{
|
||||
QSPIC->QSPIC_ERASECMDA_REG =
|
||||
(QSPIC->QSPIC_ERASECMDA_REG &
|
||||
~(REG_MSK(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_SUS_INST) |
|
||||
REG_MSK(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_RES_INST))) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_SUS_INST, erase_suspend_inst) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_RES_INST, erase_resume_inst);
|
||||
QSPIC->QSPIC_ERASECMDB_REG =
|
||||
(QSPIC->QSPIC_ERASECMDB_REG &
|
||||
~(REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_SUS_TX_MD) |
|
||||
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RES_TX_MD) |
|
||||
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RESSUS_DLY))) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_SUS_TX_MD, suspend_inst_phase) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RES_TX_MD, resume_inst_phase) |
|
||||
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RESSUS_DLY, minimum_delay);
|
||||
}
|
||||
|
||||
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_break_sequence(uint16_t sequence, HW_QSPI_BUS_MODE mode,
|
||||
HW_QSPI_BREAK_SEQ_SIZE size, uint8_t dis_out)
|
||||
{
|
||||
QSPIC->QSPIC_BURSTBRK_REG =
|
||||
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_SEC_HF_DS, dis_out) |
|
||||
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_SZ, size) |
|
||||
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_TX_MD, mode) |
|
||||
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_EN, 1) |
|
||||
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_WRD, sequence);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
__RETAINED_CODE void hw_qspi_set_div(HW_QSPI_DIV div)
|
||||
{
|
||||
REG_SETF(CRG_TOP, CLK_AMBA_REG, QSPI_DIV, div);
|
||||
}
|
||||
|
||||
#endif /* dg_configUSE_HW_QSPI */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* \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 <black_orca.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 */
|
||||
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 ;
|
||||
|
||||
/* 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 */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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)
|
||||
#define HW_TRNG_RAM (0x40040000)
|
||||
|
||||
static hw_trng_cb trng_cb;
|
||||
|
||||
static void hw_disable_trng(void)
|
||||
{
|
||||
REG_CLR_BIT(TRNG, TRNG_CTRL_REG, TRNG_ENABLE);
|
||||
}
|
||||
|
||||
static void hw_disable_trng_clk(void)
|
||||
{
|
||||
REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE);
|
||||
}
|
||||
|
||||
static void hw_trng_clear_pending(void)
|
||||
{
|
||||
// read TRNG_FIFOLVL_REG to clear level-sensitive source.
|
||||
TRNG->TRNG_FIFOLVL_REG;
|
||||
NVIC_ClearPendingIRQ(TRNG_IRQn);
|
||||
}
|
||||
|
||||
void hw_trng_enable(hw_trng_cb callback)
|
||||
{
|
||||
hw_trng_disable();
|
||||
|
||||
if (callback != NULL)
|
||||
{
|
||||
trng_cb = callback;
|
||||
hw_trng_clear_pending();
|
||||
NVIC_EnableIRQ(TRNG_IRQn);
|
||||
}
|
||||
|
||||
REG_SET_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE);
|
||||
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] = *((volatile uint32_t *)HW_TRNG_RAM);
|
||||
}
|
||||
}
|
||||
|
||||
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(void)
|
||||
{
|
||||
hw_disable_trng();
|
||||
NVIC_DisableIRQ(TRNG_IRQn);
|
||||
hw_trng_clear_pending();
|
||||
hw_disable_trng_clk();
|
||||
}
|
||||
|
||||
void TRNG_Handler(void)
|
||||
{
|
||||
SEGGER_SYSTEMVIEW_ISR_ENTER();
|
||||
|
||||
if (trng_cb != NULL)
|
||||
{
|
||||
trng_cb();
|
||||
}
|
||||
|
||||
hw_trng_clear_pending();
|
||||
|
||||
SEGGER_SYSTEMVIEW_ISR_EXIT();
|
||||
}
|
||||
|
||||
#endif /* dg_configUSE_HW_TRNG */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* \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))
|
||||
{
|
||||
__asm("BKPT #0\n");
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* \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_USB_WKUP
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <hw_wkup.h>
|
||||
|
||||
static hw_wkup_interrupt_cb intr_cb __RETAINED /* = NULL*/;
|
||||
|
||||
void hw_wkup_init(const wkup_config *cfg)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
REG_SET_BIT(CRG_TOP, CLK_TMR_REG, WAKEUPCT_ENABLE);
|
||||
|
||||
/* reset configuration */
|
||||
WAKEUP->WKUP_CTRL_REG = 0;
|
||||
WAKEUP->WKUP_COMPARE_REG = 0;
|
||||
|
||||
/* disable all pins */
|
||||
for (i = 0; i < 5; i++) {
|
||||
*((volatile uint16_t *)WAKEUP_BASE + 5 + i) = 0;
|
||||
*((volatile uint16_t *)WAKEUP_BASE + 10 + i) = 0;
|
||||
}
|
||||
|
||||
NVIC_DisableIRQ(WKUP_GPIO_IRQn);
|
||||
|
||||
hw_wkup_configure(cfg);
|
||||
}
|
||||
|
||||
void hw_wkup_configure(const wkup_config *cfg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!cfg) {
|
||||
return;
|
||||
}
|
||||
|
||||
hw_wkup_set_counter_threshold(cfg->threshold);
|
||||
hw_wkup_set_debounce_time(cfg->debounce);
|
||||
|
||||
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;
|
||||
|
||||
HW_WKUP_REG_SETF(CTRL, WKUP_ENABLE_IRQ, 1);
|
||||
|
||||
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;
|
||||
|
||||
HW_WKUP_REG_SETF(CTRL, WKUP_ENABLE_IRQ, 0);
|
||||
|
||||
NVIC_DisableIRQ(WKUP_GPIO_IRQn);
|
||||
}
|
||||
|
||||
void hw_wkup_handler(void)
|
||||
{
|
||||
if (intr_cb) {
|
||||
intr_cb();
|
||||
} else {
|
||||
hw_wkup_reset_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OS_BAREMETAL
|
||||
void WKUP_GPIO_Handler(void)
|
||||
{
|
||||
hw_wkup_handler();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* dg_configUSE_HW_USB_WKUP */
|
||||
/**
|
||||
* \}
|
||||
* \}
|
||||
* \}
|
||||
*/
|
||||
@@ -0,0 +1,470 @@
|
||||
/**
|
||||
\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 "sys_tcs.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)))
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
const uint32_t *tcs_ptr __RETAINED;
|
||||
|
||||
bool 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)
|
||||
{
|
||||
int i = array_ptr;
|
||||
int sort_start;
|
||||
int sort_end;
|
||||
|
||||
if (array_ptr == tcs_length)
|
||||
{
|
||||
return array_ptr; // Nothing else is left in the array
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
is_calibrated_chip = false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
is_calibrated_chip = true;
|
||||
}
|
||||
|
||||
if (address == (uint32_t)&CRG_TOP->CLK_16M_REG)
|
||||
{
|
||||
value |= 1; // Make sure that RC16 is enabled!
|
||||
}
|
||||
|
||||
apply_pair(address, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
store_in_array(address, value);
|
||||
}
|
||||
|
||||
return 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 (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[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[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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
\addtogroup INTERFACES
|
||||
\{
|
||||
\addtogroup RADIO
|
||||
\{
|
||||
\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_canSleep( )
|
||||
*/
|
||||
#define AD_FTDF_SLEEP_COMPENSATION 1500
|
||||
|
||||
#endif /* AD_FTDF_CONFIG_H */
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
\addtogroup INTERFACES
|
||||
\{
|
||||
\addtogroup RADIO
|
||||
\{
|
||||
\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_setExtAddress( FTDF_ExtAddress address);
|
||||
|
||||
/**
|
||||
* \brief Get Extended Address
|
||||
*
|
||||
* Gets interface extended address. This is thread safe.
|
||||
*
|
||||
* \returns The extended address of the interface
|
||||
*/
|
||||
FTDF_ExtAddress ad_ftdf_getExtAddress( void);
|
||||
|
||||
/**
|
||||
* \brief Transmits a frame
|
||||
*
|
||||
* Transmits a frame. Params:
|
||||
*
|
||||
* \param[in] frameLength - 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] csmaSuppress - 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 ad_ftdf_send_frame_simple( FTDF_DataLength frameLength,
|
||||
FTDF_Octet* frame,
|
||||
FTDF_ChannelNumber channel,
|
||||
FTDF_PTI pti,
|
||||
FTDF_Boolean csmaSuppress);
|
||||
|
||||
/**
|
||||
* \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 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
|
||||
*
|
||||
* 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_dbgBusGpioConfig(void);
|
||||
#endif /* FTDF_DBG_BUS_ENABLE */
|
||||
|
||||
#endif /* AD_FTDF_PHY_API_H */
|
||||
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
|
||||
+3102
File diff suppressed because it is too large
Load Diff
+150
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 0x01
|
||||
#define FTDF_PHYTXFINISH 0x00
|
||||
#define FTDF_PHYTRXWAIT 0x0f
|
||||
#define FTDF_PHYRXSTARTUP 0
|
||||
#define FTDF_PHYRXLATENCY 0
|
||||
#define FTDF_PHYENABLE 0
|
||||
|
||||
#ifndef FTDF_LITE
|
||||
#define FTDF_LITE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \remark See FTDF_GET_MSG_BUFFER in ftdf.h
|
||||
*/
|
||||
#define FTDF_GET_MSG_BUFFER ad_ftdf_getMsgBuffer
|
||||
|
||||
/**
|
||||
* \remark See FTDF_REL_MSG_BUFFER in ftdf.h
|
||||
*/
|
||||
#define FTDF_REL_MSG_BUFFER ad_ftdf_relMsgBuffer
|
||||
|
||||
/**
|
||||
* \remark See FTDF_REC_MSG in ftdf.h
|
||||
*/
|
||||
#define FTDF_RCV_MSG ad_ftdf_rcvMsg
|
||||
|
||||
/**
|
||||
* \remark See FTDF_GET_DATA_BUFFER in ftdf.h
|
||||
*/
|
||||
#define FTDF_GET_DATA_BUFFER ad_ftdf_getDataBuffer
|
||||
|
||||
/**
|
||||
* \remark See FTDF_REL_DATA_BUFFER in ftdf.h
|
||||
*/
|
||||
#define FTDF_REL_DATA_BUFFER ad_ftdf_relDataBuffer
|
||||
|
||||
/**
|
||||
* \remark See FTDF_GET_EXT_ADDRESS in ftdf.h
|
||||
*/
|
||||
#define FTDF_GET_EXT_ADDRESS ad_ftdf_getExtAddress
|
||||
|
||||
/**
|
||||
* \remark See FTDF_RCV_FRAME_TRANSPARENT in ftdf.h
|
||||
*/
|
||||
#define FTDF_RCV_FRAME_TRANSPARENT FTDF_rcvFrameTransparent
|
||||
|
||||
/**
|
||||
* \remark See FTDF_SEND_FRAME_TRANSPARENT_CONFIRM in ftdf.h
|
||||
*/
|
||||
#define FTDF_SEND_FRAME_TRANSPARENT_CONFIRM FTDF_sendFrameTransparentConfirm
|
||||
|
||||
/**
|
||||
* \remark See FTDF_WAKE_UP_READY in ftdf.h
|
||||
*/
|
||||
#define FTDF_WAKE_UP_READY ad_ftdf_wakeUpReady
|
||||
|
||||
/**
|
||||
* \remark See FTDF_SLEEP_CALLBACK in ftdf.h
|
||||
*/
|
||||
#define FTDF_SLEEP_CALLBACK ad_ftdf_sleepCb
|
||||
|
||||
/* Forward declaration */
|
||||
void sleep_when_possible( uint8_t explicit_request, uint32_t sleepTime );
|
||||
|
||||
#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 );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \remark Critical section
|
||||
*/
|
||||
|
||||
|
||||
#define FTDF_criticalVar( )
|
||||
#define FTDF_enterCritical( ) vPortEnterCritical()
|
||||
#define FTDF_exitCritical( ) vPortExitCritical()
|
||||
|
||||
#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_dbgBusGpioConfig
|
||||
#endif /* FTDF_DBG_BUS_ENABLE */
|
||||
|
||||
#endif /* FTDF_CONFIG_PHY_API_H_ */
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file 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.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#ifndef FTDF_PHY_API
|
||||
#include "osal.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include "sys_power_mgr.h"
|
||||
#endif
|
||||
|
||||
#include "ad_rf.h"
|
||||
|
||||
#include "sys_tcs.h"
|
||||
|
||||
#include "black_orca.h"
|
||||
#include "ad_ftdf.h"
|
||||
#include "ad_rf.h"
|
||||
#include "internal.h"
|
||||
#include "regmap.h"
|
||||
#if FTDF_DBG_BUS_ENABLE
|
||||
#include "hw_gpio.h"
|
||||
#endif /* FTDF_DBG_BUS_ENABLE */
|
||||
|
||||
#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_rw")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
PRIVILEGED_DATA FTDF_Boolean explicit_sleep; /* = FTDF_FALSE; */
|
||||
PRIVILEGED_DATA eSleepStatus sleep_status;
|
||||
|
||||
PRIVILEGED_DATA FTDF_ExtAddress uExtAddress;
|
||||
|
||||
|
||||
static void ad_ftdf_sleep(void)
|
||||
{
|
||||
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP); // go sleep
|
||||
FTDF_exitCritical();
|
||||
|
||||
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_DOWN) == 0x0) // don't go-go before I sleep
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void ad_ftdf_wake_up_internal(bool sync)
|
||||
{
|
||||
if (sleep_status != BLOCK_SLEEPING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
/* Wake up power domains */
|
||||
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP); // go wake up
|
||||
FTDF_exitCritical();
|
||||
|
||||
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP) == 0x0) // don't go-go before I sleep
|
||||
{
|
||||
}
|
||||
|
||||
/* Power on and configure RF */
|
||||
#if dg_configRF_ADAPTER
|
||||
ad_rf_request_on(false);
|
||||
#else
|
||||
vPortEnterCritical();
|
||||
hw_rf_request_on(false);
|
||||
vPortExitCritical();
|
||||
#endif
|
||||
|
||||
/* Apply trim values */
|
||||
sys_tcs_apply(tcs_ftdf);
|
||||
|
||||
#if dg_configRF_ADAPTER
|
||||
ad_rf_request_recommended_settings();
|
||||
#else
|
||||
vPortEnterCritical();
|
||||
hw_rf_request_recommended_settings();
|
||||
vPortExitCritical();
|
||||
#endif
|
||||
|
||||
if (sync)
|
||||
{
|
||||
FTDF_initLmac();
|
||||
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_wakeUpReady();
|
||||
#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 sleepTime)
|
||||
{
|
||||
FTDF_Boolean blockSleep = FTDF_FALSE;
|
||||
|
||||
if ((!AD_FTDF_SLEEP_WHEN_IDLE && !explicit_request) || sleep_status != BLOCK_ACTIVE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FTDF_USec us;
|
||||
|
||||
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
#ifdef FTDF_PHY_API
|
||||
|
||||
if (explicit_request && FTDF_GET_FIELD(ON_OFF_REGMAP_LMACREADY4SLEEP) == 0)
|
||||
{
|
||||
volatile uint32_t *lmacCtrlMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_MASK);
|
||||
volatile uint32_t *lmacReady4sleepEvent = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_LMACREADY4SLEEP_D);
|
||||
|
||||
/* clear a previous interrupt */
|
||||
*lmacReady4sleepEvent = MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP_D;
|
||||
|
||||
/* Enable (unmask) interrupt */
|
||||
*lmacCtrlMask |= MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP_M;
|
||||
us = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
us = FTDF_canSleep();
|
||||
}
|
||||
|
||||
#else
|
||||
us = FTDF_canSleep();
|
||||
#endif
|
||||
|
||||
/* Try to sleep as much as needed (if sleepTime is 0, then sleep as much as possible).
|
||||
* Otherwise, sleep as much as possible. */
|
||||
if (explicit_request == FTDF_TRUE)
|
||||
{
|
||||
if (sleepTime && us > sleepTime)
|
||||
{
|
||||
us = sleepTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (us > (WUP_LATENCY / 1000000) + AD_FTDF_SLEEP_COMPENSATION)
|
||||
{
|
||||
// Subtract sleep compensation from the sleep time, compensating for delays
|
||||
us -= AD_FTDF_SLEEP_COMPENSATION;
|
||||
|
||||
blockSleep = FTDF_prepareForSleep(us);
|
||||
|
||||
if (blockSleep)
|
||||
{
|
||||
// FTDF ready to sleep, disable clocks
|
||||
sleep_status = BLOCK_SLEEPING;
|
||||
explicit_sleep = explicit_request;
|
||||
ad_ftdf_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
FTDF_exitCritical();
|
||||
|
||||
if (blockSleep)
|
||||
{
|
||||
#if dg_configRF_ADAPTER
|
||||
ad_rf_request_off(false);
|
||||
#else
|
||||
vPortEnterCritical();
|
||||
hw_rf_request_off(false);
|
||||
vPortExitCritical();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialization function of FTDF adapter
|
||||
*/
|
||||
void ad_ftdf_init(void)
|
||||
{
|
||||
/* Wake up power domains */
|
||||
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP); // go wake up
|
||||
|
||||
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP) == 0x0) // don't go-go before I sleep
|
||||
{
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/* Power on and configure RF */
|
||||
ad_rf_request_on(false);
|
||||
|
||||
/* Apply trim values */
|
||||
sys_tcs_apply(tcs_ftdf);
|
||||
|
||||
ad_rf_request_recommended_settings();
|
||||
|
||||
FTDF_setSleepAttributes(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_sleepCb(FTDF_USec sleepTime)
|
||||
{
|
||||
sleep_when_possible(FTDF_TRUE, sleepTime);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if FTDF_DBG_BUS_ENABLE
|
||||
void ad_ftdf_dbgBusGpioConfig(void)
|
||||
{
|
||||
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);
|
||||
hw_gpio_set_pin_function(HW_GPIO_PORT_0, HW_GPIO_PIN_6, HW_GPIO_MODE_OUTPUT,
|
||||
HW_GPIO_FUNC_FTDF_DIAG);
|
||||
hw_gpio_set_pin_function(HW_GPIO_PORT_0, HW_GPIO_PIN_7, HW_GPIO_MODE_OUTPUT,
|
||||
HW_GPIO_FUNC_FTDF_DIAG);
|
||||
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 /* FTDF_DBG_BUS_ENABLE */
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
\addtogroup INTERFACES
|
||||
\{
|
||||
\addtogroup RADIO
|
||||
\{
|
||||
\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
|
||||
} eSleepStatus;
|
||||
|
||||
extern eSleepStatus sleep_status;
|
||||
extern FTDF_ExtAddress uExtAddress;
|
||||
extern FTDF_Boolean 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 sleepTime );
|
||||
|
||||
#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_dbgBusGpioConfig(void);
|
||||
#endif /* FTDF_DBG_BUS_ENABLE */
|
||||
|
||||
#endif /* AD_FTDF_H */
|
||||
/**
|
||||
\}
|
||||
\}
|
||||
\}
|
||||
*/
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file 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.
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "black_orca.h"
|
||||
#include "ad_ftdf.h"
|
||||
#include "ad_ftdf_phy_api.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef OS_FREERTOS
|
||||
static unsigned long uxCriticalNesting = 0x0 ;//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_confirmLmacInterrupt();
|
||||
FTDF_eventHandler();
|
||||
}
|
||||
/**
|
||||
* @brief ftdf_wakup_irq interrupt service routine
|
||||
*/
|
||||
void FTDF_WAKEUP_Handler(void)
|
||||
{
|
||||
ad_ftdf_wake_up_async();
|
||||
}
|
||||
|
||||
void ad_ftdf_setExtAddress(FTDF_ExtAddress address)
|
||||
{
|
||||
uExtAddress = address;
|
||||
}
|
||||
|
||||
FTDF_ExtAddress ad_ftdf_getExtAddress(void)
|
||||
{
|
||||
return uExtAddress;
|
||||
}
|
||||
|
||||
void ad_ftdf_wakeUpReady(void)
|
||||
{
|
||||
}
|
||||
|
||||
FTDF_Status ad_ftdf_send_frame_simple(FTDF_DataLength frameLength,
|
||||
FTDF_Octet *frame,
|
||||
FTDF_ChannelNumber channel,
|
||||
FTDF_PTI pti,
|
||||
FTDF_Boolean csmaSuppress)
|
||||
{
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
|
||||
if (FTDF_txInProgress == FTDF_TRUE)
|
||||
{
|
||||
FTDF_exitCritical();
|
||||
return FTDF_TRANSPARENT_OVERFLOW;
|
||||
}
|
||||
|
||||
FTDF_txInProgress = FTDF_TRUE;
|
||||
FTDF_exitCritical();
|
||||
|
||||
if (sleep_status == BLOCK_SLEEPING)
|
||||
{
|
||||
/* Wake-up the block */
|
||||
ad_ftdf_wake_up_async();
|
||||
sleep_status = BLOCK_ACTIVE;
|
||||
}
|
||||
|
||||
return FTDF_sendFrameSimple(frameLength, frame, channel, pti, csmaSuppress);
|
||||
}
|
||||
|
||||
|
||||
void ad_ftdf_sleep_when_possible(FTDF_Boolean 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();
|
||||
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(0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,662 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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"
|
||||
#include "regmap.h"
|
||||
|
||||
#ifndef FTDF_LITE
|
||||
void FTDF_processDataRequest(FTDF_DataRequest *dataRequest)
|
||||
{
|
||||
#ifndef FTDF_NO_TSCH
|
||||
|
||||
if (FTDF_pib.tschEnabled &&
|
||||
FTDF_tschSlotLink->request != dataRequest)
|
||||
{
|
||||
FTDF_Status status;
|
||||
|
||||
if (dataRequest->dstAddrMode == FTDF_SHORT_ADDRESS &&
|
||||
!dataRequest->indirectTX)
|
||||
{
|
||||
status = FTDF_scheduleTsch((FTDF_MsgBuffer *) dataRequest);
|
||||
|
||||
if (status == FTDF_SUCCESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = FTDF_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FTDF_sendDataConfirm(dataRequest,
|
||||
status,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
int queue;
|
||||
FTDF_AddressMode dstAddrMode = dataRequest->dstAddrMode;
|
||||
FTDF_PANId dstPANId = dataRequest->dstPANId;
|
||||
FTDF_Address dstAddr = dataRequest->dstAddr;
|
||||
|
||||
// Search for an existing indirect queue
|
||||
for (queue = 0; queue < FTDF_NR_OF_REQ_BUFFERS; queue++)
|
||||
{
|
||||
if (dstAddrMode == FTDF_SHORT_ADDRESS)
|
||||
{
|
||||
if (FTDF_txPendingList[ queue ].addrMode == dstAddrMode &&
|
||||
FTDF_txPendingList[ queue ].addr.shortAddress == dstAddr.shortAddress)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (dstAddrMode == FTDF_EXTENDED_ADDRESS)
|
||||
{
|
||||
if (FTDF_txPendingList[ queue ].addrMode == dstAddrMode &&
|
||||
FTDF_txPendingList[ queue ].addr.extAddress == dstAddr.extAddress)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dataRequest->indirectTX)
|
||||
{
|
||||
FTDF_Status status = FTDF_SUCCESS;
|
||||
|
||||
if (queue < FTDF_NR_OF_REQ_BUFFERS)
|
||||
{
|
||||
// Queue request in existing queue
|
||||
status = FTDF_queueReqHead((FTDF_MsgBuffer *) dataRequest, &FTDF_txPendingList[ queue ].queue);
|
||||
|
||||
if (status == FTDF_SUCCESS)
|
||||
{
|
||||
FTDF_addTxPendingTimer((FTDF_MsgBuffer *) dataRequest,
|
||||
queue,
|
||||
FTDF_pib.transactionPersistenceTime * FTDF_BASE_SUPERFRAME_DURATION,
|
||||
FTDF_sendTransactionExpired);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (dstAddrMode != FTDF_EXTENDED_ADDRESS &&
|
||||
dstAddrMode != FTDF_SHORT_ADDRESS)
|
||||
{
|
||||
status = FTDF_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (status != FTDF_SUCCESS)
|
||||
{
|
||||
// Queueing of indirect transfer was successful
|
||||
FTDF_sendDataConfirm(dataRequest,
|
||||
status,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Search for an empty indirect queue
|
||||
for (queue = 0; queue < FTDF_NR_OF_REQ_BUFFERS; queue++)
|
||||
{
|
||||
if (FTDF_txPendingList[ queue ].addrMode == FTDF_NO_ADDRESS)
|
||||
{
|
||||
FTDF_txPendingList[ queue ].addrMode = dstAddrMode;
|
||||
FTDF_txPendingList[ queue ].PANId = dstPANId;
|
||||
FTDF_txPendingList[ queue ].addr = dstAddr;
|
||||
|
||||
status = FTDF_queueReqHead((FTDF_MsgBuffer *) dataRequest,
|
||||
&FTDF_txPendingList[ queue ].queue);
|
||||
|
||||
if (status == FTDF_SUCCESS)
|
||||
{
|
||||
FTDF_addTxPendingTimer((FTDF_MsgBuffer *) dataRequest,
|
||||
queue,
|
||||
FTDF_pib.transactionPersistenceTime * FTDF_BASE_SUPERFRAME_DURATION,
|
||||
FTDF_sendTransactionExpired);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Did not find an existing or an empty queue
|
||||
FTDF_sendDataConfirm(dataRequest, FTDF_TRANSACTION_OVERFLOW,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (FTDF_reqCurrent == NULL)
|
||||
{
|
||||
FTDF_reqCurrent = (FTDF_MsgBuffer *) dataRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FTDF_queueReqHead((FTDF_MsgBuffer *) dataRequest, &FTDF_reqQueue) == FTDF_TRANSACTION_OVERFLOW)
|
||||
{
|
||||
FTDF_sendDataConfirm(dataRequest, FTDF_TRANSACTION_OVERFLOW,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FTDF_FrameHeader *frameHeader = &FTDF_fh;
|
||||
FTDF_SecurityHeader *securityHeader = &FTDF_sh;
|
||||
|
||||
frameHeader->frameType = dataRequest->sendMultiPurpose ? FTDF_MULTIPURPOSE_FRAME : FTDF_DATA_FRAME;
|
||||
|
||||
FTDF_Boolean framePending;
|
||||
|
||||
if (queue < FTDF_NR_OF_REQ_BUFFERS)
|
||||
{
|
||||
framePending = FTDF_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
framePending = FTDF_FALSE;
|
||||
}
|
||||
|
||||
frameHeader->options =
|
||||
(dataRequest->securityLevel > 0 ? FTDF_OPT_SECURITY_ENABLED : 0) |
|
||||
(dataRequest->ackTX ? FTDF_OPT_ACK_REQUESTED : 0) |
|
||||
(framePending ? FTDF_OPT_FRAME_PENDING : 0) |
|
||||
((dataRequest->frameControlOptions & FTDF_PAN_ID_PRESENT) ? FTDF_OPT_PAN_ID_PRESENT : 0) |
|
||||
((dataRequest->frameControlOptions & FTDF_IES_INCLUDED) ? FTDF_OPT_IES_PRESENT : 0) |
|
||||
((dataRequest->frameControlOptions & FTDF_SEQ_NR_SUPPRESSED) ? FTDF_OPT_SEQ_NR_SUPPRESSED : 0);
|
||||
|
||||
if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled)
|
||||
{
|
||||
frameHeader->options |= FTDF_OPT_ENHANCED;
|
||||
}
|
||||
|
||||
frameHeader->srcAddrMode = dataRequest->srcAddrMode;
|
||||
frameHeader->srcPANId = FTDF_pib.PANId;
|
||||
frameHeader->dstAddrMode = dataRequest->dstAddrMode;
|
||||
frameHeader->dstPANId = dataRequest->dstPANId;
|
||||
frameHeader->dstAddr = dataRequest->dstAddr;
|
||||
|
||||
securityHeader->securityLevel = dataRequest->securityLevel;
|
||||
securityHeader->keyIdMode = dataRequest->keyIdMode;
|
||||
securityHeader->keyIndex = dataRequest->keyIndex;
|
||||
securityHeader->keySource = dataRequest->keySource;
|
||||
securityHeader->frameCounter = FTDF_pib.frameCounter;
|
||||
securityHeader->frameCounterMode = FTDF_pib.frameCounterMode;
|
||||
|
||||
#ifndef FTDF_NO_TSCH
|
||||
|
||||
if (FTDF_pib.tschEnabled)
|
||||
{
|
||||
frameHeader->SN = FTDF_processTschSN((FTDF_MsgBuffer *)dataRequest,
|
||||
FTDF_pib.DSN,
|
||||
&dataRequest->requestSN);
|
||||
}
|
||||
else
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
{
|
||||
frameHeader->SN = FTDF_pib.DSN;
|
||||
}
|
||||
|
||||
FTDF_Octet *txPtr = (FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO) +
|
||||
(FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
|
||||
|
||||
// Skip PHY header (= MAC length)
|
||||
txPtr++;
|
||||
|
||||
FTDF_DataLength msduLength = dataRequest->msduLength;
|
||||
|
||||
txPtr = FTDF_addFrameHeader(txPtr,
|
||||
frameHeader,
|
||||
msduLength);
|
||||
|
||||
txPtr = FTDF_addSecurityHeader(txPtr,
|
||||
securityHeader);
|
||||
|
||||
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
|
||||
|
||||
if (dataRequest->frameControlOptions & FTDF_IES_INCLUDED)
|
||||
{
|
||||
txPtr = FTDF_addIes(txPtr,
|
||||
dataRequest->headerIEList,
|
||||
dataRequest->payloadIEList,
|
||||
dataRequest->msduLength);
|
||||
}
|
||||
|
||||
#endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */
|
||||
|
||||
FTDF_Status status = FTDF_sendFrame(FTDF_pib.currentChannel,
|
||||
frameHeader,
|
||||
securityHeader,
|
||||
txPtr,
|
||||
dataRequest->msduLength,
|
||||
dataRequest->msdu);
|
||||
|
||||
if (status != FTDF_SUCCESS)
|
||||
{
|
||||
FTDF_sendDataConfirm(dataRequest, status,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
FTDF_reqCurrent = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FTDF_nrOfRetries = 0;
|
||||
|
||||
if (frameHeader->SN == FTDF_pib.DSN)
|
||||
{
|
||||
FTDF_pib.DSN++;
|
||||
}
|
||||
}
|
||||
|
||||
void FTDF_sendDataConfirm(FTDF_DataRequest *dataRequest,
|
||||
FTDF_Status status,
|
||||
FTDF_Time timestamp,
|
||||
FTDF_SN DSN,
|
||||
FTDF_NumOfBackoffs numOfBackoffs,
|
||||
FTDF_IEList *ackPayload)
|
||||
{
|
||||
FTDF_REL_DATA_BUFFER(dataRequest->msdu);
|
||||
|
||||
FTDF_DataConfirm *dataConfirm = (FTDF_DataConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_DataConfirm));
|
||||
|
||||
dataConfirm->msgId = FTDF_DATA_CONFIRM;
|
||||
dataConfirm->msduHandle = dataRequest->msduHandle;
|
||||
dataConfirm->status = status;
|
||||
dataConfirm->timestamp = timestamp;
|
||||
dataConfirm->numOfBackoffs = numOfBackoffs;
|
||||
dataConfirm->DSN = DSN;
|
||||
dataConfirm->ackPayload = ackPayload;
|
||||
|
||||
if (FTDF_reqCurrent == (FTDF_MsgBuffer *)dataRequest)
|
||||
{
|
||||
FTDF_reqCurrent = NULL;
|
||||
}
|
||||
|
||||
FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) dataRequest);
|
||||
FTDF_RCV_MSG((FTDF_MsgBuffer *) dataConfirm);
|
||||
|
||||
FTDF_processNextRequest();
|
||||
}
|
||||
|
||||
void FTDF_sendDataIndication(FTDF_FrameHeader *frameHeader,
|
||||
FTDF_SecurityHeader *securityHeader,
|
||||
FTDF_IEList *payloadIEList,
|
||||
FTDF_DataLength msduLength,
|
||||
FTDF_Octet *msdu,
|
||||
FTDF_LinkQuality mpduLinkQuality,
|
||||
FTDF_Time timestamp)
|
||||
{
|
||||
FTDF_DataIndication *dataIndication = (FTDF_DataIndication *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_DataIndication));
|
||||
FTDF_Octet *msduBuf = FTDF_GET_DATA_BUFFER(msduLength);
|
||||
FTDF_Octet *bufPtr = msduBuf;
|
||||
|
||||
int n;
|
||||
|
||||
for (n = 0; n < msduLength; n++)
|
||||
{
|
||||
*msduBuf++ = *msdu++;
|
||||
}
|
||||
|
||||
dataIndication->msgId = FTDF_DATA_INDICATION;
|
||||
dataIndication->srcAddrMode = frameHeader->srcAddrMode;
|
||||
dataIndication->srcPANId = frameHeader->srcPANId;
|
||||
dataIndication->srcAddr = frameHeader->srcAddr;
|
||||
dataIndication->dstAddrMode = frameHeader->dstAddrMode;
|
||||
dataIndication->dstPANId = frameHeader->dstPANId;
|
||||
dataIndication->dstAddr = frameHeader->dstAddr;
|
||||
dataIndication->msduLength = msduLength;
|
||||
dataIndication->msdu = bufPtr;
|
||||
dataIndication->mpduLinkQuality = mpduLinkQuality;
|
||||
dataIndication->DSN = frameHeader->SN;
|
||||
dataIndication->timestamp = timestamp;
|
||||
dataIndication->securityLevel = securityHeader->securityLevel;
|
||||
dataIndication->keyIdMode = securityHeader->keyIdMode;
|
||||
dataIndication->keyIndex = securityHeader->keyIndex;
|
||||
dataIndication->payloadIEList = payloadIEList;
|
||||
|
||||
if (dataIndication->keyIdMode == 0x2)
|
||||
{
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
dataIndication->keySource[ n ] = securityHeader->keySource[ n ];
|
||||
}
|
||||
}
|
||||
else if (dataIndication->keyIdMode == 0x3)
|
||||
{
|
||||
for (n = 0; n < 8; n++)
|
||||
{
|
||||
dataIndication->keySource[ n ] = securityHeader->keySource[ n ];
|
||||
}
|
||||
}
|
||||
|
||||
FTDF_RCV_MSG((FTDF_MsgBuffer *) dataIndication);
|
||||
}
|
||||
|
||||
void FTDF_processPollRequest(FTDF_PollRequest *pollRequest)
|
||||
{
|
||||
if (FTDF_reqCurrent == NULL)
|
||||
{
|
||||
FTDF_reqCurrent = (FTDF_MsgBuffer *) pollRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FTDF_queueReqHead((FTDF_MsgBuffer *) pollRequest, &FTDF_reqQueue) == FTDF_TRANSACTION_OVERFLOW)
|
||||
{
|
||||
FTDF_sendPollConfirm(pollRequest, FTDF_TRANSACTION_OVERFLOW);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FTDF_FrameHeader *frameHeader = &FTDF_fh;
|
||||
FTDF_SecurityHeader *securityHeader = &FTDF_sh;
|
||||
|
||||
frameHeader->frameType = FTDF_MAC_COMMAND_FRAME;
|
||||
frameHeader->options =
|
||||
(pollRequest->securityLevel > 0 ? FTDF_OPT_SECURITY_ENABLED : 0) | FTDF_OPT_ACK_REQUESTED;
|
||||
|
||||
if (FTDF_pib.shortAddress < 0xfffe)
|
||||
{
|
||||
frameHeader->srcAddrMode = FTDF_SHORT_ADDRESS;
|
||||
frameHeader->srcAddr.shortAddress = FTDF_pib.shortAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameHeader->srcAddrMode = FTDF_EXTENDED_ADDRESS;
|
||||
frameHeader->srcAddr.extAddress = FTDF_pib.extAddress;
|
||||
}
|
||||
|
||||
frameHeader->srcPANId = FTDF_pib.PANId;
|
||||
frameHeader->dstAddrMode = pollRequest->coordAddrMode;
|
||||
frameHeader->dstPANId = pollRequest->coordPANId;
|
||||
frameHeader->dstAddr = pollRequest->coordAddr;
|
||||
|
||||
securityHeader->securityLevel = pollRequest->securityLevel;
|
||||
securityHeader->keyIdMode = pollRequest->keyIdMode;
|
||||
securityHeader->keyIndex = pollRequest->keyIndex;
|
||||
securityHeader->keySource = pollRequest->keySource;
|
||||
securityHeader->frameCounter = FTDF_pib.frameCounter;
|
||||
securityHeader->frameCounterMode = FTDF_pib.frameCounterMode;
|
||||
|
||||
FTDF_Octet *txPtr = (FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO) +
|
||||
(FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
|
||||
|
||||
// Skip PHY header (= MAC length)
|
||||
txPtr++;
|
||||
|
||||
frameHeader->SN = FTDF_pib.DSN;
|
||||
|
||||
txPtr = FTDF_addFrameHeader(txPtr,
|
||||
frameHeader,
|
||||
1);
|
||||
|
||||
txPtr = FTDF_addSecurityHeader(txPtr,
|
||||
securityHeader);
|
||||
|
||||
*txPtr++ = FTDF_COMMAND_DATA_REQUEST;
|
||||
|
||||
FTDF_Status status = FTDF_sendFrame(FTDF_pib.currentChannel,
|
||||
frameHeader,
|
||||
securityHeader,
|
||||
txPtr,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (status != FTDF_SUCCESS)
|
||||
{
|
||||
FTDF_sendPollConfirm(pollRequest, status);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FTDF_nrOfRetries = 0;
|
||||
FTDF_pib.DSN++;
|
||||
}
|
||||
|
||||
void FTDF_sendPollConfirm(FTDF_PollRequest *pollRequest, FTDF_Status status)
|
||||
{
|
||||
FTDF_PollConfirm *pollConfirm = (FTDF_PollConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_PollConfirm));
|
||||
|
||||
pollConfirm->msgId = FTDF_POLL_CONFIRM;
|
||||
pollConfirm->status = status;
|
||||
|
||||
if (FTDF_reqCurrent == (FTDF_MsgBuffer *)pollRequest)
|
||||
{
|
||||
FTDF_reqCurrent = NULL;
|
||||
}
|
||||
|
||||
FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) pollRequest);
|
||||
FTDF_RCV_MSG((FTDF_MsgBuffer *) pollConfirm);
|
||||
|
||||
FTDF_processNextRequest();
|
||||
}
|
||||
|
||||
void FTDF_processPurgeRequest(FTDF_PurgeRequest *purgeRequest)
|
||||
{
|
||||
FTDF_Handle msduHandle = purgeRequest->msduHandle;
|
||||
FTDF_Status status = FTDF_INVALID_HANDLE;
|
||||
|
||||
int n;
|
||||
|
||||
for (n = 0; n < FTDF_NR_OF_REQ_BUFFERS; n++)
|
||||
{
|
||||
FTDF_MsgBuffer *request = FTDF_dequeueByHandle(msduHandle, &FTDF_txPendingList[ n ].queue);
|
||||
|
||||
if (request)
|
||||
{
|
||||
FTDF_DataRequest *dataRequest = (FTDF_DataRequest *) request;
|
||||
|
||||
if (dataRequest->indirectTX == FTDF_TRUE)
|
||||
{
|
||||
FTDF_removeTxPendingTimer(request);
|
||||
|
||||
if (FTDF_isQueueEmpty(&FTDF_txPendingList[ n ].queue))
|
||||
{
|
||||
FTDF_txPendingList[ n ].addrMode = FTDF_NO_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
FTDF_REL_DATA_BUFFER(dataRequest->msdu);
|
||||
FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) dataRequest);
|
||||
|
||||
status = FTDF_SUCCESS;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FTDF_PurgeConfirm *purgeConfirm = (FTDF_PurgeConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_PurgeConfirm));
|
||||
|
||||
purgeConfirm->msgId = FTDF_PURGE_CONFIRM;
|
||||
purgeConfirm->msduHandle = msduHandle;
|
||||
purgeConfirm->status = status;
|
||||
|
||||
FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) purgeRequest);
|
||||
FTDF_RCV_MSG((FTDF_MsgBuffer *) purgeConfirm);
|
||||
}
|
||||
#endif /* !FTDF_LITE */
|
||||
|
||||
#ifdef FTDF_PHY_API
|
||||
FTDF_Status FTDF_sendFrameSimple(FTDF_DataLength frameLength,
|
||||
FTDF_Octet *frame,
|
||||
FTDF_ChannelNumber channel,
|
||||
FTDF_PTI pti,
|
||||
FTDF_Boolean csmaSuppress)
|
||||
{
|
||||
|
||||
FTDF_Octet *fp = frame;
|
||||
|
||||
if (frameLength > 127 ||
|
||||
FTDF_transparentMode != FTDF_TRUE)
|
||||
{
|
||||
return FTDF_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FTDF_Octet *txPtr = (FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO) +
|
||||
(FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
|
||||
|
||||
/* This data copy could/should be optimized using DMA */
|
||||
*txPtr++ = frameLength;
|
||||
|
||||
int n;
|
||||
|
||||
for (n = 0; n < frameLength; n++)
|
||||
{
|
||||
*txPtr++ = *fp++;
|
||||
}
|
||||
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
FTDF_nrOfRetries = 0;
|
||||
FTDF_exitCritical();
|
||||
FTDF_sendTransparentFrame(frameLength,
|
||||
frame,
|
||||
channel,
|
||||
pti,
|
||||
csmaSuppress);
|
||||
|
||||
return FTDF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else /* !FTDF_PHY_API */
|
||||
void FTDF_processTransparentRequest(FTDF_TransparentRequest *transparentRequest)
|
||||
{
|
||||
FTDF_DataLength frameLength = transparentRequest->frameLength;
|
||||
|
||||
if (frameLength > 127 ||
|
||||
FTDF_transparentMode != FTDF_TRUE)
|
||||
{
|
||||
FTDF_SEND_FRAME_TRANSPARENT_CONFIRM(transparentRequest->handle,
|
||||
FTDF_INVALID_PARAMETER);
|
||||
|
||||
FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) transparentRequest);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (FTDF_reqCurrent == NULL)
|
||||
{
|
||||
FTDF_reqCurrent = (FTDF_MsgBuffer *) transparentRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef FTDF_LITE
|
||||
|
||||
if (FTDF_queueReqHead((FTDF_MsgBuffer *) transparentRequest, &FTDF_reqQueue) == FTDF_TRANSACTION_OVERFLOW)
|
||||
{
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_SEND_FRAME_TRANSPARENT_CONFIRM(transparentRequest->handle,
|
||||
FTDF_TRANSPARENT_OVERFLOW);
|
||||
|
||||
FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) transparentRequest);
|
||||
#ifndef FTDF_LITE
|
||||
}
|
||||
|
||||
#endif /* !FTDF_LITE */
|
||||
return;
|
||||
}
|
||||
|
||||
FTDF_Octet *txPtr = (FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO) +
|
||||
(FTDF_BUFFER_LENGTH * FTDF_TX_DATA_BUFFER);
|
||||
|
||||
*txPtr++ = frameLength;
|
||||
|
||||
FTDF_Octet *frame = transparentRequest->frame;
|
||||
|
||||
int n;
|
||||
|
||||
for (n = 0; n < frameLength; n++)
|
||||
{
|
||||
*txPtr++ = *frame++;
|
||||
}
|
||||
|
||||
FTDF_sendTransparentFrame(frameLength,
|
||||
transparentRequest->frame,
|
||||
transparentRequest->channel,
|
||||
transparentRequest->pti,
|
||||
transparentRequest->cmsaSuppress);
|
||||
FTDF_nrOfRetries = 0;
|
||||
}
|
||||
|
||||
|
||||
void FTDF_sendFrameTransparent(FTDF_DataLength frameLength,
|
||||
FTDF_Octet *frame,
|
||||
FTDF_ChannelNumber channel,
|
||||
FTDF_PTI pti,
|
||||
FTDF_Boolean cmsaSuppress,
|
||||
void *handle)
|
||||
{
|
||||
FTDF_TransparentRequest *transparentRequest =
|
||||
(FTDF_TransparentRequest *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_TransparentRequest));
|
||||
|
||||
transparentRequest->msgId = FTDF_TRANSPARENT_REQUEST;
|
||||
transparentRequest->frameLength = frameLength;
|
||||
transparentRequest->frame = frame;
|
||||
transparentRequest->channel = channel;
|
||||
transparentRequest->pti = pti;
|
||||
transparentRequest->cmsaSuppress = cmsaSuppress;
|
||||
transparentRequest->handle = handle;
|
||||
|
||||
FTDF_processTransparentRequest(transparentRequest);
|
||||
}
|
||||
|
||||
#endif /* FTDF_PHY_API */
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#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_getUmacRelName( void );
|
||||
const char* FTDF_getUmacBuildTime( void );
|
||||
|
||||
#endif /* FTDFINFO_H_ */
|
||||
+673
@@ -0,0 +1,673 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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
|
||||
#define FTDF_NR_OF_REQ_BUFFERS 16
|
||||
#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
|
||||
|
||||
// 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_GET_FIELD_ADDR( fieldName ) ( (volatile uint32_t*) ( IND_F_FTDF_ ## fieldName ) )
|
||||
#define FTDF_GET_FIELD_ADDR_INDEXED( fieldName, index ) ( (volatile uint32_t*) ( IND_F_FTDF_ ## fieldName + \
|
||||
(intptr_t) index * \
|
||||
FTDF_ ## fieldName ## _INTVL ) )
|
||||
#define FTDF_GET_REG_ADDR( regName ) ( (volatile uint32_t*) ( IND_R_FTDF_ ## regName ) )
|
||||
#define FTDF_GET_REG_ADDR_INDEXED( regName, index ) ( (volatile uint32_t*) ( IND_R_FTDF_ ## regName + \
|
||||
(intptr_t) index * \
|
||||
FTDF_ ## regName ## _INTVL ) )
|
||||
#define FTDF_GET_FIELD( fieldName ) ( ( ( *(volatile uint32_t*) ( IND_F_FTDF_ ## fieldName ) ) & \
|
||||
MSK_F_FTDF_ ## fieldName ) >> OFF_F_FTDF_ ## fieldName )
|
||||
#define FTDF_GET_FIELD_INDEXED( fieldName, \
|
||||
index ) ( ( ( *FTDF_GET_FIELD_ADDR_INDEXED( fieldName, \
|
||||
index ) ) \
|
||||
& MSK_F_FTDF_ ## fieldName ) >> OFF_F_FTDF_ ## fieldName )
|
||||
|
||||
#define FTDF_SET_FIELD( fieldName, value ) do { \
|
||||
uint32_t tmp = *FTDF_GET_FIELD_ADDR( fieldName ) & ~MSK_F_FTDF_ ## fieldName; \
|
||||
*FTDF_GET_FIELD_ADDR( fieldName ) = tmp | \
|
||||
( ( ( value ) << OFF_F_FTDF_ ## fieldName ) & MSK_F_FTDF_ ## fieldName ); \
|
||||
} \
|
||||
while ( 0 )
|
||||
|
||||
#define FTDF_processRequest FTDF_sndMsg
|
||||
|
||||
struct FTDF_Pib
|
||||
{
|
||||
FTDF_ExtAddress extAddress;
|
||||
FTDF_Period ackWaitDuration;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Boolean associatedPANCoord;
|
||||
FTDF_Boolean associationPermit;
|
||||
FTDF_Boolean autoRequest;
|
||||
FTDF_Boolean battLifeExt;
|
||||
FTDF_NumOfBackoffs battLifeExtPeriods;
|
||||
FTDF_Octet beaconPayload[ FTDF_MAX_BEACON_PAYLOAD_LENGTH ];
|
||||
FTDF_Size beaconPayloadLength;
|
||||
FTDF_Order beaconOrder;
|
||||
FTDF_Time beaconTxTime;
|
||||
FTDF_SN BSN;
|
||||
FTDF_ExtAddress coordExtAddress;
|
||||
FTDF_ShortAddress coordShortAddress;
|
||||
FTDF_SN DSN;
|
||||
FTDF_Boolean GTSPermit;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_BEExponent maxBE;
|
||||
FTDF_Size maxCSMABackoffs;
|
||||
FTDF_Period maxFrameTotalWaitTime;
|
||||
FTDF_Size maxFrameRetries;
|
||||
FTDF_BEExponent minBE;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Period LIFSPeriod;
|
||||
FTDF_Period SIFSPeriod;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_PANId PANId;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Boolean promiscuousMode; /* Not supported. Use transparent mode instead */
|
||||
FTDF_Size responseWaitTime;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_Boolean rxOnWhenIdle;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Boolean securityEnabled;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_ShortAddress shortAddress;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Size superframeOrder;
|
||||
FTDF_Period syncSymbolOffset;
|
||||
FTDF_Boolean timestampSupported;
|
||||
FTDF_Period transactionPersistenceTime;
|
||||
FTDF_Period enhAckWaitDuration;
|
||||
FTDF_Boolean implicitBroadcast;
|
||||
FTDF_SimpleAddress simpleAddress;
|
||||
FTDF_Period disconnectTime;
|
||||
FTDF_Priority joinPriority;
|
||||
FTDF_ASN ASN;
|
||||
FTDF_Boolean noHLBuffers;
|
||||
FTDF_SlotframeTable slotframeTable;
|
||||
FTDF_LinkTable linkTable;
|
||||
FTDF_TimeslotTemplate timeslotTemplate;
|
||||
FTDF_HoppingSequenceId HoppingSequenceId;
|
||||
FTDF_ChannelPage channelPage;
|
||||
FTDF_ChannelNumber numberOfChannels;
|
||||
FTDF_Bitmap32 phyConfiguration;
|
||||
FTDF_Bitmap8 extendedBitmap;
|
||||
FTDF_Length hoppingSequenceLength;
|
||||
FTDF_ChannelNumber hoppingSequenceList[ FTDF_MAX_HOPPING_SEQUENCE_LENGTH ];
|
||||
FTDF_Length currentHop;
|
||||
FTDF_Period dwellTime;
|
||||
FTDF_Period CSLPeriod;
|
||||
FTDF_Period CSLMaxPeriod;
|
||||
FTDF_Bitmap32 CSLChannelMask;
|
||||
FTDF_Period CSLFramePendingWaitT;
|
||||
FTDF_Boolean lowEnergySuperframeSupported;
|
||||
FTDF_Boolean lowEnergySuperframeSyncInterval;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_PerformanceMetrics performanceMetrics;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Boolean useEnhancedBecaon;
|
||||
FTDF_IEList EBIEList;
|
||||
FTDF_Boolean EBFilteringEnabled;
|
||||
FTDF_SN EBSN;
|
||||
FTDF_AutoSA EBAutoSA;
|
||||
FTDF_IEList EAckIEList;
|
||||
FTDF_Boolean tschEnabled;
|
||||
FTDF_Boolean leEnabled;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_ChannelNumber currentChannel;
|
||||
FTDF_TXPowerTolerance TXPowerTolerance;
|
||||
FTDF_DBm TXPower;
|
||||
FTDF_CCAMode CCAMode;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_ChannelPage currentPage;
|
||||
FTDF_Period maxFrameDuration;
|
||||
FTDF_Period SHRDuration;
|
||||
FTDF_KeyTable keyTable;
|
||||
FTDF_DeviceTable deviceTable;
|
||||
FTDF_SecurityLevelTable securityLevelTable;
|
||||
FTDF_FrameCounter frameCounter;
|
||||
FTDF_SecurityLevel mtDataSecurityLevel;
|
||||
FTDF_KeyIdMode mtDataKeyIdMode;
|
||||
FTDF_Octet mtDataKeySource[ 8 ];
|
||||
FTDF_KeyIndex mtDataKeyIndex;
|
||||
FTDF_Octet defaultKeySource[ 8 ];
|
||||
FTDF_ExtAddress PANCoordExtAddress;
|
||||
FTDF_ShortAddress PANCoordShortAddress;
|
||||
FTDF_FrameCounterMode frameCounterMode;
|
||||
FTDF_Period CSLSyncTxMargin;
|
||||
FTDF_Period CSLMaxAgeRemoteInfo;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_TrafficCounters trafficCounters;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Boolean LECapable;
|
||||
FTDF_Boolean LLCapable;
|
||||
FTDF_Boolean DSMECapable;
|
||||
FTDF_Boolean RFIDCapable;
|
||||
FTDF_Boolean AMCACapable;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_Boolean metricsCapable;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Boolean rangingSupported;
|
||||
#endif /* !FTDF_LITE */
|
||||
FTDF_Boolean keepPhyEnabled;
|
||||
FTDF_Boolean metricsEnabled;
|
||||
#ifndef FTDF_LITE
|
||||
FTDF_Boolean beaconAutoRespond;
|
||||
FTDF_Boolean tschCapable;
|
||||
FTDF_Period tsSyncCorrectThreshold;
|
||||
#endif /* !FTDF_LITE */
|
||||
};
|
||||
|
||||
typedef uint8_t FTDF_FrameVersion;
|
||||
#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_FrameType frameType;
|
||||
FTDF_FrameVersion frameVersion;
|
||||
FTDF_Bitmap8 options;
|
||||
FTDF_SN SN;
|
||||
FTDF_AddressMode srcAddrMode;
|
||||
FTDF_PANId srcPANId;
|
||||
FTDF_Address srcAddr;
|
||||
FTDF_AddressMode dstAddrMode;
|
||||
FTDF_PANId dstPANId;
|
||||
FTDF_Address dstAddr;
|
||||
FTDF_CommandFrameId commandFrameId;
|
||||
} FTDF_FrameHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FTDF_SecurityLevel securityLevel;
|
||||
FTDF_KeyIdMode keyIdMode;
|
||||
FTDF_KeyIndex keyIndex;
|
||||
FTDF_FrameCounterMode frameCounterMode;
|
||||
FTDF_Octet* keySource;
|
||||
FTDF_FrameCounter frameCounter;
|
||||
} FTDF_SecurityHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FTDF_Boolean fastA;
|
||||
FTDF_Boolean dataR;
|
||||
} FTDF_AssocAdmin;
|
||||
|
||||
typedef uint8_t FTDF_SNSel;
|
||||
#define FTDF_SN_SEL_DSN 0
|
||||
#define FTDF_SN_SEL_BSN 1
|
||||
#define FTDF_SN_SEL_EBSN 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FTDF_AddressMode addrMode;
|
||||
FTDF_Address addr;
|
||||
FTDF_Time timestamp;
|
||||
FTDF_Boolean dsnValid;
|
||||
FTDF_SN dsn;
|
||||
FTDF_Boolean bsnValid;
|
||||
FTDF_SN bsn;
|
||||
FTDF_Boolean ebsnValid;
|
||||
FTDF_SN ebsn;
|
||||
} FTDF_RxAddressAdmin;
|
||||
|
||||
struct FTDF_Buffer_;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct FTDF_Buffer_* next;
|
||||
struct FTDF_Buffer_* prev;
|
||||
} FTDF_BufferHeader;
|
||||
|
||||
typedef struct FTDF_Buffer_
|
||||
{
|
||||
FTDF_BufferHeader header;
|
||||
FTDF_MsgBuffer* request;
|
||||
} FTDF_Buffer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FTDF_BufferHeader head;
|
||||
FTDF_BufferHeader tail;
|
||||
} FTDF_Queue;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FTDF_Address addr;
|
||||
FTDF_AddressMode addrMode;
|
||||
FTDF_PANId PANId;
|
||||
FTDF_Queue queue;
|
||||
} FTDF_Pending;
|
||||
|
||||
typedef struct _FTDF_PendingTL_
|
||||
{
|
||||
struct _FTDF_PendingTL_* next;
|
||||
FTDF_Boolean free;
|
||||
FTDF_MsgBuffer* request;
|
||||
FTDF_Time delta;
|
||||
uint8_t pendListNr;
|
||||
void ( * func )( struct _FTDF_PendingTL_* );
|
||||
} FTDF_PendingTL;
|
||||
|
||||
typedef uint8_t FTDF_RemoteId;
|
||||
#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_MsgId msgId;
|
||||
FTDF_RemoteId remoteId;
|
||||
FTDF_ShortAddress dstAddr;
|
||||
} FTDF_RemoteRequest;
|
||||
|
||||
#ifndef FTDF_NO_CSL
|
||||
typedef struct
|
||||
{
|
||||
FTDF_ShortAddress addr;
|
||||
FTDF_Time time;
|
||||
FTDF_Period period;
|
||||
} FTDF_PeerCslTiming;
|
||||
#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_ShortAddress nodeAddr;
|
||||
FTDF_Size nrOfRetries;
|
||||
FTDF_Size nrOfCcaRetries;
|
||||
FTDF_BEExponent BE;
|
||||
} FTDF_TschRetry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FTDF_ShortAddress dstAddr;
|
||||
FTDF_KeepAlivePeriod period;
|
||||
FTDF_RemoteRequest msg;
|
||||
} FTDF_NeighborEntry;
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FTDF_Count fcsErrorCnt;
|
||||
FTDF_Count txStdAckCnt;
|
||||
FTDF_Count rxStdAckCnt;
|
||||
} FTDF_LmacCounters;
|
||||
|
||||
extern struct FTDF_Pib FTDF_pib;
|
||||
extern FTDF_State* FTDF_state;
|
||||
extern FTDF_Boolean FTDF_transparentMode;
|
||||
extern FTDF_Bitmap32 FTDF_transparentModeOptions;
|
||||
extern FTDF_Queue FTDF_reqQueue;
|
||||
extern FTDF_Queue FTDF_freeQueue;
|
||||
extern FTDF_Pending FTDF_txPendingList[ FTDF_NR_OF_REQ_BUFFERS ];
|
||||
extern FTDF_PendingTL FTDF_txPendingTimerList[ FTDF_NR_OF_REQ_BUFFERS ];
|
||||
extern FTDF_PendingTL* FTDF_txPendingTimerHead;
|
||||
extern FTDF_Time FTDF_txPendingTimerLT;
|
||||
extern FTDF_Time FTDF_txPendingTimerTime;
|
||||
extern FTDF_MsgBuffer* FTDF_reqCurrent;
|
||||
extern FTDF_Size FTDF_nrOfRetries;
|
||||
extern FTDF_Boolean FTDF_isPANCoordinator;
|
||||
extern FTDF_SlotframeEntry FTDF_slotframeTable[ FTDF_MAX_SLOTFRAMES ];
|
||||
extern FTDF_LinkEntry FTDF_linkTable[ FTDF_MAX_LINKS ];
|
||||
#ifndef FTDF_NO_TSCH
|
||||
extern FTDF_LinkEntry* FTDF_startLinks[ FTDF_MAX_SLOTFRAMES ];
|
||||
extern FTDF_LinkEntry* FTDF_endLinks[ FTDF_MAX_SLOTFRAMES ];
|
||||
extern FTDF_NeighborEntry FTDF_neighborTable[ FTDF_NR_OF_NEIGHBORS ];
|
||||
extern FTDF_Boolean FTDF_wakeUpEnableTsch;
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
#ifndef FTDF_NO_CSL
|
||||
extern FTDF_Boolean FTDF_wakeUpEnableLe;
|
||||
#endif /* FTDF_NO_CSL */
|
||||
extern FTDF_LmacCounters FTDF_lmacCounters;
|
||||
|
||||
extern FTDF_FrameHeader FTDF_fh;
|
||||
extern FTDF_SecurityHeader FTDF_sh;
|
||||
extern FTDF_AssocAdmin FTDF_aa;
|
||||
extern FTDF_Boolean FTDF_txInProgress;
|
||||
#ifndef FTDF_NO_CSL
|
||||
extern FTDF_Time FTDF_rzTime;
|
||||
extern FTDF_ShortAddress FTDF_sendFramePending;
|
||||
#endif /* FTDF_NO_CSL */
|
||||
extern FTDF_Time FTDF_startCslSampleTime;
|
||||
|
||||
#ifndef FTDF_NO_TSCH
|
||||
extern FTDF_LinkEntry* FTDF_tschSlotLink;
|
||||
extern FTDF_Time64 FTDF_tschSlotTime;
|
||||
extern FTDF_ASN FTDF_tschSlotASN;
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
void FTDF_processDataRequest( FTDF_DataRequest* req );
|
||||
void FTDF_processPurgeRequest( FTDF_PurgeRequest* req );
|
||||
void FTDF_processAssociateRequest( FTDF_AssociateRequest* req );
|
||||
void FTDF_processAssociateResponse( FTDF_AssociateResponse* req );
|
||||
void FTDF_processDisassociateRequest( FTDF_DisassociateRequest* req );
|
||||
void FTDF_processGetRequest( FTDF_GetRequest* req );
|
||||
void FTDF_processSetRequest( FTDF_SetRequest* req );
|
||||
void FTDF_processOrphanResponse( FTDF_OrphanResponse* req );
|
||||
void FTDF_processResetRequest( FTDF_ResetRequest* req );
|
||||
void FTDF_processRxEnableRequest( FTDF_RxEnableRequest* req );
|
||||
void FTDF_processScanRequest( FTDF_ScanRequest* req );
|
||||
void FTDF_processStartRequest( FTDF_StartRequest* req );
|
||||
void FTDF_processPollRequest( FTDF_PollRequest* req );
|
||||
#ifndef FTDF_NO_TSCH
|
||||
void FTDF_processSetSlotframeRequest( FTDF_SetSlotframeRequest* req );
|
||||
void FTDF_processSetLinkRequest( FTDF_SetLinkRequest* req );
|
||||
void FTDF_processTschModeRequest( FTDF_TschModeRequest* req );
|
||||
void FTDF_processKeepAliveRequest( FTDF_KeepAliveRequest* req );
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
void FTDF_processBeaconRequest( FTDF_BeaconRequest* req );
|
||||
void FTDF_processTransparentRequest( FTDF_TransparentRequest* req );
|
||||
void FTDF_processRemoteRequest( FTDF_RemoteRequest* req );
|
||||
|
||||
void FTDF_processNextRequest( void );
|
||||
void FTDF_processRxEvent( void );
|
||||
void FTDF_processTxEvent( void );
|
||||
void FTDF_processSymbolTimerEvent( void );
|
||||
|
||||
void FTDF_sendDataConfirm( FTDF_DataRequest* dataRequest,
|
||||
FTDF_Status status,
|
||||
FTDF_Time timestamp,
|
||||
FTDF_SN DSN,
|
||||
FTDF_NumOfBackoffs numOfBackoffs,
|
||||
FTDF_IEList* ackPayload );
|
||||
|
||||
void FTDF_sendDataIndication( FTDF_FrameHeader* frameHeader,
|
||||
FTDF_SecurityHeader* securityHeader,
|
||||
FTDF_IEList* payloadIEList,
|
||||
FTDF_DataLength msduLength,
|
||||
FTDF_Octet* msdu,
|
||||
FTDF_LinkQuality mpduLinkQuality,
|
||||
FTDF_Time timestamp );
|
||||
|
||||
void FTDF_sendPollConfirm( FTDF_PollRequest* pollRequest, FTDF_Status status );
|
||||
|
||||
void FTDF_sendScanConfirm( FTDF_ScanRequest* scanRequest, FTDF_Status status );
|
||||
|
||||
void FTDF_sendBeaconNotifyIndication( FTDF_PANDescriptor* PANDescriptor );
|
||||
|
||||
void FTDF_sendBeaconConfirm( FTDF_BeaconRequest* beaconRequest, FTDF_Status status );
|
||||
|
||||
void FTDF_sendAssociateConfirm( FTDF_AssociateRequest* associateRequest,
|
||||
FTDF_Status status,
|
||||
FTDF_ShortAddress assocShortAddr );
|
||||
|
||||
void FTDF_sendAssociateDataRequest( void );
|
||||
|
||||
void FTDF_sendDisassociateConfirm( FTDF_DisassociateRequest* disReq, FTDF_Status status );
|
||||
|
||||
void FTDF_sendSyncLossIndication( FTDF_LossReason lossReason, FTDF_SecurityHeader* securityHeader );
|
||||
|
||||
void FTDF_sendPANIdConflictNotification( FTDF_FrameHeader* frameHeader, FTDF_SecurityHeader* securityHeader );
|
||||
|
||||
void FTDF_sendCommStatusIndication( FTDF_MsgBuffer* request,
|
||||
FTDF_Status status,
|
||||
FTDF_PANId PANId,
|
||||
FTDF_AddressMode srcAddrMode,
|
||||
FTDF_Address srcAddr,
|
||||
FTDF_AddressMode dstAddrMode,
|
||||
FTDF_Address dstAddr,
|
||||
FTDF_SecurityLevel securityLevel,
|
||||
FTDF_KeyIdMode keyIdMode,
|
||||
FTDF_Octet* keySource,
|
||||
FTDF_KeyIndex keyIndex );
|
||||
|
||||
void FTDF_startTimer( FTDF_Period period,
|
||||
void ( * timerFunc )( void* params ),
|
||||
void* params );
|
||||
|
||||
FTDF_Octet* FTDF_getTxBufPtr( FTDF_Buffer* txBuffer );
|
||||
|
||||
void FTDF_setTxMetaData( FTDF_Buffer* txBuffer,
|
||||
FTDF_DataLength frameLength,
|
||||
FTDF_ChannelNumber channel,
|
||||
FTDF_FrameType frameType,
|
||||
FTDF_Boolean ackTX,
|
||||
FTDF_SN SN );
|
||||
|
||||
FTDF_Status FTDF_sendFrame( FTDF_ChannelNumber channel,
|
||||
FTDF_FrameHeader* frameHeader,
|
||||
FTDF_SecurityHeader* securityHeader,
|
||||
FTDF_Octet* txPtr,
|
||||
FTDF_DataLength payloadSize,
|
||||
FTDF_Octet* payload );
|
||||
|
||||
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
|
||||
FTDF_Status FTDF_sendAckFrame( FTDF_FrameHeader* frameHeader,
|
||||
FTDF_SecurityHeader* securityHeader,
|
||||
FTDF_Octet* txPtr );
|
||||
#endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */
|
||||
|
||||
void FTDF_sendTransparentFrame( FTDF_DataLength frameLength,
|
||||
FTDF_Octet* frame,
|
||||
FTDF_ChannelNumber channel,
|
||||
FTDF_PTI pti,
|
||||
FTDF_Boolean cmsaSuppress );
|
||||
|
||||
FTDF_Octet* FTDF_getRxBuffer( void );
|
||||
|
||||
void FTDF_processRxEvent( void );
|
||||
|
||||
FTDF_Octet* FTDF_addFrameHeader( FTDF_Octet* txPtr,
|
||||
FTDF_FrameHeader* frameHeader,
|
||||
FTDF_DataLength msduLength );
|
||||
|
||||
FTDF_Octet* FTDF_getFrameHeader( FTDF_Octet* rxPtr,
|
||||
FTDF_FrameHeader* frameHeader );
|
||||
|
||||
FTDF_DataLength FTDF_getMicLength( FTDF_SecurityLevel securityLevel );
|
||||
|
||||
FTDF_Octet* FTDF_getSecurityHeader( FTDF_Octet* rxPtr,
|
||||
uint8_t frameVersion,
|
||||
FTDF_SecurityHeader* securityHeader );
|
||||
|
||||
FTDF_Octet* FTDF_addSecurityHeader( FTDF_Octet* txPtr,
|
||||
FTDF_SecurityHeader* securityHeader );
|
||||
|
||||
FTDF_Status FTDF_secureFrame( FTDF_Octet* bufPtr,
|
||||
FTDF_Octet* privPtr,
|
||||
FTDF_FrameHeader* frameHeader,
|
||||
FTDF_SecurityHeader* securityHeader );
|
||||
|
||||
FTDF_Status FTDF_unsecureFrame( FTDF_Octet* bufPtr,
|
||||
FTDF_Octet* privPtr,
|
||||
FTDF_FrameHeader* frameHeader,
|
||||
FTDF_SecurityHeader* securityHeader );
|
||||
|
||||
FTDF_KeyDescriptor* FTDF_lookupKey( FTDF_AddressMode devAddrMode,
|
||||
FTDF_PANId devPANId,
|
||||
FTDF_Address devAddr,
|
||||
FTDF_FrameType frameType,
|
||||
FTDF_KeyIdMode keyIdMode,
|
||||
FTDF_KeyIndex keyIndex,
|
||||
FTDF_Octet* keySource );
|
||||
|
||||
FTDF_DeviceDescriptor* FTDF_lookupDevice( FTDF_Size nrOfDeviceDescriptorHandles,
|
||||
FTDF_DeviceDescriptorHandle* deviceDescriptorHandles,
|
||||
FTDF_AddressMode devAddrMode,
|
||||
FTDF_PANId devPANId,
|
||||
FTDF_Address devAddr );
|
||||
|
||||
FTDF_SecurityLevelDescriptor* FTDF_getSecurityLevelDescr( FTDF_FrameType frameType,
|
||||
FTDF_CommandFrameId commandFrameId );
|
||||
|
||||
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
|
||||
FTDF_Octet* FTDF_addIes( FTDF_Octet* txPtr,
|
||||
FTDF_IEList* headerIEList,
|
||||
FTDF_IEList* payloadIEList,
|
||||
FTDF_Boolean withTerminationIE );
|
||||
|
||||
FTDF_Octet* FTDF_getIes( FTDF_Octet* rxPtr,
|
||||
FTDF_Octet* frameEndPtr,
|
||||
FTDF_IEList** headerIEList,
|
||||
FTDF_IEList** payloadIEList );
|
||||
#endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */
|
||||
|
||||
#ifndef FTDF_NO_CSL
|
||||
void FTDF_setPeerCslTiming( FTDF_IEList* headerIEList,
|
||||
FTDF_Time timeStamp );
|
||||
void FTDF_setCslSampleTime( void );
|
||||
void FTDF_getWakeupParams( FTDF_ShortAddress dstAddr,
|
||||
FTDF_Time* wakeupStartTime,
|
||||
FTDF_Period* wakeupPeriod );
|
||||
#endif /* FTDF_NO_CSL */
|
||||
|
||||
void FTDF_getExtAddress( void );
|
||||
void FTDF_setExtAddress( void );
|
||||
void FTDF_getAckWaitDuration( void );
|
||||
void FTDF_getEnhAckWaitDuration( void );
|
||||
void FTDF_setEnhAckWaitDuration( void );
|
||||
void FTDF_getImplicitBroadcast( void );
|
||||
void FTDF_setImplicitBroadcast( void );
|
||||
void FTDF_setShortAddress( void );
|
||||
void FTDF_setSimpleAddress( void );
|
||||
void FTDF_getRxOnWhenIdle( void );
|
||||
void FTDF_setRxOnWhenIdle( void );
|
||||
void FTDF_getPANId( void );
|
||||
void FTDF_setPANId( void );
|
||||
void FTDF_getCurrentChannel( void );
|
||||
void FTDF_setCurrentChannel( void );
|
||||
void FTDF_getMaxFrameTotalWaitTime( void );
|
||||
void FTDF_setMaxFrameTotalWaitTime( void );
|
||||
#ifndef FTDF_NO_CSL
|
||||
void FTDF_setLeEnabled( void );
|
||||
void FTDF_getCslFramePendingWaitT( void );
|
||||
void FTDF_setCslFramePendingWaitT( void );
|
||||
#endif /* FTDF_NO_CSL */
|
||||
void FTDF_getLmacPmData( void );
|
||||
void FTDF_getLmacTrafficCounters( void );
|
||||
void FTDF_setMaxCSMABackoffs( void );
|
||||
void FTDF_setMaxBE( void );
|
||||
void FTDF_setMinBE( void );
|
||||
void FTDF_getKeepPhyEnabled( void );
|
||||
void FTDF_setKeepPhyEnabled( void );
|
||||
#ifndef FTDF_NO_TSCH
|
||||
void FTDF_setTimeslotTemplate( void );
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
void FTDF_initLmac( void );
|
||||
void FTDF_initQueues( void );
|
||||
void FTDF_initQueue( FTDF_Queue* queue );
|
||||
void FTDF_queueBufferHead( FTDF_Buffer* buffer, FTDF_Queue* queue );
|
||||
FTDF_Status FTDF_queueReqHead( FTDF_MsgBuffer* request, FTDF_Queue* queue );
|
||||
FTDF_Buffer* FTDF_dequeueBufferTail( FTDF_Queue* queue );
|
||||
FTDF_MsgBuffer* FTDF_dequeueReqTail( FTDF_Queue* queue );
|
||||
FTDF_MsgBuffer* FTDF_dequeueByHandle( FTDF_Handle handle, FTDF_Queue* queue );
|
||||
FTDF_Buffer* FTDF_dequeueByBuffer( FTDF_Buffer* buffer, FTDF_Queue* queue );
|
||||
FTDF_Boolean FTDF_isQueueEmpty( FTDF_Queue* queue );
|
||||
void FTDF_addTxPendingTimer( FTDF_MsgBuffer* request, uint8_t pendListNr, FTDF_Time delta, void ( * func )(
|
||||
FTDF_PendingTL* ) );
|
||||
void FTDF_removeTxPendingTimer( FTDF_MsgBuffer* request );
|
||||
void FTDF_restoreTxPendingTimer( void );
|
||||
FTDF_Boolean FTDF_getTxPendingTimerHead( FTDF_Time* time );
|
||||
void FTDF_sendTransactionExpired( FTDF_PendingTL* ptr );
|
||||
#ifndef FTDF_NO_TSCH
|
||||
void FTDF_processKeepAliveTimerExp( FTDF_PendingTL* ptr );
|
||||
void FTDF_resetKeepAliveTimer( FTDF_ShortAddress dstAddr );
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
void FTDF_processCommandFrame( FTDF_Octet* rxBuffer,
|
||||
FTDF_FrameHeader* frameHeader,
|
||||
FTDF_SecurityHeader* securityHeader,
|
||||
FTDF_IEList* payloadIEList );
|
||||
|
||||
void FTDF_scanReady( FTDF_ScanRequest* );
|
||||
void FTDF_addPANdescriptor( FTDF_PANDescriptor* );
|
||||
void FTDF_sendBeaconRequest( FTDF_ChannelNumber channel );
|
||||
void FTDF_sendBeaconRequestIndication( FTDF_FrameHeader* frameHeader,
|
||||
FTDF_IEList* payloadIEList );
|
||||
void FTDF_sendOrphanNotification( FTDF_ChannelNumber channel );
|
||||
|
||||
#ifndef FTDF_NO_TSCH
|
||||
void FTDF_setTschEnabled( void );
|
||||
FTDF_Status FTDF_scheduleTsch( FTDF_MsgBuffer* request );
|
||||
void FTDF_tschProcessRequest( void );
|
||||
FTDF_Size FTDF_getTschSyncSubIe( void );
|
||||
FTDF_Octet* FTDF_addTschSyncSubIe( FTDF_Octet* txPtr );
|
||||
FTDF_ShortAddress FTDF_getRequestAddress( FTDF_MsgBuffer* request );
|
||||
FTDF_MsgBuffer* FTDF_tschGetPending( FTDF_MsgBuffer* request );
|
||||
FTDF_Octet* FTDF_addCorrTimeIE( FTDF_Octet* txPtr, FTDF_Time rxTimestamp );
|
||||
void FTDF_correctSlotTime( FTDF_Time rxTimestamp );
|
||||
void FTDF_correctSlotTimeFromAck( FTDF_IEList* headerIEList );
|
||||
void FTDF_initTschRetries( void );
|
||||
FTDF_TschRetry* FTDF_getTschRetry( FTDF_ShortAddress nodeAddr );
|
||||
FTDF_NumOfBackoffs FTDF_getNumOfBackoffs( FTDF_BEExponent BE );
|
||||
void FTDF_initBackoff( void );
|
||||
FTDF_SN FTDF_processTschSN( FTDF_MsgBuffer* msg, FTDF_SN sn, uint8_t* priv );
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
FTDF_Time64 FTDF_getCurTime64( void );
|
||||
void FTDF_initCurTime64( void );
|
||||
@@ -0,0 +1,321 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 "regmap.h"
|
||||
#include "ftdfInfo.h"
|
||||
|
||||
void FTDF_getReleaseInfo(char **lmacRelName, char **lmacBuildTime, char **umacRelName, char **umacBuildTime)
|
||||
{
|
||||
static char lrelName[ 16 ];
|
||||
static char lbldTime[ 16 ];
|
||||
static char urelName[ 16 ];
|
||||
static char ubldTime[ 16 ];
|
||||
uint8_t i;
|
||||
|
||||
volatile uint32_t *ptr = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_REL_NAME);
|
||||
uint32_t *chrPtr = (uint32_t *)lrelName;
|
||||
|
||||
for (i = 0; i < FTDF_ON_OFF_REGMAP_REL_NAME_NUM; i++)
|
||||
{
|
||||
*chrPtr++ = *ptr++;
|
||||
}
|
||||
|
||||
ptr = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_BUILDTIME);
|
||||
chrPtr = (uint32_t *)lbldTime;
|
||||
|
||||
for (i = 0; i < FTDF_ON_OFF_REGMAP_BUILDTIME_NUM; i++)
|
||||
{
|
||||
*chrPtr++ = *ptr++;
|
||||
}
|
||||
|
||||
const char *umacVPtr = FTDF_getUmacRelName();
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
urelName[ i ] = umacVPtr[ i ];
|
||||
|
||||
if (umacVPtr[ i ] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
umacVPtr = FTDF_getUmacBuildTime();
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
ubldTime[ i ] = umacVPtr[ i ];
|
||||
|
||||
if (umacVPtr[ i ] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lrelName[ 15 ] = '\0';
|
||||
lbldTime[ 15 ] = '\0';
|
||||
urelName[ 15 ] = '\0';
|
||||
ubldTime[ 15 ] = '\0';
|
||||
|
||||
*lmacRelName = lrelName;
|
||||
*lmacBuildTime = lbldTime;
|
||||
*umacRelName = urelName;
|
||||
*umacBuildTime = ubldTime;
|
||||
}
|
||||
|
||||
void FTDF_confirmLmacInterrupt(void)
|
||||
{
|
||||
volatile uint32_t *ftdfCm = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CM);
|
||||
*ftdfCm = 0;
|
||||
}
|
||||
|
||||
void FTDF_eventHandler(void)
|
||||
{
|
||||
volatile uint32_t ftdfCe = *FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CE);
|
||||
|
||||
if (ftdfCe & FTDF_MSK_RX_CE)
|
||||
{
|
||||
FTDF_processRxEvent();
|
||||
}
|
||||
|
||||
if (ftdfCe & FTDF_MSK_TX_CE)
|
||||
{
|
||||
FTDF_processTxEvent();
|
||||
}
|
||||
|
||||
if (ftdfCe & FTDF_MSK_SYMBOL_TMR_CE)
|
||||
{
|
||||
FTDF_processSymbolTimerEvent();
|
||||
}
|
||||
|
||||
#ifndef FTDF_LITE
|
||||
#ifndef FTDF_NO_CSL
|
||||
|
||||
if (FTDF_pib.leEnabled)
|
||||
{
|
||||
FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL);
|
||||
FTDF_Time delta = curTime - FTDF_rzTime;
|
||||
|
||||
if (delta < 0x80000000)
|
||||
{
|
||||
// RZ has passed check if a send frame is pending
|
||||
if (FTDF_sendFramePending != 0xfffe)
|
||||
{
|
||||
FTDF_Time wakeupStartTime;
|
||||
FTDF_Period wakeupPeriod;
|
||||
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
|
||||
FTDF_getWakeupParams(FTDF_sendFramePending, &wakeupStartTime, &wakeupPeriod);
|
||||
|
||||
FTDF_txInProgress = FTDF_TRUE;
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLSTARTSAMPLETIME, wakeupStartTime);
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_MACWUPERIOD, wakeupPeriod);
|
||||
|
||||
volatile uint32_t *txFlagSet = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_SET);
|
||||
*txFlagSet |= ((1 << FTDF_TX_DATA_BUFFER) | (1 << FTDF_TX_WAKEUP_BUFFER));
|
||||
|
||||
FTDF_sendFramePending = 0xfffe;
|
||||
|
||||
FTDF_exitCritical();
|
||||
}
|
||||
|
||||
if (FTDF_txInProgress == FTDF_FALSE)
|
||||
{
|
||||
FTDF_setCslSampleTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FTDF_NO_CSL */
|
||||
#endif /* !FTDF_LITE */
|
||||
volatile uint32_t *ftdfCm = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CM);
|
||||
*ftdfCm = FTDF_MSK_TX_CE | FTDF_MSK_RX_CE | FTDF_MSK_SYMBOL_TMR_CE;
|
||||
}
|
||||
|
||||
#ifndef FTDF_PHY_API
|
||||
void FTDF_sndMsg(FTDF_MsgBuffer *msgBuf)
|
||||
{
|
||||
switch (msgBuf->msgId)
|
||||
{
|
||||
#ifndef FTDF_LITE
|
||||
|
||||
case FTDF_DATA_REQUEST:
|
||||
FTDF_processDataRequest((FTDF_DataRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_PURGE_REQUEST:
|
||||
FTDF_processPurgeRequest((FTDF_PurgeRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_ASSOCIATE_REQUEST:
|
||||
FTDF_processAssociateRequest((FTDF_AssociateRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_ASSOCIATE_RESPONSE:
|
||||
FTDF_processAssociateResponse((FTDF_AssociateResponse *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_DISASSOCIATE_REQUEST:
|
||||
FTDF_processDisassociateRequest((FTDF_DisassociateRequest *) msgBuf);
|
||||
break;
|
||||
#endif /* !FTDF_LITE */
|
||||
|
||||
case FTDF_GET_REQUEST:
|
||||
FTDF_processGetRequest((FTDF_GetRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_SET_REQUEST:
|
||||
FTDF_processSetRequest((FTDF_SetRequest *) msgBuf);
|
||||
break;
|
||||
#ifndef FTDF_LITE
|
||||
|
||||
case FTDF_ORPHAN_RESPONSE:
|
||||
FTDF_processOrphanResponse((FTDF_OrphanResponse *) msgBuf);
|
||||
break;
|
||||
#endif /* !FTDF_LITE */
|
||||
|
||||
case FTDF_RESET_REQUEST:
|
||||
FTDF_processResetRequest((FTDF_ResetRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_RX_ENABLE_REQUEST:
|
||||
FTDF_processRxEnableRequest((FTDF_RxEnableRequest *) msgBuf);
|
||||
break;
|
||||
#ifndef FTDF_LITE
|
||||
|
||||
case FTDF_SCAN_REQUEST:
|
||||
FTDF_processScanRequest((FTDF_ScanRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_START_REQUEST:
|
||||
FTDF_processStartRequest((FTDF_StartRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_POLL_REQUEST:
|
||||
FTDF_processPollRequest((FTDF_PollRequest *) msgBuf);
|
||||
break;
|
||||
#ifndef FTDF_NO_TSCH
|
||||
|
||||
case FTDF_SET_SLOTFRAME_REQUEST:
|
||||
FTDF_processSetSlotframeRequest((FTDF_SetSlotframeRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_SET_LINK_REQUEST:
|
||||
FTDF_processSetLinkRequest((FTDF_SetLinkRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_TSCH_MODE_REQUEST:
|
||||
FTDF_processTschModeRequest((FTDF_TschModeRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_KEEP_ALIVE_REQUEST:
|
||||
FTDF_processKeepAliveRequest((FTDF_KeepAliveRequest *) msgBuf);
|
||||
break;
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
case FTDF_BEACON_REQUEST:
|
||||
FTDF_processBeaconRequest((FTDF_BeaconRequest *) msgBuf);
|
||||
break;
|
||||
#endif /* !FTDF_LITE */
|
||||
|
||||
case FTDF_TRANSPARENT_ENABLE_REQUEST:
|
||||
FTDF_enableTransparentMode(((FTDF_TransparentEnableRequest *) msgBuf)->enable,
|
||||
((FTDF_TransparentEnableRequest *) msgBuf)->options);
|
||||
FTDF_REL_MSG_BUFFER(msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_TRANSPARENT_REQUEST:
|
||||
FTDF_processTransparentRequest((FTDF_TransparentRequest *) msgBuf);
|
||||
break;
|
||||
|
||||
case FTDF_SLEEP_REQUEST:
|
||||
FTDF_SLEEP_CALLBACK(((FTDF_SleepRequest *)msgBuf)->sleepTime);
|
||||
FTDF_REL_MSG_BUFFER(msgBuf);
|
||||
break;
|
||||
#ifndef FTDF_LITE
|
||||
|
||||
case FTDF_REMOTE_REQUEST:
|
||||
FTDF_processRemoteRequest((FTDF_RemoteRequest *)msgBuf);
|
||||
break;
|
||||
#endif /* !FTDF_LITE */
|
||||
#if FTDF_DBG_BUS_ENABLE
|
||||
|
||||
case FTDF_DBG_MODE_SET_REQUEST:
|
||||
FTDF_setDbgMode(((FTDF_DbgModeSetRequest *) msgBuf)->dbgMode);
|
||||
FTDF_REL_MSG_BUFFER(msgBuf);
|
||||
break;
|
||||
#endif /* FTDF_DBG_BUS_ENABLE */
|
||||
|
||||
default:
|
||||
// Silenty release the message buffer
|
||||
FTDF_REL_MSG_BUFFER(msgBuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FTDF_sendFrameTransparentConfirm(void *handle,
|
||||
FTDF_Bitmap32 status)
|
||||
{
|
||||
FTDF_TransparentConfirm *confirm =
|
||||
(FTDF_TransparentConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_TransparentConfirm));
|
||||
|
||||
confirm->msgId = FTDF_TRANSPARENT_CONFIRM;
|
||||
confirm->handle = handle;
|
||||
confirm->status = status;
|
||||
|
||||
FTDF_RCV_MSG((FTDF_MsgBuffer *) confirm);
|
||||
}
|
||||
|
||||
void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
|
||||
FTDF_Octet *frame,
|
||||
FTDF_Bitmap32 status)
|
||||
{
|
||||
FTDF_TransparentIndication *indication =
|
||||
(FTDF_TransparentIndication *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_TransparentIndication));
|
||||
|
||||
indication->msgId = FTDF_TRANSPARENT_INDICATION;
|
||||
indication->frameLength = frameLength;
|
||||
indication->status = status;
|
||||
indication->frame = FTDF_GET_DATA_BUFFER(frameLength);
|
||||
memcpy(indication->frame, frame, frameLength);
|
||||
|
||||
FTDF_RCV_MSG((FTDF_MsgBuffer *) indication);
|
||||
}
|
||||
#endif /* !FTDF_PHY_API */
|
||||
@@ -0,0 +1,319 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @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 "regmap.h"
|
||||
|
||||
static FTDF_PSec FTDF_lowPowerClockCycle __attribute__((section(".retention")));
|
||||
static FTDF_PSec FTDF_wakeUpLatency __attribute__((section(".retention")));
|
||||
/* Pre-calculated value for optimization. */
|
||||
static FTDF_USec FTDF_lowPowerClockCycleUSec __attribute__((section(".retention")));
|
||||
/* Pre-calculated value for optimization. */
|
||||
static FTDF_USec FTDF_wakeUpLatencyUSec __attribute__((section(".retention")));
|
||||
/* Pre-calculated value for optimization. */
|
||||
static FTDF_NrLowPowerClockCycles FTDF_csmacaWakeupThr __attribute__((section(".retention")));
|
||||
|
||||
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
|
||||
static uint32_t FTDF_eventCurrVal __attribute__((section(".retention")));
|
||||
static uint32_t FTDF_timeStampCurrVal __attribute__((section(".retention")));
|
||||
static uint32_t FTDF_timeStampCurrPhaseVal __attribute__((section(".retention")));
|
||||
#endif
|
||||
#ifndef FTDF_NO_CSL
|
||||
FTDF_Boolean FTDF_wakeUpEnableLe __attribute__((section(".retention")));
|
||||
#endif /* FTDF_NO_CSL */
|
||||
#ifndef FTDF_NO_TSCH
|
||||
FTDF_Boolean FTDF_wakeUpEnableTsch;
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
|
||||
void FTDF_setSleepAttributes(FTDF_PSec lowPowerClockCycle,
|
||||
FTDF_NrLowPowerClockCycles wakeUpLatency)
|
||||
{
|
||||
FTDF_lowPowerClockCycle = lowPowerClockCycle;
|
||||
FTDF_wakeUpLatency = (uint64_t)wakeUpLatency * lowPowerClockCycle;
|
||||
FTDF_lowPowerClockCycleUSec = FTDF_lowPowerClockCycle / 1000000;
|
||||
FTDF_wakeUpLatencyUSec = FTDF_wakeUpLatency / 1000000;
|
||||
FTDF_csmacaWakeupThr = (FTDF_NrLowPowerClockCycles)
|
||||
(((FTDF_PSec) 0xffffffff * 1000000 - FTDF_wakeUpLatency) / FTDF_lowPowerClockCycle);
|
||||
}
|
||||
|
||||
FTDF_USec FTDF_canSleep(void)
|
||||
{
|
||||
#ifdef FTDF_PHY_API
|
||||
|
||||
if (FTDF_txInProgress || FTDF_pib.keepPhyEnabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (FTDF_reqCurrent || FTDF_pib.keepPhyEnabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (FTDF_GET_FIELD(ON_OFF_REGMAP_LMACREADY4SLEEP) == 0 ||
|
||||
FTDF_GET_FIELD(ON_OFF_REGMAP_SECBUSY) == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FTDF_NO_CSL
|
||||
|
||||
if (FTDF_pib.leEnabled)
|
||||
{
|
||||
if (FTDF_txInProgress == FTDF_FALSE)
|
||||
{
|
||||
FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL);
|
||||
FTDF_Time delta = curTime - FTDF_startCslSampleTime;
|
||||
|
||||
// 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_startCslSampleTime - curTime) * 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FTDF_NO_CSL */
|
||||
|
||||
#ifndef FTDF_NO_TSCH
|
||||
|
||||
if (FTDF_pib.tschEnabled)
|
||||
{
|
||||
FTDF_Time64 curTime64 = FTDF_getCurTime64();
|
||||
FTDF_Time64 delta = curTime64 - FTDF_tschSlotTime;
|
||||
|
||||
// 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 sleepTime = (FTDF_USec)(FTDF_tschSlotTime - curTime64);
|
||||
|
||||
FTDF_Time pendListTime;
|
||||
FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL);
|
||||
FTDF_Boolean pending = FTDF_getTxPendingTimerHead(&pendListTime);
|
||||
|
||||
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 - pendListTime < 0x80000000)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
FTDF_USec tmpSleepTime = (FTDF_USec)(pendListTime - curTime);
|
||||
|
||||
if (tmpSleepTime < sleepTime)
|
||||
{
|
||||
sleepTime = tmpSleepTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (sleepTime < FTDF_TSCH_MAX_PROCESS_REQUEST_TIME + FTDF_TSCH_MAX_SCHEDULE_TIME)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (sleepTime - (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_txPendingList[ n ].addrMode != FTDF_NO_ADDRESS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !FTDF_LITE */
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
FTDF_Boolean FTDF_prepareForSleep(FTDF_USec sleepTime)
|
||||
{
|
||||
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
|
||||
|
||||
if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled)
|
||||
{
|
||||
if (sleepTime < 2 * FTDF_lowPowerClockCycleUSec)
|
||||
{
|
||||
return FTDF_FALSE;
|
||||
}
|
||||
|
||||
// Correct sleeptime with the inaccuracy of this function
|
||||
sleepTime -= 2 * FTDF_lowPowerClockCycleUSec;
|
||||
|
||||
if (sleepTime < FTDF_wakeUpLatencyUSec + 500)
|
||||
{
|
||||
return FTDF_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
|
||||
#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
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_GETGENERATORVAL, 1);
|
||||
|
||||
#endif
|
||||
// Save current LMAC PM counters
|
||||
FTDF_lmacCounters.fcsErrorCnt += FTDF_GET_FIELD(ON_OFF_REGMAP_MACFCSERRORCOUNT);
|
||||
FTDF_lmacCounters.txStdAckCnt += FTDF_GET_FIELD(ON_OFF_REGMAP_MACTXSTDACKFRMCNT);
|
||||
FTDF_lmacCounters.rxStdAckCnt += FTDF_GET_FIELD(ON_OFF_REGMAP_MACRXSTDACKFRMOKCNT);
|
||||
|
||||
#if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH)
|
||||
volatile uint32_t *getGeneratorValE = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_GETGENERATORVAL_E);
|
||||
|
||||
// Wait until data is ready
|
||||
while ((*getGeneratorValE & MSK_F_FTDF_ON_OFF_REGMAP_GETGENERATORVAL_E) == 0)
|
||||
{ }
|
||||
|
||||
FTDF_eventCurrVal = FTDF_GET_FIELD(ON_OFF_REGMAP_EVENTCURRVAL);
|
||||
FTDF_timeStampCurrVal = FTDF_GET_FIELD(ON_OFF_REGMAP_TIMESTAMPCURRVAL);
|
||||
FTDF_timeStampCurrPhaseVal = FTDF_GET_FIELD(ON_OFF_REGMAP_TIMESTAMPCURRPHASEVAL);
|
||||
|
||||
#ifdef SIMULATOR
|
||||
*getGeneratorValE &= ~MSK_F_FTDF_ON_OFF_REGMAP_GETGENERATORVAL_E;
|
||||
#else
|
||||
*getGeneratorValE = MSK_F_FTDF_ON_OFF_REGMAP_GETGENERATORVAL_E;
|
||||
#endif
|
||||
uint64_t nextWakeUpThr;
|
||||
|
||||
if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled)
|
||||
{
|
||||
uint64_t picoSleepTime = (uint64_t)sleepTime * 1000000;
|
||||
nextWakeUpThr = (picoSleepTime - FTDF_wakeUpLatency) / FTDF_lowPowerClockCycle;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextWakeUpThr = FTDF_csmacaWakeupThr;
|
||||
}
|
||||
|
||||
// Set wake up threshold
|
||||
uint32_t wakeUpIntThr = FTDF_eventCurrVal + nextWakeUpThr;
|
||||
|
||||
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPINTTHR, wakeUpIntThr);
|
||||
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPENABLE, 1);
|
||||
#endif
|
||||
FTDF_exitCritical();
|
||||
|
||||
return FTDF_TRUE;
|
||||
}
|
||||
|
||||
void FTDF_wakeUp(void)
|
||||
{
|
||||
#ifndef FTDF_PHY_API
|
||||
FTDF_criticalVar();
|
||||
FTDF_enterCritical();
|
||||
|
||||
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_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
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_GETGENERATORVAL, 1);
|
||||
|
||||
volatile uint32_t *getGeneratorValE = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_GETGENERATORVAL_E);
|
||||
|
||||
// Wait until data is ready
|
||||
while ((*getGeneratorValE & MSK_F_FTDF_ON_OFF_REGMAP_GETGENERATORVAL_E) == 0)
|
||||
{ }
|
||||
|
||||
uint32_t eventNewCurrVal = FTDF_GET_FIELD(ON_OFF_REGMAP_EVENTCURRVAL);
|
||||
|
||||
#ifdef SIMULATOR
|
||||
*getGeneratorValE &= ~MSK_F_FTDF_ON_OFF_REGMAP_GETGENERATORVAL_E;
|
||||
#else
|
||||
*getGeneratorValE = MSK_F_FTDF_ON_OFF_REGMAP_GETGENERATORVAL_E;
|
||||
#endif
|
||||
|
||||
// Backward calculate the time slept
|
||||
FTDF_PSec sleepTime = ((uint64_t)(eventNewCurrVal - FTDF_eventCurrVal) * FTDF_lowPowerClockCycle) + FTDF_wakeUpLatency;
|
||||
|
||||
// Calculate sync values
|
||||
uint64_t newSyncVals = ((uint64_t)FTDF_timeStampCurrVal << 8) | (FTDF_timeStampCurrPhaseVal & 0xff);
|
||||
newSyncVals += (sleepTime / 62500) + 1;
|
||||
|
||||
uint32_t syncTimestampThr = FTDF_eventCurrVal + (sleepTime / FTDF_lowPowerClockCycle);
|
||||
uint32_t syncTimestampVal = (newSyncVals & 0xffffffff00) >> 8;
|
||||
uint32_t syncTimestampPhaseVal = (newSyncVals & 0xff);
|
||||
|
||||
// Set values
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_SYNCTIMESTAMPTHR, syncTimestampThr);
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_SYNCTIMESTAMPVAL, syncTimestampVal);
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_SYNCTIMESTAMPPHASEVAL, syncTimestampPhaseVal);
|
||||
FTDF_SET_FIELD(ON_OFF_REGMAP_SYNCTIMESTAMPENA, 1);
|
||||
#endif
|
||||
|
||||
FTDF_exitCritical();
|
||||
|
||||
#ifndef FTDF_NO_CSL
|
||||
FTDF_wakeUpEnableLe = FTDF_pib.leEnabled;
|
||||
FTDF_pib.leEnabled = FTDF_FALSE;
|
||||
#endif /* FTDF_NO_CSL */
|
||||
|
||||
#ifndef FTDF_NO_TSCH
|
||||
FTDF_wakeUpEnableTsch = FTDF_pib.tschEnabled;
|
||||
FTDF_pib.tschEnabled = FTDF_FALSE;
|
||||
#endif /* FTDF_NO_TSCH */
|
||||
#endif /* ! FTDF_PHY_API */
|
||||
// Init LMAC
|
||||
FTDF_initLmac();
|
||||
}
|
||||
+4103
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
arm-none-eabi-objcopy -O binary ../../../output/bin/arm-none-eabi-ot-cli-ftd ../../../output/bin/arm-none-eabi-ot-cli-ftd.bin
|
||||
./bin2image qspi_cached ../../../output/bin/arm-none-eabi-ot-cli-ftd.bin ../../../output/bin/arm-none-eabi-ot-cli-ftd.img AD enable_uart
|
||||
|
||||
|
||||
BIN
Binary file not shown.
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
URL: http://www.dialog-semiconductor.com/openthread-sandbox-development-kit
|
||||
|
||||
Version: TO BE UPDATED!
|
||||
|
||||
|
||||
License: BSD3
|
||||
|
||||
|
||||
Description:
|
||||
|
||||
DialogSDK - contain board support package and radio interface used for build
|
||||
|
||||
DialogTools - contain flash tools
|
||||
imgprep.sh - prepare image from generated binary using bin2image tool
|
||||
cli_programmer and uartboot - utilities for loading image into the platform
|
||||
|
||||
Look into examples/platform/da15000/README.am for DialogTools usage description.
|
||||
Reference in New Issue
Block a user