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_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 #elif RADIO_TYPE == RADIO_ATMEGA256RFR2
    00064 # include "atmega_rfr2.h"
    00065 #else
    00066 # error "RADIO_TYPE is not defined or wrong"
    00067 #endif
    00068 #include <stdbool.h>
    00069
    00070 /* === Externals ============================================================= */
    00071
    00072 /* === Types ================================================================= */
    00073
    00074 #if defined(DOXYGEN)
    00075
    00076     /* this types are defined in at86rfXXX.{h,txt} in order
    00077        to provide a radio abstraction */
    00078
    00081     typedef uint8_t trx_ramaddr_t;
    00082
    00085     typedef uint8_t trx_regval_t;
    00086
    00089     typedef uint8_t trx_regaddr_t;
    00090
    00091 #endif
    00092
    00095 typedef void (*trx_irq_handler_t)(uint8_t cause);
    00096
    00097 typedef enum
    00098 {
    00099    CFG_FLASH,
    00100    CFG_EEPROM,
    00101    CFG_NONE
    00102 } trx_cfg_t;
    00103
    00104 /* === Macros ================================================================ */
    00105 /* error codes */
    00107 #define TRX_OK        (0)
    00108
    00109 #define TRX_INIT_FAIL (1)
    00110
    00111 #define TRX_PLL_FAIL  (2)
    00112
    00113 #define INVALID_PART_NUM (2)
    00114 #define INVALID_REV_NUM  (1)
    00116 /* Data Rate macros, generated by python Tools/cmdhash.py  `cat rates.txt` */
    00117 #define BPSK20 (0x52)
    00118 #define BPSK20_STR "BPSK20"
    00119 #define BPSK40 (0x92)
    00120 #define BPSK40_STR "BPSK40"
    00121 #define OQPSK100 (0x90)
    00122 #define OQPSK100_STR "OQPSK100"
    00123 #define OQPSK200 (0x93)
    00124 #define OQPSK200_STR "OQPSK200"
    00125 #define OQPSK250 (0x33)
    00126 #define OQPSK250_STR "OQPSK250"
    00127 #define OQPSK400 (0x95)
    00128 #define OQPSK400_STR "OQPSK400"
    00129 #define OQPSK500 (0x94)
    00130 #define OQPSK500_STR "OQPSK500"
    00131 #define OQPSK1000 (0x34)
    00132 #define OQPSK1000_STR "OQPSK1000"
    00133 #define OQPSK2000 (0x54)
    00134 #define OQPSK2000_STR "OQPSK2000"
    00135
    00136 #define RATE_NONE (0xFF)
    00137
    00139 #ifndef MAX_FRAME_SIZE
    00140 # define MAX_FRAME_SIZE (127)
    00141 #endif
    00142
    00143 /* channel handling */
    00144 #define TRX_NEXT_CHANNEL(x) ((channel_t)(x+1) > TRX_MAX_CHANNEL ? TRX_MAX_CHANNEL : x+1)
    00145 #define TRX_PREV_CHANNEL(x) ((channel_t)(x-1) < TRX_MIN_CHANNEL ? TRX_MIN_CHANNEL : x-1)
    00146 #define TRX_NEXT_CHANNEL_WRAP(x) ((channel_t)(x+1) > TRX_MAX_CHANNEL ? TRX_MIN_CHANNEL : x+1 )
    00147 #define TRX_PREV_CHANNEL_WRAP(x) ((channel_t)(x-1) < TRX_MIN_CHANNEL ? TRX_MAX_CHANNEL : x-1 )
    00148
    00149
    00150 #if defined (SR_MASK_AMI) || defined(DOXYGEN)
    00151
    00152 # define TRX_IRQ_AMI_EI() trx_bit_write(SR_MASK_AMI, 1);
    00153
    00154 # define TRX_IRQ_AMI_DI() trx_bit_write(SR_MASK_AMI, 0);
    00155 #endif
    00156
    00157 #if defined (SR_MASK_BAT_LOW) || defined(DOXYGEN)
    00158
    00159 # define TRX_IRQ_BAT_LOW_EI() trx_bit_write(SR_MASK_BAT_LOW, 1);
    00160
    00161 # define TRX_IRQ_BAT_LOW_DI() trx_bit_write(SR_MASK_BAT_LOW, 0);
    00162 #endif
    00163
    00164 #if defined (SR_MASK_CCA_ED_READY) || defined(DOXYGEN)
    00165
    00166 # define TRX_IRQ_CCA_ED_READY_EI() trx_bit_write(SR_MASK_CCA_ED_READY, 1);
    00167
    00168 # define TRX_IRQ_CCA_ED_READY_DI() trx_bit_write(SR_MASK_CCA_ED_READY, 0);
    00169 #endif
    00170
    00171 #if defined (SR_MASK_PLL_UNLOCK) || defined(DOXYGEN)
    00172
    00173 # define TRX_IRQ_PLL_UNLOCK_EI() trx_bit_write(SR_MASK_PLL_UNLOCK, 1);
    00174
    00175 # define TRX_IRQ_PLL_UNLOCK_DI() trx_bit_write(SR_MASK_PLL_UNLOCK, 0);
    00176 #endif
    00177
    00178 #if defined (SR_MASK_RX_START) || defined(DOXYGEN)
    00179
    00180 # define TRX_IRQ_RX_START_EI() trx_bit_write(SR_MASK_RX_START, 1);
    00181
    00182 # define TRX_IRQ_RX_START_DI() trx_bit_write(SR_MASK_RX_START, 0);
    00183 #endif
    00184
    00185 #if defined (SR_MASK_TRX_IRQ_END) || defined(DOXYGEN)
    00186
    00187 # define TRX_IRQ_TRX_IRQ_END_EI() trx_bit_write(SR_MASK_TRX_IRQ_END, 1);
    00188
    00189 # define TRX_IRQ_TRX_IRQ_END_DI() trx_bit_write(SR_MASK_TRX_IRQ_END, 0);
    00190 #endif
    00191
    00192 #if defined (SR_MASK_TRX_IRQ_START) || defined(DOXYGEN)
    00193
    00194 # define TRX_IRQ_TRX_IRQ_START_EI() trx_bit_write(SR_MASK_TRX_IRQ_START, 1);
    00195
    00196 # define TRX_IRQ_TRX_IRQ_START_DI() trx_bit_write(SR_MASK_TRX_IRQ_START, 0);
    00197 #endif
    00198
    00199 #if defined (SR_MASK_UR) || defined(DOXYGEN)
    00200
    00201 # define TRX_IRQ_UR_EI() trx_bit_write(SR_MASK_UR, 1);
    00202
    00203 # define TRX_IRQ_UR_DI() trx_bit_write(SR_MASK_UR, 0);
    00204 #endif
    00205
    00206 #ifndef DEFAULT_SPI_RATE
    00207 /* define a dummy SPI RATE */
    00208 # define DEFAULT_SPI_RATE  (0)
    00209 #endif
    00210
    00211 /* === Prototypes ============================================================ */
    00212 #ifdef __cplusplus
    00213 extern "C" {
    00214 #endif
    00215
    00224 void trx_io_init (uint8_t spirate);
    00225
    00226
    00229 void trx_set_irq_handler(trx_irq_handler_t irqhandler);
    00230
    00238 void trx_reg_write(trx_regaddr_t addr, trx_regval_t val);
    00239
    00248 uint8_t trx_reg_read(trx_regaddr_t addr);
    00249
    00250
    00251
    00267 trx_regval_t trx_bit_read(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos);
    00268
    00269
    00286 void trx_bit_write(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos, trx_regval_t value);
    00287
    00298 void trx_frame_write(uint8_t length, uint8_t *data);
    00299
    00311 uint8_t trx_frame_read(uint8_t *data, uint8_t datasz, uint8_t *lqi);
    00312
    00313
    00330 uint8_t trx_frame_read_crc(uint8_t *data, uint8_t datasz, bool *crc_ok);
    00331
    00332
    00350 uint8_t trx_frame_read_data_crc(uint8_t *data, uint8_t datasz, uint8_t *lqi, bool *crc_ok);
    00351
    00359 uint8_t trx_frame_get_length(void);
    00360
    00371 void trx_sram_write(trx_ramaddr_t addr, uint8_t length, uint8_t *data);
    00372
    00381 void trx_sram_read(trx_ramaddr_t addr, uint8_t length, uint8_t *data);
    00382
    00392 void trx_parms_get(trx_param_t *p);
    00393
    00406 uint8_t trx_parms_set(trx_param_t *p);
    00407
    00419 uint8_t trx_set_datarate(uint8_t rate_type);
    00420
    00425 uint8_t trx_get_datarate(void);
    00426
    00431 uint8_t trx_get_number_datarates(void);
    00432
    00443 void * trx_get_datarate_str_p(uint8_t idx);
    00444
    00451 void * trx_decode_datarate_p(uint8_t rhash);
    00452
    00462 uint8_t trx_get_datarate_str(uint8_t idx, char * rstr, uint8_t nlen);
    00463
    00473 uint8_t trx_decode_datarate(uint8_t rhash, char * rstr, uint8_t nlen);
    00474
    00475 /*=== Inline Functions ================================================*/
    00476 /*
    00477  * This are functions that are usually called once in an application,
    00478  * so we decalre it inline here
    00479  */
    00480
    00484 static inline uint8_t trx_init(void)
    00485 {
    00486 uint8_t val;
    00487
    00488     /* reset transceiver */
    00489     TRX_RESET_LOW();
    00490     TRX_SLPTR_LOW();
    00491     DELAY_US(TRX_RESET_TIME_US);
    00492     TRX_RESET_HIGH();
    00493
    00494     /* set TRX_OFF (for the case we come from P_ON) */
    00495     trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
    00496     DELAY_US(TRX_INIT_TIME_US);
    00497     val = trx_reg_read(RG_TRX_STATUS);
    00498     return (val != TRX_OFF) ? TRX_OK : TRX_INIT_FAIL;
    00499 }
    00500
    00501
    00502 static inline uint8_t trx_check_pll_lock(void)
    00503 {
    00504 uint8_t val, cnt = 255;
    00505
    00506     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00507     trx_reg_write(RG_IRQ_MASK, TRX_IRQ_PLL_LOCK);
    00508     trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);
    00509     cnt = 255;
    00510     do
    00511     {
    00512         DELAY_US(TRX_PLL_LOCK_TIME_US);
    00513         val = trx_reg_read(RG_IRQ_STATUS);
    00514         if (val & TRX_IRQ_PLL_LOCK)
    00515         {
    00516             break;
    00517         }
    00518     }
    00519     while(--cnt);
    00520
    00521     /* clear pending IRQs*/
    00522     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00523     trx_reg_read(RG_IRQ_STATUS);
    00524     return (cnt > 0) ? TRX_OK : TRX_PLL_FAIL;
    00525 }
    00526
    00527
    00537 static inline int trx_identify(void)
    00538 {
    00539     int ret = 0;
    00540
    00541     if(RADIO_PART_NUM != trx_reg_read(RG_PART_NUM))
    00542     {
    00543         ret |= INVALID_PART_NUM;
    00544     }
    00545
    00546     if(RADIO_VERSION_NUM != trx_reg_read(RG_VERSION_NUM))
    00547     {
    00548         ret |= INVALID_REV_NUM;
    00549     }
    00550     return ret;
    00551 }
    00552
    00556 static inline void trx_set_panid(uint16_t panid)
    00557 {
    00558     trx_reg_write(RG_PAN_ID_0,(panid&0xff));
    00559     trx_reg_write(RG_PAN_ID_1,(panid>>8));
    00560 }
    00561
    00566 static inline void trx_set_shortaddr(uint16_t shortaddr)
    00567 {
    00568     trx_reg_write(RG_SHORT_ADDR_0,(shortaddr&0xff));
    00569     trx_reg_write(RG_SHORT_ADDR_1,(shortaddr>>8));
    00570 }
    00571
    00576 static inline void trx_set_longaddr(uint64_t longaddr)
    00577 {
    00578     trx_reg_write(RG_IEEE_ADDR_0, (uint8_t)(longaddr>>0) );
    00579     trx_reg_write(RG_IEEE_ADDR_1, (uint8_t)(longaddr>>8) );
    00580     trx_reg_write(RG_IEEE_ADDR_2, (uint8_t)(longaddr>>16));
    00581     trx_reg_write(RG_IEEE_ADDR_3, (uint8_t)(longaddr>>24));
    00582     trx_reg_write(RG_IEEE_ADDR_4, (uint8_t)(longaddr>>32));
    00583     trx_reg_write(RG_IEEE_ADDR_5, (uint8_t)(longaddr>>40));
    00584     trx_reg_write(RG_IEEE_ADDR_6, (uint8_t)(longaddr>>48));
    00585     trx_reg_write(RG_IEEE_ADDR_7, (uint8_t)(longaddr>>56));
    00586 }
    00587
    00588 /* todo add and test a fucntion for setting the ext address */
    00589
    00590 #ifdef __cplusplus
    00591 } /* extern "C" */
    00592 #endif
    00593
    00597 #endif /* TRANSCEIVER_H */