Commit 327f0609 authored by TMRh20's avatar TMRh20

Add optional write timeout/failure handling

Per issue #5 by sven337
- Add optional failure handling/timeout
- Un-comment #define FAILURE_HANDLING in RF24_config.h to enable
- Add radio.errorDetected variable - indicates if an error/timeout was
detected
example:
if(radio.failureDetected){
delay(1000);
radio.begin();
radio.failureDetected = 0;
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]);
report_failure(); //blink leds, send a message, etc.
}

Additional:
- removed unused wide_band boolean
- remove rx buffer flushes for RPi also
parent 1d180150
...@@ -329,7 +329,7 @@ void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty) ...@@ -329,7 +329,7 @@ void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
/****************************************************************************/ /****************************************************************************/
RF24::RF24(uint8_t _cepin, uint8_t _cspin): RF24::RF24(uint8_t _cepin, uint8_t _cspin):
ce_pin(_cepin), csn_pin(_cspin), wide_band(false), p_variant(false), ce_pin(_cepin), csn_pin(_cspin), p_variant(false),
payload_size(32), dynamic_payloads_enabled(false), addr_width(5)//,pipe0_reading_address(0) payload_size(32), dynamic_payloads_enabled(false), addr_width(5)//,pipe0_reading_address(0)
{ {
} }
...@@ -338,9 +338,6 @@ RF24::RF24(uint8_t _cepin, uint8_t _cspin): ...@@ -338,9 +338,6 @@ RF24::RF24(uint8_t _cepin, uint8_t _cspin):
void RF24::setChannel(uint8_t channel) void RF24::setChannel(uint8_t channel)
{ {
// TODO: This method could take advantage of the 'wide_band' calculation
// done in setChannel() to require certain channel spacing.
const uint8_t max_channel = 127; const uint8_t max_channel = 127;
write_register(RF_CH,min(channel,max_channel)); write_register(RF_CH,min(channel,max_channel));
} }
...@@ -568,6 +565,13 @@ void RF24::powerUp(void) ...@@ -568,6 +565,13 @@ void RF24::powerUp(void)
} }
} }
/******************************************************************/
#if defined (FAILURE_HANDLING)
void RF24::errNotify(){
IF_SERIAL_DEBUG(printf_P(PSTR("HARDWARE FAIL\r\n")));
failureDetected = 1;
}
#endif
/******************************************************************/ /******************************************************************/
//Similar to the previous write, clears the interrupt flags //Similar to the previous write, clears the interrupt flags
...@@ -577,9 +581,18 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ) ...@@ -577,9 +581,18 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast )
startFastWrite(buf,len,multicast); startFastWrite(buf,len,multicast);
//Wait until complete or failed //Wait until complete or failed
//ACK payloads that are handled improperly will cause this to hang #if defined (FAILURE_HANDLING)
//If autoAck is ON, a payload has to be written prior to reading a payload, else write after reading a payload uint32_t timer = millis();
while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) { } #endif
while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) {
#if defined (FAILURE_HANDLING)
if(millis() - timer > 75){
errNotify();
return 0;
}
#endif
}
ce(LOW); ce(LOW);
...@@ -615,6 +628,12 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout ) ...@@ -615,6 +628,12 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout )
reUseTX(); //Set re-transmit and clear the MAX_RT interrupt flag reUseTX(); //Set re-transmit and clear the MAX_RT interrupt flag
if(millis() - timer > timeout){ return 0; } //If this payload has exceeded the user-defined timeout, exit and return 0 if(millis() - timer > timeout){ return 0; } //If this payload has exceeded the user-defined timeout, exit and return 0
} }
#if defined (FAILURE_HANDLING)
if(millis() - timer > (timeout+75) ){
errNotify();
return 0;
}
#endif
} }
...@@ -642,6 +661,10 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast ) ...@@ -642,6 +661,10 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
//Return 0 so the user can control the retrys and set a timer or failure counter if required //Return 0 so the user can control the retrys and set a timer or failure counter if required
//The radio will auto-clear everything in the FIFO as long as CE remains high //The radio will auto-clear everything in the FIFO as long as CE remains high
#if defined (FAILURE_HANDLING)
uint32_t timer = millis();
#endif
while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or fail while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or fail
if( get_status() & _BV(MAX_RT)){ if( get_status() & _BV(MAX_RT)){
...@@ -650,7 +673,12 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast ) ...@@ -650,7 +673,12 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
return 0; //Return 0. The previous payload has been retransmitted return 0; //Return 0. The previous payload has been retransmitted
//From the user perspective, if you get a 0, just keep trying to send the same payload //From the user perspective, if you get a 0, just keep trying to send the same payload
} }
#if defined (FAILURE_HANDLING)
if(millis() - timer > 75 ){
errNotify();
return 0;
}
#endif
} }
//Start Writing //Start Writing
startFastWrite(buf,len,multicast); startFastWrite(buf,len,multicast);
...@@ -696,7 +724,9 @@ void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ){ ...@@ -696,7 +724,9 @@ void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ){
} }
bool RF24::txStandBy(){ bool RF24::txStandBy(){
#if defined (FAILURE_HANDLING)
uint32_t timeout = millis();
#endif
while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){ while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){
if( get_status() & _BV(MAX_RT)){ if( get_status() & _BV(MAX_RT)){
write_register(STATUS,_BV(MAX_RT) ); write_register(STATUS,_BV(MAX_RT) );
...@@ -704,6 +734,12 @@ bool RF24::txStandBy(){ ...@@ -704,6 +734,12 @@ bool RF24::txStandBy(){
flush_tx(); //Non blocking, flush the data flush_tx(); //Non blocking, flush the data
return 0; return 0;
} }
#if defined (FAILURE_HANDLING)
if( millis() - timeout > 75){
errNotify();
return 0;
}
#endif
} }
ce(LOW); //Set STANDBY-I mode ce(LOW); //Set STANDBY-I mode
...@@ -723,7 +759,15 @@ bool RF24::txStandBy(uint32_t timeout){ ...@@ -723,7 +759,15 @@ bool RF24::txStandBy(uint32_t timeout){
ce(LOW); flush_tx(); return 0; ce(LOW); flush_tx(); return 0;
} }
} }
#if defined (FAILURE_HANDLING)
if( millis() - start > (timeout+75)){
errNotify();
return 0;
}
#endif
} }
ce(LOW); //Set STANDBY-I mode ce(LOW); //Set STANDBY-I mode
return 1; return 1;
...@@ -1115,13 +1159,11 @@ bool RF24::setDataRate(rf24_datarate_e speed) ...@@ -1115,13 +1159,11 @@ bool RF24::setDataRate(rf24_datarate_e speed)
uint8_t setup = read_register(RF_SETUP) ; uint8_t setup = read_register(RF_SETUP) ;
// HIGH and LOW '00' is 1Mbs - our default // HIGH and LOW '00' is 1Mbs - our default
wide_band = false ;
setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ; setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ;
if( speed == RF24_250KBPS ) if( speed == RF24_250KBPS )
{ {
// Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
// Making it '10'. // Making it '10'.
wide_band = false ;
setup |= _BV( RF_DR_LOW ) ; setup |= _BV( RF_DR_LOW ) ;
} }
else else
...@@ -1130,14 +1172,8 @@ bool RF24::setDataRate(rf24_datarate_e speed) ...@@ -1130,14 +1172,8 @@ bool RF24::setDataRate(rf24_datarate_e speed)
// Making it '01' // Making it '01'
if ( speed == RF24_2MBPS ) if ( speed == RF24_2MBPS )
{ {
wide_band = true ;
setup |= _BV(RF_DR_HIGH); setup |= _BV(RF_DR_HIGH);
} }
else
{
// 1Mbs
wide_band = false ;
}
} }
write_register(RF_SETUP,setup); write_register(RF_SETUP,setup);
...@@ -1146,10 +1182,6 @@ bool RF24::setDataRate(rf24_datarate_e speed) ...@@ -1146,10 +1182,6 @@ bool RF24::setDataRate(rf24_datarate_e speed)
{ {
result = true; result = true;
} }
else
{
wide_band = false;
}
return result; return result;
} }
......
...@@ -47,12 +47,13 @@ class RF24 ...@@ -47,12 +47,13 @@ class RF24
private: private:
uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */ uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
uint8_t csn_pin; /**< SPI Chip select */ uint8_t csn_pin; /**< SPI Chip select */
bool wide_band; /* 2Mbs data rate in use? */
bool p_variant; /* False for RF24L01 and true for RF24L01P */ bool p_variant; /* False for RF24L01 and true for RF24L01P */
uint8_t payload_size; /**< Fixed size of payloads */ uint8_t payload_size; /**< Fixed size of payloads */
bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */ bool dynamic_payloads_enabled; /**< Whether dynamic payloads are enabled. */
uint8_t pipe0_reading_address[5]; /**< Last address set on pipe 0 for reading. */ uint8_t pipe0_reading_address[5]; /**< Last address set on pipe 0 for reading. */
uint8_t addr_width; uint8_t addr_width;
public: public:
...@@ -770,7 +771,30 @@ public: ...@@ -770,7 +771,30 @@ public:
* *
*/ */
void disableCRC( void ) ; void disableCRC( void ) ;
/**
* Enable error detection by un-commenting #define FAILURE_HANDLING in RF24_config.h
* If a failure has been detected, it usually indicates a hardware issue. By default the library
* will cease operation when a failure is detected.
* This should allow advanced users to detect and resolve intermittent hardware issues.
*
* In most cases, the radio must be re-enabled via radio.begin(); and the appropriate settings
* applied after a failure occurs, if wanting to re-enable the device immediately.
*
* Usage: (Failure handling must be enabled per above)
* @code
* if(radio.failureDetected){
* radio.begin(); // Attempt to re-configure the radio with defaults
* radio.failureDetected = 0; // Reset the detection value
* radio.openWritingPipe(addresses[1]); // Re-configure pipe addresses
* radio.openReadingPipe(1,addresses[0]);
* report_failure(); // Blink leds, send a message, etc. to indicate failure
* }
* @endcode
*/
#if defined (FAILURE_HANDLING)
bool failureDetected;
#endif
/**@}*/ /**@}*/
/** /**
* @name Deprecated * @name Deprecated
...@@ -974,6 +998,11 @@ private: ...@@ -974,6 +998,11 @@ private:
*/ */
uint8_t spiTrans(uint8_t cmd); uint8_t spiTrans(uint8_t cmd);
#if defined (FAILURE_HANDLING)
void errNotify(void);
#endif
/**@}*/ /**@}*/
}; };
...@@ -1124,7 +1153,7 @@ private: ...@@ -1124,7 +1153,7 @@ private:
* *
* This library fork is designed to be... * This library fork is designed to be...
* @li More compliant with the manufacturer specified operation of the chip, while allowing advanced users * @li More compliant with the manufacturer specified operation of the chip, while allowing advanced users
* to work outside the reccommended operation. * to work outside the recommended operation.
* @li Utilize the capabilities of the radio to their full potential via Arduino * @li Utilize the capabilities of the radio to their full potential via Arduino
* @li More reliable, responsive and feature rich * @li More reliable, responsive and feature rich
* @li Easy for beginners to use, with well documented examples and features * @li Easy for beginners to use, with well documented examples and features
...@@ -1132,17 +1161,17 @@ private: ...@@ -1132,17 +1161,17 @@ private:
* *
* @section News News * @section News News
* *
* <b>April 2014: Official Release: Still some work to do, but most benefits have been realized </b><br> * <b>Main changes: </b><br>
* - The library has been tweaked to allow full use of the FIFO buffers for maximum transfer speeds * - 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 * - 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 * - Extended timeout periods have been added to aid in noisy or otherwise unreliable environments
* - Delays have been removed where possible to ensure maximum efficiency * - Delays have been removed where possible to ensure maximum efficiency
* - Full Due support with extended SPI functions * - Full Due support with extended SPI functions
* - ATTiny 24/44/84 25/45/85 now supported. * - ATTiny now supported.
* - Raspberry Pi now supported * - Raspberry Pi now supported
* - More! See the links below and class documentation for more info. * - More! See the links below and class documentation for more info.
* *
* If issues are discovered with the documentation, please report them here: <a href="https://github.com/TMRh20/tmrh20.github.io/issues"> here</a> * If issues are discovered with the documentation, please report them <a href="https://github.com/TMRh20/tmrh20.github.io/issues"> here</a>
* @section Useful Useful References * @section Useful Useful References
* *
* Please refer to: * Please refer to:
...@@ -1150,7 +1179,7 @@ private: ...@@ -1150,7 +1179,7 @@ private:
* @li <a href="http://tmrh20.github.io/">Documentation Main Page</a> * @li <a href="http://tmrh20.github.io/">Documentation Main Page</a>
* @li <a href="http://tmrh20.github.io/RF24/classRF24.html">RF24 Class Documentation</a> * @li <a href="http://tmrh20.github.io/RF24/classRF24.html">RF24 Class Documentation</a>
* @li <a href="https://github.com/tmrh20/RF24/">Source Code</a> * @li <a href="https://github.com/tmrh20/RF24/">Source Code</a>
* @li <a href="https://github.com/tmrh20/RF24/archives/master">Downloads Page</a> * @li <a href="https://github.com/TMRh20/RF24/archive/master.zip">Download</a>
* @li <a href="http://www.nordicsemi.com/files/Product/data_sheet/nRF24L01_Product_Specification_v2_0.pdf">Chip Datasheet</a> * @li <a href="http://www.nordicsemi.com/files/Product/data_sheet/nRF24L01_Product_Specification_v2_0.pdf">Chip Datasheet</a>
* @li <a href="https://github.com/maniacbug/RF24">Original Library</a> * @li <a href="https://github.com/maniacbug/RF24">Original Library</a>
* *
...@@ -1162,13 +1191,13 @@ private: ...@@ -1162,13 +1191,13 @@ private:
* Most standard Arduino based boards are supported: * Most standard Arduino based boards are supported:
* - ATMega 328 based boards (Uno, Nano, etc) * - ATMega 328 based boards (Uno, Nano, etc)
* - Mega Boards (1280, 2560, etc) * - Mega Boards (1280, 2560, etc)
* - ARM based boards (Arduino Due) Note: Do not include printf.h or use printf begin. This functionality is already present. Must use one of the * - Arduino Due: Must use one of the hardware SS/CSN pins as extended SPI methods are used.
* hardware SS/CSN pins as extended SPI methods are used.
* Initial Due support taken from https://github.com/mcrosson/RF24/tree/due * Initial Due support taken from https://github.com/mcrosson/RF24/tree/due
* - ATTiny board support added from https://github.com/jscrane/RF24 * - ATTiny board support added from https://github.com/jscrane/RF24
* Note: ATTiny support is built into the library. Do not include SPI.h. <br> * Note: ATTiny support is built into the library. Do not include SPI.h. <br>
* ATTiny 85: D0(pin 5): MISO, D1(pin6) MOSI, D2(pin7) SCK, D3(pin2):CSN/SS, D4(pin3): CE <br> * ATTiny 85: D0(pin 5): MISO, D1(pin6) MOSI, D2(pin7) SCK, D3(pin2):CSN/SS, D4(pin3): CE <br>
* ATTiny 84: PA6:MISO, PA5:MOSI, PA4:SCK, PA7:CSN/SS, CE as desired <br> * ATTiny 84: PA6:MISO, PA5:MOSI, PA4:SCK, PA7:CSN/SS, CE as desired <br>
* See https://github.com/TCWORLD/ATTinyCore/tree/master/PCREL%20Patch%20for%20GCC for ATTiny patch
* - Raspberry Pi Support: See the readme at https://github.com/TMRh20/RF24/tree/master/RPi * - Raspberry Pi Support: See the readme at https://github.com/TMRh20/RF24/tree/master/RPi
* *
* @section More More Information * @section More More Information
...@@ -1177,7 +1206,7 @@ private: ...@@ -1177,7 +1206,7 @@ private:
* *
* @li Project blog: * @li Project blog:
* @li <a href="http://TMRh20.blogspot.com"> TMRh20.blogspot.com </a> * @li <a href="http://TMRh20.blogspot.com"> TMRh20.blogspot.com </a>
* @li <a href="https://github.com/TMRh20"> RF24 Wireless Audio Library (Coming Soon) </a> * @li <a href="http://tmrh20.github.io/RF24Audio/"> RF24 Wireless Audio Library </a>
* @li <a href="https://github.com/TMRh20/RF24Network"> Optimized RF24 Network Layer </a> * @li <a href="https://github.com/TMRh20/RF24Network"> Optimized RF24 Network Layer </a>
* @li <a href="https://github.com/maniacbug/RF24"> ManiacBug on GitHub (Original Library Author)</a> * @li <a href="https://github.com/maniacbug/RF24"> ManiacBug on GitHub (Original Library Author)</a>
*/ */
......
...@@ -20,9 +20,12 @@ ...@@ -20,9 +20,12 @@
#include <stddef.h> #include <stddef.h>
//TMRh20: /*** USER DEFINES: ***/
//#define FAILURE_HANDLING
//#define SERIAL_DEBUG
//#define MINIMAL //#define MINIMAL
/**********************/
// Define _BV for non-Arduino platforms and for Arduino DUE // Define _BV for non-Arduino platforms and for Arduino DUE
#if defined (ARDUINO) && !defined (__arm__) #if defined (ARDUINO) && !defined (__arm__)
#include <SPI.h> #include <SPI.h>
...@@ -47,8 +50,7 @@ ...@@ -47,8 +50,7 @@
#endif #endif
#undef SERIAL_DEBUG
#ifdef SERIAL_DEBUG #ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({x;}) #define IF_SERIAL_DEBUG(x) ({x;})
#else #else
......
...@@ -265,18 +265,15 @@ void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty) ...@@ -265,18 +265,15 @@ void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
/****************************************************************************/ /****************************************************************************/
RF24::RF24(uint8_t _cepin, uint8_t _cspin, uint32_t _spi_speed): RF24::RF24(uint8_t _cepin, uint8_t _cspin, uint32_t _spi_speed):
ce_pin(_cepin), csn_pin(_cspin), spi_speed(_spi_speed), wide_band(true), p_variant(false), ce_pin(_cepin), csn_pin(_cspin), spi_speed(_spi_speed),p_variant(false),
payload_size(32), dynamic_payloads_enabled(false),addr_width(5)//,pipe0_reading_address(0) payload_size(32), dynamic_payloads_enabled(false),addr_width(5)//,pipe0_reading_address(0)
{ {
} }
/****************************************************************************/ /****************************************************************************/
void RF24::setChannel(uint8_t channel) void RF24::setChannel(uint8_t channel)
{ {
// TODO: This method could take advantage of the 'wide_band' calculation
// done in setChannel() to require certain channel spacing.
const uint8_t max_channel = 127; const uint8_t max_channel = 127;
write_register(RF_CH,min(channel,max_channel)); write_register(RF_CH,min(channel,max_channel));
} }
...@@ -408,8 +405,10 @@ void RF24::printDetails(void) ...@@ -408,8 +405,10 @@ void RF24::printDetails(void)
bool RF24::begin(void) bool RF24::begin(void)
{ {
debug = false; debug = false;
//debug = true; #if defined(DEBUG)
// This initialize the SPI bus with debug = true;
#endif
// This initialize the SPI bus with
// csn pin as chip select (custom or not) // csn pin as chip select (custom or not)
...@@ -488,7 +487,7 @@ bool RF24::begin(void) ...@@ -488,7 +487,7 @@ bool RF24::begin(void)
setChannel(76); setChannel(76);
// Flush buffers // Flush buffers
flush_rx(); //flush_rx();
flush_tx(); flush_tx();
powerUp(); powerUp();
...@@ -513,7 +512,7 @@ void RF24::startListening(void) ...@@ -513,7 +512,7 @@ void RF24::startListening(void)
write_register(RX_ADDR_P0, pipe0_reading_address,addr_width); write_register(RX_ADDR_P0, pipe0_reading_address,addr_width);
} }
// Flush buffers // Flush buffers
flush_rx(); //flush_rx();
flush_tx(); flush_tx();
// Go! // Go!
...@@ -559,6 +558,14 @@ void RF24::powerUp(void) ...@@ -559,6 +558,14 @@ void RF24::powerUp(void)
/******************************************************************/ /******************************************************************/
#if defined (FAILURE_HANDLING)
void RF24::errNotify(){
if(debug){ printf("HARDWARE FAIL\n\r"); }
failureDetect = true;
}
#endif
/******************************************************************/
bool RF24::write( const void* buf, uint8_t len, const bool multicast ){ bool RF24::write( const void* buf, uint8_t len, const bool multicast ){
// Begin the write // Begin the write
...@@ -566,9 +573,18 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ){ ...@@ -566,9 +573,18 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ){
//Wait until complete or failed //Wait until complete or failed
#if defined (FAILURE_HANDLING)
uint32_t timer = millis();
#endif
// If this hangs, it ain't coming back, no sense in timing out // If this hangs, it ain't coming back, no sense in timing out
while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) { } while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) {
#if defined (FAILURE_HANDLING)
if(millis() - timer > 175){
errNotify();
return 0;
}
#endif
}
bcm2835_gpio_write(ce_pin, LOW); bcm2835_gpio_write(ce_pin, LOW);
uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) ); uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
...@@ -604,7 +620,12 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout ) ...@@ -604,7 +620,12 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout )
reUseTX(); //Set re-transmit and clear the MAX_RT interrupt flag reUseTX(); //Set re-transmit and clear the MAX_RT interrupt flag
if(millis() - timer > timeout){ return 0; } //If this payload has exceeded the user-defined timeout, exit and return 0 if(millis() - timer > timeout){ return 0; } //If this payload has exceeded the user-defined timeout, exit and return 0
} }
#if defined (FAILURE_HANDLING)
if(millis() - timer > (timeout+75) ){
errNotify();
return 0;
}
#endif
} }
//Start Writing //Start Writing
...@@ -632,6 +653,10 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast ) ...@@ -632,6 +653,10 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
//Return 0 so the user can control the retrys and set a timer or failure counter if required //Return 0 so the user can control the retrys and set a timer or failure counter if required
//The radio will auto-clear everything in the FIFO as long as CE remains high //The radio will auto-clear everything in the FIFO as long as CE remains high
#if defined (FAILURE_HANDLING)
uint32_t timer = millis();
#endif
while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or fail while( ( get_status() & ( _BV(TX_FULL) ))) { //Blocking only if FIFO is full. This will loop and block until TX is successful or fail
if( get_status() & _BV(MAX_RT)){ if( get_status() & _BV(MAX_RT)){
...@@ -640,7 +665,12 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast ) ...@@ -640,7 +665,12 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
return 0; //Return 0. The previous payload has been retransmitted return 0; //Return 0. The previous payload has been retransmitted
//From the user perspective, if you get a 0, just keep trying to send the same payload //From the user perspective, if you get a 0, just keep trying to send the same payload
} }
#if defined (FAILURE_HANDLING)
if(millis() - timer > 75 ){
errNotify();
return 0;
}
#endif
} }
//Start Writing //Start Writing
startFastWrite(buf,len,multicast); startFastWrite(buf,len,multicast);
...@@ -683,7 +713,9 @@ void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ) ...@@ -683,7 +713,9 @@ void RF24::startWrite( const void* buf, uint8_t len, const bool multicast )
/****************************************************************************/ /****************************************************************************/
bool RF24::txStandBy(){ bool RF24::txStandBy(){
#if defined (FAILURE_HANDLING)
uint32_t timer = millis();
#endif
while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){ while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){
if( get_status() & _BV(MAX_RT)){ if( get_status() & _BV(MAX_RT)){
write_register(STATUS,_BV(MAX_RT) ); write_register(STATUS,_BV(MAX_RT) );
...@@ -691,6 +723,12 @@ bool RF24::txStandBy(){ ...@@ -691,6 +723,12 @@ bool RF24::txStandBy(){
flush_tx(); //Non blocking, flush the data flush_tx(); //Non blocking, flush the data
return 0; return 0;
} }
#if defined (FAILURE_HANDLING)
if( millis() - timer > 75){
errNotify();
return 0;
}
#endif
} }
bcm2835_gpio_write(ce_pin, LOW); //Set STANDBY-I mode bcm2835_gpio_write(ce_pin, LOW); //Set STANDBY-I mode
...@@ -714,6 +752,12 @@ bool RF24::txStandBy(uint32_t timeout){ ...@@ -714,6 +752,12 @@ bool RF24::txStandBy(uint32_t timeout){
return 0; return 0;
} }
} }
#if defined (FAILURE_HANDLING)
if( millis() - start > (timeout+75)){
errNotify();
return 0;
}
#endif
} }
bcm2835_gpio_write(ce_pin, LOW); //Set STANDBY-I mode bcm2835_gpio_write(ce_pin, LOW); //Set STANDBY-I mode
return 1; return 1;
...@@ -1079,13 +1123,11 @@ bool RF24::setDataRate(rf24_datarate_e speed) ...@@ -1079,13 +1123,11 @@ bool RF24::setDataRate(rf24_datarate_e speed)
uint8_t setup = read_register(RF_SETUP) ; uint8_t setup = read_register(RF_SETUP) ;
// HIGH and LOW '00' is 1Mbs - our default // HIGH and LOW '00' is 1Mbs - our default
wide_band = false ;
setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ; setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ;
if( speed == RF24_250KBPS ) if( speed == RF24_250KBPS )
{ {
// Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0 // Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
// Making it '10'. // Making it '10'.
wide_band = false ;
setup |= _BV( RF_DR_LOW ) ; setup |= _BV( RF_DR_LOW ) ;
} }
else else
...@@ -1094,14 +1136,8 @@ bool RF24::setDataRate(rf24_datarate_e speed) ...@@ -1094,14 +1136,8 @@ bool RF24::setDataRate(rf24_datarate_e speed)
// Making it '01' // Making it '01'
if ( speed == RF24_2MBPS ) if ( speed == RF24_2MBPS )
{ {
wide_band = true ;
setup |= _BV(RF_DR_HIGH); setup |= _BV(RF_DR_HIGH);
} }
else
{
// 1Mbs
wide_band = false ;
}
} }
write_register(RF_SETUP,setup); write_register(RF_SETUP,setup);
...@@ -1110,10 +1146,6 @@ bool RF24::setDataRate(rf24_datarate_e speed) ...@@ -1110,10 +1146,6 @@ bool RF24::setDataRate(rf24_datarate_e speed)
{ {
result = true; result = true;
} }
else
{
wide_band = false;
}
return result; return result;
} }
......
...@@ -51,6 +51,30 @@ typedef enum { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 } rf24_crclength_e ...@@ -51,6 +51,30 @@ typedef enum { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 } rf24_crclength_e
class RF24 class RF24
{ {
public:
/**
* Enable error detection by un-commenting #define FAILURE_HANDLING in RF24_config.h
* If a failure has been detected, it usually indicates a hardware issue. By default the library
* will cease operation when a failure is detected.
* This should allow advanced users to detect and resolve intermittent hardware issues.
*
* In most cases, the radio must be re-enabled via radio.begin(); and the appropriate settings
* applied after a failure occurs, if wanting to re-enable the device immediately.
*
* Usage: (Failure handling must be enabled per above)
* @code
* if(radio.failureDetected){
* radio.begin(); // Attempt to re-configure the radio with defaults
* radio.failureDetected = 0; // Reset the detection value
* radio.openWritingPipe(addresses[1]); // Re-configure pipe addresses
* radio.openReadingPipe(1,addresses[0]);
* report_failure(); // Blink leds, send a message, etc. to indicate failure
* }
* @endcode
**/
#if defined (FAILURE_HANDLING)
bool failureDetect;
#endif
private: private:
uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */ uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
uint8_t csn_pin; /**< SPI Chip select */ uint8_t csn_pin; /**< SPI Chip select */
...@@ -87,7 +111,7 @@ protected: ...@@ -87,7 +111,7 @@ protected:
* @return Current value of status register * @return Current value of status register
*/ */
uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len); uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len);
/** /**
* Read single byte from a register * Read single byte from a register
* *
...@@ -95,7 +119,7 @@ protected: ...@@ -95,7 +119,7 @@ protected:
* @return Current value of register @p reg * @return Current value of register @p reg
*/ */
uint8_t read_register(uint8_t reg); uint8_t read_register(uint8_t reg);
/** /**
* Write a chunk of data to a register * Write a chunk of data to a register
* *
...@@ -202,6 +226,11 @@ protected: ...@@ -202,6 +226,11 @@ protected:
* are enabled. See the datasheet for details. * are enabled. See the datasheet for details.
*/ */
void toggle_features(void); void toggle_features(void);
#if defined (FAILURE_HANDLING)
void errNotify(void);
#endif
/**@}*/ /**@}*/
public: public:
...@@ -424,6 +453,20 @@ public: ...@@ -424,6 +453,20 @@ public:
*/ */
void enableDynamicPayloads(void); void enableDynamicPayloads(void);
/**
* 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(void);
/** /**
* Determine whether the hardware is an nRF24L01+ or not. * Determine whether the hardware is an nRF24L01+ or not.
* *
...@@ -513,6 +556,8 @@ public: ...@@ -513,6 +556,8 @@ public:
*/ */
void disableCRC( void ) ; void disableCRC( void ) ;
/**@}*/ /**@}*/
/** /**
* @name Deprecated * @name Deprecated
...@@ -837,20 +882,6 @@ public: ...@@ -837,20 +882,6 @@ public:
*/ */
void writeAckPayload(uint8_t pipe, const void* buf, uint8_t len); 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 * Determine if an ack payload was received in the most recent call to
* write(). * write().
......
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
#ifndef __RF24_CONFIG_H__ #ifndef __RF24_CONFIG_H__
#define __RF24_CONFIG_H__ #define __RF24_CONFIG_H__
/*** USER DEFINES: ***/
//#define FAILURE_HANDLING
//#define DEBUG
/**********************/
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment