Maniacbug's RF24 arduino library ported to mbed. Tested, it works for Nucleo F411
Dependents: RF24Network_Send RF24Network_Receive WeatherStation maple_chotobot_rf_motores ... more
RF24.cpp
00001 /* 00002 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> 00003 00004 This program is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU General Public License 00006 version 2 as published by the Free Software Foundation. 00007 */ 00008 00009 /* 00010 * Mbed support added by Akash Vibhute <akash.roboticist@gmail.com> 00011 * Porting completed on Nov/05/2015 00012 * 00013 * Updated 1: Synced with TMRh20's RF24 library on Nov/04/2015 from https://github.com/TMRh20 00014 * Updated 2: Synced with TMRh20's RF24 library on Apr/18/2015 from https://github.com/TMRh20 00015 * 00016 */ 00017 00018 #include "nRF24L01.h" 00019 #include "RF24_config.h" 00020 #include "RF24.h" 00021 00022 /****************************************************************************/ 00023 00024 void RF24::csn(bool mode) 00025 { 00026 00027 csn_pin = mode; 00028 00029 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 } 00066 00067 /****************************************************************************/ 00068 00069 void RF24::ce(bool level) 00070 { 00071 ce_pin = level; 00072 00073 } 00074 00075 /****************************************************************************/ 00076 00077 inline void RF24::beginTransaction() { 00078 00079 00080 csn(LOW); 00081 } 00082 00083 /****************************************************************************/ 00084 00085 inline void RF24::endTransaction() { 00086 csn(HIGH); 00087 00088 00089 00090 } 00091 00092 /****************************************************************************/ 00093 00094 uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) 00095 { 00096 uint8_t status; 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 beginTransaction(); 00120 status = spi.write( R_REGISTER | ( REGISTER_MASK & reg ) ); 00121 while ( len-- ){ 00122 *buf++ = spi.write(0xff); 00123 } 00124 endTransaction(); 00125 00126 00127 00128 return status; 00129 } 00130 00131 /****************************************************************************/ 00132 00133 uint8_t RF24::read_register(uint8_t reg) 00134 { 00135 uint8_t result; 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 beginTransaction(); 00153 spi.write( R_REGISTER | ( REGISTER_MASK & reg ) ); 00154 result = spi.write(0xff); 00155 endTransaction(); 00156 00157 00158 00159 return result; 00160 } 00161 00162 /****************************************************************************/ 00163 00164 uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) 00165 { 00166 uint8_t status; 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 beginTransaction(); 00184 status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) ); 00185 while ( len-- ) 00186 spi.write(*buf++); 00187 endTransaction(); 00188 00189 00190 00191 return status; 00192 } 00193 00194 /****************************************************************************/ 00195 00196 uint8_t RF24::write_register(uint8_t reg, uint8_t value) 00197 { 00198 uint8_t status; 00199 00200 IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); 00201 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 00213 00214 beginTransaction(); 00215 status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) ); 00216 spi.write(value); 00217 endTransaction(); 00218 00219 00220 00221 return status; 00222 } 00223 00224 /****************************************************************************/ 00225 00226 uint8_t RF24::write_payload(const void* buf, uint8_t data_len, const uint8_t writeType) 00227 { 00228 uint8_t status; 00229 const uint8_t* current = reinterpret_cast<const uint8_t*>(buf); 00230 00231 data_len = rf24_min(data_len, payload_size); 00232 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; 00233 00234 //printf("[Writing %u bytes %u blanks]",data_len,blank_len); 00235 IF_SERIAL_DEBUG( printf("[Writing %u bytes %u blanks]\n",data_len,blank_len); ); 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 00253 00254 00255 00256 beginTransaction(); 00257 status = spi.write( writeType ); 00258 while ( data_len-- ) { 00259 spi.write(*current++); 00260 } 00261 while ( blank_len-- ) { 00262 spi.write(0); 00263 } 00264 endTransaction(); 00265 00266 00267 00268 return status; 00269 } 00270 00271 /****************************************************************************/ 00272 00273 uint8_t RF24::read_payload(void* buf, uint8_t data_len) 00274 { 00275 uint8_t status; 00276 uint8_t* current = reinterpret_cast<uint8_t*>(buf); 00277 00278 if(data_len > payload_size) data_len = payload_size; 00279 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; 00280 00281 //printf("[Reading %u bytes %u blanks]",data_len,blank_len); 00282 00283 IF_SERIAL_DEBUG( printf("[Reading %u bytes %u blanks]\n",data_len,blank_len); ); 00284 00285 00286 00287 00288 00289 00290 00291 00292 00293 00294 00295 00296 00297 00298 00299 00300 00301 00302 00303 00304 00305 00306 00307 00308 00309 00310 00311 beginTransaction(); 00312 status = spi.write( R_RX_PAYLOAD ); 00313 while ( data_len-- ) { 00314 *current++ = spi.write(0xFF); 00315 } 00316 while ( blank_len-- ) { 00317 spi.write(0xff); 00318 } 00319 endTransaction(); 00320 00321 00322 00323 return status; 00324 } 00325 00326 /****************************************************************************/ 00327 00328 uint8_t RF24::flush_rx(void) 00329 { 00330 return spiTrans( FLUSH_RX ); 00331 } 00332 00333 /****************************************************************************/ 00334 00335 uint8_t RF24::flush_tx(void) 00336 { 00337 return spiTrans( FLUSH_TX ); 00338 } 00339 00340 /****************************************************************************/ 00341 00342 uint8_t RF24::spiTrans(uint8_t cmd){ 00343 00344 uint8_t status; 00345 00346 beginTransaction(); 00347 status = spi.write( cmd ); 00348 endTransaction(); 00349 00350 return status; 00351 } 00352 00353 /****************************************************************************/ 00354 00355 uint8_t RF24::get_status(void) 00356 { 00357 return spiTrans(NOP); 00358 } 00359 00360 /****************************************************************************/ 00361 #if !defined (MINIMAL) 00362 void RF24::print_status(uint8_t status) 00363 { 00364 printf_P(PSTR("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"), 00365 status, 00366 (status & _BV(RX_DR))?1:0, 00367 (status & _BV(TX_DS))?1:0, 00368 (status & _BV(MAX_RT))?1:0, 00369 ((status >> RX_P_NO) & 0b111), 00370 (status & _BV(TX_FULL))?1:0 00371 ); 00372 } 00373 00374 /****************************************************************************/ 00375 00376 void RF24::print_observe_tx(uint8_t value) 00377 { 00378 printf_P(PSTR("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), 00379 value, 00380 (value >> PLOS_CNT) & 0b1111, 00381 (value >> ARC_CNT) & 0b1111 00382 ); 00383 } 00384 00385 /****************************************************************************/ 00386 00387 void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty) 00388 { 00389 //char extra_tab = strlen_P(name) < 8 ? '\t' : 0; 00390 //printf_P(PSTR(PRIPSTR"\t%c ="),name,extra_tab); 00391 00392 00393 00394 printf_P(PSTR(PRIPSTR"\t ="),name); 00395 00396 while (qty--) 00397 printf_P(PSTR(" 0x%02x"),read_register(reg++)); 00398 printf_P(PSTR("\r\n")); 00399 } 00400 00401 /****************************************************************************/ 00402 00403 void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty) 00404 { 00405 00406 00407 00408 00409 printf_P(PSTR(PRIPSTR"\t ="),name); 00410 00411 while (qty--) 00412 { 00413 uint8_t buffer[addr_width]; 00414 read_register(reg++,buffer,sizeof buffer); 00415 00416 printf_P(PSTR(" 0x")); 00417 uint8_t* bufptr = buffer + sizeof buffer; 00418 while( --bufptr >= buffer ) 00419 printf_P(PSTR("%02x"),*bufptr); 00420 } 00421 00422 printf_P(PSTR("\r\n")); 00423 } 00424 #endif 00425 /****************************************************************************/ 00426 RF24::RF24(PinName mosi, PinName miso, PinName sck, PinName _cepin, PinName _csnpin): 00427 spi(mosi, miso, sck), ce_pin(_cepin), csn_pin(_csnpin), p_variant(true), 00428 payload_size(32), dynamic_payloads_enabled(false), addr_width(5) 00429 { 00430 pipe0_reading_address[0]=0; 00431 00432 //spi.frequency(10000000/5); // 2Mbit, 1/5th the maximum transfer rate for the spi bus 00433 spi.frequency(10000000); 00434 //spi.format(8,0); // 8-bit, ClockPhase = 0, ClockPolarity = 0 00435 spi.format(8,0); 00436 wait_ms(10); 00437 } 00438 00439 00440 00441 00442 00443 00444 00445 00446 /****************************************************************************/ 00447 00448 void RF24::setChannel(uint8_t channel) 00449 { 00450 const uint8_t max_channel = 125; 00451 write_register(RF_CH,rf24_min(channel,max_channel)); 00452 } 00453 00454 uint8_t RF24::getChannel() 00455 { 00456 00457 return read_register(RF_CH); 00458 } 00459 /****************************************************************************/ 00460 00461 void RF24::setPayloadSize(uint8_t size) 00462 { 00463 payload_size = rf24_min(size,32); 00464 } 00465 00466 /****************************************************************************/ 00467 00468 uint8_t RF24::getPayloadSize(void) 00469 { 00470 return payload_size; 00471 } 00472 00473 /****************************************************************************/ 00474 00475 #if !defined (MINIMAL) 00476 00477 static const char rf24_datarate_e_str_0[] PROGMEM = "1MBPS"; 00478 static const char rf24_datarate_e_str_1[] PROGMEM = "2MBPS"; 00479 static const char rf24_datarate_e_str_2[] PROGMEM = "250KBPS"; 00480 static const char * const rf24_datarate_e_str_P[] PROGMEM = { 00481 rf24_datarate_e_str_0, 00482 rf24_datarate_e_str_1, 00483 rf24_datarate_e_str_2, 00484 }; 00485 static const char rf24_model_e_str_0[] PROGMEM = "nRF24L01"; 00486 static const char rf24_model_e_str_1[] PROGMEM = "nRF24L01+"; 00487 static const char * const rf24_model_e_str_P[] PROGMEM = { 00488 rf24_model_e_str_0, 00489 rf24_model_e_str_1, 00490 }; 00491 static const char rf24_crclength_e_str_0[] PROGMEM = "Disabled"; 00492 static const char rf24_crclength_e_str_1[] PROGMEM = "8 bits"; 00493 static const char rf24_crclength_e_str_2[] PROGMEM = "16 bits" ; 00494 static const char * const rf24_crclength_e_str_P[] PROGMEM = { 00495 rf24_crclength_e_str_0, 00496 rf24_crclength_e_str_1, 00497 rf24_crclength_e_str_2, 00498 }; 00499 static const char rf24_pa_dbm_e_str_0[] PROGMEM = "PA_MIN"; 00500 static const char rf24_pa_dbm_e_str_1[] PROGMEM = "PA_LOW"; 00501 static const char rf24_pa_dbm_e_str_2[] PROGMEM = "PA_HIGH"; 00502 static const char rf24_pa_dbm_e_str_3[] PROGMEM = "PA_MAX"; 00503 static const char * const rf24_pa_dbm_e_str_P[] PROGMEM = { 00504 rf24_pa_dbm_e_str_0, 00505 rf24_pa_dbm_e_str_1, 00506 rf24_pa_dbm_e_str_2, 00507 rf24_pa_dbm_e_str_3, 00508 }; 00509 00510 00511 00512 00513 00514 00515 00516 00517 00518 00519 00520 00521 00522 00523 void RF24::printDetails(void) 00524 { 00525 00526 00527 00528 00529 00530 00531 00532 00533 00534 00535 00536 00537 00538 00539 00540 00541 00542 00543 00544 00545 00546 00547 00548 00549 00550 00551 00552 00553 00554 00555 00556 00557 00558 print_status(get_status()); 00559 00560 print_address_register(PSTR("RX_ADDR_P0-1"),RX_ADDR_P0,2); 00561 print_byte_register(PSTR("RX_ADDR_P2-5"),RX_ADDR_P2,4); 00562 print_address_register(PSTR("TX_ADDR\t"),TX_ADDR); 00563 00564 print_byte_register(PSTR("RX_PW_P0-6"),RX_PW_P0,6); 00565 print_byte_register(PSTR("EN_AA\t"),EN_AA); 00566 print_byte_register(PSTR("EN_RXADDR"),EN_RXADDR); 00567 print_byte_register(PSTR("RF_CH\t"),RF_CH); 00568 print_byte_register(PSTR("RF_SETUP"),RF_SETUP); 00569 print_byte_register(PSTR("CONFIG\t"),NRF_CONFIG); 00570 print_byte_register(PSTR("DYNPD/FEATURE"),DYNPD,2); 00571 00572 printf_P(PSTR("Data Rate\t = " PRIPSTR "\r\n"),pgm_read_word(&rf24_datarate_e_str_P[getDataRate()])); 00573 printf_P(PSTR("Model\t\t = " PRIPSTR "\r\n"),pgm_read_word(&rf24_model_e_str_P[isPVariant()])); 00574 printf_P(PSTR("CRC Length\t = " PRIPSTR "\r\n"),pgm_read_word(&rf24_crclength_e_str_P[getCRCLength()])); 00575 printf_P(PSTR("PA Power\t = " PRIPSTR "\r\n"), pgm_read_word(&rf24_pa_dbm_e_str_P[getPALevel()])); 00576 00577 } 00578 00579 #endif 00580 /****************************************************************************/ 00581 00582 bool RF24::begin(void) 00583 { 00584 00585 uint8_t setup=0; 00586 00587 mainTimer.start(); 00588 00589 ce(LOW); 00590 csn(HIGH); 00591 00592 wait_ms(100); 00593 00594 00595 00596 00597 00598 00599 00600 00601 00602 00603 00604 00605 00606 00607 00608 00609 00610 00611 00612 00613 00614 00615 00616 00617 00618 00619 00620 00621 00622 00623 00624 00625 00626 00627 00628 00629 00630 00631 00632 00633 // Must allow the radio time to settle else configuration bits will not necessarily stick. 00634 // This is actually only required following power up but some settling time also appears to 00635 // be required after resets too. For full coverage, we'll always assume the worst. 00636 // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped. 00637 // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure. 00638 // WARNING: Delay is based on P-variant whereby non-P *may* require different timing. 00639 wait_ms( 5 ) ; 00640 00641 // Reset NRF_CONFIG and enable 16-bit CRC. 00642 write_register( NRF_CONFIG, 0b00001100 ) ; 00643 00644 // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier 00645 // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet 00646 // sizes must never be used. See documentation for a more complete explanation. 00647 setRetries(5,15); 00648 00649 // Reset value is MAX 00650 //setPALevel( RF24_PA_MAX ) ; 00651 00652 // check for connected module and if this is a p nRF24l01 variant 00653 // 00654 if( setDataRate( RF24_250KBPS ) ) 00655 { 00656 p_variant = true ; 00657 } 00658 setup = read_register(RF_SETUP); 00659 /*if( setup == 0b00001110 ) // register default for nRF24L01P 00660 { 00661 p_variant = true ; 00662 }*/ 00663 00664 // Then set the data rate to the slowest (and most reliable) speed supported by all 00665 // hardware. 00666 //setDataRate( RF24_1MBPS ) ; 00667 setDataRate( RF24_2MBPS ) ; 00668 00669 // Initialize CRC and request 2-byte (16bit) CRC 00670 //setCRCLength( RF24_CRC_16 ) ; 00671 00672 // Disable dynamic payloads, to match dynamic_payloads_enabled setting - Reset value is 0 00673 toggle_features(); 00674 write_register(FEATURE,0 ); 00675 write_register(DYNPD,0); 00676 00677 // Reset current status 00678 // Notice reset and flush is the last thing we do 00679 write_register(NRF_STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); 00680 00681 // Set up default configuration. Callers can always change it later. 00682 // This channel should be universally safe and not bleed over into adjacent 00683 // spectrum. 00684 setChannel(76); 00685 00686 // Flush buffers 00687 flush_rx(); 00688 flush_tx(); 00689 00690 powerUp(); //Power up by default when begin() is called 00691 00692 // Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp ) 00693 // PTX should use only 22uA of power 00694 write_register(NRF_CONFIG, ( read_register(NRF_CONFIG) ) & ~_BV(PRIM_RX) ); 00695 //printDetails(); 00696 // if setup is 0 or ff then there was no response from module 00697 return ( setup != 0 && setup != 0xff ); 00698 } 00699 00700 /****************************************************************************/ 00701 00702 void RF24::startListening(void) 00703 { 00704 00705 00706 00707 write_register(NRF_CONFIG, read_register(NRF_CONFIG) | _BV(PRIM_RX)); 00708 write_register(NRF_STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); 00709 ce(HIGH); 00710 // Restore the pipe0 adddress, if exists 00711 if (pipe0_reading_address[0] > 0){ 00712 write_register(RX_ADDR_P0, pipe0_reading_address, addr_width); 00713 }else{ 00714 closeReadingPipe(0); 00715 } 00716 00717 // Flush buffers 00718 //flush_rx(); 00719 if(read_register(FEATURE) & _BV(EN_ACK_PAY)){ 00720 flush_tx(); 00721 } 00722 00723 // Go! 00724 //delayMicroseconds(100); 00725 } 00726 00727 /****************************************************************************/ 00728 static const uint8_t child_pipe_enable[] PROGMEM = 00729 { 00730 ERX_P0, ERX_P1, ERX_P2, ERX_P3, ERX_P4, ERX_P5 00731 }; 00732 00733 void RF24::stopListening(void) 00734 { 00735 ce(LOW); 00736 00737 wait_us(txRxDelay); 00738 00739 if(read_register(FEATURE) & _BV(EN_ACK_PAY)){ 00740 wait_us(txRxDelay); //200 00741 flush_tx(); 00742 } 00743 //flush_rx(); 00744 write_register(NRF_CONFIG, ( read_register(NRF_CONFIG) ) & ~_BV(PRIM_RX) ); 00745 00746 00747 00748 00749 00750 00751 00752 00753 write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[0]))); // Enable RX on pipe0 00754 00755 //delayMicroseconds(100); 00756 00757 } 00758 00759 /****************************************************************************/ 00760 00761 void RF24::powerDown(void) 00762 { 00763 ce(LOW); // Guarantee CE is low on powerDown 00764 write_register(NRF_CONFIG,read_register(NRF_CONFIG) & ~_BV(PWR_UP)); 00765 } 00766 00767 /****************************************************************************/ 00768 00769 //Power up now. Radio will not power down unless instructed by MCU for config changes etc. 00770 void RF24::powerUp(void) 00771 { 00772 uint8_t cfg = read_register(NRF_CONFIG); 00773 00774 // if not powered up then power up and wait for the radio to initialize 00775 if (!(cfg & _BV(PWR_UP))){ 00776 write_register(NRF_CONFIG, cfg | _BV(PWR_UP)); 00777 00778 // For nRF24L01+ to go from power down mode to TX or RX mode it must first pass through stand-by mode. 00779 // There must be a delay of Tpd2stby (see Table 16.) after the nRF24L01+ leaves power down mode before 00780 // the CEis set high. - Tpd2stby can be up to 5ms per the 1.0 datasheet 00781 wait_ms(5); 00782 } 00783 } 00784 00785 /******************************************************************/ 00786 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00787 void RF24::errNotify(){ 00788 #if defined (SERIAL_DEBUG) || defined (RF24_LINUX) 00789 printf_P(PSTR("RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.\r\n")); 00790 #endif 00791 #if defined (FAILURE_HANDLING) 00792 failureDetected = 1; 00793 #else 00794 wait_ms(5000); 00795 #endif 00796 } 00797 #endif 00798 /******************************************************************/ 00799 00800 //Similar to the previous write, clears the interrupt flags 00801 bool RF24::write( const void* buf, uint8_t len, const bool multicast ) 00802 { 00803 //Start Writing 00804 startFastWrite(buf,len,multicast); 00805 00806 //Wait until complete or failed 00807 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00808 uint32_t timer = mainTimer.read_ms(); 00809 #endif 00810 00811 while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) { 00812 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00813 if(mainTimer.read_ms() - timer > 95){ 00814 errNotify(); 00815 #if defined (FAILURE_HANDLING) 00816 return 0; 00817 #else 00818 wait_ms(100); 00819 #endif 00820 } 00821 #endif 00822 } 00823 00824 ce(LOW); 00825 00826 uint8_t status = write_register(NRF_STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); 00827 00828 //Max retries exceeded 00829 if( status & _BV(MAX_RT)){ 00830 flush_tx(); //Only going to be 1 packet int the FIFO at a time using this method, so just flush 00831 return 0; 00832 } 00833 //TX OK 1 or 0 00834 return 1; 00835 } 00836 00837 bool RF24::write( const void* buf, uint8_t len ){ 00838 return write(buf,len,0); 00839 } 00840 /****************************************************************************/ 00841 00842 //For general use, the interrupt flags are not important to clear 00843 bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout ) 00844 { 00845 //Block until the FIFO is NOT full. 00846 //Keep track of the MAX retries and set auto-retry if seeing failures 00847 //This way the FIFO will fill up and allow blocking until packets go through 00848 //The radio will auto-clear everything in the FIFO as long as CE remains high 00849 00850 uint32_t timer = mainTimer.read_ms(); //Get the time that the payload transmission started 00851 00852 while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or timeout 00853 00854 if( get_status() & _BV(MAX_RT)){ //If MAX Retries have been reached 00855 reUseTX(); //Set re-transmit and clear the MAX_RT interrupt flag 00856 if(mainTimer.read_ms() - timer > timeout){ return 0; } //If this payload has exceeded the user-defined timeout, exit and return 0 00857 } 00858 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00859 if(mainTimer.read_ms() - timer > (timeout+95) ){ 00860 errNotify(); 00861 #if defined (FAILURE_HANDLING) 00862 return 0; 00863 #endif 00864 } 00865 #endif 00866 00867 } 00868 00869 //Start Writing 00870 startFastWrite(buf,len,0); //Write the payload if a buffer is clear 00871 00872 return 1; //Return 1 to indicate successful transmission 00873 } 00874 00875 /****************************************************************************/ 00876 00877 void RF24::reUseTX(){ 00878 write_register(NRF_STATUS,_BV(MAX_RT) ); //Clear max retry flag 00879 spiTrans( REUSE_TX_PL ); 00880 ce(LOW); //Re-Transfer packet 00881 ce(HIGH); 00882 } 00883 00884 /****************************************************************************/ 00885 00886 bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast ) 00887 { 00888 //Block until the FIFO is NOT full. 00889 //Keep track of the MAX retries and set auto-retry if seeing failures 00890 //Return 0 so the user can control the retrys and set a timer or failure counter if required 00891 //The radio will auto-clear everything in the FIFO as long as CE remains high 00892 00893 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00894 uint32_t timer = mainTimer.read_ms(); 00895 #endif 00896 00897 while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or fail 00898 00899 if( get_status() & _BV(MAX_RT)){ 00900 //reUseTX(); //Set re-transmit 00901 write_register(NRF_STATUS,_BV(MAX_RT) ); //Clear max retry flag 00902 return 0; //Return 0. The previous payload has been retransmitted 00903 //From the user perspective, if you get a 0, just keep trying to send the same payload 00904 } 00905 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00906 if(mainTimer.read_ms() - timer > 95 ){ 00907 errNotify(); 00908 #if defined (FAILURE_HANDLING) 00909 return 0; 00910 #endif 00911 } 00912 #endif 00913 } 00914 //Start Writing 00915 startFastWrite(buf,len,multicast); 00916 00917 return 1; 00918 } 00919 00920 bool RF24::writeFast( const void* buf, uint8_t len ){ 00921 return writeFast(buf,len,0); 00922 } 00923 00924 /****************************************************************************/ 00925 00926 //Per the documentation, we want to set PTX Mode when not listening. Then all we do is write data and set CE high 00927 //In this mode, if we can keep the FIFO buffers loaded, packets will transmit immediately (no 130us delay) 00928 //Otherwise we enter Standby-II mode, which is still faster than standby mode 00929 //Also, we remove the need to keep writing the config register over and over and delaying for 150 us each time if sending a stream of data 00930 00931 void RF24::startFastWrite( const void* buf, uint8_t len, const bool multicast, bool startTx){ //TMRh20 00932 00933 //write_payload( buf,len); 00934 write_payload( buf, len,multicast ? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD ) ; 00935 if(startTx){ 00936 ce(HIGH); 00937 } 00938 00939 } 00940 00941 /****************************************************************************/ 00942 00943 //Added the original startWrite back in so users can still use interrupts, ack payloads, etc 00944 //Allows the library to pass all tests 00945 void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ){ 00946 00947 // Send the payload 00948 00949 //write_payload( buf, len ); 00950 write_payload( buf, len,multicast? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD ) ; 00951 ce(HIGH); 00952 00953 wait_us(10); 00954 00955 ce(LOW); 00956 00957 00958 } 00959 00960 /****************************************************************************/ 00961 00962 bool RF24::rxFifoFull(){ 00963 return read_register(FIFO_STATUS) & _BV(RX_FULL); 00964 } 00965 /****************************************************************************/ 00966 00967 bool RF24::txStandBy(){ 00968 00969 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00970 uint32_t timeout = mainTimer.read_ms(); 00971 #endif 00972 while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){ 00973 if( get_status() & _BV(MAX_RT)){ 00974 write_register(NRF_STATUS,_BV(MAX_RT) ); 00975 ce(LOW); 00976 flush_tx(); //Non blocking, flush the data 00977 return 0; 00978 } 00979 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 00980 if( mainTimer.read_ms() - timeout > 95){ 00981 errNotify(); 00982 #if defined (FAILURE_HANDLING) 00983 return 0; 00984 #endif 00985 } 00986 #endif 00987 } 00988 00989 ce(LOW); //Set STANDBY-I mode 00990 return 1; 00991 } 00992 00993 /****************************************************************************/ 00994 00995 bool RF24::txStandBy(uint32_t timeout, bool startTx){ 00996 00997 if(startTx){ 00998 stopListening(); 00999 ce(HIGH); 01000 } 01001 uint32_t start = mainTimer.read_ms(); 01002 01003 while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){ 01004 if( get_status() & _BV(MAX_RT)){ 01005 write_register(NRF_STATUS,_BV(MAX_RT) ); 01006 ce(LOW); //Set re-transmit 01007 ce(HIGH); 01008 if(mainTimer.read_ms() - start >= timeout){ 01009 ce(LOW); flush_tx(); return 0; 01010 } 01011 } 01012 #if defined (FAILURE_HANDLING) || defined (RF24_LINUX) 01013 if( mainTimer.read_ms() - start > (timeout+95)){ 01014 errNotify(); 01015 #if defined (FAILURE_HANDLING) 01016 return 0; 01017 #endif 01018 } 01019 #endif 01020 } 01021 01022 01023 ce(LOW); //Set STANDBY-I mode 01024 return 1; 01025 01026 } 01027 01028 /****************************************************************************/ 01029 01030 void RF24::maskIRQ(bool tx, bool fail, bool rx){ 01031 01032 uint8_t config = read_register(NRF_CONFIG); 01033 /* clear the interrupt flags */ 01034 config &= ~(1 << MASK_MAX_RT | 1 << MASK_TX_DS | 1 << MASK_RX_DR); 01035 /* set the specified interrupt flags */ 01036 config |= fail << MASK_MAX_RT | tx << MASK_TX_DS | rx << MASK_RX_DR; 01037 write_register(NRF_CONFIG, config); 01038 } 01039 01040 /****************************************************************************/ 01041 01042 uint8_t RF24::getDynamicPayloadSize(void) 01043 { 01044 uint8_t result = 0; 01045 01046 01047 01048 01049 01050 01051 01052 01053 01054 beginTransaction(); 01055 spi.write( R_RX_PL_WID ); 01056 result = spi.write(0xff); 01057 endTransaction(); 01058 01059 01060 if(result > 32) { flush_rx(); wait_ms(2); return 0; } 01061 return result; 01062 } 01063 01064 /****************************************************************************/ 01065 01066 bool RF24::available(void) 01067 { 01068 return available(NULL); 01069 } 01070 01071 /****************************************************************************/ 01072 01073 bool RF24::available(uint8_t* pipe_num) 01074 { 01075 if (!( read_register(FIFO_STATUS) & _BV(RX_EMPTY) )){ 01076 01077 // If the caller wants the pipe number, include that 01078 if ( pipe_num ){ 01079 uint8_t status = get_status(); 01080 *pipe_num = ( status >> RX_P_NO ) & 0b111; 01081 } 01082 return 1; 01083 } 01084 01085 01086 return 0; 01087 01088 01089 } 01090 01091 /****************************************************************************/ 01092 01093 void RF24::read( void* buf, uint8_t len ){ 01094 01095 // Fetch the payload 01096 read_payload( buf, len ); 01097 01098 //Clear the two possible interrupt flags with one command 01099 write_register(NRF_STATUS,_BV(RX_DR) | _BV(MAX_RT) | _BV(TX_DS) ); 01100 01101 } 01102 01103 /****************************************************************************/ 01104 01105 void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready) 01106 { 01107 // Read the status & reset the status in one easy call 01108 // Or is that such a good idea? 01109 uint8_t status = write_register(NRF_STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); 01110 01111 // Report to the user what happened 01112 tx_ok = status & _BV(TX_DS); 01113 tx_fail = status & _BV(MAX_RT); 01114 rx_ready = status & _BV(RX_DR); 01115 } 01116 01117 /****************************************************************************/ 01118 01119 void RF24::openWritingPipe(uint64_t value) 01120 { 01121 // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) 01122 // expects it LSB first too, so we're good. 01123 01124 write_register(RX_ADDR_P0, reinterpret_cast<uint8_t*>(&value), addr_width); 01125 write_register(TX_ADDR, reinterpret_cast<uint8_t*>(&value), addr_width); 01126 01127 01128 //const uint8_t max_payload_size = 32; 01129 //write_register(RX_PW_P0,rf24_min(payload_size,max_payload_size)); 01130 write_register(RX_PW_P0,payload_size); 01131 } 01132 01133 /****************************************************************************/ 01134 void RF24::openWritingPipe(const uint8_t *address) 01135 { 01136 // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) 01137 // expects it LSB first too, so we're good. 01138 01139 write_register(RX_ADDR_P0,address, addr_width); 01140 write_register(TX_ADDR, address, addr_width); 01141 01142 //const uint8_t max_payload_size = 32; 01143 //write_register(RX_PW_P0,rf24_min(payload_size,max_payload_size)); 01144 write_register(RX_PW_P0,payload_size); 01145 } 01146 01147 /****************************************************************************/ 01148 static const uint8_t child_pipe[] PROGMEM = 01149 { 01150 RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5 01151 }; 01152 static const uint8_t child_payload_size[] PROGMEM = 01153 { 01154 RX_PW_P0, RX_PW_P1, RX_PW_P2, RX_PW_P3, RX_PW_P4, RX_PW_P5 01155 }; 01156 01157 01158 void RF24::openReadingPipe(uint8_t child, uint64_t address) 01159 { 01160 // If this is pipe 0, cache the address. This is needed because 01161 // openWritingPipe() will overwrite the pipe 0 address, so 01162 // startListening() will have to restore it. 01163 if (child == 0){ 01164 memcpy(pipe0_reading_address,&address,addr_width); 01165 } 01166 01167 if (child <= 6) 01168 { 01169 // For pipes 2-5, only write the LSB 01170 if ( child < 2 ) 01171 write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), addr_width); 01172 else 01173 write_register(pgm_read_byte(&child_pipe[child]), reinterpret_cast<const uint8_t*>(&address), 1); 01174 01175 write_register(pgm_read_byte(&child_payload_size[child]),payload_size); 01176 01177 // Note it would be more efficient to set all of the bits for all open 01178 // pipes at once. However, I thought it would make the calling code 01179 // more simple to do it this way. 01180 write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[child]))); 01181 } 01182 } 01183 01184 /****************************************************************************/ 01185 void RF24::setAddressWidth(uint8_t a_width){ 01186 01187 if(a_width -= 2){ 01188 write_register(SETUP_AW,a_width%4); 01189 addr_width = (a_width%4) + 2; 01190 } 01191 01192 } 01193 01194 /****************************************************************************/ 01195 01196 void RF24::openReadingPipe(uint8_t child, const uint8_t *address) 01197 { 01198 // If this is pipe 0, cache the address. This is needed because 01199 // openWritingPipe() will overwrite the pipe 0 address, so 01200 // startListening() will have to restore it. 01201 if (child == 0){ 01202 memcpy(pipe0_reading_address,address,addr_width); 01203 } 01204 if (child <= 6) 01205 { 01206 // For pipes 2-5, only write the LSB 01207 if ( child < 2 ){ 01208 write_register(pgm_read_byte(&child_pipe[child]), address, addr_width); 01209 }else{ 01210 write_register(pgm_read_byte(&child_pipe[child]), address, 1); 01211 } 01212 write_register(pgm_read_byte(&child_payload_size[child]),payload_size); 01213 01214 // Note it would be more efficient to set all of the bits for all open 01215 // pipes at once. However, I thought it would make the calling code 01216 // more simple to do it this way. 01217 write_register(EN_RXADDR,read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[child]))); 01218 01219 } 01220 } 01221 01222 /****************************************************************************/ 01223 01224 void RF24::closeReadingPipe( uint8_t pipe ) 01225 { 01226 write_register(EN_RXADDR,read_register(EN_RXADDR) & ~_BV(pgm_read_byte(&child_pipe_enable[pipe]))); 01227 } 01228 01229 /****************************************************************************/ 01230 01231 void RF24::toggle_features(void) 01232 { 01233 beginTransaction(); 01234 spi.write( ACTIVATE ); 01235 spi.write( 0x73 ); 01236 endTransaction(); 01237 } 01238 01239 /****************************************************************************/ 01240 01241 void RF24::enableDynamicPayloads(void) 01242 { 01243 // Enable dynamic payload throughout the system 01244 01245 //toggle_features(); 01246 write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) ); 01247 01248 01249 IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); 01250 01251 // Enable dynamic payload on all pipes 01252 // 01253 // Not sure the use case of only having dynamic payload on certain 01254 // pipes, so the library does not support it. 01255 write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P5) | _BV(DPL_P4) | _BV(DPL_P3) | _BV(DPL_P2) | _BV(DPL_P1) | _BV(DPL_P0)); 01256 01257 dynamic_payloads_enabled = true; 01258 } 01259 01260 /****************************************************************************/ 01261 01262 void RF24::enableAckPayload(void) 01263 { 01264 // 01265 // enable ack payload and dynamic payload features 01266 // 01267 01268 //toggle_features(); 01269 write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) ); 01270 01271 IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); 01272 01273 // 01274 // Enable dynamic payload on pipes 0 & 1 01275 // 01276 01277 write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0)); 01278 dynamic_payloads_enabled = true; 01279 } 01280 01281 /****************************************************************************/ 01282 01283 void RF24::enableDynamicAck(void){ 01284 // 01285 // enable dynamic ack features 01286 // 01287 //toggle_features(); 01288 write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) ); 01289 01290 IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); 01291 01292 01293 } 01294 01295 /****************************************************************************/ 01296 01297 void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) 01298 { 01299 const uint8_t* current = reinterpret_cast<const uint8_t*>(buf); 01300 01301 uint8_t data_len = rf24_min(len,32); 01302 01303 01304 01305 01306 01307 01308 01309 01310 01311 01312 01313 01314 01315 beginTransaction(); 01316 spi.write(W_ACK_PAYLOAD | ( pipe & 0b111 ) ); 01317 01318 while ( data_len-- ) 01319 spi.write(*current++); 01320 endTransaction(); 01321 01322 01323 01324 } 01325 01326 /****************************************************************************/ 01327 01328 bool RF24::isAckPayloadAvailable(void) 01329 { 01330 return ! (read_register(FIFO_STATUS) & _BV(RX_EMPTY)); 01331 } 01332 01333 /****************************************************************************/ 01334 01335 bool RF24::isPVariant(void) 01336 { 01337 return p_variant ; 01338 } 01339 01340 /****************************************************************************/ 01341 01342 void RF24::setAutoAck(bool enable) 01343 { 01344 if ( enable ) 01345 write_register(EN_AA, 0b111111); 01346 else 01347 write_register(EN_AA, 0); 01348 } 01349 01350 /****************************************************************************/ 01351 01352 void RF24::setAutoAck( uint8_t pipe, bool enable ) 01353 { 01354 if ( pipe <= 6 ) 01355 { 01356 uint8_t en_aa = read_register( EN_AA ) ; 01357 if( enable ) 01358 { 01359 en_aa |= _BV(pipe) ; 01360 } 01361 else 01362 { 01363 en_aa &= ~_BV(pipe) ; 01364 } 01365 write_register( EN_AA, en_aa ) ; 01366 } 01367 } 01368 01369 /****************************************************************************/ 01370 01371 bool RF24::testCarrier(void) 01372 { 01373 return ( read_register(CD) & 1 ); 01374 } 01375 01376 /****************************************************************************/ 01377 01378 bool RF24::testRPD(void) 01379 { 01380 return ( read_register(RPD) & 1 ) ; 01381 } 01382 01383 /****************************************************************************/ 01384 01385 void RF24::setPALevel(uint8_t level) 01386 { 01387 01388 uint8_t setup = read_register(RF_SETUP) & 0b11111000; 01389 01390 if(level > 3){ // If invalid level, go to max PA 01391 level = (RF24_PA_MAX << 1) + 1; // +1 to support the SI24R1 chip extra bit 01392 }else{ 01393 level = (level << 1) + 1; // Else set level as requested 01394 } 01395 01396 01397 write_register( RF_SETUP, setup |= level ) ; // Write it to the chip 01398 } 01399 01400 /****************************************************************************/ 01401 01402 uint8_t RF24::getPALevel(void) 01403 { 01404 01405 return (read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH))) >> 1 ; 01406 } 01407 01408 /****************************************************************************/ 01409 01410 bool RF24::setDataRate(rf24_datarate_e speed) 01411 { 01412 bool result = false; 01413 uint8_t setup = read_register(RF_SETUP) ; 01414 01415 // HIGH and LOW '00' is 1Mbs - our default 01416 setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ; 01417 01418 01419 01420 01421 txRxDelay=85; 01422 01423 if( speed == RF24_250KBPS ) 01424 { 01425 // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 01426 // Making it '10'. 01427 setup |= _BV( RF_DR_LOW ) ; 01428 01429 01430 01431 txRxDelay=155; 01432 01433 } 01434 else 01435 { 01436 // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1 01437 // Making it '01' 01438 if ( speed == RF24_2MBPS ) 01439 { 01440 setup |= _BV(RF_DR_HIGH); 01441 01442 01443 //txRxDelay=65; 01444 txRxDelay=15; //mbed works fine with this latency 01445 01446 } 01447 } 01448 write_register(RF_SETUP,setup); 01449 01450 // Verify our result 01451 if ( read_register(RF_SETUP) == setup ) 01452 { 01453 result = true; 01454 } 01455 return result; 01456 } 01457 01458 /****************************************************************************/ 01459 01460 rf24_datarate_e RF24::getDataRate( void ) 01461 { 01462 rf24_datarate_e result ; 01463 uint8_t dr = read_register(RF_SETUP) & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)); 01464 01465 // switch uses RAM (evil!) 01466 // Order matters in our case below 01467 if ( dr == _BV(RF_DR_LOW) ) 01468 { 01469 // '10' = 250KBPS 01470 result = RF24_250KBPS ; 01471 } 01472 else if ( dr == _BV(RF_DR_HIGH) ) 01473 { 01474 // '01' = 2MBPS 01475 result = RF24_2MBPS ; 01476 } 01477 else 01478 { 01479 // '00' = 1MBPS 01480 result = RF24_1MBPS ; 01481 } 01482 return result ; 01483 } 01484 01485 /****************************************************************************/ 01486 01487 void RF24::setCRCLength(rf24_crclength_e length) 01488 { 01489 uint8_t config = read_register(NRF_CONFIG) & ~( _BV(CRCO) | _BV(EN_CRC)) ; 01490 01491 // switch uses RAM (evil!) 01492 if ( length == RF24_CRC_DISABLED ) 01493 { 01494 // Do nothing, we turned it off above. 01495 } 01496 else if ( length == RF24_CRC_8 ) 01497 { 01498 config |= _BV(EN_CRC); 01499 } 01500 else 01501 { 01502 config |= _BV(EN_CRC); 01503 config |= _BV( CRCO ); 01504 } 01505 write_register( NRF_CONFIG, config ) ; 01506 } 01507 01508 /****************************************************************************/ 01509 01510 rf24_crclength_e RF24::getCRCLength(void) 01511 { 01512 rf24_crclength_e result = RF24_CRC_DISABLED; 01513 01514 uint8_t config = read_register(NRF_CONFIG) & ( _BV(CRCO) | _BV(EN_CRC)) ; 01515 uint8_t AA = read_register(EN_AA); 01516 01517 if ( config & _BV(EN_CRC ) || AA) 01518 { 01519 if ( config & _BV(CRCO) ) 01520 result = RF24_CRC_16; 01521 else 01522 result = RF24_CRC_8; 01523 } 01524 01525 return result; 01526 } 01527 01528 /****************************************************************************/ 01529 01530 void RF24::disableCRC( void ) 01531 { 01532 uint8_t disable = read_register(NRF_CONFIG) & ~_BV(EN_CRC) ; 01533 write_register( NRF_CONFIG, disable ) ; 01534 } 01535 01536 /****************************************************************************/ 01537 void RF24::setRetries(uint8_t delay, uint8_t count) 01538 { 01539 write_register(SETUP_RETR,(delay&0xf)<<ARD | (count&0xf)<<ARC); 01540 } 01541
Generated on Tue Jul 12 2022 18:10:10 by 1.7.2