Hold GC1109 FEM power during deep sleep for LNA RX wake (#9572)

* Hold GC1109 PA_POWER and PA_EN during deep sleep for LNA RX wake

Use rtc_gpio_hold_en to latch PA_POWER (LDO) and PA_EN (CSD) HIGH
during deep sleep so the GC1109 LNA remains powered for wake-on-packet
RX. Previously these pins used weak pull-ups which could lose state.

On deep sleep wake, skip these pins in the blanket RTC hold release and
instead release them in SX126xInterface::init() after GPIO registers are
set HIGH first, avoiding a power glitch on the GC1109.

Trade-off: ~6.5mA additional deep sleep current for significantly
improved wake-on-packet RX sensitivity (~17dB).

Reference: https://github.com/meshcore-dev/MeshCore/pull/1600

* Add LDO startup delay before GC1109 chip enable

TLV75733P LDO has ~550us startup time (datasheet tSTR). On cold boot,
wait 1ms for VBAT to stabilise before driving CSD/CPS, per GC1109
power-on sequence requirement. On deep sleep wake the LDO is held on
via RTC latch so no delay is needed.
This commit is contained in:
Wessel
2026-02-20 16:12:54 -06:00
committed by GitHub
co-authored by GitHub
parent 8c37d6923b
commit af518fbd2b
2 changed files with 37 additions and 2 deletions
+14 -2
View File
@@ -162,6 +162,13 @@ void initDeepSleep()
if (wakeCause != ESP_SLEEP_WAKEUP_UNDEFINED) {
LOG_DEBUG("Disable any holds on RTC IO pads");
for (uint8_t i = 0; i <= GPIO_NUM_MAX; i++) {
#if defined(USE_GC1109_PA)
// Skip GC1109 FEM power pins - they are held HIGH during deep sleep to keep
// the LNA active for RX wake. Released later in SX126xInterface::init() after
// GPIO registers are set HIGH first, avoiding a power glitch.
if (i == LORA_PA_POWER || i == LORA_PA_EN)
continue;
#endif
if (rtc_gpio_is_valid_gpio((gpio_num_t)i))
rtc_gpio_hold_dis((gpio_num_t)i);
@@ -556,8 +563,13 @@ void enableLoraInterrupt()
#endif
#if defined(USE_GC1109_PA)
gpio_pullup_en((gpio_num_t)LORA_PA_POWER);
gpio_pullup_en((gpio_num_t)LORA_PA_EN);
// Keep GC1109 FEM powered during deep sleep so LNA remains active for RX wake.
// Set PA_POWER and PA_EN HIGH (overrides SX126xInterface::sleep() shutdown),
// then latch with RTC hold so the state survives deep sleep.
digitalWrite(LORA_PA_POWER, HIGH);
rtc_gpio_hold_en((gpio_num_t)LORA_PA_POWER);
digitalWrite(LORA_PA_EN, HIGH);
rtc_gpio_hold_en((gpio_num_t)LORA_PA_EN);
gpio_pulldown_en((gpio_num_t)LORA_PA_TX_EN);
#endif