A Atmel RF2xx Radio Library for Mbed

Dependents:   xBedRadio MxSniffer

Committer:
fredqian
Date:
Thu Apr 09 16:42:51 2015 +0800
Revision:
0:5f1d66c85ae0
init commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fredqian 0:5f1d66c85ae0 1 /* Copyright (c) 2011 Frank Zhao
fredqian 0:5f1d66c85ae0 2 All rights reserved.
fredqian 0:5f1d66c85ae0 3
fredqian 0:5f1d66c85ae0 4 Redistribution and use in source and binary forms, with or without
fredqian 0:5f1d66c85ae0 5 modification, are permitted provided that the following conditions
fredqian 0:5f1d66c85ae0 6 are met:
fredqian 0:5f1d66c85ae0 7
fredqian 0:5f1d66c85ae0 8 * Redistributions of source code must retain the above copyright
fredqian 0:5f1d66c85ae0 9 notice, this list of conditions and the following disclaimer.
fredqian 0:5f1d66c85ae0 10 * Redistributions in binary form must reproduce the above copyright
fredqian 0:5f1d66c85ae0 11 notice, this list of conditions and the following disclaimer in the
fredqian 0:5f1d66c85ae0 12 documentation and/or other materials provided with the distribution.
fredqian 0:5f1d66c85ae0 13 * Neither the name of the authors nor the names of its contributors
fredqian 0:5f1d66c85ae0 14 may be used to endorse or promote products derived from this software
fredqian 0:5f1d66c85ae0 15 without specific prior written permission.
fredqian 0:5f1d66c85ae0 16
fredqian 0:5f1d66c85ae0 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
fredqian 0:5f1d66c85ae0 18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
fredqian 0:5f1d66c85ae0 19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
fredqian 0:5f1d66c85ae0 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
fredqian 0:5f1d66c85ae0 21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
fredqian 0:5f1d66c85ae0 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
fredqian 0:5f1d66c85ae0 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
fredqian 0:5f1d66c85ae0 24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
fredqian 0:5f1d66c85ae0 25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
fredqian 0:5f1d66c85ae0 26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
fredqian 0:5f1d66c85ae0 27 POSSIBILITY OF SUCH DAMAGE. */
fredqian 0:5f1d66c85ae0 28
fredqian 0:5f1d66c85ae0 29 #include "MxRadio.h"
fredqian 0:5f1d66c85ae0 30 #include "MxRadioEvents.h"
fredqian 0:5f1d66c85ae0 31 //#define radio_set_state radio_force_state
fredqian 0:5f1d66c85ae0 32
fredqian 0:5f1d66c85ae0 33 // the write function checks if beginTransmission was called prior to write
fredqian 0:5f1d66c85ae0 34 // in order to determine whether to use immediate or non-immediate transmission
fredqian 0:5f1d66c85ae0 35
fredqian 0:5f1d66c85ae0 36 const uint8_t HeadSize=9;
fredqian 0:5f1d66c85ae0 37
fredqian 0:5f1d66c85ae0 38 // a busy indicator so transmit functions can wait until the last transmission has finished
fredqian 0:5f1d66c85ae0 39 volatile uint8_t txIsBusy = 0;
fredqian 0:5f1d66c85ae0 40
fredqian 0:5f1d66c85ae0 41
fredqian 0:5f1d66c85ae0 42 cMxRadio::~cMxRadio()
fredqian 0:5f1d66c85ae0 43 {
fredqian 0:5f1d66c85ae0 44 }
fredqian 0:5f1d66c85ae0 45 // empty constructor, should not be called by user
fredqian 0:5f1d66c85ae0 46 cMxRadio::cMxRadio(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName slp, PinName irq)
fredqian 0:5f1d66c85ae0 47 :m_spi(mosi, miso, sclk), m_cs(cs), reset_pin(rst), sleep_pin(slp),irq_pin(irq)
fredqian 0:5f1d66c85ae0 48 {
fredqian 0:5f1d66c85ae0 49 // default event handlers
fredqian 0:5f1d66c85ae0 50
fredqian 0:5f1d66c85ae0 51 zrEventTxDone=0;
fredqian 0:5f1d66c85ae0 52 zrEventReceiveFrame=0;
fredqian 0:5f1d66c85ae0 53 temprssi=0;
fredqian 0:5f1d66c85ae0 54 setautotx=false;
fredqian 0:5f1d66c85ae0 55 setautorx=false;
fredqian 0:5f1d66c85ae0 56 needack=false;
fredqian 0:5f1d66c85ae0 57 usedBeginTransmission = 0;
fredqian 0:5f1d66c85ae0 58 hasAttachedTxEvent = 0;
fredqian 0:5f1d66c85ae0 59 hasAttachedRxEvent = 0;
fredqian 0:5f1d66c85ae0 60 lastLqi = 0;
fredqian 0:5f1d66c85ae0 61 lastRssi = 0;
fredqian 0:5f1d66c85ae0 62 txTmpBufferLength = 0;
fredqian 0:5f1d66c85ae0 63 rxRingBufferHead = 0;
fredqian 0:5f1d66c85ae0 64 rxRingBufferTail = 0;
fredqian 0:5f1d66c85ae0 65 /*
fredqian 0:5f1d66c85ae0 66 user_radio_tx_done=0;
fredqian 0:5f1d66c85ae0 67 user_radio_receive_frame=0;
fredqian 0:5f1d66c85ae0 68 user_radio_irq=0;
fredqian 0:5f1d66c85ae0 69 user_radio_error=0;
fredqian 0:5f1d66c85ae0 70 */
fredqian 0:5f1d66c85ae0 71 zr_attach_receive_frame(&cMxRadio::onReceiveFrame);
fredqian 0:5f1d66c85ae0 72 zr_attach_tx_done(&cMxRadio::onTxDone);
fredqian 0:5f1d66c85ae0 73
fredqian 0:5f1d66c85ae0 74 }
fredqian 0:5f1d66c85ae0 75
fredqian 0:5f1d66c85ae0 76 /**
fredqian 0:5f1d66c85ae0 77 * @brief Radio Initialization
fredqian 0:5f1d66c85ae0 78 *
fredqian 0:5f1d66c85ae0 79 * The function initializes all IO ressources,
fredqian 0:5f1d66c85ae0 80 * needed for the usage of the radio and performs
fredqian 0:5f1d66c85ae0 81 * a reset to the radio.
fredqian 0:5f1d66c85ae0 82 * It prepares the frame header.
fredqian 0:5f1d66c85ae0 83 * Then it sets the channel number and defaults to RX state.
fredqian 0:5f1d66c85ae0 84 *
fredqian 0:5f1d66c85ae0 85 * @param chan the channel number for the radio to use, 11 to 26
fredqian 0:5f1d66c85ae0 86 */
fredqian 0:5f1d66c85ae0 87 void cMxRadio::begin(channel_t chan)
fredqian 0:5f1d66c85ae0 88 {
fredqian 0:5f1d66c85ae0 89 begin(chan, 0);
fredqian 0:5f1d66c85ae0 90 }
fredqian 0:5f1d66c85ae0 91
fredqian 0:5f1d66c85ae0 92 void cMxRadio::begin(channel_t chan,uint16_t panid,uint16_t localaddress,bool needackval,bool autotxval,bool autorxval,char autoretrycount)
fredqian 0:5f1d66c85ae0 93 {
fredqian 0:5f1d66c85ae0 94 setautotx=autotxval;
fredqian 0:5f1d66c85ae0 95 setautorx=autorxval;
fredqian 0:5f1d66c85ae0 96 needack=needackval;
fredqian 0:5f1d66c85ae0 97 radio_init(rxFrameBuffer, MAX_FRAME_SIZE);
fredqian 0:5f1d66c85ae0 98
fredqian 0:5f1d66c85ae0 99 //////////////////////////////
fredqian 0:5f1d66c85ae0 100 #ifdef SR_MAX_FRAME_RETRES
fredqian 0:5f1d66c85ae0 101 trx_bit_write(SR_MAX_FRAME_RETRES,autoretrycount & 0Xf);//for auto wake up
fredqian 0:5f1d66c85ae0 102 //////////////////////////////
fredqian 0:5f1d66c85ae0 103 #endif
fredqian 0:5f1d66c85ae0 104
fredqian 0:5f1d66c85ae0 105
fredqian 0:5f1d66c85ae0 106 if(!needack)
fredqian 0:5f1d66c85ae0 107 txTmpBuffer[0] = 0x41;
fredqian 0:5f1d66c85ae0 108 else
fredqian 0:5f1d66c85ae0 109 txTmpBuffer[0] = 0x61; //ack required
fredqian 0:5f1d66c85ae0 110 txTmpBuffer[1] = 0x88;
fredqian 0:5f1d66c85ae0 111 txTmpBuffer[2] = 0;
fredqian 0:5f1d66c85ae0 112 txTmpBuffer[3]=(uint8_t)(panid & 0xFF );
fredqian 0:5f1d66c85ae0 113 txTmpBuffer[4]=(uint8_t)((panid>>8) & 0xFF );
fredqian 0:5f1d66c85ae0 114 txTmpBuffer[5] = 0xFF; //dest address low byte
fredqian 0:5f1d66c85ae0 115 txTmpBuffer[6] = 0xFF; //dest address hight byte
fredqian 0:5f1d66c85ae0 116 txTmpBuffer[7] = (uint8_t)(localaddress & 0xFF );
fredqian 0:5f1d66c85ae0 117 txTmpBuffer[8] = (uint8_t)((localaddress>>8) & 0xFF );
fredqian 0:5f1d66c85ae0 118 setParam(phyPanId,(uint16_t)panid );
fredqian 0:5f1d66c85ae0 119 setParam(phyShortAddr,(uint16_t)localaddress );
fredqian 0:5f1d66c85ae0 120
fredqian 0:5f1d66c85ae0 121 radio_set_param(RP_CHANNEL(chan));
fredqian 0:5f1d66c85ae0 122
fredqian 0:5f1d66c85ae0 123 // default to receiver
fredqian 0:5f1d66c85ae0 124 if (setautorx)
fredqian 0:5f1d66c85ae0 125 radio_set_state(STATE_RXAUTO);
fredqian 0:5f1d66c85ae0 126 else
fredqian 0:5f1d66c85ae0 127 radio_set_state(STATE_RX);
fredqian 0:5f1d66c85ae0 128 #ifdef ENABLE_DIG3_DIG4
fredqian 0:5f1d66c85ae0 129 trx_bit_write(SR_PA_EXT_EN, 1);
fredqian 0:5f1d66c85ae0 130 #endif
fredqian 0:5f1d66c85ae0 131 }
fredqian 0:5f1d66c85ae0 132 void cMxRadio::begin(channel_t chan,uint16_t panid,uint16_t localaddress,bool needackval,bool autotxval,bool autorxval)
fredqian 0:5f1d66c85ae0 133 {
fredqian 0:5f1d66c85ae0 134 cMxRadio::begin(chan,panid,localaddress,needackval,autotxval,autorxval,4);
fredqian 0:5f1d66c85ae0 135
fredqian 0:5f1d66c85ae0 136 }
fredqian 0:5f1d66c85ae0 137 void cMxRadio::sendFrame(uint16_t destaddress,bool needackval,uint8_t* frm, uint8_t len)
fredqian 0:5f1d66c85ae0 138 {
fredqian 0:5f1d66c85ae0 139 uint8_t oldvalue=txTmpBuffer[0];
fredqian 0:5f1d66c85ae0 140 if(!needackval)
fredqian 0:5f1d66c85ae0 141 txTmpBuffer[0] = 0x41;
fredqian 0:5f1d66c85ae0 142 else
fredqian 0:5f1d66c85ae0 143 txTmpBuffer[0] = 0x61;
fredqian 0:5f1d66c85ae0 144 beginTransmission(destaddress);
fredqian 0:5f1d66c85ae0 145 write(frm,len);
fredqian 0:5f1d66c85ae0 146 endTransmission();
fredqian 0:5f1d66c85ae0 147 txTmpBuffer[0]=oldvalue;
fredqian 0:5f1d66c85ae0 148
fredqian 0:5f1d66c85ae0 149 }
fredqian 0:5f1d66c85ae0 150 /**
fredqian 0:5f1d66c85ae0 151 * @brief Radio Initialization
fredqian 0:5f1d66c85ae0 152 *
fredqian 0:5f1d66c85ae0 153 * Overload for radio initalization that allows for the user to set a custom frame header
fredqian 0:5f1d66c85ae0 154 *
fredqian 0:5f1d66c85ae0 155 * @param chan channel number for the radio to use, 11 to 26
fredqian 0:5f1d66c85ae0 156 * @param frameHeader HeadSize byte custom frame header
fredqian 0:5f1d66c85ae0 157 */
fredqian 0:5f1d66c85ae0 158 void cMxRadio::begin(channel_t chan, uint8_t* frameHeader)
fredqian 0:5f1d66c85ae0 159 {
fredqian 0:5f1d66c85ae0 160 radio_init(rxFrameBuffer, MAX_FRAME_SIZE);
fredqian 0:5f1d66c85ae0 161
fredqian 0:5f1d66c85ae0 162 if (frameHeader)
fredqian 0:5f1d66c85ae0 163 {
fredqian 0:5f1d66c85ae0 164 // copy custom frame header
fredqian 0:5f1d66c85ae0 165 int i;
fredqian 0:5f1d66c85ae0 166 for (i = 0; i < HeadSize; i++)
fredqian 0:5f1d66c85ae0 167 txTmpBuffer[i] = frameHeader[i];
fredqian 0:5f1d66c85ae0 168 }
fredqian 0:5f1d66c85ae0 169 else
fredqian 0:5f1d66c85ae0 170 {
fredqian 0:5f1d66c85ae0 171 txTmpBuffer[0] = 0x41;
fredqian 0:5f1d66c85ae0 172 txTmpBuffer[1] = 0x88;
fredqian 0:5f1d66c85ae0 173 txTmpBuffer[2] = 0;
fredqian 0:5f1d66c85ae0 174 txTmpBuffer[3]=0xCD;
fredqian 0:5f1d66c85ae0 175 txTmpBuffer[4]=0xAB;
fredqian 0:5f1d66c85ae0 176 txTmpBuffer[5] = 0xFF; //dest address low byte
fredqian 0:5f1d66c85ae0 177 txTmpBuffer[6] = 0xFF; //dest address hight byte
fredqian 0:5f1d66c85ae0 178 txTmpBuffer[7] = 0x01;;
fredqian 0:5f1d66c85ae0 179 txTmpBuffer[8] = 0x00;;
fredqian 0:5f1d66c85ae0 180 }
fredqian 0:5f1d66c85ae0 181
fredqian 0:5f1d66c85ae0 182 // set the channel
fredqian 0:5f1d66c85ae0 183 radio_set_param(RP_CHANNEL(chan));
fredqian 0:5f1d66c85ae0 184
fredqian 0:5f1d66c85ae0 185 // default to receiver
fredqian 0:5f1d66c85ae0 186 if (setautorx)
fredqian 0:5f1d66c85ae0 187 radio_set_state(STATE_RXAUTO);
fredqian 0:5f1d66c85ae0 188 else
fredqian 0:5f1d66c85ae0 189 radio_set_state(STATE_RX);
fredqian 0:5f1d66c85ae0 190
fredqian 0:5f1d66c85ae0 191 #ifdef ENABLE_DIG3_DIG4
fredqian 0:5f1d66c85ae0 192 trx_bit_write(SR_PA_EXT_EN, 1);
fredqian 0:5f1d66c85ae0 193 #endif
fredqian 0:5f1d66c85ae0 194
fredqian 0:5f1d66c85ae0 195 }
fredqian 0:5f1d66c85ae0 196
fredqian 0:5f1d66c85ae0 197 /**
fredqian 0:5f1d66c85ae0 198 * @brief Set Frame Header
fredqian 0:5f1d66c85ae0 199 *
fredqian 0:5f1d66c85ae0 200 * changes the custom frame header
fredqian 0:5f1d66c85ae0 201 *
fredqian 0:5f1d66c85ae0 202 * @param frameHeader HeadSize byte custom frame header
fredqian 0:5f1d66c85ae0 203 */
fredqian 0:5f1d66c85ae0 204 void cMxRadio::setFrameHeader(uint8_t* frameHeader)
fredqian 0:5f1d66c85ae0 205 {
fredqian 0:5f1d66c85ae0 206 // copy custom frame header
fredqian 0:5f1d66c85ae0 207 int i;
fredqian 0:5f1d66c85ae0 208 for (i = 0; i < HeadSize; i++)
fredqian 0:5f1d66c85ae0 209 txTmpBuffer[i] = frameHeader[i];
fredqian 0:5f1d66c85ae0 210 }
fredqian 0:5f1d66c85ae0 211
fredqian 0:5f1d66c85ae0 212 /**
fredqian 0:5f1d66c85ae0 213 * @brief Attach Error Event Handler
fredqian 0:5f1d66c85ae0 214 *
fredqian 0:5f1d66c85ae0 215 * Allows the user to set a error handling function
fredqian 0:5f1d66c85ae0 216 * An empty one is used if none is set
fredqian 0:5f1d66c85ae0 217 *
fredqian 0:5f1d66c85ae0 218 * @param funct the function pointer to the event handler
fredqian 0:5f1d66c85ae0 219 */
fredqian 0:5f1d66c85ae0 220 void cMxRadio::attachError(void (*funct)(radio_error_t))
fredqian 0:5f1d66c85ae0 221 {
fredqian 0:5f1d66c85ae0 222 user_radio_error = funct;
fredqian 0:5f1d66c85ae0 223 }
fredqian 0:5f1d66c85ae0 224
fredqian 0:5f1d66c85ae0 225 /**
fredqian 0:5f1d66c85ae0 226 * @brief Attach IRQ Event Handler
fredqian 0:5f1d66c85ae0 227 *
fredqian 0:5f1d66c85ae0 228 * Allows the user to set a IRQ handling function
fredqian 0:5f1d66c85ae0 229 * An empty one is used if none is set
fredqian 0:5f1d66c85ae0 230 *
fredqian 0:5f1d66c85ae0 231 * @param funct the function pointer to the event handler
fredqian 0:5f1d66c85ae0 232 */
fredqian 0:5f1d66c85ae0 233 void cMxRadio::attachIrq(void (*funct)(uint8_t))
fredqian 0:5f1d66c85ae0 234 {
fredqian 0:5f1d66c85ae0 235 user_radio_irq = funct;
fredqian 0:5f1d66c85ae0 236 }
fredqian 0:5f1d66c85ae0 237
fredqian 0:5f1d66c85ae0 238 /**
fredqian 0:5f1d66c85ae0 239 * @brief Attach RX Event Handler
fredqian 0:5f1d66c85ae0 240 *
fredqian 0:5f1d66c85ae0 241 * Allows the user to set a RX handling function
fredqian 0:5f1d66c85ae0 242 * The default handler will read in the received frame and place it into the RX FIFO ring buffer
fredqian 0:5f1d66c85ae0 243 * If the user chooses to use this attach function, then the default handler will not be used
fredqian 0:5f1d66c85ae0 244 * This means read/peek/available/flush will stop working
fredqian 0:5f1d66c85ae0 245 *
fredqian 0:5f1d66c85ae0 246 * @param funct the function pointer to the event handler
fredqian 0:5f1d66c85ae0 247 */
fredqian 0:5f1d66c85ae0 248 void cMxRadio::attachReceiveFrame(uint8_t* (*funct)(uint8_t, uint8_t*, uint8_t,int8_t, uint8_t))
fredqian 0:5f1d66c85ae0 249 {
fredqian 0:5f1d66c85ae0 250 zrEventReceiveFrame = funct;
fredqian 0:5f1d66c85ae0 251 hasAttachedRxEvent = (funct == 0) ? 0 : 1;
fredqian 0:5f1d66c85ae0 252 }
fredqian 0:5f1d66c85ae0 253
fredqian 0:5f1d66c85ae0 254 /**
fredqian 0:5f1d66c85ae0 255 * @brief Attach TX Complete Event Handler
fredqian 0:5f1d66c85ae0 256 *
fredqian 0:5f1d66c85ae0 257 * Allows the user to set a TX complete handling function
fredqian 0:5f1d66c85ae0 258 * An empty one is used if none is set
fredqian 0:5f1d66c85ae0 259 * The event will occur before the busy flag is reset and returning to RX state
fredqian 0:5f1d66c85ae0 260 *
fredqian 0:5f1d66c85ae0 261 * @param funct the function pointer to the event handler
fredqian 0:5f1d66c85ae0 262 */
fredqian 0:5f1d66c85ae0 263 void cMxRadio::attachTxDone(void (*funct)(radio_tx_done_t))
fredqian 0:5f1d66c85ae0 264 {
fredqian 0:5f1d66c85ae0 265 zrEventTxDone = funct;
fredqian 0:5f1d66c85ae0 266 hasAttachedTxEvent = (funct == 0) ? 0 : 1;
fredqian 0:5f1d66c85ae0 267 }
fredqian 0:5f1d66c85ae0 268
fredqian 0:5f1d66c85ae0 269 /**
fredqian 0:5f1d66c85ae0 270 * @brief Default RX Event Handler
fredqian 0:5f1d66c85ae0 271 *
fredqian 0:5f1d66c85ae0 272 * If the user has not attached a custom event handler, then the bytes are placed into the FIFO ring buffer
fredqian 0:5f1d66c85ae0 273 * If the frame contains a header, then the frame header is ignored, only the payload is read
fredqian 0:5f1d66c85ae0 274 * The above does not occur if a user handler is attached, which will be called instead
fredqian 0:5f1d66c85ae0 275 * The LQI and RSSI is always remembered
fredqian 0:5f1d66c85ae0 276 *
fredqian 0:5f1d66c85ae0 277 * This should not be called by the user
fredqian 0:5f1d66c85ae0 278 *
fredqian 0:5f1d66c85ae0 279 * @param len length of the frame
fredqian 0:5f1d66c85ae0 280 * @param frm array containing frame data
fredqian 0:5f1d66c85ae0 281 * @param lqi link quality indicator
fredqian 0:5f1d66c85ae0 282 * @param crc_fail boolean indicating whether the received frame failed FCS verification, not used
fredqian 0:5f1d66c85ae0 283 */
fredqian 0:5f1d66c85ae0 284 uint8_t* cMxRadio::onReceiveFrame(uint8_t len, uint8_t* frm, uint8_t lqi, int8_t ed,uint8_t crc_fail)
fredqian 0:5f1d66c85ae0 285 {
fredqian 0:5f1d66c85ae0 286 if (crc_fail)
fredqian 0:5f1d66c85ae0 287 return rxRingBuffer;
fredqian 0:5f1d66c85ae0 288 lastLqi = lqi;
fredqian 0:5f1d66c85ae0 289 //lastRssi=ed;
fredqian 0:5f1d66c85ae0 290 if (hasAttachedRxEvent == 0)
fredqian 0:5f1d66c85ae0 291 {
fredqian 0:5f1d66c85ae0 292 // no event handler, so write it into the FIFO
fredqian 0:5f1d66c85ae0 293
fredqian 0:5f1d66c85ae0 294 if (len >= HeadSize-1)
fredqian 0:5f1d66c85ae0 295 {
fredqian 0:5f1d66c85ae0 296 // frame header exists
fredqian 0:5f1d66c85ae0 297 // copy only payload
fredqian 0:5f1d66c85ae0 298
fredqian 0:5f1d66c85ae0 299 for (uint8_t i = HeadSize; i < len - 2; i++)
fredqian 0:5f1d66c85ae0 300 {
fredqian 0:5f1d66c85ae0 301 uint16_t j = ((uint16_t)((uint16_t)rxRingBufferHead + 1)) % ZR_FIFO_SIZE;
fredqian 0:5f1d66c85ae0 302 if (j != rxRingBufferTail)
fredqian 0:5f1d66c85ae0 303 {
fredqian 0:5f1d66c85ae0 304 // push into FIFO
fredqian 0:5f1d66c85ae0 305 rxRingBuffer[rxRingBufferHead] = frm[i];
fredqian 0:5f1d66c85ae0 306 rxRingBufferHead = j;
fredqian 0:5f1d66c85ae0 307 }
fredqian 0:5f1d66c85ae0 308 else
fredqian 0:5f1d66c85ae0 309 {
fredqian 0:5f1d66c85ae0 310 // FIFO full
fredqian 0:5f1d66c85ae0 311 break;
fredqian 0:5f1d66c85ae0 312 }
fredqian 0:5f1d66c85ae0 313 }
fredqian 0:5f1d66c85ae0 314 }
fredqian 0:5f1d66c85ae0 315 else
fredqian 0:5f1d66c85ae0 316 {
fredqian 0:5f1d66c85ae0 317 // frame header does not exist
fredqian 0:5f1d66c85ae0 318 // copy everything
fredqian 0:5f1d66c85ae0 319
fredqian 0:5f1d66c85ae0 320 for (uint8_t i = 0; i < len; i++)
fredqian 0:5f1d66c85ae0 321 {
fredqian 0:5f1d66c85ae0 322 uint16_t j = ((uint16_t)((uint16_t)rxRingBufferHead + 1)) % ZR_FIFO_SIZE;
fredqian 0:5f1d66c85ae0 323 if (j != rxRingBufferTail)
fredqian 0:5f1d66c85ae0 324 {
fredqian 0:5f1d66c85ae0 325 // push into FIFO
fredqian 0:5f1d66c85ae0 326 rxRingBuffer[rxRingBufferHead] = frm[i];
fredqian 0:5f1d66c85ae0 327 rxRingBufferHead = j;
fredqian 0:5f1d66c85ae0 328 }
fredqian 0:5f1d66c85ae0 329 else
fredqian 0:5f1d66c85ae0 330 {
fredqian 0:5f1d66c85ae0 331 // FIFO full
fredqian 0:5f1d66c85ae0 332 break;
fredqian 0:5f1d66c85ae0 333 }
fredqian 0:5f1d66c85ae0 334 }
fredqian 0:5f1d66c85ae0 335 }
fredqian 0:5f1d66c85ae0 336
fredqian 0:5f1d66c85ae0 337 return rxRingBuffer;
fredqian 0:5f1d66c85ae0 338 }
fredqian 0:5f1d66c85ae0 339 else
fredqian 0:5f1d66c85ae0 340 {
fredqian 0:5f1d66c85ae0 341 // user event is attached so call it
fredqian 0:5f1d66c85ae0 342 return zrEventReceiveFrame(len, frm, lqi, ed,crc_fail);
fredqian 0:5f1d66c85ae0 343 }
fredqian 0:5f1d66c85ae0 344 }
fredqian 0:5f1d66c85ae0 345
fredqian 0:5f1d66c85ae0 346 /**
fredqian 0:5f1d66c85ae0 347 * @brief RX Buffer Flush
fredqian 0:5f1d66c85ae0 348 *
fredqian 0:5f1d66c85ae0 349 * Flush the RX FIFO ring buffer
fredqian 0:5f1d66c85ae0 350 */
fredqian 0:5f1d66c85ae0 351 void cMxRadio::flush()
fredqian 0:5f1d66c85ae0 352 {
fredqian 0:5f1d66c85ae0 353 rxRingBufferHead = rxRingBufferTail;
fredqian 0:5f1d66c85ae0 354 }
fredqian 0:5f1d66c85ae0 355
fredqian 0:5f1d66c85ae0 356 /**
fredqian 0:5f1d66c85ae0 357 * @brief RX Buffer Read
fredqian 0:5f1d66c85ae0 358 *
fredqian 0:5f1d66c85ae0 359 * pops and returns the next byte from the FIFO ring buffer
fredqian 0:5f1d66c85ae0 360 *
fredqian 0:5f1d66c85ae0 361 * @return the next byte, or -1 if buffer is empty
fredqian 0:5f1d66c85ae0 362 */
fredqian 0:5f1d66c85ae0 363 int16_t cMxRadio::read()
fredqian 0:5f1d66c85ae0 364 {
fredqian 0:5f1d66c85ae0 365 // if the head isn't ahead of the tail, we don't have any characters
fredqian 0:5f1d66c85ae0 366 if (rxRingBufferHead == rxRingBufferTail)
fredqian 0:5f1d66c85ae0 367 {
fredqian 0:5f1d66c85ae0 368 return -1;
fredqian 0:5f1d66c85ae0 369 }
fredqian 0:5f1d66c85ae0 370 else
fredqian 0:5f1d66c85ae0 371 {
fredqian 0:5f1d66c85ae0 372 uint8_t c = rxRingBuffer[rxRingBufferTail];
fredqian 0:5f1d66c85ae0 373 rxRingBufferTail = (rxRingBufferTail + 1) % ZR_FIFO_SIZE; // pop
fredqian 0:5f1d66c85ae0 374 return c;
fredqian 0:5f1d66c85ae0 375 }
fredqian 0:5f1d66c85ae0 376 }
fredqian 0:5f1d66c85ae0 377
fredqian 0:5f1d66c85ae0 378 /**
fredqian 0:5f1d66c85ae0 379 * @brief RX Buffer Peek
fredqian 0:5f1d66c85ae0 380 *
fredqian 0:5f1d66c85ae0 381 * returns the next byte from the FIFO ring buffer without removing it
fredqian 0:5f1d66c85ae0 382 *
fredqian 0:5f1d66c85ae0 383 * @return the next byte, or -1 if buffer is empty
fredqian 0:5f1d66c85ae0 384 */
fredqian 0:5f1d66c85ae0 385 int16_t cMxRadio::peek()
fredqian 0:5f1d66c85ae0 386 {
fredqian 0:5f1d66c85ae0 387 // if the head isn't ahead of the tail, we don't have any characters
fredqian 0:5f1d66c85ae0 388 if (rxRingBufferHead == rxRingBufferTail)
fredqian 0:5f1d66c85ae0 389 {
fredqian 0:5f1d66c85ae0 390 return -1;
fredqian 0:5f1d66c85ae0 391 }
fredqian 0:5f1d66c85ae0 392 else
fredqian 0:5f1d66c85ae0 393 {
fredqian 0:5f1d66c85ae0 394 uint8_t c = rxRingBuffer[rxRingBufferTail];
fredqian 0:5f1d66c85ae0 395 return c;
fredqian 0:5f1d66c85ae0 396 }
fredqian 0:5f1d66c85ae0 397 }
fredqian 0:5f1d66c85ae0 398
fredqian 0:5f1d66c85ae0 399 /**
fredqian 0:5f1d66c85ae0 400 * @brief RX Buffer Size
fredqian 0:5f1d66c85ae0 401 *
fredqian 0:5f1d66c85ae0 402 * Shows how many bytes are in the RX FIFO ring buffer
fredqian 0:5f1d66c85ae0 403 *
fredqian 0:5f1d66c85ae0 404 * @return how many bytes are in the RX FIFO ring buffer
fredqian 0:5f1d66c85ae0 405 */
fredqian 0:5f1d66c85ae0 406 int8_t cMxRadio::available()
fredqian 0:5f1d66c85ae0 407 {
fredqian 0:5f1d66c85ae0 408 return ((int16_t)((int16_t)ZR_FIFO_SIZE + (int16_t)rxRingBufferHead - (int16_t)rxRingBufferTail)) % ZR_FIFO_SIZE;
fredqian 0:5f1d66c85ae0 409 }
fredqian 0:5f1d66c85ae0 410
fredqian 0:5f1d66c85ae0 411 /**
fredqian 0:5f1d66c85ae0 412 * @brief Raw Frame Transmit
fredqian 0:5f1d66c85ae0 413 *
fredqian 0:5f1d66c85ae0 414 * Transmits a frame
fredqian 0:5f1d66c85ae0 415 * Warning: no frame header or FCS is added
fredqian 0:5f1d66c85ae0 416 *
fredqian 0:5f1d66c85ae0 417 * @param frm array containing frame data
fredqian 0:5f1d66c85ae0 418 * @param len length of the frame
fredqian 0:5f1d66c85ae0 419 */
fredqian 0:5f1d66c85ae0 420 void cMxRadio::txFrame(uint8_t* frm, uint8_t len)
fredqian 0:5f1d66c85ae0 421 {
fredqian 0:5f1d66c85ae0 422 #ifdef ZR_TXWAIT_BEFORE
fredqian 0:5f1d66c85ae0 423 waitTxDone(0xFFFF);
fredqian 0:5f1d66c85ae0 424 #endif
fredqian 0:5f1d66c85ae0 425 txIsBusy = 1;
fredqian 0:5f1d66c85ae0 426 if (setautotx)
fredqian 0:5f1d66c85ae0 427 radio_set_state(STATE_TXAUTO);
fredqian 0:5f1d66c85ae0 428 else
fredqian 0:5f1d66c85ae0 429 radio_set_state(STATE_TX);
fredqian 0:5f1d66c85ae0 430 ZR_RFTX_LED_ON();
fredqian 0:5f1d66c85ae0 431 radio_send_frame(len, frm, 0);
fredqian 0:5f1d66c85ae0 432 #ifdef ZR_TXWAIT_AFTER
fredqian 0:5f1d66c85ae0 433 waitTxDone(0xFFFF);
fredqian 0:5f1d66c85ae0 434 if (setautorx)
fredqian 0:5f1d66c85ae0 435 radio_set_state(STATE_RXAUTO);
fredqian 0:5f1d66c85ae0 436 else
fredqian 0:5f1d66c85ae0 437 radio_set_state(STATE_RX);
fredqian 0:5f1d66c85ae0 438 txIsBusy = 0;
fredqian 0:5f1d66c85ae0 439 #endif
fredqian 0:5f1d66c85ae0 440 }
fredqian 0:5f1d66c85ae0 441
fredqian 0:5f1d66c85ae0 442 /**
fredqian 0:5f1d66c85ae0 443 * @brief Prepare for Trasmission
fredqian 0:5f1d66c85ae0 444 *
fredqian 0:5f1d66c85ae0 445 * Goes into non-immediate transmit mode, resets the transmit payload
fredqian 0:5f1d66c85ae0 446 * Non-immediate mode sends multiple bytes per frame
fredqian 0:5f1d66c85ae0 447 *
fredqian 0:5f1d66c85ae0 448 */
fredqian 0:5f1d66c85ae0 449 void cMxRadio::beginTransmission()
fredqian 0:5f1d66c85ae0 450 {
fredqian 0:5f1d66c85ae0 451 usedBeginTransmission = 1;
fredqian 0:5f1d66c85ae0 452 txTmpBuffer[5]= 0xFF;
fredqian 0:5f1d66c85ae0 453 txTmpBuffer[6]= 0XFF;
fredqian 0:5f1d66c85ae0 454 // add frame header
fredqian 0:5f1d66c85ae0 455 txTmpBufferLength = HeadSize;
fredqian 0:5f1d66c85ae0 456 }
fredqian 0:5f1d66c85ae0 457
fredqian 0:5f1d66c85ae0 458 void cMxRadio::beginTransmission(uint16_t destaddress)
fredqian 0:5f1d66c85ae0 459 {
fredqian 0:5f1d66c85ae0 460 txTmpBuffer[5]=(uint8_t)(destaddress & 0xFF );
fredqian 0:5f1d66c85ae0 461 txTmpBuffer[6]=(uint8_t)((destaddress>>8) & 0xFF );
fredqian 0:5f1d66c85ae0 462 usedBeginTransmission = 1;
fredqian 0:5f1d66c85ae0 463
fredqian 0:5f1d66c85ae0 464 // add frame header
fredqian 0:5f1d66c85ae0 465 txTmpBufferLength = HeadSize;
fredqian 0:5f1d66c85ae0 466 }
fredqian 0:5f1d66c85ae0 467
fredqian 0:5f1d66c85ae0 468 /**
fredqian 0:5f1d66c85ae0 469 * @brief Finalize Trasmission
fredqian 0:5f1d66c85ae0 470 *
fredqian 0:5f1d66c85ae0 471 * Finalize the payload and transmits it when ready
fredqian 0:5f1d66c85ae0 472 *
fredqian 0:5f1d66c85ae0 473 */
fredqian 0:5f1d66c85ae0 474 void cMxRadio::endTransmission()
fredqian 0:5f1d66c85ae0 475 {
fredqian 0:5f1d66c85ae0 476 usedBeginTransmission = 0;
fredqian 0:5f1d66c85ae0 477
fredqian 0:5f1d66c85ae0 478 // empty FCS field
fredqian 0:5f1d66c85ae0 479 txTmpBufferLength += 2;
fredqian 0:5f1d66c85ae0 480
fredqian 0:5f1d66c85ae0 481 #ifdef ZR_TXWAIT_BEFORE
fredqian 0:5f1d66c85ae0 482 waitTxDone(0xFFFF);
fredqian 0:5f1d66c85ae0 483 #endif
fredqian 0:5f1d66c85ae0 484 txIsBusy = 1;
fredqian 0:5f1d66c85ae0 485 if (setautotx)
fredqian 0:5f1d66c85ae0 486 radio_set_state(STATE_TXAUTO);
fredqian 0:5f1d66c85ae0 487 else
fredqian 0:5f1d66c85ae0 488 radio_set_state(STATE_TX);
fredqian 0:5f1d66c85ae0 489 ZR_RFTX_LED_ON();
fredqian 0:5f1d66c85ae0 490 //if broadcase ,cant need ack
fredqian 0:5f1d66c85ae0 491 if(txTmpBuffer[5]==0xff && txTmpBuffer[5]==0xff)
fredqian 0:5f1d66c85ae0 492 txTmpBuffer[0]=txTmpBuffer[0]&0xdf;
fredqian 0:5f1d66c85ae0 493 else
fredqian 0:5f1d66c85ae0 494 {
fredqian 0:5f1d66c85ae0 495 if(!needack)
fredqian 0:5f1d66c85ae0 496 txTmpBuffer[0] = 0x41;
fredqian 0:5f1d66c85ae0 497 else
fredqian 0:5f1d66c85ae0 498 txTmpBuffer[0] = 0x61; //ack required
fredqian 0:5f1d66c85ae0 499 }
fredqian 0:5f1d66c85ae0 500 radio_send_frame(txTmpBufferLength, txTmpBuffer, 0);
fredqian 0:5f1d66c85ae0 501 #ifdef ZR_TXWAIT_AFTER
fredqian 0:5f1d66c85ae0 502 waitTxDone(0xFFFF);
fredqian 0:5f1d66c85ae0 503 if (setautorx)
fredqian 0:5f1d66c85ae0 504 radio_set_state(STATE_RXAUTO);
fredqian 0:5f1d66c85ae0 505 else
fredqian 0:5f1d66c85ae0 506 radio_set_state(STATE_RX);
fredqian 0:5f1d66c85ae0 507 txIsBusy = 0;
fredqian 0:5f1d66c85ae0 508 #endif
fredqian 0:5f1d66c85ae0 509 }
fredqian 0:5f1d66c85ae0 510
fredqian 0:5f1d66c85ae0 511 /**
fredqian 0:5f1d66c85ae0 512 * @brief Cancel Trasmission
fredqian 0:5f1d66c85ae0 513 *
fredqian 0:5f1d66c85ae0 514 * Clears payload buffer
fredqian 0:5f1d66c85ae0 515 *
fredqian 0:5f1d66c85ae0 516 * Warning: does not actually cancel a transmission in progress
fredqian 0:5f1d66c85ae0 517 *
fredqian 0:5f1d66c85ae0 518 */
fredqian 0:5f1d66c85ae0 519 void cMxRadio::cancelTransmission()
fredqian 0:5f1d66c85ae0 520 {
fredqian 0:5f1d66c85ae0 521 usedBeginTransmission = 0;
fredqian 0:5f1d66c85ae0 522
fredqian 0:5f1d66c85ae0 523 // add frame header
fredqian 0:5f1d66c85ae0 524 txTmpBufferLength = HeadSize;
fredqian 0:5f1d66c85ae0 525 }
fredqian 0:5f1d66c85ae0 526 /**
fredqian 0:5f1d66c85ae0 527 * @brief TX a Byte
fredqian 0:5f1d66c85ae0 528 *
fredqian 0:5f1d66c85ae0 529 * Wrapper for "write", since the "Wire" library uses "send"
fredqian 0:5f1d66c85ae0 530 *
fredqian 0:5f1d66c85ae0 531 */
fredqian 0:5f1d66c85ae0 532 void cMxRadio::send(uint8_t c)
fredqian 0:5f1d66c85ae0 533 {
fredqian 0:5f1d66c85ae0 534 write(c);
fredqian 0:5f1d66c85ae0 535 }
fredqian 0:5f1d66c85ae0 536
fredqian 0:5f1d66c85ae0 537 /**
fredqian 0:5f1d66c85ae0 538 * @brief TX a Byte
fredqian 0:5f1d66c85ae0 539 *
fredqian 0:5f1d66c85ae0 540 * If "beginTrasmission" was used, then it writes into the transmit buffer for non-immediate mode
fredqian 0:5f1d66c85ae0 541 * If "beginTrasmission" was not used, then it transmits the single byte immediately (slower for multiple bytes)
fredqian 0:5f1d66c85ae0 542 *
fredqian 0:5f1d66c85ae0 543 * @param c character to be sent
fredqian 0:5f1d66c85ae0 544 */
fredqian 0:5f1d66c85ae0 545 void cMxRadio::write(uint8_t c)
fredqian 0:5f1d66c85ae0 546 {
fredqian 0:5f1d66c85ae0 547 if (usedBeginTransmission)
fredqian 0:5f1d66c85ae0 548 {
fredqian 0:5f1d66c85ae0 549 if (txTmpBufferLength < ZR_TXTMPBUFF_SIZE - 2)
fredqian 0:5f1d66c85ae0 550 {
fredqian 0:5f1d66c85ae0 551 txTmpBuffer[txTmpBufferLength] = c;
fredqian 0:5f1d66c85ae0 552 txTmpBufferLength++;
fredqian 0:5f1d66c85ae0 553
fredqian 0:5f1d66c85ae0 554 if (txTmpBufferLength >= ZR_TXTMPBUFF_SIZE - 2)
fredqian 0:5f1d66c85ae0 555 {
fredqian 0:5f1d66c85ae0 556 // buffer is now full
fredqian 0:5f1d66c85ae0 557 // just send it all out so we have more room
fredqian 0:5f1d66c85ae0 558 endTransmission();
fredqian 0:5f1d66c85ae0 559 beginTransmission();
fredqian 0:5f1d66c85ae0 560 }
fredqian 0:5f1d66c85ae0 561 }
fredqian 0:5f1d66c85ae0 562 }
fredqian 0:5f1d66c85ae0 563 else
fredqian 0:5f1d66c85ae0 564 {
fredqian 0:5f1d66c85ae0 565 txTmpBuffer[HeadSize] = c; // set payload
fredqian 0:5f1d66c85ae0 566 txTmpBuffer[HeadSize+1] = 0; // empty FCS
fredqian 0:5f1d66c85ae0 567 txTmpBuffer[HeadSize+2] = 0; // empty FCS
fredqian 0:5f1d66c85ae0 568
fredqian 0:5f1d66c85ae0 569 #ifdef ZR_TXWAIT_BEFORE
fredqian 0:5f1d66c85ae0 570 waitTxDone(0xFFFF);
fredqian 0:5f1d66c85ae0 571 #endif
fredqian 0:5f1d66c85ae0 572 txIsBusy = 1;
fredqian 0:5f1d66c85ae0 573 if (setautotx)
fredqian 0:5f1d66c85ae0 574 radio_set_state(STATE_TXAUTO);
fredqian 0:5f1d66c85ae0 575 else
fredqian 0:5f1d66c85ae0 576 radio_set_state(STATE_TX);
fredqian 0:5f1d66c85ae0 577 ZR_RFTX_LED_ON();
fredqian 0:5f1d66c85ae0 578 radio_send_frame(10, txTmpBuffer, 0);
fredqian 0:5f1d66c85ae0 579 #ifdef ZR_TXWAIT_AFTER
fredqian 0:5f1d66c85ae0 580 waitTxDone(0xFFFF);
fredqian 0:5f1d66c85ae0 581 if (setautorx)
fredqian 0:5f1d66c85ae0 582 radio_set_state(STATE_RXAUTO);
fredqian 0:5f1d66c85ae0 583 else
fredqian 0:5f1d66c85ae0 584 radio_set_state(STATE_RX);
fredqian 0:5f1d66c85ae0 585 txIsBusy = 0;
fredqian 0:5f1d66c85ae0 586 #endif
fredqian 0:5f1d66c85ae0 587 }
fredqian 0:5f1d66c85ae0 588 }
fredqian 0:5f1d66c85ae0 589 /**
fredqian 0:5f1d66c85ae0 590 * @brief TX a String
fredqian 0:5f1d66c85ae0 591 *
fredqian 0:5f1d66c85ae0 592 * A overload for "write" that sends a null-terminated string
fredqian 0:5f1d66c85ae0 593 *
fredqian 0:5f1d66c85ae0 594 * @param str null-terminated string to be sent
fredqian 0:5f1d66c85ae0 595 */
fredqian 0:5f1d66c85ae0 596 void cMxRadio::write(char* str)
fredqian 0:5f1d66c85ae0 597 {
fredqian 0:5f1d66c85ae0 598 while (*str)
fredqian 0:5f1d66c85ae0 599 write(*str++);
fredqian 0:5f1d66c85ae0 600 }
fredqian 0:5f1d66c85ae0 601
fredqian 0:5f1d66c85ae0 602 /**
fredqian 0:5f1d66c85ae0 603 * @brief TX an Array
fredqian 0:5f1d66c85ae0 604 *
fredqian 0:5f1d66c85ae0 605 * A overload for "write" that sends an array
fredqian 0:5f1d66c85ae0 606 *
fredqian 0:5f1d66c85ae0 607 * @param arr data array to be sent
fredqian 0:5f1d66c85ae0 608 * @param len length of data array
fredqian 0:5f1d66c85ae0 609 */
fredqian 0:5f1d66c85ae0 610 void cMxRadio::write(uint8_t* arr, uint8_t len)
fredqian 0:5f1d66c85ae0 611 {
fredqian 0:5f1d66c85ae0 612 uint8_t i;
fredqian 0:5f1d66c85ae0 613 for (i = 0; i < len; i++)
fredqian 0:5f1d66c85ae0 614 write(arr[i]);
fredqian 0:5f1d66c85ae0 615 }
fredqian 0:5f1d66c85ae0 616
fredqian 0:5f1d66c85ae0 617 /**
fredqian 0:5f1d66c85ae0 618 * @brief Default TX Complete Event Handler
fredqian 0:5f1d66c85ae0 619 *
fredqian 0:5f1d66c85ae0 620 * Calls the user event function if one is attached
fredqian 0:5f1d66c85ae0 621 * Clear the TX busy status flag
fredqian 0:5f1d66c85ae0 622 * Defaults back to RX state
fredqian 0:5f1d66c85ae0 623 *
fredqian 0:5f1d66c85ae0 624 * this should not be called by the user
fredqian 0:5f1d66c85ae0 625 *
fredqian 0:5f1d66c85ae0 626 * @param x one of the radio_tx_done_t enumerations indicating transmission success
fredqian 0:5f1d66c85ae0 627 */
fredqian 0:5f1d66c85ae0 628 void cMxRadio::onTxDone(radio_tx_done_t x)
fredqian 0:5f1d66c85ae0 629 {
fredqian 0:5f1d66c85ae0 630 if (hasAttachedTxEvent)
fredqian 0:5f1d66c85ae0 631 {
fredqian 0:5f1d66c85ae0 632 zrEventTxDone(x);
fredqian 0:5f1d66c85ae0 633 }
fredqian 0:5f1d66c85ae0 634
fredqian 0:5f1d66c85ae0 635 txIsBusy = 0;
fredqian 0:5f1d66c85ae0 636 }
fredqian 0:5f1d66c85ae0 637
fredqian 0:5f1d66c85ae0 638 /**
fredqian 0:5f1d66c85ae0 639 * @brief radio_set_param Wrapper
fredqian 0:5f1d66c85ae0 640 *
fredqian 0:5f1d66c85ae0 641 * set a radio parameter
fredqian 0:5f1d66c85ae0 642 *
fredqian 0:5f1d66c85ae0 643 * see radio.h for more info
fredqian 0:5f1d66c85ae0 644 */
fredqian 0:5f1d66c85ae0 645 void cMxRadio::setParam(radio_attribute_t attr, radio_param_t parm)
fredqian 0:5f1d66c85ae0 646 {
fredqian 0:5f1d66c85ae0 647 radio_set_param(attr, parm);
fredqian 0:5f1d66c85ae0 648 }
fredqian 0:5f1d66c85ae0 649
fredqian 0:5f1d66c85ae0 650 /**
fredqian 0:5f1d66c85ae0 651 * @brief radio_do_cca Wrapper
fredqian 0:5f1d66c85ae0 652 *
fredqian 0:5f1d66c85ae0 653 * perform CCA measure
fredqian 0:5f1d66c85ae0 654 *
fredqian 0:5f1d66c85ae0 655 * see radio.h for more info
fredqian 0:5f1d66c85ae0 656 */
fredqian 0:5f1d66c85ae0 657 radio_cca_t cMxRadio::doCca()
fredqian 0:5f1d66c85ae0 658 {
fredqian 0:5f1d66c85ae0 659 return radio_do_cca();
fredqian 0:5f1d66c85ae0 660 }
fredqian 0:5f1d66c85ae0 661
fredqian 0:5f1d66c85ae0 662 /**
fredqian 0:5f1d66c85ae0 663 * @brief Set Radio State Wrapper
fredqian 0:5f1d66c85ae0 664 *
fredqian 0:5f1d66c85ae0 665 * sets or forces the radio into a state
fredqian 0:5f1d66c85ae0 666 *
fredqian 0:5f1d66c85ae0 667 * see radio.h for more info
fredqian 0:5f1d66c85ae0 668 *
fredqian 0:5f1d66c85ae0 669 * @param state requested radio state
fredqian 0:5f1d66c85ae0 670 * @param force boolean indicating to force the state
fredqian 0:5f1d66c85ae0 671 */
fredqian 0:5f1d66c85ae0 672 void cMxRadio::setState(radio_state_t state, uint8_t force)
fredqian 0:5f1d66c85ae0 673 {
fredqian 0:5f1d66c85ae0 674 if (force)
fredqian 0:5f1d66c85ae0 675 radio_force_state(state);
fredqian 0:5f1d66c85ae0 676 else
fredqian 0:5f1d66c85ae0 677 radio_set_state(state);
fredqian 0:5f1d66c85ae0 678 }
fredqian 0:5f1d66c85ae0 679
fredqian 0:5f1d66c85ae0 680 /**
fredqian 0:5f1d66c85ae0 681 * @brief radio_set_state Wrapper
fredqian 0:5f1d66c85ae0 682 *
fredqian 0:5f1d66c85ae0 683 * bring the the radio in the requested state
fredqian 0:5f1d66c85ae0 684 *
fredqian 0:5f1d66c85ae0 685 * see radio.h for more info
fredqian 0:5f1d66c85ae0 686 */
fredqian 0:5f1d66c85ae0 687 void cMxRadio::setState(radio_state_t state)
fredqian 0:5f1d66c85ae0 688 {
fredqian 0:5f1d66c85ae0 689 radio_set_state(state);
fredqian 0:5f1d66c85ae0 690 }
fredqian 0:5f1d66c85ae0 691
fredqian 0:5f1d66c85ae0 692 /**
fredqian 0:5f1d66c85ae0 693 * @brief radio_set_state to STATE_RX
fredqian 0:5f1d66c85ae0 694 *
fredqian 0:5f1d66c85ae0 695 * bring the the radio in the requested state of STATE_RX
fredqian 0:5f1d66c85ae0 696 *
fredqian 0:5f1d66c85ae0 697 * the radio state does not return to STATE_RX automatically if ZR_TXWAIT_AFTER is not used
fredqian 0:5f1d66c85ae0 698 * thus why this is provided
fredqian 0:5f1d66c85ae0 699 *
fredqian 0:5f1d66c85ae0 700 * see radio.h for more info
fredqian 0:5f1d66c85ae0 701 */
fredqian 0:5f1d66c85ae0 702 void cMxRadio::setStateRx()
fredqian 0:5f1d66c85ae0 703 {
fredqian 0:5f1d66c85ae0 704 if (setautorx)
fredqian 0:5f1d66c85ae0 705 radio_set_state(STATE_RXAUTO);
fredqian 0:5f1d66c85ae0 706 else
fredqian 0:5f1d66c85ae0 707 radio_set_state(STATE_RX);
fredqian 0:5f1d66c85ae0 708 }
fredqian 0:5f1d66c85ae0 709
fredqian 0:5f1d66c85ae0 710 /**
fredqian 0:5f1d66c85ae0 711 * @brief radio_force_state Wrapper
fredqian 0:5f1d66c85ae0 712 *
fredqian 0:5f1d66c85ae0 713 * force the radio to the requested state
fredqian 0:5f1d66c85ae0 714 *
fredqian 0:5f1d66c85ae0 715 * see radio.h for more info
fredqian 0:5f1d66c85ae0 716 */
fredqian 0:5f1d66c85ae0 717 void cMxRadio::forceState(radio_state_t state)
fredqian 0:5f1d66c85ae0 718 {
fredqian 0:5f1d66c85ae0 719 radio_force_state(state);
fredqian 0:5f1d66c85ae0 720 }
fredqian 0:5f1d66c85ae0 721
fredqian 0:5f1d66c85ae0 722 /**
fredqian 0:5f1d66c85ae0 723 * @brief Sets Radio Channel
fredqian 0:5f1d66c85ae0 724 *
fredqian 0:5f1d66c85ae0 725 * changes the radio channel by setting the radio channel state
fredqian 0:5f1d66c85ae0 726 *
fredqian 0:5f1d66c85ae0 727 * @param chan channel number, 11 to 26
fredqian 0:5f1d66c85ae0 728 */
fredqian 0:5f1d66c85ae0 729 void cMxRadio::setChannel(channel_t chan)
fredqian 0:5f1d66c85ae0 730 {
fredqian 0:5f1d66c85ae0 731 radio_set_param(RP_CHANNEL(chan));
fredqian 0:5f1d66c85ae0 732 }
fredqian 0:5f1d66c85ae0 733 uint8_t cMxRadio::getChannel()
fredqian 0:5f1d66c85ae0 734 {
fredqian 0:5f1d66c85ae0 735 trx_param_t p;
fredqian 0:5f1d66c85ae0 736 trx_parms_get(&p);
fredqian 0:5f1d66c85ae0 737 channel_t chan= p.chan;
fredqian 0:5f1d66c85ae0 738 return (uint8_t)chan;
fredqian 0:5f1d66c85ae0 739 }
fredqian 0:5f1d66c85ae0 740
fredqian 0:5f1d66c85ae0 741
fredqian 0:5f1d66c85ae0 742 /**
fredqian 0:5f1d66c85ae0 743 * @brief Read Receiver Signal Strength Indicator Now
fredqian 0:5f1d66c85ae0 744 *
fredqian 0:5f1d66c85ae0 745 * returns the current RSSI
fredqian 0:5f1d66c85ae0 746 *
fredqian 0:5f1d66c85ae0 747 * range is between -91 and -9 dBm
fredqian 0:5f1d66c85ae0 748 * where -9 is the best
fredqian 0:5f1d66c85ae0 749 *
fredqian 0:5f1d66c85ae0 750 * @return RSSI of the last transmission received
fredqian 0:5f1d66c85ae0 751 */
fredqian 0:5f1d66c85ae0 752 int8_t cMxRadio::getRssiNow()
fredqian 0:5f1d66c85ae0 753 {
fredqian 0:5f1d66c85ae0 754 int16_t rssi = ((int16_t)(trx_reg_read(RG_PHY_RSSI) & 0x1F)); // mask only important bits
fredqian 0:5f1d66c85ae0 755 rssi = (rssi == 0) ? (RSSI_BASE_VAL - 1) : ((rssi < 28) ? ((rssi - 1) * 3 + RSSI_BASE_VAL) : -9);
fredqian 0:5f1d66c85ae0 756 // if 0, then rssi < RSSI_BASE_VAL, if 28, then >= -10
fredqian 0:5f1d66c85ae0 757
fredqian 0:5f1d66c85ae0 758 return rssi;
fredqian 0:5f1d66c85ae0 759 }
fredqian 0:5f1d66c85ae0 760
fredqian 0:5f1d66c85ae0 761
fredqian 0:5f1d66c85ae0 762
fredqian 0:5f1d66c85ae0 763 /**
fredqian 0:5f1d66c85ae0 764 * @brief Read Last Receiver Signal Strength Indicator
fredqian 0:5f1d66c85ae0 765 *
fredqian 0:5f1d66c85ae0 766 * returns the RSSI of the last transmission
fredqian 0:5f1d66c85ae0 767 *
fredqian 0:5f1d66c85ae0 768 * range is between -91 and -9 dBm
fredqian 0:5f1d66c85ae0 769 * where -9 is the best
fredqian 0:5f1d66c85ae0 770 *
fredqian 0:5f1d66c85ae0 771 * @return RSSI of the last transmission received
fredqian 0:5f1d66c85ae0 772 */
fredqian 0:5f1d66c85ae0 773 int8_t cMxRadio::getLastRssi()
fredqian 0:5f1d66c85ae0 774 {
fredqian 0:5f1d66c85ae0 775 int16_t rssi = ((int16_t)(temprssi & 0x1F)); // mask only important bits
fredqian 0:5f1d66c85ae0 776 rssi = (rssi == 0) ? (RSSI_BASE_VAL - 1) : ((rssi < 28) ? ((rssi - 1) * 3 + RSSI_BASE_VAL) : -9);
fredqian 0:5f1d66c85ae0 777 // if 0, then rssi < RSSI_BASE_VAL, if 28, then >= -10
fredqian 0:5f1d66c85ae0 778
fredqian 0:5f1d66c85ae0 779 return rssi;
fredqian 0:5f1d66c85ae0 780 }
fredqian 0:5f1d66c85ae0 781
fredqian 0:5f1d66c85ae0 782
fredqian 0:5f1d66c85ae0 783 /**
fredqian 0:5f1d66c85ae0 784 * @brief Read Link Quality Indicator
fredqian 0:5f1d66c85ae0 785 *
fredqian 0:5f1d66c85ae0 786 * returns the LQI of the last transmission received
fredqian 0:5f1d66c85ae0 787 *
fredqian 0:5f1d66c85ae0 788 * range is from 0 to 255
fredqian 0:5f1d66c85ae0 789 * 255 is the best
fredqian 0:5f1d66c85ae0 790 *
fredqian 0:5f1d66c85ae0 791 * @return LQI of the last transmission received
fredqian 0:5f1d66c85ae0 792 */
fredqian 0:5f1d66c85ae0 793 uint8_t cMxRadio::getLqi()
fredqian 0:5f1d66c85ae0 794 {
fredqian 0:5f1d66c85ae0 795 return lastLqi;
fredqian 0:5f1d66c85ae0 796 }
fredqian 0:5f1d66c85ae0 797
fredqian 0:5f1d66c85ae0 798 /**
fredqian 0:5f1d66c85ae0 799 * @brief Read Last Energy Detection Level
fredqian 0:5f1d66c85ae0 800 *
fredqian 0:5f1d66c85ae0 801 * returns the ED level of the last transmission received
fredqian 0:5f1d66c85ae0 802 *
fredqian 0:5f1d66c85ae0 803 * range is between -90 and -6 dBm
fredqian 0:5f1d66c85ae0 804 * where -6 is the best
fredqian 0:5f1d66c85ae0 805 *
fredqian 0:5f1d66c85ae0 806 * @return ED level of the last transmission received
fredqian 0:5f1d66c85ae0 807 */
fredqian 0:5f1d66c85ae0 808 int8_t cMxRadio::getLastEd()
fredqian 0:5f1d66c85ae0 809 {
fredqian 0:5f1d66c85ae0 810 int8_t ed = trx_reg_read(RG_PHY_ED_LEVEL);
fredqian 0:5f1d66c85ae0 811
fredqian 0:5f1d66c85ae0 812 return ed == 0xFF ? 0 : (ed + RSSI_BASE_VAL);
fredqian 0:5f1d66c85ae0 813 //return lastRssi == 0xFF ? 0 : (lastRssi + RSSI_BASE_VAL);
fredqian 0:5f1d66c85ae0 814
fredqian 0:5f1d66c85ae0 815 }
fredqian 0:5f1d66c85ae0 816
fredqian 0:5f1d66c85ae0 817 /**
fredqian 0:5f1d66c85ae0 818 * @brief Read Energy Detection Level Now
fredqian 0:5f1d66c85ae0 819 *
fredqian 0:5f1d66c85ae0 820 * forces a reading of the ED level
fredqian 0:5f1d66c85ae0 821 *
fredqian 0:5f1d66c85ae0 822 * range is between -90 and -6 dBm
fredqian 0:5f1d66c85ae0 823 * where -6 is the best
fredqian 0:5f1d66c85ae0 824 *
fredqian 0:5f1d66c85ae0 825 * @return ED level
fredqian 0:5f1d66c85ae0 826 */
fredqian 0:5f1d66c85ae0 827 int8_t cMxRadio::getEdNow()
fredqian 0:5f1d66c85ae0 828 {
fredqian 0:5f1d66c85ae0 829 trx_reg_write(RG_PHY_ED_LEVEL, 0); // forces a reading
fredqian 0:5f1d66c85ae0 830
fredqian 0:5f1d66c85ae0 831 return getLastEd();
fredqian 0:5f1d66c85ae0 832 }
fredqian 0:5f1d66c85ae0 833
fredqian 0:5f1d66c85ae0 834 /**
fredqian 0:5f1d66c85ae0 835 * @brief Wait for TX to Complete
fredqian 0:5f1d66c85ae0 836 *
fredqian 0:5f1d66c85ae0 837 * waits until the last transmission is complete, or timed out
fredqian 0:5f1d66c85ae0 838 *
fredqian 0:5f1d66c85ae0 839 * @param timeout iterations to countdown before timeout
fredqian 0:5f1d66c85ae0 840 */
fredqian 0:5f1d66c85ae0 841 void cMxRadio::waitTxDone(uint16_t timeout)
fredqian 0:5f1d66c85ae0 842 {
fredqian 0:5f1d66c85ae0 843 volatile uint16_t cnt = timeout;
fredqian 0:5f1d66c85ae0 844 while (txIsBusy && cnt--);
fredqian 0:5f1d66c85ae0 845 }
fredqian 0:5f1d66c85ae0 846
fredqian 0:5f1d66c85ae0 847