diff --git a/src/modules/SX126x/STM32WLx.cpp b/src/modules/SX126x/STM32WLx.cpp index a1ec8a58..bad38dc9 100644 --- a/src/modules/SX126x/STM32WLx.cpp +++ b/src/modules/SX126x/STM32WLx.cpp @@ -9,6 +9,7 @@ This file is licensed under the MIT License: https://opensource.org/licenses/MIT #include "STM32WLx.h" #if !defined(RADIOLIB_EXCLUDE_STM32WLX) +#include STM32WLx::STM32WLx(STM32WLx_Module* mod) : SX1262(mod) { } @@ -72,5 +73,30 @@ int16_t STM32WLx::setOutputPower(int8_t power) { return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1)); } +int16_t STM32WLx::clearIrqStatus(uint16_t clearIrqParams) { + int16_t res = SX126x::clearIrqStatus(clearIrqParams); + // The NVIC interrupt is level-sensitive, so clear away any pending + // flag that is only set because the radio IRQ status was not cleared + // in the interrupt (to prevent each IRQ triggering twice and allow + // reading the irq status through the pending flag). + SubGhz.clearPendingInterrupt(); + if(SubGhz.hasInterrupt()) + SubGhz.enableInterrupt(); + return(res); +} + +void STM32WLx::setDio1Action(void (*func)(void)) { + SubGhz.attachInterrupt([func]() { + // Because the interrupt is level-triggered, we disable it in the + // NVIC (otherwise we would need an SPI command to clear the IRQ in + // the radio, or it would trigger over and over again). + SubGhz.disableInterrupt(); + func(); + }); +} + +void STM32WLx::clearDio1Action() { + SubGhz.detachInterrupt(); +} #endif // !defined(RADIOLIB_EXCLUDE_STM32WLX) diff --git a/src/modules/SX126x/STM32WLx.h b/src/modules/SX126x/STM32WLx.h index d90f1450..5778dfb1 100644 --- a/src/modules/SX126x/STM32WLx.h +++ b/src/modules/SX126x/STM32WLx.h @@ -112,6 +112,23 @@ class STM32WLx : public SX1262 { // Note: This explicitly inherits this method only to override docs using SX126x::setRfSwitchTable; + /*! + \brief Sets interrupt service routine to call when DIO1/2/3 activates. + + \param func ISR to call. + */ + void setDio1Action(void (*func)(void)); + + /*! + \brief Clears interrupt service routine to call when DIO1/2/3 activates. + */ + void clearDio1Action(); + +#if !defined(RADIOLIB_GODMODE) + protected: +#endif + virtual int16_t clearIrqStatus(uint16_t clearIrqParams) override; + #if !defined(RADIOLIB_GODMODE) private: #endif diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index ae479859..e1b603ba 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -982,7 +982,7 @@ class SX126x: public PhysicalLayer { int16_t writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00); int16_t readBuffer(uint8_t* data, uint8_t numBytes); int16_t setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask = RADIOLIB_SX126X_IRQ_NONE, uint16_t dio3Mask = RADIOLIB_SX126X_IRQ_NONE); - int16_t clearIrqStatus(uint16_t clearIrqParams = RADIOLIB_SX126X_IRQ_ALL); + virtual int16_t clearIrqStatus(uint16_t clearIrqParams = RADIOLIB_SX126X_IRQ_ALL); int16_t setRfFrequency(uint32_t frf); int16_t calibrateImage(uint8_t* data); uint8_t getPacketType();