diff --git a/RF24.cpp b/RF24.cpp
index fc85f47b..aaade07f 100644
--- a/RF24.cpp
+++ b/RF24.cpp
@@ -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)
{
}
@@ -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));
}
@@ -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
@@ -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);
@@ -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
}
@@ -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)){
@@ -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);
@@ -696,7 +724,9 @@ 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) );
@@ -704,6 +734,12 @@ bool RF24::txStandBy(){
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
@@ -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;
@@ -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
@@ -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);
@@ -1146,10 +1182,6 @@ bool RF24::setDataRate(rf24_datarate_e speed)
{
result = true;
}
- else
- {
- wide_band = false;
- }
return result;
}
diff --git a/RF24.h b/RF24.h
index e1c576f4..9964d510 100644
--- a/RF24.h
+++ b/RF24.h
@@ -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:
@@ -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
@@ -974,6 +998,11 @@ class RF24
*/
uint8_t spiTrans(uint8_t cmd);
+
+ #if defined (FAILURE_HANDLING)
+ void errNotify(void);
+ #endif
+
/**@}*/
};
@@ -1124,7 +1153,7 @@ 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
@@ -1132,17 +1161,17 @@ class RF24
*
* @section News News
*
- * April 2014: Official Release: Still some work to do, but most benefits have been realized
+ * Main changes:
* - 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: here
+ * If issues are discovered with the documentation, please report them here
* @section Useful Useful References
*
* Please refer to:
@@ -1150,7 +1179,7 @@ class RF24
* @li Documentation Main Page
* @li RF24 Class Documentation
* @li Source Code
- * @li Downloads Page
+ * @li Download
* @li Chip Datasheet
* @li Original Library
*
@@ -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.
* ATTiny 85: D0(pin 5): MISO, D1(pin6) MOSI, D2(pin7) SCK, D3(pin2):CSN/SS, D4(pin3): CE
* ATTiny 84: PA6:MISO, PA5:MOSI, PA4:SCK, PA7:CSN/SS, CE as desired
+ * 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
@@ -1177,7 +1206,7 @@ class RF24
*
* @li Project blog:
* @li TMRh20.blogspot.com
- * @li RF24 Wireless Audio Library (Coming Soon)
+ * @li RF24 Wireless Audio Library
* @li Optimized RF24 Network Layer
* @li ManiacBug on GitHub (Original Library Author)
*/
diff --git a/RF24_config.h b/RF24_config.h
index 583268a2..28d912cd 100644
--- a/RF24_config.h
+++ b/RF24_config.h
@@ -20,9 +20,12 @@
#include
- //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
@@ -47,8 +50,7 @@
#endif
-
- #undef SERIAL_DEBUG
+
#ifdef SERIAL_DEBUG
#define IF_SERIAL_DEBUG(x) ({x;})
#else
diff --git a/RPi/RF24/RF24.cpp b/RPi/RF24/RF24.cpp
index bee0f85a..6d7709bc 100644
--- a/RPi/RF24/RF24.cpp
+++ b/RPi/RF24/RF24.cpp
@@ -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):
- 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)
-{
+{
}
/****************************************************************************/
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));
}
@@ -408,8 +405,10 @@ void RF24::printDetails(void)
bool RF24::begin(void)
{
debug = false;
- //debug = true;
- // This initialize the SPI bus with
+ #if defined(DEBUG)
+ debug = true;
+ #endif
+ // This initialize the SPI bus with
// csn pin as chip select (custom or not)
@@ -488,7 +487,7 @@ bool RF24::begin(void)
setChannel(76);
// Flush buffers
- flush_rx();
+ //flush_rx();
flush_tx();
powerUp();
@@ -513,7 +512,7 @@ void RF24::startListening(void)
write_register(RX_ADDR_P0, pipe0_reading_address,addr_width);
}
// Flush buffers
- flush_rx();
+ //flush_rx();
flush_tx();
// Go!
@@ -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 ){
// Begin the write
@@ -566,9 +573,18 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ){
//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
- 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);
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 )
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
}
//Start Writing
@@ -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
//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)){
@@ -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
//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);
@@ -683,7 +713,9 @@ void RF24::startWrite( const void* buf, uint8_t len, const bool multicast )
/****************************************************************************/
bool RF24::txStandBy(){
-
+ #if defined (FAILURE_HANDLING)
+ uint32_t timer = millis();
+ #endif
while( ! (read_register(FIFO_STATUS) & _BV(TX_EMPTY)) ){
if( get_status() & _BV(MAX_RT)){
write_register(STATUS,_BV(MAX_RT) );
@@ -691,6 +723,12 @@ bool RF24::txStandBy(){
flush_tx(); //Non blocking, flush the data
return 0;
}
+ #if defined (FAILURE_HANDLING)
+ if( millis() - timer > 75){
+ errNotify();
+ return 0;
+ }
+ #endif
}
bcm2835_gpio_write(ce_pin, LOW); //Set STANDBY-I mode
@@ -714,6 +752,12 @@ bool RF24::txStandBy(uint32_t timeout){
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
return 1;
@@ -1079,13 +1123,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
@@ -1094,14 +1136,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);
@@ -1110,10 +1146,6 @@ bool RF24::setDataRate(rf24_datarate_e speed)
{
result = true;
}
- else
- {
- wide_band = false;
- }
return result;
}
diff --git a/RPi/RF24/RF24.h b/RPi/RF24/RF24.h
index 5d8b20a6..b913d89f 100644
--- a/RPi/RF24/RF24.h
+++ b/RPi/RF24/RF24.h
@@ -51,6 +51,30 @@ typedef enum { RF24_CRC_DISABLED = 0, RF24_CRC_8, RF24_CRC_16 } rf24_crclength_e
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:
uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
uint8_t csn_pin; /**< SPI Chip select */
@@ -87,7 +111,7 @@ class RF24
* @return Current value of status register
*/
uint8_t read_register(uint8_t reg, uint8_t* buf, uint8_t len);
-
+
/**
* Read single byte from a register
*
@@ -95,7 +119,7 @@ class RF24
* @return Current value of register @p reg
*/
uint8_t read_register(uint8_t reg);
-
+
/**
* Write a chunk of data to a register
*
@@ -202,6 +226,11 @@ class RF24
* are enabled. See the datasheet for details.
*/
void toggle_features(void);
+
+ #if defined (FAILURE_HANDLING)
+ void errNotify(void);
+ #endif
+
/**@}*/
public:
@@ -424,6 +453,20 @@ class RF24
*/
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.
*
@@ -513,6 +556,8 @@ class RF24
*/
void disableCRC( void ) ;
+
+
/**@}*/
/**
* @name Deprecated
@@ -837,20 +882,6 @@ class RF24
*/
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().
diff --git a/RPi/RF24/RF24_config.h b/RPi/RF24/RF24_config.h
index eef07047..304e29d3 100644
--- a/RPi/RF24/RF24_config.h
+++ b/RPi/RF24/RF24_config.h
@@ -15,6 +15,11 @@
#ifndef __RF24_CONFIG_H__
#define __RF24_CONFIG_H__
+ /*** USER DEFINES: ***/
+ //#define FAILURE_HANDLING
+ //#define DEBUG
+ /**********************/
+
#include
#include
#include