Merge branch 'contiki' into osd
This commit is contained in:
commit
6a0d407806
84 changed files with 2097 additions and 1029 deletions
|
@ -106,6 +106,7 @@ env:
|
|||
## of environment variable defined below
|
||||
- BUILD_TYPE='doxygen' BUILD_CATEGORY='doxygen'
|
||||
- BUILD_TYPE='compile-base' BUILD_CATEGORY='compile'
|
||||
- BUILD_TYPE='compile-tools' BUILD_CATEGORY='compile'
|
||||
- BUILD_TYPE='collect'
|
||||
- BUILD_TYPE='collect-lossy'
|
||||
- BUILD_TYPE='rpl'
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "er-coap-separate.h"
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "contiki-net.h"
|
||||
|
||||
#include "er-coap.h"
|
||||
|
|
|
@ -79,10 +79,6 @@ enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
|
|||
#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE))
|
||||
#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE)))
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
/* parsed message struct */
|
||||
typedef struct {
|
||||
uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */
|
||||
|
|
|
@ -57,13 +57,12 @@
|
|||
|
||||
#include "lib/assert.h"
|
||||
#include "lib/list.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#define PRINTF(...) PRINTF(__VA_ARGS__)
|
||||
|
|
|
@ -62,10 +62,6 @@
|
|||
#define REST_MAX_CHUNK_SIZE 64
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
struct resource_s;
|
||||
struct periodic_resource_s;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "sys/energest.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sys/cc.h"
|
||||
|
||||
struct power_msg {
|
||||
uint16_t len;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "shell-sky.h"
|
||||
|
||||
#include "dev/watchdog.h"
|
||||
|
@ -84,8 +85,6 @@ SHELL_COMMAND(rfchannel_command,
|
|||
"rfchannel <channel>: change CC2420 radio channel (11 - 26)",
|
||||
&shell_rfchannel_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define MAX(a, b) ((a) > (b)? (a): (b))
|
||||
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||
struct spectrum {
|
||||
int channel[16];
|
||||
};
|
||||
|
|
|
@ -36,13 +36,10 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "shell.h"
|
||||
#include "telnet.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(shell_tcpsend_process, "tcpsend");
|
||||
SHELL_COMMAND(tcpsend_command,
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "shell-time.h"
|
||||
|
||||
#include "sys/clock.h"
|
||||
|
@ -51,11 +52,6 @@
|
|||
#define MAX_COMMANDLENGTH 64
|
||||
#define PERIOD_INTERVAL 60
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(shell_time_process, "time");
|
||||
SHELL_COMMAND(time_command,
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include "contiki-lib.h"
|
||||
#include "contiki-net.h"
|
||||
#include "lib/petsciiconv.h"
|
||||
|
@ -103,7 +104,6 @@ static uint8_t connected;
|
|||
|
||||
#define MAX_SILENCE_TIME (CLOCK_SECOND * 30)
|
||||
|
||||
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
buf_init(struct telnetd_buf *buf)
|
||||
|
|
|
@ -57,36 +57,36 @@ extern unsigned char spi_busy;
|
|||
void spi_init(void);
|
||||
|
||||
/* Write one character to SPI */
|
||||
#define SPI_WRITE(data) \
|
||||
do { \
|
||||
SPI_WAITFORTx_BEFORE(); \
|
||||
SPI_TXBUF = data; \
|
||||
SPI_WAITFOREOTx(); \
|
||||
#define SPI_WRITE(data) \
|
||||
do { \
|
||||
SPI_WAITFORTx_BEFORE(); \
|
||||
SPI_TXBUF = data; \
|
||||
SPI_WAITFOREOTx(); \
|
||||
} while(0)
|
||||
|
||||
/* Write one character to SPI - will not wait for end
|
||||
useful for multiple writes with wait after final */
|
||||
#define SPI_WRITE_FAST(data) \
|
||||
do { \
|
||||
SPI_WAITFORTx_BEFORE(); \
|
||||
SPI_TXBUF = data; \
|
||||
SPI_WAITFORTx_AFTER(); \
|
||||
#define SPI_WRITE_FAST(data) \
|
||||
do { \
|
||||
SPI_WAITFORTx_BEFORE(); \
|
||||
SPI_TXBUF = data; \
|
||||
SPI_WAITFORTx_AFTER(); \
|
||||
} while(0)
|
||||
|
||||
/* Read one character from SPI */
|
||||
#define SPI_READ(data) \
|
||||
do { \
|
||||
SPI_TXBUF = 0; \
|
||||
SPI_WAITFOREORx(); \
|
||||
data = SPI_RXBUF; \
|
||||
#define SPI_READ(data) \
|
||||
do { \
|
||||
SPI_TXBUF = 0; \
|
||||
SPI_WAITFOREORx(); \
|
||||
data = SPI_RXBUF; \
|
||||
} while(0)
|
||||
|
||||
/* Flush the SPI read register */
|
||||
#ifndef SPI_FLUSH
|
||||
#define SPI_FLUSH() \
|
||||
do { \
|
||||
SPI_RXBUF; \
|
||||
} while(0);
|
||||
do { \
|
||||
SPI_RXBUF; \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#endif /* SPI_H_ */
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
#define SETTINGS_BOTTOM_ADDR (SETTINGS_TOP_ADDR + 1 - SETTINGS_MAX_SIZE)
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?a:b)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#if SETTINGS_CONF_SUPPORT_LARGE_VALUES
|
||||
uint8_t size_extra;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "contiki-net.h"
|
||||
|
||||
#include "lib/list.h"
|
||||
|
@ -39,7 +40,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
static void relisten(struct tcp_socket *s);
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@
|
|||
#include "net/ipv4/uip-neighbor.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "sys/cc.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Variable definitions. */
|
||||
|
||||
|
@ -1953,7 +1955,6 @@ void
|
|||
uip_send(const void *data, int len)
|
||||
{
|
||||
int copylen;
|
||||
#define MIN(a,b) ((a) < (b)? (a): (b))
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
|
||||
(int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
|
||||
if(copylen > 0) {
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
* the packet back to the peer.
|
||||
*/
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ip/uipopt.h"
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
|
@ -2332,7 +2333,6 @@ void
|
|||
uip_send(const void *data, int len)
|
||||
{
|
||||
int copylen;
|
||||
#define MIN(a,b) ((a) < (b)? (a): (b))
|
||||
|
||||
if(uip_sappdata != NULL) {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
|
||||
|
|
|
@ -229,10 +229,6 @@ static struct compower_activity current_packet;
|
|||
|
||||
#define DEFAULT_STREAM_TIME (4 * CYCLE_TIME)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
#if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
|
||||
static struct timer broadcast_rate_timer;
|
||||
static int broadcast_rate_counter;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "sys/rtimer.h"
|
||||
|
||||
#include "contiki-conf.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
#ifdef EXPERIMENT_SETUP
|
||||
#include "experiment-setup.h"
|
||||
|
@ -215,10 +216,6 @@ static linkaddr_t is_streaming_to, is_streaming_to_too;
|
|||
static rtimer_clock_t stream_until;
|
||||
#define DEFAULT_STREAM_TIME (RTIMER_ARCH_SECOND)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
on(void)
|
||||
|
|
|
@ -92,8 +92,6 @@ static struct broadcast_announcement_state {
|
|||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) ((a)<(b)?(a):(b))
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
send_adv(void *ptr)
|
||||
|
|
|
@ -42,20 +42,13 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include "net/rime/rime.h"
|
||||
#include "net/rime/ipolite.h"
|
||||
#include "lib/random.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b)? (a) : (b))
|
||||
#endif /* MAX */
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include "lib/list.h"
|
||||
#include "net/rime/rime.h"
|
||||
#include "net/rime/announcement.h"
|
||||
|
@ -90,8 +90,6 @@ static struct polite_announcement_state {
|
|||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) ((a)<(b)?(a):(b))
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
send_adv(clock_time_t interval)
|
||||
|
|
|
@ -42,21 +42,13 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include "net/rime/rime.h"
|
||||
#include "net/rime/polite.h"
|
||||
#include "lib/random.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) > (b)? (a) : (b))
|
||||
#endif /* MAX */
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
recv(struct abc_conn *abc)
|
||||
|
|
|
@ -127,14 +127,33 @@
|
|||
#define NULL 0
|
||||
#endif /* NULL */
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(n, m) (((n) < (m)) ? (m) : (n))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(n, m) (((n) < (m)) ? (n) : (m))
|
||||
#endif
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(n) (((n) < 0) ? -(n) : (n))
|
||||
#endif
|
||||
|
||||
|
||||
#define CC_CONCAT2(s1, s2) s1##s2
|
||||
/**
|
||||
* A C preprocessing macro for concatenating to
|
||||
* strings.
|
||||
* A C preprocessing macro for concatenating two preprocessor tokens.
|
||||
*
|
||||
* We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow
|
||||
* concatenation of two \#defined macros.
|
||||
*/
|
||||
#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2)
|
||||
#define CC_CONCAT_EXT_2(s1, s2) CC_CONCAT2(s1, s2)
|
||||
|
||||
/**
|
||||
* A C preprocessing macro for concatenating three preprocessor tokens.
|
||||
*/
|
||||
#define CC_CONCAT3(s1, s2, s3) s1##s2##s3
|
||||
#define CC_CONCAT_EXT_3(s1, s2, s3) CC_CONCAT3(s1, s2, s3)
|
||||
|
||||
#endif /* CC_H_ */
|
||||
|
|
|
@ -280,9 +280,6 @@ typedef char r_uart_ptchar;
|
|||
#define OUT_X(addrx,value) (*addrx = value)
|
||||
#define IN_X(addrx) (*addrx)
|
||||
|
||||
# define Max(a, b) ( (a)>(b) ? (a) : (b) ) // Take the max between a and b
|
||||
# define Min(a, b) ( (a)<(b) ? (a) : (b) ) // Take the min between a and b
|
||||
|
||||
// Align on the upper value <val> on a <n> boundary
|
||||
// i.e. Upper(0, 4)= 4
|
||||
// Upper(1, 4)= 4
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2013, University of Michigan.
|
||||
*
|
||||
* Copyright (c) 2015, Weptech elektronik GmbH
|
||||
* Author: Ulf Knoblich, ulf.knoblich@weptech.de
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -41,102 +45,281 @@
|
|||
#include "dev/spi.h"
|
||||
#include "dev/ssi.h"
|
||||
#include "dev/gpio.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Check port / pin settings for SPI0 and provide default values for spi_cfg */
|
||||
#ifndef SPI0_CLK_PORT
|
||||
#define SPI0_CLK_PORT (-1)
|
||||
#endif
|
||||
#ifndef SPI0_CLK_PIN
|
||||
#define SPI0_CLK_PIN (-1)
|
||||
#endif
|
||||
#if SPI0_CLK_PORT >= 0 && SPI0_CLK_PIN < 0 || \
|
||||
SPI0_CLK_PORT < 0 && SPI0_CLK_PIN >= 0
|
||||
#error Both SPI0_CLK_PORT and SPI0_CLK_PIN must be valid or invalid
|
||||
#endif
|
||||
|
||||
#define SPI_CLK_PORT_BASE GPIO_PORT_TO_BASE(SPI_CLK_PORT)
|
||||
#define SPI_CLK_PIN_MASK GPIO_PIN_MASK(SPI_CLK_PIN)
|
||||
#define SPI_MOSI_PORT_BASE GPIO_PORT_TO_BASE(SPI_MOSI_PORT)
|
||||
#define SPI_MOSI_PIN_MASK GPIO_PIN_MASK(SPI_MOSI_PIN)
|
||||
#define SPI_MISO_PORT_BASE GPIO_PORT_TO_BASE(SPI_MISO_PORT)
|
||||
#define SPI_MISO_PIN_MASK GPIO_PIN_MASK(SPI_MISO_PIN)
|
||||
#ifndef SPI0_TX_PORT
|
||||
#define SPI0_TX_PORT (-1)
|
||||
#endif
|
||||
#ifndef SPI0_TX_PIN
|
||||
#define SPI0_TX_PIN (-1)
|
||||
#endif
|
||||
#if SPI0_TX_PORT >= 0 && SPI0_TX_PIN < 0 || \
|
||||
SPI0_TX_PORT < 0 && SPI0_TX_PIN >= 0
|
||||
#error Both SPI0_TX_PORT and SPI0_TX_PIN must be valid or invalid
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize the SPI bus.
|
||||
*
|
||||
* This SPI init() function uses the following defines to set the pins:
|
||||
* SPI_CLK_PORT SPI_CLK_PIN
|
||||
* SPI_MOSI_PORT SPI_MOSI_PIN
|
||||
* SPI_MISO_PORT SPI_MISO_PIN
|
||||
*
|
||||
* This sets the mode to Motorola SPI with the following format options:
|
||||
* Clock phase: 1; data captured on second (rising) edge
|
||||
* Clock polarity: 1; clock is high when idle
|
||||
* Data size: 8 bits
|
||||
*/
|
||||
#ifndef SPI0_RX_PORT
|
||||
#define SPI0_RX_PORT (-1)
|
||||
#endif
|
||||
#ifndef SPI0_RX_PIN
|
||||
#define SPI0_RX_PIN (-1)
|
||||
#endif
|
||||
#if SPI0_RX_PORT >= 0 && SPI0_RX_PIN < 0 || \
|
||||
SPI0_RX_PORT < 0 && SPI0_RX_PIN >= 0
|
||||
#error Both SPI0_RX_PORT and SPI0_RX_PIN must be valid or invalid
|
||||
#endif
|
||||
|
||||
/* Here we check that either all or none of the ports are defined. As
|
||||
we did already check that both ports + pins are either defined or
|
||||
not for every pin, this means that we can check for an incomplete
|
||||
configuration by only looking at the port defines */
|
||||
/* If some SPI0 pads are valid */
|
||||
#if SPI0_CLK_PORT >= 0 || SPI0_TX_PORT >= 0 || SPI0_RX_PORT >= 0
|
||||
/* but not all */
|
||||
#if SPI0_CLK_PORT < 0 || SPI0_TX_PORT < 0 || SPI0_RX_PORT < 0
|
||||
#error Some SPI0 pad definitions are invalid
|
||||
#endif
|
||||
#define SPI0_PADS_VALID
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Check port / pin settings for SPI1 and provide default values for spi_cfg */
|
||||
#ifndef SPI1_CLK_PORT
|
||||
#define SPI1_CLK_PORT (-1)
|
||||
#endif
|
||||
#ifndef SPI1_CLK_PIN
|
||||
#define SPI1_CLK_PIN (-1)
|
||||
#endif
|
||||
#if SPI1_CLK_PORT >= 0 && SPI1_CLK_PIN < 0 || \
|
||||
SPI1_CLK_PORT < 0 && SPI1_CLK_PIN >= 0
|
||||
#error Both SPI1_CLK_PORT and SPI1_CLK_PIN must be valid or invalid
|
||||
#endif
|
||||
|
||||
#ifndef SPI1_TX_PORT
|
||||
#define SPI1_TX_PORT (-1)
|
||||
#endif
|
||||
#ifndef SPI1_TX_PIN
|
||||
#define SPI1_TX_PIN (-1)
|
||||
#endif
|
||||
#if SPI1_TX_PORT >= 0 && SPI1_TX_PIN < 0 || \
|
||||
SPI1_TX_PORT < 0 && SPI1_TX_PIN >= 0
|
||||
#error Both SPI1_TX_PORT and SPI1_TX_PIN must be valid or invalid
|
||||
#endif
|
||||
|
||||
#ifndef SPI1_RX_PORT
|
||||
#define SPI1_RX_PORT (-1)
|
||||
#endif
|
||||
#ifndef SPI1_RX_PIN
|
||||
#define SPI1_RX_PIN (-1)
|
||||
#endif
|
||||
#if SPI1_RX_PORT >= 0 && SPI1_RX_PIN < 0 || \
|
||||
SPI1_RX_PORT < 0 && SPI1_RX_PIN >= 0
|
||||
#error Both SPI1_RX_PORT and SPI1_RX_PIN must be valid or invalid
|
||||
#endif
|
||||
|
||||
/* If some SPI1 pads are valid */
|
||||
#if SPI1_CLK_PORT >= 0 || SPI1_TX_PORT >= 0 || SPI1_RX_PORT >= 0
|
||||
/* but not all */
|
||||
#if SPI1_CLK_PORT < 0 || SPI1_TX_PORT < 0 || SPI1_RX_PORT < 0
|
||||
#error Some SPI1 pad definitions are invalid
|
||||
#endif
|
||||
#define SPI1_PADS_VALID
|
||||
#endif
|
||||
|
||||
#ifdef SPI_DEFAULT_INSTANCE
|
||||
#if SPI_DEFAULT_INSTANCE == 0
|
||||
#ifndef SPI0_PADS_VALID
|
||||
#error SPI_DEFAULT_INSTANCE is set to SPI0, but its pads are not valid
|
||||
#endif
|
||||
#elif SPI_DEFAULT_INSTANCE == 1
|
||||
#ifndef SPI1_PADS_VALID
|
||||
#error SPI_DEFAULT_INSTANCE is set to SPI1, but its pads are not valid
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (SPI0_CPRS_CPSDVSR & 1) == 1 || SPI0_CPRS_CPSDVSR < 2 || SPI0_CPRS_CPSDVSR > 254
|
||||
#error SPI0_CPRS_CPSDVSR must be an even number between 2 and 254
|
||||
#endif
|
||||
|
||||
#if (SPI1_CPRS_CPSDVSR & 1) == 1 || SPI1_CPRS_CPSDVSR < 2 || SPI1_CPRS_CPSDVSR > 254
|
||||
#error SPI1_CPRS_CPSDVSR must be an even number between 2 and 254
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
int8_t port;
|
||||
int8_t pin;
|
||||
} spi_pad_t;
|
||||
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_pad_t clk;
|
||||
spi_pad_t tx;
|
||||
spi_pad_t rx;
|
||||
} 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 = SPI0_CPRS_CPSDVSR,
|
||||
.clk = { SPI0_CLK_PORT, SPI0_CLK_PIN },
|
||||
.tx = { SPI0_TX_PORT, SPI0_TX_PIN },
|
||||
.rx = { SPI0_RX_PORT, SPI0_RX_PIN }
|
||||
}, {
|
||||
.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 = SPI1_CPRS_CPSDVSR,
|
||||
.clk = { SPI1_CLK_PORT, SPI1_CLK_PIN },
|
||||
.tx = { SPI1_TX_PORT, SPI1_TX_PIN },
|
||||
.rx = { SPI1_RX_PORT, SPI1_RX_PIN }
|
||||
}
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Deprecated function call provided for compatibility reasons */
|
||||
#ifdef SPI_DEFAULT_INSTANCE
|
||||
void
|
||||
spi_init(void)
|
||||
{
|
||||
spi_enable();
|
||||
spix_init(SPI_DEFAULT_INSTANCE);
|
||||
}
|
||||
#endif /* #ifdef SPI_DEFAULT_INSTANCE */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spix_init(uint8_t spi)
|
||||
{
|
||||
const spi_regs_t *regs;
|
||||
|
||||
if(spi >= SSI_INSTANCE_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
regs = &spi_regs[spi];
|
||||
|
||||
if(regs->clk.port < 0) {
|
||||
/* Port / pin configuration invalid. We checked for completeness
|
||||
above. If clk.port is < 0, this means that all other defines are
|
||||
< 0 as well */
|
||||
return;
|
||||
}
|
||||
|
||||
spix_enable(spi);
|
||||
|
||||
/* Start by disabling the peripheral before configuring it */
|
||||
REG(SSI0_BASE + SSI_CR1) = 0;
|
||||
REG(regs->base + SSI_CR1) = 0;
|
||||
|
||||
/* Set the IO clock as the SSI clock */
|
||||
REG(SSI0_BASE + SSI_CC) = 1;
|
||||
REG(regs->base + SSI_CC) = 1;
|
||||
|
||||
/* Set the mux correctly to connect the SSI pins to the correct GPIO pins */
|
||||
ioc_set_sel(SPI_CLK_PORT, SPI_CLK_PIN, IOC_PXX_SEL_SSI0_CLKOUT);
|
||||
ioc_set_sel(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_PXX_SEL_SSI0_TXD);
|
||||
REG(IOC_SSIRXD_SSI0) = (SPI_MISO_PORT * 8) + SPI_MISO_PIN;
|
||||
ioc_set_sel(regs->clk.port,
|
||||
regs->clk.pin,
|
||||
regs->ioc_pxx_sel_ssi_clkout);
|
||||
ioc_set_sel(regs->tx.port,
|
||||
regs->tx.pin,
|
||||
regs->ioc_pxx_sel_ssi_txd);
|
||||
REG(regs->ioc_ssirxd_ssi) = (regs->rx.port * 8) + regs->rx.pin;
|
||||
|
||||
/* Put all the SSI gpios into peripheral mode */
|
||||
GPIO_PERIPHERAL_CONTROL(SPI_CLK_PORT_BASE, SPI_CLK_PIN_MASK);
|
||||
GPIO_PERIPHERAL_CONTROL(SPI_MOSI_PORT_BASE, SPI_MOSI_PIN_MASK);
|
||||
GPIO_PERIPHERAL_CONTROL(SPI_MISO_PORT_BASE, SPI_MISO_PIN_MASK);
|
||||
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->clk.port),
|
||||
GPIO_PIN_MASK(regs->clk.pin));
|
||||
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->tx.port),
|
||||
GPIO_PIN_MASK(regs->tx.pin));
|
||||
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->rx.port),
|
||||
GPIO_PIN_MASK(regs->rx.pin));
|
||||
|
||||
/* Disable any pull ups or the like */
|
||||
ioc_set_over(SPI_CLK_PORT, SPI_CLK_PIN, IOC_OVERRIDE_DIS);
|
||||
ioc_set_over(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_OVERRIDE_DIS);
|
||||
ioc_set_over(SPI_MISO_PORT, SPI_MISO_PIN, IOC_OVERRIDE_DIS);
|
||||
ioc_set_over(regs->clk.port, regs->clk.pin, IOC_OVERRIDE_DIS);
|
||||
ioc_set_over(regs->tx.port, regs->tx.pin, IOC_OVERRIDE_DIS);
|
||||
ioc_set_over(regs->rx.port, regs->rx.pin, IOC_OVERRIDE_DIS);
|
||||
|
||||
/* Configure the clock */
|
||||
REG(SSI0_BASE + SSI_CPSR) = 2;
|
||||
REG(regs->base + SSI_CPSR) = regs->ssi_cprs_cpsdvsr;
|
||||
|
||||
/* Configure the default SPI options.
|
||||
/*
|
||||
* Configure the default SPI options.
|
||||
* mode: Motorola frame format
|
||||
* clock: High when idle
|
||||
* data: Valid on rising edges of the clock
|
||||
* bits: 8 byte data
|
||||
*/
|
||||
REG(SSI0_BASE + SSI_CR0) = SSI_CR0_SPH | SSI_CR0_SPO | (0x07);
|
||||
REG(regs->base + SSI_CR0) = SSI_CR0_SPH | SSI_CR0_SPO | (0x07);
|
||||
|
||||
/* Enable the SSI */
|
||||
REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE;
|
||||
REG(regs->base + SSI_CR1) |= SSI_CR1_SSE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spi_cs_init(uint8_t port, uint8_t pin)
|
||||
spix_enable(uint8_t spi)
|
||||
{
|
||||
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin));
|
||||
if(spi >= SSI_INSTANCE_COUNT) {
|
||||
return;
|
||||
}
|
||||
REG(SYS_CTRL_RCGCSSI) |= (1 << spi);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spix_disable(uint8_t spi)
|
||||
{
|
||||
if(spi >= SSI_INSTANCE_COUNT) {
|
||||
return;
|
||||
}
|
||||
REG(SYS_CTRL_RCGCSSI) &= ~(1 << spi);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spix_set_mode(uint8_t spi,
|
||||
uint32_t frame_format,
|
||||
uint32_t clock_polarity,
|
||||
uint32_t clock_phase,
|
||||
uint32_t data_size)
|
||||
{
|
||||
const spi_regs_t *regs;
|
||||
|
||||
if(spi >= SSI_INSTANCE_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
regs = &spi_regs[spi];
|
||||
|
||||
/* Disable the SSI peripheral to configure it */
|
||||
REG(regs->base + SSI_CR1) = 0;
|
||||
|
||||
/* Configure the SSI options */
|
||||
REG(regs->base + SSI_CR0) = clock_phase |
|
||||
clock_polarity |
|
||||
frame_format |
|
||||
(data_size - 1);
|
||||
|
||||
/* Re-enable the SSI */
|
||||
REG(regs->base + SSI_CR1) |= SSI_CR1_SSE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spix_cs_init(uint8_t port, uint8_t pin)
|
||||
{
|
||||
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port),
|
||||
GPIO_PIN_MASK(pin));
|
||||
ioc_set_over(port, pin, IOC_OVERRIDE_DIS);
|
||||
GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin));
|
||||
GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spi_enable(void)
|
||||
{
|
||||
/* Enable the clock for the SSI peripheral */
|
||||
REG(SYS_CTRL_RCGCSSI) |= 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spi_disable(void)
|
||||
{
|
||||
/* Gate the clock for the SSI peripheral */
|
||||
REG(SYS_CTRL_RCGCSSI) &= ~1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spi_set_mode(uint32_t frame_format, uint32_t clock_polarity,
|
||||
uint32_t clock_phase, uint32_t data_size)
|
||||
{
|
||||
/* Disable the SSI peripheral to configure it */
|
||||
REG(SSI0_BASE + SSI_CR1) = 0;
|
||||
|
||||
/* Configure the SSI options */
|
||||
REG(SSI0_BASE + SSI_CR0) = clock_phase | clock_polarity | frame_format | (data_size - 1);
|
||||
|
||||
/* Re-enable the SSI */
|
||||
REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE;
|
||||
}
|
||||
/** @} */
|
||||
|
|
|
@ -45,6 +45,12 @@
|
|||
#ifndef SSI_H_
|
||||
#define SSI_H_
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Number of SSI instances supported by this CPU.
|
||||
* @{
|
||||
*/
|
||||
#define SSI_INSTANCE_COUNT 2
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Base register memory locations.
|
||||
* @{
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2013, University of Michigan.
|
||||
*
|
||||
* Copyright (c) 2015, Weptech elektronik GmbH
|
||||
* Author: Ulf Knoblich, ulf.knoblich@weptech.de
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -34,66 +38,144 @@
|
|||
* Header file for the cc2538 SPI driver, including macros for the
|
||||
* implementation of the low-level SPI primitives such as waiting for the TX
|
||||
* FIFO to be ready, inserting into the TX FIFO, etc.
|
||||
*
|
||||
* It supports the usage of SSI_NUM_INSTANCES instances by providing new
|
||||
* functions calls like
|
||||
*
|
||||
* - spix_init(uint8_t instance)
|
||||
* - spix_enable(uint8_t instance)
|
||||
* - spix_disable(uint8_t instance)
|
||||
* - spix_set_mode(unit8_t instance, ...)
|
||||
*
|
||||
* and new macros like
|
||||
*
|
||||
* - SPIX_WAITFORTxREADY(x)
|
||||
* - SPIX_WAITFOREOTx(x)
|
||||
* - SPIX_WAITFOREORx(x)
|
||||
* - SPIX_FLUSH(x)
|
||||
*
|
||||
* Some of the old functions and macros are still supported.
|
||||
* 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:
|
||||
*
|
||||
* For the SSI0 module:
|
||||
*
|
||||
* - SPI0_CKL_PORT
|
||||
* - SPI0_CLK_PIN
|
||||
* - SPI0_TX_PORT
|
||||
* - SPI0_TX_PIN
|
||||
* - SPI0_RX_PORT
|
||||
* - SPI0_RX_PIN
|
||||
*
|
||||
* For the SSI1 module:
|
||||
*
|
||||
* - SPI1_CKL_PORT
|
||||
* - SPI1_CLK_PIN
|
||||
* - SPI1_TX_PORT
|
||||
* - SPI1_TX_PIN
|
||||
* - SPI1_RX_PORT
|
||||
* - SPI1_RX_PIN
|
||||
*/
|
||||
#ifndef SPI_ARCH_H_
|
||||
#define SPI_ARCH_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
#include "dev/ssi.h"
|
||||
|
||||
#define SPI_WAITFORTxREADY() do { \
|
||||
while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_TNF)); \
|
||||
} while(0)
|
||||
|
||||
#define SPI_TXBUF REG(SSI0_BASE + SSI_DR)
|
||||
|
||||
#define SPI_RXBUF REG(SSI0_BASE + SSI_DR)
|
||||
|
||||
#define SPI_WAITFOREOTx() do { \
|
||||
while(REG(SSI0_BASE + SSI_SR) & SSI_SR_BSY); \
|
||||
} while(0)
|
||||
|
||||
#define SPI_WAITFOREORx() do { \
|
||||
while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE)); \
|
||||
} while(0)
|
||||
|
||||
#ifdef SPI_FLUSH
|
||||
#error "You must include spi-arch.h before spi.h for the CC2538."
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* The SPI instance to use when using the deprecated SPI API. */
|
||||
#ifdef SPI_CONF_DEFAULT_INSTANCE
|
||||
#if SPI_CONF_DEFAULT_INSTANCE > (SSI_INSTANCE_COUNT - 1)
|
||||
#error Invalid SPI_CONF_DEFAULT_INSTANCE: valid values are 0 and 1
|
||||
#else
|
||||
#define SPI_DEFAULT_INSTANCE SPI_CONF_DEFAULT_INSTANCE
|
||||
#endif
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Default values for the clock rate divider */
|
||||
#ifdef SPI0_CONF_CPRS_CPSDVSR
|
||||
#define SPI0_CPRS_CPSDVSR SPI0_CONF_CPRS_CPSDVSR
|
||||
#else
|
||||
#define SPI0_CPRS_CPSDVSR 2
|
||||
#endif
|
||||
#define SPI_FLUSH() do { \
|
||||
SPI_WAITFOREORx(); \
|
||||
while (REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE) { \
|
||||
SPI_RXBUF; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define SPI_CS_CLR(port, pin) do { \
|
||||
GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \
|
||||
#ifdef SPI1_CONF_CPRS_CPSDVSR
|
||||
#define SPI1_CPRS_CPSDVSR SPI1_CONF_CPRS_CPSDVSR
|
||||
#else
|
||||
#define SPI1_CPRS_CPSDVSR 2
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* New API macros */
|
||||
#define SPIX_WAITFORTxREADY(spi) do { \
|
||||
while(!(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_TNF)) ; \
|
||||
} while(0)
|
||||
|
||||
#define SPI_CS_SET(port, pin) do { \
|
||||
GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \
|
||||
#define SPIX_BUF(spi) REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_DR)
|
||||
#define SPIX_WAITFOREOTx(spi) do { \
|
||||
while(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_BSY) ; \
|
||||
} while(0)
|
||||
#define SPIX_WAITFOREORx(spi) do { \
|
||||
while(!(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_RNE)) ; \
|
||||
} while(0)
|
||||
#define SPIX_FLUSH(spi) do { \
|
||||
while(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_RNE) { \
|
||||
SPIX_BUF(spi); \
|
||||
} \
|
||||
} while(0)
|
||||
#define SPIX_CS_CLR(port, pin) do { \
|
||||
GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \
|
||||
} while(0)
|
||||
#define SPIX_CS_SET(port, pin) do { \
|
||||
GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \
|
||||
} while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Deprecated macros provided for compatibility reasons */
|
||||
#ifdef SPI_DEFAULT_INSTANCE
|
||||
#define SPI_WAITFORTxREADY() SPIX_WAITFORTxREADY(SPI_DEFAULT_INSTANCE)
|
||||
#define SPI_TXBUF SPIX_BUF(SPI_DEFAULT_INSTANCE)
|
||||
#define SPI_RXBUF SPI_TXBUF
|
||||
#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
|
||||
#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 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Arch-specific SPI functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Configure a GPIO to be the chip select pin
|
||||
* \brief Initialize the SPI bus for the instance given
|
||||
*
|
||||
* This sets the mode to Motorola SPI with the following format options:
|
||||
* Clock phase: 1; data captured on second (rising) edge
|
||||
* Clock polarity: 1; clock is high when idle
|
||||
* Data size: 8 bits
|
||||
*
|
||||
* Use spix_set_mode() to change the spi mode.
|
||||
*/
|
||||
void spi_cs_init(uint8_t port, uint8_t pin);
|
||||
|
||||
/** \brief Enables the SPI peripheral
|
||||
*/
|
||||
void spi_enable(void);
|
||||
|
||||
/** \brief Disables the SPI peripheral
|
||||
* \note Call this function to save power when the SPI is unused.
|
||||
*/
|
||||
void spi_disable(void);
|
||||
void spix_init(uint8_t spi);
|
||||
|
||||
/**
|
||||
* \brief Configure the SPI data and clock polarity and the data size.
|
||||
* \brief Enables the SPI peripheral for the instance given
|
||||
*/
|
||||
void spix_enable(uint8_t spi);
|
||||
|
||||
/**
|
||||
* \brief Disables the SPI peripheral for the instance given
|
||||
* \note Call this function to save power when the SPI is unused.
|
||||
*/
|
||||
void spix_disable(uint8_t spi);
|
||||
|
||||
/**
|
||||
* \brief Configure the SPI data and clock polarity and the data size for the
|
||||
* instance given
|
||||
*
|
||||
* This function configures the SSI peripheral to use a particular SPI
|
||||
* configuration that a slave device requires. It should always be called
|
||||
|
@ -101,6 +183,7 @@ void spi_disable(void);
|
|||
*
|
||||
* See section 19.4.4 in the CC2538 user guide for more information.
|
||||
*
|
||||
* \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
|
||||
|
@ -110,8 +193,17 @@ void spi_disable(void);
|
|||
* \param data_size The number of bits in each "byte" of data. Must be
|
||||
* between 4 and 16, inclusive.
|
||||
*/
|
||||
void spi_set_mode(uint32_t frame_format, uint32_t clock_polarity,
|
||||
uint32_t clock_phase, uint32_t data_size);
|
||||
void spix_set_mode(uint8_t spi, uint32_t frame_format,
|
||||
uint32_t clock_polarity, uint32_t clock_phase,
|
||||
uint32_t data_size);
|
||||
|
||||
/**
|
||||
* \brief Configure a GPIO to be the chip select pin.
|
||||
*
|
||||
* Even if this function does not depend on the SPI instance used, we rename
|
||||
* it to reflect the new naming convention.
|
||||
*/
|
||||
void spix_cs_init(uint8_t port, uint8_t pin);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c cc26xx-rtc.c uart.c
|
|||
CONTIKI_CPU_SOURCEFILES += cc26xx-rf.c contiki-watchdog.c
|
||||
CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c
|
||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c
|
||||
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c
|
||||
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c
|
||||
|
||||
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
|
||||
|
||||
|
|
|
@ -79,8 +79,14 @@ clock_init(void)
|
|||
* Here, we configure GPT0 Timer A, which we subsequently use in
|
||||
* clock_delay_usec
|
||||
*
|
||||
* First, enable GPT0 in run mode. We don't need it in sleep mode
|
||||
* We need to access registers, so firstly power up the PD and then enable
|
||||
* the clock to GPT0.
|
||||
*/
|
||||
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
|
||||
PRCM_DOMAIN_POWER_ON) {
|
||||
power_domain_on();
|
||||
}
|
||||
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
@ -155,11 +161,19 @@ clock_wait(clock_time_t i)
|
|||
void
|
||||
clock_delay_usec(uint16_t len)
|
||||
{
|
||||
uint32_t clock_status;
|
||||
|
||||
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
|
||||
PRCM_DOMAIN_POWER_ON) {
|
||||
power_domain_on();
|
||||
}
|
||||
|
||||
clock_status = HWREG(PRCM_BASE + PRCM_O_GPTCLKGR) & PRCM_GPIOCLKGR_CLK_EN;
|
||||
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
ti_lib_timer_load_set(GPT0_BASE, TIMER_B, len);
|
||||
ti_lib_timer_enable(GPT0_BASE, TIMER_B);
|
||||
|
||||
|
@ -168,6 +182,12 @@ clock_delay_usec(uint16_t len)
|
|||
* function, hence the direct register access here
|
||||
*/
|
||||
while(HWREG(GPT0_BASE + GPT_O_CTL) & GPT_CTL_TBEN);
|
||||
|
||||
if(clock_status == 0) {
|
||||
ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "contiki.h"
|
||||
#include "dev/radio.h"
|
||||
#include "dev/cc26xx-rf.h"
|
||||
#include "dev/oscillators.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/rime/rimestats.h"
|
||||
#include "net/linkaddr.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
#include "sys/energest.h"
|
||||
#include "sys/clock.h"
|
||||
#include "sys/rtimer.h"
|
||||
#include "sys/cc.h"
|
||||
#include "lpm.h"
|
||||
#include "ti-lib.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -68,6 +70,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define BUSYWAIT_UNTIL(cond, max_time) \
|
||||
do { \
|
||||
|
@ -76,10 +79,6 @@
|
|||
while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \
|
||||
} while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef MIN
|
||||
#define MIN(n, m) (((n) < (m)) ? (n) : (m))
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef __GNUC__
|
||||
#define CC_ALIGN_ATTR(n) __attribute__ ((aligned(n)))
|
||||
#else
|
||||
|
@ -393,74 +392,6 @@ static int on(void);
|
|||
static int off(void);
|
||||
static void setup_interrupts(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Select the HF XOSC as the source for the HF clock, but don't switch yet */
|
||||
static void
|
||||
request_hf_xosc(void)
|
||||
{
|
||||
/* Enable OSC DIG interface to change clock sources */
|
||||
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);
|
||||
|
||||
if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) {
|
||||
/*
|
||||
* Request to switch to the crystal to enable radio operation. It takes a
|
||||
* while for the XTAL to be ready so instead of performing the actual
|
||||
* switch, we return and we do other stuff while the XOSC is getting ready.
|
||||
*/
|
||||
ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_XOSC_HF);
|
||||
}
|
||||
|
||||
/* Disable OSC DIG interface */
|
||||
ti_lib_osc_interface_disable();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Switch to the XOSC. This will block until the XOSC is ready, so this must
|
||||
* be preceded by a call to select_hf_xosc()
|
||||
*/
|
||||
static void
|
||||
switch_to_hf_xosc(void)
|
||||
{
|
||||
/* Enable OSC DIG interface to change clock sources */
|
||||
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);
|
||||
|
||||
if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) {
|
||||
/* Switch the HF clock source (cc26xxware executes this from ROM) */
|
||||
ti_lib_osc_hf_source_switch();
|
||||
}
|
||||
|
||||
/* Disable OSC DIG interface */
|
||||
ti_lib_osc_interface_disable();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
switch_to_hf_rc_osc(void)
|
||||
{
|
||||
/* Enable OSC DIG interface to change clock sources */
|
||||
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);
|
||||
|
||||
/* Set all clock sources to the HF RC Osc */
|
||||
ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_RCOSC_HF);
|
||||
|
||||
/* Check to not enable HF RC oscillator if already enabled */
|
||||
if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_RCOSC_HF) {
|
||||
/* Switch the HF clock source (cc26xxware executes this from ROM) */
|
||||
ti_lib_osc_hf_source_switch();
|
||||
}
|
||||
ti_lib_osc_interface_disable();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
rf_is_accessible(void)
|
||||
{
|
||||
|
@ -498,16 +429,19 @@ static uint_fast8_t
|
|||
rf_send_cmd(uint32_t cmd, uint32_t *status)
|
||||
{
|
||||
uint32_t timeout_count = 0;
|
||||
bool interrupts_disabled;
|
||||
|
||||
/*
|
||||
* Make sure ContikiMAC doesn't turn us off from within an interrupt while
|
||||
* we are accessing RF Core registers
|
||||
*/
|
||||
ti_lib_int_master_disable();
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
if(!rf_is_accessible()) {
|
||||
PRINTF("rf_send_cmd: RF was off\n");
|
||||
ti_lib_int_master_enable();
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
return RF_CMD_ERROR;
|
||||
}
|
||||
|
||||
|
@ -516,12 +450,16 @@ rf_send_cmd(uint32_t cmd, uint32_t *status)
|
|||
*status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA);
|
||||
if(++timeout_count > 50000) {
|
||||
PRINTF("rf_send_cmd: Timeout\n");
|
||||
ti_lib_int_master_enable();
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
return RF_CMD_ERROR;
|
||||
}
|
||||
} while(*status == RF_CMD_STATUS_PENDING);
|
||||
|
||||
ti_lib_int_master_enable();
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* If we reach here the command is no longer pending. It is either completed
|
||||
|
@ -978,8 +916,8 @@ static int
|
|||
power_up(void)
|
||||
{
|
||||
uint32_t cmd_status;
|
||||
bool interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
ti_lib_int_master_disable();
|
||||
ti_lib_int_pend_clear(INT_RF_CPE0);
|
||||
ti_lib_int_pend_clear(INT_RF_CPE1);
|
||||
ti_lib_int_disable(INT_RF_CPE0);
|
||||
|
@ -1002,7 +940,10 @@ power_up(void)
|
|||
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
|
||||
ti_lib_int_enable(INT_RF_CPE0);
|
||||
ti_lib_int_enable(INT_RF_CPE1);
|
||||
ti_lib_int_master_enable();
|
||||
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
/* Let CPE boot */
|
||||
HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = RF_CORE_CLOCKS_MASK;
|
||||
|
@ -1022,7 +963,7 @@ power_up(void)
|
|||
static void
|
||||
power_down(void)
|
||||
{
|
||||
ti_lib_int_master_disable();
|
||||
bool interrupts_disabled = ti_lib_int_master_disable();
|
||||
ti_lib_int_disable(INT_RF_CPE0);
|
||||
ti_lib_int_disable(INT_RF_CPE1);
|
||||
|
||||
|
@ -1045,7 +986,9 @@ power_down(void)
|
|||
ti_lib_int_pend_clear(INT_RF_CPE1);
|
||||
ti_lib_int_enable(INT_RF_CPE0);
|
||||
ti_lib_int_enable(INT_RF_CPE1);
|
||||
ti_lib_int_master_enable();
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
|
@ -1160,6 +1103,8 @@ cc26xx_rf_cpe0_isr(void)
|
|||
static void
|
||||
setup_interrupts(void)
|
||||
{
|
||||
bool interrupts_disabled;
|
||||
|
||||
/* We are already turned on by the caller, so this should not happen */
|
||||
if(!rf_is_accessible()) {
|
||||
PRINTF("setup_interrupts: No access\n");
|
||||
|
@ -1167,7 +1112,7 @@ setup_interrupts(void)
|
|||
}
|
||||
|
||||
/* Disable interrupts */
|
||||
ti_lib_int_master_disable();
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
/* Set all interrupt channels to CPE0 channel, error to CPE1 */
|
||||
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ;
|
||||
|
@ -1182,7 +1127,10 @@ setup_interrupts(void)
|
|||
ti_lib_int_pend_clear(INT_RF_CPE1);
|
||||
ti_lib_int_enable(INT_RF_CPE0);
|
||||
ti_lib_int_enable(INT_RF_CPE1);
|
||||
ti_lib_int_master_enable();
|
||||
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
@ -1199,7 +1147,7 @@ request(void)
|
|||
return LPM_MODE_MAX_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL);
|
||||
LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
init(void)
|
||||
|
@ -1530,7 +1478,7 @@ on(void)
|
|||
* Request the HF XOSC as the source for the HF clock. Needed before we can
|
||||
* use the FS. This will only request, it will _not_ perform the switch.
|
||||
*/
|
||||
request_hf_xosc();
|
||||
oscillators_request_hf_xosc();
|
||||
|
||||
/*
|
||||
* If we are in the middle of a BLE operation, we got called by ContikiMAC
|
||||
|
@ -1568,7 +1516,7 @@ on(void)
|
|||
* This will block until the XOSC is actually ready, but give how we
|
||||
* requested it early on, this won't be too long a wait/
|
||||
*/
|
||||
switch_to_hf_xosc();
|
||||
oscillators_switch_to_hf_xosc();
|
||||
|
||||
if(rf_radio_setup(RF_MODE_IEEE) != RF_CMD_OK) {
|
||||
PRINTF("on: radio_setup() failed\n");
|
||||
|
@ -1597,7 +1545,7 @@ off(void)
|
|||
power_down();
|
||||
|
||||
/* Switch HF clock source to the RCOSC to preserve power */
|
||||
switch_to_hf_rc_osc();
|
||||
oscillators_switch_to_hf_rc();
|
||||
|
||||
/* We pulled the plug, so we need to restore the status manually */
|
||||
GET_FIELD(cmd_ieee_rx_buf, radioOp, status) = IDLE;
|
||||
|
@ -1993,6 +1941,7 @@ PROCESS_THREAD(cc26xx_rf_ble_beacon_process, ev, data)
|
|||
uint8_t was_on;
|
||||
int j;
|
||||
uint32_t cmd_status;
|
||||
bool interrupts_disabled;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
@ -2023,9 +1972,11 @@ PROCESS_THREAD(cc26xx_rf_ble_beacon_process, ev, data)
|
|||
* Under ContikiMAC, some IEEE-related operations will be called from an
|
||||
* interrupt context. We need those to see that we are in BLE mode.
|
||||
*/
|
||||
ti_lib_int_master_disable();
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
ble_mode_on = 1;
|
||||
ti_lib_int_master_enable();
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Send BLE_ADV_MESSAGES beacon bursts. Each burst on all three
|
||||
|
@ -2061,7 +2012,7 @@ PROCESS_THREAD(cc26xx_rf_ble_beacon_process, ev, data)
|
|||
}
|
||||
} else {
|
||||
/* Request the HF XOSC to source the HF clock. */
|
||||
request_hf_xosc();
|
||||
oscillators_request_hf_xosc();
|
||||
|
||||
/* We were off: Boot the CPE */
|
||||
if(power_up() != RF_CMD_OK) {
|
||||
|
@ -2079,7 +2030,7 @@ PROCESS_THREAD(cc26xx_rf_ble_beacon_process, ev, data)
|
|||
}
|
||||
|
||||
/* Trigger a switch to the XOSC, so that we can use the FS */
|
||||
switch_to_hf_xosc();
|
||||
oscillators_switch_to_hf_xosc();
|
||||
}
|
||||
|
||||
/* Enter BLE mode */
|
||||
|
@ -2118,13 +2069,17 @@ PROCESS_THREAD(cc26xx_rf_ble_beacon_process, ev, data)
|
|||
power_down();
|
||||
|
||||
/* Switch HF clock source to the RCOSC to preserve power */
|
||||
switch_to_hf_rc_osc();
|
||||
oscillators_switch_to_hf_rc();
|
||||
}
|
||||
etimer_set(&ble_adv_et, BLE_ADV_DUTY_CYCLE);
|
||||
|
||||
ti_lib_int_master_disable();
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
ble_mode_on = 0;
|
||||
ti_lib_int_master_enable();
|
||||
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
||||
/* Wait unless this is the last burst */
|
||||
if(i < BLE_ADV_MESSAGES - 1) {
|
||||
|
@ -2132,9 +2087,13 @@ PROCESS_THREAD(cc26xx_rf_ble_beacon_process, ev, data)
|
|||
}
|
||||
}
|
||||
|
||||
ti_lib_int_master_disable();
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
ble_mode_on = 0;
|
||||
ti_lib_int_master_enable();
|
||||
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "ti-lib.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define cc26xx_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -54,9 +55,11 @@ void
|
|||
cc26xx_rtc_init(void)
|
||||
{
|
||||
uint32_t compare_value;
|
||||
bool interrupts_disabled;
|
||||
|
||||
/* Disable and clear interrupts */
|
||||
ti_lib_int_master_disable();
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
ti_lib_aon_rtc_disable();
|
||||
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
|
||||
|
@ -65,22 +68,25 @@ cc26xx_rtc_init(void)
|
|||
/* Setup the wakeup event */
|
||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC0);
|
||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC2);
|
||||
ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH2);
|
||||
|
||||
/* Configure channel 2 in continuous compare, 128 ticks / sec */
|
||||
ti_lib_aon_rtc_inc_value_ch2_set(RTIMER_SECOND / CLOCK_SECOND);
|
||||
ti_lib_aon_rtc_mode_ch2_set(AON_RTC_MODE_CH2_CONTINUOUS);
|
||||
compare_value = (RTIMER_SECOND / CLOCK_SECOND) +
|
||||
ti_lib_aon_rtc_current_compare_value_get();
|
||||
ti_lib_aon_rtc_compare_value_set(AON_RTC_CH2, compare_value);
|
||||
ti_lib_aon_rtc_inc_value_ch2_set(RTIMER_SECOND / CLOCK_SECOND);
|
||||
ti_lib_aon_rtc_mode_ch2_set(AON_RTC_MODE_CH2_CONTINUOUS);
|
||||
|
||||
/* Enable event generation for channels 0 and 2 and enable the RTC */
|
||||
ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH2);
|
||||
/* Enable channel 2 and the RTC */
|
||||
ti_lib_aon_rtc_channel_enable(AON_RTC_CH2);
|
||||
|
||||
ti_lib_aon_rtc_enable();
|
||||
|
||||
ti_lib_int_enable(INT_AON_RTC);
|
||||
ti_lib_int_master_enable();
|
||||
|
||||
/* Re-enable interrupts */
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rtimer_clock_t
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "sys/energest.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Which events to trigger a UART interrupt */
|
||||
#define CC26XX_UART_RX_INTERRUPT_TRIGGERS (UART_INT_RX | UART_INT_RT)
|
||||
|
@ -53,35 +54,98 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
static int (*input_handler)(unsigned char c);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
power_domain_on(void)
|
||||
static bool
|
||||
usable(void)
|
||||
{
|
||||
if(BOARD_IOID_UART_RX == IOID_UNUSED ||
|
||||
BOARD_IOID_UART_TX == IOID_UNUSED ||
|
||||
CC26XX_UART_CONF_ENABLE == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
power_and_clock(void)
|
||||
{
|
||||
/* Power on the SERIAL PD */
|
||||
ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL);
|
||||
while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON);
|
||||
|
||||
/* Enable UART clock in active mode */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Returns 0 if either the SERIAL PD is off, or the PD is on but the run mode
|
||||
* clock is gated. If this function would return 0, accessing UART registers
|
||||
* will return a precise bus fault. If this function returns 1, it is safe to
|
||||
* access UART registers.
|
||||
*
|
||||
* This function only checks the 'run mode' clock gate, since it can only ever
|
||||
* be called with the MCU in run mode.
|
||||
*/
|
||||
static bool
|
||||
accessible(void)
|
||||
{
|
||||
/* First, check the PD */
|
||||
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Then check the 'run mode' clock gate */
|
||||
if(!(HWREG(PRCM_BASE + PRCM_O_UARTCLKGR) & PRCM_UARTCLKGR_CLK_EN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
configure_baud_rate(void)
|
||||
disable_interrupts(void)
|
||||
{
|
||||
/* Acknowledge UART interrupts */
|
||||
ti_lib_int_disable(INT_UART0);
|
||||
|
||||
/* Disable all UART module interrupts */
|
||||
ti_lib_uart_int_disable(UART0_BASE, CC26XX_UART_INTERRUPT_ALL);
|
||||
|
||||
/* Clear all UART interrupts */
|
||||
ti_lib_uart_int_clear(UART0_BASE, CC26XX_UART_INTERRUPT_ALL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
enable_interrupts(void)
|
||||
{
|
||||
/* Clear all UART interrupts */
|
||||
ti_lib_uart_int_clear(UART0_BASE, CC26XX_UART_INTERRUPT_ALL);
|
||||
|
||||
/* Enable RX-related interrupts only if we have an input handler */
|
||||
if(input_handler) {
|
||||
/* Configure which interrupts to generate: FIFO level or after RX timeout */
|
||||
ti_lib_uart_int_enable(UART0_BASE, CC26XX_UART_RX_INTERRUPT_TRIGGERS);
|
||||
|
||||
/* Acknowledge UART interrupts */
|
||||
ti_lib_int_enable(INT_UART0);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
configure(void)
|
||||
{
|
||||
uint32_t ctl_val = UART_CTL_UARTEN | UART_CTL_TXE;
|
||||
/*
|
||||
* Configure the UART for 115,200, 8-N-1 operation.
|
||||
* This function uses SysCtrlClockGet() to get the system clock
|
||||
* frequency. This could be also be a variable or hard coded value
|
||||
* instead of a function call.
|
||||
* Make sure the TX pin is output / high before assigning it to UART control
|
||||
* to avoid falling edge glitches
|
||||
*/
|
||||
ti_lib_uart_config_set_exp_clk(UART0_BASE,
|
||||
ti_lib_sys_ctrl_peripheral_clock_get(
|
||||
PRCM_PERIPH_UART0,
|
||||
SYSCTRL_SYSBUS_ON),
|
||||
CC26XX_UART_CONF_BAUD_RATE,
|
||||
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
|
||||
UART_CONFIG_PAR_NONE));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
configure_registers(void)
|
||||
{
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_UART_TX);
|
||||
ti_lib_gpio_pin_write(BOARD_UART_TX, 1);
|
||||
|
||||
/*
|
||||
* Map UART signals to the correct GPIO pins and configure them as
|
||||
* hardware controlled.
|
||||
|
@ -89,7 +153,14 @@ configure_registers(void)
|
|||
ti_lib_ioc_pin_type_uart(UART0_BASE, BOARD_IOID_UART_RX, BOARD_IOID_UART_TX,
|
||||
BOARD_IOID_UART_CTS, BOARD_IOID_UART_RTS);
|
||||
|
||||
configure_baud_rate();
|
||||
/* Configure the UART for 115,200, 8-N-1 operation. */
|
||||
ti_lib_uart_config_set_exp_clk(UART0_BASE,
|
||||
ti_lib_sys_ctrl_peripheral_clock_get(
|
||||
PRCM_PERIPH_UART0,
|
||||
SYSCTRL_SYSBUS_ON),
|
||||
CC26XX_UART_CONF_BAUD_RATE,
|
||||
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
|
||||
UART_CONFIG_PAR_NONE));
|
||||
|
||||
/*
|
||||
* Generate an RX interrupt at FIFO 1/2 full.
|
||||
|
@ -97,116 +168,138 @@ configure_registers(void)
|
|||
*/
|
||||
ti_lib_uart_fifo_level_set(UART0_BASE, UART_FIFO_TX7_8, UART_FIFO_RX4_8);
|
||||
|
||||
/* Configure which interrupts to generate: FIFO level or after RX timeout */
|
||||
ti_lib_uart_int_enable(UART0_BASE, CC26XX_UART_RX_INTERRUPT_TRIGGERS);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
uart_on(void)
|
||||
{
|
||||
power_domain_on();
|
||||
/* Enable FIFOs */
|
||||
HWREG(UART0_BASE + UART_O_LCRH) |= UART_LCRH_FEN;
|
||||
|
||||
/* Configure baud rate and enable */
|
||||
if((HWREG(UART0_BASE + UART_O_CTL) & UART_CTL_UARTEN) == 0) {
|
||||
configure_registers();
|
||||
|
||||
/* Enable UART */
|
||||
ti_lib_uart_enable(UART0_BASE);
|
||||
if(input_handler) {
|
||||
ctl_val += UART_CTL_RXE;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
lpm_permit_max_pm_handler(void)
|
||||
{
|
||||
return LPM_MODE_MAX_SUPPORTED;
|
||||
|
||||
/* Enable TX, RX (conditionally), and the UART. */
|
||||
HWREG(UART0_BASE + UART_O_CTL) = ctl_val;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
lpm_drop_handler(uint8_t mode)
|
||||
{
|
||||
/* Do nothing if the PD is off */
|
||||
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON) {
|
||||
return;
|
||||
/*
|
||||
* First, wait for any outstanding TX to complete. If we have an input
|
||||
* handler, the SERIAL PD will be kept on and the UART module clock will
|
||||
* be enabled under sleep as well as deep sleep. In theory, this means that
|
||||
* we shouldn't lose any outgoing bytes, but we actually do on occasion.
|
||||
* This byte loss may (or may not) be related to the freezing of IO latches
|
||||
* between MCU and AON when we drop to deep sleep. This here is essentially a
|
||||
* workaround
|
||||
*/
|
||||
if(accessible() == true) {
|
||||
while(ti_lib_uart_busy(UART0_BASE));
|
||||
}
|
||||
|
||||
/* Wait for outstanding TX to complete */
|
||||
while(ti_lib_uart_busy(UART0_BASE));
|
||||
|
||||
/*
|
||||
* Check our clock gate under Deep Sleep. If it's off, we can shut down. If
|
||||
* it's on, this means that some other code module wants UART functionality
|
||||
* during deep sleep, so we stay enabled
|
||||
* If we have a registered input_handler then we need to retain RX
|
||||
* capability. Thus, if this is not a shutdown notification and we have an
|
||||
* input handler, we do nothing
|
||||
*/
|
||||
if((HWREG(PRCM_BASE + PRCM_O_UARTCLKGDS) & 1) == 0) {
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_UART_RX);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_UART_TX);
|
||||
|
||||
ti_lib_uart_disable(UART0_BASE);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
lpm_wakeup_handler(void)
|
||||
{
|
||||
uart_on();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Declare a data structure to register with LPM. */
|
||||
LPM_MODULE(uart_module, lpm_permit_max_pm_handler,
|
||||
lpm_drop_handler, lpm_wakeup_handler);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc26xx_uart_init()
|
||||
{
|
||||
/* Exit without initialising if ports are misconfigured */
|
||||
if(BOARD_IOID_UART_RX == IOID_UNUSED ||
|
||||
BOARD_IOID_UART_TX == IOID_UNUSED) {
|
||||
if((mode != LPM_MODE_SHUTDOWN) && (input_handler != NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable the serial domain and wait for domain to be on */
|
||||
power_domain_on();
|
||||
/*
|
||||
* If we reach here, we either don't care about staying awake or we have
|
||||
* received a shutdown notification
|
||||
*
|
||||
* Only touch UART registers if the module is powered and clocked
|
||||
*/
|
||||
if(accessible() == true) {
|
||||
/* Disable the module */
|
||||
ti_lib_uart_disable(UART0_BASE);
|
||||
|
||||
/* Enable the UART clock when running and sleeping */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_UART0);
|
||||
/* Disable all UART interrupts and clear all flags */
|
||||
disable_interrupts();
|
||||
}
|
||||
|
||||
/* Apply clock settings and wait for them to take effect */
|
||||
/*
|
||||
* Always stop the clock in run mode. Also stop in Sleep and Deep Sleep if
|
||||
* this is a request for full shutdown
|
||||
*/
|
||||
ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_UART0);
|
||||
if(mode == LPM_MODE_SHUTDOWN) {
|
||||
ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_UART0);
|
||||
}
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
/* Disable Interrupts */
|
||||
ti_lib_int_master_disable();
|
||||
/* Set pins to low leakage configuration in preparation for deep sleep */
|
||||
lpm_pin_set_default_state(BOARD_IOID_UART_TX);
|
||||
lpm_pin_set_default_state(BOARD_IOID_UART_RX);
|
||||
lpm_pin_set_default_state(BOARD_IOID_UART_CTS);
|
||||
lpm_pin_set_default_state(BOARD_IOID_UART_RTS);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Declare a data structure to register with LPM. */
|
||||
LPM_MODULE(uart_module, NULL, lpm_drop_handler, NULL, LPM_DOMAIN_NONE);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
enable(void)
|
||||
{
|
||||
power_and_clock();
|
||||
|
||||
/* Make sure the peripheral is disabled */
|
||||
ti_lib_uart_disable(UART0_BASE);
|
||||
|
||||
/* Disable all UART module interrupts */
|
||||
ti_lib_uart_int_disable(UART0_BASE, CC26XX_UART_INTERRUPT_ALL);
|
||||
/* Disable all UART interrupts and clear all flags */
|
||||
disable_interrupts();
|
||||
|
||||
configure_registers();
|
||||
/* Setup pins, Baud rate and FIFO levels */
|
||||
configure();
|
||||
|
||||
/* Acknowledge UART interrupts */
|
||||
ti_lib_int_enable(INT_UART0);
|
||||
/* Enable UART interrupts */
|
||||
enable_interrupts();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc26xx_uart_init()
|
||||
{
|
||||
bool interrupts_disabled;
|
||||
|
||||
/* Re-enable processor interrupts */
|
||||
ti_lib_int_master_enable();
|
||||
/* Return early if disabled by user conf or if ports are misconfigured */
|
||||
if(usable() == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable UART */
|
||||
ti_lib_uart_enable(UART0_BASE);
|
||||
/* Disable Interrupts */
|
||||
interrupts_disabled = ti_lib_int_master_disable();
|
||||
|
||||
/* Register ourselves with the LPM module */
|
||||
lpm_register_module(&uart_module);
|
||||
|
||||
/* Only TX and EN to start with. RX will be enabled only if needed */
|
||||
input_handler = NULL;
|
||||
|
||||
/*
|
||||
* init() won't actually fire up the UART. We turn it on only when (and if)
|
||||
* it gets requested, either to enable input or to send out a character
|
||||
*
|
||||
* Thus, we simply re-enable processor interrupts here
|
||||
*/
|
||||
if(!interrupts_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc26xx_uart_write_byte(uint8_t c)
|
||||
{
|
||||
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON) {
|
||||
/* Return early if disabled by user conf or if ports are misconfigured */
|
||||
if(usable() == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(accessible() == false) {
|
||||
enable();
|
||||
}
|
||||
|
||||
ti_lib_uart_char_put(UART0_BASE, c);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -214,9 +307,52 @@ void
|
|||
cc26xx_uart_set_input(int (*input)(unsigned char c))
|
||||
{
|
||||
input_handler = input;
|
||||
|
||||
/* Return early if disabled by user conf or if ports are misconfigured */
|
||||
if(usable() == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(input == NULL) {
|
||||
/* Let the SERIAL PD power down */
|
||||
uart_module.domain_lock = LPM_DOMAIN_NONE;
|
||||
|
||||
/* Disable module clocks under sleep and deep sleep */
|
||||
ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_UART0);
|
||||
} else {
|
||||
/* Request the SERIAL PD to stay on during deep sleep */
|
||||
uart_module.domain_lock = LPM_DOMAIN_SERIAL;
|
||||
|
||||
/* Enable module clocks under sleep and deep sleep */
|
||||
ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_UART0);
|
||||
}
|
||||
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
enable();
|
||||
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
cc26xx_uart_busy(void)
|
||||
{
|
||||
/* Return early if disabled by user conf or if ports are misconfigured */
|
||||
if(usable() == false) {
|
||||
return UART_IDLE;
|
||||
}
|
||||
|
||||
/* If the UART is not accessible, it is not busy */
|
||||
if(accessible() == false) {
|
||||
return UART_IDLE;
|
||||
}
|
||||
|
||||
return ti_lib_uart_busy(UART0_BASE);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc26xx_uart_isr(void)
|
||||
{
|
||||
|
@ -225,6 +361,8 @@ cc26xx_uart_isr(void)
|
|||
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
|
||||
power_and_clock();
|
||||
|
||||
/* Read out the masked interrupt status */
|
||||
flags = ti_lib_uart_int_status(UART0_BASE, true);
|
||||
|
||||
|
|
|
@ -63,9 +63,32 @@ void cc26xx_uart_write_byte(uint8_t b);
|
|||
/**
|
||||
* \brief Assigns a callback to be called when the UART receives a byte
|
||||
* \param input A pointer to the function
|
||||
*
|
||||
* If \e input is NULL, the UART driver will assume that RX functionality is
|
||||
* not required and it will be disabled. It will also disable the module's
|
||||
* clocks under sleep and deep sleep and allow the SERIAL PD to be powered off.
|
||||
*
|
||||
* If \e input is not NULL, the UART driver will assume that RX is in fact
|
||||
* required and it will be enabled. The module's clocks will be enabled under
|
||||
* sleep and deep sleep and the driver will not allow the SERIAL PD to turn
|
||||
* off during deep sleep, so that the UART can still receive bytes.
|
||||
*
|
||||
* \note This has a significant impact on overall energy consumption, so you
|
||||
* should only enabled UART RX input when it's actually required.
|
||||
*/
|
||||
void cc26xx_uart_set_input(int (*input)(unsigned char c));
|
||||
|
||||
/**
|
||||
* \brief Returns the UART busy status
|
||||
* \return UART_IDLE or UART_BUSY
|
||||
*
|
||||
* ti_lib_uart_busy() will access UART registers. It is our responsibility
|
||||
* to first make sure the UART is accessible before calling it. Hence this
|
||||
* wrapper.
|
||||
*
|
||||
* Return values are defined in CC26xxware's uart.h
|
||||
*/
|
||||
uint8_t cc26xx_uart_busy(void);
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* CC26XX_UART_H_ */
|
||||
|
|
172
cpu/cc26xx/dev/oscillators.c
Normal file
172
cpu/cc26xx/dev/oscillators.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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-oscillators
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of CC26xxware oscillator control wrappers.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint32_t
|
||||
osc_interface_en(void)
|
||||
{
|
||||
uint32_t smph_clk_state;
|
||||
|
||||
/* Enable OSC DIG interface to change clock sources */
|
||||
ti_lib_osc_interface_enable();
|
||||
|
||||
/* Save the state of the SMPH clock within AUX */
|
||||
smph_clk_state = ti_lib_aux_wuc_clock_status(AUX_WUC_SMPH_CLOCK);
|
||||
|
||||
/* 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);
|
||||
|
||||
return smph_clk_state;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
osc_interface_dis(uint32_t smph_clk_state)
|
||||
{
|
||||
/* If the SMPH clock was off, turn it back off */
|
||||
if(smph_clk_state == AUX_WUC_CLOCK_OFF) {
|
||||
ti_lib_aux_wuc_clock_disable(AUX_WUC_SMPH_CLOCK);
|
||||
}
|
||||
|
||||
/* Disable OSC DIG interface */
|
||||
ti_lib_osc_interface_disable();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
oscillators_select_lf_xosc(void)
|
||||
{
|
||||
/* Enable the Osc interface and remember the state of the SMPH clock */
|
||||
uint32_t smph_clk_state = osc_interface_en();
|
||||
|
||||
/* Switch LF clock source to the LF XOSC 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);
|
||||
|
||||
/* Wait for LF clock source to become XOSC_LF */
|
||||
while(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_XOSC_LF);
|
||||
|
||||
/* Disable the LF clock qualifiers */
|
||||
ti_lib_ddi_16_bit_field_write(AUX_DDI0_OSC_BASE, DDI_0_OSC_O_CTL0,
|
||||
DDI_0_OSC_CTL0_BYPASS_XOSC_LF_CLK_QUAL_M |
|
||||
DDI_0_OSC_CTL0_BYPASS_RCOSC_LF_CLK_QUAL_M,
|
||||
DDI_0_OSC_CTL0_BYPASS_RCOSC_LF_CLK_QUAL_S,
|
||||
0x3);
|
||||
}
|
||||
|
||||
/* Restore the SMPH clock and disable the OSC interface */
|
||||
osc_interface_dis(smph_clk_state);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
oscillators_select_lf_rcosc(void)
|
||||
{
|
||||
/* Enable the Osc interface and remember the state of the SMPH clock */
|
||||
uint32_t smph_clk_state = osc_interface_en();
|
||||
|
||||
/* Switch LF clock source to the LF XOSC if required */
|
||||
if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_RCOSC_LF) {
|
||||
ti_lib_osc_clock_source_set(OSC_SRC_CLK_LF, OSC_RCOSC_LF);
|
||||
|
||||
/* Wait for LF clock source to become XOSC_LF */
|
||||
while(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_RCOSC_LF);
|
||||
}
|
||||
|
||||
/* Restore the SMPH clock and disable the OSC interface */
|
||||
osc_interface_dis(smph_clk_state);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
oscillators_request_hf_xosc(void)
|
||||
{
|
||||
/* Enable the Osc interface and remember the state of the SMPH clock */
|
||||
uint32_t smph_clk_state = osc_interface_en();
|
||||
|
||||
if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) {
|
||||
/*
|
||||
* Request to switch to the crystal to enable radio operation. It takes a
|
||||
* while for the XTAL to be ready so instead of performing the actual
|
||||
* switch, we return and we do other stuff while the XOSC is getting ready.
|
||||
*/
|
||||
ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_XOSC_HF);
|
||||
}
|
||||
|
||||
/* Restore the SMPH clock and disable the OSC interface */
|
||||
osc_interface_dis(smph_clk_state);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
oscillators_switch_to_hf_xosc(void)
|
||||
{
|
||||
/* Enable the Osc interface and remember the state of the SMPH clock */
|
||||
uint32_t smph_clk_state = osc_interface_en();
|
||||
|
||||
if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) {
|
||||
/* Switch the HF clock source (cc26xxware executes this from ROM) */
|
||||
ti_lib_osc_hf_source_switch();
|
||||
}
|
||||
|
||||
/* Restore the SMPH clock and disable the OSC interface */
|
||||
osc_interface_dis(smph_clk_state);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
oscillators_switch_to_hf_rc(void)
|
||||
{
|
||||
/* Enable the Osc interface and remember the state of the SMPH clock */
|
||||
uint32_t smph_clk_state = osc_interface_en();
|
||||
|
||||
/* Set all clock sources to the HF RC Osc */
|
||||
ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_RCOSC_HF);
|
||||
|
||||
/* Check to not enable HF RC oscillator if already enabled */
|
||||
if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_RCOSC_HF) {
|
||||
/* Switch the HF clock source (cc26xxware executes this from ROM) */
|
||||
ti_lib_osc_hf_source_switch();
|
||||
}
|
||||
|
||||
/* Restore the SMPH clock and disable the OSC interface */
|
||||
osc_interface_dis(smph_clk_state);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
101
cpu/cc26xx/dev/oscillators.h
Normal file
101
cpu/cc26xx/dev/oscillators.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* @{
|
||||
*
|
||||
* \defgroup cc26xx-oscillators CC26XX oscillator control
|
||||
*
|
||||
* Wrapper around those CC26xxware OSC functions that we need in Contiki.
|
||||
*
|
||||
* All CC26xxware OSC control requires access to the semaphore module within
|
||||
* AUX. Thus, in addition to enabling the oscillator interface, we need to
|
||||
* start the clock to SMPH and restore it to its previous state when we are
|
||||
* done.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the CC26XX oscillator control
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef OSCILLATORS_H_
|
||||
#define OSCILLATORS_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Set the LF clock source to be the LF XOSC
|
||||
*
|
||||
* This function is only called once as soon as the system starts.
|
||||
*
|
||||
* Do not switch the LF clock source to the RC OSC for normal system operation
|
||||
* See CC26xx Errata (swrz058)
|
||||
*/
|
||||
void oscillators_select_lf_xosc(void);
|
||||
|
||||
/**
|
||||
* \brief Set the LF clock source to be the LF RCOSC
|
||||
*
|
||||
* This function is only called once, when the systen transitions to a full
|
||||
* shutdown
|
||||
*
|
||||
* Do not switch the LF clock source to the RC OSC for normal system operation
|
||||
* See CC26xx Errata (swrz058)
|
||||
*/
|
||||
void oscillators_select_lf_rcosc(void);
|
||||
|
||||
/**
|
||||
* \brief Requests the HF XOSC as the source for the HF clock, but does not
|
||||
* perform the actual switch.
|
||||
*
|
||||
* This triggers the startup sequence of the HF XOSC and returns so the CPU
|
||||
* can perform other tasks while the XOSC is starting.
|
||||
*
|
||||
* The XOSC is requested as the source for the HF as well as the MF clock.
|
||||
*/
|
||||
void oscillators_request_hf_xosc(void);
|
||||
|
||||
/**
|
||||
* \brief Performs the switch to the XOSC
|
||||
*
|
||||
* This function must be preceded by a call to oscillators_request_hf_xosc()
|
||||
*/
|
||||
void oscillators_switch_to_hf_xosc(void);
|
||||
|
||||
/**
|
||||
* \brief Switches MF and HF clock source to be the HF RC OSC
|
||||
*/
|
||||
void oscillators_switch_to_hf_rc(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* OSCILLATORS_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
231
cpu/cc26xx/lpm.c
231
cpu/cc26xx/lpm.c
|
@ -49,6 +49,7 @@
|
|||
#include "dev/leds.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "dev/cc26xx-rtc.h"
|
||||
#include "dev/oscillators.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if ENERGEST_CONF_ON
|
||||
static unsigned long irq_energest = 0;
|
||||
|
@ -64,9 +65,6 @@ static unsigned long irq_energest = 0;
|
|||
/*---------------------------------------------------------------------------*/
|
||||
LIST(modules_list);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Control what power domains we are allow to run under what mode */
|
||||
LIST(power_domain_locks_list);
|
||||
|
||||
/* PDs that may stay on in deep sleep */
|
||||
#define LOCKABLE_DOMAINS ((uint32_t)(PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -76,49 +74,48 @@ LIST(power_domain_locks_list);
|
|||
*/
|
||||
#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 8)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Variables used by the power on/off (Power mode: SHUTDOWN) functionality */
|
||||
static uint8_t shutdown_requested;
|
||||
static uint32_t pin;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lpm_pd_lock_obtain(lpm_power_domain_lock_t *lock, uint32_t domains)
|
||||
{
|
||||
/* We only accept locks for specific PDs */
|
||||
domains &= LOCKABLE_DOMAINS;
|
||||
|
||||
if(domains == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock->domains = domains;
|
||||
|
||||
list_add(power_domain_locks_list, lock);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lpm_pd_lock_release(lpm_power_domain_lock_t *lock)
|
||||
{
|
||||
lock->domains = 0;
|
||||
|
||||
list_remove(power_domain_locks_list, lock);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lpm_shutdown(uint32_t wakeup_pin)
|
||||
{
|
||||
shutdown_requested = 1;
|
||||
pin = wakeup_pin;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
shutdown_now(void)
|
||||
lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
|
||||
{
|
||||
lpm_registered_module_t *module;
|
||||
int i;
|
||||
rtimer_clock_t t0;
|
||||
uint32_t io_cfg = (IOC_STD_INPUT & ~IOC_IOPULL_M) | IOC_IOPULL_UP |
|
||||
IOC_WAKE_ON_LOW;
|
||||
int i, j;
|
||||
uint32_t io_cfg = (IOC_STD_INPUT & ~IOC_IOPULL_M) | io_pull |
|
||||
wake_on;
|
||||
|
||||
/* This procedure may not be interrupted */
|
||||
ti_lib_int_master_disable();
|
||||
|
||||
/* Disable the RTC */
|
||||
ti_lib_aon_rtc_disable();
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH1);
|
||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH2);
|
||||
|
||||
/* Reset AON even fabric to default wakeup sources */
|
||||
for(i = AON_EVENT_MCU_WU0; i <= AON_EVENT_MCU_WU3; i++) {
|
||||
ti_lib_aon_event_mcu_wake_up_set(i, AON_EVENT_NULL);
|
||||
}
|
||||
for(i = AON_EVENT_AUX_WU0; i <= AON_EVENT_AUX_WU2; i++) {
|
||||
ti_lib_aon_event_aux_wake_up_set(i, AON_EVENT_NULL);
|
||||
}
|
||||
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
||||
watchdog_periodic();
|
||||
|
||||
/* fade away....... */
|
||||
j = 1000;
|
||||
|
||||
for(i = j; i > 0; --i) {
|
||||
leds_on(LEDS_ALL);
|
||||
clock_delay_usec(i);
|
||||
leds_off(LEDS_ALL);
|
||||
clock_delay_usec(j - i);
|
||||
}
|
||||
|
||||
leds_off(LEDS_ALL);
|
||||
|
||||
/* Notify all modules that we're shutting down */
|
||||
for(module = list_head(modules_list); module != NULL;
|
||||
module = module->next) {
|
||||
if(module->shutdown) {
|
||||
|
@ -126,34 +123,76 @@ shutdown_now(void)
|
|||
}
|
||||
}
|
||||
|
||||
leds_off(LEDS_ALL);
|
||||
/* Configure the wakeup trigger */
|
||||
ti_lib_gpio_dir_mode_set((1 << wakeup_pin), GPIO_DIR_MODE_IN);
|
||||
ti_lib_ioc_port_configure_set(wakeup_pin, IOC_PORT_GPIO, io_cfg);
|
||||
|
||||
for(i = 0; i < 5; i++) {
|
||||
t0 = RTIMER_NOW();
|
||||
leds_toggle(LEDS_ALL);
|
||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(), (t0 + (RTIMER_SECOND >> 3))));
|
||||
}
|
||||
/* Freeze I/O latches in AON */
|
||||
ti_lib_aon_ioc_freeze_enable();
|
||||
|
||||
leds_off(LEDS_ALL);
|
||||
/* Turn off RFCORE, SERIAL and PERIPH PDs. This will happen immediately */
|
||||
ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL |
|
||||
PRCM_DOMAIN_PERIPH);
|
||||
|
||||
ti_lib_gpio_dir_mode_set((1 << pin), GPIO_DIR_MODE_IN);
|
||||
ti_lib_ioc_port_configure_set(pin, IOC_PORT_GPIO, io_cfg);
|
||||
oscillators_switch_to_hf_rc();
|
||||
oscillators_select_lf_rcosc();
|
||||
|
||||
ti_lib_pwr_ctrl_state_set(LPM_MODE_SHUTDOWN);
|
||||
/* Configure clock sources for MCU and AUX: No clock */
|
||||
ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK);
|
||||
ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK);
|
||||
|
||||
/* Disable retentions: SRAM, CPU, AUX, RFCORE - possibly not required */
|
||||
ti_lib_aon_wuc_mcu_sram_config(0);
|
||||
ti_lib_prcm_retention_disable(PRCM_DOMAIN_CPU);
|
||||
ti_lib_aon_wuc_aux_sram_config(false);
|
||||
ti_lib_prcm_retention_disable(PRCM_DOMAIN_RFCORE);
|
||||
|
||||
/*
|
||||
* Request CPU, SYSBYS and VIMS PD off.
|
||||
* This will only happen when the CM3 enters deep sleep
|
||||
*/
|
||||
ti_lib_prcm_power_domain_off(PRCM_DOMAIN_CPU | PRCM_DOMAIN_VIMS |
|
||||
PRCM_DOMAIN_SYSBUS);
|
||||
|
||||
/* Request JTAG domain power off */
|
||||
ti_lib_aon_wuc_jtag_power_off();
|
||||
|
||||
/* Turn off AUX */
|
||||
ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF);
|
||||
ti_lib_aon_wuc_domain_power_down_enable();
|
||||
while(ti_lib_aon_wuc_power_status() & AONWUC_AUX_POWER_ON);
|
||||
|
||||
/*
|
||||
* Request MCU VD power off.
|
||||
* This will only happen when the CM3 enters deep sleep
|
||||
*/
|
||||
ti_lib_prcm_mcu_power_off();
|
||||
|
||||
/* Set MCU wakeup to immediate and disable virtual power off */
|
||||
ti_lib_aon_wuc_mcu_wake_up_config(MCU_IMM_WAKE_UP);
|
||||
ti_lib_aon_wuc_mcu_power_off_config(MCU_VIRT_PWOFF_DISABLE);
|
||||
|
||||
/* Latch the IOs in the padring and enable I/O pad sleep mode */
|
||||
ti_lib_pwr_ctrl_io_freeze_enable();
|
||||
|
||||
/* Turn off VIMS cache, CRAM and TRAM - possibly not required */
|
||||
ti_lib_prcm_retention_disable(PRCM_DOMAIN_VIMS);
|
||||
ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF);
|
||||
|
||||
/* Enable shutdown and sync AON */
|
||||
ti_lib_aon_wuc_shut_down_enable();
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
||||
/* Deep Sleep */
|
||||
ti_lib_prcm_deep_sleep();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* We'll get called on three occasions:
|
||||
* - While running
|
||||
* - While sleeping
|
||||
* - While deep sleeping
|
||||
*
|
||||
* For the former two, we don't need to do anything. For the latter, we
|
||||
* notify all modules that we're back on and rely on them to restore clocks
|
||||
* Notify all modules that we're back on and rely on them to restore clocks
|
||||
* and power domains as required.
|
||||
*/
|
||||
void
|
||||
lpm_wake_up()
|
||||
static void
|
||||
wake_up(void)
|
||||
{
|
||||
lpm_registered_module_t *module;
|
||||
|
||||
|
@ -182,8 +221,8 @@ lpm_wake_up()
|
|||
ti_lib_aon_ioc_freeze_disable();
|
||||
ti_lib_sys_ctrl_aon_sync();
|
||||
|
||||
/* Power up AUX and allow it to go to sleep */
|
||||
ti_lib_aon_wuc_aux_wakeup_event(AONWUC_AUX_ALLOW_SLEEP);
|
||||
/* Check operating conditions, optimally choose DCDC versus GLDO */
|
||||
ti_lib_sys_ctrl_dcdc_voltage_conditional_control();
|
||||
|
||||
/* Notify all registered modules that we've just woken up */
|
||||
for(module = list_head(modules_list); module != NULL;
|
||||
|
@ -198,16 +237,11 @@ void
|
|||
lpm_drop()
|
||||
{
|
||||
lpm_registered_module_t *module;
|
||||
lpm_power_domain_lock_t *lock;
|
||||
uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
|
||||
uint8_t module_pm;
|
||||
|
||||
uint32_t domains = LOCKABLE_DOMAINS;
|
||||
|
||||
if(shutdown_requested) {
|
||||
shutdown_now();
|
||||
}
|
||||
|
||||
if(RTIMER_CLOCK_LT(cc26xx_rtc_get_next_trigger(),
|
||||
RTIMER_NOW() + STANDBY_MIN_DURATION)) {
|
||||
lpm_sleep();
|
||||
|
@ -244,26 +278,21 @@ lpm_drop()
|
|||
* This is a chance for modules to delay us a little bit until an ongoing
|
||||
* operation has finished (e.g. uart TX) or to configure themselves for
|
||||
* deep sleep.
|
||||
*
|
||||
* At this stage, we also collect power domain locks, if any.
|
||||
* The argument to PRCMPowerDomainOff() is a bitwise OR, so every time
|
||||
* we encounter a lock we just clear the respective bits in the 'domains'
|
||||
* variable as required by the lock. In the end the domains variable will
|
||||
* just hold whatever has not been cleared
|
||||
*/
|
||||
for(module = list_head(modules_list); module != NULL;
|
||||
module = module->next) {
|
||||
if(module->shutdown) {
|
||||
module->shutdown(max_pm);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate PD locks to see what we can and cannot turn off.
|
||||
*
|
||||
* The argument to PRCMPowerDomainOff() is a bitwise OR, so every time
|
||||
* we encounter a lock we just clear the respective bits in the 'domains'
|
||||
* variable as required by the lock. In the end the domains variable will
|
||||
* just hold whatever has not been cleared
|
||||
*/
|
||||
for(lock = list_head(power_domain_locks_list); lock != NULL;
|
||||
lock = lock->next) {
|
||||
/* Clear the bits specified in the lock */
|
||||
domains &= ~lock->domains;
|
||||
domains &= ~module->domain_lock;
|
||||
}
|
||||
|
||||
/* Pat the dog: We don't want it to shout right after we wake up */
|
||||
|
@ -289,6 +318,20 @@ lpm_drop()
|
|||
ti_lib_prcm_power_domain_off(domains);
|
||||
}
|
||||
|
||||
/*
|
||||
* Before entering Deep Sleep, we must switch off the HF XOSC. The HF XOSC
|
||||
* is predominantly controlled by the RF driver. In a build with radio
|
||||
* cycling (e.g. ContikiMAC), the RF driver will request the XOSC before
|
||||
* using the Freq. Synth, and switch back to the RC when it is about to
|
||||
* turn back off.
|
||||
*
|
||||
* If the radio is on, we won't even reach here, and if it's off the HF
|
||||
* clock source should already be the HF RC.
|
||||
*
|
||||
* Nevertheless, request the switch to the HF RC explicitly here.
|
||||
*/
|
||||
oscillators_switch_to_hf_rc();
|
||||
|
||||
/* Configure clock sources for MCU and AUX: No clock */
|
||||
ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK);
|
||||
ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK);
|
||||
|
@ -304,11 +347,7 @@ lpm_drop()
|
|||
ti_lib_aon_wuc_aux_sram_config(false);
|
||||
|
||||
/* Disable retention in the RFCORE RAM */
|
||||
HWREG(PRCM_BASE + PRCM_O_RAMRETEN) &= ~PRCM_RAMRETEN_RFC;
|
||||
|
||||
/* Disable retention of VIMS RAM (TRAM and CRAM) */
|
||||
//TODO: This can probably be removed, we are calling ti_lib_prcm_retention_disable(PRCM_DOMAIN_VIMS); further down
|
||||
HWREG(PRCM_BASE + PRCM_O_RAMRETEN) &= ~PRCM_RAMRETEN_VIMS_M;
|
||||
ti_lib_prcm_retention_disable(PRCM_DOMAIN_RFCORE);
|
||||
|
||||
/*
|
||||
* Always turn off RFCORE, CPU, SYSBUS and VIMS. RFCORE should be off
|
||||
|
@ -329,7 +368,7 @@ lpm_drop()
|
|||
ti_lib_sys_ctrl_set_recharge_before_power_down(false);
|
||||
|
||||
/*
|
||||
* If both PERIPH and SERIAL PDs are off, request the uLDO for as the power
|
||||
* If both PERIPH and SERIAL PDs are off, request the uLDO as the power
|
||||
* source while in deep sleep.
|
||||
*/
|
||||
if(domains == LOCKABLE_DOMAINS) {
|
||||
|
@ -362,7 +401,7 @@ lpm_drop()
|
|||
* the chip properly, and then we will enable the global interrupt without
|
||||
* unpending events so the handlers can fire
|
||||
*/
|
||||
lpm_wake_up();
|
||||
wake_up();
|
||||
|
||||
ti_lib_int_master_enable();
|
||||
}
|
||||
|
@ -396,10 +435,26 @@ lpm_register_module(lpm_registered_module_t *module)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lpm_unregister_module(lpm_registered_module_t *module)
|
||||
{
|
||||
list_remove(modules_list, module);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lpm_init()
|
||||
{
|
||||
list_init(modules_list);
|
||||
list_init(power_domain_locks_list);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lpm_pin_set_default_state(uint32_t ioid)
|
||||
{
|
||||
if(ioid == IOID_UNUSED) {
|
||||
return;
|
||||
}
|
||||
|
||||
ti_lib_ioc_port_configure_set(ioid, IOC_PORT_GPIO, IOC_STD_OUTPUT);
|
||||
ti_lib_gpio_dir_mode_set((1 << ioid), GPIO_DIR_MODE_IN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -49,17 +49,22 @@
|
|||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define LPM_MODE_SLEEP PWRCTRL_ACTIVE
|
||||
#define LPM_MODE_DEEP_SLEEP PWRCTRL_POWER_DOWN
|
||||
#define LPM_MODE_SHUTDOWN PWRCTRL_SHUTDOWN
|
||||
#define LPM_MODE_SLEEP 1
|
||||
#define LPM_MODE_DEEP_SLEEP 2
|
||||
#define LPM_MODE_SHUTDOWN 3
|
||||
|
||||
#define LPM_MODE_MAX_SUPPORTED LPM_MODE_DEEP_SLEEP
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define LPM_DOMAIN_NONE 0
|
||||
#define LPM_DOMAIN_SERIAL PRCM_DOMAIN_SERIAL
|
||||
#define LPM_DOMAIN_PERIPH PRCM_DOMAIN_PERIPH
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct lpm_registered_module {
|
||||
struct lpm_registered_module *next;
|
||||
uint8_t (*request_max_pm)(void);
|
||||
void (*shutdown)(uint8_t mode);
|
||||
void (*wakeup)(void);
|
||||
uint32_t domain_lock;
|
||||
} lpm_registered_module_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -78,46 +83,14 @@ typedef struct lpm_registered_module {
|
|||
* woken up. This can be used to e.g. turn a peripheral back on. This
|
||||
* function is in charge of turning power domains back on. This
|
||||
* function will normally be called within an interrupt context.
|
||||
* \param l Power domain locks, if any are required. The module can request
|
||||
* that the SERIAL or PERIPH PD be kept powered up at the transition
|
||||
* to deep sleep. This field can be a bitwise OR of LPM_DOMAIN_x, so
|
||||
* if required multiple domains can be kept powered.
|
||||
*/
|
||||
#define LPM_MODULE(n, m, s, w) static lpm_registered_module_t n = \
|
||||
{ NULL, m, s, w }
|
||||
#define LPM_MODULE(n, m, s, w, l) static lpm_registered_module_t n = \
|
||||
{ NULL, m, s, w, l }
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* \brief Data type used to control whether a PD will get shut down when the
|
||||
* CM3 drops to deep sleep
|
||||
*
|
||||
* Modules using these facilities must allocate a variable of this type, but
|
||||
* they must not try to manipulate it directly. Instead, the respective
|
||||
* functions must be used
|
||||
*
|
||||
* \sa lpm_pd_lock_obtain(), lpm_pd_lock_release()
|
||||
*/
|
||||
typedef struct lpm_power_domain_lock {
|
||||
struct lpm_power_domain_lock *next;
|
||||
uint32_t domains;
|
||||
} lpm_power_domain_lock_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Prohibit a PD from turning off in standby mode
|
||||
* \param lock A pointer to a lpm_power_domain_lock_t
|
||||
* \param domains Bitwise OR from PRCM_DOMAIN_PERIPH, PRCM_DOMAIN_SERIAL
|
||||
*
|
||||
* The caller is responsible for allocating lpm_power_domain_lock_t
|
||||
*
|
||||
* Only the domains listed above can be locked / released, but a single lock
|
||||
* can be used for multiple domains
|
||||
*/
|
||||
void lpm_pd_lock_obtain(lpm_power_domain_lock_t *lock, uint32_t domains);
|
||||
|
||||
/**
|
||||
* \brief Permit a PD to turn off in standby mode
|
||||
* \param pd A pointer to a previously used lock
|
||||
*
|
||||
* \sa lpm_pd_lock_obtain()
|
||||
*/
|
||||
void lpm_pd_lock_release(lpm_power_domain_lock_t *pd);
|
||||
|
||||
/**
|
||||
* \brief Drop the cortex to sleep / deep sleep and shut down peripherals
|
||||
*
|
||||
|
@ -134,17 +107,11 @@ void lpm_sleep(void);
|
|||
/**
|
||||
* \brief Put the chip in shutdown power mode
|
||||
* \param wakeup_pin The GPIO pin which will wake us up. Must be IOID_0 etc...
|
||||
* \param io_pull Pull configuration for the shutdown pin: IOC_NO_IOPULL,
|
||||
* IOC_IOPULL_UP or IOC_IOPULL_DOWN
|
||||
* \param wake_on High or Low (IOC_WAKE_ON_LOW or IOC_WAKE_ON_HIGH)
|
||||
*/
|
||||
void lpm_shutdown(uint32_t wakeup_pin);
|
||||
|
||||
/**
|
||||
* \brief Wake up from sleep mode
|
||||
*
|
||||
* This function must be called at the start of any interrupt context which
|
||||
* may bring us out of sleep. Current interrupts do this already, but make sure
|
||||
* to do the same when adding new ISRs
|
||||
*/
|
||||
void lpm_wake_up(void);
|
||||
void lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on);
|
||||
|
||||
/**
|
||||
* \brief Register a module for LPM notifications.
|
||||
|
@ -159,10 +126,31 @@ void lpm_wake_up(void);
|
|||
*/
|
||||
void lpm_register_module(lpm_registered_module_t *module);
|
||||
|
||||
/**
|
||||
* \brief Unregister a module from LPM notifications.
|
||||
* \param module A pointer to the data structure with the module definition
|
||||
*
|
||||
* When a previously registered module is no longer interested in LPM
|
||||
* notifications, this function can be used to unregister it.
|
||||
*/
|
||||
void lpm_unregister_module(lpm_registered_module_t *module);
|
||||
|
||||
/**
|
||||
* \brief Initialise the low-power mode management module
|
||||
*/
|
||||
void lpm_init(void);
|
||||
|
||||
/**
|
||||
* \brief Sets an IOID to a default state
|
||||
* \param ioid IOID_0...
|
||||
*
|
||||
* This will set ioid to sw control, input, no pull. Input buffer and output
|
||||
* driver will both be disabled
|
||||
*
|
||||
* The function will do nothing if ioid == IOID_UNUSED, so the caller does not
|
||||
* have to check board configuration before calling this.
|
||||
*/
|
||||
void lpm_pin_set_default_state(uint32_t ioid);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* LPM_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "cc26xx-uart.h"
|
||||
#include "ti-lib.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -47,9 +48,16 @@ puts(const char *str)
|
|||
return 0;
|
||||
}
|
||||
for(i = 0; i < strlen(str); i++) {
|
||||
putchar(str[i]);
|
||||
cc26xx_uart_write_byte(str[i]);
|
||||
}
|
||||
putchar('\n');
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -62,9 +70,16 @@ dbg_send_bytes(const unsigned char *s, unsigned int len)
|
|||
if(i >= len) {
|
||||
break;
|
||||
}
|
||||
putchar(*s++);
|
||||
cc26xx_uart_write_byte(*s++);
|
||||
i++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the buffer to go out. This is to prevent garbage when used
|
||||
* between UART on/off cycles
|
||||
*/
|
||||
while(cc26xx_uart_busy() == UART_BUSY);
|
||||
|
||||
return i;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -58,6 +58,10 @@ slip_arch_writeb(unsigned char c)
|
|||
void
|
||||
slip_arch_init(unsigned long ubr)
|
||||
{
|
||||
/*
|
||||
* Enable an input handler. In doing so, the driver will make sure that UART
|
||||
* RX stays operational during deep sleep
|
||||
*/
|
||||
cc26xx_uart_set_input(slip_input_byte);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -148,7 +148,7 @@
|
|||
#include "driverlib/aux_wuc.h"
|
||||
|
||||
#define ti_lib_aux_wuc_clock_enable(...) AUXWUCClockEnable(__VA_ARGS__)
|
||||
#define ti_lib_aux_wuc_clock_disble(...) AUXWUCClockDisable(__VA_ARGS__)
|
||||
#define ti_lib_aux_wuc_clock_disable(...) AUXWUCClockDisable(__VA_ARGS__)
|
||||
#define ti_lib_aux_wuc_clock_status(...) AUXWUCClockStatus(__VA_ARGS__)
|
||||
#define ti_lib_aux_wuc_clock_freq_req(...) AUXWUCClockFreqReq(__VA_ARGS__)
|
||||
#define ti_lib_aux_wuc_power_ctrl(...) AUXWUCPowerCtrl(__VA_ARGS__)
|
||||
|
@ -531,6 +531,8 @@
|
|||
#define ti_lib_sys_ctrl_aon_update(...) SysCtrlAonUpdate(__VA_ARGS__)
|
||||
#define ti_lib_sys_ctrl_set_recharge_before_power_down(...) SysCtrlSetRechargeBeforePowerDown(__VA_ARGS__)
|
||||
#define ti_lib_sys_ctrl_adjust_recharge_after_power_down(...) SysCtrlAdjustRechargeAfterPowerDown(__VA_ARGS__)
|
||||
#define ti_lib_sys_ctrl_dcdc_voltage_conditional_control(...) SysCtrl_DCDC_VoltageConditionalControl(__VA_ARGS__)
|
||||
#define ti_lib_sys_ctrl_reset_source_get(...) SysCtrlResetSourceGet(__VA_ARGS__)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* ssi.h */
|
||||
#include "driverlib/ssi.h"
|
||||
|
|
|
@ -4,6 +4,8 @@ ifdef nodeid
|
|||
CFLAGS += -DNODEID=$(nodeid)
|
||||
endif
|
||||
|
||||
CFLAGS += -gstabs+
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
### Define the CPU directory
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "sfrs-ext.h"
|
||||
|
||||
#include "contiki.h" /* for clock_wait() and CLOCK_SECOND. */
|
||||
#include "sys/cc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** Macros Definitions *******************************/
|
||||
|
@ -91,9 +92,6 @@
|
|||
while(condition) { body; break_loop(); } \
|
||||
} while(0)
|
||||
|
||||
#undef MIN
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
|
||||
/******************************************************************************/
|
||||
/************************ Variables Definitions *******************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -6,8 +6,6 @@ boards. More specifically, the example demonstrates:
|
|||
* How to take sensor readings
|
||||
* How to use buttons and the reed relay (triggered by holding a magnet near S3
|
||||
on the SensorTag).
|
||||
* How to keep a power domain powered and a peripheral clocked under low power
|
||||
operation
|
||||
* How to send out BLE advertisements. The device will periodically send out BLE
|
||||
beacons with the platform name as payload. Those beacons/BLE ADV packets can
|
||||
be captured with any BLE capable device. Two such applications for iOS are the
|
||||
|
|
|
@ -77,12 +77,6 @@
|
|||
* - The example also shows how to retrieve the duration of a
|
||||
* button press (in ticks). The driver will generate a
|
||||
* sensors_changed event upon button release
|
||||
* - UART : Receiving an entire line of text over UART (ending
|
||||
* in \\r) will cause CC26XX_DEMO_LEDS_SERIAL_IN to toggle
|
||||
* This also demonstrates how a code module can influence
|
||||
* low-power operation: In this example we keep the UART on
|
||||
* and capable to RX even with the chip in deep sleep.
|
||||
* see keep_uart_on() and the UART driver
|
||||
* - Reed Relay : Will toggle the sensortag buzzer on/off
|
||||
*
|
||||
* @{
|
||||
|
@ -100,7 +94,6 @@
|
|||
#include "button-sensor.h"
|
||||
#include "batmon-sensor.h"
|
||||
#include "board-peripherals.h"
|
||||
#include "lpm.h"
|
||||
#include "cc26xx-rf.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
@ -251,8 +244,7 @@ get_light_reading()
|
|||
printf("OPT: Light Read Error\n");
|
||||
}
|
||||
|
||||
SENSORS_DEACTIVATE(opt_3001_sensor);
|
||||
|
||||
/* The OPT will turn itself off, so we don't need to call its DEACTIVATE */
|
||||
ctimer_set(&opt_timer, next, init_opt_reading, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -369,26 +361,6 @@ init_sensor_readings(void)
|
|||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static lpm_power_domain_lock_t lock;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* In order to maintain UART input operation:
|
||||
* - Keep the uart clocked in sleep and deep sleep
|
||||
* - Keep the serial PD on in deep sleep
|
||||
*/
|
||||
static void
|
||||
keep_uart_on(void)
|
||||
{
|
||||
/* Keep the serial PD on */
|
||||
lpm_pd_lock_obtain(&lock, PRCM_DOMAIN_SERIAL);
|
||||
|
||||
/* Keep the UART clock on during Sleep and Deep Sleep */
|
||||
ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(cc26xx_demo_process, ev, data)
|
||||
{
|
||||
|
||||
|
@ -406,8 +378,6 @@ PROCESS_THREAD(cc26xx_demo_process, ev, data)
|
|||
get_sync_sensor_readings();
|
||||
init_sensor_readings();
|
||||
|
||||
keep_uart_on();
|
||||
|
||||
while(1) {
|
||||
|
||||
PROCESS_YIELD();
|
||||
|
@ -462,8 +432,6 @@ PROCESS_THREAD(cc26xx_demo_process, ev, data)
|
|||
button_select_sensor.value(BUTTON_SENSOR_VALUE_DURATION));
|
||||
#endif
|
||||
}
|
||||
} else if(ev == serial_line_event_message) {
|
||||
leds_toggle(CC26XX_DEMO_LEDS_SERIAL_IN);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -574,8 +574,6 @@ get_light_reading()
|
|||
|
||||
value = opt_3001_sensor.value(0);
|
||||
|
||||
SENSORS_DEACTIVATE(opt_3001_sensor);
|
||||
|
||||
if(value != CC26XX_SENSOR_READING_ERROR) {
|
||||
opt_reading.raw = value;
|
||||
|
||||
|
@ -587,6 +585,7 @@ get_light_reading()
|
|||
value % 100);
|
||||
}
|
||||
|
||||
/* The OPT will turn itself off, so we don't need to call its DEACTIVATE */
|
||||
ctimer_set(&opt_timer, next, init_light_reading, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -59,12 +59,13 @@
|
|||
#include "contiki-conf.h"
|
||||
#include "sys/process.h"
|
||||
#include "dev/serial-line.h"
|
||||
#include "dev/cc26xx-uart.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ip/uip-udp-packet.h"
|
||||
#include "net/ip/uiplib.h"
|
||||
#include "lpm.h"
|
||||
#include "net-uart.h"
|
||||
#include "httpd-simple.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
#include "ti-lib.h"
|
||||
|
||||
|
@ -86,10 +87,6 @@
|
|||
#define ADDRESS_CONVERSION_OK 1
|
||||
#define ADDRESS_CONVERSION_ERROR 0
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef MIN
|
||||
#define MIN(n, m) (((n) < (m)) ? (n) : (m))
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static struct uip_udp_conn *udp_conn = NULL;
|
||||
|
||||
static uint8_t buffer[MAX_MSG_SIZE];
|
||||
|
@ -148,37 +145,16 @@ net_input(void)
|
|||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* In order to maintain UART input operation:
|
||||
* - Keep the uart clocked in sleep and deep sleep
|
||||
* - Keep the serial PD on in deep sleep
|
||||
*/
|
||||
static lpm_power_domain_lock_t lock;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
release_uart(void)
|
||||
{
|
||||
/* Release serial PD lock */
|
||||
lpm_pd_lock_release(&lock);
|
||||
|
||||
/* Let the UART turn off during Sleep and Deep Sleep */
|
||||
ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
cc26xx_uart_set_input(NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
keep_uart_on(void)
|
||||
{
|
||||
/* Keep the serial PD on */
|
||||
lpm_pd_lock_obtain(&lock, PRCM_DOMAIN_SERIAL);
|
||||
|
||||
/* Keep the UART clock on during Sleep and Deep Sleep */
|
||||
ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_UART0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
cc26xx_uart_set_input(serial_line_input_byte);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "sys/cc.h"
|
||||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "net/netstack.h"
|
||||
#include "net/rime/rime.h"
|
||||
#include "net/rime/collect.h"
|
||||
|
@ -120,8 +121,6 @@ PROCESS_THREAD(depth_blink_process, ev, data)
|
|||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define MAX(a, b) ((a) > (b)? (a): (b))
|
||||
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||
struct spectrum {
|
||||
int channel[16];
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
|
||||
#include "contiki-net.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -104,7 +105,6 @@ PROCESS_THREAD(tcp_server_process, ev, data)
|
|||
while(bytes_to_send > 0) {
|
||||
PROCESS_PAUSE();
|
||||
int len, tosend;
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
tosend = MIN(bytes_to_send, sizeof(outputbuf));
|
||||
len = tcp_socket_send(&socket, (uint8_t *)"", tosend);
|
||||
bytes_to_send -= len;
|
||||
|
|
|
@ -411,7 +411,7 @@ lcd_num_putdec(int numb, lcd_padding_t padding)
|
|||
}
|
||||
|
||||
/* Convert to BCD */
|
||||
bcd = itobcd(abs(numb));
|
||||
bcd = itobcd(ABS(numb));
|
||||
|
||||
/* Print */
|
||||
return lcd_num_print(bcd, (bool)(numb<0), padding);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
|
@ -753,7 +754,7 @@ uint16_t p=(uint16_t)&__bss_end;
|
|||
radio_get_rssi_value(&RSSI);
|
||||
RSSI*=3;
|
||||
#endif
|
||||
maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI);
|
||||
maxRSSI[i-11]=MAX(maxRSSI[i-11],RSSI);
|
||||
accRSSI[i-11]+=RSSI;
|
||||
}
|
||||
if(j&(1<<7)) {
|
||||
|
@ -774,7 +775,7 @@ uint16_t p=(uint16_t)&__bss_end;
|
|||
#endif
|
||||
PRINTF_P(PSTR("\n"));
|
||||
for(i=11;i<=26;i++) {
|
||||
uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7));
|
||||
uint8_t activity=MIN(maxRSSI[i-11],accRSSI[i-11]/(1<<7));
|
||||
PRINTF_P(PSTR(" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1));
|
||||
for(;activity--;maxRSSI[i-11]--) {
|
||||
PRINTF_P(PSTR("#"));
|
||||
|
|
|
@ -76,7 +76,7 @@ The toolchain used to build contiki is arm-gcc, also used by other arm-based Con
|
|||
|
||||
The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors". This is the recommended version and the one being used by Contiki's regression tests on Travis. <https://launchpad.net/gcc-arm-embedded>
|
||||
|
||||
The older version (Sourcery G++ Lite 2008q3-66) shown above should still work, but the port is no longer being tested with it.
|
||||
The older version (Sourcery G++ Lite 2008q3-66) shown above should still work, but the port is no longer being tested with it. <http://sourcery.mentor.com/public/gnu_toolchain/arm-none-eabi>
|
||||
|
||||
Drivers
|
||||
-------
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
/**
|
||||
* \addtogroup cc2538dk
|
||||
* @{
|
||||
*
|
||||
|
@ -78,28 +78,28 @@
|
|||
#undef LEDS_RED
|
||||
#undef LEDS_CONF_ALL
|
||||
|
||||
#define LEDS_YELLOW 2 /**< LED2 (Yellow) -> PC1 */
|
||||
#define LEDS_GREEN 4 /**< LED3 (Green) -> PC2 */
|
||||
#define LEDS_ORANGE 8 /**< LED4 (Orange) -> PC3 */
|
||||
#define LEDS_YELLOW 2 /**< LED2 (Yellow) -> PC1 */
|
||||
#define LEDS_GREEN 4 /**< LED3 (Green) -> PC2 */
|
||||
#define LEDS_ORANGE 8 /**< LED4 (Orange) -> PC3 */
|
||||
|
||||
#if USB_SERIAL_CONF_ENABLE
|
||||
#define LEDS_CONF_ALL 14
|
||||
#define LEDS_RED LEDS_ORANGE
|
||||
#define LEDS_CONF_ALL 14
|
||||
#define LEDS_RED LEDS_ORANGE
|
||||
#else
|
||||
#define LEDS_CONF_ALL 15
|
||||
#define LEDS_RED 1 /**< LED1 (Red) -> PC0 */
|
||||
#define LEDS_CONF_ALL 15
|
||||
#define LEDS_RED 1 /**< LED1 (Red) -> PC0 */
|
||||
#endif
|
||||
|
||||
/* Notify various examples that we have LEDs */
|
||||
#define PLATFORM_HAS_LEDS 1
|
||||
#define PLATFORM_HAS_LEDS 1
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name USB configuration
|
||||
*
|
||||
* The USB pullup is driven by PC0 and is shared with LED1
|
||||
*/
|
||||
#define USB_PULLUP_PORT GPIO_C_NUM
|
||||
#define USB_PULLUP_PIN 0
|
||||
#define USB_PULLUP_PORT GPIO_C_NUM
|
||||
#define USB_PULLUP_PIN 0
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name UART configuration
|
||||
|
@ -115,17 +115,17 @@
|
|||
* UART1_* below.
|
||||
* @{
|
||||
*/
|
||||
#define UART0_RX_PORT GPIO_A_NUM
|
||||
#define UART0_RX_PIN 0
|
||||
#define UART0_RX_PORT GPIO_A_NUM
|
||||
#define UART0_RX_PIN 0
|
||||
|
||||
#define UART0_TX_PORT GPIO_A_NUM
|
||||
#define UART0_TX_PIN 1
|
||||
#define UART0_TX_PORT GPIO_A_NUM
|
||||
#define UART0_TX_PIN 1
|
||||
|
||||
#define UART1_CTS_PORT GPIO_B_NUM
|
||||
#define UART1_CTS_PIN 0
|
||||
#define UART1_CTS_PORT GPIO_B_NUM
|
||||
#define UART1_CTS_PIN 0
|
||||
|
||||
#define UART1_RTS_PORT GPIO_D_NUM
|
||||
#define UART1_RTS_PIN 3
|
||||
#define UART1_RTS_PORT GPIO_D_NUM
|
||||
#define UART1_RTS_PIN 3
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SmartRF Button configuration
|
||||
|
@ -139,32 +139,32 @@
|
|||
* @{
|
||||
*/
|
||||
/** BUTTON_SELECT -> PA3 */
|
||||
#define BUTTON_SELECT_PORT GPIO_A_NUM
|
||||
#define BUTTON_SELECT_PIN 3
|
||||
#define BUTTON_SELECT_VECTOR NVIC_INT_GPIO_PORT_A
|
||||
#define BUTTON_SELECT_PORT GPIO_A_NUM
|
||||
#define BUTTON_SELECT_PIN 3
|
||||
#define BUTTON_SELECT_VECTOR NVIC_INT_GPIO_PORT_A
|
||||
|
||||
/** BUTTON_LEFT -> PC4 */
|
||||
#define BUTTON_LEFT_PORT GPIO_C_NUM
|
||||
#define BUTTON_LEFT_PIN 4
|
||||
#define BUTTON_LEFT_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
#define BUTTON_LEFT_PORT GPIO_C_NUM
|
||||
#define BUTTON_LEFT_PIN 4
|
||||
#define BUTTON_LEFT_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
|
||||
/** BUTTON_RIGHT -> PC5 */
|
||||
#define BUTTON_RIGHT_PORT GPIO_C_NUM
|
||||
#define BUTTON_RIGHT_PIN 5
|
||||
#define BUTTON_RIGHT_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
#define BUTTON_RIGHT_PORT GPIO_C_NUM
|
||||
#define BUTTON_RIGHT_PIN 5
|
||||
#define BUTTON_RIGHT_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
|
||||
/** BUTTON_UP -> PC6 */
|
||||
#define BUTTON_UP_PORT GPIO_C_NUM
|
||||
#define BUTTON_UP_PIN 6
|
||||
#define BUTTON_UP_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
#define BUTTON_UP_PORT GPIO_C_NUM
|
||||
#define BUTTON_UP_PIN 6
|
||||
#define BUTTON_UP_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
|
||||
/** BUTTON_DOWN -> PC7 */
|
||||
#define BUTTON_DOWN_PORT GPIO_C_NUM
|
||||
#define BUTTON_DOWN_PIN 7
|
||||
#define BUTTON_DOWN_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
#define BUTTON_DOWN_PORT GPIO_C_NUM
|
||||
#define BUTTON_DOWN_PIN 7
|
||||
#define BUTTON_DOWN_VECTOR NVIC_INT_GPIO_PORT_C
|
||||
|
||||
/* Notify various examples that we have Buttons */
|
||||
#define PLATFORM_HAS_BUTTON 1
|
||||
#define PLATFORM_HAS_BUTTON 1
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -176,23 +176,49 @@
|
|||
* ADC inputs can only be on port A.
|
||||
* @{
|
||||
*/
|
||||
#define ADC_ALS_PWR_PORT GPIO_A_NUM /**< ALS power GPIO control port */
|
||||
#define ADC_ALS_PWR_PIN 7 /**< ALS power GPIO control pin */
|
||||
#define ADC_ALS_OUT_PIN 6 /**< ALS output ADC input pin on port A */
|
||||
#define ADC_ALS_PWR_PORT GPIO_A_NUM /**< ALS power GPIO control port */
|
||||
#define ADC_ALS_PWR_PIN 7 /**< ALS power GPIO control pin */
|
||||
#define ADC_ALS_OUT_PIN 6 /**< ALS output ADC input pin on port A */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name SPI configuration
|
||||
*
|
||||
* These values configure which CC2538 pins to use for the SPI lines.
|
||||
* These values configure which CC2538 pins to use for the SPI lines. Both
|
||||
* SPI instances can be used independently by providing the corresponding
|
||||
* port / pin macros.
|
||||
* @{
|
||||
*/
|
||||
#define SPI_CLK_PORT GPIO_A_NUM /**< Clock port */
|
||||
#define SPI_CLK_PIN 2 /**< Clock pin */
|
||||
#define SPI_MOSI_PORT GPIO_A_NUM /**< MOSI port */
|
||||
#define SPI_MOSI_PIN 4 /**< MOSI pin */
|
||||
#define SPI_MISO_PORT GPIO_A_NUM /**< MISO port */
|
||||
#define SPI_MISO_PIN 5 /**< MISO pin */
|
||||
#define SPI0_IN_USE 0
|
||||
#define SPI1_IN_USE 0
|
||||
#if SPI0_IN_USE
|
||||
/** Clock port SPI0 */
|
||||
#define SPI0_CLK_PORT GPIO_A_NUM
|
||||
/** Clock pin SPI0 */
|
||||
#define SPI0_CLK_PIN 2
|
||||
/** TX port SPI0 (master mode: MOSI) */
|
||||
#define SPI0_TX_PORT GPIO_A_NUM
|
||||
/** TX pin SPI0 */
|
||||
#define SPI0_TX_PIN 4
|
||||
/** RX port SPI0 (master mode: MISO */
|
||||
#define SPI0_RX_PORT GPIO_A_NUM
|
||||
/** RX pin SPI0 */
|
||||
#define SPI0_RX_PIN 5
|
||||
#endif /* #if SPI0_IN_USE */
|
||||
#if SPI1_IN_USE
|
||||
/** Clock port SPI1 */
|
||||
#define SPI1_CLK_PORT GPIO_A_NUM
|
||||
/** Clock pin SPI1 */
|
||||
#define SPI1_CLK_PIN 2
|
||||
/** TX port SPI1 (master mode: MOSI) */
|
||||
#define SPI1_TX_PORT GPIO_A_NUM
|
||||
/** TX pin SPI1 */
|
||||
#define SPI1_TX_PIN 4
|
||||
/** RX port SPI1 (master mode: MISO) */
|
||||
#define SPI1_RX_PORT GPIO_A_NUM
|
||||
/** RX pin SPI1 */
|
||||
#define SPI1_RX_PIN 5
|
||||
#endif /* #if SPI1_IN_USE */
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
#include "sys/clock.h"
|
||||
#include "sys/etimer.h"
|
||||
|
@ -136,8 +137,6 @@ long referenceVar;
|
|||
static struct cooja_mt_thread rtimer_thread;
|
||||
static struct cooja_mt_thread process_run_thread;
|
||||
|
||||
#define MIN(a, b) ( (a)<(b) ? (a) : (b) )
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
static void
|
||||
|
|
|
@ -37,18 +37,6 @@
|
|||
#ifndef HAL_LCD_H
|
||||
#define HAL_LCD_H
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(n, m) (((n) < (m)) ? (n) : (m))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(n, m) (((n) < (m)) ? (m) : (n))
|
||||
#endif
|
||||
|
||||
#ifndef ABS
|
||||
# define ABS(n) (((n) < 0) ? -(n) : (n))
|
||||
#endif
|
||||
|
||||
#define LCD_BACKLT_OUT P8OUT
|
||||
#define LCD_BACKLT_DIR P8DIR
|
||||
#define LCD_BACKLT_SEL P8SEL
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "lpm.h"
|
||||
#include "gpio-interrupt.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "dev/oscillators.h"
|
||||
#include "ieee-addr.h"
|
||||
#include "vims.h"
|
||||
#include "cc26xx-model.h"
|
||||
|
@ -119,23 +120,6 @@ set_rf_params(void)
|
|||
#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
|
||||
*
|
||||
|
@ -144,41 +128,39 @@ select_lf_xosc(void)
|
|||
int
|
||||
main(void)
|
||||
{
|
||||
/* Enable flash cache and prefetch. */
|
||||
ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_ENABLED);
|
||||
ti_lib_vims_configure(VIMS_BASE, true, true);
|
||||
|
||||
ti_lib_int_master_disable();
|
||||
|
||||
/* 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);
|
||||
oscillators_select_lf_xosc();
|
||||
|
||||
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();
|
||||
|
||||
/*
|
||||
* Disable I/O pad sleep mode and open I/O latches in the AON IOC interface
|
||||
* This is only relevant when returning from shutdown (which is what froze
|
||||
* latches in the first place. Before doing these things though, we should
|
||||
* allow software to first regain control of pins
|
||||
*/
|
||||
ti_lib_pwr_ctrl_io_freeze_disable();
|
||||
|
||||
fade(LEDS_RED);
|
||||
|
||||
ti_lib_int_master_enable();
|
||||
|
||||
cc26xx_rtc_init();
|
||||
clock_init();
|
||||
rtimer_init();
|
||||
|
||||
board_init();
|
||||
|
||||
watchdog_init();
|
||||
process_init();
|
||||
|
||||
|
@ -187,7 +169,6 @@ main(void)
|
|||
/* Character I/O Initialisation */
|
||||
#if CC26XX_UART_CONF_ENABLE
|
||||
cc26xx_uart_init();
|
||||
cc26xx_uart_set_input(serial_line_input_byte);
|
||||
#endif
|
||||
|
||||
serial_line_init();
|
||||
|
|
|
@ -136,7 +136,7 @@ static int enabled = SENSOR_STATUS_DISABLED;
|
|||
static uint8_t sensor_value[SENSOR_DATA_BUF_SIZE];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Wait SENSOR_STARTUP_DELAY clock ticks for the sensor to be ready - ~80ms */
|
||||
#define SENSOR_STARTUP_DELAY 11
|
||||
#define SENSOR_STARTUP_DELAY 3
|
||||
|
||||
static struct ctimer startup_timer;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -187,7 +187,7 @@ enable_sensor(bool enable)
|
|||
|
||||
if(enable) {
|
||||
/* Enable forced mode */
|
||||
val = PM_NORMAL | OSRSP(1) | OSRST(1);
|
||||
val = PM_FORCED | OSRSP(1) | OSRST(1);
|
||||
} else {
|
||||
val = PM_OFF;
|
||||
}
|
||||
|
@ -345,6 +345,7 @@ configure(int type, int enable)
|
|||
case SENSORS_HW_INIT:
|
||||
enabled = SENSOR_STATUS_INITIALISED;
|
||||
init();
|
||||
enable_sensor(0);
|
||||
break;
|
||||
case SENSORS_ACTIVE:
|
||||
/* Must be initialised first */
|
||||
|
|
|
@ -42,12 +42,10 @@
|
|||
*
|
||||
* Once the sensor is stable, the driver will generate a sensors_changed event.
|
||||
*
|
||||
* Once a reading has been taken, the caller has two options:
|
||||
* - Turn the sensor off by calling SENSORS_DEACTIVATE, but in order to take
|
||||
* subsequent readings SENSORS_ACTIVATE must be called again
|
||||
* - Leave the sensor on. In this scenario, the caller can simply keep calling
|
||||
* value() for subsequent readings, but having the sensor on will consume
|
||||
* energy
|
||||
* We take readings in "Forced" mode. In this mode, the BMP will take a single
|
||||
* measurement and it will then automatically go to sleep.
|
||||
*
|
||||
* SENSORS_ACTIVATE must be called again to trigger a new reading cycle
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
|
|
|
@ -39,9 +39,55 @@
|
|||
#include "contiki-conf.h"
|
||||
#include "ti-lib.h"
|
||||
#include "board-i2c.h"
|
||||
#include "lpm.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define NO_INTERFACE 0xFF
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t slave_addr = 0x00;
|
||||
static uint8_t interface = 0xFF;
|
||||
static uint8_t interface = NO_INTERFACE;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
accessible(void)
|
||||
{
|
||||
/* First, check the PD */
|
||||
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Then check the 'run mode' clock gate */
|
||||
if(!(HWREG(PRCM_BASE + PRCM_O_I2CCLKGR) & PRCM_I2CCLKGR_CLK_EN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
board_i2c_wakeup()
|
||||
{
|
||||
/* First, make sure the SERIAL PD is on */
|
||||
ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL);
|
||||
while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON));
|
||||
|
||||
/* Enable the clock to I2C */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_I2C0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
/* Reset the I2C controller */
|
||||
HWREG(PRCM_BASE + PRCM_O_RESETI2C) = PRCM_RESETI2C_I2C;
|
||||
|
||||
/* Enable and initialize the I2C master module */
|
||||
ti_lib_i2c_master_init_exp_clk(I2C0_BASE,
|
||||
ti_lib_sys_ctrl_peripheral_clock_get(
|
||||
PRCM_PERIPH_I2C0, SYSCTRL_SYSBUS_ON),
|
||||
true);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
i2c_status()
|
||||
|
@ -57,21 +103,34 @@ i2c_status()
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
board_i2c_init()
|
||||
board_i2c_shutdown()
|
||||
{
|
||||
/* The I2C peripheral must be enabled */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_I2C0);
|
||||
interface = NO_INTERFACE;
|
||||
|
||||
if(accessible()) {
|
||||
ti_lib_i2c_master_disable(I2C0_BASE);
|
||||
}
|
||||
|
||||
ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_I2C0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
/* Reset the I2C controller */
|
||||
HWREG(PRCM_BASE + PRCM_O_RESETI2C) = PRCM_RESETI2C_I2C;
|
||||
/*
|
||||
* Set all pins to GPIO Input and disable the output driver. Set internal
|
||||
* pull to match external pull
|
||||
*
|
||||
* SDA and SCL: external PU resistor
|
||||
* SDA HP and SCL HP: MPU PWR low
|
||||
*/
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA_HP);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA_HP, IOC_IOPULL_DOWN);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL_HP);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL_HP, IOC_IOPULL_DOWN);
|
||||
|
||||
/* Enable and initialize the I2C master module */
|
||||
ti_lib_i2c_master_init_exp_clk(I2C0_BASE,
|
||||
ti_lib_sys_ctrl_peripheral_clock_get(
|
||||
PRCM_PERIPH_I2C0, SYSCTRL_SYSBUS_ON),
|
||||
true);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA, IOC_IOPULL_UP);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL, IOC_IOPULL_UP);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
|
@ -248,8 +307,15 @@ board_i2c_select(uint8_t new_interface, uint8_t address)
|
|||
{
|
||||
slave_addr = address;
|
||||
|
||||
if(accessible() == false) {
|
||||
board_i2c_wakeup();
|
||||
}
|
||||
|
||||
if(new_interface != interface) {
|
||||
interface = new_interface;
|
||||
|
||||
ti_lib_i2c_master_disable(I2C0_BASE);
|
||||
|
||||
if(interface == BOARD_I2C_INTERFACE_0) {
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA, IOC_NO_IOPULL);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL, IOC_NO_IOPULL);
|
||||
|
@ -263,6 +329,12 @@ board_i2c_select(uint8_t new_interface, uint8_t address)
|
|||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL);
|
||||
}
|
||||
|
||||
/* Enable and initialize the I2C master module */
|
||||
ti_lib_i2c_master_init_exp_clk(I2C0_BASE,
|
||||
ti_lib_sys_ctrl_peripheral_clock_get(
|
||||
PRCM_PERIPH_I2C0, SYSCTRL_SYSBUS_ON),
|
||||
true);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -48,13 +48,15 @@
|
|||
#define BOARD_I2C_INTERFACE_0 0
|
||||
#define BOARD_I2C_INTERFACE_1 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define board_i2c_deselect(...)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initialise the I2C controller with defaults for the sensortag
|
||||
* \brief Put the I2C controller in a known state
|
||||
*
|
||||
* In this state, pins SDA and SCL will be under i2c control and pins SDA HP
|
||||
* and SCL HP will be configured as gpio inputs. This is equal to selecting
|
||||
* BOARD_I2C_INTERFACE_0, but without selecting a slave device address
|
||||
*/
|
||||
void board_i2c_init(void);
|
||||
|
||||
#define board_i2c_deselect() board_i2c_select(BOARD_I2C_INTERFACE_0, 0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Select an I2C slave
|
||||
* \param interface The I2C interface to be used (BOARD_I2C_INTERFACE_0 or _1)
|
||||
|
@ -99,6 +101,27 @@ bool board_i2c_write_single(uint8_t data);
|
|||
*/
|
||||
bool board_i2c_write_read(uint8_t *wdata, uint8_t wlen, uint8_t *rdata,
|
||||
uint8_t rlen);
|
||||
|
||||
/**
|
||||
* \brief Enables the I2C peripheral with defaults
|
||||
*
|
||||
* This function is called to wakeup and initialise the I2C.
|
||||
*
|
||||
* This function can be called explicitly, but it will also be called
|
||||
* automatically by board_i2c_select() when required. One of those two
|
||||
* functions MUST be called before any other I2C operation after a chip
|
||||
* sleep / wakeup cycle or after a call to board_i2c_shutdown(). Failing to do
|
||||
* so will lead to a bus fault.
|
||||
*/
|
||||
void board_i2c_wakeup(void);
|
||||
|
||||
/**
|
||||
* \brief Stops the I2C peripheral and restores pins to s/w control
|
||||
*
|
||||
* This function is called automatically by the board's LPM logic, but it
|
||||
* can also be called explicitly.
|
||||
*/
|
||||
void board_i2c_shutdown(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* BOARD_I2C_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -40,12 +40,35 @@
|
|||
#include "ti-lib.h"
|
||||
#include "board-spi.h"
|
||||
#include "board.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CPU_FREQ 48000000ul
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
accessible(void)
|
||||
{
|
||||
/* First, check the PD */
|
||||
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Then check the 'run mode' clock gate */
|
||||
if(!(HWREG(PRCM_BASE + PRCM_O_SSICLKGR) & PRCM_SSICLKGR_CLK_EN_SSI0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
board_spi_write(const uint8_t *buf, size_t len)
|
||||
{
|
||||
if(accessible() == false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(len > 0) {
|
||||
uint32_t ul;
|
||||
|
||||
|
@ -61,6 +84,10 @@ board_spi_write(const uint8_t *buf, size_t len)
|
|||
int
|
||||
board_spi_read(uint8_t *buf, size_t len)
|
||||
{
|
||||
if(accessible() == false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(len > 0) {
|
||||
uint32_t ul;
|
||||
|
||||
|
@ -79,6 +106,10 @@ board_spi_read(uint8_t *buf, size_t len)
|
|||
void
|
||||
board_spi_flush()
|
||||
{
|
||||
if(accessible() == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t ul;
|
||||
while(ti_lib_rom_ssi_data_get_non_blocking(SSI0_BASE, &ul));
|
||||
}
|
||||
|
@ -88,7 +119,12 @@ board_spi_open(uint32_t bit_rate, uint32_t clk_pin)
|
|||
{
|
||||
uint32_t buf;
|
||||
|
||||
/* SPI power */
|
||||
/* First, make sure the SERIAL PD is on */
|
||||
ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL);
|
||||
while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
|
||||
!= PRCM_DOMAIN_POWER_ON));
|
||||
|
||||
/* Enable clock in active mode */
|
||||
ti_lib_rom_prcm_peripheral_run_enable(PRCM_PERIPH_SSI0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
@ -113,6 +149,16 @@ board_spi_close()
|
|||
ti_lib_rom_prcm_peripheral_run_disable(PRCM_PERIPH_SSI0);
|
||||
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(BOARD_IOID_SPI_MISO);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SPI_MISO, IOC_IOPULL_DOWN);
|
||||
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SPI_MOSI);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SPI_MOSI, IOC_IOPULL_DOWN);
|
||||
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SPI_CLK_FLASH);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SPI_CLK_FLASH, IOC_IOPULL_DOWN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -46,17 +46,16 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define PRCM_DOMAINS (PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH)
|
||||
#include <stdbool.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
power_domains_on(void)
|
||||
{
|
||||
/* Turn on relevant power domains */
|
||||
ti_lib_prcm_power_domain_on(PRCM_DOMAINS);
|
||||
/* Turn on the PERIPH PD */
|
||||
ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH);
|
||||
|
||||
/* Wait for domains to power on */
|
||||
while((ti_lib_prcm_power_domain_status(PRCM_DOMAINS)
|
||||
while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH)
|
||||
!= PRCM_DOMAIN_POWER_ON));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -64,8 +63,6 @@ static void
|
|||
lpm_wakeup_handler(void)
|
||||
{
|
||||
power_domains_on();
|
||||
|
||||
board_i2c_init();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -77,8 +74,12 @@ shutdown_handler(uint8_t mode)
|
|||
SENSORS_DEACTIVATE(opt_3001_sensor);
|
||||
SENSORS_DEACTIVATE(tmp_007_sensor);
|
||||
SENSORS_DEACTIVATE(hdc_1000_sensor);
|
||||
mpu_9250_sensor.configure(MPU_9250_SENSOR_SHUTDOWN, 0);
|
||||
SENSORS_DEACTIVATE(mpu_9250_sensor);
|
||||
ti_lib_gpio_pin_clear(BOARD_MPU_POWER);
|
||||
}
|
||||
|
||||
/* In all cases, stop the I2C */
|
||||
board_i2c_shutdown();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
@ -88,13 +89,47 @@ shutdown_handler(uint8_t mode)
|
|||
* wake up so we can turn power domains back on for I2C and SSI, and to make
|
||||
* sure everything on the board is off before CM3 shutdown.
|
||||
*/
|
||||
LPM_MODULE(sensortag_module, NULL, shutdown_handler, lpm_wakeup_handler);
|
||||
LPM_MODULE(sensortag_module, NULL, shutdown_handler, lpm_wakeup_handler,
|
||||
LPM_DOMAIN_NONE);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
configure_unused_pins(void)
|
||||
{
|
||||
/* DP[0..3] */
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP0);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP0, IOC_IOPULL_DOWN);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP1);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP1, IOC_IOPULL_DOWN);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP2);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP2, IOC_IOPULL_DOWN);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP3);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP3, IOC_IOPULL_DOWN);
|
||||
|
||||
/* Devpack ID */
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DEVPK_ID);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_DEVPK_ID, IOC_IOPULL_UP);
|
||||
|
||||
/* Digital Microphone */
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_MIC_POWER);
|
||||
ti_lib_gpio_pin_clear((1 << BOARD_IOID_MIC_POWER));
|
||||
ti_lib_ioc_io_drv_strength_set(BOARD_IOID_MIC_POWER, IOC_CURRENT_2MA,
|
||||
IOC_STRENGTH_MIN);
|
||||
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_AUDIO_DI);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_AUDIO_DI, IOC_IOPULL_DOWN);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_AUDIO_CLK);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_AUDIO_CLK, IOC_IOPULL_DOWN);
|
||||
|
||||
/* UART over Devpack - TX only (ToDo: Map all UART pins to Debugger) */
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP5_UARTTX);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP5_UARTTX, IOC_IOPULL_DOWN);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
board_init()
|
||||
{
|
||||
/* Disable global interrupts */
|
||||
uint8_t int_disabled = ti_lib_int_master_disable();
|
||||
bool int_disabled = ti_lib_int_master_disable();
|
||||
|
||||
power_domains_on();
|
||||
|
||||
|
@ -112,37 +147,19 @@ board_init()
|
|||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
/* Enable GPT0 module - Wait for the clock to be enabled */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
/* Keys (input pullup) */
|
||||
ti_lib_rom_ioc_pin_type_gpio_input(BOARD_IOID_KEY_LEFT);
|
||||
ti_lib_rom_ioc_pin_type_gpio_input(BOARD_IOID_KEY_RIGHT);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_KEY_LEFT, IOC_IOPULL_UP);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP);
|
||||
|
||||
/* I2C controller */
|
||||
board_i2c_init();
|
||||
|
||||
/* Sensor interface */
|
||||
ti_lib_rom_ioc_pin_type_gpio_input(BOARD_IOID_MPU_INT);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_MPU_INT, IOC_IOPULL_DOWN);
|
||||
|
||||
ti_lib_rom_ioc_pin_type_gpio_input(BOARD_IOID_REED_RELAY);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_REED_RELAY, IOC_IOPULL_DOWN);
|
||||
|
||||
ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_MPU_POWER);
|
||||
|
||||
/* Flash interface */
|
||||
ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_FLASH_CS);
|
||||
ti_lib_gpio_pin_write(BOARD_FLASH_CS, 1);
|
||||
board_i2c_wakeup();
|
||||
|
||||
buzzer_init();
|
||||
|
||||
/* Make sure the external flash is in the lower power mode */
|
||||
ext_flash_init();
|
||||
|
||||
lpm_register_module(&sensortag_module);
|
||||
|
||||
/* For unsupported peripherals, select a default pin configuration */
|
||||
configure_unused_pins();
|
||||
|
||||
/* Re-enable interrupt if initially enabled. */
|
||||
if(!int_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
|
|
|
@ -100,12 +100,16 @@
|
|||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
#define BOARD_IOID_UART_RX IOID_17
|
||||
#define BOARD_IOID_DP4_UARTRX IOID_28
|
||||
#define BOARD_IOID_DP5_UARTTX IOID_29
|
||||
|
||||
#define BOARD_IOID_UART_RX BOARD_IOID_DP4_UARTRX
|
||||
#define BOARD_IOID_UART_TX IOID_16
|
||||
|
||||
#define BOARD_IOID_UART_CTS IOID_UNUSED
|
||||
#define BOARD_IOID_UART_RTS IOID_UNUSED
|
||||
#define BOARD_UART_RXD (1 << BOARD_IOID_UART_RXD)
|
||||
#define BOARD_UART_TXD (1 << BOARD_IOID_UART_TXD)
|
||||
#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX)
|
||||
#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX)
|
||||
#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS)
|
||||
#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS)
|
||||
/** @} */
|
||||
|
@ -156,7 +160,7 @@
|
|||
*/
|
||||
#define BOARD_IOID_FLASH_CS IOID_14
|
||||
#define BOARD_FLASH_CS (1 << BOARD_IOID_FLASH_CS)
|
||||
#define BOARD_SPI_CLK_FLASH IOID_11
|
||||
#define BOARD_IOID_SPI_CLK_FLASH IOID_17
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -183,6 +187,44 @@
|
|||
#define BOARD_MPU_POWER (1 << BOARD_IOID_MPU_POWER)
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Board devpack IOID mappings (LCD etc.)
|
||||
*
|
||||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
#define BOARD_IOID_AUDIOFS_TDO IOID_16
|
||||
#define BOARD_IOID_DEVPACK_CS IOID_20
|
||||
#define BOARD_IOID_DEVPK_LCD_EXTCOMIN IOID_22
|
||||
#define BOARD_IOID_AUDIODO IOID_22
|
||||
#define BOARD_IOID_DP2 IOID_23
|
||||
#define BOARD_IOID_DP1 IOID_24
|
||||
#define BOARD_IOID_DP0 IOID_25
|
||||
#define BOARD_IOID_DP3 IOID_27
|
||||
#define BOARD_IOID_DEVPK_ID IOID_30
|
||||
#define BOARD_DEVPACK_CS (1 << BOARD_IOID_DEVPACK_CS)
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief TMP Sensor
|
||||
*
|
||||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
#define BOARD_IOID_TMP_RDY IOID_1
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Digital Microphone
|
||||
*
|
||||
* Those values are not meant to be modified by the user
|
||||
* @{
|
||||
*/
|
||||
#define BOARD_IOID_MIC_POWER IOID_13
|
||||
#define BOARD_IOID_AUDIO_DI IOID_2
|
||||
#define BOARD_IOID_AUDIO_CLK IOID_11
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Device string used on startup
|
||||
* @{
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
#define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \
|
||||
IOC_IOPULL_UP | IOC_SLEW_DISABLE | \
|
||||
IOC_HYST_DISABLE | IOC_BOTH_EDGES | \
|
||||
IOC_HYST_ENABLE | IOC_BOTH_EDGES | \
|
||||
IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \
|
||||
IOC_NO_WAKE_UP | IOC_INPUT_ENABLE | \
|
||||
IOC_JTAG_DISABLE)
|
||||
|
@ -116,7 +116,7 @@ button_press_handler(uint8_t ioid)
|
|||
sensors_changed(&button_right_sensor);
|
||||
}
|
||||
} else {
|
||||
lpm_shutdown(BOARD_IOID_KEY_RIGHT);
|
||||
lpm_shutdown(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP, IOC_WAKE_ON_LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,19 +46,12 @@
|
|||
#include <stdio.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t buzzer_on;
|
||||
static lpm_power_domain_lock_t lock;
|
||||
LPM_MODULE(buzzer_module, NULL, NULL, NULL, LPM_DOMAIN_PERIPH);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
buzzer_init()
|
||||
{
|
||||
buzzer_on = 0;
|
||||
|
||||
/* Drive the I/O ID with GPT0 / Timer A */
|
||||
ti_lib_ioc_port_configure_set(BOARD_IOID_BUZZER, IOC_PORT_MCU_PORT_EVENT0,
|
||||
IOC_STD_OUTPUT);
|
||||
|
||||
/* GPT0 / Timer A: PWM, Interrupt Enable */
|
||||
HWREG(GPT0_BASE + GPT_O_TAMR) = (TIMER_CFG_A_PWM & 0xFF) | GPT_TAMR_TAPWMIE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
|
@ -72,9 +65,28 @@ buzzer_start(int freq)
|
|||
{
|
||||
uint32_t load;
|
||||
|
||||
/* Enable GPT0 clocks under active, sleep, deep sleep */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
/* Drive the I/O ID with GPT0 / Timer A */
|
||||
ti_lib_ioc_port_configure_set(BOARD_IOID_BUZZER, IOC_PORT_MCU_PORT_EVENT0,
|
||||
IOC_STD_OUTPUT);
|
||||
|
||||
/* GPT0 / Timer A: PWM, Interrupt Enable */
|
||||
HWREG(GPT0_BASE + GPT_O_TAMR) = (TIMER_CFG_A_PWM & 0xFF) | GPT_TAMR_TAPWMIE;
|
||||
|
||||
buzzer_on = 1;
|
||||
|
||||
lpm_pd_lock_obtain(&lock, PRCM_DOMAIN_PERIPH);
|
||||
/*
|
||||
* Register ourself with LPM. This will keep the PERIPH PD powered on
|
||||
* during deep sleep, allowing the buzzer to keep working while the chip is
|
||||
* being power-cycled
|
||||
*/
|
||||
lpm_register_module(&buzzer_module);
|
||||
|
||||
/* Stop the timer */
|
||||
ti_lib_timer_disable(GPT0_BASE, TIMER_A);
|
||||
|
@ -88,12 +100,6 @@ buzzer_start(int freq)
|
|||
/* Start */
|
||||
ti_lib_timer_enable(GPT0_BASE, TIMER_A);
|
||||
}
|
||||
|
||||
/* Run in sleep mode */
|
||||
ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -101,24 +107,37 @@ buzzer_stop()
|
|||
{
|
||||
buzzer_on = 0;
|
||||
|
||||
lpm_pd_lock_release(&lock);
|
||||
/*
|
||||
* Unregister the buzzer module from LPM. This will effectively release our
|
||||
* lock for the PERIPH PD allowing it to be powered down (unless some other
|
||||
* module keeps it on)
|
||||
*/
|
||||
lpm_unregister_module(&buzzer_module);
|
||||
|
||||
/* Stop the timer */
|
||||
ti_lib_timer_disable(GPT0_BASE, TIMER_A);
|
||||
|
||||
/*
|
||||
* Stop running in sleep mode.
|
||||
* ToDo: Currently GPT0 is in use by clock_delay_usec (GPT0/TB) and by this
|
||||
* module here (GPT0/TA). clock_delay_usec will never need GPT0/TB in sleep
|
||||
* mode and we control TA here. Thus, with the current setup, it's OK to
|
||||
* control whether GPT0 runs in sleep mode in this module here. However, if
|
||||
* some other module at some point starts using GPT0, we should change this
|
||||
* to happen through an umbrella module
|
||||
* Stop the module clock:
|
||||
*
|
||||
* Currently GPT0 is in use by clock_delay_usec (GPT0/TB) and by this
|
||||
* module here (GPT0/TA).
|
||||
*
|
||||
* clock_delay_usec
|
||||
* - is definitely not running when we enter here and
|
||||
* - handles the module clock internally
|
||||
*
|
||||
* Thus, we can safely change the state of module clocks here.
|
||||
*/
|
||||
ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_TIMER0);
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
/* Un-configure the pin */
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_BUZZER);
|
||||
ti_lib_ioc_io_input_set(BOARD_IOID_BUZZER, IOC_INPUT_DISABLE);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
/* Part specific constants */
|
||||
|
||||
#define BLS_MANUFACTURER_ID 0xEF
|
||||
#define BLS_DEVICE_ID 0x11
|
||||
#define BLS_DEVICE_ID 0x12
|
||||
|
||||
#define BLS_PROGRAM_PAGE_SIZE 256
|
||||
#define BLS_ERASE_SECTOR_SIZE 4096
|
||||
|
@ -140,50 +140,8 @@ wait_ready(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Put the device in power save mode. No access to data; only
|
||||
* the status register is accessible.
|
||||
* \return True when SPI transactions succeed
|
||||
*/
|
||||
static bool
|
||||
power_down(void)
|
||||
{
|
||||
uint8_t cmd;
|
||||
bool success;
|
||||
|
||||
cmd = BLS_CODE_DP;
|
||||
select();
|
||||
success = board_spi_write(&cmd, sizeof(cmd));
|
||||
deselect();
|
||||
|
||||
return success;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Take device out of power save mode and prepare it for normal operation
|
||||
* \return True if the command was written successfully
|
||||
*/
|
||||
static bool
|
||||
power_standby(void)
|
||||
{
|
||||
uint8_t cmd;
|
||||
bool success;
|
||||
|
||||
cmd = BLS_CODE_RDP;
|
||||
select();
|
||||
success = board_spi_write(&cmd, sizeof(cmd));
|
||||
|
||||
if(success) {
|
||||
success = wait_ready() == 0;
|
||||
}
|
||||
|
||||
deselect();
|
||||
|
||||
return success;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Verify the flash part.
|
||||
* @return True when successful.
|
||||
* \brief Verify the flash part.
|
||||
* \return True when successful.
|
||||
*/
|
||||
static bool
|
||||
verify_part(void)
|
||||
|
@ -210,6 +168,57 @@ verify_part(void)
|
|||
return true;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Put the device in power save mode. No access to data; only
|
||||
* the status register is accessible.
|
||||
*/
|
||||
static void
|
||||
power_down(void)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t i;
|
||||
|
||||
cmd = BLS_CODE_DP;
|
||||
select();
|
||||
board_spi_write(&cmd, sizeof(cmd));
|
||||
deselect();
|
||||
|
||||
i = 0;
|
||||
while(i < 10) {
|
||||
if(!verify_part()) {
|
||||
/* Verify Part failed: Device is powered down */
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Should not be required */
|
||||
deselect();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Take device out of power save mode and prepare it for normal operation
|
||||
* \return True if the command was written successfully
|
||||
*/
|
||||
static bool
|
||||
power_standby(void)
|
||||
{
|
||||
uint8_t cmd;
|
||||
bool success;
|
||||
|
||||
cmd = BLS_CODE_RDP;
|
||||
select();
|
||||
success = board_spi_write(&cmd, sizeof(cmd));
|
||||
|
||||
if(success) {
|
||||
success = wait_ready() == 0;
|
||||
}
|
||||
|
||||
deselect();
|
||||
|
||||
return success;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Enable write.
|
||||
* \return Zero when successful.
|
||||
|
@ -232,7 +241,7 @@ write_enable(void)
|
|||
bool
|
||||
ext_flash_open()
|
||||
{
|
||||
board_spi_open(4000000, BOARD_SPI_CLK_FLASH);
|
||||
board_spi_open(4000000, BOARD_IOID_SPI_CLK_FLASH);
|
||||
|
||||
/* GPIO pin configuration */
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_FLASH_CS);
|
||||
|
@ -406,4 +415,11 @@ ext_flash_test(void)
|
|||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
ext_flash_init()
|
||||
{
|
||||
ext_flash_open();
|
||||
ext_flash_close();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -54,6 +54,8 @@ bool ext_flash_open(void);
|
|||
|
||||
/**
|
||||
* \brief Close the storage driver
|
||||
*
|
||||
* This call will put the device in its lower power mode (power down).
|
||||
*/
|
||||
void ext_flash_close(void);
|
||||
|
||||
|
@ -94,6 +96,17 @@ bool ext_flash_write(size_t offset, size_t length, const uint8_t *buf);
|
|||
* \return True when successful.
|
||||
*/
|
||||
bool ext_flash_test(void);
|
||||
|
||||
/**
|
||||
* \brief Initialise the external flash
|
||||
*
|
||||
* This function will explicitly put the part in its lowest power mode
|
||||
* (power-down).
|
||||
*
|
||||
* In order to perform any operation, the caller must first wake the device
|
||||
* up by calling ext_flash_open()
|
||||
*/
|
||||
void ext_flash_init(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* EXT_FLASH_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -212,12 +212,12 @@ static uint8_t acc_range_reg;
|
|||
static uint8_t val;
|
||||
static uint8_t interrupt_status;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define SENSOR_STATUS_DISABLED 0
|
||||
#define SENSOR_STATUS_BOOTING 1
|
||||
#define SENSOR_STATUS_ENABLED 2
|
||||
#define SENSOR_STATE_DISABLED 0
|
||||
#define SENSOR_STATE_BOOTING 1
|
||||
#define SENSOR_STATE_ENABLED 2
|
||||
|
||||
static int enabled = SENSOR_STATUS_DISABLED;
|
||||
static int elements;
|
||||
static int state = SENSOR_STATE_DISABLED;
|
||||
static int elements = MPU_9250_SENSOR_TYPE_NONE;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* 3 16-byte words for all sensor readings */
|
||||
#define SENSOR_DATA_BUF_SIZE 3
|
||||
|
@ -289,7 +289,9 @@ static void
|
|||
select_axes(void)
|
||||
{
|
||||
val = ~mpu_config;
|
||||
SENSOR_SELECT();
|
||||
sensor_common_write_reg(PWR_MGMT_2, &val, 1);
|
||||
SENSOR_DESELECT();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -334,37 +336,6 @@ acc_set_range(uint8_t new_range)
|
|||
return success;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initialise the MPU
|
||||
* \return True if success
|
||||
*/
|
||||
static bool
|
||||
init_sensor(void)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
interrupt_status = false;
|
||||
acc_range = ACC_RANGE_INVALID;
|
||||
mpu_config = 0; /* All axes off */
|
||||
|
||||
/* Device reset */
|
||||
val = 0x80;
|
||||
SENSOR_SELECT();
|
||||
ret = sensor_common_write_reg(PWR_MGMT_1, &val, 1);
|
||||
SENSOR_DESELECT();
|
||||
|
||||
if(ret) {
|
||||
delay_ms(200);
|
||||
|
||||
/* Initial configuration */
|
||||
acc_set_range(ACC_RANGE_8G);
|
||||
/* Power save */
|
||||
sensor_sleep();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Check whether a data or wake on motion interrupt has occurred
|
||||
* \return Return the interrupt status
|
||||
|
@ -450,13 +421,13 @@ gyro_read(uint16_t *data)
|
|||
/* Burst read of all gyroscope values */
|
||||
success = sensor_common_read_reg(GYRO_XOUT_H, (uint8_t *)data, DATA_SIZE);
|
||||
|
||||
SENSOR_DESELECT();
|
||||
|
||||
if(success) {
|
||||
convert_to_le((uint8_t *)data, DATA_SIZE);
|
||||
} else {
|
||||
sensor_common_set_error_data((uint8_t *)data, DATA_SIZE);
|
||||
}
|
||||
|
||||
SENSOR_DESELECT();
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
@ -514,15 +485,13 @@ gyro_convert(int16_t raw_data)
|
|||
static void
|
||||
notify_ready(void *not_used)
|
||||
{
|
||||
enabled = SENSOR_STATUS_ENABLED;
|
||||
state = SENSOR_STATE_ENABLED;
|
||||
sensors_changed(&mpu_9250_sensor);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
initialise(void *not_used)
|
||||
{
|
||||
init_sensor();
|
||||
|
||||
/* Configure the accelerometer range */
|
||||
if((elements & MPU_9250_SENSOR_TYPE_ACC) != 0) {
|
||||
acc_set_range(MPU_9250_SENSOR_ACC_RANGE);
|
||||
|
@ -537,7 +506,7 @@ static void
|
|||
power_up(void)
|
||||
{
|
||||
ti_lib_gpio_pin_write(BOARD_MPU_POWER, 1);
|
||||
enabled = SENSOR_STATUS_BOOTING;
|
||||
state = SENSOR_STATE_BOOTING;
|
||||
|
||||
ctimer_set(&startup_timer, SENSOR_BOOT_DELAY, initialise, NULL);
|
||||
}
|
||||
|
@ -553,7 +522,7 @@ value(int type)
|
|||
int rv;
|
||||
float converted_val = 0;
|
||||
|
||||
if(enabled == SENSOR_STATUS_DISABLED) {
|
||||
if(state == SENSOR_STATE_DISABLED) {
|
||||
PRINTF("MPU: Sensor Disabled\n");
|
||||
return CC26XX_SENSOR_READING_ERROR;
|
||||
}
|
||||
|
@ -632,33 +601,42 @@ configure(int type, int enable)
|
|||
{
|
||||
switch(type) {
|
||||
case SENSORS_HW_INIT:
|
||||
ti_lib_rom_ioc_pin_type_gpio_input(BOARD_IOID_MPU_INT);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_MPU_INT, IOC_IOPULL_DOWN);
|
||||
ti_lib_ioc_io_hyst_set(BOARD_IOID_MPU_INT, IOC_HYST_ENABLE);
|
||||
|
||||
ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_MPU_POWER);
|
||||
ti_lib_ioc_io_drv_strength_set(BOARD_IOID_MPU_POWER, IOC_CURRENT_4MA,
|
||||
IOC_STRENGTH_MAX);
|
||||
ti_lib_gpio_pin_clear(BOARD_MPU_POWER);
|
||||
elements = MPU_9250_SENSOR_TYPE_NONE;
|
||||
break;
|
||||
case SENSORS_ACTIVE:
|
||||
if((enable & MPU_9250_SENSOR_TYPE_ACC) != 0 ||
|
||||
(enable & MPU_9250_SENSOR_TYPE_GYRO) != 0) {
|
||||
if(((enable & MPU_9250_SENSOR_TYPE_ACC) != 0) ||
|
||||
((enable & MPU_9250_SENSOR_TYPE_GYRO) != 0)) {
|
||||
PRINTF("MPU: Enabling\n");
|
||||
elements = enable & MPU_9250_SENSOR_TYPE_ALL;
|
||||
|
||||
power_up();
|
||||
|
||||
enabled = SENSOR_STATUS_BOOTING;
|
||||
state = SENSOR_STATE_BOOTING;
|
||||
} else {
|
||||
PRINTF("MPU: Disabling\n");
|
||||
ctimer_stop(&startup_timer);
|
||||
elements = MPU_9250_SENSOR_TYPE_NONE;
|
||||
enable_sensor(0);
|
||||
while(ti_lib_i2c_master_busy(I2C0_BASE));
|
||||
enabled = SENSOR_STATUS_DISABLED;
|
||||
if(HWREG(GPIO_BASE + GPIO_O_DOUT31_0) & BOARD_MPU_POWER) {
|
||||
/* Then check our state */
|
||||
elements = MPU_9250_SENSOR_TYPE_NONE;
|
||||
ctimer_stop(&startup_timer);
|
||||
sensor_sleep();
|
||||
while(ti_lib_i2c_master_busy(I2C0_BASE));
|
||||
state = SENSOR_STATE_DISABLED;
|
||||
ti_lib_gpio_pin_clear(BOARD_MPU_POWER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MPU_9250_SENSOR_SHUTDOWN:
|
||||
ti_lib_gpio_pin_write(BOARD_MPU_POWER, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return enabled;
|
||||
return state;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -672,12 +650,12 @@ status(int type)
|
|||
switch(type) {
|
||||
case SENSORS_ACTIVE:
|
||||
case SENSORS_READY:
|
||||
return enabled;
|
||||
return state;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SENSOR_STATUS_DISABLED;
|
||||
return SENSOR_STATE_DISABLED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
SENSORS_SENSOR(mpu_9250_sensor, "MPU9250", value, configure, status);
|
||||
|
|
|
@ -86,8 +86,6 @@
|
|||
#define MPU_9250_SENSOR_TYPE_NONE 0
|
||||
#define MPU_9250_SENSOR_TYPE_ALL (MPU_9250_SENSOR_TYPE_ACC | \
|
||||
MPU_9250_SENSOR_TYPE_GYRO)
|
||||
|
||||
#define MPU_9250_SENSOR_SHUTDOWN 0xFF
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Accelerometer range */
|
||||
#define MPU_9250_SENSOR_ACC_RANGE_2G 0
|
||||
|
|
|
@ -69,16 +69,42 @@
|
|||
#define REG_MANUFACTURER_ID 0x7E
|
||||
#define REG_DEVICE_ID 0x7F
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Register values */
|
||||
#define MANUFACTURER_ID 0x5449 /* TI */
|
||||
#define DEVICE_ID 0x3001 /* Opt 3001 */
|
||||
#define CONFIG_RESET 0xC810
|
||||
#define CONFIG_TEST 0xCC10
|
||||
#define CONFIG_ENABLE 0x10CC /* 0xCC10 */
|
||||
#define CONFIG_DISABLE 0x108C /* 0xC810 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Bit values */
|
||||
#define DATA_RDY_BIT 0x0080 /* Data ready */
|
||||
/*
|
||||
* Configuration Register Bits and Masks.
|
||||
* We use uint16_t to read from / write to registers, meaning that the
|
||||
* register's MSB is the variable's LSB.
|
||||
*/
|
||||
#define CONFIG_RN 0x00F0 /* [15..12] Range Number */
|
||||
#define CONFIG_CT 0x0008 /* [11] Conversion Time */
|
||||
#define CONFIG_M 0x0006 /* [10..9] Mode of Conversion */
|
||||
#define CONFIG_OVF 0x0001 /* [8] Overflow */
|
||||
#define CONFIG_CRF 0x8000 /* [7] Conversion Ready Field */
|
||||
#define CONFIG_FH 0x4000 /* [6] Flag High */
|
||||
#define CONFIG_FL 0x2000 /* [5] Flag Low */
|
||||
#define CONFIG_L 0x1000 /* [4] Latch */
|
||||
#define CONFIG_POL 0x0800 /* [3] Polarity */
|
||||
#define CONFIG_ME 0x0400 /* [2] Mask Exponent */
|
||||
#define CONFIG_FC 0x0300 /* [1..0] Fault Count */
|
||||
|
||||
/* Possible Values for CT */
|
||||
#define CONFIG_CT_100 0x0000
|
||||
#define CONFIG_CT_800 CONFIG_CT
|
||||
|
||||
/* Possible Values for M */
|
||||
#define CONFIG_M_CONTI 0x0004
|
||||
#define CONFIG_M_SINGLE 0x0002
|
||||
#define CONFIG_M_SHUTDOWN 0x0000
|
||||
|
||||
/* Reset Value for the register 0xC810. All zeros except: */
|
||||
#define CONFIG_RN_RESET 0x00C0
|
||||
#define CONFIG_CT_RESET CONFIG_CT_800
|
||||
#define CONFIG_L_RESET 0x1000
|
||||
#define CONFIG_DEFAULTS (CONFIG_RN_RESET | CONFIG_CT_100 | CONFIG_L_RESET)
|
||||
|
||||
/* Enable / Disable */
|
||||
#define CONFIG_ENABLE_CONTINUOUS (CONFIG_M_CONTI | CONFIG_DEFAULTS)
|
||||
#define CONFIG_ENABLE_SINGLE_SHOT (CONFIG_M_SINGLE | CONFIG_DEFAULTS)
|
||||
#define CONFIG_DISABLE CONFIG_DEFAULTS
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Register length */
|
||||
#define REGISTER_LENGTH 2
|
||||
|
@ -86,24 +112,22 @@
|
|||
/* Sensor data size */
|
||||
#define DATA_LENGTH 2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define SENSOR_STATUS_DISABLED 0
|
||||
#define SENSOR_STATUS_NOT_READY 1
|
||||
#define SENSOR_STATUS_ENABLED 2
|
||||
/*
|
||||
* SENSOR_STATE_SLEEPING and SENSOR_STATE_ACTIVE are mutually exclusive.
|
||||
* SENSOR_STATE_DATA_READY can be ORd with both of the above. For example the
|
||||
* sensor may be sleeping but with a conversion ready to read out.
|
||||
*/
|
||||
#define SENSOR_STATE_SLEEPING 0
|
||||
#define SENSOR_STATE_ACTIVE 1
|
||||
#define SENSOR_STATE_DATA_READY 2
|
||||
|
||||
static int enabled = SENSOR_STATUS_DISABLED;
|
||||
static int state = SENSOR_STATE_SLEEPING;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Wait SENSOR_STARTUP_DELAY for the sensor to be ready - 125ms */
|
||||
#define SENSOR_STARTUP_DELAY (CLOCK_SECOND >> 3)
|
||||
|
||||
static struct ctimer startup_timer;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
notify_ready(void *not_used)
|
||||
{
|
||||
enabled = SENSOR_STATUS_ENABLED;
|
||||
sensors_changed(&opt_3001_sensor);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Select the sensor on the I2C bus
|
||||
*/
|
||||
|
@ -114,6 +138,28 @@ select(void)
|
|||
board_i2c_select(BOARD_I2C_INTERFACE_0, OPT3001_I2C_ADDRESS);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
notify_ready(void *not_used)
|
||||
{
|
||||
/*
|
||||
* Depending on the CONFIGURATION.CONVERSION_TIME bits, a conversion will
|
||||
* take either 100 or 800 ms. Here we inspect the CONVERSION_READY bit and
|
||||
* if the reading is ready we notify, otherwise we just reschedule ourselves
|
||||
*/
|
||||
uint16_t val;
|
||||
|
||||
select();
|
||||
|
||||
sensor_common_read_reg(REG_CONFIGURATION, (uint8_t *)&val, REGISTER_LENGTH);
|
||||
|
||||
if(val & CONFIG_CRF) {
|
||||
sensors_changed(&opt_3001_sensor);
|
||||
state = SENSOR_STATE_DATA_READY;
|
||||
} else {
|
||||
ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Turn the sensor on/off
|
||||
* \param enable TRUE: on, FALSE: off
|
||||
|
@ -122,13 +168,20 @@ static void
|
|||
enable_sensor(bool enable)
|
||||
{
|
||||
uint16_t val;
|
||||
uint16_t had_data_ready = state & SENSOR_STATE_DATA_READY;
|
||||
|
||||
select();
|
||||
|
||||
if(enable) {
|
||||
val = CONFIG_ENABLE;
|
||||
val = CONFIG_ENABLE_SINGLE_SHOT;
|
||||
|
||||
/* Writing CONFIG_ENABLE_SINGLE_SHOT to M bits will clear CRF bits */
|
||||
state = SENSOR_STATE_ACTIVE;
|
||||
} else {
|
||||
val = CONFIG_DISABLE;
|
||||
|
||||
/* Writing CONFIG_DISABLE to M bits will not clear CRF bits */
|
||||
state = SENSOR_STATE_SLEEPING | had_data_ready;
|
||||
}
|
||||
|
||||
sensor_common_write_reg(REG_CONFIGURATION, (uint8_t *)&val, REGISTER_LENGTH);
|
||||
|
@ -145,15 +198,15 @@ read_data(uint16_t *raw_data)
|
|||
bool success;
|
||||
uint16_t val;
|
||||
|
||||
if((state & SENSOR_STATE_DATA_READY) != SENSOR_STATE_DATA_READY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
select();
|
||||
|
||||
success = sensor_common_read_reg(REG_CONFIGURATION, (uint8_t *)&val,
|
||||
REGISTER_LENGTH);
|
||||
|
||||
if(success) {
|
||||
success = (val & DATA_RDY_BIT) == DATA_RDY_BIT;
|
||||
}
|
||||
|
||||
if(success) {
|
||||
success = sensor_common_read_reg(REG_RESULT, (uint8_t *)&val, DATA_LENGTH);
|
||||
}
|
||||
|
@ -196,14 +249,9 @@ value(int type)
|
|||
uint16_t raw_val;
|
||||
float converted_val;
|
||||
|
||||
if(enabled != SENSOR_STATUS_ENABLED) {
|
||||
PRINTF("Sensor disabled or starting up (%d)\n", enabled);
|
||||
return CC26XX_SENSOR_READING_ERROR;
|
||||
}
|
||||
|
||||
rv = read_data(&raw_val);
|
||||
|
||||
if(rv == 0) {
|
||||
if(rv == false) {
|
||||
return CC26XX_SENSOR_READING_ERROR;
|
||||
}
|
||||
|
||||
|
@ -229,30 +277,38 @@ value(int type)
|
|||
static int
|
||||
configure(int type, int enable)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
switch(type) {
|
||||
case SENSORS_HW_INIT:
|
||||
/*
|
||||
* Device reset won't reset the sensor, so we put it to sleep here
|
||||
* explicitly
|
||||
*/
|
||||
enable_sensor(0);
|
||||
rv = 0;
|
||||
break;
|
||||
case SENSORS_ACTIVE:
|
||||
if(enable) {
|
||||
enable_sensor(1);
|
||||
ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL);
|
||||
enabled = SENSOR_STATUS_NOT_READY;
|
||||
rv = 1;
|
||||
} else {
|
||||
ctimer_stop(&startup_timer);
|
||||
enable_sensor(0);
|
||||
enabled = SENSOR_STATUS_DISABLED;
|
||||
rv = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return enabled;
|
||||
return rv;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Returns the status of the sensor
|
||||
* \param type SENSORS_ACTIVE or SENSORS_READY
|
||||
* \return 1 if the sensor is enabled
|
||||
* \param type ignored
|
||||
* \return The state of the sensor SENSOR_STATE_xyz
|
||||
*/
|
||||
static int
|
||||
status(int type)
|
||||
|
@ -260,12 +316,10 @@ status(int type)
|
|||
switch(type) {
|
||||
case SENSORS_ACTIVE:
|
||||
case SENSORS_READY:
|
||||
return enabled;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SENSOR_STATUS_DISABLED;
|
||||
return state;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
SENSORS_SENSOR(opt_3001_sensor, "OPT3001", value, configure, status);
|
||||
|
|
|
@ -40,14 +40,16 @@
|
|||
* sequence, but the call will not wait for it to complete so that the CPU can
|
||||
* perform other tasks or drop to a low power mode.
|
||||
*
|
||||
* Once the sensor is stable, the driver will generate a sensors_changed event.
|
||||
* Once the reading and conversion are complete, the driver will generate a
|
||||
* sensors_changed event.
|
||||
*
|
||||
* Once a reading has been taken, the caller has two options:
|
||||
* - Turn the sensor off by calling SENSORS_DEACTIVATE, but in order to take
|
||||
* subsequent readings SENSORS_ACTIVATE must be called again
|
||||
* - Leave the sensor on. In this scenario, the caller can simply keep calling
|
||||
* value() for subsequent readings, but having the sensor on will consume
|
||||
* energy
|
||||
* We use single-shot readings. In this mode, the hardware automatically goes
|
||||
* back to its shutdown mode after the conversion is finished. However, it will
|
||||
* still respond to I2C operations, so the last conversion can still be read
|
||||
* out.
|
||||
*
|
||||
* In order to take a new reading, the caller has to use SENSORS_ACTIVATE
|
||||
* again.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
#define SWAP(v) ((LO_UINT16(v) << 8) | HI_UINT16(v))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define SELECT() board_i2c_select(BOARD_I2C_INTERFACE_0, SENSOR_I2C_ADDRESS);
|
||||
#define SELECT() board_i2c_select(BOARD_I2C_INTERFACE_0, SENSOR_I2C_ADDRESS)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t buf[DATA_SIZE];
|
||||
static uint16_t val;
|
||||
|
@ -124,7 +124,7 @@ enable_sensor(bool enable)
|
|||
{
|
||||
bool success;
|
||||
|
||||
SELECT()
|
||||
SELECT();
|
||||
|
||||
if(enable) {
|
||||
val = TMP007_VAL_CONFIG_ON;
|
||||
|
@ -267,6 +267,10 @@ configure(int type, int enable)
|
|||
{
|
||||
switch(type) {
|
||||
case SENSORS_HW_INIT:
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_TMP_RDY);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_TMP_RDY, IOC_IOPULL_UP);
|
||||
ti_lib_ioc_io_hyst_set(BOARD_IOID_TMP_RDY, IOC_HYST_ENABLE);
|
||||
|
||||
enable_sensor(false);
|
||||
enabled = SENSOR_STATUS_INITIALISED;
|
||||
break;
|
||||
|
|
|
@ -45,95 +45,65 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define PRCM_DOMAINS (PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL | \
|
||||
PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU | \
|
||||
PRCM_DOMAIN_SYSBUS | PRCM_DOMAIN_VIMS)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define LPM_DOMAINS (PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
power_domains_on(void)
|
||||
wakeup_handler(void)
|
||||
{
|
||||
/* Turn on relevant power domains */
|
||||
ti_lib_prcm_power_domain_on(LPM_DOMAINS);
|
||||
|
||||
/* Wait for domains to power on */
|
||||
while((ti_lib_prcm_power_domain_status(LPM_DOMAINS)
|
||||
/* Turn on the PERIPH PD */
|
||||
ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH);
|
||||
while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH)
|
||||
!= PRCM_DOMAIN_POWER_ON));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
lpm_wakeup_handler(void)
|
||||
{
|
||||
power_domains_on();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Declare a data structure to register with LPM.
|
||||
* We don't care about what power mode we'll drop to, we don't care about
|
||||
* getting notified before deep sleep. All we need is to be notified when we
|
||||
* wake up so we can turn power domains back on
|
||||
*/
|
||||
LPM_MODULE(srf_module, NULL, NULL, lpm_wakeup_handler);
|
||||
LPM_MODULE(srf_module, NULL, NULL, wakeup_handler, LPM_DOMAIN_NONE);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
board_init()
|
||||
static void
|
||||
configure_unused_pins(void)
|
||||
{
|
||||
uint8_t int_disabled = ti_lib_int_master_disable();
|
||||
|
||||
/* Turn on all power domains */
|
||||
ti_lib_prcm_power_domain_on(PRCM_DOMAINS);
|
||||
|
||||
/* Wait for power on domains */
|
||||
while((ti_lib_prcm_power_domain_status(PRCM_DOMAINS)
|
||||
!= PRCM_DOMAIN_POWER_ON));
|
||||
|
||||
/* Configure all clock domains to run at full speed */
|
||||
ti_lib_prcm_clock_configure_set(PRCM_DOMAIN_SYSBUS | PRCM_DOMAIN_CPU |
|
||||
PRCM_DOMAIN_CPU | PRCM_DOMAIN_TIMER |
|
||||
PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH,
|
||||
PRCM_CLOCK_DIV_1);
|
||||
|
||||
/* Enable GPIO peripheral */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO);
|
||||
|
||||
/* Apply settings and wait for them to take effect */
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get()) ;
|
||||
|
||||
/* Keys (input pullup) */
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_KEY_UP);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_KEY_DOWN);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_KEY_LEFT);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_KEY_RIGHT);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_KEY_SELECT);
|
||||
|
||||
/* Turn off 3.3V domain (Powers the LCD and SD card reader): Output, low */
|
||||
/* Turn off 3.3-V domain (lcd/sdcard power, output low) */
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_3V3_EN);
|
||||
ti_lib_gpio_pin_write(BOARD_3V3_EN, 0);
|
||||
|
||||
/* LCD CSn (output high) */
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_LCD_CS);
|
||||
ti_lib_gpio_pin_write(BOARD_LCD_CS, 1);
|
||||
|
||||
/* SD Card reader CSn (output high) */
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_SDCARD_CS);
|
||||
ti_lib_gpio_pin_write(BOARD_SDCARD_CS, 1);
|
||||
|
||||
/* Accelerometer (PWR output low, CSn output high) */
|
||||
/* Accelerometer (PWR output low, CSn output, high) */
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ACC_PWR);
|
||||
ti_lib_gpio_pin_write(BOARD_ACC_PWR, 0);
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ACC_CS);
|
||||
ti_lib_gpio_pin_write(BOARD_IOID_ACC_CS, 1);
|
||||
|
||||
/* Ambient light sensor (off, output low) */
|
||||
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR);
|
||||
ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0);
|
||||
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_ALS_OUT);
|
||||
ti_lib_ioc_io_port_pull_set(BOARD_IOID_ALS_OUT, IOC_NO_IOPULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
board_init()
|
||||
{
|
||||
uint8_t int_disabled = ti_lib_int_master_disable();
|
||||
|
||||
/* Turn on relevant PDs */
|
||||
wakeup_handler();
|
||||
|
||||
/* Configure all clock domains to run at full speed */
|
||||
ti_lib_prcm_clock_configure_set(PRCM_DOMAIN_SYSBUS | PRCM_DOMAIN_CPU |
|
||||
PRCM_DOMAIN_TIMER | PRCM_DOMAIN_SERIAL |
|
||||
PRCM_DOMAIN_PERIPH, PRCM_CLOCK_DIV_1);
|
||||
|
||||
/* Enable GPIO peripheral */
|
||||
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO);
|
||||
|
||||
/* Apply settings and wait for them to take effect */
|
||||
ti_lib_prcm_load_set();
|
||||
while(!ti_lib_prcm_load_get());
|
||||
|
||||
lpm_register_module(&srf_module);
|
||||
|
||||
configure_unused_pins();
|
||||
|
||||
/* Re-enable interrupt if initially enabled. */
|
||||
if(!int_disabled) {
|
||||
ti_lib_int_master_enable();
|
||||
|
|
|
@ -107,8 +107,8 @@
|
|||
*/
|
||||
#define BOARD_IOID_UART_RX IOID_2
|
||||
#define BOARD_IOID_UART_TX IOID_3
|
||||
#define BOARD_IOID_UART_CTS IOID_0
|
||||
#define BOARD_IOID_UART_RTS IOID_21
|
||||
#define BOARD_IOID_UART_CTS IOID_UNUSED
|
||||
#define BOARD_IOID_UART_RTS IOID_UNUSED
|
||||
#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX)
|
||||
#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX)
|
||||
#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS)
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
#define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \
|
||||
IOC_IOPULL_UP | IOC_SLEW_DISABLE | \
|
||||
IOC_HYST_DISABLE | IOC_BOTH_EDGES | \
|
||||
IOC_HYST_ENABLE | IOC_BOTH_EDGES | \
|
||||
IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \
|
||||
IOC_NO_WAKE_UP | IOC_INPUT_ENABLE | \
|
||||
IOC_JTAG_DISABLE)
|
||||
|
@ -137,7 +137,7 @@ button_press_handler(uint8_t ioid)
|
|||
sensors_changed(&button_right_sensor);
|
||||
}
|
||||
} else {
|
||||
lpm_shutdown(BOARD_IOID_KEY_RIGHT);
|
||||
lpm_shutdown(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP, IOC_WAKE_ON_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
72
regression-tests/20-compile-tools/Makefile
Normal file
72
regression-tests/20-compile-tools/Makefile
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Copyright (c) 2014, Friedrich-Alexander University Erlangen-Nuremberg
|
||||
# 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 University 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 UNIVERSITY 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 INSTITUTE 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.
|
||||
|
||||
TOOLS=sky tools stm32w z80=hex2bin sensinode=nano_programmer
|
||||
FAILTOOLS=stm32w=uip6_bridge sky=uip6-bridge sensinode=nano_usb_programmer
|
||||
|
||||
|
||||
TOOLSDIR=../../tools
|
||||
LOGS=$(patsubst %,%.log, $(TOOLS))
|
||||
|
||||
all: summary
|
||||
|
||||
FRC:
|
||||
|
||||
|
||||
sky.log: RMFILES=serialdump-linux
|
||||
stm32w.log: RMFILES=serialdump-linux
|
||||
|
||||
|
||||
tools.log:
|
||||
@$(MAKE) -C $(TOOLSDIR) > $@ 2>&1 && $(RM) $@.failed || touch $@.failed
|
||||
|
||||
|
||||
%.log: FRC
|
||||
@( cd $(TOOLSDIR)/$(subst =,/,$*) && $(RM) $(RMFILES) )
|
||||
@touch $@
|
||||
@$(MAKE) -C $(TOOLSDIR)/$(subst =,/,$*) > $@ 2>&1 && $(RM) $@.failed || touch $@.failed
|
||||
|
||||
|
||||
summary: $(LOGS)
|
||||
@(\
|
||||
for T in $(TOOLS) ; do \
|
||||
if [ -f $$T.log.failed ] ; then \
|
||||
echo tools/$$T: FAIL ಠ_ಠ >> $@;\
|
||||
cat $$T.log >> $@;\
|
||||
else \
|
||||
echo tools/$$T: OK >> $@;\
|
||||
fi\
|
||||
done \
|
||||
)
|
||||
@echo "Info: The following tools need fixing and are not tested:" $(subst =,/,$(FAILTOOLS)) >> $@
|
||||
@echo $@
|
||||
|
||||
clean:
|
||||
@make -C $(DOCDIR) clean
|
||||
|
||||
|
||||
.PHONY: %.log
|
|
@ -1,4 +1,4 @@
|
|||
all: codeprop tunslip
|
||||
all: tunslip
|
||||
|
||||
gitclean:
|
||||
@git clean -d -x -n ..
|
||||
|
@ -20,4 +20,4 @@ cleantargets:
|
|||
@rm -f -v ${addprefix ../examples/*/*., ${shell ls ../platform/}}
|
||||
@rm -f -v ${addprefix ../examples/*/*/*., ${shell ls ../platform/}}
|
||||
cleandone:
|
||||
@echo ${info All done!}
|
||||
@echo ${info All done!}
|
||||
|
|
|
@ -169,6 +169,7 @@ public class MRM extends AbstractRadioMedium {
|
|||
if (sender.getChannel() >= 0 &&
|
||||
recv.getChannel() >= 0 &&
|
||||
sender.getChannel() != recv.getChannel()) {
|
||||
newConnection.addInterfered(recv);
|
||||
continue;
|
||||
}
|
||||
final Radio recvFinal = recv;
|
||||
|
@ -313,15 +314,15 @@ public class MRM extends AbstractRadioMedium {
|
|||
/* Interfering/colliding radio connections */
|
||||
for (RadioConnection conn : conns) {
|
||||
for (Radio intfRadio : ((MRMRadioConnection) conn).getInterfered()) {
|
||||
double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio);
|
||||
if (intfRadio.getCurrentSignalStrength() < signalStrength) {
|
||||
intfRadio.setCurrentSignalStrength(signalStrength);
|
||||
}
|
||||
if (conn.getSource().getChannel() >= 0 &&
|
||||
intfRadio.getChannel() >= 0 &&
|
||||
conn.getSource().getChannel() != intfRadio.getChannel()) {
|
||||
continue;
|
||||
}
|
||||
double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio);
|
||||
if (intfRadio.getCurrentSignalStrength() < signalStrength) {
|
||||
intfRadio.setCurrentSignalStrength(signalStrength);
|
||||
}
|
||||
|
||||
if (!intfRadio.isInterfered()) {
|
||||
/*logger.warn("Radio was not interfered: " + intfRadio);*/
|
||||
|
|
|
@ -236,8 +236,9 @@ public abstract class AbstractRadioMedium extends RadioMedium {
|
|||
case RECEPTION_STARTED:
|
||||
case RECEPTION_INTERFERED:
|
||||
case RECEPTION_FINISHED:
|
||||
break;
|
||||
|
||||
case UNKNOWN:
|
||||
return;
|
||||
case HW_ON: {
|
||||
/* Update signal strengths */
|
||||
updateSignalStrengths();
|
||||
|
@ -292,7 +293,7 @@ public abstract class AbstractRadioMedium extends RadioMedium {
|
|||
break;
|
||||
case TRANSMISSION_FINISHED: {
|
||||
/* Remove radio connection */
|
||||
|
||||
|
||||
/* Connection */
|
||||
RadioConnection connection = getActiveConnectionFrom(radio);
|
||||
if (connection == null) {
|
||||
|
@ -322,7 +323,10 @@ public abstract class AbstractRadioMedium extends RadioMedium {
|
|||
COUNTER_RX += connection.getDestinations().length;
|
||||
COUNTER_INTERFERED += connection.getInterfered().length;
|
||||
for (Radio intRadio : connection.getInterferedNonDestinations()) {
|
||||
intRadio.signalReceptionEnd();
|
||||
|
||||
if (intRadio.isInterfered()) {
|
||||
intRadio.signalReceptionEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/* Update signal strengths */
|
||||
|
|
|
@ -42,6 +42,7 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
|||
public double signal = AbstractRadioMedium.SS_STRONG; /* RSSI */
|
||||
public long delay = 0; /* EXPERIMENTAL: Propagation delay (us). */
|
||||
public int lqi = 105;
|
||||
public int channel = -1; /* not set by default */
|
||||
|
||||
public DGRMDestinationRadio() {
|
||||
super();
|
||||
|
@ -50,12 +51,17 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
|||
super(dest);
|
||||
}
|
||||
|
||||
public int getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
DGRMDestinationRadio clone = new DGRMDestinationRadio(this.radio);
|
||||
clone.ratio = this.ratio;
|
||||
clone.delay = this.delay;
|
||||
clone.signal = this.signal;
|
||||
clone.lqi = this.lqi;
|
||||
clone.channel = this.channel;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
@ -75,10 +81,13 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
|||
element.setText("" + lqi);
|
||||
config.add(element);
|
||||
|
||||
|
||||
element = new Element("delay");
|
||||
element.setText("" + delay);
|
||||
config.add(element);
|
||||
|
||||
element = new Element("channel");
|
||||
element.setText("" + channel);
|
||||
config.add(element);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
@ -96,6 +105,8 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
|||
lqi = Integer.parseInt(element.getText());
|
||||
} else if (element.getName().equals("delay")) {
|
||||
delay = Long.parseLong(element.getText());
|
||||
} else if (element.getName().equals("channel")) {
|
||||
channel = Integer.parseInt(element.getText());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -166,6 +166,19 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
|||
DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource());
|
||||
if (dstRadios == null) continue;
|
||||
for (DGRMDestinationRadio dstRadio : dstRadios) {
|
||||
|
||||
int activeSourceChannel = conn.getSource().getChannel();
|
||||
int edgeChannel = dstRadio.channel;
|
||||
int activeDstChannel = dstRadio.radio.getChannel();
|
||||
if (activeSourceChannel != -1) {
|
||||
if (edgeChannel != -1 && activeSourceChannel != edgeChannel) {
|
||||
continue;
|
||||
}
|
||||
if (activeDstChannel != -1 && activeSourceChannel != activeDstChannel) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (dstRadio.radio.getCurrentSignalStrength() < dstRadio.signal) {
|
||||
dstRadio.radio.setCurrentSignalStrength(dstRadio.signal);
|
||||
}
|
||||
|
@ -247,13 +260,27 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
|||
|
||||
/*logger.info(source + ": " + destinations.length + " potential destinations");*/
|
||||
for (DGRMDestinationRadio dest: destinations) {
|
||||
|
||||
|
||||
if (dest.radio == source) {
|
||||
/* Fail: cannot receive our own transmission */
|
||||
/*logger.info(source + ": Fail, receiver is sender");*/
|
||||
continue;
|
||||
}
|
||||
|
||||
int srcc = source.getChannel();
|
||||
int dstc = dest.radio.getChannel();
|
||||
int edgeChannel = dest.getChannel();
|
||||
|
||||
if (edgeChannel >= 0 && dstc >= 0 && edgeChannel != dstc) {
|
||||
/* Fail: the edge is configured for a different radio channel */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (srcc >= 0 && dstc >= 0 && srcc != dstc) {
|
||||
/* Fail: radios are on different (but configured) channels */
|
||||
newConn.addInterfered(dest.radio);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dest.radio.isRadioOn()) {
|
||||
/* Fail: radio is off */
|
||||
|
@ -268,14 +295,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
|||
newConn.addInterfered(dest.radio);
|
||||
continue;
|
||||
}
|
||||
|
||||
int srcc = source.getChannel();
|
||||
int dstc = dest.radio.getChannel();
|
||||
if ( srcc >= 0 && dstc >= 0 && srcc != dstc) {
|
||||
/* Fail: radios are on different (but configured) channels */
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (dest.radio.isReceiving()) {
|
||||
/* Fail: radio is already actively receiving */
|
||||
/*logger.info(source + ": Fail, receiving");*/
|
||||
|
|
|
@ -192,6 +192,13 @@ public class UDGM extends AbstractRadioMedium {
|
|||
if (sender.getChannel() >= 0 &&
|
||||
recv.getChannel() >= 0 &&
|
||||
sender.getChannel() != recv.getChannel()) {
|
||||
|
||||
/* Add the connection in a dormant state;
|
||||
it will be activated later when the radio will be
|
||||
turned on and switched to the right channel. This behavior
|
||||
is consistent with the case when receiver is turned off. */
|
||||
newConnection.addInterfered(recv);
|
||||
|
||||
continue;
|
||||
}
|
||||
Position recvPos = recv.getPosition();
|
||||
|
|
25
tools/stm32w/Makefile
Normal file
25
tools/stm32w/Makefile
Normal file
|
@ -0,0 +1,25 @@
|
|||
ifndef HOST_OS
|
||||
ifeq ($(OS),Windows_NT)
|
||||
HOST_OS := Windows
|
||||
else
|
||||
HOST_OS := $(shell uname)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS),Windows)
|
||||
SERIALDUMP = serialdump-windows
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
SERIALDUMP = serialdump-macos
|
||||
endif
|
||||
|
||||
ifndef SERIALDUMP
|
||||
# Assume Linux
|
||||
SERIALDUMP = serialdump-linux
|
||||
endif
|
||||
|
||||
all: $(SERIALDUMP)
|
||||
|
||||
$(SERIALDUMP): serialdump.c
|
||||
$(CC) -O2 -o $@ $<
|
Loading…
Reference in a new issue