mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-03 01:33:50 +00:00
104 lines
5.9 KiB
Plaintext
104 lines
5.9 KiB
Plaintext
# ESP32 system power management — light sleep between events.
|
|
#
|
|
# AUTO-ENABLED for repeater builds on the DIO1-wake-capable Heltec boards; see
|
|
# the allowlist block in CMakeLists.txt for who qualifies and why the others
|
|
# must not. Passing it by hand is still supported for testing another board:
|
|
#
|
|
# west build -b heltec_wifi_lora32_v3/esp32s3/procpu zephcore --pristine -- \
|
|
# -DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/pm_esp32.conf"
|
|
#
|
|
# CONSOLE BEHAVIOUR — helpers/pm_esp32_console.c does two things without which
|
|
# light sleep makes a node unusable: it flushes the console UART before every
|
|
# sleep (Zephyr's PM path does not, so lines would be cut mid-character), and
|
|
# it blocks sleep for ZEPHCORE_PM_BOOT_AWAKE_MS (default 10 min) after boot so
|
|
# there is a guaranteed window to configure the node. AFTER THAT WINDOW THE USB
|
|
# CLI STOPS ANSWERING: nothing arms a UART wake source, so typed characters are
|
|
# dropped. Connecting a terminal usually resets the board (the USB bridge
|
|
# drives EN from DTR) which re-arms the window — but a terminal that does not
|
|
# toggle DTR needs a manual power cycle. Remote admin over LoRa is unaffected.
|
|
#
|
|
# Only Heltec V3 actually consoles on uart0. V4, V4.3 and Wireless Tracker V2
|
|
# choose usb_serial in board.overlay, and the uart0 reroute in
|
|
# boards/common/esp32s3_usb.overlay is companion-only, so a REPEATER build of
|
|
# those boards has a USB Serial/JTAG console. The flush above then targets a
|
|
# peripheral that is not their console and is inert, and the USJ peripheral
|
|
# drops off the bus in light sleep with no wake source in the HAL. Net effect
|
|
# on those three: no USB CLI at all after the boot window, rather than a CLI
|
|
# that merely ignores keystrokes. This is accepted so the boards stay in the
|
|
# field exercising light sleep — see the allowlist block in CMakeLists.txt.
|
|
#
|
|
# WiFi builds hold a pm_policy lock and never light-sleep at all — the OTA
|
|
# session takes one for its duration (adapters/ota/wifi_ota.c) and an uplink or
|
|
# observer station takes one permanently (adapters/wifi/ZephyrWiFiStation.c).
|
|
#
|
|
# What it buys: Espressif parts have no equivalent of the nRF52's "idle at
|
|
# microamps in WFI" — WAITI gates the core clock but leaves PLL, peripherals
|
|
# and RAM powered, so an idle ESP32 sits in the tens of mA. Light sleep is
|
|
# sub-mA. On a repeater that is the difference between the MCU dominating the
|
|
# power budget and the radio dominating it.
|
|
#
|
|
# REPEATERS ONLY. Do not pair this with a companion build. The Espressif HCI
|
|
# driver (drivers/bluetooth/hci/hci_esp32.c) takes no pm_policy locks, so
|
|
# nothing stops the SoC light-sleeping mid-advertising or mid-connection; the
|
|
# NXP driver does take them, Espressif's does not. repeater.conf sets
|
|
# CONFIG_BT=n, which removes the problem rather than papering over it.
|
|
#
|
|
# BOARD REQUIREMENT — DIO1 must be an RTC-capable GPIO. On ESP32-S3
|
|
# esp_sleep_is_valid_wakeup_gpio() reduces to RTC_GPIO_IS_VALID_GPIO(), i.e.
|
|
# GPIO 0-21. A board wiring DIO1 above that CANNOT wake on a received packet:
|
|
#
|
|
# OK heltec_wifi_lora32_v3 / v4 / v43, heltec_wireless_tracker(_v2)
|
|
# -> DIO1 = GPIO14
|
|
# NOT OK xiao_esp32s3 (GPIO39), station_g2 (GPIO48), thinknode_m9 (GPIO42),
|
|
# lilygo_tlora_c6 (GPIO23, outside the C6's LP range 0-7)
|
|
# N/A ttgo_lora32 -> SX127x; patch 0003 arms DIO1 in the sx126x driver
|
|
# only, so nothing marks the pin as a wake source at all
|
|
#
|
|
# On a NOT-OK board the driver logs "Pin N is not wakeup capable" at boot and
|
|
# the node will light-sleep straight through inbound packets while looking
|
|
# excellent on a current meter. Check that log line before trusting any
|
|
# measurement.
|
|
#
|
|
# PAD HOLD — light sleep powers down RTC_PERIPH, so every RTC-capable pad
|
|
# (GPIO 0-21, which is all of them on these boards) loses its level unless
|
|
# held. The paired overlay holds the SX1262 NSS and RESET; without that, a
|
|
# floating NSS lets the sleeping radio clock garbage into its own retention
|
|
# RAM and the node transmits ~30 dB down until the next reboot. The overlay
|
|
# hardcodes NSS GPIO8 / RESET GPIO12 / &spi2 — verify a new board matches
|
|
# before adding it to the allowlist below.
|
|
#
|
|
# Also required and supplied by the paired pm_esp32.overlay:
|
|
# - &rtc_timer enabled. soc/espressif/common/power.c refuses to sleep without
|
|
# it, logging "Sleep skipped. Make sure '&rtc_timer' is enabled as a wakeup
|
|
# source." — i.e. CONFIG_PM=y alone silently does nothing.
|
|
# - &gpio0 as a wakeup-source, so the driver's PM resume hook calls
|
|
# esp_sleep_enable_gpio_wakeup().
|
|
# And patches/zephyr/0003 marks DIO1 itself with GPIO_INT_WAKEUP.
|
|
#
|
|
# Kernel time is safe across sleep: the Xtensa/ESP32 timer drivers implement
|
|
# the LPM hooks (esp32_lptim_hook_on_lpm_entry/exit) that read the RTC counter
|
|
# and announce elapsed ticks, so k_uptime_get() and every maintenance deadline
|
|
# stay correct.
|
|
#
|
|
# NOT YET VALIDATED ON HARDWARE — and it is now auto-enabled, so this is the
|
|
# first thing to check if an allowlisted board misbehaves. Verify in this
|
|
# order: (1) no "not wakeup capable" line at boot, (2) the node still receives
|
|
# packets, (3) only then measure current. A deaf repeater is the expected
|
|
# failure and it is not obvious from the outside. To rule it out on a suspect
|
|
# unit, rebuild with -DCONFIG_PM=n.
|
|
|
|
CONFIG_PM=y
|
|
|
|
# The RTC timer is a COUNTER driver. Enabling the DT node alone is not enough:
|
|
# without the counter subsystem drivers/counter is never built, no device
|
|
# object is emitted, and power.c's DEVICE_DT_GET_OR_NULL(rtc_timer) fails to
|
|
# link ("undefined reference to __device_dts_ord_NN"). COUNTER_RTC_ESP32 is
|
|
# then default y off the enabled DT node.
|
|
CONFIG_COUNTER=y
|
|
|
|
# System-managed device PM stays off. prj.conf pins it off globally so that
|
|
# turning on CONFIG_PM cannot silently start suspending devices from the idle
|
|
# thread — that is the trap that historically killed GPS. Device suspends stay
|
|
# explicit (pm_device_action_run from the main thread).
|
|
CONFIG_PM_DEVICE_SYSTEM_MANAGED=n
|