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 #include <signal.h>
00038 #include <stdio.h>
00039 #include <string.h>
00040
00041 #include "contiki.h"
00042
00043 #include "dev/leds.h"
00044 #include "dev/serial-line.h"
00045 #include "dev/slip.h"
00046 #include "dev/xmem.h"
00047 #include "dev/button-sensor.h"
00048 #include "lib/random.h"
00049 #include "net/netstack.h"
00050 #include "net/mac/frame802154.h"
00051
00052 #if WITH_UIP6
00053 #include "net/sicslowpan.h"
00054 #include "net/uip-ds6.h"
00055 #include "net/mac/sicslowmac.h"
00056 #endif
00057
00058 #include "net/rime.h"
00059
00060 #include "sys/autostart.h"
00061 #include "sys/profile.h"
00062
00063
00064 #include "mc1322x.h"
00065 #include "default_lowlevel.h"
00066 #include "contiki-maca.h"
00067 #include "contiki-uart.h"
00068
00069 #define DEBUG 1
00070 #if DEBUG
00071 #include <stdio.h>
00072 #define PRINTF(...) printf(__VA_ARGS__)
00073 #define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15])
00074 #define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5])
00075 #else
00076 #define PRINTF(...)
00077 #define PRINT6ADDR(addr)
00078 #define PRINTLLADDR(addr)
00079 #endif
00080
00081 #ifndef RIMEADDR_NVM
00082 #define RIMEADDR_NVM 0x1E000
00083 #endif
00084
00085 #ifndef RIMEADDR_NBYTES
00086 #define RIMEADDR_NBYTES 8
00087 #endif
00088
00089 #define PLATFORM_DEBUG 1
00090 #if PLATFORM_DEBUG
00091 #define PRINTF(...) printf(__VA_ARGS__)
00092 #else
00093 #define PRINTF(...)
00094 #endif
00095
00096
00097 #if UIP_CONF_ROUTER
00098
00099 #ifndef UIP_ROUTER_MODULE
00100 #ifdef UIP_CONF_ROUTER_MODULE
00101 #define UIP_ROUTER_MODULE UIP_CONF_ROUTER_MODULE
00102 #else
00103 #define UIP_ROUTER_MODULE rimeroute
00104 #endif
00105 #endif
00106
00107 extern const struct uip_router UIP_ROUTER_MODULE;
00108
00109 #endif
00110
00111 #if DCOSYNCH_CONF_ENABLED
00112 static struct timer mgt_timer;
00113 #endif
00114
00115 #ifndef WITH_UIP
00116 #define WITH_UIP 0
00117 #endif
00118
00119 #if WITH_UIP
00120 #include "net/uip.h"
00121 #include "net/uip-fw.h"
00122 #include "net/uip-fw-drv.h"
00123 #include "net/uip-over-mesh.h"
00124 static struct uip_fw_netif slipif =
00125 {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
00126 static struct uip_fw_netif meshif =
00127 {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
00128
00129 #endif
00130
00131 #define UIP_OVER_MESH_CHANNEL 8
00132 #if WITH_UIP
00133 static uint8_t is_gateway;
00134 #endif
00135
00136
00137 void uip_log(char *msg) { printf("%c",msg); }
00138
00139 #ifndef RF_CHANNEL
00140 #define RF_CHANNEL 26
00141 #endif
00142
00143 #if WITH_UIP
00144 static void
00145 set_gateway(void)
00146 {
00147 if(!is_gateway) {
00148
00149 printf("%d.%d: making myself the IP network gateway.\n\n",
00150 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00151 printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
00152 uip_ipaddr_to_quad(&uip_hostaddr));
00153 uip_over_mesh_set_gateway(&rimeaddr_node_addr);
00154 uip_over_mesh_make_announced_gateway();
00155 is_gateway = 1;
00156 }
00157 }
00158 #endif
00159
00160 static void
00161 print_processes(struct process * const processes[])
00162 {
00163
00164 printf("Starting");
00165 while(*processes != NULL) {
00166 printf(" '%s'", (*processes)->name);
00167 processes++;
00168 }
00169 printf("\n");
00170 }
00171
00172
00173 SENSORS(&button_sensor);
00174
00175 void
00176 init_lowlevel(void)
00177 {
00178
00179 set_bit(*GPIO_PAD_DIR0,8);
00180 set_bit(*GPIO_PAD_DIR0,9);
00181 set_bit(*GPIO_PAD_DIR0,10);
00182 set_bit(*GPIO_PAD_DIR0,23);
00183 set_bit(*GPIO_PAD_DIR0,24);
00184 set_bit(*GPIO_PAD_DIR0,25);
00185
00186
00187
00188 enable_irq_kbi(4);
00189 kbi_edge(4);
00190 enable_ext_wu(4);
00191
00192
00193
00194
00195
00196 trim_xtal();
00197
00198
00199 uart_init(INC, MOD, SAMP);
00200
00201 default_vreg_init();
00202
00203 maca_init();
00204
00205 set_channel(RF_CHANNEL - 11);
00206 set_power(0x12);
00207
00208
00209 *GPIO_FUNC_SEL2 = (0x01 << ((44-16*2)*2));
00210 gpio_pad_dir_set( 1ULL << 44 );
00211
00212 enable_irq(CRM);
00213
00214 #if USE_32KHZ_XTAL
00215 enable_32khz_xtal();
00216 #else
00217 cal_ring_osc();
00218 #endif
00219
00220 #if USE_32KHZ_XTAL
00221 *CRM_RTC_TIMEOUT = 32768 * 10;
00222 #else
00223 *CRM_RTC_TIMEOUT = cal_rtc_secs * 10;
00224 #endif
00225
00226
00227
00228
00229
00230
00231 }
00232
00233 #if RIMEADDR_SIZE == 1
00234 const rimeaddr_t addr_ff = { { 0xff } };
00235 #else
00236 #if RIMEADDR_SIZE == 2
00237 const rimeaddr_t addr_ff = { { 0xff, 0xff } };
00238 #else
00239 #if RIMEADDR_SIZE == 8
00240 const rimeaddr_t addr_ff = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
00241 #endif
00242 #endif
00243 #endif
00244
00245 void iab_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint16_t iab, uint32_t ext) {
00246
00247 eui64->u8[0] = 0x00;
00248 eui64->u8[1] = 0x50;
00249 eui64->u8[2] = 0xc2;
00250
00251
00252 eui64->u8[3] = 0xff;
00253 eui64->u8[4] = 0xfe;
00254
00255
00256 eui64->u8[5] = (iab >> 4) & 0xff;
00257 eui64->u8[6] = (iab & 0xf) << 4;
00258
00259
00260 eui64->u8[6] |= ((ext >> 8) & 0xf);
00261 eui64->u8[7] = ext & 0xff;
00262 }
00263
00264 void oui_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint32_t ext) {
00265
00266 eui64->u8[0] = (oui >> 16) & 0xff;
00267 eui64->u8[1] = (oui >> 8) & 0xff;
00268 eui64->u8[2] = oui & 0xff;
00269
00270
00271 eui64->u8[3] = 0xff;
00272 eui64->u8[4] = 0xfe;
00273
00274
00275 eui64->u8[5] = (ext >> 16) & 0xff;
00276 eui64->u8[6] = (ext >> 8) & 0xff;
00277 eui64->u8[7] = ext & 0xff;
00278 }
00279
00280 void
00281 set_rimeaddr(rimeaddr_t *addr)
00282 {
00283 nvmType_t type=0;
00284 nvmErr_t err;
00285 volatile uint8_t buf[RIMEADDR_NBYTES];
00286 rimeaddr_t eui64;
00287 int i;
00288
00289 err = nvm_detect(gNvmInternalInterface_c, &type);
00290
00291 err = nvm_read(gNvmInternalInterface_c, type, (uint8_t *)buf, RIMEADDR_NVM, RIMEADDR_NBYTES);
00292
00293 rimeaddr_copy(addr,&rimeaddr_null);
00294
00295 for(i=0; i<RIMEADDR_CONF_SIZE; i++) {
00296 addr->u8[i] = buf[i];
00297 }
00298
00299 if (memcmp(addr, &addr_ff, RIMEADDR_CONF_SIZE)==0) {
00300
00301
00302 #ifdef IAB
00303 #ifdef EXT_ID
00304 PRINTF("address in flash blank, setting to defined IAB and extension.\n\r");
00305 iab_to_eui64(&eui64, OUI, IAB, EXT_ID);
00306 #else
00307 PRINTF("address in flash blank, setting to defined IAB with a random extension.\n\r");
00308 iab_to_eui64(&eui64, OUI, IAB, *MACA_RANDOM & 0xfff);
00309 #endif
00310
00311 #else
00312
00313 #ifdef EXT_ID
00314 PRINTF("address in flash blank, setting to defined OUI and extension.\n\r");
00315 oui_to_eui64(&eui64, OUI, EXT_ID);
00316 #else
00317 PRINTF("address in flash blank, setting to defined OUI with a random extension.\n\r");
00318 oui_to_eui64(&eui64, OUI, *MACA_RANDOM & 0xffffff);
00319 #endif
00320
00321 #endif
00322
00323 rimeaddr_copy(addr, &eui64);
00324 #ifdef FLASH_BLANK_ADDR
00325 PRINTF("flashing blank address\n\r");
00326 err = nvm_write(gNvmInternalInterface_c, type, &(eui64.u8), RIMEADDR_NVM, RIMEADDR_NBYTES);
00327 #endif
00328 } else {
00329 PRINTF("loading rime address from flash.\n\r");
00330 }
00331
00332 rimeaddr_set_node_addr(addr);
00333 }
00334
00335 int
00336 main(void)
00337 {
00338 volatile uint32_t i;
00339 rimeaddr_t addr;
00340
00341
00342
00343 init_lowlevel();
00344
00345
00346 clock_init();
00347
00348
00349 process_init();
00350 process_start(&etimer_process, NULL);
00351 process_start(&contiki_maca_process, NULL);
00352
00353 ctimer_init();
00354
00355 set_rimeaddr(&addr);
00356
00357 printf("Rime started with address ");
00358 for(i = 0; i < sizeof(addr.u8) - 1; i++) {
00359 printf("%02X:", addr.u8[i]);
00360 }
00361 printf("%02X\n", addr.u8[i]);
00362
00363
00364 #if WITH_UIP6
00365 memcpy(&uip_lladdr.addr, &addr.u8, sizeof(uip_lladdr.addr));
00366
00367
00368
00369
00370
00371 queuebuf_init();
00372 NETSTACK_RDC.init();
00373 NETSTACK_MAC.init();
00374 NETSTACK_NETWORK.init();
00375
00376 printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00377 NETSTACK_MAC.name, NETSTACK_RDC.name,
00378 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
00379 NETSTACK_RDC.channel_check_interval()),
00380 RF_CHANNEL);
00381
00382 process_start(&tcpip_process, NULL);
00383
00384 printf("Tentative link-local IPv6 address ");
00385 {
00386 int i, a;
00387 for(a = 0; a < UIP_DS6_ADDR_NB; a++) {
00388 if (uip_ds6_if.addr_list[a].isused) {
00389 for(i = 0; i < 7; ++i) {
00390 printf("%02x%02x:",
00391 uip_ds6_if.addr_list[a].ipaddr.u8[i * 2],
00392 uip_ds6_if.addr_list[a].ipaddr.u8[i * 2 + 1]);
00393 }
00394 printf("%02x%02x\n",
00395 uip_ds6_if.addr_list[a].ipaddr.u8[14],
00396 uip_ds6_if.addr_list[a].ipaddr.u8[15]);
00397 }
00398 }
00399 }
00400
00401 if(1) {
00402 uip_ipaddr_t ipaddr;
00403 int i;
00404 uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
00405 uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
00406 uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
00407 printf("Tentative global IPv6 address ");
00408 for(i = 0; i < 7; ++i) {
00409 printf("%02x%02x:",
00410 ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
00411 }
00412 printf("%02x%02x\n",
00413 ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
00414 }
00415
00416
00417 #else
00418
00419 NETSTACK_RDC.init();
00420 NETSTACK_MAC.init();
00421 NETSTACK_NETWORK.init();
00422
00423 printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00424 NETSTACK_MAC.name, NETSTACK_RDC.name,
00425 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
00426 NETSTACK_RDC.channel_check_interval()),
00427 RF_CHANNEL);
00428 #endif
00429
00430 #if PROFILE_CONF_ON
00431 profile_init();
00432 #endif
00433
00434 #if TIMESYNCH_CONF_ENABLED
00435 timesynch_init();
00436 timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
00437 #endif
00438
00439 #if WITH_UIP
00440 process_start(&tcpip_process, NULL);
00441 process_start(&uip_fw_process, NULL);
00442 process_start(&slip_process, NULL);
00443
00444 slip_set_input_callback(set_gateway);
00445
00446 {
00447 uip_ipaddr_t hostaddr, netmask;
00448
00449 uip_init();
00450
00451 uip_ipaddr(&hostaddr, 172,16,
00452 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00453 uip_ipaddr(&netmask, 255,255,0,0);
00454 uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
00455
00456 uip_sethostaddr(&hostaddr);
00457 uip_setnetmask(&netmask);
00458 uip_over_mesh_set_net(&hostaddr, &netmask);
00459
00460 uip_over_mesh_set_gateway_netif(&slipif);
00461 uip_fw_default(&meshif);
00462 uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
00463 printf("uIP started with IP address %d.%d.%d.%d\n",
00464 uip_ipaddr_to_quad(&hostaddr));
00465 }
00466 #endif
00467
00468 process_start(&sensors_process, NULL);
00469
00470 print_processes(autostart_processes);
00471 autostart_start(autostart_processes);
00472
00473
00474 while(1) {
00475 check_maca();
00476
00477
00478 if(uart1_input_handler != NULL) {
00479 if(uart1_can_get()) {
00480 uart1_input_handler(uart1_getc());
00481 }
00482 }
00483
00484 process_run();
00485 }
00486
00487 return 0;
00488 }
00489
00490
00491 #if LOG_CONF_ENABLED
00492 void
00493 log_message(char *m1, char *m2)
00494 {
00495 printf("%s%s\n", m1, m2);
00496 }
00497 #endif