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