A Atmel RF2xx Radio Library for Mbed
Dependents: xBedRadio MxSniffer
MxRadio.h
00001 /* Copyright (c) 2011 Frank Zhao 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 #ifndef MxRadio_h 00030 00031 #ifdef __cplusplus 00032 extern "C" { 00033 #endif 00034 #include "uracolib/board.h" 00035 #include "MxRadioCfg.h" 00036 #include "uracolib/radio.h" 00037 #include "uracolib/transceiver.h" 00038 #include <stdint.h> 00039 #ifdef __cplusplus 00040 } /* extern "C" */ 00041 #endif 00042 00043 #include "mbed.h" 00044 #define ZR_RXFRMBUFF_SIZE MAX_FRAME_SIZE 00045 #define ZR_FIFO_SIZE 128 // size for the RX FIFO ring buffer 00046 #define ZR_TXTMPBUFF_SIZE MAX_FRAME_SIZE // size for the TX non-immediate transmit buffer 00047 00048 #define ZR_TXWAIT_BEFORE // when you call any TX functions, it will wait until the previous transmission has finished before initiating a new transmission 00049 #define ZR_TXWAIT_AFTER // when you call any TX functions, it will transmit and then wait until that transmission finished 00050 00051 // just a class definition, for usage and comments, see the cpp file 00052 class cMxRadio 00053 { 00054 private: 00055 00056 uint8_t temprssi; 00057 radio_status_t radiostatus; 00058 SPI m_spi; 00059 DigitalOut m_cs; 00060 DigitalOut reset_pin; 00061 DigitalOut sleep_pin; 00062 00063 protected: 00064 InterruptIn irq_pin; 00065 private: 00066 uint8_t rxFrameBuffer[ZR_RXFRMBUFF_SIZE]; 00067 uint8_t rxRingBuffer[ZR_FIFO_SIZE]; 00068 uint8_t rxRingBufferHead; 00069 uint8_t rxRingBufferTail; 00070 uint8_t txTmpBuffer[ZR_TXTMPBUFF_SIZE]; 00071 uint8_t txTmpBufferLength; 00072 uint8_t lastLqi; 00073 uint8_t lastRssi; 00074 uint8_t hasAttachedRxEvent; 00075 uint8_t hasAttachedTxEvent; 00076 uint8_t usedBeginTransmission; 00077 volatile uint8_t txIsBusy; 00078 00079 uint8_t* (*zrEventReceiveFrame)(uint8_t, uint8_t*, uint8_t, int8_t,uint8_t); 00080 void (*zrEventTxDone)(radio_tx_done_t); 00081 00082 uint8_t* onReceiveFrame(uint8_t, uint8_t*, uint8_t, int8_t,uint8_t); 00083 void onTxDone(radio_tx_done_t); 00084 bool setautotx,setautorx,needack; 00085 00086 //come from radio.h 00087 void radio_init(uint8_t * rxbuf, uint8_t rxbufsz); 00088 void radio_force_state(radio_state_t state); 00089 void radio_set_state(radio_state_t state); 00090 void radio_set_param(radio_attribute_t attr, radio_param_t parm); 00091 void radio_send_frame(uint8_t len, uint8_t *frm, uint8_t compcrc); 00092 radio_cca_t radio_do_cca(void); 00093 int radio_putchar(int c); 00094 int radio_getchar(void); 00095 void usr_radio_error(radio_error_t err); 00096 void usr_radio_irq(uint8_t cause); 00097 uint8_t * usr_radio_receive_frame(uint8_t len, uint8_t *frm, uint8_t lqi, int8_t ed, uint8_t crc_fail); 00098 void usr_radio_tx_done(radio_tx_done_t status); 00099 //come from transciever 00100 void trx_io_init (int spirate); 00101 void trx_reg_write(trx_regaddr_t addr, trx_regval_t val); 00102 uint8_t trx_reg_read(trx_regaddr_t addr); 00103 trx_regval_t trx_bit_read(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos); 00104 void trx_bit_write(trx_regaddr_t addr, trx_regval_t mask, uint8_t pos, trx_regval_t value); 00105 void trx_frame_write(uint8_t length, uint8_t *data); 00106 uint8_t trx_frame_read(uint8_t *data, uint8_t datasz, uint8_t *lqi); 00107 //uint8_t trx_frame_read_crc(uint8_t *data, uint8_t datasz, bool *crc_ok); 00108 //uint8_t trx_frame_read_data_crc(uint8_t *data, uint8_t datasz, uint8_t *lqi, bool *crc_ok); 00109 uint8_t trx_frame_get_length(void); 00110 void trx_sram_write(trx_ramaddr_t addr, uint8_t length, uint8_t *data); 00111 void trx_sram_read(trx_ramaddr_t addr, uint8_t length, uint8_t *data); 00112 void trx_parms_get(trx_param_t *p); 00113 uint8_t trx_parms_set(trx_param_t *p); 00114 uint8_t trx_set_datarate(uint8_t rate_type); 00115 uint8_t trx_get_datarate(void); 00116 uint8_t trx_get_number_datarates(void); 00117 //void * trx_get_datarate_str_p(uint8_t idx); 00118 //void * trx_decode_datarate_p(uint8_t rhash); 00119 //uint8_t trx_get_datarate_str(uint8_t idx, char * rstr, uint8_t nlen); 00120 //uint8_t trx_decode_datarate(uint8_t rhash, char * rstr, uint8_t nlen); 00121 /** 00122 * @brief Basic radio initialization function, 00123 */ 00124 inline uint8_t trx_init(void) 00125 { 00126 uint8_t val; 00127 /* reset transceiver */ 00128 reset_pin=0;//TRX_RESET_LOW(); 00129 sleep_pin=0;//TRX_SLPTR_LOW(); 00130 DELAY_US(TRX_RESET_TIME_US); 00131 reset_pin=1;//TRX_RESET_HIGH(); 00132 /* set TRX_OFF (for the case we come from P_ON) */ 00133 trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF); 00134 00135 #if RADIO_TYPE == RADIO_AT86RF212 00136 trx_reg_write(RG_TRX_CTRL_0, 0x19); 00137 #ifdef CHINABAND 00138 trx_reg_write(RG_CC_CTRL_1, CCBAND ); 00139 trx_reg_write(RG_CC_CTRL_0, 11);//channel 0 00140 trx_reg_write(RG_TRX_CTRL_2, TRX_OQPSK250); 00141 DELAY_US(510); 00142 #endif 00143 #endif 00144 00145 DELAY_US(TRX_INIT_TIME_US); 00146 val = trx_reg_read(RG_TRX_STATUS); 00147 return (val != TRX_OFF) ? TRX_OK : TRX_INIT_FAIL; 00148 } 00149 inline uint8_t trx_check_pll_lock(void) 00150 { 00151 uint8_t val, cnt = 255; 00152 00153 trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF); 00154 trx_reg_write(RG_IRQ_MASK, TRX_IRQ_PLL_LOCK); 00155 trx_reg_write(RG_TRX_STATE, CMD_PLL_ON); 00156 cnt = 255; 00157 do 00158 { 00159 DELAY_US(TRX_PLL_LOCK_TIME_US); 00160 val = trx_reg_read(RG_IRQ_STATUS); 00161 if (val & TRX_IRQ_PLL_LOCK) 00162 { 00163 break; 00164 } 00165 } 00166 while(--cnt); 00167 00168 /* clear pending IRQs*/ 00169 trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF); 00170 trx_reg_read(RG_IRQ_STATUS); 00171 return (cnt > 0) ? TRX_OK : TRX_PLL_FAIL; 00172 } 00173 00174 /** 00175 * @brief Verify that correct radio type is used. 00176 * 00177 * @return status value, with the following meaning: 00178 * - 0 if part and revision number match 00179 * - 1 if revision number does @b not match 00180 * - 2 if part number does @b not match 00181 * - 3 if part and revision number does @b not match 00182 */ 00183 inline int trx_identify(void) 00184 { 00185 int ret = 0; 00186 00187 if(RADIO_PART_NUM != trx_reg_read(RG_PART_NUM)) 00188 { 00189 ret |= INVALID_PART_NUM; 00190 } 00191 00192 if(RADIO_VERSION_NUM != trx_reg_read(RG_VERSION_NUM)) 00193 { 00194 ret |= INVALID_REV_NUM; 00195 } 00196 return ret; 00197 } 00198 00199 /** 00200 * @brief Write the PANID to the address filter registers 00201 */ 00202 inline void trx_set_panid(uint16_t panid) 00203 { 00204 trx_reg_write(RG_PAN_ID_0,(panid&0xff)); 00205 trx_reg_write(RG_PAN_ID_1,(panid>>8)); 00206 } 00207 00208 /** 00209 * @brief Write the 16 bit short address to the 00210 * address filter registers 00211 */ 00212 inline void trx_set_shortaddr(uint16_t shortaddr) 00213 { 00214 trx_reg_write(RG_SHORT_ADDR_0,(shortaddr&0xff)); 00215 trx_reg_write(RG_SHORT_ADDR_1,(shortaddr>>8)); 00216 } 00217 00218 /** 00219 * @brief Write the 64 bit long address (MAC address) to the 00220 * address filter registers 00221 */ 00222 inline void trx_set_longaddr(uint64_t longaddr) 00223 { 00224 trx_reg_write(RG_IEEE_ADDR_0, (uint8_t)(longaddr>>0) ); 00225 trx_reg_write(RG_IEEE_ADDR_1, (uint8_t)(longaddr>>8) ); 00226 trx_reg_write(RG_IEEE_ADDR_2, (uint8_t)(longaddr>>16)); 00227 trx_reg_write(RG_IEEE_ADDR_3, (uint8_t)(longaddr>>24)); 00228 trx_reg_write(RG_IEEE_ADDR_4, (uint8_t)(longaddr>>32)); 00229 trx_reg_write(RG_IEEE_ADDR_5, (uint8_t)(longaddr>>40)); 00230 trx_reg_write(RG_IEEE_ADDR_6, (uint8_t)(longaddr>>48)); 00231 trx_reg_write(RG_IEEE_ADDR_7, (uint8_t)(longaddr>>56)); 00232 } 00233 00234 inline uint16_t crc16_update(uint16_t crc, uint8_t a) 00235 { 00236 int i; 00237 00238 crc ^= a; 00239 for (i = 0; i < 8; ++i) 00240 { 00241 if (crc & 1) 00242 crc = (crc >> 1) ^ 0xA001; 00243 else 00244 crc = (crc >> 1); 00245 } 00246 00247 return crc; 00248 } 00249 00250 void rf_irq_callback(); 00251 00252 //rf230.cpp 00253 void radio_error(radio_error_t err); 00254 void radio_receive_frame(void); 00255 void radio_irq_handler(uint8_t cause); 00256 //events 00257 void zr_attach_error(void (*)(radio_error_t)); 00258 void zr_attach_irq(void (*)(uint8_t)); 00259 void zr_attach_receive_frame(uint8_t* (cMxRadio::*)(uint8_t, uint8_t*, uint8_t, int8_t,uint8_t)); 00260 void zr_attach_tx_done(void (cMxRadio::*)(radio_tx_done_t)); 00261 00262 void (*user_radio_error)(radio_error_t); 00263 void (*user_radio_irq)(uint8_t); 00264 uint8_t* (cMxRadio::*user_radio_receive_frame)(uint8_t, uint8_t*, uint8_t, int8_t,uint8_t); 00265 void (cMxRadio::*user_radio_tx_done)(radio_tx_done_t); 00266 00267 00268 public: 00269 cMxRadio(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName slp, PinName irq); 00270 ~cMxRadio(); 00271 void begin(channel_t); 00272 void begin(channel_t,uint16_t,uint16_t,bool,bool,bool,char); 00273 void begin(channel_t,uint16_t,uint16_t,bool,bool,bool); 00274 void begin(channel_t, uint8_t*); 00275 void setFrameHeader(uint8_t*); 00276 void attachError(void(*)(radio_error_t)); 00277 void attachIrq(void(*)(uint8_t)); 00278 void attachReceiveFrame(uint8_t* (*)(uint8_t, uint8_t*, uint8_t, int8_t,uint8_t)); 00279 void sendFrame(uint16_t ,bool ,uint8_t* , uint8_t ); 00280 void attachTxDone(void(*)(radio_tx_done_t)); 00281 int8_t available(); 00282 int16_t peek(); 00283 int16_t read(); 00284 void flush(); 00285 void write(uint8_t); 00286 void write(char*); 00287 void write(uint8_t*, uint8_t); 00288 void send(uint8_t); 00289 void txFrame(uint8_t*, uint8_t); 00290 void beginTransmission(); 00291 void beginTransmission(uint16_t); 00292 void endTransmission(); 00293 void cancelTransmission(); 00294 void setParam(radio_attribute_t, radio_param_t); 00295 radio_cca_t doCca(); 00296 void setState(radio_state_t, uint8_t); 00297 void setState(radio_state_t); 00298 void setStateRx(); 00299 void setChannel(channel_t); 00300 uint8_t getChannel(); 00301 void forceState(radio_state_t); 00302 void waitTxDone(uint16_t); 00303 int8_t getRssiNow(); 00304 int8_t getLastRssi(); 00305 uint8_t getLqi(); 00306 int8_t getLastEd(); 00307 int8_t getEdNow(); 00308 }; 00309 00310 extern cMxRadio MxRadio; // make single instance accessible 00311 00312 #define MxRadio_h 00313 #endif
Generated on Thu Jul 14 2022 01:09:39 by
1.7.2