Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors 00003 * to the MC1322x project (http://mc1322x.devl.org) and Contiki. 00004 * 00005 * Copyright (c) 2006, Technical University of Munich 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 1. Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in the 00015 * documentation and/or other materials provided with the distribution. 00016 * 3. Neither the name of the Institute nor the names of its contributors 00017 * may be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00024 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00025 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00026 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00027 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00028 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00029 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00030 * SUCH DAMAGE. 00031 * 00032 * This file is part of the Contiki operating system. 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 /* WITH_UIP6 */ 00057 00058 #include "net/rime.h" 00059 00060 #include "sys/autostart.h" 00061 #include "sys/profile.h" 00062 00063 /* from libmc1322x */ 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 ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_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 /* UIP_CONF_ROUTER_MODULE */ 00103 #define UIP_ROUTER_MODULE rimeroute 00104 #endif /* UIP_CONF_ROUTER_MODULE */ 00105 #endif /* UIP_ROUTER_MODULE */ 00106 00107 extern const struct uip_router UIP_ROUTER_MODULE; 00108 00109 #endif /* UIP_CONF_ROUTER */ 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 /* WITH_UIP */ 00130 00131 #define UIP_OVER_MESH_CHANNEL 8 00132 #if WITH_UIP 00133 static uint8_t is_gateway; 00134 #endif /* WITH_UIP */ 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 // leds_on(LEDS_RED); 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 /* WITH_UIP */ 00159 /*---------------------------------------------------------------------------*/ 00160 static void 00161 print_processes(struct process * const processes[]) 00162 { 00163 /* const struct process * const * p = processes;*/ 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 /* led direction init */ 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 /* button init */ 00187 /* set up kbi */ 00188 enable_irq_kbi(4); 00189 kbi_edge(4); 00190 enable_ext_wu(4); 00191 // kbi_pol_neg(7); 00192 // kbi_pol_pos(7); 00193 // gpio_sel0_pullup(29); 00194 // gpio_pu0_disable(29); 00195 00196 trim_xtal(); 00197 00198 /* uart init */ 00199 uart_init(BRINC, BRMOD, SAMP); 00200 00201 default_vreg_init(); 00202 00203 maca_init(); 00204 00205 set_channel(RF_CHANNEL - 11); /* channel 11 */ 00206 set_power(0x12); /* 0x12 is the highest, not documented */ 00207 00208 /* control TX_ON with the radio */ 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 /* XXX debug */ 00227 /* trigger periodic rtc int */ 00228 // clear_rtc_wu_evt(); 00229 // enable_rtc_wu(); 00230 // enable_rtc_wu_irq(); 00231 } 00232 00233 #if RIMEADDR_SIZE == 1 00234 const rimeaddr_t addr_ff = { { 0xff } }; 00235 #else /*RIMEADDR_SIZE == 2*/ 00236 #if RIMEADDR_SIZE == 2 00237 const rimeaddr_t addr_ff = { { 0xff, 0xff } }; 00238 #else /*RIMEADDR_SIZE == 2*/ 00239 #if RIMEADDR_SIZE == 8 00240 const rimeaddr_t addr_ff = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; 00241 #endif /*RIMEADDR_SIZE == 8*/ 00242 #endif /*RIMEADDR_SIZE == 2*/ 00243 #endif /*RIMEADDR_SIZE == 1*/ 00244 00245 void iab_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint16_t iab, uint32_t ext) { 00246 /* OUI for IABs */ 00247 eui64->u8[0] = 0x00; 00248 eui64->u8[1] = 0x50; 00249 eui64->u8[2] = 0xc2; 00250 00251 /* EUI64 field */ 00252 eui64->u8[3] = 0xff; 00253 eui64->u8[4] = 0xfe; 00254 00255 /* IAB */ 00256 eui64->u8[5] = (iab >> 4) & 0xff; 00257 eui64->u8[6] = (iab & 0xf) << 4; 00258 00259 /* EXT */ 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 /* OUI */ 00266 eui64->u8[0] = (oui >> 16) & 0xff; 00267 eui64->u8[1] = (oui >> 8) & 0xff; 00268 eui64->u8[2] = oui & 0xff; 00269 00270 /* EUI64 field */ 00271 eui64->u8[3] = 0xff; 00272 eui64->u8[4] = 0xfe; 00273 00274 /* EXT */ 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 //set addr to EUI64 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 /* ifdef EXT_ID */ 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 /* ifdef EXT_ID */ 00310 00311 #else /* ifdef IAB */ 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 /*ifdef EXT_ID */ 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 /*endif EXTID */ 00320 00321 #endif /* ifdef IAB */ 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 /* ifdef FLASH_BLANK_ADDR */ 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 /* Initialize hardware and */ 00342 /* go into user mode */ 00343 init_lowlevel(); 00344 00345 /* Clock */ 00346 clock_init(); 00347 00348 /* Process subsystem */ 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 /* Setup nullmac-like MAC for 802.15.4 */ 00367 /* sicslowpan_init(sicslowmac_init(&cc2420_driver)); */ 00368 /* printf(" %s channel %u\n", sicslowmac_driver.name, RF_CHANNEL); */ 00369 00370 /* Setup X-MAC for 802.15.4 */ 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 /* WITH_UIP6 */ 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 /* WITH_UIP6 */ 00429 00430 #if PROFILE_CONF_ON 00431 profile_init(); 00432 #endif /* PROFILE_CONF_ON */ 00433 00434 #if TIMESYNCH_CONF_ENABLED 00435 timesynch_init(); 00436 timesynch_set_authority_level(rimeaddr_node_addr.u8[0]); 00437 #endif /* TIMESYNCH_CONF_ENABLED */ 00438 00439 #if WITH_UIP 00440 process_start(&tcpip_process, NULL); 00441 process_start(&uip_fw_process, NULL); /* Start IP output */ 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 /* uip_fw_register(&slipif);*/ 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 /* WITH_UIP */ 00467 00468 process_start(&sensors_process, NULL); 00469 00470 print_processes(autostart_processes); 00471 autostart_start(autostart_processes); 00472 00473 /* Main scheduler loop */ 00474 while(1) { 00475 check_maca(); 00476 00477 /* TODO: replace this with a uart rx interrupt */ 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 /* LOG_CONF_ENABLED */