Merge pull request #502 from contiki-ng/release-4.1

Release v4.1
This commit is contained in:
Simon Duquennoy 2018-05-11 16:59:14 +02:00 committed by GitHub
commit 7da2787933
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1019 changed files with 38042 additions and 30899 deletions

17
.gitignore vendored
View File

@ -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

6
.gitmodules vendored
View File

@ -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

View File

@ -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'

View File

@ -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.

View File

@ -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

View File

@ -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

54
arch/cpu/arm/Makefile.arm Normal file
View File

@ -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 $< $@

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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
*/

View File

@ -1,7 +1,6 @@
#include <efs-sdcard.h>
#include <sys/process.h>
#include <cfs/cfs.h>
#include <debug-uart.h>
#include <stdio.h>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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)
{
}
/*----------------------------------------------------------------------------*/
/** @} */

View File

@ -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_ */
/**
* @}
* @}
*/

View File

@ -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

View File

@ -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;

View File

@ -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__ */

View File

@ -66,7 +66,7 @@
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex-M0+
\ingroup Cortex_M0_plus
@{
*/

View File

@ -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
*/

View File

@ -0,0 +1,3 @@
CONTIKI_ARM_DIRS += cortex-m cortex-m/CMSIS
include $(CONTIKI)/arch/cpu/arm/Makefile.arm

View File

@ -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

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/** @} */
/**
* @}
* @}
*/

View File

@ -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

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View File

@ -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_ */
/*---------------------------------------------------------------------------*/

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -0,0 +1,4 @@
/**
* \defgroup arm Support for Arm CPUs
* \ingroup cpu
*/

View File

@ -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

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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_ */
/*---------------------------------------------------------------------------*/

View File

@ -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);

View File

@ -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;

View File

@ -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_ */
/**
* @}
* @}
* @}
* @}
*/

View File

@ -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;
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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_ */
/**
* @}
* @}
*/

View File

@ -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);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View File

@ -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));
}
/** @} */

View File

@ -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_ */
/**

View File

@ -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)
{

View File

@ -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)

View File

@ -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_ */
/**
* @}

View File

@ -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;
}
/*---------------------------------------------------------------------------*/

View File

@ -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"
/*---------------------------------------------------------------------------*/

View File

@ -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
*/

View File

@ -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;
}
/*---------------------------------------------------------------------------*/
/**
* @}

View File

@ -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();
}

View File

@ -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 ? \

View File

@ -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);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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();
}
/*----------------------------------------------------------------------------*/
/** @} */

View File

@ -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 */

View File

@ -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;
/** @} */

View File

@ -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__ */

View File

@ -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

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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_ */
/*---------------------------------------------------------------------------*/

View File

@ -56,7 +56,7 @@ _estack = ORIGIN(SRAM) + LENGTH(SRAM); /* End of SRAM */
/*. Generate a link error if heap and stack dont 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))

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View File

@ -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)
}
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
* @}
* @}
* @}
*/

View File

@ -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)
{

View File

@ -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"

View File

@ -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
/*---------------------------------------------------------------------------*/

View File

@ -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);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View File

@ -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);
}
}
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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;
}

View File

@ -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
*/

View File

@ -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

View File

@ -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();

View File

@ -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__ */

View File

@ -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

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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();

View File

@ -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

View File

@ -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