45 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
50 #include <avr/pgmspace.h>
52 #include <avr/eeprom.h>
54 #include <util/delay.h>
59 #include "loader/symbols-def.h"
60 #include "loader/symtab.h"
63 #include "contiki-net.h"
64 #include "contiki-lib.h"
65 #include "contiki-raven.h"
71 #if USB_CONF_SERIAL||USB_CONF_RS232
72 #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
82 #include "dev/rs232.h"
87 #include "storage/storage_task.h"
90 #include "dev/watchdog.h"
93 #if JACKDAW_CONF_USE_SETTINGS
97 #if RF230BB //radio driver using contiki core mac
100 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
102 #define tmp_addr macLongAddr
103 #else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC
106 #include "sicslowmac.h"
117 #define STACKMONITOR 600
118 uint8_t rtimerflag=1;
121 void rtimercycle(
void) {rtimerflag=1;}
124 #if UIP_CONF_IPV6_RPL
146 const struct uip_fallback_interface rpl_interface = {
150 #if RPL_BORDER_ROUTER
151 #include "net/rpl/rpl.h"
154 uint16_t dag_id[] PROGMEM = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
156 PROCESS(border_router_process,
"RPL Border Router");
165 char buf[
sizeof(dag_id)];
166 memcpy_P(buf,dag_id,
sizeof(dag_id));
167 dag = rpl_set_root((uip_ip6addr_t *)buf);
174 PRINTD(
"created a new RPL dag\n");
176 #if UIP_CONF_ROUTER_RECEIVE_RA
181 uip_ip6addr_t ipaddr;
182 uip_ip6addr(&ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x200);
183 uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
184 rpl_set_prefix(dag, &ipaddr, 64);
210 #include <avr/signature.h>
213 typedef struct {
const unsigned char B2;
const unsigned char B1;
const unsigned char B0;} __signature_t;
214 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
222 FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
225 uint8_t default_mac_address[8] PROGMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
226 #ifdef CHANNEL_802_15_4
227 uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
229 uint8_t default_channel PROGMEM = 26;
231 #ifdef IEEE802154_PANID
232 uint16_t default_panid PROGMEM = IEEE802154_PANID;
234 uint16_t default_panid PROGMEM = 0xABCD;
236 #ifdef IEEE802154_PANADDR
237 uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
239 uint16_t default_panaddr PROGMEM = 0;
241 #ifdef RF230_MAX_TX_POWER
242 uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
244 uint8_t default_txpower PROGMEM = 0;
247 #if JACKDAW_CONF_RANDOM_MAC
250 generate_new_eui64(uint8_t eui64[8]) {
252 eui64[1] = rng_get_uint8();
253 eui64[2] = rng_get_uint8();
256 eui64[5] = rng_get_uint8();
257 eui64[6] = rng_get_uint8();
258 eui64[7] = rng_get_uint8();
262 #if !JACKDAW_CONF_USE_SETTINGS
271 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
272 #ifdef CHANNEL_802_15_4
273 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
275 uint8_t eemem_channel[2] EMEM = {26, ~26};
277 #ifdef IEEE802154_PANID
278 uint16_t eemem_panid EEMEM = IEEE802154_PANID;
280 uint16_t eemem_panid EEMEM = 0xABCD;
282 #ifdef IEEE802154_PANADDR
283 uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
285 uint16_t eemem_panaddr EEMEM = 0;
287 #ifdef RF230_MAX_TX_POWER
288 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
290 uint8_t eemem_txpower EEMEM = 0;
292 static uint8_t get_channel_from_eeprom() {
294 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
295 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
298 #if JACKDAW_CONF_RANDOM_MAC
299 PRINTA(
"Generating random MAC address.\n");
300 generate_new_eui64(&mac);
302 {uint8_t i;
for (i=0;i<8;i++) mac[i] = pgm_read_byte_near(default_mac_address+i);}
304 eeprom_write_block(&mac, &eemem_mac_address, 8);
305 eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
306 eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
307 eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
308 x[0] = pgm_read_byte_near(&default_channel);
310 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
314 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
315 eeprom_read_block ((
void *)macptr, &eemem_mac_address, 8);
316 return macptr[0]!=0xFF;
318 static uint16_t get_panid_from_eeprom(
void) {
319 return eeprom_read_word(&eemem_panid);
321 static uint16_t get_panaddr_from_eeprom(
void) {
322 return eeprom_read_word (&eemem_panaddr);
324 static uint8_t get_txpower_from_eeprom(
void)
326 return eeprom_read_byte(&eemem_txpower);
331 static uint8_t get_channel_from_eeprom() {
332 uint8_t x = settings_get_uint8(SETTINGS_KEY_CHANNEL, 0);
333 if(!x) x = pgm_read_byte_near(&default_channel);
336 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
338 if(settings_get(SETTINGS_KEY_EUI64, 0, (
unsigned char*)macptr, &size)==SETTINGS_STATUS_OK) {
339 PRINTD(
"<=Get EEPROM MAC address.\n");
342 #if JACKDAW_CONF_RANDOM_MAC
343 PRINTA(
"--Generating random MAC address.\n");
344 generate_new_eui64(macptr);
346 {uint8_t i;
for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
348 settings_add(SETTINGS_KEY_EUI64,(
unsigned char*)macptr,8);
349 PRINTA(
"->Set EEPROM MAC address.\n");
352 static uint16_t get_panid_from_eeprom(
void) {
354 if (settings_check(SETTINGS_KEY_PAN_ID,0)) {
355 x = settings_get_uint16(SETTINGS_KEY_PAN_ID,0);
356 PRINTD(
"<-Get EEPROM PAN ID of %04x.\n",x);
358 x=pgm_read_word_near(&default_panid);
359 if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
360 PRINTA(
"->Set EEPROM PAN ID to %04x.\n",x);
365 static uint16_t get_panaddr_from_eeprom(
void) {
367 if (settings_check(SETTINGS_KEY_PAN_ADDR,0)) {
368 x = settings_get_uint16(SETTINGS_KEY_PAN_ADDR,0);
369 PRINTD(
"<-Get EEPROM PAN address of %04x.\n",x);
371 x=pgm_read_word_near(&default_panaddr);
372 if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
373 PRINTA(
"->Set EEPROM PAN address to %04x.\n",x);
378 static uint8_t get_txpower_from_eeprom(
void) {
380 if (settings_check(SETTINGS_KEY_TXPOWER,0)) {
381 x = settings_get_uint8(SETTINGS_KEY_TXPOWER,0);
382 PRINTD(
"<-Get EEPROM tx power of %d. (0=max)\n",x);
384 x=pgm_read_byte_near(&default_txpower);
385 if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
386 PRINTA(
"->Set EEPROM tx power of %d. (0=max)\n",x);
395 static void initialize(
void) {
400 #if CONFIG_STACK_MONITOR
405 extern uint16_t __bss_end;
406 uint16_t p=(uint16_t)&__bss_end;
408 *(uint16_t *)p = 0x4242;
433 while (ADCSRA&(1<<ADSC));
434 PRINTD(
"ADC=%d\n",ADC);
440 rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
442 rs232_redirect_stdout(RS232_PORT_0);
444 PRINTA(
"\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
466 for (i=0;i<65535;i++) {
472 PRINTA(
"\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
476 if (!stdout) Led3_on();
479 #if JACKDAW_CONF_USE_SETTINGS
480 PRINTA(
"Settings manager will be used.\n");
483 *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel);
484 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
485 PRINTA(
"Invalid EEPROM settings detected. Rewriting with default values.\n");
486 get_channel_from_eeprom();
494 NETSTACK_RADIO.init();
498 memset(&tmp_addr, 0,
sizeof(rimeaddr_t));
500 if(get_eui64_from_eeprom(tmp_addr.u8));
510 get_panid_from_eeprom(),
511 get_panaddr_from_eeprom(),
512 (uint8_t *)&tmp_addr.u8
515 rf230_set_channel(get_channel_from_eeprom());
516 rf230_set_txpower(get_txpower_from_eeprom());
524 NETSTACK_NETWORK.init();
527 PRINTA(
"MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r",tmp_addr.u8[0],tmp_addr.u8[1],tmp_addr.u8[2],tmp_addr.u8[3],tmp_addr.u8[4],tmp_addr.u8[5],tmp_addr.u8[6],tmp_addr.u8[7]);
528 PRINTA(
"%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
529 if (NETSTACK_RDC.channel_check_interval) {
531 tmp=
CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
532 NETSTACK_RDC.channel_check_interval());
533 if (tmp<65535) PRINTA(
", check rate %u Hz",tmp);
538 #if UIP_CONF_IPV6_RPL
539 #if RPL_BORDER_ROUTER
542 PRINTD (
"RPL Border Router Started\n");
545 PRINTD (
"RPL Started\n");
548 extern struct process httpd_process;
550 PRINTD (
"Webserver Started\n");
571 autostart_start(autostart_processes);
578 PRINTA(
"Online. Type ? for Jackdaw menu.\n");
591 asm volatile (
"clr r1");
598 for(p = PROCESS_LIST();p !=
NULL; p = ((
struct process *)p->next)) {
599 PRINTA(
"Process=%p Thread=%p Name=\"%s\" \n",p,p->thread,PROCESS_NAME_STRING(p));
610 #ifdef RF230_MIN_RX_POWER
612 if (rf230_last_rssi != lastprint) {
613 PRINTA(
"%u ",rf230_last_rssi);
614 lastprint=rf230_last_rssi;
622 extern uint8_t rf230_calibrated;
623 if (rf230_calibrated) {
624 PRINTA(
"\nRF230 calibrated!\n");
640 if ((rtime%STAMPS)==0) {
641 PRINTA(
"%us ",rtime);
642 if (rtime%STAMPS*10) PRINTA(
"\n");
647 #if PINGS && UIP_CONF_IPV6_RPL
648 extern void raven_ping6(
void);
649 if ((rtime%PINGS)==1) {
655 #if ROUTES && UIP_CONF_IPV6_RPL
656 if ((rtime%ROUTES)==2) {
663 PRINTA(
"\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
664 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
665 if (uip_ds6_if.addr_list[i].isused) {
666 uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
670 PRINTA(
"\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
671 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
672 if(uip_ds6_nbr_cache[i].isused) {
673 uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
678 if (j) PRINTA(
" <none>");
679 PRINTA(
"\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
680 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
681 if(uip_ds6_routing_table[i].isused) {
682 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
683 PRINTA(
"/%u (via ", uip_ds6_routing_table[i].length);
684 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
686 PRINTA(
") %lus\n", uip_ds6_routing_table[i].state.lifetime);
693 if (j) PRINTA(
" <none>");
694 PRINTA(
"\n---------\n");
698 #if STACKMONITOR && CONFIG_STACK_MONITOR
699 if ((rtime%STACKMONITOR)==3) {
700 extern uint16_t __bss_end;
701 uint16_t p=(uint16_t)&__bss_end;
703 if (*(uint16_t *)p != 0x4242) {
704 PRINTA(
"Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
708 }
while (p<RAMEND-10);
717 extern uint8_t debugflowsize,debugflow[];
719 debugflow[debugflowsize]=0;
720 PRINTA(
"%s",debugflow);