Merge branch 'fix/spi_data_output_inversion_idle_level' into 'master'

fix(spi): remove idle compensation for data output inversion

See merge request espressif/esp-idf!52864
This commit is contained in:
Steven (Yang Minghui)
2026-09-16 13:14:04 +08:00
3 changed files with 6 additions and 17 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -732,14 +732,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);