Skip to content

Commit

Permalink
Add optional write timeout/failure handling
Browse files Browse the repository at this point in the history
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
  • Loading branch information
TMRh20 committed Jul 31, 2014
1 parent 1d18015 commit 327f060
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 77 deletions.
74 changes: 53 additions & 21 deletions RF24.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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):
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)
{
}
Expand All @@ -338,9 +338,6 @@ RF24::RF24(uint8_t _cepin, uint8_t _cspin):

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;
write_register(RF_CH,min(channel,max_channel));
}
Expand Down Expand Up @@ -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
Expand All @@ -577,9 +581,18 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast )
startFastWrite(buf,len,multicast);

//Wait until complete or failed
//ACK payloads that are handled improperly will cause this to hang
//If autoAck is ON, a payload has to be written prior to reading a payload, else write after reading a payload
while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) { }
#if defined (FAILURE_HANDLING)
uint32_t timer = millis();
#endif

while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) {
#if defined (FAILURE_HANDLING)
if(millis() - timer > 75){
errNotify();
return 0;
}
#endif
}

ce(LOW);

Expand Down Expand Up @@ -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
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

}

Expand Down Expand Up @@ -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
//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

if( get_status() & _BV(MAX_RT)){
Expand All @@ -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
//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
startFastWrite(buf,len,multicast);
Expand Down Expand Up @@ -696,14 +724,22 @@ void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ){
}

bool RF24::txStandBy(){

#if defined (FAILURE_HANDLING)
uint32_t timeout = millis();
#endif
while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){
if( get_status() & _BV(MAX_RT)){
write_register(STATUS,_BV(MAX_RT) );
ce(LOW);
flush_tx(); //Non blocking, flush the data
return 0;
}
#if defined (FAILURE_HANDLING)
if( millis() - timeout > 75){
errNotify();
return 0;
}
#endif
}

ce(LOW); //Set STANDBY-I mode
Expand All @@ -723,7 +759,15 @@ bool RF24::txStandBy(uint32_t timeout){
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
return 1;

Expand Down Expand Up @@ -1115,13 +1159,11 @@ bool RF24::setDataRate(rf24_datarate_e speed)
uint8_t setup = read_register(RF_SETUP) ;

// HIGH and LOW '00' is 1Mbs - our default
wide_band = false ;
setup &= ~(_BV(RF_DR_LOW) | _BV(RF_DR_HIGH)) ;
if( speed == RF24_250KBPS )
{
// Must set the RF_DR_LOW to 1; RF_DR_HIGH (used to be RF_DR) is already 0
// Making it '10'.
wide_band = false ;
setup |= _BV( RF_DR_LOW ) ;
}
else
Expand All @@ -1130,14 +1172,8 @@ bool RF24::setDataRate(rf24_datarate_e speed)
// Making it '01'
if ( speed == RF24_2MBPS )
{
wide_band = true ;
setup |= _BV(RF_DR_HIGH);
}
else
{
// 1Mbs
wide_band = false ;
}
}
write_register(RF_SETUP,setup);

Expand All @@ -1146,10 +1182,6 @@ bool RF24::setDataRate(rf24_datarate_e speed)
{
result = true;
}
else
{
wide_band = false;
}

return result;
}
Expand Down
49 changes: 39 additions & 10 deletions RF24.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ class RF24
private:
uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
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 */
uint8_t payload_size; /**< Fixed size of payloads */
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 addr_width;


public:

Expand Down Expand Up @@ -770,7 +771,30 @@ class RF24
*
*/
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
Expand Down Expand Up @@ -974,6 +998,11 @@ class RF24
*/

uint8_t spiTrans(uint8_t cmd);

#if defined (FAILURE_HANDLING)
void errNotify(void);
#endif

/**@}*/

};
Expand Down Expand Up @@ -1124,33 +1153,33 @@ class RF24
*
* This library fork is designed to be...
* @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 More reliable, responsive and feature rich
* @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>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
* - 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.
* - ATTiny now supported.
* - Raspberry Pi now supported
* - 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
*
* Please refer to:
*
* @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="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="https://github.com/maniacbug/RF24">Original Library</a>
*
Expand All @@ -1162,13 +1191,13 @@ class RF24
* Most standard Arduino based boards are supported:
* - ATMega 328 based boards (Uno, Nano, 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
* hardware SS/CSN pins as extended SPI methods are used.
* - Arduino Due: Must use one of the hardware SS/CSN pins as extended SPI methods are used.
* Initial Due support taken from https://github.com/mcrosson/RF24/tree/due
* - ATTiny board support added from https://github.com/jscrane/RF24
* 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 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
*
* @section More More Information
Expand All @@ -1177,7 +1206,7 @@ class RF24
*
* @li Project blog:
* @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/maniacbug/RF24"> ManiacBug on GitHub (Original Library Author)</a>
*/
Expand Down
10 changes: 6 additions & 4 deletions RF24_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@

#include <stddef.h>

//TMRh20:
/*** USER DEFINES: ***/
//#define FAILURE_HANDLING
//#define SERIAL_DEBUG
//#define MINIMAL

/**********************/

// Define _BV for non-Arduino platforms and for Arduino DUE
#if defined (ARDUINO) && !defined (__arm__)
#include <SPI.h>
Expand All @@ -47,8 +50,7 @@

#endif


#undef SERIAL_DEBUG

#ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({x;})
#else
Expand Down
Loading

0 comments on commit 327f060

Please sign in to comment.