transceiver.h

Go to the documentation of this file.
00001 /* Copyright (c) 2007 Axel Wachtler
00002    All rights reserved.
00003 
00004    Redistribution and use in source and binary forms, with or without
00005    modification, are permitted provided that the following conditions
00006    are met:
00007 
00008    * Redistributions of source code must retain the above copyright
00009      notice, this list of conditions and the following disclaimer.
00010    * Redistributions in binary form must reproduce the above copyright
00011      notice, this list of conditions and the following disclaimer in the
00012      documentation and/or other materials provided with the distribution.
00013    * Neither the name of the authors nor the names of its contributors
00014      may be used to endorse or promote products derived from this software
00015      without specific prior written permission.
00016 
00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027    POSSIBILITY OF SUCH DAMAGE. */
00028 
00029 /* $Id: transceiver_8h_source.html,v 1.1.1.4 2013/04/09 21:12:16 awachtler Exp $ */
00035 #ifndef TRANSCEIVER_H
00036 #define TRANSCEIVER_H
00037 
00043 /* === Includes ============================================================== */
00044 #include "board.h"
00045 
00046 #if RADIO_TYPE == RADIO_AT86RF230 || defined(DOXYGEN)
00047 # include "at86rf230a.h"
00048 #elif RADIO_TYPE == RADIO_AT86RF230B
00049 # include "at86rf230b.h"
00050 #elif RADIO_TYPE == RADIO_AT86RF231
00051 # include "at86rf231.h"
00052 #elif RADIO_TYPE == RADIO_AT86RF212
00053 # include "at86rf212.h"
00054 #elif RADIO_TYPE == RADIO_AT86RF232
00055 # include "at86rf232.h"
00056 #elif RADIO_TYPE == RADIO_AT86RF233
00057 # include "at86rf233.h"
00058 #elif RADIO_TYPE == RADIO_ATMEGA128RFA1_A ||\
00059       RADIO_TYPE == RADIO_ATMEGA128RFA1_B ||\
00060       RADIO_TYPE == RADIO_ATMEGA128RFA1_C ||\
00061       RADIO_TYPE == RADIO_ATMEGA128RFA1_D
00062 # include "atmega_rfa1.h"
00063 #else
00064 # error "RADIO_TYPE is not defined or wrong"
00065 #endif
00066 #include <stdbool.h>
00067 
00068 /* === Externals ============================================================= */
00069 
00070 /* === Types ================================================================= */
00071 
00072 #if defined(DOXYGEN)
00073 
00074     /* this types are defined in at86rfXXX.{h,txt} in order
00075        to provide a radio abstraction */
00076 
00079     typedef uint8_t trx_ramaddr_t;
00080 
00083     typedef uint8_t trx_regval_t;
00084 
00087     typedef uint8_t trx_regaddr_t;
00088 
00089 #endif
00090 
00093 typedef void (*trx_irq_handler_t)(uint8_t cause);
00094 
00095 typedef enum
00096 {
00097    CFG_FLASH,
00098    CFG_EEPROM,
00099    CFG_NONE
00100 } trx_cfg_t;
00101 
00102 /* === Macros ================================================================ */
00103 /* error codes */
00105 #define TRX_OK        (0)
00106 
00107 #define TRX_INIT_FAIL (1)
00108 
00109 #define TRX_PLL_FAIL  (2)
00110 
00111 #define INVALID_PART_NUM (2)  
00112 #define INVALID_REV_NUM  (1)  
00114 /* Data Rate macros, generated by python Tools/cmdhash.py  `cat rates.txt` */
00115 #define BPSK20 (0x52)
00116 #define BPSK20_STR "BPSK20"
00117 #define BPSK40 (0x92)
00118 #define BPSK40_STR "BPSK40"
00119 #define OQPSK100 (0x90)
00120 #define OQPSK100_STR "OQPSK100"
00121 #define OQPSK200 (0x93)
00122 #define OQPSK200_STR "OQPSK200"
00123 #define OQPSK250 (0x33)
00124 #define OQPSK250_STR "OQPSK250"
00125 #define OQPSK400 (0x95)
00126 #define OQPSK400_STR "OQPSK400"
00127 #define OQPSK500 (0x94)
00128 #define OQPSK500_STR "OQPSK500"
00129 #define OQPSK1000 (0x34)
00130 #define OQPSK1000_STR "OQPSK1000"
00131 #define OQPSK2000 (0x54)
00132 #define OQPSK2000_STR "OQPSK2000"
00133 
00134 #define RATE_NONE (0xFF)
00135 
00137 #ifndef MAX_FRAME_SIZE
00138 # define MAX_FRAME_SIZE (127)
00139 #endif
00140 
00141 /* channel handling */
00142 #define TRX_NEXT_CHANNEL(x) ((channel_t)(x+1) > TRX_MAX_CHANNEL ? TRX_MAX_CHANNEL : x+1)
00143 #define TRX_PREV_CHANNEL(x) ((channel_t)(x-1) < TRX_MIN_CHANNEL ? TRX_MIN_CHANNEL : x-1)
00144 #define TRX_NEXT_CHANNEL_WRAP(x) ((channel_t)(x+1) > TRX_MAX_CHANNEL ? TRX_MIN_CHANNEL : x+1 )
00145 #define TRX_PREV_CHANNEL_WRAP(x) ((channel_t)(x-1) < TRX_MIN_CHANNEL ? TRX_MAX_CHANNEL : x-1 )
00146 
00147 
00148 #if defined (SR_MASK_AMI) || defined(DOXYGEN)
00149 
00150 # define TRX_IRQ_AMI_EI() trx_bit_write(SR_MASK_AMI, 1);
00151 
00152 # define TRX_IRQ_AMI_DI() trx_bit_write(SR_MASK_AMI, 0);
00153 #endif
00154 
00155 #if defined (SR_MASK_BAT_LOW) || defined(DOXYGEN)
00156 
00157 # define TRX_IRQ_BAT_LOW_EI() trx_bit_write(SR_MASK_BAT_LOW, 1);
00158 
00159 # define TRX_IRQ_BAT_LOW_DI() trx_bit_write(SR_MASK_BAT_LOW, 0);
00160 #endif
00161 
00162 #if defined (SR_MASK_CCA_ED_READY) || defined(DOXYGEN)
00163 
00164 # define TRX_IRQ_CCA_ED_READY_EI() trx_bit_write(SR_MASK_CCA_ED_READY, 1);
00165 
00166 # define TRX_IRQ_CCA_ED_READY_DI() trx_bit_write(SR_MASK_CCA_ED_READY, 0);
00167 #endif
00168 
00169 #if defined (SR_MASK_PLL_UNLOCK) || defined(DOXYGEN)
00170 
00171 # define TRX_IRQ_PLL_UNLOCK_EI() trx_bit_write(SR_MASK_PLL_UNLOCK, 1);
00172 
00173 # define TRX_IRQ_PLL_UNLOCK_DI() trx_bit_write(SR_MASK_PLL_UNLOCK, 0);
00174 #endif
00175 
00176 #if defined (SR_MASK_RX_START) || defined(DOXYGEN)
00177 
00178 # define TRX_IRQ_RX_START_EI() trx_bit_write(SR_MASK_RX_START, 1);
00179 
00180 # define TRX_IRQ_RX_START_DI() trx_bit_write(SR_MASK_RX_START, 0);
00181 #endif
00182 
00183 #if defined (SR_MASK_TRX_IRQ_END) || defined(DOXYGEN)
00184 
00185 # define TRX_IRQ_TRX_IRQ_END_EI() trx_bit_write(SR_MASK_TRX_IRQ_END, 1);
00186 
00187 # define TRX_IRQ_TRX_IRQ_END_DI() trx_bit_write(SR_MASK_TRX_IRQ_END, 0);
00188 #endif
00189 
00190 #if defined (SR_MASK_TRX_IRQ_START) || defined(DOXYGEN)
00191 
00192 # define TRX_IRQ_TRX_IRQ_START_EI() trx_bit_write(SR_MASK_TRX_IRQ_START, 1);
00193 
00194 # define TRX_IRQ_TRX_IRQ_START_DI() trx_bit_write(SR_MASK_TRX_IRQ_START, 0);
00195 #endif
00196 
00197 #if defined (SR_MASK_UR) || defined(DOXYGEN)
00198 
00199 # define TRX_IRQ_UR_EI() trx_bit_write(SR_MASK_UR, 1);
00200 
00201 # define TRX_IRQ_UR_DI() trx_bit_write(SR_MASK_UR, 0);
00202 #endif
00203 
00204 /* === Prototypes ============================================================ */
00205 #ifdef __cplusplus
00206 extern "C" {
00207 #endif
00208 
00209 #if !defined(TRX_IF_RFA1)
00210 
00219 void trx_io_init (uint8_t spirate);
00220 #else  /* RFA1 */
00221 #define trx_io_init(dummy) do { /* dummy macro */ } while (0)
00222 #endif
00223 
00224 
00227 void trx_set_irq_handler(trx_irq_handler_t irqhandler);
00228 
00236 void trx_reg_write(trx_regaddr_t addr, trx_regval_t val);
00237 
00246 uint8_t trx_reg_read(trx_regaddr_t addr);
00247 
00248 
00249 
00265 trx_regval_t trx_bit_read(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos);
00266 
00267 
00284 void trx_bit_write(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos, trx_regval_t value);
00285 
00296 void trx_frame_write(uint8_t length, uint8_t *data);
00297 
00309 uint8_t trx_frame_read(uint8_t *data, uint8_t datasz, uint8_t *lqi);
00310 
00311 
00328 uint8_t trx_frame_read_crc(uint8_t *data, uint8_t datasz, bool *crc_ok);
00329 
00330 
00348 uint8_t trx_frame_read_data_crc(uint8_t *data, uint8_t datasz, uint8_t *lqi, bool *crc_ok);
00349 
00357 uint8_t trx_frame_get_length(void);
00358 
00369 void trx_sram_write(trx_ramaddr_t addr, uint8_t length, uint8_t *data);
00370 
00379 void trx_sram_read(trx_ramaddr_t addr, uint8_t length, uint8_t *data);
00380 
00390 void trx_parms_get(trx_param_t *p);
00391 
00404 uint8_t trx_parms_set(trx_param_t *p);
00405 
00417 uint8_t trx_set_datarate(uint8_t rate_type);
00418 
00423 uint8_t trx_get_datarate(void);
00424 
00429 uint8_t trx_get_number_datarates(void);
00430 
00441 void * trx_get_datarate_str_p(uint8_t idx);
00442 
00449 void * trx_decode_datarate_p(uint8_t rhash);
00450 
00460 uint8_t trx_get_datarate_str(uint8_t idx, char * rstr, uint8_t nlen);
00461 
00471 uint8_t trx_decode_datarate(uint8_t rhash, char * rstr, uint8_t nlen);
00472 
00473 /*=== Inline Functions ================================================*/
00474 /*
00475  * This are functions that are usually called once in an application,
00476  * so we decalre it inline here
00477  */
00478 
00482 static inline uint8_t trx_init(void)
00483 {
00484 uint8_t val;
00485 
00486     /* reset transceiver */
00487     TRX_RESET_LOW();
00488     TRX_SLPTR_LOW();
00489     DELAY_US(TRX_RESET_TIME_US);
00490     TRX_RESET_HIGH();
00491 
00492     /* set TRX_OFF (for the case we come from P_ON) */
00493     trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
00494     DELAY_US(TRX_INIT_TIME_US);
00495     val = trx_reg_read(RG_TRX_STATUS);
00496     return (val != TRX_OFF) ? TRX_OK : TRX_INIT_FAIL;
00497 }
00498 
00499 
00500 static inline uint8_t trx_check_pll_lock(void)
00501 {
00502 uint8_t val, cnt = 255;
00503 
00504     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
00505     trx_reg_write(RG_IRQ_MASK, TRX_IRQ_PLL_LOCK);
00506     trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);
00507     cnt = 255;
00508     do
00509     {
00510         DELAY_US(TRX_PLL_LOCK_TIME_US);
00511         val = trx_reg_read(RG_IRQ_STATUS);
00512         if (val & TRX_IRQ_PLL_LOCK)
00513         {
00514             break;
00515         }
00516     }
00517     while(--cnt);
00518 
00519     /* clear pending IRQs*/
00520     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
00521     trx_reg_read(RG_IRQ_STATUS);
00522     return (cnt > 0) ? TRX_OK : TRX_PLL_FAIL;
00523 }
00524 
00525 
00535 static inline int trx_identify(void)
00536 {
00537     int ret = 0;
00538 
00539     if(RADIO_PART_NUM != trx_reg_read(RG_PART_NUM))
00540     {
00541         ret |= INVALID_PART_NUM;
00542     }
00543 
00544     if(RADIO_VERSION_NUM != trx_reg_read(RG_VERSION_NUM))
00545     {
00546         ret |= INVALID_REV_NUM;
00547     }
00548     return ret;
00549 }
00550 
00554 static inline void trx_set_panid(uint16_t panid)
00555 {
00556     trx_reg_write(RG_PAN_ID_0,(panid&0xff));
00557     trx_reg_write(RG_PAN_ID_1,(panid>>8));
00558 }
00559 
00564 static inline void trx_set_shortaddr(uint16_t shortaddr)
00565 {
00566     trx_reg_write(RG_SHORT_ADDR_0,(shortaddr&0xff));
00567     trx_reg_write(RG_SHORT_ADDR_1,(shortaddr>>8));
00568 }
00569 
00574 static inline void trx_set_longaddr(uint64_t longaddr)
00575 {
00576     trx_reg_write(RG_IEEE_ADDR_0, (uint8_t)(longaddr>>0) );
00577     trx_reg_write(RG_IEEE_ADDR_1, (uint8_t)(longaddr>>8) );
00578     trx_reg_write(RG_IEEE_ADDR_2, (uint8_t)(longaddr>>16));
00579     trx_reg_write(RG_IEEE_ADDR_3, (uint8_t)(longaddr>>24));
00580     trx_reg_write(RG_IEEE_ADDR_4, (uint8_t)(longaddr>>32));
00581     trx_reg_write(RG_IEEE_ADDR_5, (uint8_t)(longaddr>>40));
00582     trx_reg_write(RG_IEEE_ADDR_6, (uint8_t)(longaddr>>48));
00583     trx_reg_write(RG_IEEE_ADDR_7, (uint8_t)(longaddr>>56));
00584 }
00585 
00586 /* todo add and test a fucntion for setting the ext address */
00587 
00588 #ifdef __cplusplus
00589 } /* extern "C" */
00590 #endif
00591 
00595 #endif /* TRANSCEIVER_H */

This documentation for µracoli was generated on Tue Apr 9 2013 by  doxygen 1.7.1