2 * Copyright (c) 2006, Swedish Institute of Computer Science
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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
29 * @(#)$Id: contiki-z1-main.c,v 1.4 2010/08/26 22:08:11 nifi Exp $
35 #include <stdarg.h> //Enric_Joakim
41 #include "dev/cc2420.h"
43 #include "dev/serial-line.h"
45 #include "dev/uart0.h"
46 #include "dev/watchdog.h"
48 #include "lib/random.h"
49 #include "net/netstack.h"
50 #include "net/mac/frame802154.h"
51 #include "dev/button-sensor.h"
54 #include "net/uip-ds6.h"
55 #endif /* WITH_UIP6 */
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
;
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
)};
92 #define UIP_OVER_MESH_CHANNEL 8
94 static uint8_t is_gateway
;
97 #ifdef EXPERIMENT_SETUP
98 #include "experiment-setup.h"
104 #define PRINTF(...) printf(__VA_ARGS__)
109 /*---------------------------------------------------------------------------*/
112 force_float_inclusion()
114 extern int __fixsfsi
;
115 extern int __floatsisf
;
119 return __fixsfsi
+ __floatsisf
+ __mulsf3
+ __subsf3
;
122 /*---------------------------------------------------------------------------*/
123 void uip_log(char *msg
) { puts(msg
); }
124 /*---------------------------------------------------------------------------*/
126 #define RF_CHANNEL 26
128 /*---------------------------------------------------------------------------*/
131 force_inclusion(int d1
, int d2
)
133 snprintf(NULL
, 0, "%d", d1
% d2
);
136 /*---------------------------------------------------------------------------*/
143 memset(&addr
, 0, sizeof(rimeaddr_t
));
145 memcpy(addr
.u8
, node_mac
, sizeof(addr
.u8
));
148 for(i
= 0; i
< sizeof(rimeaddr_t
); ++i
) {
149 addr
.u8
[i
] = node_mac
[7 - i
];
152 addr
.u8
[0] = node_id
& 0xff;
153 addr
.u8
[1] = node_id
>> 8;
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 /*---------------------------------------------------------------------------*/
165 print_processes(struct process
* const processes
[])
167 /* const struct process * const * p = processes;*/
169 while(*processes
!= NULL
) {
170 printf(" '%s'", (*processes
)->name
);
175 /*--------------------------------------------------------------------------*/
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();
191 #endif /* WITH_UIP */
192 /*---------------------------------------------------------------------------*/
194 main(int argc
, char **argv
)
197 * Initalize hardware.
206 uart0_init(BAUD2UBR(115200)); /* Must come before first printf */
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)
214 //Enric node_mac[2] &= 0xfe;
229 * Hardware initialization done!
233 /* Restore node id if such has been stored in external mem */
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;
246 //Enric random_init(node_mac[0] + node_id);
249 * Initialize Contiki and our processes.
252 process_start(&etimer_process
, NULL
);
254 process_start(&sensors_process
, NULL
);
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
);
279 PRINTF(CONTIKI_VERSION_STRING
" started. ");
282 PRINTF("Node id is set to %u.\n", node_id
);
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]);
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 */
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()),
311 process_start(&tcpip_process
, NULL
);
313 printf("Tentative link-local IPv6 address ");
315 uip_ds6_addr_t
*lladdr
;
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
) {
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
) {
334 ipaddr
.u8
[i
* 2], ipaddr
.u8
[i
* 2 + 1]);
337 ipaddr
.u8
[7 * 2], ipaddr
.u8
[7 * 2 + 1]);
340 #else /* WITH_UIP6 */
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()),
351 #endif /* WITH_UIP6 */
353 #if !WITH_UIP && !WITH_UIP6
354 uart0_set_input(serial_line_input_byte
);
360 #endif /* PROFILE_CONF_ON */
362 leds_off(LEDS_GREEN
);
364 #if TIMESYNCH_CONF_ENABLED
366 timesynch_set_authority_level(rimeaddr_node_addr
.u8
[0]);
367 #endif /* TIMESYNCH_CONF_ENABLED */
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
;
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 */
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
);
411 /* watchdog_stop();*/
415 profile_episode_start();
416 #endif /* PROFILE_CONF_ON */
418 /* Reset watchdog. */
423 profile_episode_end();
424 #endif /* PROFILE_CONF_ON */
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. */
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
);
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
450 energest_type_set(ENERGEST_TYPE_IRQ
, irq_energest
);
452 _BIS_SR(GIE
| SCG0
| SCG1
| CPUOFF
); /* LPM3 sleep. This
459 /* We get the current processing time for interrupts that was
460 done during the LPM and store it for next time around. */
462 irq_energest
= energest_type_time(ENERGEST_TYPE_IRQ
);
465 ENERGEST_OFF(ENERGEST_TYPE_LPM
);
466 ENERGEST_ON(ENERGEST_TYPE_CPU
);
472 /*---------------------------------------------------------------------------*/
475 log_message(char *m1
, char *m2
)
477 printf("%s%s\n", m1
, m2
);
479 #endif /* LOG_CONF_ENABLED */