Contiki 2.6
|
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 /*---------------------------------------------------------------------------*/