Skip to content

Waveshare ESP32-S3 Touch LCD 2: SPI bus init fails on soft-reset ("can't convert to int") #143

@bitcoin3us

Description

@bitcoin3us

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

  1. Boot the device normally — board init succeeds.
  2. From mpremote, run exec "import machine; machine.soft_reset()".
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions