Skip to content

Commit

Permalink
ExpressLRS - Fix data-race in ISR handling that was observed that caused
Browse files Browse the repository at this point in the history
RX loss.

Likely caused by RX task running *very* late and a new EXTI flag being
set, and then being immediately cleared without processing it.

More likely to happen on the bench than in the air due to task latency
caused by USB activity.
  • Loading branch information
hydra committed Jan 28, 2022
1 parent 3c5a572 commit a91166b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 15 deletions.
25 changes: 18 additions & 7 deletions src/main/drivers/rx/rx_sx127x.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@

#ifdef USE_RX_SX127X

#include "build/atomic.h"

#include "drivers/bus_spi.h"
#include "drivers/io.h"
#include "drivers/io_impl.h"
#include "drivers/nvic.h"
#include "drivers/rx/rx_sx127x.h"
#include "drivers/rx/rx_spi.h"
#include "drivers/time.h"
Expand Down Expand Up @@ -73,15 +76,23 @@ static bool sx127xDetectChip(void)

uint8_t sx127xISR(timeUs_t *timeStamp)
{
if (rxSpiPollExti()) {
if (rxSpiGetLastExtiTimeUs()) {
*timeStamp = rxSpiGetLastExtiTimeUs();
}
bool extiTriggered = false;
timeUs_t extiTimestamp;

uint8_t irqReason;
irqReason = sx127xGetIrqReason();
ATOMIC_BLOCK(NVIC_PRIO_RX_SPI_INT_EXTI) {
// prevent a data-race that can occur if a new EXTI ISR occurs during this block.
extiTriggered = rxSpiPollExti();
extiTimestamp = rxSpiGetLastExtiTimeUs();
if (extiTriggered) {
rxSpiResetExti();
}
}

rxSpiResetExti();
if (extiTriggered) {
uint8_t irqReason = sx127xGetIrqReason();
if (extiTimestamp) {
*timeStamp = extiTimestamp;
}

return irqReason;
}
Expand Down
26 changes: 18 additions & 8 deletions src/main/drivers/rx/rx_sx1280.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@

#ifdef USE_RX_SX1280

#include "build/atomic.h"

#include "drivers/bus_spi.h"
#include "drivers/io.h"
#include "drivers/io_impl.h"
#include "drivers/nvic.h"
#include "drivers/rx/rx_sx1280.h"
#include "drivers/rx/rx_spi.h"
#include "drivers/time.h"
Expand Down Expand Up @@ -103,16 +106,23 @@ bool sx1280Init(IO_t resetPin, IO_t busyPin)

uint8_t sx1280ISR(timeUs_t *timeStamp)
{
if (rxSpiPollExti()) {
if (rxSpiGetLastExtiTimeUs()) {
*timeStamp = rxSpiGetLastExtiTimeUs();
}

uint8_t irqReason;
irqReason = sx1280GetIrqReason();
bool extiTriggered = false;
timeUs_t extiTimestamp;

rxSpiResetExti();
ATOMIC_BLOCK(NVIC_PRIO_RX_SPI_INT_EXTI) {
// prevent a data-race that can occur if a new EXTI ISR occurs during this block.
extiTriggered = rxSpiPollExti();
extiTimestamp = rxSpiGetLastExtiTimeUs();
if (extiTriggered) {
rxSpiResetExti();
}
}

if (extiTriggered) {
uint8_t irqReason = sx1280GetIrqReason();
if (extiTimestamp) {
*timeStamp = extiTimestamp;
}
return irqReason;
}
return 0;
Expand Down

0 comments on commit a91166b

Please sign in to comment.