Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2005, 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 * This file is part of the Contiki operating system. 00030 * 00031 * @(#)$Id: contiki-esb-main.c,v 1.19 2010/06/21 15:15:12 nifi Exp $ 00032 */ 00033 00034 #include <stdio.h> 00035 #include <string.h> 00036 00037 #include "contiki.h" 00038 #include "contiki-esb.h" 00039 00040 #include "dev/watchdog.h" 00041 #include "sys/autostart.h" 00042 #include "net/uip-driver.h" 00043 #include "net/netstack.h" 00044 00045 #if WITH_UIP 00046 00047 static struct uip_fw_netif tr1001if = 00048 {UIP_FW_NETIF(0,0,0,0, 0,0,0,0, uip_driver_send)}; 00049 00050 #if WITH_SLIP 00051 static struct uip_fw_netif slipif = 00052 {UIP_FW_NETIF(172,16,0,0, 255,255,255,0, slip_send)}; 00053 #endif /* WITH_SLIP */ 00054 00055 #endif /* WITH_UIP */ 00056 00057 #ifdef DCOSYNCH_CONF_PERIOD 00058 #define DCOSYNCH_PERIOD DCOSYNCH_CONF_PERIOD 00059 #else 00060 #define DCOSYNCH_PERIOD 30 00061 #endif /* DCOSYNCH_CONF_PERIOD */ 00062 00063 #ifdef DCOSYNCH_CONF_ENABLED 00064 #define DCOSYNCH_ENABLED DCOSYNCH_CONF_ENABLED 00065 #else 00066 #define DCOSYNCH_ENABLED 0 00067 #endif /* DCOSYNCH_CONF_ENABLED */ 00068 00069 #if DCOSYNCH_ENABLED 00070 static struct timer dco_timer; 00071 #endif /* DCOSYNCH_ENABLED */ 00072 00073 SENSORS(&button_sensor, &sound_sensor, &vib_sensor, 00074 &pir_sensor, &radio_sensor, &battery_sensor, &ctsrts_sensor, 00075 &temperature_sensor); 00076 00077 /*---------------------------------------------------------------------------*/ 00078 static void 00079 set_rime_addr(void) 00080 { 00081 int i; 00082 rimeaddr_t rimeaddr; 00083 00084 rimeaddr.u8[0] = node_id & 0xff; 00085 rimeaddr.u8[1] = node_id >> 8; 00086 rimeaddr_set_node_addr(&rimeaddr); 00087 00088 printf("Rime started with address "); 00089 for(i = 0; i < sizeof(rimeaddr.u8) - 1; i++) { 00090 printf("%u.", rimeaddr.u8[i]); 00091 } 00092 printf("%u\n", rimeaddr.u8[i]); 00093 } 00094 /*---------------------------------------------------------------------------*/ 00095 #if WITH_UIP 00096 static void 00097 init_uip_net(void) 00098 { 00099 uip_ipaddr_t hostaddr; 00100 00101 uip_init(); 00102 uip_fw_init(); 00103 00104 process_start(&tcpip_process, NULL); 00105 #if WITH_SLIP 00106 process_start(&slip_process, NULL); 00107 rs232_set_input(slip_input_byte); 00108 #endif /* WITH_SLIP */ 00109 process_start(&uip_fw_process, NULL); 00110 00111 if (node_id > 0) { 00112 /* node id is set, construct an ip address based on the node id */ 00113 uip_ipaddr(&hostaddr, 172, 16, 1, node_id & 0xff); 00114 uip_sethostaddr(&hostaddr); 00115 } 00116 00117 #if WITH_SLIP 00118 uip_fw_register(&slipif); 00119 #endif /* WITH_SLIP */ 00120 00121 uip_fw_default(&tr1001if); 00122 } 00123 #endif /* WITH_UIP */ 00124 /*---------------------------------------------------------------------------*/ 00125 static void 00126 print_processes(struct process * const processes[]) 00127 { 00128 printf("Starting"); 00129 while(*processes != NULL) { 00130 printf(" '%s'", (*processes)->name); 00131 processes++; 00132 } 00133 /* Needed to force link with putchar */ 00134 putchar('\n'); 00135 } 00136 /*---------------------------------------------------------------------------*/ 00137 static void init_ports_toberemoved() { 00138 ////////// Port 1 //// 00139 P1SEL = 0x00; 00140 P1DIR = 0x81; // Outputs: P10=IRSend, P17=RS232RTS 00141 // Inputs: P11=Light, P12=IRRec, P13=PIR, P14=Vibration, 00142 // P15=Clockalarm, P16=RS232CTS 00143 P1OUT = 0x00; 00144 00145 ////////// Port 2 //// 00146 P2SEL = 0x00; // No Sels 00147 P2DIR = 0x7F; // Outpus: P20..P23=Leds+Beeper, P24..P26=Poti 00148 // Inputs: P27=Taster 00149 P2OUT = 0x77; 00150 00151 ////////// Port 3 //// 00152 P3SEL = 0xE0; // Sels for P34..P37 to activate UART, 00153 P3DIR = 0x5F; // Inputs: P30..P33=CON4, P35/P37=RXD Transceiver/RS232 00154 // OutPuts: P36/P38=TXD Transceiver/RS232 00155 P3OUT = 0xE0; // Output a Zero on P34(TXD Transceiver) and turn SELECT off when receiving!!! 00156 00157 ////////// Port 4 //// 00158 P4SEL = 0x00; // CON5 Stecker 00159 P4DIR = 0xFF; 00160 P4OUT = 0x00; 00161 00162 ////////// Port 5 //// 00163 P5SEL = 0x00; // P50/P51= Clock SDA/SCL, P52/P53/P54=EEPROM SDA/SCL/WP 00164 P5DIR = 0xDA; // P56/P57=Transceiver CNTRL0/1 00165 P5OUT = 0x0F; 00166 00167 ////////// Port 6 //// 00168 P6SEL = 0x00; // P60=Microphone, P61=PIR digital (same as P13), P62=PIR analog 00169 P6DIR = 0x00; // P63=extern voltage, P64=battery voltage, P65=Receive power 00170 P6OUT = 0x00; 00171 } 00172 /*---------------------------------------------------------------------------*/ 00173 int 00174 main(void) 00175 { 00176 msp430_cpu_init(); 00177 00178 init_ports_toberemoved(); 00179 00180 init_lowlevel(); 00181 00182 clock_init(); 00183 00184 rtimer_init(); 00185 00186 process_init(); 00187 00188 random_init(0); 00189 00190 node_id_restore(); 00191 00192 process_start(&etimer_process, NULL); 00193 process_start(&sensors_process, NULL); 00194 00195 ctimer_init(); 00196 00197 set_rime_addr(); 00198 00199 printf(CONTIKI_VERSION_STRING " started. "); 00200 if(node_id > 0) { 00201 printf("Node id is set to %u.\n", node_id); 00202 } else { 00203 printf("Node id is not set.\n"); 00204 } 00205 00206 netstack_init(); 00207 00208 printf("%s %s, channel check rate %lu Hz\n", 00209 NETSTACK_MAC.name, NETSTACK_RDC.name, 00210 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: 00211 NETSTACK_RDC.channel_check_interval())); 00212 00213 beep_spinup(); 00214 leds_on(LEDS_RED); 00215 clock_delay(100); 00216 leds_off(LEDS_RED); 00217 00218 #if !WITH_SLIP 00219 rs232_set_input(serial_line_input_byte); 00220 serial_line_init(); 00221 #endif 00222 00223 #if WITH_UIP 00224 init_uip_net(); 00225 #endif /* WITH_UIP */ 00226 00227 #if PROFILE_CONF_ON 00228 profile_init(); 00229 #endif /* PROFILE_CONF_ON */ 00230 00231 #if ENERGEST_CONF_ON 00232 energest_init(); 00233 ENERGEST_ON(ENERGEST_TYPE_CPU); 00234 #endif /* ENERGEST_CONF_ON */ 00235 00236 init_apps(); 00237 print_processes(autostart_processes); 00238 autostart_start(autostart_processes); 00239 00240 #if DCOSYNCH_ENABLED 00241 timer_set(&dco_timer, DCOSYNCH_PERIOD * CLOCK_SECOND); 00242 #endif /* DCOSYNCH_ENABLED */ 00243 00244 /* 00245 * This is the scheduler loop. 00246 */ 00247 watchdog_start(); 00248 while(1) { 00249 int r; 00250 #if PROFILE_CONF_ON 00251 profile_episode_start(); 00252 #endif /* PROFILE_CONF_ON */ 00253 do { 00254 /* Reset watchdog. */ 00255 watchdog_periodic(); 00256 r = process_run(); 00257 } while(r > 0); 00258 #if PROFILE_CONF_ON 00259 profile_episode_end(); 00260 #endif /* PROFILE_CONF_ON */ 00261 00262 /* 00263 * Idle processing. 00264 */ 00265 dint(); 00266 if(process_nevents() != 0) { 00267 eint(); 00268 } else { 00269 #if ENERGEST_CONF_ON 00270 static unsigned long irq_energest = 0; 00271 #endif /* ENERGEST_CONF_ON */ 00272 00273 #if DCOSYNCH_CONF_ENABLED 00274 /* before going down to sleep possibly do some management */ 00275 if(timer_expired(&dco_timer)) { 00276 timer_reset(&dco_timer); 00277 msp430_sync_dco(); 00278 } 00279 #endif /* DCOSYNCH_CONF_ENABLED */ 00280 00281 #if ENERGEST_CONF_ON 00282 /* Re-enable interrupts and go to sleep atomically. */ 00283 ENERGEST_OFF(ENERGEST_TYPE_CPU); 00284 ENERGEST_ON(ENERGEST_TYPE_LPM); 00285 00286 /* We only want to measure the processing done in IRQs when we 00287 are asleep, so we discard the processing time done when we 00288 were awake. */ 00289 energest_type_set(ENERGEST_TYPE_IRQ, irq_energest); 00290 #endif /* ENERGEST_CONF_ON */ 00291 00292 watchdog_stop(); 00293 _BIS_SR(GIE | SCG0 | CPUOFF); /* LPM1 sleep. */ 00294 00295 #if ENERGEST_CONF_ON 00296 /* We get the current processing time for interrupts that was 00297 done during the LPM and store it for next time around. */ 00298 dint(); 00299 irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); 00300 eint(); 00301 ENERGEST_OFF(ENERGEST_TYPE_LPM); 00302 ENERGEST_ON(ENERGEST_TYPE_CPU); 00303 #endif /* ENERGEST_CONF_ON */ 00304 00305 watchdog_start(); 00306 } 00307 } 00308 } 00309 /*---------------------------------------------------------------------------*/ 00310 /* char *arg_alloc(char size) {return NULL;} */ 00311 /* void arg_init(void) {} */ 00312 /* void arg_free(char *arg) {} */ 00313 /*---------------------------------------------------------------------------*/ 00314 #if UIP_LOGGING 00315 void 00316 uip_log(char *m) 00317 { 00318 printf("uIP log: '%s'\n", m); 00319 } 00320 #endif /* UIP_LOGGING */