From 9fe39d546180361916c070b388d13202aa9ea6ce Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 18 Aug 2024 11:04:52 +0200 Subject: [PATCH 01/39] [PHY] Added channel scan configuration --- src/protocols/PhysicalLayer/PhysicalLayer.cpp | 10 ++++ src/protocols/PhysicalLayer/PhysicalLayer.h | 59 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.cpp b/src/protocols/PhysicalLayer/PhysicalLayer.cpp index 6953447c9..4949ddbdd 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.cpp +++ b/src/protocols/PhysicalLayer/PhysicalLayer.cpp @@ -325,6 +325,11 @@ int16_t PhysicalLayer::startChannelScan() { return(RADIOLIB_ERR_UNSUPPORTED); } +int16_t PhysicalLayer::startChannelScan(ChannelScanConfig_t config) { + (void)config; + return(RADIOLIB_ERR_UNSUPPORTED); +} + int16_t PhysicalLayer::getChannelScanResult() { return(RADIOLIB_ERR_UNSUPPORTED); } @@ -333,6 +338,11 @@ int16_t PhysicalLayer::scanChannel() { return(RADIOLIB_ERR_UNSUPPORTED); } +int16_t PhysicalLayer::scanChannel(ChannelScanConfig_t config) { + (void)config; + return(RADIOLIB_ERR_UNSUPPORTED); +} + int32_t PhysicalLayer::random(int32_t max) { if(max == 0) { return(0); diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.h b/src/protocols/PhysicalLayer/PhysicalLayer.h index 408408aed..fc94a6682 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -55,6 +55,48 @@ union DataRate_t { FSKRate_t fsk; }; +/*! + \struct CADScanConfig_t + \brief Channel scan configuration interpretation in case LoRa CAD is used +*/ +struct CADScanConfig_t { + /*! \brief Number of symbols to consider signal present */ + uint8_t symNum; + + /*! \brief Number of peak detection symbols */ + uint8_t detPeak; + + /*! \brief Number of minimum detection symbols */ + uint8_t detMin; + + /*! \brief Exit mode after signal detection is complete - module-specific value */ + uint8_t exitMode; + + /*! \brief Timeout in milliseconds */ + RadioLibTime_t timeout; +}; + +/*! + \struct RSSIScanConfig_t + \brief Channel scan configuration interpretation in case RSSI threshold is used +*/ +struct RSSIScanConfig_t { + /*! \brief RSSI limit in dBm */ + float limit; +}; + +/*! + \union ChannelScanConfig_t + \brief Common channel scan configuration structure +*/ +union ChannelScanConfig_t { + /*! \brief Interpretation for modems that use CAD (usually LoRa modems)*/ + CADScanConfig_t cad; + + /*! \brief Interpretation for modems that use RSSI threshold*/ + RSSIScanConfig_t rssi; +}; + /*! \class PhysicalLayer @@ -386,6 +428,14 @@ class PhysicalLayer { */ virtual int16_t startChannelScan(); + /*! + \brief Interrupt-driven channel activity detection method. interrupt will be activated + when packet is detected. Must be implemented in module class. + \param config Scan configuration structure. Interpretation depends on currently active modem. + \returns \ref status_codes + */ + virtual int16_t startChannelScan(ChannelScanConfig_t config); + /*! \brief Read the channel scan result \returns \ref status_codes @@ -400,6 +450,15 @@ class PhysicalLayer { */ virtual int16_t scanChannel(); + /*! + \brief Check whether the current communication channel is free or occupied. Performs CAD for LoRa modules, + or RSSI measurement for FSK modules. + \param config Scan configuration structure. Interpretation depends on currently active modem. + \returns RADIOLIB_CHANNEL_FREE when channel is free, + RADIOLIB_PREAMBLE_DETECTEDwhen occupied or other \ref status_codes. + */ + virtual int16_t scanChannel(ChannelScanConfig_t config); + /*! \brief Get truly random number in range 0 - max. \param max The maximum value of the random number (non-inclusive). From 6fdc07799916e7e26954fff4e58728bcc5ba2246 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 18 Aug 2024 11:07:27 +0200 Subject: [PATCH 02/39] [LR11x0] Added channel scan configuration --- src/modules/LR11x0/LR11x0.cpp | 41 ++++++++++++++++++++++++++++------- src/modules/LR11x0/LR11x0.h | 16 +++++--------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index bcef4d0bd..35a4c4dba 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -278,12 +278,21 @@ int16_t LR11x0::receiveDirect() { } int16_t LR11x0::scanChannel() { - return(this->scanChannel(RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT)); + ChannelScanConfig_t config = { + .cad = { + .symNum = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .detPeak = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .timeout = 0, + }, + }; + return(this->scanChannel(config)); } -int16_t LR11x0::scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { +int16_t LR11x0::scanChannel(ChannelScanConfig_t config) { // set mode to CAD - int state = startChannelScan(symbolNum, detPeak, detMin); + int state = startChannelScan(config); RADIOLIB_ASSERT(state); // wait for channel activity detected or timeout @@ -541,10 +550,19 @@ int16_t LR11x0::readData(uint8_t* data, size_t len) { } int16_t LR11x0::startChannelScan() { - return(this->startChannelScan(RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT)); + ChannelScanConfig_t config = { + .cad = { + .symNum = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .detPeak = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .timeout = 0, + }, + }; + return(this->startChannelScan(config)); } -int16_t LR11x0::startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { +int16_t LR11x0::startChannelScan(ChannelScanConfig_t config) { // check active modem int16_t state = RADIOLIB_ERR_NONE; uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE; @@ -570,7 +588,7 @@ int16_t LR11x0::startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t det RADIOLIB_ASSERT(state); // set mode to CAD - return(startCad(symbolNum, detPeak, detMin)); + return(startCad(config.cad.symNum, config.cad.detPeak, config.cad.detMin, config.cad.exitMode, config.cad.timeout)); } int16_t LR11x0::getChannelScanResult() { @@ -2007,7 +2025,7 @@ int16_t LR11x0::setPacketMode(uint8_t mode, uint8_t len) { return(state); } -int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { +int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout) { // check active modem uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE; int16_t state = getPacketType(&type); @@ -2034,9 +2052,16 @@ int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { min = 10; } + uint8_t mode = exitMode; + if(mode == RADIOLIB_LR11X0_CAD_PARAM_DEFAULT) { + mode = RADIOLIB_LR11X0_CAD_EXIT_MODE_STBY_RC; + } + + uint32_t timeout_raw = (float)timeout*1000 / 30.52f; + // set CAD parameters // TODO add configurable exit mode and timeout - state = setCadParams(num, peak, min, RADIOLIB_LR11X0_CAD_EXIT_MODE_STBY_RC, 0); + state = setCadParams(num, peak, min, mode, timeout_raw); RADIOLIB_ASSERT(state); // start CAD diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index dffac085f..7c05efe59 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -844,12 +844,10 @@ class LR11x0: public PhysicalLayer { /*! \brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload. - \param symbolNum Number of symbols for CAD detection. - \param detPeak Peak value for CAD detection. - \param detMin Minimum value for CAD detection. + \param config CAD configuration structure. \returns \ref status_codes */ - int16_t scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin); + int16_t scanChannel(ChannelScanConfig_t config) override; /*! \brief Sets the module to standby mode (overload for PhysicalLayer compatibility, uses 13 MHz RC oscillator). @@ -979,14 +977,12 @@ class LR11x0: public PhysicalLayer { int16_t startChannelScan() override; /*! - \brief Interrupt-driven channel activity detection method. IRQ1 will be activated + \brief Interrupt-driven channel activity detection method. DIO1 will be activated when LoRa preamble is detected, or upon timeout. - \param symbolNum Number of symbols for CAD detection. - \param detPeak Peak value for CAD detection. - \param detMin Minimum value for CAD detection. + \param config CAD configuration structure. \returns \ref status_codes */ - int16_t startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin); + int16_t startChannelScan(ChannelScanConfig_t config) override; /*! \brief Read the channel scan result @@ -1618,7 +1614,7 @@ class LR11x0: public PhysicalLayer { bool findChip(uint8_t ver); int16_t config(uint8_t modem); int16_t setPacketMode(uint8_t mode, uint8_t len); - int16_t startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin); + int16_t startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout); int16_t setHeaderType(uint8_t hdrType, size_t len = 0xFF); // common methods to avoid some copy-paste From b0f9ed6d7867516f428ce3b691b39966836cbdd3 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 18 Aug 2024 11:08:44 +0200 Subject: [PATCH 03/39] [SX126x] Added channel scan configuration --- src/modules/SX126x/SX126x.cpp | 70 ++++++++++++++++++----------------- src/modules/SX126x/SX126x.h | 15 +++----- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 1c2a9e483..04f9b00f1 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -425,12 +425,21 @@ int16_t SX126x::packetMode() { } int16_t SX126x::scanChannel() { - return(this->scanChannel(RADIOLIB_SX126X_CAD_PARAM_DEFAULT, RADIOLIB_SX126X_CAD_PARAM_DEFAULT, RADIOLIB_SX126X_CAD_PARAM_DEFAULT)); -} - -int16_t SX126x::scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { + ChannelScanConfig_t config = { + .cad = { + .symNum = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .detPeak = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .timeout = 0, + }, + }; + return(this->scanChannel(config)); +} + +int16_t SX126x::scanChannel(ChannelScanConfig_t config) { // set mode to CAD - int state = startChannelScan(symbolNum, detPeak, detMin); + int state = startChannelScan(config); RADIOLIB_ASSERT(state); // wait for channel activity detected or timeout @@ -732,10 +741,19 @@ int16_t SX126x::readData(uint8_t* data, size_t len) { } int16_t SX126x::startChannelScan() { - return(this->startChannelScan(RADIOLIB_SX126X_CAD_PARAM_DEFAULT, RADIOLIB_SX126X_CAD_PARAM_DEFAULT, RADIOLIB_SX126X_CAD_PARAM_DEFAULT)); -} - -int16_t SX126x::startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { + ChannelScanConfig_t config = { + .cad = { + .symNum = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .detPeak = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .timeout = 0, + }, + }; + return(this->startChannelScan(config)); +} + +int16_t SX126x::startChannelScan(ChannelScanConfig_t config) { // check active modem if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) { return(RADIOLIB_ERR_WRONG_MODEM); @@ -757,7 +775,7 @@ int16_t SX126x::startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t det RADIOLIB_ASSERT(state); // set mode to CAD - state = setCad(symbolNum, detPeak, detMin); + state = setCad(config.cad.symNum, config.cad.detPeak, config.cad.detMin, config.cad.exitMode, config.cad.timeout); return(state); } @@ -1761,8 +1779,7 @@ int16_t SX126x::setRx(uint32_t timeout) { return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_RX, data, 3, true, false)); } - -int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { +int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout) { // default CAD parameters are shown in Semtech AN1200.48, page 41. const uint8_t detPeakValues[6] = { 22, 22, 24, 25, 26, 30}; @@ -1773,29 +1790,17 @@ int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { this->spreadingFactor = 12; } - // build the packet + // build the packet with default configuration uint8_t data[7]; data[0] = RADIOLIB_SX126X_CAD_ON_2_SYMB; data[1] = detPeakValues[this->spreadingFactor - 7]; data[2] = RADIOLIB_SX126X_CAD_PARAM_DET_MIN; data[3] = RADIOLIB_SX126X_CAD_GOTO_STDBY; - data[4] = 0x00; - data[5] = 0x00; - data[6] = 0x00; - + uint32_t timeout_raw = (float)timeout*1000 / 15.625f; + data[4] = (uint8_t)((timeout_raw >> 16) & 0xFF); + data[5] = (uint8_t)((timeout_raw >> 8) & 0xFF); + data[6] = (uint8_t)(timeout_raw & 0xFF); - /* - CAD Configuration Note: - The default CAD configuration applied by `scanChannel` overrides the optimal SF-specific configurations, leading to suboptimal detection. - I.e., anything that is not RADIOLIB_SX126X_CAD_PARAM_DEFAULT is overridden. But CAD settings are SF specific. - To address this, the user override has been commented out, ensuring consistent application of the optimal CAD settings as - per Semtech's Application Note AN1200.48 (page 41) for the 125KHz setting. This approach significantly reduces false CAD occurrences. - Testing has shown that there is no reason for a user to change CAD settings for anything other than most optimal ones described in AN1200.48 . - However, this change does not respect CAD configs from the LoRaWAN layer. Future considerations or use cases might require revisiting this decision. - Hence this note. -*/ - -/* // set user-provided values if(symbolNum != RADIOLIB_SX126X_CAD_PARAM_DEFAULT) { data[0] = symbolNum; @@ -1809,10 +1814,9 @@ int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) { data[2] = detMin; } -*/ - (void)symbolNum; - (void)detPeak; - (void)detMin; + if(exitMode != RADIOLIB_SX126X_CAD_PARAM_DEFAULT) { + data[3] = exitMode; + } // configure parameters int16_t state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_CAD_PARAMS, data, 7); diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index 68598650c..d2fd43579 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -533,18 +533,17 @@ class SX126x: public PhysicalLayer { /*! \brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload. + Configuration defaults to the values recommended by AN1200.48. \returns \ref status_codes */ int16_t scanChannel() override; /*! \brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload. - \param symbolNum Number of symbols for CAD detection. Defaults to the value recommended by AN1200.48. - \param detPeak Peak value for CAD detection. Defaults to the value recommended by AN1200.48. - \param detMin Minimum value for CAD detection. Defaults to the value recommended by AN1200.48. + \param config CAD configuration structure. \returns \ref status_codes */ - int16_t scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin); + int16_t scanChannel(ChannelScanConfig_t config) override; /*! \brief Sets the module to sleep mode. To wake the device up, call standby(). @@ -717,12 +716,10 @@ class SX126x: public PhysicalLayer { /*! \brief Interrupt-driven channel activity detection method. DIO1 will be activated when LoRa preamble is detected, or upon timeout. - \param symbolNum Number of symbols for CAD detection. - \param detPeak Peak value for CAD detection. - \param detMin Minimum value for CAD detection. + \param config CAD configuration structure. \returns \ref status_codes */ - int16_t startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin); + int16_t startChannelScan(ChannelScanConfig_t config) override; /*! \brief Read the channel scan result @@ -1160,7 +1157,7 @@ class SX126x: public PhysicalLayer { int16_t setFs(); int16_t setTx(uint32_t timeout = 0); int16_t setRx(uint32_t timeout); - int16_t setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin); + int16_t setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout); int16_t writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes); int16_t readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes); int16_t writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00); From 5a040071874d13dfb3f9e60ce1d800d50893874d Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 18 Aug 2024 11:09:15 +0200 Subject: [PATCH 04/39] [SX128x] Added channel scan configuration --- src/modules/SX128x/SX128x.cpp | 29 ++++++++++++++++++++++++++--- src/modules/SX128x/SX128x.h | 20 ++++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/modules/SX128x/SX128x.cpp b/src/modules/SX128x/SX128x.cpp index fb9ed3283..d2c7229c3 100644 --- a/src/modules/SX128x/SX128x.cpp +++ b/src/modules/SX128x/SX128x.cpp @@ -411,8 +411,17 @@ int16_t SX128x::receiveDirect() { } int16_t SX128x::scanChannel() { + ChannelScanConfig_t config = { + .cad = { + .symNum = RADIOLIB_SX128X_CAD_PARAM_DEFAULT, + }, + }; + return(this->scanChannel(config)); +} + +int16_t SX128x::scanChannel(ChannelScanConfig_t config) { // set mode to CAD - int16_t state = startChannelScan(); + int16_t state = startChannelScan(config); RADIOLIB_ASSERT(state); // wait for channel activity detected or timeout @@ -668,6 +677,15 @@ int16_t SX128x::checkIrq(uint8_t irq) { } int16_t SX128x::startChannelScan() { + ChannelScanConfig_t config = { + .cad = { + .symNum = RADIOLIB_SX128X_CAD_PARAM_DEFAULT, + }, + }; + return(this->startChannelScan(config)); +} + +int16_t SX128x::startChannelScan(ChannelScanConfig_t config) { // check active modem if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) { return(RADIOLIB_ERR_WRONG_MODEM); @@ -689,7 +707,7 @@ int16_t SX128x::startChannelScan() { this->mod->setRfSwitchState(Module::MODE_RX); // set mode to CAD - return(setCad()); + return(setCad(config.cad.symNum)); } int16_t SX128x::getChannelScanResult() { @@ -1464,7 +1482,12 @@ int16_t SX128x::setRx(uint16_t periodBaseCount, uint8_t periodBase) { return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_RX, data, 3)); } -int16_t SX128x::setCad() { +int16_t SX128x::setCad(uint8_t symbolNum) { + // configure parameters + int16_t state = this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_CAD_PARAMS, &symbolNum, 1); + RADIOLIB_ASSERT(state); + + // start CAD return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_CAD, NULL, 0)); } diff --git a/src/modules/SX128x/SX128x.h b/src/modules/SX128x/SX128x.h index 43c1f4128..f9b590a25 100644 --- a/src/modules/SX128x/SX128x.h +++ b/src/modules/SX128x/SX128x.h @@ -186,6 +186,7 @@ #define RADIOLIB_SX128X_CAD_ON_4_SYMB 0x40 // 7 0 4 #define RADIOLIB_SX128X_CAD_ON_8_SYMB 0x60 // 7 0 8 #define RADIOLIB_SX128X_CAD_ON_16_SYMB 0x80 // 7 0 16 +#define RADIOLIB_SX128X_CAD_PARAM_DEFAULT RADIOLIB_SX128X_CAD_ON_8_SYMB //RADIOLIB_SX128X_CMD_SET_MODULATION_PARAMS #define RADIOLIB_SX128X_BLE_GFSK_BR_2_000_BW_2_4 0x04 // 7 0 GFSK/BLE bit rate and bandwidth setting: 2.0 Mbps 2.4 MHz @@ -457,6 +458,13 @@ class SX128x: public PhysicalLayer { */ int16_t scanChannel() override; + /*! + \brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload. + \param config CAD configuration structure. + \returns \ref status_codes + */ + int16_t scanChannel(ChannelScanConfig_t config) override; + /*! \brief Sets the module to sleep mode. To wake the device up, call standby(). Overload for PhysicalLayer compatibility. @@ -584,11 +592,19 @@ class SX128x: public PhysicalLayer { /*! \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. + when LoRa preamble is detected, or upon timeout. \returns \ref status_codes */ int16_t startChannelScan() override; + /*! + \brief Interrupt-driven channel activity detection method. DIO1 will be activated + when LoRa preamble is detected, or upon timeout. + \param config CAD configuration structure. + \returns \ref status_codes + */ + int16_t startChannelScan(ChannelScanConfig_t config) override; + /*! \brief Read the channel scan result \returns \ref status_codes @@ -837,7 +853,7 @@ class SX128x: public PhysicalLayer { int16_t readBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00); int16_t setTx(uint16_t periodBaseCount = RADIOLIB_SX128X_TX_TIMEOUT_NONE, uint8_t periodBase = RADIOLIB_SX128X_PERIOD_BASE_15_625_US); int16_t setRx(uint16_t periodBaseCount, uint8_t periodBase = RADIOLIB_SX128X_PERIOD_BASE_15_625_US); - int16_t setCad(); + int16_t setCad(uint8_t symbolNum); uint8_t getPacketType(); int16_t setRfFrequency(uint32_t frf); int16_t setTxParams(uint8_t pwr, uint8_t rampTime = RADIOLIB_SX128X_PA_RAMP_10_US); From f2d005ce9e67fa02a316e3bdb4714bddd70cae9f Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 18 Aug 2024 17:36:59 +0200 Subject: [PATCH 05/39] Use microsecond timeout --- src/modules/LR11x0/LR11x0.cpp | 2 +- src/modules/SX126x/SX126x.cpp | 2 +- src/protocols/PhysicalLayer/PhysicalLayer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index 35a4c4dba..3b52fd9b6 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -2057,7 +2057,7 @@ int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uin mode = RADIOLIB_LR11X0_CAD_EXIT_MODE_STBY_RC; } - uint32_t timeout_raw = (float)timeout*1000 / 30.52f; + uint32_t timeout_raw = (float)timeout / 30.52f; // set CAD parameters // TODO add configurable exit mode and timeout diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 04f9b00f1..952a3a184 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -1796,7 +1796,7 @@ int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8 data[1] = detPeakValues[this->spreadingFactor - 7]; data[2] = RADIOLIB_SX126X_CAD_PARAM_DET_MIN; data[3] = RADIOLIB_SX126X_CAD_GOTO_STDBY; - uint32_t timeout_raw = (float)timeout*1000 / 15.625f; + uint32_t timeout_raw = (float)timeout / 15.625f; data[4] = (uint8_t)((timeout_raw >> 16) & 0xFF); data[5] = (uint8_t)((timeout_raw >> 8) & 0xFF); data[6] = (uint8_t)(timeout_raw & 0xFF); diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.h b/src/protocols/PhysicalLayer/PhysicalLayer.h index fc94a6682..27e8b116f 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -72,7 +72,7 @@ struct CADScanConfig_t { /*! \brief Exit mode after signal detection is complete - module-specific value */ uint8_t exitMode; - /*! \brief Timeout in milliseconds */ + /*! \brief Timeout in microseconds */ RadioLibTime_t timeout; }; From 02b92fd8eb6cb4e2fa7164e98d1db17989b9c529 Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:32:47 +0200 Subject: [PATCH 06/39] [PHY] Added generalized IRQ handling via PHY --- src/protocols/PhysicalLayer/PhysicalLayer.cpp | 35 ++++++++++++- src/protocols/PhysicalLayer/PhysicalLayer.h | 52 +++++++++++++++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.cpp b/src/protocols/PhysicalLayer/PhysicalLayer.cpp index 4949ddbdd..85885cc09 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.cpp +++ b/src/protocols/PhysicalLayer/PhysicalLayer.cpp @@ -316,7 +316,40 @@ int16_t PhysicalLayer::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) return(RADIOLIB_ERR_UNSUPPORTED); } -int16_t PhysicalLayer::checkIrq(uint8_t irq) { +int16_t PhysicalLayer::checkIrq(RadioIrqFlags_t irq) { + if((irq > RADIOLIB_IRQ_TIMEOUT) || (this->irqMap[irq] == RADIOLIB_IRQ_NOT_SUPPORTED)) { + return(RADIOLIB_ERR_UNSUPPORTED); + } + + return(getIrqFlags() & this->irqMap[irq]); +} + +int16_t PhysicalLayer::setIrq(RadioIrqFlags_t irq) { + if((irq > RADIOLIB_IRQ_TIMEOUT) || (this->irqMap[irq] == RADIOLIB_IRQ_NOT_SUPPORTED)) { + return(RADIOLIB_ERR_UNSUPPORTED); + } + + return(setIrqFlags(this->irqMap[irq])); +} + +int16_t PhysicalLayer::clearIrq(RadioIrqFlags_t irq) { + if((irq > RADIOLIB_IRQ_TIMEOUT) || (this->irqMap[irq] == RADIOLIB_IRQ_NOT_SUPPORTED)) { + return(RADIOLIB_ERR_UNSUPPORTED); + } + + return(clearIrqFlags(this->irqMap[irq])); +} + +uint32_t PhysicalLayer::getIrqFlags() { + return(RADIOLIB_ERR_UNSUPPORTED); +} + +int16_t PhysicalLayer::setIrqFlags(RadioIrqFlags_t irq) { + (void)irq; + return(RADIOLIB_ERR_UNSUPPORTED); +} + +int16_t PhysicalLayer::clearIrqFlags(RadioIrqFlags_t irq) { (void)irq; return(RADIOLIB_ERR_UNSUPPORTED); } diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.h b/src/protocols/PhysicalLayer/PhysicalLayer.h index 27e8b116f..42fb22735 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -15,6 +15,7 @@ #define RADIOLIB_IRQ_CAD_DONE 0x07 #define RADIOLIB_IRQ_CAD_DETECTED 0x08 #define RADIOLIB_IRQ_TIMEOUT 0x09 +#define RADIOLIB_IRQ_NOT_SUPPORTED 0xFF /*! \struct LoRaRate_t @@ -39,7 +40,7 @@ struct FSKRate_t { /*! \brief FSK bit rate in kbps */ float bitRate; - /*! \brief FS frequency deviation in kHz*/ + /*! \brief FSK frequency deviation in kHz */ float freqDev; }; @@ -74,6 +75,9 @@ struct CADScanConfig_t { /*! \brief Timeout in microseconds */ RadioLibTime_t timeout; + + /*! \brief Optional IRQ flags to set, one of RADIOLIB_IRQ_ */ + RadioIrqFlags_t irqFlags; }; /*! @@ -417,9 +421,49 @@ class PhysicalLayer { /*! \brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone). - \returns Whether requested IRQ is set. + \param irq Flags to check, one of RADIOLIB_IRQ_*. + \returns 1 when requested IRQ is set, 0 when it is not or RADIOLIB_ERR_UNSUPPORTED if the IRQ is not supported. + */ + int16_t checkIrq(RadioIrqFlags_t irq); + + /*! + \brief Set interrupt on specific IRQ bit(s) (e.g. RxTimeout, CadDone). + Keep in mind that not all radio modules support all RADIOLIB_IRQ_ flags! + \param irq Flags to set, one of RADIOLIB_IRQ_*. + \returns \ref status_codes + */ + int16_t setIrq(RadioIrqFlags_t irq); + + /*! + \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). + Keep in mind that not all radio modules support all RADIOLIB_IRQ_ flags! + \param irq Flags to clear, one of RADIOLIB_IRQ_*. + \returns \ref status_codes + */ + int16_t clearIrq(RadioIrqFlags_t irq); + + /*! + \brief Read currently active IRQ flags. + Must be implemented in module class. + \returns IRQ flags. + */ + virtual uint32_t getIrqFlags(); + + /*! + \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). + Must be implemented in module class. + \param irq Module-specific IRQ flags. + \returns \ref status_codes */ - virtual int16_t checkIrq(uint8_t irq); + virtual int16_t setIrqFlags(uint32_t irq); + + /*! + \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). + Must be implemented in module class. + \param irq Module-specific IRQ flags. + \returns \ref status_codes + */ + virtual int16_t clearIrqFlags(uint32_t irq); /*! \brief Interrupt-driven channel activity detection method. Interrupt will be activated @@ -590,6 +634,8 @@ class PhysicalLayer { #if !RADIOLIB_GODMODE protected: #endif + uint32_t irqMap[10]; + #if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE void updateDirectBuffer(uint8_t bit); #endif From d75e286aa553d51485f803ba8ff3fe59a07466d8 Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:34:05 +0200 Subject: [PATCH 07/39] [LR11x0] Added generalized IRQ handling via PHY --- src/modules/LR11x0/LR11x0.cpp | 52 ++++++++++++++++------------------- src/modules/LR11x0/LR11x0.h | 20 ++++++++++++-- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index 3b52fd9b6..f4b2e3d7e 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -11,6 +11,16 @@ LR11x0::LR11x0(Module* mod) : PhysicalLayer(RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE, RADIOLIB_LR11X0_MAX_PACKET_LENGTH) { this->mod = mod; this->XTAL = false; + this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_LR11X0_IRQ_TX_DONE; + this->irqMap[RADIOLIB_IRQ_RX_DONE] = RADIOLIB_LR11X0_IRQ_RX_DONE; + this->irqMap[RADIOLIB_IRQ_PREAMBLE_DETECTED] = RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED; + this->irqMap[RADIOLIB_IRQ_SYNC_WORD_VALID] = RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID; + this->irqMap[RADIOLIB_IRQ_HEADER_VALID] = RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID; + this->irqMap[RADIOLIB_IRQ_HEADER_ERR] = RADIOLIB_LR11X0_IRQ_HEADER_ERR; + this->irqMap[RADIOLIB_IRQ_CRC_ERR] = RADIOLIB_LR11X0_IRQ_CRC_ERR; + this->irqMap[RADIOLIB_IRQ_CAD_DONE] = RADIOLIB_LR11X0_IRQ_CAD_DONE; + this->irqMap[RADIOLIB_IRQ_CAD_DETECTED] = RADIOLIB_LR11X0_IRQ_CAD_DETECTED; + this->irqMap[RADIOLIB_IRQ_TIMEOUT] = RADIOLIB_LR11X0_IRQ_TIMEOUT; } int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage) { @@ -285,6 +295,7 @@ int16_t LR11x0::scanChannel() { .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .timeout = 0, + .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; return(this->scanChannel(config)); @@ -557,6 +568,7 @@ int16_t LR11x0::startChannelScan() { .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .timeout = 0, + .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; return(this->startChannelScan(config)); @@ -580,7 +592,8 @@ int16_t LR11x0::startChannelScan(ChannelScanConfig_t config) { this->mod->setRfSwitchState(Module::MODE_RX); // set DIO pin mapping - state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_CAD_DETECTED | RADIOLIB_LR11X0_IRQ_CAD_DONE); + uint16_t irqFlags = (config.cad.irqFlags == RADIOLIB_IRQ_NOT_SUPPORTED) ? RADIOLIB_LR11X0_IRQ_CAD_DETECTED | RADIOLIB_LR11X0_IRQ_CAD_DONE : config.cad.irqFlags; + state = setDioIrqParams(irqFlags, irqFlags); RADIOLIB_ASSERT(state); // clear interrupt flags @@ -1346,33 +1359,16 @@ int16_t LR11x0::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) { return(RADIOLIB_ERR_NONE); } -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); +uint32_t LR11x0::getIrqFlags() { + return((uint32_t)this->getIrqStatus()); +} + +int16_t LR11x0::setIrqFlags(uint32_t irq) { + return(this->setDioIrqParams(irq, irq)); +} + +int16_t LR11x0::clearIrqFlags(uint32_t irq) { + return(this->clearIrq(irq)); } uint8_t LR11x0::randomByte() { diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index 7c05efe59..93aeb65dd 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -1225,10 +1225,24 @@ class LR11x0: public PhysicalLayer { int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override; /*! - \brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone). - \returns Whether requested IRQ is set. + \brief Read currently active IRQ flags. + \returns IRQ flags. */ - int16_t checkIrq(uint8_t irq) override; + uint32_t getIrqFlags(); + + /*! + \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes + */ + int16_t setIrqFlags(uint32_t irq); + + /*! + \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes + */ + int16_t clearIrqFlags(uint32_t irq); /*! \brief Get one truly random byte from RSSI noise. From fcdc1d782ee03461a8a622d10ad6ee223a53a3db Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:36:01 +0200 Subject: [PATCH 08/39] [SX126x] Added generalized IRQ handling via PHY --- src/modules/SX126x/SX126x.cpp | 69 +++++++++++++++-------------------- src/modules/SX126x/SX126x.h | 26 ++++++++----- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 952a3a184..3ba080321 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -7,6 +7,16 @@ SX126x::SX126x(Module* mod) : PhysicalLayer(RADIOLIB_SX126X_FREQUENCY_STEP_SIZE, this->mod = mod; this->XTAL = false; this->standbyXOSC = false; + this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_SX126X_IRQ_TX_DONE; + this->irqMap[RADIOLIB_IRQ_RX_DONE] = RADIOLIB_SX126X_IRQ_RX_DONE; + this->irqMap[RADIOLIB_IRQ_PREAMBLE_DETECTED] = RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED; + this->irqMap[RADIOLIB_IRQ_SYNC_WORD_VALID] = RADIOLIB_SX126X_IRQ_SYNC_WORD_VALID; + this->irqMap[RADIOLIB_IRQ_HEADER_VALID] = RADIOLIB_SX126X_IRQ_HEADER_VALID; + this->irqMap[RADIOLIB_IRQ_HEADER_ERR] = RADIOLIB_SX126X_IRQ_HEADER_ERR; + this->irqMap[RADIOLIB_IRQ_CRC_ERR] = RADIOLIB_SX126X_IRQ_CRC_ERR; + this->irqMap[RADIOLIB_IRQ_CAD_DONE] = RADIOLIB_SX126X_IRQ_CAD_DONE; + this->irqMap[RADIOLIB_IRQ_CAD_DETECTED] = RADIOLIB_SX126X_IRQ_CAD_DETECTED; + this->irqMap[RADIOLIB_IRQ_TIMEOUT] = RADIOLIB_SX126X_IRQ_TIMEOUT; } int16_t SX126x::begin(uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) { @@ -317,7 +327,7 @@ int16_t SX126x::receive(uint8_t* data, size_t len) { } // check whether this was a timeout or not - if((getIrqStatus() & RADIOLIB_SX126X_IRQ_TIMEOUT) || softTimeout) { + if((getIrqFlags() & RADIOLIB_SX126X_IRQ_TIMEOUT) || softTimeout) { standby(); fixImplicitTimeout(); clearIrqStatus(); @@ -432,6 +442,7 @@ int16_t SX126x::scanChannel() { .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .timeout = 0, + .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; return(this->scanChannel(config)); @@ -451,7 +462,6 @@ int16_t SX126x::scanChannel(ChannelScanConfig_t config) { return(getChannelScanResult()); } - int16_t SX126x::sleep() { return(SX126x::sleep(true)); } @@ -706,14 +716,14 @@ int16_t SX126x::readData(uint8_t* data, size_t len) { // if that's the case, the first call will return "SPI command timeout error" // check the IRQ to be sure this really originated from timeout event int16_t state = this->mod->SPIcheckStream(); - if((state == RADIOLIB_ERR_SPI_CMD_TIMEOUT) && (getIrqStatus() & RADIOLIB_SX126X_IRQ_TIMEOUT)) { + if((state == RADIOLIB_ERR_SPI_CMD_TIMEOUT) && (getIrqFlags() & RADIOLIB_SX126X_IRQ_TIMEOUT)) { // this is definitely Rx timeout return(RADIOLIB_ERR_RX_TIMEOUT); } RADIOLIB_ASSERT(state); // check integrity CRC - uint16_t irq = getIrqStatus(); + uint16_t irq = getIrqFlags(); int16_t crcState = RADIOLIB_ERR_NONE; if((irq & RADIOLIB_SX126X_IRQ_CRC_ERR) || (irq & RADIOLIB_SX126X_IRQ_HEADER_ERR)) { crcState = RADIOLIB_ERR_CRC_MISMATCH; @@ -748,6 +758,7 @@ int16_t SX126x::startChannelScan() { .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .timeout = 0, + .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; return(this->startChannelScan(config)); @@ -767,7 +778,8 @@ int16_t SX126x::startChannelScan(ChannelScanConfig_t config) { this->mod->setRfSwitchState(Module::MODE_RX); // set DIO pin mapping - state = setDioIrqParams(RADIOLIB_SX126X_IRQ_CAD_DETECTED | RADIOLIB_SX126X_IRQ_CAD_DONE, RADIOLIB_SX126X_IRQ_CAD_DETECTED | RADIOLIB_SX126X_IRQ_CAD_DONE); + uint16_t irqFlags = (config.cad.irqFlags == RADIOLIB_IRQ_NOT_SUPPORTED) ? RADIOLIB_SX126X_IRQ_CAD_DETECTED | RADIOLIB_SX126X_IRQ_CAD_DONE : config.cad.irqFlags; + state = setDioIrqParams(irqFlags, irqFlags); RADIOLIB_ASSERT(state); // clear interrupt flags @@ -786,7 +798,7 @@ int16_t SX126x::getChannelScanResult() { } // check CAD result - uint16_t cadResult = getIrqStatus(); + uint16_t cadResult = getIrqFlags(); if(cadResult & RADIOLIB_SX126X_IRQ_CAD_DETECTED) { // detected some LoRa activity return(RADIOLIB_LORA_DETECTED); @@ -1484,33 +1496,18 @@ int16_t SX126x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) { return(RADIOLIB_ERR_NONE); } -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); +uint32_t SX126x::getIrqFlags() { + uint8_t data[] = { 0x00, 0x00 }; + this->mod->SPIreadStream(RADIOLIB_SX126X_CMD_GET_IRQ_STATUS, data, 2); + return(((uint32_t)(data[0]) << 8) | data[1]); +} + +int16_t SX126x::setIrqFlags(uint32_t irq) { + return(this->setDioIrqParams(irq, irq)); +} + +int16_t SX126x::clearIrqFlags(uint32_t irq) { + return(this->clearIrqStatus(irq)); } int16_t SX126x::implicitHeader(size_t len) { @@ -1863,12 +1860,6 @@ int16_t SX126x::setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t di return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_DIO_IRQ_PARAMS, data, 8)); } -uint16_t SX126x::getIrqStatus() { - uint8_t data[] = { 0x00, 0x00 }; - this->mod->SPIreadStream(RADIOLIB_SX126X_CMD_GET_IRQ_STATUS, data, 2); - return(((uint16_t)(data[0]) << 8) | data[1]); -} - int16_t SX126x::clearIrqStatus(uint16_t clearIrqParams) { uint8_t data[] = { (uint8_t)((clearIrqParams >> 8) & 0xFF), (uint8_t)(clearIrqParams & 0xFF) }; return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CLEAR_IRQ_STATUS, data, 2)); diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index d2fd43579..9bd221bf4 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -690,12 +690,6 @@ class SX126x: public PhysicalLayer { */ int16_t startReceiveDutyCycleAuto(uint16_t senderPreambleLength = 0, uint16_t minSymbols = 8, uint16_t irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT, uint16_t irqMask = RADIOLIB_SX126X_IRQ_RX_DONE); - /*! - \brief Reads the current IRQ status. - \returns IRQ status bits - */ - uint16_t getIrqStatus(); - /*! \brief Reads data received after calling startReceive method. When the packet length is not known in advance, getPacketLength method must be called BEFORE calling readData! @@ -994,10 +988,24 @@ class SX126x: public PhysicalLayer { int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override; /*! - \brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone). - \returns Whether requested IRQ is set. + \brief Read currently active IRQ flags. + \returns IRQ flags. + */ + uint32_t getIrqFlags(); + + /*! + \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes + */ + int16_t setIrqFlags(uint32_t irq); + + /*! + \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes */ - int16_t checkIrq(uint8_t irq) override; + int16_t clearIrqFlags(uint32_t irq); /*! \brief Set implicit header mode for future reception/transmission. From 7067c673046bb7720d6574987f52ae908d7470fe Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:37:12 +0200 Subject: [PATCH 09/39] [SX127x] Added generalized IRQ handling via PHY --- src/modules/SX127x/SX127x.cpp | 129 ++++++++++++++++++++++++---------- src/modules/SX127x/SX127x.h | 22 ++++-- 2 files changed, 108 insertions(+), 43 deletions(-) diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 7cc33c9fd..60b81ed73 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -12,6 +12,18 @@ int16_t SX127x::begin(uint8_t* chipVersions, uint8_t numVersions, uint8_t syncWo this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput); this->mod->hal->pinMode(this->mod->getGpio(), this->mod->hal->GpioModeInput); + // set IRQ mapping - it is different for LoRa and FSK mode + this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_SX127X_CLEAR_IRQ_FLAG_TX_DONE; + this->irqMap[RADIOLIB_IRQ_RX_DONE] = RADIOLIB_SX127X_CLEAR_IRQ_FLAG_RX_DONE; + this->irqMap[RADIOLIB_IRQ_PREAMBLE_DETECTED] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_SYNC_WORD_VALID] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_HEADER_VALID] = RADIOLIB_SX127X_CLEAR_IRQ_FLAG_VALID_HEADER; + this->irqMap[RADIOLIB_IRQ_HEADER_ERR] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_CRC_ERR] = RADIOLIB_SX127X_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR; + this->irqMap[RADIOLIB_IRQ_CAD_DONE] = RADIOLIB_SX127X_CLEAR_IRQ_FLAG_CAD_DONE; + this->irqMap[RADIOLIB_IRQ_CAD_DETECTED] = RADIOLIB_SX127X_CLEAR_IRQ_FLAG_CAD_DETECTED; + this->irqMap[RADIOLIB_IRQ_TIMEOUT] = RADIOLIB_SX127X_CLEAR_IRQ_FLAG_RX_TIMEOUT; + // try to find the SX127x chip if(!SX127x::findChip(chipVersions, numVersions)) { RADIOLIB_DEBUG_BASIC_PRINTLN("No SX127x found!"); @@ -63,6 +75,18 @@ int16_t SX127x::beginFSK(uint8_t* chipVersions, uint8_t numVersions, float freqD this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput); this->mod->hal->pinMode(this->mod->getGpio(), this->mod->hal->GpioModeInput); + // set IRQ mapping - it is different for LoRa and FSK mode + this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_SX127X_FLAG_PACKET_SENT << 8; + this->irqMap[RADIOLIB_IRQ_RX_DONE] = RADIOLIB_SX127X_FLAG_PAYLOAD_READY << 8; + this->irqMap[RADIOLIB_IRQ_PREAMBLE_DETECTED] = RADIOLIB_SX127X_FLAG_PREAMBLE_DETECT << 0; + this->irqMap[RADIOLIB_IRQ_SYNC_WORD_VALID] = RADIOLIB_SX127X_FLAG_SYNC_ADDRESS_MATCH << 0; + this->irqMap[RADIOLIB_IRQ_HEADER_VALID] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_HEADER_ERR] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_CRC_ERR] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_CAD_DONE] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_CAD_DETECTED] = RADIOLIB_IRQ_NOT_SUPPORTED; + this->irqMap[RADIOLIB_IRQ_TIMEOUT] = RADIOLIB_SX127X_FLAG_TIMEOUT << 0; + // try to find the SX127x chip if(!SX127x::findChip(chipVersions, numVersions)) { RADIOLIB_DEBUG_BASIC_PRINTLN("No SX127x found!"); @@ -211,13 +235,13 @@ int16_t SX127x::receive(uint8_t* data, size_t len) { if(this->mod->getGpio() == RADIOLIB_NC) { // no GPIO pin provided, use software timeout if(this->mod->hal->millis() - start > timeout) { - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); return(RADIOLIB_ERR_RX_TIMEOUT); } } else { // GPIO provided, use that if(this->mod->hal->digitalRead(this->mod->getGpio())) { - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); return(RADIOLIB_ERR_RX_TIMEOUT); } } @@ -237,7 +261,7 @@ int16_t SX127x::receive(uint8_t* data, size_t len) { while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); if(this->mod->hal->millis() - start > timeout) { - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); return(RADIOLIB_ERR_RX_TIMEOUT); } } @@ -389,7 +413,7 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { RADIOLIB_ERRATA_SX127X(true); // clear interrupt flags - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); // set FIFO pointers state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_RX_BASE_ADDR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX); @@ -402,7 +426,7 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { RADIOLIB_ASSERT(state); // clear interrupt flags - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); // FSK modem does not distinguish between Rx single and continuous if(mode == RADIOLIB_SX127X_RXCONTINUOUS) { @@ -571,7 +595,7 @@ int16_t SX127x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) { RADIOLIB_ERRATA_SX127X(false); // clear interrupt flags - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); // set packet length state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len); @@ -582,7 +606,7 @@ int16_t SX127x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) { } else if(modem == RADIOLIB_SX127X_FSK_OOK) { // clear interrupt flags - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); // set DIO mapping if(len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK) { @@ -628,7 +652,7 @@ int16_t SX127x::finishTransmit() { mod->hal->delayMicroseconds(1000000/1200); // clear interrupt flags - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); // set mode to standby to disable transmitter/RF switch return(standby()); @@ -686,7 +710,7 @@ int16_t SX127x::readData(uint8_t* data, size_t len) { this->packetLengthQueried = false; // clear interrupt flags - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); return(state); } @@ -702,7 +726,7 @@ int16_t SX127x::startChannelScan() { RADIOLIB_ASSERT(state); // clear interrupt flags - clearIRQFlags(); + clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); // set DIO pin mapping state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_CAD_DONE | RADIOLIB_SX127X_DIO1_LORA_CAD_DETECTED, 7, 4); @@ -1302,29 +1326,66 @@ int16_t SX127x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) { return(RADIOLIB_ERR_NONE); } -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); +uint32_t SX127x::getIrqFlags() { + return((uint32_t)this->getIRQFlags()); +} + +int16_t SX127x::setIrqFlags(uint32_t irq) { + // this is a bit convoluted, but unfortunately SX127x IRQ flags are not used to enable/disable that IRQ ... + int16_t modem = getActiveModem(); + if(modem == RADIOLIB_SX127X_LORA) { + switch(irq) { + case(RADIOLIB_SX127X_CLEAR_IRQ_FLAG_TX_DONE): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PACKET_SENT, 7, 6)); + case(RADIOLIB_SX127X_CLEAR_IRQ_FLAG_RX_DONE): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_RX_DONE, 7, 6)); + case(RADIOLIB_SX127X_CLEAR_IRQ_FLAG_VALID_HEADER): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO3_LORA_VALID_HEADER, 1, 0)); + case(RADIOLIB_SX127X_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO3_LORA_PAYLOAD_CRC_ERROR, 1, 0)); + case(RADIOLIB_SX127X_CLEAR_IRQ_FLAG_CAD_DONE): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_CAD_DONE, 7, 6)); + case(RADIOLIB_SX127X_CLEAR_IRQ_FLAG_CAD_DETECTED): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_LORA_CAD_DETECTED, 5, 4)); + case(RADIOLIB_SX127X_CLEAR_IRQ_FLAG_RX_TIMEOUT): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_LORA_RX_TIMEOUT, 5, 4)); + } + return(RADIOLIB_ERR_UNSUPPORTED); + + } else if(modem == RADIOLIB_SX127X_FSK_OOK) { + switch(irq) { + case(RADIOLIB_SX127X_FLAG_PACKET_SENT << 8): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PACKET_SENT, 7, 6)); + case(RADIOLIB_SX127X_FLAG_PAYLOAD_READY << 8): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PAYLOAD_READY, 7, 6)); + case(RADIOLIB_SX127X_FLAG_PREAMBLE_DETECT << 0): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_2, RADIOLIB_SX127X_DIO4_PACK_RSSI_PREAMBLE_DETECT, 7, 6)); + case(RADIOLIB_SX127X_FLAG_SYNC_ADDRESS_MATCH << 0): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO2_PACK_SYNC_ADDRESS, 3, 2)); + case(RADIOLIB_SX127X_FLAG_TIMEOUT << 0): + return(this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO2_PACK_TIMEOUT, 3, 2)); + } + return(RADIOLIB_ERR_UNSUPPORTED); } + return(RADIOLIB_ERR_UNSUPPORTED); } +int16_t SX127x::clearIrqFlags(uint32_t irq) { + int16_t modem = getActiveModem(); + if(modem == RADIOLIB_SX127X_LORA) { + this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, (uint8_t)irq); + return(RADIOLIB_ERR_NONE); + + } else if(modem == RADIOLIB_SX127X_FSK_OOK) { + this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_1, (uint8_t)irq); + this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, (uint8_t)(irq >> 8)); + return(RADIOLIB_ERR_NONE); + } + + return(RADIOLIB_ERR_UNKNOWN); +} + int16_t SX127x::setCrcFiltering(bool enable) { this->crcOn = enable; @@ -1619,16 +1680,6 @@ int16_t SX127x::setActiveModem(uint8_t modem) { return(state); } -void SX127x::clearIRQFlags() { - int16_t modem = getActiveModem(); - if(modem == RADIOLIB_SX127X_LORA) { - this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, 0b11111111); - } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_1, 0b11111111); - this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, 0b11111111); - } -} - void SX127x::clearFIFO(size_t count) { while(count) { this->mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO); diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index c00cd42f9..b24d20519 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -500,6 +500,7 @@ #define RADIOLIB_SX127X_FLAG_PAYLOAD_READY 0b00000100 // 2 2 packet was successfully received #define RADIOLIB_SX127X_FLAG_CRC_OK 0b00000010 // 1 1 CRC check passed #define RADIOLIB_SX127X_FLAG_LOW_BAT 0b00000001 // 0 0 battery voltage dropped below threshold +#define RADIOLIB_SX127X_FLAGS_ALL 0xFFFF // RADIOLIB_SX127X_REG_DIO_MAPPING_1 #define RADIOLIB_SX127X_DIO0_LORA_RX_DONE 0b00000000 // 7 6 @@ -1073,10 +1074,24 @@ class SX127x: public PhysicalLayer { int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override; /*! - \brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone). - \returns Whether requested IRQ is set. + \brief Read currently active IRQ flags. + \returns IRQ flags. + */ + uint32_t getIrqFlags(); + + /*! + \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes + */ + int16_t setIrqFlags(uint32_t irq); + + /*! + \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes */ - int16_t checkIrq(uint8_t irq) override; + int16_t clearIrqFlags(uint32_t irq); /*! \brief Enable CRC filtering and generation. @@ -1257,7 +1272,6 @@ class SX127x: public PhysicalLayer { bool findChip(const uint8_t* vers, uint8_t num); int16_t setMode(uint8_t mode); int16_t setActiveModem(uint8_t modem); - void clearIRQFlags(); void clearFIFO(size_t count); // used mostly to clear remaining bytes in FIFO after a packet read /*! From 8c24a5fcf57677700e31a5b167e155038e1790ff Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:37:23 +0200 Subject: [PATCH 10/39] [SX128x] Added generalized IRQ handling via PHY --- src/modules/SX128x/SX128x.cpp | 52 ++++++++++++++++------------------- src/modules/SX128x/SX128x.h | 20 ++++++++++++-- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/modules/SX128x/SX128x.cpp b/src/modules/SX128x/SX128x.cpp index d2c7229c3..45db25f93 100644 --- a/src/modules/SX128x/SX128x.cpp +++ b/src/modules/SX128x/SX128x.cpp @@ -4,6 +4,16 @@ SX128x::SX128x(Module* mod) : PhysicalLayer(RADIOLIB_SX128X_FREQUENCY_STEP_SIZE, RADIOLIB_SX128X_MAX_PACKET_LENGTH) { this->mod = mod; + this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_SX128X_IRQ_TX_DONE; + this->irqMap[RADIOLIB_IRQ_RX_DONE] = RADIOLIB_SX128X_IRQ_RX_DONE; + this->irqMap[RADIOLIB_IRQ_PREAMBLE_DETECTED] = RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED; + this->irqMap[RADIOLIB_IRQ_SYNC_WORD_VALID] = RADIOLIB_SX128X_IRQ_SYNC_WORD_VALID; + this->irqMap[RADIOLIB_IRQ_HEADER_VALID] = RADIOLIB_SX128X_IRQ_HEADER_VALID; + this->irqMap[RADIOLIB_IRQ_HEADER_ERR] = RADIOLIB_SX128X_IRQ_HEADER_ERROR; + this->irqMap[RADIOLIB_IRQ_CRC_ERR] = RADIOLIB_SX128X_IRQ_CRC_ERROR; + this->irqMap[RADIOLIB_IRQ_CAD_DONE] = RADIOLIB_SX128X_IRQ_CAD_DONE; + this->irqMap[RADIOLIB_IRQ_CAD_DETECTED] = RADIOLIB_SX128X_IRQ_CAD_DETECTED; + this->irqMap[RADIOLIB_IRQ_TIMEOUT] = RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT; } int16_t SX128x::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t pwr, uint16_t preambleLength) { @@ -414,6 +424,7 @@ int16_t SX128x::scanChannel() { ChannelScanConfig_t config = { .cad = { .symNum = RADIOLIB_SX128X_CAD_PARAM_DEFAULT, + .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; return(this->scanChannel(config)); @@ -647,39 +658,23 @@ 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); +uint32_t SX128x::getIrqFlags() { + return((uint32_t)this->getIrqStatus()); +} + +int16_t SX128x::setIrqFlags(uint32_t irq) { + return(this->setDioIrqParams(irq, irq)); +} + +int16_t SX128x::clearIrqFlags(uint32_t irq) { + return(this->clearIrqStatus(irq)); } int16_t SX128x::startChannelScan() { ChannelScanConfig_t config = { .cad = { .symNum = RADIOLIB_SX128X_CAD_PARAM_DEFAULT, + .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; return(this->startChannelScan(config)); @@ -696,7 +691,8 @@ int16_t SX128x::startChannelScan(ChannelScanConfig_t config) { RADIOLIB_ASSERT(state); // set DIO pin mapping - state = setDioIrqParams(RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE, RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE); + uint16_t irqFlags = (config.cad.irqFlags == RADIOLIB_IRQ_NOT_SUPPORTED) ? RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE : config.cad.irqFlags; + state = setDioIrqParams(irqFlags, irqFlags); RADIOLIB_ASSERT(state); // clear interrupt flags diff --git a/src/modules/SX128x/SX128x.h b/src/modules/SX128x/SX128x.h index f9b590a25..05755297d 100644 --- a/src/modules/SX128x/SX128x.h +++ b/src/modules/SX128x/SX128x.h @@ -585,10 +585,24 @@ 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. + \brief Read currently active IRQ flags. + \returns IRQ flags. */ - int16_t checkIrq(uint8_t irq) override; + uint32_t getIrqFlags(); + + /*! + \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes + */ + int16_t setIrqFlags(uint32_t irq); + + /*! + \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). + \param irq Module-specific IRQ flags. + \returns \ref status_codes + */ + int16_t clearIrqFlags(uint32_t irq); /*! \brief Interrupt-driven channel activity detection method. DIO1 will be activated From d1803bcc49402aab168994db5d7160cb14b15da1 Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:38:49 +0200 Subject: [PATCH 11/39] Added missing typedef --- src/TypeDef.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/TypeDef.h b/src/TypeDef.h index 55434cf12..17ff288e6 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -615,6 +615,11 @@ */ typedef unsigned long RadioLibTime_t; +/*! + \brief Type used for radio-agnostic IRQ flags. +*/ +typedef uint8_t RadioIrqFlags_t; + /*! \} */ From 25458860e3d7a5a4cde2623f067ec4412db22bcb Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:44:34 +0200 Subject: [PATCH 12/39] [PHY] Fix IRQ method argument type --- src/protocols/PhysicalLayer/PhysicalLayer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.cpp b/src/protocols/PhysicalLayer/PhysicalLayer.cpp index 85885cc09..7d67614d6 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.cpp +++ b/src/protocols/PhysicalLayer/PhysicalLayer.cpp @@ -344,12 +344,12 @@ uint32_t PhysicalLayer::getIrqFlags() { return(RADIOLIB_ERR_UNSUPPORTED); } -int16_t PhysicalLayer::setIrqFlags(RadioIrqFlags_t irq) { +int16_t PhysicalLayer::setIrqFlags(uint32_t irq) { (void)irq; return(RADIOLIB_ERR_UNSUPPORTED); } -int16_t PhysicalLayer::clearIrqFlags(RadioIrqFlags_t irq) { +int16_t PhysicalLayer::clearIrqFlags(uint32_t irq) { (void)irq; return(RADIOLIB_ERR_UNSUPPORTED); } From bac67910669c82b03f945c6e7609de6c4c019293 Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:45:48 +0200 Subject: [PATCH 13/39] [SX128x] Fix non-trivial initializer usage --- src/modules/SX128x/SX128x.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/SX128x/SX128x.cpp b/src/modules/SX128x/SX128x.cpp index 45db25f93..7fae67122 100644 --- a/src/modules/SX128x/SX128x.cpp +++ b/src/modules/SX128x/SX128x.cpp @@ -424,6 +424,10 @@ int16_t SX128x::scanChannel() { ChannelScanConfig_t config = { .cad = { .symNum = RADIOLIB_SX128X_CAD_PARAM_DEFAULT, + .detPeak = 0, + .detMin = 0, + .exitMode = 0, + .timeout = 0, .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; @@ -674,6 +678,10 @@ int16_t SX128x::startChannelScan() { ChannelScanConfig_t config = { .cad = { .symNum = RADIOLIB_SX128X_CAD_PARAM_DEFAULT, + .detPeak = 0, + .detMin = 0, + .exitMode = 0, + .timeout = 0, .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, }, }; From 76096ef29e30a5ef0bec5cda946486d37a397034 Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:50:50 +0200 Subject: [PATCH 14/39] [LR11x0] Added missing override specifiers --- src/modules/LR11x0/LR11x0.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index 93aeb65dd..95c7c363a 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -1228,21 +1228,21 @@ class LR11x0: public PhysicalLayer { \brief Read currently active IRQ flags. \returns IRQ flags. */ - uint32_t getIrqFlags(); + uint32_t getIrqFlags() override; /*! \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t setIrqFlags(uint32_t irq); + int16_t setIrqFlags(uint32_t irq) override; /*! \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t clearIrqFlags(uint32_t irq); + int16_t clearIrqFlags(uint32_t irq) override; /*! \brief Get one truly random byte from RSSI noise. From 21bf99cfe63b4d8d7056d2c7a416838c81ea2607 Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:51:00 +0200 Subject: [PATCH 15/39] [SX126x] Added missing override specifiers --- src/modules/SX126x/SX126x.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index 9bd221bf4..99ca688f0 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -991,21 +991,21 @@ class SX126x: public PhysicalLayer { \brief Read currently active IRQ flags. \returns IRQ flags. */ - uint32_t getIrqFlags(); + uint32_t getIrqFlags() override; /*! \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t setIrqFlags(uint32_t irq); + int16_t setIrqFlags(uint32_t irq) override; /*! \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t clearIrqFlags(uint32_t irq); + int16_t clearIrqFlags(uint32_t irq) override; /*! \brief Set implicit header mode for future reception/transmission. From 28f404a23769f0bcd59d7ea61821e47d0541218a Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:51:06 +0200 Subject: [PATCH 16/39] [SX127x] Added missing override specifiers --- src/modules/SX127x/SX127x.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index b24d20519..e89cdfd47 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -1077,21 +1077,21 @@ class SX127x: public PhysicalLayer { \brief Read currently active IRQ flags. \returns IRQ flags. */ - uint32_t getIrqFlags(); + uint32_t getIrqFlags() override; /*! \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t setIrqFlags(uint32_t irq); + int16_t setIrqFlags(uint32_t irq) override; /*! \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t clearIrqFlags(uint32_t irq); + int16_t clearIrqFlags(uint32_t irq) override; /*! \brief Enable CRC filtering and generation. From 77241d29df17d4031af97334b9af25b182808301 Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:51:12 +0200 Subject: [PATCH 17/39] [SX128x] Added missing override specifiers --- src/modules/SX128x/SX128x.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/SX128x/SX128x.h b/src/modules/SX128x/SX128x.h index 05755297d..cadc7909e 100644 --- a/src/modules/SX128x/SX128x.h +++ b/src/modules/SX128x/SX128x.h @@ -588,21 +588,21 @@ class SX128x: public PhysicalLayer { \brief Read currently active IRQ flags. \returns IRQ flags. */ - uint32_t getIrqFlags(); + uint32_t getIrqFlags() override; /*! \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t setIrqFlags(uint32_t irq); + int16_t setIrqFlags(uint32_t irq) override; /*! \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */ - int16_t clearIrqFlags(uint32_t irq); + int16_t clearIrqFlags(uint32_t irq) override; /*! \brief Interrupt-driven channel activity detection method. DIO1 will be activated From 44c474219f0608bd42ef86d4136939d102e91c3e Mon Sep 17 00:00:00 2001 From: jgromes Date: Tue, 20 Aug 2024 20:55:45 +0200 Subject: [PATCH 18/39] [PHY] Added missing IRQ map initializer --- src/protocols/PhysicalLayer/PhysicalLayer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.h b/src/protocols/PhysicalLayer/PhysicalLayer.h index 42fb22735..82a2b57b0 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -634,7 +634,7 @@ class PhysicalLayer { #if !RADIOLIB_GODMODE protected: #endif - uint32_t irqMap[10]; + uint32_t irqMap[10] = { 0 }; #if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE void updateDirectBuffer(uint8_t bit); From 4f3c7d449f87512f01f607f341d3338b0760a913 Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 21 Aug 2024 19:33:47 +0200 Subject: [PATCH 19/39] [CI] Drop APRS builds on AVR --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e2635a8bf..5ec735722 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,7 +46,7 @@ jobs: # platform-dependent settings - extra board options, board index URLs, skip patterns etc. include: - id: arduino:avr:uno - run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update|Pager)" >> $GITHUB_OUTPUT + run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update|Pager|APRS)" >> $GITHUB_OUTPUT - id: arduino:avr:mega run: | echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT From b9ffbb1f0649e8041dedad1038b95118c5b0785e Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:09:23 +0200 Subject: [PATCH 20/39] [CI] Drop Morse builds for AVR --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5ec735722..063f259ed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,7 +46,7 @@ jobs: # platform-dependent settings - extra board options, board index URLs, skip patterns etc. include: - id: arduino:avr:uno - run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update|Pager|APRS)" >> $GITHUB_OUTPUT + run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update|Pager|APRS|Morse)" >> $GITHUB_OUTPUT - id: arduino:avr:mega run: | echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT From 644d0ecef8aebeb08c61dcd623f0eb3931fef62e Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:10:43 +0200 Subject: [PATCH 21/39] [PHY] Rework generic IRQ to allow multiple flags --- src/protocols/PhysicalLayer/PhysicalLayer.cpp | 34 +++++----- src/protocols/PhysicalLayer/PhysicalLayer.h | 68 +++++++++++-------- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.cpp b/src/protocols/PhysicalLayer/PhysicalLayer.cpp index 7d67614d6..a5cb9cfa3 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.cpp +++ b/src/protocols/PhysicalLayer/PhysicalLayer.cpp @@ -132,7 +132,7 @@ int16_t PhysicalLayer::startReceive() { return(RADIOLIB_ERR_UNSUPPORTED); } -int16_t PhysicalLayer::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) { +int16_t PhysicalLayer::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { (void)timeout; (void)irqFlags; (void)irqMask; @@ -310,13 +310,19 @@ RadioLibTime_t PhysicalLayer::calculateRxTimeout(RadioLibTime_t timeoutUs) { return(0); } -int16_t PhysicalLayer::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) { - (void)irqFlags; - (void)irqMask; - return(RADIOLIB_ERR_UNSUPPORTED); +uint32_t PhysicalLayer::getIrqMapped(RadioLibIrqFlags_t irq) { + // iterate over all set bits and build the module-specific flags + uint32_t irqRaw = 0; + for(uint8_t i = 0; i < 8*(sizeof(RadioLibIrqFlags_t)); i++) { + if((irq & (uint32_t)(1UL << i)) && (this->irqMap[i] != RADIOLIB_IRQ_NOT_SUPPORTED)) { + irqRaw |= this->irqMap[i]; + } + } + + return(irqRaw); } -int16_t PhysicalLayer::checkIrq(RadioIrqFlags_t irq) { +int16_t PhysicalLayer::checkIrq(RadioLibIrqType_t irq) { if((irq > RADIOLIB_IRQ_TIMEOUT) || (this->irqMap[irq] == RADIOLIB_IRQ_NOT_SUPPORTED)) { return(RADIOLIB_ERR_UNSUPPORTED); } @@ -324,20 +330,12 @@ int16_t PhysicalLayer::checkIrq(RadioIrqFlags_t irq) { return(getIrqFlags() & this->irqMap[irq]); } -int16_t PhysicalLayer::setIrq(RadioIrqFlags_t irq) { - if((irq > RADIOLIB_IRQ_TIMEOUT) || (this->irqMap[irq] == RADIOLIB_IRQ_NOT_SUPPORTED)) { - return(RADIOLIB_ERR_UNSUPPORTED); - } - - return(setIrqFlags(this->irqMap[irq])); +int16_t PhysicalLayer::setIrq(RadioLibIrqFlags_t irq) { + return(setIrqFlags(getIrqMapped(irq))); } -int16_t PhysicalLayer::clearIrq(RadioIrqFlags_t irq) { - if((irq > RADIOLIB_IRQ_TIMEOUT) || (this->irqMap[irq] == RADIOLIB_IRQ_NOT_SUPPORTED)) { - return(RADIOLIB_ERR_UNSUPPORTED); - } - - return(clearIrqFlags(this->irqMap[irq])); +int16_t PhysicalLayer::clearIrq(RadioLibIrqFlags_t irq) { + return(clearIrqFlags(getIrqMapped(irq))); } uint32_t PhysicalLayer::getIrqFlags() { diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.h b/src/protocols/PhysicalLayer/PhysicalLayer.h index 82a2b57b0..3e2dedd67 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -4,18 +4,26 @@ #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 -#define RADIOLIB_IRQ_NOT_SUPPORTED 0xFF +// common IRQ values - the IRQ flags in RadioLibIrqFlags_t arguments are offset by this value +enum RadioLibIrqType_t { + RADIOLIB_IRQ_TX_DONE = 0x00, + RADIOLIB_IRQ_RX_DONE = 0x01, + RADIOLIB_IRQ_PREAMBLE_DETECTED = 0x02, + RADIOLIB_IRQ_SYNC_WORD_VALID = 0x03, + RADIOLIB_IRQ_HEADER_VALID = 0x04, + RADIOLIB_IRQ_HEADER_ERR = 0x05, + RADIOLIB_IRQ_CRC_ERR = 0x06, + RADIOLIB_IRQ_CAD_DONE = 0x07, + RADIOLIB_IRQ_CAD_DETECTED = 0x08, + RADIOLIB_IRQ_TIMEOUT = 0x09, + RADIOLIB_IRQ_NOT_SUPPORTED = 0x1F, // this must be the last value, intentionally set to 31 +}; + +// some commonly used default values - defined here to ensure all modules have the same default behavior +#define RADIOLIB_IRQ_RX_DEFAULT_FLAGS ((1UL << RADIOLIB_IRQ_RX_DONE) | (1UL << RADIOLIB_IRQ_TIMEOUT) | (1UL << RADIOLIB_IRQ_CRC_ERR) | (1UL << RADIOLIB_IRQ_HEADER_ERR)) +#define RADIOLIB_IRQ_RX_DEFAULT_MASK ((1UL << RADIOLIB_IRQ_RX_DONE)) +#define RADIOLIB_IRQ_CAD_DEFAULT_FLAGS ((1UL << RADIOLIB_IRQ_CAD_DETECTED) | (1UL << RADIOLIB_IRQ_CAD_DONE)) +#define RADIOLIB_IRQ_CAD_DEFAULT_MASK ((1UL << RADIOLIB_IRQ_CAD_DETECTED) | (1UL << RADIOLIB_IRQ_CAD_DONE)) /*! \struct LoRaRate_t @@ -76,8 +84,11 @@ struct CADScanConfig_t { /*! \brief Timeout in microseconds */ RadioLibTime_t timeout; - /*! \brief Optional IRQ flags to set, one of RADIOLIB_IRQ_ */ - RadioIrqFlags_t irqFlags; + /*! \brief Optional IRQ flags to set, bits offset by the value of RADIOLIB_IRQ_ */ + RadioLibIrqFlags_t irqFlags; + + /*! \brief Optional IRQ mask to set, bits offset by the value of RADIOLIB_IRQ_ */ + RadioLibIrqFlags_t irqMask; }; /*! @@ -198,16 +209,16 @@ class PhysicalLayer { \param timeout Raw timeout value. Some modules use this argument to specify operation mode (single vs. continuous receive). \param irqFlags Sets the IRQ flags. - \param irqMask Sets the mask of IRQ flags that will trigger the DIO pin. + \param irqMask Sets the mask of IRQ flags that will trigger the radio interrupt pin. \param len Packet length, needed for some modules under special circumstances (e.g. LoRa implicit header mode). \returns \ref status_codes */ - virtual int16_t startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len); + virtual int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len); /*! \brief Binary receive method. Must be implemented in module class. \param data Pointer to array to save the received binary data. - \param len Number of bytes that will be received. Must be known in advance for binary transmissions. + \param len Packet length, needed for some modules under special circumstances (e.g. LoRa implicit header mode). \returns \ref status_codes */ virtual int16_t receive(uint8_t* data, size_t len); @@ -412,35 +423,36 @@ class PhysicalLayer { 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. - \returns \ref status_codes + \brief Convert from radio-agnostic IRQ flags to radio-specific flags. + \param irq Radio-agnostic IRQ flags. + \returns Flags for a specific radio module. */ - virtual int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask); + uint32_t getIrqMapped(RadioLibIrqFlags_t irq); /*! \brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone). - \param irq Flags to check, one of RADIOLIB_IRQ_*. + \param irq IRQ type to check, one of RADIOLIB_IRQ_*. \returns 1 when requested IRQ is set, 0 when it is not or RADIOLIB_ERR_UNSUPPORTED if the IRQ is not supported. */ - int16_t checkIrq(RadioIrqFlags_t irq); + int16_t checkIrq(RadioLibIrqType_t irq); /*! \brief Set interrupt on specific IRQ bit(s) (e.g. RxTimeout, CadDone). Keep in mind that not all radio modules support all RADIOLIB_IRQ_ flags! - \param irq Flags to set, one of RADIOLIB_IRQ_*. + \param irq Flags to set, multiple bits may be enabled. IRQ to enable corresponds to the bit index (RadioLibIrq_t). + For example, if bit 0 is enabled, the module will enable its RADIOLIB_IRQ_TX_DONE (if it is supported). \returns \ref status_codes */ - int16_t setIrq(RadioIrqFlags_t irq); + int16_t setIrq(RadioLibIrqFlags_t irq); /*! \brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone). Keep in mind that not all radio modules support all RADIOLIB_IRQ_ flags! - \param irq Flags to clear, one of RADIOLIB_IRQ_*. + \param irq Flags to set, multiple bits may be enabled. IRQ to enable corresponds to the bit index (RadioLibIrq_t). + For example, if bit 0 is enabled, the module will enable its RADIOLIB_IRQ_TX_DONE (if it is supported). \returns \ref status_codes */ - int16_t clearIrq(RadioIrqFlags_t irq); + int16_t clearIrq(RadioLibIrqFlags_t irq); /*! \brief Read currently active IRQ flags. From ef5ee1f08949ff56f13c3156a7e6d40da16592d4 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:12:03 +0200 Subject: [PATCH 22/39] [LR11x0] Rework generic IRQ to allow multiple flags --- src/modules/LR11x0/LR11x0.cpp | 11 ++--------- src/modules/LR11x0/LR11x0.h | 8 -------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index f4b2e3d7e..9bab97ee5 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -480,10 +480,9 @@ int16_t LR11x0::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMa // set DIO mapping uint32_t irq = irqFlags; if(timeout != RADIOLIB_LR11X0_RX_TIMEOUT_INF) { - irq |= RADIOLIB_LR11X0_IRQ_TIMEOUT; + irq |= (1UL << RADIOLIB_IRQ_TIMEOUT); } - - state = setDioIrqParams(irq); + state = setDioIrqParams(getIrqMapped(irq)); RADIOLIB_ASSERT(state); // clear interrupt flags @@ -1353,12 +1352,6 @@ RadioLibTime_t LR11x0::calculateRxTimeout(RadioLibTime_t timeoutUs) { return(timeout); } -int16_t LR11x0::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) { - irqFlags = RADIOLIB_LR11X0_IRQ_RX_DONE | RADIOLIB_LR11X0_IRQ_TIMEOUT; // flags that can appear in the IRQ register - irqMask = irqFlags; // on LR11x0, these are the same - return(RADIOLIB_ERR_NONE); -} - uint32_t LR11x0::getIrqFlags() { return((uint32_t)this->getIrqStatus()); } diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index 95c7c363a..d7cf2d2a7 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -1216,14 +1216,6 @@ class LR11x0: public PhysicalLayer { */ RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs) override; - /*! - \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 - */ - int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override; - /*! \brief Read currently active IRQ flags. \returns IRQ flags. From cc299053b14ec20232ca7851c9d5484d6ed7548f Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:15:52 +0200 Subject: [PATCH 23/39] [SX126x] Rework generic IRQ to allow multiple flags --- src/modules/SX126x/SX126x.cpp | 27 +++++++++++---------------- src/modules/SX126x/SX126x.h | 31 ++++++++++++------------------- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 3ba080321..ca8648b5f 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -443,6 +443,7 @@ int16_t SX126x::scanChannel() { .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .timeout = 0, .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK, }, }; return(this->scanChannel(config)); @@ -601,10 +602,10 @@ int16_t SX126x::finishTransmit() { } int16_t SX126x::startReceive() { - return(this->startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF, RADIOLIB_SX126X_IRQ_RX_DEFAULT, RADIOLIB_SX126X_IRQ_RX_DONE, 0)); + return(this->startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0)); } -int16_t SX126x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) { +int16_t SX126x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { (void)len; int16_t state = startReceiveCommon(timeout, irqFlags, irqMask); RADIOLIB_ASSERT(state); @@ -618,7 +619,7 @@ int16_t SX126x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMa return(state); } -int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, uint16_t irqFlags, uint16_t irqMask) { +int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask) { // datasheet claims time to go to sleep is ~500us, same to wake up, compensate for that with 1 ms + TCXO delay uint32_t transitionTime = this->tcxoDelay + 1000; sleepPeriod -= transitionTime; @@ -645,7 +646,7 @@ int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, u return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_RX_DUTY_CYCLE, data, 6)); } -int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_t minSymbols, uint16_t irqFlags, uint16_t irqMask) { +int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_t minSymbols, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask) { if(senderPreambleLength == 0) { senderPreambleLength = this->preambleLengthLoRa; } @@ -683,12 +684,12 @@ int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_ return(startReceiveDutyCycle(wakePeriod, sleepPeriod, irqFlags, irqMask)); } -int16_t SX126x::startReceiveCommon(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask) { +int16_t SX126x::startReceiveCommon(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask) { // set DIO mapping if(timeout != RADIOLIB_SX126X_RX_TIMEOUT_INF) { - irqMask |= RADIOLIB_SX126X_IRQ_TIMEOUT; + irqMask |= (1UL << RADIOLIB_IRQ_TIMEOUT); } - int16_t state = setDioIrqParams(irqFlags, irqMask); + int16_t state = setDioIrqParams(getIrqMapped(irqFlags), getIrqMapped(irqMask)); RADIOLIB_ASSERT(state); // set buffer pointers @@ -758,7 +759,8 @@ int16_t SX126x::startChannelScan() { .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .timeout = 0, - .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK, }, }; return(this->startChannelScan(config)); @@ -778,8 +780,7 @@ int16_t SX126x::startChannelScan(ChannelScanConfig_t config) { this->mod->setRfSwitchState(Module::MODE_RX); // set DIO pin mapping - uint16_t irqFlags = (config.cad.irqFlags == RADIOLIB_IRQ_NOT_SUPPORTED) ? RADIOLIB_SX126X_IRQ_CAD_DETECTED | RADIOLIB_SX126X_IRQ_CAD_DONE : config.cad.irqFlags; - state = setDioIrqParams(irqFlags, irqFlags); + state = setDioIrqParams(getIrqMapped(config.cad.irqFlags), getIrqMapped(config.cad.irqMask)); RADIOLIB_ASSERT(state); // clear interrupt flags @@ -1490,12 +1491,6 @@ RadioLibTime_t SX126x::calculateRxTimeout(RadioLibTime_t timeoutUs) { return(timeout); } -int16_t SX126x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) { - irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT; // flags that can appear in the IRQ register - irqMask = RADIOLIB_SX126X_IRQ_RX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT; // flags that will trigger DIO0 - return(RADIOLIB_ERR_NONE); -} - uint32_t SX126x::getIrqFlags() { uint8_t data[] = { 0x00, 0x00 }; this->mod->SPIreadStream(RADIOLIB_SX126X_CMD_GET_IRQ_STATUS, data, 2); diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index 99ca688f0..4404faa05 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -222,7 +222,6 @@ #define RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED 0b0000000000000100 // 2 2 preamble detected #define RADIOLIB_SX126X_IRQ_RX_DONE 0b0000000000000010 // 1 1 packet received #define RADIOLIB_SX126X_IRQ_TX_DONE 0b0000000000000001 // 0 0 packet transmission completed -#define RADIOLIB_SX126X_IRQ_RX_DEFAULT 0b0000001001100010 // 14 0 default for Rx (RX_DONE, TIMEOUT, CRC_ERR and HEADER_ERR) #define RADIOLIB_SX126X_IRQ_ALL 0b0100001111111111 // 14 0 all interrupts #define RADIOLIB_SX126X_IRQ_NONE 0b0000000000000000 // 14 0 no interrupts @@ -655,24 +654,26 @@ class SX126x: public PhysicalLayer { For any other value, timeout will be applied and signal will be generated on DIO1 for conditions defined by irqFlags and irqMask. - \param irqFlags Sets the IRQ flags, defaults to RADIOLIB_SX126X_IRQ_RX_DEFAULT. - \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RADIOLIB_SX126X_IRQ_RX_DONE. + \param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error. + \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done. \param len Only for PhysicalLayer compatibility, not used. \returns \ref status_codes */ - int16_t startReceive(uint32_t timeout, uint32_t irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT, uint32_t irqMask = RADIOLIB_SX126X_IRQ_RX_DONE, size_t len = 0); + int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0); /*! \brief Interrupt-driven receive method where the device mostly sleeps and periodically wakes to listen. Note that this function assumes the unit will take 500us + TCXO_delay to change state. See datasheet section 13.1.7, version 1.2. + \param rxPeriod The duration the receiver will be in Rx mode, in microseconds. \param sleepPeriod The duration the receiver will not be in Rx mode, in microseconds. - \param irqFlags Sets the IRQ flags, defaults to RADIOLIB_SX126X_IRQ_RX_DEFAULT. - \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RADIOLIB_SX126X_IRQ_RX_DONE. + + \param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error. + \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done. \returns \ref status_codes */ - int16_t startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, uint16_t irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT, uint16_t irqMask = RADIOLIB_SX126X_IRQ_RX_DONE); + int16_t startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK); /*! \brief Calls \ref startReceiveDutyCycle with rxPeriod and sleepPeriod set so the unit shouldn't miss any messages. @@ -684,11 +685,11 @@ class SX126x: public PhysicalLayer { According to Semtech, receiver requires 8 symbols to reliably latch a preamble. This makes this method redundant when transmitter preamble length is less than 17 (2*minSymbols + 1). - \param irqFlags Sets the IRQ flags, defaults to RADIOLIB_SX126X_IRQ_RX_DEFAULT. - \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RADIOLIB_SX126X_IRQ_RX_DONE. + \param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error. + \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done. \returns \ref status_codes */ - int16_t startReceiveDutyCycleAuto(uint16_t senderPreambleLength = 0, uint16_t minSymbols = 8, uint16_t irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT, uint16_t irqMask = RADIOLIB_SX126X_IRQ_RX_DONE); + int16_t startReceiveDutyCycleAuto(uint16_t senderPreambleLength = 0, uint16_t minSymbols = 8, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK); /*! \brief Reads data received after calling startReceive method. When the packet length is not known in advance, @@ -979,14 +980,6 @@ class SX126x: public PhysicalLayer { */ RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs) override; - /*! - \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 - */ - int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override; - /*! \brief Read currently active IRQ flags. \returns IRQ flags. @@ -1227,7 +1220,7 @@ class SX126x: public PhysicalLayer { int16_t config(uint8_t modem); bool findChip(const char* verStr); - int16_t startReceiveCommon(uint32_t timeout = RADIOLIB_SX126X_RX_TIMEOUT_INF, uint16_t irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT, uint16_t irqMask = RADIOLIB_SX126X_IRQ_RX_DONE); + int16_t startReceiveCommon(uint32_t timeout = RADIOLIB_SX126X_RX_TIMEOUT_INF, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK); int16_t setPacketMode(uint8_t mode, uint8_t len); int16_t setHeaderType(uint8_t hdrType, size_t len = 0xFF); int16_t directMode(); From 17de5754ae75d3a433980f760c7c8457fdd2c6dd Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:16:05 +0200 Subject: [PATCH 24/39] [SX127x] Rework generic IRQ to allow multiple flags --- src/modules/SX127x/SX127x.cpp | 31 ++++++++++--------------------- src/modules/SX127x/SX127x.h | 17 ++++------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 60b81ed73..c0d51c2f9 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -386,21 +386,23 @@ int16_t SX127x::packetMode() { } int16_t SX127x::startReceive() { - return(this->startReceive(0, RADIOLIB_SX127X_RXCONTINUOUS)); + return(this->startReceive(0, RADIOLIB_SX127X_RXCONTINUOUS, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK)); } -int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { +int16_t SX127x::startReceive(uint8_t len, uint8_t mode, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask) { // set mode to standby int16_t state = setMode(RADIOLIB_SX127X_STANDBY); RADIOLIB_ASSERT(state); + // set DIO pin mapping + state = this->setIrqFlags(irqFlags & irqMask); + RADIOLIB_ASSERT(state); + int16_t modem = getActiveModem(); if(modem == RADIOLIB_SX127X_LORA) { - // set DIO pin mapping + // in FHSS mode, enable channel change interrupt if(this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) { - state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_RX_DONE | RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 7, 4); - } else { - state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_RX_DONE | RADIOLIB_SX127X_DIO1_LORA_RX_TIMEOUT, 7, 4); + state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 5, 4); } // set expected packet length for SF6 @@ -421,10 +423,6 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { RADIOLIB_ASSERT(state); } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - // set DIO pin mapping - state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PAYLOAD_READY, 7, 6); - RADIOLIB_ASSERT(state); - // clear interrupt flags clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); @@ -443,9 +441,7 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { return(setMode(mode)); } -int16_t SX127x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) { - (void)irqFlags; - (void)irqMask; +int16_t SX127x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS; if(timeout != 0) { // for non-zero timeout value, change mode to Rx single and set the timeout @@ -456,7 +452,7 @@ int16_t SX127x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMa state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYMB_TIMEOUT_LSB, lsb_sym); RADIOLIB_ASSERT(state); } - return(startReceive((uint8_t)len, mode)); + return(startReceive((uint8_t)len, mode, irqFlags, irqMask)); } void SX127x::setDio0Action(void (*func)(void), uint32_t dir) { @@ -1319,13 +1315,6 @@ RadioLibTime_t SX127x::calculateRxTimeout(RadioLibTime_t timeoutUs) { return(numSymbols); } -int16_t SX127x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) { - // IRQ flags/masks are inverted to what seems logical for SX127x (0 being activated, 1 being deactivated) - irqFlags = RADIOLIB_SX127X_MASK_IRQ_FLAG_RX_DEFAULT; - irqMask = RADIOLIB_SX127X_MASK_IRQ_FLAG_RX_DONE & RADIOLIB_SX127X_MASK_IRQ_FLAG_RX_TIMEOUT; - return(RADIOLIB_ERR_NONE); -} - uint32_t SX127x::getIrqFlags() { return((uint32_t)this->getIRQFlags()); } diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index e89cdfd47..86f5144b6 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -160,7 +160,6 @@ #define RADIOLIB_SX127X_MASK_IRQ_FLAG_CAD_DONE 0b11111011 // 2 2 CAD complete #define RADIOLIB_SX127X_MASK_IRQ_FLAG_FHSS_CHANGE_CHANNEL 0b11111101 // 1 1 FHSS change channel #define RADIOLIB_SX127X_MASK_IRQ_FLAG_CAD_DETECTED 0b11111110 // 0 0 valid LoRa signal detected during CAD operation -#define RADIOLIB_SX127X_MASK_IRQ_FLAG_RX_DEFAULT 0b00011111 // 7 0 default for Rx (RX_TIMEOUT, RX_DONE, CRC_ERR) // RADIOLIB_SX127X_REG_FIFO_TX_BASE_ADDR #define RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX 0b00000000 // 7 0 allocate the entire FIFO buffer for TX only @@ -820,7 +819,7 @@ class SX127x: public PhysicalLayer { \param mode Receive mode to be used. Defaults to RxContinuous. \returns \ref status_codes */ - int16_t startReceive(uint8_t len, uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS); + int16_t startReceive(uint8_t len, uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK); /*! \brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer. @@ -828,12 +827,12 @@ class SX127x: public PhysicalLayer { When set to 0, the timeout will be infinite and the device will remain in Rx mode until explicitly commanded to stop (Rx continuous mode). When non-zero (maximum 1023), the device will be set to Rx single mode and timeout will be set. - \param irqFlags Ignored. - \param irqMask Ignored. + \param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error. + \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done. \param len Expected length of packet to be received. Required for LoRa spreading factor 6. \returns \ref status_codes */ - int16_t startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) override; + int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) override; /*! \brief Reads data that was received after calling startReceive method. When the packet length is not known in advance, @@ -1065,14 +1064,6 @@ class SX127x: public PhysicalLayer { */ RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs) override; - /*! - \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 - */ - int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override; - /*! \brief Read currently active IRQ flags. \returns IRQ flags. From 8fe6ba86ab9c27f80e429daef51b8b763df909f3 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:16:15 +0200 Subject: [PATCH 25/39] [SX128x] Rework generic IRQ to allow multiple flags --- src/modules/SX128x/SX128x.cpp | 17 +++++++++-------- src/modules/SX128x/SX128x.h | 7 +++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/modules/SX128x/SX128x.cpp b/src/modules/SX128x/SX128x.cpp index 7fae67122..1279b5713 100644 --- a/src/modules/SX128x/SX128x.cpp +++ b/src/modules/SX128x/SX128x.cpp @@ -428,7 +428,8 @@ int16_t SX128x::scanChannel() { .detMin = 0, .exitMode = 0, .timeout = 0, - .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK, }, }; return(this->scanChannel(config)); @@ -582,10 +583,10 @@ int16_t SX128x::finishTransmit() { } int16_t SX128x::startReceive() { - return(this->startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_SX128X_IRQ_RX_DEFAULT, RADIOLIB_SX128X_IRQ_RX_DONE, 0)); + return(this->startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0)); } -int16_t SX128x::startReceive(uint16_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) { +int16_t SX128x::startReceive(uint16_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { (void)len; // check active modem @@ -595,10 +596,10 @@ int16_t SX128x::startReceive(uint16_t timeout, uint32_t irqFlags, uint32_t irqMa // set DIO mapping if(timeout != RADIOLIB_SX128X_RX_TIMEOUT_INF) { - irqMask |= RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT; + irqMask |= (1UL << RADIOLIB_IRQ_TIMEOUT); } - int16_t state = setDioIrqParams(irqFlags, irqMask); + int16_t state = setDioIrqParams(getIrqMapped(irqFlags), getIrqMapped(irqMask)); RADIOLIB_ASSERT(state); // set buffer pointers @@ -682,7 +683,8 @@ int16_t SX128x::startChannelScan() { .detMin = 0, .exitMode = 0, .timeout = 0, - .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK, }, }; return(this->startChannelScan(config)); @@ -699,8 +701,7 @@ int16_t SX128x::startChannelScan(ChannelScanConfig_t config) { RADIOLIB_ASSERT(state); // set DIO pin mapping - uint16_t irqFlags = (config.cad.irqFlags == RADIOLIB_IRQ_NOT_SUPPORTED) ? RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE : config.cad.irqFlags; - state = setDioIrqParams(irqFlags, irqFlags); + state = setDioIrqParams(getIrqMapped(config.cad.irqFlags), getIrqMapped(config.cad.irqMask)); RADIOLIB_ASSERT(state); // clear interrupt flags diff --git a/src/modules/SX128x/SX128x.h b/src/modules/SX128x/SX128x.h index cadc7909e..03d87e68d 100644 --- a/src/modules/SX128x/SX128x.h +++ b/src/modules/SX128x/SX128x.h @@ -328,7 +328,6 @@ #define RADIOLIB_SX128X_IRQ_SYNC_WORD_VALID 0x0004 // 2 2 sync word valid #define RADIOLIB_SX128X_IRQ_RX_DONE 0x0002 // 1 1 Rx done #define RADIOLIB_SX128X_IRQ_TX_DONE 0x0001 // 0 0 Tx done -#define RADIOLIB_SX128X_IRQ_RX_DEFAULT 0x4062 // 15 0 default for Rx (RX_DONE, RX_TX_TIMEOUT, CRC_ERROR and HEADER_ERROR) #define RADIOLIB_SX128X_IRQ_NONE 0x0000 // 15 0 none #define RADIOLIB_SX128X_IRQ_ALL 0xFFFF // 15 0 all @@ -561,12 +560,12 @@ class SX128x: public PhysicalLayer { set to RADIOLIB_SX128X_RX_TIMEOUT_NONE for no timeout (Rx single mode). If timeout other than infinite is set, signal will be generated on DIO1. - \param irqFlags Sets the IRQ flags, defaults to RADIOLIB_SX128X_IRQ_RX_DEFAULT. - \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RADIOLIB_SX128X_IRQ_RX_DONE. + \param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error. + \param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done. \param len Only for PhysicalLayer compatibility, not used. \returns \ref status_codes */ - int16_t startReceive(uint16_t timeout, uint32_t irqFlags = RADIOLIB_SX128X_IRQ_RX_DEFAULT, uint32_t irqMask = RADIOLIB_SX128X_IRQ_RX_DONE, size_t len = 0); + int16_t startReceive(uint16_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0); /*! \brief Reads the current IRQ status. From 1a462dcd8762740f9921584b0825419f511d302c Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:16:39 +0200 Subject: [PATCH 26/39] [LoRaWAN] Use generic IRQ --- src/protocols/LoRaWAN/LoRaWAN.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/protocols/LoRaWAN/LoRaWAN.cpp b/src/protocols/LoRaWAN/LoRaWAN.cpp index c27feaa4f..a1f63a7d7 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.cpp +++ b/src/protocols/LoRaWAN/LoRaWAN.cpp @@ -1190,9 +1190,8 @@ int16_t LoRaWANNode::downlinkCommon() { RADIOLIB_ASSERT(state); // create the masks that are required for receiving downlinks - uint32_t irqFlags = 0; - uint32_t irqMask = 0; - this->phyLayer->irqRxDoneRxTimeout(irqFlags, irqMask); + RadioLibIrqFlags_t irqFlags = (1UL << RADIOLIB_IRQ_RX_DONE) | (1UL << RADIOLIB_IRQ_TIMEOUT); + RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK; this->phyLayer->setPacketReceivedAction(LoRaWANNodeOnDownlinkAction); From b3edfd89bd2ce2ca8d4d3496cf78c764953026ff Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 25 Aug 2024 18:19:22 +0200 Subject: [PATCH 27/39] Add missing typedef --- src/TypeDef.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/TypeDef.h b/src/TypeDef.h index 17ff288e6..de6e06b6e 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -616,9 +616,10 @@ typedef unsigned long RadioLibTime_t; /*! - \brief Type used for radio-agnostic IRQ flags. + \brief Type used for radio-agnostic IRQ flags. IRQ to enable corresponds to the bit index (RadioLibIrq_t). + For example, if bit 0 is set, the module will enable its RADIOLIB_IRQ_TX_DONE (if it is supported). */ -typedef uint8_t RadioIrqFlags_t; +typedef uint32_t RadioLibIrqFlags_t; /*! \} From 29dd65d7adbfd4248e2065f25ef36e9b81c0c6ec Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:10:05 +0200 Subject: [PATCH 28/39] [SX127x] Make Rx mode implicit based on timeout --- src/modules/SX127x/SX127x.cpp | 40 +++++++++++++++-------------------- src/modules/SX127x/SX127x.h | 9 -------- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index c0d51c2f9..7e00c8980 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -217,7 +217,7 @@ int16_t SX127x::receive(uint8_t* data, size_t len) { int16_t modem = getActiveModem(); if(modem == RADIOLIB_SX127X_LORA) { // set mode to receive - state = startReceive(len, RADIOLIB_SX127X_RXSINGLE); + state = startReceive(100, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, len); RADIOLIB_ASSERT(state); // if no DIO1 is provided, use software timeout (100 LoRa symbols, same as hardware timeout) @@ -253,7 +253,7 @@ int16_t SX127x::receive(uint8_t* data, size_t len) { RadioLibTime_t timeout = (getTimeOnAir(len) * 5) / 1000; // set mode to receive - state = startReceive(len, RADIOLIB_SX127X_RX); + state = startReceive(0, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, len); RADIOLIB_ASSERT(state); // wait for packet reception or timeout @@ -386,10 +386,12 @@ int16_t SX127x::packetMode() { } int16_t SX127x::startReceive() { - return(this->startReceive(0, RADIOLIB_SX127X_RXCONTINUOUS, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK)); + return(this->startReceive(0, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0)); } -int16_t SX127x::startReceive(uint8_t len, uint8_t mode, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask) { +int16_t SX127x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { + uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS; + // set mode to standby int16_t state = setMode(RADIOLIB_SX127X_STANDBY); RADIOLIB_ASSERT(state); @@ -400,6 +402,16 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode, RadioLibIrqFlags_t irqFl int16_t modem = getActiveModem(); if(modem == RADIOLIB_SX127X_LORA) { + if(timeout != 0) { + // for non-zero timeout value, change mode to Rx single and set the timeout + mode = RADIOLIB_SX127X_RXSINGLE; + uint8_t msb_sym = (timeout > 0x3FF) ? 0x3 : (uint8_t)(timeout >> 8); + uint8_t lsb_sym = (timeout > 0x3FF) ? 0xFF : (uint8_t)(timeout & 0xFF); + int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, msb_sym, 1, 0); + state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYMB_TIMEOUT_LSB, lsb_sym); + RADIOLIB_ASSERT(state); + } + // in FHSS mode, enable channel change interrupt if(this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) { state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 5, 4); @@ -427,11 +439,7 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode, RadioLibIrqFlags_t irqFl clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL); // FSK modem does not distinguish between Rx single and continuous - if(mode == RADIOLIB_SX127X_RXCONTINUOUS) { - // set RF switch (if present) - this->mod->setRfSwitchState(Module::MODE_RX); - return(setMode(RADIOLIB_SX127X_RX)); - } + mode = RADIOLIB_SX127X_RX; } // set RF switch (if present) @@ -441,20 +449,6 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode, RadioLibIrqFlags_t irqFl return(setMode(mode)); } -int16_t SX127x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { - uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS; - if(timeout != 0) { - // for non-zero timeout value, change mode to Rx single and set the timeout - mode = RADIOLIB_SX127X_RXSINGLE; - uint8_t msb_sym = (timeout > 0x3FF) ? 0x3 : (uint8_t)(timeout >> 8); - uint8_t lsb_sym = (timeout > 0x3FF) ? 0xFF : (uint8_t)(timeout & 0xFF); - int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, msb_sym, 1, 0); - state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYMB_TIMEOUT_LSB, lsb_sym); - RADIOLIB_ASSERT(state); - } - return(startReceive((uint8_t)len, mode, irqFlags, irqMask)); -} - void SX127x::setDio0Action(void (*func)(void), uint32_t dir) { this->mod->hal->attachInterrupt(this->mod->hal->pinToInterrupt(this->mod->getIrq()), func, dir); } diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index 86f5144b6..a1df97e01 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -811,15 +811,6 @@ class SX127x: public PhysicalLayer { \returns \ref status_codes */ int16_t startReceive() override; - - /*! - \brief Interrupt-driven receive method. DIO0 will be activated when full valid packet is received. - \param len Expected length of packet to be received, or 0 when unused. - Defaults to 0, non-zero required for LoRa spreading factor 6. - \param mode Receive mode to be used. Defaults to RxContinuous. - \returns \ref status_codes - */ - int16_t startReceive(uint8_t len, uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK); /*! \brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer. From 0caedc188686f65c1ca288cbf4cdeaea5f0cd6df Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:15:13 +0200 Subject: [PATCH 29/39] [SX127x] Fixed shadowed variable --- src/modules/SX127x/SX127x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 7e00c8980..b1a1bb0aa 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -407,7 +407,7 @@ int16_t SX127x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, Radi mode = RADIOLIB_SX127X_RXSINGLE; uint8_t msb_sym = (timeout > 0x3FF) ? 0x3 : (uint8_t)(timeout >> 8); uint8_t lsb_sym = (timeout > 0x3FF) ? 0xFF : (uint8_t)(timeout & 0xFF); - int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, msb_sym, 1, 0); + state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, msb_sym, 1, 0); state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYMB_TIMEOUT_LSB, lsb_sym); RADIOLIB_ASSERT(state); } From 26aae8da8d43f77d6da8a8dbce66a2f396e9703e Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:23:09 +0200 Subject: [PATCH 30/39] [LR11x0] Fix missing initializers --- src/modules/LR11x0/LR11x0.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index 9bab97ee5..c51e7af91 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -295,7 +295,8 @@ int16_t LR11x0::scanChannel() { .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .timeout = 0, - .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK, }, }; return(this->scanChannel(config)); From 0e694f3985652697b23550d5a20ae7ef109437d9 Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:26:26 +0200 Subject: [PATCH 31/39] [SX127x] Added default startReceive arguments --- .../SX127x_Channel_Activity_Detection_Receive.ino | 4 ++-- src/modules/SX127x/SX127x.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino b/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino index 35f9d40df..f78d747a4 100644 --- a/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino +++ b/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino @@ -168,9 +168,9 @@ void loop() { // check if we got a preamble if(detectedFlag) { - // LoRa preamble was detected + // LoRa preamble was detected, start reception with timeout of 100 LoRa symbols Serial.print(F("[SX1278] Preamble detected, starting reception ... ")); - state = radio.startReceive(0, RADIOLIB_SX127X_RXSINGLE); + state = radio.startReceive(100); if (state == RADIOLIB_ERR_NONE) { Serial.println(F("success!")); } else { diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index a1df97e01..94db00ab6 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -811,7 +811,7 @@ class SX127x: public PhysicalLayer { \returns \ref status_codes */ int16_t startReceive() override; - + /*! \brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer. \param timeout Receive mode type and/or raw timeout value in symbols. @@ -823,7 +823,7 @@ class SX127x: public PhysicalLayer { \param len Expected length of packet to be received. Required for LoRa spreading factor 6. \returns \ref status_codes */ - int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) override; + int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0) override; /*! \brief Reads data that was received after calling startReceive method. When the packet length is not known in advance, From d81d8020766d6870697354656aabc26ed3115459 Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:35:53 +0200 Subject: [PATCH 32/39] [LR11x0] Pass scan config by const reference --- src/modules/LR11x0/LR11x0.cpp | 2 +- src/modules/LR11x0/LR11x0.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index c51e7af91..e0f9d733e 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -574,7 +574,7 @@ int16_t LR11x0::startChannelScan() { return(this->startChannelScan(config)); } -int16_t LR11x0::startChannelScan(ChannelScanConfig_t config) { +int16_t LR11x0::startChannelScan(const ChannelScanConfig_t &config) { // check active modem int16_t state = RADIOLIB_ERR_NONE; uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE; diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index d7cf2d2a7..5677ac462 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -982,7 +982,7 @@ class LR11x0: public PhysicalLayer { \param config CAD configuration structure. \returns \ref status_codes */ - int16_t startChannelScan(ChannelScanConfig_t config) override; + int16_t startChannelScan(const ChannelScanConfig_t &config) override; /*! \brief Read the channel scan result From fa1760d0b1ee77a73ae6c9b250caa0efea4fd017 Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:36:12 +0200 Subject: [PATCH 33/39] [SX126x] Pass scan config by const reference --- src/modules/SX126x/SX126x.cpp | 2 +- src/modules/SX126x/SX126x.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index ca8648b5f..a4e761ff4 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -766,7 +766,7 @@ int16_t SX126x::startChannelScan() { return(this->startChannelScan(config)); } -int16_t SX126x::startChannelScan(ChannelScanConfig_t config) { +int16_t SX126x::startChannelScan(const ChannelScanConfig_t &config) { // check active modem if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) { return(RADIOLIB_ERR_WRONG_MODEM); diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index 4404faa05..143a25e0e 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -714,7 +714,7 @@ class SX126x: public PhysicalLayer { \param config CAD configuration structure. \returns \ref status_codes */ - int16_t startChannelScan(ChannelScanConfig_t config) override; + int16_t startChannelScan(const ChannelScanConfig_t &config) override; /*! \brief Read the channel scan result From d5987ac22e96781309287d26b08067a3ba2b495b Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:36:21 +0200 Subject: [PATCH 34/39] [SX128x] Pass scan config by const reference --- src/modules/SX128x/SX128x.cpp | 2 +- src/modules/SX128x/SX128x.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/SX128x/SX128x.cpp b/src/modules/SX128x/SX128x.cpp index 1279b5713..6ef2b4bf9 100644 --- a/src/modules/SX128x/SX128x.cpp +++ b/src/modules/SX128x/SX128x.cpp @@ -690,7 +690,7 @@ int16_t SX128x::startChannelScan() { return(this->startChannelScan(config)); } -int16_t SX128x::startChannelScan(ChannelScanConfig_t config) { +int16_t SX128x::startChannelScan(const ChannelScanConfig_t &config) { // check active modem if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) { return(RADIOLIB_ERR_WRONG_MODEM); diff --git a/src/modules/SX128x/SX128x.h b/src/modules/SX128x/SX128x.h index 03d87e68d..1e1dea1f0 100644 --- a/src/modules/SX128x/SX128x.h +++ b/src/modules/SX128x/SX128x.h @@ -616,7 +616,7 @@ class SX128x: public PhysicalLayer { \param config CAD configuration structure. \returns \ref status_codes */ - int16_t startChannelScan(ChannelScanConfig_t config) override; + int16_t startChannelScan(const ChannelScanConfig_t &config) override; /*! \brief Read the channel scan result From 9d99e38a43a9a86e08a7782fedc30d54a329140c Mon Sep 17 00:00:00 2001 From: jgromes Date: Wed, 28 Aug 2024 19:36:43 +0200 Subject: [PATCH 35/39] [PHY] Pass scan config by const reference --- src/protocols/PhysicalLayer/PhysicalLayer.cpp | 2 +- src/protocols/PhysicalLayer/PhysicalLayer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.cpp b/src/protocols/PhysicalLayer/PhysicalLayer.cpp index a5cb9cfa3..1a2c19f96 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.cpp +++ b/src/protocols/PhysicalLayer/PhysicalLayer.cpp @@ -356,7 +356,7 @@ int16_t PhysicalLayer::startChannelScan() { return(RADIOLIB_ERR_UNSUPPORTED); } -int16_t PhysicalLayer::startChannelScan(ChannelScanConfig_t config) { +int16_t PhysicalLayer::startChannelScan(const ChannelScanConfig_t &config) { (void)config; return(RADIOLIB_ERR_UNSUPPORTED); } diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.h b/src/protocols/PhysicalLayer/PhysicalLayer.h index 3e2dedd67..0920076a4 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -490,7 +490,7 @@ class PhysicalLayer { \param config Scan configuration structure. Interpretation depends on currently active modem. \returns \ref status_codes */ - virtual int16_t startChannelScan(ChannelScanConfig_t config); + virtual int16_t startChannelScan(const ChannelScanConfig_t &config); /*! \brief Read the channel scan result From 7d1df89df0d26a888befffb8d7f3172bf798b0b7 Mon Sep 17 00:00:00 2001 From: jgromes Date: Fri, 30 Aug 2024 18:54:59 +0200 Subject: [PATCH 36/39] [SX127x] Add missing IRQ conversion --- src/modules/SX127x/SX127x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index b1a1bb0aa..7561b2351 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -397,7 +397,7 @@ int16_t SX127x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, Radi RADIOLIB_ASSERT(state); // set DIO pin mapping - state = this->setIrqFlags(irqFlags & irqMask); + state = this->setIrqFlags(getIrqMapped(irqFlags & irqMask)); RADIOLIB_ASSERT(state); int16_t modem = getActiveModem(); From ed30c50f8b0c8dc75ed8985d232efdb13d805114 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sat, 31 Aug 2024 16:49:45 +0200 Subject: [PATCH 37/39] [SX126x] Fixed default CAD scan config IRQ --- src/modules/SX126x/SX126x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index a4e761ff4..718507ebd 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -442,7 +442,7 @@ int16_t SX126x::scanChannel() { .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, .timeout = 0, - .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK, }, }; From 595e7806d5394392d9297ef83cc37b0a5fc873d9 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sat, 31 Aug 2024 16:50:04 +0200 Subject: [PATCH 38/39] [LR11x0] Fixed default CAD scan config IRQ --- src/modules/LR11x0/LR11x0.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index e0f9d733e..3570b2880 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -568,7 +568,8 @@ int16_t LR11x0::startChannelScan() { .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, .timeout = 0, - .irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK, }, }; return(this->startChannelScan(config)); From 6fc4bfa8fcd17facb7f11a46b1d1158e9a4aafc9 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 1 Sep 2024 18:12:30 +0200 Subject: [PATCH 39/39] [LR11x0] Fix comments referencing DIO1 --- src/modules/LR11x0/LR11x0.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index 5677ac462..7c5737bd7 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -977,7 +977,7 @@ class LR11x0: public PhysicalLayer { int16_t startChannelScan() override; /*! - \brief Interrupt-driven channel activity detection method. DIO1 will be activated + \brief Interrupt-driven channel activity detection method. IRQ pin will be activated when LoRa preamble is detected, or upon timeout. \param config CAD configuration structure. \returns \ref status_codes @@ -1223,7 +1223,7 @@ class LR11x0: public PhysicalLayer { uint32_t getIrqFlags() override; /*! - \brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). + \brief Set interrupt on IRQ pin to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone). \param irq Module-specific IRQ flags. \returns \ref status_codes */