00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #define DEBUG 0
00044 #if DEBUG
00045 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
00046 #else
00047 #define PRINTD(...)
00048 #endif
00049
00050 #include <avr/pgmspace.h>
00051 #include <avr/fuse.h>
00052 #include <avr/eeprom.h>
00053 #include <avr/wdt.h>
00054 #include <util/delay.h>
00055 #include <stdio.h>
00056 #include <string.h>
00057
00058 #include "lib/mmem.h"
00059 #include "loader/symbols-def.h"
00060 #include "loader/symtab.h"
00061
00062 #include "contiki.h"
00063 #include "contiki-net.h"
00064 #include "contiki-lib.h"
00065 #include "contiki-raven.h"
00066
00067
00068 #define ANNOUNCE 1
00069
00070
00071 #if USB_CONF_SERIAL||USB_CONF_RS232
00072 #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
00073 #else
00074 #define PRINTA(...)
00075 #endif
00076
00077 #include "usb_task.h"
00078 #if USB_CONF_SERIAL
00079 #include "cdc_task.h"
00080 #endif
00081 #if USB_CONF_RS232
00082 #include "dev/rs232.h"
00083 #endif
00084
00085 #include "rndis/rndis_task.h"
00086 #if USB_CONF_STORAGE
00087 #include "storage/storage_task.h"
00088 #endif
00089
00090 #include "dev/watchdog.h"
00091 #include "dev/usb/usb_drv.h"
00092
00093 #if JACKDAW_CONF_USE_SETTINGS
00094 #include "settings.h"
00095 #endif
00096
00097 #if RF230BB //radio driver using contiki core mac
00098 #include "radio/rf230bb/rf230bb.h"
00099 #include "net/mac/frame802154.h"
00100 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
00101 rimeaddr_t macLongAddr;
00102 #define tmp_addr macLongAddr
00103 #else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC
00104 #include <stdbool.h>
00105 #include "mac.h"
00106 #include "sicslowmac.h"
00107 #include "sicslowpan.h"
00108 #include "ieee-15-4-manager.h"
00109 #endif
00110
00111
00112 #define TESTRTIMER 0
00113 #if TESTRTIMER
00114 #define PINGS 0
00115 #define STAMPS 60
00116 #define ROUTES 120
00117 #define STACKMONITOR 600
00118 uint8_t rtimerflag=1;
00119 uint16_t rtime;
00120 struct rtimer rt;
00121 void rtimercycle(void) {rtimerflag=1;}
00122 #endif
00123
00124 #if UIP_CONF_IPV6_RPL
00125
00126
00127
00128
00129
00130 static void
00131 init(void)
00132 {
00133 }
00134 void mac_LowpanToEthernet(void);
00135 static void
00136 output(void)
00137 {
00138
00139
00140
00141
00142 PRINTD("SUT: %u\n", uip_len);
00143 mac_LowpanToEthernet();
00144
00145 }
00146 const struct uip_fallback_interface rpl_interface = {
00147 init, output
00148 };
00149
00150 #if RPL_BORDER_ROUTER
00151 #include "net/rpl/rpl.h"
00152
00153
00154 uint16_t dag_id[] PROGMEM = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
00155
00156 PROCESS(border_router_process, "RPL Border Router");
00157 PROCESS_THREAD(border_router_process, ev, data)
00158 {
00159
00160 PROCESS_BEGIN();
00161
00162 PROCESS_PAUSE();
00163
00164 { rpl_dag_t *dag;
00165 char buf[sizeof(dag_id)];
00166 memcpy_P(buf,dag_id,sizeof(dag_id));
00167 dag = rpl_set_root((uip_ip6addr_t *)buf);
00168
00169
00170
00171
00172
00173 if(dag != NULL) {
00174 PRINTD("created a new RPL dag\n");
00175
00176 #if UIP_CONF_ROUTER_RECEIVE_RA
00177
00178
00179
00180 #else
00181 uip_ip6addr_t ipaddr;
00182 uip_ip6addr(&ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x200);
00183 uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
00184 rpl_set_prefix(dag, &ipaddr, 64);
00185 #endif
00186 }
00187 }
00188
00189
00190
00191
00192 while(1) {
00193 PROCESS_YIELD();
00194
00195
00196
00197
00198 }
00199
00200 PROCESS_END();
00201 }
00202 #endif
00203
00204 #endif
00205
00206
00207
00208 #if 1
00209
00210 #include <avr/signature.h>
00211 #else
00212
00213 typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t;
00214 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
00215 SIGNATURE = {
00216 .B2 = 0x82,
00217 .B1 = 0x97,
00218 .B0 = 0x1E,
00219 };
00220 #endif
00221
00222 FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
00223
00224
00225 uint8_t default_mac_address[8] PROGMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
00226 #ifdef CHANNEL_802_15_4
00227 uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
00228 #else
00229 uint8_t default_channel PROGMEM = 26;
00230 #endif
00231 #ifdef IEEE802154_PANID
00232 uint16_t default_panid PROGMEM = IEEE802154_PANID;
00233 #else
00234 uint16_t default_panid PROGMEM = 0xABCD;
00235 #endif
00236 #ifdef IEEE802154_PANADDR
00237 uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
00238 #else
00239 uint16_t default_panaddr PROGMEM = 0;
00240 #endif
00241 #ifdef RF230_MAX_TX_POWER
00242 uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
00243 #else
00244 uint8_t default_txpower PROGMEM = 0;
00245 #endif
00246
00247 #if JACKDAW_CONF_RANDOM_MAC
00248 #include "rng.h"
00249 static void
00250 generate_new_eui64(uint8_t eui64[8]) {
00251 eui64[0] = 0x02;
00252 eui64[1] = rng_get_uint8();
00253 eui64[2] = rng_get_uint8();
00254 eui64[3] = 0xFF;
00255 eui64[4] = 0xFE;
00256 eui64[5] = rng_get_uint8();
00257 eui64[6] = rng_get_uint8();
00258 eui64[7] = rng_get_uint8();
00259 }
00260 #endif
00261
00262 #if !JACKDAW_CONF_USE_SETTINGS
00263
00264
00265
00266
00267
00268
00269
00270
00271 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
00272 #ifdef CHANNEL_802_15_4
00273 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
00274 #else
00275 uint8_t eemem_channel[2] EMEM = {26, ~26};
00276 #endif
00277 #ifdef IEEE802154_PANID
00278 uint16_t eemem_panid EEMEM = IEEE802154_PANID;
00279 #else
00280 uint16_t eemem_panid EEMEM = 0xABCD;
00281 #endif
00282 #ifdef IEEE802154_PANADDR
00283 uint16_t eemem_panaddr EEMEM = IEEE802154_PANID;
00284 #else
00285 uint16_t eemem_panaddr EEMEM = 0;
00286 #endif
00287 #ifdef RF230_MAX_TX_POWER
00288 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
00289 #else
00290 uint8_t eemem_txpower EEMEM = 0;
00291 #endif
00292 static uint8_t get_channel_from_eeprom() {
00293 uint8_t x[2];
00294 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
00295 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
00296
00297 uint8_t mac[8];
00298 #if JACKDAW_CONF_RANDOM_MAC
00299 PRINTA("Generating random MAC address.\n");
00300 generate_new_eui64(&mac);
00301 #else
00302 {uint8_t i; for (i=0;i<8;i++) mac[i] = pgm_read_byte_near(default_mac_address+i);}
00303 #endif
00304 eeprom_write_block(&mac, &eemem_mac_address, 8);
00305 eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
00306 eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
00307 eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
00308 x[0] = pgm_read_byte_near(&default_channel);
00309 x[1]= ~x[0];
00310 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
00311 }
00312 return x[0];
00313 }
00314 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
00315 eeprom_read_block ((void *)macptr, &eemem_mac_address, 8);
00316 return macptr[0]!=0xFF;
00317 }
00318 static uint16_t get_panid_from_eeprom(void) {
00319 return eeprom_read_word(&eemem_panid);
00320 }
00321 static uint16_t get_panaddr_from_eeprom(void) {
00322 return eeprom_read_word (&eemem_panaddr);
00323 }
00324 static uint8_t get_txpower_from_eeprom(void)
00325 {
00326 return eeprom_read_byte(&eemem_txpower);
00327 }
00328
00329 #else
00330
00331 static uint8_t get_channel_from_eeprom() {
00332 uint8_t x = settings_get_uint8(SETTINGS_KEY_CHANNEL, 0);
00333 if(!x) x = pgm_read_byte_near(&default_channel);
00334 return x;
00335 }
00336 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
00337 size_t size = 8;
00338 if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)macptr, &size)==SETTINGS_STATUS_OK) {
00339 PRINTD("<=Get EEPROM MAC address.\n");
00340 return true;
00341 }
00342 #if JACKDAW_CONF_RANDOM_MAC
00343 PRINTA("--Generating random MAC address.\n");
00344 generate_new_eui64(macptr);
00345 #else
00346 {uint8_t i;for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
00347 #endif
00348 settings_add(SETTINGS_KEY_EUI64,(unsigned char*)macptr,8);
00349 PRINTA("->Set EEPROM MAC address.\n");
00350 return true;
00351 }
00352 static uint16_t get_panid_from_eeprom(void) {
00353 uint16_t x;
00354 if (settings_check(SETTINGS_KEY_PAN_ID,0)) {
00355 x = settings_get_uint16(SETTINGS_KEY_PAN_ID,0);
00356 PRINTD("<-Get EEPROM PAN ID of %04x.\n",x);
00357 } else {
00358 x=pgm_read_word_near(&default_panid);
00359 if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
00360 PRINTA("->Set EEPROM PAN ID to %04x.\n",x);
00361 }
00362 }
00363 return x;
00364 }
00365 static uint16_t get_panaddr_from_eeprom(void) {
00366 uint16_t x;
00367 if (settings_check(SETTINGS_KEY_PAN_ADDR,0)) {
00368 x = settings_get_uint16(SETTINGS_KEY_PAN_ADDR,0);
00369 PRINTD("<-Get EEPROM PAN address of %04x.\n",x);
00370 } else {
00371 x=pgm_read_word_near(&default_panaddr);
00372 if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
00373 PRINTA("->Set EEPROM PAN address to %04x.\n",x);
00374 }
00375 }
00376 return x;
00377 }
00378 static uint8_t get_txpower_from_eeprom(void) {
00379 uint8_t x;
00380 if (settings_check(SETTINGS_KEY_TXPOWER,0)) {
00381 x = settings_get_uint8(SETTINGS_KEY_TXPOWER,0);
00382 PRINTD("<-Get EEPROM tx power of %d. (0=max)\n",x);
00383 } else {
00384 x=pgm_read_byte_near(&default_txpower);
00385 if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
00386 PRINTA("->Set EEPROM tx power of %d. (0=max)\n",x);
00387 }
00388 }
00389 return x;
00390 }
00391 #endif
00392
00393
00394
00395 static void initialize(void) {
00396
00397 watchdog_init();
00398 watchdog_start();
00399
00400 #if CONFIG_STACK_MONITOR
00401
00402
00403
00404 {
00405 extern uint16_t __bss_end;
00406 uint16_t p=(uint16_t)&__bss_end;
00407 do {
00408 *(uint16_t *)p = 0x4242;
00409 p+=100;
00410 } while (p<SP-100);
00411 }
00412 #endif
00413
00414
00415
00416 init_lowlevel();
00417
00418
00419 clock_init();
00420
00421
00422
00423 Leds_init();
00424 Led1_on();
00425
00426 #if USB_CONF_RS232
00427
00428 rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
00429
00430 rs232_redirect_stdout(RS232_PORT_0);
00431 #if ANNOUNCE
00432 PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
00433 #endif
00434 #endif
00435
00436
00437 rtimer_init();
00438
00439
00440 process_init();
00441
00442
00443 process_start(&etimer_process, NULL);
00444
00445 Led2_on();
00446
00447 process_start(&usb_process, NULL);
00448
00449
00450
00451 #if USB_CONF_SERIAL
00452 process_start(&cdc_process, NULL);
00453 {unsigned short i;
00454 for (i=0;i<65535;i++) {
00455 process_run();
00456 watchdog_periodic();
00457 if (stdout) break;
00458 }
00459 #if !USB_CONF_RS232
00460 PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
00461 #endif
00462 }
00463 #endif
00464 if (!stdout) Led3_on();
00465
00466 #if RF230BB
00467 #if JACKDAW_CONF_USE_SETTINGS
00468 PRINTA("Settings manager will be used.\n");
00469 #else
00470 {uint8_t x[2];
00471 *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel);
00472 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
00473 PRINTA("Invalid EEPROM settings detected. Rewriting with default values.\n");
00474 get_channel_from_eeprom();
00475 }
00476 }
00477 #endif
00478
00479 ctimer_init();
00480
00481
00482 NETSTACK_RADIO.init();
00483
00484
00485
00486 memset(&tmp_addr, 0, sizeof(rimeaddr_t));
00487
00488 if(get_eui64_from_eeprom(tmp_addr.u8));
00489
00490
00491 init_net();
00492
00493 #if UIP_CONF_IPV6
00494 memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8);
00495 #endif
00496
00497 rf230_set_pan_addr(
00498 get_panid_from_eeprom(),
00499 get_panaddr_from_eeprom(),
00500 (uint8_t *)&tmp_addr.u8
00501 );
00502
00503 rf230_set_channel(get_channel_from_eeprom());
00504 rf230_set_txpower(get_txpower_from_eeprom());
00505
00506 rimeaddr_set_node_addr(&tmp_addr);
00507
00508
00509 queuebuf_init();
00510 NETSTACK_RDC.init();
00511 NETSTACK_MAC.init();
00512 NETSTACK_NETWORK.init();
00513
00514 #if ANNOUNCE
00515 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]);
00516 PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
00517 if (NETSTACK_RDC.channel_check_interval) {
00518 unsigned short tmp;
00519 tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
00520 NETSTACK_RDC.channel_check_interval());
00521 if (tmp<65535) PRINTA(", check rate %u Hz",tmp);
00522 }
00523 PRINTA("\n");
00524 #endif
00525
00526 #if UIP_CONF_IPV6_RPL
00527 #if RPL_BORDER_ROUTER
00528 process_start(&tcpip_process, NULL);
00529 process_start(&border_router_process, NULL);
00530 PRINTD ("RPL Border Router Started\n");
00531 #else
00532 process_start(&tcpip_process, NULL);
00533 PRINTD ("RPL Started\n");
00534 #endif
00535 #if RPL_HTTPD_SERVER
00536 extern struct process httpd_process;
00537 process_start(&httpd_process, NULL);
00538 PRINTD ("Webserver Started\n");
00539 #endif
00540 #endif
00541
00542 #else
00543
00544 process_start(&mac_process, NULL);
00545 process_start(&tcpip_process, NULL);
00546 #endif
00547
00548
00549 process_start(&usb_eth_process, NULL);
00550 #if USB_CONF_STORAGE
00551 process_start(&storage_process, NULL);
00552 #endif
00553
00554 #if ANNOUNCE
00555 #if USB_CONF_RS232
00556 PRINTA("Online.\n");
00557 #else
00558 PRINTA("Online. Type ? for Jackdaw menu.\n");
00559 #endif
00560 #endif
00561
00562 Leds_off();
00563 }
00564
00565
00566
00567 int
00568 main(void)
00569 {
00570
00571 asm volatile ("clr r1");
00572
00573
00574 initialize();
00575
00576 #if DEBUG
00577 {struct process *p;
00578 for(p = PROCESS_LIST();p != NULL; p = ((struct process *)p->next)) {
00579 PRINTA("Process=%p Thread=%p Name=\"%s\" \n",p,p->thread,PROCESS_NAME_STRING(p));
00580 }
00581 }
00582 #endif
00583
00584 while(1) {
00585 process_run();
00586
00587 watchdog_periodic();
00588
00589
00590 #ifdef RF230_MIN_RX_POWER
00591 uint8_t lastprint;
00592 if (rf230_last_rssi != lastprint) {
00593 PRINTA("%u ",rf230_last_rssi);
00594 lastprint=rf230_last_rssi;
00595 }
00596 #endif
00597
00598 #if 0
00599
00600
00601
00602 extern uint8_t rf230_calibrated;
00603 if (rf230_calibrated) {
00604 PRINTA("\nRF230 calibrated!\n");
00605 rf230_calibrated=0;
00606 }
00607 #endif
00608
00609 #if TESTRTIMER
00610
00611
00612
00613
00614
00615 if (rtimerflag) {
00616 rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
00617 rtimerflag=0;
00618
00619 #if STAMPS
00620 if ((rtime%STAMPS)==0) {
00621 PRINTA("%us ",rtime);
00622 if (rtime%STAMPS*10) PRINTA("\n");
00623 }
00624 #endif
00625 rtime+=1;
00626
00627 #if PINGS && UIP_CONF_IPV6_RPL
00628 extern void raven_ping6(void);
00629 if ((rtime%PINGS)==1) {
00630 PRINTA("**Ping\n");
00631 raven_ping6();
00632 }
00633 #endif
00634
00635 #if ROUTES && UIP_CONF_IPV6_RPL
00636 if ((rtime%ROUTES)==2) {
00637
00638 extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
00639 extern uip_ds6_route_t uip_ds6_routing_table[];
00640 extern uip_ds6_netif_t uip_ds6_if;
00641
00642 uint8_t i,j;
00643 PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
00644 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
00645 if (uip_ds6_if.addr_list[i].isused) {
00646 uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
00647 PRINTA("\n");
00648 }
00649 }
00650 PRINTA("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
00651 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
00652 if(uip_ds6_nbr_cache[i].isused) {
00653 uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
00654 PRINTA("\n");
00655 j=0;
00656 }
00657 }
00658 if (j) PRINTA(" <none>");
00659 PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
00660 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
00661 if(uip_ds6_routing_table[i].isused) {
00662 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
00663 PRINTA("/%u (via ", uip_ds6_routing_table[i].length);
00664 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
00665
00666 PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
00667
00668
00669
00670 j=0;
00671 }
00672 }
00673 if (j) PRINTA(" <none>");
00674 PRINTA("\n---------\n");
00675 }
00676 #endif
00677
00678 #if STACKMONITOR && CONFIG_STACK_MONITOR
00679 if ((rtime%STACKMONITOR)==3) {
00680 extern uint16_t __bss_end;
00681 uint16_t p=(uint16_t)&__bss_end;
00682 do {
00683 if (*(uint16_t *)p != 0x4242) {
00684 PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
00685 break;
00686 }
00687 p+=100;
00688 } while (p<RAMEND-10);
00689 }
00690 #endif
00691
00692 }
00693 #endif
00694
00695
00696 #if RF230BB&&0
00697 extern uint8_t debugflowsize,debugflow[];
00698 if (debugflowsize) {
00699 debugflow[debugflowsize]=0;
00700 PRINTA("%s",debugflow);
00701 debugflowsize=0;
00702 }
00703 #endif
00704
00705 }
00706 return 0;
00707 }