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  * David Kopf dak664@embarqmail.com
13  * Ivan Delamer delamer@ieee.com
14  *
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are met:
19  *
20  * * Redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer.
22  * * Redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in
24  * the documentation and/or other materials provided with the
25  * distribution.
26  * * Neither the name of the copyright holders nor the names of
27  * contributors may be used to endorse or promote products derived
28  * from this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40  * POSSIBILITY OF SUCH DAMAGE.
41  */
42 
43 /**
44  * \addtogroup hal
45  * @{
46  */
47 
48 /**
49  * \file
50  * \brief This file contains low-level radio driver code.
51  *
52 */
53 
54 #ifndef HAL_AVR_H
55 #define HAL_AVR_H
56 /*============================ INCLUDE =======================================*/
57 #include <stdint.h>
58 #include <stdbool.h>
59 //#include <util/crc16.h>
60 #include "contiki-conf.h"
61 /*============================ MACROS ========================================*/
62 
63 /** \name This is the list of pin configurations needed for a given platform.
64  * \brief Change these values to port to other platforms.
65  * \{
66  */
67 /* Define all possible platform types/revisions here. */
68 // Don't use zero, it will match if undefined!
69 // RAVEN_D : Raven kit with LCD display
70 // RAVENUSB_C : used for RZRAVEN USB key
71 // RCB_B : RZ200 kit from Atmel based on 1281V
72 // ZIGBIT : Zigbit module from Meshnetics
73 // ATMEGA128RFA1 : Bare chip with internal radio
74 // IRIS : IRIS Mote from MEMSIC
75 #define RAVENUSB_C 1
76 #define RAVEN_D 2
77 #define RCB_B 3
78 #define ZIGBIT 4
79 #define IRIS 5
80 #define ATMEGA128RFA1 6
81 #define ATMEGA256RFR2 7
82 
83 #if PLATFORM_TYPE == RCB_B
84 /* 1281 rcb */
85 # define SSPORT B
86 # define SSPIN (0x00)
87 # define SPIPORT B
88 # define MOSIPIN (0x02)
89 # define MISOPIN (0x03)
90 # define SCKPIN (0x01)
91 # define RSTPORT B
92 # define RSTPIN (0x05)
93 # define IRQPORT D
94 # define IRQPIN (0x04)
95 # define SLPTRPORT B
96 # define SLPTRPIN (0x04)
97 
98 #elif PLATFORM_TYPE == ZIGBIT
99 /* 1281V Zigbit */
100 # define SSPORT B
101 # define SSPIN (0x00)
102 # define SPIPORT B
103 # define MOSIPIN (0x02)
104 # define MISOPIN (0x03)
105 # define SCKPIN (0x01)
106 # define RSTPORT A
107 # define RSTPIN (0x07)
108 # define IRQPORT E
109 # define IRQPIN (0x05)
110 # define SLPTRPORT B
111 # define SLPTRPIN (0x04)
112 
113 
114 #elif PLATFORM_TYPE == RAVEN_D
115 /* 1284 raven */
116 # define SSPORT B
117 # define SSPIN (0x04)
118 # define SPIPORT B
119 # define MOSIPIN (0x05)
120 # define MISOPIN (0x06)
121 # define SCKPIN (0x07)
122 # define RSTPORT B
123 # define RSTPIN (0x01)
124 # define IRQPORT D
125 # define IRQPIN (0x06)
126 # define SLPTRPORT B
127 # define SLPTRPIN (0x03)
128 
129 #elif PLATFORM_TYPE == RAVENUSB_C
130 /* 1287USB raven */
131 # define SSPORT B
132 # define SSPIN (0x00)
133 # define SPIPORT B
134 # define MOSIPIN (0x02)
135 # define MISOPIN (0x03)
136 # define SCKPIN (0x01)
137 # define RSTPORT B
138 # define RSTPIN (0x05)
139 # define IRQPORT D
140 # define IRQPIN (0x04)
141 # define SLPTRPORT B
142 # define SLPTRPIN (0x04)
143 
144 #elif PLATFORM_TYPE == ATMEGA128RFA1
145 /* ATmega1281 with internal AT86RF231 radio */
146 # define SLPTRPORT TRXPR
147 # define SLPTRPIN 1
148 
149 #elif PLATFORM_TYPE == ATMEGA256RFR2
150 /* ATmega1281 with internal AT86RF231 radio */
151 # define SLPTRPORT TRXPR
152 # define SLPTRPIN 1
153 
154 #elif CONTIKI_TARGET_MULLE
155 /* mulle 5.2 (TODO: move to platform specific) */
156 # define SSPORT 3
157 # define SSPIN 5
158 # define MOSIPORT 1
159 # define MOSIPIN 1
160 # define MISOPORT 1
161 # define MISOPIN 0
162 # define SCKPORT 3
163 # define SCKPIN 3
164 # define RSTPORT 4
165 # define RSTPIN 3
166 # define IRQPORT 8
167 # define IRQPIN 3
168 # define SLPTRPORT 0
169 # define SLPTRPIN 7
170 
171 #elif PLATFORM_TYPE == IRIS
172 /* 1281 IRIS */
173 # define SSPORT B
174 # define SSPIN (0x00)
175 # define SPIPORT B
176 # define MOSIPIN (0x02)
177 # define MISOPIN (0x03)
178 # define SCKPIN (0x01)
179 # define RSTPORT A
180 # define RSTPIN (0x06)
181 # define IRQPORT D
182 # define IRQPIN (0x04)
183 # define SLPTRPORT B
184 # define SLPTRPIN (0x07)
185 #else
186 
187 #error "PLATFORM_TYPE undefined in hal.h"
188 
189 #endif
190 
191 /* For architectures that have all SPI signals on the same port */
192 #ifndef SSPORT
193 #define SSPORT SPIPORT
194 #endif
195 
196 #ifndef SCKPORT
197 #define SCKPORT SPIPORT
198 #endif
199 
200 #ifndef MOSIPORT
201 #define MOSIPORT SPIPORT
202 #endif
203 
204 #ifndef MISOPORT
205 #define MISOPORT SPIPORT
206 #endif
207 
208 /** \} */
209 
210 /**
211  * \name Macros used to generate read register names from platform-specific definitions of ports.
212  * \brief The various CAT macros (DDR, PORT, and PIN) are used to
213  * assign port/pin/DDR names to various macro variables. The
214  * variables are assigned based on the specific connections made in
215  * the hardware. For example TCCR(TICKTIMER,A) can be used in place of TCCR0A
216  * if TICKTIMER is defined as 0.
217  * \{
218  */
219 #if defined(__AVR__)
220 #define CAT(x, y) x##y
221 #define DDR(x) CAT(DDR, x)
222 #define PORT(x) CAT(PORT, x)
223 #define PIN(x) CAT(PIN, x)
224 #endif
225 
226 /* TODO: Move to CPU specific */
227 #if defined(CONTIKI_TARGET_MULLE)
228 #define CAT(x, y) x##y.BYTE
229 #define DDR(x) CAT(PD, x)
230 #define PORT(x) CAT(P, x)
231 #define PIN(x) CAT(P, x)
232 #endif
233 
234 /** \} */
235 
236 /**
237  * \name Pin macros
238  * \brief These macros convert the platform-specific pin defines into names and functions
239  * that the source code can directly use.
240  * \{
241  */
242 #if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__)
243 
244 #define hal_set_rst_low( ) ( TRXPR &= ~( 1 << TRXRST ) ) /**< This macro pulls the RST pin low. */
245 #define hal_set_rst_high( ) ( TRXPR |= ( 1 << TRXRST ) ) /**< This macro pulls the RST pin high. */
246 #define hal_set_slptr_high( ) ( TRXPR |= ( 1 << SLPTR ) ) /**< This macro pulls the SLP_TR pin high. */
247 #define hal_set_slptr_low( ) ( TRXPR &= ~( 1 << SLPTR ) ) /**< This macro pulls the SLP_TR pin low. */
248 #define hal_get_slptr( ) ( TRXPR & ( 1 << SLPTR ) ) /**< Read current state of the SLP_TR pin (High/Low). */
249 
250 #else
251 #define SLP_TR SLPTRPIN /**< Pin number that corresponds to the SLP_TR pin. */
252 #define DDR_SLP_TR DDR( SLPTRPORT ) /**< Data Direction Register that corresponds to the port where SLP_TR is connected. */
253 #define PORT_SLP_TR PORT( SLPTRPORT ) /**< Port (Write Access) where SLP_TR is connected. */
254 #define PIN_SLP_TR PIN( SLPTRPORT ) /**< Pin (Read Access) where SLP_TR is connected. */
255 #define hal_set_slptr_high( ) ( PORT_SLP_TR |= ( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin high. */
256 #define hal_set_slptr_low( ) ( PORT_SLP_TR &= ~( 1 << SLP_TR ) ) /**< This macro pulls the SLP_TR pin low. */
257 #define hal_get_slptr( ) ( PIN_SLP_TR & ( 1 << SLP_TR ) ) /**< Read current state of the SLP_TR pin (High/Low). */
258 #define RST RSTPIN /**< Pin number that corresponds to the RST pin. */
259 #define DDR_RST DDR( RSTPORT ) /**< Data Direction Register that corresponds to the port where RST is */
260 #define PORT_RST PORT( RSTPORT ) /**< Port (Write Access) where RST is connected. */
261 #define PIN_RST PIN( RSTPORT /* BUG? */) /**< Pin (Read Access) where RST is connected. */
262 #define hal_set_rst_high( ) ( PORT_RST |= ( 1 << RST ) ) /**< This macro pulls the RST pin high. */
263 #define hal_set_rst_low( ) ( PORT_RST &= ~( 1 << RST ) ) /**< This macro pulls the RST pin low. */
264 #define hal_get_rst( ) ( ( PIN_RST & ( 1 << RST ) ) >> RST ) /**< Read current state of the RST pin (High/Low). */
265 #define HAL_SS_PIN SSPIN /**< The slave select pin. */
266 #define HAL_SCK_PIN SCKPIN /**< Data bit for SCK. */
267 #define HAL_MOSI_PIN MOSIPIN
268 #define HAL_MISO_PIN MISOPIN
269 #define HAL_PORT_SPI PORT( SPIPORT ) /**< The SPI module is located on PORTB. */
270 #define HAL_PORT_SS PORT( SSPORT )
271 #define HAL_PORT_SCK PORT( SCKPORT )
272 #define HAL_PORT_MOSI PORT( MOSIPORT ) /**< The SPI module uses GPIO might be split on different ports. */
273 #define HAL_PORT_MISO PORT( MISOPORT ) /**< The SPI module uses GPIO might be split on different ports. */
274 #define HAL_DDR_SPI DDR( SPIPORT ) /**< Data Direction Register for PORTB. */
275 #define HAL_DDR_SS DDR( SSPORT ) /**< Data Direction Register for MISO GPIO pin. */
276 #define HAL_DDR_SCK DDR( SCKPORT ) /**< Data Direction Register for MISO GPIO pin. */
277 #define HAL_DDR_MOSI DDR( MOSIPORT ) /**< Data Direction Register for MISO GPIO pin. */
278 #define HAL_DDR_MISO DDR( MISOPORT ) /**< Data Direction Register for MOSI GPIO pin. */
279 #define HAL_DD_SS SSPIN /**< Data Direction bit for SS. */
280 #define HAL_DD_SCK SCKPIN /**< Data Direction bit for SCK. */
281 #define HAL_DD_MOSI MOSIPIN /**< Data Direction bit for MOSI. */
282 #define HAL_DD_MISO MISOPIN /**< Data Direction bit for MISO. */
283 #endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) */
284 
285 /** \} */
286 
287 
288 #define HAL_SS_HIGH( ) (HAL_PORT_SS |= ( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS high. */
289 #define HAL_SS_LOW( ) (HAL_PORT_SS &= ~( 1 << HAL_SS_PIN )) /**< MACRO for pulling SS low. */
290 
291 #if defined(__AVR__)
292 
293 #if PLATFORM_TYPE == ZIGBIT
294 // IRQ E5 for Zigbit example
295 #define RADIO_VECT INT5_vect
296 #define HAL_ENABLE_RADIO_INTERRUPT( ) { ( EIMSK |= ( 1 << INT5 ) ) ; EICRB |= 0x0C ; PORTE &= ~(1<<PE5); DDRE &= ~(1<<DDE5); }
297 #define HAL_DISABLE_RADIO_INTERRUPT( ) ( EIMSK &= ~( 1 << INT5 ) )
298 #else
299 #define RADIO_VECT TIMER1_CAPT_vect
300 // Raven and Jackdaw
301 #define HAL_ENABLE_RADIO_INTERRUPT( ) { TCCR1B = ( 1 << ICES1 ) | ( 1 << CS10 ); TIFR1 |= (1 << ICF1); TIMSK1 |= ( 1 << ICIE1 ) ; }
302 #define HAL_DISABLE_RADIO_INTERRUPT( ) ( TIMSK1 &= ~( 1 << ICIE1 ) )
303 #endif
304 
305 #define HAL_ENABLE_OVERFLOW_INTERRUPT( ) ( TIMSK1 |= ( 1 << TOIE1 ) )
306 #define HAL_DISABLE_OVERFLOW_INTERRUPT( ) ( TIMSK1 &= ~( 1 << TOIE1 ) )
307 
308 /** This macro will protect the following code from interrupts.*/
309 #define HAL_ENTER_CRITICAL_REGION( ) {uint8_t volatile saved_sreg = SREG; cli( )
310 
311 /** This macro must always be used in conjunction with HAL_ENTER_CRITICAL_REGION
312  so that interrupts are enabled again.*/
313 #define HAL_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg;}
314 
315 #else /* MULLE */
316 
317 #define HAL_ENABLE_RADIO_INTERRUPT( ) ( INT1IC.BYTE |= 1 )
318 #define HAL_DISABLE_RADIO_INTERRUPT( ) ( INT1IC.BYTE &= ~(1) )
319 
320 #define HAL_ENABLE_OVERFLOW_INTERRUPT( ) ( TB4IC.BYTE = 1 )
321 #define HAL_DISABLE_OVERFLOW_INTERRUPT( ) ( TB4IC.BYTE = 0 )
322 
323 /** This macro will protect the following code from interrupts.*/
324 #define HAL_ENTER_CRITICAL_REGION( ) MULLE_ENTER_CRITICAL_REGION( )
325 
326 /** This macro must always be used in conjunction with HAL_ENTER_CRITICAL_REGION
327  so that interrupts are enabled again.*/
328 #define HAL_LEAVE_CRITICAL_REGION( ) MULLE_LEAVE_CRITICAL_REGION( )
329 
330 #endif /* !__AVR__ */
331 
332 
333 /** \brief Enable the interrupt from the radio transceiver.
334  */
335 #define hal_enable_trx_interrupt( ) HAL_ENABLE_RADIO_INTERRUPT( )
336 
337 /** \brief Disable the interrupt from the radio transceiver.
338  *
339  * \retval 0 if the pin is low, 1 if the pin is high.
340  */
341 #define hal_disable_trx_interrupt( ) HAL_DISABLE_RADIO_INTERRUPT( )
342 /*============================ TYPDEFS =======================================*/
343 /*============================ PROTOTYPES ====================================*/
344 /*============================ MACROS ========================================*/
345 /** \name Macros for radio operation.
346  * \{
347  */
348 #define HAL_BAT_LOW_MASK ( 0x80 ) /**< Mask for the BAT_LOW interrupt. */
349 #define HAL_TRX_UR_MASK ( 0x40 ) /**< Mask for the TRX_UR interrupt. */
350 #define HAL_TRX_END_MASK ( 0x08 ) /**< Mask for the TRX_END interrupt. */
351 #define HAL_RX_START_MASK ( 0x04 ) /**< Mask for the RX_START interrupt. */
352 #define HAL_PLL_UNLOCK_MASK ( 0x02 ) /**< Mask for the PLL_UNLOCK interrupt. */
353 #define HAL_PLL_LOCK_MASK ( 0x01 ) /**< Mask for the PLL_LOCK interrupt. */
354 
355 #define HAL_MIN_FRAME_LENGTH ( 0x03 ) /**< A frame should be at least 3 bytes. */
356 #define HAL_MAX_FRAME_LENGTH ( 0x7F ) /**< A frame should no more than 127 bytes. */
357 /** \} */
358 /*============================ TYPDEFS =======================================*/
359 /** \struct hal_rx_frame_t
360  * \brief This struct defines the rx data container.
361  *
362  * \see hal_frame_read
363  */
364 typedef struct{
365  uint8_t length; /**< Length of frame. */
366  uint8_t data[ HAL_MAX_FRAME_LENGTH ]; /**< Actual frame data. */
367  uint8_t lqi; /**< LQI value for received frame. */
368  bool crc; /**< Flag - did CRC pass for received frame? */
370 
371 
372 /*============================ PROTOTYPES ====================================*/
373 void hal_init( void );
374 
375 /* Hack for atmega128rfa1 with integrated radio. Access registers directly, not through SPI */
376 #if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__)
377 //#define hal_register_read(address) _SFR_MEM8((uint16_t)address)
378 #define hal_register_read(address) address
379 uint8_t hal_subregister_read( uint16_t address, uint8_t mask, uint8_t position );
380 void hal_subregister_write( uint16_t address, uint8_t mask, uint8_t position,
381  uint8_t value );
382 
383 //#define hal_register_write(address, value) _SFR_MEM8((uint16_t)address)=value
384 #define hal_register_write(address, value) address=value
385 //#define hal_subregister_read( address, mask, position ) (_SFR_MEM8((uint16_t)address)&mask)>>position
386 //#define hal_subregister_read1( address, mask, position ) (address&mask)>>position
387 //#define hal_subregister_write( address, mask, position, value ) address=(address<<position)&mask
388 #else
389 uint8_t hal_register_read( uint8_t address );
390 void hal_register_write( uint8_t address, uint8_t value );
391 uint8_t hal_subregister_read( uint8_t address, uint8_t mask, uint8_t position );
392 void hal_subregister_write( uint8_t address, uint8_t mask, uint8_t position,
393  uint8_t value );
394 #endif
395 
396 
397 
398 void hal_frame_read(hal_rx_frame_t *rx_frame);
399 void hal_frame_write( uint8_t *write_buffer, uint8_t length );
400 void hal_sram_read( uint8_t address, uint8_t length, uint8_t *data );
401 void hal_sram_write( uint8_t address, uint8_t length, uint8_t *data );
402 /* Number of receive buffers in RAM. */
403 #ifndef RF230_CONF_RX_BUFFERS
404 #define RF230_CONF_RX_BUFFERS 1
405 #endif
406 
407 #endif
408 /** @} */
409 /*EOF*/
void hal_init(void)
This function initializes the Hardware Abstraction Layer.
Definition: hal.c:133
void hal_register_write(uint8_t address, uint8_t value)
This function writes a new value to one of the radio transceiver's registers.
Definition: hal.c:342
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_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's subregisters.
Definition: hal.c:400
#define HAL_MAX_FRAME_LENGTH
A frame should no more than 127 bytes.
Definition: hal.h:356
uint8_t hal_register_read(uint8_t address)
This function reads data from one of the radio transceiver's registers.
Definition: hal.c:304
void hal_frame_read(hal_rx_frame_t *rx_frame)
Transfer a frame from the radio transceiver to a RAM buffer.
Definition: halbb.c:399
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's frame buffer.
Definition: hal.c:516
void hal_sram_read(uint8_t address, uint8_t length, uint8_t *data)
Read SRAM.
Definition: hal.c:558
This struct defines the rx data container.
Definition: hal.h:351