From da32729e823393899e7b31c68803bbd73d807069 Mon Sep 17 00:00:00 2001 From: wanckl Date: Mon, 1 Sep 2025 16:58:35 +0800 Subject: [PATCH] feat(driver_spi): update p4 eco5 spi support on real chip --- components/esp_driver_spi/src/gpspi/spi_common.c | 3 ++- components/esp_driver_spi/src/gpspi/spi_master.c | 4 +--- components/esp_driver_spi/src/gpspi/spi_slave.c | 8 +++++++- components/hal/esp32/include/hal/spi_ll.h | 6 ++++++ components/hal/esp32p4/include/hal/spi_ll.h | 5 +++++ 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index a8b310a5dbe..3efbea76422 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -591,7 +591,8 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf } //set flags for DUAL mode according to output-capability of MOSI and MISO pins. if ((bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num)) && - (bus_config->miso_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->miso_io_num))) { + (bus_config->miso_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->miso_io_num)) && + (bus_config->miso_io_num != bus_config->mosi_io_num)) { temp_flag |= SPICOMMON_BUSFLAG_DUAL; } diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index 5869d8522da..c29605e4cbe 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -620,9 +620,7 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle) esp_err_t spi_device_get_actual_freq(spi_device_handle_t handle, int* freq_khz) { - if ((spi_device_t *)handle == NULL || freq_khz == NULL) { - return ESP_ERR_INVALID_ARG; - } + SPI_CHECK(handle && freq_khz, "invalid arg", ESP_ERR_INVALID_ARG); *freq_khz = handle->hal_dev.timing_conf.real_freq / 1000; return ESP_OK; diff --git a/components/esp_driver_spi/src/gpspi/spi_slave.c b/components/esp_driver_spi/src/gpspi/spi_slave.c index 749245ad228..debaf742238 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave.c @@ -100,20 +100,26 @@ static inline bool SPI_SLAVE_ISR_ATTR bus_is_iomux(spi_slave_t *host) return host->flags & SPICOMMON_BUSFLAG_IOMUX_PINS; } -static void SPI_SLAVE_ISR_ATTR freeze_cs(spi_slave_t *host) +static inline void SPI_SLAVE_ISR_ATTR freeze_cs(spi_slave_t *host) { +#if SPI_LL_SLAVE_NEEDS_CS_WORKAROUND + // This workaround only for ESP32 due to old hardware design, see MR !3207 esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, host->cs_in_signal, false); +#endif } // Use this function instead of cs_initial to avoid overwrite the output config // This is used in test by internal gpio matrix connections static inline void SPI_SLAVE_ISR_ATTR restore_cs(spi_slave_t *host) { +#if SPI_LL_SLAVE_NEEDS_CS_WORKAROUND + // This workaround only for ESP32 due to old hardware design, see MR !3207 if (host->cs_iomux) { gpio_ll_iomux_in(GPIO_HAL_GET_HW(GPIO_PORT_0), host->cfg.spics_io_num, host->cs_in_signal); } else { esp_rom_gpio_connect_in_signal(host->cfg.spics_io_num, host->cs_in_signal, false); } +#endif } #if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE) diff --git a/components/hal/esp32/include/hal/spi_ll.h b/components/hal/esp32/include/hal/spi_ll.h index 84113565176..b7f907877c1 100644 --- a/components/hal/esp32/include/hal/spi_ll.h +++ b/components/hal/esp32/include/hal/spi_ll.h @@ -44,6 +44,12 @@ extern "C" { #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words #define SPI_LL_MOSI_FREE_LEVEL 0 //Default level after bus initialized +// CS_WORKAROUND: SPI slave with using DMA, the rx dma suffers from unexpected transactions +// before slave is ready, need disconnect CS before and after each transaction +#define SPI_LL_SLAVE_NEEDS_CS_WORKAROUND 1 +#define SPI_LL_SLAVE_NEEDS_RESET_WORKAROUND 1 +#define SPI_LL_SUPPORT_TIME_TUNING 1 + /** * The data structure holding calculated clock configuration. Since the * calculation needs long time, it should be calculated during initialization and diff --git a/components/hal/esp32p4/include/hal/spi_ll.h b/components/hal/esp32p4/include/hal/spi_ll.h index 8e0d75cab9c..c056fad8955 100644 --- a/components/hal/esp32p4/include/hal/spi_ll.h +++ b/components/hal/esp32p4/include/hal/spi_ll.h @@ -247,6 +247,10 @@ static inline void spi_ll_master_init(spi_dev_t *hw) hw->slave.val = 0; hw->user.val = 0; + //Disable unused error_end condition + hw->user1.mst_wfull_err_end_en = 0; + hw->user2.mst_rempty_err_end_en = 0; + hw->dma_conf.val = 0; hw->dma_conf.slv_tx_seg_trans_clr_en = 1; hw->dma_conf.slv_rx_seg_trans_clr_en = 1; @@ -748,6 +752,7 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) *----------------------------------------------------------------------------*/ /** * Set the standard clock mode for master. + * This config take effect only when SPI_CLK (pre-div before periph) div >=2 * * @param hw Beginning address of the peripheral registers. * @param enable_std True for std timing, False for half cycle delay sampling.