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)
50 #define DEBUGFLOWSIZE 32
52 unsigned char debugflowsize,debugflow[DEBUGFLOWSIZE];
53 #define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
58 #include <avr/pgmspace.h>
60 #include <avr/eeprom.h>
63 #include <dev/watchdog.h>
65 #include "loader/symbols-def.h"
66 #include "loader/symtab.h"
68 #if RF230BB //radio driver using contiki core mac
74 #else //radio driver using Atmel/Cisco 802.15.4'ish MAC
77 #include "sicslowmac.h"
83 #include "contiki-net.h"
84 #include "contiki-lib.h"
86 #include "dev/rs232.h"
90 #ifdef RAVEN_LCD_INTERFACE
91 #include "raven-lcd.h"
96 #include "httpd-cgi.h"
104 #if UIP_CONF_ROUTER&&0
105 #include "net/routing/rimeroute.h"
106 #include "net/rime/rime-udp.h"
116 #define PERIODICPRINTS 1
121 #define STACKMONITOR 600
125 uint8_t rtimerflag=1;
127 void rtimercycle(
void) {rtimerflag=1;}
130 uint16_t node_id = 0;
136 #include <avr/signature.h>
139 typedef struct {
const unsigned char B2;
const unsigned char B1;
const unsigned char B0;} __signature_t;
140 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
148 #if !MCU_CONF_LOW_WEAR
150 FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
155 rng_get_uint8(
void) {
158 for (i=0,j=0;i<4;i++) {
162 while (ADCSRA&(1<<ADSC));
166 PRINTD(
"rng issues %d\n",j);
172 void initialize(
void)
177 #ifdef RAVEN_LCD_INTERFACE
179 rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
184 rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
188 rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
190 rs232_redirect_stdout(RS232_PORT_1);
193 PRINTD(
"\n\nChecking MCUSR...\n");
194 if(MCUSR & (1<<PORF )) PRINTD(
"Power-on reset.\n");
195 if(MCUSR & (1<<EXTRF)) PRINTD(
"External reset!\n");
196 if(MCUSR & (1<<BORF )) PRINTD(
"Brownout reset!\n");
197 if(MCUSR & (1<<WDRF )) PRINTD(
"Watchdog reset!\n");
198 if(MCUSR & (1<<JTRF )) PRINTD(
"JTAG reset!\n");
202 PRINTD(
"RTIMER_ARCH_SECOND %lu\n",RTIMER_ARCH_SECOND);
203 PRINTD(
"F_CPU %lu\n",F_CPU);
211 extern uint16_t __bss_end;
212 uint16_t p=(uint16_t)&__bss_end;
214 *(uint16_t *)p = 0x4242;
221 #define CONF_CALIBRATE_OSCCAL 0
222 #if CONF_CALIBRATE_OSCCAL
225 extern uint8_t osccal_calibrated;
227 PRINTD(
"\nBefore calibration OSCCAL=%x\n",OSCCAL);
230 PRINTD(
"Calibrated=%x\n",osccal_calibrated);
239 PRINTA(
"\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
254 NETSTACK_RADIO.init();
265 if (params_get_eui64(addr.u8)) {
266 PRINTA(
"Random EUI64 address generated\n");
270 PRINTD(
"Initial node_id %u\n",node_id);
272 addr.u8[3]=node_id&0xff;
273 addr.u8[4]=(node_id&0xff)>>8;
278 node_id=addr.u8[7]+(addr.u8[6]<<8);
280 memcpy(&
uip_lladdr.addr, &addr.u8,
sizeof(linkaddr_t));
282 rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8);
284 node_id=get_panaddr_from_eeprom();
285 addr.u8[1]=node_id&0xff;
286 addr.u8[0]=(node_id&0xff00)>>8;
287 PRINTA(
"Node ID from eeprom: %X\n",node_id);
288 uint16_t inv_node_id=((node_id&0xff00)>>8)+((node_id&0xff)<<8);
290 rf230_set_pan_addr(params_get_panid(),inv_node_id,
NULL);
293 rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8);
295 rf230_set_channel(params_get_channel());
299 PRINTA(
"EUI-64 MAC: %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]);
301 PRINTA(
"MAC address ");
303 for (i=
sizeof(linkaddr_t); i>0; i--){
304 PRINTA(
"%x:",addr.u8[i-1]);
313 NETSTACK_NETWORK.init();
316 PRINTA(
"%s %s, channel %u , check rate %u Hz tx power %u\n",NETSTACK_MAC.name, NETSTACK_RDC.name, rf230_get_channel(),
317 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:NETSTACK_RDC.channel_check_interval()),
318 rf230_get_txpower());
319 #if UIP_CONF_IPV6_RPL
320 PRINTA(
"RPL Enabled\n");
323 PRINTA(
"Routing Enabled\n");
339 #ifdef RAVEN_LCD_INTERFACE
343 #if !RAVEN_LCD_INTERFACE
349 autostart_start(autostart_processes);
355 PRINTA(
"No index.html file found, creating upload.html!\n");
356 PRINTA(
"Formatting FLASH file system for coffee...");
360 int r = cfs_write(fa, &
"It works!", 9);
361 if (r<0) PRINTA(
"Can''t create /index.html!\n");
371 uip_ip6addr_t ipaddr;
373 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
383 char buf1[40],buf[40];
386 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
387 if (uip_ds6_if.addr_list[i].isused) {
388 httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf);
389 PRINTA(
"IPv6 Address: %s\n",buf);
393 eeprom_read_block (buf1,eemem_server_name,
sizeof(eemem_server_name));
394 eeprom_read_block (buf,eemem_domain_name,
sizeof(eemem_domain_name));
396 buf1[
sizeof(eemem_server_name)]=0;
398 buf[
sizeof(eemem_domain_name)]=0;
399 size=httpd_fs_get_size();
401 PRINTA(
".%s online with fixed %u byte web content\n",buf,size);
402 #elif COFFEE_FILES==1
403 PRINTA(
".%s online with static %u byte EEPROM file system\n",buf,size);
404 #elif COFFEE_FILES==2
405 PRINTA(
".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
406 #elif COFFEE_FILES==3
407 PRINTA(
".%s online with static %u byte program memory file system\n",buf,size);
408 #elif COFFEE_FILES==4
409 PRINTA(
".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
420 #if ROUTES && UIP_CONF_IPV6
422 ipaddr_add(
const uip_ipaddr_t *addr)
426 for(i = 0, f = 0; i <
sizeof(uip_ipaddr_t); i += 2) {
427 a = (addr->u8[i] << 8) + addr->u8[i + 1];
428 if(a == 0 && f >= 0) {
429 if(f++ == 0) PRINTF(
"::");
466 NETSTACK_RDC.input();
473 extern uint8_t rf230_calibrated;
474 if (rf230_calibrated) {
475 PRINTD(
"\nRF230 calibrated!\n");
483 debugflow[debugflowsize]=0;
484 PRINTF(
"%s\n",debugflow);
504 if ((clocktime%STAMPS)==0) {
509 extern volatile unsigned long radioontime;
510 PRINTF(
"%u(%u)s\n",clocktime,radioontime);
512 PRINTF(
"%us\n",clocktime);
521 #if PINGS && UIP_CONF_IPV6
522 extern void raven_ping6(
void);
523 if ((clocktime%PINGS)==1) {
529 #if ROUTES && UIP_CONF_IPV6
530 if ((clocktime%ROUTES)==2) {
535 PRINTF(
"\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
536 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
537 if (uip_ds6_if.addr_list[i].isused) {
538 ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
542 PRINTF(
"\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
543 for(nbr = nbr_table_head(ds6_neighbors);
545 nbr = nbr_table_next(ds6_neighbors, nbr)) {
546 ipaddr_add(&nbr->ipaddr);
550 if (j) PRINTF(
" <none>");
553 PRINTF(
"\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
558 ipaddr_add(&r->ipaddr);
559 PRINTF(
"/%u (via ", r->length);
560 ipaddr_add(uip_ds6_route_nexthop(r));
561 PRINTF(
") %lus\n", r->state.lifetime);
565 if (j) PRINTF(
" <none>");
566 PRINTF(
"\n---------\n");
571 if ((clocktime%STACKMONITOR)==3) {
572 extern uint16_t __bss_end;
573 uint16_t p=(uint16_t)&__bss_end;
575 if (*(uint16_t *)p != 0x4242) {
576 PRINTF(
"Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
580 }
while (p<RAMEND-10);
588 extern uint8_t rf230processflag;
589 if (rf230processflag) {
590 PRINTF(
"rf230p%d",rf230processflag);
596 extern uint8_t rf230interruptflag;
597 if (rf230interruptflag) {
599 PRINTF(
"**RI%u\n",rf230interruptflag);
601 rf230interruptflag=0;
610 void log_message(
char *m1,
char *m2)
612 PRINTF(
"%s%s\n", m1, m2);