Contiki 3.x
hal.h
Go to the documentation of this file.
1 /* Copyright (c) 2008, Swedish Institute of Computer Science
2  * All rights reserved.
3  *
4  * Additional fixes for AVR contributed by:
5  *
6  * Colin O'Flynn coflynn@newae.com
7  * Eric Gnoske egnoske@gmail.com
8  * Blake Leverett bleverett@gmail.com
9  * Mike Vidales mavida404@gmail.com
10  * Kevin Brown kbrown3@uccs.edu
11  * Nate Bohlmann nate@elfwerks.com
12  *
13  * All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions are met:
17  *
18  * * Redistributions of source code must retain the above copyright
19  * notice, this list of conditions and the following disclaimer.
20  * * Redistributions in binary form must reproduce the above copyright
21  * notice, this list of conditions and the following disclaimer in
22  * the documentation and/or other materials provided with the
23  * distribution.
24  * * Neither the name of the copyright holders nor the names of
25  * contributors may be used to endorse or promote products derived
26  * from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /**
42  * \addtogroup hal
43  * @{
44  */
45 
46 /**
47  * \file
48  * \brief This file contains low-level radio driver code.
49  *
50 */
51 
52 #ifndef HAL_AVR_H
53 #define HAL_AVR_H
54 /*============================ INCLUDE =======================================*/
55 #include <stdint.h>
56 #include <stdbool.h>
57 #include <avr/io.h>
58 #include <avr/interrupt.h>
59 #include <util/crc16.h>
60 #include "contiki-conf.h"
61 /*============================ MACROS ========================================*/
62 
63 // TEST CODE
64 #define TRIG1 DDRB |= 0x04, PINB |= 0x04
65 #define TRIG2 DDRD |= 0x80, PIND |= 0x80
66 
67 /** \name This is the list of pin configurations needed for a given platform.
68  * \brief Change these values to port to other platforms.
69  * \{
70  */
71 /* Define all possible revisions here */
72 // Don't use zero, it will match if undefined!
73 // RAVEN_D : Raven kit with LCD display
74 // RAVENUSB_C : used for USB key or Raven card
75 // RCB_B : RZ200 kit from Atmel based on 1281V
76 // ZIGBIT : Zigbit module from Meshnetics
77 // IRIS : IRIS Mote from MEMSIC
78 #define RAVEN_D 1
79 #define RAVENUSB_C 2
80 #define RCB_B 3
81 #define ZIGBIT 4
82 #define IRIS 5
83 
84 
85 
86 
87 #if PLATFORM_TYPE == RCB_B
88 /* 1281 rcb */
89 # define SSPORT B
90 # define SSPIN (0x00)
91 # define SPIPORT B
92 # define MOSIPIN (0x02)
93 # define MISOPIN (0x03)
94 # define SCKPIN (0x01)
95 # define RSTPORT B
96 # define RSTPIN (0x05)
97 # define IRQPORT D
98 # define IRQPIN (0x04)
99 # define SLPTRPORT B
100 # define SLPTRPIN (0x04)
101 # define USART 1
102 # define USARTVECT USART1_RX_vect
103 # define TICKTIMER 3
104 # define HAS_SPARE_TIMER
105 
106 #elif PLATFORM_TYPE == ZIGBIT
107 /* 1281V Zigbit */
108 # define SSPORT B
109 # define SSPIN (0x00)
110 # define SPIPORT B
111 # define MOSIPIN (0x02)
112 # define MISOPIN (0x03)
113 # define SCKPIN (0x01)
114 # define RSTPORT A
115 # define RSTPIN (0x07)
116 # define IRQPORT E
117 # define IRQPIN (0x05)
118 # define SLPTRPORT B
119 # define SLPTRPIN (0x04)
120 # define TXCWPORT B
121 # define TXCWPIN (0x07)
122 # define USART 1
123 # define USARTVECT USART1_RX_vect
124 //# define TICKTIMER 3
125 //# define HAS_SPARE_TIMER // Not used
126 
127 
128 #elif RAVEN_REVISION == RAVEN_D
129 /* 1284 raven */
130 # define SSPORT B
131 # define SSPIN (0x04)
132 # define SPIPORT B
133 # define MOSIPIN (0x05)
134 # define MISOPIN (0x06)
135 # define SCKPIN (0x07)
136 # define RSTPORT B
137 # define RSTPIN (0x01)
138 # define IRQPORT D
139 # define IRQPIN (0x06)
140 # define SLPTRPORT B
141 # define SLPTRPIN (0x03)
142 # define TXCWPORT B
143 # define TXCWPIN (0x00)
144 # define USART 1
145 # define USARTVECT USART1_RX_vect
146 # define TICKTIMER 3
147 # define HAS_CW_MODE
148 # define HAS_SPARE_TIMER
149 
150 #elif RAVEN_REVISION == RAVENUSB_C
151 /* 1287USB raven */
152 # define SSPORT B
153 # define SSPIN (0x00)
154 # define SPIPORT B
155 # define MOSIPIN (0x02)
156 # define MISOPIN (0x03)
157 # define SCKPIN (0x01)
158 # define RSTPORT B
159 # define RSTPIN (0x05)
160 # define IRQPORT D
161 # define IRQPIN (0x04)
162 # define SLPTRPORT B
163 # define SLPTRPIN (0x04)
164 # define TXCWPORT B
165 # define TXCWPIN (0x07)
166 # define USART 1
167 # define USARTVECT USART1_RX_vect
168 # define TICKTIMER 3
169 # define HAS_CW_MODE
170 # define HAS_SPARE_TIMER
171 
172 #elif PLATFORM_TYPE == IRIS
173 /* 1281 IRIS */
174 # define SSPORT B
175 # define SSPIN (0x00)
176 # define SPIPORT B
177 # define MOSIPIN (0x02)
178 # define MISOPIN (0x03)
179 # define SCKPIN (0x01)
180 # define RSTPORT A
181 # define RSTPIN (0x06)
182 # define IRQPORT D
183 # define IRQPIN (0x04)
184 # define SLPTRPORT B
185 # define SLPTRPIN (0x07)
186 //# define TXCWPORT B
187 //# define TXCWPIN (0x07)
188 # define USART 1
189 # define USARTVECT USART1_RX_vect
190 //# define TICKTIMER 3
191 //# define HAS_SPARE_TIMER // Not used
192 #else
193 
194 #error "Platform undefined in hal.h"
195 
196 #endif
197 
198 /** \} */
199 
200 /**
201  * \name Macros used to generate read register names from platform-specific definitions of ports.
202  * \brief The various CAT macros (DDR, PORT, and PIN) are used to
203  * assign port/pin/DDR names to various macro variables. The
204  * variables are assigned based on the specific connections made in
205  * the hardware. For example TCCR(TICKTIMER,A) can be used in place of TCCR0A
206  * if TICKTIMER is defined as 0.
207  * \{
208  */
209 #define CAT(x, y) x##y
210 #define CAT2(x, y, z) x##y##z
211 #define DDR(x) CAT(DDR, x)
212 #define PORT(x) CAT(PORT, x)
213 #define PIN(x) CAT(PIN, x)
214 #define UCSR(num, let) CAT2(UCSR,num,let)
215 #define RXEN(x) CAT(RXEN,x)
216 #define TXEN(x) CAT(TXEN,x)
217 #define TXC(x) CAT(TXC,x)
218 #define RXC(x) CAT(RXC,x)
219 #define RXCIE(x) CAT(RXCIE,x)
220 #define UCSZ(x,y) CAT2(UCSZ,x,y)
221 #define UBRR(x,y) CAT2(UBRR,x,y)
222 #define UDRE(x) CAT(UDRE,x)
223 #define UDRIE(x) CAT(UDRIE,x)
224 #define UDR(x) CAT(UDR,x)
225 #define TCNT(x) CAT(TCNT,x)
226 #define TIMSK(x) CAT(TIMSK,x)
227 #define TCCR(x,y) CAT2(TCCR,x,y)
228 #define COM(x,y) CAT2(COM,x,y)
229 #define OCR(x,y) CAT2(OCR,x,y)
230 #define CS(x,y) CAT2(CS,x,y)
231 #define WGM(x,y) CAT2(WGM,x,y)
232 #define OCIE(x,y) CAT2(OCIE,x,y)
233 #define COMPVECT(x) CAT2(TIMER,x,_COMPA_vect)
234 #define UDREVECT(x) CAT2(USART,x,_UDRE_vect)
235 #define RXVECT(x) CAT2(USART,x,_RX_vect)
236 /** \} */
237 
238 /**
239  * \name Pin macros
240  * \brief These macros convert the platform-specific pin defines into names and functions
241  * that the source code can directly use.
242  * \{
243  */
244 #define SLP_TR SLPTRPIN /**< Pin number that corresponds to the SLP_TR pin. */
245 #define DDR_SLP_TR DDR( SLPTRPORT ) /**< Data Direction Register that corresponds to the port where SLP_TR is connected. */
246 #define PORT_SLP_TR PORT( SLPTRPORT ) /**< Port (Write Access) where SLP_TR is connected. */
247 #define PIN_SLP_TR PIN( SLPTRPORT ) /**< Pin (Read Access) where SLP_TR is connected. */
248 #define hal_set_slptr_high( ) ( PORT_SLP_TR |= ( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin high. */
249 #define hal_set_slptr_low( ) ( PORT_SLP_TR &= ~( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin low. */
250 #define hal_get_slptr( ) ( ( PIN_SLP_TR & ( 1 << SLP_TR ) ) >> SLP_TR ) /**< Read current state of the SLP_TR pin (High/Low). */
251 #define RST RSTPIN /**< Pin number that corresponds to the RST pin. */
252 #define DDR_RST DDR( RSTPORT ) /**< Data Direction Register that corresponds to the port where RST is */
253 #define PORT_RST PORT( RSTPORT ) /**< Port (Write Access) where RST is connected. */
254 #define PIN_RST PIN( RSTPORT ) /**< Pin (Read Access) where RST is connected. */
255 #define hal_set_rst_high( ) ( PORT_RST |= ( 1 << RST ) ) /**< This macro pulls the RST pin high. */
256 #define hal_set_rst_low( ) ( PORT_RST &= ~( 1 << RST ) ) /**< This macro pulls the RST pin low. */
257 #define hal_get_rst( ) ( ( PIN_RST & ( 1 << RST ) ) >> RST ) /**< Read current state of the RST pin (High/Low). */
258 #define HAL_SS_PIN SSPIN /**< The slave select pin. */
259 #define HAL_PORT_SPI PORT( SPIPORT ) /**< The SPI module is located on PORTB. */
260 #define HAL_DDR_SPI DDR( SPIPORT ) /**< Data Direction Register for PORTB. */
261 #define HAL_DD_SS SSPIN /**< Data Direction bit for SS. */
262 #define HAL_DD_SCK SCKPIN /**< Data Direction bit for SCK. */
263 #define HAL_DD_MOSI MOSIPIN /**< Data Direction bit for MOSI. */
264 #define HAL_DD_MISO MISOPIN /**< Data Direction bit for MISO. */
265 /** \} */
266 
267 
268 #define HAL_SS_HIGH( ) (HAL_PORT_SPI |= ( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS high. */
269 #define HAL_SS_LOW( ) (HAL_PORT_SPI &= ~( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS low. */
270 
271 /** \brief Macros defined for HAL_TIMER1.
272  *
273  * These macros are used to define the correct setupt of the AVR's Timer1, and
274  * to ensure that the hal_get_system_time function returns the system time in
275  * symbols (16 us ticks).
276  */
277 
278 #if ( F_CPU == 16000000UL )
279  #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS12 ) )
280  #define HAL_US_PER_SYMBOL ( 1 )
281  #define HAL_SYMBOL_MASK ( 0xFFFFffff )
282 #elif ( F_CPU == 8000000UL )
283  #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) )
284  #define HAL_US_PER_SYMBOL ( 2 )
285  #define HAL_SYMBOL_MASK ( 0x7FFFffff )
286 #elif ( F_CPU == 4000000UL )
287  #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) )
288  #define HAL_US_PER_SYMBOL ( 1 )
289  #define HAL_SYMBOL_MASK ( 0xFFFFffff )
290 #elif ( F_CPU == 1000000UL )
291  #define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) )
292  #define HAL_US_PER_SYMBOL ( 2 )
293  #define HAL_SYMBOL_MASK ( 0x7FFFffff )
294 #else
295  #error "Clock speed not supported."
296 #endif
297 
298 #if PLATFORM_TYPE == ZIGBIT
299 // IRQ E5 for Zigbit example
300 #define RADIO_VECT INT5_vect
301 #define HAL_ENABLE_RADIO_INTERRUPT( ) { ( EIMSK |= ( 1 << INT5 ) ) ; EICRB |= 0x0C ; PORTE &= ~(1<<PE5); DDRE &= ~(1<<DDE5); }
302 #define HAL_DISABLE_RADIO_INTERRUPT( ) ( EIMSK &= ~( 1 << INT5 ) )
303 #else
304 #define RADIO_VECT TIMER1_CAPT_vect
305 #define HAL_ENABLE_RADIO_INTERRUPT( ) ( TIMSK1 |= ( 1 << ICIE1 ) )
306 #define HAL_DISABLE_RADIO_INTERRUPT( ) ( TIMSK1 &= ~( 1 << ICIE1 ) )
307 #endif
308 
309 #define HAL_ENABLE_OVERFLOW_INTERRUPT( ) ( TIMSK1 |= ( 1 << TOIE1 ) )
310 #define HAL_DISABLE_OVERFLOW_INTERRUPT( ) ( TIMSK1 &= ~( 1 << TOIE1 ) )
311 
312 /** This macro will protect the following code from interrupts.*/
313 #define AVR_ENTER_CRITICAL_REGION( ) {uint8_t volatile saved_sreg = SREG; cli( )
314 
315 /** This macro must always be used in conjunction with AVR_ENTER_CRITICAL_REGION
316  so that interrupts are enabled again.*/
317 #define AVR_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg;}
318 
319 
320 /** \brief Enable the interrupt from the radio transceiver.
321  */
322 #define hal_enable_trx_interrupt( ) HAL_ENABLE_RADIO_INTERRUPT( )
323 
324 /** \brief Disable the interrupt from the radio transceiver.
325  *
326  * \retval 0 if the pin is low, 1 if the pin is high.
327  */
328 #define hal_disable_trx_interrupt( ) HAL_DISABLE_RADIO_INTERRUPT( )
329 /*============================ TYPDEFS =======================================*/
330 /*============================ PROTOTYPES ====================================*/
331 /*============================ MACROS ========================================*/
332 /** \name Macros for radio operation.
333  * \{
334  */
335 #define HAL_BAT_LOW_MASK ( 0x80 ) /**< Mask for the BAT_LOW interrupt. */
336 #define HAL_TRX_UR_MASK ( 0x40 ) /**< Mask for the TRX_UR interrupt. */
337 #define HAL_TRX_END_MASK ( 0x08 ) /**< Mask for the TRX_END interrupt. */
338 #define HAL_RX_START_MASK ( 0x04 ) /**< Mask for the RX_START interrupt. */
339 #define HAL_PLL_UNLOCK_MASK ( 0x02 ) /**< Mask for the PLL_UNLOCK interrupt. */
340 #define HAL_PLL_LOCK_MASK ( 0x01 ) /**< Mask for the PLL_LOCK interrupt. */
341 
342 #define HAL_MIN_FRAME_LENGTH ( 0x03 ) /**< A frame should be at least 3 bytes. */
343 #define HAL_MAX_FRAME_LENGTH ( 0x7F ) /**< A frame should no more than 127 bytes. */
344 /** \} */
345 /*============================ TYPDEFS =======================================*/
346 /** \struct hal_rx_frame_t
347  * \brief This struct defines the rx data container.
348  *
349  * \see hal_frame_read
350  */
351 typedef struct{
352  uint8_t length; /**< Length of frame. */
353  uint8_t data[ HAL_MAX_FRAME_LENGTH ]; /**< Actual frame data. */
354  uint8_t lqi; /**< LQI value for received frame. */
355  bool crc; /**< Flag - did CRC pass for received frame? */
357 
358 /** RX_START event handler callback type. Is called with timestamp in IEEE 802.15.4 symbols and frame length. See hal_set_rx_start_event_handler(). */
359 typedef void (*hal_rx_start_isr_event_handler_t)(uint32_t const isr_timestamp, uint8_t const frame_length);
360 
361 /** RRX_END event handler callback type. Is called with timestamp in IEEE 802.15.4 symbols and frame length. See hal_set_trx_end_event_handler(). */
362 typedef void (*hal_trx_end_isr_event_handler_t)(uint32_t const isr_timestamp);
363 
364 typedef void (*rx_callback_t) (uint16_t data);
365 
366 /*============================ PROTOTYPES ====================================*/
367 void hal_init( void );
368 
369 void hal_reset_flags( void );
370 uint8_t hal_get_bat_low_flag( void );
371 void hal_clear_bat_low_flag( void );
372 
374 void hal_set_trx_end_event_handler( hal_trx_end_isr_event_handler_t trx_end_callback_handle );
376 
380 
381 uint8_t hal_get_pll_lock_flag( void );
382 void hal_clear_pll_lock_flag( void );
383 
384 uint8_t hal_register_read( uint8_t address );
385 void hal_register_write( uint8_t address, uint8_t value );
386 uint8_t hal_subregister_read( uint8_t address, uint8_t mask, uint8_t position );
387 void hal_subregister_write( uint8_t address, uint8_t mask, uint8_t position,
388  uint8_t value );
389 void hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback);
390 void hal_frame_write( uint8_t *write_buffer, uint8_t length );
391 void hal_sram_read( uint8_t address, uint8_t length, uint8_t *data );
392 void hal_sram_write( uint8_t address, uint8_t length, uint8_t *data );
393 
394 #endif
395 /** @} */
396 /*EOF*/
void hal_reset_flags(void)
This function reset the interrupt flags and interrupt event handlers (Callbacks) to their default val...
Definition: hal.c:163
uint8_t hal_get_bat_low_flag(void)
This function returns the current value of the BAT_LOW flag.
Definition: hal.c:186
uint8_t lqi
LQI value for received frame.
Definition: hal.h:354
uint8_t hal_register_read(uint8_t address)
This function reads data from one of the radio transceiver&#39;s registers.
Definition: hal.c:304
void hal_clear_pll_lock_flag(void)
This function clears the PLL_LOCK flag.
Definition: hal.c:286
void hal_clear_bat_low_flag(void)
This function clears the BAT_LOW flag.
Definition: hal.c:195
hal_trx_end_isr_event_handler_t hal_get_trx_end_event_handler(void)
This function is used to set new TRX_END event handler, overriding old handler reference.
Definition: hal.c:207
void hal_clear_rx_start_event_handler(void)
Remove event handler reference.
Definition: hal.c:262
uint8_t length
Length of frame.
Definition: hal.h:352
uint8_t hal_get_pll_lock_flag(void)
This function returns the current value of the PLL_LOCK flag.
Definition: hal.c:277
uint8_t hal_subregister_read(uint8_t address, uint8_t mask, uint8_t position)
This function reads the value of a specific subregister.
Definition: hal.c:377
void hal_init(void)
This function initializes the Hardware Abstraction Layer.
Definition: hal.c:133
This struct defines the rx data container.
Definition: hal.h:351
void hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position, uint8_t value)
This function writes a new value to one of the radio transceiver&#39;s subregisters.
Definition: hal.c:400
void hal_sram_read(uint8_t address, uint8_t length, uint8_t *data)
Read SRAM.
Definition: hal.c:558
bool crc
Flag - did CRC pass for received frame?
Definition: hal.h:355
void hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback)
This function will upload a frame from the radio transceiver&#39;s frame buffer.
Definition: hal.c:429
void(* hal_trx_end_isr_event_handler_t)(uint32_t const isr_timestamp)
RRX_END event handler callback type.
Definition: hal.h:362
void hal_sram_write(uint8_t address, uint8_t length, uint8_t *data)
Write SRAM.
Definition: hal.c:597
void hal_frame_write(uint8_t *write_buffer, uint8_t length)
This function will download a frame to the radio transceiver&#39;s frame buffer.
Definition: hal.c:516
void hal_set_rx_start_event_handler(hal_rx_start_isr_event_handler_t rx_start_callback_handle)
This function is used to set new RX_START event handler, overriding old handler reference.
Definition: hal.c:251
hal_rx_start_isr_event_handler_t hal_get_rx_start_event_handler(void)
This function returns the active RX_START event handler.
Definition: hal.c:241
#define HAL_MAX_FRAME_LENGTH
A frame should no more than 127 bytes.
Definition: hal.h:343
void hal_clear_trx_end_event_handler(void)
Remove event handler reference.
Definition: hal.c:228
void hal_register_write(uint8_t address, uint8_t value)
This function writes a new value to one of the radio transceiver&#39;s registers.
Definition: hal.c:342
void hal_set_trx_end_event_handler(hal_trx_end_isr_event_handler_t trx_end_callback_handle)
This function is used to set new TRX_END event handler, overriding old handler reference.
Definition: hal.c:217
void(* hal_rx_start_isr_event_handler_t)(uint32_t const isr_timestamp, uint8_t const frame_length)
RX_START event handler callback type.
Definition: hal.h:359