From bdec65b889e651601fae731689685f72d647aef2 Mon Sep 17 00:00:00 2001 From: David Kopf Date: Sun, 28 Aug 2011 16:04:36 -0400 Subject: [PATCH 1/4] Fix typos and file endings --- cpu/avr/dev/clock.c | 2 +- cpu/avr/radio/rf230bb/rf230bb.h | 4 ++-- platform/avr-ravenusb/contiki-raven-main.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpu/avr/dev/clock.c b/cpu/avr/dev/clock.c index e433eefcf..b71c8660e 100644 --- a/cpu/avr/dev/clock.c +++ b/cpu/avr/dev/clock.c @@ -253,4 +253,4 @@ 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 +#endif diff --git a/cpu/avr/radio/rf230bb/rf230bb.h b/cpu/avr/radio/rf230bb/rf230bb.h index 6693f7aec..33be07373 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.h +++ b/cpu/avr/radio/rf230bb/rf230bb.h @@ -9,6 +9,7 @@ * Mike Vidales mavida404@gmail.com * Kevin Brown kbrown3@uccs.edu * Nate Bohlmann nate@elfwerks.com + * David Kopf dak664@embarqmail.com * * All rights reserved. * @@ -45,7 +46,6 @@ * \file * \brief This file contains radio driver code. * - * $Id: rf230bb.h,v 1.6 2010/12/15 16:50:44 dak664 Exp $ */ #ifndef RADIO_H @@ -228,4 +228,4 @@ uint8_t rf230_get_raw_rssi(void); #endif /** @} */ -/*EOF*/ \ No newline at end of file +/*EOF*/ diff --git a/platform/avr-ravenusb/contiki-raven-main.c b/platform/avr-ravenusb/contiki-raven-main.c index edd3b7b71..59595170e 100644 --- a/platform/avr-ravenusb/contiki-raven-main.c +++ b/platform/avr-ravenusb/contiki-raven-main.c @@ -280,7 +280,7 @@ uint16_t eemem_panid EEMEM = IEEE802154_PANID; uint16_t eemem_panid EEMEM = 0xABCD; #endif #ifdef IEEE802154_PANADDR -uint16_t eemem_panaddr EEMEM = IEEE802154_PANID; +uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR; #else uint16_t eemem_panaddr EEMEM = 0; #endif From 5f2b2074f091f5d622ff96ae58da350eba5adbc7 Mon Sep 17 00:00:00 2001 From: David Kopf Date: Sun, 28 Aug 2011 16:11:48 -0400 Subject: [PATCH 2/4] Implement WITH_RPL option in makefile --- cpu/avr/Makefile.avr | 4 ++++ examples/webserver-ipv6-raven/Makefile.webserver | 2 ++ examples/webserver-ipv6-raven/README | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/cpu/avr/Makefile.avr b/cpu/avr/Makefile.avr index 623879372..a98c8e44d 100644 --- a/cpu/avr/Makefile.avr +++ b/cpu/avr/Makefile.avr @@ -34,6 +34,10 @@ CONTIKI_TARGET_SOURCEFILES += $(USB) //AVR = clock.c mtarch.c eeprom.c flash.c leds-arch.c watchdog.c rtimer-arch.c endif +ifdef WITH_RPL + CFLAGS += -DUIP_CONF_IPV6_RPL=$(WITH_RPL) +endif + #For a coffee file system, the application makefile can define COFFEE_FILES=n #to select the type and COFFEE_ADDRESS=0xaaaaaaaa as the starting byte address. #If only one is define the other will use the (Raven webserver 1284p) defaults diff --git a/examples/webserver-ipv6-raven/Makefile.webserver b/examples/webserver-ipv6-raven/Makefile.webserver index 3faa39b7a..fb7f12964 100644 --- a/examples/webserver-ipv6-raven/Makefile.webserver +++ b/examples/webserver-ipv6-raven/Makefile.webserver @@ -4,6 +4,8 @@ all: webserver6 APPS=raven-webserver raven-lcd-interface TARGET=avr-raven UIP_CONF_IPV6=1 + +#WITH_RPL=1 //RPL is not yet the default. #RF230BB=1 //Use radio driver that communicates with the core MAC layer. Now the default. #COFFEE_FILES=1 //Use coffee file system in EEPROM #COFFEE_FILES=2 //Use coffee file system in program flash diff --git a/examples/webserver-ipv6-raven/README b/examples/webserver-ipv6-raven/README index ad7d725fd..50d5887d6 100644 --- a/examples/webserver-ipv6-raven/README +++ b/examples/webserver-ipv6-raven/README @@ -40,3 +40,15 @@ $make WEBDIR=xxx always forces regeneration of web content into httpd-fsdata.c a so requires PERL. A bare $make after that will not regenerate httpd-fsdata.c. Use $make WEBDIR=default to switch back to the default /http-fs/ content. +See Makefile.webserver for optional switches for RPL or a coffee file system. +$make WITH_RPL=1 for a RPL node, or if rpl has become the contiki default, +$make WITH_RPL=0 to override + +Much headbanging can result if you do not $make clean when changing make options, +as the normal build dependencies are bypassed and the needed object modules +may not be rebuilt. + +$make connect will invoke the /tools/serial-log.pl perl script to connect to +your serial debug port. This will log to the console and optional log file, +adding useful time stamps. Edit the makefile for your serial port configuration. + From 4c4d9aa57c894d56451f4f228bd2551bee5c9d3a Mon Sep 17 00:00:00 2001 From: David Kopf Date: Sun, 28 Aug 2011 16:12:41 -0400 Subject: [PATCH 3/4] Add serial logging tool. --- tools/serial-log.pl | 124 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 tools/serial-log.pl diff --git a/tools/serial-log.pl b/tools/serial-log.pl new file mode 100644 index 000000000..81b49a515 --- /dev/null +++ b/tools/serial-log.pl @@ -0,0 +1,124 @@ +#!/usr/bin/perl -w +#Log serial port to terminal and file with timestamps +#D.Kopf 8/28/2001 +# + +use Device::SerialPort; +use Term::ReadKey; +use Getopt::Long; +use Time::HiRes qw(usleep); + +use strict; + +my $term = '/dev/com1'; +my $baud = '57600'; +my $rts = 'none'; +my $logfile = 'none'; +my $ssss = ''; + +GetOptions ('terminal=s' => \$term, + 'baud=s' => \$baud, + 'rts=s' => \$rts, + 'seconds!' => \$ssss, + 'logfile:s' =>\$logfile +) or goto printhelp; +goto bypass; +printhelp: + print "Example serial-log.pl -t /dev/ttyS0 -b 57600 -r none -l logfile\n"; + print " -t, --terminal\n"; + print " -b, --baud\n"; + print " -r,--rts [none|rts] flow control\n"; + print " -s,--seconds Display ssss instead of hh:mm:ss\n"; + print " -l,--logfile outputfile (.log will be added, -l defaults to serial.log)\n"; + print "\n"; + print "The default is equivalent to serial-log.pl -t /dev/com1 -b 57600 -r none\n"; + exit; +bypass: + +my $ob = Device::SerialPort->new ($term) or die "Can't start $term\n"; + # next test will die at runtime unless $ob + +$ob->baudrate($baud); +$ob->parity('none'); +$ob->databits(8); +$ob->stopbits(1); +if($rts eq 'rts') { + $ob->handshake('rts'); +} else { + $ob->handshake('none'); +} +$ob->read_const_time(1000); # 1 second per unfulfilled "read" call +$ob->rts_active(1); + +my $c; my $count; +my ($hh,$mm,$ss,$mday,$mon,$year,$wday,$yday,$isdst,$theTime,$seconds,$startseconds); +#use POSIX qw(strftime); + +($ss,$mm,$hh,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; +$theTime = sprintf "on %02d/%02d/%04d at %02d:%02d:%02d\n", $mon+1, $mday, $year+1900, $hh, $mm, $ss; +if($logfile ne 'none') { + if($logfile eq '') {$logfile = 'serial';} + $logfile ="${logfile}.log"; + $c=1; + open LOGFILE, "$logfile" or do {$c=0;}; + if ($c) { + print "File $logfile exists. Restart, append, or quit (r,a,q) (q) ? "; + #$| = 1; # force a flush after print + $_ = ;chomp; + if ($_ eq 'r') { + open LOGFILE, ">$logfile" or die $!; + print "Restarting $logfile $theTime\n"; + print LOGFILE "serial-log.pl logging to $logfile started $theTime\n"; + } else { + if ($_ eq 'a') { + open LOGFILE, ">>$logfile" or die $!; + print "Appending to $logfile $theTime\n"; + print LOGFILE "serial-log.pl appending to $logfile $theTime\n"; + } else { + print "Quitting, file unchanged.\n"; + exit; + } + } + } else { + open LOGFILE, ">$logfile" or die $!; + print LOGFILE "serial-log.pl logging to $logfile started $theTime\n"; + print "Starting $logfile $theTime\n"; + + } + LOGFILE->autoflush(1); +} else { + $logfile=''; + print "Serial logging of $term started $theTime\n"; +} +if($ssss ne '') { + $startseconds=$hh*3600+$mm*60+$ss; +} + +$theTime=''; + +while(1) { + ($count, $c) = $ob->read(1); + if (defined($count) && ($count != 0)) { + if ($theTime eq '') { + ($ss,$mm,$hh) = localtime(time); + if ($ssss ne '') { + $seconds = $hh*3600+$mm*60+$ss-$startseconds; + if ($seconds < 0) {$seconds+=24*60*60;} + $theTime = sprintf("%04d ",$seconds); + } else { + $theTime = sprintf("%02d:%02s:%02d ", $hh,$mm,$ss); + #$theTime = strftime "%H:%M:%S ", localtime; + } + print $theTime ; + if ($logfile) {LOGFILE->autoflush(1);print LOGFILE $theTime;} + } + print $c ; + if ($logfile) { print LOGFILE $c;} + if ($c eq "\n") {$theTime=''}; + } +} +if ($logfile) {close LOGFILE or die $!} +$ob -> close or die "Serial port close failed: $!\n"; +ReadMode 0; +undef $ob; # closes port AND frees memory in perl +exit; From d2aece89ef18111c9bbfca20a46b369d4097d621 Mon Sep 17 00:00:00 2001 From: David Kopf Date: Sun, 28 Aug 2011 16:22:39 -0400 Subject: [PATCH 4/4] Add settings manager with program flash defaults, random routine, periodic prints with ENERGEST, node-id. --- examples/webserver-ipv6-raven/Makefile | 5 + .../apps/raven-lcd-interface/raven-lcd.c | 12 +- .../raven-webserver/httpd-fs/makefsdata.h | 9 +- platform/avr-raven/contiki-conf.h | 13 +- platform/avr-raven/contiki-raven-main.c | 576 +++++++++++++----- platform/avr-raven/node-id.h | 45 ++ 6 files changed, 507 insertions(+), 153 deletions(-) create mode 100644 platform/avr-raven/node-id.h diff --git a/examples/webserver-ipv6-raven/Makefile b/examples/webserver-ipv6-raven/Makefile index a9b6f3e6b..a61e71506 100644 --- a/examples/webserver-ipv6-raven/Makefile +++ b/examples/webserver-ipv6-raven/Makefile @@ -27,3 +27,8 @@ clean: # rm ../../platform/avr-raven/apps/raven-webserver/httpd-fsdata.c rm symbols.c symbols.h webserver6.elf $(OUTFILE).elf $(OUTFILE).hex rm -rf obj_avr-raven + +connect: +#Connect to serial debug port for timestamp log (requires PERL). +#Change the baud rate and device to agree with your serial connection. + ../../tools/serial-log.pl -b 57600 -t /dev/com1 -l \ No newline at end of file diff --git a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c index dafc52a9b..635ed9a73 100644 --- a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c +++ b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c @@ -452,12 +452,12 @@ raven_lcd_show_text(char *text) { static void lcd_show_servername(void) { -//extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h -extern uint8_t server_name[16]; -//extern uint8_t domain_name[30]; -char buf[sizeof(server_name)+1]; - eeprom_read_block (buf,server_name, sizeof(server_name)); - buf[sizeof(server_name)]=0; +//extern uint8_t eemem_mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h +extern uint8_t eemem_server_name[16]; +//extern uint8_t eemem_domain_name[30]; +char buf[sizeof(eemem_server_name)+1]; + eeprom_read_block (buf,eemem_server_name, sizeof(eemem_server_name)); + buf[sizeof(eemem_server_name)]=0; raven_lcd_show_text(buf); //must fit in all the buffers or it will be truncated! } #endif diff --git a/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h b/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h index 612ebf949..b146f8dc6 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h +++ b/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h @@ -1,7 +1,10 @@ #include /* Link layer ipv6 address will become fe80::11:22ff:fe33:4455 */ -uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; -uint8_t server_name[16] EEMEM = "Contiki-Raven"; -uint8_t domain_name[30] EEMEM = "localhost"; +uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; +uint8_t default_server_name[16] PROGMEM = "Contiki-Raven"; +uint8_t default_domain_name[30] PROGMEM = "localhost"; +uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; +uint8_t eemem_server_name[16] EEMEM = "Contiki-Raven"; +uint8_t eemem_domain_name[30] EEMEM = "localhost"; diff --git a/platform/avr-raven/contiki-conf.h b/platform/avr-raven/contiki-conf.h index b9e72fedb..9213758a9 100644 --- a/platform/avr-raven/contiki-conf.h +++ b/platform/avr-raven/contiki-conf.h @@ -99,11 +99,22 @@ unsigned long clock_seconds(void); //#define RADIO_CONF_CALIBRATE_INTERVAL 256 /* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */ -#define RADIOSTATS 1 +#define RADIOSTATS 1 + +/* More extensive stats */ +#define ENERGEST_CONF_ON 0 + +/* Use settings manager to save configuration in EEPROM */ +/* Adds ~1700 bytes to progmem */ +#define CONTIKI_CONF_SETTINGS_MANAGER 1 /* Possible watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */ +/* AVR Studio simulator tends to reboot due to clocking the WD 8 times too fast */ //#define WATCHDOG_CONF_TIMEOUT -1 +/* Debugflow macro, useful for tracing path through mac and radio interrupts */ +//#define DEBUGFLOWSIZE 128 + /* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */ #if RF230BB #undef PACKETBUF_CONF_HDR_SIZE //Use the packetbuf default for header size diff --git a/platform/avr-raven/contiki-raven-main.c b/platform/avr-raven/contiki-raven-main.c index ff0865934..3a362be4e 100644 --- a/platform/avr-raven/contiki-raven-main.c +++ b/platform/avr-raven/contiki-raven-main.c @@ -30,14 +30,28 @@ * * @(#)$$ */ -#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size +#if ANNOUNCE_BOOT +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) +#endif + #define DEBUG 0 #if DEBUG -#define PRINTFD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) #else -#define PRINTFD(...) +#define PRINTD(...) +#endif + +/* Track interrupt flow through mac, rdc and radio driver */ +#if DEBUGFLOWSIZE +uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; +#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c +#else +#define DEBUGFLOW(c) #endif #include @@ -93,85 +107,334 @@ #include "net/rime.h" -/* Test rtimers, also for pings, stack monitor, neighbor/route printout and time stamps */ -#define TESTRTIMER 0 -#if TESTRTIMER +/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */ +/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */ +/* STAMPS will print ENERGEST outputs if that is enabled. */ +#define PERIODICPRINTS 1 +#if PERIODICPRINTS //#define PINGS 64 -#define ROUTES 300 +#define ROUTES 600 #define STAMPS 60 #define STACKMONITOR 600 - +uint32_t clocktime; +#define TESTRTIMER 0 +#if TESTRTIMER 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 +#endif -#endif /* TESTRTIMER */ +#if WITH_NODE_ID +uint16_t node_id; +#endif /*-------------------------------------------------------------------------*/ /*----------------------Configuration of the .elf file---------------------*/ -typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t; +#if 1 +/* The proper way to set the signature is */ +#include +#else +/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ +typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t; #define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) SIGNATURE = { -/* Older AVR-GCCs may not define the SIGNATURE_n bytes so use explicit 1284p values */ - .B2 = 0x05,//SIGNATURE_2, - .B1 = 0x97,//SIGNATURE_1, - .B0 = 0x1E,//SIGNATURE_0, + .B2 = 0x05,//SIGNATURE_2, //ATMEGA1284p + .B1 = 0x97,//SIGNATURE_1, //128KB flash + .B0 = 0x1E,//SIGNATURE_0, //Atmel }; +#endif + +/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */ FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,}; -/*----------------------Configuration of EEPROM---------------------------*/ -/* Use existing EEPROM if it passes the integrity test, else reinitialize with build values */ - -/* Put default MAC address in EEPROM */ +/* Put the default settings into program flash memory */ +/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */ #if AVR_WEBSERVER -extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h -extern uint8_t server_name[16]; -extern uint8_t domain_name[30]; +extern uint8_t default_mac_address[8]; +extern uint8_t default_server_name[16]; +extern uint8_t default_domain_name[30]; #else -uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; +#ifdef MAC_ADDRESS +uint8_t default_mac_address[8] PROGMEM = MAC_ADDRESS; +#else +uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; #endif +#ifdef SERVER_NAME +uint8_t default_server_name[16] PROGMEM = SERVER_NAME; +#else +uint8_t default_server_name[16] PROGMEM = "Raven_webserver"; +#endif +#ifdef DOMAIN_NAME +uint8_t default_domain_name[30] PROGMEM = DOMAIN_NAME +#else +uint8_t default_domain_name[30] PROGMEM = "localhost"; +#endif +#endif /* AVR_WEBSERVER */ - +#ifdef NODE_ID +uint16_t default_nodeid PROGMEM = NODEID; +#else +uint16_t default_nodeid PROGMEM = 0; +#endif #ifdef CHANNEL_802_15_4 -uint8_t rf_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4}; +uint8_t default_channel PROGMEM = CHANNEL_802_15_4; #else -uint8_t rf_channel[2] EEMEM = {22, ~22}; +uint8_t default_channel PROGMEM = 26; +#endif +#ifdef IEEE802154_PANID +uint16_t default_panid PROGMEM = IEEE802154_PANID; +#else +uint16_t default_panid PROGMEM = 0xABCD; +#endif +#ifdef IEEE802154_PANADDR +uint16_t default_panaddr PROGMEM = IEEE802154_PANID; +#else +uint16_t default_panaddr PROGMEM = 0; +#endif +#ifdef RF230_MAX_TX_POWER +uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER; +#else +uint8_t default_txpower PROGMEM = 0; #endif - volatile uint8_t eeprom_channel; -static uint8_t get_channel_from_eeprom() { -// volatile uint8_t eeprom_channel; - uint8_t eeprom_check; - eeprom_channel = eeprom_read_byte(&rf_channel[0]); - eeprom_check = eeprom_read_byte(&rf_channel[1]); - if(eeprom_channel==~eeprom_check) - return eeprom_channel; +/* Get a pseudo random number using the ADC */ +static uint8_t +rng_get_uint8(void) { +uint8_t i,j; + ADCSRA=1< 26)) x[1]=x[0]; +/* Do exclusive or test on the two values read */ + if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit +/* Verification fails, rewrite everything */ + uint8_t i,buffer[32]; + PRINTD("EEPROM is corrupt, rewriting with defaults.\n"); +#if CONTIKI_CONF_RANDOM_MAC + PRINTA("Generating random MAC address.\n"); + generate_new_eui64(&buffer); +#else + for (i=0;i26)) { + PRINTF("Unusual RF channel %u in EEPROM\n",x); + } + PRINTD("<=Get RF channel %u.\n",x); + } else { + x = pgm_read_byte_near(&default_channel); + if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM RF channel to %d.\n",x); + } + } + return x; } - -void calibrate_rc_osc_32k(); +static bool +get_eui64_from_eeprom(uint8_t macptr[8]) { + size_t size = sizeof(rimeaddr_t); + if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)macptr, &size) == SETTINGS_STATUS_OK) { + PRINTD("<=Get MAC address.\n"); + return true; + } +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("--Generating random MAC address.\n"); + generate_new_eui64(macptr); +#else + {uint8_t i;for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);} +#endif + if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)macptr,8)) { + PRINTD("->Set EEPROM MAC address.\n"); + } + return true; +} +static uint16_t +get_panid_from_eeprom(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN ID of %04x.\n",x); + } else { + x=pgm_read_word_near(&default_panid); + if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN ID to %04x.\n",x); + } + } + return x; +} +static uint16_t +get_panaddr_from_eeprom(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN address of %04x.\n",x); + } else { + x=pgm_read_word_near(&default_panaddr); + if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN address to %04x.\n",x); + } + } + return x; +} +static uint8_t +get_txpower_from_eeprom(void) { + uint8_t x; + size_t size = 1; + if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get tx power of %d. (0=max)\n",x); + } else { + x=pgm_read_byte_near(&default_txpower); + if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM tx power of %d. (0=max)\n",x); + } + } + return x; +} +#endif /* CONTIKI_CONF_SETTINGS_MANAGER */ /*-------------------------Low level initialization------------------------*/ /*------Done in a subroutine to keep main routine stack usage small--------*/ @@ -195,7 +458,7 @@ void initialize(void) #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 + * loop. In conjuction with PERIODICPRINTS, never-used stack will be printed * every STACKMONITOR seconds. */ { @@ -212,23 +475,18 @@ uint16_t p=(uint16_t)&__bss_end; * Some layers will ignore duplicates found in a history (e.g. Contikimac) * causing the initial packets to be ignored after a short-cycle restart. */ - ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference. - ADCSRA=1< //#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) // delay_us(50000); @@ -237,16 +495,15 @@ uint8_t i; } #endif -#if ANNOUNCE_BOOT - PRINTF("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); -#endif + PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); /* rtimers needed for radio cycling */ rtimer_init(); /* Initialize process subsystem */ process_init(); - /* etimers must be started before ctimer_init */ + + /* etimers must be started before ctimer_init */ process_start(&etimer_process, NULL); #if RF230BB @@ -258,22 +515,37 @@ uint8_t i; /* Set addresses BEFORE starting tcpip process */ rimeaddr_t addr; - memset(&addr, 0, sizeof(rimeaddr_t)); - get_mac_from_eeprom(addr.u8); +// memset(&addr, 0, sizeof(rimeaddr_t)); + get_eui64_from_eeprom(addr.u8); #if UIP_CONF_IPV6 - memcpy(&uip_lladdr.addr, &addr.u8, 8); + memcpy(&uip_lladdr.addr, &addr.u8, sizeof(rimeaddr_t)); +#elif WITH_NODE_ID + node_id=get_panaddr_from_eeprom(); + addr.u8[1]=node_id&0xff; + addr.u8[0]=(node_id&0xff00)>>8; + PRINTA("Node ID from eeprom: %X\n",node_id); #endif + rimeaddr_set_node_addr(&addr); + rf230_set_pan_addr( get_panid_from_eeprom(), get_panaddr_from_eeprom(), (uint8_t *)&addr.u8 ); rf230_set_channel(get_channel_from_eeprom()); + rf230_set_txpower(get_txpower_from_eeprom()); - 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]); +#if UIP_CONF_IPV6 + PRINTA("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); +#else + PRINTA("MAC address "); + uint8_t i; + for (i=sizeof(rimeaddr_t); i>0; i--){ + PRINTA("%x:",addr.u8[i-1]); + } + PRINTA("\n"); +#endif /* Initialize stack protocols */ queuebuf_init(); @@ -282,20 +554,20 @@ 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 power %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()),rf230_get_txpower(); 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) PRINTA(", check rate %u Hz",tmp); } - PRINTF("\n"); + PRINTA("\n"); #if UIP_CONF_IPV6_RPL - PRINTF("RPL Enabled\n"); + PRINTA("RPL Enabled\n"); #endif #if UIP_CONF_ROUTER - PRINTF("Routing Enabled\n"); + PRINTA("Routing Enabled\n"); #endif #endif /* ANNOUNCE_BOOT */ @@ -305,12 +577,12 @@ uint8_t i; process_start(&tcpip_process, NULL); -#else +#else /* !RF230BB */ /* Original RF230 combined mac/radio driver */ /* mac process must be started before tcpip process! */ process_start(&mac_process, NULL); process_start(&tcpip_process, NULL); -#endif /*RF230BB*/ +#endif /* RF230BB */ #ifdef RAVEN_LCD_INTERFACE process_start(&raven_lcd_process, NULL); @@ -326,13 +598,13 @@ uint8_t i; #if COFFEE_FILES 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("No index.html file found, creating upload.html!\n"); + 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"); + if (r<0) PRINTA("Can''t create /index.html!\n"); cfs_close(fa); // fa = cfs_open("upload.html"), CFW_WRITE); //
@@ -351,7 +623,7 @@ uint8_t i; /*--------------------------Announce the configuration---------------------*/ #if ANNOUNCE_BOOT - +{ #if AVR_WEBSERVER uint8_t i; char buf[80]; @@ -360,36 +632,59 @@ 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 /* AVR_WEBSERVER */ #endif /* ANNOUNCE_BOOT */ } +} -#if RF230BB -extern char rf230_interrupt_flag, rf230processflag; +#if ROUTES && UIP_CONF_IPV6 +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 /*-------------------------------------------------------------------------*/ @@ -422,39 +717,64 @@ main(void) */ extern uint8_t rf230_calibrated; if (rf230_calibrated) { - PRINTF("\nRF230 calibrated!\n"); + PRINTD("\nRF230 calibrated!\n"); rf230_calibrated=0; } #endif +#if DEBUGFLOWSIZE + if (debugflowsize) { + debugflow[debugflowsize]=0; + PRINTF("%s",debugflow); + debugflowsize=0; + } +#endif + + watchdog_periodic(); + +#if PERIODICPRINTS #if TESTRTIMER -/* Timeout can be increased up to 8 seconds maximum (at 8MHz with 1024 prescaler) +/* Timeout can be increased up to 8 seconds maximum. * A one second cycle is convenient for triggering the various debug printouts. * The triggers are staggered to avoid printing everything at once. */ if (rtimerflag) { rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); rtimerflag=0; +#else + if (clocktime!=clock_seconds()) { + clocktime=clock_seconds(); +#endif #if STAMPS -if ((rtime%STAMPS)==0) { - PRINTF("%us ",rtime); +if ((clocktime%STAMPS)==0) { +#if ENERGEST_CONF_ON +#include "lib/print-stats.h" + print_stats(); +#elif RADIOSTATS +extern volatile unsigned long radioontime; + PRINTF("%u(%u)s\n",clocktime,radioontime); +#else + PRINTF("%us\n",clocktime); +#endif + } #endif - rtime+=1; +#if TESTRTIMER + clocktime+=1; +#endif -#if PINGS -if ((rtime%PINGS)==1) { +#if PINGS && UIP_CONF_IPV6 +extern void raven_ping6(void); +if ((clocktime%PINGS)==1) { PRINTF("**Ping\n"); raven_ping6(); } #endif -#if ROUTES -if ((rtime%ROUTES)==2) { +#if ROUTES && UIP_CONF_IPV6 +if ((clocktime%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; @@ -462,7 +782,7 @@ extern uip_ds6_netif_t uip_ds6_if; uint8_t i,j; PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); for (i=0;iu8[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/node-id.h b/platform/avr-raven/node-id.h new file mode 100644 index 000000000..6c3a2d9c7 --- /dev/null +++ b/platform/avr-raven/node-id.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + */ + +#ifndef NODE_ID_H +#define NODE_ID_H + +#include "contiki-conf.h" + +void node_id_restore(void); +void node_id_burn(uint16_t node_id); + +extern uint16_t node_id; + +#endif /* !NODE_ID_H */