A Atmel RF2xx Radio Library for Mbed

Dependents:   xBedRadio MxSniffer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MxRadio.h Source File

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