Merge pull request #1188 from jgromes/irqFlags

[PHY, modules, LoRaWAN] Generalize IRQ checks
This commit is contained in:
Jan Gromeš 2024-08-18 09:57:40 +02:00 committed by GitHub
commit 0abb7512fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 154 additions and 36 deletions

View file

@ -1328,12 +1328,35 @@ int16_t LR11x0::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) {
return(RADIOLIB_ERR_NONE);
}
bool LR11x0::isRxTimeout() {
uint32_t irq = getIrqStatus();
bool rxTimedOut = irq & RADIOLIB_LR11X0_IRQ_TIMEOUT;
return(rxTimedOut);
int16_t LR11x0::checkIrq(uint8_t irq) {
uint16_t flags = getIrqStatus();
switch(irq) {
case RADIOLIB_IRQ_TX_DONE:
return(flags & RADIOLIB_LR11X0_IRQ_TX_DONE);
case RADIOLIB_IRQ_RX_DONE:
return(flags & RADIOLIB_LR11X0_IRQ_RX_DONE);
case RADIOLIB_IRQ_PREAMBLE_DETECTED:
return(flags & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED);
case RADIOLIB_IRQ_SYNC_WORD_VALID:
return(flags & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID);
case RADIOLIB_IRQ_HEADER_VALID:
return(flags & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID);
case RADIOLIB_IRQ_HEADER_ERR:
return(flags & RADIOLIB_LR11X0_IRQ_HEADER_ERR);
case RADIOLIB_IRQ_CRC_ERR:
return(flags & RADIOLIB_LR11X0_IRQ_CRC_ERR);
case RADIOLIB_IRQ_CAD_DONE:
return(flags & RADIOLIB_LR11X0_IRQ_CAD_DONE);
case RADIOLIB_IRQ_CAD_DETECTED:
return(flags & RADIOLIB_LR11X0_IRQ_CAD_DETECTED);
case RADIOLIB_IRQ_TIMEOUT:
return(flags & RADIOLIB_LR11X0_IRQ_TIMEOUT);
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
return(RADIOLIB_ERR_UNSUPPORTED);
}
uint8_t LR11x0::randomByte() {
uint32_t num = 0;
(void)getRandomNumber(&num);

View file

@ -1229,10 +1229,10 @@ class LR11x0: public PhysicalLayer {
int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override;
/*!
\brief Check whether the IRQ bit for RxTimeout is set
\returns Whether RxTimeout IRQ is set
\brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone).
\returns Whether requested IRQ is set.
*/
bool isRxTimeout() override;
int16_t checkIrq(uint8_t irq) override;
/*!
\brief Get one truly random byte from RSSI noise.

View file

@ -1466,10 +1466,33 @@ int16_t SX126x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) {
return(RADIOLIB_ERR_NONE);
}
bool SX126x::isRxTimeout() {
uint16_t irq = getIrqStatus();
bool rxTimedOut = irq & RADIOLIB_SX126X_IRQ_TIMEOUT;
return(rxTimedOut);
int16_t SX126x::checkIrq(uint8_t irq) {
uint16_t flags = getIrqStatus();
switch(irq) {
case RADIOLIB_IRQ_TX_DONE:
return(flags & RADIOLIB_SX126X_IRQ_TX_DONE);
case RADIOLIB_IRQ_RX_DONE:
return(flags & RADIOLIB_SX126X_IRQ_RX_DONE);
case RADIOLIB_IRQ_PREAMBLE_DETECTED:
return(flags & RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED);
case RADIOLIB_IRQ_SYNC_WORD_VALID:
return(flags & RADIOLIB_SX126X_IRQ_SYNC_WORD_VALID);
case RADIOLIB_IRQ_HEADER_VALID:
return(flags & RADIOLIB_SX126X_IRQ_HEADER_VALID);
case RADIOLIB_IRQ_HEADER_ERR:
return(flags & RADIOLIB_SX126X_IRQ_HEADER_ERR);
case RADIOLIB_IRQ_CRC_ERR:
return(flags & RADIOLIB_SX126X_IRQ_CRC_ERR);
case RADIOLIB_IRQ_CAD_DONE:
return(flags & RADIOLIB_SX126X_IRQ_CAD_DONE);
case RADIOLIB_IRQ_CAD_DETECTED:
return(flags & RADIOLIB_SX126X_IRQ_CAD_DETECTED);
case RADIOLIB_IRQ_TIMEOUT:
return(flags & RADIOLIB_SX126X_IRQ_TIMEOUT);
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
return(RADIOLIB_ERR_UNSUPPORTED);
}
int16_t SX126x::implicitHeader(size_t len) {

View file

@ -997,10 +997,10 @@ class SX126x: public PhysicalLayer {
int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override;
/*!
\brief Check whether the IRQ bit for RxTimeout is set
\returns Whether RxTimeout IRQ is set
\brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone).
\returns Whether requested IRQ is set.
*/
bool isRxTimeout() override;
int16_t checkIrq(uint8_t irq) override;
/*!
\brief Set implicit header mode for future reception/transmission.

View file

@ -1302,10 +1302,27 @@ int16_t SX127x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) {
return(RADIOLIB_ERR_NONE);
}
bool SX127x::isRxTimeout() {
uint16_t irq = getIRQFlags();
bool rxTimedOut = irq & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_RX_TIMEOUT;
return(rxTimedOut);
int16_t SX127x::checkIrq(uint8_t irq) {
uint16_t flags = getIRQFlags();
switch(irq) {
case RADIOLIB_IRQ_TX_DONE:
return(flags & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_TX_DONE);
case RADIOLIB_IRQ_RX_DONE:
return(flags & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_RX_DONE);
case RADIOLIB_IRQ_HEADER_VALID:
return(flags & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_VALID_HEADER);
case RADIOLIB_IRQ_CRC_ERR:
return(flags & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR);
case RADIOLIB_IRQ_CAD_DONE:
return(flags & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_CAD_DONE);
case RADIOLIB_IRQ_CAD_DETECTED:
return(flags & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_CAD_DETECTED);
case RADIOLIB_IRQ_TIMEOUT:
return(flags & RADIOLIB_SX127X_CLEAR_IRQ_FLAG_RX_TIMEOUT);
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
return(RADIOLIB_ERR_UNSUPPORTED);
}
int16_t SX127x::setCrcFiltering(bool enable) {

View file

@ -1073,10 +1073,10 @@ class SX127x: public PhysicalLayer {
int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override;
/*!
\brief Check whether the IRQ bit for RxTimeout is set
\returns Whether RxTimeout IRQ is set
\brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone).
\returns Whether requested IRQ is set.
*/
bool isRxTimeout() override;
int16_t checkIrq(uint8_t irq) override;
/*!
\brief Enable CRC filtering and generation.

View file

@ -638,6 +638,35 @@ int16_t SX128x::readData(uint8_t* data, size_t len) {
return(state);
}
int16_t SX128x::checkIrq(uint8_t irq) {
uint16_t flags = getIrqStatus();
switch(irq) {
case RADIOLIB_IRQ_TX_DONE:
return(flags & RADIOLIB_SX128X_IRQ_TX_DONE);
case RADIOLIB_IRQ_RX_DONE:
return(flags & RADIOLIB_SX128X_IRQ_RX_DONE);
case RADIOLIB_IRQ_PREAMBLE_DETECTED:
return(flags & RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED);
case RADIOLIB_IRQ_SYNC_WORD_VALID:
return(flags & RADIOLIB_SX128X_IRQ_SYNC_WORD_VALID);
case RADIOLIB_IRQ_HEADER_VALID:
return(flags & RADIOLIB_SX128X_IRQ_HEADER_VALID);
case RADIOLIB_IRQ_HEADER_ERR:
return(flags & RADIOLIB_SX128X_IRQ_HEADER_ERROR);
case RADIOLIB_IRQ_CRC_ERR:
return(flags & RADIOLIB_SX128X_IRQ_CRC_ERROR);
case RADIOLIB_IRQ_CAD_DONE:
return(flags & RADIOLIB_SX128X_IRQ_CAD_DONE);
case RADIOLIB_IRQ_CAD_DETECTED:
return(flags & RADIOLIB_SX128X_IRQ_CAD_DETECTED);
case RADIOLIB_IRQ_TIMEOUT:
return(flags & RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT);
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
return(RADIOLIB_ERR_UNSUPPORTED);
}
int16_t SX128x::startChannelScan() {
// check active modem
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) {

View file

@ -576,6 +576,12 @@ class SX128x: public PhysicalLayer {
*/
int16_t readData(uint8_t* data, size_t len) override;
/*!
\brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone).
\returns Whether requested IRQ is set.
*/
int16_t checkIrq(uint8_t irq) override;
/*!
\brief Interrupt-driven channel activity detection method. DIO1 will be activated
when LoRa preamble is detected, or upon timeout. Defaults to CAD parameter values recommended by AN1200.48.

View file

@ -1196,6 +1196,8 @@ int16_t LoRaWANNode::downlinkCommon() {
this->phyLayer->setPacketReceivedAction(LoRaWANNodeOnDownlinkAction);
int16_t timedOut = 0;
// perform listening in the two Rx windows
for(uint8_t i = 0; i < 2; i++) {
downlinkAction = false;
@ -1226,7 +1228,11 @@ int16_t LoRaWANNode::downlinkCommon() {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Closing Rx%d window", i+1);
// check if the IRQ bit for Rx Timeout is set
if(!this->phyLayer->isRxTimeout()) {
timedOut = this->phyLayer->checkIrq(RADIOLIB_IRQ_TIMEOUT);
if(timedOut == RADIOLIB_ERR_UNSUPPORTED) {
return(timedOut);
}
if(!timedOut) {
break;
} else if(i == 0) {
@ -1248,7 +1254,7 @@ int16_t LoRaWANNode::downlinkCommon() {
this->rxDelayEnd = mod->hal->millis();
// if we got here due to a timeout, stop ongoing activities
if(this->phyLayer->isRxTimeout()) {
if(timedOut) {
this->phyLayer->standby(); // TODO check: this should be done automagically due to RxSingle?
if(this->modulation == RADIOLIB_LORAWAN_MODULATION_LORA) {
this->phyLayer->invertIQ(false);

View file

@ -316,8 +316,9 @@ int16_t PhysicalLayer::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask)
return(RADIOLIB_ERR_UNSUPPORTED);
}
bool PhysicalLayer::isRxTimeout() {
return(false);
int16_t PhysicalLayer::checkIrq(uint8_t irq) {
(void)irq;
return(RADIOLIB_ERR_UNSUPPORTED);
}
int16_t PhysicalLayer::startChannelScan() {

View file

@ -4,6 +4,18 @@
#include "../../TypeDef.h"
#include "../../Module.h"
// common IRQ flags
#define RADIOLIB_IRQ_TX_DONE 0x00
#define RADIOLIB_IRQ_RX_DONE 0x01
#define RADIOLIB_IRQ_PREAMBLE_DETECTED 0x02
#define RADIOLIB_IRQ_SYNC_WORD_VALID 0x03
#define RADIOLIB_IRQ_HEADER_VALID 0x04
#define RADIOLIB_IRQ_HEADER_ERR 0x05
#define RADIOLIB_IRQ_CRC_ERR 0x06
#define RADIOLIB_IRQ_CAD_DONE 0x07
#define RADIOLIB_IRQ_CAD_DETECTED 0x08
#define RADIOLIB_IRQ_TIMEOUT 0x09
/*!
\struct LoRaRate_t
\brief Data rate structure interpretation in case LoRa is used
@ -346,28 +358,29 @@ class PhysicalLayer {
virtual RadioLibTime_t getTimeOnAir(size_t len);
/*!
\brief Calculate the timeout value for this specific module / series (in number of symbols or units of time)
\param timeoutUs Timeout in microseconds to listen for
\returns Timeout value in a unit that is specific for the used module
\brief Calculate the timeout value for this specific module / series
(in number of symbols or units of time).
\param timeoutUs Timeout in microseconds to listen for.
\returns Timeout value in a unit that is specific for the used module.
*/
virtual RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs);
/*!
\brief Create the flags that make up RxDone and RxTimeout used for receiving downlinks
\param irqFlags The flags for which IRQs must be triggered
\param irqMask Mask indicating which IRQ triggers a DIO
\brief Create the flags that make up RxDone and RxTimeout used for receiving downlinks.
\param irqFlags The flags for which IRQs must be triggered.
\param irqMask Mask indicating which IRQ triggers a DIO.
\returns \ref status_codes
*/
virtual int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask);
/*!
\brief Check whether the IRQ bit for RxTimeout is set
\returns Whether RxTimeout IRQ is set
\brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone).
\returns Whether requested IRQ is set.
*/
virtual bool isRxTimeout();
virtual int16_t checkIrq(uint8_t irq);
/*!
\brief Interrupt-driven channel activity detection method. interrupt will be activated
\brief Interrupt-driven channel activity detection method. Interrupt will be activated
when packet is detected. Must be implemented in module class.
\returns \ref status_codes
*/