Implement cold sleep for onboard SX1262 on RAK4630 when 13302 booster board is installed and report sleep state - #3241
Open
agessaman wants to merge 2 commits into
Conversation
A RAK4631 core paired with a RAK13302 leaves the core's own SX1262 powered but never initialized, idling in STDBY_RC for the life of the board. Firmware cannot cut its supply -- P1.05 is the RF switch rail, not the radio's -- so bring it up on its own pins just long enough to issue a cold sleep, before std_init() repins SPI onto the RAK13302. Gated behind RAK4631_ONBOARD_SX1262_SLEEP and exposed through seven RAK_4631_13302_* envs, so RAK_3401_* artifacts are unchanged. The sleep is issued regardless of what begin() returns: Module::init() runs first, so SPI stays usable even if TCXO calibration fails. NSS is then held high, since the SX1262 wakes on an NSS falling edge. Verified on RAK19007 + RAK4631 + RAK13302: begin=0 sleep=0, RAK13302 init clean (device_errors=0x0000), TX and RX both confirmed. The current saving itself is derived from the datasheet (600 uA STDBY_RC -> 160 nA cold sleep) and is not measured.
BUSY is driven low in STDBY_RC and high while asleep, so reading it either side of the sleep gives a non-invasive readback of the state the chip was found in and the state it was left in. Confirmed on hardware. This is what makes the sleep observable at all. The only other symptom of a failed sleep is ~600 uA, which is below what an inline USB meter can resolve, so without this a regression would be silent. It immediately earned itself: busy_before reads 0 on every boot, showing the cold sleep does not survive an MCU reset. GPIOs revert to input during reset, NSS stops being driven high, and the falling edge wakes the chip. The helper re-sleeps it, so this is self-healing, but it means the chip is never found already asleep.
agessaman
marked this pull request as ready for review
August 19, 2026 19:54
Contributor
Author
|
I implemented this with new envs for discoverability—a user with a 4631 wouldn't necessarily go looking for a 3401 firmware and know that it would work. But it could be implemented as a conditional check on the RAK3401 initialization. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(rak3401): cold-sleep the RAK4631's onboard SX1262 on RAK13302 builds
A RAK4631 core paired with a RAK13302 leaves the core's own SX1262 powered but never initialized—it idles in
STDBY_RCfor the life of the board. Firmware can't cut its supply (P1.05 is the RF switch rail, not the radio's), so this brings it up on its own pins just long enough to issue a cold sleep, beforestd_init()repins SPI onto the RAK13302.Gated behind
RAK4631_ONBOARD_SX1262_SLEEPand exposed through sevenRAK_4631_13302_*envs. RAK_3401_*` builds are untouched.Verified on RAK19007 + RAK4631 + RAK13302
begin=0 sleep=0— chip present, cold sleep accepteddevice_errors=0x0000, TX and RX both confirmedNot verified
The current saving is datasheet-derived, not measured: 600 µA
STDBY_RC→ 160 nA cold sleep. That's ~0.5 mA at a 5 V input, below what was resolvable here—the WisBlock LiPo charger dominates any USB-input reading. No current reduction is claimed.Notes
STDBY_RCand high while asleep, making the state observable—without it a failed sleep would be silent.