Summary
On MicroPython 1.29.0, import walter_modem fails on an ESP32-S3 (Walter) with:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/lib/walter_modem/__init__.py", line 1, in <module>
File "/lib/walter_modem/modem.py", line 3, in <module>
File "/lib/walter_modem/core.py", line 6, in <module>
ImportError: can't import name gpio_deep_sleep_hold
core.py imports the symbol at module scope:
from esp32 import gpio_deep_sleep_hold # core.py:6
so the failure is not confined to deep-sleep users — it takes down every import of the library, and with it any application module that imports it at startup.
Cause
ports/esp32/modesp32.c has guarded this function for several releases:
#if SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
The guard is unchanged between v1.28.0 and v1.29.0. What changed is the IDF underneath it: 1.29 builds against ESP-IDF v5.5.2, which sets SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP for the ESP32-S3. The whole-GPIO-bank hold is therefore compiled out on the S3, leaving only per-IO hold (Pin(..., hold=True) / gpio_hold_en()).
Reproduce
- Flash
ESP32_GENERIC_S3-20260824-v1.29.0.bin to a Walter.
- Install
walter_modem (any version through current main).
import walter_modem.
Works on v1.28.0, fails on v1.29.0.
Suggested fix
Guard the import, since ModemCore.__init__ is the only caller:
try:
from esp32 import gpio_deep_sleep_hold
except ImportError:
def gpio_deep_sleep_hold(_enable):
pass
Or, if the intent is to preserve pin state across deep sleep on newer builds, call gpio_hold_en() per pin (via Pin(..., hold=True)) where the bank hold is unavailable — the S3 supports the per-IO form.
Happy to send a PR for the guarded-import version if that's the direction you'd prefer.
Summary
On MicroPython 1.29.0,
import walter_modemfails on an ESP32-S3 (Walter) with:core.pyimports the symbol at module scope:so the failure is not confined to deep-sleep users — it takes down every import of the library, and with it any application module that imports it at startup.
Cause
ports/esp32/modesp32.chas guarded this function for several releases:The guard is unchanged between v1.28.0 and v1.29.0. What changed is the IDF underneath it: 1.29 builds against ESP-IDF v5.5.2, which sets
SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLPfor the ESP32-S3. The whole-GPIO-bank hold is therefore compiled out on the S3, leaving only per-IO hold (Pin(..., hold=True)/gpio_hold_en()).Reproduce
ESP32_GENERIC_S3-20260824-v1.29.0.binto a Walter.walter_modem(any version through currentmain).import walter_modem.Works on v1.28.0, fails on v1.29.0.
Suggested fix
Guard the import, since
ModemCore.__init__is the only caller:Or, if the intent is to preserve pin state across deep sleep on newer builds, call
gpio_hold_en()per pin (viaPin(..., hold=True)) where the bank hold is unavailable — the S3 supports the per-IO form.Happy to send a PR for the guarded-import version if that's the direction you'd prefer.