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