µracoli Manual Version foo

- µracoli
- User Guide
- Reference Guide

board.h
1 /* Copyright (c) 2007-2014 Axel Wachtler
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * 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 * Neither the name of the authors 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND 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 COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE. */
28
29 /* $Id$ */
35 #ifndef BOARD_H
36 #define BOARD_H (1)
37
38 #ifndef F_CPU
39 # error "F_CPU is undefined"
40 #endif
41
42 /* === includes ============================================================ */
43 #include <stdlib.h>
44 #include <stdint.h>
45 #include <inttypes.h>
46 #include <avr/io.h>
47 #include <avr/sleep.h>
48 #include <avr/interrupt.h>
49 #include <util/delay.h>
50 #include <avr/pgmspace.h>
51 #include <avr/eeprom.h>
52 #include <util/crc16.h>
53 #include "const.h"
54 #include "board_cfg.h"
55
61 /* === macros ============================================================== */
62
68 #define MCU_IRQ_ENABLE sei
69
75 #define MCU_IRQ_DISABLE cli
76
89 #define DELAY_US(x) _delay_ms(x/1000.0)
90
93 #define DELAY_MS(x) _delay_ms(x)
94
95 #ifndef PULLUP_KEYS
96
99 # define PULLUP_KEYS (0)
100 #endif
101
102
106 #define SLEEP_ON_IDLE()\
107 do{\
108 set_sleep_mode(SLEEP_MODE_IDLE);\
109 sleep_mode();\
110 }while(0);
111
112
113 #ifdef NO_TIMER
114 //# define HAVE_MALLOC_TIMERS
116 # define TIMER_POOL_SIZE (0)
117 # define TIMER_INIT() do{}while(0)
118 # define TIMER_IRQ TIMER1_OVF_vect
119 #endif
120
121 #ifndef HIF_DEFAULT_BAUDRATE
122 # define HIF_DEFAULT_BAUDRATE (9600)
123 #endif
124
125 #ifndef HIF_TYPE
126
127 # define NO_HIF (1)
128 # define HIF_TYPE (HIF_NONE)
129 #endif
130
131 #ifndef HIF_IO_ENABLE
132
133 # define HIF_IO_ENABLE() do{}while(0)
134 #endif
135
136 #define HIF_TYPE_IS_NONE (HIF_TYPE == HIF_NONE)
137 #define HIF_TYPE_IS_UART ((HIF_TYPE >= HIF_UART_0) && ( HIF_TYPE <= HIF_USARTE0))
138 #define HIF_TYPE_IS_USB ((HIF_TYPE == HIF_FT245) || (HIF_TYPE == HIF_AT90USB))
139
140 #ifndef DEFAULT_SPI_RATE
141
147 # define DEFAULT_SPI_RATE (SPI_RATE_1_2)
148 #endif
149
150 /* === Radio Control Pins === */
151 #ifndef TRX_RESET_INIT
152
153 # define TRX_RESET_INIT() DDR_TRX_RESET |= MASK_TRX_RESET
154 #endif
155
156 #ifndef TRX_RESET_HIGH
157
158 # define TRX_RESET_HIGH() PORT_TRX_RESET |= MASK_TRX_RESET
159 #endif
160
161 #ifndef TRX_RESET_LOW
162
163 # define TRX_RESET_LOW() PORT_TRX_RESET &= ~MASK_TRX_RESET
164 #endif
165
166 #ifndef TRX_SLPTR_INIT
167
168 # define TRX_SLPTR_INIT() DDR_TRX_SLPTR |= MASK_TRX_SLPTR
169 #endif
170
171 #ifndef TRX_SLPTR_HIGH
172
173 # define TRX_SLPTR_HIGH() PORT_TRX_SLPTR |= MASK_TRX_SLPTR
174 #endif
175
176 #ifndef TRX_SLPTR_LOW
177
178 # define TRX_SLPTR_LOW() PORT_TRX_SLPTR &= ~MASK_TRX_SLPTR
179 #endif
180
181 #if ! defined(DI_TRX_IRQ) && ! defined(EI_TRX_IRQ)
182 /* the functions (disable,enable)_all_trx_irqs are defined in atmga_rfa1.h */
183 # define DI_TRX_IRQ disable_all_trx_irqs
184 # define EI_TRX_IRQ enable_all_trx_irqs
185 #endif
186
187 #if ! defined(ACK_TRX_IRQ)
188 # define ACK_TRX_IRQ() do{}while(0)
189 #endif
190
191 #if defined (DBG_PORT) && defined (DBG_DDR) && defined (DBG_PIN)
192 # define DBG_INIT() do{DBG_DDR |= DBG_PIN; DBG_PORT &= ~DBG_PIN;}while(0)
193 # define DBG_SET() do{DBG_PORT |= DBG_PIN;}while(0)
194 # define DBG_CLR() do{DBG_PORT &= ~DBG_PIN;}while(0)
195 # define DBG_TOGGLE() do{DBG_PORT ^= DBG_PIN;}while(0)
196 #else
197 # define DBG_INIT() do{}while(0)
198 # define DBG_SET() do{}while(0)
199 # define DBG_CLR() do{}while(0)
200 # define DBG_TOGGLE() do{}while(0)
201 #endif
202
203
204 /* === WiBO Control === */
205 #if ! defined(NO_KEYS) && 0 == 1
206 # define WIBO_FLAVOUR_KEYPRESS (1)
207 # define WIBO_FLAVOUR_KEYPRESS_KEYNB (0)
208 #endif
209
210 #if defined(GPIOR0) && 0 == 1
211 # define WIBO_FLAVOUR_MAILBOX (1)
212 # define WIBO_FLAVOUR_MAILBOX_REGISTER (GPIOR0)
213 # define WIBO_FLAVOUR_MAILBOX_CODE (0xA5)
214 #endif
215
216 #if defined(WIBO_FLAVOUR_MAILBOX)
217 # define WIBO_MAILBOX_SET() \
218 do{WIBO_FLAVOUR_MAILBOX_REGISTER = WIBO_FLAVOUR_MAILBOX_CODE;}while(0);
219 # define WIBO_MAILBOX_CLR() \
220 do{WIBO_FLAVOUR_MAILBOX_REGISTER = ~WIBO_FLAVOUR_MAILBOX_CODE;}while(0);
221 #endif
222
223 /* === types =============================================================== */
224
233 typedef struct
234 {
236 uint16_t short_addr;
238 uint16_t pan_id;
240 uint64_t ieee_addr;
242 uint8_t channel;
244 uint8_t _reserved_[2];
246 uint8_t crc;
247 } node_config_t;
248
258 static inline uint8_t get_node_config(node_config_t *ncfg)
259 {
260 uint8_t i = sizeof(node_config_t);
261 uint8_t *pram = (uint8_t*)ncfg;
262 uint8_t crc = 0, zcnt = 0;
263 do
264 {
265 #if FLASHEND > 0xffffL
266 *pram = pgm_read_byte_far(((long)FLASHEND - i + 1));
267 #else
268 *pram = pgm_read_byte_near((FLASHEND - i + 1));
269 #endif
270
271 crc = _crc_ibutton_update(crc, *pram);
272 zcnt += *pram ? 0 : 1;
273 pram ++;
274 }
275 while(--i);
276
277 /* return true if crc does not match or all */
278 if (zcnt == sizeof(node_config_t))
279 {
280 crc = 0x55;
281 }
282
283 return crc;
284 }
285
296 static inline uint8_t get_node_config_eeprom(node_config_t *ncfg, uint8_t * offset)
297 {
298 uint8_t i = sizeof(node_config_t);
299 uint8_t *pram = (uint8_t*)ncfg;
300 uint8_t crc = 0, zcnt = 0;
301 do
302 {
303 *pram = eeprom_read_byte( (const uint8_t *) offset++ );
304 crc = _crc_ibutton_update(crc, *pram);
305 zcnt += *pram ? 0 : 1;
306 pram ++;
307 }
308 while(--i);
309 if (zcnt == sizeof(node_config_t))
310 {
311 crc = 0x55;
312 }
313 return crc;
314 }
315
325 static inline void store_node_config_eeprom(node_config_t *ncfg, uint8_t * offset)
326 {
327 uint8_t i = sizeof(node_config_t) - sizeof(uint8_t);
328 uint8_t *pram = (uint8_t*)ncfg;
329 uint8_t crc = 0;
330 do
331 {
332 eeprom_write_byte( (uint8_t *)offset++, *pram );
333 crc = _crc_ibutton_update(crc, *pram++);
334 }
335 while(--i);
336 eeprom_write_byte((uint8_t *)offset, crc );
337 }
338
342 static inline void jump_to_bootloader(void)
343 {
344 typedef void (*func_ptr_t)(void) __attribute__((noreturn));
345 const func_ptr_t jmp_boot = (func_ptr_t) BOOTLOADER_ADDRESS;
346 #if defined(WIBO_FLAVOUR_MAILBOX)
347 WIBO_MAILBOX_SET();
348 #endif
349 MCU_IRQ_DISABLE();
350 jmp_boot();
351 }
352
353 #if defined(__AVR_XMEGA__)
354
355 #if F_CPU == 4000000UL
356 #define CLK_PSADIV (CLK_PSADIV_8_gc)
357 #elif F_CPU == 8000000UL
358 #define CLK_PSADIV (CLK_PSADIV_4_gc)
359 #elif F_CPU == 16000000UL
360 #define CLK_PSADIV (CLK_PSADIV_2_gc)
361 #elif F_CPU == 32000000UL
362 #define CLK_PSADIV (CLK_PSADIV_1_gc)
363 #else
364 #error F_CPU frequency not supported
365 #endif
366
373 static inline void atxmega_switch_clock(void)
374 {
375 OSC.CTRL |= OSC_RC32MEN_bm;
376 while (!(OSC.STATUS & OSC_RC32MRDY_bm));
377
378 CCP = 0xD8;
379 CLK.PSCTRL = CLK_PSADIV | CLK_PSBCDIV_1_1_gc;
380
381 /* when compiling with optimization > -O1, this instruction is required on ATxmega256A3 for some reason */
382 __asm__ volatile ("nop");
383
384 CCP = 0xD8;
385 CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
386 }
387
388 #undef CLK_PSADIV
389
390 #endif /* defined(__AVR_XMEGA__) */
391
396 static inline void mcu_init(void)
397 {
398 #if defined(__AVR_XMEGA__)
399 atxmega_switch_clock();
400 #endif
401
402 #ifdef CHECKBOOTLOADER
403 CHECKBOOTLOADER();
404 #endif
405 }
406
407 /* === prototypes ========================================================== */
408 #ifdef __cplusplus
409 extern "C" {
410 #endif
411
412 #ifdef __cplusplus
413 } /* extern "C" */
414 #endif
415
417 #endif /* #ifndef BOARD_H */
store_node_config_eeprom
static void store_node_config_eeprom(node_config_t *ncfg, uint8_t *offset)
Definition: board.h:325
node_config_t::pan_id
uint16_t pan_id
Definition: board.h:238
node_config_t::ieee_addr
uint64_t ieee_addr
Definition: board.h:240
mcu_init
static void mcu_init(void)
Definition: board.h:396
node_config_t::short_addr
uint16_t short_addr
Definition: board.h:236
jump_to_bootloader
static void jump_to_bootloader(void)
Definition: board.h:342
MCU_IRQ_DISABLE
#define MCU_IRQ_DISABLE
Enable interrupts globally.
Definition: board.h:75
node_config_t::channel
uint8_t channel
Definition: board.h:242
node_config_t
Definition: board.h:233
node_config_t::crc
uint8_t crc
Definition: board.h:246
get_node_config_eeprom
static uint8_t get_node_config_eeprom(node_config_t *ncfg, uint8_t *offset)
Definition: board.h:296
get_node_config
static uint8_t get_node_config(node_config_t *ncfg)
Definition: board.h:258