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 <stdarg.h>
34 
35 #include "contiki.h"
37 #include "dev/leds.h"
38 #include "dev/serial-line.h"
39 #include "dev/slip.h"
40 #include "dev/uart0.h"
41 #include "dev/watchdog.h"
42 #include "dev/xmem.h"
43 #include "lib/random.h"
44 #include "net/netstack.h"
46 #include "dev/adxl345.h"
47 #include "sys/clock.h"
48 #include "sys/energest.h"
49 
50 #if NETSTACK_CONF_WITH_IPV6
51 #include "net/ipv6/uip-ds6.h"
52 #endif /* NETSTACK_CONF_WITH_IPV6 */
53 
54 #include "node-id-z1.h"
55 #include "cfs-coffee-arch.h"
56 #include "cfs/cfs-coffee.h"
57 
58 extern unsigned char node_mac[8];
59 
60 #if DCOSYNCH_CONF_ENABLED
61 static struct timer mgt_timer;
62 #endif
63 extern int msp430_dco_required;
64 
65 #define UIP_OVER_MESH_CHANNEL 8
66 #if NETSTACK_CONF_WITH_IPV4
67 static uint8_t is_gateway;
68 #endif /* NETSTACK_CONF_WITH_IPV4 */
69 
70 #ifdef EXPERIMENT_SETUP
71 #include "experiment-setup.h"
72 #endif
73 
74 void init_platform(void);
75 /*---------------------------------------------------------------------------*/
76 /* Log configuration */
77 #include "sys/log.h"
78 #define LOG_MODULE "Z1"
79 #define LOG_LEVEL LOG_LEVEL_MAIN
80 /*---------------------------------------------------------------------------*/
81 #ifdef UART0_CONF_BAUD_RATE
82 #define UART0_BAUD_RATE UART0_CONF_BAUD_RATE
83 #else
84 #define UART0_BAUD_RATE 115200
85 #endif
86 /*---------------------------------------------------------------------------*/
87 #if 0
88 int
89 force_float_inclusion()
90 {
91  extern int __fixsfsi;
92  extern int __floatsisf;
93  extern int __mulsf3;
94  extern int __subsf3;
95 
96  return __fixsfsi + __floatsisf + __mulsf3 + __subsf3;
97 }
98 #endif
99 /*---------------------------------------------------------------------------*/
100 void
101 uip_log(char *msg)
102 {
103  puts(msg);
104 }
105 /*---------------------------------------------------------------------------*/
106 #if 0
107 void
108 force_inclusion(int d1, int d2)
109 {
110  snprintf(NULL, 0, "%d", d1 % d2);
111 }
112 #endif
113 /*---------------------------------------------------------------------------*/
114 static void
115 set_lladdr(void)
116 {
117  linkaddr_t addr;
118 
119  memset(&addr, 0, sizeof(linkaddr_t));
120 #if NETSTACK_CONF_WITH_IPV6
121  memcpy(addr.u8, node_mac, sizeof(addr.u8));
122 #else
123  if(node_id == 0) {
124  int i;
125  for(i = 0; i < sizeof(linkaddr_t); ++i) {
126  addr.u8[i] = node_mac[7 - i];
127  }
128  } else {
129  addr.u8[0] = node_id & 0xff;
130  addr.u8[1] = node_id >> 8;
131  }
132 #endif
133  linkaddr_set_node_addr(&addr);
134 }
135 /*---------------------------------------------------------------------------*/
136 void
138 {
139  /*
140  * Initalize hardware.
141  */
142  msp430_cpu_init();
143 
144  leds_init();
145  leds_on(LEDS_RED);
146 }
147 /*---------------------------------------------------------------------------*/
148 void
150 {
151  clock_wait(100);
152 
153  uart0_init(BAUD2UBR(UART0_BAUD_RATE)); /* Must come before first printf */
154 
155  xmem_init();
156 
157  leds_off(LEDS_RED);
158  /*
159  * Hardware initialization done!
160  */
161 
162  /* Restore node id if such has been stored in external mem */
163  node_id_z1_restore();
164 
165  /* If no MAC address was burned, we use the node id or the Z1 product ID */
166  if(!(node_mac[0] | node_mac[1] | node_mac[2] | node_mac[3] |
167  node_mac[4] | node_mac[5] | node_mac[6] | node_mac[7])) {
168 
169 #ifdef SERIALNUM
170  if(!node_id) {
171  LOG_INFO("Node id is not set, using Z1 product ID\n");
172  node_id = SERIALNUM;
173  }
174 #endif
175  node_mac[0] = 0xc1; /* Hardcoded for Z1 */
176  node_mac[1] = 0x0c; /* Hardcoded for Revision C */
177  node_mac[2] = 0x00; /* Hardcoded to arbitrary even number so that
178  the 802.15.4 MAC address is compatible with
179  an Ethernet MAC address - byte 0 (byte 2 in
180  the DS ID) */
181  node_mac[3] = 0x00; /* Hardcoded */
182  node_mac[4] = 0x00; /* Hardcoded */
183  node_mac[5] = 0x00; /* Hardcoded */
184  node_mac[6] = node_id >> 8;
185  node_mac[7] = node_id & 0xff;
186  }
187 
188  /* Overwrite node MAC if desired at compile time */
189 #ifdef MACID
190 #warning "***** CHANGING DEFAULT MAC *****"
191  node_mac[0] = 0xc1; /* Hardcoded for Z1 */
192  node_mac[1] = 0x0c; /* Hardcoded for Revision C */
193  node_mac[2] = 0x00; /* Hardcoded to arbitrary even number so that
194  the 802.15.4 MAC address is compatible with
195  an Ethernet MAC address - byte 0 (byte 2 in
196  the DS ID) */
197  node_mac[3] = 0x00; /* Hardcoded */
198  node_mac[4] = 0x00; /* Hardcoded */
199  node_mac[5] = 0x00; /* Hardcoded */
200  node_mac[6] = MACID >> 8;
201  node_mac[7] = MACID & 0xff;
202 #endif
203 
204 #ifdef IEEE_802154_MAC_ADDRESS
205  /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */
206  {
207  uint8_t ieee[] = IEEE_802154_MAC_ADDRESS;
208  memcpy(node_mac, ieee, sizeof(uip_lladdr.addr));
209  node_mac[7] = node_id & 0xff;
210  }
211 #endif /* IEEE_802154_MAC_ADDRESS */
212 
213  random_init(node_mac[6] + node_mac[7]);
214 
215  set_lladdr();
216 
217  /*
218  * main() will turn the radio on inside netstack_init(). The CC2420
219  * must already be initialised by that time, so we do this here early.
220  * Later on in stage three we set correct values for PANID and radio
221  * short/long address.
222  */
223  cc2420_init();
224 
225  SENSORS_ACTIVATE(adxl345);
226 
228 }
229 /*---------------------------------------------------------------------------*/
230 void
232 {
233  uint8_t longaddr[8];
234  uint16_t shortaddr;
235 
236  init_platform();
237 
238  shortaddr = (linkaddr_node_addr.u8[0] << 8) + linkaddr_node_addr.u8[1];
239  memset(longaddr, 0, sizeof(longaddr));
240  linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr);
241 
242  cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
243 
244  LOG_INFO("CC2420 CCA threshold %i\n", CC2420_CONF_CCA_THRESH);
245 
246 #if DCOSYNCH_CONF_ENABLED
247  timer_set(&mgt_timer, DCOSYNCH_PERIOD * CLOCK_SECOND);
248 #endif
249 }
250 /*---------------------------------------------------------------------------*/
251 void
253 {
254  /*
255  * Idle processing.
256  */
257  int s = splhigh(); /* Disable interrupts. */
258  /* uart0_active is for avoiding LPM3 when still sending or receiving */
259  if(process_nevents() != 0 || uart0_active()) {
260  splx(s); /* Re-enable interrupts. */
261  } else {
262 #if DCOSYNCH_CONF_ENABLED
263  /* before going down to sleep possibly do some management */
264  if(timer_expired(&mgt_timer)) {
266  timer_reset(&mgt_timer);
267  msp430_sync_dco();
268 #if CC2420_CONF_SFD_TIMESTAMPS
269  cc2420_arch_sfd_init();
270 #endif /* CC2420_CONF_SFD_TIMESTAMPS */
271  }
272 #endif
273 
274  /* Re-enable interrupts and go to sleep atomically. */
275  ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
276  watchdog_stop();
277  /* check if the DCO needs to be on - if so - only LPM 1 */
278  if (msp430_dco_required) {
279  _BIS_SR(GIE | CPUOFF); /* LPM1 sleep for DMA to work!. */
280  } else {
281  _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This
282  statement will block
283  until the CPU is
284  woken up by an
285  interrupt that sets
286  the wake up flag. */
287  }
288  watchdog_start();
289  ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
290  }
291 }
292 /*---------------------------------------------------------------------------*/
CC2420 driver header file
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:107
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
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:84
void uip_log(char *m)
Print out a uIP log message.
Definition: platform.c:342
Header for the Coffee file system.
void clock_wait(clock_time_t i)
Wait for a given number of ticks.
Definition: clock.c:136
A timer.
Definition: timer.h:82
void leds_on(unsigned char leds)
Turn on multiple LEDs.
Definition: minileds.c:63
#define LEDS_ALL
The OR mask representation of all device LEDs.
Definition: leds.h:195
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
Coffee architecture-dependent header for the Zolertia Z1 platform.
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
void uart0_init(unsigned long ubr)
Initalize the RS232 port.
Definition: uart0.c:139
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:123
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.
Include file for the Contiki low-layer network stack (NETSTACK)
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:85
Device drivers header file for adxl345 accelerometer in Zolertia Z1.
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.