Skip to content

Commit b5a2fc2

Browse files
marceloaqnomfalkvidd
authored andcommitted
Linux: RF24 interrupt trigger workaround (mysensors#1094)
Fix mysensors#870
1 parent fb95a84 commit b5a2fc2

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

drivers/RF24/RF24.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,11 @@ LOCAL int16_t RF24_getSendingRSSI(void)
410410
LOCAL void RF24_irqHandler(void)
411411
{
412412
if (RF24_receiveCallback) {
413+
#if defined(MY_GATEWAY_SERIAL) && !defined(__linux__)
413414
// Will stay for a while (several 100us) in this interrupt handler. Any interrupts from serial
414415
// rx coming in during our stay will not be handled and will cause characters to be lost.
415416
// As a workaround we re-enable interrupts to allow nested processing of other interrupts.
416417
// Our own handler is disconnected to prevent recursive calling of this handler.
417-
#if defined(MY_GATEWAY_SERIAL) && !defined(__linux__)
418418
detachInterrupt(digitalPinToInterrupt(MY_RF24_IRQ_PIN));
419419
interrupts();
420420
#endif
@@ -423,13 +423,28 @@ LOCAL void RF24_irqHandler(void)
423423
// 1.Read payload, 2.Clear RX_DR IRQ, 3.Read FIFO_status, 4.Repeat when more data available.
424424
// Datasheet (ch. 8.5) states, that the nRF de-asserts IRQ after reading STATUS.
425425

426+
#if defined(__linux__)
427+
// Start checking if RX-FIFO is not empty, as we might end up here from an interrupt
428+
// for a message we've already read.
429+
if (RF24_isDataAvailable()) {
430+
do {
431+
RF24_receiveCallback(); // Must call RF24_readMessage(), which will clear RX_DR IRQ !
432+
} while (RF24_isDataAvailable());
433+
} else {
434+
// Occasionally interrupt is triggered but no data is available - clear RX interrupt only
435+
RF24_setStatus(_BV(RF24_RX_DR));
436+
logNotice("RF24: Recovered from a bad interrupt trigger.\n");
437+
}
438+
#else
426439
// Start checking if RX-FIFO is not empty, as we might end up here from an interrupt
427440
// for a message we've already read.
428441
while (RF24_isDataAvailable()) {
429442
RF24_receiveCallback(); // Must call RF24_readMessage(), which will clear RX_DR IRQ !
430443
}
431-
// Restore our interrupt handler.
444+
#endif
445+
432446
#if defined(MY_GATEWAY_SERIAL) && !defined(__linux__)
447+
// Restore our interrupt handler.
433448
noInterrupts();
434449
attachInterrupt(digitalPinToInterrupt(MY_RF24_IRQ_PIN), RF24_irqHandler, FALLING);
435450
#endif

0 commit comments

Comments
 (0)