enableDynamicAck(), Single NOACK, default RT,
- Added new function: enableDynamicAck() to enable single-write NOACK payloads (merge closer with gcopeland fork) - Added single NOACK writes for write(), writeFast(), startWrite() and startFastWrite() - powerUp() now checks to see if radio is powered on. No delay if powered up. - radio must still be powered up manually if powered down manually - use setRetries function in begin() - set CE low on powerDown - updated readme
This commit is contained in:
@@ -2,20 +2,23 @@
|
||||
|
||||
Design Goals: This library is designed to be...
|
||||
|
||||
* More compliant with the manufacturer specified operation of the chip
|
||||
* More compliant with the manufacturer specified operation of the chip, while allowing advanced users
|
||||
* to work outside the reccommended operation.
|
||||
* Utilize the capabilities of the radio to their full potential via Arduino
|
||||
* More reliable and feature rich
|
||||
* Easy for beginners to use
|
||||
* Easy for beginners to use, with well documented examples and features
|
||||
* Consumed with a public interface that's similiar to other Arduino standard libraries
|
||||
* Built against the standard SPI library.
|
||||
|
||||
March 2014: Optimization begun
|
||||
April 2014: Optimization nearing completion
|
||||
* The library has been tweaked to allow full use of the FIFO buffers for maximum transfer speeds
|
||||
* Changes to read() functionality have increased reliability and response
|
||||
* Extended timeout periods have been added to aid in noisy or otherwise unreliable environments
|
||||
* Delays have been removed where possible to ensure maximum efficiency
|
||||
* Arduino Due fully supported with extended SPI functions
|
||||
* More! See the links below and class documentation for more info.
|
||||
April 2014: Official Release: Still some work to do, but most benefits have been realized
|
||||
|
||||
* The library has been tweaked to allow full use of the FIFO buffers for maximum transfer speeds
|
||||
* Changes to read() and available () functionality have increased reliability and response
|
||||
* Extended timeout periods have been added to aid in noisy or otherwise unreliable environments
|
||||
* Delays have been removed where possible to ensure maximum efficiency
|
||||
* Full Due support with extended SPI functions
|
||||
* ATTiny 24/44/84 25/45/85 now supported.
|
||||
* More! See the links below and class documentation for more info.
|
||||
|
||||
Please refer to:
|
||||
|
||||
@@ -27,4 +30,11 @@ Please refer to:
|
||||
|
||||
This chip uses the SPI bus, plus two chip control pins. Remember that pin 10 must still remain an output, or
|
||||
the SPI hardware will go into 'slave' mode.
|
||||
|
||||
|
||||
Supported Boards:
|
||||
|
||||
* Uno, Nano, etc (328 based boards)
|
||||
* Mega Types (2560, 1280, etc)
|
||||
* ARM (Arduino Due) via extended SPI methods
|
||||
* ATTiny 24/44/84 25/45/85
|
||||
* See the [documentation](http://tmrh20.github.io/) for more info
|
||||
@@ -135,7 +135,7 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
uint8_t RF24::write_payload(const void* buf, uint8_t data_len)
|
||||
uint8_t RF24::write_payload(const void* buf, uint8_t data_len, const uint8_t writeType)
|
||||
{
|
||||
uint8_t status;
|
||||
const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
|
||||
@@ -147,7 +147,7 @@ uint8_t RF24::write_payload(const void* buf, uint8_t data_len)
|
||||
|
||||
#if defined (__arm__)
|
||||
|
||||
status = SPI.transfer(csn_pin, W_TX_PAYLOAD , SPI_CONTINUE);
|
||||
status = SPI.transfer(csn_pin, writeType , SPI_CONTINUE);
|
||||
|
||||
if(blank_len){
|
||||
while ( data_len--){
|
||||
@@ -160,14 +160,14 @@ uint8_t RF24::write_payload(const void* buf, uint8_t data_len)
|
||||
}else{
|
||||
while( --data_len ){
|
||||
SPI.transfer(csn_pin,*current++, SPI_CONTINUE);
|
||||
}
|
||||
}
|
||||
SPI.transfer(csn_pin,*current);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
csn(LOW);
|
||||
status = SPI.transfer( W_TX_PAYLOAD );
|
||||
status = SPI.transfer( writeType );
|
||||
while ( data_len-- ) {
|
||||
SPI.transfer(*current++);
|
||||
}
|
||||
@@ -205,7 +205,7 @@ uint8_t RF24::read_payload(void* buf, uint8_t data_len)
|
||||
}
|
||||
while ( --blank_len ){
|
||||
SPI.transfer(csn_pin,0xFF, SPI_CONTINUE);
|
||||
}
|
||||
}
|
||||
SPI.transfer(csn_pin,0xFF);
|
||||
}else{
|
||||
while ( --data_len ){
|
||||
@@ -346,7 +346,7 @@ void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
|
||||
/****************************************************************************/
|
||||
|
||||
RF24::RF24(uint8_t _cepin, uint8_t _cspin):
|
||||
ce_pin(_cepin), csn_pin(_cspin), wide_band(true), p_variant(false),
|
||||
ce_pin(_cepin), csn_pin(_cspin), wide_band(false), p_variant(false),
|
||||
payload_size(32), ack_payload_available(false), dynamic_payloads_enabled(false),
|
||||
pipe0_reading_address(0)
|
||||
{
|
||||
@@ -466,8 +466,6 @@ void RF24::begin(void)
|
||||
csn(HIGH);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Must allow the radio time to settle else configuration bits will not necessarily stick.
|
||||
// This is actually only required following power up but some settling time also appears to
|
||||
// be required after resets too. For full coverage, we'll always assume the worst.
|
||||
@@ -479,7 +477,7 @@ void RF24::begin(void)
|
||||
// Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
|
||||
// WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
|
||||
// sizes must never be used. See documentation for a more complete explanation.
|
||||
write_register(SETUP_RETR,(B0100 << ARD) | (B1111 << ARC));
|
||||
setRetries(5,15);
|
||||
|
||||
// Restore our default PA level
|
||||
setPALevel( RF24_PA_MAX ) ;
|
||||
@@ -516,9 +514,10 @@ void RF24::begin(void)
|
||||
flush_rx();
|
||||
flush_tx();
|
||||
|
||||
powerUp();
|
||||
delay(5);
|
||||
//Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp )
|
||||
powerUp(); //Power up by default when begin() is called
|
||||
|
||||
// Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp )
|
||||
// PTX should use only 22uA of power
|
||||
write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) );
|
||||
|
||||
|
||||
@@ -528,7 +527,8 @@ void RF24::begin(void)
|
||||
|
||||
void RF24::startListening(void)
|
||||
{
|
||||
write_register(CONFIG, read_register(CONFIG) | _BV(PWR_UP) | _BV(PRIM_RX));
|
||||
powerUp();
|
||||
write_register(CONFIG, read_register(CONFIG) | _BV(PRIM_RX));
|
||||
write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
|
||||
|
||||
// Restore the pipe0 adddress, if exists
|
||||
@@ -559,6 +559,7 @@ void RF24::stopListening(void)
|
||||
|
||||
void RF24::powerDown(void)
|
||||
{
|
||||
ce(LOW); // Guarantee CE is low on powerDown
|
||||
write_register(CONFIG,read_register(CONFIG) & ~_BV(PWR_UP));
|
||||
}
|
||||
|
||||
@@ -567,17 +568,23 @@ void RF24::powerDown(void)
|
||||
//Power up now. Radio will not power down unless instructed by MCU for config changes etc.
|
||||
void RF24::powerUp(void)
|
||||
{
|
||||
write_register(CONFIG,read_register(CONFIG) | _BV(PWR_UP));
|
||||
delay(5);
|
||||
uint8_t cfg = read_register(CONFIG);
|
||||
|
||||
// if not powered up then power up and wait for the radio to initialize
|
||||
if (!(cfg & _BV(PWR_UP))){
|
||||
write_register(CONFIG,read_register(CONFIG) | _BV(PWR_UP));
|
||||
delayMicroseconds(1500);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
//Similar to the previous write, clears the interrupt flags
|
||||
bool RF24::write( const void* buf, uint8_t len )
|
||||
bool RF24::write( const void* buf, uint8_t len, const bool multicast )
|
||||
{
|
||||
//Start Writing
|
||||
startWrite(buf,len);
|
||||
startWrite(buf,len,multicast);
|
||||
|
||||
//Wait until complete or failed
|
||||
//ACK payloads that are handled improperly will cause this to hang
|
||||
@@ -595,6 +602,9 @@ bool RF24::write( const void* buf, uint8_t len )
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool RF24::write( const void* buf, uint8_t len ){
|
||||
write(buf,len,0);
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
//For general use, the interrupt flags are not important to clear
|
||||
@@ -617,7 +627,7 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout )
|
||||
}
|
||||
|
||||
//Start Writing
|
||||
startFastWrite(buf,len); //Write the payload if a buffer is clear
|
||||
startFastWrite(buf,len,0); //Write the payload if a buffer is clear
|
||||
|
||||
return 1; //Return 1 to indicate successful transmission
|
||||
}
|
||||
@@ -638,7 +648,7 @@ void RF24::reUseTX(){
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
bool RF24::writeFast( const void* buf, uint8_t len )
|
||||
bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
|
||||
{
|
||||
//Block until the FIFO is NOT full.
|
||||
//Keep track of the MAX retries and set auto-retry if seeing failures
|
||||
@@ -656,12 +666,14 @@ bool RF24::writeFast( const void* buf, uint8_t len )
|
||||
|
||||
}
|
||||
//Start Writing
|
||||
startFastWrite(buf,len);
|
||||
startFastWrite(buf,len,multicast);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool RF24::writeFast( const void* buf, uint8_t len ){
|
||||
writeFast(buf,len,0);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -670,9 +682,10 @@ bool RF24::writeFast( const void* buf, uint8_t len )
|
||||
//Otherwise we enter Standby-II mode, which is still faster than standby mode
|
||||
//Also, we remove the need to keep writing the config register over and over and delaying for 150 us each time if sending a stream of data
|
||||
|
||||
void RF24::startFastWrite( const void* buf, uint8_t len ){ //TMRh20
|
||||
void RF24::startFastWrite( const void* buf, uint8_t len, const bool multicast){ //TMRh20
|
||||
|
||||
write_payload( buf,len);
|
||||
//write_payload( buf,len);
|
||||
write_payload( buf, len,multicast?static_cast<uint8_t>(W_TX_PAYLOAD_NO_ACK):static_cast<uint8_t>(W_TX_PAYLOAD) ) ;
|
||||
ce(HIGH);
|
||||
|
||||
}
|
||||
@@ -680,11 +693,12 @@ void RF24::startFastWrite( const void* buf, uint8_t len ){ //TMRh20
|
||||
|
||||
//Added the original startWrite back in so users can still use interrupts, ack payloads, etc
|
||||
//Allows the library to pass all tests
|
||||
void RF24::startWrite( const void* buf, uint8_t len ){
|
||||
void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ){
|
||||
|
||||
// Send the payload
|
||||
|
||||
write_payload( buf, len );
|
||||
//write_payload( buf, len );
|
||||
write_payload( buf, len,multicast?static_cast<uint8_t>(W_TX_PAYLOAD_NO_ACK):static_cast<uint8_t>(W_TX_PAYLOAD) ) ;
|
||||
ce(HIGH);
|
||||
ce(LOW);
|
||||
|
||||
@@ -933,6 +947,27 @@ void RF24::enableAckPayload(void)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void RF24::enableDynamicAck(void){
|
||||
//
|
||||
// enable dynamic ack features
|
||||
//
|
||||
|
||||
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) );
|
||||
|
||||
// If it didn't work, the features are not enabled
|
||||
if ( ! read_register(FEATURE) & _BV(EN_DYN_ACK) ){
|
||||
// So enable them and try again
|
||||
toggle_features();
|
||||
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DYN_ACK) );
|
||||
}
|
||||
|
||||
IF_SERIAL_DEBUG(printf("FEATURE=%i\r\n",read_register(FEATURE)));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
|
||||
{
|
||||
const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
|
||||
|
||||
@@ -256,6 +256,22 @@ public:
|
||||
*/
|
||||
void powerUp(void) ;
|
||||
|
||||
/**
|
||||
* Write for single NOACK writes. Disables acknowledgements/autoretries for a single write.
|
||||
*
|
||||
* @note enableDynamicAck() must be called to enable this feature
|
||||
*
|
||||
* Can be used with enableAckPayload() to request a response
|
||||
* @see enableDynamicAck()
|
||||
* @see setAutoAck()
|
||||
* @see write()
|
||||
*
|
||||
* @param buf Pointer to the data to be sent
|
||||
* @param len Number of bytes to be sent
|
||||
* @param multicast Request ACK (0), NOACK (1)
|
||||
*/
|
||||
bool write( const void* buf, uint8_t len, const bool multicast );
|
||||
|
||||
/**
|
||||
* @note Optimization: New Command *
|
||||
* This will not block until the 3 FIFO buffers are filled with data.
|
||||
@@ -289,6 +305,19 @@ public:
|
||||
*/
|
||||
bool writeFast( const void* buf, uint8_t len );
|
||||
|
||||
/**
|
||||
* WriteFast for single NOACK writes. Disables acknowledgements/autoretries for a single write.
|
||||
*
|
||||
* @note enableDynamicAck() must be called to enable this feature
|
||||
* @see enableDynamicAck()
|
||||
* @see setAutoAck()
|
||||
*
|
||||
* @param buf Pointer to the data to be sent
|
||||
* @param len Number of bytes to be sent
|
||||
* @param multicast Request ACK (0) or NOACK (1)
|
||||
*/
|
||||
bool writeFast( const void* buf, uint8_t len, const bool multicast );
|
||||
|
||||
/**
|
||||
* @note Optimization: New Command
|
||||
* This function extends the auto-retry mechanism to any specified duration.
|
||||
@@ -383,6 +412,20 @@ public:
|
||||
*/
|
||||
void writeAckPayload(uint8_t pipe, const void* buf, uint8_t len);
|
||||
|
||||
/**
|
||||
* Enable dynamic ACKs (single write multicasting) for chosen messages
|
||||
*
|
||||
* @note To enable full multicasting or per-pipe multicast, use setAutoAck()
|
||||
*
|
||||
* @warning This MUST be called prior to attempting single write NOACK calls
|
||||
* @code
|
||||
* radio.enableDynamicAck();
|
||||
* radio.write(&data,32,1); // Sends a payload with no acknowledgement requested
|
||||
* radio.write(&data,32,0); // Sends a payload using auto-retry/autoACK
|
||||
* @endcode
|
||||
*/
|
||||
void enableDynamicAck();
|
||||
|
||||
/**
|
||||
* Determine if an ack payload was received in the most recent call to
|
||||
* write().
|
||||
@@ -424,11 +467,16 @@ public:
|
||||
* @see startWrite()
|
||||
* @see writeBlocking()
|
||||
*
|
||||
* For single noAck writes see:
|
||||
* @see enableDynamicAck()
|
||||
* @see setAutoAck()
|
||||
*
|
||||
* @param buf Pointer to the data to be sent
|
||||
* @param len Number of bytes to be sent
|
||||
* @param multicast Request ACK (0) or NOACK (1)
|
||||
* @return True if the payload was delivered successfully false if not
|
||||
*/
|
||||
void startFastWrite( const void* buf, uint8_t len );
|
||||
void startFastWrite( const void* buf, uint8_t len, const bool multicast );
|
||||
|
||||
/**
|
||||
* Non-blocking write to the open writing pipe
|
||||
@@ -445,11 +493,16 @@ public:
|
||||
* @see startFastWrite()
|
||||
* @see whatHappened()
|
||||
*
|
||||
* For single noAck writes see:
|
||||
* @see enableDynamicAck()
|
||||
* @see setAutoAck()
|
||||
*
|
||||
* @param buf Pointer to the data to be sent
|
||||
* @param len Number of bytes to be sent
|
||||
* @param multicast Request ACK (0) or NOACK (1)
|
||||
*
|
||||
*/
|
||||
void startWrite( const void* buf, uint8_t len );
|
||||
void startWrite( const void* buf, uint8_t len, const bool multicast );
|
||||
|
||||
/**
|
||||
* Optimization: New Command
|
||||
@@ -776,7 +829,7 @@ private:
|
||||
* @param len Number of bytes to be sent
|
||||
* @return Current value of status register
|
||||
*/
|
||||
uint8_t write_payload(const void* buf, uint8_t len);
|
||||
uint8_t write_payload(const void* buf, uint8_t len, const uint8_t writeType);
|
||||
|
||||
/**
|
||||
* Read the receive payload
|
||||
@@ -1003,18 +1056,18 @@ private:
|
||||
* @section Goals Design Goals
|
||||
*
|
||||
* This library fork is designed to be...
|
||||
* @li More compliant with the manufacturer specified operation of the chip
|
||||
* @li More compliant with the manufacturer specified operation of the chip, while allowing advanced users
|
||||
* to work outside the reccommended operation.
|
||||
* @li Utilize the capabilities of the radio to their full potential via Arduino
|
||||
* @li More reliable, responsive and feature rich
|
||||
* @li Easy for beginners to use
|
||||
* @li Easy for beginners to use, with well documented examples and features
|
||||
* @li Consumed with a public interface that's similiar to other Arduino standard libraries
|
||||
*
|
||||
* @section News News
|
||||
*
|
||||
* <b>March 2014: Optimization begun<br>
|
||||
* April 2014: Optimization nearing completion </b><br>
|
||||
* <b>April 2014: Official Release: Still some work to do, but most benefits have been realized </b><br>
|
||||
* - The library has been tweaked to allow full use of the FIFO buffers for maximum transfer speeds
|
||||
* - Changes to read() functionality have increased reliability and response
|
||||
* - Changes to read() and available () functionality have increased reliability and response
|
||||
* - Extended timeout periods have been added to aid in noisy or otherwise unreliable environments
|
||||
* - Delays have been removed where possible to ensure maximum efficiency
|
||||
* - Full Due support with extended SPI functions
|
||||
|
||||
+16
-14
@@ -1,24 +1,25 @@
|
||||
/*
|
||||
Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
|
||||
Portions Copyright (C) 2011 Greg Copeland
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
@@ -117,6 +118,7 @@
|
||||
|
||||
/* P model memory Map */
|
||||
#define RPD 0x09
|
||||
#define W_TX_PAYLOAD_NO_ACK 0xB0
|
||||
|
||||
/* P model bit Mnemonics */
|
||||
#define RF_DR_LOW 5
|
||||
|
||||
Reference in New Issue
Block a user