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>
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"
87 #include "dev/rs232.h"
91 #ifdef RAVEN_LCD_INTERFACE
92 #include "raven-lcd.h"
97 #include "httpd-cgi.h"
105 #if UIP_CONF_ROUTER&&0
106 #include "net/routing/rimeroute.h"
115 #define PERIODICPRINTS 1
120 #define STACKMONITOR 600
124 uint8_t rtimerflag=1;
127 void rtimercycle(
void) {rtimerflag=1;}
139 #include <avr/signature.h>
142 typedef struct {
const unsigned char B2;
const unsigned char B1;
const unsigned char B0;} __signature_t;
143 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
152 FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
157 extern uint8_t default_mac_address[8];
158 extern uint8_t default_server_name[16];
159 extern uint8_t default_domain_name[30];
162 uint8_t default_mac_address[8] PROGMEM = MAC_ADDRESS;
164 uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
167 uint8_t default_server_name[16] PROGMEM = SERVER_NAME;
169 uint8_t default_server_name[16] PROGMEM =
"Raven_webserver";
172 uint8_t default_domain_name[30] PROGMEM = DOMAIN_NAME
174 uint8_t default_domain_name[30] PROGMEM =
"localhost";
179 uint16_t default_nodeid PROGMEM = NODEID;
181 uint16_t default_nodeid PROGMEM = 0;
183 #ifdef CHANNEL_802_15_4
184 uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
186 uint8_t default_channel PROGMEM = 26;
188 #ifdef IEEE802154_PANID
189 uint16_t default_panid PROGMEM = IEEE802154_PANID;
191 uint16_t default_panid PROGMEM = 0xABCD;
193 #ifdef IEEE802154_PANADDR
194 uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
196 uint16_t default_panaddr PROGMEM = 0;
198 #ifdef RF230_MAX_TX_POWER
199 uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
201 uint8_t default_txpower PROGMEM = 0;
206 rng_get_uint8(
void) {
213 while (ADCSRA&(1<<ADSC));
217 PRINTD(
"rng issues %d\n",j);
221 #if CONTIKI_CONF_RANDOM_MAC
223 generate_new_eui64(uint8_t eui64[8]) {
225 eui64[1] = rng_get_uint8();
226 eui64[2] = rng_get_uint8();
229 eui64[5] = rng_get_uint8();
230 eui64[6] = rng_get_uint8();
231 eui64[7] = rng_get_uint8();
235 #if !CONTIKI_CONF_SETTINGS_MANAGER
244 extern uint8_t eemem_mac_address[8];
245 extern uint8_t eemem_server_name[16];
246 extern uint8_t eemem_domain_name[30];
249 uint8_t eemem_mac_address[8] EEMEM = MAC_ADDRESS;
251 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
254 uint8_t eemem_server_name[16] EEMEM = SERVER_NAME;
256 uint8_t eemem_server_name[16] EEMEM =
"Raven_webserver";
259 uint8_t eemem_domain_name[30] EEMEM = DOMAIN_NAME
261 uint8_t eemem_domain_name[30] EEMEM =
"localhost";
266 uint16_t eemem_nodeid EEMEM = NODEID;
268 uint16_t eemem_nodeid EEMEM = 0;
270 #ifdef CHANNEL_802_15_4
271 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
273 uint8_t eemem_channel[2] EMEM = {26, ~26};
275 #ifdef IEEE802154_PANID
276 uint16_t eemem_panid EEMEM = IEEE802154_PANID;
278 uint16_t eemem_panid EEMEM = 0xABCD;
280 #ifdef IEEE802154_PANADDR
281 uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
283 uint16_t eemem_panaddr EEMEM = 0;
285 #ifdef RF230_MAX_TX_POWER
286 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
288 uint8_t eemem_txpower EEMEM = 0;
292 get_channel_from_eeprom() {
294 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
296 if( (x[0]<11) || (x[0] > 26)) x[1]=x[0];
298 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
300 uint8_t i,buffer[32];
301 PRINTD(
"EEPROM is corrupt, rewriting with defaults.\n");
302 #if CONTIKI_CONF_RANDOM_MAC
303 PRINTA(
"Generating random MAC address.\n");
304 generate_new_eui64(&buffer);
306 for (i=0;i<
sizeof(default_mac_address);i++) buffer[i] = pgm_read_byte_near(default_mac_address+i);
309 eeprom_write_block(&buffer, &eemem_mac_address,
sizeof(eemem_mac_address));
310 for (i=0;i<
sizeof(default_server_name);i++) buffer[i] = pgm_read_byte_near(default_server_name+i);
311 eeprom_write_block(&buffer, &eemem_server_name,
sizeof(eemem_server_name));
312 for (i=0;i<
sizeof(default_domain_name);i++) buffer[i] = pgm_read_byte_near(default_domain_name+i);
313 eeprom_write_block(&buffer, &eemem_domain_name,
sizeof(eemem_domain_name));
314 eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
315 eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
316 eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
317 eeprom_write_word(&eemem_nodeid, pgm_read_word_near(&default_nodeid));
318 x[0] = pgm_read_byte_near(&default_channel);
320 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
327 get_eui64_from_eeprom(uint8_t macptr[
sizeof(rimeaddr_t)]) {
329 eeprom_read_block ((
void *)macptr, &eemem_mac_address,
sizeof(rimeaddr_t));
331 return macptr[0]!=0xFF;
334 get_panid_from_eeprom(
void) {
335 return eeprom_read_word(&eemem_panid);
338 get_panaddr_from_eeprom(
void) {
339 return eeprom_read_word (&eemem_panaddr);
342 get_txpower_from_eeprom(
void)
344 return eeprom_read_byte(&eemem_txpower);
349 #include "settings.h"
352 #define settings_add(...) 0
353 #define settings_add_uint8(...) 0
354 #define settings_add_uint16(...) 0
358 extern uint8_t eemem_mac_address[8];
359 extern uint8_t eemem_server_name[16];
360 extern uint8_t eemem_domain_name[30];
364 get_channel_from_eeprom() {
367 if (settings_get(SETTINGS_KEY_CHANNEL, 0,(
unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
368 if ((x<11) || (x>26)) {
369 PRINTF(
"Unusual RF channel %u in EEPROM\n",x);
371 PRINTD(
"<=Get RF channel %u.\n",x);
373 x = pgm_read_byte_near(&default_channel);
374 if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) {
375 PRINTD(
"->Set EEPROM RF channel to %d.\n",x);
381 get_eui64_from_eeprom(uint8_t macptr[8]) {
382 size_t size =
sizeof(rimeaddr_t);
383 if(settings_get(SETTINGS_KEY_EUI64, 0, (
unsigned char*)macptr, &size) == SETTINGS_STATUS_OK) {
384 PRINTD(
"<=Get MAC address.\n");
387 #if CONTIKI_CONF_RANDOM_MAC
388 PRINTD(
"--Generating random MAC address.\n");
389 generate_new_eui64(macptr);
391 {uint8_t i;
for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
393 if (settings_add(SETTINGS_KEY_EUI64,(
unsigned char*)macptr,8)) {
394 PRINTD(
"->Set EEPROM MAC address.\n");
399 get_panid_from_eeprom(
void) {
402 if (settings_get(SETTINGS_KEY_PAN_ID, 0,(
unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
403 PRINTD(
"<-Get PAN ID of %04x.\n",x);
405 x=pgm_read_word_near(&default_panid);
406 if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
407 PRINTD(
"->Set EEPROM PAN ID to %04x.\n",x);
413 get_panaddr_from_eeprom(
void) {
416 if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(
unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
417 PRINTD(
"<-Get PAN address of %04x.\n",x);
419 x=pgm_read_word_near(&default_panaddr);
420 if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
421 PRINTD(
"->Set EEPROM PAN address to %04x.\n",x);
427 get_txpower_from_eeprom(
void) {
430 if (settings_get(SETTINGS_KEY_TXPOWER, 0,(
unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
431 PRINTD(
"<-Get tx power of %d. (0=max)\n",x);
433 x=pgm_read_byte_near(&default_txpower);
434 if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
435 PRINTD(
"->Set EEPROM tx power of %d. (0=max)\n",x);
444 void initialize(
void)
449 #ifdef RAVEN_LCD_INTERFACE
451 rs232_init(RS232_PORT_1, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
457 rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
459 rs232_redirect_stdout(RS232_PORT_0);
468 extern uint16_t __bss_end;
469 uint16_t p=(uint16_t)&__bss_end;
471 *(uint16_t *)p = 0x4242;
481 random_init(rng_get_uint8());
483 #define CONF_CALIBRATE_OSCCAL 0
484 #if CONF_CALIBRATE_OSCCAL
487 extern uint8_t osccal_calibrated;
489 PRINTD(
"\nBefore calibration OSCCAL=%x\n",OSCCAL);
492 PRINTD(
"Calibrated=%x\n",osccal_calibrated);
501 PRINTA(
"\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
516 NETSTACK_RADIO.init();
521 memset(&addr, 0,
sizeof(rimeaddr_t));
522 get_mac_from_eeprom(addr.u8);
523 node_id=get_panaddr_from_eeprom();
526 memcpy(&
uip_lladdr.addr, &addr.u8,
sizeof(rimeaddr_t));
528 node_id=get_panaddr_from_eeprom();
529 addr.u8[1]=node_id&0xff;
530 addr.u8[0]=(node_id&0xff00)>>8;
531 PRINTA(
"Node ID from eeprom: %X\n",node_id);
536 get_panid_from_eeprom(),
537 get_panaddr_from_eeprom(),
540 rf230_set_channel(get_channel_from_eeprom());
541 rf230_set_txpower(get_txpower_from_eeprom());
545 PRINTF(
"MAC address: ");
546 for (alen=0; alen <
sizeof(rimeaddr_t);alen++){
547 PRINTF(
"%u:",addr.u8[alen]);
552 PRINTF(
"node ID %u\n",node_id);
558 NETSTACK_NETWORK.init();
561 PRINTA(
"%s %s, channel %u power %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()),rf230_get_txpower();
562 if (NETSTACK_RDC.channel_check_interval) {
564 tmp=
CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
565 NETSTACK_RDC.channel_check_interval());
566 if (tmp<65535) PRINTA(
", check rate %u Hz",tmp);
570 #if UIP_CONF_IPV6_RPL
571 PRINTA(
"RPL Enabled\n");
574 PRINTA(
"Routing Enabled\n");
591 #ifdef RAVEN_LCD_INTERFACE
596 autostart_start(autostart_processes);
605 PRINTA(
"No index.html file found, creating upload.html!\n");
606 PRINTA(
"Formatting FLASH file system for coffee...");
610 int r = cfs_write(fa, &
"It works!", 9);
611 if (r<0) PRINTA(
"Can''t create /index.html!\n");
616 PRINTF(
"index.html found\n");
623 uip_ip6addr_t ipaddr;
625 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
638 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
639 if (uip_ds6_if.addr_list[i].isused) {
640 httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf);
641 PRINTA(
"IPv6 Address: %s\n",buf);
645 eeprom_read_block (buf,eemem_server_name,
sizeof(eemem_server_name));
647 buf[
sizeof(eemem_server_name)]=0;
650 eeprom_read_block (buf,eemem_domain_name,
sizeof(eemem_domain_name));
652 buf[
sizeof(eemem_domain_name)]=0;
653 size=httpd_fs_get_size();
655 PRINTA(
".%s online with fixed %u byte web content\n",buf,size);
656 #elif COFFEE_FILES==1
657 PRINTA(
".%s online with static %u byte EEPROM file system\n",buf,size);
658 #elif COFFEE_FILES==2
659 PRINTA(
".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
660 #elif COFFEE_FILES==3
661 PRINTA(
".%s online with static %u byte program memory file system\n",buf,size);
662 #elif COFFEE_FILES==4
663 PRINTA(
".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
674 #if ROUTES && UIP_CONF_IPV6
681 a = (addr->u8[i] << 8) + addr->u8[i + 1];
682 if(a == 0 && f >= 0) {
683 if(f++ == 0) PRINTF(
"::");
717 NETSTACK_RDC.input();
724 extern uint8_t rf230_calibrated;
725 if (rf230_calibrated) {
726 PRINTD(
"\nRF230 calibrated!\n");
733 debugflow[debugflowsize]=0;
734 PRINTF(
"%s",debugflow);
751 if (clocktime!=clock_seconds()) {
752 clocktime=clock_seconds();
756 if ((clocktime%STAMPS)==0) {
761 extern volatile unsigned long radioontime;
762 PRINTF(
"%u(%u)s\n",clocktime,radioontime);
764 PRINTF(
"%us\n",clocktime);
773 #if PINGS && UIP_CONF_IPV6
774 extern void raven_ping6(
void);
775 if ((clocktime%PINGS)==1) {
781 #if ROUTES && UIP_CONF_IPV6
782 if ((clocktime%ROUTES)==2) {
789 PRINTF(
"\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
790 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
791 if (uip_ds6_if.addr_list[i].isused) {
792 ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
796 PRINTF(
"\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
797 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
798 if(uip_ds6_nbr_cache[i].isused) {
799 ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
804 if (j) PRINTF(
" <none>");
805 PRINTF(
"\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
806 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
807 if(uip_ds6_routing_table[i].isused) {
808 ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
809 PRINTF(
"/%u (via ", uip_ds6_routing_table[i].length);
810 ipaddr_add(&uip_ds6_routing_table[i].nexthop);
812 PRINTF(
") %lus\n", uip_ds6_routing_table[i].state.lifetime);
819 if (j) PRINTF(
" <none>");
820 PRINTF(
"\n---------\n");
825 if ((clocktime%STACKMONITOR)==3) {
826 extern uint16_t __bss_end;
827 uint16_t p=(uint16_t)&__bss_end;
829 if (*(uint16_t *)p != 0x4242) {
830 PRINTF(
"Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
834 }
while (p<RAMEND-10);
842 extern uint8_t rf230processflag;
843 if (rf230processflag) {
844 PRINTF(
"rf230p%d",rf230processflag);
850 extern uint8_t rf230_interrupt_flag;
851 if (rf230_interrupt_flag) {
853 PRINTF(
"**RI%u",rf230_interrupt_flag);
855 rf230_interrupt_flag=0;
864 void log_message(
char *m1,
char *m2)
866 PRINTF(
"%s%s\n", m1, m2);