Contiki 2.5
contiki-esb-main.c
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * @(#)$Id: contiki-esb-main.c,v 1.19 2010/06/21 15:15:12 nifi Exp $
32  */
33 
34 #include <stdio.h>
35 #include <string.h>
36 
37 #include "contiki.h"
38 #include "contiki-esb.h"
39 
40 #include "dev/watchdog.h"
41 #include "sys/autostart.h"
42 #include "net/uip-driver.h"
43 #include "net/netstack.h"
44 
45 #if WITH_UIP
46 
47 static struct uip_fw_netif tr1001if =
48  {UIP_FW_NETIF(0,0,0,0, 0,0,0,0, uip_driver_send)};
49 
50 #if WITH_SLIP
51 static struct uip_fw_netif slipif =
52  {UIP_FW_NETIF(172,16,0,0, 255,255,255,0, slip_send)};
53 #endif /* WITH_SLIP */
54 
55 #endif /* WITH_UIP */
56 
57 #ifdef DCOSYNCH_CONF_PERIOD
58 #define DCOSYNCH_PERIOD DCOSYNCH_CONF_PERIOD
59 #else
60 #define DCOSYNCH_PERIOD 30
61 #endif /* DCOSYNCH_CONF_PERIOD */
62 
63 #ifdef DCOSYNCH_CONF_ENABLED
64 #define DCOSYNCH_ENABLED DCOSYNCH_CONF_ENABLED
65 #else
66 #define DCOSYNCH_ENABLED 0
67 #endif /* DCOSYNCH_CONF_ENABLED */
68 
69 #if DCOSYNCH_ENABLED
70 static struct timer dco_timer;
71 #endif /* DCOSYNCH_ENABLED */
72 
73 SENSORS(&button_sensor, &sound_sensor, &vib_sensor,
74  &pir_sensor, &radio_sensor, &battery_sensor, &ctsrts_sensor,
75  &temperature_sensor);
76 
77 /*---------------------------------------------------------------------------*/
78 static void
79 set_rime_addr(void)
80 {
81  int i;
82  rimeaddr_t rimeaddr;
83 
84  rimeaddr.u8[0] = node_id & 0xff;
85  rimeaddr.u8[1] = node_id >> 8;
86  rimeaddr_set_node_addr(&rimeaddr);
87 
88  printf("Rime started with address ");
89  for(i = 0; i < sizeof(rimeaddr.u8) - 1; i++) {
90  printf("%u.", rimeaddr.u8[i]);
91  }
92  printf("%u\n", rimeaddr.u8[i]);
93 }
94 /*---------------------------------------------------------------------------*/
95 #if WITH_UIP
96 static void
97 init_uip_net(void)
98 {
99  uip_ipaddr_t hostaddr;
100 
101  uip_init();
102  uip_fw_init();
103 
104  process_start(&tcpip_process, NULL);
105 #if WITH_SLIP
106  process_start(&slip_process, NULL);
107  rs232_set_input(slip_input_byte);
108 #endif /* WITH_SLIP */
109  process_start(&uip_fw_process, NULL);
110 
111  if (node_id > 0) {
112  /* node id is set, construct an ip address based on the node id */
113  uip_ipaddr(&hostaddr, 172, 16, 1, node_id & 0xff);
114  uip_sethostaddr(&hostaddr);
115  }
116 
117 #if WITH_SLIP
118  uip_fw_register(&slipif);
119 #endif /* WITH_SLIP */
120 
121  uip_fw_default(&tr1001if);
122 }
123 #endif /* WITH_UIP */
124 /*---------------------------------------------------------------------------*/
125 static void
126 print_processes(struct process * const processes[])
127 {
128  printf("Starting");
129  while(*processes != NULL) {
130  printf(" '%s'", (*processes)->name);
131  processes++;
132  }
133  /* Needed to force link with putchar */
134  putchar('\n');
135 }
136 /*---------------------------------------------------------------------------*/
137 static void init_ports_toberemoved() {
138  ////////// Port 1 ////
139  P1SEL = 0x00;
140  P1DIR = 0x81; // Outputs: P10=IRSend, P17=RS232RTS
141  // Inputs: P11=Light, P12=IRRec, P13=PIR, P14=Vibration,
142  // P15=Clockalarm, P16=RS232CTS
143  P1OUT = 0x00;
144 
145  ////////// Port 2 ////
146  P2SEL = 0x00; // No Sels
147  P2DIR = 0x7F; // Outpus: P20..P23=Leds+Beeper, P24..P26=Poti
148  // Inputs: P27=Taster
149  P2OUT = 0x77;
150 
151  ////////// Port 3 ////
152  P3SEL = 0xE0; // Sels for P34..P37 to activate UART,
153  P3DIR = 0x5F; // Inputs: P30..P33=CON4, P35/P37=RXD Transceiver/RS232
154  // OutPuts: P36/P38=TXD Transceiver/RS232
155  P3OUT = 0xE0; // Output a Zero on P34(TXD Transceiver) and turn SELECT off when receiving!!!
156 
157  ////////// Port 4 ////
158  P4SEL = 0x00; // CON5 Stecker
159  P4DIR = 0xFF;
160  P4OUT = 0x00;
161 
162  ////////// Port 5 ////
163  P5SEL = 0x00; // P50/P51= Clock SDA/SCL, P52/P53/P54=EEPROM SDA/SCL/WP
164  P5DIR = 0xDA; // P56/P57=Transceiver CNTRL0/1
165  P5OUT = 0x0F;
166 
167  ////////// Port 6 ////
168  P6SEL = 0x00; // P60=Microphone, P61=PIR digital (same as P13), P62=PIR analog
169  P6DIR = 0x00; // P63=extern voltage, P64=battery voltage, P65=Receive power
170  P6OUT = 0x00;
171 }
172 /*---------------------------------------------------------------------------*/
173 int
174 main(void)
175 {
176  msp430_cpu_init();
177 
178  init_ports_toberemoved();
179 
180  init_lowlevel();
181 
182  clock_init();
183 
184  rtimer_init();
185 
186  process_init();
187 
188  random_init(0);
189 
190  node_id_restore();
191 
192  process_start(&etimer_process, NULL);
193  process_start(&sensors_process, NULL);
194 
195  ctimer_init();
196 
197  set_rime_addr();
198 
199  printf(CONTIKI_VERSION_STRING " started. ");
200  if(node_id > 0) {
201  printf("Node id is set to %u.\n", node_id);
202  } else {
203  printf("Node id is not set.\n");
204  }
205 
206  netstack_init();
207 
208  printf("%s %s, channel check rate %lu Hz\n",
209  NETSTACK_MAC.name, NETSTACK_RDC.name,
210  CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
211  NETSTACK_RDC.channel_check_interval()));
212 
213  beep_spinup();
214  leds_on(LEDS_RED);
215  clock_delay(100);
216  leds_off(LEDS_RED);
217 
218 #if !WITH_SLIP
219  rs232_set_input(serial_line_input_byte);
220  serial_line_init();
221 #endif
222 
223 #if WITH_UIP
224  init_uip_net();
225 #endif /* WITH_UIP */
226 
227 #if PROFILE_CONF_ON
228  profile_init();
229 #endif /* PROFILE_CONF_ON */
230 
231 #if ENERGEST_CONF_ON
232  energest_init();
233  ENERGEST_ON(ENERGEST_TYPE_CPU);
234 #endif /* ENERGEST_CONF_ON */
235 
236  init_apps();
237  print_processes(autostart_processes);
238  autostart_start(autostart_processes);
239 
240 #if DCOSYNCH_ENABLED
241  timer_set(&dco_timer, DCOSYNCH_PERIOD * CLOCK_SECOND);
242 #endif /* DCOSYNCH_ENABLED */
243 
244  /*
245  * This is the scheduler loop.
246  */
247  watchdog_start();
248  while(1) {
249  int r;
250 #if PROFILE_CONF_ON
251  profile_episode_start();
252 #endif /* PROFILE_CONF_ON */
253  do {
254  /* Reset watchdog. */
255  watchdog_periodic();
256  r = process_run();
257  } while(r > 0);
258 #if PROFILE_CONF_ON
259  profile_episode_end();
260 #endif /* PROFILE_CONF_ON */
261 
262  /*
263  * Idle processing.
264  */
265  dint();
266  if(process_nevents() != 0) {
267  eint();
268  } else {
269 #if ENERGEST_CONF_ON
270  static unsigned long irq_energest = 0;
271 #endif /* ENERGEST_CONF_ON */
272 
273 #if DCOSYNCH_CONF_ENABLED
274  /* before going down to sleep possibly do some management */
275  if(timer_expired(&dco_timer)) {
276  timer_reset(&dco_timer);
277  msp430_sync_dco();
278  }
279 #endif /* DCOSYNCH_CONF_ENABLED */
280 
281 #if ENERGEST_CONF_ON
282  /* Re-enable interrupts and go to sleep atomically. */
283  ENERGEST_OFF(ENERGEST_TYPE_CPU);
284  ENERGEST_ON(ENERGEST_TYPE_LPM);
285 
286  /* We only want to measure the processing done in IRQs when we
287  are asleep, so we discard the processing time done when we
288  were awake. */
289  energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
290 #endif /* ENERGEST_CONF_ON */
291 
292  watchdog_stop();
293  _BIS_SR(GIE | SCG0 | CPUOFF); /* LPM1 sleep. */
294 
295 #if ENERGEST_CONF_ON
296  /* We get the current processing time for interrupts that was
297  done during the LPM and store it for next time around. */
298  dint();
299  irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
300  eint();
301  ENERGEST_OFF(ENERGEST_TYPE_LPM);
302  ENERGEST_ON(ENERGEST_TYPE_CPU);
303 #endif /* ENERGEST_CONF_ON */
304 
305  watchdog_start();
306  }
307  }
308 
309  return 0;
310 }
311 /*---------------------------------------------------------------------------*/
312 /* char *arg_alloc(char size) {return NULL;} */
313 /* void arg_init(void) {} */
314 /* void arg_free(char *arg) {} */
315 /*---------------------------------------------------------------------------*/
316 #if UIP_LOGGING
317 void
318 uip_log(char *m)
319 {
320  printf("uIP log: '%s'\n", m);
321 }
322 #endif /* UIP_LOGGING */