Symptom
After machine.soft_reset() on a Waveshare ESP32-S3 Touch LCD 2, board init fails during machine.SPI.Bus() construction:
waveshare_esp32_s3_touch_lcd_2.py initialization
waveshare_esp32_s3_touch_lcd_2.py machine.SPI.Bus() initialization
Error initializing SPI bus: can't convert to int
Attempting hard reset in 3sec...
(Note the double space in convert to int — looks like an empty %s in the C-level error format.)
The existing try/except → machine.reset() workaround at waveshare_esp32_s3_touch_lcd_2.py:27-33 catches it and the device recovers via hard reset — so it's not blocking, just one wasted boot cycle on every soft-reset.
Environment
- Board: Waveshare ESP32-S3 Touch LCD 2
- MicroPythonOS: 0.10.0
- MicroPython: 1.27.0 (build
78ff170de9-dirty, 2026-05-18, _mpy=11014, _build=ESP32_GENERIC_S3-SPIRAM_OCT, _thread=GIL)
Repro
- Boot the device normally — board init succeeds.
- From
mpremote, run exec "import machine; machine.soft_reset()".
- Observe the error above. Device hard-resets after 3s and boots fine the second time.
Analysis
The board file's SPI call is consistent with every other MPOS board:
spi_bus = machine.SPI.Bus(host=SPI_BUS, mosi=LCD_MOSI, miso=LCD_MISO, sck=LCD_SCLK)
All other MPOS board files using machine.SPI.Bus (fri3d_2024, fri3d_2026, lilygo_t_hmi, lilygo_t_watch_s3_plus, m5stack_*, odroid_go, matouch_*, unphone) use the same kwarg pattern with integer values. The waveshare board is the only one that wraps the call in try/except + reset, suggesting somebody observed the failure on this board specifically.
Most likely root cause: stale ESP32 SPI peripheral state across soft-reset. ESP-IDF's spi_bus_initialize() returns ESP_ERR_INVALID_STATE if the host is already initialized, and the lvgl_micropython machine.SPI.Bus binding may not de-initialize the host on soft-reset. The "can't convert to int" likely comes from the binding mis-reporting an init error through mp_obj_get_int on an empty value.
If the root cause is in the lvgl_micropython binding, the fix likely belongs there (deinit-on-soft-reset, or an explicit .Bus.deinit() from the board file before re-init).
Possible directions
- Verify by adding
machine.SPI.Bus.deinit() (or equivalent) before the .Bus() call — if that fixes soft-reset, the real fix belongs in the binding.
- Improve the binding's error message so a bare "can't convert to int" reports something diagnostic.
- Document soft-reset as unsupported on this board, or have MPOS hard-reset transparently when a board's init needs it.
Happy to test patches on the device.
Symptom
After
machine.soft_reset()on a Waveshare ESP32-S3 Touch LCD 2, board init fails duringmachine.SPI.Bus()construction:(Note the double space in
convert to int— looks like an empty%sin the C-level error format.)The existing
try/except → machine.reset()workaround atwaveshare_esp32_s3_touch_lcd_2.py:27-33catches it and the device recovers via hard reset — so it's not blocking, just one wasted boot cycle on every soft-reset.Environment
78ff170de9-dirty, 2026-05-18,_mpy=11014,_build=ESP32_GENERIC_S3-SPIRAM_OCT,_thread=GIL)Repro
mpremote, runexec "import machine; machine.soft_reset()".Analysis
The board file's SPI call is consistent with every other MPOS board:
All other MPOS board files using
machine.SPI.Bus(fri3d_2024,fri3d_2026,lilygo_t_hmi,lilygo_t_watch_s3_plus,m5stack_*,odroid_go,matouch_*,unphone) use the same kwarg pattern with integer values. The waveshare board is the only one that wraps the call in try/except + reset, suggesting somebody observed the failure on this board specifically.Most likely root cause: stale ESP32 SPI peripheral state across soft-reset. ESP-IDF's
spi_bus_initialize()returnsESP_ERR_INVALID_STATEif the host is already initialized, and the lvgl_micropythonmachine.SPI.Busbinding may not de-initialize the host on soft-reset. The "can't convert to int" likely comes from the binding mis-reporting an init error throughmp_obj_get_inton an empty value.If the root cause is in the lvgl_micropython binding, the fix likely belongs there (deinit-on-soft-reset, or an explicit
.Bus.deinit()from the board file before re-init).Possible directions
machine.SPI.Bus.deinit()(or equivalent) before the.Bus()call — if that fixes soft-reset, the real fix belongs in the binding.Happy to test patches on the device.