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