Merge branch 'master' into osd

Conflicts:
	examples/osd/triggerbaord/sketch.pde
This commit is contained in:
Harald Pichler 2016-10-26 17:03:37 +02:00
commit e6dbb8c3f2
246 changed files with 6885 additions and 2878 deletions

6
.gitmodules vendored
View file

@ -6,10 +6,10 @@
url = https://github.com/JelmerT/cc2538-bsl.git
[submodule "cpu/cc26xx-cc13xx/lib/cc26xxware"]
path = cpu/cc26xx-cc13xx/lib/cc26xxware
url = https://github.com/g-oikonomou/cc26xxware.git
url = https://github.com/contiki-os/cc26xxware.git
[submodule "cpu/cc26xx-cc13xx/lib/cc13xxware"]
path = cpu/cc26xx-c../.gitmodulesc13xx/lib/cc13xxware
url = https://github.com/g-oikonomou/cc13xxware.git
path = cpu/cc26xx-cc13xx/lib/cc13xxware
url = https://github.com/contiki-os/cc13xxware.git
[submodule "platform/stm32nucleo-spirit1/stm32cube-lib"]
path = platform/stm32nucleo-spirit1/stm32cube-lib
url = https://github.com/STclab/stm32nucleo-spirit1-lib

View file

@ -56,6 +56,7 @@
#include "adc.h"
#include "hw-arduino.h"
#include "contiki.h"
#include "net/netstack.h"
#define DEBUG 0
#if DEBUG
@ -110,20 +111,26 @@ PROCESS(arduino_sketch, "Arduino Sketch Wrapper");
#define LOOP_INTERVAL (1 * CLOCK_SECOND)
#endif
#ifndef SLEEP_NETWORK_INTERVAL
#define SLEEP_NETWORK_INTERVAL (60 * CLOCK_SECOND)
#endif
PROCESS_THREAD(arduino_sketch, ev, data)
{
static struct etimer loop_periodic_timer;
static struct etimer network_off_periodic_timer;
PROCESS_BEGIN();
adc_init ();
mcu_sleep_init ();
setup ();
/* Define application-specific events here. */
etimer_set(&loop_periodic_timer, LOOP_INTERVAL);
etimer_set(&network_off_periodic_timer, SLEEP_NETWORK_INTERVAL);
while (1) {
PROCESS_WAIT_EVENT();
#if PLATFORM_HAS_BUTTON
if(ev == sensors_event && data == &button_sensor) {
NETSTACK_MAC.off(1);
mcu_sleep_off();
PRINTF("*******BUTTON*******\n");
@ -136,6 +143,11 @@ PROCESS_THREAD(arduino_sketch, ev, data)
}
#endif /* PLATFORM_HAS_BUTTON */
if(etimer_expired(&network_off_periodic_timer)) {
// NETSTACK_MAC.off(0);
NETSTACK_MAC.on();
etimer_reset(&network_off_periodic_timer);
}
if(etimer_expired(&loop_periodic_timer)) {
mcu_sleep_off();
loop ();

View file

@ -587,6 +587,40 @@ get_resource(const lwm2m_instance_t *instance, lwm2m_context_t *context)
return NULL;
}
/*---------------------------------------------------------------------------*/
/**
* @brief Write a list of object instances as a CoRE Link-format list
*/
static int
write_object_instances_link(const lwm2m_object_t *object,
char *buffer, size_t size)
{
const lwm2m_instance_t *instance;
int len, rdlen, i;
PRINTF("</%d>", object->id);
rdlen = snprintf(buffer, size, "</%d>",
object->id);
if(rdlen < 0 || rdlen >= size) {
return -1;
}
for(i = 0; i < object->count; i++) {
if((object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) == 0) {
continue;
}
instance = &object->instances[i];
PRINTF(",</%d/%d>", object->id, instance->id);
len = snprintf(&buffer[rdlen], size - rdlen,
",<%d/%d>", object->id, instance->id);
rdlen += len;
if(len < 0 || rdlen >= size) {
return -1;
}
}
return rdlen;
}
/*---------------------------------------------------------------------------*/
static int
write_rd_link_data(const lwm2m_object_t *object,
const lwm2m_instance_t *instance,
@ -1052,6 +1086,23 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
REST.set_header_content_type(response, LWM2M_JSON);
}
}
} else if(depth == 1) {
/* produce a list of instances */
if(method != METHOD_GET) {
REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05);
} else {
int rdlen;
PRINTF("Sending instance list for object %u\n", object->id);
/* TODO: if(accept == APPLICATION_LINK_FORMAT) { */
rdlen = write_object_instances_link(object, (char *)buffer, preferred_size);
if(rdlen < 0) {
PRINTF("Failed to generate object response\n");
REST.set_response_status(response, SERVICE_UNAVAILABLE_5_03);
return;
}
REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT);
REST.set_response_payload(response, buffer, rdlen);
}
}
}
/*---------------------------------------------------------------------------*/

View file

@ -155,10 +155,13 @@ make_tcp_stats(void *arg)
{
struct uip_conn *conn;
struct httpd_state *s = (struct httpd_state *)arg;
#if NETSTACK_CONF_WITH_IPV6
char buf[48];
#endif
conn = &uip_conns[s->u.count];
#if NETSTACK_CONF_WITH_IPV6
char buf[48];
httpd_sprint_ip6(conn->ripaddr, buf);
return snprintf((char *)uip_appdata, uip_mss(),
"<tr align=\"center\"><td>%d</td><td>%s:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n",

View file

@ -81,7 +81,7 @@ enum {
*/
static uint8_t state = STATE_TWOPACKETS;
static uint16_t begin, end;
static uint16_t begin, next_free;
static uint8_t rxbuf[RX_BUFSIZE];
static uint16_t pkt_end; /* SLIP_END tracker. */
@ -153,7 +153,7 @@ slip_write(const void *_ptr, int len)
static void
rxbuf_init(void)
{
begin = end = pkt_end = 0;
begin = next_free = pkt_end = 0;
state = STATE_OK;
}
/*---------------------------------------------------------------------------*/
@ -164,7 +164,7 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
/* This is a hack and won't work across buffer edge! */
if(rxbuf[begin] == 'C') {
int i;
if(begin < end && (end - begin) >= 6
if(begin < next_free && (next_free - begin) >= 6
&& memcmp(&rxbuf[begin], "CLIENT", 6) == 0) {
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
memset(&rxbuf[begin], 0x0, 6);
@ -182,7 +182,7 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
/* Used by tapslip6 to request mac for auto configure */
int i, j;
char* hexchar = "0123456789abcdef";
if(begin < end && (end - begin) >= 2
if(begin < next_free && (next_free - begin) >= 2
&& rxbuf[begin + 1] == 'M') {
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
rxbuf[begin] = 0;
@ -210,37 +210,109 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
*/
if(begin != pkt_end) {
uint16_t len;
uint16_t cur_next_free;
uint16_t cur_ptr;
int esc = 0;
if(begin < pkt_end) {
len = pkt_end - begin;
uint16_t i;
len = 0;
for(i = begin; i < pkt_end; ++i) {
if(len > blen) {
len = 0;
break;
}
if (esc) {
if(rxbuf[i] == SLIP_ESC_ESC) {
outbuf[len] = SLIP_ESC;
len++;
} else if(rxbuf[i] == SLIP_ESC_END) {
outbuf[len] = SLIP_END;
len++;
}
esc = 0;
} else if(rxbuf[i] == SLIP_ESC) {
esc = 1;
} else {
memcpy(outbuf, &rxbuf[begin], len);
outbuf[len] = rxbuf[i];
len++;
}
}
} else {
len = (RX_BUFSIZE - begin) + (pkt_end - 0);
uint16_t i;
len = 0;
for(i = begin; i < RX_BUFSIZE; ++i) {
if(len > blen) {
len = 0;
} else {
unsigned i;
for(i = begin; i < RX_BUFSIZE; i++) {
*outbuf++ = rxbuf[i];
break;
}
for(i = 0; i < pkt_end; i++) {
*outbuf++ = rxbuf[i];
if (esc) {
if(rxbuf[i] == SLIP_ESC_ESC) {
outbuf[len] = SLIP_ESC;
len++;
} else if(rxbuf[i] == SLIP_ESC_END) {
outbuf[len] = SLIP_END;
len++;
}
esc = 0;
} else if(rxbuf[i] == SLIP_ESC) {
esc = 1;
} else {
outbuf[len] = rxbuf[i];
len++;
}
}
for(i = 0; i < pkt_end; ++i) {
if(len > blen) {
len = 0;
break;
}
if (esc) {
if(rxbuf[i] == SLIP_ESC_ESC) {
outbuf[len] = SLIP_ESC;
len++;
} else if(rxbuf[i] == SLIP_ESC_END) {
outbuf[len] = SLIP_END;
len++;
}
esc = 0;
} else if(rxbuf[i] == SLIP_ESC) {
esc = 1;
} else {
outbuf[len] = rxbuf[i];
len++;
}
}
}
/* Remove data from buffer together with the copied packet. */
begin = pkt_end;
if(state == STATE_TWOPACKETS) {
pkt_end = end;
state = STATE_OK; /* Assume no bytes where lost! */
pkt_end = pkt_end + 1;
if(pkt_end == RX_BUFSIZE) {
pkt_end = 0;
}
if(pkt_end != next_free) {
cur_next_free = next_free;
cur_ptr = pkt_end;
while(cur_ptr != cur_next_free) {
if(rxbuf[cur_ptr] == SLIP_END) {
uint16_t tmp_begin = pkt_end;
pkt_end = cur_ptr;
begin = tmp_begin;
/* One more packet is buffered, need to be polled again! */
process_poll(&slip_process);
break;
}
cur_ptr++;
if(cur_ptr == RX_BUFSIZE) {
cur_ptr = 0;
}
}
if(cur_ptr == cur_next_free) {
/* no more pending full packet found */
begin = pkt_end;
}
} else {
begin = pkt_end;
}
return len;
}
@ -316,6 +388,7 @@ PROCESS_THREAD(slip_process, ev, data)
int
slip_input_byte(unsigned char c)
{
uint16_t cur_end;
switch(state) {
case STATE_RUBBISH:
if(c == SLIP_END) {
@ -323,64 +396,34 @@ slip_input_byte(unsigned char c)
}
return 0;
case STATE_TWOPACKETS: /* Two packets are already buffered! */
return 0;
case STATE_ESC:
if(c == SLIP_ESC_END) {
c = SLIP_END;
} else if(c == SLIP_ESC_ESC) {
c = SLIP_ESC;
} else {
if(c != SLIP_ESC_END && c != SLIP_ESC_ESC) {
state = STATE_RUBBISH;
SLIP_STATISTICS(slip_rubbish++);
end = pkt_end; /* remove rubbish */
next_free = pkt_end; /* remove rubbish */
return 0;
}
state = STATE_OK;
break;
}
case STATE_OK:
if(c == SLIP_ESC) {
state = STATE_ESC;
return 0;
} else if(c == SLIP_END) {
/*
* We have a new packet, possibly of zero length.
*
* There may already be one packet buffered.
*/
if(end != pkt_end) { /* Non zero length. */
if(begin == pkt_end) { /* None buffered. */
pkt_end = end;
} else {
state = STATE_TWOPACKETS;
SLIP_STATISTICS(slip_twopackets++);
}
process_poll(&slip_process);
return 1;
}
return 0;
}
break;
}
/* add_char: */
{
unsigned next;
next = end + 1;
if(next == RX_BUFSIZE) {
next = 0;
cur_end = next_free;
next_free = next_free + 1;
if(next_free == RX_BUFSIZE) {
next_free = 0;
}
if(next == begin) { /* rxbuf is full */
if(next_free == begin) { /* rxbuf is full */
state = STATE_RUBBISH;
SLIP_STATISTICS(slip_overflow++);
end = pkt_end; /* remove rubbish */
next_free = pkt_end; /* remove rubbish */
return 0;
}
rxbuf[end] = c;
end = next;
}
rxbuf[cur_end] = c;
/* There could be a separate poll routine for this. */
if(c == 'T' && rxbuf[begin] == 'C') {
@ -388,6 +431,27 @@ slip_input_byte(unsigned char c)
return 1;
}
if(c == SLIP_END) {
/*
* We have a new packet, possibly of zero length.
*
* There may already be one packet buffered.
*/
if(cur_end != pkt_end) { /* Non zero length. */
if(begin == pkt_end) { /* None buffered. */
pkt_end = cur_end;
} else {
SLIP_STATISTICS(slip_twopackets++);
}
process_poll(&slip_process);
return 1;
} else {
/* Empty packet, reset the pointer */
next_free = cur_end;
}
return 0;
}
return 0;
}
/*---------------------------------------------------------------------------*/

View file

@ -548,6 +548,15 @@ tcpip_ipv6_output(void)
return;
}
#if UIP_CONF_IPV6_RPL
if(!rpl_update_header()) {
/* Packet can not be forwarded */
PRINTF("tcpip_ipv6_output: RPL header update error\n");
uip_clear_buf();
return;
}
#endif /* UIP_CONF_IPV6_RPL */
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
/* Next hop determination */
@ -651,12 +660,6 @@ tcpip_ipv6_output(void)
/* End of next hop determination */
#if UIP_CONF_IPV6_RPL
if(!rpl_finalize_header(nexthop)) {
uip_clear_buf();
return;
}
#endif /* UIP_CONF_IPV6_RPL */
nbr = uip_ds6_nbr_lookup(nexthop);
if(nbr == NULL) {
#if UIP_ND6_SEND_NA

4
core/net/ip/uip-debug.c Normal file → Executable file
View file

@ -56,7 +56,7 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
#if NETSTACK_CONF_WITH_IPV6
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
/*
* Printing IPv4-mapped addresses is done according to RFC 3513 [1]
* Printing IPv4-mapped addresses is done according to RFC 4291 [1]
*
* "An alternative form that is sometimes more
* convenient when dealing with a mixed environment
@ -67,7 +67,7 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
* low-order 8-bit pieces of the address (standard
* IPv4 representation)."
*
* [1] https://tools.ietf.org/html/rfc3513#page-5
* [1] https://tools.ietf.org/html/rfc4291#page-4
*/
PRINTA("::FFFF:%u.%u.%u.%u", addr->u8[12], addr->u8[13], addr->u8[14], addr->u8[15]);
} else {

6
core/net/ip/uip.h Normal file → Executable file
View file

@ -2012,7 +2012,7 @@ CCIF extern uip_lladdr_t uip_lladdr;
(((a)->u8[15]) == 0x02))
/**
* \brief is addr (a) a link local unicast address, see RFC3513
* \brief is addr (a) a link local unicast address, see RFC 4291
* i.e. is (a) on prefix FE80::/10
* a is of type uip_ipaddr_t*
*/
@ -2036,7 +2036,7 @@ CCIF extern uip_lladdr_t uip_lladdr;
} while(0)
/**
* \brief is addr (a) a solicited node multicast address, see RFC3513
* \brief is addr (a) a solicited node multicast address, see RFC 4291
* a is of type uip_ipaddr_t*
*/
#define uip_is_addr_solicited_node(a) \
@ -2097,7 +2097,7 @@ CCIF extern uip_lladdr_t uip_lladdr;
#endif /*UIP_CONF_LL_802154*/
/**
* \brief is address a multicast address, see RFC 3513
* \brief is address a multicast address, see RFC 4291
* a is of type uip_ipaddr_t*
* */
#define uip_is_addr_mcast(a) \

View file

@ -7,8 +7,14 @@ What does it do
These files, alongside some core modifications, add support for IPv6 multicast
to contiki's uIPv6 engine.
Currently, two modes are supported:
Currently, three modes are supported:
* 'Enhanced Stateless Multicast RPL Forwarding' (ESMRF)
ESMRF is an enhanced version of the SMRF engine with the aim
of resolving the sending limitation of SMRF to allow any node
within the DODAG to send multicast traffic up and down the RPL tree.
ESMRF is documented here:
http://dl.acm.org/citation.cfm?id=2753479
* 'Stateless Multicast RPL Forwarding' (SMRF)
RPL in MOP 3 handles group management as per the RPL docs,
SMRF is a lightweight engine which handles datagram forwarding.

View file

@ -50,8 +50,6 @@
#include "net/nbr-table.h"
#include "sys/stimer.h"
#include "net/ipv6/uip-ds6.h"
#include "net/nbr-table.h"
#if UIP_CONF_IPV6_QUEUE_PKT
#include "net/ip/uip-packetqueue.h"
#endif /*UIP_CONF_QUEUE_PKT */

View file

@ -82,14 +82,10 @@ void uip_ds6_notification_rm(struct uip_ds6_notification *n);
#endif
/* Routing table */
#ifndef UIP_CONF_MAX_ROUTES
#ifdef UIP_CONF_DS6_ROUTE_NBU
#define UIP_DS6_ROUTE_NB UIP_CONF_DS6_ROUTE_NBU
#else /* UIP_CONF_DS6_ROUTE_NBU */
#define UIP_DS6_ROUTE_NB 4
#endif /* UIP_CONF_DS6_ROUTE_NBU */
#else /* UIP_CONF_MAX_ROUTES */
#ifdef UIP_CONF_MAX_ROUTES
#define UIP_DS6_ROUTE_NB UIP_CONF_MAX_ROUTES
#else /* UIP_CONF_MAX_ROUTES */
#define UIP_DS6_ROUTE_NB 4
#endif /* UIP_CONF_MAX_ROUTES */
/** \brief define some additional RPL related route state and

View file

@ -56,6 +56,8 @@
* - the number of elements requested by the user in contiki configuration (name suffixed by _NBU)
* - the number of elements assigned by the system (name suffixed by _NBS)
* - the total number of elements is the sum (name suffixed by _NB)
* The routing table definitions can be found in uip-ds6-route.h
* The Neighbor cache definitions can be found in nbr-table.h
*/
/* Default router list */

View file

@ -160,11 +160,6 @@ echo_request_input(void)
uip_ext_len = 0;
}
/* Insert RPL extension headers */
#if UIP_CONF_IPV6_RPL
rpl_insert_header();
#endif /* UIP_CONF_IPV6_RPL */
/* Below is important for the correctness of UIP_ICMP_BUF and the
* checksum
*/
@ -260,10 +255,6 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
UIP_ICMP_BUF->icmpchksum = 0;
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
#if UIP_CONF_IPV6_RPL
rpl_insert_header();
#endif /* UIP_CONF_IPV6_RPL */
UIP_STAT(++uip_stat.icmp.sent);
PRINTF("Sending ICMPv6 ERROR message type %d code %d to ", type, code);
@ -301,9 +292,6 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
UIP_STAT(++uip_stat.icmp.sent);
UIP_STAT(++uip_stat.ip.sent);
#if UIP_CONF_IPV6_RPL
rpl_insert_header();
#endif /* UIP_CONF_IPV6_RPL */
tcpip_ipv6_output();
}
/*---------------------------------------------------------------------------*/

View file

@ -662,7 +662,8 @@ rs_input(void)
}
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
lladdr, UIP_LLADDR_LEN) != 0) {
uip_ds6_nbr_t nbr_data = *nbr;
uip_ds6_nbr_t nbr_data;
nbr_data = *nbr;
uip_ds6_nbr_rm(nbr);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);

View file

@ -73,6 +73,7 @@
#include "sys/cc.h"
#include "net/ip/uip.h"
#include "net/ip/uip_arch.h"
#include "net/ip/uipopt.h"
#include "net/ipv6/uip-icmp6.h"
#include "net/ipv6/uip-nd6.h"
@ -890,7 +891,7 @@ ext_hdr_options_process(void)
*/
#if UIP_CONF_IPV6_RPL
PRINTF("Processing RPL option\n");
if(rpl_verify_hbh_header(uip_ext_opt_offset)) {
if(!rpl_verify_hbh_header(uip_ext_opt_offset)) {
PRINTF("RPL Option Error: Dropping Packet\n");
return 1;
}
@ -1228,14 +1229,6 @@ uip_process(uint8_t flag)
goto send;
}
#if UIP_CONF_IPV6_RPL
if(!rpl_update_header()) {
/* Packet can not be forwarded */
PRINTF("RPL header update error\n");
goto drop;
}
#endif /* UIP_CONF_IPV6_RPL */
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
PRINTF("Forwarding packet to ");
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
@ -1582,10 +1575,6 @@ uip_process(uint8_t flag)
}
#endif /* UIP_UDP_CHECKSUMS */
#if UIP_CONF_IPV6_RPL
rpl_insert_header();
#endif /* UIP_CONF_IPV6_RPL */
UIP_STAT(++uip_stat.udp.sent);
goto ip_send_nolen;
#endif /* UIP_UDP */
@ -1854,8 +1843,10 @@ uip_process(uint8_t flag)
if((UIP_TCP_BUF->flags & TCP_SYN)) {
if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
goto tcp_send_synack;
#if UIP_ACTIVE_OPEN
} else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
goto tcp_send_syn;
#endif
}
}
goto tcp_send_ack;

View file

@ -289,9 +289,15 @@ off(void)
}
}
/*---------------------------------------------------------------------------*/
static volatile rtimer_clock_t cycle_start;
static void powercycle_wrapper(struct rtimer *t, void *ptr);
static char powercycle(struct rtimer *t, void *ptr);
/*---------------------------------------------------------------------------*/
static volatile rtimer_clock_t cycle_start;
#if SYNC_CYCLE_STARTS
static volatile rtimer_clock_t sync_cycle_start;
static volatile uint8_t sync_cycle_phase;
#endif
/*---------------------------------------------------------------------------*/
static void
schedule_powercycle(struct rtimer *t, rtimer_clock_t time)
{
@ -367,13 +373,34 @@ powercycle_wrapper(struct rtimer *t, void *ptr)
powercycle(t, ptr);
}
/*---------------------------------------------------------------------------*/
static void
advance_cycle_start(void)
{
#if SYNC_CYCLE_STARTS
/* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple
of CHANNEL_CHECK_RATE */
if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) {
sync_cycle_phase = 0;
sync_cycle_start += RTIMER_ARCH_SECOND;
cycle_start = sync_cycle_start;
} else if( (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535) {
uint32_t phase_time = sync_cycle_phase*RTIMER_ARCH_SECOND;
cycle_start = sync_cycle_start + phase_time/NETSTACK_RDC_CHANNEL_CHECK_RATE;
} else {
unsigned phase_time = sync_cycle_phase*RTIMER_ARCH_SECOND;
cycle_start = sync_cycle_start + phase_time/NETSTACK_RDC_CHANNEL_CHECK_RATE;
}
#endif
cycle_start += CYCLE_TIME;
}
/*---------------------------------------------------------------------------*/
static char
powercycle(struct rtimer *t, void *ptr)
{
#if SYNC_CYCLE_STARTS
static volatile rtimer_clock_t sync_cycle_start;
static volatile uint8_t sync_cycle_phase;
#endif
PT_BEGIN(&pt);
@ -387,24 +414,6 @@ powercycle(struct rtimer *t, void *ptr)
static uint8_t packet_seen;
static uint8_t count;
#if SYNC_CYCLE_STARTS
/* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple
of CHANNEL_CHECK_RATE */
if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) {
sync_cycle_phase = 0;
sync_cycle_start += RTIMER_ARCH_SECOND;
cycle_start = sync_cycle_start;
} else {
#if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535
cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE;
#else
cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE;
#endif
}
#else
cycle_start += CYCLE_TIME;
#endif
packet_seen = 0;
for(count = 0; count < CCA_COUNT_MAX; ++count) {
@ -472,8 +481,8 @@ powercycle(struct rtimer *t, void *ptr)
break;
}
schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME);
PT_YIELD(&pt);
// schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME);
// PT_YIELD(&pt);
}
if(radio_is_on) {
if(!(NETSTACK_RADIO.receiving_packet() ||
@ -485,24 +494,26 @@ powercycle(struct rtimer *t, void *ptr)
}
}
if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) {
advance_cycle_start();
if(RTIMER_CLOCK_LT(RTIMER_NOW() , cycle_start - CHECK_TIME * 4)) {
/* Schedule the next powercycle interrupt, or sleep the mcu
until then. Sleeping will not exit from this interrupt, so
ensure an occasional wake cycle or foreground processing will
be blocked until a packet is detected */
#if RDC_CONF_MCU_SLEEP
static uint8_t sleepcycle;
if((sleepcycle++ < mcusleepcycle) && !we_are_sending && !radio_is_on) {
rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start));
if((sleepcycle++ < mcusleepcycle) && !we_are_sending && !radio_is_on && !(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet())) {
rtimer_arch_sleep(cycle_start - RTIMER_NOW());
} else {
sleepcycle = 0;
#ifndef RDC_CONF_PT_YIELD_OFF
schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
schedule_powercycle_fixed(t, cycle_start);
PT_YIELD(&pt);
#endif
}
#else
schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
schedule_powercycle_fixed(t, cycle_start);
PT_YIELD(&pt);
#endif
}

View file

@ -146,31 +146,19 @@ frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest
}
if(fcf->frame_version == FRAME802154_IEEE802154E_2012) {
/* IEEE 802.15.4e-2012, Table 2a, PAN ID Compression */
if(!fcf->panid_compression) {
/* Compressed PAN ID == no PAN ID at all */
if(fcf->dest_addr_mode == fcf->dest_addr_mode) {
/* No address or both addresses: include destination PAN ID */
dest_pan_id = 1;
} else if(fcf->dest_addr_mode) {
/* Only dest address, include dest PAN ID */
if(fcf->dest_addr_mode) {
/* Use destination PAN ID if destination address is present */
dest_pan_id = 1;
} else if(fcf->src_addr_mode) {
/* Only src address, include src PAN ID */
src_pan_id = 1;
}
}
if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 1) {
/* No address included, include dest PAN ID conditionally */
if(!fcf->panid_compression) {
} else if((fcf->dest_addr_mode == 0) && (fcf->src_addr_mode == 0)) {
/* No address included: PAN ID compression flag changes meaning */
dest_pan_id = 1;
}
}
/* Remove the following rule the day rows 2 and 3 from table 2a are fixed: */
if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 0) {
/* Not meaningful, we include a PAN ID iff the compress flag is set, but
* this is what the standard currently stipulates */
dest_pan_id = fcf->panid_compression;
}
} else {
/* No PAN ID in ACK */
if(fcf->frame_type != FRAME802154_ACKFRAME) {

View file

@ -86,14 +86,16 @@ create_frame(int type, int do_create)
params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
if(packetbuf_holds_broadcast()) {
params.fcf.ack_required = 0;
/* Suppress seqno on broadcast if supported (frame v2 or more) */
params.fcf.sequence_number_suppression = FRAME802154_VERSION >= FRAME802154_IEEE802154E_2012;
} else {
params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK);
params.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO;
}
/* We do not compress PAN ID in outgoing frames, i.e. include one PAN ID (dest by default)
* There is one exception, seemingly a typo in Table 2a: rows 2 and 3: when there is no
* source nor destination address, we have dest PAN ID iff compression is *set*. */
params.fcf.panid_compression = 0;
params.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO;
/* Insert IEEE 802.15.4 version bits. */
params.fcf.frame_version = FRAME802154_VERSION;

View file

@ -51,9 +51,16 @@
struct seqno {
linkaddr_t sender;
clock_time_t timestamp;
uint8_t seqno;
};
#ifdef NETSTACK_CONF_MAC_SEQNO_MAX_AGE
#define SEQNO_MAX_AGE NETSTACK_CONF_MAC_SEQNO_MAX_AGE
#else /* NETSTACK_CONF_MAC_SEQNO_MAX_AGE */
#define SEQNO_MAX_AGE (20 * CLOCK_SECOND)
#endif /* NETSTACK_CONF_MAC_SEQNO_MAX_AGE */
#ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY
#define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY
#else /* NETSTACK_CONF_MAC_SEQNO_HISTORY */
@ -66,6 +73,7 @@ int
mac_sequence_is_duplicate(void)
{
int i;
clock_time_t now = clock_time();
/*
* Check for duplicate packet by comparing the sequence number of the incoming
@ -75,9 +83,15 @@ mac_sequence_is_duplicate(void)
if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
&received_seqnos[i].sender)) {
if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) == received_seqnos[i].seqno) {
#if SEQNO_MAX_AGE > 0
if(now - received_seqnos[i].timestamp <= SEQNO_MAX_AGE) {
/* Duplicate packet. */
return 1;
}
#else /* SEQNO_MAX_AGE > 0 */
return 1;
#endif /* SEQNO_MAX_AGE > 0 */
}
break;
}
}
@ -103,6 +117,7 @@ mac_sequence_register_seqno(void)
memcpy(&received_seqnos[j], &received_seqnos[j - 1], sizeof(struct seqno));
}
received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
received_seqnos[0].timestamp = clock_time();
linkaddr_copy(&received_seqnos[0].sender,
packetbuf_addr(PACKETBUF_ADDR_SENDER));
}

View file

@ -11,6 +11,7 @@ which defines how to run a basic RPL+TSCH network.
It was developped by:
* Simon Duquennoy, SICS, simonduq@sics.se, github user: [simonduq](https://github.com/simonduq)
* Beshr Al Nahas, SICS (now Chalmers University), beshr@chalmers.se, github user: [beshrns](https://github.com/beshrns)
* Atis Elsts, Univ. Bristol, atis.elsts@bristol.ac.uk, github user: [atiselsts](https://github.com/atiselsts)
You can find an extensive evaluation of this implementation in our paper [*Orchestra: Robust Mesh Networks Through Autonomously Scheduled TSCH*](http://www.simonduquennoy.net/papers/duquennoy15orchestra.pdf), ACM SenSys'15.
@ -31,6 +32,7 @@ This implementation includes:
* A scheduling API to add/remove slotframes and links
* A system for logging from TSCH timeslot operation interrupt, with postponed printout
* Orchestra: an autonomous scheduler for TSCH+RPL networks
* A drift compensation mechanism
It has been tested on the following platforms:
* NXP JN516x (`jn516x`, tested on hardware)
@ -38,6 +40,7 @@ It has been tested on the following platforms:
* Zolertia Z1 (`z1`, tested in cooja only)
* CC2538DK (`cc2538dk`, tested on hardware)
* Zolertia Zoul (`zoul`, tested on hardware)
* OpenMote-CC2538 (`openmote-cc2538`, tested on hardware)
* CC2650 (`srf06-cc26xx`, tested on hardware)
This implementation was present at the ETSI Plugtest
@ -71,6 +74,7 @@ Implements the 6TiSCH minimal configuration K1-K2 keys pair.
* `tsch-rpl.[ch]`: used for TSCH+RPL networks, to align TSCH and RPL states (preferred parent -> time source,
rank -> join priority) as defined in the 6TiSCH minimal configuration.
* `tsch-log.[ch]`: logging system for TSCH, including delayed messages for logging from slot operation interrupt.
* `tsch-adaptive-timesync.c`: used to learn the relative drift to the node's time source and automatically compensate for it.
Orchestra is implemented in:
* `apps/orchestra`: see `apps/orchestra/README.md` for more information.
@ -79,7 +83,7 @@ Orchestra is implemented in:
A simple TSCH+RPL example is included under `examples/ipv6/rpl-tsch`.
To use TSCH, first make sure your platform supports it.
Currently, `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul` and `srf06-cc26xx` are the supported platforms.
Currently, `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul`, `openmote-cc2538`, and `srf06-cc26xx` are the supported platforms.
To add your own, we refer the reader to the next section.
To add TSCH to your application, first include the TSCH module from your makefile with:
@ -165,7 +169,7 @@ Finally, one can also implement his own scheduler, centralized or distributed, b
## Porting TSCH to a new platform
Porting TSCH to a new platform requires a few new features in the radio driver, a number of timing-related configuration paramters.
The easiest is probably to start from one of the existing port: `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul`, `srf06-cc26xx`.
The easiest is probably to start from one of the existing port: `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul`, `openmote-cc2538`, `srf06-cc26xx`.
### Radio features required for TSCH
@ -199,6 +203,8 @@ too slow for the default 10ms timeslots.
1. [IEEE 802.15.4e-2012 ammendment][ieee802.15.4e-2012]
2. [IETF 6TiSCH Working Group][ietf-6tisch-wg]
3. [A test procedure for Contiki timers in TSCH][tsch-sync-test]
[ieee802.15.4e-2012]: http://standards.ieee.org/getieee802/download/802.15.4e-2012.pdf
[ietf-6tisch-wg]: https://datatracker.ietf.org/wg/6tisch
[tsch-sync-test]: https://github.com/abbypjoby/Contiki-Synchronisation-Test

View file

@ -85,12 +85,12 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size,
p.seq = seqno;
#if TSCH_PACKET_EACK_WITH_DEST_ADDR
if(dest_addr != NULL) {
p.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
p.fcf.dest_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;;
linkaddr_copy((linkaddr_t *)&p.dest_addr, dest_addr);
}
#endif
#if TSCH_PACKET_EACK_WITH_SRC_ADDR
p.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
p.fcf.src_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;;
p.src_pid = IEEE802154_PANID;
linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr);
#endif
@ -189,7 +189,7 @@ tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
/*---------------------------------------------------------------------------*/
/* Create an EB packet */
int
tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
tsch_packet_create_eb(uint8_t *buf, int buf_size,
uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset)
{
int ret = 0;
@ -208,10 +208,9 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
p.fcf.frame_type = FRAME802154_BEACONFRAME;
p.fcf.ie_list_present = 1;
p.fcf.frame_version = FRAME802154_IEEE802154E_2012;
p.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
p.fcf.src_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;
p.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
p.seq = seqno;
p.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO;
p.fcf.sequence_number_suppression = 1;
/* It is important not to compress PAN ID, as this would result in not including either
* source nor destination PAN ID, leaving potential joining devices unaware of the PAN ID. */
p.fcf.panid_compression = 0;

View file

@ -94,7 +94,7 @@ int tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
uint8_t seqno, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len);
/* Create an EB packet */
int tsch_packet_create_eb(uint8_t *buf, int buf_size,
uint8_t seqno, uint8_t *hdr_len, uint8_t *tsch_sync_ie_ptr);
uint8_t *hdr_len, uint8_t *tsch_sync_ie_ptr);
/* Update ASN in EB packet */
int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset);
/* Parse EB and extract ASN and join priority */

View file

@ -154,6 +154,9 @@ static rtimer_clock_t volatile current_slot_start;
/* Are we currently inside a slot? */
static volatile int tsch_in_slot_operation = 0;
/* If we are inside a slot, this tells the current channel */
static uint8_t current_channel;
/* Info about the link, packet and neighbor of
* the current (or next) slot */
struct tsch_link *current_link = NULL;
@ -580,7 +583,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
tsch_radio_on(TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT);
/* Wait for ACK to come */
BUSYWAIT_UNTIL_ABS(NETSTACK_RADIO.receiving_packet(),
tx_start_time, tx_duration + tsch_timing[tsch_ts_rx_ack_delay] + tsch_timing[tsch_ts_ack_wait]);
tx_start_time, tx_duration + tsch_timing[tsch_ts_rx_ack_delay] + tsch_timing[tsch_ts_ack_wait] + RADIO_DELAY_BEFORE_DETECT);
TSCH_DEBUG_TX_EVENT();
ack_start_time = RTIMER_NOW() - RADIO_DELAY_BEFORE_DETECT;
@ -753,7 +756,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
if(!packet_seen) {
/* Check if receiving within guard time */
BUSYWAIT_UNTIL_ABS((packet_seen = NETSTACK_RADIO.receiving_packet()),
current_slot_start, tsch_timing[tsch_ts_rx_offset] + tsch_timing[tsch_ts_rx_wait]);
current_slot_start, tsch_timing[tsch_ts_rx_offset] + tsch_timing[tsch_ts_rx_wait] + RADIO_DELAY_BEFORE_DETECT);
}
if(!packet_seen) {
/* no packets on air */
@ -780,6 +783,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi);
current_input->rx_asn = current_asn;
current_input->rssi = (signed)radio_last_rssi;
current_input->channel = current_channel;
header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame);
frame_valid = header_len > 0 &&
frame802154_check_dest_panid(&frame) &&
@ -937,7 +941,6 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
);
} else {
uint8_t current_channel;
int is_active_slot;
TSCH_DEBUG_SLOT_START();
tsch_in_slot_operation = 1;

View file

@ -89,7 +89,8 @@ struct input_packet {
uint8_t payload[TSCH_PACKET_MAX_LEN]; /* Packet payload */
struct asn_t rx_asn; /* ASN when the packet was received */
int len; /* Packet len */
uint16_t rssi; /* RSSI for this packet */
int16_t rssi; /* RSSI for this packet */
uint8_t channel; /* Channel we received the packet on */
};
/***** External Variables *****/

View file

@ -45,6 +45,7 @@
#include "net/netstack.h"
#include "net/packetbuf.h"
#include "net/queuebuf.h"
#include "net/nbr-table.h"
#include "net/mac/framer-802154.h"
#include "net/mac/tsch/tsch.h"
#include "net/mac/tsch/tsch-slot-operation.h"
@ -53,6 +54,7 @@
#include "net/mac/tsch/tsch-log.h"
#include "net/mac/tsch/tsch-packet.h"
#include "net/mac/tsch/tsch-security.h"
#include "net/mac/mac-sequence.h"
#include "lib/random.h"
#if FRAME802154_VERSION < FRAME802154_IEEE802154E_2012
@ -69,26 +71,12 @@
/* Use to collect link statistics even on Keep-Alive, even though they were
* not sent from an upper layer and don't have a valid packet_sent callback */
#ifndef TSCH_LINK_NEIGHBOR_CALLBACK
#if NETSTACK_CONF_WITH_IPV6
void uip_ds6_link_neighbor_callback(int status, int numtx);
#define TSCH_LINK_NEIGHBOR_CALLBACK(dest, status, num) uip_ds6_link_neighbor_callback(status, num)
#endif /* NETSTACK_CONF_WITH_IPV6 */
#endif /* TSCH_LINK_NEIGHBOR_CALLBACK */
/* 802.15.4 duplicate frame detection */
struct seqno {
linkaddr_t sender;
uint8_t seqno;
};
/* Size of the sequence number history */
#ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY
#define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY
#else /* NETSTACK_CONF_MAC_SEQNO_HISTORY */
#define MAX_SEQNOS 8
#endif /* NETSTACK_CONF_MAC_SEQNO_HISTORY */
/* Seqno history */
static struct seqno received_seqnos[MAX_SEQNOS];
/* Let TSCH select a time source with no help of an upper layer.
* We do so using statistics from incoming EBs */
#if TSCH_AUTOSELECT_TIME_SOURCE
@ -147,7 +135,7 @@ struct asn_t current_asn;
/* Device rank or join priority:
* For PAN coordinator: 0 -- lower is better */
uint8_t tsch_join_priority;
/* The current TSCH sequence number, used for both data and EBs */
/* The current TSCH sequence number, used for unicast data frames only */
static uint8_t tsch_packet_seqno = 0;
/* Current period for EB output */
static clock_time_t tsch_current_eb_period;
@ -280,13 +268,13 @@ eb_input(struct input_packet *current_input)
#if TSCH_AUTOSELECT_TIME_SOURCE
if(!tsch_is_coordinator) {
/* Maintain EB received counter for every neighbor */
struct eb_stat *stat = (struct eb_stat *)nbr_table_get_from_lladdr(eb_stats, &frame.src_addr);
struct eb_stat *stat = (struct eb_stat *)nbr_table_get_from_lladdr(eb_stats, (linkaddr_t *)&frame.src_addr);
if(stat == NULL) {
stat = (struct eb_stat *)nbr_table_add_lladdr(eb_stats, &frame.src_addr);
stat = (struct eb_stat *)nbr_table_add_lladdr(eb_stats, (linkaddr_t *)&frame.src_addr, NBR_TABLE_REASON_MAC, NULL);
}
if(stat != NULL) {
stat->rx_count++;
stat->jp = eb_ies.join_priority;
stat->jp = eb_ies.ie_join_priority;
best_neighbor_eb_count = MAX(best_neighbor_eb_count, stat->rx_count);
}
/* Select best time source */
@ -361,6 +349,7 @@ tsch_rx_process_pending()
/* Copy to packetbuf for processing */
packetbuf_copyfrom(current_input->payload, current_input->len);
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, current_input->rssi);
packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, current_input->channel);
}
/* Remove input from ringbuf */
@ -561,10 +550,6 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
if(n != NULL) {
tsch_queue_update_time_source((linkaddr_t *)&frame.src_addr);
#ifdef TSCH_CALLBACK_JOINING_NETWORK
TSCH_CALLBACK_JOINING_NETWORK();
#endif
/* Set PANID */
frame802154_set_pan_id(frame.src_pid);
@ -575,9 +560,13 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
tsch_is_associated = 1;
tsch_is_pan_secured = frame.fcf.security_enabled;
/* Association done, schedule keepalive messages */
/* Start sending keep-alives now that tsch_is_associated is set */
tsch_schedule_keepalive();
#ifdef TSCH_CALLBACK_JOINING_NETWORK
TSCH_CALLBACK_JOINING_NETWORK();
#endif
PRINTF("TSCH: association done, sec %u, PAN ID %x, asn-%x.%lx, jp %u, timeslot id %u, hopping id %u, slotframe len %u with %u links, from ",
tsch_is_pan_secured,
frame.src_pid,
@ -741,12 +730,7 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data)
uint8_t tsch_sync_ie_offset;
/* Prepare the EB packet and schedule it to be sent */
packetbuf_clear();
/* We don't use seqno 0 */
if(++tsch_packet_seqno == 0) {
tsch_packet_seqno++;
}
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
/* Set security level, key id and index */
@ -756,7 +740,7 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data)
}
#endif /* LLSEC802154_ENABLED */
eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE,
tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset);
&hdr_len, &tsch_sync_ie_offset);
if(eb_len != 0) {
struct tsch_packet *p;
packetbuf_set_datalen(eb_len);
@ -889,14 +873,14 @@ send_packet(mac_callback_t sent, void *ptr)
return;
}
/* Ask for ACK if we are sending anything other than broadcast */
if(!linkaddr_cmp(addr, &linkaddr_null)) {
/* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity
in framer-802154.c. */
if(++tsch_packet_seqno == 0) {
tsch_packet_seqno++;
}
/* Ask for ACK if we are sending anything other than broadcast */
if(!linkaddr_cmp(addr, &linkaddr_null)) {
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
} else {
/* Broadcast packets shall be added to broadcast queue
@ -906,7 +890,6 @@ send_packet(mac_callback_t sent, void *ptr)
}
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
@ -927,7 +910,10 @@ send_packet(mac_callback_t sent, void *ptr)
/* Enqueue packet */
p = tsch_queue_add_packet(addr, sent, ptr);
if(p == NULL) {
PRINTF("TSCH:! can't send packet !tsch_queue_add_packet\n");
PRINTF("TSCH:! can't send packet to %u with seqno %u, queue %u %u\n",
TSCH_LOG_ID_FROM_LINKADDR(addr), tsch_packet_seqno,
packet_count_before,
tsch_queue_packet_count(addr));
ret = MAC_TX_ERR;
} else {
p->header_len = hdr_len;
@ -959,28 +945,15 @@ packet_input(void)
/* Seqno of 0xffff means no seqno */
if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) != 0xffff) {
/* Check for duplicate packet by comparing the sequence number
of the incoming packet with the last few ones we saw. */
int i;
for(i = 0; i < MAX_SEQNOS; ++i) {
if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) == received_seqnos[i].seqno &&
linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
&received_seqnos[i].sender)) {
/* Check for duplicates */
duplicate = mac_sequence_is_duplicate();
if(duplicate) {
/* Drop the packet. */
PRINTF("TSCH:! drop dup ll from %u seqno %u\n",
TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)),
packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
duplicate = 1;
}
}
if(!duplicate) {
for(i = MAX_SEQNOS - 1; i > 0; --i) {
memcpy(&received_seqnos[i], &received_seqnos[i - 1],
sizeof(struct seqno));
}
received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
linkaddr_copy(&received_seqnos[0].sender,
packetbuf_addr(PACKETBUF_ADDR_SENDER));
} else {
mac_sequence_register_seqno();
}
}
@ -1013,6 +986,11 @@ turn_on(void)
static int
turn_off(int keep_radio_on)
{
if(keep_radio_on) {
NETSTACK_RADIO.on();
} else {
NETSTACK_RADIO.off();
}
return 1;
}
/*---------------------------------------------------------------------------*/

View file

@ -169,7 +169,7 @@ header_size(const struct packetbuf_attrlist *a)
return size;
}
/*---------------------------------------------------------------------------*/
void CC_INLINE
static void CC_INLINE
set_bits_in_byte(uint8_t *target, int bitpos, uint8_t val, int vallen)
{
unsigned short shifted_val;

View file

@ -554,13 +554,6 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
if(instance->def_route == NULL) {
return 0;
}
} else {
PRINTF("RPL: Removing default route\n");
if(instance->def_route != NULL) {
uip_ds6_defrt_rm(instance->def_route);
} else {
PRINTF("RPL: Not actually removing default route, since instance had no default route\n");
}
}
return 1;
}
@ -917,11 +910,11 @@ rpl_select_parent(rpl_dag_t *dag)
/* Probe the best parent shortly in order to get a fresh estimate */
dag->instance->urgent_probing_target = best;
rpl_schedule_probing(dag->instance);
}
#else /* RPL_WITH_PROBING */
rpl_set_preferred_parent(dag, best);
dag->rank = rpl_rank_via_parent(dag->preferred_parent);
#endif /* RPL_WITH_PROBING */
}
} else {
rpl_set_preferred_parent(dag, NULL);
}
@ -1086,6 +1079,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|| (!RPL_WITH_STORING && (dio->mop == RPL_MOP_STORING_NO_MULTICAST
|| dio->mop == RPL_MOP_STORING_MULTICAST))) {
PRINTF("RPL: DIO advertising a non-supported MOP %u\n", dio->mop);
return;
}
/* Determine the objective function by using the

View file

@ -78,26 +78,22 @@ rpl_verify_hbh_header(int uip_ext_opt_offset)
uip_ds6_route_t *route;
rpl_parent_t *sender = NULL;
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) {
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
return 1;
}
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
PRINTF("RPL: Non RPL Hop-by-hop option\n");
return 1;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
PRINTF("RPL: Bad header option! (wrong length)\n");
return 1;
PRINTF("RPL: Hop-by-hop extension header has wrong size or type (%u %u %u)\n",
UIP_HBHO_BUF->len,
UIP_EXT_HDR_OPT_RPL_BUF->opt_type,
UIP_EXT_HDR_OPT_RPL_BUF->opt_len);
return 0; /* Drop */
}
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
if(instance == NULL) {
PRINTF("RPL: Unknown instance: %u\n",
UIP_EXT_HDR_OPT_RPL_BUF->instance);
return 1;
return 0;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
@ -116,14 +112,13 @@ rpl_verify_hbh_header(int uip_ext_opt_offset)
/* Trigger DAO retransmission */
rpl_reset_dio_timer(instance);
/* drop the packet as it is not routable */
return 1;
return 0;
}
if(!instance->current_dag->joined) {
PRINTF("RPL: No DAG in the instance\n");
return 1;
return 0;
}
down = 0;
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
down = 1;
@ -167,16 +162,16 @@ rpl_verify_hbh_header(int uip_ext_opt_offset)
PRINTF("RPL: Rank error signalled in RPL option!\n");
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
rpl_reset_dio_timer(instance);
return 1;
return 0;
}
PRINTF("RPL: Single error tolerated\n");
RPL_STAT(rpl_stats.loop_warnings++);
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
return 0;
return 1;
}
PRINTF("RPL: Rank OK\n");
return 0;
return 1;
}
/*---------------------------------------------------------------------------*/
#if RPL_WITH_NON_STORING
@ -195,22 +190,19 @@ rpl_srh_get_next_hop(uip_ipaddr_t *ipaddr)
/* Look for routing header */
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
switch(*uip_next_hdr) {
case UIP_PROTO_TCP:
case UIP_PROTO_UDP:
case UIP_PROTO_ICMP6:
case UIP_PROTO_NONE:
uip_next_hdr = NULL;
break;
case UIP_PROTO_HBHO:
case UIP_PROTO_DESTO:
case UIP_PROTO_FRAG:
/*
* As per RFC 2460, only the Hop-by-Hop Options header and
* Destination Options header can appear before the Routing
* header.
*/
/* Move to next header */
if(uip_next_hdr != &UIP_IP_BUF->proto) {
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
}
uip_next_hdr = &UIP_EXT_BUF->next;
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
break;
default:
uip_next_hdr = NULL;
break;
}
}
@ -249,22 +241,19 @@ rpl_process_srh_header(void)
/* Look for routing header */
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
switch(*uip_next_hdr) {
case UIP_PROTO_TCP:
case UIP_PROTO_UDP:
case UIP_PROTO_ICMP6:
case UIP_PROTO_NONE:
uip_next_hdr = NULL;
break;
case UIP_PROTO_HBHO:
case UIP_PROTO_DESTO:
case UIP_PROTO_FRAG:
/*
* As per RFC 2460, only the Hop-by-Hop Options header and
* Destination Options header can appear before the Routing
* header.
*/
/* Move to next header */
if(uip_next_hdr != &UIP_IP_BUF->proto) {
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
}
uip_next_hdr = &UIP_EXT_BUF->next;
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
break;
default:
uip_next_hdr = NULL;
break;
}
}
@ -389,7 +378,7 @@ insert_srh_header(void)
if(node == root_node) {
PRINTF("RPL: SRH no need to insert SRH\n");
return 0;
return 1;
}
while(node != NULL && node != root_node) {
@ -488,40 +477,27 @@ update_hbh_header(void)
uip_ext_len = 0;
uip_ext_opt_offset = 2;
PRINTF("RPL: Verifying the presence of the RPL header option\n");
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL) {
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
switch(UIP_IP_BUF->proto) {
case UIP_PROTO_HBHO:
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) {
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
uip_ext_len = last_uip_ext_len;
return 1;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
PRINTF("RPL: Non RPL Hop-by-hop option support not implemented\n");
uip_ext_len = last_uip_ext_len;
return 1;
}
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
PRINTF("RPL: RPL Hop-by-hop option has wrong length\n");
uip_ext_len = last_uip_ext_len;
return 1;
PRINTF("RPL: Hop-by-hop extension header has wrong size (%u %u)\n",
UIP_EXT_HDR_OPT_RPL_BUF->opt_len,
uip_ext_len);
return 0; /* Drop */
}
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
return 1;
}
break;
default:
PRINTF("RPL: No hop-by-hop option found\n");
return 1;
PRINTF("RPL: Unable to add/update hop-by-hop extension header: incorrect instance\n");
uip_ext_len = last_uip_ext_len;
return 0; /* Drop */
}
switch(UIP_EXT_HDR_OPT_BUF->type) {
case UIP_EXT_HDR_OPT_RPL:
PRINTF("RPL: Updating RPL option\n");
/* Update sender rank and instance, will update flags next */
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
if(RPL_IS_STORING(instance)) { /* In non-storing mode, downwards traffic does not have the HBH option */
/* Check the direction of the down flag, as per Section 11.2.2.3,
@ -558,18 +534,14 @@ update_hbh_header(void)
}
}
}
}
uip_ext_len = last_uip_ext_len;
return 1;
default:
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
uip_ext_len = last_uip_ext_len;
return 1;
}
}
/*---------------------------------------------------------------------------*/
static int
insert_hbh_header(void)
insert_hbh_header(const rpl_instance_t *instance)
{
int uip_ext_opt_offset;
int last_uip_ext_len;
@ -600,8 +572,8 @@ insert_hbh_header(void)
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
UIP_EXT_HDR_OPT_RPL_BUF->instance = 0;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
uip_len += RPL_HOP_BY_HOP_LEN;
temp_len = UIP_IP_BUF->len[1];
UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN;
@ -610,44 +582,9 @@ insert_hbh_header(void)
}
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
return 1;
}
/*---------------------------------------------------------------------------*/
int
rpl_finalize_header(uip_ipaddr_t *addr)
{
rpl_parent_t *parent;
int uip_ext_opt_offset;
int last_uip_ext_len;
last_uip_ext_len = uip_ext_len;
uip_ext_len = 0;
uip_ext_opt_offset = 2;
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO) {
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) {
PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n");
uip_ext_len = last_uip_ext_len;
return 1;
}
if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) {
if(UIP_EXT_HDR_OPT_RPL_BUF->senderrank == 0) {
PRINTF("RPL: Updating RPL option\n");
if(default_instance == NULL || !default_instance->used || !default_instance->current_dag->joined) {
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect default instance\n");
return 0;
}
parent = rpl_find_parent(default_instance->current_dag, addr);
if(parent == NULL || parent != parent->dag->preferred_parent) {
UIP_EXT_HDR_OPT_RPL_BUF->flags = RPL_HDR_OPT_DOWN;
}
UIP_EXT_HDR_OPT_RPL_BUF->instance = default_instance->instance_id;
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(default_instance->current_dag->rank);
}
}
}
return 1;
/* Update header before returning */
return update_hbh_header();
}
/*---------------------------------------------------------------------------*/
void
@ -660,16 +597,9 @@ rpl_remove_header(void)
uip_ext_len = 0;
uip_next_hdr = &UIP_IP_BUF->proto;
PRINTF("RPL: Verifying the presence of RPL extension headers\n");
/* Look for hop-by-hop and routing headers */
while(uip_next_hdr != NULL) {
switch(*uip_next_hdr) {
case UIP_PROTO_TCP:
case UIP_PROTO_UDP:
case UIP_PROTO_ICMP6:
case UIP_PROTO_NONE:
return;
case UIP_PROTO_HBHO:
case UIP_PROTO_ROUTING:
/* Remove hop-by-hop and routing headers */
@ -684,48 +614,32 @@ rpl_remove_header(void)
PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len);
memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN);
break;
default:
case UIP_PROTO_DESTO:
/*
* As per RFC 2460, any header other than the Destination
* Options header does not appear between the Hop-by-Hop
* Options header and the Routing header.
*
* We're moving to the next header only if uip_next_hdr has
* UIP_PROTO_DESTO. Otherwise, we'll return.
*/
/* Move to next header */
if(uip_next_hdr != &UIP_IP_BUF->proto) {
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
}
uip_next_hdr = &UIP_EXT_BUF->next;
break;
}
}
}
/*---------------------------------------------------------------------------*/
void
rpl_insert_header(void)
{
if(default_instance == NULL || default_instance->current_dag == NULL
|| uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) || uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
default:
return;
}
if(RPL_IS_STORING(default_instance)) {
insert_hbh_header();
}
if(RPL_IS_NON_STORING(default_instance)) {
if(default_instance->current_dag != NULL) {
if(default_instance->current_dag->rank == ROOT_RANK(default_instance)) {
insert_srh_header();
} else {
insert_hbh_header();
}
}
}
}
/*---------------------------------------------------------------------------*/
int
rpl_update_header(void)
{
if(default_instance == NULL) {
return 0;
if(default_instance == NULL || default_instance->current_dag == NULL
|| uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) || uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
return 1;
}
if(default_instance->current_dag != NULL) {
if(default_instance->current_dag->rank == ROOT_RANK(default_instance)) {
/* At the root, remove headers if any, and insert SRH or HBH
* (SRH is inserted only if the destination is in the DODAG) */
@ -733,13 +647,18 @@ rpl_update_header(void)
if(RPL_IS_NON_STORING(default_instance)) {
return insert_srh_header();
} else {
return insert_hbh_header();
return insert_hbh_header(default_instance);
}
} else {
if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)
&& UIP_IP_BUF->ttl == uip_ds6_if.cur_hop_limit) {
/* Insert HBH option at source. Checking the address is not sufficient because
* in non-storing mode, a packet may go up and then down the same path again */
return insert_hbh_header(default_instance);
} else {
/* Update HBH option at forwarders */
return update_hbh_header();
}
} else {
return 0;
}
}

View file

@ -67,6 +67,6 @@ rpl_ns_node_t *rpl_ns_node_next(rpl_ns_node_t *item);
rpl_ns_node_t *rpl_ns_get_node(const rpl_dag_t *dag, const uip_ipaddr_t *addr);
int rpl_ns_is_node_reachable(const rpl_dag_t *dag, const uip_ipaddr_t *addr);
void rpl_ns_get_node_global_addr(uip_ipaddr_t *addr, rpl_ns_node_t *node);
void rpl_ns_periodic();
void rpl_ns_periodic(void);
#endif /* RPL_NS_H */

View file

@ -34,17 +34,23 @@
#include "contiki-net.h"
#include "net/ethernet.h"
#include "net/ip/tcpip.h"
#include "net/ipv4/uip-neighbor.h"
#include "net/ethernet-drv.h"
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
PROCESS(ethernet_process, "Ethernet driver");
/*---------------------------------------------------------------------------*/
uint8_t
#if NETSTACK_CONF_WITH_IPV6
ethernet_output(const uip_lladdr_t *)
#else
ethernet_output(void)
#endif
{
uip_arp_out();
ethernet_send();
@ -61,7 +67,7 @@ pollhandler(void)
if(uip_len > 0) {
#if NETSTACK_CONF_WITH_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src);
uip_neighbor_add(&IPBUF->srcipaddr, (struct uip_neighbor_addr *)&BUF->src);
tcpip_input();
} else
#endif /* NETSTACK_CONF_WITH_IPV6 */

View file

@ -42,6 +42,10 @@ struct ethernet_config {
PROCESS_NAME(ethernet_process);
#if NETSTACK_CONF_WITH_IPV6
uint8_t ethernet_output(const uip_lladdr_t *);
#else
uint8_t ethernet_output(void);
#endif
#endif /* ETHERNET_DRV_H_ */

View file

@ -57,20 +57,6 @@ static RIE_BaseConfigs base_config = ADUCRF101_RADIO_BASE_CONFIG;
static int current_channel = 915000000;
static int current_power = 31;
static int radio_is_on = 0;
/*---------------------------------------------------------------------------*/
/* Sniffer configuration. We can re-use the CC2538 sniffer application
if we also accept CC2538_RF_CONF_SNIFFER. */
#ifndef ADUCRF101_RF_CONF_SNIFFER
#if CC2538_RF_CONF_SNIFFER
#define ADUCRF101_RF_CONF_SNIFFER 1
#endif
#endif
#if ADUCRF101_RF_CONF_SNIFFER
#include "dev/uart.h"
static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */
#endif
/*---------------------------------------------------------------------------*/
/* "Channel" is really frequency, and can be within the bands:
431000000 Hz to 464000000 Hz
@ -246,20 +232,6 @@ read(void *buf, unsigned short buf_len)
/* Re-enter receive mode immediately after receiving a packet */
RadioRxPacketVariableLen();
#if ADUCRF101_RF_CONF_SNIFFER
uart_put(magic[0]);
uart_put(magic[1]);
uart_put(magic[2]);
uart_put(magic[3]);
uart_put(packet_len + 2);
for(int i = 0; i < packet_len; i++) {
uart_put(((uint8_t *)buf)[i]);
}
/* FCS value is Wireshark's "TI CC24xx format" option: */
uart_put(rssi); /* RSSI */
uart_put(0x80); /* CRC is OK, LQI correlation is 0 */
#endif
return packet_len;
}
/*---------------------------------------------------------------------------*/

View file

@ -12,6 +12,7 @@ static struct timer debouncetimer;
static int status(int type);
static int enabled = 0;
volatile static int bstate;
volatile static int bstatei;
struct sensors_sensor *sensors[1];
unsigned char sensors_flags[1];
@ -22,18 +23,18 @@ unsigned char sensors_flags[1];
/*---------------------------------------------------------------------------*/
ISR(INT4_vect)
{
// leds_toggle(LEDS_RED);
if(BUTTON_CHECK_IRQ()) {
bstatei = (PINE & _BV(PE4) ? 0 : 1);
if(timer_expired(&debouncetimer)) {
// led1_on();
timer_set(&debouncetimer, CLOCK_SECOND / 8);
// led1_on();
timer_set(&debouncetimer, CLOCK_SECOND / 16);
bstate = (PINE & _BV(PE4) ? 0 : 1);
if(bstate == bstatei){
sensors_changed(&button_sensor);
}
// led1_off();
}
}
}
/*---------------------------------------------------------------------------*/

View file

@ -1796,8 +1796,8 @@ rf230_cca(void)
// if (cca & 0x40) {/*DEBUGFLOW('3')*/;} else {rf230_pending=1;DEBUGFLOW('4');}
if (cca & 0x40) {
// DEBUGFLOW('5');
// return 1;
return 0;
return 1;
// return 0;
} else {
// DEBUGFLOW('6');
busyexit:

View file

@ -39,8 +39,6 @@
* On the cc2538, character I/O can be directed over USB or UART. This is
* controlled by a series of configuration directives:
* - SLIP_ARCH_CONF_USB: Controls the operation of slip-arch.
* - CC2538_RF_CONF_SNIFFER_USB: Controls the output of the RF driver when
* operating as a sniffer
* - DBG_CONF_USB: Controls all debugging output
*
* Defaults for those defines are set in contiki-conf.h

View file

@ -91,29 +91,6 @@
/* 192 usec off -> on interval (RX Callib -> SFD Wait). We wait a bit more */
#define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
/*---------------------------------------------------------------------------*/
/* Sniffer configuration */
#ifndef CC2538_RF_CONF_SNIFFER_USB
#define CC2538_RF_CONF_SNIFFER_USB 0
#endif
#if CC2538_RF_CONF_SNIFFER
static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */
#if CC2538_RF_CONF_SNIFFER_USB
#include "usb/usb-serial.h"
#define write_byte(b) usb_serial_writeb(b)
#define flush() usb_serial_flush()
#else
#include "dev/uart.h"
#define write_byte(b) uart_write_byte(CC2538_RF_CONF_SNIFFER_UART, b)
#define flush()
#endif
#else /* CC2538_RF_CONF_SNIFFER */
#define write_byte(b)
#define flush()
#endif /* CC2538_RF_CONF_SNIFFER */
/*---------------------------------------------------------------------------*/
#ifdef CC2538_RF_CONF_AUTOACK
#define CC2538_RF_AUTOACK CC2538_RF_CONF_AUTOACK
#else
@ -135,9 +112,6 @@ static uint8_t volatile poll_mode = 0;
static uint8_t send_on_cca = 1;
static int8_t rssi;
static uint8_t crc_corr;
void mac_timer_init(void);
uint32_t get_sfd_timestamp(void);
/*---------------------------------------------------------------------------*/
static uint8_t rf_flags;
static uint8_t rf_channel = CC2538_RF_CHANNEL;
@ -185,8 +159,8 @@ get_channel()
{
uint8_t chan = REG(RFCORE_XREG_FREQCTRL) & RFCORE_XREG_FREQCTRL_FREQ;
return ((chan - CC2538_RF_CHANNEL_MIN) / CC2538_RF_CHANNEL_SPACING
+ CC2538_RF_CHANNEL_MIN);
return (chan - CC2538_RF_CHANNEL_MIN) / CC2538_RF_CHANNEL_SPACING
+ CC2538_RF_CHANNEL_MIN;
}
/*---------------------------------------------------------------------------*/
/**
@ -213,8 +187,9 @@ set_channel(uint8_t channel)
was_on = 1;
off();
}
REG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN
+ (channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING);
REG(RFCORE_XREG_FREQCTRL) = CC2538_RF_CHANNEL_MIN +
(channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING;
/* switch radio back on only if radio was on before - otherwise will turn on radio foor sleepy nodes */
if(was_on) {
on();
@ -222,7 +197,7 @@ set_channel(uint8_t channel)
rf_channel = channel;
return (int8_t) channel;
return (int8_t)channel;
}
/*---------------------------------------------------------------------------*/
static radio_value_t
@ -348,18 +323,32 @@ set_frame_filtering(uint8_t enable)
}
/*---------------------------------------------------------------------------*/
static void
mac_timer_init(void)
{
CLOCK_STABLE();
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_SYNC;
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_RUN;
while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE));
REG(RFCORE_SFR_MTCTRL) &= ~RFCORE_SFR_MTCTRL_RUN;
while(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE);
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_SYNC;
REG(RFCORE_SFR_MTCTRL) |= (RFCORE_SFR_MTCTRL_RUN);
while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE));
}
/*---------------------------------------------------------------------------*/
static void
set_poll_mode(uint8_t enable)
{
poll_mode = enable;
if(enable) {
mac_timer_init();
REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; // mask out FIFOP interrupt source
REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; // clear pending FIFOP interrupt
nvic_interrupt_disable(NVIC_INT_RF_RXTX); // disable RF interrupts
REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; /* mask out FIFOP interrupt source */
REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; /* clear pending FIFOP interrupt */
nvic_interrupt_disable(NVIC_INT_RF_RXTX); /* disable RF interrupts */
} else {
REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; // enable FIFOP interrupt source
nvic_interrupt_enable(NVIC_INT_RF_RXTX); // enable RF interrupts
REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; /* enable FIFOP interrupt source */
nvic_interrupt_enable(NVIC_INT_RF_RXTX); /* enable RF interrupts */
}
}
/*---------------------------------------------------------------------------*/
@ -379,6 +368,34 @@ set_auto_ack(uint8_t enable)
}
}
/*---------------------------------------------------------------------------*/
static uint32_t
get_sfd_timestamp(void)
{
uint64_t sfd, timer_val, buffer;
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000000;
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE;
timer_val = REG(RFCORE_SFR_MTM0) & RFCORE_SFR_MTM0_MTM0;
timer_val |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8);
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000000;
timer_val |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16);
timer_val |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24);
buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2;
timer_val |= (buffer << 32);
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000001;
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE;
sfd = REG(RFCORE_SFR_MTM0) & RFCORE_SFR_MTM0_MTM0;
sfd |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8);
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000010;
sfd |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16);
sfd |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24);
buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2;
sfd |= (buffer << 32);
return RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd);
}
/*---------------------------------------------------------------------------*/
/* Netstack API radio driver functions */
/*---------------------------------------------------------------------------*/
static int
@ -486,11 +503,6 @@ init(void)
REG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_AUTOACK;
#endif
/* If we are a sniffer, turn off frame filtering */
#if CC2538_RF_CONF_SNIFFER
REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN;
#endif
/* Disable source address matching and autopend */
REG(RFCORE_XREG_SRCMATCH) = 0;
@ -758,20 +770,6 @@ read(void *buf, unsigned short bufsize)
return 0;
}
#if CC2538_RF_CONF_SNIFFER
write_byte(magic[0]);
write_byte(magic[1]);
write_byte(magic[2]);
write_byte(magic[3]);
write_byte(len + 2);
for(i = 0; i < len; ++i) {
write_byte(((unsigned char *)(buf))[i]);
}
write_byte(rssi);
write_byte(crc_corr);
flush();
#endif
if(!poll_mode) {
/* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */
if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) {
@ -783,9 +781,7 @@ read(void *buf, unsigned short bufsize)
}
}
CC2538_RF_CSP_ISFLUSHRX();
return (len);
return len;
}
/*---------------------------------------------------------------------------*/
static int
@ -799,9 +795,9 @@ receiving_packet(void)
*
* FSMSTAT1 & (TX_ACTIVE | SFD) == SFD <=> receiving
*/
return ((REG(RFCORE_XREG_FSMSTAT1)
return (REG(RFCORE_XREG_FSMSTAT1)
& (RFCORE_XREG_FSMSTAT1_TX_ACTIVE | RFCORE_XREG_FSMSTAT1_SFD))
== RFCORE_XREG_FSMSTAT1_SFD);
== RFCORE_XREG_FSMSTAT1_SFD;
}
/*---------------------------------------------------------------------------*/
static int
@ -809,7 +805,7 @@ pending_packet(void)
{
PRINTF("RF: Pending\n");
return (REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP);
return REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP;
}
/*---------------------------------------------------------------------------*/
static radio_result_t
@ -968,7 +964,7 @@ get_object(radio_param_t param, void *dest, size_t size)
if(size != sizeof(rtimer_clock_t) || !dest) {
return RADIO_RESULT_INVALID_VALUE;
}
*(rtimer_clock_t*)dest = get_sfd_timestamp();
*(rtimer_clock_t *)dest = get_sfd_timestamp();
return RADIO_RESULT_OK;
}
@ -1127,44 +1123,4 @@ cc2538_rf_set_promiscous_mode(char p)
set_frame_filtering(p);
}
/*---------------------------------------------------------------------------*/
uint32_t get_sfd_timestamp(void)
{
uint64_t sfd, timer_val, buffer;
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000000;
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE;
timer_val = REG(RFCORE_SFR_MTM0) & RFCORE_SFR_MTM0_MTM0;
timer_val |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8);
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000000;
timer_val |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16);
timer_val |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24);
buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2;
timer_val |= (buffer << 32);
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000001;
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE;
sfd = REG(RFCORE_SFR_MTM0) & RFCORE_SFR_MTM0_MTM0;
sfd |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8);
REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000010;
sfd |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16);
sfd |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24);
buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2;
sfd |= (buffer << 32);
return (RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd));
}
/*---------------------------------------------------------------------------*/
void mac_timer_init(void)
{
CLOCK_STABLE();
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_SYNC;
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_RUN;
while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE));
REG(RFCORE_SFR_MTCTRL) &= ~RFCORE_SFR_MTCTRL_RUN;
while(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE);
REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_SYNC;
REG(RFCORE_SFR_MTCTRL) |= (RFCORE_SFR_MTCTRL_RUN);
while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE));
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -29,7 +29,7 @@
* SUCH DAMAGE.
*/
/**
* \addtogroup c2538-ecc-algo
* \addtogroup cc2538-ecc-algo
* @{
*
* \file

View file

@ -29,7 +29,7 @@
* SUCH DAMAGE.
*/
/**
* \addtogroup c2538-ecc-curves
* \addtogroup cc2538-ecc-curves
* @{
*/
#include "contiki.h"

View file

@ -171,7 +171,7 @@ i2c_single_send(uint8_t slave_addr, uint8_t data)
uint8_t
i2c_single_receive(uint8_t slave_addr, uint8_t *data)
{
uint32_t temp;
uint8_t temp;
i2c_master_set_slave_address(slave_addr, I2C_RECEIVE);
i2c_master_command(I2C_MASTER_CMD_SINGLE_RECEIVE);

View file

@ -90,7 +90,8 @@ permit_pm1(void)
}
/*---------------------------------------------------------------------------*/
int8_t
pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab)
pwm_enable(uint32_t freq, uint8_t duty, uint32_t count, uint8_t timer,
uint8_t ab)
{
uint8_t offset = 0;
uint32_t interval_load, duty_count, copy;
@ -109,7 +110,7 @@ pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab)
return PWM_ERROR;
}
PRINTF("PWM: F%08luHz: %u%% on GPT%u-%u\n", freq, duty, timer, ab);
PRINTF("PWM: F%08luHz: %u%%/%lu on GPT%u-%u\n", freq, duty, count, timer, ab);
lpm_register_peripheral(permit_pm1);
@ -147,14 +148,21 @@ pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab)
/* If the duty cycle is zero, leave the GPTIMER configured as PWM to pass a next
* configured check, but do nothing else */
if(!duty) {
if((!duty) && (!count)) {
REG(gpt_base + GPTIMER_CTL) |= (copy | gpt_dir);
return PWM_SUCCESS;
}
/* Get the peripheral clock and equivalent deassert count */
/* Get the peripheral clock and equivalent deassert count, depending on the
* value given by the user, either use the count number of the duty cycle in
* percentage
*/
interval_load = sys_ctrl_get_sys_clock() / freq;
if(duty) {
duty_count = ((interval_load * duty) + 1) / 100;
} else {
duty_count = count;
}
PRINTF("PWM: sys %luHz: %lu %lu\n", sys_ctrl_get_sys_clock(),
interval_load, duty_count);

View file

@ -116,11 +116,13 @@
/** \brief Configures the general purpose timer in PWM mode
* \param freq PWM frequency (in Hz)
* \param duty PWM duty cycle (percentage in integers)
* \param count PWM duty cycle (count number)
* \param timer General purpose timer to use [0-3]
* \param ab Select which timer to use (Timer A or B)
* \return \c PWM_SUCCESS if successful, else \c PWM_ERROR
*/
int8_t pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab);
int8_t pwm_enable(uint32_t freq, uint8_t duty, uint32_t count, uint8_t timer,
uint8_t ab);
/*---------------------------------------------------------------------------*/
/** \brief Disables a previously PWM configured GPTn
* \param timer General purpose timer to disable [0-3]

View file

@ -37,7 +37,7 @@
* \addtogroup cc2538-crypto
* @{
*
* \defgroup cc2538-sha526 cc2538 SHA-256
* \defgroup cc2538-sha256 cc2538 SHA-256
*
* Driver for the cc2538 SHA-256 mode of the security core
* @{

View file

@ -230,9 +230,7 @@ permit_pm1(void)
const uart_regs_t *regs;
for(regs = &uart_regs[0]; regs < &uart_regs[UART_INSTANCE_COUNT]; regs++) {
/* Note: UART_FR.TXFE reads 0 if the UART clock is gated. */
if((REG(SYS_CTRL_RCGCUART) & regs->sys_ctrl_rcgcuart_uart) != 0 &&
(REG(regs->base + UART_FR) & UART_FR_TXFE) == 0) {
if((REG(regs->base + UART_FR) & UART_FR_BUSY) != 0) {
return false;
}
}

View file

@ -101,11 +101,6 @@
#define CC2530_RF_TX_POWER_TXCTRL_MIN_VAL 0x09 /* Value for min TX Power */
#define CC2530_RF_TX_POWER_TXCTRL_DEF_VAL 0x69 /* Reset Value */
/*---------------------------------------------------------------------------*/
#if CC2530_RF_CONF_HEXDUMP
#include "dev/io-arch.h"
static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */
#endif
/*---------------------------------------------------------------------------*/
#ifdef CC2530_RF_CONF_AUTOACK
#define CC2530_RF_AUTOACK CC2530_RF_CONF_AUTOACK
#else
@ -531,15 +526,6 @@ read(void *buf, unsigned short bufsize)
return 0;
}
#if CC2530_RF_CONF_HEXDUMP
/* If we reach here, chances are the FIFO is holding a valid frame */
io_arch_writeb(magic[0]);
io_arch_writeb(magic[1]);
io_arch_writeb(magic[2]);
io_arch_writeb(magic[3]);
io_arch_writeb(len);
#endif
RF_RX_LED_ON();
PUTSTRING("RF: read (0x");
@ -548,9 +534,6 @@ read(void *buf, unsigned short bufsize)
len -= CHECKSUM_LEN;
for(i = 0; i < len; ++i) {
((unsigned char *)(buf))[i] = RFD;
#if CC2530_RF_CONF_HEXDUMP
io_arch_writeb(((unsigned char *)(buf))[i]);
#endif
PUTHEX(((unsigned char *)(buf))[i]);
}
PUTSTRING("\n");
@ -559,12 +542,6 @@ read(void *buf, unsigned short bufsize)
rssi = ((int8_t) RFD) - RSSI_OFFSET;
crc_corr = RFD;
#if CC2530_RF_CONF_HEXDUMP
io_arch_writeb(rssi);
io_arch_writeb(crc_corr);
io_arch_flush();
#endif
/* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
if(crc_corr & CRC_BIT_MASK) {
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);

View file

@ -73,6 +73,7 @@ CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c adc-sensor.c
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c
CONTIKI_CPU_SOURCEFILES += rf-core.c rf-ble.c ieee-mode.c
CONTIKI_CPU_SOURCEFILES += random.c soc-trng.c
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
@ -100,6 +101,12 @@ $(OBJECTDIR)/ieee-addr.o: ieee-addr.c FORCE | $(OBJECTDIR)
$(TRACE_CC)
$(Q)$(CC) $(CFLAGS) -c $< -o $@
### Always re-build ccfg.c so changes to ccfg-conf.h will apply without having
### to make clean first
$(OBJECTDIR)/ccfg.o: ccfg.c FORCE | $(OBJECTDIR)
$(TRACE_CC)
$(Q)$(CC) $(CFLAGS) -include "contiki-conf.h" -c $< -o $@
### Compilation rules
CUSTOM_RULE_LINK=1

View file

@ -36,6 +36,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/*---------------------------------------------------------------------------*/
LIST(consumers_list);
/*---------------------------------------------------------------------------*/

View file

@ -120,7 +120,7 @@ static void
disable_interrupts(void)
{
/* Acknowledge UART interrupts */
ti_lib_int_disable(INT_UART0);
ti_lib_int_disable(INT_UART0_COMB);
/* Disable all UART module interrupts */
ti_lib_uart_int_disable(UART0_BASE, CC26XX_UART_INTERRUPT_ALL);
@ -141,7 +141,7 @@ enable_interrupts(void)
ti_lib_uart_int_enable(UART0_BASE, CC26XX_UART_RX_INTERRUPT_TRIGGERS);
/* Acknowledge UART interrupts */
ti_lib_int_enable(INT_UART0);
ti_lib_int_enable(INT_UART0_COMB);
}
}
/*---------------------------------------------------------------------------*/
@ -154,7 +154,7 @@ configure(void)
* to avoid falling edge glitches
*/
ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_UART_TX);
ti_lib_gpio_pin_write(BOARD_UART_TX, 1);
ti_lib_gpio_set_dio(BOARD_IOID_UART_TX);
/*
* Map UART signals to the correct GPIO pins and configure them as

View file

@ -55,7 +55,7 @@ gpio_interrupt_register_handler(uint8_t ioid, gpio_interrupt_handler_t f)
uint8_t interrupts_disabled = ti_lib_int_master_disable();
/* Clear interrupts on specified pins */
ti_lib_gpio_event_clear(1 << ioid);
ti_lib_gpio_clear_event_dio(ioid);
handlers[ioid] = f;
@ -74,7 +74,7 @@ gpio_interrupt_init()
handlers[i] = NULL;
}
ti_lib_int_enable(INT_EDGE_DETECT);
ti_lib_int_enable(INT_AON_GPIO_EDGE);
}
/*---------------------------------------------------------------------------*/
void
@ -86,13 +86,13 @@ gpio_interrupt_isr(void)
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/* Read interrupt flags */
pin_mask = (HWREG(GPIO_BASE + GPIO_O_EVFLAGS31_0) & GPIO_PIN_MASK);
pin_mask = (HWREG(GPIO_BASE + GPIO_O_EVFLAGS31_0) & GPIO_DIO_ALL_MASK);
/* Clear the interrupt flags */
HWREG(GPIO_BASE + GPIO_O_EVFLAGS31_0) = pin_mask;
/* Run custom ISRs */
for(i = 0; i < NUM_GPIO_PINS; i++) {
for(i = 0; i < NUM_IO_MAX; i++) {
/* Call the handler if there is one registered for this event */
if((pin_mask & (1 << i)) && handlers[i] != NULL) {
handlers[i](i);

View file

@ -100,7 +100,7 @@ soc_rtc_init(void)
ti_lib_aon_rtc_channel_enable(AON_RTC_CH1);
ti_lib_aon_rtc_enable();
ti_lib_int_enable(INT_AON_RTC);
ti_lib_rom_int_enable(INT_AON_RTC_COMB);
/* Re-enable interrupts */
if(!interrupts_disabled) {

View file

@ -0,0 +1,315 @@
/*
* Copyright (c) 2016, University of Bristol - http://www.bristol.ac.uk
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 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-trng
* @{
*
* \file
*
* Implementation of the CC13xx/CC26xx RNG driver
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#include "lpm.h"
#include "sys/process.h"
#include "dev/soc-trng.h"
#include "ti-lib.h"
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/*---------------------------------------------------------------------------*/
#ifdef SOC_TRNG_CONF_CACHE_LEN
#define SOC_TRNG_CACHE_LEN SOC_TRNG_CONF_CACHE_LEN
#else
/** Size of the random number cache. Each slot holds 4 16-bit numbers */
#define SOC_TRNG_CACHE_LEN 4
#endif
/*---------------------------------------------------------------------------*/
#define MIN_REFILL_CYCLES_MAX 0x00000000
/*---------------------------------------------------------------------------*/
PROCESS(soc_trng_process, "CC13xx/CC26xx TRNG process");
/*---------------------------------------------------------------------------*/
static process_event_t rng_ready_event = PROCESS_EVENT_NONE;
/*---------------------------------------------------------------------------*/
static soc_trng_callback_t notify_cb = NULL;
/*---------------------------------------------------------------------------*/
#define soc_trng_isr TRNGIntHandler
/*---------------------------------------------------------------------------*/
static uint64_t rands_cache[SOC_TRNG_CACHE_LEN];
static bool rands_mask[SOC_TRNG_CACHE_LEN];
/*---------------------------------------------------------------------------*/
static void
disable_number_ready_interrupt(void)
{
ti_lib_trng_int_disable(TRNG_NUMBER_READY);
ti_lib_rom_int_disable(INT_TRNG_IRQ);
}
/*---------------------------------------------------------------------------*/
static void
enable_number_ready_interrupt(void)
{
ti_lib_trng_int_clear(TRNG_NUMBER_READY);
ti_lib_trng_int_enable(TRNG_NUMBER_READY);
ti_lib_rom_int_enable(INT_TRNG_IRQ);
}
/*---------------------------------------------------------------------------*/
static bool
accessible(void)
{
/* First, check the PD */
if(ti_lib_rom_prcm_power_domain_status(PRCM_DOMAIN_PERIPH)
!= PRCM_DOMAIN_POWER_ON) {
return false;
}
/* Then check the 'run mode' clock gate */
if(!(HWREG(PRCM_BASE + PRCM_O_SECDMACLKGR) &
PRCM_SECDMACLKGDS_TRNG_CLK_EN_M)) {
return false;
}
return true;
}
/*---------------------------------------------------------------------------*/
static void
power_up(void)
{
/* First, make sure the PERIPH PD is on */
ti_lib_rom_prcm_power_domain_on(PRCM_DOMAIN_PERIPH);
while((ti_lib_rom_prcm_power_domain_status(PRCM_DOMAIN_PERIPH)
!= PRCM_DOMAIN_POWER_ON));
/* Enable clock in active mode */
ti_lib_rom_prcm_peripheral_run_enable(PRCM_PERIPH_TRNG);
ti_lib_prcm_load_set();
while(!ti_lib_prcm_load_get());
}
/*---------------------------------------------------------------------------*/
static void
reset_synchronous(void)
{
ti_lib_trng_reset();
while(HWREG(TRNG_BASE + TRNG_O_SWRESET));
}
/*---------------------------------------------------------------------------*/
static uint8_t
request(void)
{
if(notify_cb) {
return LPM_MODE_SLEEP;
}
return LPM_MODE_MAX_SUPPORTED;
}
/*---------------------------------------------------------------------------*/
LPM_MODULE(rng_module, request, NULL, NULL, LPM_DOMAIN_NONE);
/*---------------------------------------------------------------------------*/
static uint64_t
read_number(void)
{
uint64_t ran = (uint64_t)HWREG(TRNG_BASE + TRNG_O_OUT1) << 32;
ran += ti_lib_rom_trng_number_get(TRNG_LOW_WORD);
return ran;
}
/*---------------------------------------------------------------------------*/
uint64_t
soc_trng_rand_synchronous()
{
uint64_t ran;
bool interrupts_disabled;
int i;
/* If the TRNG is gathering entropy, return a cached value */
if(notify_cb) {
for(i = 0; i < SOC_TRNG_CACHE_LEN; i++) {
if(rands_mask[i]) {
rands_mask[i] = false;
return rands_cache[i];
}
}
return 0;
}
if(!accessible()) {
power_up();
}
/*
* If we were previously enabled, we either have a number already available,
* or we need clock, which means we are calculating. If neither is true then
* we need setup from scratch.
*/
if((ti_lib_trng_status_get() & (TRNG_NEED_CLOCK | TRNG_NUMBER_READY)) == 0) {
reset_synchronous();
ti_lib_trng_configure(MIN_REFILL_CYCLES_MAX, SOC_TRNG_REFILL_CYCLES_MIN, 0);
ti_lib_trng_enable();
}
interrupts_disabled = ti_lib_int_master_disable();
while((ti_lib_trng_status_get() & TRNG_NUMBER_READY) == 0);
ran = read_number();
if(!interrupts_disabled) {
ti_lib_int_master_enable();
}
return ran;
}
/*---------------------------------------------------------------------------*/
uint8_t
soc_trng_rand_asynchronous(uint32_t samples, soc_trng_callback_t cb)
{
int i;
bool interrupts_disabled;
if(notify_cb != NULL) {
return SOC_TRNG_RAND_ASYNC_REQUEST_ERROR;
}
if(!accessible()) {
power_up();
}
/*
* First we need to cache some random numbers for general use in case the
* application requests them while we are calculating.
*
* If we were previously enabled, we either have a number already available,
* or we need clock, which means we are calculating. If neither is true then
* we need setup from scratch.
*/
if((ti_lib_trng_status_get() & (TRNG_NEED_CLOCK | TRNG_NUMBER_READY)) == 0) {
reset_synchronous();
}
interrupts_disabled = ti_lib_int_master_disable();
ti_lib_trng_disable();
ti_lib_trng_configure(MIN_REFILL_CYCLES_MAX, SOC_TRNG_REFILL_CYCLES_MIN, 0);
ti_lib_trng_enable();
/* Cache SOC_TRNG_CACHE_LEN min-entropy rands */
for(i = 0; i < SOC_TRNG_CACHE_LEN; i++) {
while((ti_lib_trng_status_get() & TRNG_NUMBER_READY) == 0);
rands_mask[i] = true;
rands_cache[i] = read_number();
}
/* Configure the RNG to the required entropy */
ti_lib_trng_disable();
ti_lib_trng_configure(MIN_REFILL_CYCLES_MAX, samples, 0);
/*
* Clear the TRNG_NUMBER_READY flag. This will trigger a new calculation
* as soon as the module gets enabled.
*/
ti_lib_trng_int_clear(TRNG_NUMBER_READY);
/* Enable clock in sleep mode and register with LPM */
ti_lib_rom_prcm_peripheral_sleep_enable(PRCM_PERIPH_TRNG);
ti_lib_prcm_load_set();
while(!ti_lib_prcm_load_get());
lpm_register_module(&rng_module);
notify_cb = cb;
/* Enable the number ready interrupt and fire-up the module */
enable_number_ready_interrupt();
ti_lib_trng_enable();
if(!interrupts_disabled) {
ti_lib_int_master_enable();
}
return SOC_TRNG_RAND_ASYNC_REQUEST_OK;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(soc_trng_process, ev, data)
{
PROCESS_BEGIN();
while(1) {
PROCESS_YIELD_UNTIL(ev == rng_ready_event);
if(notify_cb) {
uint64_t ran = read_number();
notify_cb(ran);
notify_cb = NULL;
}
/* Disable clock in sleep mode */
ti_lib_rom_prcm_peripheral_sleep_disable(PRCM_PERIPH_TRNG);
ti_lib_prcm_load_set();
while(!ti_lib_prcm_load_get());
lpm_unregister_module(&rng_module);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
soc_trng_isr(void)
{
ENERGEST_ON(ENERGEST_TYPE_IRQ);
ti_lib_trng_disable();
disable_number_ready_interrupt();
ti_lib_trng_configure(MIN_REFILL_CYCLES_MAX, SOC_TRNG_REFILL_CYCLES_MIN, 0);
ti_lib_trng_enable();
process_post(&soc_trng_process, rng_ready_event, NULL);
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
/*---------------------------------------------------------------------------*/
void
soc_trng_init()
{
if(rng_ready_event != PROCESS_EVENT_NONE) {
return;
}
/* Register the RNG ready event */
rng_ready_event = process_alloc_event();
process_start(&soc_trng_process, NULL);
}
/*---------------------------------------------------------------------------*/
/**
* @}
*/

View file

@ -0,0 +1,135 @@
/*
* Copyright (c) 2016, University of Bristol - http://www.bristol.ac.uk
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 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-trng CC13xx/CC26xx Random Number Generator
*
* Driver for the CC13xx/CC26xx Random Number Generator
*
* @{
*
* \file
*
* Header file for the CC13xx/CC26xx TRNG driver
*/
/*---------------------------------------------------------------------------*/
#ifndef SOC_TRNG_H_
#define SOC_TRNG_H_
/*---------------------------------------------------------------------------*/
#include <stdint.h>
/*---------------------------------------------------------------------------*/
#define SOC_TRNG_RAND_ASYNC_REQUEST_ERROR 0 /**< Async request rejected */
#define SOC_TRNG_RAND_ASYNC_REQUEST_OK 1 /**< Async request accepted */
/*---------------------------------------------------------------------------*/
#define SOC_TRNG_REFILL_CYCLES_MIN 0x00000100
#define SOC_TRNG_REFILL_CYCLES_MAX 0x00000000
/*---------------------------------------------------------------------------*/
/**
* \brief Pointer to a callback to be provided as an argument to
* soc_trng_rand_asynchronous()
*/
typedef void (*soc_trng_callback_t)(uint64_t rand);
/*---------------------------------------------------------------------------*/
/**
* \name TRNG functions
* @{
*/
/**
* \brief Returns a minimum entropy random number
* \return The random number
*
* This function is synchronous. This function will make sure the PERIPH PD is
* powered and the TRNG is clocked. The function will then configure the TRNG
* to generate a random number of minimum entropy. These numbers are not
* suitable for cryptographic usage, but their generation is very fast.
*
* If a high-entropy random number is currently being generated, this function
* will return a cached random number. The cache is of configurable size and
* can hold a maximum SOC_TRNG_CONF_CACHE_LEN numbers. If the cache gets
* emptied while high-entropy generation is in progress (e.g. because a
* function requested many random numbers in a row), this function will return
* 0. Care must therefore be taken when the return value is 0, which can also
* be a valid random number.
*
* This function can be safely called from within an interrupt context.
*/
uint64_t soc_trng_rand_synchronous();
/**
* \brief Initialise the CC13xx/CC26xx TRNG driver
*/
void soc_trng_init(void);
/**
* \brief Request a 64-bit, configurable-entropy random number
* \param samples Controls the entropy generated for the random number
* \param cb A callback function to be called when the generation is complete
* \retval SOC_TRNG_RAND_ASYNC_REQUEST_ERROR There was an error adding request.
* \retval SOC_TRNG_RAND_ASYNC_REQUEST_OK Request successfully registered
*
* This function is asynchronous, it will start generation of a random number
* and will return. The caller must provide a callback that will be called when
* the generation is complete. This callback must either use the random number
* immediately or store it, since it will not be possible to retrieve it again
* later form the soc-trng module.
*
* Only one generation can be active at any given point in time. If this
* function gets called when a generation is already in progress, it will
* return SOC_TRNG_RAND_ASYNC_REQUEST_ERROR.
*
* The function will configure the TRNG to generate entropy by sampling the
* FROs for a number clock cycles controlled by the samples argument. The 8 LS
* bits of this argument will be truncated by CC13xxware/CC26xxware and the
* resulting number of clock cycles will be (samples >> 8) * 2^8. Increasing
* the value of this argument increases entropy, but it also increases latency.
* Maximum entropy can be generated by passing SOC_TRNG_REFILL_CYCLES_MAX, but
* this will take approximately 350ms. Consult the chip's technical reference
* manual for advice on what would constitute sufficient entropy for random
* numbers meant to be used for crypto.
*
* While this function is executing, calls to soc_trng_rand_synchronous() will
* return cached random numbers.
*
* This function is not re-entrant and must not be called from an interrupt
* context.
*/
uint8_t soc_trng_rand_asynchronous(uint32_t samples, soc_trng_callback_t cb);
/** @} */
/*---------------------------------------------------------------------------*/
#endif /* SOC_TRNG_H_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View file

@ -83,7 +83,7 @@ LIST(modules_list);
#define SLEEP_GUARD_TIME (RTIMER_SECOND / 1000) /* 1.0 ms */
#define MAX_SLEEP_TIME RTIMER_SECOND
#define MINIMAL_SAFE_SCHEDULE 8u
#define MIN_SAFE_SCHEDULE 8u
/*---------------------------------------------------------------------------*/
/* Prototype of a function in clock.c. Called every time we come out of DS */
void clock_update(void);
@ -127,7 +127,7 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
/* Configure the wakeup trigger */
if(wakeup_pin != IOID_UNUSED) {
ti_lib_gpio_dir_mode_set((1 << wakeup_pin), GPIO_DIR_MODE_IN);
ti_lib_gpio_set_output_enable_dio(wakeup_pin, GPIO_OUTPUT_DISABLE);
ti_lib_ioc_port_configure_set(wakeup_pin, IOC_PORT_GPIO, io_cfg);
}
@ -251,71 +251,71 @@ wake_up(void)
#endif
}
/*---------------------------------------------------------------------------*/
static int
setup_sleep_mode(rtimer_clock_t *next_timer)
static uint8_t
check_next_rtimer(rtimer_clock_t now, rtimer_clock_t *next_rtimer, bool *next_rtimer_set)
{
uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
if(ti_lib_aon_rtc_channel_active(AON_RTC_CH0)) {
*next_rtimer_set = true;
/* find out the timer of the next rtimer interrupt */
*next_rtimer = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0);
if(RTIMER_CLOCK_LT(*next_rtimer, now + 2)) {
max_pm = MIN(max_pm, LPM_MODE_AWAKE);
} else if(RTIMER_CLOCK_LT(*next_rtimer, now + STANDBY_MIN_DURATION)) {
max_pm = MIN(max_pm, LPM_MODE_SLEEP);
}
} else {
*next_rtimer_set = false;
}
return max_pm;
}
/*---------------------------------------------------------------------------*/
static uint8_t
check_next_etimer(rtimer_clock_t now, rtimer_clock_t *next_etimer, bool *next_etimer_set)
{
uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
*next_etimer_set = false;
/* Find out the time of the next etimer */
if(etimer_pending()) {
int32_t until_next_etimer = (int32_t)etimer_next_expiration_time() - (int32_t)clock_time();
if(until_next_etimer < 1) {
max_pm = MIN(max_pm, LPM_MODE_AWAKE);
} else {
*next_etimer_set = true;
*next_etimer = soc_rtc_last_isr_time() + (until_next_etimer * (RTIMER_SECOND / CLOCK_SECOND));
if(RTIMER_CLOCK_LT(*next_etimer, now + STANDBY_MIN_DURATION)) {
max_pm = MIN(max_pm, LPM_MODE_SLEEP);
}
}
}
return max_pm;
}
/*---------------------------------------------------------------------------*/
static uint8_t
setup_sleep_mode(void)
{
lpm_registered_module_t *module;
uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
uint8_t pm;
rtimer_clock_t now = RTIMER_NOW();
const rtimer_clock_t max_sleep = now + MAX_SLEEP_TIME;
/* next_timer will hold the time of the next system wakeup due to a timer*/
*next_timer = max_sleep;
rtimer_clock_t now;
rtimer_clock_t next_rtimer = 0;
rtimer_clock_t next_etimer = 0;
bool next_rtimer_set = false;
bool next_etimer_set = false;
/* Check if any events fired before we turned interrupts off. If so, abort */
if(LPM_MODE_MAX_SUPPORTED == LPM_MODE_AWAKE || process_nevents()) {
return LPM_MODE_AWAKE;
}
if(ti_lib_aon_rtc_channel_active(AON_RTC_CH0)) {
rtimer_clock_t next_rtimer;
/* find out the timer of the next rtimer interrupt */
next_rtimer = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0);
if(RTIMER_CLOCK_LT(next_rtimer, now + 2)) {
return LPM_MODE_AWAKE;
}
if(RTIMER_CLOCK_LT(next_rtimer, now + STANDBY_MIN_DURATION)) {
return LPM_MODE_SLEEP;
}
*next_timer = next_rtimer;
}
/* also find out the timer of the next etimer */
if(etimer_pending()) {
int32_t until_next_etimer;
rtimer_clock_t next_etimer;
until_next_etimer = (int32_t)etimer_next_expiration_time() - (int32_t)clock_time();
if(until_next_etimer < 1) {
return LPM_MODE_AWAKE;
}
next_etimer = soc_rtc_last_isr_time() + (until_next_etimer * (RTIMER_SECOND / CLOCK_SECOND));
if(RTIMER_CLOCK_LT(next_etimer, now + STANDBY_MIN_DURATION)) {
/* ensure that we schedule sleep a minimal number of ticks into the
future */
soc_rtc_schedule_one_shot(AON_RTC_CH1, now + MINIMAL_SAFE_SCHEDULE);
return LPM_MODE_SLEEP;
}
if(RTIMER_CLOCK_LT(max_sleep, next_etimer)) {
/* if max_pm is LPM_MODE_SLEEP, we could trigger the watchdog if we slept
for too long. */
if(RTIMER_CLOCK_LT(max_sleep, *next_timer)) {
soc_rtc_schedule_one_shot(AON_RTC_CH1, max_sleep);
}
} else {
/* Reschedule AON RTC CH1 to fire just in time for the next etimer event */
soc_rtc_schedule_one_shot(AON_RTC_CH1, next_etimer);
}
if(RTIMER_CLOCK_LT(next_etimer, *next_timer)) {
/* set `next_timer` to the time the first etimer fires */
*next_timer = next_etimer;
}
}
/* Collect max allowed PM permission from interested modules */
for(module = list_head(modules_list); module != NULL;
module = module->next) {
@ -327,6 +327,60 @@ setup_sleep_mode(rtimer_clock_t *next_timer)
}
}
now = RTIMER_NOW();
pm = check_next_rtimer(now, &next_rtimer, &next_rtimer_set);
if(pm < max_pm) {
max_pm = pm;
}
pm = check_next_etimer(now, &next_etimer, &next_etimer_set);
if(pm < max_pm) {
max_pm = pm;
}
if(max_pm == LPM_MODE_SLEEP) {
if(next_etimer_set) {
/* Schedule the next system wakeup due to etimer */
if(RTIMER_CLOCK_LT(next_etimer, now + MIN_SAFE_SCHEDULE)) {
/* Too soon in future, use this minimal interval instead */
next_etimer = now + MIN_SAFE_SCHEDULE;
} else if(RTIMER_CLOCK_LT(now + MAX_SLEEP_TIME, next_etimer)) {
/* Too far in future, use MAX_SLEEP_TIME instead */
next_etimer = now + MAX_SLEEP_TIME;
}
soc_rtc_schedule_one_shot(AON_RTC_CH1, next_etimer);
} else {
/* No etimers set. Since by default the CH1 RTC fires once every clock tick,
* need to explicitly schedule a wakeup in the future to save energy.
* But do not stay in this mode for too long, otherwise watchdog will be trigerred. */
soc_rtc_schedule_one_shot(AON_RTC_CH1, now + MAX_SLEEP_TIME);
}
} else if(max_pm == LPM_MODE_DEEP_SLEEP) {
/* Watchdog is not enabled, so deep sleep can continue an arbitrary long time.
* On the other hand, if `CC2650_FAST_RADIO_STARTUP` is defined,
* early wakeup before the next rtimer should be scheduled. */
#if CC2650_FAST_RADIO_STARTUP
if(next_rtimer_set) {
if(!next_etimer_set || RTIMER_CLOCK_LT(next_rtimer - SLEEP_GUARD_TIME, next_etimer)) {
/* schedule a wakeup briefly before the next rtimer to wake up the system */
soc_rtc_schedule_one_shot(AON_RTC_CH2, next_rtimer - SLEEP_GUARD_TIME);
}
}
#endif
if(next_etimer_set) {
/* Schedule the next system wakeup due to etimer.
* No need to compare the `next_etimer` to `now` here as this branch
* is only entered when there's sufficient time for deep sleeping. */
soc_rtc_schedule_one_shot(AON_RTC_CH1, next_etimer);
} else {
/* Use the farthest possible wakeup time */
soc_rtc_schedule_one_shot(AON_RTC_CH1, now - 1);
}
}
return max_pm;
}
/*---------------------------------------------------------------------------*/
@ -350,16 +404,11 @@ lpm_sleep(void)
}
/*---------------------------------------------------------------------------*/
static void
deep_sleep(rtimer_clock_t next_timer)
deep_sleep(void)
{
uint32_t domains = LOCKABLE_DOMAINS;
lpm_registered_module_t *module;
#if CC2650_FAST_RADIO_STARTUP
/* schedule a wakeup briefly before the next etimer/rtimer to wake up the system */
soc_rtc_schedule_one_shot(AON_RTC_CH2, next_timer - SLEEP_GUARD_TIME);
#endif
/*
* Notify all registered modules that we are dropping to mode X. We do not
* need to do this for simple sleep.
@ -490,18 +539,17 @@ void
lpm_drop()
{
uint8_t max_pm;
rtimer_clock_t next_timer;
/* Critical. Don't get interrupted! */
ti_lib_int_master_disable();
max_pm = setup_sleep_mode(&next_timer);
max_pm = setup_sleep_mode();
/* Drop */
if(max_pm == LPM_MODE_SLEEP) {
lpm_sleep();
} else if(max_pm == LPM_MODE_DEEP_SLEEP) {
deep_sleep(next_timer);
deep_sleep();
}
ti_lib_int_master_enable();
@ -536,7 +584,7 @@ lpm_pin_set_default_state(uint32_t ioid)
}
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);
ti_lib_gpio_set_output_enable_dio(ioid, GPIO_OUTPUT_DISABLE);
}
/*---------------------------------------------------------------------------*/
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
* Copyright (c) 2016, University of Bristol - http://www.bristol.ac.uk
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -10,7 +10,6 @@
* 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.
@ -28,40 +27,39 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup zoul-examples
* @{
*
* \defgroup zoul-cc1200-sniffer CC1200 Sniffer
*
* Sniffer for the Zolertia's Zoul CC1200 on-board radio
*
* This example is to be used combined with the sensniff host-side tool,
* which can be downloaded from: https://github.com/g-oikonomou/sensniff
*
* \addtogroup cc26xx-trng
* @{
*
* \file
* Implementation of a Sniffer Process Thread
*
* This file overrides core/lib/random.c and calls SoC-specific RNG functions
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#define DEBUG DEBUG_NONE
#include "net/ip/uip-debug.h"
#include "dev/soc-trng.h"
/*---------------------------------------------------------------------------*/
PROCESS(sniffer_process, "Sniffer process");
AUTOSTART_PROCESSES(&sniffer_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sniffer_process, ev, data)
/**
* \brief Generates a new random number using the hardware TRNG.
* \return The random number.
*/
unsigned short
random_rand(void)
{
PROCESS_BEGIN();
PRINTF("Sniffer started\n");
PROCESS_EXIT();
PROCESS_END();
return (unsigned short)soc_trng_rand_synchronous() & 0xFFFF;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Function required by the API
* \param seed Ignored.
*/
void
random_init(unsigned short seed)
{
soc_trng_init();
}
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View file

@ -763,9 +763,9 @@ check_rat_overflow(bool first_time)
{
static uint32_t last_value;
uint32_t current_value;
uint8_t interrupts_enabled;
uint8_t interrupts_disabled;
interrupts_enabled = ti_lib_int_master_disable();
interrupts_disabled = ti_lib_int_master_disable();
if(first_time) {
last_value = HWREG(RFC_RAT_BASE + RATCNT);
} else {
@ -777,7 +777,7 @@ check_rat_overflow(bool first_time)
}
last_value = current_value;
}
if(interrupts_enabled) {
if(!interrupts_disabled) {
ti_lib_int_master_enable();
}
}
@ -867,7 +867,6 @@ transmit(unsigned short transmit_len)
uint8_t tx_active = 0;
rtimer_clock_t t0;
volatile rfc_CMD_IEEE_TX_t cmd;
uint8_t interrupts_enabled;
if(!rf_is_on()) {
was_off = 1;
@ -908,16 +907,8 @@ transmit(unsigned short transmit_len)
cmd.startTime = 0;
cmd.startTrigger.triggerType = TRIG_NOW;
/* XXX: there seems to be no function that gets interrupt state w/o changing it */
interrupts_enabled = ti_lib_int_master_disable();
if(interrupts_enabled) {
ti_lib_int_master_enable();
}
/* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */
if(interrupts_enabled) {
rf_core_cmd_done_en(true, poll_mode);
}
ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status);
@ -934,7 +925,7 @@ transmit(unsigned short transmit_len)
* 1) make the `lpm_sleep()` call here unconditional;
* 2) change the radio ISR priority to allow radio ISR to interrupt rtimer ISR.
*/
if(interrupts_enabled) {
if(!poll_mode) {
lpm_sleep();
}
}
@ -966,13 +957,11 @@ transmit(unsigned short transmit_len)
ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
if(interrupts_enabled) {
/*
* Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it
* except when we are transmitting
*/
rf_core_cmd_done_dis(poll_mode);
}
if(was_off) {
off();
@ -1222,13 +1211,11 @@ on(void)
return RF_CORE_CMD_OK;
}
#if !CC2650_FAST_RADIO_STARTUP
/*
* 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.
*/
oscillators_request_hf_xosc();
#endif
if(rf_is_on()) {
PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(),

View file

@ -107,16 +107,6 @@
#define PROP_MODE_USE_CRC16 0
#endif
/*---------------------------------------------------------------------------*/
#ifdef PROP_MODE_CONF_SNIFFER
#define PROP_MODE_SNIFFER PROP_MODE_CONF_SNIFFER
#else
#define PROP_MODE_SNIFFER 0
#endif
#if PROP_MODE_SNIFFER
static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 };
#endif
/*---------------------------------------------------------------------------*/
/**
* \brief Returns the current status of a running Radio Op command
* \param a A pointer with the buffer used to initiate the command
@ -773,28 +763,7 @@ read_frame(void *buf, unsigned short buf_len)
}
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (int8_t)data_ptr[len]);
#if PROP_MODE_SNIFFER
{
int i;
cc26xx_uart_write_byte(magic[0]);
cc26xx_uart_write_byte(magic[1]);
cc26xx_uart_write_byte(magic[2]);
cc26xx_uart_write_byte(magic[3]);
cc26xx_uart_write_byte(len + 2);
for(i = 0; i < len; ++i) {
cc26xx_uart_write_byte(((uint8_t *)(buf))[i]);
}
cc26xx_uart_write_byte((uint8_t)rx_stats.lastRssi);
cc26xx_uart_write_byte(0x80);
while(cc26xx_uart_busy() == UART_BUSY);
}
#endif
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, 0x7F);
}
/* Move read entry pointer to next entry */
@ -1082,6 +1051,8 @@ set_value(radio_param_t param, radio_value_t value)
rv = RADIO_RESULT_ERROR;
}
return RADIO_RESULT_OK;
case RADIO_PARAM_RX_MODE:
return RADIO_RESULT_OK;
case RADIO_PARAM_CCA_THRESHOLD:
rssi_threshold = (int8_t)value;
@ -1104,7 +1075,7 @@ set_value(radio_param_t param, radio_value_t value)
rv = RADIO_RESULT_ERROR;
}
if(rx_on_prop() != RF_CORE_CMD_OK) {
if(soft_on_prop() != RF_CORE_CMD_OK) {
PRINTF("set_value: rx_on_prop() failed\n");
rv = RADIO_RESULT_ERROR;
}

View file

@ -236,10 +236,10 @@ rf_core_power_up()
uint32_t cmd_status;
bool interrupts_disabled = 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);
ti_lib_int_disable(INT_RF_CPE1);
ti_lib_int_pend_clear(INT_RFC_CPE_0);
ti_lib_int_pend_clear(INT_RFC_CPE_1);
ti_lib_int_disable(INT_RFC_CPE_0);
ti_lib_int_disable(INT_RFC_CPE_1);
/* Enable RF Core power domain */
ti_lib_prcm_power_domain_on(PRCM_DOMAIN_RFCORE);
@ -252,8 +252,8 @@ rf_core_power_up()
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
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_enable(INT_RFC_CPE_0);
ti_lib_int_enable(INT_RFC_CPE_1);
if(!interrupts_disabled) {
ti_lib_int_master_enable();
@ -335,8 +335,8 @@ void
rf_core_power_down()
{
bool interrupts_disabled = ti_lib_int_master_disable();
ti_lib_int_disable(INT_RF_CPE0);
ti_lib_int_disable(INT_RF_CPE1);
ti_lib_int_disable(INT_RFC_CPE_0);
ti_lib_int_disable(INT_RFC_CPE_1);
if(rf_core_is_accessible()) {
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
@ -358,10 +358,10 @@ rf_core_power_down()
while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE)
!= PRCM_DOMAIN_POWER_OFF);
ti_lib_int_pend_clear(INT_RF_CPE0);
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_pend_clear(INT_RFC_CPE_0);
ti_lib_int_pend_clear(INT_RFC_CPE_1);
ti_lib_int_enable(INT_RFC_CPE_0);
ti_lib_int_enable(INT_RFC_CPE_1);
if(!interrupts_disabled) {
ti_lib_int_master_enable();
}
@ -371,27 +371,18 @@ uint8_t
rf_core_set_modesel()
{
uint8_t rv = RF_CORE_CMD_ERROR;
ChipType_t chip_type = ti_lib_chipinfo_get_chip_type();
if(ti_lib_chipinfo_chip_family_is_cc26xx()) {
if(ti_lib_chipinfo_supports_ble() == true &&
ti_lib_chipinfo_supports_ieee_802_15_4() == true) {
/* CC2650 */
if(chip_type == CHIP_TYPE_CC2650) {
HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
rv = RF_CORE_CMD_OK;
} else if(ti_lib_chipinfo_supports_ble() == false &&
ti_lib_chipinfo_supports_ieee_802_15_4() == true) {
/* CC2630 */
} else if(chip_type == CHIP_TYPE_CC2630) {
HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE2;
rv = RF_CORE_CMD_OK;
}
} else if(ti_lib_chipinfo_chip_family_is_cc13xx()) {
if(ti_lib_chipinfo_supports_ble() == false &&
ti_lib_chipinfo_supports_ieee_802_15_4() == false) {
/* CC1310 */
} else if(chip_type == CHIP_TYPE_CC1310) {
HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3;
rv = RF_CORE_CMD_OK;
}
}
return rv;
}
@ -462,10 +453,10 @@ rf_core_setup_interrupts(bool poll_mode)
/* Clear interrupt flags, active low clear(?) */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
ti_lib_int_pend_clear(INT_RF_CPE0);
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_pend_clear(INT_RFC_CPE_0);
ti_lib_int_pend_clear(INT_RFC_CPE_1);
ti_lib_int_enable(INT_RFC_CPE_0);
ti_lib_int_enable(INT_RFC_CPE_1);
if(!interrupts_disabled) {
ti_lib_int_master_enable();

View file

@ -0,0 +1,193 @@
/*
* Copyright (c) 2016, 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-ti-lib
* @{
*
* \file
* Header file with CC13xxware/CC26xxware ROM API.
*/
/*---------------------------------------------------------------------------*/
#ifndef TI_LIB_ROM_H_
#define TI_LIB_ROM_H_
/*---------------------------------------------------------------------------*/
/* rom.h */
#include "driverlib/rom.h"
/* AON API */
#define ti_lib_rom_aon_event_mcu_wake_up_set ROM_AONEventMcuWakeUpSet
#define ti_lib_rom_aon_event_mcu_wake_up_get ROM_AONEventMcuWakeUpGet
#define ti_lib_rom_aon_event_aux_wake_up_set ROM_AONEventAuxWakeUpSet
#define ti_lib_rom_aon_event_aux_wake_up_get ROM_AONEventAuxWakeUpGet
#define ti_lib_rom_aon_event_mcu_set ROM_AONEventMcuSet
#define ti_lib_rom_aon_event_mcu_get ROM_AONEventMcuGet
/* AON_WUC API */
#define ti_lib_rom_aon_wuc_aux_reset ROM_AONWUCAuxReset
#define ti_lib_rom_aon_wuc_recharge_ctrl_config_set ROM_AONWUCRechargeCtrlConfigSet
#define ti_lib_rom_aon_wuc_osc_config ROM_AONWUCOscConfig
/* AUX_TDC API */
#define ti_lib_rom_aux_tdc_config_set ROM_AUXTDCConfigSet
#define ti_lib_rom_aux_tdc_measurement_done ROM_AUXTDCMeasurementDone
/* AUX_WUC API */
#define ti_lib_rom_aux_wuc_clock_enable ROM_AUXWUCClockEnable
#define ti_lib_rom_aux_wuc_clock_disable ROM_AUXWUCClockDisable
#define ti_lib_rom_aux_wuc_clock_status ROM_AUXWUCClockStatus
#define ti_lib_rom_aux_wuc_power_ctrl ROM_AUXWUCPowerCtrl
/* FLASH API */
#define ti_lib_rom_flash_power_mode_get ROM_FlashPowerModeGet
#define ti_lib_rom_flash_protection_set ROM_FlashProtectionSet
#define ti_lib_rom_flash_protection_get ROM_FlashProtectionGet
#define ti_lib_rom_flash_protection_save ROM_FlashProtectionSave
#define ti_lib_rom_flash_efuse_read_row ROM_FlashEfuseReadRow
#define ti_lib_rom_flash_disable_sectors_for_write ROM_FlashDisableSectorsForWrite
/* I2C API */
#define ti_lib_rom_i2c_master_init_exp_clk ROM_I2CMasterInitExpClk
#define ti_lib_rom_i2c_master_err ROM_I2CMasterErr
/* INTERRUPT API */
#define ti_lib_rom_int_priority_grouping_set ROM_IntPriorityGroupingSet
#define ti_lib_rom_int_priority_grouping_get ROM_IntPriorityGroupingGet
#define ti_lib_rom_int_priority_set ROM_IntPrioritySet
#define ti_lib_rom_int_priority_get ROM_IntPriorityGet
#define ti_lib_rom_int_enable ROM_IntEnable
#define ti_lib_rom_int_disable ROM_IntDisable
#define ti_lib_rom_int_pend_set ROM_IntPendSet
#define ti_lib_rom_int_pend_get ROM_IntPendGet
#define ti_lib_rom_int_pend_clear ROM_IntPendClear
/* IOC API */
#define ti_lib_rom_ioc_port_configure_set ROM_IOCPortConfigureSet
#define ti_lib_rom_ioc_port_configure_get ROM_IOCPortConfigureGet
#define ti_lib_rom_ioc_io_shutdown_set ROM_IOCIOShutdownSet
#define ti_lib_rom_ioc_io_mode_set ROM_IOCIOModeSet
#define ti_lib_rom_ioc_io_int_set ROM_IOCIOIntSet
#define ti_lib_rom_ioc_io_port_pull_set ROM_IOCIOPortPullSet
#define ti_lib_rom_ioc_io_hyst_set ROM_IOCIOHystSet
#define ti_lib_rom_ioc_io_input_set ROM_IOCIOInputSet
#define ti_lib_rom_ioc_io_slew_ctrl_set ROM_IOCIOSlewCtrlSet
#define ti_lib_rom_ioc_io_drv_strength_set ROM_IOCIODrvStrengthSet
#define ti_lib_rom_ioc_io_port_id_set ROM_IOCIOPortIdSet
#define ti_lib_rom_ioc_int_enable ROM_IOCIntEnable
#define ti_lib_rom_ioc_int_disable ROM_IOCIntDisable
#define ti_lib_rom_ioc_pin_type_gpio_input ROM_IOCPinTypeGpioInput
#define ti_lib_rom_ioc_pin_type_gpio_output ROM_IOCPinTypeGpioOutput
#define ti_lib_rom_ioc_pin_type_uart ROM_IOCPinTypeUart
#define ti_lib_rom_ioc_pin_type_ssi_master ROM_IOCPinTypeSsiMaster
#define ti_lib_rom_ioc_pin_type_ssi_slave ROM_IOCPinTypeSsiSlave
#define ti_lib_rom_ioc_pin_type_i2c ROM_IOCPinTypeI2c
#define ti_lib_rom_ioc_pin_type_aux ROM_IOCPinTypeAux
/* PRCM API */
#define ti_lib_rom_prcm_inf_clock_configure_set ROM_PRCMInfClockConfigureSet
#define ti_lib_rom_prcm_inf_clock_configure_get ROM_PRCMInfClockConfigureGet
#define ti_lib_rom_prcm_audio_clock_config_set ROM_PRCMAudioClockConfigSet
#define ti_lib_rom_prcm_power_domain_on ROM_PRCMPowerDomainOn
#define ti_lib_rom_prcm_power_domain_off ROM_PRCMPowerDomainOff
#define ti_lib_rom_prcm_peripheral_run_enable ROM_PRCMPeripheralRunEnable
#define ti_lib_rom_prcm_peripheral_run_disable ROM_PRCMPeripheralRunDisable
#define ti_lib_rom_prcm_peripheral_sleep_enable ROM_PRCMPeripheralSleepEnable
#define ti_lib_rom_prcm_peripheral_sleep_disable ROM_PRCMPeripheralSleepDisable
#define ti_lib_rom_prcm_peripheral_deep_sleep_enable ROM_PRCMPeripheralDeepSleepEnable
#define ti_lib_rom_prcm_peripheral_deep_sleep_disable ROM_PRCMPeripheralDeepSleepDisable
#define ti_lib_rom_prcm_power_domain_status ROM_PRCMPowerDomainStatus
#define ti_lib_rom_prcm_deep_sleep ROM_PRCMDeepSleep
/* SMPH API */
#define ti_lib_rom_smph_acquire ROM_SMPHAcquire
/* SSI API */
#define ti_lib_rom_ssi_config_set_exp_clk ROM_SSIConfigSetExpClk
#define ti_lib_rom_ssi_data_put ROM_SSIDataPut
#define ti_lib_rom_ssi_data_put_non_blocking ROM_SSIDataPutNonBlocking
#define ti_lib_rom_ssi_data_get ROM_SSIDataGet
#define ti_lib_rom_ssi_data_get_non_blocking ROM_SSIDataGetNonBlocking
/* TIMER API */
#define ti_lib_rom_timer_configure ROM_TimerConfigure
#define ti_lib_rom_timer_level_control ROM_TimerLevelControl
#define ti_lib_rom_timer_stall_control ROM_TimerStallControl
#define ti_lib_rom_timer_wait_on_trigger_control ROM_TimerWaitOnTriggerControl
/* TRNG API */
#define ti_lib_rom_trng_number_get ROM_TRNGNumberGet
/* UART API */
#define ti_lib_rom_uart_fifo_level_get ROM_UARTFIFOLevelGet
#define ti_lib_rom_uart_config_set_exp_clk ROM_UARTConfigSetExpClk
#define ti_lib_rom_uart_config_get_exp_clk ROM_UARTConfigGetExpClk
#define ti_lib_rom_uart_disable ROM_UARTDisable
#define ti_lib_rom_uart_char_get_non_blocking ROM_UARTCharGetNonBlocking
#define ti_lib_rom_uart_char_get ROM_UARTCharGet
#define ti_lib_rom_uart_char_put_non_blocking ROM_UARTCharPutNonBlocking
#define ti_lib_rom_uart_char_put ROM_UARTCharPut
/* UDMA API */
#define ti_lib_rom_udma_channel_attribute_enable ROM_uDMAChannelAttributeEnable
#define ti_lib_rom_udma_channel_attribute_disable ROM_uDMAChannelAttributeDisable
#define ti_lib_rom_udma_channel_attribute_get ROM_uDMAChannelAttributeGet
#define ti_lib_rom_udma_channel_control_set ROM_uDMAChannelControlSet
#define ti_lib_rom_udma_channel_transfer_set ROM_uDMAChannelTransferSet
#define ti_lib_rom_udma_channel_scatter_gather_set ROM_uDMAChannelScatterGatherSet
#define ti_lib_rom_udma_channel_size_get ROM_uDMAChannelSizeGet
#define ti_lib_rom_udma_channel_mode_get ROM_uDMAChannelModeGet
/* VIMS API */
#define ti_lib_rom_vims_configure ROM_VIMSConfigure
#define ti_lib_rom_vims_mode_set ROM_VIMSModeSet
/* HAPI */
#define ti_lib_hapi_crc32(a, b, c) HapiCrc32(a, b, c)
#define ti_lib_hapi_get_flash_size() HapiGetFlashSize()
#define ti_lib_hapi_get_chip_id() HapiGetChipId()
#define ti_lib_hapi_sector_erase(a) HapiSectorErase(a)
#define ti_lib_hapi_program_flash(a, b, c) HapiProgramFlash(a, b, c)
#define ti_lib_hapi_reset_device() HapiResetDevice()
#define ti_lib_hapi_fletcher32(a, b, c) HapiFletcher32(a, b, c)
#define ti_lib_hapi_min_value(a, b) HapiMinValue(a,b)
#define ti_lib_hapi_max_value(a, b) HapiMaxValue(a,b)
#define ti_lib_hapi_mean_value(a, b) HapiMeanValue(a,b)
#define ti_lib_hapi_stand_deviation_value(a, b) HapiStandDeviationValue(a,b)
#define ti_lib_hapi_hf_source_safe_switch() HapiHFSourceSafeSwitch()
#define ti_lib_hapi_select_comp_a_input(a) HapiSelectCompAInput(a)
#define ti_lib_hapi_select_comp_a_ref(a) HapiSelectCompARef(a)
#define ti_lib_hapi_select_adc_comp_b_input(a) HapiSelectADCCompBInput(a)
#define ti_lib_hapi_select_comp_b_ref(a) HapiSelectCompBRef(a)
/*---------------------------------------------------------------------------*/
#endif /* TI_LIB_ROM_H_ */
/*---------------------------------------------------------------------------*/
/**
* @}
*/

View file

@ -52,6 +52,9 @@
#ifndef TI_LIB_H_
#define TI_LIB_H_
/*---------------------------------------------------------------------------*/
/* Include ROM API */
#include "ti-lib-rom.h"
/*---------------------------------------------------------------------------*/
/* aon_batmon.h */
#include "driverlib/aon_batmon.h"
@ -195,6 +198,7 @@
#define ti_lib_chipinfo_package_type_is_5x5(...) ChipInfo_PackageTypeIs5x5(__VA_ARGS__)
#define ti_lib_chipinfo_package_type_is_7x7(...) ChipInfo_PackageTypeIs7x7(__VA_ARGS__)
#define ti_lib_chipinfo_get_device_id_hw_rev_code(...) ChipInfo_GetDeviceIdHwRevCode(__VA_ARGS__)
#define ti_lib_chipinfo_get_chip_type(...) ChipInfo_GetChipType(__VA_ARGS__)
#define ti_lib_chipinfo_get_chip_family(...) ChipInfo_GetChipFamily(__VA_ARGS__)
#define ti_lib_chipinfo_chip_family_is_cc26xx(...) ChipInfo_ChipFamilyIsCC26xx(__VA_ARGS__)
#define ti_lib_chipinfo_chip_family_is_cc13xx(...) ChipInfo_ChipFamilyIsCC13xx(__VA_ARGS__)
@ -225,14 +229,24 @@
/* gpio.h */
#include "driverlib/gpio.h"
#define ti_lib_gpio_dir_mode_set(...) GPIODirModeSet(__VA_ARGS__)
#define ti_lib_gpio_dir_mode_get(...) GPIODirModeGet(__VA_ARGS__)
#define ti_lib_gpio_pin_write(...) GPIOPinWrite(__VA_ARGS__)
#define ti_lib_gpio_pin_read(...) GPIOPinRead(__VA_ARGS__)
#define ti_lib_gpio_pin_clear(...) GPIOPinClear(__VA_ARGS__)
#define ti_lib_gpio_pin_toggle(...) GPIOPinToggle(__VA_ARGS__)
#define ti_lib_gpio_event_get(...) GPIOEventGet(__VA_ARGS__)
#define ti_lib_gpio_event_clear(...) GPIOEventClear(__VA_ARGS__)
#define ti_lib_gpio_read_dio(...) GPIO_readDio(__VA_ARGS__)
#define ti_lib_gpio_read_multi_dio(...) GPIO_readMultiDio(__VA_ARGS__)
#define ti_lib_gpio_write_dio(...) GPIO_writeDio(__VA_ARGS__)
#define ti_lib_gpio_write_multi_dio(...) GPIO_writeMultiDio(__VA_ARGS__)
#define ti_lib_gpio_set_dio(...) GPIO_setDio(__VA_ARGS__)
#define ti_lib_gpio_set_multi_dio(...) GPIO_setMultiDio(__VA_ARGS__)
#define ti_lib_gpio_clear_dio(...) GPIO_clearDio(__VA_ARGS__)
#define ti_lib_gpio_clear_multi_dio(...) GPIO_clearMultiDio(__VA_ARGS__)
#define ti_lib_gpio_toggle_dio(...) GPIO_toggleDio(__VA_ARGS__)
#define ti_lib_gpio_toggle_multi_dio(...) GPIO_toggleMultiDio(__VA_ARGS__)
#define ti_lib_gpio_get_output_enable_dio(...) GPIO_getOutputEnableDio(__VA_ARGS__)
#define ti_lib_gpio_get_output_enable_multi_dio(...) GPIO_getOutputEnableMultiDio(__VA_ARGS__)
#define ti_lib_gpio_set_output_enable_dio(...) GPIO_setOutputEnableDio(__VA_ARGS__)
#define ti_lib_gpio_set_output_enable_multi_dio(...) GPIO_setOutputEnableMultiDio(__VA_ARGS__)
#define ti_lib_gpio_get_event_dio(...) GPIO_getEventDio(__VA_ARGS__)
#define ti_lib_gpio_get_event_multi_dio(...) GPIO_getEventMultiDio(__VA_ARGS__)
#define ti_lib_gpio_clear_event_dio(...) GPIO_clearEventDio(__VA_ARGS__)
#define ti_lib_gpio_clear_event_multi_dio(...) GPIO_clearEventMultiDio(__VA_ARGS__)
/*---------------------------------------------------------------------------*/
/* i2c.h */
#include "driverlib/i2c.h"
@ -317,15 +331,22 @@
#include "driverlib/osc.h"
#define ti_lib_osc_xhf_power_mode_set(...) OSCXHfPowerModeSet(__VA_ARGS__)
#define ti_lib_osc_clock_loss_event_enable(...) OSCClockLossEventEnable(__VA_ARGS__)
#define ti_lib_osc_clock_loss_event_disable(...) OSCClockLossEventDisable(__VA_ARGS__)
#define ti_lib_osc_clock_source_set(...) OSCClockSourceSet(__VA_ARGS__)
#define ti_lib_osc_clock_source_get(...) OSCClockSourceGet(__VA_ARGS__)
#define ti_lib_osc_hf_source_ready(...) OSCHfSourceReady(__VA_ARGS__)
#define ti_lib_osc_hf_source_switch(...) OSCHfSourceSwitch(__VA_ARGS__)
#define ti_lib_osc_interface_enable(...) OSCInterfaceEnable(__VA_ARGS__)
#define ti_lib_osc_interface_disable(...) OSCInterfaceDisable(__VA_ARGS__)
#define ti_lib_osc_hf_get_startup_time(...) OSCHF_GetStartupTime(__VA_ARGS__)
#define ti_lib_osc_hf_turn_on_xosc(...) OSCHF_TurnOnXosc(__VA_ARGS__)
#define ti_lib_osc_hf_attempt_to_switch_to_xosc(...) OSCHF_AttemptToSwitchToXosc(__VA_ARGS__)
#define ti_lib_osc_hf_debug_get_crystal_amplitude(...) OSCHF_DebugGetCrystalAmplitude(__VA_ARGS__)
#define ti_lib_osc_hf_debug_get_expected_average_crystal_amplitude(...) \
OSCHF_DebugGetExpectedAverageCrystalAmplitude(__VA_ARGS__)
#define ti_lib_osc_hposc_relative_frequency_offset_get(...) \
OSC_HPOSCRelativeFrequencyOffsetGet(__VA_ARGS__)
#define ti_lib_osc_hposc_relative_frequency_offset_to_rf_core_format_convert(...) \
OSC_HPOSCRelativeFrequencyOffsetToRFCoreFormatConvert(__VA_ARGS__)
#define ti_lib_osc_hf_switch_to_rc_osc_turn_off_xosc(...) OSCHF_SwitchToRcOscTurnOffXosc(__VA_ARGS__)
/*---------------------------------------------------------------------------*/
/* prcm.h */
@ -370,192 +391,6 @@
#define ti_lib_pwr_ctrl_io_freeze_enable(...) PowerCtrlIOFreezeEnable(__VA_ARGS__)
#define ti_lib_pwr_ctrl_io_freeze_disable(...) PowerCtrlIOFreezeDisable(__VA_ARGS__)
/*---------------------------------------------------------------------------*/
/* rom.h */
#include "driverlib/rom.h"
/* AON API */
#define ti_lib_rom_aon_event_mcu_wake_up_set ROM_AONEventMcuWakeUpSet
#define ti_lib_rom_aon_event_mcu_wake_up_get ROM_AONEventMcuWakeUpGet
#define ti_lib_rom_aon_event_aux_wake_up_set ROM_AONEventAuxWakeUpSet
#define ti_lib_rom_aon_event_aux_wake_up_get ROM_AONEventAuxWakeUpGet
#define ti_lib_rom_aon_event_mcu_set ROM_AONEventMcuSet
#define ti_lib_rom_aon_event_mcu_get ROM_AONEventMcuGet
/* AON_IOC API */
#define ti_lib_rom_aon_ioc_drive_strength_set ROM_AONIOCDriveStrengthSet
#define ti_lib_rom_aon_ioc_drive_strength_get ROM_AONIOCDriveStrengthGet
/* AON_RTC API */
#define ti_lib_rom_aon_rtc_status ROM_AONRTCStatus
#define ti_lib_rom_aon_rtc_event_clear ROM_AONRTCEventClear
#define ti_lib_rom_aon_rtc_event_get ROM_AONRTCEventGet
#define ti_lib_rom_aon_rtc_mode_ch1_set ROM_AONRTCModeCh1Set
#define ti_lib_rom_aon_rtc_mode_ch1_get ROM_AONRTCModeCh1Get
#define ti_lib_rom_aon_rtc_mode_ch2_set ROM_AONRTCModeCh2Set
#define ti_lib_rom_aon_rtc_mode_ch2_get ROM_AONRTCModeCh2Get
#define ti_lib_rom_aon_rtc_channel_enable ROM_AONRTCChannelEnable
#define ti_lib_rom_aon_rtc_channel_disable ROM_AONRTCChannelDisable
#define ti_lib_rom_aon_rtc_compare_value_set ROM_AONRTCCompareValueSet
#define ti_lib_rom_aon_rtc_compare_value_get ROM_AONRTCCompareValueGet
#define ti_lib_rom_aon_rtc_current_compare_value_get ROM_AONRTCCurrentCompareValueGet
/* AON_WUC API */
#define ti_lib_rom_aon_wuc_aux_s_ram_config ROM_AONWUCAuxSRamConfig
#define ti_lib_rom_aon_wuc_aux_wakeup_event ROM_AONWUCAuxWakeupEvent
#define ti_lib_rom_aon_wuc_aux_reset ROM_AONWUCAuxReset
#define ti_lib_rom_aon_wuc_recharge_ctrl_config_set ROM_AONWUCRechargeCtrlConfigSet
#define ti_lib_rom_aon_wuc_osc_config ROM_AONWUCOscConfig
/* AUX_TDC API */
#define ti_lib_rom_aux_tdc_config_set ROM_AUXTDCConfigSet
#define ti_lib_rom_aux_tdc_measurement_done ROM_AUXTDCMeasurementDone
/* AUX_TIMER API */
#define ti_lib_rom_aux_timer_configure ROM_AUXTimerConfigure
#define ti_lib_rom_aux_timer_start ROM_AUXTimerStart
#define ti_lib_rom_aux_timer_stop ROM_AUXTimerStop
#define ti_lib_rom_aux_timer_prescale_set ROM_AUXTimerPrescaleSet
#define ti_lib_rom_aux_timer_prescale_get ROM_AUXTimerPrescaleGet
/* AUX_WUC API */
#define ti_lib_rom_aux_wuc_clock_enable ROM_AUXWUCClockEnable
#define ti_lib_rom_aux_wuc_clock_disable ROM_AUXWUCClockDisable
#define ti_lib_rom_aux_wuc_clock_status ROM_AUXWUCClockStatus
#define ti_lib_rom_aux_wuc_power_ctrl ROM_AUXWUCPowerCtrl
/* FLASH API */
#define ti_lib_rom_flash_power_mode_get ROM_FlashPowerModeGet
#define ti_lib_rom_flash_protection_set ROM_FlashProtectionSet
#define ti_lib_rom_flash_protection_get ROM_FlashProtectionGet
#define ti_lib_rom_flash_protection_save ROM_FlashProtectionSave
#define ti_lib_rom_flash_efuse_read_row ROM_FlashEfuseReadRow
#define ti_lib_rom_flash_disable_sectors_for_write ROM_FlashDisableSectorsForWrite
/* I2C API */
#define ti_lib_rom_i2c_master_init_exp_clk ROM_I2CMasterInitExpClk
#define ti_lib_rom_i2c_master_err ROM_I2CMasterErr
/* INTERRUPT API */
#define ti_lib_rom_int_priority_grouping_set ROM_IntPriorityGroupingSet
#define ti_lib_rom_int_priority_grouping_get ROM_IntPriorityGroupingGet
#define ti_lib_rom_int_priority_set ROM_IntPrioritySet
#define ti_lib_rom_int_priority_get ROM_IntPriorityGet
#define ti_lib_rom_int_enable ROM_IntEnable
#define ti_lib_rom_int_disable ROM_IntDisable
#define ti_lib_rom_int_pend_set ROM_IntPendSet
#define ti_lib_rom_int_pend_get ROM_IntPendGet
#define ti_lib_rom_int_pend_clear ROM_IntPendClear
/* IOC API */
#define ti_lib_rom_ioc_port_configure_set ROM_IOCPortConfigureSet
#define ti_lib_rom_ioc_port_configure_get ROM_IOCPortConfigureGet
#define ti_lib_rom_ioc_io_shutdown_set ROM_IOCIOShutdownSet
#define ti_lib_rom_ioc_io_jtag_set ROM_IOCIOJTagSet
#define ti_lib_rom_ioc_io_mode_set ROM_IOCIOModeSet
#define ti_lib_rom_ioc_io_int_set ROM_IOCIOIntSet
#define ti_lib_rom_ioc_io_port_pull_set ROM_IOCIOPortPullSet
#define ti_lib_rom_ioc_io_hyst_set ROM_IOCIOHystSet
#define ti_lib_rom_ioc_io_input_set ROM_IOCIOInputSet
#define ti_lib_rom_ioc_io_slew_ctrl_set ROM_IOCIOSlewCtrlSet
#define ti_lib_rom_ioc_io_drv_strength_set ROM_IOCIODrvStrengthSet
#define ti_lib_rom_ioc_io_port_id_set ROM_IOCIOPortIdSet
#define ti_lib_rom_ioc_int_enable ROM_IOCIntEnable
#define ti_lib_rom_ioc_int_disable ROM_IOCIntDisable
#define ti_lib_rom_ioc_pin_type_gpio_input ROM_IOCPinTypeGpioInput
#define ti_lib_rom_ioc_pin_type_gpio_output ROM_IOCPinTypeGpioOutput
#define ti_lib_rom_ioc_pin_type_uart ROM_IOCPinTypeUart
#define ti_lib_rom_ioc_pin_type_ssi_master ROM_IOCPinTypeSsiMaster
#define ti_lib_rom_ioc_pin_type_ssi_slave ROM_IOCPinTypeSsiSlave
#define ti_lib_rom_ioc_pin_type_i2c ROM_IOCPinTypeI2c
#define ti_lib_rom_ioc_pin_type_spis ROM_IOCPinTypeSpis
#define ti_lib_rom_ioc_pin_type_aux ROM_IOCPinTypeAux
/* PRCM API */
#define ti_lib_rom_prcm_inf_clock_configure_set ROM_PRCMInfClockConfigureSet
#define ti_lib_rom_prcm_inf_clock_configure_get ROM_PRCMInfClockConfigureGet
#define ti_lib_rom_prcm_audio_clock_config_set ROM_PRCMAudioClockConfigSet
#define ti_lib_rom_prcm_power_domain_on ROM_PRCMPowerDomainOn
#define ti_lib_rom_prcm_power_domain_off ROM_PRCMPowerDomainOff
#define ti_lib_rom_prcm_peripheral_run_enable ROM_PRCMPeripheralRunEnable
#define ti_lib_rom_prcm_peripheral_run_disable ROM_PRCMPeripheralRunDisable
#define ti_lib_rom_prcm_peripheral_sleep_enable ROM_PRCMPeripheralSleepEnable
#define ti_lib_rom_prcm_peripheral_sleep_disable ROM_PRCMPeripheralSleepDisable
#define ti_lib_rom_prcm_peripheral_deep_sleep_enable ROM_PRCMPeripheralDeepSleepEnable
#define ti_lib_rom_prcm_peripheral_deep_sleep_disable ROM_PRCMPeripheralDeepSleepDisable
#define ti_lib_rom_prcm_power_domain_status ROM_PRCMPowerDomainStatus
#define ti_lib_rom_prcm_deep_sleep ROM_PRCMDeepSleep
/* SMPH API */
#define ti_lib_rom_smph_acquire ROM_SMPHAcquire
/* SPIS API */
#define ti_lib_rom_spis_data_put ROM_SPISDataPut
#define ti_lib_rom_spis_tx_get_value ROM_SPISTxGetValue
#define ti_lib_rom_spis_data_get ROM_SPISDataGet
#define ti_lib_rom_spis_rx_get_value ROM_SPISRxGetValue
#define ti_lib_rom_spis_int_status ROM_SPISIntStatus
/* SSI API */
#define ti_lib_rom_ssi_config_set_exp_clk ROM_SSIConfigSetExpClk
#define ti_lib_rom_ssi_data_put ROM_SSIDataPut
#define ti_lib_rom_ssi_data_put_non_blocking ROM_SSIDataPutNonBlocking
#define ti_lib_rom_ssi_data_get ROM_SSIDataGet
#define ti_lib_rom_ssi_data_get_non_blocking ROM_SSIDataGetNonBlocking
/* TIMER API */
#define ti_lib_rom_timer_configure ROM_TimerConfigure
#define ti_lib_rom_timer_level_control ROM_TimerLevelControl
#define ti_lib_rom_timer_trigger_control ROM_TimerTriggerControl
#define ti_lib_rom_timer_stall_control ROM_TimerStallControl
#define ti_lib_rom_timer_wait_on_trigger_control ROM_TimerWaitOnTriggerControl
/* TRNG API */
#define ti_lib_rom_trng_configure ROM_TRNGConfigure
#define ti_lib_rom_trng_number_get ROM_TRNGNumberGet
/* UART API */
#define ti_lib_rom_uart_fifo_level_get ROM_UARTFIFOLevelGet
#define ti_lib_rom_uart_config_set_exp_clk ROM_UARTConfigSetExpClk
#define ti_lib_rom_uart_config_get_exp_clk ROM_UARTConfigGetExpClk
#define ti_lib_rom_uart_disable ROM_UARTDisable
#define ti_lib_rom_uart_char_get_non_blocking ROM_UARTCharGetNonBlocking
#define ti_lib_rom_uart_char_get ROM_UARTCharGet
#define ti_lib_rom_uart_char_put_non_blocking ROM_UARTCharPutNonBlocking
#define ti_lib_rom_uart_char_put ROM_UARTCharPut
/* UDMA API */
#define ti_lib_rom_udma_channel_attribute_enable ROM_uDMAChannelAttributeEnable
#define ti_lib_rom_udma_channel_attribute_disable ROM_uDMAChannelAttributeDisable
#define ti_lib_rom_udma_channel_attribute_get ROM_uDMAChannelAttributeGet
#define ti_lib_rom_udma_channel_control_set ROM_uDMAChannelControlSet
#define ti_lib_rom_udma_channel_transfer_set ROM_uDMAChannelTransferSet
#define ti_lib_rom_udma_channel_scatter_gather_set ROM_uDMAChannelScatterGatherSet
#define ti_lib_rom_udma_channel_size_get ROM_uDMAChannelSizeGet
#define ti_lib_rom_udma_channel_mode_get ROM_uDMAChannelModeGet
/* VIMS API */
#define ti_lib_rom_vims_configure ROM_VIMSConfigure
#define ti_lib_rom_vims_mode_set ROM_VIMSModeSet
#define ti_lib_rom_vims_mode_get ROM_VIMSModeGet
/* HAPI */
#define ti_lib_hapi_crc32(a, b, c) HapiCrc32(a, b, c)
#define ti_lib_hapi_get_chip_id() HapiGetChipId()
#define ti_lib_hapi_reset_device() HapiResetDevice()
#define ti_lib_hapi_fletcher32(a, b, c) HapiFletcher32(a, b, c)
#define ti_lib_hapi_min_value(a, b) HapiMinValue(a,b)
#define ti_lib_hapi_max_value(a, b) HapiMaxValue(a,b)
#define ti_lib_hapi_mean_value(a, b) HapiMeanValue(a,b)
#define ti_lib_hapi_stand_deviation_value(a, b) HapiStandDeviationValue(a,b)
#define ti_lib_hapi_hf_source_safe_switch() HapiHFSourceSafeSwitch()
#define ti_lib_hapi_select_comp_a_input(a) HapiSelectCompAInput(a)
#define ti_lib_hapi_select_comp_a_ref(a) HapiSelectCompARef(a)
#define ti_lib_hapi_select_adc_comp_b_input(a) HapiSelectADCCompBInput(a)
#define ti_lib_hapi_select_comp_b_ref(a) HapiSelectCompBRef(a)
#define ti_lib_hapi_get_flash_size() HapiGetFlashSize()
#define ti_lib_hapi_sector_erase(a) HapiSectorErase(a)
#define ti_lib_hapi_program_flash(a, b, c) HapiProgramFlash(a, b, c)
/*---------------------------------------------------------------------------*/
/* sys_ctrl.h */
#include "driverlib/sys_ctrl.h"
@ -639,6 +474,22 @@
#define ti_lib_timer_match_update_mode(...) TimerMatchUpdateMode(__VA_ARGS__)
#define ti_lib_timer_interval_load_mode(...) TimerIntervalLoadMode(__VA_ARGS__)
/*---------------------------------------------------------------------------*/
/* trng.h */
#include "driverlib/trng.h"
#define ti_lib_trng_configure(...) TRNGConfigure(__VA_ARGS__)
#define ti_lib_trng_enable(...) TRNGEnable(__VA_ARGS__)
#define ti_lib_trng_disable(...) TRNGDisable(__VA_ARGS__)
#define ti_lib_trng_number_get(...) TRNGNumberGet(__VA_ARGS__)
#define ti_lib_trng_status_get(...) TRNGStatusGet(__VA_ARGS__)
#define ti_lib_trng_reset(...) TRNGReset(__VA_ARGS__)
#define ti_lib_trng_int_enable(...) TRNGIntEnable(__VA_ARGS__)
#define ti_lib_trng_int_disable(...) TRNGIntDisable(__VA_ARGS__)
#define ti_lib_trng_int_status(...) TRNGIntStatus(__VA_ARGS__)
#define ti_lib_trng_int_clear(...) TRNGIntClear(__VA_ARGS__)
#define ti_lib_trng_int_register(...) TRNGIntRegister(__VA_ARGS__)
#define ti_lib_trng_int_unregister(...) TRNGIntUnregister(__VA_ARGS__)
/*---------------------------------------------------------------------------*/
/* uart.h */
#include "driverlib/uart.h"

View file

@ -146,8 +146,8 @@ uart0_init(unsigned long ubr)
UCA0CTL1 |= UCSWRST; /* Hold peripheral in reset state */
UCA0CTL1 |= UCSSEL_2; /* CLK = SMCLK */
UCA0BR0 = ubr; /* 8MHz/115200 = 69 = 0x45 */
UCA0BR1 = 0x00;
UCA0BR0 = ((uint8_t *)&ubr)[0]; /* 8MHz/115200 = 69 = 0x45 */
UCA0BR1 = ((uint8_t *)&ubr)[1];
UCA0MCTL = UCBRS_3; /* Modulation UCBRSx = 3 */
P3DIR &= ~0x20; /* P3.5 = USCI_A0 RXD as input */

View file

@ -140,6 +140,18 @@ SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c)
prot_domains_disable_mmio();
}
/*---------------------------------------------------------------------------*/
/**
* \brief Perform common initialization that must precede per-port
* initialization.
*/
/*---------------------------------------------------------------------------*/
void
uart_16x50_init(void)
{
SYSCALLS_INIT(uart_16x50_setup);
SYSCALLS_INIT(uart_16x50_tx);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Initialize an MMIO-programmable 16X50 UART.
* \param c_this Structure that will be initialized to represent the device.
@ -147,7 +159,7 @@ SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c)
* \param dl Divisor setting to configure the baud rate.
*/
void
uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
uart_16x50_init_port(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
pci_config_addr_t pci_addr,
uint16_t dl)
{
@ -157,9 +169,7 @@ uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
* firmware during boot.
*/
pci_init(c_this, pci_addr, UART_MMIO_SZ, 0, 0);
SYSCALLS_INIT(uart_16x50_setup);
SYSCALLS_AUTHZ(uart_16x50_setup, *c_this);
SYSCALLS_INIT(uart_16x50_tx);
SYSCALLS_AUTHZ(uart_16x50_tx, *c_this);
prot_domains_copy_dcd(&loc_c_this, c_this);

View file

@ -35,7 +35,9 @@
typedef pci_driver_t uart_16x50_driver_t;
void uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
void uart_16x50_init(void);
void uart_16x50_init_port(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
pci_config_addr_t pci_addr,
uint16_t dl);

View file

@ -35,19 +35,30 @@
PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart0);
PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart1);
/* Divisor setting for 115200 baud from section 18.2.2 of Intel Quark SoC
* X1000 Datasheet.
/* UART base frequency from section 18.2.2 of Intel Quark SoC X1000
* Datasheet.
*/
#define QUARK_X1000_UART_DL_115200 24
#define QUARK_X1000_UART_FBASE 44236800
/*---------------------------------------------------------------------------*/
/**
* \brief Perform common initialization that must precede per-port
* initialization.
*/
void
quarkX1000_uart_init(void)
{
uart_16x50_init();
}
/*---------------------------------------------------------------------------*/
/**
* \brief Initialize a UART.
* \param dev Device to initialize.
*/
void
quarkX1000_uart_init(quarkX1000_uart_dev_t dev)
quarkX1000_uart_init_port(quarkX1000_uart_dev_t dev, unsigned baud)
{
uint16_t dl;
pci_config_addr_t pci_addr;
uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *drv;
@ -67,7 +78,9 @@ quarkX1000_uart_init(quarkX1000_uart_dev_t dev)
drv = &quarkX1000_uart1;
PROT_DOMAINS_INIT_ID(quarkX1000_uart1);
}
uart_16x50_init(drv, pci_addr, QUARK_X1000_UART_DL_115200);
/* Divisor setting from section 18.2.2 of Intel Quark SoC X1000 Datasheet. */
dl = QUARK_X1000_UART_FBASE / (16 * baud);
uart_16x50_init_port(drv, pci_addr, dl);
}
/*---------------------------------------------------------------------------*/
/**

View file

@ -38,7 +38,8 @@ typedef enum {
QUARK_X1000_UART_1
} quarkX1000_uart_dev_t;
void quarkX1000_uart_init(quarkX1000_uart_dev_t dev);
void quarkX1000_uart_init(void);
void quarkX1000_uart_init_port(quarkX1000_uart_dev_t dev, unsigned baud);
void quarkX1000_uart_tx(quarkX1000_uart_dev_t dev, uint8_t c);
#endif /* CPU_X86_DRIVERS_QUARKX1000_UART_H_ */

View file

@ -222,15 +222,5 @@
#define CC1200_RX_LEDS CC1200_CONF_RX_LEDS
#endif
/*---------------------------------------------------------------------------*/
/*
* If set, enable sniff mode: turn radio on (and keep it on), disable
* address filter and auto ack
*/
#ifdef CC1200_CONF_SNIFFER
#define CC1200_SNIFFER CC1200_CONF_SNIFFER
#else
#define CC1200_SNIFFER 0
#endif
/*---------------------------------------------------------------------------*/
#endif /* CC1200_H_ */

View file

@ -374,17 +374,6 @@ extern const cc1200_rf_cfg_t CC1200_RF_CFG;
} while(0)
#endif
/*---------------------------------------------------------------------------*/
/* Sniffer configuration */
#if CC1200_SNIFFER
static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 };
#include "dev/uart.h"
#define write_byte(b) uart_write_byte(CC1200_RF_CONF_SNIFFER_UART, b)
#define flush()
#else /* CC1200_SNIFFER */
#define write_byte(b)
#define flush()
#endif /* CC1200_SNIFFER */
/*---------------------------------------------------------------------------*/
/* Variables */
/*---------------------------------------------------------------------------*/
/* Flag indicating whether non-interrupt routines are using SPI */
@ -553,11 +542,6 @@ calculate_freq(uint8_t channel);
/* Update rf channel if possible, else postpone it (-> pollhandler). */
static int
set_channel(uint8_t channel);
#if !CC1200_SNIFFER
/* Check broadcast address. */
static int
is_broadcast_addr(uint8_t mode, uint8_t *addr);
#endif /* CC1200_SNIFFER */
/* Validate address and send ACK if requested. */
static int
addr_check_auto_ack(uint8_t *frame, uint16_t frame_len);
@ -574,8 +558,7 @@ PROCESS_THREAD(cc1200_process, ev, data)
PROCESS_BEGIN();
#if CC1200_USE_RX_WATCHDOG && !CC1200_SNIFFER
/* RX watchdog interferes with sniffer. Reason unknown... */
#if CC1200_USE_RX_WATCHDOG
while(1) {
if((rf_flags & (RF_ON | RF_TX_ACTIVE)) == RF_ON) {
@ -716,11 +699,6 @@ init(void)
* configuration of the GPIO0 pin
*/
off();
/* #if CC1200_SNIFFER */
/* on(); */
/* #endif */
}
return 1;
@ -881,10 +859,6 @@ read(void *buf, unsigned short buf_len)
int len = 0;
#if CC1200_SNIFFER
uint8_t i;
#endif
if(rx_pkt_len > 0) {
int8_t rssi = rx_pkt[rx_pkt_len - 2];
@ -911,21 +885,6 @@ read(void *buf, unsigned short buf_len)
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY,
crc_lqi & ~(1 << 7));
#if CC1200_SNIFFER
write_byte(magic[0]);
write_byte(magic[1]);
write_byte(magic[2]);
write_byte(magic[3]);
write_byte(len + 2);
for(i = 0; i < len; ++i) {
write_byte(((unsigned char *)(buf))[i]);
}
write_byte(rssi);
write_byte(crc_lqi);
flush();
#endif
RIMESTATS_ADD(llrx);
}
@ -2137,7 +2096,6 @@ set_channel(uint8_t channel)
}
/*---------------------------------------------------------------------------*/
/* Check broadcast address. */
#if !CC1200_SNIFFER
static int
is_broadcast_addr(uint8_t mode, uint8_t *addr)
{
@ -2153,30 +2111,7 @@ is_broadcast_addr(uint8_t mode, uint8_t *addr)
return 1;
}
#endif /* CC12100_SNIFFER */
/*---------------------------------------------------------------------------*/
/* Validate address and send ACK if requested. */
#if CC1200_SNIFFER
static int
addr_check_auto_ack(uint8_t *frame, uint16_t frame_len)
{
frame802154_t info154;
if(frame802154_parse(frame, frame_len, &info154) != 0) {
/* We accept all 802.15.4 frames ... */
return ADDR_CHECK_OK;
} else {
/* .. and discard others. */
return INVALID_FRAME;
}
}
#else /* CC1200_SNIFFER */
static int
addr_check_auto_ack(uint8_t *frame, uint16_t frame_len)
{
@ -2245,7 +2180,6 @@ addr_check_auto_ack(uint8_t *frame, uint16_t frame_len)
return INVALID_FRAME;
}
#endif /* CC1200_SNIFFER */
/*---------------------------------------------------------------------------*/
/*
* The CC1200 interrupt handler: called by the hardware interrupt

View file

@ -55,12 +55,19 @@
#define FOOTER1_CRC_OK 0x80
#define FOOTER1_CORRELATION 0x7f
#ifdef CC2520_CONF_RSSI_OFFSET
#define RSSI_OFFSET CC2520_CONF_RSSI_OFFSET
#else /* CC2520_CONF_RSSI_OFFSET */
/* The RSSI_OFFSET is approximate 76 (see CC2520 specification) */
#define RSSI_OFFSET 76
#endif /* CC2520_CONF_RSSI_OFFSET */
#include <stdio.h>
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while (0)
#define PRINTF(...) do {} while(0)
#endif
#if 0 && DEBUG
@ -97,7 +104,6 @@ static volatile uint16_t last_packet_timestamp;
PROCESS(cc2520_process, "CC2520 driver");
/*---------------------------------------------------------------------------*/
int cc2520_on(void);
int cc2520_off(void);
@ -141,7 +147,6 @@ get_value(radio_param_t param, radio_value_t *value)
return RADIO_RESULT_NOT_SUPPORTED;
}
}
static radio_result_t
set_value(radio_param_t param, radio_value_t value)
{
@ -166,21 +171,18 @@ set_value(radio_param_t param, radio_value_t value)
return RADIO_RESULT_NOT_SUPPORTED;
}
}
static radio_result_t
get_object(radio_param_t param, void *dest, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
static radio_result_t
set_object(radio_param_t param, const void *src, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
const struct radio_driver cc2520_driver =
{
{
cc2520_init,
cc2520_prepare,
cc2520_transmit,
@ -197,7 +199,7 @@ const struct radio_driver cc2520_driver =
set_value,
get_object,
set_object
};
};
/*---------------------------------------------------------------------------*/
@ -269,7 +271,9 @@ off(void)
}
/*---------------------------------------------------------------------------*/
#define GET_LOCK() locked++
static void RELEASE_LOCK(void) {
static void
RELEASE_LOCK(void)
{
if(locked == 1) {
if(lock_on) {
on();
@ -340,7 +344,7 @@ cc2520_init(void)
/* correlation threshold = 20, RX bandpass filter = 1.3uA.*/
setreg(CC2520_TXCTRL, 0x94);
setreg(CC2520_TXPOWER, 0x13); // Output power 1 dBm
setreg(CC2520_TXPOWER, 0x13); /* Output power 1 dBm */
/*
@ -357,21 +361,21 @@ cc2520_init(void)
0xF2 -> 3 dBm
0xF7 -> 5 dBm
*/
setreg(CC2520_CCACTRL0, 0xF8); // CCA treshold -80dBm
setreg(CC2520_CCACTRL0, 0xF8); /* CCA treshold -80dBm */
// Recommended RX settings
setreg(CC2520_MDMCTRL0, 0x84); // Controls modem
setreg(CC2520_MDMCTRL1, 0x14); // Controls modem
setreg(CC2520_RXCTRL, 0x3F); // Adjust currents in RX related analog modules
setreg(CC2520_FSCTRL, 0x5A); // Adjust currents in synthesizer.
setreg(CC2520_FSCAL1, 0x2B); // Adjust currents in VCO
setreg(CC2520_AGCCTRL1, 0x11); // Adjust target value for AGC control loop
/* Recommended RX settings */
setreg(CC2520_MDMCTRL0, 0x84); /* Controls modem */
setreg(CC2520_MDMCTRL1, 0x14); /* Controls modem */
setreg(CC2520_RXCTRL, 0x3F); /* Adjust currents in RX related analog modules */
setreg(CC2520_FSCTRL, 0x5A); /* Adjust currents in synthesizer. */
setreg(CC2520_FSCAL1, 0x2B); /* Adjust currents in VCO */
setreg(CC2520_AGCCTRL1, 0x11); /* Adjust target value for AGC control loop */
setreg(CC2520_AGCCTRL2, 0xEB);
// Disable external clock
/* Disable external clock */
setreg(CC2520_EXTCLOCK, 0x00);
// Tune ADC performance
/* Tune ADC performance */
setreg(CC2520_ADCTEST0, 0x10);
setreg(CC2520_ADCTEST1, 0x0E);
setreg(CC2520_ADCTEST2, 0x03);
@ -379,7 +383,7 @@ cc2520_init(void)
/* Set auto CRC on frame. */
#if CC2520_CONF_AUTOACK
setreg(CC2520_FRMCTRL0, AUTOCRC | AUTOACK);
setreg(CC2520_FRMFILT0, FRAME_MAX_VERSION|FRAME_FILTER_ENABLE);
setreg(CC2520_FRMFILT0, FRAME_MAX_VERSION | FRAME_FILTER_ENABLE);
#else
/* setreg(CC2520_FRMCTRL0, 0x60); */
setreg(CC2520_FRMCTRL0, AUTOCRC);
@ -430,7 +434,7 @@ cc2520_transmit(unsigned short payload_len)
#if WITH_SEND_CCA
strobe(CC2520_INS_SRXON);
BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID) , RTIMER_SECOND / 10);
BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID), RTIMER_SECOND / 10);
strobe(CC2520_INS_STXONCCA);
#else /* WITH_SEND_CCA */
strobe(CC2520_INS_STXON);
@ -462,11 +466,11 @@ cc2520_transmit(unsigned short payload_len)
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
/* We wait until transmission has ended so that we get an
accurate measurement of the transmission time.*/
//BUSYWAIT_UNTIL(getreg(CC2520_EXCFLAG0) & TX_FRM_DONE , RTIMER_SECOND / 100);
/* BUSYWAIT_UNTIL(getreg(CC2520_EXCFLAG0) & TX_FRM_DONE , RTIMER_SECOND / 100); */
BUSYWAIT_UNTIL(!(status() & BV(CC2520_TX_ACTIVE)), RTIMER_SECOND / 10);
#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2520_get_txpower());
ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT, cc2520_get_txpower());
#endif
ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
if(receive_on) {
@ -641,15 +645,14 @@ cc2520_set_pan_addr(unsigned pan,
tmp[1] = pan >> 8;
CC2520_WRITE_RAM(&tmp, CC2520RAM_PANID, 2);
tmp[0] = addr & 0xff;
tmp[1] = addr >> 8;
CC2520_WRITE_RAM(&tmp, CC2520RAM_SHORTADDR, 2);
if(ieee_addr != NULL) {
int f;
uint8_t tmp_addr[8];
// LSB first, MSB last for 802.15.4 addresses in CC2520
for (f = 0; f < 8; f++) {
/* LSB first, MSB last for 802.15.4 addresses in CC2520 */
for(f = 0; f < 8; f++) {
tmp_addr[7 - f] = ieee_addr[f];
}
CC2520_WRITE_RAM(tmp_addr, CC2520RAM_IEEEADDR, 8);
@ -737,15 +740,13 @@ cc2520_read(void *buf, unsigned short bufsize)
getrxdata(footer, FOOTER_LEN);
if(footer[1] & FOOTER1_CRC_OK) {
cc2520_last_rssi = footer[0];
cc2520_last_rssi = footer[0] - RSSI_OFFSET;
cc2520_last_correlation = footer[1] & FOOTER1_CORRELATION;
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2520_last_rssi);
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2520_last_correlation);
RIMESTATS_ADD(llrx);
} else {
RIMESTATS_ADD(badcrc);
len = FOOTER_LEN;
@ -809,6 +810,7 @@ cc2520_rssi(void)
BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID), RTIMER_SECOND / 100);
rssi = (int)((signed char)getreg(CC2520_RSSI));
rssi -= RSSI_OFFSET;
if(radio_was_off) {
cc2520_off();
@ -818,12 +820,12 @@ cc2520_rssi(void)
}
/*---------------------------------------------------------------------------*/
/*
static int
detected_energy(void)
{
static int
detected_energy(void)
{
return cc2520_rssi();
}
*/
}
*/
/*---------------------------------------------------------------------------*/
int
cc2520_cca_valid(void)

2
doc/uip6-doc.txt Normal file → Executable file
View file

@ -339,7 +339,7 @@ We will soon support RFC4944 transmission of IPv6 packets over 802.15.4\n
\li Path MTU Discovery RFC 1981 (SHOULD): no support
\li Jumbograms RFC 2675 (MAY): no support
\li ICMPv6 RFC 4443 (MUST): full support
\li IPv6 addressing architecture RFC 3513 (MUST): full support
\li IPv6 addressing architecture RFC 4291 (MUST): full support
\li Privacy extensions for address autoconfiguration RFC 3041 (SHOULD): no support.
\li Default Address Selection RFC 3484 (MUST): full support.
\li MLDv1 (RFC 2710) and MLDv2 (RFC 3810) (conditional MUST applying here): no support. As we run IPv6 over Multicast or broadcast capable links (Ethernet or 802.15.4), the conditional MUST applies. We should be able to send an MLD report when joining a solicited node multicast group at address configuration time. This will be available in a later release.

View file

@ -1,222 +1,10 @@
Contiki client for sensd
========================
Sensd README describes the concept. sensd code is on github.
Contiki client connects to:
"sensd - A WSN Internet GW, hub, agent, proxy & cloud"
sensd - A WSN Internet GW, hub, agent, proxy & cloud
====================================================
Authors
--------
Robert Olsson <robert@radio-sensors.com>
Jens Laas <jens.laas@uadm.uu.se>
Contributors
------------
Abstract
--------
We've outlined, designed and implemented and very simple concept for WSN
data sharing, including data collection, storage and retrieval using
standard text tools. The concept restricts Internet access to WSN
motes and acts agent not to expose motes directly for robustness and
security reasons. Low level, physical or link WSN protocol can be used.
including 6lowpan, RIME etc and any type of Radio Duty Cycling (RDC).
sensd works on the application layer. A TCP connection initiates an
implicit "subscribe". The M2P model is currently supported.
Key concepts
------------
* Agent. sensd works as an agent and does not allow direct Internet
access to motes. Recall motes are constrained in most aspects and
can not support many connections, has weak security etc.
* Hub. Share the data from the root or sink node over TCP. In effect sensor
data can be sent over Internet to be shared over among TCP active listeners.
The TCP connection initiates an implicit "subscribe".
* Proxy. The support proxy functions over ipv4 and well as ipv6. Sensd can
forward to a proxy on a public IP. The typical case is when GW is behind
a NAT.
* WSN RP "rendez-vous point". A concepts where data from various WSN nets
are merged. This models a "cloud service" functionality for WSN networks.
sensd can be used both to forward data to RP. It can also work as the RP.
RP receiving WSN data and allowing multiple TCP listeners.
* All programs are written C, script in Java and bash. Designed for small
footprint and with minimal dependencies. sensd runs on Raspberry Pi and
Openwrt.
* This work introduces a simple tag format for sensor data. The overall
idea is that data tagging is an "agreement" between producers and consumer.
Tags are simple are description of the data. Example T=25.2. where T=
is the tag 25.2 the value. Most likely this a temperature. But we
can't be sure since we don't know since this is an agreement between
the producer and the consumer. Tags are also used for identification.
Example tags, E64= Where globally unique ID can used. Another more
relaxed example is TXT= a user description. See docs.
* Geotagging and timestamping is supported via tags.
* Ecosystem support. There are telphone apps to for data monitoring and
and plotting. Android app can act as WSN-agent and forward to proxy/RP.
* The concept also includes a mapping to URI (Unified Resource Identifier)
to form a WSN caching server similar to CoAP using http-proxy.
* Copyright. Open-Source via GPL. Projecet used github.com
Introduction
------------
This is collection of software to implement data monitoring and data collection
from WSN Wireless Sensor Networks. The goal is to have a very simple,
straight-forward and robust framework.
The scenario: One or several motes is connected to USB or serial port to gather
received information from connected WSN motes. Data can be visualized in
several ways.
* Sensor data report can be transmitted and propagated throughout the
Internet. sensd acts as server and sends incoming report to active
listeners.
* Data is kept in ASCII with tagging and ID information. Data is conveniently
handled, copied and viewed with standard text utilities of your OS.
* Last mote report is cached into the file system suitable for URI use. The
Format is SID/TAG. Typical tags are EUI64 and unique serial numbers. The
different TAGS are left for mote user to define. Although the TAGS used in
our example setup are included in this draft for example purposes.
Both formats can easily be stored or linked directly in web tree to form a
URI to format WSN logging/datafile or caching service.
A daemon that reads WSN mote reports from USB/serial and stores data in a ASCII
data file. Default is located at _/var/log/sensors.dat_
Addtional components
--------------------
* seltag [More info] (https://github.com/herjulf/sensd/blob/master/seltag/README.md)
* js A set of Java-scripts can plot, print and visualize sensor data from
sensd directly in your web-browser.
* documentation and sample files. [More info] (https://github.com/herjulf/sensd/blob/master/seltag/README.md)
* Read Sensors Android app. [Source Code] (https://github.com/herjulf/Read-Sensors)
Datafile logging
----------------
Below is and example of the anatomy of a sensors.dat file we are currently using in our WSN
data collection networks.
2012-05-22 14:07:46 UT=1337688466 ID=283c0cdd030000d7 PS=0 T=30.56 T_MCU=34.6 V_MCU=3.08 UP=2C15C V_IN=4.66
2012-05-22 14:11:41 UT=1337688701 ID=28a9d5dc030000af PS=0 T=36.00 V_MCU=2.92 UP=12C8A0 RH=42.0 V_IN=4.13 V_A1=3.43 [ADDR=0.175 SEQ=33 RSSI=21 LQI=255 DRP=1.00]
Each line is a mote report. They start with date and time and are followed by a set of
tags. The tags is different for different motes. In other words they can
send different data. Essential is the ID which should be unique for each mote.
The information with brackets is information generated by the receiving mote
and is not a part the motes data. Typically RSSI (Receiver Signal Strength
Indicator) and LQI (Link Quality Indicator)
Internet sensor data
--------------------
Start sensd with the `-report` option. This enables reports to be transmitted
over IP to remote listeners. Default TCP port 1234.
Server side example:
sensd -report -p 1234 -D /dev/ttyUSB0
Client side. Example using netcat:
nc server-ip 1234
URI format
----------
URI (Unified Resource Identifier) displays the node ID and the tags in a file tree.
It is easy to export this into a web tree to form a URI similar to a CoAP gateway.
Example: In our case we have a unique sensor ID followed by the different data
fields represented by "tags".
/tmp/WSN1-GW1/281a98d20200004a:
DRP ID LQI PS RH RSSI SEQ T V_IN V_MCU ADDR
/tmp/WSN1-GW1/28be51ce02000031:
DRP ID LQI PS RH RSSI SEQ T UP V_IN V_MCU ADDR
Read Temp from a sensor:
cat /tmp/WSN1-GW1/281a98d20200004a/T
19.44
And it's very easy to link this tree into a web-server.
GPS support
-----------
Positioning support has been added via GPS device connected to serial
or USB port. Tags added when enabled GWGPS_LON & GWGPS_LAT.
GPS code from. https://github.com/herjulf/gps_simple
Getting the source and building
-------------------------------
Code is stored in github. Typically procedure below is the very straight-
forward unix way:
git clone http://github.com/herjulf/sensd
cd sensd
make
Put your binaries after your preference:
Pre-built binary versions
--------------------------
For x86:
Sensd and friends are available in Bifrost/Linux packages. Those packages are
statically linked and can be used on most x86 Linuxes. 32-bit compiled.
http://ftp.sunet.se/pub/Linux/distributions/bifrost/download/opt/opt-sensd-2.3-1.tar.gz
Use
---
The WSN data logging and caching concept is in actual use with Contiki, RIME
broadcast application.
Tips
----
One can use netcat to listen to reports:
Example:
nc radio-sensors.com 1235
To save in file use nohup:
nohup nc radio-sensors.com 1235 > /var/log/sensors.dat
As sensd used TCP and ASCII encoding. tetlnet and web-browsers can be used
as well.
For full sensd documentation and code see:
https://github.com/herjulf/sensd

View file

@ -1,11 +0,0 @@
DEFINES+=PROJECT_CONF_H
PROJECT_SOURCEFILES += stub-rdc.c
CONTIKI_PROJECT = sniffer
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
CONTIKI_WITH_RIME = 1
include $(CONTIKI)/Makefile.include

View file

@ -1 +0,0 @@
TARGET = cc2530dk

View file

@ -1,49 +0,0 @@
/*
* Copyright (c) 2010, Loughborough University - Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Stub file overriding core/net/netstack.c. What we want to achieve
* here is call netstack_init from main without initialising the RDC,
* MAC and Network layers. It will just turn on the radio instead.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "netstack.h"
/*---------------------------------------------------------------------------*/
void
netstack_init(void)
{
NETSTACK_RADIO.init();
}
/*---------------------------------------------------------------------------*/

View file

@ -1,56 +0,0 @@
/*
* Copyright (c) 2010, Loughborough University - Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Project specific configuration defines for the sniffer example.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define CC2530_RF_CONF_HEXDUMP 1
#define CC2530_RF_CONF_AUTOACK 0
#define NETSTACK_CONF_RDC stub_rdc_driver
#define ADC_SENSOR_CONF_ON 0
#define LPM_CONF_MODE 0
#define UART0_CONF_HIGH_SPEED 1
/* Change to 0 to build for the SmartRF + cc2530 EM */
#define MODELS_CONF_CC2531_USB_STICK 1
/* Used by cc2531 USB dongle builds, has no effect on SmartRF builds */
#define USB_SERIAL_CONF_BUFFERED 1
#endif /* PROJECT_CONF_H_ */

View file

@ -1,54 +0,0 @@
/*
* 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 Institute 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "cc253x.h"
#define DEBUG DEBUG_NONE
#include "net/ip/uip-debug.h"
/*---------------------------------------------------------------------------*/
PROCESS(sniffer_process, "Sniffer process");
AUTOSTART_PROCESSES(&sniffer_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sniffer_process, ev, data)
{
PROCESS_BEGIN();
PRINTF("Sniffer started\n");
/* Turn off RF Address Recognition - We need to accept all frames */
FRMFILT0 &= ~0x01;
PROCESS_EXIT();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -1,10 +0,0 @@
DEFINES+=PROJECT_CONF_H=\"project-conf.h\"
PROJECT_SOURCEFILES += stub-rdc.c
CONTIKI_PROJECT = sniffer
all: $(CONTIKI_PROJECT)
CONTIKI = ../../..
CONTIKI_WITH_RIME = 1
include $(CONTIKI)/Makefile.include

View file

@ -1 +0,0 @@
TARGET = cc2538dk

View file

@ -1,96 +0,0 @@
/*
* Copyright (c) 2010, Loughborough University - Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute 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 INSTITUTE 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.
*/
/**
* \file
* Definition of a fake RDC driver to be used with passive
* examples. The sniffer will never send packets and it will never
* push incoming packets up the stack. We do this by defining this
* driver as our RDC. We then drop everything
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "net/mac/mac.h"
#include "net/mac/rdc.h"
/*---------------------------------------------------------------------------*/
static void
send(mac_callback_t sent, void *ptr)
{
if(sent) {
sent(ptr, MAC_TX_OK, 1);
}
}
/*---------------------------------------------------------------------------*/
static void
send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list)
{
if(sent) {
sent(ptr, MAC_TX_OK, 1);
}
}
/*---------------------------------------------------------------------------*/
static void
input(void)
{
}
/*---------------------------------------------------------------------------*/
static int
on(void)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static int
off(int keep_radio_on)
{
return keep_radio_on;
}
/*---------------------------------------------------------------------------*/
static unsigned short
cca(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
}
/*---------------------------------------------------------------------------*/
const struct rdc_driver stub_rdc_driver = {
"stub-rdc",
init,
send,
send_list,
input,
on,
off,
cca,
};
/*---------------------------------------------------------------------------*/

View file

@ -145,7 +145,7 @@ PROCESS_THREAD(cc2538_pwm_test, ev, data)
PRINTF("\nStarting the test\n");
for(i = 0; i < MAX_PWM; i++) {
if(pwm_enable(pwm_num[i].freq, pwm_num[i].duty,
if(pwm_enable(pwm_num[i].freq, pwm_num[i].duty, 0,
pwm_num[i].timer, pwm_num[i].ab) == PWM_SUCCESS) {
pwm_en[i] = 1;
PRINTF("%s (%u) configuration OK\n", gpt_name(pwm_num[i].timer),

View file

@ -42,13 +42,16 @@
#define CC26XX_WEB_DEMO_CONF_COAP_SERVER 1
#define CC26XX_WEB_DEMO_CONF_NET_UART 1
/*---------------------------------------------------------------------------*/
/* Enable the ROM bootloader */
#define ROM_BOOTLOADER_ENABLE 1
/*---------------------------------------------------------------------------*/
/*
* Shrink the size of the uIP buffer, routing table and ND cache.
* Set the TCP MSS
*/
#define UIP_CONF_BUFFER_SIZE 900
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#define UIP_CONF_MAX_ROUTES 8
#define NBR_TABLE_CONF_MAX_NEIGHBORS 5
#define UIP_CONF_MAX_ROUTES 5
#define UIP_CONF_TCP_MSS 128
/*---------------------------------------------------------------------------*/
#endif /* PROJECT_CONF_H_ */

View file

@ -34,6 +34,9 @@
/* Disable button shutdown functionality */
#define BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN 0
/*---------------------------------------------------------------------------*/
/* Enable the ROM bootloader */
#define ROM_BOOTLOADER_ENABLE 1
/*---------------------------------------------------------------------------*/
/* Change to match your configuration */
#define IEEE802154_CONF_PANID 0xABCD
#define RF_CORE_CONF_CHANNEL 25

View file

@ -35,6 +35,9 @@
#define IEEE802154_CONF_PANID 0xABCD
#define RF_CORE_CONF_CHANNEL 25
/*---------------------------------------------------------------------------*/
/* Enable the ROM bootloader */
#define ROM_BOOTLOADER_ENABLE 1
/*---------------------------------------------------------------------------*/
/* For very sleepy operation */
#define RF_BLE_CONF_ENABLED 0
#define UIP_DS6_CONF_PERIOD CLOCK_SECOND

View file

@ -33,10 +33,11 @@
#include "contiki.h"
#include "sys/ctimer.h"
#include "galileo-gpio.h"
#include "gpio.h"
#define PIN_OUTPUT 5
#define PIN_INPUT 6
#define PIN_OUTPUT 2
#define PIN_INPUT 3
static uint32_t value;
static struct ctimer timer;
@ -51,9 +52,9 @@ timeout(void *data)
/* toggle pin state */
value = !value;
quarkX1000_gpio_write(PIN_OUTPUT, value);
galileo_gpio_write(PIN_OUTPUT, value);
quarkX1000_gpio_read(PIN_INPUT, &value_in);
galileo_gpio_read(PIN_INPUT, &value_in);
if (value == value_in)
printf("GPIO pin value match!\n");
@ -67,9 +68,6 @@ PROCESS_THREAD(gpio_input_process, ev, data)
{
PROCESS_BEGIN();
quarkX1000_gpio_config(PIN_OUTPUT, QUARKX1000_GPIO_OUT);
quarkX1000_gpio_config(PIN_INPUT, QUARKX1000_GPIO_IN);
quarkX1000_gpio_clock_enable();
ctimer_set(&timer, CLOCK_SECOND / 2, timeout, NULL);

View file

@ -33,10 +33,11 @@
#include "contiki.h"
#include "sys/ctimer.h"
#include "galileo-gpio.h"
#include "gpio.h"
#define PIN_OUTPUT 5
#define PIN_INTR 6
#define PIN_OUTPUT 2
#define PIN_INTR 3
static struct ctimer timer;
@ -47,8 +48,8 @@ static void
timeout(void *data)
{
/* emulate an interrupt */
quarkX1000_gpio_write(PIN_OUTPUT, 0);
quarkX1000_gpio_write(PIN_OUTPUT, 1);
galileo_gpio_write(PIN_OUTPUT, 0);
galileo_gpio_write(PIN_OUTPUT, 1);
ctimer_reset(&timer);
}
@ -63,8 +64,7 @@ PROCESS_THREAD(gpio_interrupt_process, ev, data)
{
PROCESS_BEGIN();
quarkX1000_gpio_config(PIN_OUTPUT, QUARKX1000_GPIO_OUT);
quarkX1000_gpio_config(PIN_INTR, QUARKX1000_GPIO_INT | QUARKX1000_GPIO_ACTIVE_HIGH | QUARKX1000_GPIO_EDGE);
galileo_gpio_config(PIN_INTR, QUARKX1000_GPIO_INT | QUARKX1000_GPIO_ACTIVE_HIGH | QUARKX1000_GPIO_EDGE);
quarkX1000_gpio_set_callback(callback);

View file

@ -33,9 +33,10 @@
#include "contiki.h"
#include "sys/ctimer.h"
#include "galileo-gpio.h"
#include "gpio.h"
#define PIN 5 /* IO2 */
#define PIN 2
static uint32_t value;
static struct ctimer timer;
@ -48,7 +49,7 @@ timeout(void *data)
{
/* toggle pin state */
value = !value;
quarkX1000_gpio_write(PIN, value);
galileo_gpio_write(PIN, value);
ctimer_reset(&timer);
}
@ -57,8 +58,6 @@ PROCESS_THREAD(gpio_output_process, ev, data)
{
PROCESS_BEGIN();
quarkX1000_gpio_config(PIN, QUARKX1000_GPIO_OUT);
quarkX1000_gpio_clock_enable();
ctimer_set(&timer, CLOCK_SECOND / 2, timeout, NULL);

View file

@ -60,9 +60,9 @@
#define UIP_CONF_TCP 0
/* Code/RAM footprint savings so that things will fit on our device */
#undef UIP_CONF_DS6_NBR_NBU
#undef UIP_CONF_DS6_ROUTE_NBU
#define UIP_CONF_DS6_NBR_NBU 10
#define UIP_CONF_DS6_ROUTE_NBU 10
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
#undef UIP_CONF_MAX_ROUTES
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#define UIP_CONF_MAX_ROUTES 10
#endif /* PROJECT_CONF_H_ */

View file

@ -41,7 +41,10 @@
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include "net/rpl/rpl.h"
#include "net/rpl/rpl-private.h"
#if RPL_WITH_NON_STORING
#include "net/rpl/rpl-ns.h"
#endif /* RPL_WITH_NON_STORING */
#include "net/netstack.h"
#include "dev/button-sensor.h"
#include "dev/slip.h"
@ -144,6 +147,9 @@ static
PT_THREAD(generate_routes(struct httpd_state *s))
{
static uip_ds6_route_t *r;
#if RPL_WITH_NON_STORING
static rpl_ns_node_t *link;
#endif /* RPL_WITH_NON_STORING */
static uip_ds6_nbr_t *nbr;
#if BUF_USES_STACK
char buf[256];
@ -210,7 +216,7 @@ PT_THREAD(generate_routes(struct httpd_state *s))
}
#endif
}
ADD("</pre>Routes<pre>");
ADD("</pre>Routes<pre>\n");
SEND_STRING(&s->sout, buf);
#if BUF_USES_STACK
bufptr = buf; bufend = bufptr + sizeof(buf);
@ -259,6 +265,65 @@ PT_THREAD(generate_routes(struct httpd_state *s))
}
ADD("</pre>");
#if RPL_WITH_NON_STORING
ADD("Links<pre>\n");
SEND_STRING(&s->sout, buf);
#if BUF_USES_STACK
bufptr = buf; bufend = bufptr + sizeof(buf);
#else
blen = 0;
#endif
for(link = rpl_ns_node_head(); link != NULL; link = rpl_ns_node_next(link)) {
if(link->parent != NULL) {
uip_ipaddr_t child_ipaddr;
uip_ipaddr_t parent_ipaddr;
rpl_ns_get_node_global_addr(&child_ipaddr, link);
rpl_ns_get_node_global_addr(&parent_ipaddr, link->parent);
#if BUF_USES_STACK
#if WEBSERVER_CONF_ROUTE_LINKS
ADD("<a href=http://[");
ipaddr_add(&child_ipaddr);
ADD("]/status.shtml>");
ipaddr_add(&child_ipaddr);
ADD("</a>");
#else
ipaddr_add(&child_ipaddr);
#endif
#else
#if WEBSERVER_CONF_ROUTE_LINKS
ADD("<a href=http://[");
ipaddr_add(&child_ipaddr);
ADD("]/status.shtml>");
SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
blen = 0;
ipaddr_add(&child_ipaddr);
ADD("</a>");
#else
ipaddr_add(&child_ipaddr);
#endif
#endif
ADD(" (parent: ");
ipaddr_add(&parent_ipaddr);
if(1 || (link->lifetime < 600)) {
ADD(") %us\n", (unsigned int)link->lifetime); // iotlab printf does not have %lu
//ADD(") %lus\n", (unsigned long)r->state.lifetime);
} else {
ADD(")\n");
}
SEND_STRING(&s->sout, buf);
#if BUF_USES_STACK
bufptr = buf; bufend = bufptr + sizeof(buf);
#else
blen = 0;
#endif
}
}
ADD("</pre>");
#endif /* RPL_WITH_NON_STORING */
#if WEBSERVER_CONF_FILESTATS
static uint16_t numtimes;
ADD("<br><i>This page sent %u times</i>",++numtimes);

View file

@ -41,6 +41,7 @@
#include "net/rpl/rpl.h"
#include "net/ipv6/uip-ds6-route.h"
#include "net/mac/tsch/tsch.h"
#include "net/rpl/rpl-private.h"
#if WITH_ORCHESTRA
#include "orchestra.h"
#endif /* WITH_ORCHESTRA */
@ -68,46 +69,73 @@ print_network_status(void)
int i;
uint8_t state;
uip_ds6_defrt_t *default_route;
#if RPL_WITH_STORING
uip_ds6_route_t *route;
#endif /* RPL_WITH_STORING */
#if RPL_WITH_NON_STORING
rpl_ns_node_t *link;
#endif /* RPL_WITH_NON_STORING */
PRINTA("--- Network status ---\n");
PRINTF("--- Network status ---\n");
/* Our IPv6 addresses */
PRINTA("- Server IPv6 addresses:\n");
PRINTF("- Server IPv6 addresses:\n");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
PRINTA("-- ");
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
PRINTA("\n");
PRINTF("-- ");
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n");
}
}
/* Our default route */
PRINTA("- Default route:\n");
PRINTF("- Default route:\n");
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
if(default_route != NULL) {
PRINTA("-- ");
uip_debug_ipaddr_print(&default_route->ipaddr);
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
PRINTF("-- ");
PRINT6ADDR(&default_route->ipaddr);
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
} else {
PRINTA("-- None\n");
PRINTF("-- None\n");
}
#if RPL_WITH_STORING
/* Our routing entries */
PRINTA("- Routing entries (%u in total):\n", uip_ds6_route_num_routes());
PRINTF("- Routing entries (%u in total):\n", uip_ds6_route_num_routes());
route = uip_ds6_route_head();
while(route != NULL) {
PRINTA("-- ");
uip_debug_ipaddr_print(&route->ipaddr);
PRINTA(" via ");
uip_debug_ipaddr_print(uip_ds6_route_nexthop(route));
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
PRINTF("-- ");
PRINT6ADDR(&route->ipaddr);
PRINTF(" via ");
PRINT6ADDR(uip_ds6_route_nexthop(route));
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
route = uip_ds6_route_next(route);
}
#endif
PRINTA("----------------------\n");
#if RPL_WITH_NON_STORING
/* Our routing links */
PRINTF("- Routing links (%u in total):\n", rpl_ns_num_nodes());
link = rpl_ns_node_head();
while(link != NULL) {
if(link->parent != NULL) {
uip_ipaddr_t child_ipaddr;
uip_ipaddr_t parent_ipaddr;
rpl_ns_get_node_global_addr(&child_ipaddr, link);
rpl_ns_get_node_global_addr(&parent_ipaddr, link->parent);
PRINTF("-- ");
PRINT6ADDR(&child_ipaddr);
PRINTF(" to ");
PRINT6ADDR(&parent_ipaddr);
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)link->lifetime);
}
link = rpl_ns_node_next(link);
}
#endif
PRINTF("----------------------\n");
}
/*---------------------------------------------------------------------------*/
static void

View file

@ -45,6 +45,17 @@
#define WITH_SECURITY 0
#endif /* WITH_SECURITY */
/*******************************************************/
/********* Enable RPL non-storing mode *****************/
/*******************************************************/
#undef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */
#undef RPL_CONF_MOP
#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/
#undef ORCHESTRA_CONF_RULES
#define ORCHESTRA_CONF_RULES { &eb_per_time_source, &unicast_per_neighbor_rpl_ns, &default_common } /* Orchestra in non-storing */
/*******************************************************/
/********************* Enable TSCH *********************/
/*******************************************************/
@ -140,8 +151,8 @@
#define UIP_CONF_TCP 0
#undef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 3
#undef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 8
#undef RPL_NS_CONF_LINK_NUM
#define RPL_NS_CONF_LINK_NUM 8
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#undef UIP_CONF_ND6_SEND_NA
@ -164,4 +175,10 @@
#endif /* CONTIKI_TARGET_Z1 */
#if CONTIKI_TARGET_CC2538DK || CONTIKI_TARGET_ZOUL || \
CONTIKI_TARGET_OPENMOTE_CC2538
#define TSCH_CONF_HW_FRAME_FILTERING 0
#endif /* CONTIKI_TARGET_CC2538DK || CONTIKI_TARGET_ZOUL \
|| CONTIKI_TARGET_OPENMOTE_CC2538 */
#endif /* __PROJECT_CONF_H__ */

View file

@ -60,10 +60,6 @@
#define RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME 1
#ifndef RPL_CONF_WITH_NON_STORING
#define RPL_CONF_WITH_NON_STORING 0 /* Set this to run with non-storing mode */
#endif /* RPL_CONF_WITH_NON_STORING */
#if WITH_NON_STORING
#undef RPL_NS_CONF_LINK_NUM
#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root. Can be set to 0 at non-root nodes. */

View file

@ -38,7 +38,7 @@
#define SICSLOWPAN_CONF_FRAG 1
#define LOOP_INTERVAL (10 * CLOCK_SECOND)
#define LOOP_INTERVAL (30 * CLOCK_SECOND)
/* Save energy */
//#define RDC_CONF_PT_YIELD_OFF

View file

@ -42,10 +42,12 @@ void setup (void)
rest_activate_resource (&res_htu21dtemp, "s/temp");
rest_activate_resource (&res_htu21dhum, "s/hum");
rest_activate_resource (&res_battery, "s/battery");
mcu_sleep_set(128); // Power consumtion 278uA; average over 20 minutes
}
// at project-conf.h
// LOOP_INTERVAL (10 * CLOCK_SECOND)
// LOOP_INTERVAL (30 * CLOCK_SECOND)
void loop (void)
{
mcu_sleep_off();

View file

@ -39,8 +39,8 @@
#define SICSLOWPAN_CONF_FRAG 1
/* For Debug: Dont allow MCU sleeping between channel checks */
//#undef RDC_CONF_MCU_SLEEP
//#define RDC_CONF_MCU_SLEEP 0
#undef RDC_CONF_MCU_SLEEP
#define RDC_CONF_MCU_SLEEP 0
/* Disabling RDC for demo purposes. Core updates often require more memory. */
/* For projects, optimize memory and enable RDC again. */

View file

@ -36,6 +36,9 @@
//#define PLATFORM_HAS_BUTTON 1
#define PLATFORM_HAS_BATTERY 1
/* Save energy */
//#define RDC_CONF_PT_YIELD_OFF
/* For Debug: Dont allow MCU sleeping between channel checks */
//#undef RDC_CONF_MCU_SLEEP
//#define RDC_CONF_MCU_SLEEP 0

View file

@ -34,6 +34,7 @@ void setup (void)
rest_activate_resource (&res_cputemp, "s/cputemp");
// NETSTACK_MAC.off(1);
// mcu_sleep_set(48);
}
void loop (void)

View file

@ -31,6 +31,9 @@
#ifndef PROJECT_ROUTER_CONF_H_
#define PROJECT_ROUTER_CONF_H_
#undef RDC_CONF_MCU_SLEEP
#define RDC_CONF_MCU_SLEEP 0
#ifndef UIP_FALLBACK_INTERFACE
#define UIP_FALLBACK_INTERFACE rpl_interface
#endif

View file

@ -41,6 +41,9 @@
/* Seeping nodes are host nodes without routing features */
#define UIP_CONF_ROUTER 0
/* Seeping nodes are host nodes without routing features */
#define UIP_CONF_ROUTER 0
/* For Debug: Dont allow MCU sleeping between channel checks */
//#undef RDC_CONF_MCU_SLEEP
//#define RDC_CONF_MCU_SLEEP 0

View file

@ -0,0 +1,10 @@
CONTIKI=../..
CONTIKI_PROJECT = node
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
CONTIKI_WITH_RIME = 1
MODULES += core/net/mac/tsch
all: $(CONTIKI_PROJECT)
include $(CONTIKI)/Makefile.include

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, Loughborough University - Computer Science
* Copyright (c) 2016, Inria.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,74 +27,73 @@
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Definition of a fake RDC driver to be used with passive
* examples. The sniffer will never send packets and it will never
* push incoming packets up the stack. We do this by defining this
* driver as our RDC. We then drop everything
*
* An example of Rime/TSCH
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
* Simon Duquennoy <simon.duquennoy@inria.fr>
*
*/
#include "net/mac/mac.h"
#include "net/mac/rdc.h"
#include <stdio.h>
#include "contiki-conf.h"
#include "net/netstack.h"
#include "net/rime/rime.h"
#include "net/mac/tsch/tsch.h"
const linkaddr_t coordinator_addr = { { 1, 0 } };
const linkaddr_t destination_addr = { { 1, 0 } };
/*---------------------------------------------------------------------------*/
PROCESS(unicast_test_process, "Rime Node");
AUTOSTART_PROCESSES(&unicast_test_process);
/*---------------------------------------------------------------------------*/
static void
send(mac_callback_t sent, void *ptr)
recv_uc(struct unicast_conn *c, const linkaddr_t *from)
{
if(sent) {
sent(ptr, MAC_TX_OK, 1);
printf("App: unicast message received from %u.%u\n",
from->u8[0], from->u8[1]);
}
/*---------------------------------------------------------------------------*/
static void
sent_uc(struct unicast_conn *ptr, int status, int num_tx)
{
printf("App: unicast message sent, status %u, num_tx %u\n",
status, num_tx);
}
static const struct unicast_callbacks unicast_callbacks = { recv_uc, sent_uc };
static struct unicast_conn uc;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(unicast_test_process, ev, data)
{
PROCESS_BEGIN();
tsch_set_coordinator(linkaddr_cmp(&coordinator_addr, &linkaddr_node_addr));
NETSTACK_MAC.on();
unicast_open(&uc, 146, &unicast_callbacks);
while(1) {
static struct etimer et;
etimer_set(&et, CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
packetbuf_copyfrom("Hello", 5);
if(!linkaddr_cmp(&destination_addr, &linkaddr_node_addr)) {
printf("App: sending unicast message to %u.%u\n", destination_addr.u8[0], destination_addr.u8[1]);
unicast_send(&uc, &destination_addr);
}
}
/*---------------------------------------------------------------------------*/
static void
send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list)
{
if(sent) {
sent(ptr, MAC_TX_OK, 1);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
input(void)
{
}
/*---------------------------------------------------------------------------*/
static int
on(void)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static int
off(int keep_radio_on)
{
return keep_radio_on;
}
/*---------------------------------------------------------------------------*/
static unsigned short
cca(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
}
/*---------------------------------------------------------------------------*/
const struct rdc_driver stub_rdc_driver = {
"stub-rdc",
init,
send,
send_list,
input,
on,
off,
cca,
};
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2016, Inria.
* 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 Institute 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 INSTITUTE 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Project config file
* \author
* Simon Duquennoy <simon.duquennoy@inria.fr>
*
*/
#ifndef __PROJECT_CONF_H__
#define __PROJECT_CONF_H__
/* Netstack layers */
#undef NETSTACK_CONF_MAC
#define NETSTACK_CONF_MAC tschmac_driver
#undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nordc_driver
#undef NETSTACK_CONF_FRAMER
#define NETSTACK_CONF_FRAMER framer_802154
/* IEEE802.15.4 frame version */
#undef FRAME802154_CONF_VERSION
#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012
#undef TSCH_CONF_AUTOSELECT_TIME_SOURCE
#define TSCH_CONF_AUTOSELECT_TIME_SOURCE 1
/* Needed for cc2420 platforms only */
/* Disable DCO calibration (uses timerB) */
#undef DCOSYNCH_CONF_ENABLED
#define DCOSYNCH_CONF_ENABLED 0
/* Enable SFD timestamps (uses timerB) */
#undef CC2420_CONF_SFD_TIMESTAMPS
#define CC2420_CONF_SFD_TIMESTAMPS 1
/* TSCH logging. 0: disabled. 1: basic log. 2: with delayed
* log messages from interrupt */
#undef TSCH_LOG_CONF_LEVEL
#define TSCH_LOG_CONF_LEVEL 2
/* IEEE802.15.4 PANID */
#undef IEEE802154_CONF_PANID
#define IEEE802154_CONF_PANID 0xabcd
/* Do not start TSCH at init, wait for NETSTACK_MAC.on() */
#undef TSCH_CONF_AUTOSTART
#define TSCH_CONF_AUTOSTART 0
/* 6TiSCH minimal schedule length.
* Larger values result in less frequent active slots: reduces capacity and saves energy. */
#undef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH
#define TSCH_SCHEDULE_CONF_DEFAULT_LENGTH 3
#undef TSCH_LOG_CONF_ID_FROM_LINKADDR
#define TSCH_LOG_CONF_ID_FROM_LINKADDR(addr) ((addr) ? (addr)->u8[LINKADDR_SIZE - 2] : 0)
#endif /* __PROJECT_CONF_H__ */

25
examples/sensniff/Makefile Executable file
View file

@ -0,0 +1,25 @@
DEFINES+=PROJECT_CONF_H=\"project-conf.h\"
CONTIKI_PROJECT = sensniff
PROJECT_SOURCEFILES += sensniff-rdc.c netstack.c
PROJECTDIRS += pool $(TARGET)
ifeq ($(TARGET),)
-include Makefile.target
ifeq ($(TARGET),)
TARGET=srf06-cc26xx
$(info TARGET not defined, using target $(TARGET))
endif
endif
CONTIKI_WITH_RIME = 1
### Optionally, the target can add its own Makefile, to do things like e.g.
### add more source files to the build or define make variables.
-include $(TARGET)/Makefile.$(TARGET)
all: $(CONTIKI_PROJECT)
CONTIKI = ../..
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,83 @@
sensniff Contiki Project
========================
This example can be used to create an IEEE 802.15.4 wireless sniffer firmware,
meant to be used in parallel with
[sensniff](https://github.com/g-oikonomou/sensniff).
Running
=======
* Build this example and program your device
* Connect your device to a host
* Run sensniff on your host
* Fire up wireshark and enjoy.
Make sure your device's UART baud rate matches the `-b` argument passed to
sensniff. I strongly recommend using at least 460800. This comment does not
apply if your device is using native USB.
Subsequently, make absolutely certain that your device is tuned to the same RF
channel as the network you are trying to sniff. You can change sniffing channel
through sensniff's text interface.
More details in sensniff's README.
Adding support for more platforms
=================================
Firstly, this example will try to turn off frame filtering and automatic h/w
ACKs by calling `NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0)`. If your
radio does not support this, then implementing this is your first step towards
running this example on your board.
Secondly, in order to be able to switch channels and retrieve current/min/max
RF channel supported from sensniff's text interface, your device's radio driver
must also support:
NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, ...)
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, ...)
NETSTACK_RADIO.get_value(RADIO_CONST_CHANNEL_MIN, ...)
NETSTACK_RADIO.get_value(RADIO_CONST_CHANNEL_MAX, ...)
The following radios have been tested:
* CC13xx/CC26xx in PROP and IEEE modes
* CC2538
* CC2530/CC2531
* CC1200
One you have the radio sorted out, you also need to configure character I/O.
The firmware captures wireless frames and streams them over a serial line to
the host where your device is connected. This can be achieved over UART or over
CDC-ACM. The example makes zero assumptions about your hardware's capability,
you have to configure thnigs explicitly.
* Firstly, create a directory named the same as your platform. Crate a header
file therein called `target-conf.h`. This will get included automatically.
* Then look at the header files under `pool`, perhaps your device's CPU is
already supported. If that's the case, then within your `target-conf.h` you
simply need to add a line like this:
#define SENSNIFF_IO_DRIVER_H "pool/cc2538-io.h"
choosing the header that corresponds to your device's CPU. Just look for any of
the platforms already supported to see how you can configure things in a more
fine-grained fashion (e.g. to select UART instance, switch between UART/USB
etc).
* If your CPU is not already supported, then you need to create an additional
header file. In that header file, you will need to define the following three:
#define sensniff_io_byte_out() <driver function that prints bytes>
#define sensniff_io_flush() <for buffered I/O. Can be empty>
#define sensniff_io_set_input() <driver function that sets an input callback>
Those should map to functions implemented by your device's peripheral driver,
e.g. your UART driver. `_byte_out()` and `set_input()` are required, but
`_flush()` is optional and is only really helpful in case of drivers/hardware
that support buffered I/O (as is the case for some Contiki's USB drivers). Once
you have provided those defines, then simple go back to your `target-conf.h`
and:
#define SENSNIFF_IO_DRIVER_H "header-with-my-own-defines.h"
That should be it!

Some files were not shown because too many files have changed in this diff Show more