fix(lora): skip DIO detach when no ISR is attached (#11386)
* fix(lora): skip DIO detach when no ISR is attached Fixes #11371 * fix(lora): latch the ISR-armed flag instead of tracking attach state The flag is now written once from task context and only read from ISR context.
This commit is contained in:
11 files changed
+38
-18
No files matched your search
@@ -318,7 +318,7 @@ template <typename T> bool LR11x0Interface<T>::reconfigure()
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T> void LR11x0Interface<T>::disableInterrupt()
|
||||
template <typename T> void LR11x0Interface<T>::clearRadioIsr()
|
||||
{
|
||||
lora.clearIrqAction();
|
||||
}
|
||||
|
||||
@@ -47,12 +47,12 @@ template <class T> class LR11x0Interface : public RadioLibInterface
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*/
|
||||
virtual void disableInterrupt() override;
|
||||
virtual void clearRadioIsr() override;
|
||||
|
||||
/**
|
||||
* Enable a particular ISR callback glue function
|
||||
*/
|
||||
virtual void enableInterrupt(void (*callback)()) { lora.setIrqAction(callback); }
|
||||
virtual void setRadioIsr(void (*callback)()) override { lora.setIrqAction(callback); }
|
||||
|
||||
/** can we detect a LoRa preamble on the current channel? */
|
||||
virtual bool isChannelActive() override;
|
||||
|
||||
@@ -323,7 +323,7 @@ template <typename T> bool LR20x0Interface<T>::reconfigure()
|
||||
return success;
|
||||
}
|
||||
|
||||
template <typename T> void LR20x0Interface<T>::disableInterrupt()
|
||||
template <typename T> void LR20x0Interface<T>::clearRadioIsr()
|
||||
{
|
||||
lora.clearIrqAction();
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ template <class T> class LR20x0Interface : public RadioLibInterface
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*/
|
||||
virtual void disableInterrupt() override;
|
||||
virtual void clearRadioIsr() override;
|
||||
|
||||
/**
|
||||
* Enable a particular ISR callback glue function
|
||||
*/
|
||||
virtual void enableInterrupt(void (*callback)()) { lora.setIrqAction(callback); }
|
||||
virtual void setRadioIsr(void (*callback)()) override { lora.setIrqAction(callback); }
|
||||
|
||||
/** can we detect a LoRa preamble on the current channel? */
|
||||
virtual bool isChannelActive() override;
|
||||
|
||||
@@ -201,7 +201,7 @@ bool RF95Interface::init()
|
||||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
void RF95Interface::disableInterrupt()
|
||||
void RF95Interface::clearRadioIsr()
|
||||
{
|
||||
lora->clearDio0Action();
|
||||
}
|
||||
|
||||
@@ -35,14 +35,14 @@ class RF95Interface : public RadioLibInterface
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*/
|
||||
virtual void disableInterrupt() override;
|
||||
virtual void clearRadioIsr() override;
|
||||
|
||||
int16_t getCurrentRSSI() override;
|
||||
|
||||
/**
|
||||
* Enable a particular ISR callback glue function
|
||||
*/
|
||||
virtual void enableInterrupt(void (*callback)()) { lora->setDio0Action(callback, RISING); }
|
||||
virtual void setRadioIsr(void (*callback)()) override { lora->setDio0Action(callback, RISING); }
|
||||
|
||||
/** can we detect a LoRa preamble on the current channel? */
|
||||
virtual bool isChannelActive() override;
|
||||
|
||||
@@ -99,6 +99,9 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
/// are _trying_ to receive a packet currently (note - we might just be waiting for one)
|
||||
bool isReceiving = false;
|
||||
|
||||
/// has the radio IRQ ever been armed? latches true and is never cleared, so ISR context only reads it
|
||||
volatile bool isrEverArmed = false;
|
||||
|
||||
protected:
|
||||
// Noise floor tracking - rolling window of samples.
|
||||
static const uint8_t NOISE_FLOOR_SAMPLES = 20;
|
||||
@@ -144,13 +147,26 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*
|
||||
* Skip the detach until the IRQ has been armed once: the first setStandby() runs before any
|
||||
* enableInterrupt(), and ESP-IDF logs "GPIO isr service is not installed" for that call.
|
||||
*/
|
||||
virtual void disableInterrupt() = 0;
|
||||
void disableInterrupt()
|
||||
{
|
||||
if (!isrEverArmed)
|
||||
return;
|
||||
clearRadioIsr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a particular ISR callback glue function
|
||||
*/
|
||||
virtual void enableInterrupt(void (*)()) = 0;
|
||||
void enableInterrupt(void (*callback)())
|
||||
{
|
||||
// Latch before arming: the ISR can fire the moment the handler is installed.
|
||||
isrEverArmed = true;
|
||||
setRadioIsr(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll as a backup to catch missed edge-triggered interrupts.
|
||||
@@ -300,6 +316,10 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
*/
|
||||
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) = 0;
|
||||
|
||||
/** Chip specific arm/disarm of the radio IRQ; call enableInterrupt()/disableInterrupt() instead */
|
||||
virtual void setRadioIsr(void (*callback)()) = 0;
|
||||
virtual void clearRadioIsr() = 0;
|
||||
|
||||
/**
|
||||
* Subclasses must override, implement and then call into this base class implementation
|
||||
*/
|
||||
|
||||
@@ -250,7 +250,7 @@ template <typename T> int16_t SX126xInterface<T>::getCurrentRSSI()
|
||||
return (int16_t)round(rssi);
|
||||
}
|
||||
|
||||
template <typename T> void SX126xInterface<T>::enableInterrupt(void (*callback)())
|
||||
template <typename T> void SX126xInterface<T>::setRadioIsr(void (*callback)())
|
||||
{
|
||||
#ifdef LORA_DIO1_SOFTWARE_POLL
|
||||
irqPollingActive = true;
|
||||
@@ -261,7 +261,7 @@ template <typename T> void SX126xInterface<T>::enableInterrupt(void (*callback)(
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T> void SX126xInterface<T>::disableInterrupt()
|
||||
template <typename T> void SX126xInterface<T>::clearRadioIsr()
|
||||
{
|
||||
#ifdef LORA_DIO1_SOFTWARE_POLL
|
||||
irqPollingActive = false;
|
||||
|
||||
@@ -47,12 +47,12 @@ template <class T> class SX126xInterface : public RadioLibInterface
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*/
|
||||
virtual void disableInterrupt() override;
|
||||
virtual void clearRadioIsr() override;
|
||||
|
||||
/**
|
||||
* Enable a particular ISR callback glue function
|
||||
*/
|
||||
virtual void enableInterrupt(void (*callback)()) override;
|
||||
virtual void setRadioIsr(void (*callback)()) override;
|
||||
|
||||
#ifdef LORA_DIO1_SOFTWARE_POLL
|
||||
void handleSoftwareLoraIrqPoll() override;
|
||||
|
||||
@@ -156,7 +156,7 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T> void SX128xInterface<T>::disableInterrupt()
|
||||
template <typename T> void SX128xInterface<T>::clearRadioIsr()
|
||||
{
|
||||
lora.clearDio1Action();
|
||||
}
|
||||
|
||||
@@ -43,12 +43,12 @@ template <class T> class SX128xInterface : public RadioLibInterface
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*/
|
||||
virtual void disableInterrupt() override;
|
||||
virtual void clearRadioIsr() override;
|
||||
|
||||
/**
|
||||
* Enable a particular ISR callback glue function
|
||||
*/
|
||||
virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
|
||||
virtual void setRadioIsr(void (*callback)()) override { lora.setDio1Action(callback); }
|
||||
|
||||
/** can we detect a LoRa preamble on the current channel? */
|
||||
virtual bool isChannelActive() override;
|
||||
|
||||
Reference in New Issue
Block a user