A Atmel RF2xx Radio Library for Mbed
Dependents: xBedRadio MxSniffer
MxRadio.cpp
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 #include "MxRadio.h" 00030 #include "MxRadioEvents.h" 00031 //#define radio_set_state radio_force_state 00032 00033 // the write function checks if beginTransmission was called prior to write 00034 // in order to determine whether to use immediate or non-immediate transmission 00035 00036 const uint8_t HeadSize=9; 00037 00038 // a busy indicator so transmit functions can wait until the last transmission has finished 00039 volatile uint8_t txIsBusy = 0; 00040 00041 00042 cMxRadio::~cMxRadio() 00043 { 00044 } 00045 // empty constructor, should not be called by user 00046 cMxRadio::cMxRadio(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName slp, PinName irq) 00047 :m_spi(mosi, miso, sclk), m_cs(cs), reset_pin(rst), sleep_pin(slp),irq_pin(irq) 00048 { 00049 // default event handlers 00050 00051 zrEventTxDone=0; 00052 zrEventReceiveFrame=0; 00053 temprssi=0; 00054 setautotx=false; 00055 setautorx=false; 00056 needack=false; 00057 usedBeginTransmission = 0; 00058 hasAttachedTxEvent = 0; 00059 hasAttachedRxEvent = 0; 00060 lastLqi = 0; 00061 lastRssi = 0; 00062 txTmpBufferLength = 0; 00063 rxRingBufferHead = 0; 00064 rxRingBufferTail = 0; 00065 /* 00066 user_radio_tx_done=0; 00067 user_radio_receive_frame=0; 00068 user_radio_irq=0; 00069 user_radio_error=0; 00070 */ 00071 zr_attach_receive_frame(&cMxRadio::onReceiveFrame); 00072 zr_attach_tx_done(&cMxRadio::onTxDone); 00073 00074 } 00075 00076 /** 00077 * @brief Radio Initialization 00078 * 00079 * The function initializes all IO ressources, 00080 * needed for the usage of the radio and performs 00081 * a reset to the radio. 00082 * It prepares the frame header. 00083 * Then it sets the channel number and defaults to RX state. 00084 * 00085 * @param chan the channel number for the radio to use, 11 to 26 00086 */ 00087 void cMxRadio::begin(channel_t chan) 00088 { 00089 begin(chan, 0); 00090 } 00091 00092 void cMxRadio::begin(channel_t chan,uint16_t panid,uint16_t localaddress,bool needackval,bool autotxval,bool autorxval,char autoretrycount) 00093 { 00094 setautotx=autotxval; 00095 setautorx=autorxval; 00096 needack=needackval; 00097 radio_init(rxFrameBuffer, MAX_FRAME_SIZE); 00098 00099 ////////////////////////////// 00100 #ifdef SR_MAX_FRAME_RETRES 00101 trx_bit_write(SR_MAX_FRAME_RETRES,autoretrycount & 0Xf);//for auto wake up 00102 ////////////////////////////// 00103 #endif 00104 00105 00106 if(!needack) 00107 txTmpBuffer[0] = 0x41; 00108 else 00109 txTmpBuffer[0] = 0x61; //ack required 00110 txTmpBuffer[1] = 0x88; 00111 txTmpBuffer[2] = 0; 00112 txTmpBuffer[3]=(uint8_t)(panid & 0xFF ); 00113 txTmpBuffer[4]=(uint8_t)((panid>>8) & 0xFF ); 00114 txTmpBuffer[5] = 0xFF; //dest address low byte 00115 txTmpBuffer[6] = 0xFF; //dest address hight byte 00116 txTmpBuffer[7] = (uint8_t)(localaddress & 0xFF ); 00117 txTmpBuffer[8] = (uint8_t)((localaddress>>8) & 0xFF ); 00118 setParam(phyPanId,(uint16_t)panid ); 00119 setParam(phyShortAddr,(uint16_t)localaddress ); 00120 00121 radio_set_param(RP_CHANNEL(chan)); 00122 00123 // default to receiver 00124 if (setautorx) 00125 radio_set_state(STATE_RXAUTO); 00126 else 00127 radio_set_state(STATE_RX); 00128 #ifdef ENABLE_DIG3_DIG4 00129 trx_bit_write(SR_PA_EXT_EN, 1); 00130 #endif 00131 } 00132 void cMxRadio::begin(channel_t chan,uint16_t panid,uint16_t localaddress,bool needackval,bool autotxval,bool autorxval) 00133 { 00134 cMxRadio::begin(chan,panid,localaddress,needackval,autotxval,autorxval,4); 00135 00136 } 00137 void cMxRadio::sendFrame(uint16_t destaddress,bool needackval,uint8_t* frm, uint8_t len) 00138 { 00139 uint8_t oldvalue=txTmpBuffer[0]; 00140 if(!needackval) 00141 txTmpBuffer[0] = 0x41; 00142 else 00143 txTmpBuffer[0] = 0x61; 00144 beginTransmission(destaddress); 00145 write(frm,len); 00146 endTransmission(); 00147 txTmpBuffer[0]=oldvalue; 00148 00149 } 00150 /** 00151 * @brief Radio Initialization 00152 * 00153 * Overload for radio initalization that allows for the user to set a custom frame header 00154 * 00155 * @param chan channel number for the radio to use, 11 to 26 00156 * @param frameHeader HeadSize byte custom frame header 00157 */ 00158 void cMxRadio::begin(channel_t chan, uint8_t* frameHeader) 00159 { 00160 radio_init(rxFrameBuffer, MAX_FRAME_SIZE); 00161 00162 if (frameHeader) 00163 { 00164 // copy custom frame header 00165 int i; 00166 for (i = 0; i < HeadSize; i++) 00167 txTmpBuffer[i] = frameHeader[i]; 00168 } 00169 else 00170 { 00171 txTmpBuffer[0] = 0x41; 00172 txTmpBuffer[1] = 0x88; 00173 txTmpBuffer[2] = 0; 00174 txTmpBuffer[3]=0xCD; 00175 txTmpBuffer[4]=0xAB; 00176 txTmpBuffer[5] = 0xFF; //dest address low byte 00177 txTmpBuffer[6] = 0xFF; //dest address hight byte 00178 txTmpBuffer[7] = 0x01;; 00179 txTmpBuffer[8] = 0x00;; 00180 } 00181 00182 // set the channel 00183 radio_set_param(RP_CHANNEL(chan)); 00184 00185 // default to receiver 00186 if (setautorx) 00187 radio_set_state(STATE_RXAUTO); 00188 else 00189 radio_set_state(STATE_RX); 00190 00191 #ifdef ENABLE_DIG3_DIG4 00192 trx_bit_write(SR_PA_EXT_EN, 1); 00193 #endif 00194 00195 } 00196 00197 /** 00198 * @brief Set Frame Header 00199 * 00200 * changes the custom frame header 00201 * 00202 * @param frameHeader HeadSize byte custom frame header 00203 */ 00204 void cMxRadio::setFrameHeader(uint8_t* frameHeader) 00205 { 00206 // copy custom frame header 00207 int i; 00208 for (i = 0; i < HeadSize; i++) 00209 txTmpBuffer[i] = frameHeader[i]; 00210 } 00211 00212 /** 00213 * @brief Attach Error Event Handler 00214 * 00215 * Allows the user to set a error handling function 00216 * An empty one is used if none is set 00217 * 00218 * @param funct the function pointer to the event handler 00219 */ 00220 void cMxRadio::attachError(void (*funct)(radio_error_t)) 00221 { 00222 user_radio_error = funct; 00223 } 00224 00225 /** 00226 * @brief Attach IRQ Event Handler 00227 * 00228 * Allows the user to set a IRQ handling function 00229 * An empty one is used if none is set 00230 * 00231 * @param funct the function pointer to the event handler 00232 */ 00233 void cMxRadio::attachIrq(void (*funct)(uint8_t)) 00234 { 00235 user_radio_irq = funct; 00236 } 00237 00238 /** 00239 * @brief Attach RX Event Handler 00240 * 00241 * Allows the user to set a RX handling function 00242 * The default handler will read in the received frame and place it into the RX FIFO ring buffer 00243 * If the user chooses to use this attach function, then the default handler will not be used 00244 * This means read/peek/available/flush will stop working 00245 * 00246 * @param funct the function pointer to the event handler 00247 */ 00248 void cMxRadio::attachReceiveFrame(uint8_t* (*funct)(uint8_t, uint8_t*, uint8_t,int8_t, uint8_t)) 00249 { 00250 zrEventReceiveFrame = funct; 00251 hasAttachedRxEvent = (funct == 0) ? 0 : 1; 00252 } 00253 00254 /** 00255 * @brief Attach TX Complete Event Handler 00256 * 00257 * Allows the user to set a TX complete handling function 00258 * An empty one is used if none is set 00259 * The event will occur before the busy flag is reset and returning to RX state 00260 * 00261 * @param funct the function pointer to the event handler 00262 */ 00263 void cMxRadio::attachTxDone(void (*funct)(radio_tx_done_t)) 00264 { 00265 zrEventTxDone = funct; 00266 hasAttachedTxEvent = (funct == 0) ? 0 : 1; 00267 } 00268 00269 /** 00270 * @brief Default RX Event Handler 00271 * 00272 * If the user has not attached a custom event handler, then the bytes are placed into the FIFO ring buffer 00273 * If the frame contains a header, then the frame header is ignored, only the payload is read 00274 * The above does not occur if a user handler is attached, which will be called instead 00275 * The LQI and RSSI is always remembered 00276 * 00277 * This should not be called by the user 00278 * 00279 * @param len length of the frame 00280 * @param frm array containing frame data 00281 * @param lqi link quality indicator 00282 * @param crc_fail boolean indicating whether the received frame failed FCS verification, not used 00283 */ 00284 uint8_t* cMxRadio::onReceiveFrame(uint8_t len, uint8_t* frm, uint8_t lqi, int8_t ed,uint8_t crc_fail) 00285 { 00286 if (crc_fail) 00287 return rxRingBuffer; 00288 lastLqi = lqi; 00289 //lastRssi=ed; 00290 if (hasAttachedRxEvent == 0) 00291 { 00292 // no event handler, so write it into the FIFO 00293 00294 if (len >= HeadSize-1) 00295 { 00296 // frame header exists 00297 // copy only payload 00298 00299 for (uint8_t i = HeadSize; i < len - 2; i++) 00300 { 00301 uint16_t j = ((uint16_t)((uint16_t)rxRingBufferHead + 1)) % ZR_FIFO_SIZE; 00302 if (j != rxRingBufferTail) 00303 { 00304 // push into FIFO 00305 rxRingBuffer[rxRingBufferHead] = frm[i]; 00306 rxRingBufferHead = j; 00307 } 00308 else 00309 { 00310 // FIFO full 00311 break; 00312 } 00313 } 00314 } 00315 else 00316 { 00317 // frame header does not exist 00318 // copy everything 00319 00320 for (uint8_t i = 0; i < len; i++) 00321 { 00322 uint16_t j = ((uint16_t)((uint16_t)rxRingBufferHead + 1)) % ZR_FIFO_SIZE; 00323 if (j != rxRingBufferTail) 00324 { 00325 // push into FIFO 00326 rxRingBuffer[rxRingBufferHead] = frm[i]; 00327 rxRingBufferHead = j; 00328 } 00329 else 00330 { 00331 // FIFO full 00332 break; 00333 } 00334 } 00335 } 00336 00337 return rxRingBuffer; 00338 } 00339 else 00340 { 00341 // user event is attached so call it 00342 return zrEventReceiveFrame(len, frm, lqi, ed,crc_fail); 00343 } 00344 } 00345 00346 /** 00347 * @brief RX Buffer Flush 00348 * 00349 * Flush the RX FIFO ring buffer 00350 */ 00351 void cMxRadio::flush() 00352 { 00353 rxRingBufferHead = rxRingBufferTail; 00354 } 00355 00356 /** 00357 * @brief RX Buffer Read 00358 * 00359 * pops and returns the next byte from the FIFO ring buffer 00360 * 00361 * @return the next byte, or -1 if buffer is empty 00362 */ 00363 int16_t cMxRadio::read() 00364 { 00365 // if the head isn't ahead of the tail, we don't have any characters 00366 if (rxRingBufferHead == rxRingBufferTail) 00367 { 00368 return -1; 00369 } 00370 else 00371 { 00372 uint8_t c = rxRingBuffer[rxRingBufferTail]; 00373 rxRingBufferTail = (rxRingBufferTail + 1) % ZR_FIFO_SIZE; // pop 00374 return c; 00375 } 00376 } 00377 00378 /** 00379 * @brief RX Buffer Peek 00380 * 00381 * returns the next byte from the FIFO ring buffer without removing it 00382 * 00383 * @return the next byte, or -1 if buffer is empty 00384 */ 00385 int16_t cMxRadio::peek() 00386 { 00387 // if the head isn't ahead of the tail, we don't have any characters 00388 if (rxRingBufferHead == rxRingBufferTail) 00389 { 00390 return -1; 00391 } 00392 else 00393 { 00394 uint8_t c = rxRingBuffer[rxRingBufferTail]; 00395 return c; 00396 } 00397 } 00398 00399 /** 00400 * @brief RX Buffer Size 00401 * 00402 * Shows how many bytes are in the RX FIFO ring buffer 00403 * 00404 * @return how many bytes are in the RX FIFO ring buffer 00405 */ 00406 int8_t cMxRadio::available() 00407 { 00408 return ((int16_t)((int16_t)ZR_FIFO_SIZE + (int16_t)rxRingBufferHead - (int16_t)rxRingBufferTail)) % ZR_FIFO_SIZE; 00409 } 00410 00411 /** 00412 * @brief Raw Frame Transmit 00413 * 00414 * Transmits a frame 00415 * Warning: no frame header or FCS is added 00416 * 00417 * @param frm array containing frame data 00418 * @param len length of the frame 00419 */ 00420 void cMxRadio::txFrame(uint8_t* frm, uint8_t len) 00421 { 00422 #ifdef ZR_TXWAIT_BEFORE 00423 waitTxDone(0xFFFF); 00424 #endif 00425 txIsBusy = 1; 00426 if (setautotx) 00427 radio_set_state(STATE_TXAUTO); 00428 else 00429 radio_set_state(STATE_TX); 00430 ZR_RFTX_LED_ON(); 00431 radio_send_frame(len, frm, 0); 00432 #ifdef ZR_TXWAIT_AFTER 00433 waitTxDone(0xFFFF); 00434 if (setautorx) 00435 radio_set_state(STATE_RXAUTO); 00436 else 00437 radio_set_state(STATE_RX); 00438 txIsBusy = 0; 00439 #endif 00440 } 00441 00442 /** 00443 * @brief Prepare for Trasmission 00444 * 00445 * Goes into non-immediate transmit mode, resets the transmit payload 00446 * Non-immediate mode sends multiple bytes per frame 00447 * 00448 */ 00449 void cMxRadio::beginTransmission() 00450 { 00451 usedBeginTransmission = 1; 00452 txTmpBuffer[5]= 0xFF; 00453 txTmpBuffer[6]= 0XFF; 00454 // add frame header 00455 txTmpBufferLength = HeadSize; 00456 } 00457 00458 void cMxRadio::beginTransmission(uint16_t destaddress) 00459 { 00460 txTmpBuffer[5]=(uint8_t)(destaddress & 0xFF ); 00461 txTmpBuffer[6]=(uint8_t)((destaddress>>8) & 0xFF ); 00462 usedBeginTransmission = 1; 00463 00464 // add frame header 00465 txTmpBufferLength = HeadSize; 00466 } 00467 00468 /** 00469 * @brief Finalize Trasmission 00470 * 00471 * Finalize the payload and transmits it when ready 00472 * 00473 */ 00474 void cMxRadio::endTransmission() 00475 { 00476 usedBeginTransmission = 0; 00477 00478 // empty FCS field 00479 txTmpBufferLength += 2; 00480 00481 #ifdef ZR_TXWAIT_BEFORE 00482 waitTxDone(0xFFFF); 00483 #endif 00484 txIsBusy = 1; 00485 if (setautotx) 00486 radio_set_state(STATE_TXAUTO); 00487 else 00488 radio_set_state(STATE_TX); 00489 ZR_RFTX_LED_ON(); 00490 //if broadcase ,cant need ack 00491 if(txTmpBuffer[5]==0xff && txTmpBuffer[5]==0xff) 00492 txTmpBuffer[0]=txTmpBuffer[0]&0xdf; 00493 else 00494 { 00495 if(!needack) 00496 txTmpBuffer[0] = 0x41; 00497 else 00498 txTmpBuffer[0] = 0x61; //ack required 00499 } 00500 radio_send_frame(txTmpBufferLength, txTmpBuffer, 0); 00501 #ifdef ZR_TXWAIT_AFTER 00502 waitTxDone(0xFFFF); 00503 if (setautorx) 00504 radio_set_state(STATE_RXAUTO); 00505 else 00506 radio_set_state(STATE_RX); 00507 txIsBusy = 0; 00508 #endif 00509 } 00510 00511 /** 00512 * @brief Cancel Trasmission 00513 * 00514 * Clears payload buffer 00515 * 00516 * Warning: does not actually cancel a transmission in progress 00517 * 00518 */ 00519 void cMxRadio::cancelTransmission() 00520 { 00521 usedBeginTransmission = 0; 00522 00523 // add frame header 00524 txTmpBufferLength = HeadSize; 00525 } 00526 /** 00527 * @brief TX a Byte 00528 * 00529 * Wrapper for "write", since the "Wire" library uses "send" 00530 * 00531 */ 00532 void cMxRadio::send(uint8_t c) 00533 { 00534 write(c); 00535 } 00536 00537 /** 00538 * @brief TX a Byte 00539 * 00540 * If "beginTrasmission" was used, then it writes into the transmit buffer for non-immediate mode 00541 * If "beginTrasmission" was not used, then it transmits the single byte immediately (slower for multiple bytes) 00542 * 00543 * @param c character to be sent 00544 */ 00545 void cMxRadio::write(uint8_t c) 00546 { 00547 if (usedBeginTransmission) 00548 { 00549 if (txTmpBufferLength < ZR_TXTMPBUFF_SIZE - 2) 00550 { 00551 txTmpBuffer[txTmpBufferLength] = c; 00552 txTmpBufferLength++; 00553 00554 if (txTmpBufferLength >= ZR_TXTMPBUFF_SIZE - 2) 00555 { 00556 // buffer is now full 00557 // just send it all out so we have more room 00558 endTransmission(); 00559 beginTransmission(); 00560 } 00561 } 00562 } 00563 else 00564 { 00565 txTmpBuffer[HeadSize] = c; // set payload 00566 txTmpBuffer[HeadSize+1] = 0; // empty FCS 00567 txTmpBuffer[HeadSize+2] = 0; // empty FCS 00568 00569 #ifdef ZR_TXWAIT_BEFORE 00570 waitTxDone(0xFFFF); 00571 #endif 00572 txIsBusy = 1; 00573 if (setautotx) 00574 radio_set_state(STATE_TXAUTO); 00575 else 00576 radio_set_state(STATE_TX); 00577 ZR_RFTX_LED_ON(); 00578 radio_send_frame(10, txTmpBuffer, 0); 00579 #ifdef ZR_TXWAIT_AFTER 00580 waitTxDone(0xFFFF); 00581 if (setautorx) 00582 radio_set_state(STATE_RXAUTO); 00583 else 00584 radio_set_state(STATE_RX); 00585 txIsBusy = 0; 00586 #endif 00587 } 00588 } 00589 /** 00590 * @brief TX a String 00591 * 00592 * A overload for "write" that sends a null-terminated string 00593 * 00594 * @param str null-terminated string to be sent 00595 */ 00596 void cMxRadio::write(char* str) 00597 { 00598 while (*str) 00599 write(*str++); 00600 } 00601 00602 /** 00603 * @brief TX an Array 00604 * 00605 * A overload for "write" that sends an array 00606 * 00607 * @param arr data array to be sent 00608 * @param len length of data array 00609 */ 00610 void cMxRadio::write(uint8_t* arr, uint8_t len) 00611 { 00612 uint8_t i; 00613 for (i = 0; i < len; i++) 00614 write(arr[i]); 00615 } 00616 00617 /** 00618 * @brief Default TX Complete Event Handler 00619 * 00620 * Calls the user event function if one is attached 00621 * Clear the TX busy status flag 00622 * Defaults back to RX state 00623 * 00624 * this should not be called by the user 00625 * 00626 * @param x one of the radio_tx_done_t enumerations indicating transmission success 00627 */ 00628 void cMxRadio::onTxDone(radio_tx_done_t x) 00629 { 00630 if (hasAttachedTxEvent) 00631 { 00632 zrEventTxDone(x); 00633 } 00634 00635 txIsBusy = 0; 00636 } 00637 00638 /** 00639 * @brief radio_set_param Wrapper 00640 * 00641 * set a radio parameter 00642 * 00643 * see radio.h for more info 00644 */ 00645 void cMxRadio::setParam(radio_attribute_t attr, radio_param_t parm) 00646 { 00647 radio_set_param(attr, parm); 00648 } 00649 00650 /** 00651 * @brief radio_do_cca Wrapper 00652 * 00653 * perform CCA measure 00654 * 00655 * see radio.h for more info 00656 */ 00657 radio_cca_t cMxRadio::doCca() 00658 { 00659 return radio_do_cca(); 00660 } 00661 00662 /** 00663 * @brief Set Radio State Wrapper 00664 * 00665 * sets or forces the radio into a state 00666 * 00667 * see radio.h for more info 00668 * 00669 * @param state requested radio state 00670 * @param force boolean indicating to force the state 00671 */ 00672 void cMxRadio::setState(radio_state_t state, uint8_t force) 00673 { 00674 if (force) 00675 radio_force_state(state); 00676 else 00677 radio_set_state(state); 00678 } 00679 00680 /** 00681 * @brief radio_set_state Wrapper 00682 * 00683 * bring the the radio in the requested state 00684 * 00685 * see radio.h for more info 00686 */ 00687 void cMxRadio::setState(radio_state_t state) 00688 { 00689 radio_set_state(state); 00690 } 00691 00692 /** 00693 * @brief radio_set_state to STATE_RX 00694 * 00695 * bring the the radio in the requested state of STATE_RX 00696 * 00697 * the radio state does not return to STATE_RX automatically if ZR_TXWAIT_AFTER is not used 00698 * thus why this is provided 00699 * 00700 * see radio.h for more info 00701 */ 00702 void cMxRadio::setStateRx() 00703 { 00704 if (setautorx) 00705 radio_set_state(STATE_RXAUTO); 00706 else 00707 radio_set_state(STATE_RX); 00708 } 00709 00710 /** 00711 * @brief radio_force_state Wrapper 00712 * 00713 * force the radio to the requested state 00714 * 00715 * see radio.h for more info 00716 */ 00717 void cMxRadio::forceState(radio_state_t state) 00718 { 00719 radio_force_state(state); 00720 } 00721 00722 /** 00723 * @brief Sets Radio Channel 00724 * 00725 * changes the radio channel by setting the radio channel state 00726 * 00727 * @param chan channel number, 11 to 26 00728 */ 00729 void cMxRadio::setChannel(channel_t chan) 00730 { 00731 radio_set_param(RP_CHANNEL(chan)); 00732 } 00733 uint8_t cMxRadio::getChannel() 00734 { 00735 trx_param_t p; 00736 trx_parms_get(&p); 00737 channel_t chan= p.chan; 00738 return (uint8_t)chan; 00739 } 00740 00741 00742 /** 00743 * @brief Read Receiver Signal Strength Indicator Now 00744 * 00745 * returns the current RSSI 00746 * 00747 * range is between -91 and -9 dBm 00748 * where -9 is the best 00749 * 00750 * @return RSSI of the last transmission received 00751 */ 00752 int8_t cMxRadio::getRssiNow() 00753 { 00754 int16_t rssi = ((int16_t)(trx_reg_read(RG_PHY_RSSI) & 0x1F)); // mask only important bits 00755 rssi = (rssi == 0) ? (RSSI_BASE_VAL - 1) : ((rssi < 28) ? ((rssi - 1) * 3 + RSSI_BASE_VAL) : -9); 00756 // if 0, then rssi < RSSI_BASE_VAL, if 28, then >= -10 00757 00758 return rssi; 00759 } 00760 00761 00762 00763 /** 00764 * @brief Read Last Receiver Signal Strength Indicator 00765 * 00766 * returns the RSSI of the last transmission 00767 * 00768 * range is between -91 and -9 dBm 00769 * where -9 is the best 00770 * 00771 * @return RSSI of the last transmission received 00772 */ 00773 int8_t cMxRadio::getLastRssi() 00774 { 00775 int16_t rssi = ((int16_t)(temprssi & 0x1F)); // mask only important bits 00776 rssi = (rssi == 0) ? (RSSI_BASE_VAL - 1) : ((rssi < 28) ? ((rssi - 1) * 3 + RSSI_BASE_VAL) : -9); 00777 // if 0, then rssi < RSSI_BASE_VAL, if 28, then >= -10 00778 00779 return rssi; 00780 } 00781 00782 00783 /** 00784 * @brief Read Link Quality Indicator 00785 * 00786 * returns the LQI of the last transmission received 00787 * 00788 * range is from 0 to 255 00789 * 255 is the best 00790 * 00791 * @return LQI of the last transmission received 00792 */ 00793 uint8_t cMxRadio::getLqi() 00794 { 00795 return lastLqi; 00796 } 00797 00798 /** 00799 * @brief Read Last Energy Detection Level 00800 * 00801 * returns the ED level of the last transmission received 00802 * 00803 * range is between -90 and -6 dBm 00804 * where -6 is the best 00805 * 00806 * @return ED level of the last transmission received 00807 */ 00808 int8_t cMxRadio::getLastEd() 00809 { 00810 int8_t ed = trx_reg_read(RG_PHY_ED_LEVEL); 00811 00812 return ed == 0xFF ? 0 : (ed + RSSI_BASE_VAL); 00813 //return lastRssi == 0xFF ? 0 : (lastRssi + RSSI_BASE_VAL); 00814 00815 } 00816 00817 /** 00818 * @brief Read Energy Detection Level Now 00819 * 00820 * forces a reading of the ED level 00821 * 00822 * range is between -90 and -6 dBm 00823 * where -6 is the best 00824 * 00825 * @return ED level 00826 */ 00827 int8_t cMxRadio::getEdNow() 00828 { 00829 trx_reg_write(RG_PHY_ED_LEVEL, 0); // forces a reading 00830 00831 return getLastEd(); 00832 } 00833 00834 /** 00835 * @brief Wait for TX to Complete 00836 * 00837 * waits until the last transmission is complete, or timed out 00838 * 00839 * @param timeout iterations to countdown before timeout 00840 */ 00841 void cMxRadio::waitTxDone(uint16_t timeout) 00842 { 00843 volatile uint16_t cnt = timeout; 00844 while (txIsBusy && cnt--); 00845 } 00846 00847
Generated on Thu Jul 14 2022 01:09:39 by
1.7.2