commit
7da2787933
|
@ -7,11 +7,14 @@
|
|||
*.elf
|
||||
*.zip
|
||||
*.d
|
||||
*.o
|
||||
*.e
|
||||
*.ihex
|
||||
*.pyc
|
||||
*~
|
||||
obj_*
|
||||
Makefile.target
|
||||
Makefile.*.defines
|
||||
tools/doxygen/html
|
||||
patches-*
|
||||
tools/tunslip
|
||||
|
@ -19,8 +22,6 @@ tools/tunslip6
|
|||
build
|
||||
tools/coffee-manager/build/
|
||||
tools/coffee-manager/coffee.jar
|
||||
tools/collect-view/build/
|
||||
tools/collect-view/dist/
|
||||
COOJA.testlog
|
||||
|
||||
# platform build artifacts
|
||||
|
@ -31,6 +32,7 @@ COOJA.testlog
|
|||
*.nrf52dk
|
||||
*.openmote-cc2538
|
||||
*.sky
|
||||
*.firmware
|
||||
*.srf06-cc26xx
|
||||
*.zoul
|
||||
|
||||
|
@ -50,14 +52,11 @@ COOJA.testlog
|
|||
|
||||
#test artifacts
|
||||
*.testlog
|
||||
*.log.prog
|
||||
*.report
|
||||
summary
|
||||
*.scriptlog
|
||||
*.coojalog
|
||||
*.summary
|
||||
*.runerr
|
||||
*.runlog
|
||||
*.faillog
|
||||
tests/[0-9][0-9]-*/report
|
||||
*.err
|
||||
summary
|
||||
tests/[0-9][0-9]-*/org/
|
||||
|
||||
# x86 UEFI files
|
||||
|
|
|
@ -13,3 +13,9 @@
|
|||
[submodule "tools/cooja"]
|
||||
path = tools/cooja
|
||||
url = https://github.com/contiki-ng/cooja.git
|
||||
[submodule "os/net/security/tinydtls"]
|
||||
path = os/net/security/tinydtls
|
||||
url = https://github.com/contiki-ng/tinydtls.git
|
||||
[submodule "tests/18-coap-lwm2m/example-lwm2m-standalone"]
|
||||
path = tests/18-coap-lwm2m/example-lwm2m-standalone
|
||||
url = https://github.com/contiki-ng/example-lwm2m-standalone.git
|
||||
|
|
131
.travis.yml
131
.travis.yml
|
@ -1,108 +1,35 @@
|
|||
# Workaround for the issue found in the stable image promoted on Dec 1, 2016.
|
||||
# See https://github.com/travis-ci/travis-ci/issues/6928#issuecomment-264227708
|
||||
group: deprecated
|
||||
# Setup environment for Docker
|
||||
language: generic
|
||||
services: docker
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
language: c #NOTE: this will set CC=gcc which might cause trouble
|
||||
before_script:
|
||||
- WGET="travis_retry wget --continue --tries=20 --waitretry=10 --retry-connrefused --no-dns-cache --timeout 300"
|
||||
- sudo apt-get -qq update
|
||||
- email: false
|
||||
|
||||
## Support building a binary that is identical to the CI
|
||||
- echo -n "Contiki will be compiled with RELSTR=" ; git --git-dir .git describe --tags --always
|
||||
|
||||
## Install doxygen
|
||||
- if [ ${BUILD_CATEGORY:-0} = doxygen ] ; then
|
||||
sudo add-apt-repository ppa:libreoffice/ppa -y && sudo apt-get -qq update &&
|
||||
sudo apt-get --no-install-suggests --no-install-recommends -qq install doxygen &&
|
||||
doxygen --version ;
|
||||
fi
|
||||
|
||||
## Install msp430 toolchain
|
||||
- sudo apt-get -qq install lib32z1
|
||||
- $WGET http://simonduq.github.io/resources/mspgcc-4.7.2-compiled.tar.bz2 &&
|
||||
tar xjf mspgcc*.tar.bz2 -C /tmp/ &&
|
||||
sudo cp -f -r /tmp/msp430/* /usr/local/ &&
|
||||
rm -rf /tmp/msp430 mspgcc*.tar.bz2 &&
|
||||
msp430-gcc --version
|
||||
|
||||
## Install 32-bit compatibility libraries
|
||||
- sudo apt-get -qq install libc6:i386 libgcc1:i386 gcc-4.6-base:i386
|
||||
libstdc++5:i386 libstdc++6:i386
|
||||
|
||||
## Install mainline ARM toolchain and srecord.
|
||||
- if [ ${BUILD_ARCH:-0} = arm-aapcs ] ; then
|
||||
sudo apt-get -qq install srecord &&
|
||||
$WGET https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 &&
|
||||
tar xjf gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 -C /tmp/ &&
|
||||
sudo cp -f -r /tmp/gcc-arm-none-eabi-5_2-2015q4/* /usr/local/ &&
|
||||
rm -rf /tmp/gcc-arm-none-eabi-* gcc-arm-none-eabi-*-linux.tar.bz2 &&
|
||||
arm-none-eabi-gcc --version ;
|
||||
fi
|
||||
|
||||
## Install NXP toolchain
|
||||
- if [ ${BUILD_ARCH:-0} = jn516x ] ; then
|
||||
$WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part1.tar.bz2 &&
|
||||
$WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part2.tar.bz2 &&
|
||||
$WGET http://simonduq.github.io/resources/jn516x-sdk-4163-1416.tar.bz2 &&
|
||||
mkdir /tmp/jn516x-sdk /tmp/ba-elf-gcc &&
|
||||
tar xjf jn516x-sdk-*.tar.bz2 -C /tmp/jn516x-sdk &&
|
||||
tar xjf ba-elf-gcc-*part1.tar.bz2 -C /tmp/ba-elf-gcc &&
|
||||
tar xjf ba-elf-gcc-*part2.tar.bz2 -C /tmp/ba-elf-gcc &&
|
||||
sudo cp -f -r /tmp/jn516x-sdk /usr/ &&
|
||||
sudo cp -f -r /tmp/ba-elf-gcc /usr/ &&
|
||||
export PATH=/usr/ba-elf-gcc/bin:$PATH &&
|
||||
rm -rf /tmp/ba-elf-gcc* /tmp/jn516x-sdk* &&
|
||||
ba-elf-gcc --version ;
|
||||
fi
|
||||
|
||||
## Install mainline ARM toolchain and download nRF52 SDK
|
||||
- if [ ${BUILD_ARCH:-0} = nrf52dk ] ; then
|
||||
sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa &&
|
||||
sudo apt-get -qq update &&
|
||||
sudo apt-get -qq install gcc-arm-embedded srecord &&
|
||||
arm-none-eabi-gcc --version &&
|
||||
$WGET https://developer.nordicsemi.com/nRF5_IoT_SDK/nRF5_IoT_SDK_v0.9.x/nrf5_iot_sdk_3288530.zip &&
|
||||
mkdir /tmp/nrf52-sdk &&
|
||||
unzip nrf5_iot_sdk_3288530.zip -d /tmp/nrf52-sdk &&
|
||||
export NRF52_SDK_ROOT=/tmp/nrf52-sdk ;
|
||||
fi
|
||||
|
||||
## Compile cooja.jar only when it's going to be needed
|
||||
- if [ ${BUILD_CATEGORY:-0} = sim ] ; then
|
||||
java -version &&
|
||||
ant -q -f tools/cooja/build.xml jar &&
|
||||
sudo java -Xshare:dump -version ;
|
||||
fi
|
||||
|
||||
script:
|
||||
## tests/Makefile handles most of generic logic
|
||||
- "make -C tests/??-$BUILD_TYPE RUNALL=true summary"
|
||||
|
||||
after_script:
|
||||
## Print cooja test logs
|
||||
- "[ ${BUILD_CATEGORY:-0} = sim ] && tail tests/??-$BUILD_TYPE/*.testlog"
|
||||
## Print a basic summary
|
||||
- "echo 'Summary:'; cat tests/??-$BUILD_TYPE/summary"
|
||||
- "FAILS=`grep -c ' FAIL ' tests/??-$BUILD_TYPE/summary`"
|
||||
## This will detect whether the build should pass or fail
|
||||
- "test $FAILS -eq 0; exit $?"
|
||||
before_install:
|
||||
# Environment setup before test script
|
||||
- export CNG_HOST_PATH=`pwd`
|
||||
- export DOCKER_IMG='simonduq/contiki-ng:latest'
|
||||
- sudo chgrp -hR 1000 $CNG_HOST_PATH
|
||||
- docker pull $DOCKER_IMG
|
||||
- ant -q -f $CNG_HOST_PATH/tools/cooja/build.xml jar
|
||||
|
||||
script: # The test script for each build.
|
||||
- docker run --privileged -v $CNG_HOST_PATH:/home/user/contiki-ng -ti $DOCKER_IMG bash --login -c "make -C tests/??-$TEST_NAME";
|
||||
# Check outcome of the test
|
||||
- $CNG_HOST_PATH/tests/check-test.sh $CNG_HOST_PATH/tests/??-$TEST_NAME; exit $?;
|
||||
|
||||
env:
|
||||
## This magically kick-off parallel jobs for each of the for the sets
|
||||
## of environment variable defined below
|
||||
- BUILD_TYPE='doxygen' BUILD_CATEGORY='doxygen'
|
||||
- BUILD_TYPE='compile-base' BUILD_CATEGORY='compile'
|
||||
- BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-aapcs'
|
||||
- BUILD_TYPE='compile-nxp-ports' BUILD_CATEGORY='compile' BUILD_ARCH='jn516x'
|
||||
- BUILD_TYPE='compile-nrf52-ports' BUILD_CATEGORY='compile' BUILD_ARCH='nrf52dk'
|
||||
- BUILD_TYPE='compile-tools' BUILD_CATEGORY='compile'
|
||||
- BUILD_TYPE='rpl-lite' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='rpl-classic' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='ipv6' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='nullnet' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='base' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='ieee802154' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='6tisch' BUILD_CATEGORY='sim'
|
||||
# Parallel builds
|
||||
- TEST_NAME='compile-base'
|
||||
- TEST_NAME='compile-arm-ports-01'
|
||||
- TEST_NAME='compile-arm-ports-02'
|
||||
- TEST_NAME='rpl-lite'
|
||||
- TEST_NAME='rpl-classic'
|
||||
- TEST_NAME='tun-rpl-br'
|
||||
- TEST_NAME='coap-lwm2m'
|
||||
- TEST_NAME='simulation-base'
|
||||
- TEST_NAME='ieee802154'
|
||||
- TEST_NAME='compile-nxp-ports'
|
||||
- TEST_NAME='doxygen'
|
||||
- TEST_NAME='compile-tools'
|
||||
- TEST_NAME='native-runs'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Contiki is licensed under the 3-clause BSD license. This license gives
|
||||
Contiki-NG is licensed under the 3-clause BSD license. This license gives
|
||||
everyone the right to use and distribute the code, either in binary or
|
||||
source code format, as long as the copyright license is retained in
|
||||
the source code.
|
||||
|
|
175
Makefile.include
175
Makefile.include
|
@ -8,7 +8,9 @@ endif
|
|||
# Setting this option is also important for tests on Cooja motes to check for warnings.
|
||||
WERROR ?= 1
|
||||
|
||||
include $(CONTIKI)/Makefile.identify-target
|
||||
include $(CONTIKI)/Makefile.identify-target
|
||||
|
||||
CONTIKI_NG_TARGET_LIB = contiki-ng-$(TARGET).a
|
||||
|
||||
ifeq ($(DEFINES),)
|
||||
-include Makefile.$(TARGET).defines
|
||||
|
@ -40,9 +42,11 @@ LOWERCASE = -abcdefghijklmnopqrstuvwxyz/
|
|||
UPPERCASE = _ABCDEFGHIJKLMNOPQRSTUVWXYZ_
|
||||
TARGET_UPPERCASE := ${strip ${shell echo $(TARGET) | sed y!$(LOWERCASE)!$(UPPERCASE)!}}
|
||||
CFLAGS += -DCONTIKI=1 -DCONTIKI_TARGET_$(TARGET_UPPERCASE)=1
|
||||
CFLAGS += -DCONTIKI_TARGET_STRING=\"$(TARGET)\"
|
||||
ifneq ($(BOARD),)
|
||||
TARGET_BOARD_UPPERCASE := ${strip ${shell echo $(BOARD) | sed y!$(LOWERCASE)!$(UPPERCASE)!}}
|
||||
CFLAGS += -DCONTIKI_BOARD_$(TARGET_BOARD_UPPERCASE)=1
|
||||
CFLAGS += -DCONTIKI_BOARD_STRING=\"$(BOARD)\"
|
||||
endif
|
||||
|
||||
MODULES += os os/sys os/dev os/lib os/services
|
||||
|
@ -52,12 +56,17 @@ ifneq ("$(wildcard project-conf.h)","")
|
|||
CFLAGS += -DPROJECT_CONF_PATH=\"project-conf.h\"
|
||||
endif
|
||||
|
||||
MODULES += os os/net os/net/mac os/storage
|
||||
MODULES += os os/net os/net/mac os/net/mac/framer os/net/routing os/storage
|
||||
|
||||
oname = ${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)}}
|
||||
define oname
|
||||
${patsubst %.c,%.o, \
|
||||
${patsubst %.S,%.o, \
|
||||
${patsubst %.s,%.o, \
|
||||
$(1) \
|
||||
}}}
|
||||
endef
|
||||
|
||||
CONTIKI_OBJECTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CONTIKI_SOURCEFILES)}}
|
||||
|
||||
PROJECT_OBJECTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(PROJECT_SOURCEFILES)}}
|
||||
|
||||
# Provide way to create $(OBJECTDIR) if it has been removed by make clean
|
||||
|
@ -80,13 +89,43 @@ else
|
|||
include $(target_makefile)
|
||||
endif
|
||||
|
||||
# Decide whether to build or to skip this target for this platform
|
||||
ifneq ("", "$(PLATFORMS_ONLY)")
|
||||
ifeq ("","$(filter $(TARGET), $(PLATFORMS_ONLY))")
|
||||
PLATFORM_ACTION = skip
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ("", "$(PLATFORMS_EXCLUDE)")
|
||||
ifneq ("","$(filter $(TARGET), $(PLATFORMS_EXCLUDE))")
|
||||
PLATFORM_ACTION = skip
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(BOARD),)
|
||||
ifneq ("", "$(BOARDS_ONLY)")
|
||||
ifeq ("","$(filter $(BOARD), $(BOARDS_ONLY))")
|
||||
PLATFORM_ACTION = skip
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ("", "$(BOARDS_EXCLUDE)")
|
||||
ifneq ("","$(filter $(BOARD), $(BOARDS_EXCLUDE))")
|
||||
PLATFORM_ACTION = skip
|
||||
endif
|
||||
endif
|
||||
endif # $(BOARD) not empty
|
||||
|
||||
PLATFORM_ACTION ?= build
|
||||
|
||||
# Configure MAC layer
|
||||
|
||||
# The different options
|
||||
MAKE_MAC_NULLMAC = 0
|
||||
MAKE_MAC_CSMA = 1
|
||||
MAKE_MAC_TSCH = 2
|
||||
MAKE_MAC_OTHER = 3
|
||||
MAKE_MAC_BLE = 3
|
||||
MAKE_MAC_OTHER = 4
|
||||
|
||||
# Make CSMA the default MAC
|
||||
MAKE_MAC ?= MAKE_MAC_CSMA
|
||||
|
@ -106,6 +145,11 @@ ifeq ($(MAKE_MAC),MAKE_MAC_TSCH)
|
|||
CFLAGS += -DMAC_CONF_WITH_TSCH=1
|
||||
endif
|
||||
|
||||
ifeq ($(MAKE_MAC),MAKE_MAC_BLE)
|
||||
MODULES += os/net/mac/ble
|
||||
CFLAGS += -DMAC_CONF_WITH_BLE=1
|
||||
endif
|
||||
|
||||
ifeq ($(MAKE_MAC),MAKE_MAC_OTHER)
|
||||
CFLAGS += -DMAC_CONF_WITH_OTHER=1
|
||||
endif
|
||||
|
@ -140,7 +184,7 @@ ifeq ($(WITH_IP64),1)
|
|||
endif
|
||||
|
||||
# Configure Routing protocol
|
||||
MAKE_ROUTING_NONE = 0
|
||||
MAKE_ROUTING_NULLROUTING = 0
|
||||
MAKE_ROUTING_RPL_CLASSIC = 1
|
||||
MAKE_ROUTING_RPL_LITE = 2
|
||||
|
||||
|
@ -148,28 +192,36 @@ MAKE_ROUTING_RPL_LITE = 2
|
|||
ifeq ($(MAKE_NET),MAKE_NET_IPV6)
|
||||
MAKE_ROUTING ?= MAKE_ROUTING_RPL_LITE
|
||||
else
|
||||
MAKE_ROUTING ?= MAKE_ROUTING_NONE
|
||||
MAKE_ROUTING ?= MAKE_ROUTING_NULLROUTING
|
||||
endif
|
||||
|
||||
ifeq ($(MAKE_ROUTING),MAKE_ROUTING_RPL_CLASSIC)
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL=1
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL_CLASSIC=1
|
||||
MODULES += os/net/rpl-classic
|
||||
CFLAGS += -DROUTING_CONF_RPL_CLASSIC=1
|
||||
MODULES += os/net/routing/rpl-classic
|
||||
else ifeq ($(MAKE_ROUTING),MAKE_ROUTING_RPL_LITE)
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL=1
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL_LITE=1
|
||||
MODULES += os/net/rpl-lite
|
||||
else
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL=0
|
||||
CFLAGS += -DROUTING_CONF_RPL_LITE=1
|
||||
MODULES += os/net/routing/rpl-lite
|
||||
else ifeq ($(MAKE_ROUTING),MAKE_ROUTING_NULLROUTING)
|
||||
CFLAGS += -DROUTING_CONF_NULLROUTING=1
|
||||
MODULES += os/net/routing/nullrouting
|
||||
endif
|
||||
|
||||
ifdef MODULES
|
||||
UNIQUEMODULES = $(call uniq,$(MODULES))
|
||||
MODULEDIRS = ${wildcard ${addprefix $(CONTIKI)/, $(UNIQUEMODULES)}}
|
||||
MODULES_SOURCES = ${foreach d, $(MODULEDIRS), ${subst ${d}/,,${wildcard $(d)/*.c}}}
|
||||
MODULES_INCLUDES = ${wildcard ${foreach d, $(MODULEDIRS), $(d)/Makefile.${notdir $(d)}}}
|
||||
include $(MODULES_INCLUDES)
|
||||
CONTIKI_SOURCEFILES += $(MODULES_SOURCES)
|
||||
MODULEDIRS = $(MODULES_REL) ${wildcard ${addprefix $(CONTIKI)/, $(MODULES)}}
|
||||
UNIQUEMODULES = $(call uniq,$(MODULEDIRS))
|
||||
MODULES_SOURCES = ${foreach d, $(MODULEDIRS), ${subst ${d}/,,${wildcard $(d)/*.c}}}
|
||||
CONTIKI_SOURCEFILES += $(MODULES_SOURCES)
|
||||
|
||||
# Include module-specific makefiles
|
||||
MODULES_INCLUDES = ${wildcard ${foreach d, $(MODULEDIRS), $(d)/Makefile.${notdir $(d)}}}
|
||||
include $(MODULES_INCLUDES)
|
||||
# Iterate once more: include the modules added from the previous include.
|
||||
# Only works with one level of nested module inclusion.
|
||||
include $(MODULES_INCLUDES)
|
||||
|
||||
# C-include module-specific macros using -imacros
|
||||
MODULES_IMACROS = ${wildcard ${foreach d, $(MODULEDIRS), $(d)/module-macros.h}}
|
||||
ifneq ($(MODULES_IMACROS),)
|
||||
CFLAGS += ${foreach d, $(MODULES_IMACROS), -imacros $(d)}
|
||||
endif
|
||||
|
||||
### Verbosity control. Use make V=1 to get verbose builds.
|
||||
|
@ -206,13 +258,15 @@ SOURCEDIRS = . $(PROJECTDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) $(CONTIKI_ARCH_DIRS)
|
|||
|
||||
vpath %.c $(SOURCEDIRS)
|
||||
vpath %.S $(SOURCEDIRS)
|
||||
vpath %.s $(SOURCEDIRS)
|
||||
|
||||
CFLAGS += ${addprefix -I,$(SOURCEDIRS) $(CONTIKI)}
|
||||
|
||||
### Check for a git repo and pass version if found
|
||||
### git.exe in Windows cmd shells may require no stderr redirection
|
||||
ifndef RELSTR
|
||||
RELSTR:=${shell git --git-dir ${CONTIKI}/.git describe --tags --always --dirty}
|
||||
RELSTR:=${shell git --git-dir ${CONTIKI}/.git --work-tree ${CONTIKI} describe \
|
||||
--tags --always --dirty}
|
||||
endif
|
||||
|
||||
ifneq ($(RELSTR),)
|
||||
|
@ -237,26 +291,26 @@ sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
|||
rm -f $(@:.o=.$$$$)
|
||||
endef
|
||||
|
||||
clean:
|
||||
-rm -f *~ *core core *.srec \
|
||||
*.lst *.map \
|
||||
*.cprg *.bin *.data contiki*.a *.firmware core-labels.S *.ihex *.ini \
|
||||
*.ce *.co
|
||||
rm -rf $(CLEAN)
|
||||
-rm -rf $(OBJECTDIR)
|
||||
### Harmonize filename of a .map file, if the platform's build system wants
|
||||
### to create one
|
||||
CONTIKI_NG_PROJECT_MAP = $(addsuffix -$(TARGET).map, $(basename $@))
|
||||
|
||||
distclean: clean
|
||||
-rm -f ${addsuffix .$(TARGET),$(CONTIKI_PROJECT)}
|
||||
.PHONY: clean distclean usage help targets boards savetarget savedefines viewconf
|
||||
|
||||
clean:
|
||||
-rm -f *.d *.e *.o $(CONTIKI_NG_TARGET_LIB) $(CLEAN)
|
||||
-rm -rf $(OBJECTDIR)
|
||||
-rm -f $(addsuffix -$(TARGET).map, $(CONTIKI_PROJECT))
|
||||
-rm -f $(addsuffix .$(TARGET), $(CONTIKI_PROJECT))
|
||||
|
||||
distclean:
|
||||
@for TARG in `ls $(CONTIKI)/arch/platform $(TARGETDIRS)`; do \
|
||||
echo make $$TARG clean; \
|
||||
make TARGET=$$TARG clean; \
|
||||
done
|
||||
|
||||
-include $(CONTIKI)/arch/platform/$(TARGET)/Makefile.customrules-$(TARGET)
|
||||
|
||||
ifndef CUSTOM_RULE_C_TO_CE
|
||||
%.ce: %.c
|
||||
$(TRACE_CC)
|
||||
$(Q)$(CC) $(CFLAGS) -DAUTOSTART_ENABLE -c $< -o $@
|
||||
$(STRIP) --strip-unneeded -g -x $@
|
||||
endif
|
||||
|
||||
ifndef CUSTOM_RULE_C_TO_OBJECTDIR_O
|
||||
$(OBJECTDIR)/%.o: %.c | $(OBJECTDIR)
|
||||
$(TRACE_CC)
|
||||
|
@ -268,6 +322,9 @@ ifndef CUSTOM_RULE_S_TO_OBJECTDIR_O
|
|||
$(OBJECTDIR)/%.o: %.S | $(OBJECTDIR)
|
||||
$(TRACE_AS)
|
||||
$(Q)$(AS) $(ASFLAGS) -o $@ $<
|
||||
$(OBJECTDIR)/%.o: %.s | $(OBJECTDIR)
|
||||
$(TRACE_AS)
|
||||
$(Q)$(AS) $(ASFLAGS) -o $@ $<
|
||||
endif
|
||||
|
||||
ifndef CUSTOM_RULE_C_TO_OBJECTDIR_S
|
||||
|
@ -300,18 +357,12 @@ ifndef CUSTOM_RULE_C_TO_E
|
|||
$(Q)$(CC) $(CFLAGS) -E $< -o $@
|
||||
endif
|
||||
|
||||
ifndef CUSTOM_RULE_C_TO_CO
|
||||
%.co: %.c
|
||||
$(TRACE_CC)
|
||||
$(Q)$(CC) $(CFLAGS) -DAUTOSTART_ENABLE -c $< -o $@
|
||||
endif
|
||||
|
||||
ifndef AROPTS
|
||||
AROPTS = rcf
|
||||
endif
|
||||
|
||||
ifndef CUSTOM_RULE_ALLOBJS_TO_TARGETLIB
|
||||
contiki-$(TARGET).a: $(CONTIKI_OBJECTFILES)
|
||||
$(CONTIKI_NG_TARGET_LIB): $(CONTIKI_OBJECTFILES)
|
||||
$(TRACE_AR)
|
||||
$(Q)$(AR) $(AROPTS) $@ $^
|
||||
endif
|
||||
|
@ -321,7 +372,7 @@ ifndef LD
|
|||
endif
|
||||
|
||||
ifndef CUSTOM_RULE_LINK
|
||||
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a
|
||||
%.$(TARGET): %.o $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) $(CONTIKI_NG_TARGET_LIB)
|
||||
$(TRACE_LD)
|
||||
$(Q)$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} \
|
||||
${filter %.a,$^} $(TARGET_LIBFILES) -o $@
|
||||
|
@ -334,7 +385,25 @@ endif
|
|||
$(NM) -S -td --size-sort $< | grep -i " [t] " | cut -d' ' -f2,4
|
||||
|
||||
usage:
|
||||
@echo "make MAKETARGETS... [TARGET=(TARGET)] [BOARD=(BOARD)] [savetarget] [targets]"
|
||||
@echo "Usage:"
|
||||
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [DEFINES=(DEFINES)] [target]"
|
||||
@echo ""
|
||||
@echo "Typical usage:"
|
||||
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [all]"
|
||||
@echo ""
|
||||
@echo " Will build Contiki-NG firmware(s) from the current example dir"
|
||||
@echo " for platform TARGET, board BOARD."
|
||||
@echo ""
|
||||
@echo "Miscellaneous targets:"
|
||||
@echo " targets Prints list of supported platforms"
|
||||
@echo " boards Prints a list of supported boards for TARGET"
|
||||
@echo " savegtarget Saves TARGET and BOARD for future invocations of make"
|
||||
@echo " savedefines Saves DEFINES for future invocations of make"
|
||||
@echo " clean Removes all compiled files for TARGET"
|
||||
@echo " distclean Removes all compiled files for all TARGETs"
|
||||
@echo " viewconf Prints Contiki-NG build configuration for TARGET"
|
||||
|
||||
help: usage
|
||||
|
||||
targets:
|
||||
@ls $(CONTIKI)/arch/platform $(TARGETDIRS)
|
||||
|
@ -366,6 +435,9 @@ viewconf:
|
|||
@echo "##### \"MAKE_MAC\": ______________________________ $(MAKE_MAC)"
|
||||
@echo "##### \"MAKE_NET\": ______________________________ $(MAKE_NET)"
|
||||
@echo "##### \"MAKE_ROUTING\": __________________________ $(MAKE_ROUTING)"
|
||||
ifdef MAKE_COAP_DTLS_KEYSTORE
|
||||
@echo "##### \"MAKE_COAP_DTLS_KEYSTORE\": _______________ $(MAKE_COAP_DTLS_KEYSTORE)"
|
||||
endif
|
||||
@echo "----------------- C variables: -----------------"
|
||||
$(Q)$(CC) $(CFLAGS) -E $(CONTIKI)/tools/viewconf.c | grep \#\#\#\#\#
|
||||
@echo "------------------------------------------------"
|
||||
|
@ -384,8 +456,15 @@ viewconf:
|
|||
# the match-anything rule below instead.
|
||||
%: %.c
|
||||
|
||||
ifeq ($(PLATFORM_ACTION),skip)
|
||||
# Skip this target.
|
||||
$(CONTIKI_PROJECT):
|
||||
@echo "Skipping $@: not for the '$(TARGET)/$(BOARD)' platform!"
|
||||
else
|
||||
# Build this target.
|
||||
# Match-anything pattern rule to allow the project makefiles to
|
||||
# abstract from the actual binary name. It needs to contain some
|
||||
# command in order to be a rule, not just a prerequisite.
|
||||
%: %.$(TARGET)
|
||||
@
|
||||
endif
|
||||
|
|
22
README.md
22
README.md
|
@ -1,11 +1,25 @@
|
|||
# Contiki-NG: the Next Generation Contiki
|
||||
# Contiki-NG: The OS for Next Generation IoT Devices
|
||||
|
||||
[![Build Status](https://travis-ci.org/contiki-ng/contiki-ng.svg?branch=master)](https://travis-ci.org/contiki-ng/contiki-ng/branches)
|
||||
[![license](https://img.shields.io/badge/license-3--clause%20bsd-brightgreen.svg)](https://github.com/contiki-ng/contiki-ng/blob/master/LICENSE.md)
|
||||
[![Latest release](https://img.shields.io/github/release/contiki-ng/contiki-ng.svg)](https://github.com/contiki-ng/contiki-ng/releases/latest)
|
||||
[![GitHub Release Date](https://img.shields.io/github/release-date/contiki-ng/contiki-ng.svg)](https://github.com/contiki-ng/contiki-ng/releases/latest)
|
||||
[![Last commit](https://img.shields.io/github/last-commit/contiki-ng/contiki-ng.svg)](https://github.com/contiki-ng/contiki-ng/commit/HEAD)
|
||||
|
||||
Contiki-NG is an open-source, cross-platform operating system for Next-Generation IoT devices. It focuses on dependable (secure and reliable) low-power communication and standard protocols, such as IPv6/6LoWPAN, 6TiSCH, RPL, and CoAP. Contiki-NG comes with extensive documentation, tutorials, a roadmap, release cycle, and well-defined development flow for smooth integration of community contributions.
|
||||
|
||||
Unless excplicitly stated otherwise, Contiki-NG sources are distributed under
|
||||
the terms of the [3-clause BSD license](LICENSE.md).
|
||||
|
||||
Contiki-NG started as a fork of the Contiki OS and retains some of its original features.
|
||||
|
||||
Find out more:
|
||||
|
||||
Contiki-NG is a fork of Contiki, with focus on next generation IoT protocols and platforms.
|
||||
Important links:
|
||||
* GitHub repository: https://github.com/contiki-ng/contiki-ng
|
||||
* Documentation: https://github.com/contiki-ng/contiki-ng/wiki
|
||||
* Web site: http://contiki-ng.org
|
||||
|
||||
Engage with the community:
|
||||
|
||||
* Gitter: https://gitter.im/contiki-ng
|
||||
* Twitter: https://twitter.com/contiki_ng
|
||||
* Web site: http://contiki-ng.org
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
CC = arm-none-eabi-gcc
|
||||
CPP = arm-none-eabi-cpp
|
||||
LD = arm-none-eabi-gcc
|
||||
AR = arm-none-eabi-ar
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
OBJDUMP = arm-none-eabi-objdump
|
||||
NM = arm-none-eabi-nm
|
||||
SIZE = arm-none-eabi-size
|
||||
SREC_CAT = srec_cat
|
||||
|
||||
CFLAGS += -mthumb -mabi=aapcs -mlittle-endian
|
||||
CFLAGS += -Werror -Wall
|
||||
CFLAGS += -std=c99
|
||||
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
|
||||
CFLAGS += -fshort-enums -fomit-frame-pointer -fno-builtin
|
||||
|
||||
LDFLAGS += -mthumb -mlittle-endian
|
||||
|
||||
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
|
||||
|
||||
### Are we building with code size optimisations?
|
||||
SMALL ?= 1
|
||||
ifeq ($(SMALL),1)
|
||||
CFLAGS += -Os
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
|
||||
### Use CMSIS and the existing dbg-io from arch/cpu/arm/common
|
||||
CONTIKI_ARM_DIRS += . common/dbg-io
|
||||
CONTIKI_CPU_DIRS += $(addprefix ../arm/, $(CONTIKI_ARM_DIRS))
|
||||
|
||||
### CPU-dependent cleanup files
|
||||
CLEAN += *.elf *.bin *.lst *.hex *.i16hex
|
||||
|
||||
### Don't treat the following files as intermediate
|
||||
.PRECIOUS: %.elf %.hex %.bin
|
||||
|
||||
%.i16hex: %.elf
|
||||
$(OBJCOPY) -O ihex $< $@
|
||||
|
||||
%.hex: %.i16hex
|
||||
$(SREC_CAT) $< -intel -o $@ -intel
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $(OBJCOPY_FLAGS) $< $@
|
||||
|
||||
%.lst: %.elf
|
||||
$(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@
|
||||
|
||||
### We don't really need the .hex and .bin for the .$(TARGET) but let's make
|
||||
### sure they get built
|
||||
%.$(TARGET): %.elf %.hex %.bin
|
||||
cp $< $@
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* 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
|
||||
|
@ -29,43 +30,56 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-gpio-interrupts CC13xx/CC26xx GPIO interrupt handling
|
||||
*
|
||||
* The CC13xx/CC26xx GPIO interrupt handler and an API which can be used by
|
||||
* other parts of the code when they wish to be notified of a GPIO interrupt
|
||||
*
|
||||
* \addtogroup arm
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC13xx/CC26xx GPIO interrupt management
|
||||
* Compiler and data type definitions for all ARM-based CPUs
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef GPIO_INTERRUPT_H_
|
||||
#define GPIO_INTERRUPT_H_
|
||||
#ifndef ARM_DEF_
|
||||
#define ARM_DEF_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef void (*gpio_interrupt_handler_t)(uint8_t ioid);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Initialise the GPIO interrupt handling module */
|
||||
void gpio_interrupt_init(void);
|
||||
|
||||
/**
|
||||
* \brief Register a GPIO interrupt handler
|
||||
* \param f Pointer to a handler to be called when an interrupt is raised on
|
||||
* ioid
|
||||
* \param ioid Associate \a f with this ioid. \e ioid must be specified with
|
||||
* its numeric representation (0, 1, .. 31). Defines for these
|
||||
* numeric representations are IOID_x
|
||||
* \name Macros and typedefs
|
||||
*
|
||||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
void gpio_interrupt_register_handler(uint8_t ioid, gpio_interrupt_handler_t f);
|
||||
#define CLOCK_CONF_SECOND 128
|
||||
|
||||
#endif /* GPIO_INTERRUPT_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
/* Clock (time) comparison macro */
|
||||
#define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0)
|
||||
|
||||
/* Platform typedefs */
|
||||
typedef uint32_t clock_time_t;
|
||||
typedef uint32_t uip_stats_t;
|
||||
|
||||
typedef uint32_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b)))
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* The stdio.h that ships with the arm-gcc toolchain does this:
|
||||
*
|
||||
* int _EXFUN(putchar, (int));
|
||||
* [...]
|
||||
* #define putchar(x) putc(x, stdout)
|
||||
*
|
||||
* This causes us a lot of trouble: For platforms using this toolchain, every
|
||||
* time we use putchar we need to first #undef putchar. What we do here is to
|
||||
* #undef putchar across the board. The resulting code will cause the linker
|
||||
* to search for a symbol named putchar and this allows us to use the
|
||||
* implementation under os/lib/dbg-io.
|
||||
*
|
||||
* This will fail if stdio.h is included before contiki.h, but it is common
|
||||
* practice to include contiki.h first
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#undef putchar
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* ARM_DEF_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* \defgroup cmsis CMSIS (Cortex Microcontroller Software Interface Standard)
|
||||
* \ingroup arm
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup aducrf101 ADUCRF101
|
||||
* \ingroup arm
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup at91sam7s AT91SAM7S
|
||||
* \ingroup arm
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup stm32f103 STM32F103
|
||||
* \ingroup arm
|
||||
*/
|
|
@ -1,7 +1,6 @@
|
|||
#include <efs-sdcard.h>
|
||||
#include <sys/process.h>
|
||||
#include <cfs/cfs.h>
|
||||
#include <debug-uart.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <debug-uart.h>
|
||||
#include <string.h>
|
||||
#include <strformat.h>
|
||||
|
||||
static StrFormatResult
|
||||
write_str(void *user_data, const char *data, unsigned int len)
|
||||
{
|
||||
if (len > 0) dbg_send_bytes((unsigned char*)data, len);
|
||||
return STRFORMAT_OK;
|
||||
}
|
||||
|
||||
|
||||
static StrFormatContext ctxt =
|
||||
{
|
||||
write_str,
|
||||
NULL
|
||||
};
|
||||
int
|
||||
printf(const char *fmt, ...)
|
||||
{
|
||||
int res;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
res = format_str_v(&ctxt, fmt, ap);
|
||||
va_end(ap);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <debug-uart.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef putchar
|
||||
#undef putc
|
||||
|
||||
int
|
||||
putchar(int c)
|
||||
{
|
||||
dbg_putchar(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
putc(int c, FILE *f)
|
||||
{
|
||||
dbg_putchar(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
__sp(struct _reent *_ptr, int c, FILE *_p) {
|
||||
dbg_putchar(c);
|
||||
return c;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <debug-uart.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
puts(const char *str)
|
||||
{
|
||||
dbg_send_bytes((unsigned char*)str, strlen(str));
|
||||
dbg_putchar('\n');
|
||||
return 0;
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <strformat.h>
|
||||
#include <string.h>
|
||||
|
||||
struct FmtBuffer
|
||||
{
|
||||
char *pos;
|
||||
size_t left;
|
||||
};
|
||||
|
||||
static StrFormatResult
|
||||
buffer_str(void *user_data, const char *data, unsigned int len)
|
||||
{
|
||||
struct FmtBuffer *buffer = (struct FmtBuffer*)user_data;
|
||||
if (len >= buffer->left) {
|
||||
len = buffer->left;
|
||||
len--;
|
||||
}
|
||||
|
||||
memcpy(buffer->pos, data, len);
|
||||
buffer->pos += len;
|
||||
buffer->left -= len;
|
||||
return STRFORMAT_OK;
|
||||
}
|
||||
|
||||
int snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
int res;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
res = vsnprintf(str, size, format, ap);
|
||||
va_end(ap);
|
||||
return res;
|
||||
}
|
||||
|
||||
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
struct FmtBuffer buffer;
|
||||
StrFormatContext ctxt;
|
||||
int res;
|
||||
ctxt.write_str = buffer_str;
|
||||
ctxt.user_data = &buffer;
|
||||
buffer.pos = str;
|
||||
buffer.left = size;
|
||||
res = format_str_v(&ctxt, format, ap);
|
||||
*buffer.pos = '\0';
|
||||
return res;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <strformat.h>
|
||||
#include <string.h>
|
||||
|
||||
static StrFormatResult
|
||||
buffer_str(void *user_data, const char *data, unsigned int len)
|
||||
{
|
||||
memcpy(*(char**)user_data, data, len);
|
||||
(*(char**)user_data) += len;
|
||||
return STRFORMAT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
sprintf(char *str, const char *format, ...)
|
||||
{
|
||||
StrFormatContext ctxt;
|
||||
int res;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
ctxt.write_str = buffer_str;
|
||||
ctxt.user_data = &str;
|
||||
res = format_str_v(&ctxt, format, ap);
|
||||
*str = '\0';
|
||||
va_end(ap);
|
||||
return res;
|
||||
}
|
|
@ -1,617 +0,0 @@
|
|||
#include <strformat.h>
|
||||
|
||||
#define HAVE_DOUBLE
|
||||
|
||||
#define HAVE_LONGLONG
|
||||
#ifndef LARGEST_SIGNED
|
||||
#ifdef HAVE_LONGLONG
|
||||
#define LARGEST_SIGNED long long int
|
||||
#else
|
||||
#define LARGEST_UNSIGNED long int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LARGEST_UNSIGNED
|
||||
#ifdef HAVE_LONGLONG
|
||||
#define LARGEST_UNSIGNED unsigned long long int
|
||||
#else
|
||||
#define LARGEST_UNSIGNED unsigned long int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef POINTER_INT
|
||||
#define POINTER_INT unsigned long
|
||||
#endif
|
||||
|
||||
typedef unsigned int FormatFlags;
|
||||
|
||||
#define MAKE_MASK(shift,size) (((1 << size) - 1) << (shift))
|
||||
|
||||
#define JUSTIFY_SHIFT 0
|
||||
#define JUSTIFY_SIZE 1
|
||||
#define JUSTIFY_RIGHT 0x0000
|
||||
#define JUSTIFY_LEFT 0x0001
|
||||
#define JUSTIFY_MASK MAKE_MASK(JUSTIFY_SHIFT,JUSTIFY_SIZE)
|
||||
|
||||
|
||||
/* How a positive number is prefixed */
|
||||
#define POSITIVE_SHIFT (JUSTIFY_SHIFT + JUSTIFY_SIZE)
|
||||
#define POSITIVE_NONE (0x0000 << POSITIVE_SHIFT)
|
||||
#define POSITIVE_SPACE (0x0001 << POSITIVE_SHIFT)
|
||||
#define POSITIVE_PLUS (0x0003 << POSITIVE_SHIFT)
|
||||
#define POSITIVE_MASK MAKE_MASK(POSITIVE_SHIFT, POSITIVE_SIZE)
|
||||
|
||||
#define POSITIVE_SIZE 2
|
||||
|
||||
#define ALTERNATE_FORM_SHIFT (POSITIVE_SHIFT + POSITIVE_SIZE)
|
||||
#define ALTERNATE_FORM_SIZE 1
|
||||
#define ALTERNATE_FORM (0x0001 << ALTERNATE_FORM_SHIFT)
|
||||
|
||||
|
||||
#define PAD_SHIFT (ALTERNATE_FORM_SHIFT + ALTERNATE_FORM_SIZE)
|
||||
#define PAD_SIZE 1
|
||||
#define PAD_SPACE (0x0000 << PAD_SHIFT)
|
||||
#define PAD_ZERO (0x0001 << PAD_SHIFT)
|
||||
|
||||
#define SIZE_SHIFT (PAD_SHIFT + PAD_SIZE)
|
||||
#define SIZE_SIZE 3
|
||||
#define SIZE_CHAR (0x0001 << SIZE_SHIFT)
|
||||
#define SIZE_SHORT (0x0002 << SIZE_SHIFT)
|
||||
#define SIZE_INT (0x0000 << SIZE_SHIFT)
|
||||
#define SIZE_LONG (0x0003 << SIZE_SHIFT)
|
||||
#define SIZE_LONGLONG (0x0004 << SIZE_SHIFT)
|
||||
#define SIZE_MASK MAKE_MASK(SIZE_SHIFT,SIZE_SIZE)
|
||||
|
||||
#define CONV_SHIFT (SIZE_SHIFT + SIZE_SIZE)
|
||||
#define CONV_SIZE 3
|
||||
#define CONV_INTEGER (0x0001 << CONV_SHIFT)
|
||||
#define CONV_FLOAT (0x0002 << CONV_SHIFT)
|
||||
#define CONV_POINTER (0x0003 << CONV_SHIFT)
|
||||
#define CONV_STRING (0x0004 << CONV_SHIFT)
|
||||
#define CONV_CHAR (0x0005 << CONV_SHIFT)
|
||||
#define CONV_PERCENT (0x0006 << CONV_SHIFT)
|
||||
#define CONV_WRITTEN (0x0007 << CONV_SHIFT)
|
||||
#define CONV_MASK MAKE_MASK(CONV_SHIFT, CONV_SIZE)
|
||||
|
||||
#define RADIX_SHIFT (CONV_SHIFT + CONV_SIZE)
|
||||
#define RADIX_SIZE 2
|
||||
#define RADIX_DECIMAL (0x0001 << RADIX_SHIFT)
|
||||
#define RADIX_OCTAL (0x0002 << RADIX_SHIFT)
|
||||
#define RADIX_HEX (0x0003 << RADIX_SHIFT)
|
||||
#define RADIX_MASK MAKE_MASK(RADIX_SHIFT,RADIX_SIZE)
|
||||
|
||||
#define SIGNED_SHIFT (RADIX_SHIFT + RADIX_SIZE)
|
||||
#define SIGNED_SIZE 1
|
||||
#define SIGNED_NO (0x0000 << SIGNED_SHIFT)
|
||||
#define SIGNED_YES (0x0001 << SIGNED_SHIFT)
|
||||
#define SIGNED_MASK MAKE_MASK(SIGNED_SHIFT,SIGNED_SIZE)
|
||||
|
||||
#define CAPS_SHIFT (SIGNED_SHIFT + SIGNED_SIZE)
|
||||
#define CAPS_SIZE 1
|
||||
#define CAPS_NO (0x0000 << CAPS_SHIFT)
|
||||
#define CAPS_YES (0x0001 << CAPS_SHIFT)
|
||||
#define CAPS_MASK MAKE_MASK(CAPS_SHIFT,CAPS_SIZE)
|
||||
|
||||
#define FLOAT_SHIFT (CAPS_SHIFT + CAPS_SIZE)
|
||||
#define FLOAT_SIZE 2
|
||||
#define FLOAT_NORMAL (0x0000 << FLOAT_SHIFT)
|
||||
#define FLOAT_EXPONENT (0x0001 << FLOAT_SHIFT)
|
||||
#define FLOAT_DEPENDANT (0x0002 << FLOAT_SHIFT)
|
||||
#define FLOAT_HEX (0x0003 << FLOAT_SHIFT)
|
||||
#define FLOAT_MASK MAKE_MASK(FLOAT_SHIFT, FLOAT_SIZE)
|
||||
|
||||
static FormatFlags
|
||||
parse_flags(const char **posp)
|
||||
{
|
||||
FormatFlags flags = 0;
|
||||
const char *pos = *posp;
|
||||
while (1) {
|
||||
switch(*pos) {
|
||||
case '-':
|
||||
flags |= JUSTIFY_LEFT;
|
||||
break;
|
||||
case '+':
|
||||
flags |= POSITIVE_PLUS;
|
||||
break;
|
||||
case ' ':
|
||||
flags |= POSITIVE_SPACE;
|
||||
break;
|
||||
case '#':
|
||||
flags |= ALTERNATE_FORM;
|
||||
break;
|
||||
case '0':
|
||||
flags |= PAD_ZERO;
|
||||
break;
|
||||
default:
|
||||
*posp = pos;
|
||||
return flags;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
parse_uint(const char **posp)
|
||||
{
|
||||
unsigned v = 0;
|
||||
const char *pos = *posp;
|
||||
char ch;
|
||||
while((ch = *pos) >= '0' && ch <= '9') {
|
||||
v = v * 10 + (ch - '0');
|
||||
pos++;
|
||||
}
|
||||
*posp = pos;
|
||||
return v;
|
||||
}
|
||||
|
||||
#define MAXCHARS_HEX ((sizeof(LARGEST_UNSIGNED) * 8) / 4 )
|
||||
|
||||
/* Largest number of characters needed for converting an unsigned integer.
|
||||
*/
|
||||
#define MAXCHARS ((sizeof(LARGEST_UNSIGNED) * 8 + 2) / 3 )
|
||||
|
||||
static unsigned int
|
||||
output_uint_decimal(char **posp, LARGEST_UNSIGNED v)
|
||||
{
|
||||
unsigned int len;
|
||||
char *pos = *posp;
|
||||
while (v > 0) {
|
||||
*--pos = (v % 10) + '0';
|
||||
v /= 10;
|
||||
}
|
||||
len = *posp - pos;
|
||||
*posp = pos;
|
||||
return len;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
output_uint_hex(char **posp, LARGEST_UNSIGNED v, unsigned int flags)
|
||||
{
|
||||
unsigned int len;
|
||||
const char *hex = (flags & CAPS_YES) ?"0123456789ABCDEF":"0123456789abcdef";
|
||||
char *pos = *posp;
|
||||
while (v > 0) {
|
||||
*--pos = hex[(v % 16)];
|
||||
v /= 16;
|
||||
}
|
||||
len = *posp - pos;
|
||||
*posp = pos;
|
||||
return len;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
output_uint_octal(char **posp, LARGEST_UNSIGNED v)
|
||||
{
|
||||
unsigned int len;
|
||||
char *pos = *posp;
|
||||
while (v > 0) {
|
||||
*--pos = (v % 8) + '0';
|
||||
v /= 8;
|
||||
}
|
||||
len = *posp - pos;
|
||||
*posp = pos;
|
||||
return len;
|
||||
}
|
||||
|
||||
static StrFormatResult
|
||||
fill_space(const StrFormatContext *ctxt, unsigned int len)
|
||||
{
|
||||
StrFormatResult res;
|
||||
static const char buffer[16] = " ";
|
||||
while(len > 16) {
|
||||
res = ctxt->write_str(ctxt->user_data, buffer, 16);
|
||||
if (res != STRFORMAT_OK) return res;
|
||||
len -= 16;
|
||||
}
|
||||
if (len == 0) return STRFORMAT_OK;
|
||||
return ctxt->write_str(ctxt->user_data, buffer, len);
|
||||
}
|
||||
|
||||
static StrFormatResult
|
||||
fill_zero(const StrFormatContext *ctxt, unsigned int len)
|
||||
{
|
||||
StrFormatResult res;
|
||||
static const char buffer[16] = "0000000000000000";
|
||||
while(len > 16) {
|
||||
res = ctxt->write_str(ctxt->user_data, buffer, 16);
|
||||
if (res != STRFORMAT_OK) return res;
|
||||
len -= 16;
|
||||
}
|
||||
if (len == 0) return STRFORMAT_OK;
|
||||
return ctxt->write_str(ctxt->user_data, buffer, len);
|
||||
}
|
||||
|
||||
#define CHECKCB(res) {if ((res) != STRFORMAT_OK) {va_end(ap); return -1;}}
|
||||
|
||||
int
|
||||
format_str(const StrFormatContext *ctxt, const char *format, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
ret = format_str_v(ctxt, format, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
format_str_v(const StrFormatContext *ctxt, const char *format, va_list ap)
|
||||
{
|
||||
unsigned int written = 0;
|
||||
const char *pos = format;
|
||||
while(*pos != '\0') {
|
||||
FormatFlags flags;
|
||||
unsigned int minwidth = 0;
|
||||
int precision = -1; /* Negative means no precision */
|
||||
char ch;
|
||||
const char *start = pos;
|
||||
while( (ch = *pos) != '\0' && ch != '%') pos++;
|
||||
if (pos != start) {
|
||||
CHECKCB(ctxt->write_str(ctxt->user_data, start, pos - start));
|
||||
written += pos - start;
|
||||
}
|
||||
if (*pos == '\0') {
|
||||
va_end(ap);
|
||||
return written;
|
||||
}
|
||||
pos++;
|
||||
if (*pos == '\0') {
|
||||
va_end(ap);
|
||||
return written;
|
||||
}
|
||||
flags = parse_flags(&pos);
|
||||
|
||||
/* parse width */
|
||||
if (*pos >= '1' && *pos <= '9') {
|
||||
minwidth = parse_uint(&pos);
|
||||
} else if (*pos == '*') {
|
||||
int w = va_arg(ap,int);
|
||||
if (w < 0) {
|
||||
flags |= JUSTIFY_LEFT;
|
||||
minwidth = w;
|
||||
} else {
|
||||
minwidth = w;
|
||||
}
|
||||
pos ++;
|
||||
}
|
||||
|
||||
/* parse precision */
|
||||
if (*pos == '.') {
|
||||
pos++;
|
||||
if (*pos >= '0' && *pos <= '9') {
|
||||
precision = parse_uint(&pos);
|
||||
} else if (*pos == '*') {
|
||||
pos++;
|
||||
precision = va_arg(ap,int);
|
||||
}
|
||||
}
|
||||
if (*pos == 'l') {
|
||||
pos++;
|
||||
if (*pos == 'l') {
|
||||
flags |= SIZE_LONGLONG;
|
||||
pos++;
|
||||
} else {
|
||||
flags |= SIZE_LONG;
|
||||
}
|
||||
} else if (*pos == 'h') {
|
||||
pos++;
|
||||
if (*pos == 'h') {
|
||||
flags |= SIZE_CHAR;
|
||||
pos++;
|
||||
} else {
|
||||
flags |= SIZE_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse conversion specifier */
|
||||
switch(*pos) {
|
||||
case 'd':
|
||||
case 'i':
|
||||
flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_YES;
|
||||
break;
|
||||
case 'u':
|
||||
flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_NO;
|
||||
break;
|
||||
case 'o':
|
||||
flags |= CONV_INTEGER | RADIX_OCTAL | SIGNED_NO;
|
||||
break;
|
||||
case 'x':
|
||||
flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO;
|
||||
break;
|
||||
case 'X':
|
||||
flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO | CAPS_YES;
|
||||
break;
|
||||
#ifdef HAVE_DOUBLE
|
||||
case 'f':
|
||||
flags |= CONV_FLOAT | FLOAT_NORMAL;
|
||||
break;
|
||||
case 'F':
|
||||
flags |= CONV_FLOAT | FLOAT_NORMAL | CAPS_YES;
|
||||
break;
|
||||
case 'e':
|
||||
flags |= CONV_FLOAT | FLOAT_EXPONENT;
|
||||
break;
|
||||
case 'E':
|
||||
flags |= CONV_FLOAT | FLOAT_EXPONENT | CAPS_YES;
|
||||
break;
|
||||
case 'g':
|
||||
flags |= CONV_FLOAT | FLOAT_DEPENDANT;
|
||||
break;
|
||||
case 'G':
|
||||
flags |= CONV_FLOAT | FLOAT_DEPENDANT | CAPS_YES;
|
||||
break;
|
||||
case 'a':
|
||||
flags |= CONV_FLOAT | FLOAT_HEX;
|
||||
break;
|
||||
case 'A':
|
||||
flags |= CONV_FLOAT | FLOAT_HEX | CAPS_YES;
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
flags |= CONV_CHAR;
|
||||
break;
|
||||
case 's':
|
||||
flags |= CONV_STRING;
|
||||
break;
|
||||
case 'p':
|
||||
flags |= CONV_POINTER;
|
||||
break;
|
||||
case 'n':
|
||||
flags |= CONV_WRITTEN;
|
||||
break;
|
||||
case '%':
|
||||
flags |= CONV_PERCENT;
|
||||
break;
|
||||
case '\0':
|
||||
va_end(ap);
|
||||
return written;
|
||||
}
|
||||
pos++;
|
||||
switch(flags & CONV_MASK) {
|
||||
case CONV_PERCENT:
|
||||
CHECKCB(ctxt->write_str(ctxt->user_data, "%", 1));
|
||||
written++;
|
||||
break;
|
||||
case CONV_INTEGER:
|
||||
{
|
||||
/* unsigned integers */
|
||||
char *prefix = 0; /* sign, "0x" or "0X" */
|
||||
unsigned int prefix_len = 0;
|
||||
char buffer[MAXCHARS];
|
||||
char *conv_pos = buffer + MAXCHARS;
|
||||
unsigned int conv_len = 0;
|
||||
unsigned int width = 0;
|
||||
unsigned int precision_fill;
|
||||
unsigned int field_fill;
|
||||
LARGEST_UNSIGNED uvalue = 0;
|
||||
int negative = 0;
|
||||
|
||||
if (precision < 0) precision = 1;
|
||||
else flags &= ~PAD_ZERO;
|
||||
|
||||
if (flags & SIGNED_YES) {
|
||||
/* signed integers */
|
||||
LARGEST_SIGNED value = 0;
|
||||
switch(flags & SIZE_MASK) {
|
||||
case SIZE_CHAR:
|
||||
value = (signed char)va_arg(ap, int);
|
||||
break;
|
||||
case SIZE_SHORT:
|
||||
value = (short)va_arg(ap, int);
|
||||
break;
|
||||
case SIZE_INT:
|
||||
value = va_arg(ap, int);
|
||||
break;
|
||||
#ifndef HAVE_LONGLONG
|
||||
case SIZE_LONGLONG: /* Treat long long the same as long */
|
||||
#endif
|
||||
case SIZE_LONG:
|
||||
value = va_arg(ap, long);
|
||||
break;
|
||||
#ifdef HAVE_LONGLONG
|
||||
case SIZE_LONGLONG:
|
||||
value = va_arg(ap, long long);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (value < 0) {
|
||||
uvalue = -value;
|
||||
negative = 1;
|
||||
} else {
|
||||
uvalue = value;
|
||||
}
|
||||
} else {
|
||||
|
||||
switch(flags & SIZE_MASK) {
|
||||
case SIZE_CHAR:
|
||||
uvalue = (unsigned char)va_arg(ap,unsigned int);
|
||||
break;
|
||||
case SIZE_SHORT:
|
||||
uvalue = (unsigned short)va_arg(ap,unsigned int);
|
||||
break;
|
||||
case SIZE_INT:
|
||||
uvalue = va_arg(ap,unsigned int);
|
||||
break;
|
||||
#ifndef HAVE_LONGLONG
|
||||
case SIZE_LONGLONG: /* Treat long long the same as long */
|
||||
#endif
|
||||
case SIZE_LONG:
|
||||
uvalue = va_arg(ap,unsigned long);
|
||||
break;
|
||||
#ifdef HAVE_LONGLONG
|
||||
case SIZE_LONGLONG:
|
||||
uvalue = va_arg(ap,unsigned long long);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
switch(flags & (RADIX_MASK)) {
|
||||
case RADIX_DECIMAL:
|
||||
conv_len = output_uint_decimal(&conv_pos,uvalue);
|
||||
break;
|
||||
case RADIX_OCTAL:
|
||||
conv_len = output_uint_octal(&conv_pos,uvalue);
|
||||
break;
|
||||
case RADIX_HEX:
|
||||
conv_len = output_uint_hex(&conv_pos,uvalue, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
width += conv_len;
|
||||
precision_fill = (precision > conv_len) ? precision - conv_len : 0;
|
||||
if ((flags & (RADIX_MASK | ALTERNATE_FORM))
|
||||
== (RADIX_OCTAL | ALTERNATE_FORM)) {
|
||||
if (precision_fill < 1) precision_fill = 1;
|
||||
}
|
||||
|
||||
width += precision_fill;
|
||||
|
||||
if ((flags & (RADIX_MASK | ALTERNATE_FORM))
|
||||
== (RADIX_HEX | ALTERNATE_FORM) && uvalue != 0) {
|
||||
prefix_len = 2;
|
||||
if (flags & CAPS_YES) {
|
||||
prefix = "0X";
|
||||
} else {
|
||||
prefix = "0x";
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & SIGNED_YES) {
|
||||
if (negative) {
|
||||
prefix = "-";
|
||||
prefix_len = 1;
|
||||
} else {
|
||||
switch(flags & POSITIVE_MASK) {
|
||||
case POSITIVE_SPACE:
|
||||
prefix = " ";
|
||||
prefix_len = 1;
|
||||
break;
|
||||
case POSITIVE_PLUS:
|
||||
prefix = "+";
|
||||
prefix_len = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width += prefix_len;
|
||||
|
||||
field_fill = (minwidth > width) ? minwidth - width : 0;
|
||||
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
|
||||
if (flags & PAD_ZERO) {
|
||||
precision_fill += field_fill;
|
||||
field_fill = 0; /* Do not double count padding */
|
||||
} else {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
}
|
||||
}
|
||||
|
||||
if (prefix_len > 0)
|
||||
CHECKCB(ctxt->write_str(ctxt->user_data, prefix, prefix_len));
|
||||
written += prefix_len;
|
||||
|
||||
CHECKCB(fill_zero(ctxt,precision_fill));
|
||||
written += precision_fill;
|
||||
|
||||
CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos,conv_len));
|
||||
written += conv_len;
|
||||
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
}
|
||||
written += field_fill;
|
||||
}
|
||||
break;
|
||||
case CONV_STRING:
|
||||
{
|
||||
unsigned int field_fill;
|
||||
unsigned int len;
|
||||
char *str = va_arg(ap,char *);
|
||||
if (str) {
|
||||
char *pos = str;
|
||||
while(*pos != '\0') pos++;
|
||||
len = pos - str;
|
||||
} else {
|
||||
str = "(null)";
|
||||
len = 6;
|
||||
}
|
||||
if (precision >= 0 && precision < len) len = precision;
|
||||
field_fill = (minwidth > len) ? minwidth - len : 0;
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
}
|
||||
CHECKCB(ctxt->write_str(ctxt->user_data, str,len));
|
||||
written += len;
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
}
|
||||
written += field_fill;
|
||||
}
|
||||
break;
|
||||
case CONV_POINTER:
|
||||
{
|
||||
LARGEST_UNSIGNED uvalue =
|
||||
(LARGEST_UNSIGNED)(POINTER_INT)va_arg(ap,void *);
|
||||
char buffer[MAXCHARS_HEX + 3];
|
||||
char *conv_pos = buffer + MAXCHARS_HEX+3;
|
||||
unsigned int conv_len;
|
||||
unsigned int field_fill;
|
||||
|
||||
conv_len = output_uint_hex(&conv_pos,uvalue,flags);
|
||||
if (conv_len == 0) {
|
||||
*--conv_pos = '0';
|
||||
conv_len++;
|
||||
}
|
||||
*--conv_pos = 'x';
|
||||
*--conv_pos = '0';
|
||||
*--conv_pos = '#';
|
||||
conv_len += 3;
|
||||
|
||||
field_fill = (minwidth > conv_len) ? minwidth - conv_len : 0;
|
||||
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
}
|
||||
|
||||
CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos,conv_len));
|
||||
written += conv_len;
|
||||
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
}
|
||||
written += field_fill;
|
||||
}
|
||||
break;
|
||||
case CONV_CHAR:
|
||||
{
|
||||
char ch = va_arg(ap,int);
|
||||
unsigned int field_fill = (minwidth > 1) ? minwidth - 1 : 0;
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
written += field_fill;
|
||||
}
|
||||
|
||||
CHECKCB(ctxt->write_str(ctxt->user_data, &ch, 1));
|
||||
written++;
|
||||
|
||||
if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
|
||||
CHECKCB(fill_space(ctxt,field_fill));
|
||||
}
|
||||
written+= field_fill;
|
||||
}
|
||||
break;
|
||||
case CONV_WRITTEN:
|
||||
{
|
||||
int *p = va_arg(ap,int*);
|
||||
*p = written;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef STRFORMAT_H_
|
||||
#define STRFORMAT_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define STRFORMAT_OK 0
|
||||
#define STRFORMAT_FAILED 1
|
||||
typedef unsigned int StrFormatResult;
|
||||
|
||||
/* The data argument may only be considered valid during the function call */
|
||||
typedef StrFormatResult (*StrFormatWrite)(void *user_data, const char *data, unsigned int len);
|
||||
|
||||
typedef struct _StrFormatContext
|
||||
{
|
||||
StrFormatWrite write_str;
|
||||
void *user_data;
|
||||
} StrFormatContext;
|
||||
|
||||
int format_str(const StrFormatContext *ctxt, const char *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2,3)));
|
||||
|
||||
int
|
||||
format_str_v(const StrFormatContext *ctxt, const char *format, va_list ap);
|
||||
|
||||
#endif /* STRFORMAT_H_ */
|
|
@ -1,281 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup arm-cm-mtarch
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implmentation of the ARM Cortex-M support for Contiki multi-threading.
|
||||
*/
|
||||
#include CMSIS_DEV_HDR
|
||||
#include "sys/mt.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define EXC_RETURN_PROCESS_THREAD_BASIC_FRAME 0xfffffffd
|
||||
|
||||
/* Check whether EXC_RETURN[3:0] in LR indicates a preempted process thread. */
|
||||
#if __ARM_ARCH == 7
|
||||
#define PREEMPTED_PROCESS_THREAD() \
|
||||
"and r0, lr, #0xf\n\t" \
|
||||
"cmp r0, #0xd\n\t"
|
||||
#elif __ARM_ARCH == 6
|
||||
#define PREEMPTED_PROCESS_THREAD() \
|
||||
"mov r0, lr\n\t" \
|
||||
"movs r1, #0xf\n\t" \
|
||||
"and r0, r1\n\t" \
|
||||
"cmp r0, #0xd\n\t"
|
||||
#else
|
||||
#error Unsupported ARM architecture
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief SVCall system handler
|
||||
*
|
||||
* This exception handler executes the action requested by the corresponding
|
||||
* \c svc instruction, which is a task switch from the main Contiki thread to an
|
||||
* mt thread or the other way around.
|
||||
*/
|
||||
__attribute__ ((__naked__))
|
||||
void
|
||||
svcall_handler(void)
|
||||
{
|
||||
/*
|
||||
* Decide whether to switch to the main thread or to a process thread,
|
||||
* depending on the type of the thread preempted by SVCall.
|
||||
*/
|
||||
__asm__ (PREEMPTED_PROCESS_THREAD()
|
||||
#if __ARM_ARCH == 7
|
||||
"it eq\n\t"
|
||||
#endif
|
||||
"beq switch_to_main_thread\n\t"
|
||||
|
||||
/*
|
||||
* - Retrieve from the main stack the PSP passed to SVCall through R0. Note
|
||||
* that it cannot be retrieved directly from R0 on exception entry because
|
||||
* this register may have been overwritten by other exceptions on SVCall
|
||||
* entry.
|
||||
* - Save the main thread context to the main stack.
|
||||
* - Restore the process thread context from the process stack.
|
||||
* - Return to Thread mode, resuming the process thread.
|
||||
*/
|
||||
#if __ARM_ARCH == 7
|
||||
"ldr r0, [sp]\n\t"
|
||||
"push {r4-r11, lr}\n\t"
|
||||
"add r1, r0, #9 * 4\n\t"
|
||||
"msr psp, r1\n\t"
|
||||
"ldmia r0, {r4-r11, pc}");
|
||||
#elif __ARM_ARCH == 6
|
||||
"mov r0, r8\n\t"
|
||||
"mov r1, r9\n\t"
|
||||
"mov r2, r10\n\t"
|
||||
"mov r3, r11\n\t"
|
||||
"push {r0-r7, lr}\n\t"
|
||||
"ldr r0, [sp, #9 * 4]\n\t"
|
||||
"ldmia r0!, {r4-r7}\n\t"
|
||||
"mov r8, r4\n\t"
|
||||
"mov r9, r5\n\t"
|
||||
"mov r10, r6\n\t"
|
||||
"mov r11, r7\n\t"
|
||||
"ldmia r0!, {r3-r7}\n\t"
|
||||
"msr psp, r0\n\t"
|
||||
"bx r3");
|
||||
#endif
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief PendSV system handler
|
||||
*
|
||||
* This exception handler executes following a call to mtarch_pstart() from
|
||||
* another exception handler. It performs a task switch to the main Contiki
|
||||
* thread if it is not already running.
|
||||
*/
|
||||
__attribute__ ((__naked__))
|
||||
void
|
||||
pendsv_handler(void)
|
||||
{
|
||||
/*
|
||||
* Return without doing anything if PendSV has not preempted a process thread.
|
||||
* This can occur either because PendSV has preempted the main thread, in
|
||||
* which case there is nothing to do, or because mtarch_pstart() has been
|
||||
* called from an exception handler without having called mt_init() first, in
|
||||
* which case PendSV may have preempted an exception handler and nothing must
|
||||
* be done because mt is not active.
|
||||
*/
|
||||
__asm__ ( PREEMPTED_PROCESS_THREAD()
|
||||
#if __ARM_ARCH == 7
|
||||
"it ne\n\t"
|
||||
"bxne lr\n"
|
||||
#elif __ARM_ARCH == 6
|
||||
"beq switch_to_main_thread\n\t"
|
||||
"bx lr\n"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* - Save the process thread context to the process stack.
|
||||
* - Place into the main stack the updated PSP that SVCall must return through
|
||||
* R0.
|
||||
* - Restore the main thread context from the main stack.
|
||||
* - Return to Thread mode, resuming the main thread.
|
||||
*/
|
||||
"switch_to_main_thread:\n\t"
|
||||
"mrs r0, psp\n\t"
|
||||
#if __ARM_ARCH == 7
|
||||
"stmdb r0!, {r4-r11, lr}\n\t"
|
||||
"str r0, [sp, #9 * 4]\n\t"
|
||||
"pop {r4-r11, pc}");
|
||||
#elif __ARM_ARCH == 6
|
||||
"mov r3, lr\n\t"
|
||||
"sub r0, #5 * 4\n\t"
|
||||
"stmia r0!, {r3-r7}\n\t"
|
||||
"mov r4, r8\n\t"
|
||||
"mov r5, r9\n\t"
|
||||
"sub r0, #9 * 4\n\t"
|
||||
"mov r6, r10\n\t"
|
||||
"mov r7, r11\n\t"
|
||||
"stmia r0!, {r4-r7}\n\t"
|
||||
"pop {r4-r7}\n\t"
|
||||
"sub r0, #4 * 4\n\t"
|
||||
"mov r8, r4\n\t"
|
||||
"mov r9, r5\n\t"
|
||||
"str r0, [sp, #5 * 4]\n\t"
|
||||
"mov r10, r6\n\t"
|
||||
"mov r11, r7\n\t"
|
||||
"pop {r4-r7, pc}");
|
||||
#endif
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mtarch_init(void)
|
||||
{
|
||||
SCB->CCR = (SCB->CCR
|
||||
#ifdef SCB_CCR_NONBASETHRDENA_Msk
|
||||
/*
|
||||
* Make sure that any attempt to enter Thread mode with exceptions
|
||||
* active faults.
|
||||
*
|
||||
* Only SVCall and PendSV are allowed to forcibly enter Thread
|
||||
* mode, and they are configured with the same, lowest exception
|
||||
* priority, so no other exceptions may be active.
|
||||
*/
|
||||
& ~SCB_CCR_NONBASETHRDENA_Msk
|
||||
#endif
|
||||
/*
|
||||
* Force 8-byte stack pointer alignment on exception entry in order
|
||||
* to be able to use AAPCS-conforming functions as exception
|
||||
* handlers.
|
||||
*/
|
||||
) | SCB_CCR_STKALIGN_Msk;
|
||||
|
||||
/*
|
||||
* Configure SVCall and PendSV with the same, lowest exception priority.
|
||||
*
|
||||
* This makes sure that they cannot preempt each other, and that the processor
|
||||
* executes them after having handled all other exceptions. If both are
|
||||
* pending at the same time, then SVCall takes precedence because of its lower
|
||||
* exception number. In addition, the associated exception handlers do not
|
||||
* have to check whether they are returning to Thread mode, because they
|
||||
* cannot preempt any other exception.
|
||||
*/
|
||||
NVIC_SetPriority(SVCall_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
|
||||
/*
|
||||
* Force the preceding configurations to take effect before further
|
||||
* operations.
|
||||
*/
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mtarch_start(struct mtarch_thread *thread,
|
||||
void (*function)(void *data), void *data)
|
||||
{
|
||||
struct mtarch_thread_context *context = &thread->start_stack.context;
|
||||
|
||||
/*
|
||||
* Initialize the thread context with the appropriate values to call
|
||||
* function() with data and to make function() return to mt_exit() without
|
||||
* having to call it explicitly.
|
||||
*/
|
||||
context->exc_return = EXC_RETURN_PROCESS_THREAD_BASIC_FRAME;
|
||||
context->r0 = (uint32_t)data;
|
||||
context->lr = (uint32_t)mt_exit;
|
||||
context->pc = (uint32_t)function;
|
||||
context->xpsr = xPSR_T_Msk;
|
||||
thread->psp = (uint32_t)context;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mtarch_exec(struct mtarch_thread *thread)
|
||||
{
|
||||
/* Pass the PSP to SVCall, and get the updated PSP as its return value. */
|
||||
register uint32_t psp __asm__ ("r0") = thread->psp;
|
||||
__asm__ volatile ("svc #0"
|
||||
: "+r" (psp)
|
||||
:: "memory");
|
||||
thread->psp = psp;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
__attribute__ ((__naked__))
|
||||
void
|
||||
mtarch_yield(void)
|
||||
{
|
||||
/* Invoke SVCall. */
|
||||
__asm__ ("svc #0\n\t"
|
||||
"bx lr");
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mtarch_stop(struct mtarch_thread *thread)
|
||||
{
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mtarch_pstart(void)
|
||||
{
|
||||
/* Trigger PendSV. */
|
||||
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mtarch_pstop(void)
|
||||
{
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mtarch_remove(void)
|
||||
{
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup arm
|
||||
* @{
|
||||
*
|
||||
* \defgroup arm-cm-mtarch ARM Cortex-M support for Contiki multi-threading
|
||||
*
|
||||
* All the Cortex-M devices supported by CMSIS-CORE are supported.
|
||||
*
|
||||
* An exception handler can decide to make the main Contiki thread preempt any
|
||||
* running mt thread by calling mtarch_pstart() (e.g. to perform urgent
|
||||
* operations that have been triggered by some event or that had been
|
||||
* scheduled). If the running thread is already the main Contiki thread, then
|
||||
* nothing happens. The corresponding task switch takes place when leaving
|
||||
* Handler mode. The main Contiki thread then resumes after the call to
|
||||
* mt_exec() that yielded to the preempted mt thread.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the ARM Cortex-M support for Contiki multi-threading.
|
||||
*/
|
||||
#ifndef MTARCH_H_
|
||||
#define MTARCH_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef MTARCH_CONF_STACKSIZE
|
||||
/** Thread stack size configuration, expressed as a number of 32-bit words. */
|
||||
#define MTARCH_CONF_STACKSIZE 256
|
||||
#endif
|
||||
/** Actual stack size, with minimum size and alignment requirements enforced. */
|
||||
#define MTARCH_STACKSIZE ((MAX(MTARCH_CONF_STACKSIZE, \
|
||||
sizeof(struct mtarch_thread_context) / \
|
||||
sizeof(uint32_t)) + 1) & ~1)
|
||||
|
||||
/**
|
||||
* Structure of a saved thread context.
|
||||
*
|
||||
* <tt>xpsr..r0</tt> are managed by the processor (except in mtarch_start()),
|
||||
* while the other register values are handled by the software.
|
||||
*/
|
||||
struct mtarch_thread_context {
|
||||
#if __ARM_ARCH == 7
|
||||
uint32_t r4;
|
||||
uint32_t r5;
|
||||
uint32_t r6;
|
||||
uint32_t r7;
|
||||
#endif
|
||||
uint32_t r8;
|
||||
uint32_t r9;
|
||||
uint32_t r10;
|
||||
uint32_t r11;
|
||||
uint32_t exc_return;
|
||||
#if __ARM_ARCH == 6
|
||||
uint32_t r4;
|
||||
uint32_t r5;
|
||||
uint32_t r6;
|
||||
uint32_t r7;
|
||||
#endif
|
||||
uint32_t r0;
|
||||
uint32_t r1;
|
||||
uint32_t r2;
|
||||
uint32_t r3;
|
||||
uint32_t r12;
|
||||
uint32_t lr;
|
||||
uint32_t pc;
|
||||
uint32_t xpsr;
|
||||
};
|
||||
|
||||
struct mtarch_thread {
|
||||
uint32_t psp;
|
||||
union {
|
||||
struct {
|
||||
uint32_t free[MTARCH_STACKSIZE -
|
||||
sizeof(struct mtarch_thread_context) / sizeof(uint32_t)];
|
||||
struct mtarch_thread_context context;
|
||||
} start_stack;
|
||||
uint32_t stack[MTARCH_STACKSIZE];
|
||||
} CC_ALIGN(8);
|
||||
};
|
||||
|
||||
#endif /* MTARCH_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -6,7 +6,7 @@ endif
|
|||
|
||||
STRUCTGEN = structgen
|
||||
|
||||
PROJECTDIRS += $(BUILTSRCDIR)
|
||||
MODULES_REL += $(BUILTSRCDIR)
|
||||
|
||||
USB_STRING_DESCRIPTORS ?= $(CONTIKI_CPU_ARM)/common/usb/cdc-acm/string-descriptors.xml
|
||||
|
||||
|
|
|
@ -122,5 +122,5 @@ const struct configuration_st {
|
|||
|
||||
};
|
||||
|
||||
const struct usb_st_configuration_descriptor const *configuration_head =
|
||||
(struct usb_st_configuration_descriptor const*)&configuration_block;
|
||||
const struct usb_st_configuration_descriptor* const configuration_head =
|
||||
(const struct usb_st_configuration_descriptor*)&configuration_block;
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
#endif
|
||||
|
||||
extern const struct usb_st_device_descriptor device_descriptor;
|
||||
extern const struct usb_st_configuration_descriptor const *configuration_head;
|
||||
extern const struct usb_st_configuration_descriptor* const configuration_head;
|
||||
#endif /* DESCRIPTORS_H_RPFUB8O7OV__ */
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex-M0+
|
||||
\ingroup Cortex_M0_plus
|
||||
@{
|
||||
*/
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* \defgroup cmsis CMSIS (Cortex Microcontroller Software Interface Standard)
|
||||
* \ingroup arm
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup CMSIS_Core_FunctionInterface
|
||||
* \ingroup cmsis
|
||||
|
@ -39,7 +44,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* \defgroup Cortex-M0+ Cortex-M0+
|
||||
* \defgroup Cortex_M0_plus Cortex-M0+
|
||||
* \ingroup cmsis
|
||||
*/
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
CONTIKI_ARM_DIRS += cortex-m cortex-m/CMSIS
|
||||
|
||||
include $(CONTIKI)/arch/cpu/arm/Makefile.arm
|
|
@ -0,0 +1,26 @@
|
|||
CONTIKI_ARM_DIRS += cortex-m/cm3
|
||||
|
||||
CFLAGS += -mcpu=cortex-m3
|
||||
|
||||
LDFLAGS += -mcpu=cortex-m3 -nostartfiles
|
||||
LDFLAGS += -T $(LDSCRIPT)
|
||||
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
||||
LDFLAGS += -Wl,-Map=$(CONTIKI_NG_PROJECT_MAP),--cref,--no-warn-mismatch
|
||||
|
||||
OBJCOPY_FLAGS += --gap-fill 0xff
|
||||
|
||||
### Build syscalls for newlib
|
||||
MODULES += os/lib/newlib
|
||||
|
||||
CPU_STARTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CPU_START_SOURCEFILES)}}
|
||||
|
||||
### Compilation rules
|
||||
CUSTOM_RULE_LINK = 1
|
||||
|
||||
.SECONDEXPANSION:
|
||||
|
||||
%.elf: $(CPU_STARTFILES) $$(CONTIKI_OBJECTFILES) %.o $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) $(LDSCRIPT)
|
||||
$(TRACE_LD)
|
||||
$(Q)$(LD) $(LDFLAGS) ${filter-out $(LDSCRIPT) %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -lm -o $@
|
||||
|
||||
include $(CONTIKI)/arch/cpu/arm/cortex-m/Makefile.cortex-m
|
|
@ -1,16 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* 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.
|
||||
|
@ -30,20 +30,24 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx-char-io
|
||||
* \addtogroup arm
|
||||
* @{
|
||||
*
|
||||
* \defgroup cm3 Arm Cortex-M3
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* This file is here because DBG I/O expects it to be. It just includes
|
||||
* our own dbg.h which has a non-misleading name and which also adheres
|
||||
* to Contiki's naming convention
|
||||
* Compiler and data type definitions for all CM3-based CPUs
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef DEBUG_UART_H_
|
||||
#define DEBUG_UART_H_
|
||||
#ifndef CM3_DEF_H_
|
||||
#define CM3_DEF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "dbg.h"
|
||||
#include "arm-def.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* DEBUG_UART_H_ */
|
||||
#endif /* CM3_DEF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -0,0 +1,13 @@
|
|||
CONTIKI_ARM_DIRS += cortex-m/cm4
|
||||
|
||||
CFLAGS += -mcpu=cortex-m4
|
||||
LDFLAGS += -mcpu=cortex-m4
|
||||
|
||||
### Compilation rules
|
||||
CUSTOM_RULE_LINK=1
|
||||
|
||||
%.elf: $(TARGET_STARTFILES) %.o $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) $(CONTIKI_NG_TARGET_LIB) $(TARGET_LIBS)
|
||||
$(TRACE_LD)
|
||||
$(Q)$(CC) $(LDFLAGS) ${filter %.o %.a,$^} -o $@
|
||||
|
||||
include $(CONTIKI)/arch/cpu/arm/cortex-m/Makefile.cortex-m
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* 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
|
||||
|
@ -29,19 +30,24 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup launchpad-peripherals
|
||||
* \addtogroup arm
|
||||
* @{
|
||||
*
|
||||
* \defgroup cm4 Arm Cortex-M4
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Generic module controlling LaunchPad sensors
|
||||
* Compiler and data type definitions for all CM4-based CPUs
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "launchpad/button-sensor.h"
|
||||
|
||||
#include <string.h>
|
||||
#ifndef CM4_DEF_H_
|
||||
#define CM4_DEF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Exports a global symbol to be used by the sensor API */
|
||||
SENSORS(&button_left_sensor, &button_right_sensor);
|
||||
#include "arm-def.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
#endif /* CM4_DEF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -29,15 +29,16 @@
|
|||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef TARGET_CONF_H_
|
||||
#define TARGET_CONF_H_
|
||||
#ifndef MEMORY_BARRIER_CORTEX_H_
|
||||
#define MEMORY_BARRIER_CORTEX_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define QUEUEBUF_CONF_NUM 4
|
||||
#define UIP_CONF_BUFFER_SIZE 140
|
||||
#include "contiki.h"
|
||||
|
||||
#define CMD_CONF_HANDLERS slip_radio_cmd_handler,cmd_handler_cc2420
|
||||
#define SLIP_RADIO_CONF_SENSORS slip_radio_sky_sensors
|
||||
#define UART1_CONF_RX_WITH_DMA 1
|
||||
#ifdef CMSIS_CONF_HEADER_PATH
|
||||
#include CMSIS_CONF_HEADER_PATH
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* TARGET_CONF_H_ */
|
||||
#define memory_barrier() __DMB()
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* MEMORY_BARRIER_CORTEX_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -1,16 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* 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.
|
||||
|
@ -27,48 +27,56 @@
|
|||
* 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.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup openmote-cc2538
|
||||
* @{
|
||||
* \addtogroup arm
|
||||
*
|
||||
* \defgroup openmote-button-sensor OpenMote-CC2538 user button driver
|
||||
*
|
||||
* The user button will generate a sensors_changed event on press as
|
||||
* well as on release.
|
||||
* Arm Cortex-M implementation of mutexes using the LDREX, STREX and DMB
|
||||
* instructions.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header for the OpenMote-CC2538 button driver
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef BUTTON_SENSOR_H_
|
||||
#define BUTTON_SENSOR_H_
|
||||
#ifndef MUTEX_CORTEX_H_
|
||||
#define MUTEX_CORTEX_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "lib/sensors.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BUTTON_SENSOR "Button"
|
||||
#include "contiki.h"
|
||||
|
||||
extern const struct sensors_sensor button_sensor;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern process_event_t button_press_duration_exceeded;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BUTTON_SENSOR_CONFIG_TYPE_INTERVAL 0x0100
|
||||
#ifdef CMSIS_CONF_HEADER_PATH
|
||||
#include CMSIS_CONF_HEADER_PATH
|
||||
#endif
|
||||
|
||||
#define BUTTON_SENSOR_VALUE_TYPE_LEVEL 0
|
||||
#define BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION 1
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define mutex_try_lock(m) mutex_cortex_try_lock(m)
|
||||
#define mutex_unlock(m) mutex_cortex_unlock(m)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define MUTEX_CONF_HAS_MUTEX_T 1
|
||||
typedef uint8_t mutex_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static inline bool
|
||||
mutex_cortex_try_lock(volatile mutex_t *mutex)
|
||||
{
|
||||
int status = 1;
|
||||
|
||||
#define BUTTON_SENSOR_PRESSED_LEVEL 0
|
||||
#define BUTTON_SENSOR_RELEASED_LEVEL 8
|
||||
if(__LDREXB(mutex) == 0) {
|
||||
status = __STREXB(1, mutex);
|
||||
}
|
||||
|
||||
__DMB();
|
||||
|
||||
return status == 0 ? true : false;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* BUTTON_SENSOR_H_ */
|
||||
static inline void
|
||||
mutex_cortex_unlock(volatile mutex_t *mutex)
|
||||
{
|
||||
__DMB();
|
||||
*mutex = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
#endif /* MUTEX_CORTEX_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* \defgroup arm Support for Arm CPUs
|
||||
* \ingroup cpu
|
||||
*/
|
|
@ -1,60 +1,26 @@
|
|||
CC = arm-none-eabi-gcc
|
||||
CPP = arm-none-eabi-cpp
|
||||
LD = arm-none-eabi-gcc
|
||||
AR = arm-none-eabi-ar
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
OBJDUMP = arm-none-eabi-objdump
|
||||
NM = arm-none-eabi-nm
|
||||
|
||||
ifndef SOURCE_LDSCRIPT
|
||||
SOURCE_LDSCRIPT = $(CONTIKI_CPU)/cc2538.lds
|
||||
endif
|
||||
LDSCRIPT = $(OBJECTDIR)/cc2538.ld
|
||||
|
||||
CFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing
|
||||
CFLAGS += -Wall -DCMSIS_DEV_HDR=\"cc2538_cm3.h\"
|
||||
LDFLAGS += -mcpu=cortex-m3 -mthumb -nostartfiles
|
||||
LDFLAGS += -T $(LDSCRIPT)
|
||||
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
||||
LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch
|
||||
OBJCOPY_FLAGS += -O binary --gap-fill 0xff
|
||||
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
|
||||
|
||||
ifeq ($(WERROR),1)
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
### Are we building with code size optimisations?
|
||||
SMALL ?= 1
|
||||
ifeq ($(SMALL),1)
|
||||
CFLAGS += -Os
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
CFLAGS += -DCMSIS_DEV_HDR=\"cc2538_cm3.h\"
|
||||
|
||||
### If the user-specified a Node ID, pass a define
|
||||
ifdef NODEID
|
||||
CFLAGS += -DIEEE_ADDR_NODE_ID=$(NODEID)
|
||||
endif
|
||||
|
||||
### CPU-dependent cleanup files
|
||||
CLEAN += *.d *.elf *.hex
|
||||
|
||||
### CPU-dependent directories
|
||||
CONTIKI_CPU_DIRS = ../arm/common/CMSIS . dev usb usb/common usb/common/cdc-acm
|
||||
|
||||
### Use the existing debug I/O in arch/cpu/arm/common
|
||||
CONTIKI_CPU_DIRS += ../arm/common/dbg-io
|
||||
CONTIKI_CPU_DIRS = . dev usb usb/common usb/common/cdc-acm
|
||||
|
||||
### CPU-dependent source files
|
||||
CONTIKI_CPU_SOURCEFILES += soc.c clock.c rtimer-arch.c uart.c watchdog.c
|
||||
CONTIKI_CPU_SOURCEFILES += nvic.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
|
||||
CONTIKI_CPU_SOURCEFILES += nvic.c sys-ctrl.c gpio.c ioc.c spi-legacy.c adc.c
|
||||
CONTIKI_CPU_SOURCEFILES += spi-arch.c
|
||||
CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c gcm.c
|
||||
CONTIKI_CPU_SOURCEFILES += ccm.c sha256.c
|
||||
CONTIKI_CPU_SOURCEFILES += ccm.c sha256.c gpio-hal-arch.c
|
||||
CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c
|
||||
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
|
||||
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c int-master.c
|
||||
CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c
|
||||
CONTIKI_CPU_SOURCEFILES += ecc-curve.c
|
||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
||||
|
@ -62,26 +28,13 @@ CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
|||
CONTIKI_CPU_SOURCEFILES += i2c.c cc2538-temp-sensor.c vdd3-sensor.c
|
||||
CONTIKI_CPU_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c pwm.c
|
||||
|
||||
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
|
||||
MODULES += os/lib/dbg-io
|
||||
|
||||
USB_SOURCEFILES += usb-core.c cdc-acm.c usb-arch.c usb-serial.c cdc-acm-descriptors.c
|
||||
|
||||
ifneq ($(TARGET_START_SOURCEFILES),)
|
||||
CPU_START_SOURCEFILES = TARGET_START_SOURCEFILES
|
||||
else
|
||||
CPU_START_SOURCEFILES = startup-gcc.c
|
||||
endif
|
||||
CPU_STARTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CPU_START_SOURCEFILES)}}
|
||||
CPU_START_SOURCEFILES = startup-gcc.c
|
||||
|
||||
CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES)
|
||||
CONTIKI_SOURCEFILES += $(USB_SOURCEFILES)
|
||||
|
||||
MODULES += lib/newlib arch/cpu/arm/common/sys
|
||||
|
||||
.SECONDEXPANSION:
|
||||
|
||||
### Don't treat the .elf as intermediate
|
||||
.PRECIOUS: %.elf %.hex %.bin
|
||||
CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(USB_SOURCEFILES)
|
||||
|
||||
### Always re-build ieee-addr.o in case the command line passes a new NODEID
|
||||
FORCE:
|
||||
|
@ -90,27 +43,6 @@ $(OBJECTDIR)/ieee-addr.o: ieee-addr.c FORCE | $(OBJECTDIR)
|
|||
$(TRACE_CC)
|
||||
$(Q)$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
### Compilation rules
|
||||
CUSTOM_RULE_LINK=1
|
||||
|
||||
%.elf: $(CPU_STARTFILES) $$(CONTIKI_OBJECTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) $(LDSCRIPT)
|
||||
$(TRACE_LD)
|
||||
$(Q)$(LD) $(LDFLAGS) ${filter-out $(LDSCRIPT) %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@
|
||||
|
||||
%.hex: %.elf
|
||||
$(OBJCOPY) -O ihex $< $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@
|
||||
|
||||
%.lst: %.elf
|
||||
$(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@
|
||||
|
||||
### We don't really need the .hex and .bin for the .$(TARGET) but let's make
|
||||
### sure they get built
|
||||
%.$(TARGET): %.elf %.hex %.bin
|
||||
cp $< $@
|
||||
|
||||
### This rule is used to generate the correct linker script
|
||||
LDGENFLAGS += $(CFLAGS)
|
||||
LDGENFLAGS += -imacros "contiki-conf.h" -imacros "dev/cc2538-dev.h"
|
||||
|
@ -121,3 +53,5 @@ LDGENFLAGS += -x c -P -E
|
|||
$(LDSCRIPT): $(SOURCE_LDSCRIPT) FORCE | $(OBJECTDIR)
|
||||
$(TRACE_CC)
|
||||
$(Q)$(CC) $(LDGENFLAGS) $< | grep -v '^\s*#\s*pragma\>' > $@
|
||||
|
||||
include $(CONTIKI)/arch/cpu/arm/cortex-m/cm3/Makefile.cm3
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc2538
|
||||
* @{
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef CC2538_CONF_H_
|
||||
#define CC2538_CONF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name CFS configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef COFFEE_CONF_SIZE
|
||||
#define COFFEE_CONF_SIZE (4 * COFFEE_SECTOR_SIZE)
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name CC2538 System Control configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef SYS_CTRL_CONF_OSC32K_USE_XTAL
|
||||
#define SYS_CTRL_CONF_OSC32K_USE_XTAL 0 /**< Use the on-board 32.768-kHz crystal */
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Watchdog Timer configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef WATCHDOG_CONF_ENABLE
|
||||
#define WATCHDOG_CONF_ENABLE 1 /**< Enable the watchdog timer */
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name USB 'core' configuration
|
||||
*
|
||||
* Those values are not meant to be modified by the user, except where stated
|
||||
* otherwise
|
||||
* @{
|
||||
*/
|
||||
#define CTRL_EP_SIZE 8
|
||||
#define USB_EP1_SIZE 32
|
||||
#define USB_EP2_SIZE 64
|
||||
#define USB_EP3_SIZE 64
|
||||
#define USB_ARCH_WRITE_NOTIFY 0
|
||||
|
||||
#ifndef USB_ARCH_CONF_DMA
|
||||
#define USB_ARCH_CONF_DMA 1 /**< Change to Enable/Disable USB DMA */
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
/**
|
||||
* \name uDMA Configuration and channel allocations
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define USB_ARCH_CONF_RX_DMA_CHAN 0 /**< USB -> RAM DMA channel */
|
||||
#define USB_ARCH_CONF_TX_DMA_CHAN 1 /**< RAM -> USB DMA channel */
|
||||
#define CC2538_RF_CONF_TX_DMA_CHAN 2 /**< RF -> RAM DMA channel */
|
||||
#define CC2538_RF_CONF_RX_DMA_CHAN 3 /**< RAM -> RF DMA channel */
|
||||
#define UDMA_CONF_MAX_CHANNEL CC2538_RF_CONF_RX_DMA_CHAN
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Character I/O Configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef UART_CONF_ENABLE
|
||||
#define UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */
|
||||
#endif
|
||||
|
||||
#ifndef UART0_CONF_BAUD_RATE
|
||||
#define UART0_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */
|
||||
#endif
|
||||
|
||||
#ifndef UART1_CONF_BAUD_RATE
|
||||
#define UART1_CONF_BAUD_RATE 115200 /**< Default UART1 baud rate */
|
||||
#endif
|
||||
|
||||
#ifndef SLIP_ARCH_CONF_USB
|
||||
#define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */
|
||||
#endif
|
||||
|
||||
#ifndef DBG_CONF_USB
|
||||
#define DBG_CONF_USB 0 /**< All debugging over UART by default */
|
||||
#endif
|
||||
|
||||
#ifndef SERIAL_LINE_CONF_UART
|
||||
#define SERIAL_LINE_CONF_UART 0 /**< UART to use with serial line */
|
||||
#endif
|
||||
|
||||
#if !SLIP_ARCH_CONF_USB
|
||||
#ifndef SLIP_ARCH_CONF_UART
|
||||
#define SLIP_ARCH_CONF_UART 0 /**< UART to use with SLIP */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !DBG_CONF_USB
|
||||
#ifndef DBG_CONF_UART
|
||||
#define DBG_CONF_UART 0 /**< UART to use for debugging */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UART1_CONF_UART
|
||||
#define UART1_CONF_UART 0 /**< UART to use for examples relying on
|
||||
the uart1_* API */
|
||||
#endif
|
||||
|
||||
#ifndef SLIP_ARCH_CONF_ENABLED
|
||||
/*
|
||||
* Determine whether we need SLIP
|
||||
* This will keep working while UIP_FALLBACK_INTERFACE and CMD_CONF_OUTPUT
|
||||
* keep using SLIP
|
||||
*/
|
||||
#if defined(UIP_FALLBACK_INTERFACE) || defined(CMD_CONF_OUTPUT)
|
||||
#define SLIP_ARCH_CONF_ENABLED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Define this as 1 to build a headless node.
|
||||
*
|
||||
* The UART will not be initialised its clock will be gated, offering some
|
||||
* energy savings. The USB will not be initialised either
|
||||
*/
|
||||
#ifndef CC2538_CONF_QUIET
|
||||
#define CC2538_CONF_QUIET 0
|
||||
#endif
|
||||
|
||||
/* CC2538_CONF_QUIET is hard and overrides all other related defines */
|
||||
#if CC2538_CONF_QUIET
|
||||
#undef USB_SERIAL_CONF_ENABLE
|
||||
#define USB_SERIAL_CONF_ENABLE 0
|
||||
|
||||
#undef UART_CONF_ENABLE
|
||||
#define UART_CONF_ENABLE 0
|
||||
#endif /* CC2538_CONF_QUIET */
|
||||
|
||||
/**
|
||||
* \brief Enable the USB core only if we need it
|
||||
*/
|
||||
#ifndef USB_SERIAL_CONF_ENABLE
|
||||
#define USB_SERIAL_CONF_ENABLE \
|
||||
((SLIP_ARCH_CONF_USB && SLIP_ARCH_CONF_ENABLED) || \
|
||||
(MAC_CONF_WITH_TSCH && (SLIP_ARCH_CONF_ENABLED || BUILD_WITH_SHELL)) || \
|
||||
DBG_CONF_USB)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If debugging and SLIP use the same peripheral, this will be 1. Don't modify
|
||||
* this
|
||||
*/
|
||||
#if SLIP_ARCH_CONF_ENABLED
|
||||
#define DBG_CONF_SLIP_MUX (SLIP_ARCH_CONF_USB == DBG_CONF_USB && \
|
||||
(SLIP_ARCH_CONF_USB || \
|
||||
SLIP_ARCH_CONF_UART == DBG_CONF_UART))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Automatic detection of whether a specific UART is in use
|
||||
*/
|
||||
#define UART_IN_USE_BY_SERIAL_LINE(u) (SERIAL_LINE_CONF_UART == (u))
|
||||
#define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \
|
||||
!SLIP_ARCH_CONF_USB && \
|
||||
SLIP_ARCH_CONF_UART == (u))
|
||||
#define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u))
|
||||
#define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u))
|
||||
|
||||
#define UART_IN_USE(u) ( \
|
||||
UART_CONF_ENABLE && \
|
||||
(UART_IN_USE_BY_SERIAL_LINE(u) || \
|
||||
UART_IN_USE_BY_SLIP(u) || \
|
||||
UART_IN_USE_BY_DBG(u) || \
|
||||
UART_IN_USE_BY_UART1(u)) \
|
||||
)
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name RF configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/* RF Config */
|
||||
|
||||
#ifdef RF_CHANNEL
|
||||
#define CC2538_RF_CONF_CHANNEL RF_CHANNEL
|
||||
#endif
|
||||
|
||||
#ifndef CC2538_RF_CONF_CHANNEL
|
||||
#define CC2538_RF_CONF_CHANNEL 26
|
||||
#endif /* CC2538_RF_CONF_CHANNEL */
|
||||
|
||||
#ifndef CC2538_RF_CONF_AUTOACK
|
||||
#define CC2538_RF_CONF_AUTOACK 1 /**< RF H/W generates ACKs */
|
||||
#endif /* CC2538_CONF_AUTOACK */
|
||||
|
||||
#ifndef CC2538_RF_CONF_TX_USE_DMA
|
||||
#define CC2538_RF_CONF_TX_USE_DMA 1 /**< RF TX over DMA */
|
||||
#endif
|
||||
|
||||
#ifndef CC2538_RF_CONF_RX_USE_DMA
|
||||
#define CC2538_RF_CONF_RX_USE_DMA 1 /**< RF RX over DMA */
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name LPM configuration
|
||||
* @{
|
||||
*/
|
||||
#ifndef LPM_CONF_ENABLE
|
||||
#define LPM_CONF_ENABLE 1 /**< Set to 0 to disable LPM entirely */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Maximum PM
|
||||
*
|
||||
* The SoC will never drop to a Power Mode deeper than the one specified here.
|
||||
* 0 for PM0, 1 for PM1 and 2 for PM2
|
||||
*/
|
||||
#ifndef LPM_CONF_MAX_PM
|
||||
#define LPM_CONF_MAX_PM 1
|
||||
#endif
|
||||
|
||||
#ifndef LPM_CONF_STATS
|
||||
#define LPM_CONF_STATS 0 /**< Set to 1 to enable LPM-related stats */
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Radio Configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef NETSTACK_CONF_RADIO
|
||||
#define NETSTACK_CONF_RADIO cc2538_rf_driver
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name IEEE address configuration
|
||||
*
|
||||
* Used to generate our link-layer & IPv6 address
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Location of the IEEE address
|
||||
* 0 => Read from InfoPage,
|
||||
* 1 => Use a hardcoded address, configured by IEEE_ADDR_CONF_ADDRESS
|
||||
*/
|
||||
#ifndef IEEE_ADDR_CONF_HARDCODED
|
||||
#define IEEE_ADDR_CONF_HARDCODED 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The hardcoded IEEE address to be used when IEEE_ADDR_CONF_HARDCODED
|
||||
* is defined as 1
|
||||
*/
|
||||
#ifndef IEEE_ADDR_CONF_ADDRESS
|
||||
#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Location of the IEEE address in the InfoPage when
|
||||
* IEEE_ADDR_CONF_HARDCODED is defined as 0
|
||||
* 0 => Use the primary address location
|
||||
* 1 => Use the secondary address location
|
||||
*/
|
||||
#ifndef IEEE_ADDR_CONF_USE_SECONDARY_LOCATION
|
||||
#define IEEE_ADDR_CONF_USE_SECONDARY_LOCATION 0
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Security
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef CRYPTO_CONF_INIT
|
||||
#define CRYPTO_CONF_INIT 1 /**< Whether to init cryptoprocessor */
|
||||
#endif
|
||||
|
||||
#ifndef AES_128_CONF
|
||||
#define AES_128_CONF cc2538_aes_128_driver /**< AES-128 driver */
|
||||
#endif
|
||||
|
||||
#ifndef CCM_STAR_CONF
|
||||
#define CCM_STAR_CONF cc2538_ccm_star_driver /**< AES-CCM* driver */
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC2538_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* 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 CC2538_DEF_H_
|
||||
#define CC2538_DEF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "cm3/cm3-def.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define RTIMER_ARCH_SECOND 32768
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* 352us from calling transmit() until the SFD byte has been sent */
|
||||
#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(352))
|
||||
/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */
|
||||
#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250))
|
||||
#define RADIO_DELAY_BEFORE_DETECT 0
|
||||
#ifndef TSCH_CONF_BASE_DRIFT_PPM
|
||||
/* The drift compared to "true" 10ms slots.
|
||||
* Enable adaptive sync to enable compensation for this.
|
||||
* Slot length 10000 usec
|
||||
* 328 ticks
|
||||
* Tick duration 30.517578125 usec
|
||||
* Real slot duration 10009.765625 usec
|
||||
* Target - real duration = -9.765625 usec
|
||||
* TSCH_CONF_BASE_DRIFT_PPM -977
|
||||
*/
|
||||
#define TSCH_CONF_BASE_DRIFT_PPM -977
|
||||
#endif
|
||||
|
||||
#if MAC_CONF_WITH_TSCH
|
||||
#define TSCH_CONF_HW_FRAME_FILTERING 0
|
||||
#endif /* MAC_CONF_WITH_TSCH */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define SPI_CONF_CONTROLLER_COUNT 2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Path to CMSIS header */
|
||||
#define CMSIS_CONF_HEADER_PATH "cc2538_cm3.h"
|
||||
|
||||
/* Path to headers with implementation of mutexes and memory barriers */
|
||||
#define MUTEX_CONF_ARCH_HEADER_PATH "mutex-cortex.h"
|
||||
#define MEMORY_BARRIER_CONF_ARCH_HEADER_PATH "memory-barrier-cortex.h"
|
||||
|
||||
#define GPIO_HAL_CONF_ARCH_HDR_PATH "dev/gpio-hal-arch.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC2538_DEF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -96,11 +96,18 @@ SECTIONS
|
|||
_ebss = .;
|
||||
} > FRSRAM
|
||||
|
||||
_end = .; /* End of the .bss segment. */
|
||||
|
||||
/* This symbol is used by the stack check library. */
|
||||
_stack = .;
|
||||
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
*(.stack)
|
||||
} > FRSRAM
|
||||
|
||||
/* This symbol is used by the stack check library. */
|
||||
_stack_origin = .;
|
||||
_heap = .;
|
||||
_eheap = ORIGIN(FRSRAM) + LENGTH(FRSRAM);
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ clock_init(void)
|
|||
REG(GPT_0_BASE + GPTIMER_TAPR) = PRESCALER_VALUE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF clock_time_t
|
||||
clock_time_t
|
||||
clock_time(void)
|
||||
{
|
||||
return rt_ticks_startup / RTIMER_CLOCK_TICK_RATIO;
|
||||
|
@ -126,7 +126,7 @@ clock_set_seconds(unsigned long sec)
|
|||
rt_ticks_epoch = (uint64_t)sec * RTIMER_SECOND;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF unsigned long
|
||||
unsigned long
|
||||
clock_seconds(void)
|
||||
{
|
||||
return rt_ticks_epoch / RTIMER_SECOND;
|
||||
|
|
|
@ -29,16 +29,7 @@
|
|||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup platform
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-platforms TI cc2538-powered platforms
|
||||
*
|
||||
* Documentation for all platforms powered by the TI cc2538 System-on-Chip
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538 The TI cc2538 System-on-Chip
|
||||
* CPU-Specific functionality - available to all cc2538-based platforms
|
||||
* \addtogroup cc2538
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-cpu cc2538 CPU
|
||||
|
@ -65,8 +56,6 @@
|
|||
#endif /* CPU_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -28,16 +28,9 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** \addtogroup cc2538-char-io
|
||||
* @{ */
|
||||
/**
|
||||
* \file
|
||||
* Implementation of arch-specific functions required by the dbg_io API in
|
||||
* cpu/arm/common/dbg-io
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
|
||||
#include "dbg.h"
|
||||
#include "dev/uart.h"
|
||||
#include "usb/usb-serial.h"
|
||||
|
||||
|
@ -55,13 +48,10 @@
|
|||
#define flush()
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#undef putchar
|
||||
#undef puts
|
||||
|
||||
#define SLIP_END 0300
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
putchar(int c)
|
||||
dbg_putchar(int c)
|
||||
{
|
||||
#if DBG_CONF_SLIP_MUX
|
||||
static char debug_frame = 0;
|
||||
|
@ -80,7 +70,7 @@ putchar(int c)
|
|||
write_byte(SLIP_END);
|
||||
debug_frame = 0;
|
||||
#endif
|
||||
dbg_flush();
|
||||
flush();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
@ -100,18 +90,3 @@ dbg_send_bytes(const unsigned char *s, unsigned int len)
|
|||
return i;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
puts(const char *s)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
while(s && *s != 0) {
|
||||
putchar(*s++);
|
||||
i++;
|
||||
}
|
||||
putchar('\n');
|
||||
return i;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-char-io cc2538 Character I/O
|
||||
*
|
||||
* CPU-specific functions for debugging and SLIP I/O
|
||||
*
|
||||
* On the cc2538, character I/O can be directed over USB or UART. This is
|
||||
* controlled by a series of configuration directives:
|
||||
* - SLIP_ARCH_CONF_USB: Controls the operation of slip-arch.
|
||||
* - DBG_CONF_USB: Controls all debugging output
|
||||
*
|
||||
* Defaults for those defines are set in contiki-conf.h
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the cc2538 Debug I/O module
|
||||
*/
|
||||
#ifndef DBG_H_
|
||||
#define DBG_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
#include "usb/usb-serial.h"
|
||||
/**
|
||||
* \brief Print a stream of bytes
|
||||
* \param seq A pointer to the stream
|
||||
* \param len The number of bytes to print
|
||||
* \return The number of printed bytes
|
||||
*
|
||||
* This function is an arch-specific implementation required by the dbg-io
|
||||
* API in cpu/arm/common/dbg-io. It prints a stream of bytes over the
|
||||
* peripheral used by the platform.
|
||||
*/
|
||||
unsigned int dbg_send_bytes(const unsigned char *seq, unsigned int len);
|
||||
|
||||
/**
|
||||
* \brief Flushes character output
|
||||
*
|
||||
* When debugging is sent over USB, this functions causes the USB
|
||||
* driver to immediately TX the content of output buffers. When
|
||||
* debugging is over UART, this function does nothing.
|
||||
*
|
||||
* There is nothing stopping you from using this macro in your code but
|
||||
* normally, you won't have to.
|
||||
*/
|
||||
#if DBG_CONF_USB
|
||||
#define dbg_flush() usb_serial_flush()
|
||||
#else
|
||||
#define dbg_flush()
|
||||
#endif
|
||||
|
||||
#endif /* DBG_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc2538-gpio-hal
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation file for the CC2538 GPIO HAL functions
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "dev/gpio-hal.h"
|
||||
#include "dev/gpio.h"
|
||||
#include "dev/ioc.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_hal_arch_pin_cfg_set(gpio_hal_pin_t pin, gpio_hal_pin_cfg_t cfg)
|
||||
{
|
||||
uint8_t port, pin_num, pin_mask;
|
||||
uint32_t port_base;
|
||||
|
||||
port = PIN_TO_PORT(pin);
|
||||
port_base = PIN_TO_PORT_BASE(pin);
|
||||
pin_num = pin % 8;
|
||||
pin_mask = GPIO_PIN_MASK(pin_num);
|
||||
|
||||
gpio_hal_pin_cfg_t tmp;
|
||||
|
||||
tmp = cfg & GPIO_HAL_PIN_CFG_EDGE_BOTH;
|
||||
if(tmp == GPIO_HAL_PIN_CFG_EDGE_NONE) {
|
||||
GPIO_DISABLE_INTERRUPT(port_base, pin_mask);
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_EDGE_RISING) {
|
||||
GPIO_DETECT_EDGE(port_base, pin_mask);
|
||||
GPIO_TRIGGER_SINGLE_EDGE(port_base, pin_mask);
|
||||
GPIO_DETECT_RISING(port_base, pin_mask);
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_EDGE_FALLING) {
|
||||
GPIO_DETECT_EDGE(port_base, pin_mask);
|
||||
GPIO_TRIGGER_SINGLE_EDGE(port_base, pin_mask);
|
||||
GPIO_DETECT_FALLING(port_base, pin_mask);
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_EDGE_BOTH) {
|
||||
GPIO_DETECT_EDGE(port_base, pin_mask);
|
||||
GPIO_TRIGGER_BOTH_EDGES(port_base, pin_mask);
|
||||
}
|
||||
|
||||
tmp = cfg & GPIO_HAL_PIN_CFG_PULL_MASK;
|
||||
if(tmp == GPIO_HAL_PIN_CFG_PULL_NONE) {
|
||||
ioc_set_over(port, pin_num, IOC_OVERRIDE_DIS);
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_PULL_DOWN) {
|
||||
ioc_set_over(port, pin_num, IOC_OVERRIDE_PDE);
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_PULL_UP) {
|
||||
ioc_set_over(port, pin_num, IOC_OVERRIDE_PUE);
|
||||
}
|
||||
|
||||
tmp = cfg & GPIO_HAL_PIN_CFG_INT_MASK;
|
||||
if(tmp == GPIO_HAL_PIN_CFG_INT_DISABLE) {
|
||||
GPIO_DISABLE_INTERRUPT(port_base, pin_mask);
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_INT_ENABLE) {
|
||||
GPIO_ENABLE_INTERRUPT(port_base, pin_mask);
|
||||
NVIC_EnableIRQ(port);
|
||||
}
|
||||
|
||||
GPIO_SOFTWARE_CONTROL(port_base, pin_mask);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
gpio_hal_pin_cfg_t
|
||||
gpio_hal_arch_pin_cfg_get(gpio_hal_pin_t pin)
|
||||
{
|
||||
uint8_t port, pin_num, pin_mask;
|
||||
uint32_t port_base;
|
||||
gpio_hal_pin_cfg_t cfg;
|
||||
uint32_t tmp;
|
||||
|
||||
port = PIN_TO_PORT(pin);
|
||||
port_base = PIN_TO_PORT_BASE(pin);
|
||||
pin_num = pin % 8;
|
||||
pin_mask = GPIO_PIN_MASK(pin_num);
|
||||
|
||||
cfg = 0;
|
||||
|
||||
/* Pull */
|
||||
tmp = ioc_get_over(port, pin_num);
|
||||
if(tmp == IOC_OVERRIDE_PUE) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_PULL_UP;
|
||||
} else if(tmp == IOC_OVERRIDE_PDE) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_PULL_DOWN;
|
||||
} else {
|
||||
cfg |= GPIO_HAL_PIN_CFG_PULL_NONE;
|
||||
}
|
||||
|
||||
/* Interrupt enable/disable */
|
||||
tmp = REG((port_base) + GPIO_IE) & pin_mask;
|
||||
if(tmp == 0) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_INT_DISABLE;
|
||||
} else {
|
||||
cfg |= GPIO_HAL_PIN_CFG_INT_ENABLE;
|
||||
}
|
||||
|
||||
/* Edge detection */
|
||||
if(REG((port_base) + GPIO_IS) & pin_mask) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_NONE;
|
||||
} else {
|
||||
if(REG((port_base) + GPIO_IBE) & pin_mask) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_BOTH;
|
||||
} else {
|
||||
if(REG((port_base) + GPIO_IEV) & pin_mask) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_RISING;
|
||||
} else {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_FALLING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_hal_arch_write_pin(gpio_hal_pin_t pin, uint8_t value)
|
||||
{
|
||||
if(value == 1) {
|
||||
gpio_hal_arch_set_pin(pin);
|
||||
return;
|
||||
}
|
||||
gpio_hal_arch_clear_pin(pin);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_hal_arch_set_pins(gpio_hal_pin_mask_t pins)
|
||||
{
|
||||
GPIO_SET_PIN(GPIO_A_BASE, pins & 0xFF);
|
||||
GPIO_SET_PIN(GPIO_B_BASE, (pins >> 8) & 0xFF);
|
||||
GPIO_SET_PIN(GPIO_C_BASE, (pins >> 16) & 0xFF);
|
||||
GPIO_SET_PIN(GPIO_D_BASE, (pins >> 24) & 0xFF);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_hal_arch_clear_pins(gpio_hal_pin_mask_t pins)
|
||||
{
|
||||
GPIO_CLR_PIN(GPIO_A_BASE, pins & 0xFF);
|
||||
GPIO_CLR_PIN(GPIO_B_BASE, (pins >> 8) & 0xFF);
|
||||
GPIO_CLR_PIN(GPIO_C_BASE, (pins >> 16) & 0xFF);
|
||||
GPIO_CLR_PIN(GPIO_D_BASE, (pins >> 24) & 0xFF);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
gpio_hal_pin_mask_t
|
||||
gpio_hal_arch_read_pins(gpio_hal_pin_mask_t pins)
|
||||
{
|
||||
gpio_hal_pin_mask_t rv = 0;
|
||||
|
||||
rv |= GPIO_READ_PIN(GPIO_A_BASE, pins & 0xFF);
|
||||
rv |= GPIO_READ_PIN(GPIO_B_BASE, (pins >> 8) & 0xFF) << 8;
|
||||
rv |= GPIO_READ_PIN(GPIO_C_BASE, (pins >> 16) & 0xFF) << 16;
|
||||
rv |= GPIO_READ_PIN(GPIO_D_BASE, (pins >> 24) & 0xFF) << 24;
|
||||
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_hal_arch_write_pins(gpio_hal_pin_mask_t pins, gpio_hal_pin_mask_t value)
|
||||
{
|
||||
GPIO_WRITE_PIN(GPIO_A_BASE, pins & 0xFF, value & 0xFF);
|
||||
GPIO_WRITE_PIN(GPIO_B_BASE, (pins >> 8) & 0xFF, (value >> 8) & 0xFF);
|
||||
GPIO_WRITE_PIN(GPIO_C_BASE, (pins >> 16) & 0xFF, (value >> 16) & 0xFF);
|
||||
GPIO_WRITE_PIN(GPIO_D_BASE, (pins >> 24) & 0xFF, (value >> 24) & 0xFF);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc2538
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc2538-gpio-hal CC2538 GPIO HAL implementation
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC2538 GPIO HAL functions
|
||||
*
|
||||
* \note
|
||||
* Do not include this header directly
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef GPIO_HAL_ARCH_H_
|
||||
#define GPIO_HAL_ARCH_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "dev/gpio.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define PIN_TO_PORT(pin) (pin >> 3)
|
||||
#define PIN_TO_NUM(pin) (pin % 8)
|
||||
#define PIN_TO_PORT_BASE(pin) GPIO_PORT_TO_BASE(PIN_TO_PORT(pin))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define gpio_hal_arch_interrupt_enable(p) do { \
|
||||
GPIO_ENABLE_INTERRUPT(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
|
||||
NVIC_EnableIRQ(PIN_TO_PORT(p)); \
|
||||
} while(0);
|
||||
|
||||
#define gpio_hal_arch_interrupt_disable(p) \
|
||||
GPIO_DISABLE_INTERRUPT(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8))
|
||||
|
||||
#define gpio_hal_arch_pin_set_input(p) do { \
|
||||
GPIO_SOFTWARE_CONTROL(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
|
||||
GPIO_SET_INPUT(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
|
||||
} while(0);
|
||||
|
||||
#define gpio_hal_arch_pin_set_output(p) do { \
|
||||
GPIO_SOFTWARE_CONTROL(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
|
||||
GPIO_SET_OUTPUT(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)); \
|
||||
} while(0);
|
||||
|
||||
#define gpio_hal_arch_set_pin(p) \
|
||||
GPIO_SET_PIN(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8))
|
||||
|
||||
#define gpio_hal_arch_clear_pin(p) \
|
||||
GPIO_CLR_PIN(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8))
|
||||
|
||||
#define gpio_hal_arch_read_pin(p) \
|
||||
(GPIO_READ_PIN(PIN_TO_PORT_BASE(p), GPIO_PIN_MASK((p) % 8)) == 0 ? 0 : 1)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* GPIO_HAL_ARCH_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -37,46 +37,13 @@
|
|||
*/
|
||||
#include "contiki.h"
|
||||
#include "dev/leds.h"
|
||||
#include "dev/gpio-hal.h"
|
||||
#include "dev/gpio.h"
|
||||
#include "dev/nvic.h"
|
||||
#include "reg.h"
|
||||
#include "lpm.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* \brief Pointer to a function to be called when a GPIO interrupt is detected.
|
||||
* Callbacks for Port A, Pins[0:7] are stored in positions [0:7] of this
|
||||
* buffer, Port B callbacks in [8:15] and so on
|
||||
*/
|
||||
static gpio_callback_t gpio_callbacks[32];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_register_callback(gpio_callback_t f, uint8_t port, uint8_t pin)
|
||||
{
|
||||
gpio_callbacks[(port << 3) + pin] = f;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Run through all registered GPIO callbacks and invoke those
|
||||
* associated with the \a port and the pins specified by \a mask
|
||||
* \param mask Search callbacks associated with pins specified by this mask
|
||||
* \param port Search callbacks associated with this port. Here, port is
|
||||
* specified as a number between 0 and 3. Port A: 0, Port B: 1 etc */
|
||||
void
|
||||
notify(uint8_t mask, uint8_t port)
|
||||
{
|
||||
uint8_t i;
|
||||
gpio_callback_t *f = &gpio_callbacks[port << 3];
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(mask & (1 << i)) {
|
||||
if((*f) != NULL) {
|
||||
(*f)(port, i);
|
||||
}
|
||||
}
|
||||
f++;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Interrupt service routine for Port \a port
|
||||
* \param port Number between 0 and 3. Port A: 0, Port B: 1, etc.
|
||||
|
@ -93,7 +60,7 @@ gpio_port_isr(uint8_t port)
|
|||
int_status = GPIO_GET_MASKED_INT_STATUS(base);
|
||||
power_up_int_status = GPIO_GET_POWER_UP_INT_STATUS(port);
|
||||
|
||||
notify(int_status | power_up_int_status, port);
|
||||
gpio_hal_event_handler((int_status | power_up_int_status) << (port << 3));
|
||||
|
||||
GPIO_CLEAR_INTERRUPT(base, int_status);
|
||||
GPIO_CLEAR_POWER_UP_INTERRUPT(port, power_up_int_status);
|
||||
|
@ -110,9 +77,4 @@ GPIO_PORT_ISR(b, B)
|
|||
GPIO_PORT_ISR(c, C)
|
||||
GPIO_PORT_ISR(d, D)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_init()
|
||||
{
|
||||
memset(gpio_callbacks, 0, sizeof(gpio_callbacks));
|
||||
}
|
||||
/** @} */
|
||||
|
|
|
@ -42,27 +42,12 @@
|
|||
*/
|
||||
#ifndef GPIO_H_
|
||||
#define GPIO_H_
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "dev/gpio-hal.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* \brief Type definition for callbacks invoked by the GPIO ISRs
|
||||
* \param port The port that triggered the GPIO interrupt. \e port is passed
|
||||
* by its numeric representation (Port A:0, B:1 etc). Defines for
|
||||
* these numeric representations are GPIO_x_NUM
|
||||
* \param pin The pin that triggered the interrupt, specified by number
|
||||
* (0, 1, ..., 7)
|
||||
*
|
||||
* This is the prototype of a function pointer passed to
|
||||
* gpio_register_callback(). These callbacks are registered on a port/pin
|
||||
* basis. When a GPIO port generates an interrupt, if a callback has been
|
||||
* registered for the port/pin combination, the ISR will invoke it. The ISR
|
||||
* will pass the port/pin as arguments in that call, so that a developer can
|
||||
* re-use the same callback for multiple port/pin combinations
|
||||
*/
|
||||
typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Base addresses for the GPIO register instances
|
||||
* @{
|
||||
|
@ -341,6 +326,14 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin);
|
|||
* number.
|
||||
*/
|
||||
#define GPIO_PORT_TO_BASE(PORT) (GPIO_A_BASE + ((PORT) << 12))
|
||||
|
||||
/**
|
||||
* \brief Converts a port/pin pair to GPIO HAL pin number
|
||||
* \param PORT The port number in the range 0 - 3 (GPIO_n_NUM).
|
||||
* \param PIN The pin number in the range 0 - 7.
|
||||
* \return The pin representation using GPIO HAL semantics
|
||||
*/
|
||||
#define GPIO_PORT_PIN_TO_GPIO_HAL_PIN(PORT, PIN) (((PORT) << 3) + (PIN))
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name GPIO Register offset declarations
|
||||
|
@ -612,21 +605,6 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin);
|
|||
#define GPIO_IRQ_DETECT_UNMASK_PAIACK0 0x00000001 /**< Port A bit 0 */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief Initialise the GPIO module */
|
||||
void gpio_init();
|
||||
|
||||
/**
|
||||
* \brief Register GPIO callback
|
||||
* \param f Pointer to a function to be called when \a pin of \a port
|
||||
* generates an interrupt
|
||||
* \param port Associate \a f with this port. \e port must be specified with
|
||||
* its numeric representation (Port A:0, B:1 etc). Defines for these
|
||||
* numeric representations are GPIO_x_NUM
|
||||
* \param pin Associate \a f with this pin, which is specified by number
|
||||
* (0, 1, ..., 7)
|
||||
*/
|
||||
void gpio_register_callback(gpio_callback_t f, uint8_t port, uint8_t pin);
|
||||
|
||||
#endif /* GPIO_H_ */
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,12 @@ ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
|
|||
ioc_over[(port << 3) + pin] = over;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint32_t
|
||||
ioc_get_over(uint8_t port, uint8_t pin)
|
||||
{
|
||||
return ioc_over[(port << 3) + pin] & 0x0F;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
ioc_set_sel(uint8_t port, uint8_t pin, uint8_t sel)
|
||||
{
|
||||
|
|
|
@ -249,6 +249,22 @@ void ioc_init();
|
|||
*/
|
||||
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over);
|
||||
|
||||
/**
|
||||
* \brief Get Port:Pin override function
|
||||
* \param port The port as a number (PA: 0, PB: 1 etc)
|
||||
* \param pin The pin as a number
|
||||
* \return The override function
|
||||
*
|
||||
* The return value can be one of
|
||||
*
|
||||
* - IOC_OVERRIDE_OE: Output
|
||||
* - IOC_OVERRIDE_PUE: Pull-Up
|
||||
* - IOC_OVERRIDE_PDE: Pull-Down
|
||||
* - IOC_OVERRIDE_ANA: Analog
|
||||
* - IOC_OVERRIDE_DIS: Disabled
|
||||
*/
|
||||
uint32_t ioc_get_over(uint8_t port, uint8_t pin);
|
||||
|
||||
/**
|
||||
* \brief Function select for Port:Pin
|
||||
* \param port The port as a number (PA: 0, PB: 1 etc)
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
* - SPIX_FLUSH(x)
|
||||
*
|
||||
* Some of the old functions and macros are still supported.
|
||||
* When using these deprecated functions, the SSI module to use
|
||||
* When using these deprecated functions, the SSI module to use
|
||||
* has to be be selected by means of the macro SPI_CONF_DEFAULT_INSTANCE.
|
||||
*
|
||||
* This SPI driver depends on the following defines:
|
||||
|
@ -78,8 +78,8 @@
|
|||
* - SPI1_RX_PORT
|
||||
* - SPI1_RX_PIN
|
||||
*/
|
||||
#ifndef SPI_ARCH_H_
|
||||
#define SPI_ARCH_H_
|
||||
#ifndef SPI_ARCH_LEGACY_H_
|
||||
#define SPI_ARCH_LEGACY_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
|
@ -95,14 +95,14 @@
|
|||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Default values for the clock rate divider */
|
||||
#ifdef SPI0_CONF_CPRS_CPSDVSR
|
||||
#define SPI0_CPRS_CPSDVSR SPI0_CONF_CPRS_CPSDVSR
|
||||
#ifdef SPI0_CONF_CPRS_CPSDVSR
|
||||
#define SPI0_CPRS_CPSDVSR SPI0_CONF_CPRS_CPSDVSR
|
||||
#else
|
||||
#define SPI0_CPRS_CPSDVSR 2
|
||||
#endif
|
||||
|
||||
#ifdef SPI1_CONF_CPRS_CPSDVSR
|
||||
#define SPI1_CPRS_CPSDVSR SPI1_CONF_CPRS_CPSDVSR
|
||||
#ifdef SPI1_CONF_CPRS_CPSDVSR
|
||||
#define SPI1_CPRS_CPSDVSR SPI1_CONF_CPRS_CPSDVSR
|
||||
#else
|
||||
#define SPI1_CPRS_CPSDVSR 2
|
||||
#endif
|
||||
|
@ -120,7 +120,7 @@
|
|||
} while(0)
|
||||
#define SPIX_FLUSH(spi) do { \
|
||||
while(REG(SSI_BASE(spi) + SSI_SR) & SSI_SR_RNE) { \
|
||||
SPIX_BUF(spi); \
|
||||
SPIX_BUF(spi); \
|
||||
} \
|
||||
} while(0)
|
||||
#define SPIX_CS_CLR(port, pin) do { \
|
||||
|
@ -138,13 +138,13 @@
|
|||
#define SPI_WAITFOREOTx() SPIX_WAITFOREOTx(SPI_DEFAULT_INSTANCE)
|
||||
#define SPI_WAITFOREORx() SPIX_WAITFOREORx(SPI_DEFAULT_INSTANCE)
|
||||
#ifdef SPI_FLUSH
|
||||
#error You must include spi-arch.h before spi.h for the CC2538
|
||||
#error You must include spi-arch-legacy.h before spi-legacy.h for the CC2538
|
||||
#else
|
||||
#define SPI_FLUSH() SPIX_FLUSH(SPI_DEFAULT_INSTANCE)
|
||||
#endif
|
||||
#define SPI_CS_CLR(port, pin) SPIX_CS_CLR(port, pin)
|
||||
#define SPI_CS_SET(port, pin) SPIX_CS_SET(port, pin)
|
||||
#endif /* #ifdef SPI_DEFAULT_INSTANCE */
|
||||
#endif /* #ifdef SPI_DEFAULT_INSTANCE */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Arch-specific SPI functions
|
||||
* @{
|
||||
|
@ -183,7 +183,7 @@ void spix_disable(uint8_t spi);
|
|||
*
|
||||
* See section 19.4.4 in the CC2538 user guide for more information.
|
||||
*
|
||||
* \param spi The SSI instance to use.
|
||||
* \param spi The SSI instance to use.
|
||||
* \param frame_format Set the SSI frame format. Use SSI_CR0_FRF_MOTOROLA,
|
||||
* SSI_CR0_FRF_TI, or SSI_CR0_FRF_MICROWIRE.
|
||||
* \param clock_polarity In Motorola mode, set whether the clock is high or low
|
||||
|
@ -215,7 +215,7 @@ void spix_cs_init(uint8_t port, uint8_t pin);
|
|||
|
||||
/** @} */
|
||||
|
||||
#endif /* SPI_ARCH_H_ */
|
||||
#endif /* SPI_ARCH_LEGACY_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017, Yanzi Networks.
|
||||
* Copyright (c) 2018, University of Bristol.
|
||||
* 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 HOLDER 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 "contiki.h"
|
||||
#include "reg.h"
|
||||
#include "dev/spi.h"
|
||||
#include "gpio-hal-arch.h"
|
||||
#include "sys/cc.h"
|
||||
#include "ioc.h"
|
||||
#include "sys-ctrl.h"
|
||||
#include "ssi.h"
|
||||
#include "gpio.h"
|
||||
#include "sys/log.h"
|
||||
#include "sys/mutex.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Log configuration */
|
||||
#define LOG_MODULE "spi-hal-arch"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Default values for the clock rate divider */
|
||||
#ifdef SPI_ARCH_CONF_SPI0_CPRS_CPSDVSR
|
||||
#define SPI_ARCH_SPI0_CPRS_CPSDVSR SPI_ARCH_CONF_SPI0_CPRS_CPSDVSR
|
||||
#else
|
||||
#define SPI_ARCH_SPI0_CPRS_CPSDVSR 2
|
||||
#endif
|
||||
|
||||
#ifdef SPI_ARCH_CONF_SPI1_CPRS_CPSDVSR
|
||||
#define SPI_ARCH_SPI1_CPRS_CPSDVSR SPI_ARCH_CONF_SPI1_CPRS_CPSDVSR
|
||||
#else
|
||||
#define SPI_ARCH_SPI1_CPRS_CPSDVSR 2
|
||||
#endif
|
||||
|
||||
#if (SPI_ARCH_SPI0_CPRS_CPSDVSR & 1) == 1 || \
|
||||
SPI_ARCH_SPI0_CPRS_CPSDVSR < 2 || \
|
||||
SPI_ARCH_SPI0_CPRS_CPSDVSR > 254
|
||||
#error SPI_ARCH_SPI0_CPRS_CPSDVSR must be an even number between 2 and 254
|
||||
#endif
|
||||
|
||||
#if (SPI_ARCH_SPI1_CPRS_CPSDVSR & 1) == 1 || \
|
||||
SPI_ARCH_SPI1_CPRS_CPSDVSR < 2 || \
|
||||
SPI_ARCH_SPI1_CPRS_CPSDVSR > 254
|
||||
#error SPI_ARCH_SPI1_CPRS_CPSDVSR must be an even number between 2 and 254
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* CS set and clear macros */
|
||||
#define SPIX_CS_CLR(port, pin) GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin))
|
||||
#define SPIX_CS_SET(port, pin) GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Clock source from which the baud clock is determined for the SSI, according
|
||||
* to SSI_CC.CS.
|
||||
*/
|
||||
#define SSI_SYS_CLOCK SYS_CTRL_SYS_CLOCK
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
uint32_t base;
|
||||
uint32_t ioc_ssirxd_ssi;
|
||||
uint32_t ioc_pxx_sel_ssi_clkout;
|
||||
uint32_t ioc_pxx_sel_ssi_txd;
|
||||
uint8_t ssi_cprs_cpsdvsr;
|
||||
} spi_regs_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const spi_regs_t spi_regs[SSI_INSTANCE_COUNT] = {
|
||||
{
|
||||
.base = SSI0_BASE,
|
||||
.ioc_ssirxd_ssi = IOC_SSIRXD_SSI0,
|
||||
.ioc_pxx_sel_ssi_clkout = IOC_PXX_SEL_SSI0_CLKOUT,
|
||||
.ioc_pxx_sel_ssi_txd = IOC_PXX_SEL_SSI0_TXD,
|
||||
.ssi_cprs_cpsdvsr = SPI_ARCH_SPI0_CPRS_CPSDVSR,
|
||||
}, {
|
||||
.base = SSI1_BASE,
|
||||
.ioc_ssirxd_ssi = IOC_SSIRXD_SSI1,
|
||||
.ioc_pxx_sel_ssi_clkout = IOC_PXX_SEL_SSI1_CLKOUT,
|
||||
.ioc_pxx_sel_ssi_txd = IOC_PXX_SEL_SSI1_TXD,
|
||||
.ssi_cprs_cpsdvsr = SPI_ARCH_SPI1_CPRS_CPSDVSR,
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct spi_locks_s {
|
||||
mutex_t lock;
|
||||
spi_device_t *owner;
|
||||
} spi_locks_t;
|
||||
|
||||
/* One lock per SPI controller */
|
||||
spi_locks_t board_spi_locks_spi[SPI_CONTROLLER_COUNT] = { { MUTEX_STATUS_UNLOCKED, NULL } };
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
spix_wait_tx_ready(spi_device_t *dev)
|
||||
{
|
||||
/* Infinite loop until SR_TNF - Transmit FIFO Not Full */
|
||||
while(!(REG(spi_regs[dev->spi_controller].base + SSI_SR) & SSI_SR_TNF));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
spix_read_buf(spi_device_t *dev)
|
||||
{
|
||||
return REG(spi_regs[dev->spi_controller].base + SSI_DR);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
spix_write_buf(spi_device_t *dev, int data)
|
||||
{
|
||||
REG(spi_regs[dev->spi_controller].base + SSI_DR) = data;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
spix_wait_eotx(spi_device_t *dev)
|
||||
{
|
||||
/* wait until not busy */
|
||||
while(REG(spi_regs[dev->spi_controller].base + SSI_SR) & SSI_SR_BSY);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
spix_wait_eorx(spi_device_t *dev)
|
||||
{
|
||||
/* wait as long as receive is empty */
|
||||
while(!(REG(spi_regs[dev->spi_controller].base + SSI_SR) & SSI_SR_RNE));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
spi_arch_has_lock(spi_device_t *dev)
|
||||
{
|
||||
if(board_spi_locks_spi[dev->spi_controller].owner == dev) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
spi_arch_is_bus_locked(spi_device_t *dev)
|
||||
{
|
||||
if(board_spi_locks_spi[dev->spi_controller].lock == MUTEX_STATUS_LOCKED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_lock_and_open(spi_device_t *dev)
|
||||
{
|
||||
const spi_regs_t *regs;
|
||||
uint32_t scr;
|
||||
uint64_t div;
|
||||
|
||||
uint32_t cs_port = PIN_TO_PORT(dev->pin_spi_cs);
|
||||
uint32_t cs_pin = PIN_TO_NUM(dev->pin_spi_cs);
|
||||
|
||||
uint32_t clk_port = PIN_TO_PORT(dev->pin_spi_sck);
|
||||
uint32_t clk_pin = PIN_TO_NUM(dev->pin_spi_sck);
|
||||
|
||||
uint32_t miso_port = PIN_TO_PORT(dev->pin_spi_miso);
|
||||
uint32_t miso_pin = PIN_TO_NUM(dev->pin_spi_miso);
|
||||
|
||||
uint32_t mosi_port = PIN_TO_PORT(dev->pin_spi_mosi);
|
||||
uint32_t mosi_pin = PIN_TO_NUM(dev->pin_spi_mosi);
|
||||
|
||||
uint32_t mode = 0;
|
||||
|
||||
/* lock the SPI bus */
|
||||
if(mutex_try_lock(&board_spi_locks_spi[dev->spi_controller].lock) == false) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
|
||||
board_spi_locks_spi[dev->spi_controller].owner = dev;
|
||||
|
||||
/* Set SPI phase */
|
||||
if(dev->spi_pha != 0) {
|
||||
mode = mode | SSI_CR0_SPH;
|
||||
}
|
||||
|
||||
/* Set SPI polarity */
|
||||
if(dev->spi_pol != 0) {
|
||||
mode = mode | SSI_CR0_SPO;
|
||||
}
|
||||
|
||||
/* CS pin configuration */
|
||||
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(cs_port),
|
||||
GPIO_PIN_MASK(cs_pin));
|
||||
ioc_set_over(cs_port, cs_pin, IOC_OVERRIDE_DIS);
|
||||
GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(cs_port), GPIO_PIN_MASK(cs_pin));
|
||||
GPIO_SET_PIN(GPIO_PORT_TO_BASE(cs_port), GPIO_PIN_MASK(cs_pin));
|
||||
|
||||
regs = &spi_regs[dev->spi_controller];
|
||||
|
||||
/* SSI Enable */
|
||||
REG(SYS_CTRL_RCGCSSI) |= (1 << dev->spi_controller);
|
||||
|
||||
/* Start by disabling the peripheral before configuring it */
|
||||
REG(regs->base + SSI_CR1) = 0;
|
||||
|
||||
/* Set the system clock as the SSI clock */
|
||||
REG(regs->base + SSI_CC) = 0;
|
||||
|
||||
/* Set the mux correctly to connect the SSI pins to the correct GPIO pins */
|
||||
ioc_set_sel(clk_port, clk_pin, regs->ioc_pxx_sel_ssi_clkout);
|
||||
ioc_set_sel(mosi_port, mosi_pin, regs->ioc_pxx_sel_ssi_txd);
|
||||
REG(regs->ioc_ssirxd_ssi) = dev->pin_spi_miso;
|
||||
|
||||
/* Put all the SSI gpios into peripheral mode */
|
||||
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(clk_port),
|
||||
GPIO_PIN_MASK(clk_pin));
|
||||
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(mosi_port),
|
||||
GPIO_PIN_MASK(mosi_pin));
|
||||
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(miso_port),
|
||||
GPIO_PIN_MASK(miso_pin));
|
||||
|
||||
/* Disable any pull ups or the like */
|
||||
ioc_set_over(clk_port, clk_pin, IOC_OVERRIDE_DIS);
|
||||
ioc_set_over(mosi_port, mosi_pin, IOC_OVERRIDE_DIS);
|
||||
ioc_set_over(miso_port, miso_pin, IOC_OVERRIDE_DIS);
|
||||
|
||||
/* Configure the clock */
|
||||
REG(regs->base + SSI_CPSR) = regs->ssi_cprs_cpsdvsr;
|
||||
|
||||
/* Configure the mode */
|
||||
REG(regs->base + SSI_CR0) = mode | (0x07);
|
||||
|
||||
/* Configure the SSI serial clock rate */
|
||||
if(!dev->spi_bit_rate) {
|
||||
scr = 255;
|
||||
} else {
|
||||
div = (uint64_t)regs->ssi_cprs_cpsdvsr * dev->spi_bit_rate;
|
||||
scr = (SSI_SYS_CLOCK + div - 1) / div;
|
||||
scr = MIN(MAX(scr, 1), 256) - 1;
|
||||
}
|
||||
REG(regs->base + SSI_CR0) = (REG(regs->base + SSI_CR0) & ~SSI_CR0_SCR_M) |
|
||||
scr << SSI_CR0_SCR_S;
|
||||
|
||||
/* Enable the SSI */
|
||||
REG(regs->base + SSI_CR1) |= SSI_CR1_SSE;
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_close_and_unlock(spi_device_t *dev)
|
||||
{
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
/* Disable SSI */
|
||||
REG(SYS_CTRL_RCGCSSI) &= ~(1 << dev->spi_controller);
|
||||
|
||||
/* Unlock the SPI bus */
|
||||
board_spi_locks_spi[dev->spi_controller].owner = NULL;
|
||||
mutex_unlock(&board_spi_locks_spi[dev->spi_controller].lock);
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_select(spi_device_t *dev)
|
||||
{
|
||||
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
SPIX_CS_CLR(PIN_TO_PORT(dev->pin_spi_cs), PIN_TO_NUM(dev->pin_spi_cs));
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_deselect(spi_device_t *dev)
|
||||
{
|
||||
SPIX_CS_SET(PIN_TO_PORT(dev->pin_spi_cs), PIN_TO_NUM(dev->pin_spi_cs));
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Assumes that checking dev and bus is not NULL before calling this */
|
||||
spi_status_t
|
||||
spi_arch_transfer(spi_device_t *dev,
|
||||
const uint8_t *write_buf, int wlen,
|
||||
uint8_t *inbuf, int rlen, int ignore_len)
|
||||
{
|
||||
int i;
|
||||
int totlen;
|
||||
uint8_t c;
|
||||
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
LOG_DBG("SPI: transfer (r:%d,w:%d) ", rlen, wlen);
|
||||
|
||||
if(write_buf == NULL && wlen > 0) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
if(inbuf == NULL && rlen > 0) {
|
||||
return SPI_DEV_STATUS_EINVAL;
|
||||
}
|
||||
|
||||
totlen = MAX(rlen + ignore_len, wlen);
|
||||
|
||||
if(totlen == 0) {
|
||||
/* Nothing to do */
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
|
||||
LOG_DBG_("%c%c%c: %u ", rlen > 0 ? 'R' : '-', wlen > 0 ? 'W' : '-',
|
||||
ignore_len > 0 ? 'S' : '-', totlen);
|
||||
|
||||
for(i = 0; i < totlen; i++) {
|
||||
spix_wait_tx_ready(dev);
|
||||
c = i < wlen ? write_buf[i] : 0;
|
||||
spix_write_buf(dev, c);
|
||||
LOG_DBG_("%c%02x->", i < rlen ? ' ' : '#', c);
|
||||
spix_wait_eotx(dev);
|
||||
spix_wait_eorx(dev);
|
||||
c = spix_read_buf(dev);
|
||||
if(i < rlen) {
|
||||
inbuf[i] = c;
|
||||
}
|
||||
LOG_DBG_("%02x", c);
|
||||
}
|
||||
LOG_DBG_("\n");
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -39,11 +39,11 @@
|
|||
*/
|
||||
#include "contiki.h"
|
||||
#include "reg.h"
|
||||
#include "spi-arch.h"
|
||||
#include "dev/spi-arch-legacy.h"
|
||||
#include "sys/cc.h"
|
||||
#include "dev/ioc.h"
|
||||
#include "dev/sys-ctrl.h"
|
||||
#include "dev/spi.h"
|
||||
#include "dev/spi-legacy.h"
|
||||
#include "dev/ssi.h"
|
||||
#include "dev/gpio.h"
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* \defgroup cc2538 The TI CC2538 System-on-Chip
|
||||
*
|
||||
* CPU-Specific functionality - available to all cc2538-based platforms
|
||||
*
|
||||
* \ingroup cpu
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup cc2538-platforms TI CC2538-powered platforms
|
||||
*
|
||||
* Documentation for all platforms powered by the TI cc2538 System-on-Chip
|
||||
* \ingroup platform
|
||||
*/
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* 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
|
||||
|
@ -29,35 +30,51 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup sensortag-cc26xx-peripherals
|
||||
* \addtogroup cc2538
|
||||
* @{
|
||||
*
|
||||
* \defgroup sensortag-cc26xx-button-sensor SensorTag 2.0 Button Sensor
|
||||
* \defgroup cc2538-interrupts CC2538 master interrupt manipulation
|
||||
*
|
||||
* Master interrupt manipulation routines for the CC2538 CPU
|
||||
*
|
||||
* One of the buttons can be configured as general purpose or as an on/off key
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the Sensortag Button Driver
|
||||
* Master interrupt manipulation implementation for the TI CC2538
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef BUTTON_SENSOR_H_
|
||||
#define BUTTON_SENSOR_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "lib/sensors.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BUTTON_SENSOR "Button"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BUTTON_SENSOR_VALUE_STATE 0
|
||||
#define BUTTON_SENSOR_VALUE_DURATION 1
|
||||
#include "contiki.h"
|
||||
#include "sys/int-master.h"
|
||||
|
||||
#define BUTTON_SENSOR_VALUE_RELEASED 0
|
||||
#define BUTTON_SENSOR_VALUE_PRESSED 1
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern const struct sensors_sensor button_left_sensor;
|
||||
extern const struct sensors_sensor button_right_sensor;
|
||||
void
|
||||
int_master_enable(void)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* BUTTON_SENSOR_H_ */
|
||||
int_master_status_t
|
||||
int_master_read_and_disable(void)
|
||||
{
|
||||
int_master_status_t primask = __get_PRIMASK();
|
||||
|
||||
__disable_irq();
|
||||
|
||||
return primask;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
int_master_status_set(int_master_status_t status)
|
||||
{
|
||||
__set_PRIMASK(status);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
int_master_is_enabled(void)
|
||||
{
|
||||
return __get_PRIMASK() ? false : true;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
|
@ -61,7 +61,7 @@
|
|||
#define DEEP_SLEEP_PM1_THRESHOLD 10
|
||||
#define DEEP_SLEEP_PM2_THRESHOLD 100
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define assert_wfi() do { asm("wfi"::); } while(0)
|
||||
#define assert_wfi() do { __asm("wfi"::); } while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if LPM_CONF_STATS
|
||||
rtimer_clock_t lpm_stats[3];
|
||||
|
@ -212,10 +212,14 @@ lpm_exit()
|
|||
/* Restore system clock to the 32 MHz XOSC */
|
||||
select_32_mhz_xosc();
|
||||
|
||||
if((REG(SYS_CTRL_PMCTL) & SYS_CTRL_PMCTL_PM3) == SYS_CTRL_PMCTL_PM1) {
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
} else {
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_DEEP_LPM, ENERGEST_TYPE_CPU);
|
||||
}
|
||||
|
||||
/* Restore PMCTL to PM0 for next pass */
|
||||
REG(SYS_CTRL_PMCTL) = SYS_CTRL_PMCTL_PM0;
|
||||
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -286,8 +290,6 @@ lpm_enter()
|
|||
REG(SYS_CTRL_PMCTL) = SYS_CTRL_PMCTL_PM1;
|
||||
}
|
||||
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
|
||||
|
||||
/* Remember the current time so we can keep stats when we wake up */
|
||||
if(LPM_CONF_STATS) {
|
||||
sleep_enter_time = RTIMER_NOW();
|
||||
|
@ -310,9 +312,13 @@ lpm_enter()
|
|||
|
||||
REG(SYS_CTRL_PMCTL) = SYS_CTRL_PMCTL_PM0;
|
||||
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
} else {
|
||||
/* All clear. Assert WFI and drop to PM1/2. This is now un-interruptible */
|
||||
if((REG(SYS_CTRL_PMCTL) & SYS_CTRL_PMCTL_PM3) == SYS_CTRL_PMCTL_PM1) {
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
|
||||
} else {
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_DEEP_LPM);
|
||||
}
|
||||
assert_wfi();
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,6 @@
|
|||
#include "contiki.h"
|
||||
#include "dev/gptimer.h"
|
||||
|
||||
#define RTIMER_ARCH_SECOND 32768
|
||||
|
||||
/* Do the math in 32bits to save precision.
|
||||
* Round to nearest integer rather than truncate. */
|
||||
#define US_TO_RTIMERTICKS(US) ((US) >= 0 ? \
|
||||
|
|
|
@ -28,21 +28,12 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc2538-char-io
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Arch-specific SLIP functions for the cc2538
|
||||
*
|
||||
* SLIP can be configured to operate over UART or over USB-Serial, depending
|
||||
* on the value of SLIP_ARCH_CONF_USB
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "dev/slip.h"
|
||||
#include "dev/uart.h"
|
||||
#include "usb/usb-serial.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef SLIP_ARCH_CONF_USB
|
||||
#define SLIP_ARCH_CONF_USB 0
|
||||
#endif
|
||||
|
@ -59,10 +50,6 @@
|
|||
|
||||
#define SLIP_END 0300
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Write a byte over SLIP
|
||||
* \param c the byte
|
||||
*/
|
||||
void
|
||||
slip_arch_writeb(unsigned char c)
|
||||
{
|
||||
|
@ -72,14 +59,9 @@ slip_arch_writeb(unsigned char c)
|
|||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initialise the arch-specific SLIP driver
|
||||
*/
|
||||
void
|
||||
slip_arch_init()
|
||||
{
|
||||
set_input(slip_input_byte);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "dev/ioc.h"
|
||||
#include "dev/nvic.h"
|
||||
#include "dev/sys-ctrl.h"
|
||||
#include "dev/gpio-hal.h"
|
||||
#include "lpm.h"
|
||||
#include "reg.h"
|
||||
#include "soc.h"
|
||||
|
@ -123,7 +124,7 @@ soc_init()
|
|||
clock_init();
|
||||
lpm_init();
|
||||
rtimer_init();
|
||||
gpio_init();
|
||||
gpio_hal_init();
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -52,8 +52,6 @@ void nmi_handler(void);
|
|||
void default_handler(void);
|
||||
|
||||
/* System Handler and ISR prototypes implemented elsewhere */
|
||||
void svcall_handler(void); /* See mtarch.c */
|
||||
void pendsv_handler(void); /* See mtarch.c */
|
||||
void clock_isr(void); /* SysTick Handler */
|
||||
void gpio_port_a_isr(void);
|
||||
void gpio_port_b_isr(void);
|
||||
|
@ -121,10 +119,10 @@ void(*const vectors[])(void) =
|
|||
0, /* 8 Reserved */
|
||||
0, /* 9 Reserved */
|
||||
0, /* 10 Reserved */
|
||||
svcall_handler, /* 11 SVCall handler */
|
||||
default_handler, /* 11 SVCall handler */
|
||||
default_handler, /* 12 Debug monitor handler */
|
||||
0, /* 13 Reserved */
|
||||
pendsv_handler, /* 14 The PendSV handler */
|
||||
default_handler, /* 14 The PendSV handler */
|
||||
clock_isr, /* 15 The SysTick handler */
|
||||
gpio_port_a_isr, /* 16 GPIO Port A */
|
||||
gpio_port_b_isr, /* 17 GPIO Port B */
|
||||
|
|
|
@ -161,7 +161,7 @@ const struct configuration_st {
|
|||
|
||||
};
|
||||
|
||||
const struct usb_st_configuration_descriptor const *configuration_head =
|
||||
(struct usb_st_configuration_descriptor const *)&configuration_block;
|
||||
const struct usb_st_configuration_descriptor* const configuration_head =
|
||||
(const struct usb_st_configuration_descriptor*)&configuration_block;
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
#endif
|
||||
|
||||
extern const struct usb_st_device_descriptor device_descriptor;
|
||||
extern const struct usb_st_configuration_descriptor const *configuration_head;
|
||||
extern const struct usb_st_configuration_descriptor* const configuration_head;
|
||||
#endif /* DESCRIPTORS_H_RPFUB8O7OV__ */
|
||||
|
|
|
@ -1,13 +1,3 @@
|
|||
CC = arm-none-eabi-gcc
|
||||
CPP = arm-none-eabi-cpp
|
||||
LD = arm-none-eabi-gcc
|
||||
AR = arm-none-eabi-ar
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
OBJDUMP = arm-none-eabi-objdump
|
||||
NM = arm-none-eabi-nm
|
||||
SIZE = arm-none-eabi-size
|
||||
SREC_CAT = srec_cat
|
||||
|
||||
CPU_ABS_PATH = arch/cpu/cc26xx-cc13xx
|
||||
TI_XXWARE = $(CONTIKI_CPU)/$(TI_XXWARE_PATH)
|
||||
|
||||
|
@ -29,59 +19,30 @@ MODULES += $(TI_XXWARE_SRC)
|
|||
|
||||
LDSCRIPT = $(CONTIKI_CPU)/cc26xx.ld
|
||||
|
||||
CFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing
|
||||
CFLAGS += -Wall -std=c99
|
||||
|
||||
LDFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian -nostartfiles
|
||||
LDFLAGS += -T $(LDSCRIPT)
|
||||
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
||||
LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch
|
||||
OBJCOPY_FLAGS += -O binary --gap-fill 0xff
|
||||
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
|
||||
|
||||
ifeq ($(WERROR),1)
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
### Are we building with code size optimisations?
|
||||
SMALL ?= 1
|
||||
ifeq ($(SMALL),1)
|
||||
CFLAGS += -Os
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
|
||||
### If the user-specified a Node ID, pass a define
|
||||
ifdef NODEID
|
||||
CFLAGS += -DIEEE_ADDR_NODE_ID=$(NODEID)
|
||||
endif
|
||||
|
||||
### CPU-dependent cleanup files
|
||||
CLEAN += *.d *.elf *.hex
|
||||
|
||||
### CPU-dependent directories
|
||||
CONTIKI_CPU_DIRS = . dev rf-core rf-core/api $(TI_XXWARE_STARTUP_DIR)
|
||||
|
||||
### Use the existing debug I/O in arch/cpu/arm/common
|
||||
CONTIKI_CPU_DIRS += ../arm/common/dbg-io
|
||||
CONTIKI_CPU_DIRS += . dev rf-core rf-core/api rf-core/ble-hal $(TI_XXWARE_STARTUP_DIR)
|
||||
|
||||
### CPU-dependent source files
|
||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c
|
||||
CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c aux-ctrl.c
|
||||
CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c adc-sensor.c
|
||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c batmon-sensor.c adc-sensor.c
|
||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c
|
||||
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c
|
||||
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c gpio-hal-arch.c oscillators.c
|
||||
CONTIKI_CPU_SOURCEFILES += rf-core.c rf-ble.c ieee-mode.c
|
||||
CONTIKI_CPU_SOURCEFILES += random.c soc-trng.c
|
||||
CONTIKI_CPU_SOURCEFILES += ble-cc2650.c ble-hal-cc26xx.c ble-addr.c rf-ble-cmd.c
|
||||
CONTIKI_CPU_SOURCEFILES += random.c soc-trng.c int-master.c
|
||||
CONTIKI_CPU_SOURCEFILES += spi-arch.c
|
||||
|
||||
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
|
||||
MODULES += os/lib/dbg-io
|
||||
|
||||
CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES)
|
||||
CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES)
|
||||
|
||||
TARGET_START_SOURCEFILES += fault-handlers.c $(TI_XXWARE_STARTUP_SRCS)
|
||||
TARGET_STARTFILES = $(addprefix $(OBJECTDIR)/,$(call oname, $(TARGET_START_SOURCEFILES)))
|
||||
CPU_START_SOURCEFILES += fault-handlers.c $(TI_XXWARE_STARTUP_SRCS)
|
||||
|
||||
PYTHON = python
|
||||
BSL_FLAGS += -e -w -v
|
||||
|
@ -92,9 +53,6 @@ endif
|
|||
|
||||
BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py
|
||||
|
||||
### Don't treat the .elf as intermediate
|
||||
.PRECIOUS: %.elf %.hex %.bin
|
||||
|
||||
### Always re-build ieee-addr.o in case the command line passes a new NODEID
|
||||
FORCE:
|
||||
|
||||
|
@ -106,31 +64,7 @@ $(OBJECTDIR)/ieee-addr.o: ieee-addr.c FORCE | $(OBJECTDIR)
|
|||
### to make clean first
|
||||
$(OBJECTDIR)/ccfg.o: ccfg.c FORCE | $(OBJECTDIR)
|
||||
$(TRACE_CC)
|
||||
$(Q)$(CC) $(CFLAGS) -include "contiki-conf.h" -c $< -o $@
|
||||
|
||||
### Compilation rules
|
||||
CUSTOM_RULE_LINK=1
|
||||
|
||||
%.elf: $(TARGET_STARTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(LDSCRIPT)
|
||||
$(TRACE_LD)
|
||||
$(Q)$(LD) $(LDFLAGS) ${filter-out $(LDSCRIPT) %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -lm -o $@
|
||||
|
||||
%.i16hex: %.elf
|
||||
$(OBJCOPY) -O ihex $< $@
|
||||
|
||||
%.hex: %.i16hex
|
||||
$(SREC_CAT) $< -intel -o $@ -intel
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@
|
||||
|
||||
%.lst: %.elf
|
||||
$(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@
|
||||
|
||||
### We don't really need the .hex and .bin for the .$(TARGET) but let's make
|
||||
### sure they get built
|
||||
%.$(TARGET): %.elf %.hex %.bin
|
||||
cp $< $@
|
||||
$(Q)$(CC) $(CFLAGS) -include "ccxxware-conf.h" -c $< -o $@
|
||||
|
||||
# a target that gives a user-friendly memory profile, taking into account the RAM
|
||||
# that is statically occupied by the stack as defined in the linker script
|
||||
|
@ -170,3 +104,5 @@ UART_BAUDRATE = 115200
|
|||
|
||||
login:
|
||||
$(SERIALDUMP) -b$(UART_BAUDRATE) $(PORT)
|
||||
|
||||
include $(CONTIKI)/arch/cpu/arm/cortex-m/cm3/Makefile.cm3
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Michael Spoerk
|
||||
* 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
|
||||
* Driver for the retrieval of an BLE address from flash
|
||||
*
|
||||
* \author
|
||||
* Michael Spoerk <mi.spoerk@gmail.com>
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
||||
#include "net/linkaddr.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "ble-addr.h"
|
||||
#include "os/dev/ble-hal.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
ble_addr_cpy_to(uint8_t *dst)
|
||||
{
|
||||
int i;
|
||||
uint8_t *location = (uint8_t *)BLE_ADDR_LOCATION;
|
||||
|
||||
for(i = 0; i < BLE_ADDR_SIZE; i++) {
|
||||
dst[i] = location[BLE_ADDR_SIZE - 1 - i];
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
ble_addr_to_eui64(uint8_t *dst, uint8_t *src)
|
||||
{
|
||||
memcpy(dst, src, 3);
|
||||
dst[3] = 0xFF;
|
||||
dst[4] = 0xFE;
|
||||
memcpy(&dst[5], &src[3], 3);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
ble_eui64_addr_cpy_to(uint8_t *dst)
|
||||
{
|
||||
uint8_t ble_addr[BLE_ADDR_SIZE];
|
||||
ble_addr_cpy_to(ble_addr);
|
||||
ble_addr_to_eui64(dst, ble_addr);
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Michael Spoerk
|
||||
* 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
|
||||
* Driver for the retrieval of an BLE address from flash
|
||||
*
|
||||
* \author
|
||||
* Michael Spoerk <mi.spoerk@gmail.com>
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef BLE_ADDR_H_
|
||||
#define BLE_ADDR_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* primary BLE address location */
|
||||
#define BLE_ADDR_LOCATION 0x500012E8
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Copy the node's factory BLE address to a destination memory area
|
||||
* \param dst A pointer to the destination area where the BLE address is to be
|
||||
* written
|
||||
*
|
||||
* This function will copy 6 bytes and it will invert byte order in
|
||||
* the process. The factory address on devices is normally little-endian,
|
||||
* therefore you should expect dst to store the address in a big-endian order.
|
||||
*/
|
||||
void ble_addr_cpy_to(uint8_t *dst);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Copy the node's BLE address to a destination memory area and converts
|
||||
* it into a EUI64 address in the process
|
||||
* \param dst A pointer to the destination area where the EUI64 address is to be
|
||||
* written
|
||||
* \param src A pointer to the BLE address that is to be copied
|
||||
*/
|
||||
void ble_addr_to_eui64(uint8_t *dst, uint8_t *src);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Copy the node's EUI64 address that is based on its factory BLE address
|
||||
* to a destination memory area
|
||||
* \param dst A pointer to the destination area where the EUI64 address is to be
|
||||
* written
|
||||
*/
|
||||
void ble_eui64_addr_cpy_to(uint8_t *dst);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* BLE_ADDR_H_ */
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Template:
|
||||
* Copyright (c) 2012 ARM LIMITED
|
||||
* All rights reserved.
|
||||
*
|
||||
* CC13xx-CC26xx:
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-cm3 CC13xx/CC26xx CMSIS
|
||||
*
|
||||
* CC13xx/CC26xx Cortex-M3 CMSIS definitions
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* CMSIS Cortex-M3 core peripheral access layer header file for CC13xx/CC26xx
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef CC13XX_CC26XX_CM3_H_
|
||||
#define CC13XX_CC26XX_CM3_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Interrupt Number Definition
|
||||
* @{
|
||||
*/
|
||||
typedef enum cc13xx_cc26xx_cm3_irq_e {
|
||||
/* Cortex-M3 Processor Exceptions */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_RESET = -15, /**< 1 Reset */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_NMI = -14, /**< 2 NMI */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_HARD_FAULT = -13, /**< 3 Hard fault */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_MPU_FAULT = -12, /**< 4 MPU fault */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_BUS_FAULT = -11, /**< 5 Bus fault */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_USAGE_FAULT = -10, /**< 6 Usage fault */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_SV_CALL = -5, /**< 11 SVCall */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_DEBUG_MON = -4, /**< 12 Debug monitor */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_PEND_SV = -2, /**< 14 PendSV */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_SYS_TICK = -1, /**< 15 SysTick */
|
||||
|
||||
/* CC13xx/CC26xx interrupts */
|
||||
CC13XX_CC26XX_CM3_IRQ_EDGE_DETECT = 0, /**< 16 AON edge detect */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_I2C = 1, /**< 17 I2C */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_RF_CPE1 = 2, /**< 18 RF Command and Packet Engine 1 */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AON_SPI_SLAVE = 3, /**< 19 AON SpiSplave Rx, Tx and CS */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AON_RTC = 4, /**< 20 AON RTC */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_UART0 = 5, /**< 21 UART0 Rx and Tx */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AON_AUX_SWEV0 = 6, /**< 22 Sensor Controller software event 0, through AON domain*/
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_SSI0 = 7, /**< 23 SSI0 Rx and Tx */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_SSI1 = 8, /**< 24 SSI1 Rx and Tx */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_RF_CPE0 = 9, /**< 25 RF Command and Packet Engine 0 */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_RF_HW = 10, /**< 26 RF Core Hardware */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_RF_CMD_ACK = 11, /**< 27 RF Core Command Acknowledge */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_I2S = 12, /**< 28 I2S */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AON_AUX_SWEV1 = 13, /**< 29 Sensor Controller software event 1, through AON domain*/
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_WATCHDOG = 14, /**< 30 Watchdog timer */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_0A = 15, /**< 31 Timer 0 subtimer A */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_0B = 16, /**< 32 Timer 0 subtimer B */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_1A = 17, /**< 33 Timer 1 subtimer A */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_1B = 18, /**< 34 Timer 1 subtimer B */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_2A = 19, /**< 35 Timer 2 subtimer A */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_2B = 20, /**< 36 Timer 2 subtimer B */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_3A = 21, /**< 37 Timer 3 subtimer A */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_GPTIMER_3B = 22, /**< 38 Timer 3 subtimer B */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_CRYPTO = 23, /**< 39 Crypto Core Result available */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_UDMA = 24, /**< 40 uDMA Software */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_UDMA_ERR = 25, /**< 41 uDMA Error */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_FLASH_CTRL = 26, /**< 42 Flash controller */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_SW0 = 27, /**< 43 Software Event 0 */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AUX_COM_EVENT = 28, /**< 44 AUX combined event, directly to MCU domain*/
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AON_PRG0 = 29, /**< 45 AON programmable 0 */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_PROG = 30, /**< 46 Dynamic Programmable interrupt (default source: PRCM)*/
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AUX_COMPA = 31, /**< 47 AUX Comparator A */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_AUX_ADC = 32, /**< 48 AUX ADC IRQ */
|
||||
CC13XX_CC26XX_CM3_EXCEPTION_TRNG = 33, /**< 49 TRNG event */
|
||||
} cc13xx_cc26xx_cm3_irq_t;
|
||||
|
||||
typedef cc13xx_cc26xx_cm3_irq_t IRQn_Type;
|
||||
|
||||
#define SysTick_IRQn CC13XX_CC26XX_CM3_EXCEPTION_SYS_TICK
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Processor and Core Peripheral Section
|
||||
* @{
|
||||
*/
|
||||
/* Configuration of the Cortex-M3 Processor and Core Peripherals */
|
||||
#define __MPU_PRESENT 1 /**< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 3 /**< Number of Bits used for Priority Levels */
|
||||
#define __Vendor_SysTickConfig 0 /**< Set to 1 if different SysTick Config is used */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC13XX_CC26XX_CM3_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header with configuration defines common to all CC13xx/CC26xx platforms
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef CC13XX_CC26XX_CONF_H_
|
||||
#define CC13XX_CC26XX_CONF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Network Stack Configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* If set, the systems keeps the HF crystal oscillator on even when the radio is off.
|
||||
* You need to set this to 1 to use TSCH with its default 2.2ms or larger guard time.
|
||||
*/
|
||||
#ifndef CC2650_FAST_RADIO_STARTUP
|
||||
#define CC2650_FAST_RADIO_STARTUP (MAC_CONF_WITH_TSCH)
|
||||
#endif
|
||||
|
||||
#ifdef RF_CHANNEL
|
||||
#define RF_CORE_CONF_CHANNEL RF_CHANNEL
|
||||
#endif
|
||||
|
||||
#ifndef RF_CORE_CONF_CHANNEL
|
||||
#define RF_CORE_CONF_CHANNEL 25
|
||||
#endif
|
||||
|
||||
/* Number of Prop Mode RX buffers */
|
||||
#ifndef PROP_MODE_CONF_RX_BUF_CNT
|
||||
#define PROP_MODE_CONF_RX_BUF_CNT 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Auto-configure Prop-mode radio if we are running on CC13xx, unless the
|
||||
* project has specified otherwise. Depending on the final mode, determine a
|
||||
* default channel (again, if unspecified) and configure RDC params
|
||||
*/
|
||||
#if CPU_FAMILY_CC13XX
|
||||
#ifndef CC13XX_CONF_PROP_MODE
|
||||
#define CC13XX_CONF_PROP_MODE 1
|
||||
#endif /* CC13XX_CONF_PROP_MODE */
|
||||
#endif /* CPU_FAMILY_CC13XX */
|
||||
|
||||
#if CC13XX_CONF_PROP_MODE
|
||||
#define NETSTACK_CONF_RADIO prop_mode_driver
|
||||
|
||||
#ifndef RF_CORE_CONF_CHANNEL
|
||||
#define RF_CORE_CONF_CHANNEL 0
|
||||
#endif
|
||||
|
||||
#define CSMA_CONF_ACK_WAIT_TIME (RTIMER_SECOND / 400)
|
||||
#define CSMA_CONF_AFTER_ACK_DETECTED_WAIT_TIME (RTIMER_SECOND / 1000)
|
||||
#define CSMA_CONF_SEND_SOFT_ACK 1
|
||||
|
||||
#else /* CC13XX_CONF_PROP_MODE */
|
||||
#ifndef NETSTACK_CONF_RADIO
|
||||
#define NETSTACK_CONF_RADIO ieee_mode_driver
|
||||
#endif
|
||||
|
||||
#define CSMA_CONF_SEND_SOFT_ACK 0
|
||||
#endif /* CC13XX_CONF_PROP_MODE */
|
||||
|
||||
#define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125
|
||||
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name IEEE address configuration
|
||||
*
|
||||
* Used to generate our link-local & IPv6 address
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Location of the IEEE address
|
||||
* 0 => Read from InfoPage,
|
||||
* 1 => Use a hardcoded address, configured by IEEE_ADDR_CONF_ADDRESS
|
||||
*/
|
||||
#ifndef IEEE_ADDR_CONF_HARDCODED
|
||||
#define IEEE_ADDR_CONF_HARDCODED 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The hardcoded IEEE address to be used when IEEE_ADDR_CONF_HARDCODED
|
||||
* is defined as 1
|
||||
*/
|
||||
#ifndef IEEE_ADDR_CONF_ADDRESS
|
||||
#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF }
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name RF configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/* RF Config */
|
||||
|
||||
#ifndef IEEE_MODE_CONF_AUTOACK
|
||||
#define IEEE_MODE_CONF_AUTOACK 1 /**< RF H/W generates ACKs */
|
||||
#endif
|
||||
|
||||
#ifndef IEEE_MODE_CONF_PROMISCOUS
|
||||
#define IEEE_MODE_CONF_PROMISCOUS 0 /**< 1 to enable promiscous mode */
|
||||
#endif
|
||||
|
||||
#ifndef RF_BLE_CONF_ENABLED
|
||||
#define RF_BLE_CONF_ENABLED 0 /**< 0 to disable BLE support */
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Character I/O Configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef CC26XX_UART_CONF_ENABLE
|
||||
#define CC26XX_UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */
|
||||
#endif
|
||||
|
||||
#ifndef CC26XX_UART_CONF_BAUD_RATE
|
||||
#define CC26XX_UART_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */
|
||||
#endif
|
||||
|
||||
/* Enable I/O over the Debugger Devpack - Only relevant for the SensorTag */
|
||||
#ifndef BOARD_CONF_DEBUGGER_DEVPACK
|
||||
#define BOARD_CONF_DEBUGGER_DEVPACK 1
|
||||
#endif
|
||||
|
||||
#ifndef SLIP_ARCH_CONF_ENABLED
|
||||
/*
|
||||
* Determine whether we need SLIP
|
||||
* This will keep working while UIP_FALLBACK_INTERFACE and CMD_CONF_OUTPUT
|
||||
* keep using SLIP
|
||||
*/
|
||||
#if defined(UIP_FALLBACK_INTERFACE) || defined(CMD_CONF_OUTPUT)
|
||||
#define SLIP_ARCH_CONF_ENABLED 1
|
||||
#endif
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name JTAG interface configuration
|
||||
*
|
||||
* Enable/Disable the JTAG DAP and TAP interfaces on the chip.
|
||||
* Setting this to 0 will disable access to the debug interface
|
||||
* to secure deployed images.
|
||||
* @{
|
||||
*/
|
||||
#ifndef CCXXWARE_CONF_JTAG_INTERFACE_ENABLE
|
||||
#define CCXXWARE_CONF_JTAG_INTERFACE_ENABLE 1
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name ROM Bootloader configuration
|
||||
*
|
||||
* Enable/Disable the ROM bootloader in your image, if the board supports it.
|
||||
* Look in board.h to choose the DIO and corresponding level that will cause
|
||||
* the chip to enter bootloader mode.
|
||||
* @{
|
||||
*/
|
||||
#ifndef ROM_BOOTLOADER_ENABLE
|
||||
#define ROM_BOOTLOADER_ENABLE 0
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC13XX_CC26XX_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* 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 CC13XX_CC26XX_DEF_H_
|
||||
#define CC13XX_CC26XX_DEF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "cm3/cm3-def.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* TSCH related defines */
|
||||
|
||||
/* Delay between GO signal and SFD */
|
||||
#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(81))
|
||||
/* Delay between GO signal and start listening.
|
||||
* This value is so small because the radio is constantly on within each timeslot. */
|
||||
#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(15))
|
||||
/* Delay between the SFD finishes arriving and it is detected in software. */
|
||||
#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(352))
|
||||
|
||||
/* Timer conversion; radio is running at 4 MHz */
|
||||
#define RADIO_TIMER_SECOND 4000000u
|
||||
#if (RTIMER_SECOND % 256) || (RADIO_TIMER_SECOND % 256)
|
||||
#error RADIO_TO_RTIMER macro must be fixed!
|
||||
#endif
|
||||
#define RADIO_TO_RTIMER(X) ((uint32_t)(((uint64_t)(X) * (RTIMER_SECOND / 256)) / (RADIO_TIMER_SECOND / 256)))
|
||||
#define USEC_TO_RADIO(X) ((X) * 4)
|
||||
|
||||
/* The PHY header (preamble + SFD, 4+1 bytes) duration is equivalent to 10 symbols */
|
||||
#define RADIO_IEEE_802154_PHY_HEADER_DURATION_USEC 160
|
||||
|
||||
/* Do not turn off TSCH within a timeslot: not enough time */
|
||||
#define TSCH_CONF_RADIO_ON_DURING_TIMESLOT 1
|
||||
|
||||
/* Disable TSCH frame filtering */
|
||||
#define TSCH_CONF_HW_FRAME_FILTERING 0
|
||||
|
||||
/* Use hardware timestamps */
|
||||
#ifndef TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS
|
||||
#define TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS 1
|
||||
#define TSCH_CONF_TIMESYNC_REMOVE_JITTER 0
|
||||
#endif
|
||||
|
||||
#ifndef TSCH_CONF_BASE_DRIFT_PPM
|
||||
/* The drift compared to "true" 10ms slots.
|
||||
* Enable adaptive sync to enable compensation for this.
|
||||
* Slot length 10000 usec
|
||||
* 328 ticks
|
||||
* Tick duration 30.517578125 usec
|
||||
* Real slot duration 10009.765625 usec
|
||||
* Target - real duration = -9.765625 usec
|
||||
* TSCH_CONF_BASE_DRIFT_PPM -977
|
||||
*/
|
||||
#define TSCH_CONF_BASE_DRIFT_PPM -977
|
||||
#endif
|
||||
|
||||
/* 10 times per second */
|
||||
#ifndef TSCH_CONF_CHANNEL_SCAN_DURATION
|
||||
#define TSCH_CONF_CHANNEL_SCAN_DURATION (CLOCK_SECOND / 10)
|
||||
#endif
|
||||
|
||||
/* Slightly reduce the TSCH guard time (from 2200 usec to 1800 usec) to make sure
|
||||
* the CC26xx radio has sufficient time to start up. */
|
||||
#ifndef TSCH_CONF_RX_WAIT
|
||||
#define TSCH_CONF_RX_WAIT 1800
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define RTIMER_ARCH_SECOND 65536
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Path to CMSIS header */
|
||||
#define CMSIS_CONF_HEADER_PATH "cc13x0-cc26x0-cm3.h"
|
||||
|
||||
/* Path to headers with implementation of mutexes and memory barriers */
|
||||
#define MUTEX_CONF_ARCH_HEADER_PATH "mutex-cortex.h"
|
||||
#define MEMORY_BARRIER_CONF_ARCH_HEADER_PATH "memory-barrier-cortex.h"
|
||||
|
||||
#define GPIO_HAL_CONF_ARCH_HDR_PATH "dev/gpio-hal-arch.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define GPIO_HAL_CONF_ARCH_SW_TOGGLE 0
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define SPI_CONF_CONTROLLER_COUNT 2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC13XX_CC26XX_DEF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -56,7 +56,7 @@ _estack = ORIGIN(SRAM) + LENGTH(SRAM); /* End of SRAM */
|
|||
|
||||
/*. Generate a link error if heap and stack don’t fit into RAM .*/
|
||||
_Min_Heap_Size = 0;
|
||||
_Min_Stack_Size = 0x100;
|
||||
_Min_Stack_Size = 0x400;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
@ -90,6 +90,12 @@ SECTIONS
|
|||
_ebss = .;
|
||||
} > SRAM
|
||||
|
||||
_end = .; /* End of the .bss segment. */
|
||||
|
||||
/* These symbols are used by the stack check library. */
|
||||
_stack = .;
|
||||
_stack_origin = ORIGIN(SRAM) + LENGTH(SRAM);
|
||||
|
||||
.ccfg :
|
||||
{
|
||||
KEEP(*(.ccfg))
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Alex Stanoev
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-ccxxware-conf CCxxware-specific configuration
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* CCxxware-specific configuration for the cc26xx-cc13xx CPU family
|
||||
*/
|
||||
#ifndef CCXXWARE_CONF_H_
|
||||
#define CCXXWARE_CONF_H_
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief JTAG interface configuration
|
||||
*
|
||||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
#if CCXXWARE_CONF_JTAG_INTERFACE_ENABLE
|
||||
#define SET_CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE 0xC5
|
||||
#define SET_CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE 0xC5
|
||||
#define SET_CCFG_CCFG_TAP_DAP_0_PRCM_TAP_ENABLE 0xC5
|
||||
#define SET_CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE 0xC5
|
||||
#define SET_CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE 0xC5
|
||||
#define SET_CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE 0xC5
|
||||
#define SET_CCFG_CCFG_TAP_DAP_1_WUC_TAP_ENABLE 0xC5
|
||||
#else
|
||||
#define SET_CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE 0x00
|
||||
#define SET_CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE 0x00
|
||||
#define SET_CCFG_CCFG_TAP_DAP_0_PRCM_TAP_ENABLE 0x00
|
||||
#define SET_CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE 0x00
|
||||
#define SET_CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE 0x00
|
||||
#define SET_CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE 0x00
|
||||
#define SET_CCFG_CCFG_TAP_DAP_1_WUC_TAP_ENABLE 0x00
|
||||
#endif
|
||||
/** @} */
|
||||
#endif /* CCXXWARE_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -29,22 +29,6 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup platform
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-platforms TI CC26xx-powered platforms
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx The TI CC26xx and CC13xx CPUs
|
||||
*
|
||||
* This group documents the TI CC26xx and CC13xx CPUs. The two CPU families are
|
||||
* very similar, with the main difference being related to radio capability.
|
||||
*
|
||||
* Documentation in this group should be considered to be applicable to both
|
||||
* families, unless explicitly stated otherwise.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \addtogroup cc26xx-clocks
|
||||
* @{
|
||||
*
|
||||
|
@ -140,7 +124,7 @@ update_clock_variable(void)
|
|||
count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF clock_time_t
|
||||
clock_time_t
|
||||
clock_time(void)
|
||||
{
|
||||
update_clock_variable();
|
||||
|
@ -158,7 +142,7 @@ clock_update(void)
|
|||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF unsigned long
|
||||
unsigned long
|
||||
clock_seconds(void)
|
||||
{
|
||||
bool interrupts_disabled;
|
||||
|
@ -228,9 +212,6 @@ clock_delay(unsigned int i)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -34,33 +34,12 @@
|
|||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
putchar(int c)
|
||||
dbg_putchar(int c)
|
||||
{
|
||||
cc26xx_uart_write_byte(c);
|
||||
return c;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
puts(const char *str)
|
||||
{
|
||||
int i;
|
||||
if(str == NULL) {
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < strlen(str); i++) {
|
||||
cc26xx_uart_write_byte(str[i]);
|
||||
}
|
||||
cc26xx_uart_write_byte('\n');
|
||||
|
||||
/*
|
||||
* Wait for the line to go out. This is to prevent garbage when used between
|
||||
* UART on/off cycles
|
||||
*/
|
||||
while(cc26xx_uart_busy() == UART_BUSY);
|
||||
|
||||
return i;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned int
|
||||
dbg_send_bytes(const unsigned char *s, unsigned int len)
|
||||
{
|
|
@ -39,7 +39,6 @@
|
|||
#include "contiki.h"
|
||||
#include "lib/sensors.h"
|
||||
#include "dev/adc-sensor.h"
|
||||
#include "gpio-interrupt.h"
|
||||
#include "sys/timer.h"
|
||||
#include "lpm.h"
|
||||
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
#ifndef BATMON_SENSOR_H_
|
||||
#define BATMON_SENSOR_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "lib/sensors.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BATMON_SENSOR_TYPE_TEMP 1
|
||||
#define BATMON_SENSOR_TYPE_VOLT 2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx-gpio-hal
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation file for the CC13xx/CC26xx GPIO HAL functions
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "ti-lib.h"
|
||||
#include "ti-lib-rom.h"
|
||||
#include "dev/gpio-hal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CONFIG_MASK (IOC_IOPULL_M | IOC_INT_M | IOC_IOMODE_OPEN_SRC_INV)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_hal_arch_pin_cfg_set(gpio_hal_pin_t pin, gpio_hal_pin_cfg_t cfg)
|
||||
{
|
||||
uint32_t config;
|
||||
gpio_hal_pin_cfg_t tmp;
|
||||
|
||||
/* Clear settings that we are about to change, keep everything else */
|
||||
config = ti_lib_rom_ioc_port_configure_get(pin);
|
||||
config &= ~CONFIG_MASK;
|
||||
|
||||
tmp = cfg & GPIO_HAL_PIN_CFG_EDGE_BOTH;
|
||||
if(tmp == GPIO_HAL_PIN_CFG_EDGE_NONE) {
|
||||
config |= IOC_NO_EDGE;
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_EDGE_RISING) {
|
||||
config |= IOC_RISING_EDGE;
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_EDGE_FALLING) {
|
||||
config |= IOC_FALLING_EDGE;
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_EDGE_BOTH) {
|
||||
config |= IOC_BOTH_EDGES;
|
||||
}
|
||||
|
||||
tmp = cfg & GPIO_HAL_PIN_CFG_PULL_MASK;
|
||||
if(tmp == GPIO_HAL_PIN_CFG_PULL_NONE) {
|
||||
config |= IOC_NO_IOPULL;
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_PULL_DOWN) {
|
||||
config |= IOC_IOPULL_DOWN;
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_PULL_UP) {
|
||||
config |= IOC_IOPULL_UP;
|
||||
}
|
||||
|
||||
tmp = cfg & GPIO_HAL_PIN_CFG_INT_MASK;
|
||||
if(tmp == GPIO_HAL_PIN_CFG_INT_DISABLE) {
|
||||
config |= IOC_INT_DISABLE;
|
||||
} else if(tmp == GPIO_HAL_PIN_CFG_INT_ENABLE) {
|
||||
config |= IOC_INT_ENABLE;
|
||||
}
|
||||
|
||||
ti_lib_rom_ioc_port_configure_set(pin, IOC_PORT_GPIO, config);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
gpio_hal_pin_cfg_t
|
||||
gpio_hal_arch_pin_cfg_get(gpio_hal_pin_t pin)
|
||||
{
|
||||
gpio_hal_pin_cfg_t cfg;
|
||||
uint32_t tmp;
|
||||
uint32_t config;
|
||||
|
||||
cfg = 0;
|
||||
config = ti_lib_rom_ioc_port_configure_get(pin);
|
||||
|
||||
/* Pull */
|
||||
tmp = config & IOC_IOPULL_M;
|
||||
if(tmp == IOC_IOPULL_UP) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_PULL_UP;
|
||||
} else if(tmp == IOC_IOPULL_DOWN) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_PULL_DOWN;
|
||||
} else if(tmp == IOC_NO_IOPULL) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_PULL_NONE;
|
||||
}
|
||||
|
||||
/* Interrupt enable/disable */
|
||||
tmp = config & IOC_INT_ENABLE;
|
||||
if(tmp == IOC_INT_DISABLE) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_INT_DISABLE;
|
||||
} else if(tmp == IOC_INT_ENABLE) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_INT_ENABLE;
|
||||
}
|
||||
|
||||
/* Edge detection */
|
||||
tmp = config & IOC_BOTH_EDGES;
|
||||
if(tmp == IOC_NO_EDGE) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_NONE;
|
||||
} else if(tmp == IOC_FALLING_EDGE) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_FALLING;
|
||||
} else if(tmp == IOC_RISING_EDGE) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_RISING;
|
||||
} else if(tmp == IOC_BOTH_EDGES) {
|
||||
cfg |= GPIO_HAL_PIN_CFG_EDGE_BOTH;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
gpio_hal_pin_mask_t
|
||||
gpio_hal_arch_read_pins(gpio_hal_pin_mask_t pins)
|
||||
{
|
||||
gpio_hal_pin_mask_t oe_pins;
|
||||
|
||||
/* For pins configured as output we need to read DOUT31_0 */
|
||||
oe_pins = ti_lib_gpio_get_output_enable_multi_dio(pins);
|
||||
|
||||
pins &= ~oe_pins;
|
||||
|
||||
return (HWREG(GPIO_BASE + GPIO_O_DOUT31_0) & oe_pins) |
|
||||
ti_lib_gpio_read_multi_dio(pins);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
gpio_hal_arch_read_pin(gpio_hal_pin_t pin)
|
||||
{
|
||||
if(ti_lib_gpio_get_output_enable_dio(pin)) {
|
||||
return (HWREG(GPIO_BASE + GPIO_O_DOUT31_0) >> pin) & 1;
|
||||
}
|
||||
|
||||
return ti_lib_gpio_read_dio(pin);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-gpio-hal CC13xx/CC26xx GPIO HAL implementation
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC13xx/CC26xx GPIO HAL functions
|
||||
*
|
||||
* \note
|
||||
* Do not include this header directly
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef GPIO_HAL_ARCH_H_
|
||||
#define GPIO_HAL_ARCH_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "ti-lib.h"
|
||||
#include "ti-lib-rom.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define gpio_hal_arch_interrupt_enable(p) interrupt_enable(p)
|
||||
#define gpio_hal_arch_interrupt_disable(p) ti_lib_rom_ioc_int_disable(p)
|
||||
|
||||
#define gpio_hal_arch_pin_set_input(p) ti_lib_rom_ioc_pin_type_gpio_input(p)
|
||||
#define gpio_hal_arch_pin_set_output(p) ti_lib_rom_ioc_pin_type_gpio_output(p)
|
||||
|
||||
#define gpio_hal_arch_set_pin(p) ti_lib_gpio_set_dio(p)
|
||||
#define gpio_hal_arch_clear_pin(p) ti_lib_gpio_clear_dio(p)
|
||||
#define gpio_hal_arch_toggle_pin(p) ti_lib_gpio_toggle_dio(p)
|
||||
#define gpio_hal_arch_write_pin(p, v) ti_lib_gpio_write_dio(p, v)
|
||||
|
||||
#define gpio_hal_arch_set_pins(p) ti_lib_gpio_set_multi_dio(p)
|
||||
#define gpio_hal_arch_clear_pins(p) ti_lib_gpio_clear_multi_dio(p)
|
||||
#define gpio_hal_arch_toggle_pins(p) ti_lib_gpio_toggle_multi_dio(p)
|
||||
#define gpio_hal_arch_write_pins(p, v) ti_lib_gpio_write_multi_dio(p, v)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static inline void
|
||||
interrupt_enable(gpio_hal_pin_t pin)
|
||||
{
|
||||
ti_lib_gpio_clear_event_dio(pin);
|
||||
ti_lib_rom_ioc_int_enable(pin);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* GPIO_HAL_ARCH_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -29,72 +29,33 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx-gpio-interrupts
|
||||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of CC13xx/CC26xx GPIO interrupt handling.
|
||||
* CC13xx/CC26xx GPIO interrupt ISR.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "ioc.h"
|
||||
#include "gpio-interrupt.h"
|
||||
#include "lpm.h"
|
||||
#include "contiki.h"
|
||||
#include "dev/gpio-hal.h"
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define gpio_interrupt_isr GPIOIntHandler
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Handler array */
|
||||
static gpio_interrupt_handler_t handlers[NUM_IO_MAX];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_interrupt_register_handler(uint8_t ioid, gpio_interrupt_handler_t f)
|
||||
{
|
||||
uint8_t interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
/* Clear interrupts on specified pins */
|
||||
ti_lib_gpio_clear_event_dio(ioid);
|
||||
|
||||
handlers[ioid] = f;
|
||||
|
||||
/* Re-enable interrupts */
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_interrupt_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NUM_IO_MAX; i++) {
|
||||
handlers[i] = NULL;
|
||||
}
|
||||
|
||||
ti_lib_int_enable(INT_AON_GPIO_EDGE);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
gpio_interrupt_isr(void)
|
||||
{
|
||||
uint32_t pin_mask;
|
||||
uint8_t i;
|
||||
gpio_hal_pin_mask_t pin_mask;
|
||||
|
||||
/* Read interrupt flags */
|
||||
pin_mask = (HWREG(GPIO_BASE + GPIO_O_EVFLAGS31_0) & GPIO_DIO_ALL_MASK);
|
||||
|
||||
gpio_hal_event_handler(pin_mask);
|
||||
|
||||
/* Clear the interrupt flags */
|
||||
HWREG(GPIO_BASE + GPIO_O_EVFLAGS31_0) = pin_mask;
|
||||
|
||||
/* Run custom ISRs */
|
||||
for(i = 0; i < NUM_IO_MAX; i++) {
|
||||
/* Call the handler if there is one registered for this event */
|
||||
if((pin_mask & (1 << i)) && handlers[i] != NULL) {
|
||||
handlers[i](i);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Copyright (c) 2017, University of Bristol - http://www.bristol.ac.uk/
|
||||
* 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 HOLDER 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 "contiki.h"
|
||||
#include "ti-lib.h"
|
||||
#include "dev/spi.h"
|
||||
#include "sys/mutex.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct spi_locks_s {
|
||||
mutex_t lock;
|
||||
spi_device_t *owner;
|
||||
} spi_locks_t;
|
||||
|
||||
/* One lock per SPI controller */
|
||||
spi_locks_t board_spi_locks_spi[SPI_CONTROLLER_COUNT] = { { MUTEX_STATUS_UNLOCKED, NULL } };
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Arch-specific properties of each SPI controller */
|
||||
typedef struct board_spi_controller_s {
|
||||
uint32_t ssi_base;
|
||||
uint32_t power_domain;
|
||||
uint32_t prcm_periph;
|
||||
uint32_t ssi_clkgr_clk_en;
|
||||
} board_spi_controller_t;
|
||||
|
||||
static const board_spi_controller_t spi_controller[SPI_CONTROLLER_COUNT] = {
|
||||
{
|
||||
.ssi_base = SSI0_BASE,
|
||||
.power_domain = PRCM_DOMAIN_SERIAL,
|
||||
.prcm_periph = PRCM_PERIPH_SSI0,
|
||||
.ssi_clkgr_clk_en = PRCM_SSICLKGR_CLK_EN_SSI0
|
||||
},
|
||||
{
|
||||
.ssi_base = SSI1_BASE,
|
||||
.power_domain = PRCM_DOMAIN_PERIPH,
|
||||
.prcm_periph = PRCM_PERIPH_SSI1,
|
||||
.ssi_clkgr_clk_en = PRCM_SSICLKGR_CLK_EN_SSI1
|
||||
}
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
spi_arch_has_lock(spi_device_t *dev)
|
||||
{
|
||||
if(board_spi_locks_spi[dev->spi_controller].owner == dev) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
spi_arch_is_bus_locked(spi_device_t *dev)
|
||||
{
|
||||
if(board_spi_locks_spi[dev->spi_controller].lock == MUTEX_STATUS_LOCKED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint32_t
|
||||
get_mode(spi_device_t *dev)
|
||||
{
|
||||
/* Select the correct SPI mode */
|
||||
if(dev->spi_pha == 0 && dev->spi_pol == 0) {
|
||||
return SSI_FRF_MOTO_MODE_0;
|
||||
} else if(dev->spi_pha != 0 && dev->spi_pol == 0) {
|
||||
return SSI_FRF_MOTO_MODE_1;
|
||||
} else if(dev->spi_pha == 0 && dev->spi_pol != 0) {
|
||||
return SSI_FRF_MOTO_MODE_2;
|
||||
} else {
|
||||
return SSI_FRF_MOTO_MODE_3;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_lock_and_open(spi_device_t *dev)
|
||||
{
|
||||
uint32_t c;
|
||||
|
||||
/* Lock the SPI bus */
|
||||
if(mutex_try_lock(&board_spi_locks_spi[dev->spi_controller].lock) == false) {
|
||||
return SPI_DEV_STATUS_BUS_LOCKED;
|
||||
}
|
||||
|
||||
board_spi_locks_spi[dev->spi_controller].owner = dev;
|
||||
|
||||
/* CS pin configuration */
|
||||
ti_lib_ioc_pin_type_gpio_output(dev->pin_spi_cs);
|
||||
|
||||
/* First, make sure the SERIAL PD is on */
|
||||
ti_lib_prcm_power_domain_on(spi_controller[dev->spi_controller].power_domain);
|
||||
while((ti_lib_prcm_power_domain_status(spi_controller[dev->spi_controller].power_domain)
|
||||
!= PRCM_DOMAIN_POWER_ON)) ;
|
||||
|
||||
/* Enable clock in active mode */
|
||||
ti_lib_rom_prcm_peripheral_run_enable(spi_controller[dev->spi_controller].prcm_periph);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get()) ;
|
||||
|
||||
/* SPI configuration */
|
||||
ti_lib_ssi_int_disable(spi_controller[dev->spi_controller].ssi_base, SSI_RXOR | SSI_RXFF | SSI_RXTO | SSI_TXFF);
|
||||
ti_lib_ssi_int_clear(spi_controller[dev->spi_controller].ssi_base, SSI_RXOR | SSI_RXTO);
|
||||
ti_lib_rom_ssi_config_set_exp_clk(spi_controller[dev->spi_controller].ssi_base, ti_lib_sys_ctrl_clock_get(),
|
||||
get_mode(dev), SSI_MODE_MASTER, dev->spi_bit_rate, 8);
|
||||
ti_lib_rom_ioc_pin_type_ssi_master(spi_controller[dev->spi_controller].ssi_base, dev->pin_spi_miso,
|
||||
dev->pin_spi_mosi, IOID_UNUSED, dev->pin_spi_sck);
|
||||
|
||||
ti_lib_ssi_enable(spi_controller[dev->spi_controller].ssi_base);
|
||||
|
||||
/* Get rid of residual data from SSI port */
|
||||
while(ti_lib_ssi_data_get_non_blocking(spi_controller[dev->spi_controller].ssi_base, &c)) ;
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_close_and_unlock(spi_device_t *dev)
|
||||
{
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
/* Power down SSI */
|
||||
ti_lib_rom_prcm_peripheral_run_disable(spi_controller[dev->spi_controller].prcm_periph);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get()) ;
|
||||
|
||||
/* Restore pins to a low-consumption state */
|
||||
ti_lib_ioc_pin_type_gpio_input(dev->pin_spi_miso);
|
||||
ti_lib_ioc_io_port_pull_set(dev->pin_spi_miso, IOC_IOPULL_DOWN);
|
||||
|
||||
ti_lib_ioc_pin_type_gpio_input(dev->pin_spi_mosi);
|
||||
ti_lib_ioc_io_port_pull_set(dev->pin_spi_mosi, IOC_IOPULL_DOWN);
|
||||
|
||||
ti_lib_ioc_pin_type_gpio_input(dev->pin_spi_sck);
|
||||
ti_lib_ioc_io_port_pull_set(dev->pin_spi_sck, IOC_IOPULL_DOWN);
|
||||
|
||||
/* Unlock the SPI bus */
|
||||
board_spi_locks_spi[dev->spi_controller].owner = NULL;
|
||||
mutex_unlock(&board_spi_locks_spi[dev->spi_controller].lock);
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_transfer(spi_device_t *dev,
|
||||
const uint8_t *write_buf, int wlen,
|
||||
uint8_t *inbuf, int rlen, int ignore_len)
|
||||
{
|
||||
int i;
|
||||
int totlen;
|
||||
uint32_t c;
|
||||
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
if(ti_lib_prcm_power_domain_status(spi_controller[dev->spi_controller].power_domain)
|
||||
!= PRCM_DOMAIN_POWER_ON) {
|
||||
return SPI_DEV_STATUS_CLOSED;
|
||||
}
|
||||
|
||||
/* Then check the 'run mode' clock gate */
|
||||
if(!(HWREG(PRCM_BASE + PRCM_O_SSICLKGR) & spi_controller[dev->spi_controller].ssi_clkgr_clk_en)) {
|
||||
return SPI_DEV_STATUS_CLOSED;
|
||||
}
|
||||
|
||||
totlen = MAX(rlen + ignore_len, wlen);
|
||||
|
||||
if(totlen == 0) {
|
||||
/* Nothing to do */
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
|
||||
for(i = 0; i < totlen; i++) {
|
||||
c = i < wlen ? write_buf[i] : 0;
|
||||
ti_lib_ssi_data_put(spi_controller[dev->spi_controller].ssi_base, (uint8_t)c);
|
||||
ti_lib_rom_ssi_data_get(spi_controller[dev->spi_controller].ssi_base, &c);
|
||||
if(i < rlen) {
|
||||
inbuf[i] = (uint8_t)c;
|
||||
}
|
||||
}
|
||||
|
||||
while(ti_lib_rom_ssi_data_get_non_blocking(spi_controller[dev->spi_controller].ssi_base, &c)) ;
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
spi_status_t
|
||||
spi_arch_select(spi_device_t *dev)
|
||||
{
|
||||
|
||||
if(!spi_arch_has_lock(dev)) {
|
||||
return SPI_DEV_STATUS_BUS_NOT_OWNED;
|
||||
}
|
||||
|
||||
ti_lib_gpio_clear_dio(dev->pin_spi_cs);
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
||||
spi_status_t
|
||||
spi_arch_deselect(spi_device_t *dev)
|
||||
{
|
||||
ti_lib_gpio_set_dio(dev->pin_spi_cs);
|
||||
|
||||
return SPI_DEV_STATUS_OK;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* \defgroup cc26xx The TI CC13xx and CC26xx Systems-on-Chip
|
||||
*
|
||||
* This group documents the TI CC26xx and CC13xx CPUs. The two CPU families are
|
||||
* very similar, with the main difference being related to radio capability.
|
||||
*
|
||||
* Documentation in this group should be considered to be applicable to both
|
||||
* families, unless explicitly stated otherwise.
|
||||
*
|
||||
* \ingroup cpu
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup cc26xx-platforms TI CC26xx-powered platforms
|
||||
* \ingroup platform
|
||||
*/
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2017, George Oikonomou - http://www.spd.gr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \addtogroup cc26xx
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-interrupts CC13xx-CC26xx master interrupt manipulation
|
||||
*
|
||||
* Master interrupt manipulation routines for the CC13xx and CC26xx CPUs
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Master interrupt manipulation implementation for the TI CC13xx/CC26xx
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "sys/int-master.h"
|
||||
#include "cc13x0-cc26x0-cm3.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
int_master_enable(void)
|
||||
{
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int_master_status_t
|
||||
int_master_read_and_disable(void)
|
||||
{
|
||||
return ti_lib_int_master_disable();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
int_master_status_set(int_master_status_t status)
|
||||
{
|
||||
__set_PRIMASK(status);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
int_master_is_enabled(void)
|
||||
{
|
||||
return ti_lib_cpu_primask() ? false : true;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -1 +1 @@
|
|||
Subproject commit f4800b7af65e78fd45e0a1f72648abf70a9fe567
|
||||
Subproject commit 682cf5d60aa6b6be77c5519ff70fa18087fe3cf0
|
|
@ -1 +1 @@
|
|||
Subproject commit 40916ad11efdcac76775b9b18cebc8d0c37c48f2
|
||||
Subproject commit 568511d650601afdc80106d9b9d5c44882635d17
|
|
@ -185,7 +185,7 @@ wake_up(void)
|
|||
{
|
||||
lpm_registered_module_t *module;
|
||||
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_DEEP_LPM, ENERGEST_TYPE_CPU);
|
||||
|
||||
/* Sync so that we get the latest values before adjusting recharge settings */
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
@ -485,7 +485,7 @@ deep_sleep(void)
|
|||
ti_lib_pwr_ctrl_source_set(PWRCTRL_PWRSRC_ULDO);
|
||||
}
|
||||
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
|
||||
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_DEEP_LPM);
|
||||
|
||||
/* Sync the AON interface to ensure all writes have gone through. */
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Loughborough University - Computer Science
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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
|
||||
* Stub header file for multi-threading. It doesn't do anything, it
|
||||
* just exists so that mt.c can compile cleanly.
|
||||
*
|
||||
* This is based on the original mtarch.h for z80 by Takahide Matsutsuka
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#ifndef __MTARCH_H__
|
||||
#define __MTARCH_H__
|
||||
|
||||
struct mtarch_thread {
|
||||
unsigned char *sp;
|
||||
};
|
||||
|
||||
#endif /* __MTARCH_H__ */
|
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Graz University of Technology
|
||||
* 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
|
||||
* BLE radio for the TI CC26xx platform
|
||||
*
|
||||
* \author
|
||||
* Michael Spoerk <michael.spoerk@tugraz.at>
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "dev/radio.h"
|
||||
#include "os/dev/ble-hal.h"
|
||||
#include "rf-core/ble-hal/ble-hal-cc26xx.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RADIO"
|
||||
#define LOG_LEVEL LOG_LEVEL_MAIN
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint16_t adv_interval;
|
||||
static ble_adv_type_t adv_type;
|
||||
static ble_addr_type_t adv_own_addr_type;
|
||||
static uint8_t adv_channel_map;
|
||||
static uint16_t buffer_size = 0;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint16_t scan_interval;
|
||||
static uint16_t scan_window;
|
||||
static ble_scan_type_t scan_type;
|
||||
static ble_addr_type_t scan_own_addr_type;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static ble_addr_type_t initiator_peer_addr_type;
|
||||
static uint8_t initiator_peer_addr[BLE_ADDR_SIZE];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint16_t connection_interval;
|
||||
static uint16_t connection_latency;
|
||||
static uint16_t connection_timeout;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
init(void)
|
||||
{
|
||||
int result = ble_hal.reset();
|
||||
return result == BLE_RESULT_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
send(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
uint8_t res;
|
||||
res = ble_hal.send((void *)payload, payload_len);
|
||||
LOG_DBG("ble-mode send() %d bytes\n", payload_len);
|
||||
if(res == BLE_RESULT_OK) {
|
||||
return RADIO_TX_OK;
|
||||
} else {
|
||||
LOG_ERR("ble-mode send() error: %d\n", res);
|
||||
return RADIO_TX_ERR;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
on(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
off(void)
|
||||
{
|
||||
ble_hal.disconnect(0, 0);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_value(radio_param_t param, radio_value_t *value)
|
||||
{
|
||||
unsigned int temp;
|
||||
|
||||
if(!value) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
switch(param) {
|
||||
case RADIO_CONST_CHANNEL_MIN:
|
||||
*value = BLE_DATA_CHANNEL_MIN;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_CHANNEL_MAX:
|
||||
*value = BLE_DATA_CHANNEL_MAX;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_BLE_BUFFER_SIZE:
|
||||
if(buffer_size == 0) {
|
||||
ble_hal.read_buffer_size((unsigned int *)&buffer_size, &temp);
|
||||
}
|
||||
memcpy(value, &buffer_size, 2);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_CONST_BLE_BUFFER_AMOUNT:
|
||||
ble_hal.read_buffer_size(&temp, (unsigned int *)value);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_CONN_INTERVAL:
|
||||
ble_hal.read_connection_interval(0, (unsigned int *)value);
|
||||
return RADIO_RESULT_OK;
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_value(radio_param_t param, radio_value_t value)
|
||||
{
|
||||
switch(param) {
|
||||
case RADIO_PARAM_BLE_ADV_INTERVAL:
|
||||
if((value > BLE_ADV_INTERVAL_MAX) || (value < BLE_ADV_INTERVAL_MIN)) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
adv_interval = (uint16_t)value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_ADV_TYPE:
|
||||
adv_type = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_ADV_OWN_ADDR_TYPE:
|
||||
adv_own_addr_type = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_ADV_CHANNEL_MAP:
|
||||
adv_channel_map = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_ADV_ENABLE:
|
||||
if(value) {
|
||||
/* set the advertisement parameter before enabling */
|
||||
ble_hal.set_adv_param(adv_interval, adv_type,
|
||||
adv_own_addr_type, adv_channel_map);
|
||||
}
|
||||
ble_hal.set_adv_enable(value);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_SCAN_INTERVAL:
|
||||
if((value > BLE_SCAN_INTERVAL_MAX) || (value < BLE_SCAN_INTERVAL_MIN)) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
scan_interval = (uint16_t)value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_SCAN_WINDOW:
|
||||
if((value > BLE_SCAN_INTERVAL_MAX) || (value < BLE_SCAN_INTERVAL_MIN)) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
scan_window = (uint16_t)value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_SCAN_TYPE:
|
||||
scan_type = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_SCAN_OWN_ADDR_TYPE:
|
||||
scan_own_addr_type = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_SCAN_ENABLE:
|
||||
if(value) {
|
||||
ble_hal.set_scan_param(scan_type, scan_interval,
|
||||
scan_window, scan_own_addr_type);
|
||||
}
|
||||
ble_hal.set_scan_enable(value, 0);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_PEER_ADDR_TYPE:
|
||||
initiator_peer_addr_type = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_CONN_INTERVAL:
|
||||
connection_interval = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_CONN_LATENCY:
|
||||
connection_latency = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_CONN_SUPERVISION_TIMEOUT:
|
||||
connection_timeout = value;
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_INITIATOR_ENABLE:
|
||||
if(value) {
|
||||
ble_hal.create_connection(scan_interval, scan_window,
|
||||
initiator_peer_addr_type,
|
||||
initiator_peer_addr,
|
||||
scan_own_addr_type,
|
||||
connection_interval,
|
||||
connection_latency,
|
||||
connection_timeout);
|
||||
} else {
|
||||
ble_hal.create_connection_cancel();
|
||||
}
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_CONN_UPDATE:
|
||||
if(value) {
|
||||
return ble_hal.connection_update(0, connection_interval, connection_latency, connection_timeout);
|
||||
} else {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
default:
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
get_object(radio_param_t param, void *dest, size_t size)
|
||||
{
|
||||
switch(param) {
|
||||
case RADIO_CONST_BLE_BD_ADDR:
|
||||
if(size != BLE_ADDR_SIZE || !dest) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
ble_hal.read_bd_addr(dest);
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static radio_result_t
|
||||
set_object(radio_param_t param, const void *src, size_t size)
|
||||
{
|
||||
switch(param) {
|
||||
case RADIO_PARAM_BLE_ADV_PAYLOAD:
|
||||
if(size <= 0 || size >= BLE_ADV_DATA_LEN || !src) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
ble_hal.set_adv_data((unsigned short)size, (char *)src);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_ADV_SCAN_RESPONSE:
|
||||
if(size <= 0 || size >= BLE_SCAN_RESP_DATA_LEN || !src) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
ble_hal.set_scan_resp_data((unsigned short)size, (char *)src);
|
||||
return RADIO_RESULT_OK;
|
||||
case RADIO_PARAM_BLE_PEER_ADDR:
|
||||
if(size <= 0 || size > BLE_ADDR_SIZE || !src) {
|
||||
return RADIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
memcpy(initiator_peer_addr, src, size);
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver ble_cc2650_driver = {
|
||||
init,
|
||||
NULL,
|
||||
NULL,
|
||||
send,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
on,
|
||||
off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Graz University of Technology
|
||||
* 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
|
||||
* BLE radio hardware abstraction for the TI CC26XX controller
|
||||
*
|
||||
* \author
|
||||
* Michael Spoerk <michael.spoerk@tugraz.at>
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef BLE_HAL_CC26XX_H_
|
||||
#define BLE_HAL_CC26XX_H_
|
||||
|
||||
#include "os/dev/ble-hal.h"
|
||||
|
||||
extern const struct ble_hal_driver ble_hal;
|
||||
|
||||
#endif /* BLE_HAL_CC26XX_H_ */
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Graz University of Technology
|
||||
* 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
|
||||
* BLE commands for the TI CC26xx BLE radio.
|
||||
* These functions are specific to the TI CC26xx and cannot be
|
||||
* reused by other BLE radios.
|
||||
*
|
||||
* \author
|
||||
* Michael Spoerk <michael.spoerk@tugraz.at>
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
|
||||
#include "rf_ble_cmd.h"
|
||||
#include "rf-core/rf-core.h"
|
||||
#include "rf-core/ble-hal/rf-ble-cmd.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "BLE-RADIO"
|
||||
#define LOG_LEVEL LOG_LEVEL_MAIN
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CMD_GET_STATUS(X) (((rfc_radioOp_t *)X)->status)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* values for a selection of available TX powers (values from SmartRF Studio) */
|
||||
/*static uint16_t tx_power = 0x9330; / * +5 dBm * / */
|
||||
static uint16_t tx_power = 0x3161; /* 0 dBm */
|
||||
/*static uint16_t tx_power = 0x0CCB; / * -15 dBm * / */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* BLE overrides */
|
||||
static uint32_t ble_overrides[] = {
|
||||
0x00364038, /* Synth: Set RTRIM (POTAILRESTRIM) to 6 */
|
||||
0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */
|
||||
0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */
|
||||
0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */
|
||||
0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */
|
||||
0x00456088, /* Adjust AGC reference level */
|
||||
0x008F88B3, /* GPIO mode: https://e2e.ti.com/support/wireless_connectivity/proprietary_sub_1_ghz_simpliciti/f/156/t/488244?*/
|
||||
0xFFFFFFFF, /* End of override list */
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned short
|
||||
rf_ble_cmd_send(uint8_t *command)
|
||||
{
|
||||
uint32_t cmdsta;
|
||||
rfc_radioOp_t *cmd = (rfc_radioOp_t *)command;
|
||||
|
||||
if(rf_core_send_cmd((uint32_t)cmd, &cmdsta) != RF_CORE_CMD_OK) {
|
||||
LOG_ERR("rf_ble_cmd_send() could not send cmd. status: 0x%04X\n",
|
||||
CMD_GET_STATUS(cmd));
|
||||
return RF_BLE_CMD_ERROR;
|
||||
}
|
||||
return RF_BLE_CMD_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned short
|
||||
rf_ble_cmd_wait(uint8_t *command)
|
||||
{
|
||||
rfc_radioOp_t *cmd = (rfc_radioOp_t *)command;
|
||||
if(rf_core_wait_cmd_done((void *)cmd) != RF_CORE_CMD_OK) {
|
||||
LOG_ERR("rf_ble_cmd_wait() could not wait. status: 0x%04X\n",
|
||||
CMD_GET_STATUS(cmd));
|
||||
return RF_BLE_CMD_ERROR;
|
||||
}
|
||||
return RF_BLE_CMD_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned short
|
||||
rf_ble_cmd_setup_ble_mode(void)
|
||||
{
|
||||
rfc_CMD_RADIO_SETUP_t cmd;
|
||||
|
||||
/* Create radio setup command */
|
||||
rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP);
|
||||
|
||||
cmd.txPower = tx_power;
|
||||
cmd.pRegOverride = ble_overrides;
|
||||
cmd.mode = 0;
|
||||
|
||||
/* Send Radio setup to RF Core */
|
||||
if(rf_ble_cmd_send((uint8_t *)&cmd) != RF_BLE_CMD_OK) {
|
||||
return RF_BLE_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Wait until radio setup is done */
|
||||
return rf_ble_cmd_wait((uint8_t *)&cmd);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* ADVERTISING functions */
|
||||
void
|
||||
rf_ble_cmd_create_adv_cmd(uint8_t *command, uint8_t channel,
|
||||
uint8_t *param, uint8_t *output)
|
||||
{
|
||||
rfc_CMD_BLE_ADV_t *c = (rfc_CMD_BLE_ADV_t *)command;
|
||||
|
||||
memset(c, 0x00, sizeof(rfc_CMD_BLE_ADV_t));
|
||||
c->commandNo = CMD_BLE_ADV;
|
||||
c->condition.rule = COND_NEVER;
|
||||
c->whitening.bOverride = 0;
|
||||
c->channel = channel;
|
||||
c->pParams = (rfc_bleAdvPar_t *)param;
|
||||
c->startTrigger.triggerType = TRIG_NOW;
|
||||
c->pOutput = (rfc_bleAdvOutput_t *)output;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rf_ble_cmd_create_adv_params(uint8_t *param, dataQueue_t *rx_queue,
|
||||
uint8_t adv_data_len, uint8_t *adv_data,
|
||||
uint8_t scan_resp_data_len, uint8_t *scan_resp_data,
|
||||
ble_addr_type_t own_addr_type, uint8_t *own_addr)
|
||||
{
|
||||
rfc_bleAdvPar_t *p = (rfc_bleAdvPar_t *)param;
|
||||
|
||||
memset(p, 0x00, sizeof(rfc_bleAdvPar_t));
|
||||
|
||||
p->pRxQ = rx_queue;
|
||||
p->rxConfig.bAutoFlushIgnored = 1;
|
||||
p->rxConfig.bAutoFlushCrcErr = 0;
|
||||
p->rxConfig.bAutoFlushEmpty = 1;
|
||||
p->rxConfig.bIncludeLenByte = 1;
|
||||
p->rxConfig.bIncludeCrc = 0;
|
||||
p->rxConfig.bAppendRssi = 1;
|
||||
p->rxConfig.bAppendStatus = 1;
|
||||
p->rxConfig.bAppendTimestamp = 1;
|
||||
p->advConfig.advFilterPolicy = 0;
|
||||
p->advConfig.bStrictLenFilter = 0;
|
||||
p->advConfig.deviceAddrType = own_addr_type;
|
||||
p->pDeviceAddress = (uint16_t *)own_addr;
|
||||
p->advLen = adv_data_len;
|
||||
p->scanRspLen = scan_resp_data_len;
|
||||
p->pAdvData = adv_data;
|
||||
p->pScanRspData = scan_resp_data;
|
||||
p->endTrigger.triggerType = TRIG_NEVER;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* CONNECTION slave functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rf_ble_cmd_create_slave_cmd(uint8_t *cmd, uint8_t channel, uint8_t *params,
|
||||
uint8_t *output, uint32_t start_time)
|
||||
{
|
||||
rfc_CMD_BLE_SLAVE_t *c = (rfc_CMD_BLE_SLAVE_t *)cmd;
|
||||
|
||||
memset(c, 0x00, sizeof(rfc_CMD_BLE_SLAVE_t));
|
||||
|
||||
c->commandNo = CMD_BLE_SLAVE;
|
||||
c->condition.rule = COND_NEVER;
|
||||
c->whitening.bOverride = 0;
|
||||
c->channel = channel;
|
||||
c->pParams = (rfc_bleSlavePar_t *)params;
|
||||
c->startTrigger.triggerType = TRIG_ABSTIME;
|
||||
c->startTrigger.pastTrig = 0;
|
||||
c->startTime = start_time;
|
||||
c->pOutput = (rfc_bleMasterSlaveOutput_t *)output;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rf_ble_cmd_create_slave_params(uint8_t *params, dataQueue_t *rx_queue,
|
||||
dataQueue_t *tx_queue, uint32_t access_address,
|
||||
uint8_t crc_init_0, uint8_t crc_init_1,
|
||||
uint8_t crc_init_2, uint32_t win_size,
|
||||
uint32_t window_widening, uint8_t first_packet)
|
||||
{
|
||||
rfc_bleSlavePar_t *p = (rfc_bleSlavePar_t *)params;
|
||||
|
||||
p->pRxQ = rx_queue;
|
||||
p->pTxQ = tx_queue;
|
||||
p->rxConfig.bAutoFlushIgnored = 1;
|
||||
p->rxConfig.bAutoFlushCrcErr = 1;
|
||||
p->rxConfig.bAutoFlushEmpty = 1;
|
||||
p->rxConfig.bIncludeLenByte = 1;
|
||||
p->rxConfig.bIncludeCrc = 0;
|
||||
p->rxConfig.bAppendRssi = 1;
|
||||
p->rxConfig.bAppendStatus = 1;
|
||||
p->rxConfig.bAppendTimestamp = 1;
|
||||
|
||||
if(first_packet) {
|
||||
/* set parameters for first packet according to TI Technical Reference Manual */
|
||||
p->seqStat.lastRxSn = 1;
|
||||
p->seqStat.lastTxSn = 1;
|
||||
p->seqStat.nextTxSn = 0;
|
||||
p->seqStat.bFirstPkt = 1;
|
||||
p->seqStat.bAutoEmpty = 0;
|
||||
p->seqStat.bLlCtrlTx = 0;
|
||||
p->seqStat.bLlCtrlAckRx = 0;
|
||||
p->seqStat.bLlCtrlAckPending = 0;
|
||||
}
|
||||
|
||||
p->maxNack = 0;
|
||||
p->maxPkt = 0;
|
||||
p->accessAddress = access_address;
|
||||
p->crcInit0 = crc_init_0;
|
||||
p->crcInit1 = crc_init_1;
|
||||
p->crcInit2 = crc_init_2;
|
||||
p->timeoutTrigger.triggerType = TRIG_REL_START;
|
||||
if(first_packet) {
|
||||
p->timeoutTime = (uint32_t)(10 * win_size);
|
||||
} else {
|
||||
p->timeoutTime = (uint32_t)(win_size + 2 * window_widening);
|
||||
}
|
||||
p->endTrigger.triggerType = TRIG_NEVER;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* DATA queue functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned short
|
||||
rf_ble_cmd_add_data_queue_entry(dataQueue_t *q, uint8_t *e)
|
||||
{
|
||||
uint32_t cmdsta;
|
||||
|
||||
rfc_CMD_ADD_DATA_ENTRY_t cmd;
|
||||
cmd.commandNo = CMD_ADD_DATA_ENTRY;
|
||||
cmd.pQueue = q;
|
||||
cmd.pEntry = e;
|
||||
|
||||
if(rf_core_send_cmd((uint32_t)&cmd, &cmdsta) != RF_CORE_CMD_OK) {
|
||||
LOG_ERR("could not add entry to data queue. status: 0x%04X\n",
|
||||
CMD_GET_STATUS(&cmd));
|
||||
return RF_BLE_CMD_ERROR;
|
||||
}
|
||||
return RF_BLE_CMD_OK;
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Graz University of Technology
|
||||
* 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
|
||||
* BLE commands for the TI CC26xx BLE radio.
|
||||
* These functions are specific to the TI CC26xx and cannot be
|
||||
* reused by other BLE radios.
|
||||
*
|
||||
* \author
|
||||
* Michael Spoerk <michael.spoerk@tugraz.at>
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef RF_BLE_CMD_H_
|
||||
#define RF_BLE_CMD_H_
|
||||
|
||||
#include "os/dev/ble-hal.h"
|
||||
#include "../../ble-addr.h"
|
||||
#include "rf_common_cmd.h"
|
||||
|
||||
#define RF_BLE_CMD_OK 1
|
||||
#define RF_BLE_CMD_ERROR 0
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Sends a BLE radio command to the radio
|
||||
* \param cmd A pointer to the command to be send
|
||||
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
|
||||
*/
|
||||
unsigned short rf_ble_cmd_send(uint8_t *cmd);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Waits for a running BLE radio command to be finished
|
||||
* \param cmd A pointer to the running command
|
||||
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
|
||||
*/
|
||||
unsigned short rf_ble_cmd_wait(uint8_t *cmd);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initializes the radio core to be used as a BLE radio
|
||||
* \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR
|
||||
*/
|
||||
unsigned short rf_ble_cmd_setup_ble_mode(void);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Creates a BLE radio command structure that enables
|
||||
* BLE advertisement when sent to the radio core
|
||||
* \param command A pointer to command that is created
|
||||
* \param channel The BLE advertisement channel used for advertisement
|
||||
* \param param A pointer to the radio command parameters
|
||||
* \param output A pointer to the radio command output
|
||||
*/
|
||||
void rf_ble_cmd_create_adv_cmd(uint8_t *command, uint8_t channel,
|
||||
uint8_t *param, uint8_t *output);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Creates BLE radio command parameters that are used to enable
|
||||
* BLE advertisement on the radio core
|
||||
* \param param A pointer to parameter structure that is created
|
||||
* \param rx_queue A pointer to the RX queue that is used
|
||||
* \param adv_data_len
|
||||
* The length of the advertisement data
|
||||
* \param adv_data A pointer to the advertisement data that is advertised
|
||||
* \param scan_resp_data_len
|
||||
* The length of the scan response data
|
||||
* \param scan_resp_data
|
||||
* A pointer to the scan response data
|
||||
* \param own_addr_type
|
||||
* Either BLE_ADDR_TYPE_PUBLIC or BLE_ADDR_TYPE_RANDOM
|
||||
* \param own_addr A pointer to the device address that is used as own address
|
||||
*/
|
||||
void rf_ble_cmd_create_adv_params(uint8_t *param, dataQueue_t *rx_queue,
|
||||
uint8_t adv_data_len, uint8_t *adv_data,
|
||||
uint8_t scan_resp_data_len, uint8_t *scan_resp_data,
|
||||
ble_addr_type_t own_addr_type, uint8_t *own_addr);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Creates a BLE radio command structure that sets up a single
|
||||
* BLE connection event when sent to the radio core
|
||||
* \param cmd A pointer to command that is created
|
||||
* \param channel The BLE data channel used for the connection event
|
||||
* \param param A pointer to the radio command parameters
|
||||
* \param output A pointer to the radio command output
|
||||
* \param start_time
|
||||
* The time in rf_core_ticks when the connection event will start
|
||||
*/
|
||||
void rf_ble_cmd_create_slave_cmd(uint8_t *cmd, uint8_t channel, uint8_t *param,
|
||||
uint8_t *output, uint32_t start_time);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Creates BLE radio command parameters that are used to setup a single
|
||||
* BLE connection event on the radio core
|
||||
* \param param A pointer to parameter structure that is created
|
||||
* \param rx_queue A pointer to the RX queue that is used
|
||||
* \param tx_queue A pointer to the TX queue that is used
|
||||
* \param access_address
|
||||
* The access address of the used BLE connection
|
||||
* \param crc_init_0
|
||||
* Part of the initialization of the CRC checksum
|
||||
* \param crc_init_1
|
||||
* Part of the initialization of the CRC checksum
|
||||
* \param crc_init_2
|
||||
* Part of the initialization of the CRC checksum
|
||||
* \param win_size The window size parameter of the BLE connection event
|
||||
* \param window_widening
|
||||
* The window widening parameter used for this connection event
|
||||
* \param first_packet
|
||||
* 1 for the first packet of the BLE connection so that the
|
||||
* connection is properly initialized
|
||||
*/
|
||||
void rf_ble_cmd_create_slave_params(uint8_t *param, dataQueue_t *rx_queue,
|
||||
dataQueue_t *tx_queue, uint32_t access_address,
|
||||
uint8_t crc_init_0, uint8_t crc_init_1,
|
||||
uint8_t crc_init_2, uint32_t win_size,
|
||||
uint32_t window_widening, uint8_t first_packet);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Adds a data buffer to a BLE transmission queue
|
||||
* \param q A pointer to BLE transmission queue where the buffer
|
||||
* should be added
|
||||
* \param e A pointer to the data buffer that is added
|
||||
*/
|
||||
unsigned short rf_ble_cmd_add_data_queue_entry(dataQueue_t *q, uint8_t *e);
|
||||
|
||||
#endif /* RF_BLE_CMD_H_ */
|
|
@ -167,6 +167,9 @@ static uint8_t rf_stats[16] = { 0 };
|
|||
/* How long to wait for the RF to react on CMD_ABORT: around 1 msec */
|
||||
#define RF_TURN_OFF_WAIT_TIMEOUT (RTIMER_SECOND >> 10)
|
||||
|
||||
/* How long to wait for the RF to finish TX of a packet or an ACK */
|
||||
#define TX_FINISH_WAIT_TIMEOUT (RTIMER_SECOND >> 7)
|
||||
|
||||
#define LIMITED_BUSYWAIT(cond, timeout) do { \
|
||||
rtimer_clock_t end_time = RTIMER_NOW() + timeout; \
|
||||
while(cond) { \
|
||||
|
@ -206,7 +209,7 @@ static const output_config_t output_power[] = {
|
|||
#define OUTPUT_POWER_UNKNOWN 0xFFFF
|
||||
|
||||
/* Default TX Power - position in output_power[] */
|
||||
const output_config_t *tx_power_current = &output_power[0];
|
||||
static const output_config_t *tx_power_current = &output_power[0];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static volatile int8_t last_rssi = 0;
|
||||
static volatile uint8_t last_corr_lqi = 0;
|
||||
|
@ -260,6 +263,20 @@ static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4);
|
|||
static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN(4);
|
||||
static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN(4);
|
||||
|
||||
#define RX_BUF_INCLUDE_CRC 1
|
||||
#define RX_BUF_INCLUDE_RSSI 1
|
||||
#define RX_BUF_INCLUDE_CORR 1
|
||||
#define RX_BUF_INCLUDE_TIMESTAMP 1
|
||||
|
||||
/* The size of the metadata (excluding the packet length field) */
|
||||
#define RX_BUF_METADATA_SIZE \
|
||||
(2 * RX_BUF_INCLUDE_CRC + RX_BUF_INCLUDE_RSSI + RX_BUF_INCLUDE_CORR + 4 * RX_BUF_INCLUDE_TIMESTAMP)
|
||||
|
||||
/* The offset of the packet length in a rx buffer */
|
||||
#define RX_BUF_LENGTH_OFFSET sizeof(rfc_dataEntry_t)
|
||||
/* The offset of the packet data in a rx buffer */
|
||||
#define RX_BUF_DATA_OFFSET (RX_BUF_LENGTH_OFFSET + 1)
|
||||
|
||||
/* The RX Data Queue */
|
||||
static dataQueue_t rx_data_queue = { 0 };
|
||||
|
||||
|
@ -562,22 +579,22 @@ init_rx_buffers(void)
|
|||
entry = (rfc_dataEntry_t *)rx_buf_0;
|
||||
entry->pNextEntry = rx_buf_1;
|
||||
entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
|
||||
entry->length = sizeof(rx_buf_0) - 8;
|
||||
entry->length = sizeof(rx_buf_0) - sizeof(*entry);
|
||||
|
||||
entry = (rfc_dataEntry_t *)rx_buf_1;
|
||||
entry->pNextEntry = rx_buf_2;
|
||||
entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
|
||||
entry->length = sizeof(rx_buf_0) - 8;
|
||||
entry->length = sizeof(rx_buf_0) - sizeof(*entry);
|
||||
|
||||
entry = (rfc_dataEntry_t *)rx_buf_2;
|
||||
entry->pNextEntry = rx_buf_3;
|
||||
entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
|
||||
entry->length = sizeof(rx_buf_0) - 8;
|
||||
entry->length = sizeof(rx_buf_0) - sizeof(*entry);
|
||||
|
||||
entry = (rfc_dataEntry_t *)rx_buf_3;
|
||||
entry->pNextEntry = rx_buf_0;
|
||||
entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
|
||||
entry->length = sizeof(rx_buf_0) - 8;
|
||||
entry->length = sizeof(rx_buf_0) - sizeof(*entry);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -598,11 +615,11 @@ init_rf_params(void)
|
|||
cmd->rxConfig.bAutoFlushCrc = 1;
|
||||
cmd->rxConfig.bAutoFlushIgn = 0;
|
||||
cmd->rxConfig.bIncludePhyHdr = 0;
|
||||
cmd->rxConfig.bIncludeCrc = 1;
|
||||
cmd->rxConfig.bAppendRssi = 1;
|
||||
cmd->rxConfig.bAppendCorrCrc = 1;
|
||||
cmd->rxConfig.bIncludeCrc = RX_BUF_INCLUDE_CRC;
|
||||
cmd->rxConfig.bAppendRssi = RX_BUF_INCLUDE_RSSI;
|
||||
cmd->rxConfig.bAppendCorrCrc = RX_BUF_INCLUDE_CORR;
|
||||
cmd->rxConfig.bAppendSrcInd = 0;
|
||||
cmd->rxConfig.bAppendTimestamp = 1;
|
||||
cmd->rxConfig.bAppendTimestamp = RX_BUF_INCLUDE_TIMESTAMP;
|
||||
|
||||
cmd->pRxQ = &rx_data_queue;
|
||||
cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats;
|
||||
|
@ -697,7 +714,7 @@ rx_off(void)
|
|||
}
|
||||
|
||||
/* Wait for ongoing ACK TX to finish */
|
||||
while(transmitting());
|
||||
LIMITED_BUSYWAIT(transmitting(), TX_FINISH_WAIT_TIMEOUT);
|
||||
|
||||
/* Send a CMD_ABORT command to RF Core */
|
||||
if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
|
||||
|
@ -1076,15 +1093,15 @@ read_frame(void *buf, unsigned short buf_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(rx_read_entry[8] < 4) {
|
||||
PRINTF("RF: too short\n");
|
||||
len = rx_read_entry[RX_BUF_LENGTH_OFFSET];
|
||||
if(len <= RX_BUF_METADATA_SIZE) {
|
||||
PRINTF("RF: too short!");
|
||||
|
||||
release_data_entry();
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = rx_read_entry[8] - 8;
|
||||
|
||||
len -= RX_BUF_METADATA_SIZE;
|
||||
if(len > buf_len) {
|
||||
PRINTF("RF: too long\n");
|
||||
|
||||
|
@ -1092,13 +1109,13 @@ read_frame(void *buf, unsigned short buf_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buf, (char *)&rx_read_entry[9], len);
|
||||
memcpy(buf, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET, len);
|
||||
|
||||
last_rssi = (int8_t)rx_read_entry[9 + len + 2];
|
||||
last_corr_lqi = (uint8_t)rx_read_entry[9 + len + 3] & STATUS_CORRELATION;
|
||||
last_rssi = (int8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len + 2];
|
||||
last_corr_lqi = (uint8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len + 3] & STATUS_CORRELATION;
|
||||
|
||||
/* get the timestamp */
|
||||
memcpy(&rat_timestamp, (char *)rx_read_entry + 9 + len + 4, 4);
|
||||
memcpy(&rat_timestamp, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET + len + 4, 4);
|
||||
|
||||
last_packet_timestamp = calc_last_packet_timestamp(rat_timestamp);
|
||||
|
||||
|
@ -1140,7 +1157,7 @@ channel_clear(void)
|
|||
*
|
||||
* We could probably even simply return that the channel is clear
|
||||
*/
|
||||
while(transmitting());
|
||||
LIMITED_BUSYWAIT(transmitting(), TX_FINISH_WAIT_TIMEOUT);
|
||||
} else {
|
||||
was_off = 1;
|
||||
if(on() != RF_CORE_CMD_OK) {
|
||||
|
@ -1297,7 +1314,7 @@ off(void)
|
|||
return RF_CORE_CMD_OK;
|
||||
}
|
||||
|
||||
while(transmitting());
|
||||
LIMITED_BUSYWAIT(transmitting(), TX_FINISH_WAIT_TIMEOUT);
|
||||
|
||||
/* stopping the rx explicitly results in lower sleep-mode power usage */
|
||||
rx_off();
|
||||
|
|
|
@ -203,7 +203,7 @@ extern const prop_mode_tx_power_config_t TX_POWER_DRIVER[];
|
|||
#define OUTPUT_POWER_UNKNOWN 0xFFFF
|
||||
|
||||
/* Default TX Power - position in output_power[] */
|
||||
const prop_mode_tx_power_config_t *tx_power_current = &TX_POWER_DRIVER[1];
|
||||
static const prop_mode_tx_power_config_t *tx_power_current = &TX_POWER_DRIVER[1];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef PROP_MODE_CONF_LO_DIVIDER
|
||||
#define PROP_MODE_LO_DIVIDER PROP_MODE_CONF_LO_DIVIDER
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (c) 2017, University of Bristol - http://www.bristol.ac.uk/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -71,7 +72,7 @@
|
|||
#define BLE_ADV_TYPE_DEVINFO 0x01
|
||||
#define BLE_ADV_TYPE_NAME 0x09
|
||||
#define BLE_ADV_TYPE_MANUFACTURER 0xFF
|
||||
#define BLE_ADV_NAME_BUF_LEN 32
|
||||
#define BLE_ADV_NAME_BUF_LEN BLE_ADV_MAX_SIZE
|
||||
#define BLE_ADV_PAYLOAD_BUF_LEN 64
|
||||
#define BLE_UUID_SIZE 16
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -82,8 +83,6 @@ static uint8_t payload[BLE_ADV_PAYLOAD_BUF_LEN];
|
|||
static int p = 0;
|
||||
static int i;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint16_t tx_power = 0x9330;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* BLE beacond config */
|
||||
static struct ble_beacond_config {
|
||||
clock_time_t interval;
|
||||
|
@ -108,6 +107,38 @@ static uint32_t ble_overrides[] = {
|
|||
0xFFFFFFFF, /* End of override list */
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* TX Power dBm lookup table - values from SmartRF Studio */
|
||||
typedef struct output_config {
|
||||
radio_value_t dbm;
|
||||
uint16_t tx_power; /* Value for the CMD_RADIO_SETUP.txPower field */
|
||||
} output_config_t;
|
||||
|
||||
static const output_config_t output_power[] = {
|
||||
{ 5, 0x9330 },
|
||||
{ 4, 0x9324 },
|
||||
{ 3, 0x5a1c },
|
||||
{ 2, 0x4e18 },
|
||||
{ 1, 0x4214 },
|
||||
{ 0, 0x3161 },
|
||||
{ -3, 0x2558 },
|
||||
{ -6, 0x1d52 },
|
||||
{ -9, 0x194e },
|
||||
{ -12, 0x144b },
|
||||
{ -15, 0x0ccb },
|
||||
{ -18, 0x0cc9 },
|
||||
{ -21, 0x0cc7 },
|
||||
};
|
||||
|
||||
#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
|
||||
|
||||
/* Max and Min Output Power in dBm */
|
||||
#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm)
|
||||
#define OUTPUT_POWER_MAX (output_power[0].dbm)
|
||||
#define OUTPUT_POWER_UNKNOWN 0xFFFF
|
||||
|
||||
/* Default TX Power - position in output_power[] */
|
||||
static const output_config_t *tx_power_current = &output_power[0];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(rf_ble_beacon_process, "CC13xx / CC26xx RF BLE Beacon Process");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
|
@ -132,7 +163,7 @@ send_ble_adv_nc(int channel, uint8_t *adv_payload, int adv_payload_len)
|
|||
cmd.channel = channel;
|
||||
|
||||
/* Set up BLE Advertisement parameters */
|
||||
params->pDeviceAddress = (uint16_t *)&linkaddr_node_addr.u8[LINKADDR_SIZE - 2];
|
||||
params->pDeviceAddress = (uint16_t *)BLE_ADDRESS_PTR;
|
||||
params->endTrigger.triggerType = TRIG_NEVER;
|
||||
params->endTime = TRIG_NEVER;
|
||||
|
||||
|
@ -157,6 +188,33 @@ send_ble_adv_nc(int channel, uint8_t *adv_payload, int adv_payload_len)
|
|||
return RF_CORE_CMD_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Returns the current TX power in dBm */
|
||||
radio_value_t
|
||||
rf_ble_get_tx_power(void)
|
||||
{
|
||||
return tx_power_current->dbm;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Set TX power to 'at least' power dBm
|
||||
* This works with a lookup table. If the value of 'power' does not exist in
|
||||
* the lookup table, TXPOWER will be set to the immediately higher available
|
||||
* value
|
||||
*/
|
||||
void
|
||||
rf_ble_set_tx_power(radio_value_t power)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* First, find the correct setting and save it */
|
||||
for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
|
||||
if(power <= output_power[i].dbm) {
|
||||
tx_power_current = &output_power[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rf_ble_beacond_config(clock_time_t interval, const char *name)
|
||||
{
|
||||
|
@ -211,7 +269,6 @@ rf_ble_beacond_stop()
|
|||
{
|
||||
process_exit(&rf_ble_beacon_process);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
rf_radio_setup()
|
||||
{
|
||||
|
@ -223,7 +280,7 @@ rf_radio_setup()
|
|||
/* Create radio setup command */
|
||||
rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP);
|
||||
|
||||
cmd.txPower = tx_power;
|
||||
cmd.txPower = tx_power_current->tx_power;
|
||||
cmd.pRegOverride = ble_overrides;
|
||||
cmd.config.frontEndMode = RF_CORE_RADIO_SETUP_FRONT_END_MODE;
|
||||
cmd.config.biasMode = RF_CORE_RADIO_SETUP_BIAS_MODE;
|
||||
|
@ -246,13 +303,114 @@ rf_radio_setup()
|
|||
return RF_CORE_CMD_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(rf_ble_beacon_process, ev, data)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rf_ble_beacon_single(uint8_t channel, uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint8_t was_on;
|
||||
int j;
|
||||
uint32_t cmd_status;
|
||||
bool interrupts_disabled;
|
||||
uint8_t j, channel_selected;
|
||||
uint8_t was_on;
|
||||
|
||||
/* Adhere to the maximum BLE advertisement payload size */
|
||||
if(len > BLE_ADV_NAME_BUF_LEN) {
|
||||
len = BLE_ADV_NAME_BUF_LEN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Under ContikiMAC, some IEEE-related operations will be called from an
|
||||
* interrupt context. We need those to see that we are in BLE mode.
|
||||
*/
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
ble_mode_on = RF_BLE_ACTIVE;
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* First, determine our state:
|
||||
*
|
||||
* If we are running CSMA, we are likely in IEEE RX mode. We need to
|
||||
* abort the IEEE BG Op before entering BLE mode.
|
||||
* If we are ContikiMAC, we are likely off, in which case we need to
|
||||
* boot the CPE before entering BLE mode
|
||||
*/
|
||||
was_on = rf_core_is_accessible();
|
||||
|
||||
if(was_on) {
|
||||
/*
|
||||
* We were on: If we are in the process of receiving a frame, abort the
|
||||
* BLE beacon burst. Otherwise, terminate the primary radio Op so we
|
||||
* can switch to BLE mode
|
||||
*/
|
||||
if(NETSTACK_RADIO.receiving_packet()) {
|
||||
PRINTF("rf_ble_beacon_single: We were receiving\n");
|
||||
|
||||
/* Abort this pass */
|
||||
return;
|
||||
}
|
||||
|
||||
rf_core_primary_mode_abort();
|
||||
} else {
|
||||
|
||||
oscillators_request_hf_xosc();
|
||||
|
||||
/* We were off: Boot the CPE */
|
||||
if(rf_core_boot() != RF_CORE_CMD_OK) {
|
||||
/* Abort this pass */
|
||||
PRINTF("rf_ble_beacon_single: rf_core_boot() failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
oscillators_switch_to_hf_xosc();
|
||||
|
||||
/* Enter BLE mode */
|
||||
if(rf_radio_setup() != RF_CORE_CMD_OK) {
|
||||
/* Continue so we can at least try to restore our previous state */
|
||||
PRINTF("rf_ble_beacon_single: Error entering BLE mode\n");
|
||||
} else {
|
||||
|
||||
for(j = 0; j < 3; j++) {
|
||||
channel_selected = (channel >> j) & 0x01;
|
||||
if(channel_selected == 1) {
|
||||
if(send_ble_adv_nc(37 + j, data, len) != RF_CORE_CMD_OK) {
|
||||
/* Continue... */
|
||||
PRINTF("rf_ble_beacon_single: Channel=%d, "
|
||||
"Error advertising\n", 37 + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send a CMD_STOP command to RF Core */
|
||||
if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_STOP), &cmd_status) != RF_CORE_CMD_OK) {
|
||||
/* Continue... */
|
||||
PRINTF("rf_ble_beacon_single: status=0x%08lx\n", cmd_status);
|
||||
}
|
||||
|
||||
if(was_on) {
|
||||
/* We were on, go back to previous primary mode */
|
||||
rf_core_primary_mode_restore();
|
||||
} else {
|
||||
/* We were off. Shut back off */
|
||||
rf_core_power_down();
|
||||
|
||||
/* Switch HF clock source to the RCOSC to preserve power */
|
||||
oscillators_switch_to_hf_rc();
|
||||
}
|
||||
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
ble_mode_on = RF_BLE_IDLE;
|
||||
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(rf_ble_beacon_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
while(1) {
|
||||
|
@ -278,115 +436,21 @@ PROCESS_THREAD(rf_ble_beacon_process, ev, data)
|
|||
strlen(beacond_config.adv_name));
|
||||
p += strlen(beacond_config.adv_name);
|
||||
|
||||
/*
|
||||
* Send BLE_ADV_MESSAGES beacon bursts. Each burst on all three
|
||||
* channels, with a BLE_ADV_DUTY_CYCLE interval between bursts
|
||||
*/
|
||||
for(i = 0; i < BLE_ADV_MESSAGES; i++) {
|
||||
/*
|
||||
* Under ContikiMAC, some IEEE-related operations will be called from an
|
||||
* interrupt context. We need those to see that we are in BLE mode.
|
||||
*/
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
ble_mode_on = RF_BLE_ACTIVE;
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Send BLE_ADV_MESSAGES beacon bursts. Each burst on all three
|
||||
* channels, with a BLE_ADV_DUTY_CYCLE interval between bursts
|
||||
*
|
||||
* First, determine our state:
|
||||
*
|
||||
* If we are running CSMA, we are likely in IEEE RX mode. We need to
|
||||
* abort the IEEE BG Op before entering BLE mode.
|
||||
* If we are ContikiMAC, we are likely off, in which case we need to
|
||||
* boot the CPE before entering BLE mode
|
||||
*/
|
||||
was_on = rf_core_is_accessible();
|
||||
rf_ble_beacon_single(BLE_ADV_CHANNEL_ALL, payload, p);
|
||||
|
||||
if(was_on) {
|
||||
/*
|
||||
* We were on: If we are in the process of receiving a frame, abort the
|
||||
* BLE beacon burst. Otherwise, terminate the primary radio Op so we
|
||||
* can switch to BLE mode
|
||||
*/
|
||||
if(NETSTACK_RADIO.receiving_packet()) {
|
||||
PRINTF("rf_ble_beacon_process: We were receiving\n");
|
||||
|
||||
/* Abort this pass */
|
||||
break;
|
||||
}
|
||||
|
||||
rf_core_primary_mode_abort();
|
||||
} else {
|
||||
/* Request the HF XOSC to source the HF clock. */
|
||||
oscillators_request_hf_xosc();
|
||||
|
||||
/* We were off: Boot the CPE */
|
||||
if(rf_core_boot() != RF_CORE_CMD_OK) {
|
||||
PRINTF("rf_ble_beacon_process: rf_core_boot() failed\n");
|
||||
|
||||
/* Abort this pass */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Trigger a switch to the XOSC, so that we can use the FS */
|
||||
oscillators_switch_to_hf_xosc();
|
||||
}
|
||||
|
||||
/* Enter BLE mode */
|
||||
if(rf_radio_setup() != RF_CORE_CMD_OK) {
|
||||
PRINTF("cc26xx_rf_ble_beacon_process: Error entering BLE mode\n");
|
||||
/* Continue so we can at least try to restore our previous state */
|
||||
} else {
|
||||
/* Send advertising packets on all 3 advertising channels */
|
||||
for(j = 37; j <= 39; j++) {
|
||||
if(send_ble_adv_nc(j, payload, p) != RF_CORE_CMD_OK) {
|
||||
PRINTF("cc26xx_rf_ble_beacon_process: Channel=%d, "
|
||||
"Error advertising\n", j);
|
||||
/* Break the loop, but don't return just yet */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send a CMD_STOP command to RF Core */
|
||||
if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_STOP), &cmd_status) != RF_CORE_CMD_OK) {
|
||||
PRINTF("cc26xx_rf_ble_beacon_process: status=0x%08lx\n", cmd_status);
|
||||
/* Continue... */
|
||||
}
|
||||
|
||||
if(was_on) {
|
||||
/* We were on, go back to previous primary mode */
|
||||
rf_core_primary_mode_restore();
|
||||
} else {
|
||||
/* We were off. Shut back off */
|
||||
rf_core_power_down();
|
||||
|
||||
/* Switch HF clock source to the RCOSC to preserve power */
|
||||
oscillators_switch_to_hf_rc();
|
||||
}
|
||||
etimer_set(&ble_adv_et, BLE_ADV_DUTY_CYCLE);
|
||||
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
ble_mode_on = RF_BLE_IDLE;
|
||||
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
/* Wait unless this is the last burst */
|
||||
if(i < BLE_ADV_MESSAGES - 1) {
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&ble_adv_et));
|
||||
}
|
||||
}
|
||||
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
ble_mode_on = RF_BLE_IDLE;
|
||||
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue