diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index 170a0b85ad..93e42cfb16 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,6 +67,7 @@ typedef struct adc_digi_context_t { gdma_channel_handle_t rx_dma_channel; //dma rx channel handle #elif CONFIG_IDF_TARGET_ESP32S2 spi_host_device_t spi_host; //ADC uses this SPI DMA + spi_dma_ctx_t *spi_dma_ctx; //spi_dma context intr_handle_t intr_hdl; //Interrupt handler #elif CONFIG_IDF_TARGET_ESP32 i2s_port_t i2s_host; //ADC uses this I2S DMA @@ -167,7 +168,7 @@ esp_err_t adc_digi_deinitialize(void) gdma_del_channel(s_adc_digi_ctx->rx_dma_channel); #elif CONFIG_IDF_TARGET_ESP32S2 esp_intr_free(s_adc_digi_ctx->intr_hdl); - spicommon_dma_chan_free(s_adc_digi_ctx->spi_host); + spicommon_dma_chan_free(s_adc_digi_ctx->spi_dma_ctx); spicommon_periph_free(s_adc_digi_ctx->spi_host); #elif CONFIG_IDF_TARGET_ESP32 esp_intr_free(s_adc_digi_ctx->intr_hdl); @@ -274,13 +275,14 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) uint32_t dma_chan = 0; spi_success = spicommon_periph_claim(SPI3_HOST, "adc"); - ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &dma_chan, &dma_chan); + ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &s_adc_digi_ctx->spi_dma_ctx); if (ret == ESP_OK) { s_adc_digi_ctx->spi_host = SPI3_HOST; } if (!spi_success || (s_adc_digi_ctx->spi_host != SPI3_HOST)) { goto cleanup; } + dma_chan = s_adc_digi_ctx->spi_dma_ctx->rx_dma_chan.chan_id; ret = esp_intr_alloc(spicommon_irqdma_source_for_host(s_adc_digi_ctx->spi_host), 0, adc_dma_intr_handler, (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl); diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 97208e0429..71d405ccb8 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -196,13 +196,14 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi uint32_t dma_chan = 0; spi_success = spicommon_periph_claim(SPI3_HOST, "adc"); - ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &dma_chan, &dma_chan); + ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &adc_ctx->spi_dma_ctx); if (ret == ESP_OK) { adc_ctx->spi_host = SPI3_HOST; } if (!spi_success || (adc_ctx->spi_host != SPI3_HOST)) { goto cleanup; } + dma_chan = adc_ctx->spi_dma_ctx->rx_dma_chan.chan_id; ret = esp_intr_alloc(spicommon_irqdma_source_for_host(adc_ctx->spi_host), ESP_INTR_FLAG_IRAM, adc_dma_intr_handler, (void *)adc_ctx, &adc_ctx->dma_intr_hdl); @@ -494,7 +495,7 @@ esp_err_t adc_continuous_deinit(adc_continuous_handle_t handle) gdma_del_channel(handle->rx_dma_channel); #elif CONFIG_IDF_TARGET_ESP32S2 esp_intr_free(handle->dma_intr_hdl); - spicommon_dma_chan_free(handle->spi_host); + spicommon_dma_chan_free(handle->spi_dma_ctx); spicommon_periph_free(handle->spi_host); #elif CONFIG_IDF_TARGET_ESP32 esp_intr_free(handle->dma_intr_hdl); diff --git a/components/esp_adc/adc_continuous_internal.h b/components/esp_adc/adc_continuous_internal.h index e78787ba97..64d6ad2a5f 100644 --- a/components/esp_adc/adc_continuous_internal.h +++ b/components/esp_adc/adc_continuous_internal.h @@ -19,6 +19,7 @@ #include "esp_private/gdma.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "hal/spi_types.h" +#include "esp_private/spi_common_internal.h" #elif CONFIG_IDF_TARGET_ESP32 #include "driver/i2s_types.h" #endif @@ -77,6 +78,7 @@ struct adc_continuous_ctx_t { gdma_channel_handle_t rx_dma_channel; //dma rx channel handle #elif CONFIG_IDF_TARGET_ESP32S2 spi_host_device_t spi_host; //ADC uses this SPI DMA + spi_dma_ctx_t *spi_dma_ctx; //spi_dma context #elif CONFIG_IDF_TARGET_ESP32 i2s_port_t i2s_host; //ADC uses this I2S DMA #endif diff --git a/components/esp_driver_dac/esp32s2/dac_dma.c b/components/esp_driver_dac/esp32s2/dac_dma.c index 6f40d03f22..6e715bc4dc 100644 --- a/components/esp_driver_dac/esp32s2/dac_dma.c +++ b/components/esp_driver_dac/esp32s2/dac_dma.c @@ -38,6 +38,7 @@ typedef struct { void *periph_dev; /* DMA peripheral device address */ uint32_t dma_chan; + spi_dma_ctx_t *spi_dma_ctx; /* spi_dma context */ intr_handle_t intr_handle; /* Interrupt handle */ bool use_apll; /* Whether use APLL as digital controller clock source */ } dac_dma_periph_spi_t; @@ -142,9 +143,10 @@ esp_err_t dac_dma_periph_init(uint32_t freq_hz, bool is_alternate, bool is_apll) /* When transmit alternately, twice frequency is needed to guarantee the convert frequency in one channel */ uint32_t trans_freq_hz = freq_hz * (is_alternate ? 2 : 1); ESP_GOTO_ON_ERROR(s_dac_dma_periph_set_clock(trans_freq_hz, is_apll), err, TAG, "Failed to set clock of DMA peripheral"); - ESP_GOTO_ON_ERROR(spicommon_dma_chan_alloc(DAC_DMA_PERIPH_SPI_HOST, SPI_DMA_CH_AUTO, &s_ddp->dma_chan, &s_ddp->dma_chan), + ESP_GOTO_ON_ERROR(spicommon_dma_chan_alloc(DAC_DMA_PERIPH_SPI_HOST, SPI_DMA_CH_AUTO, &s_ddp->spi_dma_ctx), err, TAG, "Failed to allocate dma peripheral channel"); + s_ddp->dma_chan = s_ddp->spi_dma_ctx->rx_dma_chan.chan_id; spi_ll_enable_intr(s_ddp->periph_dev, SPI_LL_INTR_OUT_EOF | SPI_LL_INTR_OUT_TOTAL_EOF); dac_ll_digi_set_convert_mode(is_alternate); return ret; @@ -157,7 +159,7 @@ esp_err_t dac_dma_periph_deinit(void) { ESP_RETURN_ON_FALSE(s_ddp->intr_handle == NULL, ESP_ERR_INVALID_STATE, TAG, "The interrupt is not deregistered yet"); if (s_ddp->dma_chan) { - ESP_RETURN_ON_ERROR(spicommon_dma_chan_free(DAC_DMA_PERIPH_SPI_HOST), TAG, "Failed to free dma peripheral channel"); + ESP_RETURN_ON_ERROR(spicommon_dma_chan_free(s_ddp->spi_dma_ctx), TAG, "Failed to free dma peripheral channel"); } ESP_RETURN_ON_FALSE(spicommon_periph_free(DAC_DMA_PERIPH_SPI_HOST), ESP_FAIL, TAG, "Failed to release DAC DMA peripheral"); spi_ll_disable_intr(s_ddp->periph_dev, SPI_LL_INTR_OUT_EOF | SPI_LL_INTR_OUT_TOTAL_EOF); diff --git a/components/esp_driver_spi/CMakeLists.txt b/components/esp_driver_spi/CMakeLists.txt index 38aa46cc61..a2c123ab76 100644 --- a/components/esp_driver_spi/CMakeLists.txt +++ b/components/esp_driver_spi/CMakeLists.txt @@ -11,7 +11,8 @@ set(public_include "include") if(CONFIG_SOC_GPSPI_SUPPORTED) list(APPEND srcs "src/gpspi/spi_common.c" "src/gpspi/spi_master.c" - "src/gpspi/spi_slave.c") + "src/gpspi/spi_slave.c" + "src/gpspi/spi_dma.c") endif() if(CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2) diff --git a/components/esp_driver_spi/include/esp_private/spi_common_internal.h b/components/esp_driver_spi/include/esp_private/spi_common_internal.h index 0b4a7ac68e..4652347593 100644 --- a/components/esp_driver_spi/include/esp_private/spi_common_internal.h +++ b/components/esp_driver_spi/include/esp_private/spi_common_internal.h @@ -13,7 +13,7 @@ #include "freertos/FreeRTOS.h" #include "hal/spi_types.h" #include "hal/dma_types.h" -#include "soc/gdma_channel.h" +#include "esp_private/spi_dma.h" #include "esp_pm.h" #include "esp_private/spi_share_hw_ctrl.h" #if SOC_GDMA_SUPPORTED @@ -37,14 +37,13 @@ extern "C" #define SPI_MASTER_ATTR #endif -#if SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB -#define DMA_DESC_MEM_ALIGN_SIZE 4 -#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel -typedef dma_descriptor_align4_t spi_dma_desc_t; -#else -#define DMA_DESC_MEM_ALIGN_SIZE 8 -#define SPI_GDMA_NEW_CHANNEL gdma_new_axi_channel +//NOTE!! If both A and B are not defined, '#if (A==B)' is true, because GCC use 0 stand for undefined symbol +#if SOC_GPSPI_SUPPORTED && defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) +#define DMA_DESC_MEM_ALIGN_SIZE 8 typedef dma_descriptor_align8_t spi_dma_desc_t; +#else +#define DMA_DESC_MEM_ALIGN_SIZE 4 +typedef dma_descriptor_align4_t spi_dma_desc_t; #endif /// Attributes of an SPI bus @@ -54,60 +53,64 @@ typedef struct { int max_transfer_sz; ///< Maximum length of bytes available to send bool dma_enabled; ///< To enable DMA or not uint16_t internal_mem_align_size; ///< Buffer align byte requirement for internal memory - int tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same - int rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same - int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx. - spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX - spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX spi_bus_lock_handle_t lock; #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; ///< Power management lock #endif } spi_bus_attr_t; +typedef struct { +#if SOC_GDMA_SUPPORTED + gdma_channel_handle_t tx_dma_chan; ///< GDMA tx channel + gdma_channel_handle_t rx_dma_chan; ///< GDMA rx channel +#else + spi_dma_chan_handle_t tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same + spi_dma_chan_handle_t rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same +#endif + int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx. + spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX + spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX +} spi_dma_ctx_t; + /// Destructor called when a bus is deinitialized. typedef esp_err_t (*spi_destroy_func_t)(void*); /** - * @brief Alloc DMA for SPI + * @brief Alloc DMA channel for SPI * - * @param host_id SPI host ID - * @param dma_chan DMA channel to be used - * @param[out] out_actual_tx_dma_chan Actual TX DMA channel (if you choose to assign a specific DMA channel, this will be the channel you assigned before) - * @param[out] out_actual_rx_dma_chan Actual RX DMA channel (if you choose to assign a specific DMA channel, this will be the channel you assigned before) + * @param host_id SPI host ID + * @param dma_chan DMA channel to be used + * @param out_dma_ctx Actual DMA channel context (if you choose to assign a specific DMA channel, this will be the channel you assigned before) * * @return * - ESP_OK: On success * - ESP_ERR_NO_MEM: No enough memory * - ESP_ERR_NOT_FOUND: There is no available DMA channel */ -esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan); +esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t **out_dma_ctx); + +/** + * @brief Alloc DMA descriptors for SPI + * + * @param dma_ctx DMA context returned by `spicommon_dma_chan_alloc` + * @param[in] cfg_max_sz Expected maximum transfer size, in bytes. + * @param[out] actual_max_sz Actual max transfer size one transaction can be, in bytes. + * + * @return + * - ESP_OK: On success + * - ESP_ERR_NO_MEM: No enough memory + */ +esp_err_t spicommon_dma_desc_alloc(spi_dma_ctx_t *dma_ctx, int cfg_max_sz, int *actual_max_sz); /** * @brief Free DMA for SPI * - * @param host_id SPI host ID + * @param dma_ctx spi_dma_ctx_t struct pointer * * @return * - ESP_OK: On success */ -esp_err_t spicommon_dma_chan_free(spi_host_device_t host_id); - -#if SOC_GDMA_SUPPORTED -/** - * @brief Get SPI GDMA Handle for GMDA Supported Chip - * - * @param host_id SPI host ID - * @param gdma_handle GDMA Handle to Return - * @param gdma_direction GDMA Channel Direction in Enum - * - GDMA_CHANNEL_DIRECTION_TX - * - GDMA_CHANNEL_DIRECTION_RX - * - * @return - * - ESP_OK: On success - */ -esp_err_t spicommon_gdma_get_handle(spi_host_device_t host_id, gdma_channel_handle_t *gdma_handle, gdma_channel_direction_t gdma_direction); -#endif +esp_err_t spicommon_dma_chan_free(spi_dma_ctx_t *dma_ctx); /** * @brief Connect a SPI peripheral to GPIO pins @@ -272,6 +275,14 @@ void spi_bus_main_set_lock(spi_bus_lock_handle_t lock); */ const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id); +/** + * @brief Get the dma context of a specified SPI bus. + * + * @param host_id The specified host to get attribute + * @return (Const) Pointer to the dma context + */ +const spi_dma_ctx_t* spi_bus_get_dma_ctx(spi_host_device_t host_id); + /** * @brief Register a function to a initialized bus to make it called when deinitializing the bus. * diff --git a/components/esp_driver_spi/include/esp_private/spi_dma.h b/components/esp_driver_spi/include/esp_private/spi_dma.h new file mode 100644 index 0000000000..39ff2c3c8f --- /dev/null +++ b/components/esp_driver_spi/include/esp_private/spi_dma.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "stdbool.h" +#include "hal/spi_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !SOC_GDMA_SUPPORTED +/** + * @brief Enumeration of SPI_DMA channel direction + */ +typedef enum { + DMA_CHANNEL_DIRECTION_TX, /*!< DMA channel direction: TX */ + DMA_CHANNEL_DIRECTION_RX, /*!< DMA channel direction: RX */ +} spi_dma_chan_dir_t; + +typedef struct { + spi_host_device_t host_id; + spi_dma_chan_dir_t dir; + int chan_id; +} spi_dma_chan_handle_t; + +/** + * Enable/Disable data/desc burst for spi_dma channel + * + * @param chan_handle Context of the spi_dma channel. + * @param data_burst enable or disable data burst + * @param desc_burst enable or disable desc burst + */ +void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bool desc_burst); + +/** + * Reset dma channel for spi_dma + * + * @param chan_handle Context of the spi_dma channel. + */ +void spi_dma_reset(spi_dma_chan_handle_t chan_handle); + +/** + * Start dma channel for spi_dma + * + * @param chan_handle Context of the spi_dma channel. + * @param addr Addr of linked dma descriptor to mount + */ +void spi_dma_start(spi_dma_chan_handle_t chan_handle, void *addr); + +#endif //!SOC_GDMA_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_spi/linker.lf b/components/esp_driver_spi/linker.lf index e69de29bb2..fe92562a6b 100644 --- a/components/esp_driver_spi/linker.lf +++ b/components/esp_driver_spi/linker.lf @@ -0,0 +1,7 @@ +[mapping:gpspi_driver] +archive: libesp_driver_spi.a +entries: + if SOC_GDMA_SUPPORTED = n: + if SPI_MASTER_ISR_IN_IRAM = y || SPI_SLAVE_ISR_IN_IRAM = y: + spi_dma: spi_dma_reset (noflash) + spi_dma: spi_dma_start (noflash) diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 787c227cbe..981cd19ab5 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -10,6 +10,7 @@ #include "esp_types.h" #include "esp_attr.h" #include "esp_check.h" +#include "esp_cache.h" #include "esp_rom_gpio.h" #include "esp_heap_caps.h" #include "soc/spi_periph.h" @@ -18,6 +19,7 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/spi_common_internal.h" #include "esp_private/spi_share_hw_ctrl.h" +#include "esp_private/esp_cache_private.h" #include "hal/spi_hal.h" #include "hal/gpio_hal.h" #if CONFIG_IDF_TARGET_ESP32 @@ -25,8 +27,6 @@ #endif #if SOC_GDMA_SUPPORTED #include "esp_private/gdma.h" -#include "hal/cache_hal.h" -#include "hal/cache_ll.h" #endif static const char *SPI_TAG = "spi"; @@ -42,10 +42,7 @@ static const char *SPI_TAG = "spi"; #define SPI_MAIN_BUS_DEFAULT() { \ .host_id = 0, \ .bus_attr = { \ - .tx_dma_chan = 0, \ - .rx_dma_chan = 0, \ .max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE, \ - .dma_desc_num= 0, \ }, \ } @@ -56,6 +53,7 @@ typedef struct { spi_destroy_func_t destroy_func; void* destroy_arg; spi_bus_attr_t bus_attr; + spi_dma_ctx_t *dma_ctx; #if SOC_GDMA_SUPPORTED gdma_channel_handle_t tx_channel; gdma_channel_handle_t rx_channel; @@ -75,11 +73,19 @@ static __attribute__((constructor)) void spi_bus_lock_init_main_bus(void) } #endif -#if !SOC_GDMA_SUPPORTED +#if SOC_GDMA_SUPPORTED +//NOTE!! If both A and B are not defined, '#if (A==B)' is true, because GCC use 0 stand for undefined symbol +#if defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) +#define SPI_GDMA_NEW_CHANNEL gdma_new_axi_channel +#elif defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) +#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel +#endif + +#else //Each bit stands for 1 dma channel, BIT(0) should be used for SPI1 static uint8_t spi_dma_chan_enabled = 0; static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED; -#endif //#if !SOC_GDMA_SUPPORTED +#endif //!SOC_GDMA_SUPPORTED static inline bool is_valid_host(spi_host_device_t host) { @@ -157,7 +163,7 @@ static void connect_spi_and_dma(spi_host_device_t host, int dma_chan) #endif } -static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan) +static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t *dma_ctx) { assert(is_valid_host(host_id)); #if CONFIG_IDF_TARGET_ESP32 @@ -187,60 +193,66 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch } //On ESP32 and ESP32S2, actual_tx_dma_chan and actual_rx_dma_chan are always same - *out_actual_tx_dma_chan = actual_dma_chan; - *out_actual_rx_dma_chan = actual_dma_chan; + dma_ctx->tx_dma_chan.chan_id = actual_dma_chan; + dma_ctx->rx_dma_chan.chan_id = actual_dma_chan; + dma_ctx->tx_dma_chan.host_id = host_id; + dma_ctx->rx_dma_chan.host_id = host_id; + dma_ctx->tx_dma_chan.dir = DMA_CHANNEL_DIRECTION_TX; + dma_ctx->rx_dma_chan.dir = DMA_CHANNEL_DIRECTION_RX; if (!success) { SPI_CHECK(false, "no available dma channel", ESP_ERR_NOT_FOUND); } + connect_spi_and_dma(host_id, actual_dma_chan); - connect_spi_and_dma(host_id, *out_actual_tx_dma_chan); - + spi_dma_enable_burst(dma_ctx->tx_dma_chan, true, true); + spi_dma_enable_burst(dma_ctx->rx_dma_chan, true, true); return ret; } #else //SOC_GDMA_SUPPORTED -static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan) +static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t *dma_ctx) { assert(is_valid_host(host_id)); assert(dma_chan == SPI_DMA_CH_AUTO); - esp_err_t ret = ESP_OK; - spicommon_bus_context_t *ctx = bus_ctx[host_id]; if (dma_chan == SPI_DMA_CH_AUTO) { gdma_channel_alloc_config_t tx_alloc_config = { .flags.reserve_sibling = 1, .direction = GDMA_CHANNEL_DIRECTION_TX, }; - ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&tx_alloc_config, &ctx->tx_channel), SPI_TAG, "alloc gdma tx failed"); + ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&tx_alloc_config, &dma_ctx->tx_dma_chan), SPI_TAG, "alloc gdma tx failed"); gdma_channel_alloc_config_t rx_alloc_config = { .direction = GDMA_CHANNEL_DIRECTION_RX, - .sibling_chan = ctx->tx_channel, + .sibling_chan = dma_ctx->tx_dma_chan, }; - ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&rx_alloc_config, &ctx->rx_channel), SPI_TAG, "alloc gdma rx failed"); + ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&rx_alloc_config, &dma_ctx->rx_dma_chan), SPI_TAG, "alloc gdma rx failed"); if (host_id == SPI2_HOST) { - gdma_connect(ctx->rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); - gdma_connect(ctx->tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); + gdma_connect(dma_ctx->tx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); + gdma_connect(dma_ctx->rx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); } #if (SOC_SPI_PERIPH_NUM >= 3) else if (host_id == SPI3_HOST) { - gdma_connect(ctx->rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); - gdma_connect(ctx->tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); + gdma_connect(dma_ctx->tx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); + gdma_connect(dma_ctx->rx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); } #endif - gdma_get_channel_id(ctx->tx_channel, (int *)out_actual_tx_dma_chan); - gdma_get_channel_id(ctx->rx_channel, (int *)out_actual_rx_dma_chan); + gdma_transfer_ability_t ability = { + .psram_trans_align = 0, // fall back to use the same size of the psram data cache line size + .sram_trans_align = 4, + }; + ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->tx_dma_chan, &ability), SPI_TAG, "set gdma tx transfer ability failed"); + ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->rx_dma_chan, &ability), SPI_TAG, "set gdma rx transfer ability failed"); } - return ret; } #endif //#if !SOC_GDMA_SUPPORTED -esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan) +esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t **out_dma_ctx) { assert(is_valid_host(host_id)); #if CONFIG_IDF_TARGET_ESP32 @@ -250,60 +262,56 @@ esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma #endif esp_err_t ret = ESP_OK; - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; - spicommon_bus_context_t *ctx = (spicommon_bus_context_t *)calloc(1, sizeof(spicommon_bus_context_t)); - if (!ctx) { + spi_dma_ctx_t *dma_ctx = (spi_dma_ctx_t *)calloc(1, sizeof(spi_dma_ctx_t)); + if (!dma_ctx) { ret = ESP_ERR_NO_MEM; goto cleanup; } - bus_ctx[host_id] = ctx; - ctx->host_id = host_id; - ret = alloc_dma_chan(host_id, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + ret = alloc_dma_chan(host_id, dma_chan, dma_ctx); if (ret != ESP_OK) { goto cleanup; } - ctx->bus_attr.tx_dma_chan = actual_tx_dma_chan; - ctx->bus_attr.rx_dma_chan = actual_rx_dma_chan; - *out_actual_tx_dma_chan = actual_tx_dma_chan; - *out_actual_rx_dma_chan = actual_rx_dma_chan; - + *out_dma_ctx = dma_ctx; return ret; cleanup: - free(ctx); - ctx = NULL; + free(dma_ctx); return ret; } -#if SOC_GDMA_SUPPORTED -esp_err_t spicommon_gdma_get_handle(spi_host_device_t host_id, gdma_channel_handle_t *gdma_handle, gdma_channel_direction_t gdma_direction) +esp_err_t spicommon_dma_desc_alloc(spi_dma_ctx_t *dma_ctx, int cfg_max_sz, int *actual_max_sz) { - assert(is_valid_host(host_id)); - ESP_RETURN_ON_FALSE((gdma_direction == GDMA_CHANNEL_DIRECTION_TX) || \ - (gdma_direction == GDMA_CHANNEL_DIRECTION_RX), \ - ESP_ERR_INVALID_ARG, SPI_TAG, "GDMA Direction not supported!"); + int dma_desc_ct = (cfg_max_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; + if (dma_desc_ct == 0) { + dma_desc_ct = 1; //default to 4k when max is not given + } - if (gdma_direction == GDMA_CHANNEL_DIRECTION_TX) { - *gdma_handle = bus_ctx[host_id]->tx_channel; - } - if (gdma_direction == GDMA_CHANNEL_DIRECTION_RX) { - *gdma_handle = bus_ctx[host_id]->rx_channel; + dma_ctx->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + dma_ctx->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + if (dma_ctx->dmadesc_tx == NULL || dma_ctx->dmadesc_rx == NULL) { + if (dma_ctx->dmadesc_tx) { + free(dma_ctx->dmadesc_tx); + dma_ctx->dmadesc_tx = NULL; + } + if (dma_ctx->dmadesc_rx) { + free(dma_ctx->dmadesc_rx); + dma_ctx->dmadesc_rx = NULL; + } + return ESP_ERR_NO_MEM; } + dma_ctx->dma_desc_num = dma_desc_ct; + *actual_max_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; return ESP_OK; } -#endif // SOC_GDMA_SUPPORTED - //----------------------------------------------------------free dma periph-------------------------------------------------------// -static esp_err_t dma_chan_free(spi_host_device_t host_id) +esp_err_t spicommon_dma_chan_free(spi_dma_ctx_t *dma_ctx) { - assert(is_valid_host(host_id)); + assert(dma_ctx); - spicommon_bus_context_t *ctx = bus_ctx[host_id]; #if !SOC_GDMA_SUPPORTED //On ESP32S2, each SPI controller has its own DMA channel - int dma_chan = ctx->bus_attr.tx_dma_chan; + int dma_chan = dma_ctx->tx_dma_chan.chan_id; assert(spi_dma_chan_enabled & BIT(dma_chan)); portENTER_CRITICAL(&spi_dma_spinlock); @@ -311,41 +319,31 @@ static esp_err_t dma_chan_free(spi_host_device_t host_id) #if SPI_LL_DMA_SHARED PERIPH_RCC_RELEASE_ATOMIC(get_dma_periph(dma_chan), ref_count) { if (ref_count == 0) { - spi_dma_ll_enable_bus_clock(host_id, false); + spi_dma_ll_enable_bus_clock(dma_ctx->tx_dma_chan.host_id, false); } } #else SPI_COMMON_RCC_CLOCK_ATOMIC() { - spi_dma_ll_enable_bus_clock(host_id, false); + spi_dma_ll_enable_bus_clock(dma_ctx->tx_dma_chan.host_id, false); } #endif portEXIT_CRITICAL(&spi_dma_spinlock); #else //SOC_GDMA_SUPPORTED - if (ctx->rx_channel) { - gdma_disconnect(ctx->rx_channel); - gdma_del_channel(ctx->rx_channel); + if (dma_ctx->rx_dma_chan) { + gdma_disconnect(dma_ctx->rx_dma_chan); + gdma_del_channel(dma_ctx->rx_dma_chan); } - if (ctx->tx_channel) { - gdma_disconnect(ctx->tx_channel); - gdma_del_channel(ctx->tx_channel); + if (dma_ctx->tx_dma_chan) { + gdma_disconnect(dma_ctx->tx_dma_chan); + gdma_del_channel(dma_ctx->tx_dma_chan); } #endif + free(dma_ctx); return ESP_OK; } -esp_err_t spicommon_dma_chan_free(spi_host_device_t host_id) -{ - assert(is_valid_host(host_id)); - - esp_err_t ret = dma_chan_free(host_id); - free(bus_ctx[host_id]); - bus_ctx[host_id] = NULL; - - return ret; -} - //----------------------------------------------------------IO general-------------------------------------------------------// #if SOC_SPI_SUPPORT_OCT static bool check_iomux_pins_oct(spi_host_device_t host, const spi_bus_config_t* bus_config) @@ -757,8 +755,6 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * esp_err_t err = ESP_OK; spicommon_bus_context_t *ctx = NULL; spi_bus_attr_t *bus_attr = NULL; - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; SPI_CHECK(is_valid_host(host_id), "invalid host_id", ESP_ERR_INVALID_ARG); SPI_CHECK(bus_ctx[host_id] == NULL, "SPI bus already initialized.", ESP_ERR_INVALID_STATE); @@ -791,35 +787,22 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * if (dma_chan != SPI_DMA_DISABLED) { bus_attr->dma_enabled = 1; - err = alloc_dma_chan(host_id, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + err = spicommon_dma_chan_alloc(host_id, dma_chan, &ctx->dma_ctx); if (err != ESP_OK) { goto cleanup; } - bus_attr->tx_dma_chan = actual_tx_dma_chan; - bus_attr->rx_dma_chan = actual_rx_dma_chan; - - int dma_desc_ct = (bus_config->max_transfer_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - if (dma_desc_ct == 0) { - dma_desc_ct = 1; //default to 4k when max is not given - } - - bus_attr->max_transfer_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - bus_attr->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - bus_attr->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - if (bus_attr->dmadesc_tx == NULL || bus_attr->dmadesc_rx == NULL) { - err = ESP_ERR_NO_MEM; + err = spicommon_dma_desc_alloc(ctx->dma_ctx, bus_config->max_transfer_sz, &bus_attr->max_transfer_sz); + if (err != ESP_OK) { goto cleanup; } - bus_attr->dma_desc_num = dma_desc_ct; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - bus_attr->internal_mem_align_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, (size_t *)&bus_attr->internal_mem_align_size); #else bus_attr->internal_mem_align_size = 4; #endif } else { bus_attr->dma_enabled = 0; bus_attr->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; - bus_attr->dma_desc_num = 0; } spi_bus_lock_config_t lock_config = { @@ -854,12 +837,11 @@ cleanup: if (bus_attr->lock) { spi_bus_deinit_lock(bus_attr->lock); } - free(bus_attr->dmadesc_tx); - free(bus_attr->dmadesc_rx); - bus_attr->dmadesc_tx = NULL; - bus_attr->dmadesc_rx = NULL; - if (bus_attr->dma_enabled) { - dma_chan_free(host_id); + if (ctx->dma_ctx) { + free(ctx->dma_ctx->dmadesc_tx); + free(ctx->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(ctx->dma_ctx); + ctx->dma_ctx = NULL; } } spicommon_periph_free(host_id); @@ -877,6 +859,15 @@ const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id) return &bus_ctx[host_id]->bus_attr; } +const spi_dma_ctx_t* spi_bus_get_dma_ctx(spi_host_device_t host_id) +{ + if (bus_ctx[host_id] == NULL) { + return NULL; + } + + return bus_ctx[host_id]->dma_ctx; +} + esp_err_t spi_bus_free(spi_host_device_t host_id) { if (bus_ctx[host_id] == NULL) { @@ -890,19 +881,17 @@ esp_err_t spi_bus_free(spi_host_device_t host_id) if (ctx->destroy_func) { err = ctx->destroy_func(ctx->destroy_arg); } - spicommon_bus_free_io_cfg(&bus_attr->bus_cfg); #ifdef CONFIG_PM_ENABLE esp_pm_lock_delete(bus_attr->pm_lock); #endif spi_bus_deinit_lock(bus_attr->lock); - free(bus_attr->dmadesc_rx); - free(bus_attr->dmadesc_tx); - bus_attr->dmadesc_tx = NULL; - bus_attr->dmadesc_rx = NULL; - if (bus_attr->dma_enabled > 0) { - dma_chan_free(host_id); + if (ctx->dma_ctx) { + free(ctx->dma_ctx->dmadesc_tx); + free(ctx->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(ctx->dma_ctx); + ctx->dma_ctx = NULL; } spicommon_periph_free(host_id); free(ctx); diff --git a/components/esp_driver_spi/src/gpspi/spi_dma.c b/components/esp_driver_spi/src/gpspi/spi_dma.c new file mode 100644 index 0000000000..4d258602e6 --- /dev/null +++ b/components/esp_driver_spi/src/gpspi/spi_dma.c @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/spi_dma.h" +#include "hal/spi_ll.h" + +#if !SOC_GDMA_SUPPORTED +void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bool desc_burst) +{ + spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id); + + if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) { + spi_dma_ll_tx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst); + spi_dma_ll_tx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst); + } else { + spi_dma_ll_rx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst); + spi_dma_ll_rx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst); + } +} + +/************************************* IRAM CONTEXT **************************************/ + +void spi_dma_reset(spi_dma_chan_handle_t chan_handle) +{ + spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id); + + if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) { + spi_dma_ll_tx_reset(spi_dma, chan_handle.chan_id); + } else { + spi_dma_ll_rx_reset(spi_dma, chan_handle.chan_id); + } +} + +void spi_dma_start(spi_dma_chan_handle_t chan_handle, void *addr) +{ + spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id); + + if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) { + spi_dma_ll_tx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr); + } else { + spi_dma_ll_rx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr); + } +} +#endif diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index b29f55e9c9..5ae4d1a803 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -149,6 +149,7 @@ typedef struct { spi_trans_priv_t cur_trans_buf; int cur_cs; //current device doing transaction const spi_bus_attr_t* bus_attr; + const spi_dma_ctx_t *dma_ctx; /** * the bus is permanently controlled by a device until `spi_bus_release_bus`` is called. Otherwise @@ -221,6 +222,7 @@ static esp_err_t spi_master_init_driver(spi_host_device_t host_id) esp_err_t err = ESP_OK; const spi_bus_attr_t* bus_attr = spi_bus_get_attr(host_id); + const spi_dma_ctx_t *dma_ctx = spi_bus_get_dma_ctx(host_id); SPI_CHECK(bus_attr != NULL, "host_id not initialized", ESP_ERR_INVALID_STATE); SPI_CHECK(bus_attr->lock != NULL, "SPI Master cannot attach to bus. (Check CONFIG_SPI_FLASH_SHARE_SPI1_BUS)", ESP_ERR_INVALID_ARG); // spihost contains atomic variables, which should not be put in PSRAM @@ -236,6 +238,7 @@ static esp_err_t spi_master_init_driver(spi_host_device_t host_id) .polling = false, .device_acquiring_lock = NULL, .bus_attr = bus_attr, + .dma_ctx = dma_ctx, }; // interrupts are not allowed on SPI1 bus @@ -259,17 +262,24 @@ static esp_err_t spi_master_init_driver(spi_host_device_t host_id) } //assign the SPI, RX DMA and TX DMA peripheral registers beginning address - spi_hal_config_t hal_config = { + spi_hal_config_t hal_config = { .dma_enabled = bus_attr->dma_enabled, }; + if (bus_attr->dma_enabled && dma_ctx) { + hal_config.dmadesc_tx = dma_ctx->dmadesc_tx; + hal_config.dmadesc_rx = dma_ctx->dmadesc_rx; + hal_config.dmadesc_n = dma_ctx->dma_desc_num; +#if SOC_GDMA_SUPPORTED + //temporary used for gdma_ll alias in hal layer + gdma_get_channel_id(dma_ctx->tx_dma_chan, (int *)&hal_config.tx_dma_chan); + gdma_get_channel_id(dma_ctx->rx_dma_chan, (int *)&hal_config.rx_dma_chan); +#else //On ESP32-S2 and earlier chips, DMA registers are part of SPI registers. Pass the registers of SPI peripheral to control it. - .dma_in = SPI_LL_GET_HW(host_id), - .dma_out = SPI_LL_GET_HW(host_id), - .dma_enabled = bus_attr->dma_enabled, - .dmadesc_tx = bus_attr->dmadesc_tx, - .dmadesc_rx = bus_attr->dmadesc_rx, - .tx_dma_chan = bus_attr->tx_dma_chan, - .rx_dma_chan = bus_attr->rx_dma_chan, - .dmadesc_n = bus_attr->dma_desc_num, - }; + hal_config.dma_in = SPI_LL_GET_HW(host_id); + hal_config.dma_out = SPI_LL_GET_HW(host_id); + hal_config.tx_dma_chan = dma_ctx->tx_dma_chan.chan_id; + hal_config.rx_dma_chan = dma_ctx->rx_dma_chan.chan_id; +#endif + } + SPI_MASTER_PERI_CLOCK_ATOMIC() { spi_ll_enable_clock(host_id, true); } @@ -633,8 +643,8 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_ spi_hal_trans_config_t hal_trans = {}; hal_trans.tx_bitlen = trans->length; hal_trans.rx_bitlen = trans->rxlength; - hal_trans.rcv_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_rcv; - hal_trans.send_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_send; + hal_trans.rcv_buffer = (uint8_t*)trans_buf->buffer_to_rcv; + hal_trans.send_buffer = (uint8_t*)trans_buf->buffer_to_send; hal_trans.cmd = trans->cmd; hal_trans.addr = trans->addr; hal_trans.cs_keep_active = (trans->flags & SPI_TRANS_CS_KEEP_ACTIVE) ? 1 : 0; @@ -699,6 +709,10 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) BaseType_t do_yield = pdFALSE; spi_host_t *host = (spi_host_t *)arg; const spi_bus_attr_t* bus_attr = host->bus_attr; +#if CONFIG_IDF_TARGET_ESP32 + //only for esp32 dma workaround usage + const spi_dma_ctx_t *dma_ctx = host->dma_ctx; +#endif assert(spi_hal_usr_is_done(&host->hal)); @@ -720,7 +734,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) if (bus_attr->dma_enabled) { #if CONFIG_IDF_TARGET_ESP32 //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_idle(bus_attr->tx_dma_chan); + spicommon_dmaworkaround_idle(dma_ctx->tx_dma_chan.chan_id); #endif //#if CONFIG_IDF_TARGET_ESP32 #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible @@ -793,7 +807,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) if (bus_attr->dma_enabled && (cur_trans_buf->buffer_to_rcv || cur_trans_buf->buffer_to_send)) { //mark channel as active, so that the DMA will not be reset by the slave //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_transfer_active(bus_attr->tx_dma_chan); + spicommon_dmaworkaround_transfer_active(dma_ctx->tx_dma_chan.chan_id); } #endif //#if CONFIG_IDF_TARGET_ESP32 spi_new_trans(device_to_send, cur_trans_buf); @@ -1081,7 +1095,7 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_acquire_bus(spi_device_t *device, TickT #if CONFIG_IDF_TARGET_ESP32 if (host->bus_attr->dma_enabled) { //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_transfer_active(host->bus_attr->tx_dma_chan); + spicommon_dmaworkaround_transfer_active(host->dma_ctx->tx_dma_chan.chan_id); } #endif //#if CONFIG_IDF_TARGET_ESP32 @@ -1101,7 +1115,7 @@ void SPI_MASTER_ISR_ATTR spi_device_release_bus(spi_device_t *dev) #if CONFIG_IDF_TARGET_ESP32 if (host->bus_attr->dma_enabled) { //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_idle(host->bus_attr->tx_dma_chan); + spicommon_dmaworkaround_idle(host->dma_ctx->tx_dma_chan.chan_id); } //Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset. #endif //#if CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_driver_spi/src/gpspi/spi_slave.c b/components/esp_driver_spi/src/gpspi/spi_slave.c index 14dbe4ecad..7c7f00932e 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave.c @@ -59,6 +59,7 @@ typedef struct { typedef struct { int id; spi_bus_config_t bus_config; + spi_dma_ctx_t *dma_ctx; spi_slave_interface_config_t cfg; intr_handle_t intr; spi_slave_hal_context_t hal; @@ -72,8 +73,6 @@ typedef struct { bool cs_iomux; uint8_t cs_in_signal; uint16_t internal_mem_align_size; - uint32_t tx_dma_chan; - uint32_t rx_dma_chan; #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; #endif @@ -133,8 +132,6 @@ static void ipc_isr_reg_to_core(void *args) esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *bus_config, const spi_slave_interface_config_t *slave_config, spi_dma_chan_t dma_chan) { bool spi_chan_claimed; - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; esp_err_t ret = ESP_OK; esp_err_t err; SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG); @@ -172,19 +169,27 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b spihost[host]->dma_enabled = (dma_chan != SPI_DMA_DISABLED); if (spihost[host]->dma_enabled) { - ret = spicommon_dma_chan_alloc(host, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + ret = spicommon_dma_chan_alloc(host, dma_chan, &spihost[host]->dma_ctx); if (ret != ESP_OK) { goto cleanup; } - spihost[host]->tx_dma_chan = actual_tx_dma_chan; - spihost[host]->rx_dma_chan = actual_rx_dma_chan; - - //See how many dma descriptors we need and allocate them - int dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN; - if (dma_desc_ct == 0) { - dma_desc_ct = 1; //default to 4k when max is not given + ret = spicommon_dma_desc_alloc(spihost[host]->dma_ctx, bus_config->max_transfer_sz, &spihost[host]->max_transfer_sz); + if (ret != ESP_OK) { + goto cleanup; } - spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; + + hal->dmadesc_tx = spihost[host]->dma_ctx->dmadesc_tx; + hal->dmadesc_rx = spihost[host]->dma_ctx->dmadesc_rx; + hal->dmadesc_n = spihost[host]->dma_ctx->dma_desc_num; +#if SOC_GDMA_SUPPORTED + //temporary used for gdma_ll alias in hal layer + gdma_get_channel_id(spihost[host]->dma_ctx->tx_dma_chan, (int *)&hal->tx_dma_chan); + gdma_get_channel_id(spihost[host]->dma_ctx->rx_dma_chan, (int *)&hal->rx_dma_chan); +#else + hal->tx_dma_chan = spihost[host]->dma_ctx->tx_dma_chan.chan_id; + hal->rx_dma_chan = spihost[host]->dma_ctx->rx_dma_chan.chan_id; +#endif + #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE size_t alignment; esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, &alignment); @@ -192,14 +197,6 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b #else spihost[host]->internal_mem_align_size = 4; #endif - - hal->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - hal->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - if (!hal->dmadesc_tx || !hal->dmadesc_rx) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - hal->dmadesc_n = dma_desc_ct; } else { //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; @@ -278,9 +275,6 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b hal->tx_lsbfirst = (slave_config->flags & SPI_SLAVE_TXBIT_LSBFIRST) ? 1 : 0; hal->mode = slave_config->mode; hal->use_dma = spihost[host]->dma_enabled; - hal->tx_dma_chan = actual_tx_dma_chan; - hal->rx_dma_chan = actual_rx_dma_chan; - spi_slave_hal_setup_device(hal); return ESP_OK; @@ -301,9 +295,9 @@ cleanup: } spi_slave_hal_deinit(&spihost[host]->hal); if (spihost[host]->dma_enabled) { - spicommon_dma_chan_free(host); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); + free(spihost[host]->dma_ctx->dmadesc_tx); + free(spihost[host]->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(spihost[host]->dma_ctx); } free(spihost[host]); @@ -324,9 +318,9 @@ esp_err_t spi_slave_free(spi_host_device_t host) vQueueDelete(spihost[host]->ret_queue); } if (spihost[host]->dma_enabled) { - spicommon_dma_chan_free(host); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); + free(spihost[host]->dma_ctx->dmadesc_tx); + free(spihost[host]->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(spihost[host]->dma_ctx); } spicommon_bus_free_io_cfg(&spihost[host]->bus_config); esp_intr_free(spihost[host]->intr); @@ -586,7 +580,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //This workaround is only for esp32 if (spi_slave_hal_dma_need_reset(hal)) { //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same - spicommon_dmaworkaround_req_reset(host->tx_dma_chan, spi_slave_restart_after_dmareset, host); + spicommon_dmaworkaround_req_reset(host->dma_ctx->tx_dma_chan.chan_id, spi_slave_restart_after_dmareset, host); } #endif //#if CONFIG_IDF_TARGET_ESP32 @@ -614,7 +608,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //This workaround is only for esp32 if (use_dma) { //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same - spicommon_dmaworkaround_idle(host->tx_dma_chan); + spicommon_dmaworkaround_idle(host->dma_ctx->tx_dma_chan.chan_id); if (spicommon_dmaworkaround_reset_in_progress()) { //We need to wait for the reset to complete. Disable int (will be re-enabled on reset callback) and exit isr. esp_intr_disable(host->intr); @@ -649,7 +643,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) if (use_dma) { //This workaround is only for esp32 //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same - spicommon_dmaworkaround_transfer_active(host->tx_dma_chan); + spicommon_dmaworkaround_transfer_active(host->dma_ctx->tx_dma_chan.chan_id); } #endif //#if CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c index cdc8f7fd42..2138db26c0 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c @@ -36,15 +36,12 @@ typedef struct { typedef struct { bool dma_enabled; + spi_dma_ctx_t *dma_ctx; uint16_t internal_mem_align_size; int max_transfer_sz; uint32_t flags; portMUX_TYPE int_spinlock; intr_handle_t intr; -#if SOC_GDMA_SUPPORTED - gdma_channel_handle_t gdma_handle_tx; //varible for storge gdma handle - gdma_channel_handle_t gdma_handle_rx; -#endif intr_handle_t intr_dma; spi_slave_hd_callback_config_t callback; spi_slave_hd_hal_context_t hal; @@ -74,13 +71,10 @@ static bool spi_gdma_tx_channel_callback(gdma_channel_handle_t dma_chan, gdma_ev static void spi_slave_hd_intr_append(void *arg); static void spi_slave_hd_intr_segment(void *arg); -esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *bus_config, - const spi_slave_hd_slot_config_t *config) +esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *bus_config, const spi_slave_hd_slot_config_t *config) { bool spi_chan_claimed; bool append_mode = (config->flags & SPI_SLAVE_HD_APPEND_MODE); - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; esp_err_t ret = ESP_OK; SPIHD_CHECK(VALID_HOST(host_id), "invalid host", ESP_ERR_INVALID_ARG); @@ -104,34 +98,28 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b host->append_mode = append_mode; if (host->dma_enabled) { - ret = spicommon_dma_chan_alloc(host_id, config->dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + ret = spicommon_dma_chan_alloc(host_id, config->dma_chan, &host->dma_ctx); + if (ret != ESP_OK) { + goto cleanup; + } + ret = spicommon_dma_desc_alloc(host->dma_ctx, bus_config->max_transfer_sz, &host->max_transfer_sz); if (ret != ESP_OK) { goto cleanup; } - //Malloc for all the DMA descriptors - int dma_desc_ct = (bus_config->max_transfer_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - if (dma_desc_ct == 0) { - dma_desc_ct = 1; //default to 4k when max is not given - } - host->hal.dma_desc_num = dma_desc_ct; - spi_dma_desc_t *orig_dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - spi_dma_desc_t *orig_dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - - host->hal.dmadesc_tx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * dma_desc_ct, MALLOC_CAP_DEFAULT); - host->hal.dmadesc_rx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * dma_desc_ct, MALLOC_CAP_DEFAULT); - if (!(host->hal.dmadesc_tx && host->hal.dmadesc_rx && orig_dmadesc_tx && orig_dmadesc_rx)) { + host->hal.dma_desc_num = host->dma_ctx->dma_desc_num; + host->hal.dmadesc_tx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * host->hal.dma_desc_num, MALLOC_CAP_DEFAULT); + host->hal.dmadesc_rx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * host->hal.dma_desc_num, MALLOC_CAP_DEFAULT); + if (!(host->hal.dmadesc_tx && host->hal.dmadesc_rx)) { ret = ESP_ERR_NO_MEM; goto cleanup; } //Pair each desc to each possible trans - for (int i = 0; i < dma_desc_ct; i ++) { - host->hal.dmadesc_tx[i].desc = &orig_dmadesc_tx[i]; - host->hal.dmadesc_rx[i].desc = &orig_dmadesc_rx[i]; + for (int i = 0; i < host->hal.dma_desc_num; i ++) { + host->hal.dmadesc_tx[i].desc = &host->dma_ctx->dmadesc_tx[i]; + host->hal.dmadesc_rx[i].desc = &host->dma_ctx->dmadesc_rx[i]; } - //Get the actual SPI bus transaction size in bytes. - host->max_transfer_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE size_t alignment; esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, &alignment); @@ -156,14 +144,21 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b .dma_in = SPI_LL_GET_HW(host_id), .dma_out = SPI_LL_GET_HW(host_id), .dma_enabled = host->dma_enabled, - .tx_dma_chan = actual_tx_dma_chan, - .rx_dma_chan = actual_rx_dma_chan, .append_mode = append_mode, .mode = config->mode, .tx_lsbfirst = (config->flags & SPI_SLAVE_HD_RXBIT_LSBFIRST), .rx_lsbfirst = (config->flags & SPI_SLAVE_HD_TXBIT_LSBFIRST), }; +#if SOC_GDMA_SUPPORTED + //temporary used for gdma_ll alias in hal layer + gdma_get_channel_id(host->dma_ctx->tx_dma_chan, (int *)&hal_config.tx_dma_chan); + gdma_get_channel_id(host->dma_ctx->rx_dma_chan, (int *)&hal_config.rx_dma_chan); +#else + hal_config.tx_dma_chan = host->dma_ctx->tx_dma_chan.chan_id; + hal_config.rx_dma_chan = host->dma_ctx->rx_dma_chan.chan_id; +#endif + //Init the hal according to the hal_config set above spi_slave_hd_hal_init(&host->hal, &hal_config); @@ -219,11 +214,10 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b } #if SOC_GDMA_SUPPORTED // config gmda and ISR callback for gdma supported chip - spicommon_gdma_get_handle(host_id, &host->gdma_handle_tx, GDMA_CHANNEL_DIRECTION_TX); gdma_tx_event_callbacks_t tx_cbs = { .on_trans_eof = spi_gdma_tx_channel_callback }; - gdma_register_tx_event_callbacks(host->gdma_handle_tx, &tx_cbs, host); + gdma_register_tx_event_callbacks(host->dma_ctx->tx_dma_chan, &tx_cbs, host); #else ret = esp_intr_alloc(spicommon_irqdma_source_for_host(host_id), 0, spi_slave_hd_intr_append, (void *)host, &host->intr_dma); @@ -293,11 +287,11 @@ esp_err_t spi_slave_hd_deinit(spi_host_device_t host_id) spicommon_periph_free(host_id); if (host->dma_enabled) { - free(host->hal.dmadesc_tx->desc); - free(host->hal.dmadesc_rx->desc); + free(host->dma_ctx->dmadesc_tx); + free(host->dma_ctx->dmadesc_rx); free(host->hal.dmadesc_tx); free(host->hal.dmadesc_rx); - spicommon_dma_chan_free(host_id); + spicommon_dma_chan_free(host->dma_ctx); } free(host); spihost[host_id] = NULL; diff --git a/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c b/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c index c790d9b0d1..00622e78b8 100644 --- a/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c +++ b/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c @@ -908,8 +908,8 @@ TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test ", "[spi_ms][test_env=generic_multi #endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) //***************************************TEST FOR APPEND MODE******************************************// -#define TEST_APPEND_CACHE_SIZE 4 -#define TEST_TRANS_LEN TEST_DMA_MAX_SIZE +#define TEST_APPEND_NUM 4 +#define TEST_TRANS_LEN TEST_DMA_MAX_SIZE void prepare_data(uint8_t *buff, uint32_t len, int8_t diff) { @@ -930,20 +930,20 @@ void slave_run_append(void) TEST_ESP_OK(spi_slave_hd_init(TEST_SPI_HOST, &bus_cfg, &slave_hd_cfg)); unity_wait_for_signal("Master ready"); - spi_slave_hd_data_t *ret_trans, slave_rx_trans[TEST_APPEND_CACHE_SIZE] = {}; + spi_slave_hd_data_t *ret_trans, slave_rx_trans[TEST_APPEND_NUM] = {}; uint8_t *slave_exp = heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_DEFAULT); // append some data first - for (uint32_t cache_instans = 0; cache_instans < TEST_APPEND_CACHE_SIZE; cache_instans++) { - int trans_len = 16 << (cache_instans + 1); + for (uint32_t append_idx = 0; append_idx < TEST_APPEND_NUM; append_idx++) { + int trans_len = 16 << (append_idx + 1); if (trans_len > TEST_TRANS_LEN) { trans_len = TEST_TRANS_LEN; } - slave_rx_trans[cache_instans].data = heap_caps_calloc(1, TEST_TRANS_LEN, MALLOC_CAP_DMA); - TEST_ASSERT_NOT_NULL(slave_rx_trans[cache_instans].data); - slave_rx_trans[cache_instans].len = trans_len; - TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &slave_rx_trans[cache_instans], portMAX_DELAY)); + slave_rx_trans[append_idx].data = heap_caps_aligned_calloc(4, 1, TEST_TRANS_LEN, MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(slave_rx_trans[append_idx].data); + slave_rx_trans[append_idx].len = trans_len; + TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &slave_rx_trans[append_idx], portMAX_DELAY)); } for (int trans_num = 1; trans_num <= 8; trans_num ++) { @@ -960,7 +960,7 @@ void slave_run_append(void) ESP_LOG_BUFFER_HEX_LEVEL("slave exp", slave_exp, trans_len, ESP_LOG_DEBUG); spitest_cmp_or_dump(slave_exp, ret_trans->data, trans_len); - if (trans_num <= TEST_APPEND_CACHE_SIZE) { + if (trans_num <= TEST_APPEND_NUM) { // append one more transaction int new_append_len = trans_len << 4; if (new_append_len > TEST_TRANS_LEN) { @@ -976,16 +976,16 @@ void slave_run_append(void) free(slave_exp); //------------------------------------tx direction------------------------------ - spi_slave_hd_data_t slave_tx_trans[TEST_APPEND_CACHE_SIZE] = {}; - for (uint32_t cache_instans = 0; cache_instans < TEST_APPEND_CACHE_SIZE; cache_instans ++) { - int trans_len = 16 << (cache_instans + 1); + spi_slave_hd_data_t slave_tx_trans[TEST_APPEND_NUM] = {}; + for (uint32_t append_idx = 0; append_idx < TEST_APPEND_NUM; append_idx ++) { + int trans_len = 16 << (append_idx + 1); if (trans_len >= TEST_TRANS_LEN) { trans_len = TEST_TRANS_LEN; } - slave_tx_trans[cache_instans].data = slave_rx_trans[cache_instans].data; - slave_tx_trans[cache_instans].len = trans_len; - prepare_data(slave_tx_trans[cache_instans].data, trans_len, -3); - TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_tx_trans[cache_instans], portMAX_DELAY)); + slave_tx_trans[append_idx].data = slave_rx_trans[append_idx].data; + slave_tx_trans[append_idx].len = trans_len; + prepare_data(slave_tx_trans[append_idx].data, trans_len, -3); + TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_tx_trans[append_idx], portMAX_DELAY)); } //Get one result and load a new transaction @@ -995,7 +995,7 @@ void slave_run_append(void) ESP_LOGI("slave", "trasacted len: %d", ret_trans->len); ESP_LOG_BUFFER_HEX_LEVEL("slave tx", ret_trans->data, ret_trans->len, ESP_LOG_DEBUG); - if (trans_num <= TEST_APPEND_CACHE_SIZE) { + if (trans_num <= TEST_APPEND_NUM) { // append one more transaction int new_append_len = 16 << (trans_num + 4); if (new_append_len > TEST_TRANS_LEN) { @@ -1008,7 +1008,7 @@ void slave_run_append(void) } } printf("================Master Rx Done==================\n"); - for (int i = 0; i < TEST_APPEND_CACHE_SIZE; i++) { + for (int i = 0; i < TEST_APPEND_NUM; i++) { free(slave_tx_trans[i].data); } diff --git a/components/hal/spi_hal.c b/components/hal/spi_hal.c index 25b77b8ef6..ee58edae03 100644 --- a/components/hal/spi_hal.c +++ b/components/hal/spi_hal.c @@ -12,29 +12,6 @@ #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" -//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros. -#if SOC_GDMA_SUPPORTED -#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1) -#include "soc/gdma_struct.h" -#include "hal/gdma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable); - -#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer -#include "hal/axi_dma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable); -#endif -#endif //SOC_GDMA_SUPPORTED - /* The tag may be unused if log level is set to NONE */ static const __attribute__((unused)) char SPI_HAL_TAG[] = "spi_hal"; @@ -44,14 +21,6 @@ static const __attribute__((unused)) char SPI_HAL_TAG[] = "spi_hal"; return (ret_val); \ } -static void s_spi_hal_dma_init_config(const spi_hal_context_t *hal) -{ - spi_dma_ll_rx_enable_burst_data(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_data(hal->dma_out, hal->tx_dma_chan, 1); - spi_dma_ll_rx_enable_burst_desc(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_desc(hal->dma_out, hal->tx_dma_chan, 1); -} - void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config_t *config) { memset(hal, 0, sizeof(spi_hal_context_t)); @@ -71,9 +40,6 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config spi_ll_set_mosi_free_level(hw, 0); #endif spi_ll_master_init(hw); - if (config->dma_enabled) { - s_spi_hal_dma_init_config(hal); - } //Force a transaction done interrupt. This interrupt won't fire yet because //we initialized the SPI interrupt as disabled. This way, we can just diff --git a/components/hal/spi_slave_hal.c b/components/hal/spi_slave_hal.c index c53bd600ca..5d0f570b54 100644 --- a/components/hal/spi_slave_hal.c +++ b/components/hal/spi_slave_hal.c @@ -2,37 +2,6 @@ #include "hal/spi_ll.h" #include "soc/soc_caps.h" -//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros. -#if SOC_GDMA_SUPPORTED -#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1) -#include "soc/gdma_struct.h" -#include "hal/gdma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable); - -#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer -#include "hal/axi_dma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable); -#endif -#endif //SOC_GDMA_SUPPORTED - -static void s_spi_slave_hal_dma_init_config(const spi_slave_hal_context_t *hal) -{ - spi_dma_ll_rx_enable_burst_data(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_data(hal->dma_out, hal->tx_dma_chan, 1); - spi_dma_ll_rx_enable_burst_desc(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_desc(hal->dma_out, hal->tx_dma_chan, 1); -} - void spi_slave_hal_init(spi_slave_hal_context_t *hal, const spi_slave_hal_config_t *hal_config) { spi_dev_t *hw = SPI_LL_GET_HW(hal_config->host_id); @@ -40,9 +9,6 @@ void spi_slave_hal_init(spi_slave_hal_context_t *hal, const spi_slave_hal_config hal->dma_in = hal_config->dma_in; hal->dma_out = hal_config->dma_out; - if (hal->use_dma) { - s_spi_slave_hal_dma_init_config(hal); - } spi_ll_slave_init(hal->hw); //Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as diff --git a/components/hal/spi_slave_hd_hal.c b/components/hal/spi_slave_hd_hal.c index ff7d48abb2..a62a517269 100644 --- a/components/hal/spi_slave_hd_hal.c +++ b/components/hal/spi_slave_hd_hal.c @@ -27,10 +27,6 @@ #define spi_dma_ll_rx_restart(dev, chan) gdma_ll_rx_restart(&GDMA, chan) #define spi_dma_ll_rx_reset(dev, chan) gdma_ll_rx_reset_channel(&GDMA, chan) #define spi_dma_ll_tx_reset(dev, chan) gdma_ll_tx_reset_channel(&GDMA, chan) -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable) -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable) #define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable) #define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable) #define spi_dma_ll_get_out_eof_desc_addr(dev, chan) gdma_ll_tx_get_eof_desc_addr(&GDMA, chan) @@ -50,10 +46,6 @@ #define spi_dma_ll_rx_restart(dev, chan) axi_dma_ll_rx_restart(&AXI_DMA, chan) #define spi_dma_ll_rx_reset(dev, chan) axi_dma_ll_rx_reset_channel(&AXI_DMA, chan) #define spi_dma_ll_tx_reset(dev, chan) axi_dma_ll_tx_reset_channel(&AXI_DMA, chan) -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable) -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable) #define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable) #define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable) #define spi_dma_ll_get_out_eof_desc_addr(dev, chan) axi_dma_ll_tx_get_eof_desc_addr(&AXI_DMA, chan) @@ -71,10 +63,6 @@ static void s_spi_slave_hd_hal_dma_init_config(const spi_slave_hd_hal_context_t *hal) { - spi_dma_ll_rx_enable_burst_data(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_data(hal->dma_out, hal->tx_dma_chan, 1); - spi_dma_ll_rx_enable_burst_desc(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_desc(hal->dma_out, hal->tx_dma_chan, 1); spi_dma_ll_enable_out_auto_wrback(hal->dma_out, hal->tx_dma_chan, 1); spi_dma_ll_set_out_eof_generation(hal->dma_out, hal->tx_dma_chan, 1); }