Add missing includes
[contiki-2.x.git] / platform / z1 / contiki-z1-main.c
blob2ddfa4985c0a82107aee34751321ae9c4a843b60
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-z1-main.c,v 1.4 2010/08/26 22:08:11 nifi Exp $
32 #include <signal.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdarg.h> //Enric_Joakim
37 #include <io.h>
39 #include "contiki.h"
41 #include "dev/cc2420.h"
42 #include "dev/leds.h"
43 #include "dev/serial-line.h"
44 #include "dev/slip.h"
45 #include "dev/uart0.h"
46 #include "dev/watchdog.h"
47 #include "dev/xmem.h"
48 #include "lib/random.h"
49 #include "net/netstack.h"
50 #include "net/mac/frame802154.h"
51 #include "dev/button-sensor.h"
53 #if WITH_UIP6
54 #include "net/uip-ds6.h"
55 #endif /* WITH_UIP6 */
57 #include "net/rime.h"
59 #include "node-id.h"
60 #include "cfs-coffee-arch.h"
61 #include "cfs/cfs-coffee.h"
62 #include "sys/autostart.h"
63 #include "sys/profile.h"
66 #include "dev/battery-sensor.h"
67 #include "dev/button-sensor.h"
68 #include "dev/sht11-sensor.h"
70 SENSORS(&button_sensor);
72 #if DCOSYNCH_CONF_ENABLED
73 static struct timer mgt_timer;
74 #endif
76 #ifndef WITH_UIP
77 #define WITH_UIP 0
78 #endif
80 #if WITH_UIP
81 #include "net/uip.h"
82 #include "net/uip-fw.h"
83 #include "net/uip-fw-drv.h"
84 #include "net/uip-over-mesh.h"
85 static struct uip_fw_netif slipif =
86 {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
87 static struct uip_fw_netif meshif =
88 {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
90 #endif /* WITH_UIP */
92 #define UIP_OVER_MESH_CHANNEL 8
93 #if WITH_UIP
94 static uint8_t is_gateway;
95 #endif /* WITH_UIP */
97 #ifdef EXPERIMENT_SETUP
98 #include "experiment-setup.h"
99 #endif
101 #define DEBUG 1
102 #if DEBUG
103 #include <stdio.h>
104 #define PRINTF(...) printf(__VA_ARGS__)
105 #else
106 #define PRINTF(...)
107 #endif
109 /*---------------------------------------------------------------------------*/
110 #if 0
112 force_float_inclusion()
114 extern int __fixsfsi;
115 extern int __floatsisf;
116 extern int __mulsf3;
117 extern int __subsf3;
119 return __fixsfsi + __floatsisf + __mulsf3 + __subsf3;
121 #endif
122 /*---------------------------------------------------------------------------*/
123 void uip_log(char *msg) { puts(msg); }
124 /*---------------------------------------------------------------------------*/
125 #ifndef RF_CHANNEL
126 #define RF_CHANNEL 26
127 #endif
128 /*---------------------------------------------------------------------------*/
129 #if 0
130 void
131 force_inclusion(int d1, int d2)
133 snprintf(NULL, 0, "%d", d1 % d2);
135 #endif
136 /*---------------------------------------------------------------------------*/
137 static void
138 set_rime_addr(void)
140 rimeaddr_t addr;
141 int i;
143 memset(&addr, 0, sizeof(rimeaddr_t));
144 #if UIP_CONF_IPV6
145 memcpy(addr.u8, node_mac, sizeof(addr.u8));
146 #else
147 if(node_id == 0) {
148 for(i = 0; i < sizeof(rimeaddr_t); ++i) {
149 addr.u8[i] = node_mac[7 - i];
151 } else {
152 addr.u8[0] = node_id & 0xff;
153 addr.u8[1] = node_id >> 8;
155 #endif
156 rimeaddr_set_node_addr(&addr);
157 printf("Rime started with address ");
158 for(i = 0; i < sizeof(addr.u8) - 1; i++) {
159 printf("%d.", addr.u8[i]);
161 printf("%d\n", addr.u8[i]);
163 /*---------------------------------------------------------------------------*/
164 static void
165 print_processes(struct process * const processes[])
167 /* const struct process * const * p = processes;*/
168 printf("Starting");
169 while(*processes != NULL) {
170 printf(" '%s'", (*processes)->name);
171 processes++;
173 putchar('\n');
175 /*--------------------------------------------------------------------------*/
176 #if WITH_UIP
177 static void
178 set_gateway(void)
180 if(!is_gateway) {
181 leds_on(LEDS_RED);
182 printf("%d.%d: making myself the IP network gateway.\n\n",
183 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
184 printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
185 uip_ipaddr_to_quad(&uip_hostaddr));
186 uip_over_mesh_set_gateway(&rimeaddr_node_addr);
187 uip_over_mesh_make_announced_gateway();
188 is_gateway = 1;
191 #endif /* WITH_UIP */
192 /*---------------------------------------------------------------------------*/
194 main(int argc, char **argv)
197 * Initalize hardware.
199 msp430_cpu_init();
200 clock_init();
201 leds_init();
202 leds_on(LEDS_RED);
204 clock_wait(100);
206 uart0_init(BAUD2UBR(115200)); /* Must come before first printf */
207 #if WITH_UIP
208 slip_arch_init(BAUD2UBR(115200));
209 #endif /* WITH_UIP */
211 /* XXX hack: Fix it so that the 802.15.4 MAC address is compatible
212 with an Ethernet MAC address - byte 0 (byte 2 in the DS ID)
213 cannot be odd. */
214 //Enric node_mac[2] &= 0xfe;
215 node_mac[0] = 0x00;
216 node_mac[1] = 0x12;
217 node_mac[2] = 0x76;
218 node_mac[3] = 0x01;
219 node_mac[4] = 0x02;
220 node_mac[5] = 0x03;
221 node_mac[2] = 0x04;
222 node_mac[7] = 0x05;
225 xmem_init();
227 rtimer_init();
229 * Hardware initialization done!
233 /* Restore node id if such has been stored in external mem */
234 node_id_restore();
237 /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */
238 #ifdef IEEE_802154_MAC_ADDRESS
240 uint8_t ieee[] = IEEE_802154_MAC_ADDRESS;
241 memcpy(node_mac, ieee, sizeof(uip_lladdr.addr));
242 node_mac[7] = node_id & 0xff;
244 #endif
246 //Enric random_init(node_mac[0] + node_id);
249 * Initialize Contiki and our processes.
251 process_init();
252 process_start(&etimer_process, NULL);
254 process_start(&sensors_process, NULL);
256 ctimer_init();
258 set_rime_addr();
260 cc2420_init();
262 uint8_t longaddr[8];
263 uint16_t shortaddr;
265 shortaddr = (rimeaddr_node_addr.u8[0] << 8) +
266 rimeaddr_node_addr.u8[1];
267 memset(longaddr, 0, sizeof(longaddr));
268 rimeaddr_copy((rimeaddr_t *)&longaddr, &rimeaddr_node_addr);
269 printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
270 longaddr[0], longaddr[1], longaddr[2], longaddr[3],
271 longaddr[4], longaddr[5], longaddr[6], longaddr[7]);
273 cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
275 cc2420_set_channel(RF_CHANNEL);
277 leds_off(LEDS_ALL);
279 PRINTF(CONTIKI_VERSION_STRING " started. ");
281 if(node_id > 0) {
282 PRINTF("Node id is set to %u.\n", node_id);
283 } else {
284 PRINTF("Node id is not set.\n");
287 //Enric printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
288 //Enric node_mac[0], node_mac[1], node_mac[2], node_mac[3],
289 //Enric node_mac[4], node_mac[5], node_mac[6], node_mac[7]);
291 #if WITH_UIP6
292 PRINTF("in WITH_UIP6\n"); //Enric
293 memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr));
294 /* Setup nullmac-like MAC for 802.15.4 */
295 /* sicslowpan_init(sicslowmac_init(&cc2420_driver)); */
296 /* printf(" %s channel %u\n", sicslowmac_driver.name, RF_CHANNEL); */
298 /* Setup X-MAC for 802.15.4 */
299 queuebuf_init();
301 NETSTACK_RDC.init();
302 NETSTACK_MAC.init();
303 NETSTACK_NETWORK.init();
305 printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
306 NETSTACK_MAC.name, NETSTACK_RDC.name,
307 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
308 NETSTACK_RDC.channel_check_interval()),
309 RF_CHANNEL);
311 process_start(&tcpip_process, NULL);
313 printf("Tentative link-local IPv6 address ");
315 uip_ds6_addr_t *lladdr;
316 int i;
317 lladdr = uip_ds6_get_link_local(-1);
318 for(i = 0; i < 7; ++i) {
319 printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
320 lladdr->ipaddr.u8[i * 2 + 1]);
322 printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
325 if(!UIP_CONF_IPV6_RPL) {
326 uip_ipaddr_t ipaddr;
327 int i;
328 uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
329 uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
330 uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
331 printf("Tentative global IPv6 address ");
332 for(i = 0; i < 7; ++i) {
333 printf("%02x%02x:",
334 ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
336 printf("%02x%02x\n",
337 ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
340 #else /* WITH_UIP6 */
342 NETSTACK_RDC.init();
343 NETSTACK_MAC.init();
344 NETSTACK_NETWORK.init();
346 printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
347 NETSTACK_MAC.name, NETSTACK_RDC.name,
348 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
349 NETSTACK_RDC.channel_check_interval()),
350 RF_CHANNEL);
351 #endif /* WITH_UIP6 */
353 #if !WITH_UIP && !WITH_UIP6
354 uart0_set_input(serial_line_input_byte);
355 serial_line_init();
356 #endif
358 #if PROFILE_CONF_ON
359 profile_init();
360 #endif /* PROFILE_CONF_ON */
362 leds_off(LEDS_GREEN);
364 #if TIMESYNCH_CONF_ENABLED
365 timesynch_init();
366 timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
367 #endif /* TIMESYNCH_CONF_ENABLED */
369 #if WITH_UIP
370 process_start(&tcpip_process, NULL);
371 process_start(&uip_fw_process, NULL); /* Start IP output */
372 process_start(&slip_process, NULL);
374 slip_set_input_callback(set_gateway);
377 uip_ipaddr_t hostaddr, netmask;
379 uip_init();
381 uip_ipaddr(&hostaddr, 172,16,
382 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
383 uip_ipaddr(&netmask, 255,255,0,0);
384 uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
386 uip_sethostaddr(&hostaddr);
387 uip_setnetmask(&netmask);
388 uip_over_mesh_set_net(&hostaddr, &netmask);
389 /* uip_fw_register(&slipif);*/
390 uip_over_mesh_set_gateway_netif(&slipif);
391 uip_fw_default(&meshif);
392 uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
393 printf("uIP started with IP address %d.%d.%d.%d\n",
394 uip_ipaddr_to_quad(&hostaddr));
396 #endif /* WITH_UIP */
398 energest_init();
399 ENERGEST_ON(ENERGEST_TYPE_CPU);
401 print_processes(autostart_processes);
402 autostart_start(autostart_processes);
405 * This is the scheduler loop.
407 #if DCOSYNCH_CONF_ENABLED
408 timer_set(&mgt_timer, DCOSYNCH_PERIOD * CLOCK_SECOND);
409 #endif
410 watchdog_start();
411 /* watchdog_stop();*/
412 while(1) {
413 int r;
414 #if PROFILE_CONF_ON
415 profile_episode_start();
416 #endif /* PROFILE_CONF_ON */
417 do {
418 /* Reset watchdog. */
419 watchdog_periodic();
420 r = process_run();
421 } while(r > 0);
422 #if PROFILE_CONF_ON
423 profile_episode_end();
424 #endif /* PROFILE_CONF_ON */
427 * Idle processing.
429 int s = splhigh(); /* Disable interrupts. */
430 /* uart0_active is for avoiding LPM3 when still sending or receiving */
431 if(process_nevents() != 0 || uart0_active()) {
432 splx(s); /* Re-enable interrupts. */
433 } else {
434 static unsigned long irq_energest = 0;
436 #if DCOSYNCH_CONF_ENABLED
437 /* before going down to sleep possibly do some management */
438 if (timer_expired(&mgt_timer)) {
439 timer_reset(&mgt_timer);
440 msp430_sync_dco();
442 #endif
444 /* Re-enable interrupts and go to sleep atomically. */
445 ENERGEST_OFF(ENERGEST_TYPE_CPU);
446 ENERGEST_ON(ENERGEST_TYPE_LPM);
447 /* We only want to measure the processing done in IRQs when we
448 are asleep, so we discard the processing time done when we
449 were awake. */
450 energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
451 watchdog_stop();
452 _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This
453 statement will block
454 until the CPU is
455 woken up by an
456 interrupt that sets
457 the wake up flag. */
459 /* We get the current processing time for interrupts that was
460 done during the LPM and store it for next time around. */
461 dint();
462 irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
463 eint();
464 watchdog_start();
465 ENERGEST_OFF(ENERGEST_TYPE_LPM);
466 ENERGEST_ON(ENERGEST_TYPE_CPU);
470 return 0;
472 /*---------------------------------------------------------------------------*/
473 #if LOG_CONF_ENABLED
474 void
475 log_message(char *m1, char *m2)
477 printf("%s%s\n", m1, m2);
479 #endif /* LOG_CONF_ENABLED */