Maniacbug's nRF24L01 arduino library ported to mbed. Functional with minor issues.
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 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(RF_LOW); 00044 status = spi.write( R_REGISTER | ( REGISTER_MASK & reg ) ); 00045 while ( len-- ) 00046 *buf++ = spi.write(0xff); 00047 00048 csn(RF_HIGH); 00049 00050 return status; 00051 } 00052 00053 /****************************************************************************/ 00054 00055 uint8_t RF24::read_register(uint8_t reg) 00056 { 00057 csn(RF_LOW); 00058 spi.write( R_REGISTER | ( REGISTER_MASK & reg ) ); 00059 uint8_t result = spi.write(0xff); 00060 00061 csn(RF_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(RF_LOW); 00072 status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) ); 00073 while ( len-- ) 00074 spi.write(*buf++); 00075 00076 csn(RF_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(RF_LOW); 00090 status = spi.write( W_REGISTER | ( REGISTER_MASK & reg ) ); 00091 spi.write(value); 00092 csn(RF_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(RF_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(RF_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(RF_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(RF_HIGH); 00140 00141 return status; 00142 } 00143 00144 /****************************************************************************/ 00145 00146 uint8_t RF24::flush_rx(void) 00147 { 00148 uint8_t status; 00149 00150 csn(RF_LOW); 00151 status = spi.write( FLUSH_RX ); 00152 csn(RF_HIGH); 00153 00154 return status; 00155 } 00156 00157 /****************************************************************************/ 00158 00159 uint8_t RF24::flush_tx(void) 00160 { 00161 uint8_t status; 00162 00163 csn(RF_LOW); 00164 status = spi.write( FLUSH_TX ); 00165 csn(RF_HIGH); 00166 00167 return status; 00168 } 00169 00170 /****************************************************************************/ 00171 00172 uint8_t RF24::get_status(void) 00173 { 00174 uint8_t status; 00175 00176 csn(RF_LOW); 00177 status = spi.write( RF_NOP ); 00178 csn(RF_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\t"),RX_ADDR_P0,2); 00317 print_byte_register(("RX_ADDR_P2-5\t"),RX_ADDR_P2,4); 00318 print_address_register(("TX_ADDR\t\t"),TX_ADDR); 00319 00320 print_byte_register(("RX_PW_P0-6\t"),RX_PW_P0,6); 00321 print_byte_register(("EN_AA\t\t"),EN_AA); 00322 print_byte_register(("EN_RXADDR\t"),EN_RXADDR); 00323 print_byte_register(("RF_CH\t\t"),RF_CH); 00324 print_byte_register(("RF_SETUP\t"),RF_SETUP); 00325 print_byte_register(("CONFIG\t\t"),CONFIG); 00326 print_byte_register(("DYNPD/FEATURE\t"),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(RF_LOW); 00347 csn(RF_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(RF_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(RF_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(RF_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(RF_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(RF_HIGH); 00527 // wait_msMicroseconds(15); 00528 wait_us(15); 00529 ce(RF_LOW); 00530 } 00531 00532 /****************************************************************************/ 00533 00534 uint8_t RF24::getDynamicPayloadSize(void) 00535 { 00536 uint8_t result = 0; 00537 00538 csn(RF_LOW); 00539 spi.write( R_RX_PL_WID ); 00540 result = spi.write(0xff); 00541 csn(RF_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(RF_STATUS,_BV(RX_DR) ); 00576 00577 // Handle ack payload receipt 00578 if ( status & _BV(TX_DS) ) 00579 { 00580 write_register(RF_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(RF_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(RF_LOW); 00673 spi.write( ACTIVATE ); 00674 spi.write( 0x73 ); 00675 csn(RF_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(RF_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(RF_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 Thu Jul 14 2022 21:20:38 by 1.7.2