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