contiki-mc1322x-main.c

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 #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 /* WITH_UIP6 */
00058 
00059 #include "net/rime.h"
00060 
00061 #include "sys/autostart.h"
00062 #include "sys/profile.h"
00063 
00064 /* from libmc1322x */
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 /* UIP_CONF_ROUTER_MODULE */
00096 #define UIP_ROUTER_MODULE rimeroute
00097 #endif /* UIP_CONF_ROUTER_MODULE */
00098 #endif /* UIP_ROUTER_MODULE */
00099 
00100 extern const struct uip_router UIP_ROUTER_MODULE;
00101 
00102 #endif /* UIP_CONF_ROUTER */
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 /* WITH_UIP */
00123 
00124 #define UIP_OVER_MESH_CHANNEL 8
00125 #if WITH_UIP
00126 static uint8_t is_gateway;
00127 #endif /* WITH_UIP */
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 /* WITH_UIP */
00152 /*---------------------------------------------------------------------------*/
00153 static void
00154 print_processes(struct process * const processes[])
00155 {
00156   /*  const struct process * const * p = processes;*/
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         /* button init */
00194         /* set up kbi */
00195         enable_irq_kbi(4);
00196         kbi_edge(4);
00197         enable_ext_wu(4);
00198 //      kbi_pol_neg(7);
00199 //      kbi_pol_pos(7);
00200 //      gpio_sel0_pullup(29);
00201 //      gpio_pu0_disable(29);
00202 
00203         trim_xtal();
00204         
00205         /* uart init */
00206         uart_init(INC, MOD, SAMP);
00207         
00208         default_vreg_init();
00209 
00210         maca_init();
00211 
00212         set_channel(RF_CHANNEL - 11); /* channel 11 */
00213         set_power(0x12); /* 0x12 is the highest, not documented */
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         /* set the watchdog timer timeout to 1 sec */
00231         cop_timeout_ms(WDT_TIMEOUT);
00232         /* enable the watchdog timer */
00233         CRM->COP_CNTLbits.COP_EN = 1;
00234 #endif
00235 
00236         /* XXX debug */
00237         /* trigger periodic rtc int */
00238 //      clear_rtc_wu_evt();
00239 //      enable_rtc_wu();
00240 //      enable_rtc_wu_irq();
00241 }
00242 
00243 #if RIMEADDR_SIZE == 1
00244 const rimeaddr_t addr_ff = { { 0xff } };
00245 #else /*RIMEADDR_SIZE == 2*/
00246 #if RIMEADDR_SIZE == 2
00247 const rimeaddr_t addr_ff = { { 0xff, 0xff } };
00248 #else /*RIMEADDR_SIZE == 2*/
00249 #if RIMEADDR_SIZE == 8
00250 const rimeaddr_t addr_ff = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
00251 #endif /*RIMEADDR_SIZE == 8*/
00252 #endif /*RIMEADDR_SIZE == 2*/
00253 #endif /*RIMEADDR_SIZE == 1*/
00254 
00255 void iab_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint16_t iab, uint32_t ext) {
00256         /* OUI for IABs */
00257         eui64->u8[0] =  0x00;
00258         eui64->u8[1] =  0x50;
00259         eui64->u8[2] =  0xc2;
00260 
00261         /* IAB */
00262         eui64->u8[3] = (iab >> 4)  & 0xff;
00263         eui64->u8[4] = (iab << 4) &  0xf0;
00264 
00265         /* EXT */
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         /* OUI */
00275         eui64->u8[0] = (oui >> 16) & 0xff;
00276         eui64->u8[1] = (oui >> 8)  & 0xff;
00277         eui64->u8[2] =  oui        & 0xff;
00278 
00279         /* EXT */
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                 //set addr to EUI64
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  /* ifdef EXT_ID */
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 /* ifdef EXT_ID */
00317 
00318 #else  /* ifdef IAB */
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  /*ifdef EXT_ID */
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 /*endif EXTID */
00327 
00328 #endif /* ifdef IAB */
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 /* ifdef FLASH_BLANK_ADDR */
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         /* Initialize hardware and */
00349         /* go into user mode */
00350         init_lowlevel();
00351 
00352         /* Clock */
00353         clock_init();   
00354 
00355         /* LED driver */
00356         leds_init();
00357 
00358         /* control TX_ON with the radio */
00359         GPIO->FUNC_SEL.GPIO_44 = 2;
00360         GPIO->PAD_DIR.GPIO_44 = 1;
00361 
00362         /* Process subsystem */
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   /* Setup nullmac-like MAC for 802.15.4 */
00381 /*   sicslowpan_init(sicslowmac_init(&cc2420_driver)); */
00382 /*   printf(" %s channel %u\n", sicslowmac_driver.name, RF_CHANNEL); */
00383 
00384   /* Setup X-MAC for 802.15.4 */
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 /* WITH_UIP6 */
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 /* WITH_UIP6 */
00444 
00445   *MACA_MACPANID = 0xcdab; /* this is the hardcoded contiki pan, register is PACKET order */
00446   *MACA_MAC16ADDR = 0xffff; /* short addressing isn't used, set this to 0xffff for now */
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 /* PROFILE_CONF_ON */
00469 
00470 #if TIMESYNCH_CONF_ENABLED
00471   timesynch_init();
00472   timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
00473 #endif /* TIMESYNCH_CONF_ENABLED */
00474 
00475 #if WITH_UIP
00476   process_start(&tcpip_process, NULL);
00477   process_start(&uip_fw_process, NULL); /* Start IP output */
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     /*    uip_fw_register(&slipif);*/
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 /* WITH_UIP */
00503 
00504   process_start(&sensors_process, NULL);
00505   
00506   print_processes(autostart_processes);
00507   autostart_start(autostart_processes);
00508  
00509   /* Main scheduler loop */
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 /* LOG_CONF_ENABLED */
00538 /*---------------------------------------------------------------------------*/

Generated on Mon Apr 11 14:23:45 2011 for Contiki 2.5 by  doxygen 1.6.1