From fd639aa8eef11fe0acf425bf28326e8333c26f8f Mon Sep 17 00:00:00 2001 From: "Steven (Yang Minghui)" Date: Tue, 15 Sep 2026 20:43:46 +0800 Subject: [PATCH] fix(spi): remove idle compensation for data output inversion --- components/esp_driver_spi/include/driver/spi_common.h | 7 +++---- components/esp_driver_spi/src/gpspi/spi_master.c | 6 +----- .../test_apps/master/main/test_spi_master.c | 10 ++-------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/components/esp_driver_spi/include/driver/spi_common.h b/components/esp_driver_spi/include/driver/spi_common.h index d44c608effe..b0b3cfe8b3c 100644 --- a/components/esp_driver_spi/include/driver/spi_common.h +++ b/components/esp_driver_spi/include/driver/spi_common.h @@ -95,9 +95,8 @@ typedef spi_common_dma_t spi_dma_chan_t; * delay, which may cause incorrect read for >40MHz speeds. * * @note Be advised that the slave driver does not use the quadwp/quadhd lines and fields in spi_bus_config_t referring to these lines will be ignored and can thus safely be left uninitialized. - * @note When `SPICOMMON_BUSFLAG_DATA_OUT_INV` is set in `flags`, all configured bus signals are routed through the GPIO matrix. - * @note On ESP32, `data_io_default_level` only supports 0. When - `SPICOMMON_BUSFLAG_DATA_OUT_INV` is set, the idle data level is also inverted. + * @note Setting `SPICOMMON_BUSFLAG_DATA_OUT_INV` routes all configured bus signals through GPIO matrix and inverts data output signals, including their idle levels. + * @note On ESP32, `data_io_default_level` only supports 0. */ typedef struct { union { @@ -126,7 +125,7 @@ typedef struct { }; int iocfg[9]; ///< GPIO config in array format follow the above order. }; - bool data_io_default_level; ///< Output data IO default level when no transaction. + bool data_io_default_level; ///< Default level of output data signals when no transaction in progress. int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4092 if 0 when DMA enabled, or to hardware fifo length (usually 64 bytes) if DMA is disabled. uint32_t dma_burst_size; ///< DMA data burst size in bytes. Only used when DMA is enabled. Set to 0 to use driver default. When non-zero, must be one of the chip-supported values (see GDMA driver or chip TRM). Ignored on chips that do not support configurable burst size. uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags. diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index 164e3496c56..7b09f236cfc 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -331,11 +331,7 @@ static esp_err_t spi_master_init_driver(spi_host_device_t host_id) } spi_hal_init(&host->hal, host_id); - bool hal_idle_level = bus_attr->bus_cfg.data_io_default_level; - if (bus_attr->bus_cfg.flags & SPICOMMON_BUSFLAG_DATA_OUT_INV) { - hal_idle_level = !hal_idle_level; // Compensate for inversion set in GPIO Matrix - } - spi_hal_set_data_pin_idle_level(&host->hal, hal_idle_level); + spi_hal_set_data_pin_idle_level(&host->hal, bus_attr->bus_cfg.data_io_default_level); if (host_id != SPI1_HOST) { //SPI1 attributes are already initialized at start up. diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c index 8dc96635145..03a4d67b482 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c @@ -733,14 +733,8 @@ TEST_CASE("spi data output inversion", "[spi]") (unsigned)tx_data, (unsigned)rx_data, (unsigned)expected_rx_data); TEST_ASSERT_EQUAL_HEX8(expected_rx_data, rx_data); - /* Check the MOSI idle level after the transaction. */ - bool expected_idle_level = buscfg.data_io_default_level; -#if !SPI_LL_MOSI_FREE_LEVEL - if (invert) { - /* GPIO Matrix inversion also affects the idle level when the target cannot configure it. */ - expected_idle_level = !buscfg.data_io_default_level; - } -#endif + /* Check the MOSI idle level after the transaction. GPIO Matrix inversion affects the idle level also. */ + bool expected_idle_level = invert ? !buscfg.data_io_default_level : buscfg.data_io_default_level; int actual_idle_level = gpio_get_level(PIN_NUM_MOSI); ESP_LOGI(TAG, "Idle: MOSI=%d (expected=%d)", actual_idle_level, expected_idle_level);