Passed tests on Raven 1284p in 3 seconds with 56KB program memory disk
[contiki-2.x.git] / platform / sky / contiki-sky-main.c
blob092c18ec0efd9dc38ee19273fbe59e9e6d8ba5ac
1 /*
2 * Copyright (c) 2006, Swedish Institute of Computer Science
3 * All rights reserved.
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.
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.
29 * @(#)$Id: contiki-sky-main.c,v 1.56 2009/06/22 11:14:11 nifi Exp $
32 #include <signal.h>
33 #include <stdio.h>
34 #include <string.h>
36 #include <io.h>
38 #include "contiki.h"
40 #include "dev/button-sensor.h"
41 #include "dev/ds2411.h"
42 #include "dev/leds.h"
43 #include "dev/light.h"
44 #include "dev/battery-sensor.h"
45 #include "dev/serial-line.h"
46 #include "dev/sht11.h"
47 #include "dev/cc2420.h"
48 #include "dev/slip.h"
49 #include "dev/uart1.h"
50 #include "dev/watchdog.h"
51 #include "dev/xmem.h"
53 #include "lib/random.h"
55 #include "net/mac/frame802154.h"
57 #if WITH_UIP6
58 #include "net/sicslowpan.h"
59 #include "net/uip-netif.h"
60 #include "net/mac/sicslowmac.h"
61 #if UIP_CONF_ROUTER
62 #include "net/routing/rimeroute.h"
63 #include "net/rime/rime-udp.h"
64 #endif /* UIP_CONF_ROUTER*/
65 #endif /* WITH_UIP6 */
67 #include "net/rime.h"
69 #include "node-id.h"
70 #include "cfs-coffee-arch.h"
71 #include "cfs/cfs-coffee.h"
72 #include "sys/autostart.h"
73 #include "sys/profile.h"
75 SENSORS(&button_sensor);
77 #if DCOSYNCH_CONF_ENABLED
78 static struct timer mgt_timer;
79 #endif
81 #ifndef WITH_UIP
82 #define WITH_UIP 0
83 #endif
85 #if WITH_UIP
86 #include "net/uip.h"
87 #include "net/uip-fw.h"
88 #include "net/uip-fw-drv.h"
89 #include "net/uip-over-mesh.h"
90 static struct uip_fw_netif slipif =
91 {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
92 static struct uip_fw_netif meshif =
93 {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
95 #endif /* WITH_UIP */
97 #define UIP_OVER_MESH_CHANNEL 8
98 #if WITH_UIP
99 static uint8_t is_gateway;
100 #endif /* WITH_UIP */
102 #ifdef EXPERIMENT_SETUP
103 #include "experiment-setup.h"
104 #endif
106 #if WITH_NULLMAC
107 #define MAC_DRIVER nullmac_driver
108 #endif /* WITH_NULLMAC */
110 #ifndef MAC_DRIVER
111 #ifdef MAC_CONF_DRIVER
112 #define MAC_DRIVER MAC_CONF_DRIVER
113 #else
114 #define MAC_DRIVER xmac_driver
115 #endif /* MAC_CONF_DRIVER */
116 #endif /* MAC_DRIVER */
118 extern const struct mac_driver MAC_DRIVER;
120 /*---------------------------------------------------------------------------*/
121 #if 0
123 force_float_inclusion()
125 extern int __fixsfsi;
126 extern int __floatsisf;
127 extern int __mulsf3;
128 extern int __subsf3;
130 return __fixsfsi + __floatsisf + __mulsf3 + __subsf3;
132 #endif
133 /*---------------------------------------------------------------------------*/
134 void uip_log(char *msg) { puts(msg); }
135 /*---------------------------------------------------------------------------*/
136 #ifndef RF_CHANNEL
137 #define RF_CHANNEL 26
138 #endif
139 /*---------------------------------------------------------------------------*/
140 void
141 force_inclusion(int d1, int d2)
143 snprintf(NULL, 0, "%d", d1 % d2);
145 /*---------------------------------------------------------------------------*/
146 static void
147 set_rime_addr(void)
149 rimeaddr_t addr;
150 int i;
152 memset(&addr, 0, sizeof(rimeaddr_t));
153 #if UIP_CONF_IPV6
154 memcpy(addr.u8, ds2411_id, sizeof(addr.u8));
155 #else
156 if(node_id == 0) {
157 for(i = 0; i < sizeof(rimeaddr_t); ++i) {
158 addr.u8[i] = ds2411_id[7 - i];
160 } else {
161 addr.u8[0] = node_id & 0xff;
162 addr.u8[1] = node_id >> 8;
164 #endif
165 rimeaddr_set_node_addr(&addr);
166 printf("Rime started with address ");
167 for(i = 0; i < sizeof(addr.u8) - 1; i++) {
168 printf("%d.", addr.u8[i]);
170 printf("%d\n", addr.u8[i]);
172 /*---------------------------------------------------------------------------*/
173 static void
174 print_processes(struct process * const processes[])
176 /* const struct process * const * p = processes;*/
177 printf("Starting");
178 while(*processes != NULL) {
179 printf(" '%s'", (*processes)->name);
180 processes++;
182 putchar('\n');
184 /*--------------------------------------------------------------------------*/
185 #if WITH_UIP
186 static void
187 set_gateway(void)
189 if(!is_gateway) {
190 leds_on(LEDS_RED);
191 printf("%d.%d: making myself the IP network gateway.\n\n",
192 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
193 printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
194 uip_ipaddr_to_quad(&uip_hostaddr));
195 uip_over_mesh_set_gateway(&rimeaddr_node_addr);
196 uip_over_mesh_make_announced_gateway();
197 is_gateway = 1;
199 rime_mac->off(1);
202 #endif /* WITH_UIP */
203 /*---------------------------------------------------------------------------*/
205 main(int argc, char **argv)
208 * Initalize hardware.
210 msp430_cpu_init();
211 clock_init();
212 leds_init();
213 leds_on(LEDS_RED);
215 uart1_init(BAUD2UBR(115200)); /* Must come before first printf */
216 #if WITH_UIP
217 slip_arch_init(BAUD2UBR(115200));
218 #endif /* WITH_UIP */
220 leds_on(LEDS_GREEN);
221 ds2411_init();
223 /* XXX hack: Fix it so that the 802.15.4 MAC address is compatible
224 with an Ethernet MAC address - byte 0 (byte 2 in the DS ID)
225 cannot be odd. */
226 ds2411_id[2] &= 0xfe;
228 leds_on(LEDS_BLUE);
229 xmem_init();
231 leds_off(LEDS_RED);
232 rtimer_init();
234 * Hardware initialization done!
238 /* Restore node id if such has been stored in external mem */
239 node_id_restore();
241 random_init(ds2411_id[0] + node_id);
243 leds_off(LEDS_BLUE);
245 * Initialize Contiki and our processes.
247 process_init();
248 process_start(&etimer_process, NULL);
249 process_start(&sensors_process, NULL);
252 * Initialize light and humidity/temp sensors.
254 sensors_light_init();
255 battery_sensor.activate();
256 sht11_init();
258 ctimer_init();
260 cc2420_init();
261 cc2420_set_pan_addr(IEEE802154_PANID, 0 /*XXX*/, ds2411_id);
262 cc2420_set_channel(RF_CHANNEL);
264 printf(CONTIKI_VERSION_STRING " started. ");
265 if(node_id > 0) {
266 printf("Node id is set to %u.\n", node_id);
267 } else {
268 printf("Node id is not set.\n");
270 set_rime_addr();
271 printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
272 ds2411_id[0], ds2411_id[1], ds2411_id[2], ds2411_id[3],
273 ds2411_id[4], ds2411_id[5], ds2411_id[6], ds2411_id[7]);
275 #if WITH_UIP6
276 memcpy(&uip_lladdr.addr, ds2411_id, sizeof(uip_lladdr.addr));
277 sicslowpan_init(sicslowmac_init(&cc2420_driver));
278 process_start(&tcpip_process, NULL);
279 printf(" %s channel %u\n", sicslowmac_driver.name, RF_CHANNEL);
280 #if UIP_CONF_ROUTER
281 rime_init(rime_udp_init(NULL));
282 uip_router_register(&rimeroute);
283 #endif /* UIP_CONF_ROUTER */
284 #else /* WITH_UIP6 */
285 rime_init(MAC_DRIVER.init(&cc2420_driver));
286 printf(" %s channel %u\n", rime_mac->name, RF_CHANNEL);
287 #endif /* WITH_UIP6 */
289 #if !WITH_UIP && !WITH_UIP6
290 uart1_set_input(serial_line_input_byte);
291 serial_line_init();
292 #endif
294 #if PROFILE_CONF_ON
295 profile_init();
296 #endif /* PROFILE_CONF_ON */
298 leds_off(LEDS_GREEN);
300 #if TIMESYNCH_CONF_ENABLED
301 timesynch_init();
302 timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
303 #endif /* TIMESYNCH_CONF_ENABLED */
305 #if WITH_UIP
306 process_start(&tcpip_process, NULL);
307 process_start(&uip_fw_process, NULL); /* Start IP output */
308 process_start(&slip_process, NULL);
310 slip_set_input_callback(set_gateway);
313 uip_ipaddr_t hostaddr, netmask;
315 uip_init();
317 uip_ipaddr(&hostaddr, 172,16,
318 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
319 uip_ipaddr(&netmask, 255,255,0,0);
320 uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
322 uip_sethostaddr(&hostaddr);
323 uip_setnetmask(&netmask);
324 uip_over_mesh_set_net(&hostaddr, &netmask);
325 /* uip_fw_register(&slipif);*/
326 uip_over_mesh_set_gateway_netif(&slipif);
327 uip_fw_default(&meshif);
328 uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
329 printf("uIP started with IP address %d.%d.%d.%d\n",
330 uip_ipaddr_to_quad(&hostaddr));
332 #endif /* WITH_UIP */
334 button_sensor.activate();
336 energest_init();
337 ENERGEST_ON(ENERGEST_TYPE_CPU);
339 print_processes(autostart_processes);
340 autostart_start(autostart_processes);
343 * This is the scheduler loop.
345 #if DCOSYNCH_CONF_ENABLED
346 timer_set(&mgt_timer, DCOSYNCH_PERIOD * CLOCK_SECOND);
347 #endif
348 watchdog_start();
349 /* watchdog_stop();*/
350 while(1) {
351 int r;
352 #if PROFILE_CONF_ON
353 profile_episode_start();
354 #endif /* PROFILE_CONF_ON */
355 do {
356 /* Reset watchdog. */
357 watchdog_periodic();
358 r = process_run();
359 } while(r > 0);
360 #if PROFILE_CONF_ON
361 profile_episode_end();
362 #endif /* PROFILE_CONF_ON */
365 * Idle processing.
367 int s = splhigh(); /* Disable interrupts. */
368 /* uart1_active is for avoiding LPM3 when still sending or receiving */
369 if(process_nevents() != 0 || uart1_active()) {
370 splx(s); /* Re-enable interrupts. */
371 } else {
372 static unsigned long irq_energest = 0;
374 #if DCOSYNCH_CONF_ENABLED
375 /* before going down to sleep possibly do some management */
376 if (timer_expired(&mgt_timer)) {
377 timer_reset(&mgt_timer);
378 msp430_sync_dco();
380 #endif
382 /* Re-enable interrupts and go to sleep atomically. */
383 ENERGEST_OFF(ENERGEST_TYPE_CPU);
384 ENERGEST_ON(ENERGEST_TYPE_LPM);
385 /* We only want to measure the processing done in IRQs when we
386 are asleep, so we discard the processing time done when we
387 were awake. */
388 energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
389 watchdog_stop();
390 _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This
391 statement will block
392 until the CPU is
393 woken up by an
394 interrupt that sets
395 the wake up flag. */
397 /* We get the current processing time for interrupts that was
398 done during the LPM and store it for next time around. */
399 dint();
400 irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
401 eint();
402 watchdog_start();
403 ENERGEST_OFF(ENERGEST_TYPE_LPM);
404 ENERGEST_ON(ENERGEST_TYPE_CPU);
408 return 0;
410 /*---------------------------------------------------------------------------*/
411 #if LOG_CONF_ENABLED
412 void
413 log_message(char *m1, char *m2)
415 printf("%s%s\n", m1, m2);
417 #endif /* LOG_CONF_ENABLED */