Contiki-NG
platform.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 <stdio.h>
32 #include <string.h>
33 #include "contiki.h"
34 #include "sys/energest.h"
35 #include "cc2420.h"
36 #include "dev/ds2411/ds2411.h"
37 #include "dev/leds.h"
38 #include "dev/serial-line.h"
39 #include "dev/slip.h"
40 #include "dev/uart1.h"
41 #include "dev/watchdog.h"
42 #include "dev/xmem.h"
43 #include "lib/random.h"
44 #include "net/netstack.h"
46 
47 #if NETSTACK_CONF_WITH_IPV6
48 #include "net/ipv6/uip-ds6.h"
49 #endif /* NETSTACK_CONF_WITH_IPV6 */
50 
51 #include "sys/node-id.h"
52 #include "cfs-coffee-arch.h"
53 #include "cfs/cfs-coffee.h"
54 
55 #if DCOSYNCH_CONF_ENABLED
56 static struct timer mgt_timer;
57 #endif
58 extern int msp430_dco_required;
59 
60 #define UIP_OVER_MESH_CHANNEL 8
61 
62 #ifdef EXPERIMENT_SETUP
63 #include "experiment-setup.h"
64 #endif
65 
66 void init_platform(void);
67 /*---------------------------------------------------------------------------*/
68 /* Log configuration */
69 #include "sys/log.h"
70 #define LOG_MODULE "Sky"
71 #define LOG_LEVEL LOG_LEVEL_MAIN
72 /*---------------------------------------------------------------------------*/
73 #if 0
74 int
75 force_float_inclusion()
76 {
77  extern int __fixsfsi;
78  extern int __floatsisf;
79  extern int __mulsf3;
80  extern int __subsf3;
81 
82  return __fixsfsi + __floatsisf + __mulsf3 + __subsf3;
83 }
84 #endif
85 /*---------------------------------------------------------------------------*/
86 void uip_log(char *msg) { puts(msg); }
87 
88 /*---------------------------------------------------------------------------*/
89 #if 0
90 void
91 force_inclusion(int d1, int d2)
92 {
93  snprintf(NULL, 0, "%d", d1 % d2);
94 }
95 #endif
96 /*---------------------------------------------------------------------------*/
97 static void
98 set_lladdr(void)
99 {
100  linkaddr_t addr;
101 
102  memset(&addr, 0, sizeof(linkaddr_t));
103 #if NETSTACK_CONF_WITH_IPV6
104  memcpy(addr.u8, ds2411_id, sizeof(addr.u8));
105 #else
106  int i;
107  for(i = 0; i < sizeof(linkaddr_t); ++i) {
108  addr.u8[i] = ds2411_id[7 - i];
109  }
110 #endif
111  linkaddr_set_node_addr(&addr);
112 }
113 /*---------------------------------------------------------------------------*/
114 void
116 {
117  /*
118  * Initalize hardware.
119  */
120  msp430_cpu_init();
121 
122  leds_init();
123  leds_on(LEDS_RED);
124 }
125 /*---------------------------------------------------------------------------*/
126 void
128 {
129  uart1_init(BAUD2UBR(115200)); /* Must come before first printf */
130 
131  leds_on(LEDS_GREEN);
132  ds2411_init();
133 
134  /* XXX hack: Fix it so that the 802.15.4 MAC address is compatible
135  with an Ethernet MAC address - byte 0 (byte 2 in the DS ID)
136  cannot be odd. */
137  ds2411_id[2] &= 0xfe;
138 
139  leds_on(LEDS_BLUE);
140  xmem_init();
141 
142  leds_off(LEDS_RED);
143  /*
144  * Hardware initialization done!
145  */
146 
147  random_init(ds2411_id[0]);
148 
149  leds_off(LEDS_BLUE);
150 
151  set_lladdr();
152 
153  /*
154  * main() will turn the radio on inside netstack_init(). The CC2420
155  * must already be initialised by that time, so we do this here early.
156  * Later on in stage three we set correct values for PANID and radio
157  * short/long address.
158  */
159  cc2420_init();
160 }
161 /*---------------------------------------------------------------------------*/
162 void
164 {
165  uint8_t longaddr[8];
166  uint16_t shortaddr;
167 
168  init_platform();
169 
170  shortaddr = (linkaddr_node_addr.u8[0] << 8) + linkaddr_node_addr.u8[1];
171  memset(longaddr, 0, sizeof(longaddr));
172  linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr);
173 
174  cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
175 
176  LOG_INFO("CC2420 CCA threshold %i\n", CC2420_CONF_CCA_THRESH);
177 
178 #if !NETSTACK_CONF_WITH_IPV6
179  uart1_set_input(serial_line_input_byte);
180  serial_line_init();
181 #endif
182 
183  leds_off(LEDS_GREEN);
184 
185 #if TIMESYNCH_CONF_ENABLED
186  timesynch_init();
187  timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
188 #endif /* TIMESYNCH_CONF_ENABLED */
189 
190  /*
191  * This is the scheduler loop.
192  */
193 #if DCOSYNCH_CONF_ENABLED
194  timer_set(&mgt_timer, DCOSYNCH_PERIOD * CLOCK_SECOND);
195 #endif
196 }
197 /*---------------------------------------------------------------------------*/
198 void
200 {
201  /*
202  * Idle processing.
203  */
204  int s = splhigh(); /* Disable interrupts. */
205  /* uart1_active is for avoiding LPM3 when still sending or receiving */
206  if(process_nevents() != 0 || uart1_active()) {
207  splx(s); /* Re-enable interrupts. */
208  } else {
209 #if DCOSYNCH_CONF_ENABLED
210  /* before going down to sleep possibly do some management */
211  if(timer_expired(&mgt_timer)) {
213  timer_reset(&mgt_timer);
214  msp430_sync_dco();
215 #if CC2420_CONF_SFD_TIMESTAMPS
216  cc2420_arch_sfd_init();
217 #endif /* CC2420_CONF_SFD_TIMESTAMPS */
218  }
219 #endif
220 
221  /* Re-enable interrupts and go to sleep atomically. */
222  ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
223  watchdog_stop();
224  /* check if the DCO needs to be on - if so - only LPM 1 */
225  if (msp430_dco_required) {
226  _BIS_SR(GIE | CPUOFF); /* LPM1 sleep for DMA to work!. */
227  } else {
228  _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This
229  statement will block
230  until the CPU is
231  woken up by an
232  interrupt that sets
233  the wake up flag. */
234  }
235  watchdog_start();
236  ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
237  }
238 }
CC2420 driver header file
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:115
Header file for the energy estimation mechanism
void platform_init_stage_two()
Stage 2 of platform driver initialisation.
Definition: platform.c:123
void platform_idle()
The platform&#39;s idle/sleep function.
Definition: platform.c:185
void leds_init(void)
Initialise the LED HAL.
Definition: minileds.c:44
void timer_reset(struct timer *t)
Reset the timer with the same interval.
Definition: timer.c:85
void uip_log(char *m)
Print out a uIP log message.
Definition: platform.c:333
Header for the Coffee file system.
Node-id (simple 16-bit identifiers) handling.
void uart1_init(unsigned long ubr)
Initalize the RS232 port.
Definition: uart1.c:142
A timer.
Definition: timer.h:82
void leds_on(unsigned char leds)
Turn on multiple LEDs.
Definition: minileds.c:63
void leds_off(unsigned char leds)
Turn off multiple LEDs.
Definition: minileds.c:69
Header file for IPv6-related data structures.
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition: linkaddr.c:48
int serial_line_input_byte(unsigned char c)
Get one byte of input from the serial driver.
Definition: serial-line.c:65
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
void watchdog_start(void)
Starts the WDT in watchdog mode if enabled by user configuration, maximum interval.
Definition: watchdog.c:72
int timer_expired(struct timer *t)
Check if a timer has expired.
Definition: timer.c:122
802.15.4 frame creation and parsing functions
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
Definition: linkaddr.c:63
void platform_init_stage_three()
Final stage of platform driver initialisation.
Definition: platform.c:169
int process_nevents(void)
Number of events waiting to be processed.
Definition: process.c:316
void random_init(unsigned short seed)
Seed the cc2538 random number generator.
Definition: random.c:84
Generic serial I/O process header filer.
Coffee architecture-dependent header for the Tmote Sky platform.
Include file for the Contiki low-layer network stack (NETSTACK)
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:85
Header file for the logging system
Header file for the LED HAL.
void platform_init_stage_one(void)
Basic (Stage 1) platform driver initialisation.
Definition: platform.c:114
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
Definition: linkaddr.c:75
void watchdog_stop(void)
Stops the WDT such that it won&#39;t timeout and cause MCU reset.