µracoli Manual  Version foo
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 */
static void store_node_config_eeprom(node_config_t *ncfg, uint8_t *offset)
Definition: board.h:325
uint16_t pan_id
Definition: board.h:238
uint64_t ieee_addr
Definition: board.h:240
static void mcu_init(void)
Definition: board.h:396
uint16_t short_addr
Definition: board.h:236
static void jump_to_bootloader(void)
Definition: board.h:342
#define MCU_IRQ_DISABLE
Enable interrupts globally.
Definition: board.h:75
uint8_t channel
Definition: board.h:242
uint8_t crc
Definition: board.h:246
static uint8_t get_node_config_eeprom(node_config_t *ncfg, uint8_t *offset)
Definition: board.h:296
static uint8_t get_node_config(node_config_t *ncfg)
Definition: board.h:258