Contiki 2.6

contiki-esb-main.c

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