Merge branch 'master' into osd
Conflicts: examples/osd/triggerbaord/sketch.pde
This commit is contained in:
commit
e6dbb8c3f2
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -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
|
||||
|
|
|
@ -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,11 +143,16 @@ PROCESS_THREAD(arduino_sketch, ev, data)
|
|||
}
|
||||
#endif /* PLATFORM_HAS_BUTTON */
|
||||
|
||||
if(etimer_expired(&loop_periodic_timer)) {
|
||||
mcu_sleep_off();
|
||||
loop ();
|
||||
mcu_sleep_on();
|
||||
etimer_reset(&loop_periodic_timer);
|
||||
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 ();
|
||||
mcu_sleep_on();
|
||||
etimer_reset(&loop_periodic_timer);
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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",
|
||||
|
|
210
core/dev/slip.c
210
core/dev/slip.c
|
@ -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;
|
||||
if(len > blen) {
|
||||
len = 0;
|
||||
} else {
|
||||
memcpy(outbuf, &rxbuf[begin], len);
|
||||
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 {
|
||||
outbuf[len] = rxbuf[i];
|
||||
len++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
len = (RX_BUFSIZE - begin) + (pkt_end - 0);
|
||||
if(len > blen) {
|
||||
len = 0;
|
||||
} else {
|
||||
unsigned i;
|
||||
for(i = begin; i < RX_BUFSIZE; i++) {
|
||||
*outbuf++ = rxbuf[i];
|
||||
}
|
||||
for(i = 0; i < pkt_end; i++) {
|
||||
*outbuf++ = rxbuf[i];
|
||||
}
|
||||
uint16_t i;
|
||||
len = 0;
|
||||
for(i = begin; i < RX_BUFSIZE; ++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++;
|
||||
}
|
||||
}
|
||||
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! */
|
||||
|
||||
/* One more packet is buffered, need to be polled again! */
|
||||
process_poll(&slip_process);
|
||||
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,71 +388,42 @@ 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) {
|
||||
state = STATE_OK;
|
||||
}
|
||||
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;
|
||||
if(c == SLIP_ESC) {
|
||||
state = STATE_ESC;
|
||||
}
|
||||
|
||||
/* add_char: */
|
||||
{
|
||||
unsigned next;
|
||||
next = end + 1;
|
||||
if(next == RX_BUFSIZE) {
|
||||
next = 0;
|
||||
}
|
||||
if(next == begin) { /* rxbuf is full */
|
||||
state = STATE_RUBBISH;
|
||||
SLIP_STATISTICS(slip_overflow++);
|
||||
end = pkt_end; /* remove rubbish */
|
||||
return 0;
|
||||
}
|
||||
rxbuf[end] = c;
|
||||
end = next;
|
||||
cur_end = next_free;
|
||||
next_free = next_free + 1;
|
||||
if(next_free == RX_BUFSIZE) {
|
||||
next_free = 0;
|
||||
}
|
||||
if(next_free == begin) { /* rxbuf is full */
|
||||
state = STATE_RUBBISH;
|
||||
SLIP_STATISTICS(slip_overflow++);
|
||||
next_free = pkt_end; /* remove rubbish */
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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
4
core/net/ip/uip-debug.c
Normal file → Executable 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
6
core/net/ip/uip.h
Normal file → Executable 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) \
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -340,7 +346,7 @@ powercycle_turn_radio_off(void)
|
|||
#if CONTIKIMAC_CONF_COMPOWER
|
||||
uint8_t was_on = radio_is_on;
|
||||
#endif /* CONTIKIMAC_CONF_COMPOWER */
|
||||
|
||||
|
||||
if(we_are_sending == 0 && we_are_receiving_burst == 0) {
|
||||
off();
|
||||
#if CONTIKIMAC_CONF_COMPOWER
|
||||
|
@ -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 */
|
||||
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
|
||||
}
|
||||
|
@ -553,13 +564,13 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
int len;
|
||||
uint8_t seqno;
|
||||
#endif
|
||||
|
||||
|
||||
/* Exit if RDC and radio were explicitly turned off */
|
||||
if(!contikimac_is_on && !contikimac_keep_radio_on) {
|
||||
PRINTF("contikimac: radio is turned off\n");
|
||||
return MAC_TX_ERR_FATAL;
|
||||
}
|
||||
|
||||
|
||||
if(packetbuf_totlen() == 0) {
|
||||
PRINTF("contikimac: send_packet data len 0\n");
|
||||
return MAC_TX_ERR_FATAL;
|
||||
|
@ -601,10 +612,10 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
return MAC_TX_ERR_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transmit_len = packetbuf_totlen();
|
||||
NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len);
|
||||
|
||||
|
||||
if(!is_broadcast && !is_receiver_awake) {
|
||||
#if WITH_PHASE_OPTIMIZATION
|
||||
ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
|
||||
|
@ -616,9 +627,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
if(ret != PHASE_UNKNOWN) {
|
||||
is_known_receiver = 1;
|
||||
}
|
||||
#endif /* WITH_PHASE_OPTIMIZATION */
|
||||
#endif /* WITH_PHASE_OPTIMIZATION */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* By setting we_are_sending to one, we ensure that the rtimer
|
||||
|
@ -636,7 +647,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
|||
NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet());
|
||||
return MAC_TX_COLLISION;
|
||||
}
|
||||
|
||||
|
||||
/* Switch off the radio to ensure that we didn't start sending while
|
||||
the radio was doing a channel check. */
|
||||
off();
|
||||
|
@ -844,7 +855,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
|
|||
int ret;
|
||||
int is_receiver_awake;
|
||||
int pending;
|
||||
|
||||
|
||||
if(buf_list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -856,7 +867,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
|
|||
mac_call_sent_callback(sent, ptr, MAC_TX_COLLISION, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Create and secure frames in advance */
|
||||
curr = buf_list;
|
||||
do {
|
||||
|
@ -873,13 +884,13 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
|
|||
mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1);
|
||||
queuebuf_update_from_packetbuf(curr->buf);
|
||||
}
|
||||
curr = next;
|
||||
} while(next != NULL);
|
||||
|
||||
|
||||
/* The receiver needs to be awoken before we send */
|
||||
is_receiver_awake = 0;
|
||||
curr = buf_list;
|
||||
|
|
|
@ -146,30 +146,18 @@ 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) {
|
||||
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 if((fcf->dest_addr_mode == 0) && (fcf->src_addr_mode == 0)) {
|
||||
/* No address included: PAN ID compression flag changes meaning */
|
||||
dest_pan_id = 1;
|
||||
}
|
||||
} else {
|
||||
/* No PAN ID in ACK */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,8 +83,14 @@ 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) {
|
||||
/* Duplicate packet. */
|
||||
#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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *****/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* 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_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity
|
||||
in framer-802154.c. */
|
||||
if(++tsch_packet_seqno == 0) {
|
||||
tsch_packet_seqno++;
|
||||
}
|
||||
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)) {
|
||||
/* 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));
|
||||
/* 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));
|
||||
} 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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_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
|
||||
|
|
|
@ -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;
|
||||
|
@ -154,8 +149,8 @@ rpl_verify_hbh_header(int uip_ext_opt_offset)
|
|||
|
||||
if((down && !sender_closer) || (!down && sender_closer)) {
|
||||
PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
|
||||
sender_rank, instance->current_dag->rank,
|
||||
sender_closer);
|
||||
sender_rank, instance->current_dag->rank,
|
||||
sender_closer);
|
||||
/* Attempt to repair the loop by sending a unicast DIO back to the sender
|
||||
* so that it gets a fresh update of our rank. */
|
||||
if(sender != NULL) {
|
||||
|
@ -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,52 +477,39 @@ 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;
|
||||
PRINTF("RPL: Unable to add/update hop-by-hop extension header: incorrect instance\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0; /* Drop */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PRINTF("RPL: No hop-by-hop option found\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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,
|
||||
which states that if a packet is going down it should in
|
||||
general not go back up again. If this happens, a
|
||||
RPL_HDR_OPT_FWD_ERR should be flagged. */
|
||||
which states that if a packet is going down it should in
|
||||
general not go back up again. If this happens, a
|
||||
RPL_HDR_OPT_FWD_ERR should be flagged. */
|
||||
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||
PRINTF("RPL forwarding error\n");
|
||||
/* We should send back the packet to the originating parent,
|
||||
but it is not feasible yet, so we send a No-Path DAO instead */
|
||||
but it is not feasible yet, so we send a No-Path DAO instead */
|
||||
PRINTF("RPL generate No-Path DAO\n");
|
||||
parent = rpl_get_parent((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
if(parent != NULL) {
|
||||
|
@ -544,11 +520,11 @@ update_hbh_header(void)
|
|||
}
|
||||
} else {
|
||||
/* Set the down extension flag correctly as described in Section
|
||||
11.2 of RFC6550. If the packet progresses along a DAO route,
|
||||
the down flag should be set. */
|
||||
11.2 of RFC6550. If the packet progresses along a DAO route,
|
||||
the down flag should be set. */
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
/* No route was found, so this packet will go towards the RPL
|
||||
root. If so, we should not set the down flag. */
|
||||
root. If so, we should not set the down flag. */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
|
||||
PRINTF("RPL option going up\n");
|
||||
} else {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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,36 +614,20 @@ 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)) {
|
||||
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();
|
||||
}
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -721,25 +635,30 @@ rpl_insert_header(void)
|
|||
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) */
|
||||
rpl_remove_header();
|
||||
if(RPL_IS_NON_STORING(default_instance)) {
|
||||
return insert_srh_header();
|
||||
} else {
|
||||
return insert_hbh_header();
|
||||
}
|
||||
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) */
|
||||
rpl_remove_header();
|
||||
if(RPL_IS_NON_STORING(default_instance)) {
|
||||
return insert_srh_header();
|
||||
} else {
|
||||
return update_hbh_header();
|
||||
return insert_hbh_header(default_instance);
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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);
|
||||
sensors_changed(&button_sensor);
|
||||
if(bstate == bstatei){
|
||||
sensors_changed(&button_sensor);
|
||||
}
|
||||
// led1_off();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -207,14 +181,15 @@ set_channel(uint8_t channel)
|
|||
}
|
||||
|
||||
/* Changes to FREQCTRL take effect after the next recalibration */
|
||||
|
||||
|
||||
/* If we are off, save state, otherwise switch off and save state */
|
||||
if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) != 0) {
|
||||
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;
|
||||
|
||||
|
@ -527,7 +539,7 @@ init(void)
|
|||
*/
|
||||
udma_set_channel_src(CC2538_RF_CONF_RX_DMA_CHAN, RFCORE_SFR_RFDATA);
|
||||
}
|
||||
|
||||
|
||||
set_poll_mode(poll_mode);
|
||||
|
||||
process_start(&cc2538_rf_process, NULL);
|
||||
|
@ -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) {
|
||||
|
@ -782,10 +780,8 @@ 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)
|
||||
& (RFCORE_XREG_FSMSTAT1_TX_ACTIVE | RFCORE_XREG_FSMSTAT1_SFD))
|
||||
== RFCORE_XREG_FSMSTAT1_SFD);
|
||||
return (REG(RFCORE_XREG_FSMSTAT1)
|
||||
& (RFCORE_XREG_FSMSTAT1_TX_ACTIVE | 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
|
||||
|
@ -963,15 +959,15 @@ get_object(radio_param_t param, void *dest, size_t size)
|
|||
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
return RADIO_RESULT_NOT_SUPPORTED;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -1075,7 +1071,7 @@ void
|
|||
cc2538_rf_rx_tx_isr(void)
|
||||
{
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
|
||||
|
||||
if(!poll_mode) {
|
||||
process_poll(&cc2538_rf_process);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup c2538-ecc-algo
|
||||
* \addtogroup cc2538-ecc-algo
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup c2538-ecc-curves
|
||||
* \addtogroup cc2538-ecc-curves
|
||||
* @{
|
||||
*/
|
||||
#include "contiki.h"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
duty_count = ((interval_load * duty) + 1) / 100;
|
||||
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);
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
* @{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
LIST(consumers_list);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
315
cpu/cc26xx-cc13xx/dev/soc-trng.c
Normal file
315
cpu/cc26xx-cc13xx/dev/soc-trng.c
Normal 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);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
135
cpu/cc26xx-cc13xx/dev/soc-trng.h
Normal file
135
cpu/cc26xx-cc13xx/dev/soc-trng.h
Normal 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_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -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);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
/*
|
||||
* 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(),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,26 +371,17 @@ 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 */
|
||||
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 */
|
||||
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 */
|
||||
HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3;
|
||||
rv = RF_CORE_CMD_OK;
|
||||
}
|
||||
if(chip_type == CHIP_TYPE_CC2650) {
|
||||
HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
|
||||
rv = RF_CORE_CMD_OK;
|
||||
} else if(chip_type == CHIP_TYPE_CC2630) {
|
||||
HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE2;
|
||||
rv = RF_CORE_CMD_OK;
|
||||
} 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();
|
||||
|
|
193
cpu/cc26xx-cc13xx/ti-lib-rom.h
Normal file
193
cpu/cc26xx-cc13xx/ti-lib-rom.h
Normal 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_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,9 +159,9 @@ 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,
|
||||
pci_config_addr_t pci_addr,
|
||||
uint16_t dl)
|
||||
uart_16x50_init_port(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
|
||||
pci_config_addr_t pci_addr,
|
||||
uint16_t dl)
|
||||
{
|
||||
uart_16x50_driver_t loc_c_this;
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -35,9 +35,11 @@
|
|||
|
||||
typedef pci_driver_t uart_16x50_driver_t;
|
||||
|
||||
void uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this,
|
||||
pci_config_addr_t pci_addr,
|
||||
uint16_t dl);
|
||||
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);
|
||||
|
||||
void uart_16x50_tx(uart_16x50_driver_t c_this, uint8_t c);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -81,11 +88,11 @@ int cc2520_authority_level_of_sender;
|
|||
|
||||
int cc2520_packets_seen, cc2520_packets_read;
|
||||
|
||||
#define BUSYWAIT_UNTIL(cond, max_time) \
|
||||
do { \
|
||||
rtimer_clock_t t0; \
|
||||
t0 = RTIMER_NOW(); \
|
||||
while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \
|
||||
#define BUSYWAIT_UNTIL(cond, max_time) \
|
||||
do { \
|
||||
rtimer_clock_t t0; \
|
||||
t0 = RTIMER_NOW(); \
|
||||
while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \
|
||||
} while(0)
|
||||
|
||||
volatile uint8_t cc2520_sfd_counter;
|
||||
|
@ -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,38 +171,35 @@ 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,
|
||||
cc2520_send,
|
||||
cc2520_read,
|
||||
/* cc2520_set_channel, */
|
||||
/* detected_energy, */
|
||||
cc2520_cca,
|
||||
cc2520_receiving_packet,
|
||||
pending_packet,
|
||||
cc2520_on,
|
||||
cc2520_off,
|
||||
get_value,
|
||||
set_value,
|
||||
get_object,
|
||||
set_object
|
||||
};
|
||||
{
|
||||
cc2520_init,
|
||||
cc2520_prepare,
|
||||
cc2520_transmit,
|
||||
cc2520_send,
|
||||
cc2520_read,
|
||||
/* cc2520_set_channel, */
|
||||
/* detected_energy, */
|
||||
cc2520_cca,
|
||||
cc2520_receiving_packet,
|
||||
pending_packet,
|
||||
cc2520_on,
|
||||
cc2520_off,
|
||||
get_value,
|
||||
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();
|
||||
|
@ -315,7 +319,7 @@ cc2520_init(void)
|
|||
{
|
||||
{
|
||||
int s = splhigh();
|
||||
cc2520_arch_init(); /* Initalize ports and SPI. */
|
||||
cc2520_arch_init(); /* Initalize ports and SPI. */
|
||||
CC2520_DISABLE_FIFOP_INT();
|
||||
CC2520_FIFOP_INT_INIT();
|
||||
splx(s);
|
||||
|
@ -339,57 +343,57 @@ cc2520_init(void)
|
|||
/* Change default values as recommended in the data sheet, */
|
||||
/* correlation threshold = 20, RX bandpass filter = 1.3uA.*/
|
||||
|
||||
setreg(CC2520_TXCTRL, 0x94);
|
||||
setreg(CC2520_TXPOWER, 0x13); // Output power 1 dBm
|
||||
setreg(CC2520_TXCTRL, 0x94);
|
||||
setreg(CC2520_TXPOWER, 0x13); /* Output power 1 dBm */
|
||||
|
||||
/*
|
||||
|
||||
valeurs de TXPOWER
|
||||
0x03 -> -18 dBm
|
||||
0x2C -> -7 dBm
|
||||
0x88 -> -4 dBm
|
||||
0x81 -> -2 dBm
|
||||
0x32 -> 0 dBm
|
||||
0x13 -> 1 dBm
|
||||
0x32 -> 0 dBm
|
||||
0x13 -> 1 dBm
|
||||
0xAB -> 2 dBm
|
||||
0xF2 -> 3 dBm
|
||||
0xF7 -> 5 dBm
|
||||
*/
|
||||
setreg(CC2520_CCACTRL0, 0xF8); // CCA treshold -80dBm
|
||||
valeurs de TXPOWER
|
||||
0x03 -> -18 dBm
|
||||
0x2C -> -7 dBm
|
||||
0x88 -> -4 dBm
|
||||
0x81 -> -2 dBm
|
||||
0x32 -> 0 dBm
|
||||
0x13 -> 1 dBm
|
||||
0x32 -> 0 dBm
|
||||
0x13 -> 1 dBm
|
||||
0xAB -> 2 dBm
|
||||
0xF2 -> 3 dBm
|
||||
0xF7 -> 5 dBm
|
||||
*/
|
||||
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
|
||||
setreg(CC2520_AGCCTRL2, 0xEB);
|
||||
/* 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
|
||||
setreg(CC2520_EXTCLOCK, 0x00);
|
||||
/* Disable external clock */
|
||||
setreg(CC2520_EXTCLOCK, 0x00);
|
||||
|
||||
// Tune ADC performance
|
||||
setreg(CC2520_ADCTEST0, 0x10);
|
||||
setreg(CC2520_ADCTEST1, 0x0E);
|
||||
setreg(CC2520_ADCTEST2, 0x03);
|
||||
/* Tune ADC performance */
|
||||
setreg(CC2520_ADCTEST0, 0x10);
|
||||
setreg(CC2520_ADCTEST1, 0x0E);
|
||||
setreg(CC2520_ADCTEST2, 0x03);
|
||||
|
||||
/* 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_FRMCTRL0, AUTOCRC | AUTOACK);
|
||||
setreg(CC2520_FRMFILT0, FRAME_MAX_VERSION | FRAME_FILTER_ENABLE);
|
||||
#else
|
||||
/* setreg(CC2520_FRMCTRL0, 0x60); */
|
||||
setreg(CC2520_FRMCTRL0, AUTOCRC);
|
||||
setreg(CC2520_FRMCTRL0, AUTOCRC);
|
||||
/* Disable filter on @ (remove if you want to address specific wismote) */
|
||||
setreg(CC2520_FRMFILT0, 0x00);
|
||||
setreg(CC2520_FRMFILT0, 0x00);
|
||||
#endif /* CC2520_CONF_AUTOACK */
|
||||
/* SET_RXENMASK_ON_TX */
|
||||
setreg(CC2520_FRMCTRL1, 1);
|
||||
setreg(CC2520_FRMCTRL1, 1);
|
||||
/* Set FIFOP threshold to maximum .*/
|
||||
setreg(CC2520_FIFOPCTRL, FIFOP_THR(0x7F));
|
||||
setreg(CC2520_FIFOPCTRL, FIFOP_THR(0x7F));
|
||||
|
||||
cc2520_set_pan_addr(0xffff, 0x0000, NULL);
|
||||
cc2520_set_channel(26);
|
||||
|
@ -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);
|
||||
|
@ -457,24 +461,24 @@ cc2520_transmit(unsigned short payload_len)
|
|||
return RADIO_TX_COLLISION;
|
||||
}
|
||||
if(receive_on) {
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
}
|
||||
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);
|
||||
accurate measurement of the transmission time.*/
|
||||
/* 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) {
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
} else {
|
||||
/* We need to explicitly turn off the radio,
|
||||
* since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */
|
||||
off();
|
||||
/* We need to explicitly turn off the radio,
|
||||
* since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */
|
||||
off();
|
||||
}
|
||||
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
|
||||
|
@ -510,9 +514,9 @@ cc2520_prepare(const void *payload, unsigned short payload_len)
|
|||
|
||||
PRINTF("cc2520: sending %d bytes\n", payload_len);
|
||||
/*int i;
|
||||
for(i = 0; i < payload_len;i++)
|
||||
printf("%x",((uint8_t *) payload)[i]);
|
||||
printf("\n");*/
|
||||
for(i = 0; i < payload_len;i++)
|
||||
printf("%x",((uint8_t *) payload)[i]);
|
||||
printf("\n");*/
|
||||
RIMESTATS_ADD(lltx);
|
||||
|
||||
/* Wait for any previous transmission to finish. */
|
||||
|
@ -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)
|
||||
{
|
||||
return cc2520_rssi();
|
||||
}
|
||||
*/
|
||||
static int
|
||||
detected_energy(void)
|
||||
{
|
||||
return cc2520_rssi();
|
||||
}
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
cc2520_cca_valid(void)
|
||||
|
|
2
doc/uip6-doc.txt
Normal file → Executable file
2
doc/uip6-doc.txt
Normal file → Executable 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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
TARGET = cc2530dk
|
|
@ -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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -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_ */
|
|
@ -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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
TARGET = cc2538dk
|
|
@ -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,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -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),
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
10
examples/rime-tsch/Makefile
Normal file
10
examples/rime-tsch/Makefile
Normal 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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
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,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
88
examples/rime-tsch/project-conf.h
Normal file
88
examples/rime-tsch/project-conf.h
Normal 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
25
examples/sensniff/Makefile
Executable 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
|
83
examples/sensniff/README.md
Normal file
83
examples/sensniff/README.md
Normal 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
Loading…
Reference in a new issue