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