From 02091b083aca19cdcd198faf65b77fbaa1dd7c54 Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 11 Mar 2011 13:47:47 -0500 Subject: [PATCH 01/27] MAC address to EEMEM, not PROGMEM Sync atmega128rfa1 main routine to the raven (timed route prints, etc.) --- platform/avr-atmega128rfa1/contiki-main.c | 266 +++++++++++++++------- platform/avr-raven/contiki-raven-main.c | 2 +- 2 files changed, 185 insertions(+), 83 deletions(-) diff --git a/platform/avr-atmega128rfa1/contiki-main.c b/platform/avr-atmega128rfa1/contiki-main.c index a607b6700..7253707c8 100644 --- a/platform/avr-atmega128rfa1/contiki-main.c +++ b/platform/avr-atmega128rfa1/contiki-main.c @@ -30,16 +30,15 @@ * * @(#)$$ */ +#define LED_ON_PORTE1 0 //for Michael Hartman's prototype board #define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) #define DEBUG 0 #if DEBUG -#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#define PRINTSHORT(FORMAT,args...) printf_P(PSTR(FORMAT),##args) - +#define PRINTFD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) #else -#define PRINTF(...) -#define PRINTSHORT(...) +#define PRINTFD(...) #endif #include @@ -120,7 +119,7 @@ extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via mak extern uint8_t server_name[16]; extern uint8_t domain_name[30]; #else -uint8_t mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; +uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; #endif @@ -173,13 +172,17 @@ void initialize(void) { watchdog_init(); watchdog_start(); - -#ifdef RAVEN_LCD_INTERFACE + +#if !LED_ON_PORTE1 //Conflicts with USART0 +#if RAVEN_LCD_INTERFACE /* First rs232 port for Raven 3290 port */ - //conflicts with led on Hartmann's board, so bypass for now -// rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); + rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Set input handler for 3290 port */ -// rs232_set_input(0,raven_lcd_serial_input); + rs232_set_input(0,raven_lcd_serial_input); +#else + //Slip border router on uart0 + rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); +#endif #endif /* Second rs232 port for debugging */ @@ -188,14 +191,29 @@ void initialize(void) rs232_redirect_stdout(RS232_PORT_1); clock_init(); -#define CONF_CALIBRATE_OSCCAL 1 +#if STACKMONITOR + /* Simple stack pointer highwater monitor. Checks for magic numbers in the main + * loop. In conjuction with TESTRTIMER, never-used stack will be printed + * every STACKMONITOR seconds. + */ +{ +extern uint16_t __bss_end; +uint16_t p=(uint16_t)&__bss_end; + do { + *(uint16_t *)p = 0x4242; + p+=10; + } while (p //#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) // delay_us(50000); @@ -205,7 +223,7 @@ uint8_t i; #endif #if ANNOUNCE_BOOT - printf_P(PSTR("\n*******Booting %s*******\n"),CONTIKI_VERSION_STRING); + PRINTF("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); #endif watchdog_start(); /* rtimers needed for radio cycling */ @@ -240,7 +258,7 @@ uint8_t i; rimeaddr_set_node_addr(&addr); - PRINTF("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); + PRINTFD("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); /* Initialize stack protocols */ queuebuf_init(); @@ -249,19 +267,19 @@ uint8_t i; NETSTACK_NETWORK.init(); #if ANNOUNCE_BOOT - printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); + PRINTF("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac unsigned short tmp; tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ NETSTACK_RDC.channel_check_interval()); - if (tmp<65535) printf_P(PSTR(", check rate %u Hz"),tmp); + if (tmp<65535) PRINTF(", check rate %u Hz",tmp); } - printf_P(PSTR("\n")); + PRINTF("\n"); #endif #if UIP_CONF_ROUTER #if ANNOUNCE_BOOT - printf_P(PSTR("Routing Enabled\n")); + PRINTF("Routing Enabled\n"); #endif // rime_init(rime_udp_init(NULL)); // uip_router_register(&rimeroute); @@ -289,13 +307,13 @@ uint8_t i; #if COFFEE_FILES int fa = cfs_open( "/index.html", CFS_READ); if (fa<0) { //Make some default web content - printf_P(PSTR("No index.html file found, creating upload.html!\n")); - printf_P(PSTR("Formatting FLASH file system for coffee...")); + PRINTF("No index.html file found, creating upload.html!\n"); + PRINTF("Formatting FLASH file system for coffee..."); cfs_coffee_format(); - printf_P(PSTR("Done!\n")); + PRINTF("Done!\n"); fa = cfs_open( "/index.html", CFS_WRITE); int r = cfs_write(fa, &"It works!", 9); - if (r<0) printf_P(PSTR("Can''t create /index.html!\n")); + if (r<0) PRINTF("Can''t create /index.html!\n"); cfs_close(fa); // fa = cfs_open("upload.html"), CFW_WRITE); //
@@ -323,29 +341,29 @@ uint8_t i; for (i=0;i>10); + PRINTF(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10); #elif COFFEE_FILES==3 - printf_P(PSTR(".%s online with static %u byte program memory file system\n"),buf,size); + PRINTF(".%s online with static %u byte program memory file system\n",buf,size); #elif COFFEE_FILES==4 - printf_P(PSTR(".%s online with dynamic %u KB program memory file system\n"),buf,size>>10); + PRINTF(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); #endif /* COFFEE_FILES */ #else - printf_P(PSTR("Online\n")); + PRINTF("Online\n"); #endif /* WEBSERVER */ #endif /* ANNOUNCE_BOOT */ @@ -354,17 +372,22 @@ uint8_t i; /*---------------------------------------------------------------------------*/ void log_message(char *m1, char *m2) { - printf_P(PSTR("%s%s\n"), m1, m2); + PRINTF("%s%s\n", m1, m2); } -/* Test rtimers, also useful for pings and time stamps in simulator */ -#define TESTRTIMER 0 +/* Test rtimers, also for pings, stack monitor, neighbor/route printout and time stamps */ +#define TESTRTIMER 1 #if TESTRTIMER -#define PINGS 60 +//#define PINGS 64 +#define ROUTES 64 #define STAMPS 30 +#define STACKMONITOR 128 + uint8_t rtimerflag=1; uint16_t rtime; struct rtimer rt; void rtimercycle(void) {rtimerflag=1;} +static void ipaddr_add(const uip_ipaddr_t *addr); + #endif /* TESTRTIMER */ #if RF230BB @@ -379,85 +402,140 @@ uint16_t ledtimer; int main(void) { -#define CONFIG_STACK_MONITOR 1 -#if CONFIG_STACK_MONITOR -extern uint16_t __bss_end; - __bss_end = 0x4242; - *(uint16_t *)(&__bss_end+100) = 0x4242; -#endif initialize(); +#if LED_ON_PORTE1 /* NB: PORTE1 conflicts with UART0 */ - DDRE|=(1<>16)); -#endif - } +#if STAMPS +if ((rtime%STAMPS)==0) { + PRINTF("%us ",rtime); +} #endif rtime+=1; + #if PINGS - if ((rtime%PINGS)==0) { - PRINTF("**Ping\n"); - raven_ping6(); - } +if ((rtime%PINGS)==1) { + PRINTF("**Ping\n"); + raven_ping6(); +} #endif + +#if ROUTES +if ((rtime%ROUTES)==2) { + + //#if UIP_CONF_IPV6_RPL +//#include "rpl.h" +extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; +extern uip_ds6_route_t uip_ds6_routing_table[]; +extern uip_ds6_netif_t uip_ds6_if; + + uint8_t i,j; + PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); + for (i=0;i"); + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { + if(uip_ds6_routing_table[i].isused) { + ipaddr_add(&uip_ds6_routing_table[i].ipaddr); + PRINTF("/%u (via ", uip_ds6_routing_table[i].length); + ipaddr_add(&uip_ds6_routing_table[i].nexthop); + // if(uip_ds6_routing_table[i].state.lifetime < 600) { + PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime); + // } else { + // PRINTF(")\n"); + // } + j=0; + } + } + if (j) PRINTF(" "); + PRINTF("\n---------\n"); +} #endif +#if STACKMONITOR +if ((rtime%STACKMONITOR)==3) { + extern uint16_t __bss_end; + uint16_t p=(uint16_t)&__bss_end; + do { + if (*(uint16_t *)p != 0x4242) { + PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); + break; + } + p+=10; + } while (pu8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) PRINTF("::"); + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTF(":"); + } + PRINTF("%x",a); + } + } +} +#endif diff --git a/platform/avr-raven/contiki-raven-main.c b/platform/avr-raven/contiki-raven-main.c index fe9f482e7..722d90bc8 100644 --- a/platform/avr-raven/contiki-raven-main.c +++ b/platform/avr-raven/contiki-raven-main.c @@ -130,7 +130,7 @@ extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via mak extern uint8_t server_name[16]; extern uint8_t domain_name[30]; #else -uint8_t mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; +uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; #endif From 6a5c8ff1c43fcd7ff227bd08b283f1d3d34d28d8 Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 11 Mar 2011 14:10:30 -0500 Subject: [PATCH 02/27] Include file needed for slip rpl-border-router build --- cpu/avr/dev/uart1.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 cpu/avr/dev/uart1.h diff --git a/cpu/avr/dev/uart1.h b/cpu/avr/dev/uart1.h new file mode 100644 index 000000000..69b96e574 --- /dev/null +++ b/cpu/avr/dev/uart1.h @@ -0,0 +1,31 @@ +/* + Copied from mc1322x/dev/cpu. + + This file exists as a work-around for the hardware dependant calls + to slip_arch_init. + + Current the prototype for slip_arch_init is slip_arch_init(urb) + + and a typical call is something like + slip_arch_init(BAUD2URB(115200)) + + BAUD2UBR is hardware specific, however. Furthermore, for the sky + platform it's typically defined with #include "dev/uart1.h" (see + rpl-boarder-router/slip-bridge.c), a sky specific file. dev/uart1.h + includes msp430.h which includes the sky contiki-conf.h which + defines BAUD2UBR. + + To me, the correct think to pass is simply the baudrate and have the + hardware specific conversion happen inside slip_arch_init. + + Notably, most implementations just ignore the passed parameter + anyway. (except AVR) + + */ + +#ifndef DEV_UART1_H +#define DEV_UART1_H + +#define BAUD2UBR(x) x + +#endif From e4fcd7ebd791fc13c52a9cd3a5ef43b79ccda5c3 Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 11 Mar 2011 14:16:27 -0500 Subject: [PATCH 03/27] Add files needed for slip rpl-border-router build. --- platform/avr-atmega128rfa1/button-sensor.c | 45 +++++++++++ platform/avr-atmega128rfa1/slip_uart0.c | 93 ++++++++++++++++++++++ platform/avr-raven/Makefile.avr-raven | 4 +- platform/avr-raven/button-sensor.c | 45 +++++++++++ platform/avr-raven/slip_uart0.c | 93 ++++++++++++++++++++++ 5 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 platform/avr-atmega128rfa1/button-sensor.c create mode 100644 platform/avr-atmega128rfa1/slip_uart0.c create mode 100644 platform/avr-raven/button-sensor.c create mode 100644 platform/avr-raven/slip_uart0.c diff --git a/platform/avr-atmega128rfa1/button-sensor.c b/platform/avr-atmega128rfa1/button-sensor.c new file mode 100644 index 000000000..4daf2237e --- /dev/null +++ b/platform/avr-atmega128rfa1/button-sensor.c @@ -0,0 +1,45 @@ +/* Dummy sensor routine */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" +const struct sensors_sensor button_sensor; +static int status(int type); +struct sensors_sensor *sensors[1]; +unsigned char sensors_flags[1]; + + +static int +value(int type) +{ + return 0; +} + +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + } + } else { + } + return 1; + } + return 0; +} + +static int +status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return 1; + } + return 0; +} + +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + value, configure, status); + diff --git a/platform/avr-atmega128rfa1/slip_uart0.c b/platform/avr-atmega128rfa1/slip_uart0.c new file mode 100644 index 000000000..bf36616ad --- /dev/null +++ b/platform/avr-atmega128rfa1/slip_uart0.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010, University of Colombo School of Computing + * 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 + * Machine dependent AVR SLIP routines for UART0. + * \author + * Kasun Hewage + */ + +#include +#include "contiki.h" +#include "dev/rs232.h" +#include "slip.h" + +/*---------------------------------------------------------------------------*/ +static int +slip_putchar(char c, FILE *stream) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if (!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + slip_arch_writeb((unsigned char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if (c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + + return c; +} +/*---------------------------------------------------------------------------*/ +static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL, + _FDEV_SETUP_WRITE); +/*---------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + rs232_set_input(RS232_PORT_0, slip_input_byte); + stdout = &slip_stdout; +} +/*---------------------------------------------------------------------------*/ +/* + XXX: + Currently, the following function is in cpu/avr/dev/rs232.c file. this + should be moved to here from there hence this is a platform specific slip + related function. +void +slip_arch_writeb(unsigned char c) +{ + rs232_send(RS232_PORT_0, c); +} +*/ diff --git a/platform/avr-raven/Makefile.avr-raven b/platform/avr-raven/Makefile.avr-raven index c9ce84473..4b26db519 100644 --- a/platform/avr-raven/Makefile.avr-raven +++ b/platform/avr-raven/Makefile.avr-raven @@ -4,7 +4,9 @@ CONTIKI_CORE=contiki-raven-main CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o CONTIKI_TARGET_SOURCEFILES += contiki-raven-main.c contiki-raven-default-init-net.c #The avr cpu makefile will also add these files if COFFEE_FILES is specified. -CONTIKI_TARGET_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c +#CONTIKI_TARGET_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c +#Needed for slip +CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c CONTIKIAVR=$(CONTIKI)/cpu/avr CONTIKIBOARD=. diff --git a/platform/avr-raven/button-sensor.c b/platform/avr-raven/button-sensor.c new file mode 100644 index 000000000..4daf2237e --- /dev/null +++ b/platform/avr-raven/button-sensor.c @@ -0,0 +1,45 @@ +/* Dummy sensor routine */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" +const struct sensors_sensor button_sensor; +static int status(int type); +struct sensors_sensor *sensors[1]; +unsigned char sensors_flags[1]; + + +static int +value(int type) +{ + return 0; +} + +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + } + } else { + } + return 1; + } + return 0; +} + +static int +status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return 1; + } + return 0; +} + +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + value, configure, status); + diff --git a/platform/avr-raven/slip_uart0.c b/platform/avr-raven/slip_uart0.c new file mode 100644 index 000000000..bf36616ad --- /dev/null +++ b/platform/avr-raven/slip_uart0.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010, University of Colombo School of Computing + * 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 + * Machine dependent AVR SLIP routines for UART0. + * \author + * Kasun Hewage + */ + +#include +#include "contiki.h" +#include "dev/rs232.h" +#include "slip.h" + +/*---------------------------------------------------------------------------*/ +static int +slip_putchar(char c, FILE *stream) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if (!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + slip_arch_writeb((unsigned char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if (c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + + return c; +} +/*---------------------------------------------------------------------------*/ +static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL, + _FDEV_SETUP_WRITE); +/*---------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + rs232_set_input(RS232_PORT_0, slip_input_byte); + stdout = &slip_stdout; +} +/*---------------------------------------------------------------------------*/ +/* + XXX: + Currently, the following function is in cpu/avr/dev/rs232.c file. this + should be moved to here from there hence this is a platform specific slip + related function. +void +slip_arch_writeb(unsigned char c) +{ + rs232_send(RS232_PORT_0, c); +} +*/ From 97a71fea76188de7568287d7e423ba5ae581ed96 Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 11 Mar 2011 15:07:15 -0500 Subject: [PATCH 04/27] Conditional inclusion of the internal webserver --- examples/ipv6/rpl-border-router/border-router.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index 6373d1e95..c2cc8973e 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -45,8 +45,11 @@ #include "net/netstack.h" #include "dev/button-sensor.h" #include "dev/slip.h" +#define INTERNAL_WEBSERVER 1 +#if INTERNAL_WEBSERVER #include "webserver-nogui.h" #include "httpd-simple.h" +#endif #include #include #include @@ -65,6 +68,7 @@ static uint8_t prefix_set; PROCESS(border_router_process, "Border router process"); AUTOSTART_PROCESSES(&border_router_process); +#if INTERNAL_WEBSERVER /*---------------------------------------------------------------------------*/ /* Only one single web request at time */ static const char *TOP = "ContikiRPL\n"; @@ -169,6 +173,7 @@ print_local_addresses(void) } } } +#endif /* INTERNAL_WEBSERVER */ /*---------------------------------------------------------------------------*/ void request_prefix(void) @@ -201,8 +206,9 @@ PROCESS_THREAD(border_router_process, ev, data) prefix_set = 0; PROCESS_PAUSE(); - +#if INTERNAL_WEBSERVER process_start(&webserver_nogui_process, NULL); +#endif SENSORS_ACTIVATE(button_sensor); PRINTF("RPL-Border router started\n"); @@ -219,8 +225,9 @@ PROCESS_THREAD(border_router_process, ev, data) rpl_set_prefix(dag, &prefix, 64); PRINTF("created a new RPL dag\n"); } - +#if INTERNAL_WEBSERVER print_local_addresses(); +#endif /* The border router runs with a 100% duty cycle in order to ensure high packet reception rates. */ From abf6f1a153f5957eab654592dc8b7babaac04c09 Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 11 Mar 2011 15:08:55 -0500 Subject: [PATCH 05/27] Include objects needed for slip rpl border router build --- platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 index 9e8b7ea75..d845dd61f 100644 --- a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 +++ b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 @@ -3,6 +3,8 @@ CONTIKI_TARGET_DIRS = . apps net loader CONTIKI_CORE=contiki-main CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o CONTIKI_TARGET_SOURCEFILES += contiki-main.c +#Needed for slip +CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c CONTIKIAVR=$(CONTIKI)/cpu/avr CONTIKIBOARD=. From c9671500382c43988cef01fcd423e625225ddea6 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Fri, 11 Mar 2011 15:53:13 -0500 Subject: [PATCH 06/27] add rtc support --- lib/include/rtc.h | 57 +++++++++++++ lib/rtc.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 lib/include/rtc.h create mode 100644 lib/rtc.c diff --git a/lib/include/rtc.h b/lib/include/rtc.h new file mode 100644 index 000000000..cda1d60cb --- /dev/null +++ b/lib/include/rtc.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#ifndef RTC_H +#define RTC_H + +/* Init RTC (and calibrate, if using ring oscillator) */ +void rtc_init_osc(int use_32khz); + +#ifdef USE_32KHZ +#define rtc_init() rtc_init_osc(USE_32KHZ) +#else +#define rtc_init() rtc_init_osc(0) +#endif + +/* Calibrate the ring oscillator */ +void rtc_calibrate(void); + +/* Delay for the specified number of milliseconds by polling RTC */ +void rtc_delay_ms(uint32_t msec); + +/* Calibrated frequency of the RTC, in Hz */ +extern int rtc_freq; + +#endif diff --git a/lib/rtc.c b/lib/rtc.c new file mode 100644 index 000000000..383384c38 --- /dev/null +++ b/lib/rtc.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#include +#include +#include "rtc.h" + +/* Define USE_32KHZ in board.h to start and use the 32 KHz + oscillator, otherwise the 2 KHz ring oscillator is used. */ + +int rtc_freq = 0; +static int __use_32khz = 0; + +/* Init RTC */ +void rtc_init_osc(int use_32khz) +{ + __use_32khz = use_32khz; + + if (use_32khz) + { + uint32_t old; + + /* You have to hold its hand with this one */ + /* once you start the 32KHz crystal it can only be + * stopped with a reset (hard or soft). */ + + /* first, disable the ring osc */ + CRM->RINGOSC_CNTLbits.ROSC_EN = 0; + + /* enable the 32kHZ crystal */ + CRM->XTAL32_CNTLbits.XTAL32_EN = 1; + + /* set the XTAL32_EXISTS bit */ + /* the datasheet says to do this after you check that RTC_COUNT + is changing, but it is not correct; it needs to be set first */ + CRM->SYS_CNTLbits.XTAL32_EXISTS = 1; + + old = CRM->RTC_COUNT; + while (CRM->RTC_COUNT == old) + continue; + + /* RTC has started up */ + rtc_freq = 32000; + } + else + { + /* Enable ring osc */ + CRM->RINGOSC_CNTLbits.ROSC_EN = 1; + CRM->XTAL32_CNTLbits.XTAL32_EN = 0; + + /* Set default tune values from datasheet */ + CRM->RINGOSC_CNTLbits.ROSC_CTUNE = 0x6; + CRM->RINGOSC_CNTLbits.ROSC_FTUNE = 0x17; + + /* Trigger calibration */ + rtc_calibrate(); + } +} + +uint32_t __rtc_try(int loading, int timeout) +{ + /* Total loading is + ctune * 1000 fF + ftune * 160 fF + ctune = 0-15 + ftune = 0-31 + max = 19960 fF + */ + +#define RTC_LOADING_MIN 0 +#define RTC_LOADING_MAX 19960 + + /* The fine tune covers a range larger than a single coarse + step. Check all coarse steps within the fine tune range to + find the optimal CTUNE, FTUNE pairs. */ +#define CTUNE_MAX 15 +#define FTUNE_MAX 31 +#define CSTEP 1000 +#define FSTEP 160 +#define MAX_F (FSTEP*FTUNE_MAX) /* actually lcm(CSTEP,FSTEP) would be better, + but in this case it's basically the same */ + int ctune; + int ftune; + int ctune_start = (loading - MAX_F) / CSTEP; + int ctune_end = loading / CSTEP; + int best_err = loading, best_ctune = 0, best_ftune = 0; + + uint32_t count; + + if (ctune_start < 0) ctune_start = 0; + if (ctune_end > CTUNE_MAX) ctune_end = CTUNE_MAX; + + for (ctune = ctune_start; ctune <= ctune_end; ctune++) + { + int this_loading, this_err; + + ftune = ((loading - (ctune * CSTEP)) + (FSTEP / 2)) / FSTEP; + if (ftune < 0) ftune = 0; + if (ftune > FTUNE_MAX) ftune = FTUNE_MAX; + + this_loading = ctune * CSTEP + ftune * FSTEP; + this_err = abs(this_loading - loading); + if (this_err < best_err) { + best_err = this_err; + best_ctune = ctune; + best_ftune = ftune; + } + } + +// printf("requested loading %d, actual loading %d\r\n", loading, +// best_ctune * CSTEP + best_ftune * FSTEP); + + /* Run the calibration */ + CRM->RINGOSC_CNTLbits.ROSC_CTUNE = best_ctune; + CRM->RINGOSC_CNTLbits.ROSC_FTUNE = best_ftune; + CRM->CAL_CNTLbits.CAL_TIMEOUT = timeout; + CRM->STATUSbits.CAL_DONE = 1; + CRM->CAL_CNTLbits.CAL_EN = 1; + while (CRM->STATUSbits.CAL_DONE == 0) + continue; + + /* Result should ideally be close to (REF_OSC * (timeout / 2000)) */ + count = CRM->CAL_COUNT; + if (count == 0) count = 1; /* avoid divide by zero problems */ + return count; +} + +/* Calibrate the ring oscillator */ +void rtc_calibrate(void) +{ + /* Just bisect a few times. Our best tuning accuracy is about + 1/500 of the full scale, so doing this 8-9 times is about + as accurate as we can get */ + int i; + int low = RTC_LOADING_MIN, high = RTC_LOADING_MAX; + int mid; + uint32_t count; + + if (__use_32khz) { + rtc_freq = 32000; + return; + } + +#define TIMEOUT 100 /* 50 msec per attempt */ + + for (i = 0; i < 9; i++) + { + mid = (low + high) / 2; + count = __rtc_try(mid, TIMEOUT); + // careful about overflow + rtc_freq = REF_OSC / ((count + TIMEOUT/2) / TIMEOUT); + + if (rtc_freq > 2000) + low = mid; // increase loading + else + high = mid; // decrease loading + } + +// printf("RTC calibrated to %d Hz\r\n", rtc_freq); +} + + +/* Delay for the specified number of milliseconds by polling RTC */ +void rtc_delay_ms(uint32_t msec) +{ + uint32_t start; + + start = CRM->RTC_COUNT; + while ((CRM->RTC_COUNT - start) < ((msec * rtc_freq) / 1000)) + continue; +} From c7dc2a45a45134334096a794a5b779346ef6c61d Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Fri, 11 Mar 2011 15:55:32 -0500 Subject: [PATCH 07/27] add pwm support --- lib/include/pwm.h | 67 ++++++++++++ lib/pwm.c | 254 ++++++++++++++++++++++++++++++++++++++++++++++ tests/Makefile | 4 +- tests/pwm.c | 85 ++++++++++++++++ 4 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 lib/include/pwm.h create mode 100644 lib/pwm.c create mode 100644 tests/pwm.c diff --git a/lib/include/pwm.h b/lib/include/pwm.h new file mode 100644 index 000000000..65cfe1616 --- /dev/null +++ b/lib/include/pwm.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#ifndef PWM_H +#define PWM_H + +/* Initialize PWM output. + timer_num = 0, 1, 2, 3 + rate = desired rate in Hz, + duty = desired duty cycle. 0=always off, 65536=always on. + enable_timer = whether to actually run the timer, versus just configuring it + Returns actual PWM rate. */ +uint32_t pwm_init_ex(int timer_num, uint32_t rate, uint32_t duty, int enable_timer); + +/* Initialize PWM output, helper macros + timer = TMR0, TMR1, TMR2, TMR2 + rate = desired rate in Hz, + duty = desired duty cycle. 0=always off, 65536=always on. + Returns actual PWM rate. */ +#define pwm_init(timer,rate,duty) pwm_init_ex(TMR_NUM(timer), rate, duty, 1) +#define pwm_init_stopped(timer,rate,duty) pwm_init_ex(TMR_NUM(timer), rate, duty, 0) + +/* Change duty cycle. Safe to call at any time. + timer_num = 0, 1, 2, 3 + duty = desired duty cycle. 0=always off, 65536=always on. +*/ +void pwm_duty_ex(int timer_num, uint32_t duty); + +/* Change duty cycle. Safe to call at any time. + timer = TMR0, TMR1, TMR2, TMR2 + duty = desired duty cycle. 0=always off, 65536=always on. +*/ +#define pwm_duty(timer,duty) pwm_duty_ex(TMR_NUM(timer), duty) + +#endif diff --git a/lib/pwm.c b/lib/pwm.c new file mode 100644 index 000000000..8ee8f2eb1 --- /dev/null +++ b/lib/pwm.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#include +#include +#include "pwm.h" + +static struct { + uint32_t period; + uint32_t guard; + uint32_t pad_forced; +} pwm_info[4]; + +static inline void pad_set_output(int timer_num) { // set to output (when in GPIO mode) + switch (timer_num) { + case 0: GPIO->DATA_SEL.TMR0_PIN = 1; GPIO->PAD_DIR.TMR0_PIN = 1; break; + case 1: GPIO->DATA_SEL.TMR1_PIN = 1; GPIO->PAD_DIR.TMR1_PIN = 1; break; + case 2: GPIO->DATA_SEL.TMR2_PIN = 1; GPIO->PAD_DIR.TMR2_PIN = 1; break; + case 3: GPIO->DATA_SEL.TMR3_PIN = 1; GPIO->PAD_DIR.TMR3_PIN = 1; break; + default: break; + } +} + +static inline void pad_set_zero(int timer_num) { // set to zero in GPIO mode + switch (timer_num) { + case 0: GPIO->DATA_RESET.TMR0_PIN = 1; GPIO->FUNC_SEL.TMR0_PIN = 0; break; + case 1: GPIO->DATA_RESET.TMR1_PIN = 1; GPIO->FUNC_SEL.TMR1_PIN = 0; break; + case 2: GPIO->DATA_RESET.TMR2_PIN = 1; GPIO->FUNC_SEL.TMR2_PIN = 0; break; + case 3: GPIO->DATA_RESET.TMR3_PIN = 1; GPIO->FUNC_SEL.TMR3_PIN = 0; break; + default: break; + } +} + +static inline void pad_set_one(int timer_num) { // set to one in GPIO mode + switch (timer_num) { + case 0: GPIO->DATA_SET.TMR0_PIN = 1; GPIO->FUNC_SEL.TMR0_PIN = 0; break; + case 1: GPIO->DATA_SET.TMR1_PIN = 1; GPIO->FUNC_SEL.TMR1_PIN = 0; break; + case 2: GPIO->DATA_SET.TMR2_PIN = 1; GPIO->FUNC_SEL.TMR2_PIN = 0; break; + case 3: GPIO->DATA_SET.TMR3_PIN = 1; GPIO->FUNC_SEL.TMR3_PIN = 0; break; + default: break; + } +} + +static inline void pad_set_normal(int timer_num) { // set to TMR OFLAG output + switch (timer_num) { + case 0: GPIO->FUNC_SEL.TMR0_PIN = 1; break; + case 1: GPIO->FUNC_SEL.TMR1_PIN = 1; break; + case 2: GPIO->FUNC_SEL.TMR2_PIN = 1; break; + case 3: GPIO->FUNC_SEL.TMR3_PIN = 1; break; + default: break; + } +} + +/* Initialize PWM output. + timer_num = 0, 1, 2, 3 + rate = desired rate in Hz, + duty = desired duty cycle. 0=always off, 65536=always on. + enable_timer = whether to actually run the timer, versus just configuring it + Returns actual PWM rate. */ +uint32_t pwm_init_ex(int timer_num, uint32_t rate, uint32_t duty, int enable_timer) +{ + uint32_t actual_rate; + volatile struct TMR_struct *timer = TMR_ADDR(timer_num); + int log_divisor = 0; + uint32_t period, guard; + + /* Turn timer off */ + TMR0->ENBL &= ~(1 << timer_num); + + /* Calculate optimal rate */ + for (log_divisor = 0; log_divisor < 8; log_divisor++) + { + int denom = (rate * (1 << log_divisor)); + period = (REF_OSC + denom/2) / denom; + if (period <= 65535) + break; + } + if (log_divisor >= 8) + { + period = 65535; + log_divisor = 7; + } + + /* Guard value (for safely changing duty cycle) should be + about 32 CPU clocks. Calculate how many timer counts that + is, based on prescaler */ + guard = 32 >> log_divisor; + if (guard < 2) guard = 2; + + /* Period should be about 50% longer than guard */ + if (period < ((guard * 3) / 2)) + period = guard + 4; + + /* Store period, guard, actual rate */ + pwm_info[timer_num].period = period; + pwm_info[timer_num].guard = guard; + actual_rate = REF_OSC / (period * (1 << log_divisor)); + + /* Set up timer */ + pwm_duty_ex(timer_num, duty); // sets CMPLD1, LOAD + timer->SCTRLbits = (struct TMR_SCTRL) { + .OEN = 1, // drive OFLAG + }; + timer->CSCTRLbits = (struct TMR_CSCTRL) { + .CL1 = 0x01, // Reload COMP1 when COMP1 matches + }; + timer->COMP1 = timer->CMPLD1; + timer->CNTR = timer->LOAD; + timer->CTRLbits = (struct TMR_CTRL) { + .COUNT_MODE = 1, // Count rising edge of primary source + .PRIMARY_CNT_SOURCE = 8 + log_divisor, // Peripheral clock divided by (divisor) + .LENGTH = 1, // At compare, reset to LOAD + .OUTPUT_MODE = 6, // Set on COMP1, clear on rollover + }; + + pad_set_output(timer_num); + pad_set_normal(timer_num); + + if (enable_timer) { + TMR0->ENBL |= (1 << timer_num); + } + +// printf("pwm timer %d, addr %p, requested rate %d, actual rate: %d, period %d, guard %d, divisor %d\r\n", +// timer_num, timer, rate, actual_rate, period, guard, 1 << log_divisor); + + return actual_rate; +} + +/* Change duty cycle. Safe to call at any time. + timer_num = 0, 1, 2, 3 + duty = desired duty cycle. 0=always off, 65536=always on. +*/ +void pwm_duty_ex(int timer_num, uint32_t duty) +{ + uint16_t comp1, load; + volatile struct TMR_struct *timer = TMR_ADDR(timer_num); + uint32_t period = pwm_info[timer_num].period; + + duty = (duty * period + 32767) / 65536; + + /* We don't use the "variable PWM" mode described in the datasheet because + there's no way to reliably change the duty cycle without potentially + changing the period for one cycle, which will cause phase drifts. + + Instead, we use the "Set on compare, clear on rollover" output mode: + + waveform: |_________| |----------| + counter: 0 COMP1 LOAD 65535 + + The low portion of the wave is COMP1 cycles long. The + compare changes the counter to LOAD, and so the high + portion is (65536 - LOAD) cycles long. + + Now, we just have to make sure we're not about to hit COMP1 + before we change LOAD and COMPLD1. If (COMP1 - CNTR) is less + than GUARD cycles, we wait for it to reload before changing. + */ + + if (duty == 0) { + pad_set_zero(timer_num); + pwm_info[timer_num].pad_forced = 1; + return; + } + + if (duty >= period) { + pad_set_one(timer_num); + pwm_info[timer_num].pad_forced = 1; + return; + } + + if (pwm_info[timer_num].pad_forced) { + pad_set_normal(timer_num); + pwm_info[timer_num].pad_forced = 0; + } + + comp1 = (period - duty) - 1; + load = (65536 - duty); + + /* Disable interrupts */ + uint32_t old_INTCNTL = ITC->INTCNTL; + ITC->INTCNTL = 0; + + if (TMR0->ENBL & (1 << timer_num)) + { + /* Timer is enabled, so use the careful approach. + Implemented in ASM so we can be sure of the cycle + count */ + uint32_t tmp1, tmp2; + asm volatile (//".arm \n\t" + "1: \n\t" + "ldrh %[tmp1], %[comp] \n\t" // load COMP1 + "ldrh %[tmp2], %[count] \n\t" // load CNTR + "sub %[tmp1], %[tmp1], %[tmp2] \n\t" // subtract + "lsl %[tmp1], %[tmp1], #16 \n\t" // clear high bits + "lsr %[tmp1], %[tmp1], #16 \n\t" + "cmp %[tmp1], %[guard] \n\t" // compare to GUARD + "bls 1b \n\t" // if less, goto 1 + + "strh %[ld1], %[cmpld] \n\t" // store CMPLD1 + "strh %[ld2], %[load] \n\t" // store LOAD + : /* out */ + [tmp1] "=&l" (tmp1), + [tmp2] "=&l" (tmp2), + [cmpld] "=m" (timer->CMPLD1), + [load] "=m" (timer->LOAD) + : /* in */ + [comp] "m" (timer->COMP1), + [count] "m" (timer->CNTR), + [ld1] "l" (comp1), + [ld2] "l" (load), + [guard] "l" (pwm_info[timer_num].guard) + : "memory" + ); + } else { + /* Just set it directly, timer isn't running */ + timer->CMPLD1 = comp1; + timer->LOAD = load; + } + + /* Re-enable interrupts */ + ITC->INTCNTL = old_INTCNTL; +} diff --git a/tests/Makefile b/tests/Makefile index 88c66dae2..0380d4f8b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -11,7 +11,9 @@ TARGETS := blink-red blink-green blink-blue blink-white blink-allio \ tmr tmr-ints \ sleep \ printf \ - asm + asm \ + adc \ + pwm # these targets are built with space reserved for variables needed by ROM services # this space is initialized with a rom call to rom_data_init diff --git a/tests/pwm.c b/tests/pwm.c new file mode 100644 index 000000000..324913d54 --- /dev/null +++ b/tests/pwm.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#include +#include +#include + +#include "config.h" +#include "pwm.h" +#include "rtc.h" + +int main(void) +{ + int x = 32768; + + trim_xtal(); + uart1_init(INC,MOD,SAMP); + rtc_init(); + + printf("pwm test\r\n"); + pwm_init_stopped(TMR0, 12000000, x); + pwm_init_stopped(TMR1, 12000000, x); + TMR0->ENBL |= TMR_ENABLE_BIT(TMR0) | TMR_ENABLE_BIT(TMR1); + + for(;;) { + printf("duty %d = %d%%\r\n", x, ((x * 100 + 32768) / 65536)); + switch(uart1_getc()) { + case '[': x -= 1; break; + case ']': x += 1; break; + case '-': x -= 32; break; + case '=': x += 32; break; + case '_': x -= 512; break; + case '+': x += 512; break; + + case '`': x = 65535 * 0/10; break; + case '1': x = 65535 * 1/10; break; + case '2': x = 65535 * 2/10; break; + case '3': x = 65535 * 3/10; break; + case '4': x = 65535 * 4/10; break; + case '5': x = 65535 * 5/10; break; + case '6': x = 65535 * 6/10; break; + case '7': x = 65535 * 7/10; break; + case '8': x = 65535 * 8/10; break; + case '9': x = 65535 * 9/10; break; + case '0': x = 65535 * 10/10; break; + + } + x &= 65535; + pwm_duty(TMR0, x); + } +} + + From b2b18b37fc928e21a1ec92a253c5f31b69ed4ef3 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Fri, 11 Mar 2011 16:17:06 -0500 Subject: [PATCH 08/27] add gpio-utils --- lib/gpio-util.c | 63 +++++++++++++++++++++++++++++++++++++++++ lib/include/gpio-util.h | 28 ++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 lib/gpio-util.c create mode 100644 lib/include/gpio-util.h diff --git a/lib/gpio-util.c b/lib/gpio-util.c new file mode 100644 index 000000000..e1f55d426 --- /dev/null +++ b/lib/gpio-util.c @@ -0,0 +1,63 @@ + +#include +#include + +#include "gpio-util.h" + +void gpio_select_function(uint8_t gpio, uint8_t func) { + uint32_t mask = 3; + uint8_t major, minor, shift; + volatile uint32_t *base = GPIO_FUNC_SEL0; + uint32_t value; + major = gpio >> 4; + minor = gpio & 0xF; + shift = 2 * minor; + + value = base[major]; + value &= ~(mask << shift); + value |= (func << shift); + base[major] = value; +} + +void gpio_reg_set(volatile uint32_t* reg, uint8_t bit) { + uint8_t major, minor; + major = bit / 32; + minor = bit % 32; + *(reg + major) |= (1UL << minor); +} + +void gpio_reg_clear(volatile uint32_t* reg, uint8_t bit) { + uint8_t major, minor; + major = bit / 32; + minor = bit % 32; + *(reg + major) &= ~(1UL << minor); +} + +void gpio_set_pad_dir(uint8_t gpio, uint8_t dir) { + uint8_t major, minor; + major = gpio / 32; + minor = gpio % 32; + if (dir) gpio_reg_set(GPIO_PAD_DIR0 + major, minor); + else gpio_reg_clear(GPIO_PAD_DIR0 + major, minor); +} + +void gpio_set(uint8_t gpio) { + uint8_t major, minor; + major = gpio / 32; + minor = gpio % 32; + *(GPIO_DATA_SET0 + major) = (1UL << minor); +} + +void gpio_reset(uint8_t gpio) { + uint8_t major, minor; + major = gpio / 32; + minor = gpio % 32; + *(GPIO_DATA_RESET0 + major) = (1UL << minor); +} + +bool gpio_read(uint8_t gpio) { + uint8_t major, minor; + major = gpio / 32; + minor = gpio % 32; + return (*(GPIO_DATA0 + major) >> minor) & 1; +} diff --git a/lib/include/gpio-util.h b/lib/include/gpio-util.h new file mode 100644 index 000000000..258ecf097 --- /dev/null +++ b/lib/include/gpio-util.h @@ -0,0 +1,28 @@ + +#ifndef GPIO_UTIL_H +#define GPIO_UTIL_H + +#include +#include + +void gpio_select_function(uint8_t gpio, uint8_t func); +void gpio_reg_set(volatile uint32_t* reg, uint8_t bit); +void gpio_reg_clear(volatile uint32_t* reg, uint8_t bit); + +#define PAD_DIR_INPUT 0 +#define PAD_DIR_OUTPUT 1 +void gpio_set_pad_dir(uint8_t gpio, uint8_t dir); + +#undef gpio_set +#undef gpio_reset +#undef gpio_read + +//#define gpio_set gpio_set_ian +//#define gpio_reset gpio_reset_ian +//#define gpio_read gpio_read_ian + +void gpio_set(uint8_t gpio); +void gpio_reset(uint8_t gpio); +bool gpio_read(uint8_t gpio); + +#endif From c27e96f1e9aa8d1f781411de7ac5d0de7dafd656 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Fri, 11 Mar 2011 16:20:41 -0500 Subject: [PATCH 09/27] add adc support --- lib/adc.c | 138 ++++++++++++++++++++++++++++++++++++++ lib/include/adc.h | 164 +++++++++++++++++++++++++++++++++++++++++++++ lib/include/maca.h | 4 +- lib/maca.c | 2 +- tests/adc.c | 63 +++++++++++++++++ 5 files changed, 368 insertions(+), 3 deletions(-) create mode 100644 lib/adc.c create mode 100644 lib/include/adc.h create mode 100644 tests/adc.c diff --git a/lib/adc.c b/lib/adc.c new file mode 100644 index 000000000..841855107 --- /dev/null +++ b/lib/adc.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#include +#include "crm.h" +#include "adc.h" +#include "gpio-util.h" + +//#define ADC_CHANS_ENABLED 0x3F // channels 0-5 enabled +//#define ADC_CHANS_ENABLED 0x7E // channels 1-6 enabled +//#define ADC_CHANS_ENABLED (1 << 6) // only channel 6 enabled +#define ADC_CHANS_ENABLED 0x1FF // all channels, including battery reference voltage + +//#define ADC_PRESCALE_VALUE 24 // divide by 24 for 1MHz. + +#define ADC_SAMPLE_FREQ 400 // Hz (minimum of ~366.21 Hz) +#define ADC_PRESCALE_VALUE (REF_OSC / ADC_SAMPLE_FREQ) + +#define ADC_USE_TIMER 0 +#define ADC_USE_INTERRUPTS 0 // incomplete support + +uint16_t adc_reading[NUM_ADC_CHAN]; + +void ADC_flush(void) { + while(ADC->FIFO_STATUSbits.EMPTY == 0) ADC->FIFO_READ; +} + +uint16_t ADC_READ(void) { + while(ADC->FIFO_STATUSbits.EMPTY); // loop while empty + return ADC->FIFO_READ; // upper 4 bits are channel number +} + + +void adc_service(void) { + uint16_t value; + uint8_t channel; + while (ADC->FIFO_STATUSbits.EMPTY == 0) { + value = ADC->FIFO_READ; + channel = value >> 12; + if (channel < NUM_ADC_CHAN) adc_reading[channel] = value & 0xFFF; + } +} + +void adc_init(void) { + uint8_t n; + + ADC->CLOCK_DIVIDER = 80; // 300 KHz + ADC->PRESCALE = ADC_PRESCALE_VALUE - 1; // divide by 24 for 1MHz. + + ADC->CONTROL = 1; + + // The ON-TIME must always be 10µs or greater - typical On-Time value = 0x000A (10dec) + ADC->ON_TIME = 10; + + /* + NOTE + The ADC analog block requires 6 ADC_Clocks per conversion, and the + ADC_Clock must 300kHz or less. With 6 clocks/conversion and a 33.33µs + clock period: + * The ADC convert time must always be 20µs or greater + * If the ADC_Clock is a frequency lower than 300kHz, the convert time + must always be 6 ADC_Clock periods or greater + * For override mode, extend convert time to 40µs minimum or greater + For the convert time: + * This delay is a function of the Prescale Clock (typically 1 MHz) + * The register must be initialized for proper operation + * For a 20µs convert time with 1MHz, value = 0x0014 (20dec) + * If convert time is insufficient, inaccurate sample data will result + */ + ADC->CONVERT_TIME = 1000000 / (115200 / 8) - 1; + + ADC->MODE = 0; // Automatic + +#if ADC_USE_INTERRUPTS + ADC->FIFO_CONTROL = 7; +#else + ADC->FIFO_CONTROL = 0; +#endif + +#if ADC_USE_TIMER + ADC->SR_1_HIGH = 0x0000; + ADC->SR_1_LOW = (REF_OSC / ADC_PRESCALE_VALUE) / (115200 / 8) + 1; +#endif + + ADC->SEQ_1 = 0 +#if ADC_USE_TIMER + | (1 << 15) // sequence based on Timer 1. +#else + | (0 << 15) // sequence based on convert time. +#endif + | ADC_CHANS_ENABLED; + + ADC->CONTROL = 0xF001 +//#if ADC_USE_TIMER + | (1 << 1) // Timer 1 enable +//#endif + ; + ADC->OVERRIDE = (1 << 8); + + for (n=0; n<=8; n++) { + if ((ADC_CHANS_ENABLED >> n) & 1) { + gpio_select_function(30 + n, 1); // Function 1 = ADC + gpio_set_pad_dir(30 + n, PAD_DIR_INPUT); + } + } +} diff --git a/lib/include/adc.h b/lib/include/adc.h new file mode 100644 index 000000000..580e3545e --- /dev/null +++ b/lib/include/adc.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#ifndef ADC_H +#define ADC_H + +#include +#include "utils.h" + +/* ADC registers are all 16-bit wide with 16-bit access only */ +#define ADC_BASE (0x8000D000) + +/* Structure-based register definitions */ + +struct ADC_struct { + union { + uint16_t COMP[8]; + struct { + uint16_t COMP_0; + uint16_t COMP_1; + uint16_t COMP_2; + uint16_t COMP_3; + uint16_t COMP_4; + uint16_t COMP_5; + uint16_t COMP_6; + uint16_t COMP_7; + }; + }; + uint16_t BAT_COMP_OVER; + uint16_t BAT_COMP_UNDER; + union { + uint16_t SEQ_1; + struct ADC_SEQ_1 { + uint16_t CH0:1; + uint16_t CH1:1; + uint16_t CH2:1; + uint16_t CH3:1; + uint16_t CH4:1; + uint16_t CH5:1; + uint16_t CH6:1; + uint16_t CH7:1; + uint16_t BATT:1; + uint16_t :6; + uint16_t SEQ_MODE:1; + } SEQ_1bits; + }; + union { + uint16_t SEQ_2; + struct ADC_SEQ_2 { + uint16_t CH0:1; + uint16_t CH1:1; + uint16_t CH2:1; + uint16_t CH3:1; + uint16_t CH4:1; + uint16_t CH5:1; + uint16_t CH6:1; + uint16_t CH7:1; + uint16_t :7; + uint16_t SEQ_MODE:1; + } SEQ_2bits; + }; + union { + uint16_t CONTROL; + struct ADC_CONTROL { + uint16_t ON:1; + uint16_t TIMER1_ON:1; + uint16_t TIMER2_ON:1; + uint16_t SOFT_RESET:1; + uint16_t AD1_FREFHL_EN:1; + uint16_t AD2_VREFHL_EN:1; + uint16_t :6; + uint16_t COMPARE_IRQ_MASK:1; + uint16_t SEQ1_IRQ_MASK:1; + uint16_t SEQ2_IRQ_MASK:1; + uint16_t FIFO_IRQ_MASK:1; + } CONTROLbits; + }; + uint16_t TRIGGERS; + uint16_t PRESCALE; + uint16_t reserved1; + uint16_t FIFO_READ; + uint16_t FIFO_CONTROL; + union { + uint16_t FIFO_STATUS; + struct ADC_FIFO_STATUS { + uint16_t LEVEL:4; + uint16_t FULL:1; + uint16_t EMPTY:1; + uint16_t :10; + } FIFO_STATUSbits; + }; + uint16_t reserved2[5]; + uint16_t SR_1_HIGH; + uint16_t SR_1_LOW; + uint16_t SR_2_HIGH; + uint16_t SR_2_LOW; + uint16_t ON_TIME; + uint16_t CONVERT_TIME; + uint16_t CLOCK_DIVIDER; + uint16_t reserved3; + union { + uint16_t OVERRIDE; + struct ADC_OVERRIDE { + uint16_t MUX1:4; + uint16_t MUX2:4; + uint16_t AD1_ON:1; + uint16_t AD2_ON:1; + uint16_t :6; + } OVERRIDEbits; + }; + uint16_t IRQ; + uint16_t MODE; + uint16_t RESULT_1; + uint16_t RESULT_2; +}; + +static volatile struct ADC_struct * const ADC = (void *) (ADC_BASE); + +#define NUM_ADC_CHAN 9 + +#define adc_enable() (ADC->CONTROLbits.ON = 1) +#define adc_disable() (ADC->CONTROLbits.ON = 0) +#define adc_select_channels(chans) (ADC->SEQ_1 = (ADC->SEQ_1 & 0xFE00) | chans) + +extern uint16_t adc_reading[NUM_ADC_CHAN]; +void ADC_flush(void); +uint16_t ADC_READ(void); +void read_scanners(void); +void adc_init(void); +void adc_service(void); + +#endif diff --git a/lib/include/maca.h b/lib/include/maca.h index 2f567a9ac..d9bb283b8 100644 --- a/lib/include/maca.h +++ b/lib/include/maca.h @@ -121,8 +121,8 @@ enum { #define LFSR 6 /* 1 use polynomial for Turbolink */ #define TM 5 -#define MODE 3 -#define MODE_MASK bit_mask(2,MODE) +#define MACA_MODE 3 +#define MODE_MASK bit_mask(2,MACA_MODE) #define NO_CCA 0 #define NO_SLOT_CCA 1 #define SLOT_CCA 2 diff --git a/lib/maca.c b/lib/maca.c index e039062c3..fb14052bb 100644 --- a/lib/maca.c +++ b/lib/maca.c @@ -184,7 +184,7 @@ void maca_init(void) { /* nop, promiscuous, no cca */ *MACA_CONTROL = (prm_mode << PRM) | - (NO_CCA << MODE); + (NO_CCA << MACA_MODE); enable_irq(MACA); *INTFRC = (1 << INT_NUM_MACA); diff --git a/tests/adc.c b/tests/adc.c new file mode 100644 index 000000000..28a98ce75 --- /dev/null +++ b/tests/adc.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) + * 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 libmc1322x: see http://mc1322x.devl.org + * for details. + * + * + */ + +#include +#include +#include + +#include "config.h" +#include "adc.h" + +int main(void) +{ + uint8_t c; + + trim_xtal(); + uart1_init(INC,MOD,SAMP); + adc_init(); + + printf("adc test\r\n"); + + printf("\x1B[2J"); // clear screen + + for(;;) { + printf("\x1B[H"); // cursor home + printf("# Value\r\n"); + for (c=0; c Date: Fri, 11 Mar 2011 16:28:02 -0500 Subject: [PATCH 10/27] Defines need to be above their use in a conditional test --- platform/avr-atmega128rfa1/contiki-main.c | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/platform/avr-atmega128rfa1/contiki-main.c b/platform/avr-atmega128rfa1/contiki-main.c index 7253707c8..a05c454d9 100644 --- a/platform/avr-atmega128rfa1/contiki-main.c +++ b/platform/avr-atmega128rfa1/contiki-main.c @@ -95,6 +95,22 @@ #include "net/rime.h" +/* Test rtimers, also for pings, stack monitor, neighbor/route printout and time stamps */ +#define TESTRTIMER 1 +#if TESTRTIMER +//#define PINGS 64 +#define ROUTES 64 +#define STAMPS 30 +#define STACKMONITOR 128 + +uint8_t rtimerflag=1; +uint16_t rtime; +struct rtimer rt; +void rtimercycle(void) {rtimerflag=1;} +static void ipaddr_add(const uip_ipaddr_t *addr); + +#endif /* TESTRTIMER */ + /*-------------------------------------------------------------------------*/ /*----------------------Configuration of the .elf file---------------------*/ typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t; @@ -374,21 +390,6 @@ void log_message(char *m1, char *m2) { PRINTF("%s%s\n", m1, m2); } -/* Test rtimers, also for pings, stack monitor, neighbor/route printout and time stamps */ -#define TESTRTIMER 1 -#if TESTRTIMER -//#define PINGS 64 -#define ROUTES 64 -#define STAMPS 30 -#define STACKMONITOR 128 - -uint8_t rtimerflag=1; -uint16_t rtime; -struct rtimer rt; -void rtimercycle(void) {rtimerflag=1;} -static void ipaddr_add(const uip_ipaddr_t *addr); - -#endif /* TESTRTIMER */ #if RF230BB extern char rf230_interrupt_flag, rf230processflag; From f2b92cfa98899b80ff84af44c4e52c77cd28d3d7 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Fri, 11 Mar 2011 16:32:25 -0500 Subject: [PATCH 11/27] mc1322x: remove bad rule from cpu Makfile --- cpu/mc1322x/Makefile.mc1322x | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpu/mc1322x/Makefile.mc1322x b/cpu/mc1322x/Makefile.mc1322x index 316012133..3e45f3f06 100644 --- a/cpu/mc1322x/Makefile.mc1322x +++ b/cpu/mc1322x/Makefile.mc1322x @@ -90,8 +90,6 @@ $(OBJECTDIR)/%.o: %.c $(CC) $(CFLAGS) $(THUMB_FLAGS) -c $< -o $@ CUSTOM_RULE_S_TO_OBJECTDIR_O = yes -%.o: %.S - $(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c $(OBJECTDIR)/%.o: %.S $(CC) $(CFLAGS) $(AFLAGS) $(ARM_FLAGS) $< -c -o $@ From bf5be5056f788356a07d837c546993355469a2ea Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 11 Mar 2011 16:50:35 -0500 Subject: [PATCH 12/27] Testing $OS works with cygwin and DOS command windows --- cpu/mc1322x/Makefile.mc1322x | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/mc1322x/Makefile.mc1322x b/cpu/mc1322x/Makefile.mc1322x index 316012133..676986d34 100644 --- a/cpu/mc1322x/Makefile.mc1322x +++ b/cpu/mc1322x/Makefile.mc1322x @@ -72,8 +72,8 @@ CUSTOM_RULE_C_TO_O=yes CFLAGS += -I$(OBJECTDIR) -I$(CONTIKI_CPU)/board -DBOARD=$(TARGET) $(OBJECTDIR)/board.h: $(OBJECTDIR) -ifneq (,$(findstring cygdrive,$(shell pwd))) -${info Cygwin detected.} +ifneq (,$(findstring Windows,$(OS))) + ${info Cygwin detected.} ln -f $(CONTIKI_CPU)/board/$(TARGET).h $(OBJECTDIR)/board.h else ln -sf ../$(CONTIKI_CPU)/board/$(TARGET).h $(OBJECTDIR)/board.h From b7baf22a02f1eee81fafcf61bea7abf05cbfc45d Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sat, 12 Mar 2011 09:06:38 -0500 Subject: [PATCH 13/27] add .gitignore and ignore generated files --- .gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ca2f32a4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.a +*.bin +*.map +*.png +*.log +*.elf +*.ihex +obj_* +symbols.* +Makefile.target +doc/html +patches-* +tools/tunslip6 From 72cb4157d965fd54425c697285b9a78ea333167e Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sat, 12 Mar 2011 22:36:39 -0500 Subject: [PATCH 14/27] fix burn-macs to work on 32-bit machines too --- tools/test-grid/burn-macs.pl | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/test-grid/burn-macs.pl b/tools/test-grid/burn-macs.pl index 8434f2fb4..311bac768 100755 --- a/tools/test-grid/burn-macs.pl +++ b/tools/test-grid/burn-macs.pl @@ -5,11 +5,14 @@ my $bin = shift; my $terms = shift; my $addr = "0x1e000"; -my $company_id; -my $iab = 0xabc; # Redwire, LLC's IAB +my $iab = 0xa8c; # Redwire, LLC's IAB + +my $mac_h; +my $mac_l; if(defined($iab)) { - $company_id = (0x0050C2 << 12) | $iab; + $mac_h = 0x0050C200 | ($iab >> 4); + $mac_l = ($iab & 0xf) << 28; } if (! $terms) { @@ -19,15 +22,17 @@ if (! $terms) { for (my $t=0; $t<$terms; $t++) { my $dev_num = 2 * $t + 1; + $mac_l |= $dev_num; + #stupid 32-bit thing... my $mac; - if(defined($iab)) { - $mac = ($company_id << 28) | $dev_num; - } else { - $mac = ($company_id << 40) | $dev_num; - } + printf("mac_h %x\n", $mac_h); + printf("mac_l %x\n", $mac_l); my @words; - for(my $i=0; $i<8; $i++) { - push @words, ($mac >> ($i * 8)) & 0xff; + for(my $i=0; $i<4; $i++) { + push @words, ($mac_h >> ($i * 8)) & 0xff; + } + for(my $i=0; $i<4; $i++) { + push @words, ($mac_l >> ($i * 8)) & 0xff; } reverse @words; foreach my $byte (@words) { From a883c9bcbc8c4c52bed0b093559d48fd20c7d79d Mon Sep 17 00:00:00 2001 From: dak664 Date: Sun, 13 Mar 2011 11:57:39 -0400 Subject: [PATCH 15/27] Add PRINTA so direct calls to debug routines will always print --- core/net/uip-debug.c | 15 +++++++-------- core/net/uip-debug.h | 13 +++++++++---- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/core/net/uip-debug.c b/core/net/uip-debug.c index 60ec30f86..bc611f383 100644 --- a/core/net/uip-debug.c +++ b/core/net/uip-debug.c @@ -26,7 +26,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: uip-debug.c,v 1.1 2010/04/30 13:20:57 joxe Exp $ */ /** @@ -39,7 +38,7 @@ */ #include "net/uip-debug.h" -#include + /*---------------------------------------------------------------------------*/ void uip_debug_ipaddr_print(const uip_ipaddr_t *addr) @@ -52,19 +51,19 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr) a = (addr->u8[i] << 8) + addr->u8[i + 1]; if(a == 0 && f >= 0) { if(f++ == 0) { - printf("::"); + PRINTA("::"); } } else { if(f > 0) { f = -1; } else if(i > 0) { - printf(":"); + PRINTA(":"); } - printf("%x", a); + PRINTA("%x", a); } } #else /* UIP_CONF_IPV6 */ - printf("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); + PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); #endif /* UIP_CONF_IPV6 */ } /*---------------------------------------------------------------------------*/ @@ -74,9 +73,9 @@ uip_debug_lladdr_print(const uip_lladdr_t *addr) unsigned int i; for(i = 0; i < sizeof(uip_lladdr_t); i++) { if(i > 0) { - printf(":"); + PRINTA(":"); } - printf("%02x", addr->addr[i]); + PRINTA("%02x", addr->addr[i]); } } /*---------------------------------------------------------------------------*/ diff --git a/core/net/uip-debug.h b/core/net/uip-debug.h index 7ee280156..8015c03f1 100644 --- a/core/net/uip-debug.h +++ b/core/net/uip-debug.h @@ -43,6 +43,7 @@ #define UIP_DEBUG_H #include "net/uip.h" +#include void uip_debug_ipaddr_print(const uip_ipaddr_t *addr); void uip_debug_lladdr_print(const uip_lladdr_t *addr); @@ -52,10 +53,16 @@ void uip_debug_lladdr_print(const uip_lladdr_t *addr); #define DEBUG_ANNOTATE 2 #define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT -#if (DEBUG) & DEBUG_ANNOTATE -#include +/* PRINTA will always print if the debug routines are called directly */ #ifdef __AVR__ #include +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) printf(__VA_ARGS__) +#endif + +#if (DEBUG) & DEBUG_ANNOTATE +#ifdef __AVR__ #define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args) #else #define ANNOTATE(...) printf(__VA_ARGS__) @@ -65,9 +72,7 @@ void uip_debug_lladdr_print(const uip_lladdr_t *addr); #endif /* (DEBUG) & DEBUG_ANNOTATE */ #if (DEBUG) & DEBUG_PRINT -#include #ifdef __AVR__ -#include #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) #else #define PRINTF(...) printf(__VA_ARGS__) From 14246ef811d26c9b5f9cdbd21632487130f6d5a4 Mon Sep 17 00:00:00 2001 From: dak664 Date: Sun, 13 Mar 2011 11:59:17 -0400 Subject: [PATCH 16/27] Add optional build without internal webserver --- examples/ipv6/rpl-border-router/Makefile | 9 +++++- .../ipv6/rpl-border-router/border-router.c | 28 ++++++++++++------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/examples/ipv6/rpl-border-router/Makefile b/examples/ipv6/rpl-border-router/Makefile index fe551f15b..3fd4c82b4 100644 --- a/examples/ipv6/rpl-border-router/Makefile +++ b/examples/ipv6/rpl-border-router/Makefile @@ -5,10 +5,17 @@ CONTIKI=../../.. WITH_UIP6=1 UIP_CONF_IPV6=1 -APPS += webserver +#Override inclusion of internal webserver with make WITH_WEBSERVER=0 +WITH_WEBSERVER=1 +ifeq ($(WITH_WEBSERVER), 0) CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-bridge.c +else +APPS += webserver +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -DWEBSERVER PROJECT_SOURCEFILES += slip-bridge.c httpd-simple.c +endif include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index c2cc8973e..a7a31f48e 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -45,11 +45,13 @@ #include "net/netstack.h" #include "dev/button-sensor.h" #include "dev/slip.h" -#define INTERNAL_WEBSERVER 1 -#if INTERNAL_WEBSERVER + +/* For internal webserver Makefile must set APPS += webserver and PROJECT_SOURCEFILES += httpd-simple.c */ +#if WEBSERVER #include "webserver-nogui.h" #include "httpd-simple.h" #endif + #include #include #include @@ -68,7 +70,8 @@ static uint8_t prefix_set; PROCESS(border_router_process, "Border router process"); AUTOSTART_PROCESSES(&border_router_process); -#if INTERNAL_WEBSERVER + +#if WEBSERVER /*---------------------------------------------------------------------------*/ /* Only one single web request at time */ static const char *TOP = "ContikiRPL\n"; @@ -155,6 +158,9 @@ httpd_simple_get_script(const char *name) { return generate_routes; } + +#endif /* WEBSERVER */ + /*---------------------------------------------------------------------------*/ static void print_local_addresses(void) @@ -162,18 +168,17 @@ print_local_addresses(void) int i; uint8_t state; - PRINTF("Server IPv6 addresses:\n"); + PRINTA("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)) { - blen = 0; - ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); - PRINTF(" %s\n", buf); + PRINTA(" "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); } } } -#endif /* INTERNAL_WEBSERVER */ /*---------------------------------------------------------------------------*/ void request_prefix(void) @@ -206,9 +211,11 @@ PROCESS_THREAD(border_router_process, ev, data) prefix_set = 0; PROCESS_PAUSE(); -#if INTERNAL_WEBSERVER + +#if WEBSERVER process_start(&webserver_nogui_process, NULL); #endif + SENSORS_ACTIVATE(button_sensor); PRINTF("RPL-Border router started\n"); @@ -225,7 +232,8 @@ PROCESS_THREAD(border_router_process, ev, data) rpl_set_prefix(dag, &prefix, 64); PRINTF("created a new RPL dag\n"); } -#if INTERNAL_WEBSERVER + +#if DEBUG || 1 print_local_addresses(); #endif From 0b2d3d16155d3462059137538d64ffbfe6a8b25f Mon Sep 17 00:00:00 2001 From: dak664 Date: Sun, 13 Mar 2011 13:07:32 -0400 Subject: [PATCH 17/27] Refactor clock code with optional interrupt optimizing. Put periodic radio calibration on conditional. --- cpu/avr/dev/clock.c | 152 ++++++++++++++++++++++++++------ cpu/avr/radio/rf230bb/rf230bb.c | 7 +- 2 files changed, 132 insertions(+), 27 deletions(-) diff --git a/cpu/avr/dev/clock.c b/cpu/avr/dev/clock.c index ad1711828..14a1671fb 100644 --- a/cpu/avr/dev/clock.c +++ b/cpu/avr/dev/clock.c @@ -15,12 +15,23 @@ long sleepseconds; #if RF230BB && WEBSERVER #define RADIOSTATS 1 #endif + #if RADIOSTATS static volatile uint8_t rcount; volatile unsigned long radioontime; extern uint8_t RF230_receive_on; #endif +/* Set RADIOCALIBRATE for periodic calibration of the PLL during extended radio on time. + * The data sheet suggests every 5 minutes if the temperature is fluctuating. + * Using an eight bit counter gives 256 second calibrations. + * Actual calibration is done by the driver on the next transmit request. + */ +#if RADIOCALIBRATE +extern volatile uint8_t rf230_calibrate; +static uint8_t calibrate_interval; +#endif + /* CLOCK_SECOND is the number of ticks per second. It is defined through CONF_CLOCK_SECOND in the contiki-conf.h for each platform. @@ -46,48 +57,49 @@ void clock_adjust_seconds(uint8_t howmany) { #endif } /*---------------------------------------------------------------------------*/ -/* These routines increment the second counters. - * Calling these avoids the interrupt overhead of pushing many registers on the stack. - */ -static void increment_seconds(void) __attribute__ ((noinline)); -static void increment_seconds(void) -{ - seconds++; -} -#if RADIOSTATS -extern volatile uint8_t rf230_calibrate; -static void increment_radioontime(void) __attribute__ ((noinline)); -static void increment_radioontime(void) -{ -static uint8_t calibrate_interval; - radioontime++; - if (++calibrate_interval==0) { - rf230_calibrate=1; - } -} -#endif -/*---------------------------------------------------------------------------*/ //SIGNAL(SIG_OUTPUT_COMPARE0) ISR(AVR_OUTPUT_COMPARE_INT) { count++; if(++scount == CLOCK_SECOND) { scount = 0; - increment_seconds(); -// seconds++; + seconds++; } +#if RADIOCALIBRATE + if (++calibrate_interval==0) { + rf230_calibrate=1; + } +#endif #if RADIOSTATS if (RF230_receive_on) { if (++rcount == CLOCK_SECOND) { rcount=0; - increment_radioontime(); - // radioontime++; + radioontime++; } - } #endif + +#if 1 +/* gcc will save all registers on the stack if an external routine is called */ if(etimer_pending()) { etimer_request_poll(); } +#else +/* doing this locally saves 9 pushes and 9 pops, but these etimer.c and process.c variables have to lose the static qualifier */ + extern struct etimer *timerlist; + extern volatile unsigned char poll_requested; + +#define PROCESS_STATE_NONE 0 +#define PROCESS_STATE_RUNNING 1 +#define PROCESS_STATE_CALLED 2 + + if (timerlist) { + if(etimer_process.state == PROCESS_STATE_RUNNING || + etimer_process.state == PROCESS_STATE_CALLED) { + etimer_process.needspoll = 1; + poll_requested = 1; + } + } +#endif } /*---------------------------------------------------------------------------*/ @@ -153,3 +165,91 @@ clock_seconds(void) } while(tmp != seconds); return tmp; } + +#if 1 +/* Useful for diagnosing unknown interrupts that reset the mcu. + * Currently set up for 12mega128rfa1. + * For other mcus, enable all and then disable the conflicts. + */ +static volatile uint8_t x; +ISR( _VECTOR(0)) {while (1) x++;} +ISR( _VECTOR(1)) {while (1) x++;} +ISR( _VECTOR(2)) {while (1) x++;} +ISR( _VECTOR(3)) {while (1) x++;} +ISR( _VECTOR(4)) {while (1) x++;} +ISR( _VECTOR(5)) {while (1) x++;} +ISR( _VECTOR(6)) {while (1) x++;} +ISR( _VECTOR(7)) {while (1) x++;} +ISR( _VECTOR(8)) {while (1) x++;} +ISR( _VECTOR(9)) {while (1) x++;} +ISR( _VECTOR(10)) {while (1) x++;} +ISR( _VECTOR(11)) {while (1) x++;} +ISR( _VECTOR(12)) {while (1) x++;} +ISR( _VECTOR(13)) {while (1) x++;} +ISR( _VECTOR(14)) {while (1) x++;} +ISR( _VECTOR(15)) {while (1) x++;} +ISR( _VECTOR(16)) {while (1) x++;} +ISR( _VECTOR(17)) {while (1) x++;} +ISR( _VECTOR(18)) {while (1) x++;} +ISR( _VECTOR(19)) {while (1) x++;} +//ISR( _VECTOR(20)) {while (1) x++;} +//ISR( _VECTOR(21)) {while (1) x++;} +ISR( _VECTOR(22)) {while (1) x++;} +ISR( _VECTOR(23)) {while (1) x++;} +ISR( _VECTOR(24)) {while (1) x++;} +//ISR( _VECTOR(25)) {while (1) x++;} +ISR( _VECTOR(26)) {while (1) x++;} +//ISR( _VECTOR(27)) {while (1) x++;} +ISR( _VECTOR(28)) {while (1) x++;} +ISR( _VECTOR(29)) {while (1) x++;} +ISR( _VECTOR(30)) {while (1) x++;} +ISR( _VECTOR(31)) {while (1) x++;} +//ISR( _VECTOR(32)) {while (1) x++;} +ISR( _VECTOR(33)) {while (1) x++;} +ISR( _VECTOR(34)) {while (1) x++;} +ISR( _VECTOR(35)) {while (1) x++;} +//ISR( _VECTOR(36)) {while (1) x++;} +ISR( _VECTOR(37)) {while (1) x++;} +//ISR( _VECTOR(38)) {while (1) x++;} +ISR( _VECTOR(39)) {while (1) x++;} +ISR( _VECTOR(40)) {while (1) x++;} +ISR( _VECTOR(41)) {while (1) x++;} +ISR( _VECTOR(42)) {while (1) x++;} +ISR( _VECTOR(43)) {while (1) x++;} +ISR( _VECTOR(44)) {while (1) x++;} +ISR( _VECTOR(45)) {while (1) x++;} +ISR( _VECTOR(46)) {while (1) x++;} +ISR( _VECTOR(47)) {while (1) x++;} +ISR( _VECTOR(48)) {while (1) x++;} +ISR( _VECTOR(49)) {while (1) x++;} +ISR( _VECTOR(50)) {while (1) x++;} +ISR( _VECTOR(51)) {while (1) x++;} +ISR( _VECTOR(52)) {while (1) x++;} +ISR( _VECTOR(53)) {while (1) x++;} +ISR( _VECTOR(54)) {while (1) x++;} +ISR( _VECTOR(55)) {while (1) x++;} +ISR( _VECTOR(56)) {while (1) x++;} +//ISR( _VECTOR(57)) {while (1) x++;} +//ISR( _VECTOR(58)) {while (1) x++;} +//ISR( _VECTOR(59)) {while (1) x++;} +//ISR( _VECTOR(60)) {while (1) x++;} +ISR( _VECTOR(61)) {while (1) x++;} +ISR( _VECTOR(62)) {while (1) x++;} +ISR( _VECTOR(63)) {while (1) x++;} +ISR( _VECTOR(64)) {while (1) x++;} +ISR( _VECTOR(65)) {while (1) x++;} +ISR( _VECTOR(66)) {while (1) x++;} +ISR( _VECTOR(67)) {while (1) x++;} +ISR( _VECTOR(68)) {while (1) x++;} +ISR( _VECTOR(69)) {while (1) x++;} +ISR( _VECTOR(70)) {while (1) x++;} +ISR( _VECTOR(71)) {while (1) x++;} +ISR( _VECTOR(72)) {while (1) x++;} +ISR( _VECTOR(73)) {while (1) x++;} +ISR( _VECTOR(74)) {while (1) x++;} +ISR( _VECTOR(75)) {while (1) x++;} +ISR( _VECTOR(76)) {while (1) x++;} +ISR( _VECTOR(77)) {while (1) x++;} +ISR( _VECTOR(78)) {while (1) x++;} +ISR( _VECTOR(79)) {while (1) x++;} +#endif \ No newline at end of file diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index b937a0bbd..19aa8b253 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -148,9 +148,12 @@ struct timestamp { #if RADIOSTATS uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail; #endif + +#if RADIOCALIBRATE /* Set in clock.c every 256 seconds */ uint8_t rf230_calibrate; -uint8_t rf230_calibrated; //debugging +uint8_t rf230_calibrated; //for debugging, prints from main loop when calibration occurs +#endif /* Track flow through driver, see contiki-raven-main.c for example of use */ //#define DEBUGFLOWSIZE 64 @@ -758,6 +761,7 @@ rf230_transmit(unsigned short payload_len) // delay_us(TIME_SLEEP_TO_TRX_OFF); RF230_sleeping=0; } else { +#if RADIOCALIBRATE /* If on, do periodic calibration. See clock.c */ if (rf230_calibrate) { hal_subregister_write(SR_PLL_CF_START,1); //takes 80us max @@ -766,6 +770,7 @@ rf230_transmit(unsigned short payload_len) rf230_calibrated=1; delay_us(80); //? } +#endif } /* Wait for any previous operation or state transition to finish */ From a210e14d7888a39326176e00db31fbb93793ce62 Mon Sep 17 00:00:00 2001 From: dak664 Date: Sun, 13 Mar 2011 13:45:12 -0400 Subject: [PATCH 18/27] Add defines for watchdog configuration. --- cpu/avr/watchdog.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/cpu/avr/watchdog.c b/cpu/avr/watchdog.c index 0061a0802..5996027dc 100644 --- a/cpu/avr/watchdog.c +++ b/cpu/avr/watchdog.c @@ -28,44 +28,69 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: watchdog.c,v 1.3 2010/12/18 20:51:11 dak664 Exp $ */ - /* Dummy watchdog routines for the Raven 1284p */ +/* Watchdog routines for the AVR */ + +/* Default timeout of 2 seconds is available on most MCUs */ +#ifndef WATCHDOG_CONF_TIMEOUT +#define WATCHDOG_CONF_TIMEOUT WDTO_2S +//#define WATCHDOG_CONF_TIMEOUT WDTO_4S +#endif + + /* While balancing start and stop calls is a good idea, an imbalance will cause + * resets that can take a lot of time to track down. + * Some low power protocols may do this. + * The default is no balance; define WATCHDOG_CONF_BALANCE 1 to override. + */ +#ifndef WATCHDOG_CONF_BALANCE +#define WATCHDOG_CONF_BALANCE 0 +#endif + #include "dev/watchdog.h" #include #include +#if WATCHDOG_CONF_BALANCE static int stopped = 0; +#endif /*---------------------------------------------------------------------------*/ void watchdog_init(void) { MCUSR&=~(1< Date: Sun, 13 Mar 2011 14:07:17 -0400 Subject: [PATCH 19/27] Use uip-debug.h defines and print routines Add print to show cause of startup --- platform/avr-atmega128rfa1/contiki-main.c | 146 ++++++++++------------ 1 file changed, 63 insertions(+), 83 deletions(-) diff --git a/platform/avr-atmega128rfa1/contiki-main.c b/platform/avr-atmega128rfa1/contiki-main.c index a05c454d9..b20608adc 100644 --- a/platform/avr-atmega128rfa1/contiki-main.c +++ b/platform/avr-atmega128rfa1/contiki-main.c @@ -28,18 +28,14 @@ * * This file is part of the Contiki operating system. * - * @(#)$$ */ +#ifndef LED_ON_PORT1E #define LED_ON_PORTE1 0 //for Michael Hartman's prototype board -#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size -#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) - -#define DEBUG 0 -#if DEBUG -#define PRINTFD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTFD(...) #endif +#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size + +#define DEBUG DEBUG_PRINT +#include "uip-debug.h" ////Does #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) for AVR #include #include @@ -107,7 +103,6 @@ uint8_t rtimerflag=1; uint16_t rtime; struct rtimer rt; void rtimercycle(void) {rtimerflag=1;} -static void ipaddr_add(const uip_ipaddr_t *addr); #endif /* TESTRTIMER */ @@ -186,9 +181,6 @@ extern uint8_t osccal_calibrated; /*------Done in a subroutine to keep main routine stack usage small--------*/ void initialize(void) { - watchdog_init(); - watchdog_start(); - #if !LED_ON_PORTE1 //Conflicts with USART0 #if RAVEN_LCD_INTERFACE /* First rs232 port for Raven 3290 port */ @@ -206,6 +198,17 @@ void initialize(void) /* Redirect stdout to second port */ rs232_redirect_stdout(RS232_PORT_1); clock_init(); + +#if 1 + if(MCUSR & (1< //#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) // delay_us(50000); } clock_init(); + watchdog_start(); } #endif #if ANNOUNCE_BOOT - PRINTF("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); + PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); #endif - watchdog_start(); + /* rtimers needed for radio cycling */ rtimer_init(); @@ -274,7 +279,7 @@ uint8_t i; rimeaddr_set_node_addr(&addr); - PRINTFD("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); + PRINTF("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); /* Initialize stack protocols */ queuebuf_init(); @@ -283,19 +288,19 @@ uint8_t i; NETSTACK_NETWORK.init(); #if ANNOUNCE_BOOT - PRINTF("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); + PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac unsigned short tmp; tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ NETSTACK_RDC.channel_check_interval()); - if (tmp<65535) PRINTF(", check rate %u Hz",tmp); + if (tmp<65535) PRINTA(", check rate %u Hz",tmp); } - PRINTF("\n"); + PRINTA("\n"); #endif #if UIP_CONF_ROUTER #if ANNOUNCE_BOOT - PRINTF("Routing Enabled\n"); + PRINTA("Routing Enabled\n"); #endif // rime_init(rime_udp_init(NULL)); // uip_router_register(&rimeroute); @@ -324,9 +329,9 @@ uint8_t i; int fa = cfs_open( "/index.html", CFS_READ); if (fa<0) { //Make some default web content PRINTF("No index.html file found, creating upload.html!\n"); - PRINTF("Formatting FLASH file system for coffee..."); + PRINTA("Formatting FLASH file system for coffee..."); cfs_coffee_format(); - PRINTF("Done!\n"); + PRINTA("Done!\n"); fa = cfs_open( "/index.html", CFS_WRITE); int r = cfs_write(fa, &"It works!", 9); if (r<0) PRINTF("Can''t create /index.html!\n"); @@ -357,29 +362,29 @@ uint8_t i; for (i=0;i>10); + PRINTA(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10); #elif COFFEE_FILES==3 - PRINTF(".%s online with static %u byte program memory file system\n",buf,size); + PRINTA(".%s online with static %u byte program memory file system\n",buf,size); #elif COFFEE_FILES==4 - PRINTF(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); + PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); #endif /* COFFEE_FILES */ #else - PRINTF("Online\n"); + PRINTA("Online\n"); #endif /* WEBSERVER */ #endif /* ANNOUNCE_BOOT */ @@ -388,7 +393,7 @@ uint8_t i; /*---------------------------------------------------------------------------*/ void log_message(char *m1, char *m2) { - PRINTF("%s%s\n", m1, m2); + PRINTA("%s%s\n", m1, m2); } #if RF230BB @@ -446,7 +451,7 @@ main(void) */ extern uint8_t rf230_calibrated; if (rf230_calibrated) { - PRINTF("\nRF230 calibrated!\n"); + PRINTA("\nRF230 calibrated!\n"); rf230_calibrated=0; } #endif @@ -463,14 +468,15 @@ main(void) #if STAMPS if ((rtime%STAMPS)==0) { - PRINTF("%us ",rtime); + PRINTA("%us ",rtime); } #endif rtime+=1; #if PINGS +extern void raven_ping6(void); if ((rtime%PINGS)==1) { - PRINTF("**Ping\n"); + PRINTA("**Ping\n"); raven_ping6(); } #endif @@ -478,45 +484,43 @@ if ((rtime%PINGS)==1) { #if ROUTES if ((rtime%ROUTES)==2) { - //#if UIP_CONF_IPV6_RPL -//#include "rpl.h" extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; extern uip_ds6_route_t uip_ds6_routing_table[]; extern uip_ds6_netif_t uip_ds6_if; uint8_t i,j; - PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); + PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); for (i=0;i"); - PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + if (j) PRINTA(" "); + PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { if(uip_ds6_routing_table[i].isused) { - ipaddr_add(&uip_ds6_routing_table[i].ipaddr); - PRINTF("/%u (via ", uip_ds6_routing_table[i].length); - ipaddr_add(&uip_ds6_routing_table[i].nexthop); + uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr); + PRINTA("/%u (via ", uip_ds6_routing_table[i].length); + uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop); // if(uip_ds6_routing_table[i].state.lifetime < 600) { - PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime); + PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime); // } else { - // PRINTF(")\n"); + // PRINTA(")\n"); // } j=0; } } - if (j) PRINTF(" "); - PRINTF("\n---------\n"); + if (j) PRINTA(" "); + PRINTA("\n---------\n"); } #endif @@ -526,7 +530,7 @@ if ((rtime%STACKMONITOR)==3) { uint16_t p=(uint16_t)&__bss_end; do { if (*(uint16_t *)p != 0x4242) { - PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); + PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); break; } p+=10; @@ -542,14 +546,14 @@ if ((rtime%STACKMONITOR)==3) { extern uint8_t debugflowsize,debugflow[]; if (debugflowsize) { debugflow[debugflowsize]=0; - printf("%s",debugflow); + PRINTA("%s",debugflow); debugflowsize=0; } #endif #if RF230BB&&0 if (rf230processflag) { - printf("rf230p%d",rf230processflag); + PRINTA("rf230p%d",rf230processflag); rf230processflag=0; } #endif @@ -557,35 +561,11 @@ extern uint8_t debugflowsize,debugflow[]; #if RF230BB&&0 if (rf230_interrupt_flag) { // if (rf230_interrupt_flag!=11) { - PRINTSHORT("**RI%u",rf230_interrupt_flag); + PRINTA("**RI%u",rf230_interrupt_flag); // } rf230_interrupt_flag=0; } #endif } return 0; -} - -/*---------------------------------------------------------------------------*/ - -#if ROUTES -static void -ipaddr_add(const uip_ipaddr_t *addr) -{ - uint16_t a; - int8_t i, f; - for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { - a = (addr->u8[i] << 8) + addr->u8[i + 1]; - if(a == 0 && f >= 0) { - if(f++ == 0) PRINTF("::"); - } else { - if(f > 0) { - f = -1; - } else if(i > 0) { - PRINTF(":"); - } - PRINTF("%x",a); - } - } -} -#endif +} \ No newline at end of file From 59109b9893f5eb759511f2d2631441da706cc838 Mon Sep 17 00:00:00 2001 From: dak664 Date: Sun, 13 Mar 2011 14:08:02 -0400 Subject: [PATCH 20/27] Fix type, diagnostic interrupt code on conditional --- cpu/avr/dev/clock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpu/avr/dev/clock.c b/cpu/avr/dev/clock.c index 14a1671fb..a24afaa8c 100644 --- a/cpu/avr/dev/clock.c +++ b/cpu/avr/dev/clock.c @@ -76,6 +76,7 @@ ISR(AVR_OUTPUT_COMPARE_INT) rcount=0; radioontime++; } + } #endif #if 1 @@ -166,7 +167,7 @@ clock_seconds(void) return tmp; } -#if 1 +#ifdef HANG_ON_UNKNOWN_INTERRUPT /* Useful for diagnosing unknown interrupts that reset the mcu. * Currently set up for 12mega128rfa1. * For other mcus, enable all and then disable the conflicts. From 19c61dc5b284648a7a2584624edbdcb6708e0eb5 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sun, 13 Mar 2011 14:22:00 -0400 Subject: [PATCH 21/27] add tool to burn the mac of a single econotag --- tools/burn-mac.pl | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 tools/burn-mac.pl diff --git a/tools/burn-mac.pl b/tools/burn-mac.pl new file mode 100755 index 000000000..867d411bf --- /dev/null +++ b/tools/burn-mac.pl @@ -0,0 +1,63 @@ +#!/usr/bin/perl +use strict; +use Getopt::Long; + +my $oui; +my $addr = "0x1e000"; +my $iab; +my $term = "/dev/ttyUSB1"; + +GetOptions ('iab=s' => \$iab, + 'oui=s' => \$oui, + 'term=s' => \$term, + ) or die 'bad options'; + +my $bin = shift; +my $address = shift; + +if (!defined($address) || !defined($bin)) { + print "Usage: $0 [--iab=a8c | --oui=012345678 | --term device] flasher.bin address\n"; + die; +} + +my $mac_h; +my $mac_l; + +if(defined($iab)) { + $iab = hex($iab); + $address = hex($address); + $mac_h = 0x0050C200 | ($iab >> 4); + $mac_l = (($iab & 0xf) << 28) | $address; +} else { + $address =~ /(.*?)(.{0,8})$/; + my ($addr_h, $addr_l) = ($1, $2); + if(!$addr_h) { $addr_h = 0 }; + $oui = hex($oui); + $addr_l = hex($addr_l); + $addr_h = hex($addr_h); + $mac_h = ($oui << 8) | $addr_h; + $mac_l = $addr_l; +} + +printf("mach %x macl %x\n", $mac_h, $mac_l); + +my @words; +for(my $i=0; $i<4; $i++) { + push @words, ($mac_l >> ($i * 8)) & 0xff; +} +for(my $i=0; $i<4; $i++) { + push @words, ($mac_h >> ($i * 8)) & 0xff; +} +reverse @words; +#foreach my $byte (@words) { +# printf("%02X",$byte); +#} +#print "\n"; + +my $word1 = sprintf("%02X%02X%02X%02X",$words[4],$words[5],$words[6],$words[7]); +my $word2 = sprintf("%02X%02X%02X%02X",$words[0],$words[1],$words[2],$words[3]); + +my $cmd = "mc1322x-load.pl -e -f $bin -z -t $term -c 'bbmc -l redbee-econotag reset' $addr,0x$word1,0x$word2 &"; +print "$cmd\n"; +system($cmd); + From 51ca60b35f79e8c2d36796c4fba02d67737f219f Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sun, 13 Mar 2011 16:39:32 -0400 Subject: [PATCH 22/27] add bin2macbin.pl to create bins that will also set the mac address add usage to burn-mac.pl --- tools/bin2macbin.pl | 82 +++++++++++++++++++++++++++++++++++++++++++++ tools/burn-mac.pl | 6 ++-- 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100755 tools/bin2macbin.pl diff --git a/tools/bin2macbin.pl b/tools/bin2macbin.pl new file mode 100755 index 000000000..1c97b3243 --- /dev/null +++ b/tools/bin2macbin.pl @@ -0,0 +1,82 @@ +#!/usr/bin/perl + +use strict; +use File::Copy; +use Getopt::Long; +use File::Basename; + +my $cmd; +my $oui; +my $iab; + +GetOptions ('iab=s' => \$iab, + 'oui=s' => \$oui, + ) or die 'bad options'; + +my $address = shift; +my $infile = shift; +my $outfile = shift; + +if (!defined($address) || !defined($infile)) { + print "Usage: $0 [--iab=a8c | --oui=abcdef ] address infile [outfile]\n"; + print " iab is 12-bit and address is 28-bit e.g. --iab=a8c 1234567\n"; + print " oui is 24-bit and address is 40-bit e.g. --oui=abcdef 123456789a\n"; + print "\n"; + print " if outfile is not specified, for infile foo.bin outfile will be\n"; + print " foo-[macaddress].bin e.g:\n"; + print " for --iab=a8c 1234567 foo.bin -> foo-0050c2a8c1234567.bin\n"; + print " for --oui=abcdef 123456789a foo.bin -> foo-abcdef123456789a.bin\n"; + exit; +} + +my $mac_h; +my $mac_l; + +if(defined($iab)) { + $iab = hex($iab); + $address = hex($address); + $mac_h = 0x0050C200 | ($iab >> 4); + $mac_l = (($iab & 0xf) << 28) | $address; +} else { + $address =~ /(.*?)(.{0,8})$/; + my ($addr_h, $addr_l) = ($1, $2); + if(!$addr_h) { $addr_h = 0 }; + $oui = hex($oui); + $addr_l = hex($addr_l); + $addr_h = hex($addr_h); + $mac_h = ($oui << 8) | $addr_h; + $mac_l = $addr_l; +} + +printf("mach %x macl %x\n", $mac_h, $mac_l); + +my @words; +for(my $i=0; $i<4; $i++) { + push @words, ($mac_l >> ($i * 8)) & 0xff; +} +for(my $i=0; $i<4; $i++) { + push @words, ($mac_h >> ($i * 8)) & 0xff; +} +reverse @words; +#foreach my $byte (@words) { +# printf("%02X",$byte); +#} +#print "\n"; + +if(!defined($outfile)) +{ + my $basename = basename($infile,(".bin")); + $outfile = sprintf("-%08x%08x.bin",$mac_h, $mac_l); + $outfile = $basename . $outfile; + print "outfile $outfile\n"; +} + +copy($infile, $outfile) or die("Couldn't copy $infile to $outfile"); +$cmd = sprintf("echo -n -e '\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X\\x%02X' | dd of=$outfile bs=1 seek=122872 conv=notrunc", + $words[7],$words[6],$words[5],$words[4], + $words[3],$words[2],$words[1],$words[0]); + +print "$cmd\n"; +system("bash -c \"$cmd\""); + + diff --git a/tools/burn-mac.pl b/tools/burn-mac.pl index 867d411bf..6ea201309 100755 --- a/tools/burn-mac.pl +++ b/tools/burn-mac.pl @@ -16,8 +16,10 @@ my $bin = shift; my $address = shift; if (!defined($address) || !defined($bin)) { - print "Usage: $0 [--iab=a8c | --oui=012345678 | --term device] flasher.bin address\n"; - die; + print "Usage: $0 [--iab=a8c | --oui=abcdef | --term device] flasher.bin address\n"; + print " iab is 12-bit and address is 28-bit e.g. --iab=a8c 1234567\n"; + print " oui is 24-bit and address is 40-bit e.g. --oui=abcdef 123456789a\n"; + exit; } my $mac_h; From 59768e7bc7e4bdfb126682bc5df98ca457241d50 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Sun, 13 Mar 2011 17:48:47 -0400 Subject: [PATCH 23/27] econotag: fix problem with how IAB based mac addresses are formed --- platform/redbee-econotag/contiki-mc1322x-main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/redbee-econotag/contiki-mc1322x-main.c b/platform/redbee-econotag/contiki-mc1322x-main.c index a8b53e6c4..ff456e82c 100644 --- a/platform/redbee-econotag/contiki-mc1322x-main.c +++ b/platform/redbee-econotag/contiki-mc1322x-main.c @@ -230,11 +230,11 @@ void iab_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint16_t iab, uint32_t ext) { /* IAB */ eui64->u8[3] = (iab >> 4) & 0xff; - eui64->u8[4] = (iab & 0xf) << 4; + eui64->u8[4] = (iab << 4) & 0xf0; /* EXT */ - eui64->u8[4] = (ext >> 24) & 0xff; + eui64->u8[4] |= (ext >> 24) & 0xf; eui64->u8[5] = (ext >> 16) & 0xff; eui64->u8[6] = (ext >> 8) & 0xff; eui64->u8[7] = ext & 0xff; From bdc42d8e64dd7f06c7e31edb43b9396aeef02aba Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Mon, 14 Mar 2011 18:33:18 +0100 Subject: [PATCH 24/27] added simple example demonstrating user-defined timeout function --- tools/cooja/config/scripts/plugins.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/cooja/config/scripts/plugins.js b/tools/cooja/config/scripts/plugins.js index 48cd2097c..9e9881dd3 100644 --- a/tools/cooja/config/scripts/plugins.js +++ b/tools/cooja/config/scripts/plugins.js @@ -7,14 +7,26 @@ /* Started plugins are available from the GUI object */ -while (true) { +TIMEOUT(60000); +counter=0; +plugins=0; + +timeout_function = function my_fun() { + log.log("Script timed out.\n"); + log.log(plugins + " plugins were referenced\n"); +} + +while (counter<10) { + counter++; + GENERATE_MSG(1000, "wait"); YIELD_THEN_WAIT_UNTIL(msg.equals("wait")); /* Toggle Log Listener filter */ plugin = mote.getSimulation().getGUI().getStartedPlugin("se.sics.cooja.plugins.LogListener"); if (plugin != null) { + plugins++; log.log("LogListener: Setting filter: " + plugin.getFilter() + "\n"); if (plugin.getFilter() == null || !plugin.getFilter().equals("Contiki")) { plugin.setFilter("Contiki"); @@ -29,6 +41,7 @@ while (true) { /* Extract Timeline statistics */ plugin = mote.getSimulation().getGUI().getStartedPlugin("se.sics.cooja.plugins.TimeLine"); if (plugin != null) { + plugins++; stats = plugin.extractStatistics(); if (stats.length() > 40) { /* Stripping */ @@ -43,6 +56,7 @@ while (true) { /* Select time in Radio Logger */ plugin = mote.getSimulation().getGUI().getStartedPlugin("se.sics.cooja.plugins.RadioLogger"); if (plugin != null) { + plugins++; log.log("RadioLogger: Showing logged radio packet at mid simulation\n"); plugin.trySelectTime(time/2); } From 0829e50f4bca29e02e5654bfc1498f449de3873c Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Mon, 14 Mar 2011 19:54:58 +0100 Subject: [PATCH 25/27] get[Started]Plugin method returns plugins that end with argument + added sim and gui variables accessible from test scripts --- tools/cooja/java/se/sics/cooja/GUI.java | 17 ++++++++++++++--- .../se/sics/cooja/plugins/LogScriptEngine.java | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/GUI.java b/tools/cooja/java/se/sics/cooja/GUI.java index eb10af152..13625787f 100644 --- a/tools/cooja/java/se/sics/cooja/GUI.java +++ b/tools/cooja/java/se/sics/cooja/GUI.java @@ -1882,19 +1882,30 @@ public class GUI extends Observable { } /** - * Returns started plugin with given class name, if any. + * Returns started plugin that ends with given class name, if any. * * @param classname Class name * @return Plugin instance */ - public Plugin getStartedPlugin(String classname) { + public Plugin getPlugin(String classname) { for (Plugin p: startedPlugins) { - if (p.getClass().getName().equals(classname)) { + if (p.getClass().getName().endsWith(classname)) { return p; } } return null; } + + /** + * Returns started plugin with given class name, if any. + * + * @param classname Class name + * @return Plugin instance + * @deprecated + */ + public Plugin getStartedPlugin(String classname) { + return getPlugin(classname); + } public Plugin[] getStartedPlugins() { return startedPlugins.toArray(new Plugin[0]); diff --git a/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java b/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java index 886b605fe..4482c2934 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java +++ b/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java @@ -434,6 +434,8 @@ public class LogScriptEngine { Hashtable hash = new Hashtable(); engine.put("global", hash); + engine.put("sim", simulation); + engine.put("gui", simulation.getGUI()); scriptMote = new ScriptMote(); engine.put("node", scriptMote); From d9b5bac953b3c9012bc339aa85e58f0cec7f13f6 Mon Sep 17 00:00:00 2001 From: dak664 Date: Mon, 14 Mar 2011 16:14:47 -0400 Subject: [PATCH 26/27] Refactor with WATCHDOG_CONF_TIMEOUT --- cpu/avr/watchdog.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/cpu/avr/watchdog.c b/cpu/avr/watchdog.c index 5996027dc..9eb1807be 100644 --- a/cpu/avr/watchdog.c +++ b/cpu/avr/watchdog.c @@ -32,15 +32,28 @@ /* Watchdog routines for the AVR */ -/* Default timeout of 2 seconds is available on most MCUs */ +/* The default timeout of 2 seconds works on most MCUs. + * It should be disabled during sleep (unless used for wakeup) since + * it draws significant current (~5 uamp on 1284p, 20x the MCU consumption). + * + * Note the wdt is not properly simulated in AVR Studio 4 Simulator 1: + * On many devices calls to wdt_reset will have no effect, and a wdt reboot will occur. + * The MCUSR will not show the cause of a wdt reboot. + * A 1MHz clock is assumed; at 8MHz timeout occurs 8x faster than it should. + * Simulator 2 is supposed to work on supported devices (not atmega128rfa1), + * but neither it nor Studio 5 beta do any resets on the 1284p. + * + * Setting WATCHDOG_CONF_TIMEOUT -1 will disable the WDT. + */ +//#define WATCHDOG_CONF_TIMEOUT -1 + #ifndef WATCHDOG_CONF_TIMEOUT #define WATCHDOG_CONF_TIMEOUT WDTO_2S -//#define WATCHDOG_CONF_TIMEOUT WDTO_4S #endif - + /* While balancing start and stop calls is a good idea, an imbalance will cause * resets that can take a lot of time to track down. - * Some low power protocols may do this. + * Some low power protocols may cause this. * The default is no balance; define WATCHDOG_CONF_BALANCE 1 to override. */ #ifndef WATCHDOG_CONF_BALANCE @@ -51,7 +64,7 @@ #include #include -#if WATCHDOG_CONF_BALANCE +#if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0 static int stopped = 0; #endif @@ -59,39 +72,48 @@ static int stopped = 0; void watchdog_init(void) { +/* Clear startup bit and disable the wdt, whether or not it will be used. + Random code may have caused the last reset. + */ MCUSR&=~(1<= 0 + stopped = 1; #endif - watchdog_stop(); } /*---------------------------------------------------------------------------*/ void watchdog_start(void) { +#if WATCHDOG_CONF_TIMEOUT >= 0 #if WATCHDOG_CONF_BALANCE stopped--; if(!stopped) #endif wdt_enable(WATCHDOG_CONF_TIMEOUT); +#endif } /*---------------------------------------------------------------------------*/ void watchdog_periodic(void) { +#if WATCHDOG_CONF_TIMEOUT >= 0 #if WATCHDOG_CONF_BALANCE if(!stopped) #endif wdt_reset(); +#endif } /*---------------------------------------------------------------------------*/ void watchdog_stop(void) { +#if WATCHDOG_CONF_TIMEOUT >= 0 #if WATCHDOG_CONF_BALANCE stopped++; #endif wdt_disable(); +#endif } /*---------------------------------------------------------------------------*/ void @@ -102,3 +124,9 @@ watchdog_reboot(void) while(1); //loop } /*---------------------------------------------------------------------------*/ +#if 0 +/* Not all AVRs implement the wdt interrupt */ +ISR(WDT_vect) +{ +} +#endif \ No newline at end of file From 47391431264458a0354b86475cc20ea1d9596c31 Mon Sep 17 00:00:00 2001 From: nvt Date: Tue, 15 Mar 2011 01:16:20 +0100 Subject: [PATCH 27/27] Generalized MRHOF and added partial support for energy objects in DAG metric containers. --- core/net/rpl/rpl-icmp6.c | 18 +++++++++---- core/net/rpl/rpl-of-etx.c | 57 ++++++++++++++++++++++++--------------- core/net/rpl/rpl.h | 38 ++++++++++++++++++++------ 3 files changed, 79 insertions(+), 34 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index be919fadb..1bc70dd0f 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -250,9 +250,10 @@ dio_input(void) dio.mc.aggr = buffer[i + 4] >> 4; dio.mc.prec = buffer[i + 4] & 0xf; dio.mc.length = buffer[i + 5]; + if(dio.mc.type == RPL_DAG_MC_ETX) { - dio.mc.etx.etx = buffer[i + 6] << 8; - dio.mc.etx.etx |= buffer[i + 7]; + dio.mc.obj.etx = buffer[i + 6] << 8; + dio.mc.obj.etx |= buffer[i + 7]; PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n", (unsigned)dio.mc.type, @@ -260,7 +261,10 @@ dio_input(void) (unsigned)dio.mc.aggr, (unsigned)dio.mc.prec, (unsigned)dio.mc.length, - (unsigned)dio.mc.etx.etx); + (unsigned)dio.mc.obj.etx); + } else if(dio.mc.type == RPL_DAG_MC_ENERGY) { + dio.mc.obj.energy.flags = buffer[i + 6]; + dio.mc.obj.energy.energy_est = buffer[i + 7]; } else { PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type); return; @@ -380,8 +384,12 @@ dio_output(rpl_dag_t *dag, uip_ipaddr_t *uc_addr) buffer[pos++] |= dag->mc.prec; if(dag->mc.type == RPL_DAG_MC_ETX) { buffer[pos++] = 2; - buffer[pos++] = dag->mc.etx.etx >> 8; - buffer[pos++] = dag->mc.etx.etx & 0xff; + buffer[pos++] = dag->mc.obj.etx >> 8; + buffer[pos++] = dag->mc.obj.etx & 0xff; + } else if(dag->mc.type == RPL_DAG_MC_ENERGY) { + buffer[pos++] = 2; + buffer[pos++] = dag->mc.obj.energy.flags; + buffer[pos++] = dag->mc.obj.energy.energy_est; } else { PRINTF("RPL: Unable to send DIO because of unhandled DAG MC type %u\n", (unsigned)dag->mc.type); diff --git a/core/net/rpl/rpl-of-etx.c b/core/net/rpl/rpl-of-etx.c index e8ffefe1b..0b6265311 100644 --- a/core/net/rpl/rpl-of-etx.c +++ b/core/net/rpl/rpl-of-etx.c @@ -66,7 +66,7 @@ rpl_of_t rpl_of_etx = { #define NI_ETX_TO_RPL_ETX(etx) \ ((etx) * (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR)) -#define RPL_ETX_TO_NI_ETX(etx) \ +#define rpl_path_metric_tO_NI_ETX(etx) \ ((etx) / (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR)) /* Reject parents that have a higher link metric than the following. */ @@ -84,13 +84,12 @@ rpl_of_t rpl_of_etx = { */ #define PARENT_SWITCH_THRESHOLD_DIV 2 -typedef uint16_t rpl_etx_t; -#define MAX_ETX 65535 +typedef uint16_t rpl_path_metric_t; static uint16_t -calculate_etx(rpl_parent_t *p) +calculate_path_metric(rpl_parent_t *p) { - return p->mc.etx.etx + NI_ETX_TO_RPL_ETX(p->etx); + return p->mc.obj.etx + NI_ETX_TO_RPL_ETX(p->etx); } static void @@ -140,48 +139,64 @@ static rpl_parent_t * best_parent(rpl_parent_t *p1, rpl_parent_t *p2) { rpl_dag_t *dag; - rpl_etx_t min_diff; - rpl_etx_t p1_etx; - rpl_etx_t p2_etx; + rpl_path_metric_t min_diff; + rpl_path_metric_t p1_metric; + rpl_path_metric_t p2_metric; dag = p1->dag; /* Both parents must be in the same DAG. */ min_diff = RPL_DAG_MC_ETX_DIVISOR / PARENT_SWITCH_THRESHOLD_DIV; - p1_etx = calculate_etx(p1); - p2_etx = calculate_etx(p2); + p1_metric = calculate_path_metric(p1); + p2_metric = calculate_path_metric(p2); /* Maintain stability of the preferred parent in case of similar ranks. */ if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) { - if(p1_etx < p2_etx + min_diff && - p1_etx > p2_etx - min_diff) { + if(p1_metric < p2_metric + min_diff && + p1_metric > p2_metric - min_diff) { PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n", - p2_etx - min_diff, - p1_etx, - p2_etx + min_diff); + p2_metric - min_diff, + p1_metric, + p2_metric + min_diff); return dag->preferred_parent; } } - return p1_etx < p2_etx ? p1 : p2; + return p1_metric < p2_metric ? p1 : p2; } static void update_metric_container(rpl_dag_t *dag) { +#if RPL_DAG_MC == RPL_DAG_MC_ETX dag->mc.type = RPL_DAG_MC_ETX; dag->mc.flags = RPL_DAG_MC_FLAG_P; dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE; dag->mc.prec = 0; - dag->mc.length = sizeof(dag->mc.etx.etx); + dag->mc.length = sizeof(dag->mc.obj.etx); if(dag->rank == ROOT_RANK(dag)) { - dag->mc.etx.etx = 0; + dag->mc.obj.etx = 0; } else { - dag->mc.etx.etx = calculate_etx(dag->preferred_parent); + dag->mc.obj.etx = calculate_path_metric(dag->preferred_parent); } +#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY + dag->mc.type = RPL_DAG_MC_ENERGY; + dag->mc.flags = RPL_DAG_MC_FLAG_P; + dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE; + dag->mc.prec = 0; + dag->mc.length = sizeof(dag->mc.obj.energy); + if(dag->rank == ROOT_RANK(dag)) { + dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_MAINS << RPL_DAG_MC_ENERGY_TYPE; + } else { + dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_BATTERY << RPL_DAG_MC_ENERGY_TYPE; + } + dag->mc.obj.energy.energy_est = calculate_path_metric(dag->preferred_parent); +#else +#error "Unsupported RPL_DAG_MC configured. See rpl.h." +#endif /* RPL_DAG_MC */ PRINTF("RPL: My path ETX to the root is %u.%u\n", - dag->mc.etx.etx / RPL_DAG_MC_ETX_DIVISOR, - (dag->mc.etx.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR); + dag->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR, + (dag->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR); } diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 17a1845ec..5676ccd31 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -49,6 +49,17 @@ #define RPL_CONF_STATS 0 #endif /* RPL_CONF_STATS */ +/* + * Select routing metric supported at runtime. This must be a valid + * DAG Metric Container Object Type (see below). Currently, we only + * support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY. + */ +#ifdef RPL_CONF_DAG_MC +#define RPL_DAG_MC RPL_CONF_DAG_MC +#else +#define RPL_DAG_MC RPL_DAG_MC_ETX +#endif /* RPL_CONF_DAG_MC */ + /* * The objective function used by RPL is configurable through the * RPL_CONF_OF parameter. This should be defined to be the name of an @@ -78,8 +89,8 @@ typedef uint16_t rpl_ocp_t; /* DAG Metric Container Object Types, to be confirmed by IANA. */ #define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */ #define RPL_DAG_MC_NSA 1 /* Node State and Attributes */ -#define RPL_DAG_MC_NE 2 /* Node Energy */ -#define RPL_DAG_MC_HC 3 /* Hop Count */ +#define RPL_DAG_MC_ENERGY 2 /* Node Energy */ +#define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */ #define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */ #define RPL_DAG_MC_LATENCY 5 /* Latency */ #define RPL_DAG_MC_LQL 6 /* Link Quality Level */ @@ -99,9 +110,19 @@ typedef uint16_t rpl_ocp_t; #define RPL_DAG_MC_AGGR_MINIMUM 2 #define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3 -/* Logical representation of an ETX object in a DAG Metric Container. */ -struct rpl_metric_object_etx { - uint16_t etx; +/* The bit index within the flags field of + the rpl_metric_object_energy structure. */ +#define RPL_DAG_MC_ENERGY_INCLUDED 3 +#define RPL_DAG_MC_ENERGY_TYPE 1 +#define RPL_DAG_MC_ENERGY_ESTIMATION 0 + +#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0 +#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1 +#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2 + +struct rpl_metric_object_energy { + uint8_t flags; + uint8_t energy_est; }; /* Logical representation of a DAG Metric Container. */ @@ -111,9 +132,10 @@ struct rpl_metric_container { uint8_t aggr; uint8_t prec; uint8_t length; - /* Once we support more objects, the etx field will be replaced by a - union of those. */ - struct rpl_metric_object_etx etx; + union metric_object { + struct rpl_metric_object_energy energy; + uint16_t etx; + } obj; }; typedef struct rpl_metric_container rpl_metric_container_t; /*---------------------------------------------------------------------------*/