Contiki 2.6

contiki-exp5438-main.c

00001 /*
00002  * Copyright (c) 2006, Swedish Institute of Computer Science
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * @(#)$Id: contiki-z1-main.c,v 1.4 2010/08/26 22:08:11 nifi Exp $
00030  */
00031 
00032 #include "contiki.h"
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <stdarg.h>
00036 
00037 #include "dev/button-sensor.h"
00038 #include "dev/cc2420.h"
00039 #include "dev/flash.h"
00040 #include "dev/leds.h"
00041 #include "dev/serial-line.h"
00042 #include "dev/slip.h"
00043 #include "dev/uart1.h"
00044 #include "dev/watchdog.h"
00045 #include "dev/xmem.h"
00046 #include "lib/random.h"
00047 #include "lib/sensors.h"
00048 #include "net/mac/frame802154.h"
00049 #include "net/netstack.h"
00050 #include "net/rime.h"
00051 #include "sys/autostart.h"
00052 #include "sys/profile.h"
00053 
00054 #include "node-id.h"
00055 #include "lcd.h"
00056 #include "duty-cycle-scroller.h"
00057 
00058 #if WITH_UIP6
00059 #include "net/uip-ds6.h"
00060 #endif /* WITH_UIP6 */
00061 
00062 
00063 #define DEBUG 1
00064 #if DEBUG
00065 #include <stdio.h>
00066 #define PRINTF(...) printf(__VA_ARGS__)
00067 #else
00068 #define PRINTF(...)
00069 #endif
00070 
00071 //SENSORS(&button_sensor);
00072 /*---------------------------------------------------------------------------*/
00073 #ifndef RF_CHANNEL
00074 #define RF_CHANNEL              26
00075 #endif
00076 /*---------------------------------------------------------------------------*/
00077 static void
00078 set_rime_addr(void)
00079 {
00080   rimeaddr_t addr;
00081   int i;
00082 
00083   memset(&addr, 0, sizeof(rimeaddr_t));
00084 #if UIP_CONF_IPV6
00085   memcpy(addr.u8, node_mac, sizeof(addr.u8));
00086 #else
00087   if(node_id == 0) {
00088     for(i = 0; i < sizeof(rimeaddr_t); ++i) {
00089       addr.u8[i] = node_mac[7 - i];
00090     }
00091   } else {
00092     addr.u8[0] = node_id & 0xff;
00093     addr.u8[1] = node_id >> 8;
00094   }
00095 #endif
00096   rimeaddr_set_node_addr(&addr);
00097   printf("Rime addr ");
00098   for(i = 0; i < sizeof(addr.u8) - 1; i++) {
00099     printf("%u.", addr.u8[i]);
00100   }
00101   printf("%u\n", addr.u8[i]);
00102 }
00103 /*---------------------------------------------------------------------------*/
00104 static void
00105 print_processes(struct process * const processes[])
00106 {
00107   /*  const struct process * const * p = processes;*/
00108   printf("Starting");
00109   while(*processes != NULL) {
00110     printf(" %s", (*processes)->name);
00111     processes++;
00112   }
00113   putchar('\n');
00114 }
00115 /*--------------------------------------------------------------------------*/
00116 int
00117 main(int argc, char **argv)
00118 {
00119   /*
00120    * Initalize hardware.
00121    */
00122   msp430_cpu_init();
00123   clock_init();
00124   leds_init();
00125 
00126   leds_on(LEDS_RED);
00127 
00128   uart1_init(BAUD2UBR(115200)); /* Must come before first printf */
00129 #if WITH_UIP
00130   slip_arch_init(BAUD2UBR(115200));
00131 #endif /* WITH_UIP */
00132 
00133   leds_on(LEDS_GREEN);
00134   /* xmem_init(); */
00135   
00136   rtimer_init();
00137 
00138   lcd_init();
00139 
00140   PRINTF(CONTIKI_VERSION_STRING "\n");
00141   /*
00142    * Hardware initialization done!
00143    */
00144   
00145   leds_on(LEDS_RED);
00146   /* Restore node id if such has been stored in external mem */
00147 
00148   //  node_id_restore();
00149 #ifdef NODEID
00150   node_id = NODEID;
00151 
00152 #ifdef BURN_NODEID
00153   flash_setup();
00154   flash_clear(0x1800);
00155   flash_write(0x1800, node_id);
00156   flash_done();
00157 #endif /* BURN_NODEID */
00158 #endif /* NODE_ID */
00159 
00160   if(node_id == 0) {
00161     node_id = *((unsigned short *)0x1800);
00162   }
00163   memset(node_mac, 0, sizeof(node_mac));
00164   node_mac[6] = node_id >> 8;
00165   node_mac[7] = node_id & 0xff;
00166 
00167   /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */
00168 #ifdef MAC_1
00169   {
00170     uint8_t ieee[] = { MAC_1, MAC_2, MAC_3, MAC_4, MAC_5, MAC_6, MAC_7, MAC_8 };
00171     memcpy(node_mac, ieee, sizeof(uip_lladdr.addr));
00172   }
00173 #endif
00174 
00175    /*
00176    * Initialize Contiki and our processes.
00177    */
00178   process_init();
00179   process_start(&etimer_process, NULL);
00180 
00181   ctimer_init();
00182 
00183   set_rime_addr();
00184 
00185   cc2420_init();
00186 
00187   {
00188     uint8_t longaddr[8];
00189     uint16_t shortaddr;
00190 
00191     shortaddr = (rimeaddr_node_addr.u8[0] << 8) +
00192       rimeaddr_node_addr.u8[1];
00193     memset(longaddr, 0, sizeof(longaddr));
00194     rimeaddr_copy((rimeaddr_t *)&longaddr, &rimeaddr_node_addr);
00195     printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
00196            longaddr[0], longaddr[1], longaddr[2], longaddr[3],
00197            longaddr[4], longaddr[5], longaddr[6], longaddr[7]);
00198 
00199     cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
00200   }
00201 
00202   cc2420_set_channel(RF_CHANNEL);
00203 
00204   leds_off(LEDS_ALL);
00205 
00206   if(node_id > 0) {
00207     PRINTF("Node id %u.\n", node_id);
00208   } else {
00209     PRINTF("Node id not set.\n");
00210   }
00211 
00212 #if WITH_UIP6
00213   memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr));
00214   /* Setup nullmac-like MAC for 802.15.4 */
00215 
00216   queuebuf_init();
00217 
00218   NETSTACK_RDC.init();
00219   NETSTACK_MAC.init();
00220   NETSTACK_NETWORK.init();
00221 
00222   printf("%s %lu %u\n",
00223          NETSTACK_RDC.name,
00224          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
00225                          NETSTACK_RDC.channel_check_interval()),
00226          RF_CHANNEL);
00227 
00228   process_start(&tcpip_process, NULL);
00229 
00230   printf("IPv6 ");
00231   {
00232     uip_ds6_addr_t *lladdr;
00233     int i;
00234     lladdr = uip_ds6_get_link_local(-1);
00235     for(i = 0; i < 7; ++i) {
00236       printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
00237              lladdr->ipaddr.u8[i * 2 + 1]);
00238     }
00239     printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
00240   }
00241 
00242   if(!UIP_CONF_IPV6_RPL) {
00243     uip_ipaddr_t ipaddr;
00244     int i;
00245     uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
00246     uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
00247     uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
00248     printf("Tentative global IPv6 address ");
00249     for(i = 0; i < 7; ++i) {
00250       printf("%02x%02x:",
00251              ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
00252     }
00253     printf("%02x%02x\n",
00254            ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
00255   }
00256 
00257 #else /* WITH_UIP6 */
00258 
00259   NETSTACK_RDC.init();
00260   NETSTACK_MAC.init();
00261   NETSTACK_NETWORK.init();
00262 
00263   printf("%s %lu %u\n",
00264          NETSTACK_RDC.name,
00265          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
00266                          NETSTACK_RDC.channel_check_interval()),
00267          RF_CHANNEL);
00268 #endif /* WITH_UIP6 */
00269 
00270 #if !WITH_UIP6
00271   uart1_set_input(serial_line_input_byte);
00272   serial_line_init();
00273 #endif
00274 
00275 #if TIMESYNCH_CONF_ENABLED
00276   timesynch_init();
00277   timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
00278 #endif /* TIMESYNCH_CONF_ENABLED */
00279 
00280 
00281   /*  process_start(&sensors_process, NULL);
00282       SENSORS_ACTIVATE(button_sensor);*/
00283 
00284   energest_init();
00285   ENERGEST_ON(ENERGEST_TYPE_CPU);
00286 
00287   print_processes(autostart_processes);
00288   autostart_start(autostart_processes);
00289 
00290   duty_cycle_scroller_start(CLOCK_SECOND * 2);
00291 
00292   /*
00293    * This is the scheduler loop.
00294    */
00295   watchdog_start();
00296   watchdog_stop(); /* Stop the wdt... */
00297   while(1) {
00298     int r;
00299     do {
00300       /* Reset watchdog. */
00301       watchdog_periodic();
00302       r = process_run();
00303     } while(r > 0);
00304 
00305     /*
00306      * Idle processing.
00307      */
00308     int s = splhigh();          /* Disable interrupts. */
00309     /* uart1_active is for avoiding LPM3 when still sending or receiving */
00310     if(process_nevents() != 0 || uart1_active()) {
00311       splx(s);                  /* Re-enable interrupts. */
00312     } else {
00313       static unsigned long irq_energest = 0;
00314 
00315       /* Re-enable interrupts and go to sleep atomically. */
00316       ENERGEST_OFF(ENERGEST_TYPE_CPU);
00317       ENERGEST_ON(ENERGEST_TYPE_LPM);
00318       /* We only want to measure the processing done in IRQs when we
00319          are asleep, so we discard the processing time done when we
00320          were awake. */
00321       energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
00322       watchdog_stop();
00323       _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This
00324                                               statement will block
00325                                               until the CPU is
00326                                               woken up by an
00327                                               interrupt that sets
00328                                               the wake up flag. */
00329 
00330       /* We get the current processing time for interrupts that was
00331          done during the LPM and store it for next time around.  */
00332       dint();
00333       irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
00334       eint();
00335       watchdog_start();
00336       ENERGEST_OFF(ENERGEST_TYPE_LPM);
00337       ENERGEST_ON(ENERGEST_TYPE_CPU);
00338     }
00339   }
00340 }
00341 /*---------------------------------------------------------------------------*/