# 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$ */
    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_ATMEGA128RFA1_A ||\
    00057       RADIO_TYPE == RADIO_ATMEGA128RFA1_B ||\
    00058       RADIO_TYPE == RADIO_ATMEGA128RFA1_C ||\
    00059       RADIO_TYPE == RADIO_ATMEGA128RFA1_D
    00060 # include "atmega_rfa1.h"
    00061 #else
    00062 # error "RADIO_TYPE is not defined or wrong"
    00063 #endif
    00064 #include <stdbool.h>
    00065
    00066 /* === Externals ============================================================= */
    00067
    00068 /* === Types ================================================================= */
    00069
    00070 #if defined(DOXYGEN)
    00071
    00072     /* this types are defined in at86rfXXX.{h,txt} in order
    00073        to provide a radio abstraction */
    00074
    00077     typedef uint8_t trx_ramaddr_t;
    00078
    00081     typedef uint8_t trx_regval_t;
    00082
    00085     typedef uint8_t trx_regaddr_t;
    00086
    00087 #endif
    00088
    00091 typedef void (*trx_irq_handler_t)(uint8_t cause);
    00092
    00093 typedef enum
    00094 {
    00095    CFG_FLASH,
    00096    CFG_EEPROM,
    00097    CFG_NONE
    00098 } trx_cfg_t;
    00099
    00100 /* === Macros ================================================================ */
    00101 /* error codes */
    00103 #define TRX_OK        (0)
    00104
    00105 #define TRX_INIT_FAIL (1)
    00106
    00107 #define TRX_PLL_FAIL  (2)
    00108
    00109 #define INVALID_PART_NUM (2)
    00110 #define INVALID_REV_NUM  (1)
    00112 /* Data Rate macros, generated by python Tools/cmdhash.py  `cat rates.txt` */
    00113 #define BPSK20 (0x52)
    00114 #define BPSK20_STR "BPSK20"
    00115 #define BPSK40 (0x92)
    00116 #define BPSK40_STR "BPSK40"
    00117 #define OQPSK100 (0x90)
    00118 #define OQPSK100_STR "OQPSK100"
    00119 #define OQPSK200 (0x93)
    00120 #define OQPSK200_STR "OQPSK200"
    00121 #define OQPSK250 (0x33)
    00122 #define OQPSK250_STR "OQPSK250"
    00123 #define OQPSK400 (0x95)
    00124 #define OQPSK400_STR "OQPSK400"
    00125 #define OQPSK500 (0x94)
    00126 #define OQPSK500_STR "OQPSK500"
    00127 #define OQPSK1000 (0x34)
    00128 #define OQPSK1000_STR "OQPSK1000"
    00129 #define OQPSK2000 (0x54)
    00130 #define OQPSK2000_STR "OQPSK2000"
    00131
    00132 #define RATE_NONE (0xFF)
    00133
    00135 #ifndef MAX_FRAME_SIZE
    00136 # define MAX_FRAME_SIZE (127)
    00137 #endif
    00138
    00139 /* channel handling */
    00140 #define TRX_NEXT_CHANNEL(x) ((channel_t)(x+1) > TRX_MAX_CHANNEL ? TRX_MAX_CHANNEL : x+1)
    00141 #define TRX_PREV_CHANNEL(x) ((channel_t)(x-1) < TRX_MIN_CHANNEL ? TRX_MIN_CHANNEL : x-1)
    00142 #define TRX_NEXT_CHANNEL_WRAP(x) ((channel_t)(x+1) > TRX_MAX_CHANNEL ? TRX_MIN_CHANNEL : x+1 )
    00143 #define TRX_PREV_CHANNEL_WRAP(x) ((channel_t)(x-1) < TRX_MIN_CHANNEL ? TRX_MAX_CHANNEL : x-1 )
    00144
    00145
    00146 #if defined (SR_MASK_AMI) || defined(DOXYGEN)
    00147
    00148 # define TRX_IRQ_AMI_EI() trx_bit_write(SR_MASK_AMI, 1);
    00149
    00150 # define TRX_IRQ_AMI_DI() trx_bit_write(SR_MASK_AMI, 0);
    00151 #endif
    00152
    00153 #if defined (SR_MASK_BAT_LOW) || defined(DOXYGEN)
    00154
    00155 # define TRX_IRQ_BAT_LOW_EI() trx_bit_write(SR_MASK_BAT_LOW, 1);
    00156
    00157 # define TRX_IRQ_BAT_LOW_DI() trx_bit_write(SR_MASK_BAT_LOW, 0);
    00158 #endif
    00159
    00160 #if defined (SR_MASK_CCA_ED_READY) || defined(DOXYGEN)
    00161
    00162 # define TRX_IRQ_CCA_ED_READY_EI() trx_bit_write(SR_MASK_CCA_ED_READY, 1);
    00163
    00164 # define TRX_IRQ_CCA_ED_READY_DI() trx_bit_write(SR_MASK_CCA_ED_READY, 0);
    00165 #endif
    00166
    00167 #if defined (SR_MASK_PLL_UNLOCK) || defined(DOXYGEN)
    00168
    00169 # define TRX_IRQ_PLL_UNLOCK_EI() trx_bit_write(SR_MASK_PLL_UNLOCK, 1);
    00170
    00171 # define TRX_IRQ_PLL_UNLOCK_DI() trx_bit_write(SR_MASK_PLL_UNLOCK, 0);
    00172 #endif
    00173
    00174 #if defined (SR_MASK_RX_START) || defined(DOXYGEN)
    00175
    00176 # define TRX_IRQ_RX_START_EI() trx_bit_write(SR_MASK_RX_START, 1);
    00177
    00178 # define TRX_IRQ_RX_START_DI() trx_bit_write(SR_MASK_RX_START, 0);
    00179 #endif
    00180
    00181 #if defined (SR_MASK_TRX_IRQ_END) || defined(DOXYGEN)
    00182
    00183 # define TRX_IRQ_TRX_IRQ_END_EI() trx_bit_write(SR_MASK_TRX_IRQ_END, 1);
    00184
    00185 # define TRX_IRQ_TRX_IRQ_END_DI() trx_bit_write(SR_MASK_TRX_IRQ_END, 0);
    00186 #endif
    00187
    00188 #if defined (SR_MASK_TRX_IRQ_START) || defined(DOXYGEN)
    00189
    00190 # define TRX_IRQ_TRX_IRQ_START_EI() trx_bit_write(SR_MASK_TRX_IRQ_START, 1);
    00191
    00192 # define TRX_IRQ_TRX_IRQ_START_DI() trx_bit_write(SR_MASK_TRX_IRQ_START, 0);
    00193 #endif
    00194
    00195 #if defined (SR_MASK_UR) || defined(DOXYGEN)
    00196
    00197 # define TRX_IRQ_UR_EI() trx_bit_write(SR_MASK_UR, 1);
    00198
    00199 # define TRX_IRQ_UR_DI() trx_bit_write(SR_MASK_UR, 0);
    00200 #endif
    00201
    00202 /* === Prototypes ============================================================ */
    00203 #ifdef __cplusplus
    00204 extern "C" {
    00205 #endif
    00206
    00207 #if !defined(TRX_IF_RFA1)
    00208
    00217 void trx_io_init (uint8_t spirate);
    00218 #else  /* RFA1 */
    00219 #define trx_io_init(dummy) do { /* dummy macro */ } while (0)
    00220 #endif
    00221
    00222
    00225 void trx_set_irq_handler(trx_irq_handler_t irqhandler);
    00226
    00234 void trx_reg_write(trx_regaddr_t addr, trx_regval_t val);
    00235
    00244 uint8_t trx_reg_read(trx_regaddr_t addr);
    00245
    00246
    00247
    00263 trx_regval_t trx_bit_read(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos);
    00264
    00265
    00282 void trx_bit_write(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos, trx_regval_t value);
    00283
    00294 void trx_frame_write(uint8_t length, uint8_t *data);
    00295
    00307 uint8_t trx_frame_read(uint8_t *data, uint8_t datasz, uint8_t *lqi);
    00308
    00309
    00326 uint8_t trx_frame_read_crc(uint8_t *data, uint8_t datasz, bool *crc_ok);
    00327
    00328
    00346 uint8_t trx_frame_read_data_crc(uint8_t *data, uint8_t datasz, uint8_t *lqi, bool *crc_ok);
    00347
    00355 uint8_t trx_frame_get_length(void);
    00356
    00367 void trx_sram_write(trx_ramaddr_t addr, uint8_t length, uint8_t *data);
    00368
    00377 void trx_sram_read(trx_ramaddr_t addr, uint8_t length, uint8_t *data);
    00378
    00388 void trx_parms_get(trx_param_t *p);
    00389
    00402 uint8_t trx_parms_set(trx_param_t *p);
    00403
    00415 uint8_t trx_set_datarate(uint8_t rate_type);
    00416
    00421 uint8_t trx_get_datarate(void);
    00422
    00427 uint8_t trx_get_number_datarates(void);
    00428
    00439 void * trx_get_datarate_str_p(uint8_t idx);
    00440
    00447 void * trx_decode_datarate_p(uint8_t rhash);
    00448
    00458 uint8_t trx_get_datarate_str(uint8_t idx, char * rstr, uint8_t nlen);
    00459
    00469 uint8_t trx_decode_datarate(uint8_t rhash, char * rstr, uint8_t nlen);
    00470
    00471 /*=== Inline Functions ================================================*/
    00472 /*
    00473  * This are functions that are usually called once in an application,
    00474  * so we decalre it inline here
    00475  */
    00476
    00480 static inline uint8_t trx_init(void)
    00481 {
    00482 uint8_t val;
    00483
    00484     /* reset transceiver */
    00485     TRX_RESET_LOW();
    00486     TRX_SLPTR_LOW();
    00487     DELAY_US(TRX_RESET_TIME_US);
    00488     TRX_RESET_HIGH();
    00489
    00490     /* set TRX_OFF (for the case we come from P_ON) */
    00491     trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
    00492     DELAY_US(TRX_INIT_TIME_US);
    00493     val = trx_reg_read(RG_TRX_STATUS);
    00494     return (val != TRX_OFF) ? TRX_OK : TRX_INIT_FAIL;
    00495 }
    00496
    00497
    00498 static inline uint8_t trx_check_pll_lock(void)
    00499 {
    00500 uint8_t val, cnt = 255;
    00501
    00502     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00503     trx_reg_write(RG_IRQ_MASK, TRX_IRQ_PLL_LOCK);
    00504     trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);
    00505     cnt = 255;
    00506     do
    00507     {
    00508         DELAY_US(TRX_PLL_LOCK_TIME_US);
    00509         val = trx_reg_read(RG_IRQ_STATUS);
    00510         if (val & TRX_IRQ_PLL_LOCK)
    00511         {
    00512             break;
    00513         }
    00514     }
    00515     while(--cnt);
    00516
    00517     /* clear pending IRQs*/
    00518     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00519     trx_reg_read(RG_IRQ_STATUS);
    00520     return (cnt > 0) ? TRX_OK : TRX_PLL_FAIL;
    00521 }
    00522
    00523
    00533 static inline int trx_identify(void)
    00534 {
    00535     int ret = 0;
    00536
    00537     if(RADIO_PART_NUM != trx_reg_read(RG_PART_NUM))
    00538     {
    00539         ret |= INVALID_PART_NUM;
    00540     }
    00541
    00542     if(RADIO_VERSION_NUM != trx_reg_read(RG_VERSION_NUM))
    00543     {
    00544         ret |= INVALID_REV_NUM;
    00545     }
    00546     return ret;
    00547 }
    00548
    00552 static inline void trx_set_panid(uint16_t panid)
    00553 {
    00554     trx_reg_write(RG_PAN_ID_0,(panid&0xff));
    00555     trx_reg_write(RG_PAN_ID_1,(panid>>8));
    00556 }
    00557
    00562 static inline void trx_set_shortaddr(uint16_t shortaddr)
    00563 {
    00564     trx_reg_write(RG_SHORT_ADDR_0,(shortaddr&0xff));
    00565     trx_reg_write(RG_SHORT_ADDR_1,(shortaddr>>8));
    00566 }
    00567
    00572 static inline void trx_set_longaddr(uint64_t longaddr)
    00573 {
    00574     trx_reg_write(RG_IEEE_ADDR_0, (uint8_t)(longaddr>>0) );
    00575     trx_reg_write(RG_IEEE_ADDR_1, (uint8_t)(longaddr>>8) );
    00576     trx_reg_write(RG_IEEE_ADDR_2, (uint8_t)(longaddr>>16));
    00577     trx_reg_write(RG_IEEE_ADDR_3, (uint8_t)(longaddr>>24));
    00578     trx_reg_write(RG_IEEE_ADDR_4, (uint8_t)(longaddr>>32));
    00579     trx_reg_write(RG_IEEE_ADDR_5, (uint8_t)(longaddr>>40));
    00580     trx_reg_write(RG_IEEE_ADDR_6, (uint8_t)(longaddr>>48));
    00581     trx_reg_write(RG_IEEE_ADDR_7, (uint8_t)(longaddr>>56));
    00582 }
    00583
    00584 /* todo add and test a fucntion for setting the ext address */
    00585
    00586 #ifdef __cplusplus
    00587 } /* extern "C" */
    00588 #endif
    00589
    00593 #endif /* TRANSCEIVER_H */