diff --git a/.gitmodules b/.gitmodules index eecb69722..af65c1bda 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/apps/oma-lwm2m/lwm2m-engine.c b/apps/oma-lwm2m/lwm2m-engine.c index 0fe86bbbb..debce0282 100644 --- a/apps/oma-lwm2m/lwm2m-engine.c +++ b/apps/oma-lwm2m/lwm2m-engine.c @@ -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("", object->id); + rdlen = snprintf(buffer, size, "", + 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(",", 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); + } } } /*---------------------------------------------------------------------------*/ diff --git a/apps/webserver/httpd-cgi.c b/apps/webserver/httpd-cgi.c index d0e7e9532..506d024d2 100644 --- a/apps/webserver/httpd-cgi.c +++ b/apps/webserver/httpd-cgi.c @@ -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(), "%d%s:%u%s%u%u%c %c\r\n", diff --git a/core/dev/slip.c b/core/dev/slip.c index 451b9ec6c..299c78e3f 100644 --- a/core/dev/slip.c +++ b/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; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index df3f0608d..ea6ed6753 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -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 diff --git a/core/net/ip/uip-debug.c b/core/net/ip/uip-debug.c old mode 100644 new mode 100755 index 7804ba4db..737c7d5dc --- a/core/net/ip/uip-debug.c +++ b/core/net/ip/uip-debug.c @@ -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 { diff --git a/core/net/ip/uip.h b/core/net/ip/uip.h old mode 100644 new mode 100755 index 12d77ff10..dd41b25f0 --- a/core/net/ip/uip.h +++ b/core/net/ip/uip.h @@ -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) \ diff --git a/core/net/ipv6/multicast/README.md b/core/net/ipv6/multicast/README.md index 7a33fca0f..e65c39f6a 100644 --- a/core/net/ipv6/multicast/README.md +++ b/core/net/ipv6/multicast/README.md @@ -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. diff --git a/core/net/ipv6/uip-ds6-nbr.h b/core/net/ipv6/uip-ds6-nbr.h index 40a17d1e2..0e22e22dc 100644 --- a/core/net/ipv6/uip-ds6-nbr.h +++ b/core/net/ipv6/uip-ds6-nbr.h @@ -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 */ diff --git a/core/net/ipv6/uip-ds6-route.h b/core/net/ipv6/uip-ds6-route.h index 6855fc2cd..d6f88e943 100644 --- a/core/net/ipv6/uip-ds6-route.h +++ b/core/net/ipv6/uip-ds6-route.h @@ -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 diff --git a/core/net/ipv6/uip-ds6.h b/core/net/ipv6/uip-ds6.h index 294eb230c..8803729a0 100644 --- a/core/net/ipv6/uip-ds6.h +++ b/core/net/ipv6/uip-ds6.h @@ -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 */ diff --git a/core/net/ipv6/uip-icmp6.c b/core/net/ipv6/uip-icmp6.c index d246a4d58..466627a98 100644 --- a/core/net/ipv6/uip-icmp6.c +++ b/core/net/ipv6/uip-icmp6.c @@ -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(); } /*---------------------------------------------------------------------------*/ diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 218507228..d938ac2a0 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -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); diff --git a/core/net/ipv6/uip6.c b/core/net/ipv6/uip6.c index 94f4dfcf9..3cdcfaa8d 100644 --- a/core/net/ipv6/uip6.c +++ b/core/net/ipv6/uip6.c @@ -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; diff --git a/core/net/mac/contikimac/contikimac.c b/core/net/mac/contikimac/contikimac.c index 47e2b5733..7912fe7dd 100644 --- a/core/net/mac/contikimac/contikimac.c +++ b/core/net/mac/contikimac/contikimac.c @@ -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) { @@ -485,24 +494,27 @@ 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)); + rtimer_arch_sleep(RTIMER_NOW() - cycle_start); } 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 +565,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 +613,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 +628,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 +648,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 +856,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 +868,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 +885,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; diff --git a/core/net/mac/frame802154.c b/core/net/mac/frame802154.c index 77727ab47..a188a7358 100644 --- a/core/net/mac/frame802154.c +++ b/core/net/mac/frame802154.c @@ -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 */ diff --git a/core/net/mac/framer-802154.c b/core/net/mac/framer-802154.c index 7e524afb1..35e39cf33 100644 --- a/core/net/mac/framer-802154.c +++ b/core/net/mac/framer-802154.c @@ -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; diff --git a/core/net/mac/mac-sequence.c b/core/net/mac/mac-sequence.c index 40ac3c28a..ccbbb2114 100644 --- a/core/net/mac/mac-sequence.c +++ b/core/net/mac/mac-sequence.c @@ -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)); } diff --git a/core/net/mac/tsch/README.md b/core/net/mac/tsch/README.md index 0b7c54ef3..fc07f4007 100644 --- a/core/net/mac/tsch/README.md +++ b/core/net/mac/tsch/README.md @@ -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 diff --git a/core/net/mac/tsch/tsch-packet.c b/core/net/mac/tsch/tsch-packet.c index 17601d054..100a4ccde 100644 --- a/core/net/mac/tsch/tsch-packet.c +++ b/core/net/mac/tsch/tsch-packet.c @@ -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; diff --git a/core/net/mac/tsch/tsch-packet.h b/core/net/mac/tsch/tsch-packet.h index c48bd479b..e974230e5 100644 --- a/core/net/mac/tsch/tsch-packet.h +++ b/core/net/mac/tsch/tsch-packet.h @@ -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 */ diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index be83da4ab..62a7942f4 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -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; diff --git a/core/net/mac/tsch/tsch-slot-operation.h b/core/net/mac/tsch/tsch-slot-operation.h index f74778c00..ec05d8736 100644 --- a/core/net/mac/tsch/tsch-slot-operation.h +++ b/core/net/mac/tsch/tsch-slot-operation.h @@ -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 *****/ diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index 292744ecc..083280404 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -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; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/rime/chameleon-bitopt.c b/core/net/rime/chameleon-bitopt.c index 78bb58ebc..f659b312b 100644 --- a/core/net/rime/chameleon-bitopt.c +++ b/core/net/rime/chameleon-bitopt.c @@ -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; diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 4e9af23f7..931e9b915 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -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 diff --git a/core/net/rpl/rpl-ext-header.c b/core/net/rpl/rpl-ext-header.c index b6d17d4a9..80de287d9 100644 --- a/core/net/rpl/rpl-ext-header.c +++ b/core/net/rpl/rpl-ext-header.c @@ -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(); + } } } diff --git a/core/net/rpl/rpl-ns.h b/core/net/rpl/rpl-ns.h index 66f911f77..96c05dedb 100644 --- a/core/net/rpl/rpl-ns.h +++ b/core/net/rpl/rpl-ns.h @@ -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 */ diff --git a/cpu/6502/net/ethernet-drv.c b/cpu/6502/net/ethernet-drv.c index d5e2b80fa..d5348e644 100644 --- a/cpu/6502/net/ethernet-drv.c +++ b/cpu/6502/net/ethernet-drv.c @@ -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 */ diff --git a/cpu/6502/net/ethernet-drv.h b/cpu/6502/net/ethernet-drv.h index 6a238a9dc..4602e9fab 100644 --- a/cpu/6502/net/ethernet-drv.h +++ b/cpu/6502/net/ethernet-drv.h @@ -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_ */ diff --git a/cpu/arm/aducrf101/dev/radio.c b/cpu/arm/aducrf101/dev/radio.c index 6e2b2ca47..49cc5c124 100644 --- a/cpu/arm/aducrf101/dev/radio.c +++ b/cpu/arm/aducrf101/dev/radio.c @@ -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; } /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2538/dbg.h b/cpu/cc2538/dbg.h index 2e283c0b1..4ac02148a 100644 --- a/cpu/cc2538/dbg.h +++ b/cpu/cc2538/dbg.h @@ -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 diff --git a/cpu/cc2538/dev/cc2538-rf.c b/cpu/cc2538/dev/cc2538-rf.c index 52708e0ca..300ab7dee 100644 --- a/cpu/cc2538/dev/cc2538-rf.c +++ b/cpu/cc2538/dev/cc2538-rf.c @@ -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)); -} -/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/cpu/cc2538/dev/ecc-algorithm.c b/cpu/cc2538/dev/ecc-algorithm.c index 7ecd99ad8..9e389375f 100644 --- a/cpu/cc2538/dev/ecc-algorithm.c +++ b/cpu/cc2538/dev/ecc-algorithm.c @@ -29,7 +29,7 @@ * SUCH DAMAGE. */ /** - * \addtogroup c2538-ecc-algo + * \addtogroup cc2538-ecc-algo * @{ * * \file diff --git a/cpu/cc2538/dev/ecc-curve.c b/cpu/cc2538/dev/ecc-curve.c index d3291d1b6..fa8408a4c 100644 --- a/cpu/cc2538/dev/ecc-curve.c +++ b/cpu/cc2538/dev/ecc-curve.c @@ -29,7 +29,7 @@ * SUCH DAMAGE. */ /** - * \addtogroup c2538-ecc-curves + * \addtogroup cc2538-ecc-curves * @{ */ #include "contiki.h" diff --git a/cpu/cc2538/dev/i2c.c b/cpu/cc2538/dev/i2c.c index 76cac20f8..34537a08f 100644 --- a/cpu/cc2538/dev/i2c.c +++ b/cpu/cc2538/dev/i2c.c @@ -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); diff --git a/cpu/cc2538/dev/pwm.c b/cpu/cc2538/dev/pwm.c index d6b5b9286..73440013b 100644 --- a/cpu/cc2538/dev/pwm.c +++ b/cpu/cc2538/dev/pwm.c @@ -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); diff --git a/cpu/cc2538/dev/pwm.h b/cpu/cc2538/dev/pwm.h index 744fa4b6c..294ec3559 100644 --- a/cpu/cc2538/dev/pwm.h +++ b/cpu/cc2538/dev/pwm.h @@ -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] diff --git a/cpu/cc2538/dev/sha256.h b/cpu/cc2538/dev/sha256.h index b2e799bd8..86508e267 100644 --- a/cpu/cc2538/dev/sha256.h +++ b/cpu/cc2538/dev/sha256.h @@ -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 * @{ diff --git a/cpu/cc2538/dev/uart.c b/cpu/cc2538/dev/uart.c index cefbecf82..f4764877c 100644 --- a/cpu/cc2538/dev/uart.c +++ b/cpu/cc2538/dev/uart.c @@ -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; } } diff --git a/cpu/cc253x/dev/cc2530-rf.c b/cpu/cc253x/dev/cc2530-rf.c index 55e7d3125..52c9a1c3e 100644 --- a/cpu/cc253x/dev/cc2530-rf.c +++ b/cpu/cc253x/dev/cc2530-rf.c @@ -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); diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index 6922b45fc..9efbf091f 100644 --- a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -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 diff --git a/cpu/cc26xx-cc13xx/dev/aux-ctrl.c b/cpu/cc26xx-cc13xx/dev/aux-ctrl.c index eb316d3df..48d2da460 100644 --- a/cpu/cc26xx-cc13xx/dev/aux-ctrl.c +++ b/cpu/cc26xx-cc13xx/dev/aux-ctrl.c @@ -36,6 +36,7 @@ #include #include +#include /*---------------------------------------------------------------------------*/ LIST(consumers_list); /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c index d7753066f..140a5d203 100644 --- a/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c +++ b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c @@ -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 diff --git a/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c index b080a5d3f..41ac5b5c6 100644 --- a/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c +++ b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c @@ -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); diff --git a/cpu/cc26xx-cc13xx/dev/soc-rtc.c b/cpu/cc26xx-cc13xx/dev/soc-rtc.c index 398f14d6a..110a584c5 100644 --- a/cpu/cc26xx-cc13xx/dev/soc-rtc.c +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.c @@ -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) { diff --git a/cpu/cc26xx-cc13xx/dev/soc-trng.c b/cpu/cc26xx-cc13xx/dev/soc-trng.c new file mode 100644 index 000000000..33a217be8 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/soc-trng.c @@ -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 +#include +#include +/*---------------------------------------------------------------------------*/ +#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); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/soc-trng.h b/cpu/cc26xx-cc13xx/dev/soc-trng.h new file mode 100644 index 000000000..f84370168 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/soc-trng.h @@ -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 +/*---------------------------------------------------------------------------*/ +#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_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c index 3253202c2..f73c7827b 100644 --- a/cpu/cc26xx-cc13xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -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); } /*---------------------------------------------------------------------------*/ /** diff --git a/examples/zolertia/zoul/cc1200-sniffer/sniffer.c b/cpu/cc26xx-cc13xx/random.c similarity index 72% rename from examples/zolertia/zoul/cc1200-sniffer/sniffer.c rename to cpu/cc26xx-cc13xx/random.c index a0241f795..3b13a82de 100644 --- a/examples/zolertia/zoul/cc1200-sniffer/sniffer.c +++ b/cpu/cc26xx-cc13xx/random.c @@ -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(); } /*---------------------------------------------------------------------------*/ - /** - * @} * @} */ diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index 08843d699..f76fe2beb 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -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(), diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index 94aef33b9..21e54c181 100644 --- a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -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; } diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 15fc8e3bc..8fc9541f6 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -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(); diff --git a/cpu/cc26xx-cc13xx/ti-lib-rom.h b/cpu/cc26xx-cc13xx/ti-lib-rom.h new file mode 100644 index 000000000..7334978b9 --- /dev/null +++ b/cpu/cc26xx-cc13xx/ti-lib-rom.h @@ -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_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/cc26xx-cc13xx/ti-lib.h b/cpu/cc26xx-cc13xx/ti-lib.h index c08d05ce3..c8b38c2c6 100644 --- a/cpu/cc26xx-cc13xx/ti-lib.h +++ b/cpu/cc26xx-cc13xx/ti-lib.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" diff --git a/cpu/msp430/f2xxx/uart0.c b/cpu/msp430/f2xxx/uart0.c index 79c75f877..cbba2e7b9 100644 --- a/cpu/msp430/f2xxx/uart0.c +++ b/cpu/msp430/f2xxx/uart0.c @@ -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 */ diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.c b/cpu/x86/drivers/legacy_pc/uart-16x50.c index d17e61498..7d9493c74 100644 --- a/cpu/x86/drivers/legacy_pc/uart-16x50.c +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.c @@ -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); diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.h b/cpu/x86/drivers/legacy_pc/uart-16x50.h index 4a038b948..8a3ddad49 100644 --- a/cpu/x86/drivers/legacy_pc/uart-16x50.h +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.h @@ -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); diff --git a/cpu/x86/drivers/quarkX1000/uart.c b/cpu/x86/drivers/quarkX1000/uart.c index 341e31cf7..2044e42e8 100644 --- a/cpu/x86/drivers/quarkX1000/uart.c +++ b/cpu/x86/drivers/quarkX1000/uart.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); } /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/x86/drivers/quarkX1000/uart.h b/cpu/x86/drivers/quarkX1000/uart.h index 8b545d8cd..6b1312ed8 100644 --- a/cpu/x86/drivers/quarkX1000/uart.h +++ b/cpu/x86/drivers/quarkX1000/uart.h @@ -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_ */ diff --git a/dev/cc1200/cc1200-conf.h b/dev/cc1200/cc1200-conf.h index 1e50cc828..9d28922a4 100644 --- a/dev/cc1200/cc1200-conf.h +++ b/dev/cc1200/cc1200-conf.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_ */ diff --git a/dev/cc1200/cc1200.c b/dev/cc1200/cc1200.c index bed33c5b6..013c54ee6 100644 --- a/dev/cc1200/cc1200.c +++ b/dev/cc1200/cc1200.c @@ -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 diff --git a/dev/cc2520/cc2520.c b/dev/cc2520/cc2520.c index e0dad1b6a..c24af2670 100644 --- a/dev/cc2520/cc2520.c +++ b/dev/cc2520/cc2520.c @@ -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 #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) diff --git a/doc/uip6-doc.txt b/doc/uip6-doc.txt old mode 100644 new mode 100755 index 492337f25..916196765 --- a/doc/uip6-doc.txt +++ b/doc/uip6-doc.txt @@ -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. diff --git a/examples/avr-rss2/ipv6/sensd_client/README.md b/examples/avr-rss2/ipv6/sensd_client/README.md index 17beb02f3..b8cc23ae6 100644 --- a/examples/avr-rss2/ipv6/sensd_client/README.md +++ b/examples/avr-rss2/ipv6/sensd_client/README.md @@ -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 -Jens Laas - -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 diff --git a/examples/cc2530dk/sniffer/Makefile b/examples/cc2530dk/sniffer/Makefile deleted file mode 100644 index f57ded291..000000000 --- a/examples/cc2530dk/sniffer/Makefile +++ /dev/null @@ -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 diff --git a/examples/cc2530dk/sniffer/Makefile.target b/examples/cc2530dk/sniffer/Makefile.target deleted file mode 100644 index 70609bbdb..000000000 --- a/examples/cc2530dk/sniffer/Makefile.target +++ /dev/null @@ -1 +0,0 @@ -TARGET = cc2530dk diff --git a/examples/cc2530dk/sniffer/netstack.c b/examples/cc2530dk/sniffer/netstack.c deleted file mode 100644 index d59acc3fe..000000000 --- a/examples/cc2530dk/sniffer/netstack.c +++ /dev/null @@ -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 - - */ - -#include "netstack.h" -/*---------------------------------------------------------------------------*/ -void -netstack_init(void) -{ - NETSTACK_RADIO.init(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2530dk/sniffer/project-conf.h b/examples/cc2530dk/sniffer/project-conf.h deleted file mode 100644 index 9f8af335a..000000000 --- a/examples/cc2530dk/sniffer/project-conf.h +++ /dev/null @@ -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 - - */ - -#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_ */ diff --git a/examples/cc2530dk/sniffer/sniffer.c b/examples/cc2530dk/sniffer/sniffer.c deleted file mode 100644 index 7ad375d88..000000000 --- a/examples/cc2530dk/sniffer/sniffer.c +++ /dev/null @@ -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(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2538-common/sniffer/Makefile b/examples/cc2538-common/sniffer/Makefile deleted file mode 100644 index d40baddd8..000000000 --- a/examples/cc2538-common/sniffer/Makefile +++ /dev/null @@ -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 diff --git a/examples/cc2538-common/sniffer/Makefile.target b/examples/cc2538-common/sniffer/Makefile.target deleted file mode 100644 index 777593c88..000000000 --- a/examples/cc2538-common/sniffer/Makefile.target +++ /dev/null @@ -1 +0,0 @@ -TARGET = cc2538dk diff --git a/examples/cc2538-common/sniffer/stub-rdc.c b/examples/cc2538-common/sniffer/stub-rdc.c deleted file mode 100644 index a8c54de6a..000000000 --- a/examples/cc2538-common/sniffer/stub-rdc.c +++ /dev/null @@ -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 - - */ -#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, -}; -/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2538-common/test-pwm.c b/examples/cc2538-common/test-pwm.c index a1fa8c727..4aa5aede6 100644 --- a/examples/cc2538-common/test-pwm.c +++ b/examples/cc2538-common/test-pwm.c @@ -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), diff --git a/examples/cc26xx/cc26xx-web-demo/project-conf.h b/examples/cc26xx/cc26xx-web-demo/project-conf.h index ee77b125f..adf2f1427 100644 --- a/examples/cc26xx/cc26xx-web-demo/project-conf.h +++ b/examples/cc26xx/cc26xx-web-demo/project-conf.h @@ -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_ */ diff --git a/examples/cc26xx/project-conf.h b/examples/cc26xx/project-conf.h index 7c1363c16..fc2d23ab1 100644 --- a/examples/cc26xx/project-conf.h +++ b/examples/cc26xx/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 diff --git a/examples/cc26xx/very-sleepy-demo/project-conf.h b/examples/cc26xx/very-sleepy-demo/project-conf.h index 477a535bf..8e58e12da 100644 --- a/examples/cc26xx/very-sleepy-demo/project-conf.h +++ b/examples/cc26xx/very-sleepy-demo/project-conf.h @@ -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 diff --git a/examples/galileo/gpio-input.c b/examples/galileo/gpio-input.c index 196ea9193..804c9a86e 100644 --- a/examples/galileo/gpio-input.c +++ b/examples/galileo/gpio-input.c @@ -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); diff --git a/examples/galileo/gpio-interrupt.c b/examples/galileo/gpio-interrupt.c index 04fb4cc1b..6289fe4f1 100644 --- a/examples/galileo/gpio-interrupt.c +++ b/examples/galileo/gpio-interrupt.c @@ -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); diff --git a/examples/galileo/gpio-output.c b/examples/galileo/gpio-output.c index 4dad7d684..33a1159da 100644 --- a/examples/galileo/gpio-output.c +++ b/examples/galileo/gpio-output.c @@ -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); diff --git a/examples/ipv6/multicast/project-conf.h b/examples/ipv6/multicast/project-conf.h index 8df6d01b4..0c47ab538 100644 --- a/examples/ipv6/multicast/project-conf.h +++ b/examples/ipv6/multicast/project-conf.h @@ -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_ */ diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index 84943e68f..90b1fdf23 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -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("Routes
");
+  ADD("
Routes
\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("
"); +#if RPL_WITH_NON_STORING + ADD("Links
\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("");
+      ipaddr_add(&child_ipaddr);
+      ADD("");
+#else
+      ipaddr_add(&child_ipaddr);
+#endif
+#else
+#if WEBSERVER_CONF_ROUTE_LINKS
+      ADD("");
+      SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
+      blen = 0;
+      ipaddr_add(&child_ipaddr);
+      ADD("");
+#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("
"); +#endif /* RPL_WITH_NON_STORING */ + #if WEBSERVER_CONF_FILESTATS static uint16_t numtimes; ADD("
This page sent %u times",++numtimes); diff --git a/examples/ipv6/rpl-tsch/node.c b/examples/ipv6/rpl-tsch/node.c index 35852b608..a49540f7a 100644 --- a/examples/ipv6/rpl-tsch/node.c +++ b/examples/ipv6/rpl-tsch/node.c @@ -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 diff --git a/examples/ipv6/rpl-tsch/project-conf.h b/examples/ipv6/rpl-tsch/project-conf.h index 8ac0a93b6..d1af39604 100644 --- a/examples/ipv6/rpl-tsch/project-conf.h +++ b/examples/ipv6/rpl-tsch/project-conf.h @@ -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__ */ diff --git a/examples/ipv6/rpl-udp/project-conf.h b/examples/ipv6/rpl-udp/project-conf.h index 794897a46..1d0a04d52 100644 --- a/examples/ipv6/rpl-udp/project-conf.h +++ b/examples/ipv6/rpl-udp/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. */ diff --git a/examples/rime-tsch/Makefile b/examples/rime-tsch/Makefile new file mode 100644 index 000000000..8d9ac3116 --- /dev/null +++ b/examples/rime-tsch/Makefile @@ -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 diff --git a/examples/cc2530dk/sniffer/stub-rdc.c b/examples/rime-tsch/node.c similarity index 58% rename from examples/cc2530dk/sniffer/stub-rdc.c rename to examples/rime-tsch/node.c index a4db0710d..b8c017779 100644 --- a/examples/cc2530dk/sniffer/stub-rdc.c +++ b/examples/rime-tsch/node.c @@ -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 - + * Simon Duquennoy + * */ -#include "net/mac/mac.h" -#include "net/mac/rdc.h" +#include +#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, -}; -/*---------------------------------------------------------------------------*/ diff --git a/examples/rime-tsch/project-conf.h b/examples/rime-tsch/project-conf.h new file mode 100644 index 000000000..8a48917db --- /dev/null +++ b/examples/rime-tsch/project-conf.h @@ -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 + * + */ + +#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__ */ diff --git a/examples/sensniff/Makefile b/examples/sensniff/Makefile new file mode 100755 index 000000000..0bc269162 --- /dev/null +++ b/examples/sensniff/Makefile @@ -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 diff --git a/examples/sensniff/README.md b/examples/sensniff/README.md new file mode 100644 index 000000000..140db4bc9 --- /dev/null +++ b/examples/sensniff/README.md @@ -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() + #define sensniff_io_flush() + #define sensniff_io_set_input() + +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! + diff --git a/examples/sensniff/cc2530dk/Makefile.cc2530dk b/examples/sensniff/cc2530dk/Makefile.cc2530dk new file mode 100644 index 000000000..35c94610a --- /dev/null +++ b/examples/sensniff/cc2530dk/Makefile.cc2530dk @@ -0,0 +1 @@ +HAVE_BANKING = 1 diff --git a/examples/sensniff/cc2530dk/target-conf.h b/examples/sensniff/cc2530dk/target-conf.h new file mode 100644 index 000000000..69e405390 --- /dev/null +++ b/examples/sensniff/cc2530dk/target-conf.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* Change to 0 to build for the SmartRF + cc2530 EM */ +#define MODELS_CONF_CC2531_USB_STICK 1 +/*---------------------------------------------------------------------------*/ +/* Don't change below this line */ +#define ADC_SENSOR_CONF_ON 0 +#define LPM_CONF_MODE 0 +#define UART0_CONF_HIGH_SPEED 1 +#define UART0_RTSCTS 1 +#define UART0_CONF_WITH_INPUT 1 +#define USB_SERIAL_CONF_BUFFERED 1 +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "pool/cc2530-cc2531-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/cc2538dk/target-conf.h b/examples/sensniff/cc2538dk/target-conf.h new file mode 100644 index 000000000..56aadcb4b --- /dev/null +++ b/examples/sensniff/cc2538dk/target-conf.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* + * Selection of Sensniff I/O Interface. + * Define CC2538_IO_CONF_USB as 0 to use UART as sensniff's interface. + * This will default to using UART0, unless you also define + * CC2538_IO_CONF_USE_UART_1 as 1. + * + * Don't forget to also set a correct baud rate (460800 or higher) by defining + * the corresponding UART0_CONF_BAUD_RATE or UART1_CONF_BAUD_RATE + */ +#define CC2538_IO_CONF_USB 1 +#define CC2538_IO_CONF_USE_UART1 0 +/*---------------------------------------------------------------------------*/ +#if CC2538_IO_CONF_USB +#define USB_SERIAL_CONF_ENABLE 1 +#endif +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "pool/cc2538-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/ev-aducrf101mkxz/ev-aducrf101mkxz-io.h b/examples/sensniff/ev-aducrf101mkxz/ev-aducrf101mkxz-io.h new file mode 100644 index 000000000..883e5e598 --- /dev/null +++ b/examples/sensniff/ev-aducrf101mkxz/ev-aducrf101mkxz-io.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef EV_ADUCRF101MKXZ_IO_H_ +#define EV_ADUCRF101MKXZ_IO_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/uart.h" +/*---------------------------------------------------------------------------*/ +#define sensniff_io_byte_out(b) uart_put(b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) uart_set_input(f) +/*---------------------------------------------------------------------------*/ +#endif /* EV_ADUCRF101MKXZ_IO_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/ev-aducrf101mkxz/target-conf.h b/examples/sensniff/ev-aducrf101mkxz/target-conf.h new file mode 100644 index 000000000..bd3e518d7 --- /dev/null +++ b/examples/sensniff/ev-aducrf101mkxz/target-conf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "ev-aducrf101mkxz/ev-aducrf101mkxz-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/jn516x/jn516x-io.h b/examples/sensniff/jn516x/jn516x-io.h new file mode 100644 index 000000000..d38ae91eb --- /dev/null +++ b/examples/sensniff/jn516x/jn516x-io.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef JN516X_IO_H_ +#define JN516X_IO_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/uart0.h" +#include "dev/uart1.h" +/*---------------------------------------------------------------------------*/ +#ifdef JN516X_IO_CONF_USE_UART1 +#define JN516X_IO_USE_UART1 JN516X_IO_CONF_USE_UART1 +#else +#define JN516X_IO_USE_UART1 0 +#endif +/*---------------------------------------------------------------------------*/ +#if JN516X_IO_USE_UART1 +#define sensniff_io_byte_out(b) uart1_writeb(b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) uart1_set_input(f) +#else +#define sensniff_io_byte_out(b) uart0_writeb(b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) uart0_set_input(f) +#endif +/*---------------------------------------------------------------------------*/ +#endif /* JN516X_IO_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/jn516x/target-conf.h b/examples/sensniff/jn516x/target-conf.h new file mode 100644 index 000000000..8f30be7b2 --- /dev/null +++ b/examples/sensniff/jn516x/target-conf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "jn516x/jn516x-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc2538-common/sniffer/netstack.c b/examples/sensniff/netstack.c similarity index 83% rename from examples/cc2538-common/sniffer/netstack.c rename to examples/sensniff/netstack.c index 3aeb6968e..14068ce77 100644 --- a/examples/cc2538-common/sniffer/netstack.c +++ b/examples/sensniff/netstack.c @@ -26,21 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/** - * \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 - - */ +/*---------------------------------------------------------------------------*/ #include "netstack.h" /*---------------------------------------------------------------------------*/ void netstack_init(void) { NETSTACK_RADIO.init(); - NETSTACK_RADIO.on(); + NETSTACK_RDC.init(); } /*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/openmote-cc2538/target-conf.h b/examples/sensniff/openmote-cc2538/target-conf.h new file mode 100644 index 000000000..c4591eacb --- /dev/null +++ b/examples/sensniff/openmote-cc2538/target-conf.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* + * Selection of Sensniff I/O Interface. + * Define CC2538_IO_CONF_USB as 0 to use UART as sensniff's interface. + * This will default to using UART0, unless you also define + * CC2538_IO_CONF_USE_UART1 as 1. + * + * Don't forget to also set a correct baud rate (460800 or higher) by defining + * the corresponding UART0_CONF_BAUD_RATE or UART1_CONF_BAUD_RATE + */ +#define CC2538_IO_CONF_USB 0 +#define CC2538_IO_CONF_USE_UART1 0 +/*---------------------------------------------------------------------------*/ +#if CC2538_IO_CONF_USB +#define USB_SERIAL_CONF_ENABLE 1 +#else +#define UART0_CONF_BAUD_RATE 460800 +#endif +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "pool/cc2538-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/pool/cc13xx-cc26xx-io.h b/examples/sensniff/pool/cc13xx-cc26xx-io.h new file mode 100644 index 000000000..556fd669a --- /dev/null +++ b/examples/sensniff/pool/cc13xx-cc26xx-io.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef CC13XX_CC26XX_IO_H_ +#define CC13XX_CC26XX_IO_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/cc26xx-uart.h" +/*---------------------------------------------------------------------------*/ +#define sensniff_io_byte_out(b) cc26xx_uart_write_byte(b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) cc26xx_uart_set_input(f) +/*---------------------------------------------------------------------------*/ +#endif /* CC13XX_CC26XX_IO_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/pool/cc2530-cc2531-io.h b/examples/sensniff/pool/cc2530-cc2531-io.h new file mode 100644 index 000000000..08ecc289d --- /dev/null +++ b/examples/sensniff/pool/cc2530-cc2531-io.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef CC2530_CC2531_IO_H_ +#define CC2530_CC2531_IO_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/io-arch.h" +/*---------------------------------------------------------------------------*/ +#define sensniff_io_byte_out(b) io_arch_writeb(b) +#define sensniff_io_flush() io_arch_flush() +#define sensniff_io_set_input(f) io_arch_set_input(f) +/*---------------------------------------------------------------------------*/ +#endif /* CC2530_CC2531_IO_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/pool/cc2538-io.h b/examples/sensniff/pool/cc2538-io.h new file mode 100644 index 000000000..ee82ce0a4 --- /dev/null +++ b/examples/sensniff/pool/cc2538-io.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/uart.h" +#include "usb/usb-serial.h" +/*---------------------------------------------------------------------------*/ +#ifndef CC2538_IO_H_ +#define CC2538_IO_H_ +/*---------------------------------------------------------------------------*/ +/* + * Select whether to use native USB as sensniff's I/O interface. + * If defined as 0, UART will be used. Set to 1 to use USB. + */ +#ifdef CC2538_IO_CONF_USB +#define CC2538_IO_USB CC2538_IO_CONF_USB +#else +#define CC2538_IO_USB 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * UART instance selection. Set to 1 to use UART1. + * Ignored unless CC2538_IO_USB is 0. + */ +#ifdef CC2538_IO_CONF_USE_UART1 +#define CC2538_IO_USE_UART1 CC2538_IO_CONF_USE_UART1 +#else +#define CC2538_IO_USE_UART1 0 +#endif +/*---------------------------------------------------------------------------*/ +#if CC2538_IO_USB +#define sensniff_io_byte_out(b) usb_serial_writeb(b) +#define sensniff_io_flush() usb_serial_flush() +#define sensniff_io_set_input(f) usb_serial_set_input(f) +#else +#if CC2538_IO_USE_UART1 +#define sensniff_io_byte_out(b) uart_write_byte(1, b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) uart_set_input(1, f) +#else +#define sensniff_io_byte_out(b) uart_write_byte(0, b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) uart_set_input(0, f) +#endif /* CC2538_IO_USE_UART_1 */ +#endif /* CC2538_IO_USB */ +/*---------------------------------------------------------------------------*/ +#endif /* CC2538_IO_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/pool/msp430-io.h b/examples/sensniff/pool/msp430-io.h new file mode 100644 index 000000000..a4fefc641 --- /dev/null +++ b/examples/sensniff/pool/msp430-io.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef MSP430_IO_H_ +#define MSP430_IO_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/uart0.h" +#include "dev/uart1.h" +/*---------------------------------------------------------------------------*/ +#ifdef MSP430_IO_CONF_USE_UART1 +#define MSP430_IO_USE_UART1 MSP430_IO_CONF_USE_UART1 +#else +#define MSP430_IO_USE_UART1 0 +#endif +/*---------------------------------------------------------------------------*/ +#if MSP430_IO_USE_UART1 +#define sensniff_io_byte_out(b) uart1_writeb(b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) uart1_set_input(f) +#else +#define sensniff_io_byte_out(b) uart0_writeb(b) +#define sensniff_io_flush() +#define sensniff_io_set_input(f) uart0_set_input(f) +#endif +/*---------------------------------------------------------------------------*/ +#endif /* MSP430_IO_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/zoul/cc1200-sniffer/project-conf.h b/examples/sensniff/project-conf.h similarity index 70% rename from examples/zolertia/zoul/cc1200-sniffer/project-conf.h rename to examples/sensniff/project-conf.h index fca02e711..4d703fc43 100644 --- a/examples/zolertia/zoul/cc1200-sniffer/project-conf.h +++ b/examples/sensniff/project-conf.h @@ -1,16 +1,16 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -28,32 +28,14 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** - * \addtogroup zoul-cc1200-sniffer - * @{ - * - * \file - * Project specific configuration defines for the CC1200 sniffer - */ +/*---------------------------------------------------------------------------*/ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ - -#define CC1200_CONF_SNIFFER 1 -#define CC1200_RF_CONF_SNIFFER_UART 0 -#define CC1200_CONF_RF_CFG cc1200_802154g_863_870_fsk_50kbps - -#undef NETSTACK_CONF_RADIO -#define NETSTACK_CONF_RADIO cc1200_driver - -#define CC1200_CONF_USE_GPIO2 0 -#define CC1200_CONF_USE_RX_WATCHDOG 0 -#define ANTENNA_SW_SELECT_DEF_CONF ANTENNA_SW_SELECT_SUBGHZ - +/*---------------------------------------------------------------------------*/ #undef NETSTACK_CONF_RDC -#define NETSTACK_CONF_RDC stub_rdc_driver - -#define UART0_CONF_BAUD_RATE 460800 - +#define NETSTACK_CONF_RDC sensniff_rdc_driver +/*---------------------------------------------------------------------------*/ +/* Include platform-specific header */ +#include "target-conf.h" +/*---------------------------------------------------------------------------*/ #endif /* PROJECT_CONF_H_ */ - -/** @} */ diff --git a/examples/sensniff/sensniff-rdc.c b/examples/sensniff/sensniff-rdc.c new file mode 100644 index 000000000..3a5eef428 --- /dev/null +++ b/examples/sensniff/sensniff-rdc.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * Copyright (c) 2012-2013, Centre National de la Recherche Scientifique. + * 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. + */ +/*---------------------------------------------------------------------------*/ +/* + * Author: George Oikonomou + * Loosely based on the example contributed by Etienne Duble (CNRS / LIG), as + * part of the work done for the ANR ARESA2 project. + */ +/*---------------------------------------------------------------------------*/ +#include "net/mac/mac.h" +#include "net/mac/rdc.h" +#include "net/netstack.h" +#include "sensniff.h" +/*---------------------------------------------------------------------------*/ +static void +send(mac_callback_t sent, void *ptr) +{ +} +/*---------------------------------------------------------------------------*/ +static void +send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list) +{ +} +/*---------------------------------------------------------------------------*/ +static void +input(void) +{ + sensniff_output_frame(); +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + NETSTACK_RADIO.on(); + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return keep_radio_on; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +cca(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + on(); +} +/*---------------------------------------------------------------------------*/ +const struct rdc_driver sensniff_rdc_driver = { + "sensniff-rdc", + init, + send, + send_list, + input, + on, + off, + cca, +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/sensniff.c b/examples/sensniff/sensniff.c new file mode 100644 index 000000000..93f39ac04 --- /dev/null +++ b/examples/sensniff/sensniff.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sensniff.h" +#include "dev/radio.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "sys/process.h" +#include "sys/ctimer.h" +#include "lib/ringbuf.h" + +#include SENSNIFF_IO_DRIVER_H + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +PROCESS(sensniff_process, "sensniff process"); +AUTOSTART_PROCESSES(&sensniff_process); +/*---------------------------------------------------------------------------*/ +/* Timeout handling for incoming characters. */ +#define TIMEOUT (CLOCK_SECOND >> 1) +static struct ctimer ct; +/*---------------------------------------------------------------------------*/ +#define STATE_WAITING_FOR_MAGIC 0x00 +#define STATE_WAITING_FOR_VERSION 0x01 +#define STATE_WAITING_FOR_CMD 0x02 +#define STATE_WAITING_FOR_LEN_1 0x03 +#define STATE_WAITING_FOR_LEN_2 0x04 +#define STATE_WAITING_FOR_DATA 0x05 + +static uint8_t state; +static uint8_t in_ct; +/*---------------------------------------------------------------------------*/ +#define CMD_FRAME 0x00 +#define CMD_CHANNEL 0x01 +#define CMD_CHANNEL_MIN 0x02 +#define CMD_CHANNEL_MAX 0x03 +#define CMD_ERR_NOT_SUPPORTED 0x7F +#define CMD_GET_CHANNEL 0x81 +#define CMD_GET_CHANNEL_MIN 0x82 +#define CMD_GET_CHANNEL_MAX 0x83 +#define CMD_SET_CHANNEL 0x84 +/*---------------------------------------------------------------------------*/ +#define PROTOCOL_VERSION 2 +/*---------------------------------------------------------------------------*/ +#define BUFSIZE 32 + +static struct ringbuf rxbuf; + +typedef struct cmd_in_s { + uint8_t cmd; + uint16_t len; + uint8_t data; +} cmd_in_t; + +static cmd_in_t command; + +uint8_t cmd_buf[BUFSIZE]; +/*---------------------------------------------------------------------------*/ +static const uint8_t magic[] = { 0xC1, 0x1F, 0xFE, 0x72 }; +/*---------------------------------------------------------------------------*/ +static void +reset_state(void *byte) +{ + state = STATE_WAITING_FOR_MAGIC; + in_ct = 0; + memset(&command, 0, sizeof(command)); +} +/*---------------------------------------------------------------------------*/ +static void +send_header(uint8_t cmd, uint16_t len) +{ + uint16_t i; + + /* Send the magic */ + for(i = 0; i < 4; i++) { + sensniff_io_byte_out(magic[i]); + } + + /* Send the protocol version */ + sensniff_io_byte_out(PROTOCOL_VERSION); + + /* Send the command byte */ + sensniff_io_byte_out(cmd); + + /* Send the length, network endianness */ + sensniff_io_byte_out(len >> 8); + sensniff_io_byte_out(len & 0xFF); +} +/*---------------------------------------------------------------------------*/ +static void +send_error(void) +{ + send_header(CMD_ERR_NOT_SUPPORTED, 0); + + sensniff_io_flush(); +} +/*---------------------------------------------------------------------------*/ +static void +send_channel(void) +{ + radio_value_t chan; + + if(NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &chan) == + RADIO_RESULT_OK) { + send_header(CMD_CHANNEL, 1); + sensniff_io_byte_out(chan & 0xFF); + sensniff_io_flush(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static void +set_channel(uint8_t channel) +{ + if(NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, channel) == + RADIO_RESULT_OK) { + send_channel(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static void +send_channel_min(void) +{ + radio_value_t chan; + + if(NETSTACK_RADIO.get_value(RADIO_CONST_CHANNEL_MIN, &chan) == + RADIO_RESULT_OK) { + send_header(CMD_CHANNEL_MIN, 1); + sensniff_io_byte_out(chan & 0xFF); + sensniff_io_flush(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static void +send_channel_max(void) +{ + radio_value_t chan; + + if(NETSTACK_RADIO.get_value(RADIO_CONST_CHANNEL_MAX, &chan) == + RADIO_RESULT_OK) { + send_header(CMD_CHANNEL_MAX, 1); + sensniff_io_byte_out(chan & 0xFF); + sensniff_io_flush(); + return; + } + + send_error(); +} +/*---------------------------------------------------------------------------*/ +static int +char_in(unsigned char c) +{ + /* Bump the timeout counter */ + ctimer_set(&ct, TIMEOUT, reset_state, NULL); + + /* Add the character to our ringbuf and poll the consumer process. */ + ringbuf_put(&rxbuf, c); + + process_poll(&sensniff_process); + return 1; +} +/*---------------------------------------------------------------------------*/ +void +sensniff_output_frame() +{ + int i; + uint8_t len = packetbuf_datalen() & 0xFF; + + send_header(CMD_FRAME, len + 2); + + for(i = 0; i < len; i++) { + sensniff_io_byte_out(((uint8_t *)packetbuf_dataptr())[i]); + } + + sensniff_io_byte_out(packetbuf_attr(PACKETBUF_ATTR_RSSI) & 0xFF); + sensniff_io_byte_out(0x80 | + (packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY) & 0xFF)); + + sensniff_io_flush(); +} +/*---------------------------------------------------------------------------*/ +static void +execute_command(void) +{ + switch(command.cmd) { + case CMD_GET_CHANNEL: + send_channel(); + break; + case CMD_GET_CHANNEL_MIN: + send_channel_min(); + break; + case CMD_GET_CHANNEL_MAX: + send_channel_max(); + break; + case CMD_SET_CHANNEL: + set_channel(command.data); + break; + default: + send_error(); + break; + } +} +/*---------------------------------------------------------------------------*/ +static void +process_incoming_data(void) +{ + int c = 0; + uint8_t byte_in; + + c = ringbuf_get(&rxbuf); + + while(c != -1) { + byte_in = (uint8_t)c; + switch(state) { + case STATE_WAITING_FOR_MAGIC: + if(byte_in == magic[in_ct]) { + in_ct++; + if(in_ct == sizeof(magic)) { + state = STATE_WAITING_FOR_VERSION; + in_ct = 0; + } + } else { + reset_state(&byte_in); + } + break; + case STATE_WAITING_FOR_VERSION: + if(byte_in == PROTOCOL_VERSION) { + state = STATE_WAITING_FOR_CMD; + } else { + reset_state(&byte_in); + } + break; + case STATE_WAITING_FOR_CMD: + command.cmd = byte_in; + + if(command.cmd == CMD_GET_CHANNEL || + command.cmd == CMD_GET_CHANNEL_MIN || + command.cmd == CMD_GET_CHANNEL_MAX) { + execute_command(); + reset_state(&byte_in); + } else { + state = STATE_WAITING_FOR_LEN_1; + } + break; + case STATE_WAITING_FOR_LEN_1: + command.len = byte_in << 8; + state = STATE_WAITING_FOR_LEN_2; + break; + case STATE_WAITING_FOR_LEN_2: + command.len |= byte_in; + if(command.len == 1) { + state = STATE_WAITING_FOR_DATA; + } else { + reset_state(&byte_in); + } + break; + case STATE_WAITING_FOR_DATA: + command.data = byte_in; + execute_command(); + reset_state(&byte_in); + break; + default: + break; + } + c = ringbuf_get(&rxbuf); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sensniff_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Turn off RF frame filtering and H/W ACKs */ + if(NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0) != RADIO_RESULT_OK) { + PRINTF("sensniff: Error setting RF in promiscuous mode\n"); + PROCESS_EXIT(); + } + + /* Initialise the ring buffer */ + ringbuf_init(&rxbuf, cmd_buf, sizeof(cmd_buf)); + + /* Initialise the state machine */ + reset_state(NULL); + + /* Register for char inputs with the character I/O peripheral */ + sensniff_io_set_input(&char_in); + + while(1) { + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_POLL) { + process_incoming_data(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/sensniff.h b/examples/sensniff/sensniff.h new file mode 100644 index 000000000..cbddcb8ca --- /dev/null +++ b/examples/sensniff/sensniff.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef SENSNIFF_H_ +#define SENSNIFF_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" + +#include +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_ERROR 0xFF +#define SENSNIFF_OK 0x00 +/*---------------------------------------------------------------------------*/ +void sensniff_output_frame(void); +/*---------------------------------------------------------------------------*/ +#endif /* SENSNIFF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/srf06-cc26xx/target-conf.h b/examples/sensniff/srf06-cc26xx/target-conf.h new file mode 100644 index 000000000..4d9deffda --- /dev/null +++ b/examples/sensniff/srf06-cc26xx/target-conf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +#define CC26XX_UART_CONF_BAUD_RATE 460800 +#define RF_BLE_CONF_ENABLED 0 +#define ROM_BOOTLOADER_ENABLE 1 +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "pool/cc13xx-cc26xx-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/z1/target-conf.h b/examples/sensniff/z1/target-conf.h new file mode 100644 index 000000000..6e3db2b48 --- /dev/null +++ b/examples/sensniff/z1/target-conf.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +#define MSP430_IO_CONF_USE_UART1 0 +#define UART0_CONF_BAUD_RATE 460800 +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "pool/msp430-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensniff/zoul/target-conf.h b/examples/sensniff/zoul/target-conf.h new file mode 100644 index 000000000..9f978b4c7 --- /dev/null +++ b/examples/sensniff/zoul/target-conf.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, George Oikonomou - http://www.spd.gr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef TARGET_CONF_H_ +#define TARGET_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* Set to 1 for a sub-ghz sniffer with the CC1200 */ +#ifndef ZOUL_CONF_SUB_GHZ_SNIFFER +#define ZOUL_CONF_SUB_GHZ_SNIFFER 0 +#endif +/*---------------------------------------------------------------------------*/ +#if ZOUL_CONF_SUB_GHZ_SNIFFER +#define NETSTACK_CONF_RADIO cc1200_driver + +/* + * You will need to configure the defines below to match the configuration of + * your sub-ghz network. + */ +#define CC1200_CONF_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#define CC1200_CONF_USE_GPIO2 0 +#define CC1200_CONF_USE_RX_WATCHDOG 0 +#define CC1200_CONF_802154G 0 +#define CC1200_CONF_802154G_CRC16 0 +#define CC1200_CONF_802154G_WHITENING 0 +#define ANTENNA_SW_SELECT_DEF_CONF ANTENNA_SW_SELECT_SUBGHZ +#endif +/*---------------------------------------------------------------------------*/ +/* + * Selection of Sensniff I/O Interface. + * Define CC2538_IO_CONF_USB as 0 to use UART0 as sensniff's interface. + */ +#define CC2538_IO_CONF_USB 0 +/*---------------------------------------------------------------------------*/ +#if CC2538_IO_CONF_USB +#define USB_SERIAL_CONF_ENABLE 1 +#else +#define UART0_CONF_BAUD_RATE 460800 +#endif +/*---------------------------------------------------------------------------*/ +#define SENSNIFF_IO_DRIVER_H "pool/cc2538-io.h" +/*---------------------------------------------------------------------------*/ +#endif /* TARGET_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/z1/Makefile b/examples/zolertia/z1/Makefile index 78b18d9dc..d0ba2abc8 100644 --- a/examples/zolertia/z1/Makefile +++ b/examples/zolertia/z1/Makefile @@ -7,8 +7,11 @@ ZOLERTIA_Z1SP=0 CONTIKI_PROJECT = test-phidgets blink test-adxl345 test-tmp102 test-light-ziglet CONTIKI_PROJECT += test-battery test-relay-phidget test-tlc59116 test-sht25 -CONTIKI_SOURCEFILES += sht11.c reed-sensor.c -APPS=serial-shell + +CONTIKI_SOURCEFILES += reed-sensor.c sht25.c tlc59116.c light-ziglet.c \ + relay-phidget.c + +MODULES += dev/sht11 ifeq ($(ZOLERTIA_Z1SP),1) CONTIKI_PROJECT += test-potent diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index ddd89f4ca..c06984c73 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,15 +1,16 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" -CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-power-mgmt +CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-servo.c CONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd test-iaq CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor -CONTIKI_PROJECT += test-zonik +CONTIKI_PROJECT += test-zonik test-dht22.c test-ac-dimmer.c CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c relay.c +CONTIKI_TARGET_SOURCEFILES += dht22.c servo.c ac-dimmer.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/README.md b/examples/zolertia/zoul/README.md new file mode 100644 index 000000000..dbcff3e2a --- /dev/null +++ b/examples/zolertia/zoul/README.md @@ -0,0 +1,59 @@ +Zolertia Zoul test examples +============================================ + +The following tests are valid for the following platforms: + +* RE-Mote revision A +* RE-Mote revision B +* Firefly + +Specific RE-mote revision A examples are available at the `rev-a` folder. + +Compile and install an example +------------------- + +To flash either hardware platform use the same `TARGET=zoul` and the following: + +* RE-Mote revision A : `BOARD=remote-reva` +* RE-Mote revision B : `BOARD=remote-revb` +* Zolertia Firefly : `BOARD=firefly` + +An example on how to compile is shown next: + +`make TARGET=zoul BOARD=remote-revb` + +Or alternatively if you just type `make`, it will default to use the `BOARD=remote-revb`. + +For backward compatibility with the previous `remote` target corresponding to the +RE-Mote revision A, using `BOARD=remote` will default to `BOARD=remote-reva`. + +To upload an example to your Zolertia device, just add the `.upload` target as: + +`make TARGET=zoul BOARD=remote-revb zoul-demo.upload` + +Optionally you can select a specific USB port to flash a given device, in Linux +and assuming there is a device at the `/dev/ttyUSB0`: + +`make TARGET=zoul BOARD=remote-revb zoul-demo.upload PORT=/dev/ttyUSB0` + +If you ommit the `PORT` argument, the system will flash all Zolertia devices connected over USB. + +Visualize the console output +------------------- + +Just type `make login` to open a connection to the console via USB. +As above to specify a given port use the `PORT=/dev/ttyUSB0` argument. + +Alternatively you can save the above `PORT`, `TARGET` or `BOARD` as follows: + +`export BOARD=/dev/ttyUSB0` + +This will save you to type these when running a command on the terminal + +Documentation and guides +------------------- + +More information about the platforms, guides and specific documentation can be found at [Zolertia Wiki][wiki] + +[wiki]: https://github.com/Zolertia/Resources/wiki "Zolertia Wiki" + diff --git a/examples/zolertia/zoul/at-test/at-master-test.c b/examples/zolertia/zoul/at-test/at-master-test.c index 520c28bdb..1b7d14d53 100644 --- a/examples/zolertia/zoul/at-test/at-master-test.c +++ b/examples/zolertia/zoul/at-test/at-master-test.c @@ -481,7 +481,6 @@ PROCESS_THREAD(at_test_process, ev, data) } /*---------------------------------------------------------------------------*/ /** - * @} * @} * @} */ diff --git a/examples/zolertia/zoul/at-test/project-conf.h b/examples/zolertia/zoul/at-test/project-conf.h index 4a29f1d59..ef1581773 100644 --- a/examples/zolertia/zoul/at-test/project-conf.h +++ b/examples/zolertia/zoul/at-test/project-conf.h @@ -29,7 +29,7 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup remote-examples + * \addtogroup zoul-examples * @{ * * \defgroup zoul-AT-master-test @@ -63,5 +63,8 @@ #define NETSTACK_CONF_RDC nullrdc_driver #endif /* PROJECT_CONF_H_ */ - -/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/cc1200-demo/cc1200-demo.c b/examples/zolertia/zoul/cc1200-demo/cc1200-demo.c index 1fe69f58c..4eb4d27b1 100644 --- a/examples/zolertia/zoul/cc1200-demo/cc1200-demo.c +++ b/examples/zolertia/zoul/cc1200-demo/cc1200-demo.c @@ -35,11 +35,12 @@ * @{ * * \file - * Test file for the CC1200 demo + * Test file for the CC1200 demo * * \author * Antonio Lignan */ +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "cpu.h" #include "sys/etimer.h" diff --git a/examples/zolertia/zoul/cc1200-demo/project-conf.h b/examples/zolertia/zoul/cc1200-demo/project-conf.h index 9367973ff..add005170 100644 --- a/examples/zolertia/zoul/cc1200-demo/project-conf.h +++ b/examples/zolertia/zoul/cc1200-demo/project-conf.h @@ -43,6 +43,7 @@ * \author * Antonio Lignan */ +/*---------------------------------------------------------------------------*/ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ diff --git a/examples/zolertia/zoul/cc1200-sniffer/README.md b/examples/zolertia/zoul/cc1200-sniffer/README.md deleted file mode 100644 index 95ec65193..000000000 --- a/examples/zolertia/zoul/cc1200-sniffer/README.md +++ /dev/null @@ -1,35 +0,0 @@ -CC1200 README -======================== - -The CC1200 sniffer is heavily based on the CC2538 sniffer, used with the -IEEE 802.15.4 Sensniff application by George Oikonomou. - -Sensniff requires [Wireshark](http://www.wireshark.org/). - -Get Wireshark ------------------ -The best way is to go to the Wireshark site and follow the instructions for your -specific OS, in a bundle this will install for Ubuntu/LInux systems: - -`sudo apt-get install wireshark` - -To allow non-super users to capture packets: - -`sudo dpkg-reconfigure wireshark` - -Flash the sniffer application to the Zoul ------------------ -make sniffer.upload - -Run Sensniff ------------------ -``` -git clone https://github.com/g-oikonomou/sensniff -cd sensniff/host -python sensniff.py --non-interactive -d /dev/ttyUSB0 -b 460800 -``` - -On another terminal run: - -`sudo wireshark -i /tmp/sensnifff` - diff --git a/examples/zolertia/zoul/cc1200-sniffer/netstack.c b/examples/zolertia/zoul/cc1200-sniffer/netstack.c deleted file mode 100644 index 3aeb6968e..000000000 --- a/examples/zolertia/zoul/cc1200-sniffer/netstack.c +++ /dev/null @@ -1,46 +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 - * 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 - - */ -#include "netstack.h" -/*---------------------------------------------------------------------------*/ -void -netstack_init(void) -{ - NETSTACK_RADIO.init(); - NETSTACK_RADIO.on(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/zoul/project-conf.h b/examples/zolertia/zoul/project-conf.h index 230724b2d..34f3116f6 100644 --- a/examples/zolertia/zoul/project-conf.h +++ b/examples/zolertia/zoul/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2016, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,13 +28,15 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*---------------------------------------------------------------------------*/ /** - * \addtogroup remote-examples + * \addtogroup zoul-examples * @{ * * \file * Project specific configuration defines for the basic RE-Mote examples */ +/*---------------------------------------------------------------------------*/ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ diff --git a/examples/zolertia/zoul/cc1200-sniffer/Makefile b/examples/zolertia/zoul/rev-a/Makefile similarity index 71% rename from examples/zolertia/zoul/cc1200-sniffer/Makefile rename to examples/zolertia/zoul/rev-a/Makefile index 5c2fa1675..bf3c06f74 100644 --- a/examples/zolertia/zoul/cc1200-sniffer/Makefile +++ b/examples/zolertia/zoul/rev-a/Makefile @@ -1,7 +1,6 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" -PROJECT_SOURCEFILES += stub-rdc.c -CONTIKI_PROJECT = sniffer +CONTIKI_PROJECT = test-power-mgmt all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/cc1200-sniffer/Makefile.target b/examples/zolertia/zoul/rev-a/Makefile.target similarity index 100% rename from examples/zolertia/zoul/cc1200-sniffer/Makefile.target rename to examples/zolertia/zoul/rev-a/Makefile.target diff --git a/examples/cc2538-common/sniffer/project-conf.h b/examples/zolertia/zoul/rev-a/project-conf.h similarity index 82% rename from examples/cc2538-common/sniffer/project-conf.h rename to examples/zolertia/zoul/rev-a/project-conf.h index 7e1ac0cd6..c5a153b5c 100644 --- a/examples/cc2538-common/sniffer/project-conf.h +++ b/examples/zolertia/zoul/rev-a/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,21 +29,17 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** - * \addtogroup cc2538-sniffer + * \addtogroup remote-examples * @{ * * \file - * Project specific configuration defines for the cc2538 sniffer + * Project specific configuration defines for the basic RE-Mote examples */ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ -#define CC2538_RF_CONF_SNIFFER 1 -#define CC2538_RF_CONF_AUTOACK 0 -#undef NETSTACK_CONF_RDC -#define NETSTACK_CONF_RDC stub_rdc_driver - -#define UART0_CONF_BAUD_RATE 460800 +#define BROADCAST_CHANNEL 129 +#define NETSTACK_CONF_RDC nullrdc_driver #endif /* PROJECT_CONF_H_ */ diff --git a/examples/zolertia/zoul/test-power-mgmt.c b/examples/zolertia/zoul/rev-a/test-power-mgmt.c similarity index 88% rename from examples/zolertia/zoul/test-power-mgmt.c rename to examples/zolertia/zoul/rev-a/test-power-mgmt.c index 1b0690bdb..a29668b22 100644 --- a/examples/zolertia/zoul/test-power-mgmt.c +++ b/examples/zolertia/zoul/rev-a/test-power-mgmt.c @@ -32,8 +32,8 @@ * \addtogroup remote-power-management-test * @{ * - * Test the RE-Mote's power management features, shutdown mode and battery - * management + * Test the RE-Mote's (revision A) power management features, shutdown mode and + * battery management * * @{ * @@ -80,18 +80,18 @@ static char * print_pm(uint8_t state) { switch(state) { - case PM_SYSOFF_ON: - return "Battery on"; - case PM_SYSOFF_OFF: - return "Battery off"; - case PM_TIMER_ENABLED: - return "Nano Timer enabled"; - case PM_TIMER_DISABLED: - return "Nano Timer disabled"; - case PM_AWAITING_RTC_EVENT: - return "Awaiting RTC event"; - default: - return "UNKNOWN"; + case PM_SYSOFF_ON: + return "Battery on"; + case PM_SYSOFF_OFF: + return "Battery off"; + case PM_TIMER_ENABLED: + return "Nano Timer enabled"; + case PM_TIMER_DISABLED: + return "Nano Timer disabled"; + case PM_AWAITING_RTC_EVENT: + return "Awaiting RTC event"; + default: + return "UNKNOWN"; } } /*---------------------------------------------------------------------------*/ @@ -107,24 +107,24 @@ get_status(uint8_t mask, uint8_t *val) } if(!mask) { - printf("STATUS %u\n", status); + printf("STATUS %u\n", status); *val = PM_IDLE; return PM_SUCCESS; } /* Read back ony the requested status bit */ switch(mask) { - case PM_SYSOFF_ON_MASK: - print_msg = (status & mask) ? PM_SYSOFF_ON : PM_SYSOFF_OFF; - break; - case PM_TIMER_ENABLED_MASK: - print_msg = (status & mask) ? PM_TIMER_ENABLED : PM_TIMER_DISABLED; - break; - case PM_AWAITING_RTC_EVENT_MASK: - print_msg = (status & mask) ? PM_AWAITING_RTC_EVENT : PM_AWAITING_RTC_DIS; - break; - default: - return PM_ERROR; + case PM_SYSOFF_ON_MASK: + print_msg = (status & mask) ? PM_SYSOFF_ON : PM_SYSOFF_OFF; + break; + case PM_TIMER_ENABLED_MASK: + print_msg = (status & mask) ? PM_TIMER_ENABLED : PM_TIMER_DISABLED; + break; + case PM_AWAITING_RTC_EVENT_MASK: + print_msg = (status & mask) ? PM_AWAITING_RTC_EVENT : PM_AWAITING_RTC_DIS; + break; + default: + return PM_ERROR; } printf("Status -> %s\n", print_pm(print_msg)); @@ -194,7 +194,7 @@ PROCESS_THREAD(test_remote_pm, ev, data) broadcast_send(&bc); /* And wait a few seconds before going to sleep */ - while(1){ + while(1) { etimer_set(&et, CLOCK_SECOND); PROCESS_WAIT_EVENT(); diff --git a/examples/zolertia/zoul/rtcc/Makefile.target b/examples/zolertia/zoul/rtcc/Makefile.target new file mode 100644 index 000000000..75430a6e4 --- /dev/null +++ b/examples/zolertia/zoul/rtcc/Makefile.target @@ -0,0 +1 @@ +TARGET = zoul diff --git a/examples/zolertia/zoul/rtcc/project-conf.h b/examples/zolertia/zoul/rtcc/project-conf.h index 9ff57c953..66bf67bc0 100644 --- a/examples/zolertia/zoul/rtcc/project-conf.h +++ b/examples/zolertia/zoul/rtcc/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,18 +28,28 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*---------------------------------------------------------------------------*/ /** - * \addtogroup remote-examples + * \addtogroup zoul-examples + * @{ + * + * \defgroup remote-rtcc-test RE-Mote on-board RTCC test application + * + * Test the Real-Time-Clock-Calendar built in the RE-Motes revision A and B * @{ * * \file - * Project specific configuration defines for the basic RE-Mote examples + * Project specific configuration defines for the RTCC RE-Mote example */ +/*---------------------------------------------------------------------------*/ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ #define NETSTACK_CONF_RDC nullrdc_driver #endif /* PROJECT_CONF_H_ */ - -/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/rtcc/test-rtcc.c b/examples/zolertia/zoul/rtcc/test-rtcc.c index cb14d5fa5..9b8895c09 100644 --- a/examples/zolertia/zoul/rtcc/test-rtcc.c +++ b/examples/zolertia/zoul/rtcc/test-rtcc.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, Zolertia + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,10 +30,8 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup remote-examples + * \addtogroup remote-rtcc-test * @{ - - * \defgroup remote-rtcc-test RE-Mote on-board RTCC test application * * Example project to show the on-board RTCC configuration and operation * Retrieves the current time and date from the system, then sets an alarm to @@ -42,10 +41,8 @@ * @{ * * \file - * RE-Mote on-board RTCC test application - * + * RE-Mote on-board RTCC test application * \author - * * Antonio Lignan * Aitor Mejias * Toni Lozano @@ -178,4 +175,3 @@ PROCESS_THREAD(test_remote_rtcc_process, ev, data) * @} * @} */ - diff --git a/examples/zolertia/zoul/test-aac-sensor.c b/examples/zolertia/zoul/test-aac-sensor.c index bbda23955..d6d8bda01 100644 --- a/examples/zolertia/zoul/test-aac-sensor.c +++ b/examples/zolertia/zoul/test-aac-sensor.c @@ -28,20 +28,22 @@ * 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-aac-sensor-test Test AAC sensor * * Demonstrates the operation of the current AAC analog sensor * @{ * * \file - * Example demonstrating the Zoul module on the RE-Mote & AAC sensor 0-5V 50Amps AC + * Example demonstrating the RE-Mote & AAC sensor 0-5V 50Amps AC * * \author * Javier Sánchez */ +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "sys/etimer.h" #include "sys/rtimer.h" @@ -64,7 +66,7 @@ AUTOSTART_PROCESSES(&test_aac_sensor_process); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_aac_sensor_process, ev, data) { - + PROCESS_BEGIN(); counter = 0; @@ -86,12 +88,12 @@ PROCESS_THREAD(test_aac_sensor_process, ev, data) printf("-----------------------------------------\n" "Counter = 0x%08x\n", counter); - + printf("AC Amps = %d mA\n", adc_sensors.value(ANALOG_AAC_SENSOR)); - + etimer_set(&et, LOOP_INTERVAL); counter++; - } + } } PROCESS_END(); } @@ -100,3 +102,4 @@ PROCESS_THREAD(test_aac_sensor_process, ev, data) * @} * @} */ + diff --git a/examples/zolertia/zoul/test-ac-dimmer.c b/examples/zolertia/zoul/test-ac-dimmer.c new file mode 100644 index 000000000..6fd28faa7 --- /dev/null +++ b/examples/zolertia/zoul/test-ac-dimmer.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, Zolertia + * 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. + * + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-ac-dimmer-test Krida Electronics AC light dimmer test example + * + * Demonstrates the use of an AC dimmer with zero-crossing, connected to the + * ADC1 and ADC2 pins (PA5 and PA4 respectively), powered over the D+5.1 pin + * + * @{ + * + * \file + * A quick program to test an AC dimmer + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/ac-dimmer.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +PROCESS(remote_ac_dimmer_process, "AC light dimmer test"); +AUTOSTART_PROCESSES(&remote_ac_dimmer_process); +/*---------------------------------------------------------------------------*/ +static uint8_t dimming; +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_ac_dimmer_process, ev, data) +{ + PROCESS_BEGIN(); + + dimming = 0; + SENSORS_ACTIVATE(ac_dimmer); + + printf("AC dimmer: min %u%% max %u%%\n", DIMMER_DEFAULT_MIN_DIMM_VALUE, + DIMMER_DEFAULT_MAX_DIMM_VALUE); + + /* Set the lamp to 10% and wait a few seconds */ + ac_dimmer.value(DIMMER_DEFAULT_MIN_DIMM_VALUE); + etimer_set(&et, CLOCK_SECOND * 5); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Upon testing for duty cycles lower than 10% there was noise (probably from + * the triac), causing the driver to skip a beat, and from time to time made + * the test lamp blink. This is easily reproducible by setting the dimmer to + * 5% and using a logic analyzer on the SYNC and GATE pins. The noise was + * picked-up also by the non-connected test probes of the logic analyser. + * Nevertheless the difference between 10% and 2% bright-wise is almost + * negligible + */ + while(1) { + + dimming += DIMMER_DEFAULT_MIN_DIMM_VALUE; + if(dimming > DIMMER_DEFAULT_MAX_DIMM_VALUE) { + dimming = DIMMER_DEFAULT_MIN_DIMM_VALUE; + } + + ac_dimmer.value(dimming); + printf("AC dimmer: light is now --> %u\n", ac_dimmer.status(SENSORS_ACTIVE)); + + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-bmp085-bmp180.c b/examples/zolertia/zoul/test-bmp085-bmp180.c index 73cf0168f..81d54b31e 100644 --- a/examples/zolertia/zoul/test-bmp085-bmp180.c +++ b/examples/zolertia/zoul/test-bmp085-bmp180.c @@ -38,7 +38,7 @@ * @{ * * \file - * Test file for the BMP085/BMP180 digital pressure and temperature sensor + * Test file for the BMP085/BMP180 digital pressure and temp sensor * * \author * Antonio Lignan diff --git a/examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c b/examples/zolertia/zoul/test-dht22.c similarity index 56% rename from examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c rename to examples/zolertia/zoul/test-dht22.c index a8c54de6a..43048eba3 100644 --- a/examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c +++ b/examples/zolertia/zoul/test-dht22.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,72 +25,64 @@ * 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 - * 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 + * \addtogroup zoul-examples + * @{ * + * \defgroup zoul-dht22-test DHT22 temperature and humidity sensor test + * + * Demonstrates the use of the DHT22 digital temperature and humidity sensor + * @{ + * + * \file + * A quick program for testing the DHT22 temperature and humidity sensor * \author - * George Oikonomou - + * Antonio Lignan */ -#include "net/mac/mac.h" -#include "net/mac/rdc.h" /*---------------------------------------------------------------------------*/ -static void -send(mac_callback_t sent, void *ptr) +#include +#include "contiki.h" +#include "dev/dht22.h" +/*---------------------------------------------------------------------------*/ +PROCESS(remote_dht22_process, "DHT22 test"); +AUTOSTART_PROCESSES(&remote_dht22_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_dht22_process, ev, data) { - if(sent) { - sent(ptr, MAC_TX_OK, 1); + int16_t temperature, humidity; + + PROCESS_BEGIN(); + SENSORS_ACTIVATE(dht22); + + /* Let it spin and read sensor data */ + + while(1) { + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* The standard sensor API may be used to read sensors individually, using + * the `dht22.value(DHT22_READ_TEMP)` and `dht22.value(DHT22_READ_HUM)`, + * however a single read operation (5ms) returns both values, so by using + * the function below we save one extra operation + */ + if(dht22_read_all(&temperature, &humidity) != DHT22_ERROR) { + printf("Temperature %02d.%02d ºC, ", temperature / 10, temperature % 10); + printf("Humidity %02d.%02d RH\n", humidity / 10, humidity % 10); + } else { + printf("Failed to read the sensor\n"); + } } + 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, -}; -/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-grove-gyro.c b/examples/zolertia/zoul/test-grove-gyro.c index 24baa360f..978aa69f8 100644 --- a/examples/zolertia/zoul/test-grove-gyro.c +++ b/examples/zolertia/zoul/test-grove-gyro.c @@ -85,7 +85,7 @@ PROCESS_THREAD(remote_grove_gyro_process, ev, data) * the 3 gyroscope axis use GROVE_GYRO_SENSOR. Alternatively the value * GROVE_GYRO_ALL could also be used to power everything at once */ - grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_SENSOR); + grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_SENSOR); /* Read back the configured sensor I2C address to check if the sensor is * working OK, this is the only case in which the value() returns a value @@ -128,9 +128,9 @@ PROCESS_THREAD(remote_grove_gyro_process, ev, data) /* This sensor has a different operation from others using Contiki's sensor * API, to make data acquisition we write the readings directly to the - * extern data structure, allowing to write more than 1 value at the same - * operation, and also allowing upon a data interrupt event to immediatly - * access the data. The return value of the value() call is then the status + * extern data structure, allowing to write more than 1 value at the same + * operation, and also allowing upon a data interrupt event to immediatly + * access the data. The return value of the value() call is then the status * result of the read operation */ if(grove_gyro.value(GROVE_GYRO_XYZ) == GROVE_GYRO_SUCCESS) { diff --git a/examples/zolertia/zoul/test-iaq.c b/examples/zolertia/zoul/test-iaq.c index 147ecd8a7..9940448ce 100644 --- a/examples/zolertia/zoul/test-iaq.c +++ b/examples/zolertia/zoul/test-iaq.c @@ -29,24 +29,25 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup remote-examples + * \addtogroup zoul-examples * @{ - * \defgroup remote-iaq-test - * + * + * \defgroup zoul-iaq-test + * * RE-Mote external IAQ test application * Example of iAQ-Core implementation and simple operation reading the value - * of CO2, TVOC sensor and Status. The test checks for a each 5 minutes in + * of CO2, TVOC sensor and Status. The test checks for a each 5 minutes in * order to get the first true measurement as datasheet recomendation - * (standard result of 0x82 is obtained in first time). - * Then, once initialized, periodically each 5 seconds reads - * the values of the IAQ sensor and shows in the screen, toggling the LED + * (standard result of 0x82 is obtained in first time). + * Then, once initialized, periodically each 5 seconds reads + * the values of the IAQ sensor and shows in the screen, toggling the LED * red if CO2 was not initialized and LED green if the reading was succeed. * * @{ * \file - * RE-Mote implementation of external IAQ-CORE-C test application + * RE-Mote implementation of external IAQ-CORE-C test application * \author - * Aitor Mejias + * Aitor Mejias */ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -87,17 +88,16 @@ PROCESS_THREAD(test_remote_iaq_process, ev, data) count_delay += LOOP_PERIOD; leds_toggle(LEDS_RED); printf("Test-IAQ: Initializing Time-elapsed: %u seconds of aprox. %lu sec.\n", - count_delay, IAQ_INIT_WAIT); + count_delay, IAQ_INIT_WAIT); } else if(status == IAQ_ACTIVE) { leds_off(LEDS_RED); leds_toggle(LEDS_GREEN); /* Get data from sensor: VOC, CO2 and internal status */ - printf("CO2 current value is: %d ppm\n", iaq.value(IAQ_VOC_VALUE)); - printf("TIAQ current value is: %d ppb\n", iaq.value(IAQ_CO2_VALUE)); + printf("CO2 current value is: %d ppm\n", iaq.value(IAQ_VOC_VALUE)); + printf("TIAQ current value is: %d ppb\n", iaq.value(IAQ_CO2_VALUE)); printf("Status is: 0x%0X\n", iaq.value(IAQ_STATUS)); - } - else { + } else { printf("iAQ-Core Error: 0x%02X\n", status); } } diff --git a/examples/zolertia/zoul/test-motion.c b/examples/zolertia/zoul/test-motion.c index b5c9c3f59..1a4edfcc5 100644 --- a/examples/zolertia/zoul/test-motion.c +++ b/examples/zolertia/zoul/test-motion.c @@ -40,7 +40,7 @@ * @{ * * \file - * Test application for the digital motion/presence sensor + * Test application for the digital motion/presence sensor * * \author * Antonio Lignan @@ -100,3 +100,4 @@ PROCESS_THREAD(test_presence_sensor, ev, data) * @} * @} */ + diff --git a/examples/zolertia/zoul/test-pm10-sensor.c b/examples/zolertia/zoul/test-pm10-sensor.c index d307f9050..2f6dfae42 100644 --- a/examples/zolertia/zoul/test-pm10-sensor.c +++ b/examples/zolertia/zoul/test-pm10-sensor.c @@ -31,13 +31,14 @@ /** * \addtogroup zoul-examples * @{ + * * \defgroup zoul-pm10-sensor-test Test PM10 sensor * * Demonstrates the operation of the Sharp PM10 analog sensor * @{ * * \file - * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper * * \author * Toni Lozano @@ -93,3 +94,4 @@ PROCESS_THREAD(test_pm10_sensor_process, ev, data) * @} * @} */ + diff --git a/examples/zolertia/zoul/test-relay.c b/examples/zolertia/zoul/test-relay.c index cd743919d..51f55e537 100644 --- a/examples/zolertia/zoul/test-relay.c +++ b/examples/zolertia/zoul/test-relay.c @@ -87,3 +87,4 @@ PROCESS_THREAD(remote_relay_process, ev, data) * @} * @} */ + diff --git a/examples/zolertia/zoul/test-rotation-sensor.c b/examples/zolertia/zoul/test-rotation-sensor.c index 76fb029ec..6e03d44ea 100644 --- a/examples/zolertia/zoul/test-rotation-sensor.c +++ b/examples/zolertia/zoul/test-rotation-sensor.c @@ -38,7 +38,7 @@ * @{ * * \file - * Phidget analog rotation sensor example using the ADC sensor wrapper + * Phidget analog rotation sensor example using the ADC sensor wrapper * * \author * Antonio Lignan diff --git a/examples/zolertia/zoul/test-servo.c b/examples/zolertia/zoul/test-servo.c new file mode 100644 index 000000000..ab201c06d --- /dev/null +++ b/examples/zolertia/zoul/test-servo.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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 zoul-examples + * @{ + * + * \defgroup zoul-servo-test Test the EMAX ES08A II servo motor + * + * Demonstrates the use of the EMAX ES08A servo motor. This servo requires a + * +5V voltage, it can be powered from D+5.1 pin (of the ADC3 connector), but + * it requires either an external power supply other than the USB for programing + * or it can be powered by the USB 2.0 connector, which allows a higher current + * draw. + * + * This test uses the default servo values (freq 50Hz, traveling time 1.5-1.9ms) + * for 0-180º movement, tested with the EMAX ES08A. Depending on the servo used + * you might need to adjust these parameters in the servo.h header file. + * + * @{ + * + * \file + * A quick program for testing a servo motor + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" +#include "dev/servo.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS(servo_test_process, "Zolertia servo test process"); +AUTOSTART_PROCESSES(&servo_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(servo_test_process, ev, data) +{ + PROCESS_BEGIN(); + + static uint8_t deg = 0; + + PRINTF("\nStarting the test\n"); + + while(1) { + + servo_position(SERVO_CHANNEL_5, GPIO_A_NUM, 5, deg); + PRINTF("Current position --> %03uº\n", deg); + + etimer_set(&et, CLOCK_SECOND / 2); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Increase the position by 10º each iteration */ + deg += 10; + if(deg > SERVO_MAX_DEGREES) { + deg = 0; + servo_stop(SERVO_CHANNEL_5, GPIO_A_NUM, 5); + + /* Stop the servo and wait 2 seconds before resuming from start */ + etimer_set(&et, CLOCK_SECOND * 2); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-vac-sensor.c b/examples/zolertia/zoul/test-vac-sensor.c index 37db59edf..5be57e44b 100644 --- a/examples/zolertia/zoul/test-vac-sensor.c +++ b/examples/zolertia/zoul/test-vac-sensor.c @@ -28,20 +28,23 @@ * 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-vac-sensor-test Test VAC sensor * * Demonstrates the operation of the voltage VAC analog sensor * @{ * * \file - * Example demonstrating the Zoul module on the RE-Mote & VAC sensor 0-5V 250V AC + * Example demonstrating the RE-Mote & VAC sensor 0-5V 250V AC * * \author * Javier Sánchez */ +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "sys/etimer.h" #include "sys/rtimer.h" @@ -65,7 +68,7 @@ AUTOSTART_PROCESSES(&test_vac_sensor_process); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_vac_sensor_process, ev, data) { - + PROCESS_BEGIN(); counter = 0; @@ -90,10 +93,10 @@ PROCESS_THREAD(test_vac_sensor_process, ev, data) /*AC voltage value, with applied corresponding sensor algorithm*/ printf("AC voltage = %d V\n", adc_sensors.value(ANALOG_VAC_SENSOR)); - + etimer_set(&et, LOOP_INTERVAL); counter++; - } + } } PROCESS_END(); } @@ -102,3 +105,4 @@ PROCESS_THREAD(test_vac_sensor_process, ev, data) * @} * @} */ + diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c index 2e2bcba2f..637ba8571 100644 --- a/examples/zolertia/zoul/test-weather-meter.c +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -40,7 +40,7 @@ * @{ * * \file - * Test application for the Sparkfun's weather meter + * Test application for the Sparkfun's weather meter * * \author * Antonio Lignan @@ -153,7 +153,7 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) } /*---------------------------------------------------------------------------*/ /** - * @} * @} * @} */ + diff --git a/examples/zolertia/zoul/test-zonik.c b/examples/zolertia/zoul/test-zonik.c index 622b73291..a046a950c 100644 --- a/examples/zolertia/zoul/test-zonik.c +++ b/examples/zolertia/zoul/test-zonik.c @@ -29,22 +29,23 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup remote-examples + * \addtogroup zoul-examples * @{ + * * \defgroup remote-zonik-test Zolertia Zonik sonometer test application * * Example of Zonik board implementation and simple operation: Infinite loop * enablinkg the sensor and rading few times, acquiring the dBA of sensor * The first value acquired is invalid, because it's in hw init state awaiting - * a valid internal reading.Once the driver is initialized, posterior readings + * a valid internal reading.Once the driver is initialized, posterior readings * are valid.Finally in the loop disables the board with standard call and * shows the error, and loop again enabling it. * * @{ * \file - * RE-Mote test application of Zolertia Zonik sound sensor + * RE-Mote test application of Zolertia Zonik sound sensor * \author - * Aitor Mejias + * Aitor Mejias */ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -70,17 +71,17 @@ PROCESS_THREAD(test_remote_zonik_process, ev, data) PROCESS_BEGIN(); printf("Initial status of sensor is: 0x%04X\n", - zonik.status(SENSORS_ACTIVE)); + zonik.status(SENSORS_ACTIVE)); while(1) { /* Configure Zonik and activate the internal process readings */ SENSORS_ACTIVATE(zonik); printf("Initialized. Sensor status: 0x%04X\n", - zonik.status(SENSORS_ACTIVE)); + zonik.status(SENSORS_ACTIVE)); /* Read sensor value dBA multiple times */ - for(i=0; i 1 us between read/write operations */ - clock_delay_usec(2); -} -/* */ -/* Read one bit of information from the bus, and return it as 1 or 0 */ -/* */ - -uint8_t -read_bit(void) -{ - uint8_t bit = 0; - - /* Set pin to 0 */ - OW_SET_OUTPUT(); - OW_SET_PIN_LOW(); - - /* Pin should be 0 for at least 1 us */ - clock_delay_usec(2); - - /* Now read the bus, start by setting in/out direction and activating internal */ - /* pull-up resistor */ - OW_SET_INPUT(); - OW_SET_PIN_HIGH(); - - /* ds18b20 either keeps the pin down or releases the bus and the */ - /* bus then goes high because of the interna pull-up resistor */ - /* Check whichever happens before 15 us has passed */ - clock_delay_usec(15 - 2 - 1); - bit = OW_GET_PIN_STATE(); - - /* The complete read cycle must last at least 60 us. We have now spent */ - /* about 14-15 us in delays, so add another delay to reach >= 60 us */ - clock_delay_usec(50); - - /* Release bus */ - OW_SET_PIN_HIGH(); - OW_SET_INPUT(); - - /* Allow > 1 us between read/write operations */ - clock_delay_usec(2); - - return bit ? 1 : 0; -} -/* */ -/* Read one byte of information. A byte is read least significant bit first */ -/* */ - -uint8_t -read_byte(void) -{ - uint8_t result = 0; - uint8_t bit; - int i; - - for(i = 0; i < 8; i++) { - bit = read_bit(); - result += (bit << i); - } - return result; -} -/* */ -/* Write one byte of information. A byte is written least significant bit first */ -/* */ - -void -write_byte(uint8_t byte) -{ - int i; - - for(i = 0; i < 8; i++) { - write_bit((byte >> i) & 1); - } -} -/* */ -/* ds18b20_get_temp returns the temperature in "temp" (in degrees celsius) */ -/* Returns 0 on failure (and then "temp" is left unchanged */ -/* Returns 1 on success, and sets temp */ -/* */ - -uint8_t -ds18b20_get_temp(float *temp) -{ - uint8_t result = 0; - - /* Reset bus by probing. Probe returns 1 on success/presence of sensor */ - if(ds18b20_probe()) { - /* write command "skip rom" since we only have one sensor on the wire! */ - write_byte(DS18B20_COMMAND_SKIP_ROM); - - /* write command to start measurement */ - write_byte(DS18B20_COMMAND_START_CONVERSION); - - /* Wait for conversion to complete */ - /* Conversion is 12-bit by default. */ - /* Since we have external power to the sensor (ie not in "parasitic power" mode) */ - /* the bus is held LOW by the sensor while the conversion is going on, and then HIGH */ - /* when conversion is finished. */ - OW_SET_INPUT(); - int count = 0; - while(!OW_GET_PIN_STATE()) { - clock_delay_msec(10); - count++; - /* Longest conversion time is 750 ms (12-bit resolution) */ - /* So if count > 80 (for a little margin!), we return -274.0 */ - /* which indicates failure to read the temperature. */ - if(count > 80) { - return 0; - } - } - - /* The result is stored in the "scratch pad", a 9 byte memory block. */ - /* The first two bytes are the conversion result. Reading the scratch pad */ - /* can be terminated by sending a reset signal (but we read all 9 bytes) */ - (void)ds18b20_probe(); - write_byte(DS18B20_COMMAND_SKIP_ROM); - write_byte(DS18B20_COMMAND_READ_SCRATCH_PAD); - uint8_t i, sp_arr[9]; - for(i = 0; i < 9; i++) { - sp_arr[i] = read_byte(); - } - - /* Check CRC, if mismatch, return 0 (failure to read temperature) */ - uint8_t crc_cal = crc8_ds18b20(sp_arr, 8); - - if(crc_cal != sp_arr[8]) { - return 0; - } - - /* OK, now decode what the temperature reading is. This code assumes 12-bit resolution, */ - /* so this must be modified if the code is modified to use any other resolution! */ - int16_t temp_res; - uint8_t temp_lsb = sp_arr[0]; - uint8_t temp_msb = sp_arr[1]; - - temp_res = (int16_t)temp_msb << 8 | temp_lsb; - *temp = (float)temp_res * 0.0625; - - result = 1; - } - return result; -} -/* */ -/* crc8 algorithm for ds18b20 */ -/* http://www.miscel.dk/MiscEl/CRCcalculations.html */ -/* */ - -uint8_t -crc8_ds18b20(uint8_t *buf, uint8_t buf_len) -{ - uint8_t result = 0; - uint8_t i, b; - - for(i = 0; i < buf_len; i++) { - result = result ^ buf[i]; - for(b = 1; b < 9; b++) { - if(result & 0x1) { - result = (result >> 1) ^ 0x8C; - } else { - result = result >> 1; - } - } - } - return result; -} diff --git a/platform/cc2530dk/contiki-conf.h b/platform/cc2530dk/contiki-conf.h index 9c79aa828..33ad58433 100644 --- a/platform/cc2530dk/contiki-conf.h +++ b/platform/cc2530dk/contiki-conf.h @@ -85,17 +85,6 @@ #define UART0_CONF_WITH_INPUT 1 #endif -/* Output all captured frames over the UART in hexdump format */ -#ifndef CC2530_RF_CONF_HEXDUMP -#define CC2530_RF_CONF_HEXDUMP 0 -#endif - -#if CC2530_RF_CONF_HEXDUMP -/* We need UART1 output */ -#undef UART_ZERO_CONF_ENABLE -#define UART_ZERO_CONF_ENABLE 1 -#endif - /* Code Shortcuts */ /* * When set, this directive also configures the following bypasses: diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index 4bcb2c6f4..540055035 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -337,7 +337,7 @@ More things to play around with Build a Sniffer - Live Traffic Capture with Wireshark ----------------------------------------------------- -There is a sniffer example in `examples/cc2538dk/sniffer/` +There is a sniffer example in `examples/sensniff/` Diverging from platform defaults, this example configures the UART to use a baud rate of 460800. The reason is that sniffers operating at 115200 are liable to corrupt frames. This is almost certain to occur when sniffing a ContikiMAC-based deployment. See more details on how to configure UART baud rates in the "Advanced Topics" section. @@ -366,7 +366,6 @@ Switching between UART and USB (CDC-ACM) By default, everything is configured to use the UART (stdio, border router's SLIP, sniffer's output stream). If you want to change this, these are the relevant lines in contiki-conf.h (0: UART, 1: USB): #define SLIP_ARCH_CONF_USB 0 /** SLIP over UART by default */ - #define CC2538_RF_CONF_SNIFFER_USB 0 /** Sniffer out over UART by default */ #define DBG_CONF_USB 0 /** All debugging over UART by default */ You can multiplex things (for instance, SLIP as well as debugging over USB or SLIP over USB but debugging over UART and other combinations). @@ -377,7 +376,6 @@ By default, everything is configured to use the UART0 (stdio, border router's SL #define SERIAL_LINE_CONF_UART 0 #define SLIP_ARCH_CONF_UART 0 - #define CC2538_RF_CONF_SNIFFER_UART 0 #define DBG_CONF_UART 0 #define UART1_CONF_UART 0 diff --git a/platform/cc2538dk/contiki-conf.h b/platform/cc2538dk/contiki-conf.h index c6f0e2b6a..4707f2cc8 100644 --- a/platform/cc2538dk/contiki-conf.h +++ b/platform/cc2538dk/contiki-conf.h @@ -40,8 +40,6 @@ typedef uint32_t rtimer_clock_t; #define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) /** @} */ /*---------------------------------------------------------------------------*/ -#define TSCH_CONF_HW_FRAME_FILTERING 0 - /* 352us from calling transmit() until the SFD byte has been sent */ #define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(352)) /* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */ @@ -66,6 +64,16 @@ typedef uint32_t rtimer_clock_t; #endif /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \name CC2538 System Control configuration + * + * @{ + */ +#ifndef SYS_CTRL_CONF_OSC32K_USE_XTAL +#define SYS_CTRL_CONF_OSC32K_USE_XTAL 1 /**< Use the on-board 32.768-kHz crystal */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** * \name Watchdog Timer configuration * @@ -142,10 +150,6 @@ typedef uint32_t rtimer_clock_t; #define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */ #endif -#ifndef CC2538_RF_CONF_SNIFFER_USB -#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */ -#endif - #ifndef DBG_CONF_USB #define DBG_CONF_USB 0 /**< All debugging over UART by default */ #endif @@ -160,12 +164,6 @@ typedef uint32_t rtimer_clock_t; #endif #endif -#if !CC2538_RF_CONF_SNIFFER_USB -#ifndef CC2538_RF_CONF_SNIFFER_UART -#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */ -#endif -#endif - #if !DBG_CONF_USB #ifndef DBG_CONF_UART #define DBG_CONF_UART 0 /**< UART to use for debugging */ @@ -192,15 +190,6 @@ typedef uint32_t rtimer_clock_t; #endif #endif -/* - * When set, the radio turns off address filtering and sends all captured - * frames down a peripheral (UART or USB, depending on the value of - * CC2538_RF_CONF_SNIFFER_USB) - */ -#ifndef CC2538_RF_CONF_SNIFFER -#define CC2538_RF_CONF_SNIFFER 0 -#endif - /** * \brief Define this as 1 to build a headless node. * @@ -221,12 +210,6 @@ typedef uint32_t rtimer_clock_t; #undef STARTUP_CONF_VERBOSE #define STARTUP_CONF_VERBOSE 0 - -/* Little sanity check: We can't have quiet sniffers */ -#if CC2538_RF_CONF_SNIFFER -#error "CC2538_RF_CONF_SNIFFER == 1 and CC2538_CONF_QUIET == 1" -#error "These values are conflicting. Please set either to 0" -#endif #endif /* CC2538_CONF_QUIET */ /** @@ -235,8 +218,7 @@ typedef uint32_t rtimer_clock_t; #ifndef USB_SERIAL_CONF_ENABLE #define USB_SERIAL_CONF_ENABLE \ ((SLIP_ARCH_CONF_USB & SLIP_ARCH_CONF_ENABLED) | \ - DBG_CONF_USB | \ - (CC2538_RF_CONF_SNIFFER & CC2538_RF_CONF_SNIFFER_USB)) + DBG_CONF_USB) #endif /* @@ -256,9 +238,6 @@ typedef uint32_t rtimer_clock_t; #define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \ !SLIP_ARCH_CONF_USB && \ SLIP_ARCH_CONF_UART == (u)) -#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \ - !CC2538_RF_CONF_SNIFFER_USB && \ - CC2538_RF_CONF_SNIFFER_UART == (u)) #define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u)) #define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u)) @@ -266,7 +245,6 @@ typedef uint32_t rtimer_clock_t; UART_CONF_ENABLE && \ (UART_IN_USE_BY_SERIAL_LINE(u) || \ UART_IN_USE_BY_SLIP(u) || \ - UART_IN_USE_BY_RF_SNIFFER(u) || \ UART_IN_USE_BY_DBG(u) || \ UART_IN_USE_BY_UART1(u)) \ ) diff --git a/platform/galileo/Makefile.galileo b/platform/galileo/Makefile.galileo index 8be977bc8..35a4ad825 100644 --- a/platform/galileo/Makefile.galileo +++ b/platform/galileo/Makefile.galileo @@ -5,10 +5,20 @@ LIBGCC_PATH = /usr/lib/gcc/$(shell gcc -dumpmachine)/$(shell gcc -dumpversion) CONTIKI_TARGET_DIRS = . core/sys/ drivers/ net/ CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} -CONTIKI_SOURCEFILES += contiki-main.c clock.c rtimer-arch.c gpio-pcal9535a.c pwm-pca9685.c galileo-pinmux.c eth-proc.c eth-conf.c +CONTIKI_SOURCEFILES += contiki-main.c clock.c rtimer-arch.c eth-proc.c eth-conf.c galileo-gpio.c + +GALILEO_GEN ?= 2 +CFLAGS += -DGALILEO_GEN=$(GALILEO_GEN) +CONTIKI_SOURCEFILES += galileo-gen$(GALILEO_GEN)-pinmux.c + +ifeq ($(GALILEO_GEN),2) +CONTIKI_SOURCEFILES += gpio-pcal9535a.c pwm-pca9685.c +else +CONTIKI_SOURCEFILES += cy8c9540a.c +endif ifeq ($(CONTIKI_WITH_IPV6),1) - CONTIKI_SOURCEFILES += nbr-table.c packetbuf.c linkaddr.c + CONTIKI_SOURCEFILES += nbr-table.c packetbuf.c linkaddr.c link-stats.c endif PROJECT_SOURCEFILES += newlib-syscalls.c diff --git a/platform/galileo/README.md b/platform/galileo/README.md index e441876db..e32799e3b 100644 --- a/platform/galileo/README.md +++ b/platform/galileo/README.md @@ -47,13 +47,59 @@ Standard APIs: Optional support for protection domains is also implemented and is described in cpu/x86/mm/README.md. -Building --------- +Preparation +----------- Prerequisites on all Ubuntu Linux systems include texinfo and uuid-dev. Additional prerequisites on 64-bit Ubuntu Linux systems include gcc-multilib and g++-multilib. +Docker can optionally be used to prepare an Ubuntu-based, containerized build +environment. This has been tested with Docker installed on Microsoft Windows 10. + +If not using a containerized environment, proceed to the "Building" section +below. + +Using a Docker-based environment on Windows requires that the repository has +been checked out with Git configured to preserve UNIX-style line endings. This +can be accomplished by changing the 'core.autocrlf' setting prior to cloning +the repository [5]: +``` +git config --global core.autocrlf input +``` +Note that this is a global setting, so it may affect other Git operations. + +The drive containing the repository needs to be shared with Docker containers +for the following steps to work [6]. Note that this is a global setting that +affects other containers that may be present on the host. + +Open Microsoft PowerShell and navigate to the base directory of the repository. +Run the following command to create the build environment: +``` +docker build -t contiki-galileo-build platform/galileo/bsp/docker +``` +This creates a container named 'contiki-galileo-build' based on Ubuntu and +installs development tools in the container. + +The build commands shown below can be run within the newly-created container. To +obtain a shell, run the following command in PowerShell from the base directory +of the repository. +``` +docker run -t -i -v ${Pwd}:/contiki contiki-galileo-build +``` +This command mounts the current directory and its subdirectories at the path +'/contiki' within the container. Changes to those files in the container are +visible to the host and vice versa. However, changes to the container +filesystem are not automatically persisted when the container is stopped. + +The containerized build environment does not currently support building the Grub +bootloader nor debugging using the instructions in this document. + +See the Docker Overview for more information about working with containers [7]. + +Building +-------- + To build applications for this platform you should first build newlib (in case it wasn't already built). To build newlib you can run the following command: @@ -95,12 +141,17 @@ specify X86_CONF_RESTRICT_DMA=1 as a command-line argument to the make command that is used to build the image. This will configure and lock the IMRs. +Galileo Gen. 2 is targeted by default. Specify GALILEO_GEN=1 on the build +command line to target first generation boards. + Running ------- -In order to boot the Contiki image, you will need a multiboot-compliant -bootloader. In the bsp directory, we provide a helper script which builds the -Grub bootloader with multiboot support. To build the bootloader, just run the +You will need a multiboot-compliant bootloader to boot Contiki images in that +format. However, this is not needed for booting UEFI images. + +In the bsp directory, we provide a helper script which builds the Grub +bootloader with multiboot support. To build the bootloader, just run the following command: ``` $ platform/galileo/bsp/grub/build_grub.sh @@ -112,8 +163,18 @@ detailed instructions. ### Prepare SDcard +The instructions in this section are for a native Linux development environment, +so equivalent operations should be substituted when using some other environment +(e.g. Windows Explorer can be used to perform equivalent operations when using +Docker on Windows as a development environment). + Mount the sdcard in directory /mnt/sdcard. +Create UEFI boot directory: +``` +$ mkdir -p /mnt/sdcard/efi/boot +``` + #### Approach for Multiboot-compliant ELF Image Copy Contiki binary image to sdcard @@ -123,19 +184,20 @@ $ cp examples/hello-world/hello-world.galileo /mnt/sdcard Copy grub binary to sdcard ``` -$ cp platform/galileo/bsp/grub/bin/grub.efi /mnt/sdcard +$ cp platform/galileo/bsp/grub/bin/grub.efi /mnt/sdcard/efi/boot/bootia32.efi ``` #### Approach for UEFI Image -Copy Contiki binary image to sdcard +Copy Contiki binary image to sdcard: ``` -$ cp examples/hello-world/hello-world.galileo.efi /mnt/sdcard +$ cp examples/hello-world/hello-world.galileo.efi /mnt/sdcard/efi/boot/bootia32.efi ``` ### Connect to the console output -Connect the serial cable to your computer as shown in [2]. +Connect the serial cable to your computer as shown in [8] for first generation +boards and [2] for second generation boards. Choose a terminal emulator such as PuTTY. Make sure you use the SCO keyboard mode (on PuTTY that option is at Terminal -> Keyboard, on the left menu). @@ -150,38 +212,27 @@ Press [Enter] to directly boot. Press [F7] to show boot menu options. ``` -Press and select the option "UEFI Internal Shell" within the menu. +Waiting for the system to select the default boot device may be sufficient. +However, if this does not boot Contiki or Grub (depending on what is installed +as the UEFI boot image) then perform the following procedure after rebooting +and waiting for the boot message to appear: Press and select the option +"UEFI Misc Device" within the menu. -#### Boot Multiboot-compliant ELF Image +No additional steps should be required to boot a Contiki UEFI image. -Once you have a shell, run the following commands to run grub application: -``` -$ fs0: -$ grub.efi -``` - -You'll reach the grub shell. Now run the following commands to boot Contiki -image: +Run the following additional commands to boot a multiboot-compliant image: ``` $ multiboot /hello-world.galileo $ boot ``` -#### Boot UEFI Image - -Once you have a shell, run the following commands to boot Contiki image: -``` -$ fs0: -$ hello-world.galileo.efi -``` - ### Verify that Contiki is Running This should boot the Contiki image, resulting in the following messages being sent to the serial console: ``` Starting Contiki -Hello World +Hello, world ``` Debugging @@ -224,3 +275,11 @@ References [3] https://www.gnu.org/software/grub/manual/multiboot/multiboot.html [4] http://www.uefi.org/ + +[5] https://www.git-scm.com/book/en/v2/Customizing-Git-Git-Configuration + +[6] https://docs.docker.com/docker-for-windows/#/shared-drives + +[7] https://docs.docker.com/engine/understanding-docker/ + +[8] https://software.intel.com/en-us/articles/intel-galileo-gen-1-board-assembly-using-eclipse-and-intel-xdk-iot-edition diff --git a/platform/galileo/bsp/docker/Dockerfile b/platform/galileo/bsp/docker/Dockerfile new file mode 100644 index 000000000..87fbe2cc0 --- /dev/null +++ b/platform/galileo/bsp/docker/Dockerfile @@ -0,0 +1,8 @@ +FROM ubuntu:16.04 +RUN apt-get update \ + && apt-get install -y \ + gcc-multilib g++-multilib git make patch texinfo uuid-dev wget \ + && rm -rf /var/lib/apt/lists/* +WORKDIR /contiki +ENV TARGET galileo +CMD ["/bin/bash", "-l"] diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c index ccc1f519f..769a9d154 100644 --- a/platform/galileo/contiki-main.c +++ b/platform/galileo/contiki-main.c @@ -65,10 +65,10 @@ app_main(void) process_init(); procinit_init(); ctimer_init(); - autostart_start(autostart_processes); - eth_init(); + autostart_start(autostart_processes); + while(1) { process_run(); } @@ -86,8 +86,11 @@ main(void) quarkX1000_imr_conf(); #endif irq_init(); - /* Initialize UART connected to Galileo Gen2 FTDI header */ - quarkX1000_uart_init(QUARK_X1000_UART_1); + quarkX1000_uart_init(); + /* Initialize UART connected to Galileo Gen1 3.5mm audio-style jack or + * Galileo Gen2 FTDI header + */ + quarkX1000_uart_init_port(QUARK_X1000_UART_1, 115200); clock_init(); rtimer_init(); @@ -96,11 +99,15 @@ main(void) quarkX1000_i2c_init(); quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED_STANDARD, QUARKX1000_I2C_ADDR_MODE_7BIT); + /* The GPIO subsystem must be initialized prior to configuring pinmux, because + * the pinmux configuration automatically performs GPIO configuration for the + * relevant pins. + */ + quarkX1000_gpio_init(); /* use default pinmux configuration */ if(galileo_pinmux_initialize() < 0) { fprintf(stderr, "Failed to initialize pinmux\n"); } - quarkX1000_gpio_init(); shared_isr_init(); /* The ability to remap interrupts is not needed after this point and should diff --git a/platform/galileo/drivers/cy8c9540a.c b/platform/galileo/drivers/cy8c9540a.c new file mode 100644 index 000000000..e042f9e23 --- /dev/null +++ b/platform/galileo/drivers/cy8c9540a.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2016, Intel Corporation. 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. + */ + +#include "cy8c9540a.h" + +#include +#include "i2c.h" +#include + +/* Change this to 0x21 if J2 is set to 1-2 + * (covering the pin marked with the white triangle). */ +#define I2C_ADDR 0x20 + +#define REG_PORT_SEL 0x18 +#define REG_PORT_DIR 0x1C + +#define PORT_CNT 6 + +/* Cache the current state of each port to obviate the need for reading before + * writing to output ports when simply updating a single pin. + */ +static uint8_t out_cache[PORT_CNT]; + +/*---------------------------------------------------------------------------*/ +static void +write_reg(uint8_t reg, uint8_t data) +{ + uint8_t pkt[] = { reg, data }; + assert(quarkX1000_i2c_polling_write(pkt, sizeof(pkt), I2C_ADDR) == 0); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +read_reg(uint8_t reg) +{ + uint8_t data; + assert(quarkX1000_i2c_polling_write(®, 1, I2C_ADDR) == 0); + assert(quarkX1000_i2c_polling_read(&data, 1, I2C_ADDR) == 0); + return data; +} +/*---------------------------------------------------------------------------*/ +void +cy8c9540a_init(void) +{ + uint8_t status; + + /* has to init after I2C master */ + assert(quarkX1000_i2c_is_available()); + + status = read_reg(0x2E); + if((status >> 4) != 4) { + fprintf(stderr, "Failed to communicate with CY8C9540A. Perhaps jumper J2 " + "is not set to 2-3? Halting.\n"); + halt(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the direction (in or out) for the indicated GPIO pin. + */ +void +cy8c9540a_set_port_dir(cy8c9540a_bit_addr_t addr, cy8c9540a_port_dir_t dir) +{ + uint8_t mask; + + assert(addr.port < PORT_CNT); + + write_reg(REG_PORT_SEL, addr.port); + mask = read_reg(REG_PORT_DIR); + mask &= ~(1 << addr.pin); + mask |= ((uint8_t)dir) << addr.pin; + write_reg(REG_PORT_DIR, mask); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the drive mode for the indicated GPIO pin. + */ +void +cy8c9540a_set_drive_mode(cy8c9540a_bit_addr_t addr, + cy8c9540a_drive_mode_t drv_mode) +{ + assert(addr.port < PORT_CNT); + + write_reg(REG_PORT_SEL, addr.port); + write_reg((uint8_t)drv_mode, 1 << addr.pin); +} +/*---------------------------------------------------------------------------*/ +bool +cy8c9540a_read(cy8c9540a_bit_addr_t addr) +{ + assert(addr.port < PORT_CNT); + + return ((read_reg(addr.port) >> addr.pin) & 1) == 1; +} +/*---------------------------------------------------------------------------*/ +void +cy8c9540a_write(cy8c9540a_bit_addr_t addr, bool val) +{ + assert(addr.port < PORT_CNT); + + out_cache[addr.port] &= ~(1 << addr.pin); + out_cache[addr.port] |= ((uint8_t)val) << addr.pin; + write_reg(8 + addr.port, out_cache[addr.port]); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/galileo/drivers/cy8c9540a.h b/platform/galileo/drivers/cy8c9540a.h new file mode 100644 index 000000000..a9c31a484 --- /dev/null +++ b/platform/galileo/drivers/cy8c9540a.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PLATFORM_GALILEO_DRIVERS_CY8C9540A_H_ +#define PLATFORM_GALILEO_DRIVERS_CY8C9540A_H_ + +#include +#include + +/* Driver for Cypress Semiconductors CY8C9540A device used for GPIO, PWM, and + * pinmuxing on the first generation Intel Galileo. + */ + +/* The numeric value of each drive mode corresponds to the device register + * address for selecting that mode. Only a subset of the available modes are + * listed here. + */ +typedef enum cy8c9540a_drive_mode { + CY8C9540A_DRIVE_PULL_UP = 0x1D, + CY8C9540A_DRIVE_PULL_DOWN = 0x1E, + CY8C9540A_DRIVE_STRONG = 0x21, + CY8C9540A_DRIVE_HI_Z = 0x23 +} cy8c9540a_drive_mode_t; + +typedef enum cy8c9540a_port_dir { + CY8C9540A_PORT_DIR_OUT = 0, + CY8C9540A_PORT_DIR_IN = 1 +} cy8c9540a_port_dir_t; + +typedef struct cy8c9540a_bit_addr { + uint8_t port; + int pin; +} cy8c9540a_bit_addr_t; + +#define CY8C9540A_BIT_ADDR_INVALID_PORT 0xFF + +void cy8c9540a_init(void); +void cy8c9540a_set_port_dir(cy8c9540a_bit_addr_t addr, + cy8c9540a_port_dir_t dir); +void cy8c9540a_set_drive_mode(cy8c9540a_bit_addr_t addr, + cy8c9540a_drive_mode_t drv_mode); +bool cy8c9540a_read(cy8c9540a_bit_addr_t addr); +void cy8c9540a_write(cy8c9540a_bit_addr_t addr, bool val); + +#endif /* PLATFORM_GALILEO_DRIVERS_CY8C9540A_H_ */ diff --git a/platform/galileo/drivers/galileo-gen1-pinmux.c b/platform/galileo/drivers/galileo-gen1-pinmux.c new file mode 100644 index 000000000..fc94ab5ca --- /dev/null +++ b/platform/galileo/drivers/galileo-gen1-pinmux.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2016, Intel Corporation. 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. + */ + +#include "galileo-pinmux.h" + +#include +#include "cy8c9540a.h" +#include "gpio.h" +#include + +static cy8c9540a_bit_addr_t mux_bit_addrs[] = { + { 3, 4 }, /* IO0 */ + { 3, 5 }, /* IO1 */ + { 1, 7 }, /* IO2 */ + { 1, 6 }, /* IO3 */ + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, /* IO4 */ + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, /* IO5 */ + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, /* IO6 */ + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, /* IO7 */ + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, /* IO8 */ + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, /* IO9 */ + { 3, 6 }, /* IO10 */ + { 3, 7 }, /* IO11 */ + { 5, 2 }, /* IO12 */ + { 5, 3 }, /* IO13 */ + { 3, 1 }, /* A0 */ + { 3, 0 }, /* A1 */ + { 0, 7 }, /* A2 */ + { 0, 6 }, /* A3 */ + { 0, 5 }, /* A4 (also controlled by I2C mux) */ + { 0, 4 }, /* A5 (also controlled by I2C mux) */ +}; + +static cy8c9540a_bit_addr_t i2c_mux_bit_addr = { 1, 5 }; + +/*---------------------------------------------------------------------------*/ +static void +flatten_pin_num(galileo_pin_group_t grp, unsigned *pin) +{ + if(grp == GALILEO_PIN_GRP_ANALOG) { + *pin += GALILEO_NUM_DIGITAL_PINS; + } + + assert(*pin < GALILEO_NUM_PINS); +} +/*---------------------------------------------------------------------------*/ +/* See galileo-gpio.c for the declaration of this function. */ +int +galileo_brd_to_cpu_gpio_pin(unsigned pin, bool *sus) +{ + assert(pin < GALILEO_NUM_PINS); + *sus = false; + switch(pin) { + case 2: + return 6; + case 3: + return 7; + case 10: + return 2; + default: + return -1; /* GPIO pin may be connected to the CY8C9540A chip, but not the + CPU. */ + } +} +/*---------------------------------------------------------------------------*/ +static cy8c9540a_bit_addr_t cy8c9540a_gpio_mapping[] = { + { 4, 6 }, + { 4, 7 }, + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, + { CY8C9540A_BIT_ADDR_INVALID_PORT, 0 }, + { 1, 4 }, + { 0, 1 }, + { 1, 0 }, + { 1, 3 }, + { 1, 2 }, + { 0, 3 }, + { 0, 0 }, /* This driver configures IO10 to connect to CPU GPIO when setting + IO10 to a digital mode, but hardware exists to alternately + connect it to this pin of the CY8C9540A chip. */ + { 1, 1 }, + { 3, 2 }, + { 3, 3 }, + { 4, 0 }, + { 4, 1 }, + { 4, 2 }, + { 4, 3 }, + { 4, 4 }, + { 4, 5 } +}; +/* Map a board-level GPIO pin number to the address of the CY8C9540A pin that + * implements it. + */ +cy8c9540a_bit_addr_t +galileo_brd_to_cy8c9540a_gpio_pin(unsigned pin) +{ + assert(pin < GALILEO_NUM_PINS); + return cy8c9540a_gpio_mapping[pin]; +} +/*---------------------------------------------------------------------------*/ +/* The I2C mux control must be set high to be able to access A4 and A5. + */ +static void +set_i2c_mux(bool val) +{ + cy8c9540a_write(i2c_mux_bit_addr, val); +} +/*---------------------------------------------------------------------------*/ +static void +select_gpio_pwm(unsigned flat_pin, bool pwm) +{ + bool mux_val; + cy8c9540a_bit_addr_t mux_bit_addr; + mux_bit_addr = mux_bit_addrs[flat_pin]; + if(mux_bit_addr.port != CY8C9540A_BIT_ADDR_INVALID_PORT) { + mux_val = pwm || !(flat_pin == 2 || flat_pin == 3 || flat_pin == 10); + cy8c9540a_write(mux_bit_addr, mux_val); + } + if((GALILEO_NUM_DIGITAL_PINS + 4) <= flat_pin) { + /* This single control switches away from both I2C pins. */ + set_i2c_mux(true); + } +} +/*---------------------------------------------------------------------------*/ +static void +select_gpio(galileo_pin_group_t grp, unsigned pin, bool out) +{ + bool sus; + int cpu_pin; + cy8c9540a_bit_addr_t gpio_bit_addr; + + flatten_pin_num(grp, &pin); + select_gpio_pwm(pin, false); + + cpu_pin = galileo_brd_to_cpu_gpio_pin(pin, &sus); + if(cpu_pin == -1) { + gpio_bit_addr = galileo_brd_to_cy8c9540a_gpio_pin(pin); + cy8c9540a_set_port_dir(gpio_bit_addr, + out? + CY8C9540A_PORT_DIR_OUT : + CY8C9540A_PORT_DIR_IN); + cy8c9540a_set_drive_mode(gpio_bit_addr, + out? + CY8C9540A_DRIVE_STRONG : + CY8C9540A_DRIVE_HI_Z); + } else { + quarkX1000_gpio_config(cpu_pin, + out? QUARKX1000_GPIO_OUT : QUARKX1000_GPIO_IN); + } +} +/*---------------------------------------------------------------------------*/ +void +galileo_pinmux_select_din(galileo_pin_group_t grp, unsigned pin) +{ + select_gpio(grp, pin, false); +} +/*---------------------------------------------------------------------------*/ +void galileo_pinmux_select_dout(galileo_pin_group_t grp, unsigned pin) +{ + select_gpio(grp, pin, true); +} +/*---------------------------------------------------------------------------*/ +void galileo_pinmux_select_pwm(unsigned pin) +{ + switch(pin) { + case 3: + case 5: + case 6: + case 9: + case 10: + case 11: + break; + default: + fprintf(stderr, "%s: invalid pin: %d.\n", __FUNCTION__, pin); + halt(); + } + + select_gpio_pwm(pin, true); +} +/*---------------------------------------------------------------------------*/ +void galileo_pinmux_select_serial(unsigned pin) +{ + assert(pin == 0 || pin == 1); + + cy8c9540a_write(mux_bit_addrs[pin], false); +} +/*---------------------------------------------------------------------------*/ +void galileo_pinmux_select_i2c(void) +{ + set_i2c_mux(false); +} +/*---------------------------------------------------------------------------*/ +void galileo_pinmux_select_spi(void) +{ + unsigned pin; + for(pin = 11; pin <= 13; pin++) { + cy8c9540a_write(mux_bit_addrs[pin], false); + } +} +/*---------------------------------------------------------------------------*/ +void galileo_pinmux_select_analog(unsigned pin) +{ + assert(pin < GALILEO_NUM_ANALOG_PINS); + pin += GALILEO_NUM_DIGITAL_PINS; + + cy8c9540a_write(mux_bit_addrs[pin], false); + + if(4 <= pin) { + /* This single control switches away from both I2C pins. */ + set_i2c_mux(true); + } +} +/*---------------------------------------------------------------------------*/ +int +galileo_pinmux_initialize(void) +{ + int i; + + cy8c9540a_init(); + + /* Configure all mux control pins as outputs. */ + for(i = 0; i < GALILEO_NUM_PINS; i++) { + if(mux_bit_addrs[i].port == CY8C9540A_BIT_ADDR_INVALID_PORT) { + continue; + } + + cy8c9540a_set_port_dir(mux_bit_addrs[i], CY8C9540A_PORT_DIR_OUT); + cy8c9540a_set_drive_mode(mux_bit_addrs[i], CY8C9540A_DRIVE_STRONG); + } + cy8c9540a_set_port_dir(i2c_mux_bit_addr, CY8C9540A_PORT_DIR_OUT); + cy8c9540a_set_drive_mode(i2c_mux_bit_addr, CY8C9540A_DRIVE_STRONG); + + /* Activate default pinmux configuration. */ + galileo_pinmux_select_serial(0); + galileo_pinmux_select_serial(1); + galileo_pinmux_select_dout(GALILEO_PIN_GRP_DIGITAL, 2); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 3); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 4); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 5); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 6); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 7); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 8); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 9); + galileo_pinmux_select_dout(GALILEO_PIN_GRP_DIGITAL, 10); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 11); + galileo_pinmux_select_dout(GALILEO_PIN_GRP_DIGITAL, 12); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 13); + galileo_pinmux_select_analog(0); + galileo_pinmux_select_analog(1); + galileo_pinmux_select_analog(2); + galileo_pinmux_select_analog(3); + galileo_pinmux_select_i2c(); + + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/galileo/drivers/galileo-pinmux.c b/platform/galileo/drivers/galileo-gen2-pinmux.c similarity index 85% rename from platform/galileo/drivers/galileo-pinmux.c rename to platform/galileo/drivers/galileo-gen2-pinmux.c index 3059bdb36..f4ea5be30 100644 --- a/platform/galileo/drivers/galileo-pinmux.c +++ b/platform/galileo/drivers/galileo-gen2-pinmux.c @@ -29,10 +29,19 @@ */ #include "galileo-pinmux.h" +#include #include "gpio.h" #include "gpio-pcal9535a.h" #include "i2c.h" #include "pwm-pca9685.h" +#include + +typedef enum { + GALILEO_PINMUX_FUNC_A, + GALILEO_PINMUX_FUNC_B, + GALILEO_PINMUX_FUNC_C, + GALILEO_PINMUX_FUNC_D +} GALILEO_PINMUX_FUNC; #define GPIO_PCAL9535A_0_I2C_ADDR 0x25 #define GPIO_PCAL9535A_1_I2C_ADDR 0x26 @@ -41,7 +50,6 @@ #define PINMUX_NUM_FUNCS 4 #define PINMUX_NUM_PATHS 4 -#define PINMUX_NUM_PINS 20 typedef enum { NONE, @@ -62,29 +70,6 @@ struct pin_config { GALILEO_PINMUX_FUNC func; }; -static struct pin_config default_pinmux_config[PINMUX_NUM_PINS] = { - { 0, GALILEO_PINMUX_FUNC_C }, /* UART0_RXD */ - { 1, GALILEO_PINMUX_FUNC_C }, /* UART0_TXD */ - { 2, GALILEO_PINMUX_FUNC_A }, /* GPIO5(out) */ - { 3, GALILEO_PINMUX_FUNC_B }, /* GPIO6(in) */ - { 4, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS4 (in) */ - { 5, GALILEO_PINMUX_FUNC_B }, /* GPIO8 (in) */ - { 6, GALILEO_PINMUX_FUNC_B }, /* GPIO9 (in) */ - { 7, GALILEO_PINMUX_FUNC_B }, /* EXP1.P0_6 (in) */ - { 8, GALILEO_PINMUX_FUNC_B }, /* EXP1.P1_0 (in) */ - { 9, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS2 (in) */ - { 10, GALILEO_PINMUX_FUNC_A }, /* GPIO2 (out) */ - { 11, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS3 (in) */ - { 12, GALILEO_PINMUX_FUNC_B }, /* GPIO7 (in) */ - { 13, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS5(in) */ - { 14, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_0 (in)/ADC.IN0 */ - { 15, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_2 (in)/ADC.IN1 */ - { 16, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_4 (in)/ADC.IN2 */ - { 17, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_6 (in)/ADC.IN3 */ - { 18, GALILEO_PINMUX_FUNC_C }, /* I2C_SDA */ - { 19, GALILEO_PINMUX_FUNC_C }, /* I2C_SCL */ -}; - struct mux_pin { MUX_CHIP chip; uint8_t pin; @@ -107,7 +92,7 @@ struct pinmux_internal_data { static struct pinmux_internal_data data; -static struct mux_path galileo_pinmux_paths[PINMUX_NUM_PINS * PINMUX_NUM_FUNCS] = { +static struct mux_path galileo_pinmux_paths[GALILEO_NUM_PINS * PINMUX_NUM_FUNCS] = { {0, GALILEO_PINMUX_FUNC_A, { { EXP1, 0, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* GPIO3 out */ { EXP1, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }, @@ -529,13 +514,13 @@ static struct mux_path galileo_pinmux_paths[PINMUX_NUM_PINS * PINMUX_NUM_FUNCS] { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, }; -int +static int galileo_pinmux_set_pin(uint8_t pin, GALILEO_PINMUX_FUNC func) { struct mux_path *mux_path; uint8_t index, i; - if(pin > PINMUX_NUM_PINS) { + if(pin >= GALILEO_NUM_PINS) { return -1; } @@ -545,48 +530,151 @@ galileo_pinmux_set_pin(uint8_t pin, GALILEO_PINMUX_FUNC func) mux_path = &galileo_pinmux_paths[index]; for(i = 0; i < PINMUX_NUM_PATHS; i++) { + struct gpio_pcal9535a_data *exp = NULL; switch(mux_path->path[i].chip) { case EXP0: - if(gpio_pcal9535a_write(&data.exp0, mux_path->path[i].pin, mux_path->path[i].level) < 0) { - return -1; - } - if(gpio_pcal9535a_config(&data.exp0, mux_path->path[i].pin, mux_path->path[i].cfg) < 0) { - return -1; - } + exp = &data.exp0; break; case EXP1: - if(gpio_pcal9535a_write(&data.exp1, mux_path->path[i].pin, mux_path->path[i].level) < 0) { - return -1; - } - if(gpio_pcal9535a_config(&data.exp1, mux_path->path[i].pin, mux_path->path[i].cfg) < 0) { - return -1; - } + exp = &data.exp1; break; case EXP2: - if(gpio_pcal9535a_write(&data.exp2, mux_path->path[i].pin, mux_path->path[i].level) < 0) { - return -1; - } - if(gpio_pcal9535a_config(&data.exp2, mux_path->path[i].pin, mux_path->path[i].cfg) < 0) { - return -1; - } + exp = &data.exp2; break; case PWM0: if(pwm_pca9685_set_duty_cycle(&data.pwm0, mux_path->path[i].pin, mux_path->path[i].level ? 100 : 0) < 0) { return -1; } - break; + continue; case NONE: - break; + continue; + } + + assert(exp != NULL); + + if(gpio_pcal9535a_write(exp, mux_path->path[i].pin, mux_path->path[i].level) < 0) { + return -1; + } + if(gpio_pcal9535a_config(exp, mux_path->path[i].pin, mux_path->path[i].cfg) < 0) { + return -1; } } return 0; } +static void +flatten_pin_num(galileo_pin_group_t grp, unsigned *pin) +{ + if(grp == GALILEO_PIN_GRP_ANALOG) { + *pin += GALILEO_NUM_DIGITAL_PINS; + } + + assert(*pin < GALILEO_NUM_PINS); +} +/* See galileo-gpio.c for the declaration of this function. */ +int +galileo_brd_to_cpu_gpio_pin(unsigned pin, bool *sus) +{ + static const int SUS = 0x100; + unsigned pins[GALILEO_NUM_PINS] = { + 3, 4, 5, 6, + SUS | 4, 8, 9, SUS | 0, + SUS | 1, SUS | 2, 2, SUS | 3, + 7, SUS | 5 + }; + int cpu_pin; + + /* GPIOs in the analog pin space are implemented by EXP2, not the CPU. */ + assert(pin < GALILEO_NUM_DIGITAL_PINS); + cpu_pin = pins[pin]; + + *sus = (cpu_pin & SUS) == SUS; + + return cpu_pin & ~SUS; +} +void +galileo_pinmux_select_din(galileo_pin_group_t grp, unsigned pin) +{ + bool sus; + int cpu_pin; + + flatten_pin_num(grp, &pin); + + assert(galileo_pinmux_set_pin(pin, GALILEO_PINMUX_FUNC_B) == 0); + + cpu_pin = galileo_brd_to_cpu_gpio_pin(pin, &sus); + /* GPIO_SUS pins are currently unsupported. */ + assert(!sus); + quarkX1000_gpio_config(cpu_pin, QUARKX1000_GPIO_IN); +} +void +galileo_pinmux_select_dout(galileo_pin_group_t grp, unsigned pin) +{ + bool sus; + int cpu_pin; + + flatten_pin_num(grp, &pin); + + assert(galileo_pinmux_set_pin(pin, GALILEO_PINMUX_FUNC_A) == 0); + + cpu_pin = galileo_brd_to_cpu_gpio_pin(pin, &sus); + /* GPIO_SUS pins are currently unsupported. */ + assert(!sus); + quarkX1000_gpio_config(cpu_pin, QUARKX1000_GPIO_OUT); +} +void +galileo_pinmux_select_pwm(unsigned pin) +{ + GALILEO_PINMUX_FUNC func = GALILEO_PINMUX_FUNC_C; + switch(pin) { + case 3: + func = GALILEO_PINMUX_FUNC_D; + break; + case 5: + case 6: + case 9: + case 10: + case 11: + break; + default: + fprintf(stderr, "%s: invalid pin: %d.\n", __FUNCTION__, pin); + halt(); + } + + assert(galileo_pinmux_set_pin(pin, func) == 0); +} +void +galileo_pinmux_select_serial(unsigned pin) +{ + assert(pin < 4); + + assert(galileo_pinmux_set_pin(pin, GALILEO_PINMUX_FUNC_C) == 0); +} +void +galileo_pinmux_select_i2c(void) +{ + assert(galileo_pinmux_set_pin(18, GALILEO_PINMUX_FUNC_C) == 0); + assert(galileo_pinmux_set_pin(19, GALILEO_PINMUX_FUNC_C) == 0); +} +void +galileo_pinmux_select_spi(void) +{ + assert(galileo_pinmux_set_pin(11, GALILEO_PINMUX_FUNC_D) == 0); + assert(galileo_pinmux_set_pin(12, GALILEO_PINMUX_FUNC_C) == 0); + assert(galileo_pinmux_set_pin(13, GALILEO_PINMUX_FUNC_C) == 0); +} +void +galileo_pinmux_select_analog(unsigned pin) +{ + assert(pin < GALILEO_NUM_ANALOG_PINS); + + pin += GALILEO_NUM_DIGITAL_PINS; + + assert(galileo_pinmux_set_pin(pin, GALILEO_PINMUX_FUNC_B) == 0); +} int galileo_pinmux_initialize(void) { - uint8_t i; - /* has to init after I2C master */ if(!quarkX1000_i2c_is_available()) { return -1; @@ -608,11 +696,29 @@ galileo_pinmux_initialize(void) return -1; } - for(i = 0; i < PINMUX_NUM_PINS; i++) { - if(galileo_pinmux_set_pin(default_pinmux_config[i].pin_num, default_pinmux_config[i].func) < 0) { - return -1; - } - } + /* Activate default pinmux configuration. */ + /* Some of the following lines are commented out due to the GPIO_SUS pins + * being currently unsupported. + */ + galileo_pinmux_select_serial(0); + galileo_pinmux_select_serial(1); + galileo_pinmux_select_dout(GALILEO_PIN_GRP_DIGITAL, 2); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 3); + /*galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 4);*/ + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 5); + galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 6); + /*galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 7);*/ + /*galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 8);*/ + /*galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 9);*/ + galileo_pinmux_select_dout(GALILEO_PIN_GRP_DIGITAL, 10); + /*galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 11);*/ + galileo_pinmux_select_dout(GALILEO_PIN_GRP_DIGITAL, 12); + /*galileo_pinmux_select_din(GALILEO_PIN_GRP_DIGITAL, 13);*/ + galileo_pinmux_select_analog(0); + galileo_pinmux_select_analog(1); + galileo_pinmux_select_analog(2); + galileo_pinmux_select_analog(3); + galileo_pinmux_select_i2c(); return 0; } diff --git a/platform/galileo/drivers/galileo-gpio.c b/platform/galileo/drivers/galileo-gpio.c new file mode 100644 index 000000000..a6cee8b65 --- /dev/null +++ b/platform/galileo/drivers/galileo-gpio.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2016, Intel Corporation. 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. + */ + +#include "galileo-gpio.h" +#include +#include "gpio.h" +#if GALILEO_GEN == 1 +#include "cy8c9540a.h" +#endif + +/* Must be implemented in board-specific pinmux file to map a board-level GPIO + * pin number to the corresponding CPU GPIO pin number. + * + * For gen. 1 boards, the value -1 may be returned to indicate that the + * specified GPIO pin is not connected to any CPU pin. For gen. 2 boards, the + * return value should always be a positive number. An assertion within the + * function should check the validity of the pin number. + */ +int galileo_brd_to_cpu_gpio_pin(unsigned pin, bool *sus); +#if GALILEO_GEN == 1 +cy8c9540a_bit_addr_t galileo_brd_to_cy8c9540a_gpio_pin(unsigned pin); +#endif + +static int +brd_to_cpu_pin(unsigned pin) +{ + int cpu_pin; + bool sus; + + cpu_pin = galileo_brd_to_cpu_gpio_pin(pin, &sus); + assert(!sus); + + return cpu_pin; +} + +void galileo_gpio_config(uint8_t pin, int flags) +{ + assert(quarkX1000_gpio_config(brd_to_cpu_pin(pin), flags) == 0); +} + +/** + * \brief Read from GPIO. + * \param pin Board-level IO pin number. + */ +void galileo_gpio_read(uint8_t pin, uint8_t *value) +{ +#if GALILEO_GEN == 1 + cy8c9540a_bit_addr_t bit_addr; +#endif + int cpu_pin = brd_to_cpu_pin(pin); +#if GALILEO_GEN == 1 + if(cpu_pin == -1) { + bit_addr = galileo_brd_to_cy8c9540a_gpio_pin(pin); + *value = cy8c9540a_read(bit_addr); + return; + } +#endif + assert(quarkX1000_gpio_read(cpu_pin, value) == 0); +} + +void galileo_gpio_write(uint8_t pin, uint8_t value) +{ +#if GALILEO_GEN == 1 + cy8c9540a_bit_addr_t bit_addr; +#endif + int cpu_pin = brd_to_cpu_pin(pin); +#if GALILEO_GEN == 1 + if(cpu_pin == -1) { + bit_addr = galileo_brd_to_cy8c9540a_gpio_pin(pin); + cy8c9540a_write(bit_addr, value); + return; + } +#endif + assert(quarkX1000_gpio_write(cpu_pin, value) == 0); +} diff --git a/platform/galileo/drivers/galileo-gpio.h b/platform/galileo/drivers/galileo-gpio.h new file mode 100644 index 000000000..07dbc1082 --- /dev/null +++ b/platform/galileo/drivers/galileo-gpio.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PLATFORM_GALILEO_DRIVERS_GALILEO_GPIO_H_ +#define PLATFORM_GALILEO_DRIVERS_GALILEO_GPIO_H_ + +#include + +void galileo_gpio_config(uint8_t pin, int flags); +void galileo_gpio_read(uint8_t pin, uint8_t *value); +void galileo_gpio_write(uint8_t pin, uint8_t value); + +#endif /* PLATFORM_GALILEO_DRIVERS_GALILEO_GPIO_H_ */ diff --git a/platform/galileo/drivers/galileo-pinmux.h b/platform/galileo/drivers/galileo-pinmux.h index f7d4fa39e..022a43cf6 100644 --- a/platform/galileo/drivers/galileo-pinmux.h +++ b/platform/galileo/drivers/galileo-pinmux.h @@ -33,14 +33,51 @@ #include -typedef enum { - GALILEO_PINMUX_FUNC_A, - GALILEO_PINMUX_FUNC_B, - GALILEO_PINMUX_FUNC_C, - GALILEO_PINMUX_FUNC_D -} GALILEO_PINMUX_FUNC; +typedef enum galileo_pin_group { + GALILEO_PIN_GRP_ANALOG, + GALILEO_PIN_GRP_DIGITAL +} galileo_pin_group_t; + +#define GALILEO_NUM_ANALOG_PINS 6 +#define GALILEO_NUM_DIGITAL_PINS 14 +#define GALILEO_NUM_PINS (GALILEO_NUM_ANALOG_PINS + GALILEO_NUM_DIGITAL_PINS) int galileo_pinmux_initialize(void); -int galileo_pinmux_set_pin(uint8_t pin, GALILEO_PINMUX_FUNC func); + +/** + * \brief Set the indicated pin to be a digital input. + * \param grp Indicates whether the pin is in the analog or digital group. + * \param pin Index of pin within group. + */ +void galileo_pinmux_select_din(galileo_pin_group_t grp, unsigned pin); +/** + * \brief Set the indicated pin to be a digital output. + */ +void galileo_pinmux_select_dout(galileo_pin_group_t grp, unsigned pin); +/** + * \brief Set the indicated pin to be a PWM pin. Only a subset of the pins + * support PWM output. This implicitly operates on the digital pin + * group. + */ +void galileo_pinmux_select_pwm(unsigned pin); +/** + * \brief Connect the indicated pin to a serial port. This implicitly operates + * on the digital pin group. Galileo Gen. 2 supports UART0 on pins 0 and + * 1 and UART1 on pins 2 and 3. + */ +void galileo_pinmux_select_serial(unsigned pin); +/** + * \brief Connect analog pins 4 (SDA) and 5 (SCL) to I2C. + */ +void galileo_pinmux_select_i2c(void); +/** + * \brief Connect digital pins 11 (MOSI), 12 (MISO), and 13 (CLK) to SPI. + */ +void galileo_pinmux_select_spi(void); +/** + * \brief Set the indicated pin to be an ADC input. This implicitly operates + * on the analog pin group. + */ +void galileo_pinmux_select_analog(unsigned pin); #endif /* CPU_X86_DRIVERS_GALILEO_PINMUX_H_ */ diff --git a/platform/galileo/net/eth-conf.c b/platform/galileo/net/eth-conf.c index 061e0aae7..3afb8f211 100644 --- a/platform/galileo/net/eth-conf.c +++ b/platform/galileo/net/eth-conf.c @@ -29,8 +29,10 @@ */ #include "eth-conf.h" +#include #include "net/eth-proc.h" #include "contiki-net.h" +#include "net/ip/dhcpc.h" #include "net/linkaddr.h" #if NETSTACK_CONF_WITH_IPV6 @@ -44,6 +46,8 @@ const linkaddr_t linkaddr_null = { { 0, 0, 0, 0, 0, 0 } }; #define NAMESERVER_IP GATEWAY_IP #endif +PROCESS(dhcp_process, "DHCP"); + /*---------------------------------------------------------------------------*/ void eth_init(void) @@ -70,5 +74,52 @@ eth_init(void) #endif process_start(ð_process, NULL); + /* Comment out the following line to disable DHCP and simply use the static + * IP configuration setup above. + */ + process_start(&dhcp_process, NULL); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(dhcp_process, ev, data) +{ + PROCESS_BEGIN(); + + dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr)); + + printf("Requesting DHCP configuration...\n"); + dhcpc_request(); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { + dhcpc_appcall(ev, data); + } else if(ev == PROCESS_EVENT_EXIT) { + process_exit(&dhcp_process); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_configured(const struct dhcpc_state *s) +{ + uip_sethostaddr(&s->ipaddr); + uip_setnetmask(&s->netmask); + uip_setdraddr(&s->default_router); + uip_nameserver_update(&s->dnsaddr, UIP_NAMESERVER_INFINITE_LIFETIME); + printf("DHCP configured:\n"); + printf(" - Host IP: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s->ipaddr)); + printf(" - Netmask: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s->netmask)); + printf(" - Default router: %d.%d.%d.%d\n", + uip_ipaddr_to_quad(&s->default_router)); + printf(" - DNS server: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s->dnsaddr)); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_unconfigured(const struct dhcpc_state *s) +{ + printf("DHCP unconfigured.\n"); } /*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/exceptions.c b/platform/jn516x/dev/exceptions.c index 10a3bf11b..2991de639 100644 --- a/platform/jn516x/dev/exceptions.c +++ b/platform/jn516x/dev/exceptions.c @@ -354,6 +354,10 @@ exception_handler(uint32 *pu32Stack, eExceptionType eType) } #endif + if(eType == E_EXC_SYSCALL) { + return; + } + #if EXCEPTION_STALLS_SYSTEM while(1) { } diff --git a/platform/mbxxx/contiki-conf.h b/platform/mbxxx/contiki-conf.h index 1d2b17322..4b1e3aac6 100644 --- a/platform/mbxxx/contiki-conf.h +++ b/platform/mbxxx/contiki-conf.h @@ -109,7 +109,7 @@ #define QUEUEBUF_CONF_NUM 2 #define QUEUEBUF_CONF_REF_NUM 0 #define NBR_TABLE_CONF_MAX_NEIGHBORS 4 -#define UIP_CONF_DS6_ROUTE_NBU 4 +#define UIP_CONF_MAX_ROUTES 4 #define RPL_CONF_MAX_PARENTS_PER_DAG 4 #define RPL_CONF_MAX_INSTANCES 1 #define RPL_CONF_MAX_DAG_PER_INSTANCE 1 diff --git a/platform/openmote-cc2538/contiki-conf.h b/platform/openmote-cc2538/contiki-conf.h index 87b58f299..def315b7c 100644 --- a/platform/openmote-cc2538/contiki-conf.h +++ b/platform/openmote-cc2538/contiki-conf.h @@ -79,6 +79,12 @@ typedef uint32_t rtimer_clock_t; #define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) /** @} */ /*---------------------------------------------------------------------------*/ +/* 352us from calling transmit() until the SFD byte has been sent */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(352)) +/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250)) +#define RADIO_DELAY_BEFORE_DETECT 0 +/*---------------------------------------------------------------------------*/ /** * \name Serial Boot Loader Backdoor configuration * @@ -96,7 +102,16 @@ typedef uint32_t rtimer_clock_t; #define FLASH_CCA_CONF_BOOTLDR_BACKDOOR_ACTIVE_HIGH 0 /**< A logic low level activates the boot loader */ #endif /** @} */ - +/*---------------------------------------------------------------------------*/ +/** + * \name CC2538 System Control configuration + * + * @{ + */ +#ifndef SYS_CTRL_CONF_OSC32K_USE_XTAL +#define SYS_CTRL_CONF_OSC32K_USE_XTAL 1 /**< Use the on-board 32.768-kHz crystal */ +#endif +/** @} */ /*---------------------------------------------------------------------------*/ /** * \name CFS configuration @@ -184,10 +199,6 @@ typedef uint32_t rtimer_clock_t; #define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */ #endif -#ifndef CC2538_RF_CONF_SNIFFER_USB -#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */ -#endif - #ifndef DBG_CONF_USB #define DBG_CONF_USB 0 /**< All debugging over UART by default */ #endif @@ -202,12 +213,6 @@ typedef uint32_t rtimer_clock_t; #endif #endif -#if !CC2538_RF_CONF_SNIFFER_USB -#ifndef CC2538_RF_CONF_SNIFFER_UART -#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */ -#endif -#endif - #if !DBG_CONF_USB #ifndef DBG_CONF_UART #define DBG_CONF_UART 0 /**< UART to use for debugging */ @@ -234,15 +239,6 @@ typedef uint32_t rtimer_clock_t; #endif #endif -/* - * When set, the radio turns off address filtering and sends all captured - * frames down a peripheral (UART or USB, depending on the value of - * CC2538_RF_CONF_SNIFFER_USB) - */ -#ifndef CC2538_RF_CONF_SNIFFER -#define CC2538_RF_CONF_SNIFFER 0 -#endif - /** * \brief Define this as 1 to build a headless node. * @@ -263,12 +259,6 @@ typedef uint32_t rtimer_clock_t; #undef STARTUP_CONF_VERBOSE #define STARTUP_CONF_VERBOSE 0 - -/* Little sanity check: We can't have quiet sniffers */ -#if CC2538_RF_CONF_SNIFFER -#error "CC2538_RF_CONF_SNIFFER == 1 and CC2538_CONF_QUIET == 1" -#error "These values are conflicting. Please set either to 0" -#endif #endif /* CC2538_CONF_QUIET */ /** @@ -277,8 +267,7 @@ typedef uint32_t rtimer_clock_t; #ifndef USB_SERIAL_CONF_ENABLE #define USB_SERIAL_CONF_ENABLE \ ((SLIP_ARCH_CONF_USB & SLIP_ARCH_CONF_ENABLED) | \ - DBG_CONF_USB | \ - (CC2538_RF_CONF_SNIFFER & CC2538_RF_CONF_SNIFFER_USB)) + DBG_CONF_USB) #endif /* @@ -298,9 +287,6 @@ typedef uint32_t rtimer_clock_t; #define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \ !SLIP_ARCH_CONF_USB && \ SLIP_ARCH_CONF_UART == (u)) -#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \ - !CC2538_RF_CONF_SNIFFER_USB && \ - CC2538_RF_CONF_SNIFFER_UART == (u)) #define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u)) #define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u)) @@ -308,7 +294,6 @@ typedef uint32_t rtimer_clock_t; UART_CONF_ENABLE && \ (UART_IN_USE_BY_SERIAL_LINE(u) || \ UART_IN_USE_BY_SLIP(u) || \ - UART_IN_USE_BY_RF_SNIFFER(u) || \ UART_IN_USE_BY_DBG(u) || \ UART_IN_USE_BY_UART1(u)) \ ) diff --git a/platform/seedeye/contiki-conf.h b/platform/seedeye/contiki-conf.h index d58ff686d..de0d18c57 100644 --- a/platform/seedeye/contiki-conf.h +++ b/platform/seedeye/contiki-conf.h @@ -93,7 +93,7 @@ typedef uint32_t rtimer_clock_t; /* IPv6 configuration options */ #define NETSTACK_CONF_WITH_IPV6 1 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20 /* number of neighbors */ -#define UIP_CONF_DS6_ROUTE_NBU 20 /* number of routes */ +#define UIP_CONF_MAX_ROUTES 20 /* number of routes */ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md index 04d66a0d4..980038593 100644 --- a/platform/srf06-cc26xx/README.md +++ b/platform/srf06-cc26xx/README.md @@ -107,23 +107,31 @@ If the `BOARD` variable is unspecified, an image for the Srf06 CC26XXEM will be If you want to switch between building for one platform to the other, make certain to `make clean` before building for the new one, or you will get linker errors. -If you want to upload the compiled firmware to a node via the serial boot loader you need to manually enable the boot loader and then use `make cc26xx-demo.upload`. On the SmartRF06 board you enable the boot loader by resetting the board (EM RESET button) while holding the `select` button. (The boot loader backdoor needs to be enabled on the chip, and the chip needs to be configured correctly, for this to work. See README in the `tools/cc2538-bsl` directory for more info). The serial uploader script will automatically pick the first available serial port. If this is not the port where your node is connected, you can force the script to use a specific port by defining the `PORT` argument eg. `make cc26xx-demo.upload PORT=/dev/tty.usbserial` - -The serial bootloader can also be used with the LaunchPad and the changes required to achieve this are the same as those required for the SmartRF. The only difference is that you will need to map `BL_PIN_NUMBER` to either the left or right user button (values to be used for `BL_PIN_NUMBER` in `ccfg.c` are `0x0D` and `0x0E` respectively). - -Note that uploading over serial doesn't work for the Sensortag, you can use TI's SmartRF Flash Programmer in this case. - For the `cc26xx-demo`, the included readme describes in detail what the example does. To generate an assembly listing of the compiled firmware, run `make cc26xx-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean cc26xx-demo.lst`. +How to Program your Device +-------------------------- +To program your device on Windows, use TI's [SmartRF Flash Programmer][smart-rf-flashprog] (FLASH-PROGRAMMER-2). + +On Linux and OS X, you can program your device via the chip's serial ROM boot loader. In order for this to work, the following conditions need to be met: + +* The board can support the bootloader. This is the case for SmartRF06EB with CC26xx/CC13xx EMs and it is also the case for LaunchPads. Note that uploading over serial does not (and will not) work for the Sensortag. +* The chip is not programmed with a valid image, or the image has the bootloader backdoor unlocked. To enable the bootloader backdoor in your image, define `ROM_BOOTLOADER_ENABLE` to 1 in `contiki-conf.h`. + +You will then need to manually enter the boot loader and use the `.upload` make target (e.g. `make cc26xx-demo.upload` for the `cc26xx-demo`). On the SmartRF06, you enter the boot loader by resetting the EM (EM RESET button) while holding the `select` button. For the LaunchPad, you enter the bootloader by resetting the chip while holding `BTN_1`. It is possible to change the pin and its corresponding level (High/Low) that will trigger bootloader mode by changing `SET_CCFG_BL_CONFIG_BL_LEVEL` and `SET_CCFG_BL_CONFIG_BL_PIN_NUMBER` in `board.h`. + +The serial uploader script will automatically pick the first available serial port. If this is not the port where your node is connected, you can force the script to use a specific port by defining the `PORT` argument eg. `make cc26xx-demo.upload PORT=/dev/tty.usbserial`. + +For more information on the serial bootloader, see its README under the `tools/cc2538-bsl` directory. + CC13xx/CC26xx Border Router over UART ===================================== The platform code can be used as a border router (SLIP over UART) by using the example under `examples/ipv6/rpl-border-router`. This example defines the following: - #ifndef UIP_CONF_BUFFER_SIZE #define UIP_CONF_BUFFER_SIZE 140 #endif @@ -234,3 +242,5 @@ The chip will come out of low power mode by one of the following events: is an AON RTC Channel 2 compare interrupt. * Rtimer triggers, as part of ContikiMAC's sleep/wake-up cycles. The rtimer sits on the AON RTC channel 0. + +[smart-rf-flashprog]: http://www.ti.com/tool/flash-programmer "SmartRF Flash Programmer" diff --git a/platform/srf06-cc26xx/common/ext-flash.c b/platform/srf06-cc26xx/common/ext-flash.c index 62fea2288..7faaab0c0 100644 --- a/platform/srf06-cc26xx/common/ext-flash.c +++ b/platform/srf06-cc26xx/common/ext-flash.c @@ -94,7 +94,7 @@ static void select_on_bus(void) { - ti_lib_gpio_pin_write(BOARD_FLASH_CS, 0); + ti_lib_gpio_clear_dio(BOARD_IOID_FLASH_CS); } /*---------------------------------------------------------------------------*/ /** @@ -103,7 +103,7 @@ select_on_bus(void) static void deselect(void) { - ti_lib_gpio_pin_write(BOARD_FLASH_CS, 1); + ti_lib_gpio_set_dio(BOARD_IOID_FLASH_CS); } /*---------------------------------------------------------------------------*/ /** diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h index c1546f6a8..6342bce99 100644 --- a/platform/srf06-cc26xx/contiki-conf.h +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -66,8 +66,8 @@ #endif /* - * Disable turning off HF oscillator when the radio is off: - * You need to set this in order to use TSCH, disable to save more energy. + * If set, the systems keeps the HF crystal oscillator on even when the radio is off. + * You need to set this to 1 to use TSCH with its default 2.2ms or larger guard time. */ #ifndef CC2650_FAST_RADIO_STARTUP #define CC2650_FAST_RADIO_STARTUP 0 @@ -106,7 +106,7 @@ #define CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED (RTIMER_ARCH_SECOND / 20) #define CONTIKIMAC_CONF_SEND_SW_ACK 1 #define CONTIKIMAC_CONF_AFTER_ACK_DETECTECT_WAIT_TIME (RTIMER_SECOND / 1000) -#define CONTIKIMAC_CONF_INTER_PACKET_INTERVAL (RTIMER_SECOND / 250) +#define CONTIKIMAC_CONF_INTER_PACKET_INTERVAL (RTIMER_SECOND / 240) #else #define NETSTACK_CONF_RADIO ieee_mode_driver @@ -172,10 +172,6 @@ #ifndef RF_BLE_CONF_ENABLED #define RF_BLE_CONF_ENABLED 0 /**< 0 to disable BLE support */ #endif - -#ifndef PROP_MODE_CONF_SNIFFER -#define PROP_MODE_CONF_SNIFFER 0 /**< 1 to enable sniffer mode */ -#endif /** @} */ /*---------------------------------------------------------------------------*/ /** @} */ @@ -288,6 +284,19 @@ #endif /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \name ROM Bootloader configuration + * + * Enable/Disable the ROM bootloader in your image, if the board supports it. + * Look in board.h to choose the DIO and corresponding level that will cause + * the chip to enter bootloader mode. + * @{ + */ +#ifndef ROM_BOOTLOADER_ENABLE +#define ROM_BOOTLOADER_ENABLE 0 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** * \name Button configurations * @@ -346,9 +355,8 @@ typedef uint32_t rtimer_clock_t; /* Delay between GO signal and start listening. * This value is so small because the radio is constantly on within each timeslot. */ #define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(15)) -/* Delay between the SFD finishes arriving and it is detected in software. - * Not important on this platform as it uses hardware timestamps for SFD */ -#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(0)) +/* Delay between the SFD finishes arriving and it is detected in software. */ +#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(352)) /* Timer conversion; radio is running at 4 MHz */ #define RADIO_TIMER_SECOND 4000000u @@ -373,12 +381,22 @@ typedef uint32_t rtimer_clock_t; #define TSCH_CONF_TIMESYNC_REMOVE_JITTER 0 #endif +#ifndef TSCH_CONF_BASE_DRIFT_PPM /* The drift compared to "true" 10ms slots. - Enable adaptive sync to enable compensation for this. */ + * Enable adaptive sync to enable compensation for this. */ #define TSCH_CONF_BASE_DRIFT_PPM -977 +#endif /* 10 times per second */ -#define TSCH_CONF_ASSOCIATION_CHANNEL_SWITCH_FREQUENCY 10 +#ifndef TSCH_CONF_CHANNEL_SCAN_DURATION +#define TSCH_CONF_CHANNEL_SCAN_DURATION (CLOCK_SECOND / 10) +#endif + +/* Slightly reduce the TSCH guard time (from 2200 usec to 1800 usec) to make sure + * the CC26xx radio has sufficient time to start up. */ +#ifndef TSCH_CONF_RX_WAIT +#define TSCH_CONF_RX_WAIT 1800 +#endif /** @} */ /*---------------------------------------------------------------------------*/ diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c index b3f5c37f7..3992ff9e0 100644 --- a/platform/srf06-cc26xx/contiki-main.c +++ b/platform/srf06-cc26xx/contiki-main.c @@ -60,6 +60,7 @@ #include "sys/clock.h" #include "sys/rtimer.h" #include "sys/node-id.h" +#include "lib/random.h" #include "lib/sensors.h" #include "button-sensor.h" #include "dev/serial-line.h" @@ -149,11 +150,6 @@ main(void) /* Set the LF XOSC as the LF system clock source */ oscillators_select_lf_xosc(); -#if CC2650_FAST_RADIO_STARTUP - /* Also request HF XOSC to start up */ - oscillators_request_hf_xosc(); -#endif - lpm_init(); board_init(); diff --git a/platform/srf06-cc26xx/launchpad/button-sensor.c b/platform/srf06-cc26xx/launchpad/button-sensor.c index d37369d0a..eb8bd3033 100644 --- a/platform/srf06-cc26xx/launchpad/button-sensor.c +++ b/platform/srf06-cc26xx/launchpad/button-sensor.c @@ -83,7 +83,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0) { left_timer.start = clock_time(); left_timer.duration = 0; } else { @@ -104,7 +104,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0) { right_timer.start = clock_time(); right_timer.duration = 0; } else { @@ -122,19 +122,19 @@ config_buttons(int type, int c, uint32_t key) { switch(type) { case SENSORS_HW_INIT: - ti_lib_gpio_event_clear(1 << key); - ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); - ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + ti_lib_gpio_clear_event_dio(key); + ti_lib_rom_ioc_pin_type_gpio_input(key); + ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); gpio_interrupt_register_handler(key, button_press_handler); break; case SENSORS_ACTIVE: if(c) { - ti_lib_gpio_event_clear(1 << key); - ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); - ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); - ti_lib_ioc_int_enable(key); + ti_lib_gpio_clear_event_dio(key); + ti_lib_rom_ioc_pin_type_gpio_input(key); + ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_rom_ioc_int_enable(key); } else { - ti_lib_ioc_int_disable(key); + ti_lib_rom_ioc_int_disable(key); } break; default: @@ -164,7 +164,7 @@ status(int type, uint32_t key_io_id) switch(type) { case SENSORS_ACTIVE: case SENSORS_READY: - if(ti_lib_ioc_port_configure_get(key_io_id) & IOC_INT_ENABLE) { + if(ti_lib_rom_ioc_port_configure_get(key_io_id) & IOC_INT_ENABLE) { return 1; } break; @@ -178,7 +178,7 @@ static int value_left(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)left_timer.duration; @@ -190,7 +190,7 @@ static int value_right(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)right_timer.duration; diff --git a/platform/srf06-cc26xx/launchpad/cc1310/board.h b/platform/srf06-cc26xx/launchpad/cc1310/board.h index d6cfeeedb..9c750e0f9 100644 --- a/platform/srf06-cc26xx/launchpad/cc1310/board.h +++ b/platform/srf06-cc26xx/launchpad/cc1310/board.h @@ -150,6 +150,28 @@ #define BOARD_IOID_SDA IOID_5 /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \brief ROM bootloader configuration + * + * Change SET_CCFG_BL_CONFIG_BL_PIN_NUMBER to BOARD_IOID_KEY_xyz to select + * which button triggers the bootloader on reset. + * + * The remaining values are not meant to be modified by the user + * @{ + */ +#if ROM_BOOTLOADER_ENABLE +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0xC5 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x00 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER BOARD_IOID_KEY_LEFT +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xC5 +#else +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0x00 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x01 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER 0xFF +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xFF +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** * \brief Remaining pins * diff --git a/platform/srf06-cc26xx/launchpad/cc2650/board.h b/platform/srf06-cc26xx/launchpad/cc2650/board.h index a65ca5361..d71896c3c 100644 --- a/platform/srf06-cc26xx/launchpad/cc2650/board.h +++ b/platform/srf06-cc26xx/launchpad/cc2650/board.h @@ -150,6 +150,28 @@ #define BOARD_IOID_SDA IOID_5 /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \brief ROM bootloader configuration + * + * Change SET_CCFG_BL_CONFIG_BL_PIN_NUMBER to BOARD_IOID_KEY_xyz to select + * which button triggers the bootloader on reset. + * + * The remaining values are not meant to be modified by the user + * @{ + */ +#if ROM_BOOTLOADER_ENABLE +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0xC5 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x00 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER BOARD_IOID_KEY_LEFT +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xC5 +#else +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0x00 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x01 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER 0xFF +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xFF +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** * \brief Remaining pins * diff --git a/platform/srf06-cc26xx/launchpad/leds-arch.c b/platform/srf06-cc26xx/launchpad/leds-arch.c index e853487fd..0d8385ad6 100644 --- a/platform/srf06-cc26xx/launchpad/leds-arch.c +++ b/platform/srf06-cc26xx/launchpad/leds-arch.c @@ -55,7 +55,7 @@ leds_arch_init(void) ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_1); ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_2); - ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + ti_lib_gpio_clear_multi_dio(BOARD_LED_ALL); } /*---------------------------------------------------------------------------*/ unsigned char @@ -68,13 +68,13 @@ void leds_arch_set(unsigned char leds) { c = leds; - ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + ti_lib_gpio_clear_multi_dio(BOARD_LED_ALL); if((leds & LEDS_RED) == LEDS_RED) { - ti_lib_gpio_pin_write(BOARD_LED_1, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_1); } if((leds & LEDS_YELLOW) == LEDS_YELLOW) { - ti_lib_gpio_pin_write(BOARD_LED_2, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_2); } } /*---------------------------------------------------------------------------*/ diff --git a/platform/srf06-cc26xx/sensortag/board-i2c.c b/platform/srf06-cc26xx/sensortag/board-i2c.c index cf74e2a93..17486d65b 100644 --- a/platform/srf06-cc26xx/sensortag/board-i2c.c +++ b/platform/srf06-cc26xx/sensortag/board-i2c.c @@ -174,8 +174,6 @@ board_i2c_write(uint8_t *data, uint8_t len) bool board_i2c_write_single(uint8_t data) { - bool success; - /* Write slave address */ ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, false); @@ -188,9 +186,8 @@ board_i2c_write_single(uint8_t data) /* Assert RUN + START + STOP */ ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); while(ti_lib_i2c_master_busy(I2C0_BASE)); - success = i2c_status(); - return success; + return i2c_status(); } /*---------------------------------------------------------------------------*/ bool @@ -256,12 +253,11 @@ board_i2c_write_read(uint8_t *wdata, uint8_t wlen, uint8_t *rdata, uint8_t rlen) for(i = 1; i < wlen && success; i++) { /* Write next byte */ ti_lib_i2c_master_data_put(I2C0_BASE, wdata[i]); - if(i < wlen - 1) { - /* Clear START */ - ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); - while(ti_lib_i2c_master_busy(I2C0_BASE)); - success = i2c_status(); - } + + /* Clear START */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); } if(!success) { return false; diff --git a/platform/srf06-cc26xx/sensortag/board.c b/platform/srf06-cc26xx/sensortag/board.c index f06545170..f1f4a29e1 100644 --- a/platform/srf06-cc26xx/sensortag/board.c +++ b/platform/srf06-cc26xx/sensortag/board.c @@ -75,7 +75,7 @@ shutdown_handler(uint8_t mode) SENSORS_DEACTIVATE(tmp_007_sensor); SENSORS_DEACTIVATE(hdc_1000_sensor); SENSORS_DEACTIVATE(mpu_9250_sensor); - ti_lib_gpio_pin_clear(BOARD_MPU_POWER); + ti_lib_gpio_clear_dio(BOARD_IOID_MPU_POWER); } /* In all cases, stop the I2C */ @@ -111,7 +111,7 @@ configure_unused_pins(void) /* Digital Microphone */ ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_MIC_POWER); - ti_lib_gpio_pin_clear((1 << BOARD_IOID_MIC_POWER)); + ti_lib_gpio_clear_dio(BOARD_IOID_MIC_POWER); ti_lib_ioc_io_drv_strength_set(BOARD_IOID_MIC_POWER, IOC_CURRENT_2MA, IOC_STRENGTH_MIN); diff --git a/platform/srf06-cc26xx/sensortag/button-sensor.c b/platform/srf06-cc26xx/sensortag/button-sensor.c index 921d96b20..9df55d21d 100644 --- a/platform/srf06-cc26xx/sensortag/button-sensor.c +++ b/platform/srf06-cc26xx/sensortag/button-sensor.c @@ -86,7 +86,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0) { left_timer.start = clock_time(); left_timer.duration = 0; } else { @@ -107,7 +107,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0) { right_timer.start = clock_time(); right_timer.duration = 0; } else { @@ -132,19 +132,19 @@ config_buttons(int type, int c, uint32_t key) { switch(type) { case SENSORS_HW_INIT: - ti_lib_gpio_event_clear(1 << key); - ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); - ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + ti_lib_gpio_clear_event_dio(key); + ti_lib_rom_ioc_pin_type_gpio_input(key); + ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); gpio_interrupt_register_handler(key, button_press_handler); break; case SENSORS_ACTIVE: if(c) { - ti_lib_gpio_event_clear(1 << key); - ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); - ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); - ti_lib_ioc_int_enable(key); + ti_lib_gpio_clear_event_dio(key); + ti_lib_rom_ioc_pin_type_gpio_input(key); + ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_rom_ioc_int_enable(key); } else { - ti_lib_ioc_int_disable(key); + ti_lib_rom_ioc_int_disable(key); } break; default: @@ -225,7 +225,7 @@ static int value_left(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)left_timer.duration; @@ -237,7 +237,7 @@ static int value_right(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)right_timer.duration; diff --git a/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c b/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c index e415dca55..c36959063 100644 --- a/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c +++ b/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c @@ -55,7 +55,7 @@ leds_arch_init(void) ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_1); ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_2); - ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + ti_lib_gpio_clear_multi_dio(BOARD_LED_ALL); } /*---------------------------------------------------------------------------*/ unsigned char @@ -68,13 +68,13 @@ void leds_arch_set(unsigned char leds) { c = leds; - ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + ti_lib_gpio_clear_multi_dio(BOARD_LED_ALL); if((leds & LEDS_RED) == LEDS_RED) { - ti_lib_gpio_pin_write(BOARD_LED_1, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_1); } if((leds & LEDS_YELLOW) == LEDS_YELLOW) { - ti_lib_gpio_pin_write(BOARD_LED_2, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_2); } } /*---------------------------------------------------------------------------*/ diff --git a/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.c b/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.c index 275f2b352..5a97666b3 100644 --- a/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.c +++ b/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.c @@ -505,7 +505,7 @@ initialise(void *not_used) static void power_up(void) { - ti_lib_gpio_pin_write(BOARD_MPU_POWER, 1); + ti_lib_gpio_set_dio(BOARD_IOID_MPU_POWER); state = SENSOR_STATE_BOOTING; ctimer_set(&startup_timer, SENSOR_BOOT_DELAY, initialise, NULL); @@ -608,7 +608,7 @@ configure(int type, int enable) ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_MPU_POWER); ti_lib_ioc_io_drv_strength_set(BOARD_IOID_MPU_POWER, IOC_CURRENT_4MA, IOC_STRENGTH_MAX); - ti_lib_gpio_pin_clear(BOARD_MPU_POWER); + ti_lib_gpio_clear_dio(BOARD_IOID_MPU_POWER); elements = MPU_9250_SENSOR_TYPE_NONE; break; case SENSORS_ACTIVE: @@ -629,7 +629,7 @@ configure(int type, int enable) sensor_sleep(); while(ti_lib_i2c_master_busy(I2C0_BASE)); state = SENSOR_STATE_DISABLED; - ti_lib_gpio_pin_clear(BOARD_MPU_POWER); + ti_lib_gpio_clear_dio(BOARD_IOID_MPU_POWER); } } break; diff --git a/platform/srf06-cc26xx/sensortag/reed-relay.c b/platform/srf06-cc26xx/sensortag/reed-relay.c index 9be161b48..598bfd970 100644 --- a/platform/srf06-cc26xx/sensortag/reed-relay.c +++ b/platform/srf06-cc26xx/sensortag/reed-relay.c @@ -74,7 +74,7 @@ reed_interrupt_handler(uint8_t ioid) static int value(int type) { - return (int)ti_lib_gpio_pin_read(1 << BOARD_IOID_REED_RELAY); + return (int)ti_lib_gpio_read_dio(BOARD_IOID_REED_RELAY); } /*---------------------------------------------------------------------------*/ /** @@ -91,7 +91,7 @@ configure(int type, int value) switch(type) { case SENSORS_HW_INIT: ti_lib_ioc_int_disable(BOARD_IOID_REED_RELAY); - ti_lib_gpio_event_clear(1 << BOARD_IOID_REED_RELAY); + ti_lib_gpio_clear_event_dio(BOARD_IOID_REED_RELAY); /* Enable the GPIO clock when the CM3 is running */ ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO); diff --git a/platform/srf06-cc26xx/srf06/als-sensor.c b/platform/srf06-cc26xx/srf06/als-sensor.c index f149d16a1..3b6fdecb9 100644 --- a/platform/srf06-cc26xx/srf06/als-sensor.c +++ b/platform/srf06-cc26xx/srf06/als-sensor.c @@ -59,18 +59,18 @@ config(int type, int enable) ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); break; case SENSORS_ACTIVE: - ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); - ti_lib_ioc_port_configure_set(BOARD_IOID_ALS_OUT, IOC_PORT_GPIO, - IOC_STD_OUTPUT); - ti_lib_gpio_dir_mode_set(BOARD_ALS_OUT, GPIO_DIR_MODE_IN); + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); + ti_lib_rom_ioc_port_configure_set(BOARD_IOID_ALS_OUT, IOC_PORT_GPIO, + IOC_STD_OUTPUT); + ti_lib_rom_ioc_pin_type_gpio_input(BOARD_IOID_ALS_OUT); if(enable) { - ti_lib_gpio_pin_write(BOARD_ALS_PWR, 1); + ti_lib_gpio_set_dio(BOARD_IOID_ALS_PWR); aux_ctrl_register_consumer(&als_aux); ti_lib_aux_adc_select_input(ADC_COMPB_IN_AUXIO7); clock_delay_usec(2000); } else { - ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0); + ti_lib_gpio_clear_dio(BOARD_IOID_ALS_PWR); aux_ctrl_unregister_consumer(&als_aux); } break; diff --git a/platform/srf06-cc26xx/srf06/board.c b/platform/srf06-cc26xx/srf06/board.c index 15528f79a..2d59d4ea4 100644 --- a/platform/srf06-cc26xx/srf06/board.c +++ b/platform/srf06-cc26xx/srf06/board.c @@ -29,7 +29,7 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup sensortag-common-peripherals + * \addtogroup srf06-common-peripherals * @{ * * \file @@ -50,7 +50,7 @@ lpm_handler(uint8_t mode) { /* Ambient light sensor (off, output low) */ ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); - ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0); + ti_lib_gpio_clear_dio(BOARD_IOID_ALS_PWR); ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_ALS_OUT); ti_lib_ioc_io_port_pull_set(BOARD_IOID_ALS_OUT, IOC_NO_IOPULL); } @@ -77,11 +77,11 @@ configure_unused_pins(void) { /* Turn off 3.3-V domain (lcd/sdcard power, output low) */ ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_3V3_EN); - ti_lib_gpio_pin_write(BOARD_3V3_EN, 0); + ti_lib_gpio_clear_dio(BOARD_IOID_3V3_EN); /* Accelerometer (PWR output low, CSn output, high) */ ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ACC_PWR); - ti_lib_gpio_pin_write(BOARD_ACC_PWR, 0); + ti_lib_gpio_clear_dio(BOARD_IOID_ACC_PWR); } /*---------------------------------------------------------------------------*/ void diff --git a/platform/srf06-cc26xx/srf06/button-sensor.c b/platform/srf06-cc26xx/srf06/button-sensor.c index b397e86f5..23f668355 100644 --- a/platform/srf06-cc26xx/srf06/button-sensor.c +++ b/platform/srf06-cc26xx/srf06/button-sensor.c @@ -87,7 +87,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_SELECT) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_SELECT) == 0) { sel_timer.start = clock_time(); sel_timer.duration = 0; } else { @@ -107,7 +107,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0) { left_timer.start = clock_time(); left_timer.duration = 0; } else { @@ -128,7 +128,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0) { right_timer.start = clock_time(); right_timer.duration = 0; } else { @@ -151,7 +151,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_UP) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_UP) == 0) { up_timer.start = clock_time(); up_timer.duration = 0; } else { @@ -171,7 +171,7 @@ button_press_handler(uint8_t ioid) * Start press duration counter on press (falling), notify on release * (rising) */ - if(ti_lib_gpio_pin_read(BOARD_KEY_DOWN) == 0) { + if(ti_lib_gpio_read_dio(BOARD_IOID_KEY_DOWN) == 0) { down_timer.start = clock_time(); down_timer.duration = 0; } else { @@ -193,19 +193,19 @@ config_buttons(int type, int c, uint32_t key) { switch(type) { case SENSORS_HW_INIT: - ti_lib_gpio_event_clear(1 << key); - ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); - ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + ti_lib_gpio_clear_event_dio(key); + ti_lib_rom_ioc_pin_type_gpio_input(key); + ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); gpio_interrupt_register_handler(key, button_press_handler); break; case SENSORS_ACTIVE: if(c) { - ti_lib_gpio_event_clear(1 << key); - ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); - ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); - ti_lib_ioc_int_enable(key); + ti_lib_gpio_clear_event_dio(key); + ti_lib_rom_ioc_pin_type_gpio_input(key); + ti_lib_rom_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_rom_ioc_int_enable(key); } else { - ti_lib_ioc_int_disable(key); + ti_lib_rom_ioc_int_disable(key); } break; default: @@ -327,7 +327,7 @@ static int value_select(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_SELECT) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_SELECT) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)sel_timer.duration; @@ -339,7 +339,7 @@ static int value_left(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_LEFT) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)left_timer.duration; @@ -351,7 +351,7 @@ static int value_right(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_RIGHT) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)right_timer.duration; @@ -363,7 +363,7 @@ static int value_up(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_UP) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_UP) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)up_timer.duration; @@ -375,7 +375,7 @@ static int value_down(int type) { if(type == BUTTON_SENSOR_VALUE_STATE) { - return ti_lib_gpio_pin_read(BOARD_KEY_DOWN) == 0 ? + return ti_lib_gpio_read_dio(BOARD_IOID_KEY_DOWN) == 0 ? BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; } else if(type == BUTTON_SENSOR_VALUE_DURATION) { return (int)down_timer.duration; diff --git a/platform/srf06-cc26xx/srf06/cc13xx/board.h b/platform/srf06-cc26xx/srf06/cc13xx/board.h index eff486fc5..831c2ee33 100644 --- a/platform/srf06-cc26xx/srf06/cc13xx/board.h +++ b/platform/srf06-cc26xx/srf06/cc13xx/board.h @@ -227,6 +227,28 @@ #define BOARD_ACC_MISO BOARD_SPI_MISO /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \brief ROM bootloader configuration + * + * Change SET_CCFG_BL_CONFIG_BL_PIN_NUMBER to BOARD_IOID_KEY_xyz to select + * which button triggers the bootloader on reset. + * + * The remaining values are not meant to be modified by the user + * @{ + */ +#if ROM_BOOTLOADER_ENABLE +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0xC5 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x00 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER BOARD_IOID_KEY_SELECT +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xC5 +#else +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0x00 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x01 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER 0xFF +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xFF +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** * \name Device string used on startup * @{ diff --git a/platform/srf06-cc26xx/srf06/cc26xx/board.h b/platform/srf06-cc26xx/srf06/cc26xx/board.h index 3dd064bc3..35080aea9 100644 --- a/platform/srf06-cc26xx/srf06/cc26xx/board.h +++ b/platform/srf06-cc26xx/srf06/cc26xx/board.h @@ -227,6 +227,28 @@ #define BOARD_ACC_MISO BOARD_SPI_MISO /** @} */ /*---------------------------------------------------------------------------*/ +/** + * \brief ROM bootloader configuration + * + * Change SET_CCFG_BL_CONFIG_BL_PIN_NUMBER to BOARD_IOID_KEY_xyz to select + * which button triggers the bootloader on reset. + * + * The remaining values are not meant to be modified by the user + * @{ + */ +#if ROM_BOOTLOADER_ENABLE +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0xC5 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x00 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER BOARD_IOID_KEY_SELECT +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xC5 +#else +#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE 0x00 +#define SET_CCFG_BL_CONFIG_BL_LEVEL 0x01 +#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER 0xFF +#define SET_CCFG_BL_CONFIG_BL_ENABLE 0xFF +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** * \name Device string used on startup * @{ diff --git a/platform/srf06-cc26xx/srf06/leds-arch.c b/platform/srf06-cc26xx/srf06/leds-arch.c index 423789350..2a1627005 100644 --- a/platform/srf06-cc26xx/srf06/leds-arch.c +++ b/platform/srf06-cc26xx/srf06/leds-arch.c @@ -56,7 +56,7 @@ leds_arch_init(void) ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_LED_3); ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_LED_4); - ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + ti_lib_gpio_clear_multi_dio(BOARD_LED_ALL); } /*---------------------------------------------------------------------------*/ unsigned char @@ -71,19 +71,19 @@ leds_arch_set(unsigned char leds) c = leds; /* Clear everything */ - ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + ti_lib_gpio_clear_multi_dio(BOARD_LED_ALL); if((leds & LEDS_RED) == LEDS_RED) { - ti_lib_gpio_pin_write(BOARD_LED_1, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_1); } if((leds & LEDS_YELLOW) == LEDS_YELLOW) { - ti_lib_gpio_pin_write(BOARD_LED_2, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_2); } if((leds & LEDS_GREEN) == LEDS_GREEN) { - ti_lib_gpio_pin_write(BOARD_LED_3, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_3); } if((leds & LEDS_ORANGE) == LEDS_ORANGE) { - ti_lib_gpio_pin_write(BOARD_LED_4, 1); + ti_lib_gpio_set_dio(BOARD_IOID_LED_4); } } /*---------------------------------------------------------------------------*/ diff --git a/platform/stm32nucleo-spirit1/contiki-conf.h b/platform/stm32nucleo-spirit1/contiki-conf.h index 9a97ab355..43a3d8d9f 100644 --- a/platform/stm32nucleo-spirit1/contiki-conf.h +++ b/platform/stm32nucleo-spirit1/contiki-conf.h @@ -85,9 +85,9 @@ #define UIP_CONF_ROUTER 1 /* configure number of neighbors and routes */ -#ifndef UIP_CONF_DS6_ROUTE_NBU -#define UIP_CONF_DS6_ROUTE_NBU 30 -#endif /* UIP_CONF_DS6_ROUTE_NBU */ +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 30 +#endif /* UIP_CONF_MAX_ROUTES */ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 /* 90000// 600000 */ diff --git a/platform/z1/Makefile.common b/platform/z1/Makefile.common index 642071bdc..6d6bc2e9e 100644 --- a/platform/z1/Makefile.common +++ b/platform/z1/Makefile.common @@ -12,14 +12,12 @@ endif CLEAN += symbols.c symbols.h -ARCH=msp430.c leds.c watchdog.c xmem.c \ - spi.c cc2420.c cc2420-arch.c cc2420-arch-sfd.c\ - node-id.c sensors.c button-sensor.c cfs-coffee.c \ - radio-sensor.c uart0.c uart0-putchar.c uip-ipchksum.c \ - slip.c slip_uart0.c \ - z1-phidgets.c sht11.c sht11-sensor.c light-sensor.c \ - battery-sensor.c sky-sensors.c tmp102.c temperature-sensor.c light-ziglet.c \ - relay-phidget.c tlc59116.c sht25.c +ARCH = msp430.c leds.c watchdog.c xmem.c i2cmaster.c \ + spi.c cc2420.c cc2420-arch.c cc2420-arch-sfd.c\ + node-id.c sensors.c button-sensor.c cfs-coffee.c \ + radio-sensor.c uart0.c uart0-putchar.c uip-ipchksum.c \ + slip.c slip_uart0.c z1-sensors.c adxl345.c temperature-sensor.c \ + z1-phidgets.c light-sensor.c battery-sensor.c sky-sensors.c tmp102.c CONTIKI_TARGET_DIRS = . dev apps net ifndef CONTIKI_TARGET_MAIN @@ -31,7 +29,6 @@ CFLAGS += -DMACID=$(nodemac) endif CONTIKI_TARGET_SOURCEFILES += $(ARCH) $(UIPDRIVERS) -CONTIKI_TARGET_SOURCEFILES += i2cmaster.c adxl345.c MCU=msp430f2617 diff --git a/platform/z1/Makefile.z1 b/platform/z1/Makefile.z1 index 015171af7..6ca3ab0e8 100644 --- a/platform/z1/Makefile.z1 +++ b/platform/z1/Makefile.z1 @@ -12,4 +12,4 @@ endif MODULES += core/net \ core/net/mac core/net/mac/contikimac \ core/net/llsec \ - dev/cc2420 dev/sht11 + dev/cc2420 diff --git a/platform/z1/contiki-conf.h b/platform/z1/contiki-conf.h index 44d74efdb..536b51913 100644 --- a/platform/z1/contiki-conf.h +++ b/platform/z1/contiki-conf.h @@ -33,17 +33,33 @@ #include "platform-conf.h" +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ + #define XMAC_CONF_COMPOWER 1 #define CXMAC_CONF_COMPOWER 1 #if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ -#define NETSTACK_CONF_NETWORK sicslowpan_driver -#define NETSTACK_CONF_MAC csma_driver -#define NETSTACK_CONF_RDC contikimac_driver -#define NETSTACK_CONF_RADIO cc2420_driver -#define NETSTACK_CONF_FRAMER framer_802154 +#ifndef NETSTACK_CONF_NETWORK +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#endif + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +#ifndef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 +#endif + +#define NETSTACK_CONF_RADIO cc2420_driver /* Specify a minimum packet size for 6lowpan compression to be enabled. This is needed for ContikiMAC, which needs packets to be @@ -51,112 +67,141 @@ used. */ #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 -#define CC2420_CONF_AUTOACK 1 -#define NETSTACK_RDC_CHANNEL_CHECK_RATE 8 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 -#define CXMAC_CONF_ANNOUNCEMENTS 0 -#define XMAC_CONF_ANNOUNCEMENTS 0 +#define CC2420_CONF_AUTOACK 1 +#define NETSTACK_RDC_CHANNEL_CHECK_RATE 8 +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 -#define QUEUEBUF_CONF_NUM 4 +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +#endif #else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ +#ifndef NETSTACK_CONF_NETWORK +#define NETSTACK_CONF_NETWORK rime_driver +#endif -#define NETSTACK_CONF_NETWORK rime_driver -#define NETSTACK_CONF_MAC csma_driver -#define NETSTACK_CONF_RDC contikimac_driver +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +#ifndef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -#define NETSTACK_CONF_FRAMER contikimac_framer +#endif -#define CC2420_CONF_AUTOACK 1 +#define CC2420_CONF_AUTOACK 1 -#define COLLECT_CONF_ANNOUNCEMENTS 1 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 -#define CXMAC_CONF_ANNOUNCEMENTS 0 -#define XMAC_CONF_ANNOUNCEMENTS 0 -#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 +#define COLLECT_CONF_ANNOUNCEMENTS 1 +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 +#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 -#define CONTIKIMAC_CONF_COMPOWER 1 -#define XMAC_CONF_COMPOWER 1 -#define CXMAC_CONF_COMPOWER 1 +#define CONTIKIMAC_CONF_COMPOWER 1 +#define XMAC_CONF_COMPOWER 1 +#define CXMAC_CONF_COMPOWER 1 -#define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32 +#define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32 -#define QUEUEBUF_CONF_NUM 8 +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif #endif /* NETSTACK_CONF_WITH_IPV6 */ -#define PACKETBUF_CONF_ATTRS_INLINE 1 +#define PACKETBUF_CONF_ATTRS_INLINE 1 #ifdef RF_CHANNEL -#define CC2420_CONF_CHANNEL RF_CHANNEL +#define CC2420_CONF_CHANNEL RF_CHANNEL #endif #ifndef CC2420_CONF_CHANNEL -#define CC2420_CONF_CHANNEL 26 +#define CC2420_CONF_CHANNEL 26 #endif /* CC2420_CONF_CHANNEL */ #ifndef CC2420_CONF_CCA_THRESH -#define CC2420_CONF_CCA_THRESH -45 +#define CC2420_CONF_CCA_THRESH -45 #endif /* CC2420_CONF_CCA_THRESH */ -#define IEEE802154_CONF_PANID 0xABCD +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD +#endif /* The TSCH default slot length of 10ms is a bit too short for this platform, * use 15ms instead. */ +#ifndef TSCH_CONF_DEFAULT_TIMESLOT_LENGTH #define TSCH_CONF_DEFAULT_TIMESLOT_LENGTH 15000 +#endif -#define SHELL_VARS_CONF_RAM_BEGIN 0x1100 -#define SHELL_VARS_CONF_RAM_END 0x2000 +#define SHELL_VARS_CONF_RAM_BEGIN 0x1100 +#define SHELL_VARS_CONF_RAM_END 0x2000 -#define CFS_CONF_OFFSET_TYPE long +#define CFS_CONF_OFFSET_TYPE long -#define PROFILE_CONF_ON 0 -#define ENERGEST_CONF_ON 1 +#define PROFILE_CONF_ON 0 +#define ENERGEST_CONF_ON 1 -#define ELFLOADER_CONF_TEXT_IN_ROM 0 -#define ELFLOADER_CONF_DATAMEMORY_SIZE 0x400 -#define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x800 +#define ELFLOADER_CONF_TEXT_IN_ROM 0 +#define ELFLOADER_CONF_DATAMEMORY_SIZE 0x400 +#define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x800 #define AODV_COMPLIANCE -#define AODV_NUM_RT_ENTRIES 32 +#define AODV_NUM_RT_ENTRIES 32 -#define WITH_ASCII 1 +#define WITH_ASCII 1 -#define PROCESS_CONF_NUMEVENTS 8 -#define PROCESS_CONF_STATS 1 -/*#define PROCESS_CONF_FASTPOLL 4*/ +#define PROCESS_CONF_NUMEVENTS 8 +#define PROCESS_CONF_STATS 1 +/*#define PROCESS_CONF_FASTPOLL 4*/ #define UART0_CONF_TX_WITH_INTERRUPT 0 /* So far, printfs without interrupt. */ -#define UART0_CONF_RX_WITH_DMA 0 +#define UART0_CONF_RX_WITH_DMA 0 #ifdef NETSTACK_CONF_WITH_IPV6 -#define LINKADDR_CONF_SIZE 8 +#define LINKADDR_CONF_SIZE 8 -#define UIP_CONF_LL_802154 1 -#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 -#define UIP_CONF_ROUTER 1 +#define UIP_CONF_ROUTER 1 /* Handle 10 neighbors */ -#define NBR_TABLE_CONF_MAX_NEIGHBORS 15 -/* Handle 10 routes */ -#define UIP_CONF_MAX_ROUTES 15 +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 15 +#endif -#define UIP_CONF_ND6_SEND_RA 0 +/* Handle 10 routes */ +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 15 +#endif + +#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define NETSTACK_CONF_WITH_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_IP_FORWARD 0 -#define UIP_CONF_BUFFER_SIZE 140 + +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 140 +#endif #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG @@ -165,31 +210,33 @@ #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 #else /* NETSTACK_CONF_WITH_IPV6 */ -#define UIP_CONF_IP_FORWARD 1 -#define UIP_CONF_BUFFER_SIZE 108 +#define UIP_CONF_IP_FORWARD 1 + +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 108 +#endif + #endif /* NETSTACK_CONF_WITH_IPV6 */ -#define UIP_CONF_ICMP_DEST_UNREACH 1 +#define UIP_CONF_ICMP_DEST_UNREACH 1 #define UIP_CONF_DHCP_LIGHT -#define UIP_CONF_LLH_LEN 0 -#define UIP_CONF_RECEIVE_WINDOW 48 -#define UIP_CONF_TCP_MSS 48 -#define UIP_CONF_MAX_CONNECTIONS 4 -#define UIP_CONF_MAX_LISTENPORTS 8 -#define UIP_CONF_UDP_CONNS 12 -#define UIP_CONF_FWCACHE_SIZE 30 -#define UIP_CONF_BROADCAST 1 -#define UIP_ARCH_IPCHKSUM 1 -#define UIP_CONF_UDP 1 -#define UIP_CONF_UDP_CHECKSUMS 1 -#define UIP_CONF_PINGADDRCONF 0 -#define UIP_CONF_LOGGING 0 +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_RECEIVE_WINDOW 48 +#define UIP_CONF_TCP_MSS 48 +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 8 +#define UIP_CONF_UDP_CONNS 12 +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 -#define UIP_CONF_TCP_SPLIT 0 +#define UIP_CONF_TCP_SPLIT 0 -#ifdef PROJECT_CONF_H -#include PROJECT_CONF_H -#endif /* PROJECT_CONF_H */ +#define BOARD_STRING "Zolertia Z1 platform" #endif /* CONTIKI_CONF_H */ diff --git a/platform/z1/contiki-z1-main.c b/platform/z1/contiki-z1-main.c index 92a7b5bd7..c2c7e7caf 100644 --- a/platform/z1/contiki-z1-main.c +++ b/platform/z1/contiki-z1-main.c @@ -43,7 +43,6 @@ #include "lib/random.h" #include "net/netstack.h" #include "net/mac/frame802154.h" -#include "dev/button-sensor.h" #include "dev/adxl345.h" #include "sys/clock.h" @@ -58,12 +57,6 @@ #include "cfs/cfs-coffee.h" #include "sys/autostart.h" -#include "dev/battery-sensor.h" -#include "dev/button-sensor.h" -#include "dev/sht11/sht11-sensor.h" - -SENSORS(&button_sensor); - extern unsigned char node_mac[8]; #if DCOSYNCH_CONF_ENABLED @@ -104,7 +97,12 @@ static uint8_t is_gateway; #endif void init_platform(void); - +/*---------------------------------------------------------------------------*/ +#ifdef UART0_CONF_BAUD_RATE +#define UART0_BAUD_RATE UART0_CONF_BAUD_RATE +#else +#define UART0_BAUD_RATE 115200 +#endif /*---------------------------------------------------------------------------*/ #if 0 int @@ -202,9 +200,9 @@ main(int argc, char **argv) clock_wait(100); - uart0_init(BAUD2UBR(115200)); /* Must come before first printf */ + uart0_init(BAUD2UBR(UART0_BAUD_RATE)); /* Must come before first printf */ #if NETSTACK_CONF_WITH_IPV4 - slip_arch_init(BAUD2UBR(115200)); + slip_arch_init(BAUD2UBR(UART0_BAUD_RATE)); #endif /* NETSTACK_CONF_WITH_IPV4 */ xmem_init(); @@ -279,7 +277,7 @@ main(int argc, char **argv) set_rime_addr(); cc2420_init(); - accm_init(); + SENSORS_ACTIVATE(adxl345); { uint8_t longaddr[8]; diff --git a/platform/z1/dev/z1-sensors.c b/platform/z1/dev/z1-sensors.c new file mode 100644 index 000000000..db5b418b9 --- /dev/null +++ b/platform/z1/dev/z1-sensors.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Zolertia Z1 on-board sensors + * \author + * Antonio Lignan, Zolertia + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/tmp102.h" +#include "dev/adxl345.h" +/*---------------------------------------------------------------------------*/ +/** \brief Exports global symbols for the sensor API */ +SENSORS(&button_sensor, &adxl345, &tmp102); +/*---------------------------------------------------------------------------*/ diff --git a/platform/zoul/Makefile.zoul b/platform/zoul/Makefile.zoul index 49e6ed13b..cff7f11cf 100644 --- a/platform/zoul/Makefile.zoul +++ b/platform/zoul/Makefile.zoul @@ -4,18 +4,20 @@ ifndef CONTIKI $(error CONTIKI not defined! You must specify where CONTIKI resides!) endif -### If no board is specified the default option is the RE-Mote +### If no board is specified the default option is the RE-Mote revision B ifeq ($(BOARD),) - BOARD=remote + BOARD = remote-revb +endif + +### As previously the RE-Mote revision A was plainly defined as remote, keep for +### backward compatibility +ifeq ($(BOARD), remote) + override BOARD = remote-reva endif PYTHON = python BSL_FLAGS += -e -w -v -ifdef PORT - BSL_FLAGS += -p $(PORT) -endif - ### Configure the build for the board and pull in board-specific sources CONTIKI_TARGET_DIRS += . dev CONTIKI_TARGET_DIRS += . $(BOARD) @@ -26,7 +28,7 @@ PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) ### Include CONTIKI_TARGET_SOURCEFILES += contiki-main.c -CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c cc1200-zoul-arch.c +CONTIKI_TARGET_SOURCEFILES += leds.c cc1200-zoul-arch.c CONTIKI_TARGET_SOURCEFILES += adc-zoul.c button-sensor.c zoul-sensors.c CONTIKI_TARGET_SOURCEFILES += $(BOARD_SOURCEFILES) @@ -49,7 +51,7 @@ MODULES += core/net core/net/mac \ BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py -### USe the specific Zoul subplatform to query for connected devices +### Use the specific Zoul subplatform to query for connected devices ifdef MOTELIST_ZOLERTIA MOTELIST_FLAGS += -b $(MOTELIST_ZOLERTIA) endif @@ -57,28 +59,48 @@ endif ### Detect if a mote is connected over serial port ifeq ($(HOST_OS),Darwin) USBDEVPREFIX= - MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia-macos - MOTES = $(shell $(MOTELIST) -c 2>&- | cut -f 2 -d ,) - SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-macos + MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia-macos + MOTES := $(shell $(MOTELIST) -c 2>&- | cut -f 2 -d ,) + SERIALDUMP := $(CONTIKI)/tools/sky/serialdump-macos else ### If we are not running under Mac, we assume Linux USBDEVPREFIX= - SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux - MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia - MOTES = $(shell $(MOTELIST) -b $(MOTELIST_ZOLERTIA) -c 2>&- | cut -f 2 -d , | \ + SERIALDUMP := $(CONTIKI)/tools/sky/serialdump-linux + MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia + MOTES := $(shell $(MOTELIST) -b $(MOTELIST_ZOLERTIA) -c 2>&- | cut -f 2 -d , | \ perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') endif -%.upload: %.bin %.elf +### If PORT is defined, override to keep backward compatibility +ifdef PORT + MOTES := $(PORT) +endif + +### Check the BSL script exists ifeq ($(wildcard $(BSL)), ) +%.upload: @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" else - $(eval BSL_ADDRESS_ARG := -a $(shell $(OBJDUMP) -h $*.elf | grep -B1 LOAD | \ - grep -Ev 'LOAD|\-\-' | awk '{print "0x" $$5}' | \ - sort -g | head -1)) - $(PYTHON) $(BSL) $(BSL_FLAGS) $(BSL_ADDRESS_ARG) $< +### Upload to every MOTE +%.upload: $(foreach MOTE,$(MOTES),%.$(MOTE)) + @# Dummy recipe to prevent "No rule to make *.upload errors" endif +### Variable that expands into a pattern rule to upload to a given MOTE. +### Requires $(MOTE) to be defined +### $$$$ Double escapes $s that need to be passed to the shell - once for when make parses UPLOAD_RULE, and once for when the expanded rule is parsed by make. +define UPLOAD_RULE +%.$(MOTE): %.bin %.elf + @echo "Flashing $(MOTE)" + @BSL_ADDRESS=`$(OBJDUMP) -h $$*.elf | grep -B1 LOAD | \ + grep -Ev 'LOAD|\-\-' | awk '{print "0x" $$$$5}' | \ + sort -g | head -1`; \ + $(PYTHON) $(BSL) $(BSL_FLAGS) -a $$$${BSL_ADDRESS} -p $(MOTE) $$< +endef + +### Create an upload rule for every MOTE connected +$(foreach MOTE,$(MOTES),$(eval $(UPLOAD_RULE))) + motelist: $(MOTELIST) zoul-motelist: @@ -86,16 +108,8 @@ zoul-motelist: zoul-motes: @echo $(MOTES) -ifdef PORT -serialview: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX) $(PORT) | $(CONTIKI)/tools/timestamp - -login: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX) $(PORT) -else serialview: $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) | $(CONTIKI)/tools/timestamp login: $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) -endif diff --git a/platform/zoul/README.md b/platform/zoul/README.md index dc2960909..226e99ac5 100644 --- a/platform/zoul/README.md +++ b/platform/zoul/README.md @@ -252,10 +252,11 @@ If you prefer this guide in other formats, use the excellent [pandoc] to convert More Reading ============ 1. [Zolertia website][zolertia-site] -2. [CC2538 System-on-Chip Solution][cc2538] -3. [CC1200 sub-1GHz RF transceiver][cc1200] -4. [Zolertia Hackster channel][hackster] -5. [IoT in five days open source and online book][IoT5days] +2. [Zolertia Wiki page][zolertia-wiki] +3. [CC2538 System-on-Chip Solution][cc2538] +4. [CC1200 sub-1GHz RF transceiver][cc1200] +5. [Zolertia Hackster channel][hackster] +6. [IoT in five days open source and online book][IoT5days] Maintainers =========== @@ -263,6 +264,7 @@ The Zoul and derived platforms (as well as the Z1 mote) are maintained by Zolert Main contributor: Antonio Lignan [zolertia-site]: http://www.zolertia.io/products "Zolertia" +[zolertia-wiki]: https://github.com/Zolertia/Resources/wiki "Zolertia Wiki" [cc1200]: http://www.ti.com/product/cc1200 "CC1200" [smart-rf-studio]: http://www.ti.com/tool/smartrftm-studio "SmartRF Studio" [smart-rf-flashprog]: http://www.ti.com/tool/flash-programmer "SmartRF Flash Programmer" diff --git a/platform/zoul/contiki-conf.h b/platform/zoul/contiki-conf.h index 59463f691..bfe57994c 100644 --- a/platform/zoul/contiki-conf.h +++ b/platform/zoul/contiki-conf.h @@ -77,8 +77,6 @@ typedef uint32_t rtimer_clock_t; #define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) /** @} */ /*---------------------------------------------------------------------------*/ -#define TSCH_CONF_HW_FRAME_FILTERING 0 - /* 352us from calling transmit() until the SFD byte has been sent */ #define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(352)) /* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */ @@ -102,7 +100,16 @@ typedef uint32_t rtimer_clock_t; #define FLASH_CCA_CONF_BOOTLDR_BACKDOOR_ACTIVE_HIGH 0 /**< A logic low level activates the boot loader */ #endif /** @} */ - +/*---------------------------------------------------------------------------*/ +/** + * \name CC2538 System Control configuration + * + * @{ + */ +#ifndef SYS_CTRL_CONF_OSC32K_USE_XTAL +#define SYS_CTRL_CONF_OSC32K_USE_XTAL 1 /**< Use the on-board 32.768-kHz crystal */ +#endif +/** @} */ /*---------------------------------------------------------------------------*/ /** * \name CFS configuration @@ -190,10 +197,6 @@ typedef uint32_t rtimer_clock_t; #define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */ #endif -#ifndef CC2538_RF_CONF_SNIFFER_USB -#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */ -#endif - #ifndef DBG_CONF_USB #define DBG_CONF_USB 0 /**< All debugging over UART by default */ #endif @@ -208,12 +211,6 @@ typedef uint32_t rtimer_clock_t; #endif #endif -#if !CC2538_RF_CONF_SNIFFER_USB -#ifndef CC2538_RF_CONF_SNIFFER_UART -#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */ -#endif -#endif - #if !DBG_CONF_USB #ifndef DBG_CONF_UART #define DBG_CONF_UART 0 /**< UART to use for debugging */ @@ -240,15 +237,6 @@ typedef uint32_t rtimer_clock_t; #endif #endif -/* - * When set, the radio turns off address filtering and sends all captured - * frames down a peripheral (UART or USB, depending on the value of - * CC2538_RF_CONF_SNIFFER_USB) - */ -#ifndef CC2538_RF_CONF_SNIFFER -#define CC2538_RF_CONF_SNIFFER 0 -#endif - /** * \brief Define this as 1 to build a headless node. * @@ -269,12 +257,6 @@ typedef uint32_t rtimer_clock_t; #undef STARTUP_CONF_VERBOSE #define STARTUP_CONF_VERBOSE 0 - -/* Little sanity check: We can't have quiet sniffers */ -#if CC2538_RF_CONF_SNIFFER -#error "CC2538_RF_CONF_SNIFFER == 1 and CC2538_CONF_QUIET == 1" -#error "These values are conflicting. Please set either to 0" -#endif #endif /* CC2538_CONF_QUIET */ /** @@ -283,8 +265,7 @@ typedef uint32_t rtimer_clock_t; #ifndef USB_SERIAL_CONF_ENABLE #define USB_SERIAL_CONF_ENABLE \ ((SLIP_ARCH_CONF_USB & SLIP_ARCH_CONF_ENABLED) | \ - DBG_CONF_USB | \ - (CC2538_RF_CONF_SNIFFER & CC2538_RF_CONF_SNIFFER_USB)) + DBG_CONF_USB) #endif /* @@ -304,9 +285,6 @@ typedef uint32_t rtimer_clock_t; #define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \ !SLIP_ARCH_CONF_USB && \ SLIP_ARCH_CONF_UART == (u)) -#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \ - !CC2538_RF_CONF_SNIFFER_USB && \ - CC2538_RF_CONF_SNIFFER_UART == (u)) #define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u)) #define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u)) @@ -314,7 +292,6 @@ typedef uint32_t rtimer_clock_t; UART_CONF_ENABLE && \ (UART_IN_USE_BY_SERIAL_LINE(u) || \ UART_IN_USE_BY_SLIP(u) || \ - UART_IN_USE_BY_RF_SNIFFER(u) || \ UART_IN_USE_BY_DBG(u) || \ UART_IN_USE_BY_UART1(u)) \ ) @@ -481,7 +458,7 @@ typedef uint32_t rtimer_clock_t; /* Don't let contiki-default-conf.h decide if we are an IPv6 build */ #ifndef NETSTACK_CONF_WITH_IPV6 -#define NETSTACK_CONF_WITH_IPV6 0 +#define NETSTACK_CONF_WITH_IPV6 0 #endif #if NETSTACK_CONF_WITH_IPV6 @@ -520,7 +497,7 @@ typedef uint32_t rtimer_clock_t; #define UIP_CONF_ND6_RETRANS_TIMER 10000 #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 16 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 16 #endif #ifndef UIP_CONF_MAX_ROUTES #define UIP_CONF_MAX_ROUTES 16 diff --git a/platform/zoul/dev/ac-dimmer.c b/platform/zoul/dev/ac-dimmer.c new file mode 100644 index 000000000..47241ce33 --- /dev/null +++ b/platform/zoul/dev/ac-dimmer.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-ac-dimmer + * @{ + * + * \file + * Driver for the Krida Electronics AC light dimmer with zero-crossing, using + * a 50Hz frequency as reference (1/50Hz) ~20ms and 10ms half-cycle + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "ac-dimmer.h" +#include "dev/gpio.h" +#include "lib/sensors.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define DIMMER_SYNC_PORT_BASE GPIO_PORT_TO_BASE(DIMMER_SYNC_PORT) +#define DIMMER_SYNC_PIN_MASK GPIO_PIN_MASK(DIMMER_SYNC_PIN) +#define DIMMER_GATE_PORT_BASE GPIO_PORT_TO_BASE(DIMMER_GATE_PORT) +#define DIMMER_GATE_PIN_MASK GPIO_PIN_MASK(DIMMER_GATE_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +static uint8_t dimming; +/*---------------------------------------------------------------------------*/ +PROCESS(ac_dimmer_int_process, "AC Dimmer zero-cross interrupt process"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ac_dimmer_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + int dimtime; + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + dimtime = (uint8_t)(100 - dimming); + dimtime *= 100; + + /* Off cycle */ + clock_delay_usec(dimtime); + GPIO_SET_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + /* Triac on propagation delay */ + clock_delay_usec(DIMMER_DEFAULT_GATE_PULSE_US); + GPIO_CLR_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +dimmer_zero_cross_int_handler(uint8_t port, uint8_t pin) +{ + if((port == DIMMER_SYNC_PORT) && (pin == DIMMER_SYNC_PIN)) { + process_poll(&ac_dimmer_int_process); + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + return dimming; + case SENSORS_READY: + return enabled; + } + return DIMMER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + return DIMMER_ERROR; + } + + dimming = (uint8_t)type; + return DIMMER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return DIMMER_ERROR; + } + + if(value) { + /* This is the Triac's gate pin */ + GPIO_SOFTWARE_CONTROL(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + GPIO_SET_OUTPUT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + ioc_set_over(DIMMER_GATE_PORT, DIMMER_GATE_PIN, IOC_OVERRIDE_OE); + GPIO_CLR_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + + /* This is the zero-crossing pin and interrupt */ + GPIO_SOFTWARE_CONTROL(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + GPIO_SET_INPUT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + + /* Pull-up resistor, detect rising edge */ + GPIO_DETECT_EDGE(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + GPIO_DETECT_RISING(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + gpio_register_callback(dimmer_zero_cross_int_handler, DIMMER_SYNC_PORT, + DIMMER_SYNC_PIN); + + /* Spin process until an interrupt is received */ + process_start(&ac_dimmer_int_process, NULL); + + /* Enable interrupts */ + GPIO_ENABLE_INTERRUPT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + // ioc_set_over(DIMMER_SYNC_PORT, DIMMER_SYNC_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(DIMMER_INT_VECTOR); + + enabled = 1; + dimming = DIMMER_DEFAULT_START_VALUE; + return DIMMER_SUCCESS; + } + + /* Disable interrupt and pins */ + + GPIO_DISABLE_INTERRUPT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + GPIO_SET_INPUT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK); + GPIO_SET_OUTPUT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK); + process_exit(&ac_dimmer_int_process); + + enabled = 0; + dimming = 0; + return DIMMER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(ac_dimmer, AC_DIMMER_ACTUATOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/ac-dimmer.h b/platform/zoul/dev/ac-dimmer.h new file mode 100644 index 000000000..17d94b5b4 --- /dev/null +++ b/platform/zoul/dev/ac-dimmer.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-ac-dimmer AC light dimmer with zero-crossing driver + * + * Driver for an AC light dimmer with zero-crossing driver + * @{ + * + * \file + * Header file for an AC light dimmer with zero-crossing driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef AC_DIMMER_H_ +#define AC_DIMMER_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name AC dimmer default pins, ports and interrupt vector + * @{ + */ +#ifdef DIMMER_SYNC_CONF_PIN +#define DIMMER_SYNC_PIN DIMMER_SYNC_CONF_PIN +#else +#define DIMMER_SYNC_PIN 5 +#endif +#ifdef DIMMER_SYNC_CONF_PORT +#define DIMMER_SYNC_PORT DIMMER_SYNC_CONF_PORT +#else +#define DIMMER_SYNC_PORT GPIO_A_NUM +#endif +#ifdef DIMMER_GATE_CONF_PIN +#define DIMMER_GATE_PIN DIMMER_GATE_CONF_PIN +#else +#define DIMMER_GATE_PIN 4 +#endif +#ifdef DIMMER_GATE_CONF_PORT +#define DIMMER_GATE_PORT DIMMER_GATE_CONF_PORT +#else +#define DIMMER_GATE_PORT GPIO_A_NUM +#endif +#ifdef DIMMER_CONF_INT_VECTOR +#define DIMMER_INT_VECTOR DIMMER_CONF_INT_VECTOR +#else +#define DIMMER_INT_VECTOR NVIC_INT_GPIO_PORT_A +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name AC dimmer values + * @{ + */ +#define DIMMER_DEFAULT_START_VALUE 50 +#define DIMMER_DEFAULT_GATE_PULSE_US 15 +#define DIMMER_DEFAULT_MIN_DIMM_VALUE 10 +#define DIMMER_DEFAULT_MAX_DIMM_VALUE 80 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name AC dimmer return types + * @{ + */ +#define DIMMER_ERROR (-1) +#define DIMMER_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define AC_DIMMER_ACTUATOR "AC light dimmer zero-cross" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor ac_dimmer; +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +#endif /* RELAY_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 501eaa564..769e9d97c 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -66,7 +66,7 @@ #define ADC_WRAPPER_SUCCESS 0x00 #define ADC_WRAPPER_ERROR (-1) #define ADC_WRAPPER_EXTERNAL_VREF 5000 -#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3300 +#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3000 /*---------------------------------------------------------------------------*/ #define ANALOG_GROVE_LIGHT 0x01 #define ANALOG_PHIDGET_ROTATION_1109 0x02 diff --git a/platform/zoul/remote/antenna-sw.c b/platform/zoul/dev/antenna-sw.c similarity index 100% rename from platform/zoul/remote/antenna-sw.c rename to platform/zoul/dev/antenna-sw.c diff --git a/platform/zoul/remote/antenna-sw.h b/platform/zoul/dev/antenna-sw.h similarity index 100% rename from platform/zoul/remote/antenna-sw.h rename to platform/zoul/dev/antenna-sw.h diff --git a/platform/zoul/dev/dht22.c b/platform/zoul/dev/dht22.c new file mode 100644 index 000000000..f12859dff --- /dev/null +++ b/platform/zoul/dev/dht22.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-dht22 + * @{ + * + * \file + * Driver for the DHT22 temperature and humidity sensor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dht22.h" +#include "dev/gpio.h" +#include "lib/sensors.h" +#include "dev/ioc.h" +#include "dev/watchdog.h" +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define BUSYWAIT_UNTIL(max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) { \ + watchdog_periodic(); \ + } \ + } while(0) +/*---------------------------------------------------------------------------*/ +#define DHT22_PORT_BASE GPIO_PORT_TO_BASE(DHT22_PORT) +#define DHT22_PIN_MASK GPIO_PIN_MASK(DHT22_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +static uint8_t busy; +static uint8_t dht22_data[DHT22_BUFFER]; +/*---------------------------------------------------------------------------*/ +static int +dht22_read(void) +{ + uint8_t i; + uint8_t j = 0; + uint8_t last_state; + uint8_t counter = 0; + uint8_t checksum = 0; + + if(enabled) { + /* Exit low power mode and initialize variables */ + GPIO_SET_OUTPUT(DHT22_PORT_BASE, DHT22_PIN_MASK); + GPIO_SET_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + BUSYWAIT_UNTIL(DHT22_AWAKE_TIME); + memset(dht22_data, 0, DHT22_BUFFER); + + /* Initialization sequence */ + GPIO_CLR_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + BUSYWAIT_UNTIL(DHT22_START_TIME); + GPIO_SET_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + clock_delay_usec(DHT22_READY_TIME); + + /* Prepare to read, DHT22 should keep line low 80us, then 80us high. + * The ready-to-send-bit condition is the line kept low for 50us, then if + * the line is high between 24-25us the bit sent will be "0" (zero), else + * if the line is high between 70-74us the bit sent will be "1" (one). + */ + GPIO_SET_INPUT(DHT22_PORT_BASE, DHT22_PIN_MASK); + last_state = GPIO_READ_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + + for(i = 0; i < DHT22_MAX_TIMMING; i++) { + counter = 0; + while(GPIO_READ_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK) == last_state) { + counter++; + clock_delay_usec(DHT22_READING_DELAY); + + /* Exit if not responsive */ + if(counter == 0xFF) { + break; + } + } + + last_state = GPIO_READ_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + + /* Double check for stray sensor */ + if(counter == 0xFF) { + break; + } + + /* Ignore the first 3 transitions (the 80us x 2 start condition plus the + * first ready-to-send-bit state), and discard ready-to-send-bit counts + */ + if((i >= 4) && ((i % 2) == 0)) { + dht22_data[j / 8] <<= 1; + if(counter > DHT22_COUNT) { + dht22_data[j / 8] |= 1; + } + j++; + } + } + + for(i = 0; i < DHT22_BUFFER; i++) { + PRINTF("DHT22: (%u) %u\n", i, dht22_data[i]); + } + + /* If we have 5 bytes (40 bits), wrap-up and end */ + if(j >= 40) { + /* The first 2 bytes are humidity values, the next 2 are temperature, the + * final byte is the checksum + */ + checksum = dht22_data[0] + dht22_data[1] + dht22_data[2] + dht22_data[3]; + checksum &= 0xFF; + if(dht22_data[4] == checksum) { + GPIO_SET_INPUT(DHT22_PORT_BASE, DHT22_PIN_MASK); + GPIO_SET_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + return DHT22_SUCCESS; + } + PRINTF("DHT22: bad checksum\n"); + } + } + return DHT22_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +dht22_humidity(void) +{ + uint16_t res; + res = dht22_data[0]; + res *= 256; + res += dht22_data[1]; + busy = 0; + return res; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +dht22_temperature(void) +{ + uint16_t res; + res = dht22_data[2] & 0x7F; + res *= 256; + res += dht22_data[3]; + busy = 0; + return res; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if((type != DHT22_READ_HUM) && (type != DHT22_READ_TEMP) && + (type != DHT22_READ_ALL)) { + PRINTF("DHT22: Invalid type %u\n", type); + return DHT22_ERROR; + } + + if(busy) { + PRINTF("DHT22: ongoing operation, wait\n"); + return DHT22_BUSY; + } + + busy = 1; + + if(dht22_read() != DHT22_SUCCESS) { + PRINTF("DHT22: Fail to read sensor\n"); + GPIO_SET_INPUT(DHT22_PORT_BASE, DHT22_PIN_MASK); + GPIO_SET_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + busy = 0; + return DHT22_ERROR; + } + + switch(type) { + case DHT22_READ_HUM: + return dht22_humidity(); + case DHT22_READ_TEMP: + return dht22_temperature(); + case DHT22_READ_ALL: + return DHT22_SUCCESS; + default: + return DHT22_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +int +dht22_read_all(int *temperature, int *humidity) +{ + if((temperature == NULL) || (humidity == NULL)) { + PRINTF("DHT22: Invalid arguments\n"); + return DHT22_ERROR; + } + + if(value(DHT22_READ_ALL) != DHT22_ERROR) { + *temperature = dht22_temperature(); + *humidity = dht22_humidity(); + return DHT22_SUCCESS; + } + + /* Already cleaned-up in the value() function */ + return DHT22_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return DHT22_ERROR; + } + + GPIO_SOFTWARE_CONTROL(DHT22_PORT_BASE, DHT22_PIN_MASK); + GPIO_SET_INPUT(DHT22_PORT_BASE, DHT22_PIN_MASK); + ioc_set_over(DHT22_PORT, DHT22_PIN, IOC_OVERRIDE_OE); + GPIO_SET_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK); + + /* Restart flag */ + busy = 0; + + if(value) { + enabled = 1; + return DHT22_SUCCESS; + } + + enabled = 0; + return DHT22_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(dht22, DHT22_SENSOR, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/dht22.h b/platform/zoul/dev/dht22.h new file mode 100644 index 000000000..f75a96494 --- /dev/null +++ b/platform/zoul/dev/dht22.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-dht22 DHT22 temperature and humidity sensor + * + * Driver for the DHT22 temperature and humidity sensor + * @{ + * + * \file + * Header file for the DHT22 temperature and humidity sensor + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#ifndef DHT22_H_ +#define DHT22_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name DHT22 default pin and port + * @{ + */ +#ifdef DHT22_CONF_PIN +#define DHT22_PIN DHT22_CONF_PIN +#else +#define DHT22_PIN 5 +#endif +#ifdef DHT22_CONF_PORT +#define DHT22_PORT DHT22_CONF_PORT +#else +#define DHT22_PORT GPIO_A_NUM +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name DHT22 available commands + * @{ + */ +#define DHT22_READ_TEMP 0x01 +#define DHT22_READ_HUM 0x02 +#define DHT22_READ_ALL 0x03 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name DHT22 return types + * @{ + */ +#define DHT22_ERROR (-1) +#define DHT22_SUCCESS 0x00 +#define DHT22_BUSY 0xFF +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name DHT22 constants + * @{ + */ +#define DHT22_BUFFER 5 /**< Buffer to store the samples */ +#define DHT22_COUNT 8 /**< Minimum ticks to detect a "1" bit */ +#define DHT22_MAX_TIMMING 85 /**< Maximum ticks in a single operation */ +#define DHT22_READING_DELAY 1 /**< 1 us */ +#define DHT22_READY_TIME 20 /**< 40 us */ +#define DHT22_START_TIME (RTIMER_SECOND / 50) /**< 20 ms */ +#define DHT22_AWAKE_TIME (RTIMER_SECOND / 4) /**< 250 ms */ +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name DHT22 auxiliary functions + * @{ + */ +int dht22_read_all(int *temperature, int *humidity); +/** @} */ +/* -------------------------------------------------------------------------- */ +#define DHT22_SENSOR "DHT22 sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor dht22; +/* -------------------------------------------------------------------------- */ +#endif /* DHT22_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/pm10-sensor.h b/platform/zoul/dev/pm10-sensor.h index d43256e44..07f7811c1 100644 --- a/platform/zoul/dev/pm10-sensor.h +++ b/platform/zoul/dev/pm10-sensor.h @@ -52,7 +52,7 @@ #define PM10_SENSOR "PM10 Sensor" #define PM10_SENSOR_PULSE_DELAY 280 #define PM10_EXTERNAL_VREF 5000 -#define PM10_EXTERNAL_VREF_CROSSVAL 3300 +#define PM10_EXTERNAL_VREF_CROSSVAL 3000 /* -------------------------------------------------------------------------- */ #ifdef PM10_SENSOR_CONF_CTRL_PIN #define PM10_SENSOR_CTRL_PIN PM10_SENSOR_CONF_CTRL_PIN diff --git a/platform/zoul/remote/rtcc-config.h b/platform/zoul/dev/rtcc-config.h similarity index 100% rename from platform/zoul/remote/rtcc-config.h rename to platform/zoul/dev/rtcc-config.h diff --git a/platform/zoul/remote/rtcc.c b/platform/zoul/dev/rtcc.c similarity index 100% rename from platform/zoul/remote/rtcc.c rename to platform/zoul/dev/rtcc.c diff --git a/platform/zoul/remote/rtcc.h b/platform/zoul/dev/rtcc.h similarity index 100% rename from platform/zoul/remote/rtcc.h rename to platform/zoul/dev/rtcc.h diff --git a/platform/zoul/dev/servo.c b/platform/zoul/dev/servo.c new file mode 100644 index 000000000..2b08599a1 --- /dev/null +++ b/platform/zoul/dev/servo.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-servo + * @{ + * + * \file + * Driver for a generic Servo driver + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/pwm.h" +#include "dev/gpio.h" +#include "servo.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +int +servo_position(uint16_t gptab, uint8_t port, uint8_t pin, uint16_t pos) +{ + uint8_t gpt_num; + uint8_t gpt_ab; + uint32_t count = 0; + + if((gptab < SERVO_CHANNEL_1) && (gptab > SERVO_CHANNEL_7)) { + PRINTF("Servo: invalid servo channel\n"); + return SERVO_ERROR; + } + + /* CC2538 has 4 ports (A-D) and up to 8 pins (0-7) */ + if((port > GPIO_D_NUM) || (pin > 7)) { + PRINTF("Servo: Invalid pin/port settings\n"); + return SERVO_ERROR; + } + + if(pos > SERVO_MAX_DEGREES) { + PRINTF("Servo: invalid position (max %u)\n", SERVO_MAX_DEGREES); + return SERVO_ERROR; + } + + count = (SERVO_MAX_VAL - SERVO_MIN_VAL) * pos; + count /= SERVO_MAX_DEGREES; + count += SERVO_MIN_VAL; + + gpt_num = (uint8_t)(gptab >> 8); + gpt_ab = (uint8_t)(gptab & 0x00FF); + + PRINTF("Servo: F%uHz GPTNUM %u GPTAB %u --> %uº (%lu)\n", SERVO_DEFAULT_FREQ, + gpt_num, gpt_ab, + pos, count); + /* Use count as argument instead of percentage */ + if(pwm_enable(SERVO_DEFAULT_FREQ, 0, count, gpt_num,gpt_ab) != PWM_SUCCESS) { + PRINTF("Servo: failed to configure the pwm channel\n"); + return SERVO_ERROR; + } + + /* Start the PWM as soon as possible, keep the pulses to lock the servo in the + * given position + */ + if(pwm_start(gpt_num, gpt_ab, port, pin) != PWM_SUCCESS) { + PRINTF("Servo: failed to initialize the pwm channel\n"); + return SERVO_ERROR; + } + + return SERVO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +servo_stop(uint16_t gptab, uint8_t port, uint8_t pin) +{ + uint8_t gpt_num; + uint8_t gpt_ab; + + if((gptab < SERVO_CHANNEL_1) && (gptab > SERVO_CHANNEL_7)) { + PRINTF("Servo: invalid servo channel\n"); + return SERVO_ERROR; + } + + /* CC2538 has 4 ports (A-D) and up to 8 pins (0-7) */ + if((port > GPIO_D_NUM) || (pin > 7)) { + PRINTF("Servo: Invalid pin/port settings\n"); + return SERVO_ERROR; + } + + gpt_num = (uint8_t)((gptab & 0xFF00) >> 8); + gpt_ab = (uint8_t)(gptab & 0x00FF); + + if(pwm_disable(gpt_num, gpt_ab, port, pin) != PWM_SUCCESS) { + PRINTF("Servo: unable to disable the pwm channel\n"); + return SERVO_ERROR; + } + + return SERVO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/servo.h b/platform/zoul/dev/servo.h new file mode 100644 index 000000000..6ec2fae5f --- /dev/null +++ b/platform/zoul/dev/servo.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-servo Generic servo driver + * + * Driver for a Generic Servo actuator + * + * @{ + * + * \file + * Header file for a Generic Servo driver + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#ifndef SERVO_H_ +#define SERVO_H_ +#include +#include "dev/pwm.h" +/* -------------------------------------------------------------------------- */ +/** + * \name Servo default settings + * @{ + */ +/* -------------------------------------------------------------------------- */ +#ifndef SERVO_CONF_FREQ +#define SERVO_DEFAULT_FREQ 50 /**< 50 Hz */ +#else +#define SERVO_DEFAULT_FREQ SERVO_CONF_FREQ +#endif + +#ifndef SERVO_CONF_MAX_DEGREES +#define SERVO_MAX_DEGREES 180 +#else +#define SERVO_MAX_DEGREES SERVO_CONF_MAX_DEGREES +#endif + +#ifndef SERVO_CONF_MIN_VAL +#define SERVO_MIN_VAL 9600 /**> roughly equals to 3% duty cycle */ +#else +#define SERVO_MIN_VAL SERVO_CONF_MIN_VAL +#endif + +#ifndef SERVO_CONF_MAX_VAL +#define SERVO_MAX_VAL 38400 /**> roughly equals to 12% duty cycle */ +#else +#define SERVO_MAX_VAL SERVO_CONF_MAX_VAL +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Servo general purpose timers mapping + * @{ + */ +#define SERVO_CHANNEL_1 0x001 /**< GPT0-B */ +#define SERVO_CHANNEL_2 0x100 /**< GPT1-A */ +#define SERVO_CHANNEL_3 0x101 /**< GPT1-B */ +#define SERVO_CHANNEL_4 0x200 /**< GPT2-A */ +#define SERVO_CHANNEL_5 0x201 /**< GPT2-B */ +#define SERVO_CHANNEL_6 0x300 /**< GPT3-A */ +#define SERVO_CHANNEL_7 0x301 /**< GPT3-B */ +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Servo general constants + * @{ + */ +#define SERVO_SUCCESS 0 +#define SERVO_ERROR (-1) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Servo public funtions + * @{ + */ + +/** \brief Configures and positions a servo in a given position (by degrees) + * The servo will lock its position as long as it is not stopped + * \param gptab Servo channel (PWM GPT from 1-7) + * \param port Port number to use as PWM + * \param pin Pin number to use as PWM + * \param pos Position to map the servo to (0-360º, integer) + * \return \c SERVO_SUCCESS if successful, else \c SERVO_ERROR + */ +int servo_position(uint16_t gptab, uint8_t port, uint8_t pin, uint16_t pos); + +/** \brief Fully stop a servo and reconfigures back the pin/port as GPIO + * \param gptab Servo channel (PWM GPT from 1-7) + * \param port Port number to use as PWM + * \param pin Pin number to use as PWM + * \return \c SERVO_SUCCESS if successful, else \c SERVO_ERROR + */ +int servo_stop(uint16_t gptab, uint8_t port, uint8_t pin); +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/tmp102.c b/platform/zoul/dev/tmp102.c index 2d3e897e2..4b2de59b0 100644 --- a/platform/zoul/dev/tmp102.c +++ b/platform/zoul/dev/tmp102.c @@ -58,7 +58,8 @@ tmp102_read(uint16_t *data) if(i2c_single_send(TMP102_ADDR, TMP102_TEMP) == I2C_MASTER_ERR_NONE) { /* Read two bytes only */ if(i2c_burst_receive(TMP102_ADDR, buf, 2) == I2C_MASTER_ERR_NONE) { - temp = (buf[0] << 8) + buf[1]; + /* 12-bit value, TMP102 SBOS397F Table 8-9 */ + temp = (buf[0] << 4) + (buf[1] >> 4); if(temp > 2047) { temp -= (1 << 12); } diff --git a/platform/zoul/firefly/Makefile.firefly b/platform/zoul/firefly/Makefile.firefly index afecf9fa5..50cb71997 100644 --- a/platform/zoul/firefly/Makefile.firefly +++ b/platform/zoul/firefly/Makefile.firefly @@ -1,2 +1,2 @@ MOTELIST_ZOLERTIA = firefly -BOARD_SOURCEFILES += board.c +BOARD_SOURCEFILES += board.c leds-arch.c diff --git a/platform/zoul/images/remote-back.png b/platform/zoul/images/remote-reva-back.png similarity index 100% rename from platform/zoul/images/remote-back.png rename to platform/zoul/images/remote-reva-back.png diff --git a/platform/zoul/images/remote-front.png b/platform/zoul/images/remote-reva-front.png similarity index 100% rename from platform/zoul/images/remote-front.png rename to platform/zoul/images/remote-reva-front.png diff --git a/platform/zoul/images/remote-pinout-back.png b/platform/zoul/images/remote-reva-pinout-back.png similarity index 100% rename from platform/zoul/images/remote-pinout-back.png rename to platform/zoul/images/remote-reva-pinout-back.png diff --git a/platform/zoul/images/remote-pinout-front.png b/platform/zoul/images/remote-reva-pinout-front.png similarity index 100% rename from platform/zoul/images/remote-pinout-front.png rename to platform/zoul/images/remote-reva-pinout-front.png diff --git a/platform/zoul/remote-reva/Makefile.remote-reva b/platform/zoul/remote-reva/Makefile.remote-reva new file mode 100644 index 000000000..475208875 --- /dev/null +++ b/platform/zoul/remote-reva/Makefile.remote-reva @@ -0,0 +1,2 @@ +MOTELIST_ZOLERTIA = remote +BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c power-mgmt.c leds-arch.c diff --git a/platform/zoul/remote/README.md b/platform/zoul/remote-reva/README.md similarity index 90% rename from platform/zoul/remote/README.md rename to platform/zoul/remote-reva/README.md index c1f57a1fd..c61e8a2f1 100644 --- a/platform/zoul/remote/README.md +++ b/platform/zoul/remote-reva/README.md @@ -1,4 +1,4 @@ -Zolertia RE-Mote platform +Zolertia RE-Mote platform (revision A) ============================================ ![Zolertia RE-Mote development platform][remote-front] @@ -12,15 +12,15 @@ The RE-Mote platform was designed jointly with universities and industrial partn The RE-Mote features a Zoul as its core module and it is bundled with the following features: * ARM Cortex-M3 with 512KB flash and 32KB RAM (16KB retention), 32MHz. -* ISM 2.4-GHz IEEE 802.15.4 & Zigbee compliant. +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee/Thread compliant. * ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. * On-board RF switch to programatically select RF itnerfaces. Above RF interfaces can be used alternatively over a single RP-SMA connector for external antenna, or simultaneously by using an UFl pigtail or soldering an internal ceramic chip antenna (available on request). * AES-128/256, SHA2 Hardware Encryption Engine. * ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. -* Power consumption down to 300nA using our shutdown mode. +* Power consumption down to 170nA using our shutdown mode. * Programming over BSL without requiring to press any button to enter bootloader mode. * Built-in battery charger (500mA), Energy Harvesting and Solar Panels to be connected to standards LiPo batteries. -* Power input with wide range 3.7-26VDC. +* Power input with wide range 3.7-16VDC. * On-board micro USB connector for USB 2.0 applications. * RGB LED to allow more than 7 colour combinations. * On-board nano-watt Real Time Clock Calendar (RTCC). @@ -28,10 +28,11 @@ The RE-Mote features a Zoul as its core module and it is bundled with the follow * On-board Micro-SD for external storage. * On-board external Watchdog Timer (WDT) for resilient operation. * Small form-factor of 73x40 mm. +* Available with enclosure for indoor use The most prominent feature of the RE-Mote is its ultra low-power implementation, allowing a flexible and time/date-aware control of the platform operation modes by introducing a real-time clock (RTCC), nanowatt external timer, ultra-low power PIC governing the battery manager, etc. -The RE-Mote features an optional custom-made enclosure to fit most scenarios, allowing to easily connect sensors, actuators and rechargeable LiPo batteries. Its on-board RP-SMA antenna eliminates the need to mechanize an external antenna, allowing to alternatively use either a sub-1GHz or 2.4GHz antenna, or a multiband one. +The RE-Mote features an optional custom-made enclosure to fit most scenarios, allowing to easily connect sensors, actuators and rechargeable LiPo batteries. Its on-board RP-SMA antenna eliminates the need to mechanize an external antenna, allowing to alternatively use either a sub-1GHz or 2.4GHz antenna, or a multiband one. For dual band applications it is possible to use both sub-GHz and 2.4GHz interfaces simultaneously. The external WDT with battery monitor allows a robust and resilience operation for most critical applications. diff --git a/platform/zoul/remote/board.c b/platform/zoul/remote-reva/board.c similarity index 95% rename from platform/zoul/remote/board.c rename to platform/zoul/remote-reva/board.c index ad98f2fd0..ddf85ed86 100644 --- a/platform/zoul/remote/board.c +++ b/platform/zoul/remote-reva/board.c @@ -29,11 +29,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup remote + * \addtogroup remote-reva * @{ * * \file - * Board-initialisation for the Zolertia's RE-Mote platform + * Board-initialisation for the Zolertia's RE-Mote revision A platform * */ /*---------------------------------------------------------------------------*/ diff --git a/platform/zoul/remote/board.h b/platform/zoul/remote-reva/board.h similarity index 98% rename from platform/zoul/remote/board.h rename to platform/zoul/remote-reva/board.h index 2887f452a..338d6c8e1 100644 --- a/platform/zoul/remote/board.h +++ b/platform/zoul/remote-reva/board.h @@ -33,7 +33,7 @@ * \addtogroup zoul-platforms * @{ * - * \defgroup remote RE-Mote platform + * \defgroup remote-reva RE-Mote platform revision A * * The RE-Mote was designed jointly with universities and industry partners in * RERUM European project, to ease the development of private and secure @@ -42,7 +42,7 @@ * Shutdown mode to reduce its power consumption down to 300nA. * * This file provides connectivity information on LEDs, Buttons, UART and - * other RE-Mote peripherals + * other RE-Mote revision A peripherals * * This file can be used as the basis to configure other platforms using the * cc2538 SoC. @@ -50,7 +50,7 @@ * * \file * Header file with definitions related to the I/O connections on the Zolertia's - * RE-Mote platform, cc2538-based + * RE-Mote platform (revision A), cc2538-based * * \note Do not include this file directly. It gets included by contiki-conf * after all relevant directives have been set. @@ -485,7 +485,7 @@ * \name Device string used on startup * @{ */ -#define BOARD_STRING "Zolertia RE-Mote platform" +#define BOARD_STRING "Zolertia RE-Mote revision A platform" /** @} */ #endif /* BOARD_H_ */ diff --git a/platform/zoul/remote/power-mgmt.c b/platform/zoul/remote-reva/power-mgmt.c similarity index 100% rename from platform/zoul/remote/power-mgmt.c rename to platform/zoul/remote-reva/power-mgmt.c diff --git a/platform/zoul/remote/power-mgmt.h b/platform/zoul/remote-reva/power-mgmt.h similarity index 100% rename from platform/zoul/remote/power-mgmt.h rename to platform/zoul/remote-reva/power-mgmt.h diff --git a/platform/zoul/remote-revb/Makefile.remote-revb b/platform/zoul/remote-revb/Makefile.remote-revb new file mode 100644 index 000000000..34f526c65 --- /dev/null +++ b/platform/zoul/remote-revb/Makefile.remote-revb @@ -0,0 +1,2 @@ +MOTELIST_ZOLERTIA = remote +BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c leds-res-arch.c diff --git a/platform/zoul/remote-revb/README.md b/platform/zoul/remote-revb/README.md new file mode 100644 index 000000000..8b6095e24 --- /dev/null +++ b/platform/zoul/remote-revb/README.md @@ -0,0 +1,43 @@ +Zolertia RE-Mote platform (revision B) +============================================ + +The RE-Mote is a hardware development platform to build real IoT (Internet of Things) applications and products, aimed to high skilled developers as well as Makers (Do-It-Yourself enthusiasts) and early beginners, providing an industry-ready and resilient hardware solution for most Smart Cities, Home Comfort, eHealth and Industrial applications. The RE-Mote conciliates an ultra-low power consumption with a high performance design, meeting specifications of processing resources, security and resilient operation. + +The RE-Mote platform was designed jointly with universities and industrial partners from different countries in the context of RERUM European Project. + +The RE-Mote features a Zoul as its core module and it is bundled with the following features: + +* ARM Cortex-M3 with 512KB flash and 32KB RAM (16KB retention), 32MHz. +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee/Thread compliant. +* ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. +* On-board RF switch to programatically select RF itnerfaces. Above RF interfaces can be used alternatively over a single RP-SMA connector for external antenna, or simultaneously by using an UFl pigtail or soldering an internal ceramic chip antenna (available on request). +* AES-128/256, SHA2 Hardware Encryption Engine. +* ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. +* Power consumption down to 150nA using our shutdown mode. +* Programming over BSL without requiring to press any button to enter bootloader mode. +* Built-in battery charger (500mA), Energy Harvesting and Solar Panels to be connected to standards LiPo batteries. +* Power input with wide range 3.7-16VDC. +* On-board micro USB connector for USB 2.0 applications. +* RGB LED to allow more than 7 colour combinations. +* On-board nano-watt Real Time Clock Calendar (RTCC). +* User and Reset buttons. +* On-board Micro-SD for external storage. +* On-board external Watchdog Timer (WDT) for resilient operation. +* Small form-factor of 73x40 mm. +* Available with enclosure for indoor use + +The changes from Revision A to this new Revision B are summarized in the [Wiki](https://github.com/Zolertia/Resources/wiki/RE-Mote:-Enhancements-from-Rev.A-to-Rev.B) + +The most prominent feature of the RE-Mote is its ultra low-power implementation, allowing a flexible and time/date-aware control of the platform operation modes by using its real-time clock (RTCC) and an ultra-low power PIC governing the battery manager. + +The RE-Mote features an optional custom-made enclosure to fit most scenarios, allowing to easily connect sensors, actuators and rechargeable LiPo batteries. Its on-board RP-SMA antenna eliminates the need to mechanize an external antenna, allowing to alternatively use either a sub-1GHz or 2.4GHz antenna, or a multiband one. For dual band applications it is possible to use both sub-GHz and 2.4GHz interfaces simultaneously. + +The external WDT with battery monitor allows a robust and resilience operation for most critical applications. + +Zoul pin-out +============= + +![RE-Mote pin-out (front)][remote-pinout-front] +![RE-Mote pin-out (back)][remote-pinout-back] + + diff --git a/examples/cc2538-common/sniffer/sniffer.c b/platform/zoul/remote-revb/board.c similarity index 71% rename from examples/cc2538-common/sniffer/sniffer.c rename to platform/zoul/remote-revb/board.c index fe20b9c76..f3e39617c 100644 --- a/examples/cc2538-common/sniffer/sniffer.c +++ b/platform/zoul/remote-revb/board.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ * 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,45 +27,35 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*---------------------------------------------------------------------------*/ /** - * \addtogroup cc2538-examples - * @{ - * - * \defgroup cc2538-sniffer cc2538 Sniffer - * - * Sniffer for the CC2538-based platforms. Originally based on the sensinode - * and cc2530dk sniffers. - * - * 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 remote-revb * @{ * * \file - * Implementation of a Sniffer Process Thread + * Board-initialisation for the Zolertia's RE-Mote revision B platform + * */ -#include "contiki.h" - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" /*---------------------------------------------------------------------------*/ -PROCESS(sniffer_process, "Sniffer process"); -AUTOSTART_PROCESSES(&sniffer_process); +#include "contiki-conf.h" +#include "antenna-sw.h" +#include +#include /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(sniffer_process, ev, data) +static void +configure_unused_pins(void) { - - PROCESS_BEGIN(); - - PRINTF("Sniffer started\n"); - - PROCESS_EXIT(); - - PROCESS_END(); + /* FIXME */ +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + antenna_sw_config(); + configure_unused_pins(); } /*---------------------------------------------------------------------------*/ - /** - * @} * @} */ + diff --git a/platform/zoul/remote-revb/board.h b/platform/zoul/remote-revb/board.h new file mode 100644 index 000000000..783209e26 --- /dev/null +++ b/platform/zoul/remote-revb/board.h @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2016, Zolertia + * 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 zoul-platforms + * @{ + * + * \defgroup remote-revb RE-Mote platform revision B + * + * The RE-Mote was designed jointly with universities and industry partners in + * RERUM European project, to ease the development of private and secure + * applications for IoT and Smart City applications. The RE-Mote packs several + * on-board resources, like a RTC, external WDT, Micro-SD, RF switch and a + * Shutdown mode to reduce its power consumption down to 150nA. + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other RE-Mote revision A peripherals + * + * This file can be used as the basis to configure other platforms using the + * cc2538 SoC. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the Zolertia's + * RE-Mote platform (revision B), cc2538-based + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name Connector headers + * + * The RE-Mote features two 2.54 mm header rows over which exposes the following + * pins (facing up, Zolertia/RERUM logo above, buttons and micro USB at bottom): + * ----------------------+---+---+--------------------------------------------- + * PIN_NAME |JP6|JP5| PIN_NAME + * ----------------------+---+---+--------------------------------------------- + * LED1.R/PD4 |-01|17-| PB2/SPIO0.SCLK/CC1200.SCLK + * LED2.G/JTAG.TDO/PB7 |-02|16-| PB1/SPIO0.MOSI/CC1200.MOSI + * LED3.B/JTAG.TDI/PB6 |-03|15-| PB3/SPIO0.MISO/CC1200.MISO + * UART0.RX/PA0 |-04|14-| PA7/AIN7/USD.CS|ADC5 + * UART0.TX/PA1 |-05|13-| DGND + * PD0 |-06|12-| D+3.3 + * I2C.SDA/PC2 |-07|11-| PA5/AIN5/ADC1 + * I2C.SCL/PC3 |-08|10-| PA4/AIN4/ADC2 + * DGND |-09|09-| DGND + * D+3.3 |-10|08-| D+5.0 + * CC1200.GPIO0/PB4 |-11|07-| PA2/AIN2/ADC3 + * CC1200.GPIO2/PB0 |-12|06-| PA6/AIN6/USD.SEL|ADC4 + * UART1.RX/PC1 |-13|05-| PC6/SPI1.MISO + * UART1.TX/PC0 |-14|04-| PC5/SPI1.MOSI + * DGND |-15|03-| PC4/SPI1.SCLK + * D+3.3 |-16|02-| PS+EXT/VIN + * CC1200.CS/PB5 |-17|01-| DGND + * ----------------------+---+---+--------------------------------------------- + * + * Two auxiliary connectors allow to connect an external LiPo battery and + * access to the RESET/user buttons: + * + * - JP4 (placed below JP6 connector): |1-| DGND, |2-| VBAT + * - JP9 (placed above JP5 connector): |1-| BUTTON.RESET, |2-| BUTTON.USER|ADC6 + */ +/*---------------------------------------------------------------------------*/ +/** \name RE-Mote LED configuration + * + * LEDs on the RE-Mote are exposed in the JP6 port as follows: + * - LED1 (Red) -> PD4 + * - LED2 (Green) -> PB7 (shared with JTAG.TDO) + * - LED3 (Blue) -> PB6 (shared with JTAG.TDI) + * + * The LEDs are connected to a MOSFET to minimize current draw. The LEDs can + * be disabled by removing resistors R12, R13 and R14. + * @{ + */ +/*---------------------------------------------------------------------------*/ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_BLUE +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 /**< LED1 (Red) -> PD4 */ +#define LEDS_RED_PIN_MASK (1 << 4) +#define LEDS_RED_PORT_BASE GPIO_D_BASE + +#define LEDS_GREEN 2 /**< LED2 (Green) -> PB7 */ +#define LEDS_GREEN_PIN_MASK (1 << 7) +#define LEDS_GREEN_PORT_BASE GPIO_B_BASE + +#define LEDS_BLUE 4 /**< LED3 (Blue) -> PB6 */ +#define LEDS_BLUE_PIN_MASK (1 << 6) +#define LEDS_BLUE_PORT_BASE GPIO_B_BASE + +#define LEDS_CONF_ALL (LEDS_GREEN | LEDS_BLUE | LEDS_RED) /* 7 */ +#define LEDS_LIGHT_BLUE (LEDS_GREEN | LEDS_BLUE) /* 6 */ +#define LEDS_YELLOW (LEDS_GREEN | LEDS_RED) /* 3 */ +#define LEDS_PURPLE (LEDS_BLUE | LEDS_RED) /* 5 */ +#define LEDS_WHITE LEDS_ALL /* 7 */ + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup is enabled by an external resistor, not mapped to a GPIO + */ +#ifdef USB_PULLUP_PORT +#undef USB_PULLUP_PORT +#endif +#ifdef USB_PULLUP_PIN +#undef USB_PULLUP_PIN +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the RE-Mote, the UARTs are connected to the following ports/pins: + * + * - UART0: + * - RX: PA0, connected to CP2104 serial-to-usb converter TX pin + * - TX: PA1, connected to CP2104 serial-to-usb converter RX pin + * - UART1: + * - RX: PC1 + * - TX: PC0 + * - CTS: disabled as default, PD0 may be assigned if not using I2C interrupts + * - RTS: disabled as default + * + * We configure the port to use UART0 and UART1, CTS/RTS only for UART1, + * both without a HW pull-up resistor + * UART0 and UART1 pins are exposed over the JP6 connector + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_RX_PORT GPIO_C_NUM +#define UART1_RX_PIN 1 +#define UART1_TX_PORT GPIO_C_NUM +#define UART1_TX_PIN 0 +#define UART1_CTS_PORT (-1) +#define UART1_CTS_PIN (-1) +#define UART1_RTS_PORT (-1) +#define UART1_RTS_PIN (-1) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ADC configuration + * + * These values configure which CC2538 pins and ADC channels to use for the ADC + * inputs. By default the RE-Mote allows two out-of-the-box ADC ports with a + * phidget-like 3-pin connector (GND/VDD/ADC) + * + * The RE-Mote allows both 3.3V and 5V analogue sensors as follow: + * + * - ADC1 (PA5): up to 3.3V. + * - ADC2 (PA4): up to 3.3V + * - ADC3 (PA2): up to 5V, by means of a 2/3 voltage divider. + * + * Also there are other ADC channels shared by default with Micro SD card and + * user button implementations: + * + * - ADC4 (PA6): up to 3.3V. + * - ADC5 (PA7): up to 3.3V. + * - ADC6 (PA3): up to 3.3V. + * + * ADC inputs can only be on port A. + * All ADCx are exposed in JP5 connector, but only ADC1 and ADC3 have GND and + * VDD (3/5V) pins next to it, so these can be exposed into a 3-pin phidget-like + * connector, for ADC2 either solder a wire to connect, or use a 4-pin connector + * to expose both ADC1 and ADC2 in a single connector, but this will leave no + * space for a ADC3 connector. + * + * The internal ADC reference is 1190mV, use either a voltage divider as input, + * or a different voltage reference, like AVDD5, or externally using PA7/AIN7 + * and PA6/AIN6 configurable as differential reference, by removing the R26 and + * R33 0Ohm resistors to disconnect off the Micro-SD, and those will be + * accessible from JP5 connector. + * + * To enable the ADC[2,4-6], remove any 0Ohm resistors if required (see above), + * and define in your application `ADC_SENSORS_CONF_ADCx_PIN` and set its + * value with the corresponding pin number (i.e ADC2 to 4 as mapped to PA4). + * To disable any ADC[1-6] just define as above, but set to (-1) instead. + + * Warning: if using ADC6 (PA3), you will need to disable the bootloader by + * making FLASH_CCA_CONF_BOOTLDR_BACKDOOR equal to zero + * + * @{ + */ +#define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ + +#ifndef ADC_SENSORS_CONF_ADC1_PIN +#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5, 3V3 */ +#else +#if ((ADC_SENSORS_CONF_ADC1_PIN != -1) && (ADC_SENSORS_CONF_ADC1_PIN != 5)) +#error "ADC1 channel should be mapped to PA5 or disabled with -1" +#else +#define ADC_SENSORS_ADC1_PIN ADC_SENSORS_CONF_ADC1_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC3_PIN +#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2, 5V */ +#else +#if ((ADC_SENSORS_CONF_ADC3_PIN != -1) && (ADC_SENSORS_CONF_ADC3_PIN != 2)) +#error "ADC3 channel should be mapped to PA2 or disabled with -1" +#else +#define ADC_SENSORS_ADC3_PIN ADC_SENSORS_CONF_ADC3_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC2_PIN +#define ADC_SENSORS_ADC2_PIN (-1) /**< ADC2 no declared */ +#else +#define ADC_SENSORS_ADC2_PIN 4 /**< Hard-coded to PA4 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC4_PIN +#define ADC_SENSORS_ADC4_PIN (-1) /**< ADC4 not declared */ +#else +#define ADC_SENSORS_ADC4_PIN 6 /**< Hard-coded to PA6 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC5_PIN +#define ADC_SENSORS_ADC5_PIN (-1) /**< ADC5 not declared */ +#else +#define ADC_SENSORS_ADC5_PIN 7 /**< Hard-coded to PA7 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC6_PIN +#define ADC_SENSORS_ADC6_PIN (-1) /**< ADC6 not declared */ +#else +#define ADC_SENSORS_ADC6_PIN 3 /**< Hard-coded to PA3 */ +#endif + +#ifndef ADC_SENSORS_CONF_MAX +#define ADC_SENSORS_MAX 2 /**< Maximum sensors */ +#else +#define ADC_SENSORS_MAX ADC_SENSORS_CONF_MAX +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name RE-Mote Button configuration + * + * Buttons on the RE-Mote are connected as follows: + * - BUTTON_USER -> PA3, S1 user button, shared with bootloader + * - BUTTON_RESET -> RESET_N line, S2 reset the CC2538 + * - BUTTON_PWR -> Depending on the enabled resistor, it can be used to reset + * the onboard Low-power PIC, provoking a master reset on all + * the RE-Mote's onboards components. Note the BUTTON_RESET + * only resets the CC2538. This is disabled by default, as + * the R45 0Ohm resistor is not soldered on that position + * The other R45 position enables a test-button to drive the + * SYSOFF pin of the power management block, disconnecting the + * battery when used, leaving only powered the RTCC and + * Low-Power PIC. Useful if developing applications using the + * shutdown mode if required to snap out of it. + * @{ + */ +#define BUTTON_USER_PORT GPIO_A_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A + +/* Notify various examples that we have an user button. + * If ADC6 channel is used, then disable the user button + */ +#ifdef PLATFORM_CONF_WITH_BUTTON +#if (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) +#error "The ADC6 (PA3) and user button cannot be enabled at the same time" +#else +#define PLATFORM_HAS_BUTTON (PLATFORM_CONF_WITH_BUTTON && \ + !(ADC_SENSORS_ADC6_PIN == 3)) +#endif /* (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) */ +#else +#define PLATFORM_HAS_BUTTON !(ADC_SENSORS_ADC6_PIN == 3) +#endif /* PLATFORM_CONF_WITH_BUTTON */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI0) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI0) lines, + * reserved exclusively for the CC1200 RF transceiver. These pins are not + * exposed to any connector, and should be avoid to use it. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI0_CLK_PORT GPIO_B_NUM +#define SPI0_CLK_PIN 2 +#define SPI0_TX_PORT GPIO_B_NUM +#define SPI0_TX_PIN 1 +#define SPI0_RX_PORT GPIO_B_NUM +#define SPI0_RX_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines, + * shared with the microSD and exposed over JP5 connector. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI1_CLK_PORT GPIO_C_NUM +#define SPI1_CLK_PIN 4 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 5 +#define SPI1_RX_PORT GPIO_C_NUM +#define SPI1_RX_PIN 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * These values configure which CC2538 pins to use for the I2C lines, exposed + * over JP6 connector. + * The I2C bus is shared with the on-board RTC and the Low-Power PIC + * The I2C is exposed over the JP6 header, using a 5-pin connector with 2.54 mm + * spacing, providing also D+3.3V, GND and PD0 pin that can be used as an + * interrupt pin if required + * @{ + */ +#define I2C_SCL_PORT GPIO_C_NUM +#define I2C_SCL_PIN 3 +#define I2C_SDA_PORT GPIO_C_NUM +#define I2C_SDA_PIN 2 +#define I2C_INT_PORT GPIO_D_NUM +#define I2C_INT_PIN 0 +#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Antenna switch configuration + * + * These values configure the required pin to drive the RF antenna switch, to + * either enable the sub-1Ghz RF interface (power-up the CC1200) or the 2.4GHz + * RF interface of the CC2538, both alternatively routed to a RP-SMA connector + * to allow using an external antenna for both cases. + * + * Note it is also possible to enable both RF interfaces at the same time, by + * switching On the sub-1GHz RF interface, and placing an 0Ohm resistor (R19), + * to select between using a ceramic chip antenna (not mounted), or to connect + * and external antenna over a pigtail to the U.Fl connector (not mounted). + * + * RF switch state: + * - LOW: 2.4GHz RF interface on RP-SMA connector, CC1200 powered-off. + * - HIGH: Sub-1GHz RF interface on RP-SMA connector. + * @{ + */ +#define ANTENNA_RF_SW_PORT GPIO_D_NUM +#define ANTENNA_RF_SW_PIN 2 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Dual RF interface support + * + * Enables support for dual band operation (both CC1200 and 2.4GHz enabled). + * The driver checks the selected Radio stack, and forces the antenna switch to + * either position. Enabling the definition below forces to skip this check. + * @{ + */ +#define REMOTE_DUAL_RF_ENABLED 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC1200 configuration + * + * These values configure the required pins to drive the CC1200 + * None of the following pins are exposed to any connector, kept for internal + * use only + * @{ + */ +#define CC1200_SPI_INSTANCE 0 +#define CC1200_SPI_SCLK_PORT SPI0_CLK_PORT +#define CC1200_SPI_SCLK_PIN SPI0_CLK_PIN +#define CC1200_SPI_MOSI_PORT SPI0_TX_PORT +#define CC1200_SPI_MOSI_PIN SPI0_TX_PIN +#define CC1200_SPI_MISO_PORT SPI0_RX_PORT +#define CC1200_SPI_MISO_PIN SPI0_RX_PIN +#define CC1200_SPI_CSN_PORT GPIO_B_NUM +#define CC1200_SPI_CSN_PIN 5 +#define CC1200_GDO0_PORT GPIO_B_NUM +#define CC1200_GDO0_PIN 4 +#define CC1200_GDO2_PORT GPIO_B_NUM +#define CC1200_GDO2_PIN 0 +#define CC1200_RESET_PORT GPIO_C_NUM +#define CC1200_RESET_PIN 7 +#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name microSD configuration + * + * These values configure the required pins to drive the built-in microSD + * external module, to be used with SSI1. USD_CSN and USD_SEL are shared with + * ADC4/ADC5, but it is disabled by default as there are 0Ohm resistors + * connecting the PA6/PA7 pins to the microSD (see ADC block above for comments) + * The USD_SEL pin can be used both as output and input, to detect if there is + * a microSD in the slot, or when connected to disable the microSD to save power + * @{ + */ +#define USD_CLK_PORT SPI1_CLK_PORT +#define USD_CLK_PIN SPI1_CLK_PIN +#define USD_MOSI_PORT SPI1_TX_PORT +#define USD_MOSI_PIN SPI1_TX_PIN +#define USD_MISO_PORT SPI1_RX_PORT +#define USD_MISO_PIN SPI1_RX_PIN +#define USD_CSN_PORT GPIO_A_NUM +#define USD_CSN_PIN 7 +#define USD_SEL_PORT GPIO_A_NUM +#define USD_SEL_PIN 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Power management and shutdown mode + * + * The shutdown mode is an ultra-low power operation mode that effectively + * powers-down the entire RE-Mote (CC2538, CC1200, attached sensors, etc) and + * only keeps running a the on-board RTC and an ultra-low power consumption MCU + * The Shutdown mode allows: + * + * - Put the board in an ultra-low power sleep (shutdown) drawing <150nA avg. + * - Awake the system by scheduling the RTCC to awake the Low-Power PIC after + * it disconnects the battery and goes to sleep mode. + * - Awake the system by using the Low-Power PIC's timer + * + * As commented above, S3 can be used to restart the entire board (power + * management block included), or to kick the board out of shutdown mode by + * reconnecting the battery. + * @{ + */ +#define PM_ENABLE_PORT GPIO_D_NUM +#define PM_ENABLE_PIN 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name On-board RTCC + * + * The on-board RTCC (real time clock-calendar) is powered over USB/battery, + * and it will remain powered in shutdown mode with the Low-Power PIC. The + * RTC_INT1 is connected to the CC2538, so it is possible to receive interrupts + * from a pre-configured alarm, even waking up the CC2538 from PM3. + * A second interruption pin (RTC_INT2) is connected to the Low-Power PIC, after + * configuring the RTCC the Low-Power PIC can drive the board to shutdown mode, + * and enter into low-power mode (sleep), being the RTCC interrupt the waking up + * source to resume operation. + * + * @{ + */ +#define RTC_SDA_PORT I2C_SDA_PORT +#define RTC_SDA_PIN I2C_SDA_PIN +#define RTC_SCL_PORT I2C_SCL_PORT +#define RTC_SCL_PIN I2C_SCL_PIN +#define RTC_INT1_PORT GPIO_D_NUM +#define RTC_INT1_PIN 3 +#define RTC_INT1_VECTOR NVIC_INT_GPIO_PORT_D +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name On-board external WDT + * The RE-Mote features an on-board external WDT and battery monitor, which + * adds more robustness and prevents the mote to run wild if any unexpected + * problem shows-up. + * The external WDT requires a short pulse (<1ms) to be sent before a 2-second + * period. The battery monitor keeps the device in Reset if the voltage input + * is lower than 2.5V. + * The external WDT can be disabled by removing the R34 0Ohm resistor. + * As default the Texas Instrument's TPS3823 WDT is not mounted. + * Alternatively the testpoint or unused WDT's pad can be used to re-use as GPIO + * @{ + */ +#define EXT_WDT_PORT GPIO_D_NUM +#define EXT_WDT_PIN 5 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "Zolertia RE-Mote revision B platform" +/** @} */ + +#endif /* BOARD_H_ */ + +/** + * @} + * @} + */ diff --git a/platform/zoul/remote-revb/leds-res-arch.c b/platform/zoul/remote-revb/leds-res-arch.c new file mode 100644 index 000000000..59484c2ff --- /dev/null +++ b/platform/zoul/remote-revb/leds-res-arch.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, 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 zoul + * @{ + * + * \defgroup remote-revb-leds RE-Mote revision B arch LED + * + * LED driver implementation for the RE-Mote revision B + * @{ + * + * \file + * LED driver implementation for the RE-Mote revision B + */ +#include "contiki.h" +#include "reg.h" +#include "dev/leds.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define LEDS_PORTB_PIN_MASK (LEDS_GREEN_PIN_MASK | LEDS_BLUE_PIN_MASK) +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + /* Initialize LED2 (Green) and LED3 (Blue) */ + GPIO_SOFTWARE_CONTROL(GPIO_B_BASE, LEDS_PORTB_PIN_MASK); + GPIO_SET_OUTPUT(GPIO_B_BASE, LEDS_PORTB_PIN_MASK); + GPIO_CLR_PIN(GPIO_B_BASE, LEDS_PORTB_PIN_MASK); + + /* Initialize LED1 (Red) */ + GPIO_SOFTWARE_CONTROL(LEDS_RED_PORT_BASE, LEDS_RED_PIN_MASK); + GPIO_SET_OUTPUT(LEDS_RED_PORT_BASE, LEDS_RED_PIN_MASK); + GPIO_CLR_PIN(LEDS_RED_PORT_BASE, LEDS_RED_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + uint8_t mask_leds; + + mask_leds = GPIO_READ_PIN(LEDS_GREEN_PORT_BASE, LEDS_GREEN_PIN_MASK) == 0 ? 0: LEDS_GREEN; + mask_leds |= GPIO_READ_PIN(LEDS_BLUE_PORT_BASE, LEDS_BLUE_PIN_MASK) == 0 ? 0 : LEDS_BLUE; + mask_leds |= GPIO_READ_PIN(LEDS_RED_PORT_BASE, LEDS_RED_PIN_MASK) == 0 ? 0 : LEDS_RED; + + return mask_leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + if(leds & LEDS_GREEN) { + GPIO_SET_PIN(LEDS_GREEN_PORT_BASE, LEDS_GREEN_PIN_MASK); + } else { + GPIO_CLR_PIN(LEDS_GREEN_PORT_BASE, LEDS_GREEN_PIN_MASK); + } + + if(leds & LEDS_BLUE) { + GPIO_SET_PIN(LEDS_BLUE_PORT_BASE, LEDS_BLUE_PIN_MASK); + } else { + GPIO_CLR_PIN(LEDS_BLUE_PORT_BASE, LEDS_BLUE_PIN_MASK); + } + + if(leds & LEDS_RED) { + GPIO_SET_PIN(LEDS_RED_PORT_BASE, LEDS_RED_PIN_MASK); + } else { + GPIO_CLR_PIN(LEDS_RED_PORT_BASE, LEDS_RED_PIN_MASK); + } +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/remote/Makefile.remote b/platform/zoul/remote/Makefile.remote deleted file mode 100644 index 11f5ebe3a..000000000 --- a/platform/zoul/remote/Makefile.remote +++ /dev/null @@ -1,2 +0,0 @@ -MOTELIST_ZOLERTIA = remote -BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c power-mgmt.c diff --git a/regression-tests/01-compile-base/Makefile b/regression-tests/01-compile-base/Makefile index bc38a9777..83e5fda51 100644 --- a/regression-tests/01-compile-base/Makefile +++ b/regression-tests/01-compile-base/Makefile @@ -35,9 +35,7 @@ wget/minimal-net \ zolertia/z1/z1 \ settings-example/avr-raven \ ipv6/multicast/sky \ -ipv6/rpl-tsch/z1 \ -ipv6/rpl-tsch/z1:MAKE_WITH_ORCHESTRA=1 \ -ipv6/rpl-tsch/z1:MAKE_WITH_SECURITY=1 \ +sensniff/z1 \ cfs-coffee/sky \ cfs-coffee/z1 \ cfs-coffee/wismote \ diff --git a/regression-tests/11-ipv6/19-z1-rpl-tsch.csc b/regression-tests/11-ipv6/19-z1-rpl-tsch.csc.flaky similarity index 99% rename from regression-tests/11-ipv6/19-z1-rpl-tsch.csc rename to regression-tests/11-ipv6/19-z1-rpl-tsch.csc.flaky index 7488e8c3b..3a679a140 100644 --- a/regression-tests/11-ipv6/19-z1-rpl-tsch.csc +++ b/regression-tests/11-ipv6/19-z1-rpl-tsch.csc.flaky @@ -272,7 +272,7 @@ make node.z1 TARGET=z1 MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=0 /* Wait until a node (can only be the DAGRoot) has * 8 routing entries (i.e. can reach every node) */ log.log("Waiting for routing tables to fill\n"); -WAIT_UNTIL(msg.endsWith("Routing entries (8 in total):")); +WAIT_UNTIL(msg.endsWith("Routing links (8 in total):")); log.log("Root routing table ready\n"); log.testOK(); /* Report test success and quit */ diff --git a/regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc b/regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc.flaky similarity index 99% rename from regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc rename to regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc.flaky index 3fecd2040..9c8c19b5b 100644 --- a/regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc +++ b/regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc.flaky @@ -277,7 +277,7 @@ log.log("Orchestra started\n"); /* Wait until a node (can only be the DAGRoot) has * 8 routing entries (i.e. can reach every node) */ log.log("Waiting for routing tables to fill\n"); -WAIT_UNTIL(msg.endsWith("Routing entries (8 in total):")); +WAIT_UNTIL(msg.endsWith("Routing links (8 in total):")); log.log("Root routing table ready\n"); log.testOK(); /* Report test success and quit */ diff --git a/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc b/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc.flaky similarity index 99% rename from regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc rename to regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc.flaky index e2cda7e44..a5924fb88 100644 --- a/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc +++ b/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc.flaky @@ -274,7 +274,7 @@ log.log("Waiting for association with security\n"); /* Wait until a node (can only be the DAGRoot) has * 8 routing entries (i.e. can reach every node) */ log.log("Waiting for routing tables to fill\n"); -WAIT_UNTIL(msg.endsWith("Routing entries (8 in total):")); +WAIT_UNTIL(msg.endsWith("Routing links (8 in total):")); log.log("Root routing table ready\n"); log.testOK(); /* Report test success and quit */ diff --git a/regression-tests/14-compile-8051-ports/Makefile b/regression-tests/14-compile-8051-ports/Makefile index 974e74df2..2d1cce6c8 100644 --- a/regression-tests/14-compile-8051-ports/Makefile +++ b/regression-tests/14-compile-8051-ports/Makefile @@ -6,8 +6,8 @@ hello-world/cc2530dk \ cc2530dk/cc2530dk \ cc2530dk/border-router/cc2530dk \ cc2530dk/udp-ipv6/cc2530dk \ -cc2530dk/sniffer/cc2530dk \ ipv6/multicast/cc2530dk \ +sensniff/cc2530dk \ TOOLS= diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index e0addfa9f..a7547cd59 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -6,7 +6,6 @@ hello-world/ev-aducrf101mkxz \ ipv6/rpl-border-router/ev-aducrf101mkxz \ webserver-ipv6/ev-aducrf101mkxz \ ipv6/multicast/ev-aducrf101mkxz \ -cc2538-common/sniffer/ev-aducrf101mkxz \ cc26xx/cc26xx-web-demo/srf06-cc26xx \ cc26xx/very-sleepy-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ @@ -24,12 +23,10 @@ cc2538dk/cc2538dk \ cc2538dk/udp-ipv6-echo-server/cc2538dk \ ipv6/multicast/cc2538dk \ cc2538-common/cc2538dk \ -cc2538-common/sniffer/cc2538dk \ cc2538-common/mqtt-demo/cc2538dk \ cc2538-common/crypto/cc2538dk \ cc2538-common/pka/cc2538dk \ cc2538-common/zoul \ -cc2538-common/sniffer/zoul \ cc2538-common/mqtt-demo/zoul \ cc2538-common/crypto/zoul \ cc2538-common/pka/zoul \ @@ -47,9 +44,19 @@ stm32nucleo-spirit1/sensor-demo/stm32nucleo-spirit1 \ ipv6/multicast/stm32nucleo-spirit1 \ udp-ipv6/stm32nucleo-spirit1 \ hello-world/stm32nucleo-spirit1 \ +sensniff/cc2538dk \ +sensniff/openmote-cc2538 \ +sensniff/zoul \ +sensniff/zoul:ZOUL_CONF_SUB_GHZ_SNIFFER=1 \ +sensniff/srf06-cc26xx \ +sensniff/srf06-cc26xx:BOARD=launchpad/cc1310 \ +sensniff/ev-aducrf101mkxz \ cfs-coffee/cc2538dk \ cfs-coffee/openmote-cc2538 \ -cfs-coffee/zoul +cfs-coffee/zoul \ +ipv6/rpl-tsch/zoul \ +ipv6/rpl-tsch/zoul:MAKE_WITH_ORCHESTRA=1 \ +ipv6/rpl-tsch/zoul:MAKE_WITH_SECURITY=1 TOOLS= diff --git a/regression-tests/22-compile-nxp-ports/Makefile b/regression-tests/22-compile-nxp-ports/Makefile index 9291cd846..e1a56fe0b 100644 --- a/regression-tests/22-compile-nxp-ports/Makefile +++ b/regression-tests/22-compile-nxp-ports/Makefile @@ -16,6 +16,7 @@ jn516x/tsch/simple-sensor-network/rpl-border-router/jn516x \ jn516x/tsch/tx-power-verification/node/jn516x \ jn516x/tsch/tx-power-verification/rpl-border-router/jn516x \ jn516x/tsch/uart1-test-node/jn516x \ +sensniff/jn516x \ ipv6/rpl-tsch/jn516x \ ipv6/rpl-tsch/jn516x:MAKE_WITH_ORCHESTRA=1 \ ipv6/rpl-tsch/jn516x:MAKE_WITH_SECURITY=1 diff --git a/tools/6502/Makefile b/tools/6502/Makefile index d88a4790f..76837fe1d 100644 --- a/tools/6502/Makefile +++ b/tools/6502/Makefile @@ -31,10 +31,6 @@ # Author: Oliver Schmidt # -ifndef CONTIKI - ${error CONTIKI not defined! You must specify where Contiki resides} -endif - ifndef AC ${error AC not defined! You must specify where the AppleCommander jar resides} endif @@ -48,6 +44,7 @@ ifndef DIR2ATR endif all: apple2 atari c64 c128 +clean: apple2-clean atari-clean c64-clean c128-clean ifeq ($(shell echo),) NULLDEV = /dev/null @@ -65,26 +62,33 @@ endif CC65 := $(shell cl65 --print-target-path) define makes -$1-makes: - $(MAKE) -C ../../cpu/6502/ethconfig TARGET=$1 - $(MAKE) -C ../../cpu/6502/ipconfig TARGET=$1 - $(MAKE) -C ../../examples/webbrowser TARGET=$1 - $(MAKE) -C ../../examples/webbrowser-80col TARGET=$1 - $(MAKE) -C ../../examples/wget TARGET=$1 - $(MAKE) -C ../../examples/irc TARGET=$1 - $(MAKE) -C ../../examples/irc-80col TARGET=$1 - $(MAKE) -C ../../examples/webserver TARGET=$1 HTTPD-CFS=1 - $(MAKE) -C ../../examples/telnet-server TARGET=$1 +.PHONY: $1-$2makes +$1-$2makes: + $(MAKE) -C ../../cpu/6502/ethconfig TARGET=$1 $2 + $(MAKE) -C ../../cpu/6502/ipconfig TARGET=$1 $2 + $(MAKE) -C ../../examples/webbrowser TARGET=$1 $2 + $(MAKE) -C ../../examples/webbrowser-80col TARGET=$1 $2 + $(MAKE) -C ../../examples/wget TARGET=$1 $2 + $(MAKE) -C ../../examples/irc TARGET=$1 $2 + $(MAKE) -C ../../examples/irc-80col TARGET=$1 $2 + $(MAKE) -C ../../examples/webserver TARGET=$1 HTTPD-CFS=1 $2 + $(MAKE) -C ../../examples/telnet-server TARGET=$1 $2 endef $(eval $(call makes,apple2enh)) +$(eval $(call makes,apple2enh,clean)) %.zip: zip $@ $^ echo $(ZIPCOMMENT) | zip -z $@ +.PHONY: apple2 apple2-clean atari atari-clean c64 c64-clean c128 c128-clean + apple2: contiki-apple2.zip +apple2-clean: apple2enh-cleanmakes + rm -f contiki-apple2.zip contiki-apple2-1.dsk contiki-apple2-2.dsk contiki-apple2-3.dsk contiki-apple2.po + contiki-apple2.zip: contiki-apple2-1.dsk contiki-apple2-2.dsk contiki-apple2-3.dsk contiki-apple2.po contiki-apple2-1.dsk: apple2enh-makes @@ -168,9 +172,13 @@ contiki-apple2.po: apple2enh-makes java -jar $(AC) -p $@ notfound.htm bin 0 < ../../examples/webserver/httpd-cfs/notfound.htm $(eval $(call makes,atarixl)) +$(eval $(call makes,atarixl,clean)) atari: contiki-atari.zip +atari-clean: atarixl-cleanmakes + rm -f contiki-atari.zip contiki-atari-1.atr contiki-atari-2.atr contiki-atari-3.atr contiki-atari.atr + contiki-atari.zip: contiki-atari-1.atr contiki-atari-2.atr contiki-atari-3.atr contiki-atari.atr contiki-atari-1.atr: atarixl-makes @@ -252,9 +260,13 @@ contiki-atari.atr: atarixl-makes rm -r atr $(eval $(call makes,c64)) +$(eval $(call makes,c64,clean)) c64: contiki-c64.zip +c64-clean: c64-cleanmakes + rm -f contiki-c64.zip contiki-c64-1.d64 contiki-c64-2.d64 contiki-c64-3.d64 contiki-c64.d71 contiki-c64.d81 + contiki-c64.zip: contiki-c64-1.d64 contiki-c64-2.d64 contiki-c64-3.d64 contiki-c64.d71 contiki-c64.d81 contiki-c64-1.d64: c64-makes @@ -351,9 +363,13 @@ contiki-c64.d81: c64-makes $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s >$(NULLDEV) $(eval $(call makes,c128)) +$(eval $(call makes,c128,clean)) c128: contiki-c128.zip +c128-clean: c128-cleanmakes + rm -f contiki-c128.zip contiki-c128-1.d64 contiki-c128-2.d64 contiki-c128.d71 contiki-c128.d81 + contiki-c128.zip: contiki-c128-1.d64 contiki-c128-2.d64 contiki-c128.d71 contiki-c128.d81 contiki-c128-1.d64: c128-makes diff --git a/tools/cc2538-bsl b/tools/cc2538-bsl index c6100a779..6185d8b16 160000 --- a/tools/cc2538-bsl +++ b/tools/cc2538-bsl @@ -1 +1 @@ -Subproject commit c6100a7794c7b530923145c03e37412013a4551e +Subproject commit 6185d8b16f10047053fd57000a552340273d7d85 diff --git a/tools/zolertia/motelist-zolertia b/tools/zolertia/motelist-zolertia index e286887ac..75b95b3b9 100755 --- a/tools/zolertia/motelist-zolertia +++ b/tools/zolertia/motelist-zolertia @@ -57,6 +57,8 @@ if( $Opt{board} eq "z1" ) { $Opt{board} = "Zolertia Z1"; } elsif( $Opt{board} eq "remote" ) { $Opt{board} = "Zolertia RE-Mote platform"; +} elsif( $Opt{board} eq "firefly" ) { + $Opt{board} = "Zolertia Firefly platform"; } my @devs = $Opt{method} eq "procfs" ? scan_procfs() : scan_sysfs();