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 }