@@ -1248,32 +1248,78 @@ void RF24::errNotify()
12481248 #endif
12491249}
12501250
1251- #endif
12521251/* *****************************************************************/
12531252
1254- // Similar to the previous write, clears the interrupt flags
1255- bool RF24::write (const void * buf, uint8_t len, const bool multicast)
1253+ int8_t RF24::errHandler (bool * doRecovery)
12561254{
1257- // Start Writing
1258- startFastWrite (buf, len, multicast);
12591255
1260- // Wait until complete or failed
1261- #if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
1256+ // Wait until complete or failed
12621257 uint32_t timer = millis ();
1263- #endif // defined(FAILURE_HANDLING) || defined(RF24_LINUX)
12641258
12651259 while (!(update () & (RF24_TX_DS | RF24_TX_DF ))) {
1266- #if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
12671260 if (millis () - timer > 95 ) {
1268- errNotify ();
12691261 #if defined(FAILURE_HANDLING)
1262+ flush_rx ();
1263+ flush_tx ();
1264+ if (doRecovery) {
1265+ *doRecovery = false ;
1266+ failureRecoveryAttempts++;
1267+ ce (LOW );
1268+ return -1 ;
1269+ }
1270+ else {
1271+ #endif
1272+ errNotify ();
1273+ #if defined(FAILURE_HANDLING)
1274+ }
12701275 return 0 ;
12711276 #else
12721277 delay (100 );
12731278 #endif
12741279 }
1275- #endif
12761280 }
1281+ return 0 ;
1282+ }
1283+
1284+ /* *****************************************************************/
1285+
1286+ void RF24::errHandler ()
1287+ {
1288+
1289+ #if defined(FAILURE_HANDLING)
1290+ flush_tx ();
1291+ flush_rx ();
1292+ if (!failureFlushed) {
1293+ failureFlushed = true ;
1294+ failureRecoveryAttempts++;
1295+ }
1296+ else {
1297+ #endif
1298+ errNotify ();
1299+ #if defined(FAILURE_HANDLING)
1300+ failureFlushed = false ;
1301+ }
1302+ ce (LOW );
1303+ #endif
1304+ }
1305+
1306+ #endif
1307+
1308+ /* *****************************************************************/
1309+
1310+ // Similar to the previous write, clears the interrupt flags
1311+ bool RF24::write (const void * buf, uint8_t len, const bool multicast)
1312+ {
1313+
1314+ // Start Writing
1315+ #if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
1316+ bool doRecovery = true ;
1317+ do {
1318+ #endif
1319+ startFastWrite (buf, len, multicast);
1320+ #if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
1321+ } while (errHandler (&doRecovery) < 0 );
1322+ #endif
12771323
12781324 ce (LOW );
12791325
@@ -1288,6 +1334,8 @@ bool RF24::write(const void* buf, uint8_t len, const bool multicast)
12881334 return 1 ;
12891335}
12901336
1337+ /* ***************************************************************************/
1338+
12911339bool RF24::write (const void * buf, uint8_t len)
12921340{
12931341 return write (buf, len, 0 );
@@ -1302,6 +1350,9 @@ bool RF24::writeBlocking(const void* buf, uint8_t len, uint32_t timeout)
13021350 // Keep track of the MAX retries and set auto-retry if seeing failures
13031351 // This way the FIFO will fill up and allow blocking until packets go through
13041352 // The radio will auto-clear everything in the FIFO as long as CE remains high
1353+ #if defined(FAILURE_HANDLING)
1354+ bool timeoutInvoked = false ;
1355+ #endif
13051356
13061357 uint32_t timer = millis (); // Get the time that the payload transmission started
13071358
@@ -1310,22 +1361,34 @@ bool RF24::writeBlocking(const void* buf, uint8_t len, uint32_t timeout)
13101361 if (status & RF24_TX_DF ) { // If MAX Retries have been reached
13111362 reUseTX (); // Set re-transmit and clear the MAX_RT interrupt flag
13121363 if (millis () - timer > timeout) {
1364+ #if defined(FAILURE_HANDLING)
1365+ failureFlushed = false ;
1366+ #endif
13131367 return 0 ; // If this payload has exceeded the user-defined timeout, exit and return 0
13141368 }
13151369 }
13161370#if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
13171371 if (millis () - timer > (timeout + 95 )) {
1318- errNotify ();
1372+ errHandler ();
13191373 #if defined(FAILURE_HANDLING)
1320- return 0 ;
1374+ timeoutInvoked = true ;
1375+ if (!failureFlushed) {
1376+ #endif
1377+ return 0 ;
1378+ #if defined(FAILURE_HANDLING)
1379+ }
13211380 #endif
13221381 }
13231382#endif
13241383 }
13251384
13261385 // Start Writing
13271386 startFastWrite (buf, len, 0 ); // Write the payload if a buffer is clear
1328-
1387+ #if defined(FAILURE_HANDLING)
1388+ if (!timeoutInvoked) {
1389+ failureFlushed = false ;
1390+ }
1391+ #endif
13291392 return 1 ; // Return 1 to indicate successful transmission
13301393}
13311394
@@ -1351,25 +1414,38 @@ bool RF24::writeFast(const void* buf, uint8_t len, const bool multicast)
13511414
13521415#if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
13531416 uint32_t timer = millis ();
1417+ bool timeoutInvoked = false ;
13541418#endif
13551419
13561420 // Blocking only if FIFO is full. This will loop and block until TX is successful or fail
13571421 while (update () & _BV (TX_FULL )) {
13581422 if (status & RF24_TX_DF ) {
1423+ #if defined(FAILURE_HANDLING)
1424+ failureFlushed = false ;
1425+ #endif
13591426 return 0 ; // Return 0. The previous payload has not been retransmitted
13601427 // From the user perspective, if you get a 0, call txStandBy()
13611428 }
13621429#if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
13631430 if (millis () - timer > 95 ) {
1364- errNotify ();
1431+ timeoutInvoked = true ;
1432+ errHandler ();
13651433 #if defined(FAILURE_HANDLING)
1366- return 0 ;
1367- #endif // defined(FAILURE_HANDLING)
1434+ if (!failureFlushed) {
1435+ #endif
1436+ return 0 ;
1437+ #if defined(FAILURE_HANDLING)
1438+ }
1439+ #endif
13681440 }
13691441#endif
13701442 }
13711443 startFastWrite (buf, len, multicast); // Start Writing
1372-
1444+ #if defined(FAILURE_HANDLING)
1445+ if (!timeoutInvoked) {
1446+ failureFlushed = false ;
1447+ }
1448+ #endif
13731449 return 1 ;
13741450}
13751451
@@ -1451,19 +1527,23 @@ bool RF24::txStandBy()
14511527 write_register (NRF_STATUS , RF24_TX_DF );
14521528 ce (LOW );
14531529 flush_tx (); // Non blocking, flush the data
1530+ #if defined(FAILURE_HANDLING)
1531+ failureFlushed = false ;
1532+ #endif
14541533 return 0 ;
14551534 }
14561535#if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
14571536 if (millis () - timeout > 95 ) {
1458- errNotify ();
1459- #if defined(FAILURE_HANDLING)
1537+ errHandler ();
14601538 return 0 ;
1461- #endif
14621539 }
14631540#endif
14641541 }
14651542
14661543 ce (LOW ); // Set STANDBY-I mode
1544+ #if defined(FAILURE_HANDLING)
1545+ failureFlushed = false ;
1546+ #endif
14671547 return 1 ;
14681548}
14691549
@@ -1486,20 +1566,24 @@ bool RF24::txStandBy(uint32_t timeout, bool startTx)
14861566 if (millis () - start >= timeout) {
14871567 ce (LOW );
14881568 flush_tx ();
1569+ #if defined(FAILURE_HANDLING)
1570+ failureFlushed = false ;
1571+ #endif
14891572 return 0 ;
14901573 }
14911574 }
14921575#if defined(FAILURE_HANDLING) || defined(RF24_LINUX)
1493- if (millis () - start > (timeout + 95 )) {
1494- errNotify ();
1495- #if defined(FAILURE_HANDLING)
1576+ if (millis () - start > timeout + 95 ) {
1577+ errHandler ();
14961578 return 0 ;
1497- #endif
14981579 }
14991580#endif
15001581 }
15011582
15021583 ce (LOW ); // Set STANDBY-I mode
1584+ #if defined(FAILURE_HANDLING)
1585+ failureFlushed = false ;
1586+ #endif
15031587 return 1 ;
15041588}
15051589
0 commit comments