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.
Dependents: STM32F407VET6_nRF24L01_Master STM32F407VET6_nRF24L01_Slave Main_ntp_sd_nrf IRC_MASTER
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 #include "RF24.h" 00009 00010 /** 00011 * @brief 00012 * @note 00013 * @param 00014 * @retval 00015 */ 00016 void RF24::csn(int mode) 00017 { 00018 // Minimum ideal spi bus speed is 2x data rate 00019 00020 // If we assume 2Mbs data rate and 16Mhz clock, a 00021 // divider of 4 is the minimum we want. 00022 // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz 00023 //#ifdef ARDUINO 00024 // spi.setBitOrder(MSBFIRST); 00025 // spi.setDataMode(spi_MODE0); 00026 // spi.setClockDivider(spi_CLOCK_DIV4); 00027 //#endif 00028 // digitalWrite(csn_pin,mode); 00029 csn_pin = mode; 00030 } 00031 00032 /** 00033 * @brief 00034 * @note 00035 * @param 00036 * @retval 00037 */ 00038 void RF24::ce(int level) 00039 { 00040 //digitalWrite(ce_pin,level); 00041 00042 ce_pin = level; 00043 } 00044 00045 /** 00046 * @brief 00047 * @note 00048 * @param 00049 * @retval 00050 */ 00051 uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len) 00052 { 00053 /*-----------*/ 00054 uint8_t status; 00055 /*-----------*/ 00056 00057 csn(LOW); 00058 status = spi.write(R_REGISTER | (REGISTER_MASK & reg)); 00059 while (len--) 00060 *buf++ = spi.write(0xff); 00061 00062 csn(HIGH); 00063 00064 return status; 00065 } 00066 00067 /** 00068 * @brief 00069 * @note 00070 * @param 00071 * @retval 00072 */ 00073 uint8_t RF24::read_register(uint8_t reg) 00074 { 00075 csn(LOW); 00076 spi.write(R_REGISTER | (REGISTER_MASK & reg)); 00077 00078 /*-----------------------------*/ 00079 uint8_t result = spi.write(0xff); 00080 /*-----------------------------*/ 00081 00082 csn(HIGH); 00083 return result; 00084 } 00085 00086 /** 00087 * @brief 00088 * @note 00089 * @param 00090 * @retval 00091 */ 00092 uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) 00093 { 00094 /*-----------*/ 00095 uint8_t status; 00096 /*-----------*/ 00097 00098 csn(LOW); 00099 status = spi.write(W_REGISTER | (REGISTER_MASK & reg)); 00100 while (len--) 00101 spi.write(*buf++); 00102 00103 csn(HIGH); 00104 00105 return status; 00106 } 00107 00108 /** 00109 * @brief 00110 * @note 00111 * @param 00112 * @retval 00113 */ 00114 uint8_t RF24::write_register(uint8_t reg, uint8_t value) 00115 { 00116 /*-----------*/ 00117 uint8_t status; 00118 /*-----------*/ 00119 00120 // IF_SERIAL_DEBUG(printf(("write_register(%02x,%02x)\r\n"),reg,value)); 00121 csn(LOW); 00122 status = spi.write(W_REGISTER | (REGISTER_MASK & reg)); 00123 spi.write(value); 00124 csn(HIGH); 00125 00126 return status; 00127 } 00128 00129 /** 00130 * @brief 00131 * @note 00132 * @param 00133 * @retval 00134 */ 00135 uint8_t RF24::write_payload(const void* buf, uint8_t len) 00136 { 00137 /*-------------------------------------------------------------------------------*/ 00138 uint8_t status; 00139 const uint8_t* current = reinterpret_cast < const uint8_t * > (buf); 00140 uint8_t data_len = min (len, payload_size); 00141 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; 00142 /*-------------------------------------------------------------------------------*/ 00143 00144 //printf("[Writing %u bytes %u blanks]",data_len,blank_len); 00145 csn(LOW); 00146 status = spi.write(W_TX_PAYLOAD); 00147 while (data_len--) 00148 spi.write(*current++); 00149 while (blank_len--) 00150 spi.write(0); 00151 csn(HIGH); 00152 00153 return status; 00154 } 00155 00156 /** 00157 * @brief 00158 * @note 00159 * @param 00160 * @retval 00161 */ 00162 uint8_t RF24::read_payload(void* buf, uint8_t len) 00163 { 00164 /*---------------------------------------------------------------------------*/ 00165 uint8_t status; 00166 uint8_t* current = reinterpret_cast < uint8_t * > (buf); 00167 uint8_t data_len = min (len, payload_size); 00168 uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; 00169 /*---------------------------------------------------------------------------*/ 00170 00171 //printf("[Reading %u bytes %u blanks]",data_len,blank_len); 00172 csn(LOW); 00173 status = spi.write(R_RX_PAYLOAD); 00174 while (data_len--) 00175 *current++ = spi.write(0xff); 00176 while (blank_len--) 00177 spi.write(0xff); 00178 csn(HIGH); 00179 00180 return status; 00181 } 00182 00183 /** 00184 * @brief 00185 * @note 00186 * @param 00187 * @retval 00188 */ 00189 uint8_t RF24::flush_rx(void) 00190 { 00191 /*-----------*/ 00192 uint8_t status; 00193 /*-----------*/ 00194 00195 csn(LOW); 00196 status = spi.write(FLUSH_RX); 00197 csn(HIGH); 00198 00199 return status; 00200 } 00201 00202 /** 00203 * @brief 00204 * @note 00205 * @param 00206 * @retval 00207 */ 00208 uint8_t RF24::flush_tx(void) 00209 { 00210 /*-----------*/ 00211 uint8_t status; 00212 /*-----------*/ 00213 00214 csn(LOW); 00215 status = spi.write(FLUSH_TX); 00216 csn(HIGH); 00217 00218 return status; 00219 } 00220 00221 /** 00222 * @brief 00223 * @note 00224 * @param 00225 * @retval 00226 */ 00227 uint8_t RF24::get_status(void) 00228 { 00229 /*-----------*/ 00230 uint8_t status; 00231 /*-----------*/ 00232 00233 csn(LOW); 00234 status = spi.write(NOP); 00235 csn(HIGH); 00236 00237 return status; 00238 } 00239 00240 //void RF24::print_status(uint8_t status) 00241 //{ 00242 // printf(("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n"), 00243 // status, 00244 // (status & _BV(RX_DR))?1:0, 00245 // (status & _BV(TX_DS))?1:0, 00246 // (status & _BV(MAX_RT))?1:0, 00247 // ((status >> RX_P_NO) & 7), 00248 // (status & _BV(TX_FULL))?1:0 00249 // ); 00250 //} 00251 // 00252 // 00253 // 00254 //void RF24::print_observe_tx(uint8_t value) 00255 //{ 00256 // printf(("OBSERVE_TX=%02x: POLS_CNT=%x ARC_CNT=%x\r\n"), 00257 // value, 00258 // (value >> PLOS_CNT) & 15, 00259 // (value >> ARC_CNT) & 15 00260 // ); 00261 //} 00262 // 00263 // 00264 // 00265 //void RF24::print_byte_register(const char* name, uint8_t reg, uint8_t qty) 00266 //{ 00267 // char extra_tab = strlen(name) < 8 ? '\t' : 0; 00268 // printf("%s =",name); 00269 // while (qty--) 00270 // printf((" 0x%02x"),read_register(reg++)); 00271 // printf(("\r\n")); 00272 //} 00273 // 00274 // 00275 // 00276 //void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty) 00277 //{ 00278 // char extra_tab = strlen_P(name) < 8 ? '\t' : 0; 00279 // printf("%s =",name); 00280 // 00281 // while (qty--) 00282 // { 00283 // uint8_t buffer[5]; 00284 // read_register(reg++,buffer,sizeof buffer); 00285 // 00286 // printf((" 0x")); 00287 // uint8_t* bufptr = buffer + sizeof buffer; 00288 // while( --bufptr >= buffer ) 00289 // printf(("%02x"),*bufptr); 00290 // } 00291 // 00292 // printf(("\r\n")); 00293 //} 00294 00295 // 00296 RF24::RF24(PinName mosi, PinName miso, PinName sck, PinName _csnpin, PinName _cepin) : 00297 ce_pin(_cepin), 00298 csn_pin(_csnpin), 00299 wide_band(true), 00300 p_variant(false), 00301 payload_size(32), 00302 ack_payload_available(false), 00303 dynamic_payloads_enabled(false), 00304 pipe0_reading_address(0), 00305 spi(mosi, miso, sck) 00306 { 00307 spi.frequency(10000000 / 5); // 2Mbit, 1/5th the maximum transfer rate for the spi bus 00308 spi.format(8, 0); // 8-bit, ClockPhase = 0, ClockPolarity = 0 00309 wait_ms(100); 00310 } 00311 00312 /** 00313 * @brief 00314 * @note 00315 * @param 00316 * @retval 00317 */ 00318 void RF24::setChannel(uint8_t channel) 00319 { 00320 // TODO: This method could take advantage of the 'wide_band' calculation 00321 00322 // done in setChannel() to require certain channel spacing. 00323 /*------------------------------*/ 00324 const uint8_t max_channel = 127; 00325 /*------------------------------*/ 00326 00327 write_register(RF_CH, min (channel, max_channel)); 00328 } 00329 00330 /** 00331 * @brief 00332 * @note 00333 * @param 00334 * @retval 00335 */ 00336 void RF24::setPayloadSize(uint8_t size) 00337 { 00338 /*----------------------------------*/ 00339 const uint8_t max_payload_size = 32; 00340 /*----------------------------------*/ 00341 00342 payload_size = min (size, max_payload_size); 00343 } 00344 00345 /** 00346 * @brief 00347 * @note 00348 * @param 00349 * @retval 00350 */ 00351 uint8_t RF24::getPayloadSize(void) 00352 { 00353 return payload_size; 00354 } 00355 00356 /*$off*/ 00357 static const char rf24_datarate_e_str_0[] = "1MBPS"; 00358 static const char rf24_datarate_e_str_1[] = "2MBPS"; 00359 static const char rf24_datarate_e_str_2[] = "250KBPS"; 00360 static const char *const rf24_datarate_e_str_P[] = { rf24_datarate_e_str_0, rf24_datarate_e_str_1, rf24_datarate_e_str_2, }; 00361 00362 static const char rf24_model_e_str_0[] = "nRF24L01"; 00363 static const char rf24_model_e_str_1[] = "nRF24L01+"; 00364 static const char *const rf24_model_e_str_P[] = { rf24_model_e_str_0, rf24_model_e_str_1, }; 00365 00366 static const char rf24_crclength_e_str_0[] = "Disabled"; 00367 static const char rf24_crclength_e_str_1[] = "8 bits"; 00368 static const char rf24_crclength_e_str_2[] = "16 bits"; 00369 static const char *const rf24_crclength_e_str_P[] = { rf24_crclength_e_str_0, rf24_crclength_e_str_1, rf24_crclength_e_str_2, }; 00370 00371 static const char rf24_pa_dbm_e_str_0[] = "PA_MIN"; 00372 static const char rf24_pa_dbm_e_str_1[] = "PA_LOW"; 00373 static const char rf24_pa_dbm_e_str_2[] = "PA_MED"; 00374 static const char rf24_pa_dbm_e_str_3[] = "PA_HIGH"; 00375 static const char *const rf24_pa_dbm_e_str_P[] = { rf24_pa_dbm_e_str_0, rf24_pa_dbm_e_str_1, rf24_pa_dbm_e_str_2, rf24_pa_dbm_e_str_3, }; 00376 00377 //void RF24::printDetails(void) 00378 00379 //{ 00380 // print_status(get_status()); 00381 // 00382 // print_address_register(("RX_ADDR_P0-1"),RX_ADDR_P0,2); 00383 // print_byte_register(("RX_ADDR_P2-5"),RX_ADDR_P2,4); 00384 // print_address_register(("TX_ADDR"),TX_ADDR); 00385 // 00386 // print_byte_register(("RX_PW_P0-6"),RX_PW_P0,6); 00387 // print_byte_register(("EN_AA"),EN_AA); 00388 // print_byte_register(("EN_RXADDR"),EN_RXADDR); 00389 // print_byte_register(("RF_CH"),RF_CH); 00390 // print_byte_register(("RF_SETUP"),RF_SETUP); 00391 // print_byte_register(("CONFIG"),CONFIG); 00392 // print_byte_register(("DYNPD/FEATURE"),DYNPD,2); 00393 // 00394 // printf(("Data Rate\t = %s\r\n"), rf24_datarate_e_str_P[getDataRate()]); 00395 // printf(("Model\t\t = %s\r\n"), rf24_model_e_str_P[isPVariant()]); 00396 // printf(("CRC Length\t = %s\r\n"),rf24_crclength_e_str_P[getCRCLength()]); 00397 // printf(("PA Power\t = %s\r\n"),rf24_pa_dbm_e_str_P[getPALevel()]); 00398 //} 00399 00400 // 00401 00402 /*$on*/ 00403 bool RF24::begin (void) 00404 { 00405 // Initialize pins 00406 // pinMode(ce_pin,OUTPUT); 00407 // pinMode(csn_pin,OUTPUT); 00408 // Initialize spi bus 00409 //spi.begin(); 00410 mainTimer.start(); 00411 00412 ce(LOW); 00413 csn(HIGH); 00414 00415 // Must allow the radio time to settle else configuration bits will not necessarily stick. 00416 // This is actually only required following power up but some settling time also appears to 00417 // be required after resets too. For full coverage, we'll always assume the worst. 00418 // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped. 00419 // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure. 00420 // WARNING: wait_ms is based on P-variant whereby non-P *may* require different timing. 00421 wait_ms(5); 00422 00423 // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier 00424 // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet 00425 // sizes must never be used. See documentation for a more complete explanation. 00426 write_register(SETUP_RETR, (4 << ARD) | (15 << ARC)); 00427 00428 // Test whether setPALevel works. 00429 setPALevel(RF24_PA_MIN); 00430 if (getPALevel() != RF24_PA_MIN) 00431 return false; // Something went wrog. Check whether nRF24L01 is connected. 00432 00433 // Restore our default PA level 00434 setPALevel(RF24_PA_MAX); 00435 00436 // Determine if this is a p or non-p RF24 module and then 00437 // reset our data rate back to default value. This works 00438 // because a non-P variant won't allow the data rate to 00439 // be set to 250Kbps. 00440 if (setDataRate(RF24_250KBPS)) 00441 { 00442 p_variant = true; 00443 } 00444 // Then set the data rate to the slowest (and most reliable) speed supported by all 00445 // hardware. 00446 setDataRate(RF24_1MBPS); 00447 00448 // Initialize CRC and request 2-byte (16bit) CRC 00449 setCRCLength(RF24_CRC_16); 00450 00451 // Disable dynamic payloads, to match dynamic_payloads_enabled setting 00452 write_register(DYNPD, 0); 00453 00454 // Reset current status 00455 // Notice reset and flush is the last thing we do 00456 write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); 00457 00458 // Set up default configuration. Callers can always change it later. 00459 // This channel should be universally safe and not bleed over into adjacent 00460 // spectrum. 00461 setChannel(76); 00462 00463 //setChannel(90); 00464 // Flush buffers 00465 flush_rx(); 00466 flush_tx(); 00467 00468 // set EN_RXADDRR to 0 to prevent pipe 0 and pipe 1 from receiving 00469 write_register(EN_RXADDR, 0); 00470 00471 return true; 00472 } 00473 00474 /** 00475 * @brief 00476 * @note 00477 * @param 00478 * @retval 00479 */ 00480 void RF24::startListening(void) 00481 { 00482 write_register(CONFIG, read_register(CONFIG) | _BV(PWR_UP) | _BV(PRIM_RX)); 00483 write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); 00484 00485 // Restore the pipe0 adddress, if exists 00486 if (pipe0_reading_address) 00487 write_register(RX_ADDR_P0, reinterpret_cast < const uint8_t * > (&pipe0_reading_address), 5); 00488 00489 // Flush buffers 00490 flush_rx(); 00491 flush_tx(); 00492 00493 // Go! 00494 ce(HIGH); 00495 00496 // wait for the radio to come up 00497 wait_us(130); 00498 } 00499 00500 static const uint8_t child_pipe[] = { RX_ADDR_P0, RX_ADDR_P1, RX_ADDR_P2, RX_ADDR_P3, RX_ADDR_P4, RX_ADDR_P5 }; 00501 static const uint8_t child_payload_size[] = { RX_PW_P0, RX_PW_P1, RX_PW_P2, RX_PW_P3, RX_PW_P4, RX_PW_P5 }; 00502 static const uint8_t child_pipe_enable[] = { ERX_P0, ERX_P1, ERX_P2, ERX_P3, ERX_P4, ERX_P5 }; 00503 00504 /** 00505 * @brief 00506 * @note 00507 * @param 00508 * @retval 00509 */ 00510 void RF24::stopListening(void) 00511 { 00512 ce(LOW); 00513 00514 wait_us(txRxDelay); 00515 00516 if (read_register(FEATURE) & _BV(EN_ACK_PAY)) 00517 { 00518 wait_us(txRxDelay); //200 00519 flush_tx(); 00520 } 00521 00522 //flush_rx(); 00523 write_register(CONFIG, (read_register(CONFIG)) &~_BV(PRIM_RX)); 00524 00525 write_register(EN_RXADDR, read_register(EN_RXADDR) | _BV(child_pipe_enable[0])); // Enable RX on pipe0 00526 wait_us(100); 00527 } 00528 00529 /** 00530 * @brief 00531 * @note 00532 * @param 00533 * @retval 00534 */ 00535 void RF24::powerDown(void) 00536 { 00537 write_register(CONFIG, read_register(CONFIG) &~_BV(PWR_UP)); 00538 } 00539 00540 /** 00541 * @brief 00542 * @note 00543 * @param 00544 * @retval 00545 */ 00546 void RF24::powerUp(void) 00547 { 00548 write_register(CONFIG, read_register(CONFIG) | _BV(PWR_UP)); 00549 } 00550 00551 /** 00552 * @brief 00553 * @note 00554 * @param 00555 * @retval 00556 */ 00557 bool RF24::write(const void* buf, uint8_t len) 00558 { 00559 /*------------------------------------------*/ 00560 bool result = false; 00561 uint8_t observe_tx; 00562 uint8_t status; 00563 uint32_t sent_at = mainTimer.read_ms(); 00564 const uint32_t timeout = 500; //ms to wait for timeout 00565 00566 /*------------------------------------------*/ 00567 // Begin the write 00568 startWrite(buf, len); 00569 00570 // ------------ 00571 // At this point we could return from a non-blocking write, and then call 00572 // the rest after an interrupt 00573 // Instead, we are going to block here until we get TX_DS (transmission completed and ack'd) 00574 // or MAX_RT (maximum retries, transmission failed). Also, we'll timeout in case the radio 00575 // is flaky and we get neither. 00576 // IN the end, the send should be blocking. It comes back in 60ms worst case, or much faster 00577 // if I tighted up the retry logic. (Default settings will be 1500us. 00578 // Monitor the send 00579 do { 00580 status = read_register(OBSERVE_TX, &observe_tx, 1); 00581 00582 // IF_SERIAL_DEBUG(Serial.print(observe_tx,HEX)); 00583 } while (!(status & (_BV(TX_DS) | _BV(MAX_RT))) && (mainTimer.read_ms() - sent_at < timeout)); 00584 00585 // The part above is what you could recreate with your own interrupt handler, 00586 // and then call this when you got an interrupt 00587 // ------------ 00588 // Call this when you get an interrupt 00589 // The status tells us three things 00590 // * The send was successful (TX_DS) 00591 // * The send failed, too many retries (MAX_RT) 00592 // * There is an ack packet waiting (RX_DR) 00593 bool tx_ok, tx_fail; 00594 /*-------------------*/ 00595 00596 whatHappened(tx_ok, tx_fail, ack_payload_available); 00597 00598 //printf("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available); 00599 result = tx_ok; 00600 00601 // IF_SERIAL_DEBUG(Serial.print(result?"...OK.":"...Failed")); 00602 // Handle the ack packet 00603 if (ack_payload_available) 00604 { 00605 ack_payload_length = getDynamicPayloadSize(); 00606 00607 // IF_SERIAL_DEBUG(Serial.print("[AckPacket]/")); 00608 // IF_SERIAL_DEBUG(Serial.println(ack_payload_length,DEC)); 00609 } 00610 00611 // Yay, we are done. 00612 // Power down 00613 // powerDown(); 00614 // Flush buffers (Is this a relic of past experimentation, and not needed anymore? 00615 // flush_tx(); 00616 return result; 00617 } 00618 00619 /** 00620 * @brief 00621 * @note 00622 * @param 00623 * @retval 00624 */ 00625 void RF24::startWrite(const void* buf, uint8_t len) 00626 { 00627 // Transmitter power-up 00628 00629 write_register(CONFIG, (read_register(CONFIG) | _BV(PWR_UP)) &~_BV(PRIM_RX)); 00630 wait_us(130); 00631 00632 // Send the payload 00633 write_payload(buf, len); 00634 00635 ce(HIGH); 00636 wait_us(15); 00637 ce(LOW); 00638 } 00639 00640 /** 00641 * @brief 00642 * @note 00643 * @param 00644 * @retval 00645 */ 00646 uint8_t RF24::getDynamicPayloadSize(void) 00647 { 00648 /*---------------*/ 00649 uint8_t result = 0; 00650 /*---------------*/ 00651 00652 csn(LOW); 00653 spi.write(R_RX_PL_WID); 00654 result = spi.write(0xff); 00655 csn(HIGH); 00656 00657 return result; 00658 } 00659 00660 /** 00661 * @brief 00662 * @note 00663 * @param 00664 * @retval 00665 */ 00666 bool RF24::available(void) 00667 { 00668 return available(NULL); 00669 } 00670 00671 /** 00672 * @brief 00673 * @note 00674 * @param 00675 * @retval 00676 */ 00677 bool RF24::available(uint8_t* pipe_num) 00678 { 00679 /*-----------------------------------*/ 00680 uint8_t status = get_status(); 00681 bool result = (status & _BV(RX_DR)); 00682 /*-----------------------------------*/ 00683 00684 // Too noisy, enable if you really want lots o data!! 00685 //IF_SERIAL_DEBUG(print_status(status)); 00686 if (result) 00687 { 00688 // If the caller wants the pipe number, include that 00689 if (pipe_num) 00690 *pipe_num = (status >> RX_P_NO) & 7; 00691 00692 // Clear the status bit 00693 // ??? Should this REALLY be cleared now? Or wait until we 00694 // actually READ the payload? 00695 write_register(STATUS, _BV(RX_DR)); 00696 00697 // Handle ack payload receipt 00698 if (status & _BV(TX_DS)) 00699 { 00700 write_register(STATUS, _BV(TX_DS)); 00701 } 00702 } 00703 00704 return result; 00705 } 00706 00707 /** 00708 * @brief 00709 * @note 00710 * @param 00711 * @retval 00712 */ 00713 bool RF24::read(void* buf, uint8_t len) 00714 { 00715 // Fetch the payload 00716 00717 read_payload(buf, len); 00718 00719 // was this the last of the data available? 00720 return read_register(FIFO_STATUS) & _BV(RX_EMPTY); 00721 } 00722 00723 /** 00724 * @brief 00725 * @note 00726 * @param 00727 * @retval 00728 */ 00729 void RF24::whatHappened(bool& tx_ok, bool& tx_fail, bool& rx_ready) 00730 { 00731 // Read the status & reset the status in one easy call 00732 00733 // Or is that such a good idea? 00734 uint8_t status = write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT)); 00735 00736 // Report to the user what happened 00737 00738 tx_ok = status & _BV(TX_DS); 00739 tx_fail = status & _BV(MAX_RT); 00740 rx_ready = status & _BV(RX_DR); 00741 } 00742 00743 /** 00744 * @brief 00745 * @note 00746 * @param 00747 * @retval 00748 */ 00749 void RF24::openWritingPipe(uint64_t value) 00750 { 00751 // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+) 00752 // expects it LSB first too, so we're good. 00753 write_register(RX_ADDR_P0, reinterpret_cast < uint8_t * > (&value), 5); 00754 write_register(TX_ADDR, reinterpret_cast < uint8_t * > (&value), 5); 00755 00756 /*----------------------------------*/ 00757 const uint8_t max_payload_size = 32; 00758 /*----------------------------------*/ 00759 00760 write_register(RX_PW_P0, min (payload_size, max_payload_size)); 00761 00762 flush_tx(); 00763 } 00764 00765 /** 00766 * @brief 00767 * @note 00768 * @param 00769 * @retval 00770 */ 00771 void RF24::openReadingPipe(uint8_t child, uint64_t address) 00772 { 00773 // If this is pipe 0, cache the address. This is needed because 00774 // openWritingPipe() will overwrite the pipe 0 address, so 00775 // startListening() will have to restore it. 00776 if (child == 0) 00777 pipe0_reading_address = address; 00778 00779 if (child <= 6) 00780 { 00781 // For pipes 2-5, only write the LSB 00782 //if (child < 2) 00783 write_register(child_pipe[child], reinterpret_cast < const uint8_t * > (&address), 5); 00784 //else 00785 // write_register(child_pipe[child], reinterpret_cast < const uint8_t * > (&address), 1); 00786 00787 write_register(child_payload_size[child], payload_size); 00788 00789 // Note it would be more efficient to set all of the bits for all open 00790 // pipes at once. However, I thought it would make the calling code 00791 // more simple to do it this way. 00792 write_register(EN_RXADDR, read_register(EN_RXADDR) | _BV(child_pipe_enable[child])); 00793 } 00794 } 00795 00796 /** 00797 * @brief 00798 * @note 00799 * @param 00800 * @retval 00801 */ 00802 void RF24::toggle_features(void) 00803 { 00804 csn(LOW); 00805 spi.write(ACTIVATE); 00806 spi.write(0x73); 00807 csn(HIGH); 00808 } 00809 00810 /** 00811 * @brief 00812 * @note 00813 * @param 00814 * @retval 00815 */ 00816 void RF24::enableDynamicPayloads(void) 00817 { 00818 // Enable dynamic payload throughout the system 00819 00820 write_register(FEATURE, read_register(FEATURE) | _BV(EN_DPL)); 00821 00822 // If it didn't work, the features are not enabled 00823 if (!read_register(FEATURE)) 00824 { 00825 // So enable them and try again 00826 toggle_features(); 00827 write_register(FEATURE, read_register(FEATURE) | _BV(EN_DPL)); 00828 } 00829 00830 // IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); 00831 // Enable dynamic payload on all pipes 00832 // 00833 // Not sure the use case of only having dynamic payload on certain 00834 // pipes, so the library does not support it. 00835 write_register 00836 ( 00837 DYNPD, 00838 read_register(DYNPD) | _BV(DPL_P5) | _BV(DPL_P4) | _BV(DPL_P3) | _BV(DPL_P2) | _BV(DPL_P1) | _BV(DPL_P0) 00839 ); 00840 00841 dynamic_payloads_enabled = true; 00842 } 00843 00844 /** 00845 * @brief 00846 * @note 00847 * @param 00848 * @retval 00849 */ 00850 void RF24::enableAckPayload(void) 00851 { 00852 // 00853 00854 // enable ack payload and dynamic payload features 00855 // 00856 write_register(FEATURE, read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL)); 00857 00858 // If it didn't work, the features are not enabled 00859 if (!read_register(FEATURE)) 00860 { 00861 // So enable them and try again 00862 toggle_features(); 00863 write_register(FEATURE, read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL)); 00864 } 00865 00866 // IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE))); 00867 // 00868 // Enable dynamic payload on pipes 0 & 1 00869 // 00870 write_register(DYNPD, read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0)); 00871 } 00872 00873 /** 00874 * @brief 00875 * @note 00876 * @param 00877 * @retval 00878 */ 00879 void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len) 00880 { 00881 /*-----------------------------------------------------------------*/ 00882 const uint8_t* current = reinterpret_cast < const uint8_t * > (buf); 00883 /*-----------------------------------------------------------------*/ 00884 00885 csn(LOW); 00886 spi.write(W_ACK_PAYLOAD | (pipe & 7)); 00887 00888 /*--------------------------------------------------*/ 00889 const uint8_t max_payload_size = 32; 00890 uint8_t data_len = min (len, max_payload_size); 00891 /*--------------------------------------------------*/ 00892 00893 while (data_len--) 00894 spi.write(*current++); 00895 00896 csn(HIGH); 00897 } 00898 00899 /** 00900 * @brief 00901 * @note 00902 * @param 00903 * @retval 00904 */ 00905 bool RF24::isAckPayloadAvailable(void) 00906 { 00907 /*-----------------------------------*/ 00908 bool result = ack_payload_available; 00909 /*-----------------------------------*/ 00910 00911 ack_payload_available = false; 00912 return result; 00913 } 00914 00915 /** 00916 * @brief 00917 * @note 00918 * @param 00919 * @retval 00920 */ 00921 bool RF24::isPVariant(void) 00922 { 00923 return p_variant; 00924 } 00925 00926 /** 00927 * @brief 00928 * @note 00929 * @param 00930 * @retval 00931 */ 00932 void RF24::setAutoAck(bool enable) 00933 { 00934 if (enable) 00935 write_register(EN_AA, 63); 00936 else 00937 write_register(EN_AA, 0); 00938 } 00939 00940 /** 00941 * @brief 00942 * @note 00943 * @param 00944 * @retval 00945 */ 00946 void RF24::setAutoAck(uint8_t pipe, bool enable) 00947 { 00948 if (pipe <= 6) 00949 { 00950 /*---------------------------------*/ 00951 uint8_t en_aa = read_register(EN_AA); 00952 /*---------------------------------*/ 00953 00954 if (enable) 00955 { 00956 en_aa |= _BV(pipe); 00957 } 00958 else 00959 { 00960 en_aa &= ~_BV(pipe); 00961 } 00962 00963 write_register(EN_AA, en_aa); 00964 } 00965 } 00966 00967 /** 00968 * @brief 00969 * @note 00970 * @param 00971 * @retval 00972 */ 00973 bool RF24::testCarrier(void) 00974 { 00975 return(read_register(CD) & 1); 00976 } 00977 00978 /** 00979 * @brief 00980 * @note 00981 * @param 00982 * @retval 00983 */ 00984 bool RF24::testRPD(void) 00985 { 00986 return(read_register(RPD) & 1); 00987 } 00988 00989 /** 00990 * @brief 00991 * @note 00992 * @param 00993 * @retval 00994 */ 00995 void RF24::setPALevel(rf24_pa_dbm_e level) 00996 { 00997 /*------------------------------------*/ 00998 uint8_t setup = read_register(RF_SETUP); 00999 /*------------------------------------*/ 01000 01001 setup &= ~(_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)); 01002 01003 // switch uses RAM (evil!) 01004 if (level == RF24_PA_MAX) 01005 { 01006 setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)); 01007 } 01008 else 01009 if (level == RF24_PA_HIGH) 01010 { 01011 setup |= _BV(RF_PWR_HIGH); 01012 } 01013 else 01014 if (level == RF24_PA_LOW) 01015 { 01016 setup |= _BV(RF_PWR_LOW); 01017 } 01018 else 01019 if (level == RF24_PA_MIN) 01020 { 01021 // nothing 01022 } 01023 else 01024 if (level == RF24_PA_ERROR) 01025 { 01026 // On error, go to maximum PA 01027 setup |= (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)); 01028 } 01029 01030 write_register(RF_SETUP, setup); 01031 } 01032 01033 /** 01034 * @brief 01035 * @note 01036 * @param 01037 * @retval 01038 */ 01039 rf24_pa_dbm_e RF24::getPALevel(void) 01040 { 01041 /*-----------------------------------------------------------------------------------*/ 01042 rf24_pa_dbm_e result = RF24_PA_ERROR; 01043 uint8_t power = read_register(RF_SETUP) & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH)); 01044 /*-----------------------------------------------------------------------------------*/ 01045 01046 // switch uses RAM (evil!) 01047 if (power == (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH))) 01048 { 01049 result = RF24_PA_MAX; 01050 } 01051 else 01052 if (power == _BV(RF_PWR_HIGH)) 01053 { 01054 result = RF24_PA_HIGH; 01055 } 01056 else 01057 if (power == _BV(RF_PWR_LOW)) 01058 { 01059 result = RF24_PA_LOW; 01060 } 01061 else 01062 { 01063 result = RF24_PA_MIN; 01064 } 01065 01066 return result; 01067 } 01068 01069 /** 01070 * @brief 01071 * @note 01072 * @param 01073 * @retval 01074 */ 01075 bool RF24::setDataRate(rf24_datarate_e speed) 01076 { 01077 /*------------------------------------*/ 01078 bool result = false; 01079 uint8_t setup = read_register(RF_SETUP); 01080 /*------------------------------------*/ 01081 01082 // HIGH and LOW '00' is 1Mbs - our default 01083 setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)); 01084 01085 txRxDelay = 250; 01086 if (speed == RF24_250KBPS) 01087 { 01088 // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 01089 // Making it '10'. 01090 setup |= _BV(RF_DR_LOW); 01091 txRxDelay = 450; 01092 } 01093 else 01094 { 01095 // Set 2Mbs, RF_DR (RF_DR_HIGH) is set 1 01096 // Making it '01' 01097 if (speed == RF24_2MBPS) 01098 { 01099 setup |= _BV(RF_DR_HIGH); 01100 txRxDelay = 190; 01101 } 01102 } 01103 01104 write_register(RF_SETUP, setup); 01105 01106 // Verify our result 01107 if (read_register(RF_SETUP) == setup) 01108 { 01109 result = true; 01110 } 01111 01112 return result; 01113 } 01114 01115 /** 01116 * @brief 01117 * @note 01118 * @param 01119 * @retval 01120 */ 01121 rf24_datarate_e RF24::getDataRate(void) 01122 { 01123 /*------------------------------------------------------------------------------*/ 01124 rf24_datarate_e result; 01125 uint8_t dr = read_register(RF_SETUP) & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)); 01126 /*------------------------------------------------------------------------------*/ 01127 01128 // switch uses RAM (evil!) 01129 // Order matters in our case below 01130 if (dr == _BV(RF_DR_LOW)) 01131 { 01132 // '10' = 250KBPS 01133 result = RF24_250KBPS; 01134 } 01135 else 01136 if (dr == _BV(RF_DR_HIGH)) 01137 { 01138 // '01' = 2MBPS 01139 result = RF24_2MBPS; 01140 } 01141 else 01142 { 01143 // '00' = 1MBPS 01144 result = RF24_1MBPS; 01145 } 01146 01147 return result; 01148 } 01149 01150 /** 01151 * @brief 01152 * @note 01153 * @param 01154 * @retval 01155 */ 01156 void RF24::setCRCLength(rf24_crclength_e length) 01157 { 01158 /*---------------------------------------------------------------*/ 01159 uint8_t config = read_register(CONFIG) &~(_BV(CRCO) | _BV(EN_CRC)); 01160 /*---------------------------------------------------------------*/ 01161 01162 if (length == RF24_CRC_DISABLED) 01163 { 01164 // Do nothing, we turned it off above. 01165 } 01166 else 01167 if (length == RF24_CRC_8) 01168 { 01169 config |= _BV(EN_CRC); 01170 } 01171 else 01172 { 01173 config |= _BV(EN_CRC); 01174 config |= _BV(CRCO); 01175 } 01176 01177 write_register(CONFIG, config); 01178 } 01179 01180 /** 01181 * @brief 01182 * @note 01183 * @param 01184 * @retval 01185 */ 01186 rf24_crclength_e RF24::getCRCLength(void) 01187 { 01188 /*---------------------------------------------------------------------------*/ 01189 rf24_crclength_e result = RF24_CRC_DISABLED; 01190 uint8_t config = read_register(CONFIG) & (_BV(CRCO) | _BV(EN_CRC)); 01191 /*---------------------------------------------------------------------------*/ 01192 01193 if (config & _BV(EN_CRC)) 01194 { 01195 if (config & _BV(CRCO)) 01196 result = RF24_CRC_16; 01197 else 01198 result = RF24_CRC_8; 01199 } 01200 01201 return result; 01202 } 01203 01204 /** 01205 * @brief 01206 * @note 01207 * @param 01208 * @retval 01209 */ 01210 void RF24::disableCRC(void) 01211 { 01212 /*--------------------------------------------------*/ 01213 uint8_t disable = read_register(CONFIG) &~_BV(EN_CRC); 01214 /*--------------------------------------------------*/ 01215 01216 write_register(CONFIG, disable); 01217 } 01218 01219 /** 01220 * @brief 01221 * @note 01222 * @param 01223 * @retval 01224 */ 01225 void RF24::setRetries(uint8_t delay, uint8_t count) 01226 { 01227 write_register(SETUP_RETR, (delay & 0xf) << ARD | (count & 0xf) << ARC); 01228 } 01229 01230 /** 01231 * @brief 01232 * @note 01233 * @param 01234 * @retval 01235 */ 01236 uint8_t RF24::min (uint8_t a, uint8_t b) 01237 { 01238 if (a < b) 01239 return a; 01240 else 01241 return b; 01242 } 01243
Generated on Wed Jul 13 2022 10:10:40 by
 1.7.2
 1.7.2