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
58extern unsigned char node_mac[8];
59
60#if DCOSYNCH_CONF_ENABLED
61static struct timer mgt_timer;
62#endif
63extern int msp430_dco_required;
64
65#define UIP_OVER_MESH_CHANNEL 8
66#if NETSTACK_CONF_WITH_IPV4
67static uint8_t is_gateway;
68#endif /* NETSTACK_CONF_WITH_IPV4 */
69
70#ifdef EXPERIMENT_SETUP
71#include "experiment-setup.h"
72#endif
73
74void 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
88int
89force_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/*---------------------------------------------------------------------------*/
100void
101uip_log(char *msg)
102{
103 puts(msg);
104}
105/*---------------------------------------------------------------------------*/
106#if 0
107void
108force_inclusion(int d1, int d2)
109{
110 snprintf(NULL, 0, "%d", d1 % d2);
111}
112#endif
113/*---------------------------------------------------------------------------*/
114static void
115set_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
134}
135/*---------------------------------------------------------------------------*/
136void
138{
139 /*
140 * Initalize hardware.
141 */
142 msp430_cpu_init();
143
144 leds_init();
145 leds_on(LEDS_RED);
146}
147/*---------------------------------------------------------------------------*/
148void
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/*---------------------------------------------------------------------------*/
230void
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/*---------------------------------------------------------------------------*/
251void
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);
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 }
289 ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
290 }
291}
292/*---------------------------------------------------------------------------*/
Device drivers header file for adxl345 accelerometer in Zolertia Z1.
CC2420 driver header file.
Header for the Coffee file system.
Header file for the energy estimation mechanism.
802.15.4 frame creation and parsing functions
void clock_wait(clock_time_t i)
Wait for a given number of ticks.
Definition: clock.c:136
void random_init(unsigned short seed)
Seed the cc2538 random number generator.
Definition: random.c:84
void watchdog_start(void)
Starts the WDT in watchdog mode if enabled by user configuration, maximum interval.
Definition: watchdog.c:72
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:85
void platform_init_stage_three()
Final stage of platform driver initialisation.
Definition: platform.c:169
void platform_init_stage_one(void)
Basic (Stage 1) platform driver initialisation.
Definition: platform.c:114
void platform_idle()
The platform's idle/sleep function.
Definition: platform.c:185
void platform_init_stage_two()
Stage 2 of platform driver initialisation.
Definition: platform.c:123
void watchdog_stop(void)
Stops the WDT such that it won't timeout and cause MCU reset.
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
#define LEDS_ALL
The OR mask representation of all device LEDs.
Definition: leds.h:195
void leds_init(void)
Initialise the LED HAL.
Definition: minileds.c:44
void leds_on(leds_mask_t leds)
Turn on multiple LEDs.
Definition: leds.c:168
void leds_off(leds_mask_t leds)
Turn off multiple LEDs.
Definition: leds.c:186
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition: linkaddr.c:48
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
Definition: linkaddr.c:75
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
Definition: linkaddr.c:63
void uip_log(char *m)
Print out a uIP log message.
Definition: platform.c:342
void uart0_init(unsigned long ubr)
Initalize the RS232 port.
Definition: uart0.c:139
int process_nevents(void)
Number of events waiting to be processed.
Definition: process.c:316
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
int timer_expired(struct timer *t)
Check if a timer has expired.
Definition: timer.c:123
void timer_reset(struct timer *t)
Reset the timer with the same interval.
Definition: timer.c:84
uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:107
void xmem_init(void)
Initialize the external memory.
Definition: xmem.c:59
Header file for the LED HAL.
Header file for the logging system.
Include file for the Contiki low-layer network stack (NETSTACK)
Coffee architecture-dependent header for the Zolertia Z1 platform.
Generic serial I/O process header filer.
A timer.
Definition: timer.h:82
Header file for IPv6-related data structures.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
Header file to the external flash memory (XMem) API.