Contiki 3.x
contiki-exp5438-main.c
1 /*
2  * Copyright (c) 2006, 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  */
30 
31 #include "contiki.h"
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdarg.h>
35 
36 #include "dev/button-sensor.h"
37 #include "cc2420.h"
38 #include "dev/flash.h"
39 #include "dev/leds.h"
40 #include "dev/serial-line.h"
41 #include "dev/slip.h"
42 #include "dev/uart1.h"
43 #include "dev/watchdog.h"
44 #include "dev/xmem.h"
45 #include "lib/random.h"
46 #include "lib/sensors.h"
47 #include "net/mac/frame802154.h"
48 #include "net/netstack.h"
49 #include "net/rime/rime.h"
50 #include "sys/autostart.h"
51 
52 #include "sys/node-id.h"
53 #include "lcd.h"
54 #include "duty-cycle-scroller.h"
55 
56 #if WITH_UIP6
57 #include "net/ipv6/uip-ds6.h"
58 #endif /* WITH_UIP6 */
59 
60 
61 #define DEBUG 1
62 #if DEBUG
63 #include <stdio.h>
64 #define PRINTF(...) printf(__VA_ARGS__)
65 #else
66 #define PRINTF(...)
67 #endif
68 
69 extern unsigned char node_mac[8];
70 
71 //SENSORS(&button_sensor);
72 /*---------------------------------------------------------------------------*/
73 static void
74 set_rime_addr(void)
75 {
76  linkaddr_t addr;
77  int i;
78 
79  memset(&addr, 0, sizeof(linkaddr_t));
80 #if UIP_CONF_IPV6
81  memcpy(addr.u8, node_mac, sizeof(addr.u8));
82 #else
83  if(node_id == 0) {
84  for(i = 0; i < sizeof(linkaddr_t); ++i) {
85  addr.u8[i] = node_mac[7 - i];
86  }
87  } else {
88  addr.u8[0] = node_id & 0xff;
89  addr.u8[1] = node_id >> 8;
90  }
91 #endif
93  printf("Rime addr ");
94  for(i = 0; i < sizeof(addr.u8) - 1; i++) {
95  printf("%u.", addr.u8[i]);
96  }
97  printf("%u\n", addr.u8[i]);
98 }
99 /*---------------------------------------------------------------------------*/
100 static void
101 print_processes(struct process * const processes[])
102 {
103  /* const struct process * const * p = processes;*/
104  printf("Starting");
105  while(*processes != NULL) {
106  printf(" %s", (*processes)->name);
107  processes++;
108  }
109  putchar('\n');
110 }
111 /*--------------------------------------------------------------------------*/
112 int
113 main(int argc, char **argv)
114 {
115  /*
116  * Initalize hardware.
117  */
118  msp430_cpu_init();
119  clock_init();
120  leds_init();
121 
122  leds_on(LEDS_RED);
123 
124  uart1_init(BAUD2UBR(115200)); /* Must come before first printf */
125 #if WITH_UIP
126  slip_arch_init(BAUD2UBR(115200));
127 #endif /* WITH_UIP */
128 
129  leds_on(LEDS_GREEN);
130  /* xmem_init(); */
131 
132  rtimer_init();
133 
134  lcd_init();
135 
136  PRINTF(CONTIKI_VERSION_STRING "\n");
137  /*
138  * Hardware initialization done!
139  */
140 
141  leds_on(LEDS_RED);
142  /* Restore node id if such has been stored in external mem */
143 
144  // node_id_restore();
145 #ifdef NODEID
146  node_id = NODEID;
147 
148 #ifdef BURN_NODEID
149  flash_setup();
150  flash_clear(0x1800);
151  flash_write(0x1800, node_id);
152  flash_done();
153 #endif /* BURN_NODEID */
154 #endif /* NODE_ID */
155 
156  if(node_id == 0) {
157  node_id = *((unsigned short *)0x1800);
158  }
159  memset(node_mac, 0, sizeof(node_mac));
160  node_mac[6] = node_id >> 8;
161  node_mac[7] = node_id & 0xff;
162 
163  /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */
164 #ifdef MAC_1
165  {
166  uint8_t ieee[] = { MAC_1, MAC_2, MAC_3, MAC_4, MAC_5, MAC_6, MAC_7, MAC_8 };
167  memcpy(node_mac, ieee, sizeof(uip_lladdr.addr));
168  }
169 #endif
170 
171  /*
172  * Initialize Contiki and our processes.
173  */
174  process_init();
175  process_start(&etimer_process, NULL);
176 
177  ctimer_init();
178 
179  set_rime_addr();
180 
181  cc2420_init();
182 
183  {
184  uint8_t longaddr[8];
185  uint16_t shortaddr;
186 
187  shortaddr = (linkaddr_node_addr.u8[0] << 8) +
188  linkaddr_node_addr.u8[1];
189  memset(longaddr, 0, sizeof(longaddr));
190  linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr);
191  printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
192  longaddr[0], longaddr[1], longaddr[2], longaddr[3],
193  longaddr[4], longaddr[5], longaddr[6], longaddr[7]);
194 
195  cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
196  }
197 
198  leds_off(LEDS_ALL);
199 
200  if(node_id > 0) {
201  PRINTF("Node id %u.\n", node_id);
202  } else {
203  PRINTF("Node id not set.\n");
204  }
205 
206 #if WITH_UIP6
207  memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr));
208  /* Setup nullmac-like MAC for 802.15.4 */
209 
210  queuebuf_init();
211 
212  NETSTACK_RDC.init();
213  NETSTACK_MAC.init();
214  NETSTACK_NETWORK.init();
215 
216  printf("%s %lu %u\n",
217  NETSTACK_RDC.name,
218  CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
219  NETSTACK_RDC.channel_check_interval()),
220  CC2420_CONF_CHANNEL);
221 
222  process_start(&tcpip_process, NULL);
223 
224  printf("IPv6 ");
225  {
226  uip_ds6_addr_t *lladdr;
227  int i;
228  lladdr = uip_ds6_get_link_local(-1);
229  for(i = 0; i < 7; ++i) {
230  printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
231  lladdr->ipaddr.u8[i * 2 + 1]);
232  }
233  printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
234  }
235 
236  if(!UIP_CONF_IPV6_RPL) {
237  uip_ipaddr_t ipaddr;
238  int i;
239  uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
240  uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
241  uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
242  printf("Tentative global IPv6 address ");
243  for(i = 0; i < 7; ++i) {
244  printf("%02x%02x:",
245  ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
246  }
247  printf("%02x%02x\n",
248  ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
249  }
250 
251 #else /* WITH_UIP6 */
252 
253  NETSTACK_RDC.init();
254  NETSTACK_MAC.init();
255  NETSTACK_NETWORK.init();
256 
257  printf("%s %lu %u\n",
258  NETSTACK_RDC.name,
259  CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
260  NETSTACK_RDC.channel_check_interval()),
261  CC2420_CONF_CHANNEL);
262 #endif /* WITH_UIP6 */
263 
264 #if !WITH_UIP6
265  uart1_set_input(serial_line_input_byte);
266  serial_line_init();
267 #endif
268 
269 #if TIMESYNCH_CONF_ENABLED
270  timesynch_init();
272 #endif /* TIMESYNCH_CONF_ENABLED */
273 
274 
275  /* process_start(&sensors_process, NULL);
276  SENSORS_ACTIVATE(button_sensor);*/
277 
278  energest_init();
279  ENERGEST_ON(ENERGEST_TYPE_CPU);
280 
281  print_processes(autostart_processes);
282  autostart_start(autostart_processes);
283 
284  duty_cycle_scroller_start(CLOCK_SECOND * 2);
285 
286  /*
287  * This is the scheduler loop.
288  */
289  watchdog_start();
290  watchdog_stop(); /* Stop the wdt... */
291  while(1) {
292  int r;
293  do {
294  /* Reset watchdog. */
296  r = process_run();
297  } while(r > 0);
298 
299  /*
300  * Idle processing.
301  */
302  int s = splhigh(); /* Disable interrupts. */
303  /* uart1_active is for avoiding LPM3 when still sending or receiving */
304  if(process_nevents() != 0 || uart1_active()) {
305  splx(s); /* Re-enable interrupts. */
306  } else {
307  static unsigned long irq_energest = 0;
308 
309  /* Re-enable interrupts and go to sleep atomically. */
310  ENERGEST_OFF(ENERGEST_TYPE_CPU);
311  ENERGEST_ON(ENERGEST_TYPE_LPM);
312  /* We only want to measure the processing done in IRQs when we
313  are asleep, so we discard the processing time done when we
314  were awake. */
315  energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
316  watchdog_stop();
317  _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This
318  statement will block
319  until the CPU is
320  woken up by an
321  interrupt that sets
322  the wake up flag. */
323 
324  /* We get the current processing time for interrupts that was
325  done during the LPM and store it for next time around. */
326  dint();
327  irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
328  eint();
329  watchdog_start();
330  ENERGEST_OFF(ENERGEST_TYPE_LPM);
331  ENERGEST_ON(ENERGEST_TYPE_CPU);
332  }
333  }
334 }
335 /*---------------------------------------------------------------------------*/
void uart1_init(unsigned long ubr)
Initalize the RS232 port.
Definition: uart1.c:143
int serial_line_input_byte(unsigned char c)
Get one byte of input from the serial driver.
Definition: serial-line.c:60
linkaddr_t linkaddr_node_addr
The Rime address of the node.
Definition: linkaddr.c:48
int process_nevents(void)
Number of events waiting to be processed.
Definition: process.c:316
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:115
802.15.4 frame creation and parsing functions
#define LEDS_RED
LED1 (Red) -&gt; PC0.
Definition: board.h:89
Unicast address structure.
Definition: uip-ds6.h:172
void timesynch_init(void)
Initialize the timesynch module.
void flash_clear(unsigned short *ptr)
Clear a 16-bit word in flash ROM.
Definition: flash.c:86
void watchdog_start(void)
Starts the WDT in watchdog mode if enabled by user configuration, maximum interval.
Definition: watchdog.c:49
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
Definition: uip-ds6.c:535
void rtimer_init(void)
Initialize the real-time scheduler.
Definition: rtimer.c:61
Network interface and stateless autoconfiguration (RFC 4862)
#define NULL
The null pointer.
void clock_init(void)
Initialize the clock library.
Definition: clock.c:76
int main(void)
This is main...
Definition: ethconfig.c:49
void process_init(void)
Initialize the process module.
Definition: process.c:208
Header file for the Rime stack
void timesynch_set_authority_level(int level)
Set the authority level of the current time.
#define LEDS_GREEN
LED3 (Green) -&gt; PC2.
Definition: board.h:81
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
Definition: linkaddr.c:60
void slip_arch_init(unsigned long ubr)
Initalize the RS232 port and the SLIP driver.
Definition: slip-arch.c:56
void watchdog_stop(void)
In watchdog mode, the WDT can not be stopped.
Definition: watchdog.c:58
Generic serial I/O process header filer.
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:64
Header file for module for automatically starting and exiting a list of processes.
void ctimer_init(void)
Initialize the callback timer library.
Definition: ctimer.c:91
void flash_done(void)
Function that is to be called after flashing is done.
Definition: flash.c:76
void flash_write(unsigned short *ptr, unsigned short word)
Write a 16-bit word to flash ROM.
Definition: flash.c:98
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
Definition: uip-ds6.h:123
int process_run(void)
Run the system once - call poll handlers and process one event.
Definition: process.c:302
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
Definition: linkaddr.c:72
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
Definition: uip.h:969
int lcd_init(void)
This function will initialize the proper settings for the LCD driver.
Definition: lcd.c:277
void flash_setup(void)
Setup function to be called before any of the flash programming functions.
Definition: flash.c:48
Include file for the Contiki low-layer network stack (NETSTACK)
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82