Fix CoreS3 LCD not working on ESP-IDF v6 (SPI bus pins left in open-drain) - #251
Merged
Conversation
ESP-IDF v6 spi_bus_initialize() routes bus pins with gpio_matrix_output() and no longer clears the pad open-drain flag (v5 used gpio_set_direction(), which did). If the pads were previously configured as open-drain outputs (e.g. by the autodetect pull-up probing of the bus pins), SCLK/MOSI stay open-drain, the waveform cannot rise at MHz clock rates through the weak pull-up, and the panel never responds. Explicitly restore the bus pins to push-pull after bus initialization. Verified on M5Stack CoreS3SE: ESP-IDF v6.0.1 autodetect and draw/readRect round-trip now pass; no regression on ESP-IDF v5.5.4 (CoreS3SE) or M5StickS3 (v6.0.1).
…s in pinMode The pad_driver and func_out_sel register layouts are named differently on some chips (e.g. ESP32-C61), which required chip-specific #ifdef branches and SFINAE helpers. Delegate to gpio_ll_od_enable/od_disable and esp_rom_gpio_connect_out_signal, whose per-chip implementations absorb the naming differences, so future chips need no new branches here. Direct register access remains only as a fallback for ESP-IDF v3. esp_rom_gpio_connect_out_signal also normalizes the inv/oen matrix bits, which matches the intended plain-GPIO-output contract of pinMode. Build-verified on esp32s3 (ESP-IDF v5.5.4 / v6.0.1), esp32c61, esp32 (v5.5.4), and Arduino-ESP32 2.x (ESP-IDF v4.4); runtime-verified on M5Stack CoreS3SE with ESP-IDF v6.0.1.
There was a problem hiding this comment.
Pull request overview
Fixes CoreS3/CoreS3SE LCD failures on ESP-IDF v6 by ensuring SPI bus pins don’t remain in open-drain mode after prior pinMode(input_*) usage, and by reducing chip-specific register-field handling in pinMode() via ESP-IDF LL/ROM helpers.
Changes:
- Use
gpio_ll_od_enable/disable(when available) to manage open-drain configuration inpinMode()without chip-specific register-field branching. - Use
esp_rom_gpio_connect_out_signal()(when available) to restore GPIO output signal routing in a chip-agnostic way. - After
spi_bus_initialize(), explicitly force SPI SCLK/MOSI/MISO pads back to push-pull (disable open-drain) to avoid slow-rising edges on ESP-IDF v6.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #192
Root cause
On ESP-IDF v6, the CoreS3 / CoreS3SE display stops working (blank screen; with a cold NVS the board autodetection itself fails with
board=0). Three conditions combine:input_pullupto decide whether the SPI bus lines are externally pulled up. The internalpinMode()implements inputs as open-drain outputs driven high, which sets the pad'spad_driver(open-drain) flag.spi_bus_initialize()configured the bus pins viagpio_set_direction(..., GPIO_MODE_INPUT_OUTPUT), which cleared the open-drain flag as a side effect.gpio_matrix_output()only and no longer touchespad_driver(components/esp_driver_spi/src/gpspi/spi_common.c).As a result SCLK/MOSI remain open-drain. Through the weak pull-up the lines can no longer rise at MHz clock rates, so the panel never receives a valid command and
_read_panel_id()reads back all-ones. Register-level comparison between v5.5.4 and v6.0.1 shows the GPSPI2 block, GPIO matrix, and IO_MUX byte-identical — the only differing state isGPIO_PINn.pad_driverof GPIO36/37.Fix
spi_bus_initialize(). Harmless on all IDF versions (v5 and earlier already end up in this state).#ifdefbranches inpinMode()(pad_driver/func_out_sel) withgpio_ll_od_enable/od_disableandesp_rom_gpio_connect_out_signal, whose per-chip implementations absorb the register naming differences, so future chips need no new branches.Verification
readRectround-trip verification all pass (previously blank / autodetect failure)