33 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
35 #define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
37 #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
44 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
51 uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
52 #define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
57 #include <avr/pgmspace.h>
59 #include <avr/eeprom.h>
62 #include <dev/watchdog.h>
63 #include "lib/sensors.h"
64 #include "dev/button-sensor.h"
67 #include "loader/symbols-def.h"
68 #include "loader/symtab.h"
70 #if RF230BB //radio driver using contiki core mac
76 #else //radio driver using Atmel/Cisco 802.15.4'ish MAC
79 #include "sicslowmac.h"
85 #include "contiki-net.h"
86 #include "contiki-lib.h"
89 #include "dev/rs232.h"
95 #include "httpd-cgi.h"
103 #if UIP_CONF_ROUTER&&0
104 #include "net/routing/rimeroute.h"
109 #include "sys/sprofiling.h"
110 #include "sys/profiling.h"
115 #define PERIODICPRINTS 1
120 #define STACKMONITOR 600
124 uint8_t rtimerflag=1;
126 void rtimercycle(
void) {rtimerflag=1;}
138 #include <avr/signature.h>
141 typedef struct {
const unsigned char B2;
const unsigned char B1;
const unsigned char B0;} __signature_t;
142 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
151 FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
156 extern uint8_t default_mac_address[8];
157 extern uint8_t default_server_name[16];
158 extern uint8_t default_domain_name[30];
161 const uint8_t default_mac_address[8] PROGMEM = MAC_ADDRESS;
163 const uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
166 const uint8_t default_server_name[16] PROGMEM = SERVER_NAME;
168 const uint8_t default_server_name[16] PROGMEM =
"Raven_webserver";
171 const uint8_t default_domain_name[30] PROGMEM = DOMAIN_NAME
173 const uint8_t default_domain_name[30] PROGMEM =
"localhost";
178 const uint16_t default_nodeid PROGMEM = NODEID;
180 const uint16_t default_nodeid PROGMEM = 0;
182 #ifdef CHANNEL_802_15_4
183 const uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
185 const uint8_t default_channel PROGMEM = 26;
187 #ifdef IEEE802154_PANID
188 const uint16_t default_panid PROGMEM = IEEE802154_PANID;
190 const uint16_t default_panid PROGMEM = 0xABCD;
192 #ifdef IEEE802154_PANADDR
193 const uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
195 const uint16_t default_panaddr PROGMEM = 0;
197 #ifdef RF230_MAX_TX_POWER
198 const uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
200 const uint8_t default_txpower PROGMEM = 0;
205 rng_get_uint8(
void) {
212 while (ADCSRA&(1<<ADSC));
216 PRINTD(
"rng issues %d\n",j);
220 #if CONTIKI_CONF_RANDOM_MAC
222 generate_new_eui64(uint8_t eui64[8]) {
224 eui64[1] = rng_get_uint8();
225 eui64[2] = rng_get_uint8();
228 eui64[5] = rng_get_uint8();
229 eui64[6] = rng_get_uint8();
230 eui64[7] = rng_get_uint8();
234 #if !CONTIKI_CONF_SETTINGS_MANAGER
243 extern uint8_t eemem_mac_address[8];
244 extern uint8_t eemem_server_name[16];
245 extern uint8_t eemem_domain_name[30];
248 uint8_t eemem_mac_address[8] EEMEM = MAC_ADDRESS;
250 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
253 uint8_t eemem_server_name[16] EEMEM = SERVER_NAME;
255 uint8_t eemem_server_name[16] EEMEM =
"Raven_webserver";
258 uint8_t eemem_domain_name[30] EEMEM = DOMAIN_NAME
260 uint8_t eemem_domain_name[30] EEMEM =
"localhost";
265 uint16_t eemem_nodeid EEMEM = NODEID;
267 uint16_t eemem_nodeid EEMEM = 0;
269 #ifdef CHANNEL_802_15_4
270 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
272 uint8_t eemem_channel[2] EMEM = {26, ~26};
274 #ifdef IEEE802154_PANID
275 uint16_t eemem_panid EEMEM = IEEE802154_PANID;
277 uint16_t eemem_panid EEMEM = 0xABCD;
279 #ifdef IEEE802154_PANADDR
280 uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
282 uint16_t eemem_panaddr EEMEM = 0;
284 #ifdef RF230_MAX_TX_POWER
285 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
287 uint8_t eemem_txpower EEMEM = 0;
291 get_channel_from_eeprom() {
293 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
295 if( (x[0]<11) || (x[0] > 26)) x[1]=x[0];
297 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
299 uint8_t i,buffer[32];
300 PRINTD(
"EEPROM is corrupt, rewriting with defaults.\n");
301 #if CONTIKI_CONF_RANDOM_MAC
302 PRINTA(
"Generating random MAC address.\n");
303 generate_new_eui64(&buffer);
305 for (i=0;i<
sizeof(default_mac_address);i++) buffer[i] = pgm_read_byte_near(default_mac_address+i);
308 eeprom_write_block(&buffer, &eemem_mac_address,
sizeof(eemem_mac_address));
309 for (i=0;i<
sizeof(default_server_name);i++) buffer[i] = pgm_read_byte_near(default_server_name+i);
310 eeprom_write_block(&buffer, &eemem_server_name,
sizeof(eemem_server_name));
311 for (i=0;i<
sizeof(default_domain_name);i++) buffer[i] = pgm_read_byte_near(default_domain_name+i);
312 eeprom_write_block(&buffer, &eemem_domain_name,
sizeof(eemem_domain_name));
313 eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
314 eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
315 eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
316 eeprom_write_word(&eemem_nodeid, pgm_read_word_near(&default_nodeid));
317 x[0] = pgm_read_byte_near(&default_channel);
319 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
326 get_eui64_from_eeprom(uint8_t macptr[
sizeof(rimeaddr_t)]) {
328 eeprom_read_block ((
void *)macptr, &eemem_mac_address,
sizeof(rimeaddr_t));
330 return macptr[0]!=0xFF;
337 get_panid_from_eeprom(
void) {
338 return IEEE802154_PANID;
341 get_panaddr_from_eeprom(
void) {
342 return eeprom_read_word (&eemem_panaddr);
345 get_txpower_from_eeprom(
void)
347 return eeprom_read_byte(&eemem_txpower);
352 #include "settings.h"
355 #define settings_add(...) 0
356 #define settings_add_uint8(...) 0
357 #define settings_add_uint16(...) 0
361 extern uint8_t eemem_mac_address[8];
362 extern uint8_t eemem_server_name[16];
363 extern uint8_t eemem_domain_name[30];
367 get_channel_from_eeprom() {
371 if (settings_get(SETTINGS_KEY_CHANNEL, 0,(
unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
372 if ((x<11) || (x>26)) {
373 PRINTF(
"Unusual RF channel %u in EEPROM\n",x);
375 PRINTD(
"<=Get RF channel %u.\n",x);
377 x = pgm_read_byte_near(&default_channel);
378 if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) {
379 PRINTD(
"->Set EEPROM RF channel to %d.\n",x);
388 get_eui64_from_eeprom(uint8_t macptr[8]) {
389 size_t size =
sizeof(rimeaddr_t);
390 if(settings_get(SETTINGS_KEY_EUI64, 0, (
unsigned char*)macptr, &size) == SETTINGS_STATUS_OK) {
391 PRINTD(
"<=Get MAC address.\n");
394 #if CONTIKI_CONF_RANDOM_MAC
395 PRINTD(
"--Generating random MAC address.\n");
396 generate_new_eui64(macptr);
398 {uint8_t i;
for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
400 if (settings_add(SETTINGS_KEY_EUI64,(
unsigned char*)macptr,8)) {
401 PRINTD(
"->Set EEPROM MAC address.\n");
410 get_panid_from_eeprom(
void) {
411 return IEEE802154_PANID;
414 get_panaddr_from_eeprom(
void) {
417 if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(
unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
418 PRINTD(
"<-Get PAN address of %04x.\n",x);
420 x=pgm_read_word_near(&default_panaddr);
421 if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
422 PRINTD(
"->Set EEPROM PAN address to %04x.\n",x);
428 get_txpower_from_eeprom(
void) {
431 if (settings_get(SETTINGS_KEY_TXPOWER, 0,(
unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
432 PRINTD(
"<-Get tx power of %d. (0=max)\n",x);
434 x=pgm_read_byte_near(&default_txpower);
435 if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
436 PRINTD(
"->Set EEPROM tx power of %d. (0=max)\n",x);
445 void initialize(
void)
448 extern void *watchdog_return_addr;
451 void *wdt_addr = watchdog_return_addr;
461 rs232_init(RS232_PORT_0, USART_BAUD_19200,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
463 rs232_redirect_stdout(RS232_PORT_0);
467 if (!(reason & (_BV(BORF) | _BV(EXTRF) | _BV(PORF))))
468 profiling_stack_trace();
476 extern uint16_t __bss_end;
477 uint16_t p=(uint16_t)&__bss_end;
479 *(uint16_t *)p = 0x4242;
489 random_init(rng_get_uint8());
491 #define CONF_CALIBRATE_OSCCAL 0
492 #if CONF_CALIBRATE_OSCCAL
495 extern uint8_t osccal_calibrated;
497 PRINTD(
"\nBefore calibration OSCCAL=%x\n",OSCCAL);
500 PRINTD(
"Calibrated=%x\n",osccal_calibrated);
509 PRINTA(
"\n*******Booting %s*******\nReset reason: ",CONTIKI_VERSION_STRING);
511 if (reason & _BV(JTRF))
513 if (reason & _BV(WDRF))
515 if (reason & _BV(BORF))
516 PRINTA(
"Brown-out ");
517 if (reason & _BV(EXTRF))
519 if (reason & _BV(PORF))
522 if (reason & _BV(WDRF))
523 PRINTA(
"Watchdog possibly occured at address %p\n", wdt_addr);
544 NETSTACK_RADIO.init();
550 get_eui64_from_eeprom(addr.u8);
556 node_id=get_panaddr_from_eeprom();
557 addr.u8[1]=node_id&0xff;
558 addr.u8[0]=(node_id&0xff00)>>8;
559 PRINTA(
"Node ID from eeprom: %X\n",node_id);
562 memcpy(&
uip_lladdr.addr, &addr.u8,
sizeof(rimeaddr_t));
565 get_panid_from_eeprom(),
571 #error "IPv6 without Node_ID currently not implemented"
578 node_id=get_panaddr_from_eeprom();
579 addr.u8[1]=node_id&0xff;
580 addr.u8[0]=(node_id&0xff00)>>8;
581 PRINTA(
"Node ID from eeprom: %X\n",node_id);
586 get_panid_from_eeprom(),
594 get_panid_from_eeprom(),
595 get_panaddr_from_eeprom(),
600 rf230_set_channel(get_channel_from_eeprom());
601 rf230_set_txpower(get_txpower_from_eeprom());
605 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]);
607 PRINTA(
"MAC address ");
609 for (i=
sizeof(rimeaddr_t); i>0; i--){
610 PRINTA(
"%x:",addr.u8[i-1]);
616 PRINTF(
"node ID %u\n",node_id);
622 NETSTACK_NETWORK.init();
625 PRINTA(
"%s %s, channel %u power %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel(),rf230_get_txpower());
626 if (NETSTACK_RDC.channel_check_interval) {
628 tmp=
CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
629 NETSTACK_RDC.channel_check_interval());
630 if (tmp<65535) PRINTA(
", check rate %u Hz",tmp);
634 #if UIP_CONF_IPV6_RPL
635 PRINTA(
"RPL Enabled\n");
638 PRINTA(
"Routing Enabled\n");
655 #ifdef RAVEN_LCD_INTERFACE
660 autostart_start(autostart_processes);
669 PRINTA(
"No index.html file found, creating upload.html!\n");
670 PRINTA(
"Formatting FLASH file system for coffee...");
674 int r = cfs_write(fa, &
"It works!", 9);
675 if (r<0) PRINTA(
"Can''t create /index.html!\n");
680 PRINTF(
"index.html found\n");
687 uip_ip6addr_t ipaddr;
689 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
702 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
703 if (uip_ds6_if.addr_list[i].isused) {
704 httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf);
705 PRINTA(
"IPv6 Address: %s\n",buf);
709 eeprom_read_block (buf,eemem_server_name,
sizeof(eemem_server_name));
711 buf[
sizeof(eemem_server_name)]=0;
714 eeprom_read_block (buf,eemem_domain_name,
sizeof(eemem_domain_name));
716 buf[
sizeof(eemem_domain_name)]=0;
717 size=httpd_fs_get_size();
719 PRINTA(
".%s online with fixed %u byte web content\n",buf,size);
720 #elif COFFEE_FILES==1
721 PRINTA(
".%s online with static %u byte EEPROM file system\n",buf,size);
722 #elif COFFEE_FILES==2
723 PRINTA(
".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
724 #elif COFFEE_FILES==3
725 PRINTA(
".%s online with static %u byte program memory file system\n",buf,size);
726 #elif COFFEE_FILES==4
727 PRINTA(
".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
738 #if ROUTES && UIP_CONF_IPV6
745 a = (addr->u8[i] << 8) + addr->u8[i + 1];
746 if(a == 0 && f >= 0) {
747 if(f++ == 0) PRINTF(
"::");
763 SENSORS(&button_sensor);
785 NETSTACK_RDC.input();
792 extern uint8_t rf230_calibrated;
793 if (rf230_calibrated) {
794 PRINTD(
"\nRF230 calibrated!\n");
801 debugflow[debugflowsize]=0;
802 PRINTF(
"%s",debugflow);
819 if (clocktime!=clock_seconds()) {
820 clocktime=clock_seconds();
824 if ((clocktime%STAMPS)==0) {
829 extern volatile unsigned long radioontime;
830 PRINTF(
"%u(%u)s\n",clocktime,radioontime);
832 PRINTF(
"%us\n",clocktime);
841 #if PINGS && UIP_CONF_IPV6
842 extern void raven_ping6(
void);
843 if ((clocktime%PINGS)==1) {
849 #if ROUTES && UIP_CONF_IPV6
850 if ((clocktime%ROUTES)==2) {
857 PRINTF(
"\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
858 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
859 if (uip_ds6_if.addr_list[i].isused) {
860 ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
864 PRINTF(
"\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
865 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
866 if(uip_ds6_nbr_cache[i].isused) {
867 ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
872 if (j) PRINTF(
" <none>");
873 PRINTF(
"\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
874 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
875 if(uip_ds6_routing_table[i].isused) {
876 ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
877 PRINTF(
"/%u (via ", uip_ds6_routing_table[i].length);
878 ipaddr_add(&uip_ds6_routing_table[i].nexthop);
880 PRINTF(
") %lus\n", uip_ds6_routing_table[i].state.lifetime);
887 if (j) PRINTF(
" <none>");
888 PRINTF(
"\n---------\n");
893 if ((clocktime%STACKMONITOR)==3) {
894 extern uint16_t __bss_end;
895 uint16_t p=(uint16_t)&__bss_end;
897 if (*(uint16_t *)p != 0x4242) {
898 PRINTF(
"Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
902 }
while (p<RAMEND-10);
910 extern uint8_t rf230processflag;
911 if (rf230processflag) {
912 PRINTF(
"rf230p%d",rf230processflag);
918 extern uint8_t rf230_interrupt_flag;
919 if (rf230_interrupt_flag) {
921 PRINTF(
"**RI%u",rf230_interrupt_flag);
923 rf230_interrupt_flag=0;
932 void log_message(
char *m1,
char *m2)
934 PRINTF(
"%s%s\n", m1, m2);