Environment
- Board: M5Stack CoreS3 (ESP32-S3, ILI9342C display)
- M5GFX branch:
master
- ESP-IDF version: v6.0.1
- Symptom: Display shows nothing — slight backlight glow, zero pixels, no crash
Board is detected correctly (board:10), M5.Display.width()/height() return 320×240,
AXP2101 DLDO1 is enabled (backlight on), but fillScreen() and all draw calls produce no output.
1. Wrong LCD RST pin on AW9523
rst_control() uses 1 << 5 (P1_5), but on CoreS3 hardware the LCD RST line is
connected to AW9523 P1_1 (1 << 1). The display never received a valid hardware reset.
// Current code:
uint8_t bits = level ? (1<<5) : 0;
// New :
static constexpr uint8_t lcd_rst_bit = 1 << 1; // AW9523B P1_1
uint8_t bits = level ? lcd_rst_bit : 0;
2. Direct SPI register access broken on ESP32-S3 + IDF 6.0
Writing SPI_USR | SPI_UPDATE directly to SPI_CMD_REG no longer reliably triggers transactions on ESP32-S3 with IDF 6.0. Commands reach the SPI data registers but the hardware does not clock them out.
Fix: use spi_device_polling_transmit() for ESP32-S3 + IDF ≥ 6.0:
#if defined (CONFIG_IDF_TARGET_ESP32S3) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0))
#define LGFX_SPI_USE_IDF_POLLING_TRANSMIT
#endif
All of writeCommand(), writeData(), writeDataRepeat(), writeBytes() need a new code path using spi_device_polling_transmit().
Required changes in spi::init() for this path:
devcfg.flags = 0 (remove SPI_DEVICE_3WIRE | SPI_DEVICE_HALFDUPLEX)
buscfg.max_transfer_sz = 4096
3. GPIO35 DC/MISO function select overridden by spi_bus_initialize()
GPIO35 is shared between LCD D/C (output) and SPI MISO (input). In IDF 6.0, spi_bus_initialize() connects GPIO35 to an SPI peripheral output signal via the GPIO matrix (GPIO_FUNC35_OUT_SEL_CFG_REG), silently overriding the D/C control written to PIO_OUT1_W1TS/TC_REG. Even with OEN=1, the peripheral drives the pin, so D/C is never toggled correctly.
Fix in cs_control() — reset the GPIO function select before toggling OEN:
void cs_control(bool flg) override
{
lgfx::Panel_ILI9342::cs_control(flg);
// Force GPIO35 back to simple GPIO output — IDF6 spi_bus_initialize()
// may have connected it to a peripheral output signal.
*(volatile uint32_t*)GPIO_FUNC35_OUT_SEL_CFG_REG = SIG_GPIO_OUT_IDX;
*(volatile uint32_t*)(flg ? GPIO_ENABLE1_W1TC_REG
: GPIO_ENABLE1_W1TS_REG) = 1u << (GPIO_NUM_35 & 31);
}
Additional changes for reliable operation
bus_cfg.pin_miso = GPIO_NUM_NC — decouple GPIO35 from spi_bus_initialize()
bus_cfg.spi_3wire = false
bus_cfg.spi_host = SPI3_HOST for CoreS3
Explicit hardware reset pulse via AW9523 before SPI init (LOW 20 ms → HIGH 120 ms)
freq_write = 10 MHz as safe starting frequency
Tested on M5Stack CoreS3, ESP-IDF v6.0.1, [https://github.com/wheelbot-tech/M5GFX/tree/idfv6.0]
Note
Root cause analysis and fix developed with assistance from Codex
Environment
masterBoard is detected correctly (
board:10),M5.Display.width()/height()return 320×240,AXP2101 DLDO1 is enabled (backlight on), but
fillScreen()and all draw calls produce no output.1. Wrong LCD RST pin on AW9523
rst_control()uses1 << 5(P1_5), but on CoreS3 hardware the LCD RST line isconnected to AW9523 P1_1 (
1 << 1). The display never received a valid hardware reset.2. Direct SPI register access broken on ESP32-S3 + IDF 6.0
Writing SPI_USR | SPI_UPDATE directly to SPI_CMD_REG no longer reliably triggers transactions on ESP32-S3 with IDF 6.0. Commands reach the SPI data registers but the hardware does not clock them out.
Fix: use spi_device_polling_transmit() for ESP32-S3 + IDF ≥ 6.0:
All of writeCommand(), writeData(), writeDataRepeat(), writeBytes() need a new code path using spi_device_polling_transmit().
Required changes in spi::init() for this path:
3. GPIO35 DC/MISO function select overridden by spi_bus_initialize()
GPIO35 is shared between LCD D/C (output) and SPI MISO (input). In IDF 6.0, spi_bus_initialize() connects GPIO35 to an SPI peripheral output signal via the GPIO matrix (GPIO_FUNC35_OUT_SEL_CFG_REG), silently overriding the D/C control written to PIO_OUT1_W1TS/TC_REG. Even with OEN=1, the peripheral drives the pin, so D/C is never toggled correctly.
Fix in cs_control() — reset the GPIO function select before toggling OEN:
Additional changes for reliable operation
bus_cfg.pin_miso = GPIO_NUM_NC — decouple GPIO35 from spi_bus_initialize()
bus_cfg.spi_3wire = false
bus_cfg.spi_host = SPI3_HOST for CoreS3
Explicit hardware reset pulse via AW9523 before SPI init (LOW 20 ms → HIGH 120 ms)
freq_write = 10 MHz as safe starting frequency
Tested on M5Stack CoreS3, ESP-IDF v6.0.1, [https://github.com/wheelbot-tech/M5GFX/tree/idfv6.0]
Note
Root cause analysis and fix developed with assistance from Codex