diff --git a/platform/srf06-cc26xx/Makefile.srf06-cc26xx b/platform/srf06-cc26xx/Makefile.srf06-cc26xx new file mode 100644 index 000000000..7feefa126 --- /dev/null +++ b/platform/srf06-cc26xx/Makefile.srf06-cc26xx @@ -0,0 +1,36 @@ +# srf06-cc26xx platform makefile + +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +### Board and BSP selection +ifeq ($(BOARD),) + BOARD=srf06 +endif + +### Configure the build for the board and pull in board-specific sources +CONTIKI_TARGET_DIRS += . $(BOARD) +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) + +### Include the board dir if one exists +-include $(PLATFORM_ROOT_DIR)/$(BOARD)/Makefile.$(BOARD) + +CONTIKI_TARGET_SOURCEFILES += contiki-main.c +CONTIKI_TARGET_SOURCEFILES += sensors.c leds.c +CONTIKI_TARGET_SOURCEFILES += $(BOARD_SOURCEFILES) + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CLEAN += *.srf06-cc26xx + +### Unless the example dictates otherwise, build with code size optimisations +ifndef SMALL + SMALL = 0 +endif + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/cc26xx +include $(CONTIKI_CPU)/Makefile.cc26xx + +MODULES += core/net core/net/mac core/net/mac/contikimac core/net/llsec diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md new file mode 100644 index 000000000..4cfb9945d --- /dev/null +++ b/platform/srf06-cc26xx/README.md @@ -0,0 +1,180 @@ +Getting Started with Contiki for TI CC26xx +========================================== + +This guide's aim is to help you start using Contiki for TI's CC26xx. The +platform supports two different boards: + +* SmartRF 06 Evaluation Board with a CC26xx Evaluation Module (relevant files + and drivers are under `srf06/`) +* CC26xx SensorTag 2.0 (relevant drivers under `sensortag/`) + +The CPU code, common for both platforms, can be found under `$(CONTIKI)/cpu/cc26xx`. +The port was developed and tested with CC2650s, but the intention is for it to +work with the CC2630 as well. Thus, bug reports are welcome for both chips. +Bear in mind that the CC2630 does not have BLE capability. + +This port is only meant to work with 7x7mm chips + +This guide assumes that you have basic understanding of how to use the command +line and perform basic admin tasks on UNIX family OSs. + +Port Features +============= +The platform has the following key features: + +* Deep Sleep support with RAM retention for ultra-low energy consumption. +* Support for CC26xx RF in IEEE as well as BLE mode (BLE support is very basic + since Contiki does not provide a BLE stack). + +In terms of hardware support, the following drivers have been implemented: + +* SmartRF06 EB peripherals + * LEDs + * Buttons + * UART connectivity over the XDS100v3 backchannel +* SensorTag 2.0 + * LEDs + * Buttons (One of the buttons can be used as a shutdown button) + * Reed relay + * Motion Processing Unit (MPU9250 - Accelerometer, Gyro) + * BMP280 sensor + * TMP007 sensor + * SHT21 sensor + * OPT3001 sensor + * Buzzer + * External SPI flash + +Examples +======== +The port comes with two examples: A very basic example and a mode advanced one +(web demo). The former demonstrates how to read sensors and how to use board +peripherals. It also demonstrates how to send out BLE advertisements. +The latter includes a CoAP server, an MQTT client which connects and publishes +to the IBM quickstart service, a net-based UART and lastly a web server that +can be used to configure the rest of the example. + +More details about those two examples can be found in their respective READMEs. + +Requirements +============ +To use the port you need: + +* TI's CC26xxware sources (more below) +* Software to program the nodes. Use TI's SmartRF Flash Programmer +* A toolchain to build firmware: The port has been developed and tested with + GNU Tools for ARM Embedded Processors . + The port was developed and tested using this version: + + $ arm-none-eabi-gcc -v + [...] + gcc version 4.9.3 20141119 (release) [ARM/embedded-4_9-branch revision 218278] (GNU Tools for ARM Embedded Processors) + +* You may also need other drivers so that the SmartRF can communicate with your +operating system and so that you can use the chip's UART for I/O. Please read +the section ["Drivers" in the CC2538DK readme](https://github.com/contiki-os/contiki/tree/master/platform/cc2538dk#drivers). + +Environment +=========== +To use this port, you will need to download and extract CC26xxware sources, +provided by TI here http://www.ti.com/tool/cc26xxware. Once you have done this, you will need to configure the Contiki +build system so that it can locate and compile them as part of the build process. + +To do this, you will need to set the following environment variable: + +* `TI_CC26XXWARE` + + Stores the path to a directory containing the following: + + * cc26xxware sources under `$(TI_CC26XXWARE)/driverlib` + * cc26xxware includes under `$(TI_CC26XXWARE)/inc` + * Startup files under `$(TI_CC26XXWARE)/startup_files` + +This _must_ be a path relative to the Contiki source directory. For +example, if Contiki is in `/home/user/contiki-2.x` and the CC26xxware is in +`/home/user/cc26xxware`, then `TI_CC26XXWARE` must be set to `../cc26xxware` + +The variable can be set within the example's Makefile, by adding this: + + TI_CC26XXWARE=../cc26xxware + +or you can use an environment variable, like so: + + export TI_CC26XXWARE=../cc26xxware + +Filename conflicts between Contiki and CC26xxware +================================================= +There is a file called `timer.c` both in Contiki as well as in CC26xxware. The +way things are configured now, we don't use the latter. However, if you need to +start using it at some point, you will need to rename it: + +From `$(TI_CC26XXWARE)/driverlib/cc26xx/source/timer.c` to `driverlib-timer.c` + +Sensortag vs Srf06 +================== +To build for the sensortag, set `BOARD=sensortag`. You can do that by exporting +it as an environment variable, by adding it to your Makefile or by adding it to +your make command as an argument + +If the `BOARD` variable is not equal to `sensortag`, an image for the Srf06 +CC26XXEM will be built instead. + +If you want to switch between building for one platform to the other, make +certain to `make clean` before building for the new one, or you will get linker +errors. + +Low Power Operation +=================== +The platform takes advantage of the CC26xx's power saving features. In a +nutshell, here is how things work: + +* When the RF is TXing, the CPU will enter sleep mode and will resume after TX + has completed. +* When there are no events in the Contiki event queue, the chip will enter + 'some' low power mode (more below). + +We do not use pre-defined power profiles (e.g. as mentioned in the TRM or as +we do for the CC2538 with LPM1, LPM2 etc). Each time we enter low power +operation, we either put the CM3 to sleep or to deep sleep. The latter case is +highly configurable: the LPM engine allows other code modules to register +themselves for notifications and to configure low power operation. With these +facilities, a module can e.g. prohibit deep sleep altogether, or it can request +that a power domain be kept powered. The LPM engine will turn off as many +CC26xx components as it can while satisfying all restrictions set by registered +modules. + +To determine which power mode to use, the following logic is followed: + +* The deepest available low power mode can be hard-coded by using + the `LPM_MODE_MAX_SUPPORTED` macro in the LPM driver (`lpm.[ch]`). Thus, it + is possible to prohibit deep sleep altogether. +* Code modules which are affected by low power operation can 'register' + themselves with the LPM driver. +* If the projected low-power duration is lower than `STANDBY_MIN_DURATION`, + the chip will simply sleep. +* If the projected low power duration is sufficiently long, the LPM will visit + all registered modules to query the maximum allowed power mode (maximum means + sleep vs deep sleep in this context). It will then drop to this power mode. + This is where a code module can forbid deep sleep if required. +* All registered modules will be notified when the chip is about to enter + deep sleep, as well as after wake-up. + +When the chip does enter deep sleep: + +* The RF Core, VIMS, SYSBUS and CPU power domains are always turned off. Due to + the way the RF driver works, the RFCORE PD should be off already. +* Peripheral clocks stop +* The Serial and Peripheral power domains are turned off, unless an LPM module + requests them to stay operational. For example, the net-uart demo keeps the + serial power domain powered on and the UART clocked under sleep and deep + sleep in order to retain UART RX functionality. +* If both SERIAL and PERIPH PDs are turned off, we also switch power source to + the uLDO for ultra low leakage under deep sleep. + +The chip will come out of low power mode by one of the following events: + +* Button press or, in the case of the SensorTag, a reed relay trigger +* Software clock tick (timer). The clock ticks at 128Hz, therefore the maximum + time we will ever spend in a sleep mode is 7.8125ms. In hardware terms, this + is an AON RTC Channel 2 compare interrupt. +* Rtimer triggers, as part of ContikiMAC's sleep/wake-up cycles. The rtimer + sits on the AON RTC channel 0. diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h new file mode 100644 index 000000000..6a99c29b3 --- /dev/null +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2014, 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 cc26xx-srf-tag + * @{ + * + * \file + * Configuration for the srf06-cc26xx platform + */ +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC26xx flavour selection + * @{ + */ +#ifndef CC26XX_MODEL_CONF_CPU_VARIANT +#define CC26XX_MODEL_CONF_CPU_VARIANT 2650 /**< 2650 => CC2650, 2630 => CC2630 */ + +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#else +#define NETSTACK_CONF_NETWORK rime_driver +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +/* Configure NullRDC for when it's selected */ +#define NULLRDC_802154_AUTOACK 1 +#define NULLRDC_802154_AUTOACK_HW 1 + +/* Configure ContikiMAC for when it's selected */ +#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define WITH_FAST_SLEEP 1 + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 +#endif + +#define NETSTACK_CONF_RADIO cc26xx_rf_driver +#define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125 + +/* 6LoWPAN */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our RIME & 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 IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD /**< Default PAN ID */ +#endif + +#ifndef CC26XX_RF_CONF_CHANNEL +#define CC26XX_RF_CONF_CHANNEL 25 /**< Default RF channel */ +#endif + +#ifndef CC26XX_RF_CONF_AUTOACK +#define CC26XX_RF_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#endif + +#ifndef CC26XX_RF_CONF_PROMISCOUS +#define CC26XX_RF_CONF_PROMISCOUS 0 /**< 1 to enable promiscous mode */ +#endif + +#ifndef CC26XX_RF_CONF_BLE_SUPPORT +#define CC26XX_RF_CONF_BLE_SUPPORT 0 /**< 0 to disable BLE support */ +#endif + +/* + * Patch Management for the CPE itself and for BLE and IEEE modes + * + * Don't change these unless you know what you're doing + */ +#ifndef CC26XX_CONF_CPE_HAS_PATCHES +#define CC26XX_CONF_CPE_HAS_PATCHES 0 /**< 1 to enable patching the CPE */ +#endif + +#ifndef CC26XX_CONF_BLE_HAS_PATCHES +#define CC26XX_CONF_BLE_HAS_PATCHES 0 /**< 1 to enable patching BLE mode */ +#endif + +#ifndef CC26XX_CONF_IEEE_HAS_PATCHES +#define CC26XX_CONF_IEEE_HAS_PATCHES 0 /**< 1 to enable patching IEEE mode */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** @} */ +/** + * \name IPv6, RIME and network buffer configuration + * + * @{ + */ +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/*---------------------------------------------------------------------------*/ +/* Addresses, Sizes and Interfaces */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* The size of the uIP main buffer */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1000 +#endif + +/* ND and Routing */ +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_IP_FORWARD 0 +#define RPL_CONF_STATS 0 +#define RPL_CONF_MAX_DAG_ENTRIES 1 +#ifndef RPL_CONF_OF +#define RPL_CONF_OF rpl_mrhof +#endif + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif + +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 128 +#endif + +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 +/*---------------------------------------------------------------------------*/ +#else /* NETSTACK_CONF_WITH_IPV6 */ +/* Network setup for non-IPv6 (rime). */ +#define UIP_CONF_IP_FORWARD 1 + +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 + +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Generic Configuration directives + * + * @{ + */ +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 0 /**< Energest Module */ +#endif + +#ifndef STARTUP_CONF_VERBOSE +#define STARTUP_CONF_VERBOSE 1 /**< Set to 0 to decrease startup verbosity */ +#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 + +/* Turn off example-provided putchars */ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#define SLIP_RADIO_CONF_NO_PUTCHAR 1 + +#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 CC26XX_CONF_QUIET +#define CC26XX_CONF_QUIET 0 +#endif + +/* CC26XX_CONF_QUIET is hard and overrides all other related defines */ +#if CC26XX_CONF_QUIET +#undef CC26XX_UART_CONF_ENABLE +#define CC26XX_UART_CONF_ENABLE 0 + +#undef STARTUP_CONF_VERBOSE +#define STARTUP_CONF_VERBOSE 0 +#endif /* CC26XX_CONF_QUIET */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button configurations + * + * Configure a button as power on/off: We use the right button for both boards. + * @{ + */ +#ifndef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#define BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN 1 +#endif + +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/* Platform-specific define to signify sensor reading failure */ +#define CC26XX_SENSOR_READING_ERROR 0x80000000 +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* Clock (time) comparison macro */ +#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) + +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_LT to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) +/** @} */ +/*---------------------------------------------------------------------------*/ +/* board.h assumes that basic configuration is done */ +#include "board.h" +/*---------------------------------------------------------------------------*/ +#endif /* CONTIKI_CONF_H */ + +/** @} */ diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c new file mode 100644 index 000000000..d28643531 --- /dev/null +++ b/platform/srf06-cc26xx/contiki-main.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2014, 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 cc26xx-platforms + * @{ + * + * \defgroup cc26xx-srf-tag SmartRF+CC26xx EM and the CC26xx SensorTag 2.0 + * + * This platform supports two different boards: + * 1) A standard TI SmartRF06EB with a CC26xx EM mounted on it and + * 2) The new TI SensorTag2.0 + * @{ + */ +#include "ti-lib.h" +#include "contiki.h" +#include "contiki-net.h" +#include "leds.h" +#include "lpm.h" +#include "gpio-interrupt.h" +#include "dev/watchdog.h" +#include "ieee-addr.h" +#include "vims.h" +#include "cc26xx-model.h" +#include "dev/cc26xx-uart.h" +#include "dev/cc26xx-rtc.h" +#include "dev/cc26xx-rf.h" +#include "sys_ctrl.h" +#include "uart.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "lib/sensors.h" +#include "button-sensor.h" +#include "dev/serial-line.h" +#include "net/mac/frame802154.h" + +#include "driverlib/driverlib_ver.h" + +#include +/*---------------------------------------------------------------------------*/ +static void +fade(unsigned char l) +{ + volatile int i; + int k, j; + for(k = 0; k < 800; ++k) { + j = k > 400 ? 800 - k : k; + + leds_on(l); + for(i = 0; i < j; ++i) { + __asm("nop"); + } + leds_off(l); + for(i = 0; i < 400 - j; ++i) { + __asm("nop"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rf_params(void) +{ + uint16_t short_addr; + uint8_t ext_addr[8]; + radio_value_t val = 0; + + ieee_addr_cpy_to(ext_addr, 8); + + short_addr = ext_addr[7]; + short_addr |= ext_addr[6] << 8; + + /* Populate linkaddr_node_addr. Maintain endianness */ + memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE); + + NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); + NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC26XX_RF_CHANNEL); + NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); + + NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &val); + printf(" RF: Channel %d\n", val); + +#if STARTUP_CONF_VERBOSE + { + int i; + printf(" Link layer addr: "); + for(i = 0; i < LINKADDR_SIZE - 1; i++) { + printf("%02x:", linkaddr_node_addr.u8[i]); + } + printf("%02x\n", linkaddr_node_addr.u8[i]); + } +#endif +} +/*---------------------------------------------------------------------------*/ +static void +select_lf_xosc(void) +{ + ti_lib_osc_interface_enable(); + + /* Make sure the SMPH clock within AUX is enabled */ + ti_lib_aux_wuc_clock_enable(AUX_WUC_SMPH_CLOCK); + while(ti_lib_aux_wuc_clock_status(AUX_WUC_SMPH_CLOCK) != AUX_WUC_CLOCK_READY); + + /* Switch LF clock source to the LF RCOSC if required */ + if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_XOSC_LF) { + ti_lib_osc_clock_source_set(OSC_SRC_CLK_LF, OSC_XOSC_LF); + } + + ti_lib_osc_interface_disable(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main function for CC26xx-based platforms + * + * The same main() is used for both Srf+CC26xxEM as well as for the SensorTag + */ +int +main(void) +{ + /* Set the LF XOSC as the LF system clock source */ + select_lf_xosc(); + + /* + * Make sure to open the latches - this will be important when returning + * from shutdown + */ + ti_lib_pwr_ctrl_io_freeze_disable(); + + /* Use DCDC instead of LDO to save current */ + ti_lib_pwr_ctrl_source_set(PWRCTRL_PWRSRC_DCDC); + + lpm_init(); + + board_init(); + + /* Enable flash cache and prefetch. */ + ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_ENABLED); + ti_lib_vims_configure(VIMS_BASE, true, true); + + gpio_interrupt_init(); + + /* Clock must always be enabled for the semaphore module */ + HWREG(AUX_WUC_BASE + AUX_WUC_O_MODCLKEN1) = AUX_WUC_MODCLKEN1_SMPH; + + leds_init(); + + fade(LEDS_RED); + + cc26xx_rtc_init(); + clock_init(); + rtimer_init(); + + board_init(); + + watchdog_init(); + process_init(); + + random_init(0x1234); + + /* Character I/O Initialisation */ +#if CC26XX_UART_CONF_ENABLE + cc26xx_uart_init(); + cc26xx_uart_set_input(serial_line_input_byte); +#endif + + serial_line_init(); + + printf("Starting " CONTIKI_VERSION_STRING "\n"); + printf("With CC26xxware v%u.%02u.%02u.%u\n", DRIVERLIB_MAJOR_VER, + DRIVERLIB_MINOR_VER, DRIVERLIB_PATCH_VER, DRIVERLIB_BUILD_ID); + printf(BOARD_STRING " using CC%u\n", CC26XX_MODEL_CPU_VARIANT); + + process_start(&etimer_process, NULL); + ctimer_init(); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + fade(LEDS_YELLOW); + + printf(" Net: "); + printf("%s\n", NETSTACK_NETWORK.name); + printf(" MAC: "); + printf("%s\n", NETSTACK_MAC.name); + printf(" RDC: "); + printf("%s", NETSTACK_RDC.name); + + if(NETSTACK_RDC.channel_check_interval() != 0) { + printf(", Channel Check Interval: %u ticks", + NETSTACK_RDC.channel_check_interval()); + } + printf("\n"); + + netstack_init(); + + set_rf_params(); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); + queuebuf_init(); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + fade(LEDS_GREEN); + + process_start(&sensors_process, NULL); + + autostart_start(autostart_processes); + + watchdog_start(); + + fade(LEDS_ORANGE); + + while(1) { + uint8_t r; + do { + r = process_run(); + watchdog_periodic(); + } while(r > 0); + + /* Drop to some low power mode */ + lpm_drop(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */