From 84f1e11d29823d51a0047beb07d76b9523093ce5 Mon Sep 17 00:00:00 2001 From: Ev Lbibass <27320050+lbibass@users.noreply.github.com> Date: Sun, 20 Sep 2026 20:38:05 -0400 Subject: [PATCH] update structure of LR1121 to match LR1110 files. Implement DC-DC on LR1121 radio. saves about 30% power consumption at idle. --- src/helpers/radiolib/CustomLR1121.h | 72 ++++++++++++++++++++-- src/helpers/radiolib/CustomLR1121Wrapper.h | 3 + 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/helpers/radiolib/CustomLR1121.h b/src/helpers/radiolib/CustomLR1121.h index 873bfabc4e..67e3b52a97 100644 --- a/src/helpers/radiolib/CustomLR1121.h +++ b/src/helpers/radiolib/CustomLR1121.h @@ -4,11 +4,25 @@ #include "MeshCore.h" class CustomLR1121 : public LR1121 { + uint32_t _preambleMillis = 66; + uint32_t _maxPayloadMillis = 3934; + uint32_t _activityAt = 0; + bool _headerSeen = false; bool _rx_boosted = false; public: CustomLR1121(Module *mod) : LR1121(mod) { } + int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, + uint8_t syncWord = RADIOLIB_LR11X0_LORA_SYNC_WORD_PRIVATE, int8_t power = 10, + uint16_t preambleLength = 8, float tcxoVoltage = 1.6) { + int16_t state = LR1121::begin(freq, bw, sf, cr, syncWord, power, preambleLength, + tcxoVoltage); + // RadioLib begin() defaults to LDO; use the LR1121 DC/DC regulator. + if (state == RADIOLIB_ERR_NONE) state = setRegulatorDCDC(); + return state; + } + size_t getPacketLength(bool update) override { size_t len = LR1121::getPacketLength(update); if (len == 0 && getIrqStatus() & RADIOLIB_LR11X0_IRQ_HEADER_ERR) { @@ -31,11 +45,61 @@ class CustomLR1121 : public LR1121 { bool getRxBoostedGainMode() const { return _rx_boosted; } + int16_t startReceive() override { + // include the PREAMBLE_DETECTED irq bit in reported flags. + return LR1121::startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1UL << RADIOLIB_IRQ_PREAMBLE_DETECTED), RADIOLIB_IRQ_RX_DEFAULT_MASK, 0); + } + bool isReceiving() { - uint16_t irq = getIrqStatus(); - bool detected = ((irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID) || (irq & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED)); - return detected; + uint32_t irq = getIrqStatus(); + bool preamble = irq & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED; // bit 4 + bool header = irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID; // bit 5 + bool hdrErr = irq & RADIOLIB_LR11X0_IRQ_HEADER_ERR; // bit 6 + uint32_t now = millis(); + if (hdrErr) { + clearIrqState(RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED | RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID | RADIOLIB_LR11X0_IRQ_HEADER_ERR); + _activityAt = 0; + _headerSeen = false; + return false; + } + if (!header && _headerSeen) { + // something cleared the header flag, reset our state. + _activityAt = 0; _headerSeen = false; + return false; + } + if (header) { + if (!_headerSeen) { _headerSeen = true; _activityAt = now; }; + if (now - _activityAt > _maxPayloadMillis) { + MESH_DEBUG_PRINTLN("Clearing header IRQ after %ums", _maxPayloadMillis); + clearIrqState(RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED | RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID | RADIOLIB_LR11X0_IRQ_HEADER_ERR); + _activityAt = 0; _headerSeen = false; + return false; + } + return true; + } + if (preamble) { + if (_activityAt == 0) _activityAt = now; + if (now - _activityAt > _preambleMillis) { + clearIrqState(RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED); + _activityAt = 0; + MESH_DEBUG_PRINTLN("Clearing preamble IRQ after %ums", _preambleMillis); + + return false; + } + return true; + } + _activityAt = 0; _headerSeen = false; + return false; + } + + void setPreambleMillis(uint32_t preambleMillis) { + _preambleMillis = preambleMillis; + MESH_DEBUG_PRINTLN("Set _preambleMillis=%u", _preambleMillis); + } + void setMaxPayloadMillis(uint32_t payloadMillis) { + _maxPayloadMillis = payloadMillis; + MESH_DEBUG_PRINTLN("Set _maxPayloadMillis=%u", _maxPayloadMillis); } - uint8_t getSpreadingFactor() const { return spreadingFactor; } + uint8_t getSpreadingFactor() const { return spreadingFactor; } }; \ No newline at end of file diff --git a/src/helpers/radiolib/CustomLR1121Wrapper.h b/src/helpers/radiolib/CustomLR1121Wrapper.h index 5361ee238d..5a754cee83 100644 --- a/src/helpers/radiolib/CustomLR1121Wrapper.h +++ b/src/helpers/radiolib/CustomLR1121Wrapper.h @@ -14,6 +14,9 @@ class CustomLR1121Wrapper : public RadioLibWrapper { ((CustomLR1121 *)_radio)->setBandwidth(bw); ((CustomLR1121 *)_radio)->setCodingRate(cr); updatePreamble(sf); + PacketMillis pm = calcMaxPacketMillis(sf, bw, cr, preambleLengthForSF(sf)); + ((CustomLR1121 *)_radio)->setPreambleMillis(pm.preambleMillis); + ((CustomLR1121 *)_radio)->setMaxPayloadMillis(pm.payloadMillis); } void doResetAGC() override { lr11x0ResetAGC((LR11x0 *)_radio, ((CustomLR1121 *)_radio)->getFreqMHz(), getRxBoostedGainMode()); }