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 #ifndef LED_ON_PORT1E
00033 #define LED_ON_PORTE1 1 //for Michael Hartman's prototype board
00034 #endif
00035 #define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
00036
00037 #define DEBUG DEBUG_PRINT
00038 #include "uip-debug.h"
00039
00040 #include <avr/pgmspace.h>
00041 #include <avr/fuse.h>
00042 #include <avr/eeprom.h>
00043 #include <stdio.h>
00044 #include <string.h>
00045 #include <dev/watchdog.h>
00046
00047 #include "loader/symbols-def.h"
00048 #include "loader/symtab.h"
00049
00050 #if RF230BB //radio driver using contiki core mac
00051 #include "radio/rf230bb/rf230bb.h"
00052 #include "net/mac/frame802154.h"
00053 #include "net/mac/framer-802154.h"
00054 #include "net/sicslowpan.h"
00055
00056 #else //radio driver using Atmel/Cisco 802.15.4'ish MAC
00057 #include <stdbool.h>
00058 #include "mac.h"
00059 #include "sicslowmac.h"
00060 #include "sicslowpan.h"
00061 #include "ieee-15-4-manager.h"
00062 #endif
00063
00064 #include "contiki.h"
00065 #include "contiki-net.h"
00066 #include "contiki-lib.h"
00067
00068 #include "dev/rs232.h"
00069 #include "dev/serial-line.h"
00070 #include "dev/slip.h"
00071
00072
00073 #ifdef RAVEN_LCD_INTERFACE
00074 #include "raven-lcd.h"
00075 #endif
00076
00077 #if WEBSERVER
00078 #include "httpd-fs.h"
00079 #include "httpd-cgi.h"
00080 #endif
00081
00082 #ifdef COFFEE_FILES
00083 #include "cfs/cfs.h"
00084 #include "cfs/cfs-coffee.h"
00085 #endif
00086
00087 #if UIP_CONF_ROUTER&&0
00088 #include "net/routing/rimeroute.h"
00089 #include "net/rime/rime-udp.h"
00090 #endif
00091
00092 #include "net/rime.h"
00093
00094
00095 #define TESTRTIMER 1
00096 #if TESTRTIMER
00097
00098 #define ROUTES 600
00099 #define STAMPS 60
00100 #define STACKMONITOR 600
00101
00102 uint8_t rtimerflag=1;
00103 uint16_t rtime;
00104 struct rtimer rt;
00105 void rtimercycle(void) {rtimerflag=1;}
00106
00107 #endif
00108
00109
00110
00111 typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t;
00112 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
00113 SIGNATURE = {
00114
00115 .B2 = SIGNATURE_2,
00116 .B1 = SIGNATURE_1,
00117 .B0 = SIGNATURE_0,
00118 };
00119
00120 FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
00121
00122
00123
00124
00125
00126
00127
00128 #if WEBSERVER
00129 extern uint8_t mac_address[8];
00130 extern uint8_t server_name[16];
00131 extern uint8_t domain_name[30];
00132 #else
00133 uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
00134 #endif
00135
00136
00137 #ifdef CHANNEL_802_15_4
00138 uint8_t rf_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
00139
00140 #else
00141 uint8_t rf_channel[2] EEMEM = {26, ~26};
00142 #endif
00143 static uint8_t get_channel_from_eeprom() {
00144 uint8_t eeprom_channel;
00145 uint8_t eeprom_check;
00146
00147 eeprom_channel = eeprom_read_byte(&rf_channel[0]);
00148 eeprom_check = eeprom_read_byte(&rf_channel[1]);
00149
00150 if(eeprom_channel==~eeprom_check)
00151 return eeprom_channel;
00152
00153 #ifdef CHANNEL_802_15_4
00154
00155 return(CHANNEL_802_15_4);
00156 #else
00157 return 26;
00158 #endif
00159 }
00160
00161 static bool get_mac_from_eeprom(uint8_t* macptr) {
00162 eeprom_read_block ((void *)macptr, &mac_address, 8);
00163 return true;
00164 }
00165
00166 static uint16_t get_panid_from_eeprom(void) {
00167
00168 return IEEE802154_PANID;
00169
00170 }
00171
00172 static uint16_t get_panaddr_from_eeprom(void) {
00173
00174 return 0;
00175
00176 }
00177
00178 void calibrate_rc_osc_32k();
00179 extern uint8_t osccal_calibrated;
00180
00181
00182 void initialize(void)
00183 {
00184 #if !LED_ON_PORTE1 //Conflicts with USART0
00185 #if RAVEN_LCD_INTERFACE
00186
00187 rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
00188
00189 rs232_set_input(0,raven_lcd_serial_input);
00190 #else
00191
00192 rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
00193 #endif
00194 #endif
00195
00196
00197 rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
00198
00199 rs232_redirect_stdout(RS232_PORT_1);
00200 clock_init();
00201
00202 #if 1
00203 if(MCUSR & (1<<PORF )) PRINTA("Power-on reset.\n");
00204 if(MCUSR & (1<<EXTRF)) PRINTA("External reset!\n");
00205 if(MCUSR & (1<<BORF )) PRINTA("Brownout reset!\n");
00206 if(MCUSR & (1<<WDRF )) PRINTA("Watchdog reset!\n");
00207 if(MCUSR & (1<<JTRF )) PRINTA("JTAG reset!\n");
00208 #endif
00209
00210 watchdog_init();
00211 watchdog_start();
00212 #if UIP_CONF_IPV6_RPL==1
00213 #warning rpl selected
00214 #warning rpl selected
00215 #warning rpl selected
00216 #warning rpl selected
00217 #warning rpl selected
00218 #warning rpl selected
00219 #warning rpl selected
00220 #warning rpl selected
00221 #else
00222 #warning rpl not selected
00223 #warning rpl not selected
00224 #warning rpl not selected
00225 #warning rpl not selected
00226 #warning rpl not selected
00227 #warning rpl not selected
00228 #warning rpl not selected
00229 #warning rpl not selected
00230 #warning rpl not selected
00231 #endif
00232
00233 #if STACKMONITOR
00234
00235
00236
00237
00238 {
00239 extern uint16_t __bss_end;
00240 uint16_t p=(uint16_t)&__bss_end;
00241 do {
00242 *(uint16_t *)p = 0x4242;
00243 p+=10;
00244 } while (p<SP-10);
00245 }
00246 #endif
00247
00248 #define CONF_CALIBRATE_OSCCAL 0
00249 #if CONF_CALIBRATE_OSCCAL
00250 {
00251 uint8_t i;
00252 watchdog_stop();
00253 PRINTA("\nBefore calibration OSCCAL=%x\n",OSCCAL);
00254 for (i=0;i<10;i++) {
00255 calibrate_rc_osc_32k();
00256 PRINTA("Calibrated=%x\n",osccal_calibrated);
00257
00258
00259
00260 }
00261 clock_init();
00262 watchdog_start();
00263 }
00264 #endif
00265
00266 #if ANNOUNCE_BOOT
00267 PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
00268 #endif
00269
00270
00271 rtimer_init();
00272
00273
00274 process_init();
00275
00276 process_start(&etimer_process, NULL);
00277
00278 #if RF230BB
00279
00280 ctimer_init();
00281
00282 NETSTACK_RADIO.init();
00283
00284
00285
00286 rimeaddr_t addr;
00287 memset(&addr, 0, sizeof(rimeaddr_t));
00288 get_mac_from_eeprom(addr.u8);
00289
00290 #if UIP_CONF_IPV6
00291 memcpy(&uip_lladdr.addr, &addr.u8, 8);
00292 #endif
00293 rf230_set_pan_addr(
00294 get_panid_from_eeprom(),
00295 get_panaddr_from_eeprom(),
00296 (uint8_t *)&addr.u8
00297 );
00298 rf230_set_channel(get_channel_from_eeprom());
00299
00300 rimeaddr_set_node_addr(&addr);
00301
00302 PRINTF("MAC address %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]);
00303
00304
00305 queuebuf_init();
00306 NETSTACK_RDC.init();
00307 NETSTACK_MAC.init();
00308 NETSTACK_NETWORK.init();
00309
00310 #if ANNOUNCE_BOOT
00311 PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
00312 if (NETSTACK_RDC.channel_check_interval) {
00313 unsigned short tmp;
00314 tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
00315 NETSTACK_RDC.channel_check_interval());
00316 if (tmp<65535) PRINTA(", check rate %u Hz",tmp);
00317 }
00318 PRINTA("\n");
00319 #endif
00320
00321 #if UIP_CONF_ROUTER
00322 #if ANNOUNCE_BOOT
00323 PRINTA("Routing Enabled\n");
00324 #endif
00325
00326
00327 #endif
00328
00329 process_start(&tcpip_process, NULL);
00330
00331 #else
00332
00333 process_start(&mac_process, NULL);
00334 process_start(&tcpip_process, NULL);
00335 #endif
00336
00337 #ifdef RAVEN_LCD_INTERFACE
00338 process_start(&raven_lcd_process, NULL);
00339 #endif
00340
00341
00342 autostart_start(autostart_processes);
00343
00344
00345
00346
00347
00348 #if COFFEE_FILES
00349 int fa = cfs_open( "/index.html", CFS_READ);
00350 if (fa<0) {
00351 PRINTF("No index.html file found, creating upload.html!\n");
00352 PRINTA("Formatting FLASH file system for coffee...");
00353 cfs_coffee_format();
00354 PRINTA("Done!\n");
00355 fa = cfs_open( "/index.html", CFS_WRITE);
00356 int r = cfs_write(fa, &"It works!", 9);
00357 if (r<0) PRINTF("Can''t create /index.html!\n");
00358 cfs_close(fa);
00359
00360
00361 }
00362 #endif
00363
00364
00365 #if 0
00366 {
00367 uip_ip6addr_t ipaddr;
00368 uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
00369 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
00370
00371 }
00372 #endif
00373
00374
00375 #if ANNOUNCE_BOOT
00376
00377 #if WEBSERVER
00378 uint8_t i;
00379 char buf[80];
00380 unsigned int size;
00381
00382 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
00383 if (uip_ds6_if.addr_list[i].isused) {
00384 httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf);
00385 PRINTA("IPv6 Address: %s\n",buf);
00386 }
00387 }
00388 eeprom_read_block (buf,server_name, sizeof(server_name));
00389 buf[sizeof(server_name)]=0;
00390 PRINTA("%s",buf);
00391 eeprom_read_block (buf,domain_name, sizeof(domain_name));
00392 buf[sizeof(domain_name)]=0;
00393 size=httpd_fs_get_size();
00394 #ifndef COFFEE_FILES
00395 PRINTA(".%s online with fixed %u byte web content\n",buf,size);
00396 #elif COFFEE_FILES==1
00397 PRINTA(".%s online with static %u byte EEPROM file system\n",buf,size);
00398 #elif COFFEE_FILES==2
00399 PRINTA(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
00400 #elif COFFEE_FILES==3
00401 PRINTA(".%s online with static %u byte program memory file system\n",buf,size);
00402 #elif COFFEE_FILES==4
00403 PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
00404 #endif
00405
00406 #else
00407 PRINTA("Online\n");
00408 #endif
00409
00410 #endif
00411 }
00412
00413
00414 void log_message(char *m1, char *m2)
00415 {
00416 PRINTA("%s%s\n", m1, m2);
00417 }
00418
00419 #if RF230BB
00420 extern char rf230_interrupt_flag, rf230processflag;
00421 #endif
00422
00423 uint16_t ledtimer;
00424
00425
00426
00427
00428 int
00429 main(void)
00430 {
00431
00432 initialize();
00433
00434 #if LED_ON_PORTE1
00435
00436 DDRE|=(1<<DDE1);
00437 PORTE&=~(1<<PE1);
00438 #endif
00439
00440 while(1) {
00441 process_run();
00442
00443 #if LED_ON_PORTE1
00444
00445 if (ledtimer) {
00446 if (--ledtimer==0) {
00447 PORTE&=~(1<<PE1);
00448
00449 extern void raven_ping6(void);
00450
00451 }
00452 }
00453 #endif
00454
00455 #if 0
00456
00457
00458
00459 NETSTACK_RADIO.send(packetbuf_hdrptr(), 42);
00460 process_poll(&rf230_process);
00461 packetbuf_clear();
00462 len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
00463 packetbuf_set_datalen(42);
00464 NETSTACK_RDC.input();
00465 #endif
00466
00467 watchdog_periodic();
00468 #if 0
00469
00470
00471
00472 extern uint8_t rf230_calibrated;
00473 if (rf230_calibrated) {
00474 PRINTA("\nRF230 calibrated!\n");
00475 rf230_calibrated=0;
00476 }
00477 #endif
00478
00479 #if TESTRTIMER
00480
00481
00482
00483
00484
00485 if (rtimerflag) {
00486 rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
00487 rtimerflag=0;
00488
00489 #if STAMPS
00490 if ((rtime%STAMPS)==0) {
00491 PRINTA("%us ",rtime);
00492 }
00493 #endif
00494 rtime+=1;
00495
00496 #if PINGS
00497 extern void raven_ping6(void);
00498 if ((rtime%PINGS)==1) {
00499 PRINTA("**Ping\n");
00500 raven_ping6();
00501 }
00502 #endif
00503
00504 #if ROUTES
00505 if ((rtime%ROUTES)==2) {
00506
00507 extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
00508 extern uip_ds6_route_t uip_ds6_routing_table[];
00509 extern uip_ds6_netif_t uip_ds6_if;
00510
00511 uint8_t i,j;
00512 PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
00513 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
00514 if (uip_ds6_if.addr_list[i].isused) {
00515 uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
00516 PRINTA("\n");
00517 }
00518 }
00519 PRINTA("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
00520 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
00521 if(uip_ds6_nbr_cache[i].isused) {
00522 uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
00523 PRINTA("\n");
00524 j=0;
00525 }
00526 }
00527 if (j) PRINTA(" <none>");
00528 PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
00529 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
00530 if(uip_ds6_routing_table[i].isused) {
00531 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
00532 PRINTA("/%u (via ", uip_ds6_routing_table[i].length);
00533 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
00534
00535 PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
00536
00537
00538
00539 j=0;
00540 }
00541 }
00542 if (j) PRINTA(" <none>");
00543 PRINTA("\n---------\n");
00544 }
00545 #endif
00546
00547 #if STACKMONITOR
00548 if ((rtime%STACKMONITOR)==3) {
00549 extern uint16_t __bss_end;
00550 uint16_t p=(uint16_t)&__bss_end;
00551 do {
00552 if (*(uint16_t *)p != 0x4242) {
00553 PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
00554 break;
00555 }
00556 p+=10;
00557 } while (p<RAMEND-10);
00558 }
00559 #endif
00560
00561 }
00562 #endif
00563
00564
00565 #if RF230BB&&0
00566 extern uint8_t debugflowsize,debugflow[];
00567 if (debugflowsize) {
00568 debugflow[debugflowsize]=0;
00569 PRINTA("%s",debugflow);
00570 debugflowsize=0;
00571 }
00572 #endif
00573
00574 #if RF230BB&&0
00575 if (rf230processflag) {
00576 PRINTA("rf230p%d",rf230processflag);
00577 rf230processflag=0;
00578 }
00579 #endif
00580
00581 #if RF230BB&&0
00582 if (rf230_interrupt_flag) {
00583
00584 PRINTA("**RI%u",rf230_interrupt_flag);
00585
00586 rf230_interrupt_flag=0;
00587 }
00588 #endif
00589 }
00590 return 0;
00591 }