From 751efec8b68d8e543eac0af65908b10d57958eb9 Mon Sep 17 00:00:00 2001 From: wanlei Date: Wed, 6 Sep 2023 21:35:45 +0800 Subject: [PATCH 1/3] refactor(spi_slave_hd): refactor append mode dma_desc struct --- components/driver/spi/gpspi/spi_slave_hd.c | 68 +++++++----- components/hal/include/hal/spi_slave_hd_hal.h | 21 +--- components/hal/spi_slave_hd_hal.c | 104 ++++++------------ 3 files changed, 72 insertions(+), 121 deletions(-) diff --git a/components/driver/spi/gpspi/spi_slave_hd.c b/components/driver/spi/gpspi/spi_slave_hd.c index b384ce26ea4a..18707232ad21 100644 --- a/components/driver/spi/gpspi/spi_slave_hd.c +++ b/components/driver/spi/gpspi/spi_slave_hd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -89,12 +89,40 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b spihost[host_id] = host; host->int_spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; host->dma_enabled = (config->dma_chan != SPI_DMA_DISABLED); + 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); 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; + + lldesc_t *orig_dmadesc_tx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); + lldesc_t *orig_dmadesc_rx = heap_caps_malloc(sizeof(lldesc_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)) { + 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]; + } + + //Get the actual SPI bus transaction size in bytes. + host->max_transfer_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; + } else { + //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. + host->max_transfer_sz = 0; } ret = spicommon_bus_initialize_io(host_id, bus_config, SPICOMMON_BUSFLAG_SLAVE | bus_config->flags, &host->flags); @@ -104,7 +132,6 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b gpio_set_direction(config->spics_io_num, GPIO_MODE_INPUT); spicommon_cs_initialize(host_id, config->spics_io_num, 0, !(bus_config->flags & SPICOMMON_BUSFLAG_NATIVE_PINS)); - host->append_mode = append_mode; spi_slave_hd_hal_config_t hal_config = { .host_id = host_id, @@ -119,23 +146,6 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b .rx_lsbfirst = (config->flags & SPI_SLAVE_HD_TXBIT_LSBFIRST), }; - if (host->dma_enabled) { - //Malloc for all the DMA descriptors - uint32_t total_desc_size = spi_slave_hd_hal_get_total_desc_size(&host->hal, bus_config->max_transfer_sz); - host->hal.dmadesc_tx = heap_caps_malloc(total_desc_size, MALLOC_CAP_DMA); - host->hal.dmadesc_rx = heap_caps_malloc(total_desc_size, MALLOC_CAP_DMA); - if (!host->hal.dmadesc_tx || !host->hal.dmadesc_rx) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - - //Get the actual SPI bus transaction size in bytes. - host->max_transfer_sz = spi_salve_hd_hal_get_max_bus_size(&host->hal); - } else { - //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. - host->max_transfer_sz = 0; - } - //Init the hal according to the hal_config set above spi_slave_hd_hal_init(&host->hal, &hal_config); @@ -232,21 +242,21 @@ esp_err_t spi_slave_hd_deinit(spi_host_device_t host_id) if (host->rx_ret_queue) vQueueDelete(host->rx_ret_queue); if (host->tx_cnting_sem) vSemaphoreDelete(host->tx_cnting_sem); if (host->rx_cnting_sem) vSemaphoreDelete(host->rx_cnting_sem); - if (host) { - free(host->hal.dmadesc_tx); - free(host->hal.dmadesc_rx); - esp_intr_free(host->intr); - esp_intr_free(host->intr_dma); + esp_intr_free(host->intr); + esp_intr_free(host->intr_dma); #ifdef CONFIG_PM_ENABLE - if (host->pm_lock) { - esp_pm_lock_release(host->pm_lock); - esp_pm_lock_delete(host->pm_lock); - } -#endif + if (host->pm_lock) { + esp_pm_lock_release(host->pm_lock); + esp_pm_lock_delete(host->pm_lock); } +#endif spicommon_periph_free(host_id); if (host->dma_enabled) { + free(host->hal.dmadesc_tx->desc); + free(host->hal.dmadesc_rx->desc); + free(host->hal.dmadesc_tx); + free(host->hal.dmadesc_rx); spicommon_dma_chan_free(host_id); } free(host); diff --git a/components/hal/include/hal/spi_slave_hd_hal.h b/components/hal/include/hal/spi_slave_hd_hal.h index be38031c8785..029112df5d9b 100644 --- a/components/hal/include/hal/spi_slave_hd_hal.h +++ b/components/hal/include/hal/spi_slave_hd_hal.h @@ -62,7 +62,7 @@ extern "C" { * this structure inherits DMA descriptor, with a pointer to the transaction descriptor passed from users. */ typedef struct { - lldesc_t desc; ///< DMA descriptor + lldesc_t *desc; ///< DMA descriptor void *arg; ///< This points to the transaction descriptor user passed in } spi_slave_hd_hal_desc_append_t; @@ -105,13 +105,11 @@ typedef struct { spi_slave_hd_hal_desc_append_t *tx_cur_desc; ///< Current TX DMA descriptor that could be linked (set up). spi_slave_hd_hal_desc_append_t *tx_dma_head; ///< Head of the linked TX DMA descriptors which are not used by hardware spi_slave_hd_hal_desc_append_t *tx_dma_tail; ///< Tail of the linked TX DMA descriptors which are not used by hardware - spi_slave_hd_hal_desc_append_t tx_dummy_head; ///< Dummy descriptor for ``tx_dma_head`` to start uint32_t tx_used_desc_cnt; ///< Number of the TX descriptors that have been setup uint32_t tx_recycled_desc_cnt; ///< Number of the TX descriptors that could be recycled spi_slave_hd_hal_desc_append_t *rx_cur_desc; ///< Current RX DMA descriptor that could be linked (set up). spi_slave_hd_hal_desc_append_t *rx_dma_head; ///< Head of the linked RX DMA descriptors which are not used by hardware spi_slave_hd_hal_desc_append_t *rx_dma_tail; ///< Tail of the linked RX DMA descriptors which are not used by hardware - spi_slave_hd_hal_desc_append_t rx_dummy_head; ///< Dummy descriptor for ``rx_dma_head`` to start uint32_t rx_used_desc_cnt; ///< Number of the RX descriptors that have been setup uint32_t rx_recycled_desc_cnt; ///< Number of the RX descriptors that could be recycled @@ -129,23 +127,6 @@ typedef struct { */ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_hal_config_t *hal_config); -/** - * @brief Get the size of one DMA descriptor - * - * @param hal Context of the HAL layer - * @param bus_size SPI bus maximum transfer size, in bytes. - * @return Total size needed for all the DMA descriptors - */ -uint32_t spi_slave_hd_hal_get_total_desc_size(spi_slave_hd_hal_context_t *hal, uint32_t bus_size); - -/** - * @brief Get the actual bus size - * - * @param hal Context of the HAL layer - * @return Actual bus transaction size - */ -uint32_t spi_salve_hd_hal_get_max_bus_size(spi_slave_hd_hal_context_t *hal); - /** * @brief Check and clear signal of one event * diff --git a/components/hal/spi_slave_hd_hal.c b/components/hal/spi_slave_hd_hal.c index 81a5bf5dfacc..b0ee04bed327 100644 --- a/components/hal/spi_slave_hd_hal.c +++ b/components/hal/spi_slave_hd_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,12 +63,10 @@ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_h hal->tx_dma_chan = hal_config->tx_dma_chan; hal->rx_dma_chan = hal_config->rx_dma_chan; hal->append_mode = hal_config->append_mode; - hal->rx_cur_desc = hal->dmadesc_rx; hal->tx_cur_desc = hal->dmadesc_tx; - STAILQ_NEXT(&hal->tx_dummy_head.desc, qe) = &hal->dmadesc_tx->desc; - hal->tx_dma_head = &hal->tx_dummy_head; - STAILQ_NEXT(&hal->rx_dummy_head.desc, qe) = &hal->dmadesc_rx->desc; - hal->rx_dma_head = &hal->rx_dummy_head; + hal->rx_cur_desc = hal->dmadesc_rx; + hal->tx_dma_head = hal->dmadesc_tx + hal->dma_desc_num -1; + hal->rx_dma_head = hal->dmadesc_rx + hal->dma_desc_num -1; //Configure slave if (hal_config->dma_enabled) { @@ -119,26 +117,9 @@ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_h spi_ll_slave_set_seg_mode(hal->dev, true); } -uint32_t spi_salve_hd_hal_get_max_bus_size(spi_slave_hd_hal_context_t *hal) -{ - return hal->dma_desc_num * LLDESC_MAX_NUM_PER_DESC; -} - -uint32_t spi_slave_hd_hal_get_total_desc_size(spi_slave_hd_hal_context_t *hal, uint32_t bus_size) -{ - //See how many dma descriptors we need - int dma_desc_ct = (bus_size + LLDESC_MAX_NUM_PER_DESC - 1) / LLDESC_MAX_NUM_PER_DESC; - if (dma_desc_ct == 0) { - dma_desc_ct = 1; //default to 4k when max is not given - } - hal->dma_desc_num = dma_desc_ct; - - return hal->dma_desc_num * sizeof(spi_slave_hd_hal_desc_append_t); -} - void spi_slave_hd_hal_rxdma(spi_slave_hd_hal_context_t *hal, uint8_t *out_buf, size_t len) { - lldesc_setup_link(&hal->dmadesc_rx->desc, out_buf, len, true); + lldesc_setup_link(hal->dmadesc_rx->desc, out_buf, len, true); spi_ll_dma_rx_fifo_reset(hal->dev); spi_dma_ll_rx_reset(hal->dma_in, hal->rx_dma_chan); @@ -147,12 +128,12 @@ void spi_slave_hd_hal_rxdma(spi_slave_hd_hal_context_t *hal, uint8_t *out_buf, s spi_ll_clear_intr(hal->dev, SPI_LL_INTR_CMD7); spi_ll_dma_rx_enable(hal->dev, 1); - spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, &hal->dmadesc_rx->desc); + spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->dmadesc_rx->desc); } void spi_slave_hd_hal_txdma(spi_slave_hd_hal_context_t *hal, uint8_t *data, size_t len) { - lldesc_setup_link(&hal->dmadesc_tx->desc, data, len, false); + lldesc_setup_link(hal->dmadesc_tx->desc, data, len, false); spi_ll_dma_tx_fifo_reset(hal->dev); spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan); @@ -161,7 +142,7 @@ void spi_slave_hd_hal_txdma(spi_slave_hd_hal_context_t *hal, uint8_t *data, size spi_ll_clear_intr(hal->dev, SPI_LL_INTR_CMD8); spi_ll_dma_tx_enable(hal->dev, 1); - spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, &hal->dmadesc_tx->desc); + spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->dmadesc_tx->desc); } static spi_ll_intr_t get_event_intr(spi_slave_hd_hal_context_t *hal, spi_event_t ev) @@ -257,68 +238,45 @@ int spi_slave_hd_hal_get_rxlen(spi_slave_hd_hal_context_t *hal) int spi_slave_hd_hal_rxdma_seg_get_len(spi_slave_hd_hal_context_t *hal) { - lldesc_t *desc = &hal->dmadesc_rx->desc; + lldesc_t *desc = hal->dmadesc_rx->desc; return lldesc_get_received_len(desc, NULL); } bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans) { - if ((uint32_t)&hal->tx_dma_head->desc == spi_dma_ll_get_out_eof_desc_addr(hal->dma_out, hal->tx_dma_chan)) { + uint32_t desc_now = spi_dma_ll_get_out_eof_desc_addr(hal->dma_out, hal->tx_dma_chan); + if ((uint32_t)hal->tx_dma_head->desc == desc_now) { return false; } - hal->tx_dma_head = (spi_slave_hd_hal_desc_append_t *)STAILQ_NEXT(&hal->tx_dma_head->desc, qe); + //find used paired desc-trans by desc addr + hal->tx_dma_head++; + if (hal->tx_dma_head >= hal->dmadesc_tx + hal->dma_desc_num) { + hal->tx_dma_head = hal->dmadesc_tx; + } *out_trans = hal->tx_dma_head->arg; hal->tx_recycled_desc_cnt++; - return true; } bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, size_t *out_len) { - if ((uint32_t)&hal->rx_dma_head->desc == spi_dma_ll_get_in_suc_eof_desc_addr(hal->dma_in, hal->rx_dma_chan)) { + uint32_t desc_now = spi_dma_ll_get_in_suc_eof_desc_addr(hal->dma_in, hal->rx_dma_chan); + if ((uint32_t)hal->rx_dma_head->desc == desc_now) { return false; } - hal->rx_dma_head = (spi_slave_hd_hal_desc_append_t *)STAILQ_NEXT(&hal->rx_dma_head->desc, qe); + //find used paired desc-trans by desc addr + hal->rx_dma_head++; + if (hal->rx_dma_head >= hal->dmadesc_rx + hal->dma_desc_num) { + hal->rx_dma_head = hal->dmadesc_rx; + } *out_trans = hal->rx_dma_head->arg; - *out_len = hal->rx_dma_head->desc.length; + *out_len = hal->rx_dma_head->desc->length; hal->rx_recycled_desc_cnt++; - return true; } -static void spi_slave_hd_hal_link_append_desc(spi_slave_hd_hal_desc_append_t *dmadesc, const void *data, int len, bool isrx, void *arg) -{ - HAL_ASSERT(len <= LLDESC_MAX_NUM_PER_DESC); //TODO: Add support for transaction with length larger than 4092, IDF-2660 - int n = 0; - while (len) { - int dmachunklen = len; - if (dmachunklen > LLDESC_MAX_NUM_PER_DESC) { - dmachunklen = LLDESC_MAX_NUM_PER_DESC; - } - if (isrx) { - //Receive needs DMA length rounded to next 32-bit boundary - dmadesc[n].desc.size = (dmachunklen + 3) & (~3); - dmadesc[n].desc.length = (dmachunklen + 3) & (~3); - } else { - dmadesc[n].desc.size = dmachunklen; - dmadesc[n].desc.length = dmachunklen; - } - dmadesc[n].desc.buf = (uint8_t *)data; - dmadesc[n].desc.eof = 0; - dmadesc[n].desc.sosf = 0; - dmadesc[n].desc.owner = 1; - dmadesc[n].desc.qe.stqe_next = &dmadesc[n + 1].desc; - dmadesc[n].arg = arg; - len -= dmachunklen; - data += dmachunklen; - n++; - } - dmadesc[n - 1].desc.eof = 1; //Mark last DMA desc as end of stream. - dmadesc[n - 1].desc.qe.stqe_next = NULL; -} - esp_err_t spi_slave_hd_hal_txdma_append(spi_slave_hd_hal_context_t *hal, uint8_t *data, size_t len, void *arg) { //Check if there are enough available DMA descriptors for software to use @@ -329,7 +287,8 @@ esp_err_t spi_slave_hd_hal_txdma_append(spi_slave_hd_hal_context_t *hal, uint8_t return ESP_ERR_INVALID_STATE; } - spi_slave_hd_hal_link_append_desc(hal->tx_cur_desc, data, len, false, arg); + lldesc_setup_link(hal->tx_cur_desc->desc, data, len, false); + hal->tx_cur_desc->arg = arg; if (!hal->tx_dma_started) { hal->tx_dma_started = true; @@ -339,10 +298,10 @@ esp_err_t spi_slave_hd_hal_txdma_append(spi_slave_hd_hal_context_t *hal, uint8_t spi_ll_outfifo_empty_clr(hal->dev); spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan); spi_ll_dma_tx_enable(hal->dev, 1); - spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, &hal->tx_cur_desc->desc); + spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->tx_cur_desc->desc); } else { //there is already a consecutive link - STAILQ_NEXT(&hal->tx_dma_tail->desc, qe) = &hal->tx_cur_desc->desc; + STAILQ_NEXT(hal->tx_dma_tail->desc, qe) = hal->tx_cur_desc->desc; hal->tx_dma_tail = hal->tx_cur_desc; spi_dma_ll_tx_restart(hal->dma_out, hal->tx_dma_chan); } @@ -369,7 +328,8 @@ esp_err_t spi_slave_hd_hal_rxdma_append(spi_slave_hd_hal_context_t *hal, uint8_t return ESP_ERR_INVALID_STATE; } - spi_slave_hd_hal_link_append_desc(hal->rx_cur_desc, data, len, false, arg); + lldesc_setup_link(hal->rx_cur_desc->desc, data, len, false); + hal->rx_cur_desc->arg = arg; if (!hal->rx_dma_started) { hal->rx_dma_started = true; @@ -379,10 +339,10 @@ esp_err_t spi_slave_hd_hal_rxdma_append(spi_slave_hd_hal_context_t *hal, uint8_t spi_ll_dma_rx_fifo_reset(hal->dma_in); spi_ll_infifo_full_clr(hal->dev); spi_ll_dma_rx_enable(hal->dev, 1); - spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, &hal->rx_cur_desc->desc); + spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->rx_cur_desc->desc); } else { //there is already a consecutive link - STAILQ_NEXT(&hal->rx_dma_tail->desc, qe) = &hal->rx_cur_desc->desc; + STAILQ_NEXT(hal->rx_dma_tail->desc, qe) = hal->rx_cur_desc->desc; hal->rx_dma_tail = hal->rx_cur_desc; spi_dma_ll_rx_restart(hal->dma_in, hal->rx_dma_chan); } From daeb71d7e424115b49e0cf2be98bd92f24eaba37 Mon Sep 17 00:00:00 2001 From: wanlei Date: Thu, 14 Sep 2023 16:52:12 +0800 Subject: [PATCH 2/3] feat(spi_slave_hd): add esp32p4 support for seg and append mode --- components/driver/spi/gpspi/spi_slave.c | 4 +- components/driver/spi/gpspi/spi_slave_hd.c | 171 +++++++++++++----- .../driver/spi/include/driver/spi_slave_hd.h | 3 + .../driver/test_apps/spi/slave_hd/README.md | 4 +- .../spi/slave_hd/main/test_app_main.c | 14 +- .../spi/slave_hd/main/test_spi_slave_hd.c | 58 ++++-- components/hal/include/hal/spi_slave_hd_hal.h | 23 ++- components/hal/spi_slave_hd_hal.c | 116 ++++++++++-- .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32p4/include/soc/soc_caps.h | 2 +- 10 files changed, 298 insertions(+), 101 deletions(-) diff --git a/components/driver/spi/gpspi/spi_slave.c b/components/driver/spi/gpspi/spi_slave.c index 1ab5299cb54c..f71a0443e491 100644 --- a/components/driver/spi/gpspi/spi_slave.c +++ b/components/driver/spi/gpspi/spi_slave.c @@ -184,7 +184,9 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, (size_t *)&spihost[host]->internal_mem_align_size); + size_t alignment; + esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, &alignment); + spihost[host]->internal_mem_align_size = alignment; #else spihost[host]->internal_mem_align_size = 4; #endif diff --git a/components/driver/spi/gpspi/spi_slave_hd.c b/components/driver/spi/gpspi/spi_slave_hd.c index 18707232ad21..8612748a1de7 100644 --- a/components/driver/spi/gpspi/spi_slave_hd.c +++ b/components/driver/spi/gpspi/spi_slave_hd.c @@ -5,6 +5,7 @@ */ #include "esp_log.h" +#include "esp_check.h" #include "esp_memory_utils.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" @@ -12,9 +13,12 @@ #include "freertos/ringbuf.h" #include "driver/gpio.h" #include "esp_private/spi_common_internal.h" +#include "esp_private/esp_cache_private.h" #include "driver/spi_slave_hd.h" #include "hal/spi_slave_hd_hal.h" - +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#include "esp_cache.h" +#endif #if (SOC_SPI_PERIPH_NUM == 2) #define VALID_HOST(x) ((x) == SPI2_HOST) @@ -23,8 +27,15 @@ #endif #define SPIHD_CHECK(cond,warn,ret) do{if(!(cond)){ESP_LOGE(TAG, warn); return ret;}} while(0) +/// struct to hold private transaction data (like tx and rx buffer for DMA). +typedef struct { + spi_slave_hd_data_t *trans; //original trans + void *aligned_buffer; //actually trans buffer (re-malloced if needed) +} spi_slave_hd_trans_priv_t; + typedef struct { bool dma_enabled; + uint16_t internal_mem_align_size; int max_transfer_sz; uint32_t flags; portMUX_TYPE int_spinlock; @@ -45,8 +56,8 @@ typedef struct { QueueHandle_t tx_cnting_sem; QueueHandle_t rx_cnting_sem; - spi_slave_hd_data_t *tx_desc; - spi_slave_hd_data_t *rx_desc; + spi_slave_hd_trans_priv_t tx_curr_trans; + spi_slave_hd_trans_priv_t rx_curr_trans; #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; #endif @@ -103,9 +114,9 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b 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); - lldesc_t *orig_dmadesc_tx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); - lldesc_t *orig_dmadesc_rx = heap_caps_malloc(sizeof(lldesc_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)) { @@ -120,8 +131,15 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b //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); + host->internal_mem_align_size = alignment; +#else + host->internal_mem_align_size = 4; +#endif } else { - //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. + //We're limited to non-DMA transfers: the SPI work registers can hold (72 for S2, 64 for others) bytes at most. host->max_transfer_sz = 0; } @@ -130,8 +148,7 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b goto cleanup; } gpio_set_direction(config->spics_io_num, GPIO_MODE_INPUT); - spicommon_cs_initialize(host_id, config->spics_io_num, 0, - !(bus_config->flags & SPICOMMON_BUSFLAG_NATIVE_PINS)); + spicommon_cs_initialize(host_id, config->spics_io_num, 0, !(bus_config->flags & SPICOMMON_BUSFLAG_NATIVE_PINS)); spi_slave_hd_hal_config_t hal_config = { .host_id = host_id, @@ -159,11 +176,11 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b #endif //CONFIG_PM_ENABLE //Create Queues and Semaphores - host->tx_ret_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_data_t *)); - host->rx_ret_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_data_t *)); + host->tx_ret_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_trans_priv_t)); + host->rx_ret_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_trans_priv_t)); if (!host->append_mode) { - host->tx_trans_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_data_t *)); - host->rx_trans_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_data_t *)); + host->tx_trans_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_trans_priv_t)); + host->rx_trans_queue = xQueueCreate(config->queue_size, sizeof(spi_slave_hd_trans_priv_t)); if (!host->tx_trans_queue || !host->rx_trans_queue) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -305,10 +322,10 @@ static IRAM_ATTR void spi_slave_hd_intr_segment(void *arg) bool rx_done = false; portENTER_CRITICAL_ISR(&host->int_spinlock); - if (host->tx_desc && spi_slave_hd_hal_check_disable_event(hal, SPI_EV_SEND)) { + if (host->tx_curr_trans.trans && spi_slave_hd_hal_check_disable_event(hal, SPI_EV_SEND)) { tx_done = true; } - if (host->rx_desc && spi_slave_hd_hal_check_disable_event(hal, SPI_EV_RECV)) { + if (host->rx_curr_trans.trans && spi_slave_hd_hal_check_disable_event(hal, SPI_EV_RECV)) { rx_done = true; } portEXIT_CRITICAL_ISR(&host->int_spinlock); @@ -318,50 +335,56 @@ static IRAM_ATTR void spi_slave_hd_intr_segment(void *arg) if (callback->cb_sent) { spi_slave_hd_event_t ev = { .event = SPI_EV_SEND, - .trans = host->tx_desc, + .trans = host->tx_curr_trans.trans, }; BaseType_t cb_awoken = pdFALSE; ret_queue = callback->cb_sent(callback->arg, &ev, &cb_awoken); awoken |= cb_awoken; } if (ret_queue) { - ret = xQueueSendFromISR(host->tx_ret_queue, &host->tx_desc, &awoken); + ret = xQueueSendFromISR(host->tx_ret_queue, &host->tx_curr_trans, &awoken); // The return queue is full. All the data remian in send_queue + ret_queue should not be more than the queue length. assert(ret == pdTRUE); } - host->tx_desc = NULL; + host->tx_curr_trans.trans = NULL; } if (rx_done) { bool ret_queue = true; - host->rx_desc->trans_len = spi_slave_hd_hal_rxdma_seg_get_len(hal); + host->rx_curr_trans.trans->trans_len = spi_slave_hd_hal_rxdma_seg_get_len(hal); +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible + uint16_t alignment = host->internal_mem_align_size; + uint32_t buff_len = (host->rx_curr_trans.trans->len + alignment - 1) & (~(alignment - 1)); + esp_err_t ret = esp_cache_msync((void *)host->rx_curr_trans.aligned_buffer, buff_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(ret == ESP_OK); +#endif if (callback->cb_recv) { spi_slave_hd_event_t ev = { .event = SPI_EV_RECV, - .trans = host->rx_desc, + .trans = host->rx_curr_trans.trans, }; BaseType_t cb_awoken = pdFALSE; ret_queue = callback->cb_recv(callback->arg, &ev, &cb_awoken); awoken |= cb_awoken; } if (ret_queue) { - ret = xQueueSendFromISR(host->rx_ret_queue, &host->rx_desc, &awoken); + ret = xQueueSendFromISR(host->rx_ret_queue, &host->rx_curr_trans, &awoken); // The return queue is full. All the data remian in send_queue + ret_queue should not be more than the queue length. assert(ret == pdTRUE); } - host->rx_desc = NULL; + host->rx_curr_trans.trans = NULL; } bool tx_sent = false; bool rx_sent = false; - if (!host->tx_desc) { - ret = xQueueReceiveFromISR(host->tx_trans_queue, &host->tx_desc, &awoken); + if (!host->tx_curr_trans.trans) { + ret = xQueueReceiveFromISR(host->tx_trans_queue, &host->tx_curr_trans, &awoken); if (ret == pdTRUE) { - spi_slave_hd_hal_txdma(hal, host->tx_desc->data, host->tx_desc->len); + spi_slave_hd_hal_txdma(hal, host->tx_curr_trans.aligned_buffer, host->tx_curr_trans.trans->len); tx_sent = true; if (callback->cb_send_dma_ready) { spi_slave_hd_event_t ev = { .event = SPI_EV_SEND_DMA_READY, - .trans = host->tx_desc, + .trans = host->tx_curr_trans.trans, }; BaseType_t cb_awoken = pdFALSE; callback->cb_send_dma_ready(callback->arg, &ev, &cb_awoken); @@ -369,15 +392,15 @@ static IRAM_ATTR void spi_slave_hd_intr_segment(void *arg) } } } - if (!host->rx_desc) { - ret = xQueueReceiveFromISR(host->rx_trans_queue, &host->rx_desc, &awoken); + if (!host->rx_curr_trans.trans) { + ret = xQueueReceiveFromISR(host->rx_trans_queue, &host->rx_curr_trans, &awoken); if (ret == pdTRUE) { - spi_slave_hd_hal_rxdma(hal, host->rx_desc->data, host->rx_desc->len); + spi_slave_hd_hal_rxdma(hal, host->rx_curr_trans.aligned_buffer, host->rx_curr_trans.trans->len); rx_sent = true; if (callback->cb_recv_dma_ready) { spi_slave_hd_event_t ev = { .event = SPI_EV_RECV_DMA_READY, - .trans = host->rx_desc, + .trans = host->rx_curr_trans.trans, }; BaseType_t cb_awoken = pdFALSE; callback->cb_recv_dma_ready(callback->arg, &ev, &cb_awoken); @@ -406,10 +429,10 @@ static IRAM_ATTR void spi_slave_hd_append_tx_isr(void *arg) BaseType_t awoken = pdFALSE; BaseType_t ret __attribute__((unused)); - spi_slave_hd_data_t *trans_desc; + spi_slave_hd_trans_priv_t ret_priv_trans; while (1) { bool trans_finish = false; - trans_finish = spi_slave_hd_hal_get_tx_finished_trans(hal, (void **)&trans_desc); + trans_finish = spi_slave_hd_hal_get_tx_finished_trans(hal, (void **)&ret_priv_trans.trans, &ret_priv_trans.aligned_buffer); if (!trans_finish) { break; } @@ -418,7 +441,7 @@ static IRAM_ATTR void spi_slave_hd_append_tx_isr(void *arg) if (callback->cb_sent) { spi_slave_hd_event_t ev = { .event = SPI_EV_SEND, - .trans = trans_desc, + .trans = ret_priv_trans.trans, }; BaseType_t cb_awoken = pdFALSE; ret_queue = callback->cb_sent(callback->arg, &ev, &cb_awoken); @@ -426,7 +449,7 @@ static IRAM_ATTR void spi_slave_hd_append_tx_isr(void *arg) } if (ret_queue) { - ret = xQueueSendFromISR(host->tx_ret_queue, &trans_desc, &awoken); + ret = xQueueSendFromISR(host->tx_ret_queue, &ret_priv_trans, &awoken); assert(ret == pdTRUE); ret = xSemaphoreGiveFromISR(host->tx_cnting_sem, &awoken); @@ -444,21 +467,27 @@ static IRAM_ATTR void spi_slave_hd_append_rx_isr(void *arg) BaseType_t awoken = pdFALSE; BaseType_t ret __attribute__((unused)); - spi_slave_hd_data_t *trans_desc; + + spi_slave_hd_trans_priv_t ret_priv_trans; size_t trans_len; while (1) { bool trans_finish = false; - trans_finish = spi_slave_hd_hal_get_rx_finished_trans(hal, (void **)&trans_desc, &trans_len); + trans_finish = spi_slave_hd_hal_get_rx_finished_trans(hal, (void **)&ret_priv_trans.trans, &ret_priv_trans.aligned_buffer, &trans_len); if (!trans_finish) { break; } - trans_desc->trans_len = trans_len; - + ret_priv_trans.trans->trans_len = trans_len; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible + uint16_t alignment = host->internal_mem_align_size; + uint32_t buff_len = (ret_priv_trans.trans->len + alignment - 1) & (~(alignment - 1)); + esp_err_t ret = esp_cache_msync((void *)ret_priv_trans.aligned_buffer, buff_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(ret == ESP_OK); +#endif bool ret_queue = true; if (callback->cb_recv) { spi_slave_hd_event_t ev = { .event = SPI_EV_RECV, - .trans = trans_desc, + .trans = ret_priv_trans.trans, }; BaseType_t cb_awoken = pdFALSE; ret_queue = callback->cb_recv(callback->arg, &ev, &cb_awoken); @@ -466,7 +495,7 @@ static IRAM_ATTR void spi_slave_hd_append_rx_isr(void *arg) } if (ret_queue) { - ret = xQueueSendFromISR(host->rx_ret_queue, &trans_desc, &awoken); + ret = xQueueSendFromISR(host->rx_ret_queue, &ret_priv_trans, &awoken); assert(ret == pdTRUE); ret = xSemaphoreGiveFromISR(host->rx_cnting_sem, &awoken); @@ -514,22 +543,64 @@ static IRAM_ATTR void spi_slave_hd_intr_append(void *arg) } } +static void s_spi_slave_hd_destroy_priv_trans(spi_host_device_t host, spi_slave_hd_trans_priv_t *priv_trans, spi_slave_chan_t chan) +{ +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + spi_slave_hd_data_t *orig_trans = priv_trans->trans; + if (priv_trans->aligned_buffer != orig_trans->data) { + if (chan == SPI_SLAVE_CHAN_RX) { + memcpy(orig_trans->data, priv_trans->aligned_buffer, orig_trans->trans_len); + } + free(priv_trans->aligned_buffer); + } +#endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +} + +static esp_err_t s_spi_slave_hd_setup_priv_trans(spi_host_device_t host, spi_slave_hd_trans_priv_t *priv_trans, spi_slave_chan_t chan) +{ + spi_slave_hd_data_t *orig_trans = priv_trans->trans; + + priv_trans->aligned_buffer = orig_trans->data; + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + uint16_t alignment = spihost[host]->internal_mem_align_size; + uint32_t byte_len = orig_trans->len; + + if (((uint32_t)orig_trans->data) | (byte_len & (alignment - 1))) { + ESP_RETURN_ON_FALSE(orig_trans->flags & SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, ESP_ERR_INVALID_ARG, TAG, "data buffer addr&len not align to %d, or not dma_capable", alignment); + byte_len = (byte_len + alignment - 1) & (~(alignment - 1)); // up align to alignment + ESP_LOGD(TAG, "Re-allocate %s buffer of len %ld for DMA", (chan == SPI_SLAVE_CHAN_TX)?"TX":"RX", byte_len); + priv_trans->aligned_buffer = heap_caps_aligned_alloc(64, byte_len, MALLOC_CAP_DMA); + if (priv_trans->aligned_buffer == NULL) { + return ESP_ERR_NO_MEM; + } + } + if (chan == SPI_SLAVE_CHAN_TX) { + memcpy(priv_trans->aligned_buffer, orig_trans->data, orig_trans->len); + esp_err_t ret = esp_cache_msync((void *)priv_trans->aligned_buffer, byte_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + ESP_RETURN_ON_FALSE(ESP_OK == ret, ESP_ERR_INVALID_STATE, TAG, "mem sync c2m(writeback) fail"); + } +#endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + return ESP_OK; +} + static esp_err_t get_ret_queue_result(spi_host_device_t host_id, spi_slave_chan_t chan, spi_slave_hd_data_t **out_trans, TickType_t timeout) { spi_slave_hd_slot_t *host = spihost[host_id]; - spi_slave_hd_data_t *trans; + spi_slave_hd_trans_priv_t hd_priv_trans; BaseType_t ret; if (chan == SPI_SLAVE_CHAN_TX) { - ret = xQueueReceive(host->tx_ret_queue, &trans, timeout); + ret = xQueueReceive(host->tx_ret_queue, &hd_priv_trans, timeout); } else { - ret = xQueueReceive(host->rx_ret_queue, &trans, timeout); + ret = xQueueReceive(host->rx_ret_queue, &hd_priv_trans, timeout); } if (ret == pdFALSE) { return ESP_ERR_TIMEOUT; } - *out_trans = trans; + s_spi_slave_hd_destroy_priv_trans(host_id, &hd_priv_trans, chan); + *out_trans = hd_priv_trans.trans; return ESP_OK; } @@ -543,14 +614,17 @@ esp_err_t spi_slave_hd_queue_trans(spi_host_device_t host_id, spi_slave_chan_t c SPIHD_CHECK(trans->len <= host->max_transfer_sz && trans->len > 0, "Invalid buffer size", ESP_ERR_INVALID_ARG); SPIHD_CHECK(chan == SPI_SLAVE_CHAN_TX || chan == SPI_SLAVE_CHAN_RX, "Invalid channel", ESP_ERR_INVALID_ARG); + spi_slave_hd_trans_priv_t hd_priv_trans = {.trans = trans}; + SPIHD_CHECK( ESP_OK == s_spi_slave_hd_setup_priv_trans(host_id, &hd_priv_trans, chan), "No mem to allocate new cache buffer", ESP_ERR_NO_MEM); + if (chan == SPI_SLAVE_CHAN_TX) { - BaseType_t ret = xQueueSend(host->tx_trans_queue, &trans, timeout); + BaseType_t ret = xQueueSend(host->tx_trans_queue, &hd_priv_trans, timeout); if (ret == pdFALSE) { return ESP_ERR_TIMEOUT; } tx_invoke(host); } else { //chan == SPI_SLAVE_CHAN_RX - BaseType_t ret = xQueueSend(host->rx_trans_queue, &trans, timeout); + BaseType_t ret = xQueueSend(host->rx_trans_queue, &hd_priv_trans, timeout); if (ret == pdFALSE) { return ESP_ERR_TIMEOUT; } @@ -594,18 +668,21 @@ esp_err_t spi_slave_hd_append_trans(spi_host_device_t host_id, spi_slave_chan_t SPIHD_CHECK(trans->len <= host->max_transfer_sz && trans->len > 0, "Invalid buffer size", ESP_ERR_INVALID_ARG); SPIHD_CHECK(chan == SPI_SLAVE_CHAN_TX || chan == SPI_SLAVE_CHAN_RX, "Invalid channel", ESP_ERR_INVALID_ARG); + spi_slave_hd_trans_priv_t hd_priv_trans = {.trans = trans}; + SPIHD_CHECK( ESP_OK == s_spi_slave_hd_setup_priv_trans(host_id, &hd_priv_trans, chan), "No mem to allocate new cache buffer", ESP_ERR_NO_MEM); + if (chan == SPI_SLAVE_CHAN_TX) { BaseType_t ret = xSemaphoreTake(host->tx_cnting_sem, timeout); if (ret == pdFALSE) { return ESP_ERR_TIMEOUT; } - err = spi_slave_hd_hal_txdma_append(hal, trans->data, trans->len, trans); + err = spi_slave_hd_hal_txdma_append(hal, hd_priv_trans.aligned_buffer, trans->len, trans); } else { BaseType_t ret = xSemaphoreTake(host->rx_cnting_sem, timeout); if (ret == pdFALSE) { return ESP_ERR_TIMEOUT; } - err = spi_slave_hd_hal_rxdma_append(hal, trans->data, trans->len, trans); + err = spi_slave_hd_hal_rxdma_append(hal, hd_priv_trans.aligned_buffer, trans->len, trans); } if (err != ESP_OK) { ESP_LOGE(TAG, "Wait until the DMA finishes its transaction"); diff --git a/components/driver/spi/include/driver/spi_slave_hd.h b/components/driver/spi/include/driver/spi_slave_hd.h index 5d6ff4c2b9e3..fbd8caca4a7f 100644 --- a/components/driver/spi/include/driver/spi_slave_hd.h +++ b/components/driver/spi/include/driver/spi_slave_hd.h @@ -23,11 +23,14 @@ extern "C" #error The SPI peripheral does not support this feature #endif +#define SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO (1<<0) ///< Automatically re-malloc dma buffer if user buffer doesn't meet hardware alignment or dma_capable, this process may lose some memory and performance + /// Descriptor of data to send/receive typedef struct { uint8_t* data; ///< Buffer to send, must be DMA capable size_t len; ///< Len of data to send/receive. For receiving the buffer length should be multiples of 4 bytes, otherwise the extra part will be truncated. size_t trans_len; ///< For RX direction, it indicates the data actually received. For TX direction, it is meaningless. + uint32_t flags; ///< Bitwise OR of SPI_SLAVE_HD_TRANS_* flags void* arg; ///< Extra argument indiciating this data } spi_slave_hd_data_t; diff --git a/components/driver/test_apps/spi/slave_hd/README.md b/components/driver/test_apps/spi/slave_hd/README.md index e958430328ec..4cd177cd5b09 100644 --- a/components/driver/test_apps/spi/slave_hd/README.md +++ b/components/driver/test_apps/spi/slave_hd/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file diff --git a/components/driver/test_apps/spi/slave_hd/main/test_app_main.c b/components/driver/test_apps/spi/slave_hd/main/test_app_main.c index cd193d6a6b6b..3beae81ebfcf 100644 --- a/components/driver/test_apps/spi/slave_hd/main/test_app_main.c +++ b/components/driver/test_apps/spi/slave_hd/main/test_app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,23 +10,15 @@ #define TEST_MEMORY_LEAK_THRESHOLD (200) -static size_t before_free_8bit; -static size_t before_free_32bit; - void setUp(void) { - before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + unity_utils_record_free_mem(); } void tearDown(void) { esp_reent_cleanup(); //clean up some of the newlib's lazy allocations - size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); - printf("\n"); - unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD); - unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD); + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); } void app_main(void) diff --git a/components/driver/test_apps/spi/slave_hd/main/test_spi_slave_hd.c b/components/driver/test_apps/spi/slave_hd/main/test_spi_slave_hd.c index 67734bcda4a2..eb547e0debf1 100644 --- a/components/driver/test_apps/spi/slave_hd/main/test_spi_slave_hd.c +++ b/components/driver/test_apps/spi/slave_hd/main/test_spi_slave_hd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -224,6 +224,7 @@ static void test_hd_start(spi_device_handle_t *spi, int freq, const spitest_para ctx->tx_data = (spi_slave_hd_data_t) { .data = &ctx->slave_rddma_buf[pos], .len = len, + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }; esp_err_t err = spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ctx->tx_data, portMAX_DELAY); TEST_ESP_OK(err); @@ -231,6 +232,7 @@ static void test_hd_start(spi_device_handle_t *spi, int freq, const spitest_para ctx->rx_data = (spi_slave_hd_data_t) { .data = ctx->slave_wrdma_buf, .len = TEST_DMA_MAX_SIZE, + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }; err = spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &ctx->rx_data, portMAX_DELAY); TEST_ESP_OK(err); @@ -269,6 +271,7 @@ void test_wrdma(testhd_context_t* ctx, const spitest_param_set_t *cfg, spi_devic ctx->rx_data = (spi_slave_hd_data_t) { .data = ctx->slave_wrdma_buf, .len = TEST_DMA_MAX_SIZE, + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }; esp_err_t err = spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &ctx->rx_data, portMAX_DELAY); TEST_ESP_OK(err); @@ -302,6 +305,7 @@ void test_rddma(testhd_context_t* ctx, const spitest_param_set_t* cfg, spi_devic ctx->tx_data = (spi_slave_hd_data_t) { .data = &ctx->slave_rddma_buf[pos], .len = len, + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }; esp_err_t err = spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ctx->tx_data, portMAX_DELAY); TEST_ESP_OK(err); @@ -415,6 +419,14 @@ static void test_hd_loop(const void* arg1, void* arg2) TEST_ASSERT_EQUAL_HEX8_ARRAY(&slave_mem, recv_buffer, REG_REGION_SIZE); } + //To release the re-malloced buffer remain in slave trans queue if possible + printf("clean tx %d rx %d\n", context->tx_data.len, context->rx_data.len); + TEST_ESP_OK(essl_spi_rddma(spi, context->master_rddma_buf, context->tx_data.len, TEST_SEG_SIZE, 0)); + TEST_ESP_OK(essl_spi_wrdma(spi, context->master_wrdma_buf, context->rx_data.len, TEST_SEG_SIZE, 0)); + spi_slave_hd_data_t* ret_trans; + TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY)); + TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &ret_trans, portMAX_DELAY)); + master_free_device_bus(spi); spi_slave_hd_deinit(TEST_SLAVE_HOST); } @@ -434,8 +446,8 @@ static const ptest_func_t hd_test_func = { static int test_freq_hd[] = { // 100*1000, // 10 * 1000 * 1000, //maximum freq MISO stable before next latch edge - // 20 * 1000 * 1000, //maximum freq MISO stable before next latch edge - 40 * 1000 * 1000, //maximum freq MISO stable before next latch edge + 20 * 1000 * 1000, //maximum freq MISO stable before next latch edge + // 40 * 1000 * 1000, //maximum freq MISO stable before next latch edge 0, }; @@ -520,19 +532,23 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]" { .data = slave_recv_buf, .len = (trans_len[0] + 3) & (~3), + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }, { .data = slave_recv_buf + send_buf_size, .len = (trans_len[1] + 3) & (~3), + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }, //send { .data = slave_send_buf, .len = trans_len[0], + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }, { .data = slave_send_buf + send_buf_size, .len = trans_len[1], + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }, }; @@ -925,15 +941,17 @@ 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); - // append one more transaction - int new_append_len = trans_len << 4; - if (new_append_len > TEST_TRANS_LEN) { - new_append_len = TEST_TRANS_LEN; + if (trans_num <= TEST_APPEND_CACHE_SIZE) { + // append one more transaction + int new_append_len = trans_len << 4; + if (new_append_len > TEST_TRANS_LEN) { + new_append_len = TEST_TRANS_LEN; + } + memset(ret_trans->data, 0, ret_trans->trans_len); + ret_trans->len = new_append_len; + ret_trans->trans_len = 0; + TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, ret_trans, portMAX_DELAY)); } - memset(ret_trans->data, 0, ret_trans->trans_len); - ret_trans->len = new_append_len; - ret_trans->trans_len = 0; - TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, ret_trans, portMAX_DELAY)); } printf("================Master Tx Done==================\n\n"); free(slave_exp); @@ -958,15 +976,17 @@ 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); - // append one more transaction - int new_append_len = 16 << (trans_num + 4); - if (new_append_len > TEST_TRANS_LEN) { - new_append_len = TEST_TRANS_LEN; + if (trans_num <= TEST_APPEND_CACHE_SIZE) { + // append one more transaction + int new_append_len = 16 << (trans_num + 4); + if (new_append_len > TEST_TRANS_LEN) { + new_append_len = TEST_TRANS_LEN; + } + ret_trans->len = new_append_len; + ret_trans->trans_len = 0; + prepare_data(ret_trans->data, ret_trans->len, -3); + TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, ret_trans, portMAX_DELAY)); } - ret_trans->len = new_append_len; - ret_trans->trans_len = 0; - prepare_data(ret_trans->data, ret_trans->len, -3); - TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, ret_trans, portMAX_DELAY)); } printf("================Master Rx Done==================\n"); for (int i = 0; i < TEST_APPEND_CACHE_SIZE; i++) free(slave_tx_trans[i].data); diff --git a/components/hal/include/hal/spi_slave_hd_hal.h b/components/hal/include/hal/spi_slave_hd_hal.h index 029112df5d9b..2df4d6d06ab1 100644 --- a/components/hal/include/hal/spi_slave_hd_hal.h +++ b/components/hal/include/hal/spi_slave_hd_hal.h @@ -46,7 +46,9 @@ #include "esp_types.h" #include "esp_err.h" #include "soc/soc_caps.h" +#include "soc/gdma_channel.h" #include "hal/spi_types.h" +#include "hal/dma_types.h" #if SOC_GPSPI_SUPPORTED #include "hal/spi_ll.h" #endif @@ -57,13 +59,24 @@ extern "C" { #if SOC_GPSPI_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_TRIG_PERIPH_SPI2_BUS) +typedef dma_descriptor_align4_t spi_dma_desc_t; +#else +#if defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) +typedef dma_descriptor_align8_t spi_dma_desc_t; +#elif defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) +typedef dma_descriptor_align4_t spi_dma_desc_t; +#endif +#endif + /** * @brief Type of dma descriptor with appended members * this structure inherits DMA descriptor, with a pointer to the transaction descriptor passed from users. */ typedef struct { - lldesc_t *desc; ///< DMA descriptor - void *arg; ///< This points to the transaction descriptor user passed in + spi_dma_desc_t *desc; ///< DMA descriptor + void *arg; ///< This points to the transaction descriptor user passed in } spi_slave_hd_hal_desc_append_t; /// Configuration of the HAL @@ -253,9 +266,10 @@ int spi_slave_hd_hal_get_last_addr(spi_slave_hd_hal_context_t *hal); * * @param hal Context of the HAL layer * @param out_trans Pointer to the caller-defined transaction + * @param real_buff_addr Actually data buffer head the HW used * @return 1: Transaction is finished; 0: Transaction is not finished */ -bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans); +bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr); /** * @brief Return the finished RX transaction @@ -266,10 +280,11 @@ bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, voi * * @param hal Context of the HAL layer * @param out_trans Pointer to the caller-defined transaction + * @param real_buff_addr Actually data buffer head the HW used * @param out_len Actual number of bytes of received data * @return 1: Transaction is finished; 0: Transaction is not finished */ -bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, size_t *out_len); +bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr, size_t *out_len); /** * @brief Load the TX DMA descriptors without stopping the DMA diff --git a/components/hal/spi_slave_hd_hal.c b/components/hal/spi_slave_hd_hal.c index b0ee04bed327..ff7d48abb2d6 100644 --- a/components/hal/spi_slave_hd_hal.c +++ b/components/hal/spi_slave_hd_hal.c @@ -14,11 +14,13 @@ #include "soc/spi_periph.h" #include "soc/lldesc.h" #include "soc/soc_caps.h" +#include "soc/ext_mem_defs.h" #include "hal/spi_slave_hd_hal.h" #include "hal/assert.h" //This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros. -#if SOC_AHB_GDMA_VERSION == 1 +#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_tx_restart(dev, chan) gdma_ll_tx_restart(&GDMA, chan) @@ -41,7 +43,31 @@ gdma_ll_tx_set_desc_addr(&GDMA, chan, (uint32_t)addr);\ gdma_ll_tx_start(&GDMA, chan);\ } while (0) + +#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) +#include "hal/axi_dma_ll.h" +#define spi_dma_ll_tx_restart(dev, chan) axi_dma_ll_tx_restart(&AXI_DMA, chan) +#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) +#define spi_dma_ll_get_in_suc_eof_desc_addr(dev, chan) axi_dma_ll_rx_get_success_eof_desc_addr(&AXI_DMA, chan) +#define spi_dma_ll_rx_start(dev, chan, addr) do {\ + axi_dma_ll_rx_set_desc_addr(&AXI_DMA, chan, (uint32_t)addr);\ + axi_dma_ll_rx_start(&AXI_DMA, chan);\ + } while (0) +#define spi_dma_ll_tx_start(dev, chan, addr) do {\ + axi_dma_ll_tx_set_desc_addr(&AXI_DMA, chan, (uint32_t)addr);\ + axi_dma_ll_tx_start(&AXI_DMA, chan);\ + } while (0) #endif +#endif //SOC_GDMA_SUPPORTED static void s_spi_slave_hd_hal_dma_init_config(const spi_slave_hd_hal_context_t *hal) { @@ -117,9 +143,66 @@ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_h spi_ll_slave_set_seg_mode(hal->dev, true); } +#if SOC_NON_CACHEABLE_OFFSET +#define ADDR_DMA_2_CPU(addr) ((typeof(addr))((uint32_t)(addr) + 0x40000000)) +#define ADDR_CPU_2_DMA(addr) ((typeof(addr))((uint32_t)(addr) - 0x40000000)) +#else +#define ADDR_DMA_2_CPU(addr) (addr) +#define ADDR_CPU_2_DMA(addr) (addr) +#endif + +static void s_spi_hal_dma_desc_setup_link(spi_dma_desc_t *dmadesc, const void *data, int len, bool is_rx) +{ + dmadesc = ADDR_DMA_2_CPU(dmadesc); + int n = 0; + while (len) { + int dmachunklen = len; + if (dmachunklen > DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) { + dmachunklen = DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; + } + if (is_rx) { + //Receive needs DMA length rounded to next 32-bit boundary + dmadesc[n].dw0.size = (dmachunklen + 3) & (~3); + dmadesc[n].dw0.length = (dmachunklen + 3) & (~3); + } else { + dmadesc[n].dw0.size = dmachunklen; + dmadesc[n].dw0.length = dmachunklen; + } + dmadesc[n].buffer = (uint8_t *)data; + dmadesc[n].dw0.suc_eof = 0; + dmadesc[n].dw0.owner = 1; + dmadesc[n].next = ADDR_CPU_2_DMA(&dmadesc[n + 1]); + len -= dmachunklen; + data += dmachunklen; + n++; + } + dmadesc[n - 1].dw0.suc_eof = 1; //Mark last DMA desc as end of stream. + dmadesc[n - 1].next = NULL; +} + +static int s_desc_get_received_len_addr(spi_dma_desc_t* head, spi_dma_desc_t** out_next, void **out_buff_head) +{ + spi_dma_desc_t* desc_cpu = ADDR_DMA_2_CPU(head); + int len = 0; + if (out_buff_head) { + *out_buff_head = desc_cpu->buffer; + } + while(head) { + len += desc_cpu->dw0.length; + bool eof = desc_cpu->dw0.suc_eof; + desc_cpu = ADDR_DMA_2_CPU(desc_cpu->next); + head = head->next; + if (eof) break; + } + if (out_next) { + *out_next = head; + } + return len; +} + void spi_slave_hd_hal_rxdma(spi_slave_hd_hal_context_t *hal, uint8_t *out_buf, size_t len) { - lldesc_setup_link(hal->dmadesc_rx->desc, out_buf, len, true); + s_spi_hal_dma_desc_setup_link(hal->dmadesc_rx->desc, out_buf, len, true); spi_ll_dma_rx_fifo_reset(hal->dev); spi_dma_ll_rx_reset(hal->dma_in, hal->rx_dma_chan); @@ -128,12 +211,12 @@ void spi_slave_hd_hal_rxdma(spi_slave_hd_hal_context_t *hal, uint8_t *out_buf, s spi_ll_clear_intr(hal->dev, SPI_LL_INTR_CMD7); spi_ll_dma_rx_enable(hal->dev, 1); - spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->dmadesc_rx->desc); + spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, (lldesc_t *)hal->dmadesc_rx->desc); } void spi_slave_hd_hal_txdma(spi_slave_hd_hal_context_t *hal, uint8_t *data, size_t len) { - lldesc_setup_link(hal->dmadesc_tx->desc, data, len, false); + s_spi_hal_dma_desc_setup_link(hal->dmadesc_tx->desc, data, len, false); spi_ll_dma_tx_fifo_reset(hal->dev); spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan); @@ -142,7 +225,7 @@ void spi_slave_hd_hal_txdma(spi_slave_hd_hal_context_t *hal, uint8_t *data, size spi_ll_clear_intr(hal->dev, SPI_LL_INTR_CMD8); spi_ll_dma_tx_enable(hal->dev, 1); - spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->dmadesc_tx->desc); + spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, (lldesc_t *)hal->dmadesc_tx->desc); } static spi_ll_intr_t get_event_intr(spi_slave_hd_hal_context_t *hal, spi_event_t ev) @@ -238,11 +321,11 @@ int spi_slave_hd_hal_get_rxlen(spi_slave_hd_hal_context_t *hal) int spi_slave_hd_hal_rxdma_seg_get_len(spi_slave_hd_hal_context_t *hal) { - lldesc_t *desc = hal->dmadesc_rx->desc; - return lldesc_get_received_len(desc, NULL); + spi_dma_desc_t *desc = hal->dmadesc_rx->desc; + return s_desc_get_received_len_addr(desc, NULL, NULL); } -bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans) +bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr) { uint32_t desc_now = spi_dma_ll_get_out_eof_desc_addr(hal->dma_out, hal->tx_dma_chan); if ((uint32_t)hal->tx_dma_head->desc == desc_now) { @@ -255,11 +338,12 @@ bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, voi hal->tx_dma_head = hal->dmadesc_tx; } *out_trans = hal->tx_dma_head->arg; + s_desc_get_received_len_addr(hal->tx_dma_head->desc, NULL, real_buff_addr); hal->tx_recycled_desc_cnt++; return true; } -bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, size_t *out_len) +bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr, size_t *out_len) { uint32_t desc_now = spi_dma_ll_get_in_suc_eof_desc_addr(hal->dma_in, hal->rx_dma_chan); if ((uint32_t)hal->rx_dma_head->desc == desc_now) { @@ -272,7 +356,7 @@ bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, voi hal->rx_dma_head = hal->dmadesc_rx; } *out_trans = hal->rx_dma_head->arg; - *out_len = hal->rx_dma_head->desc->length; + *out_len = s_desc_get_received_len_addr(hal->rx_dma_head->desc, NULL, real_buff_addr); hal->rx_recycled_desc_cnt++; return true; } @@ -287,7 +371,7 @@ esp_err_t spi_slave_hd_hal_txdma_append(spi_slave_hd_hal_context_t *hal, uint8_t return ESP_ERR_INVALID_STATE; } - lldesc_setup_link(hal->tx_cur_desc->desc, data, len, false); + s_spi_hal_dma_desc_setup_link(hal->tx_cur_desc->desc, data, len, false); hal->tx_cur_desc->arg = arg; if (!hal->tx_dma_started) { @@ -298,10 +382,10 @@ esp_err_t spi_slave_hd_hal_txdma_append(spi_slave_hd_hal_context_t *hal, uint8_t spi_ll_outfifo_empty_clr(hal->dev); spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan); spi_ll_dma_tx_enable(hal->dev, 1); - spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->tx_cur_desc->desc); + spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, (lldesc_t *)hal->tx_cur_desc->desc); } else { //there is already a consecutive link - STAILQ_NEXT(hal->tx_dma_tail->desc, qe) = hal->tx_cur_desc->desc; + ADDR_DMA_2_CPU(hal->tx_dma_tail->desc)->next = hal->tx_cur_desc->desc; hal->tx_dma_tail = hal->tx_cur_desc; spi_dma_ll_tx_restart(hal->dma_out, hal->tx_dma_chan); } @@ -328,7 +412,7 @@ esp_err_t spi_slave_hd_hal_rxdma_append(spi_slave_hd_hal_context_t *hal, uint8_t return ESP_ERR_INVALID_STATE; } - lldesc_setup_link(hal->rx_cur_desc->desc, data, len, false); + s_spi_hal_dma_desc_setup_link(hal->rx_cur_desc->desc, data, len, false); hal->rx_cur_desc->arg = arg; if (!hal->rx_dma_started) { @@ -339,10 +423,10 @@ esp_err_t spi_slave_hd_hal_rxdma_append(spi_slave_hd_hal_context_t *hal, uint8_t spi_ll_dma_rx_fifo_reset(hal->dma_in); spi_ll_infifo_full_clr(hal->dev); spi_ll_dma_rx_enable(hal->dev, 1); - spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->rx_cur_desc->desc); + spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, (lldesc_t *)hal->rx_cur_desc->desc); } else { //there is already a consecutive link - STAILQ_NEXT(hal->rx_dma_tail->desc, qe) = hal->rx_cur_desc->desc; + ADDR_DMA_2_CPU(hal->rx_dma_tail->desc)->next = hal->rx_cur_desc->desc; hal->rx_dma_tail = hal->rx_cur_desc; spi_dma_ll_rx_restart(hal->dma_in, hal->rx_dma_chan); } diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index ded76ad0fb9c..33d8166b2be4 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -891,6 +891,10 @@ config SOC_SPI_MAXIMUM_BUFFER_SIZE int default 64 +config SOC_SPI_SUPPORT_SLAVE_HD_VER2 + bool + default y + config SOC_SPI_SLAVE_SUPPORT_SEG_TRANS bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index f351f934b848..835e1c354c30 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -405,7 +405,7 @@ #define SOC_SPI_MAX_CS_NUM 6 #define SOC_SPI_MAXIMUM_BUFFER_SIZE 64 -// #define SOC_SPI_SUPPORT_SLAVE_HD_VER2 1 //TODO: IDF-7505 +#define SOC_SPI_SUPPORT_SLAVE_HD_VER2 1 #define SOC_SPI_SLAVE_SUPPORT_SEG_TRANS 1 #define SOC_SPI_SUPPORT_DDRCLK 1 #define SOC_SPI_SUPPORT_CD_SIG 1 From 2e115ec98c6915e8c4dee4c07e635acd7164478a Mon Sep 17 00:00:00 2001 From: wanlei Date: Thu, 14 Sep 2023 17:07:31 +0800 Subject: [PATCH 3/3] feat(spi_slave_hd): p4 update examples and document --- .../driver/test_apps/.build-test-rules.yml | 3 -- .../driver/test_apps/spi/param/README.md | 4 +-- .../test_apps/spi/param/main/test_spi_param.c | 4 +++ docs/docs_not_updated/esp32p4.txt | 2 -- .../protocols/esp_spi_slave_protocol.rst | 30 +++++++++---------- examples/peripherals/.build-test-rules.yml | 20 ++++--------- .../spi_slave_hd/append_mode/README.md | 2 +- .../spi_slave_hd/append_mode/master/README.md | 4 +-- .../append_mode/master/main/app_main.c | 11 ++----- .../spi_slave_hd/append_mode/slave/README.md | 4 +-- .../append_mode/slave/main/app_main.c | 6 +++- .../spi_slave_hd/segment_mode/README.md | 5 ++-- .../segment_mode/seg_master/README.md | 4 +-- .../segment_mode/seg_master/main/app_main.c | 27 +++-------------- .../segment_mode/seg_slave/README.md | 4 +-- .../segment_mode/seg_slave/main/app_main.c | 25 ++-------------- 16 files changed, 52 insertions(+), 103 deletions(-) diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 23f308bc54ae..25649b7e4057 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -142,9 +142,6 @@ components/driver/test_apps/spi/master: components/driver/test_apps/spi/param: disable: - if: SOC_GPSPI_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-7505 components/driver/test_apps/spi/slave: disable: diff --git a/components/driver/test_apps/spi/param/README.md b/components/driver/test_apps/spi/param/README.md index 07b81b7c84c7..5b39ff96532d 100644 --- a/components/driver/test_apps/spi/param/README.md +++ b/components/driver/test_apps/spi/param/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file diff --git a/components/driver/test_apps/spi/param/main/test_spi_param.c b/components/driver/test_apps/spi/param/main/test_spi_param.c index 8bafdb54ac54..3ffee20b242e 100644 --- a/components/driver/test_apps/spi/param/main/test_spi_param.c +++ b/components/driver/test_apps/spi/param/main/test_spi_param.c @@ -1374,6 +1374,7 @@ static void test_slave_fd_dma(void) .tx_buffer = slave_send, .rx_buffer = slave_recive, .length = test_trans_len * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; unity_send_signal("Slave ready"); TEST_ESP_OK(spi_slave_transmit(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY)); @@ -1589,6 +1590,7 @@ static void test_slave_hd_dma(void) spi_slave_hd_data_t *ret_trans, slave_trans = { .data = slave_send, .len = test_trans_len, + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }; unity_send_signal("Slave ready"); TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_trans, portMAX_DELAY)); @@ -1690,6 +1692,7 @@ static void test_slave_hd_no_dma(void) spi_slave_hd_data_t *ret_trans, slave_trans = { .data = slave_send, .len = test_trans_len, + .flags = SPI_SLAVE_HD_TRANS_DMA_BUFFER_ALIGN_AUTO, }; unity_send_signal("Slave ready"); TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_trans, portMAX_DELAY)); @@ -1826,6 +1829,7 @@ static void test_slave_sio_dma(void) .length = TEST_STEP_LEN * 8, .tx_buffer = slave_send, .rx_buffer = slave_recive, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; unity_send_signal("Slave ready"); TEST_ESP_OK(spi_slave_transmit(TEST_SPI_HOST, &trans, portMAX_DELAY)); diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index 1423e81b2a0f..5a4bec20473c 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -106,7 +106,6 @@ api-reference/peripherals/spi_flash/auto_suspend.inc api-reference/peripherals/sdm.rst api-reference/peripherals/touch_pad.rst api-reference/peripherals/adc_calibration.rst -api-reference/peripherals/spi_slave_hd.rst api-reference/peripherals/parlio.rst api-reference/peripherals/i2c.rst api-reference/peripherals/dedic_gpio.rst @@ -168,7 +167,6 @@ api-reference/protocols/esp_local_ctrl.rst api-reference/protocols/esp_crt_bundle.rst api-reference/protocols/esp_http_client.rst api-reference/protocols/esp_https_server.rst -api-reference/protocols/esp_spi_slave_protocol.rst api-reference/protocols/modbus.rst api-reference/protocols/esp_tls.rst api-reference/protocols/mdns.rst diff --git a/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst b/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst index f2695674017a..545531480901 100644 --- a/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst +++ b/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst @@ -14,21 +14,21 @@ ESP SPI Slave HD (Half Duplex) Mode Protocol SPI Slave Capabilities of Espressif Chips ----------------------------------------- -+------------------+-------+----------+----------+----------+----------+----------+----------+ -| | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C2 | ESP32-C6 | ESP32-H2 | -+------------------+-------+----------+----------+----------+----------+----------+----------+ -| SPI Slave HD | N | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | -+------------------+-------+----------+----------+----------+----------+----------+----------+ -| Tohost intr | | N | N | N | N | N | N | -+------------------+-------+----------+----------+----------+----------+----------+----------+ -| Frhost intr | | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | -+------------------+-------+----------+----------+----------+----------+----------+----------+ -| TX DMA | | Y | Y | Y | Y | Y | Y | -+------------------+-------+----------+----------+----------+----------+----------+----------+ -| RX DMA | | Y | Y | Y | Y | Y | Y | -+------------------+-------+----------+----------+----------+----------+----------+----------+ -| Shared registers | | 72 | 64 | 64 | 64 | 64 | 64 | -+------------------+-------+----------+----------+----------+----------+----------+----------+ ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ +| | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C2 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ +| SPI Slave HD | N | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ +| Tohost intr | | N | N | N | N | N | N | N | ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ +| Frhost intr | | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ +| TX DMA | | Y | Y | Y | Y | Y | Y | Y | ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ +| RX DMA | | Y | Y | Y | Y | Y | Y | Y | ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ +| Shared registers | | 72 | 64 | 64 | 64 | 64 | 64 | 64 | ++------------------+-------+----------+----------+----------+----------+----------+----------+----------+ Introduction ------------ diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index e8c40bd3596f..66134a8dcff8 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -263,29 +263,19 @@ examples/peripherals/spi_slave: examples/peripherals/spi_slave_hd/append_mode/master: disable: - - if: IDF_TARGET in ["esp32c6", "esp32p4"] - temporary: true - reason: target(s) not supported yet # TODO: IDF-7505 + - if: SOC_GPSPI_SUPPORTED != 1 or SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1 examples/peripherals/spi_slave_hd/append_mode/slave: - enable: - - if: IDF_TARGET == "esp32s2" - temporary: true - reason: the other targets are not tested yet + disable: + - if: SOC_GPSPI_SUPPORTED != 1 or SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1 examples/peripherals/spi_slave_hd/segment_mode/seg_master: disable: - - if: SOC_GPSPI_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-7505 slave hd support + - if: SOC_GPSPI_SUPPORTED != 1 or SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1 examples/peripherals/spi_slave_hd/segment_mode/seg_slave: disable: - - if: IDF_TARGET == "esp32" or SOC_GPSPI_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-7505 slave hd support + - if: SOC_GPSPI_SUPPORTED != 1 or SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1 examples/peripherals/temperature_sensor/temp_sensor: disable: diff --git a/examples/peripherals/spi_slave_hd/append_mode/README.md b/examples/peripherals/spi_slave_hd/append_mode/README.md index d28b9f27aa1b..acd6216d26ec 100644 --- a/examples/peripherals/spi_slave_hd/append_mode/README.md +++ b/examples/peripherals/spi_slave_hd/append_mode/README.md @@ -1,4 +1,4 @@ -# SPI Halfduplex Slave Append Mode Example +# SPI Slave Halfduplex: Append Mode Example (See the README.md file in the upper level 'examples' directory for more information about examples.) diff --git a/examples/peripherals/spi_slave_hd/append_mode/master/README.md b/examples/peripherals/spi_slave_hd/append_mode/master/README.md index 04e471ea059e..93478a0c73da 100644 --- a/examples/peripherals/spi_slave_hd/append_mode/master/README.md +++ b/examples/peripherals/spi_slave_hd/append_mode/master/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | See README.md in the parent directory diff --git a/examples/peripherals/spi_slave_hd/append_mode/master/main/app_main.c b/examples/peripherals/spi_slave_hd/append_mode/master/main/app_main.c index d34696ca4b52..b16711641af0 100644 --- a/examples/peripherals/spi_slave_hd/append_mode/master/main/app_main.c +++ b/examples/peripherals/spi_slave_hd/append_mode/master/main/app_main.c @@ -15,18 +15,13 @@ #include "esp_serial_slave_link/essl.h" #include "esp_serial_slave_link/essl_spi.h" -#ifdef CONFIG_IDF_TARGET_ESP32H2 -#define GPIO_MOSI 5 -#define GPIO_MISO 0 -#define GPIO_SCLK 4 -#define GPIO_CS 1 - -#else +////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////// Please update the following configuration according to your Hardware spec ///////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////// #define GPIO_MOSI 11 #define GPIO_MISO 13 #define GPIO_SCLK 12 #define GPIO_CS 10 -#endif #define HOST_ID SPI2_HOST #define TRANSACTION_LEN 16 diff --git a/examples/peripherals/spi_slave_hd/append_mode/slave/README.md b/examples/peripherals/spi_slave_hd/append_mode/slave/README.md index 25a3dadfd12d..93478a0c73da 100644 --- a/examples/peripherals/spi_slave_hd/append_mode/slave/README.md +++ b/examples/peripherals/spi_slave_hd/append_mode/slave/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32-S2 | -| ----------------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | See README.md in the parent directory diff --git a/examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c b/examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c index 8b7160abe182..49676693b3f0 100644 --- a/examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c +++ b/examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c @@ -15,11 +15,15 @@ #include "freertos/semphr.h" #include "driver/spi_slave_hd.h" +////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////// Please update the following configuration according to your Hardware spec ///////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////// #define GPIO_MOSI 11 #define GPIO_MISO 13 #define GPIO_SCLK 12 #define GPIO_CS 10 -#define HOST_ID 1 + +#define HOST_ID SPI2_HOST #define QUEUE_SIZE 6 #define TRANSACTION_LEN 16 #define SYNC_REG_FROM_HOST (14 * 4) diff --git a/examples/peripherals/spi_slave_hd/segment_mode/README.md b/examples/peripherals/spi_slave_hd/segment_mode/README.md index 0618904a3767..23cba9fc6db9 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/README.md +++ b/examples/peripherals/spi_slave_hd/segment_mode/README.md @@ -10,7 +10,7 @@ These two projects illustrate the SPI Slave Halfduplex Segment Mode. ### Hardware Required -These two projects are supposed to be flashed onto two seperate boards and jumped together via correctly connected SPI pins defined in both of the ``app_main.c`` files. For the ``seg_master`` project, it could be flashed onto all the ESP Chips. Whereas the ``seg_slave`` currently could be flashed onto ESP32-S2. Once they are connected and flashed, they will use the SPI Master and SPI Slave Halfduplex drivers to communicate with each other. +These two projects are supposed to be flashed onto two seperate boards and jumped together via correctly connected SPI pins defined in both of the ``app_main.c`` files. Once they are connected and flashed, they will use the SPI Master and SPI Slave Halfduplex drivers to communicate with each other. Following is the connection between 2 ESP32S2 boards: @@ -21,8 +21,7 @@ Following is the connection between 2 ESP32S2 boards: | SCLK | GPIO12 | GPIO12 | | CS | GPIO10 | GPIO10 | -Plase refer to the macro definations at the top of ``app_main.c`` files, to know the connection on different chips. -Feel free to change the GPIO settings by editing the macro definations. +Feel free to change the GPIO settings by editing the macro definations on the top of the ``app_main.c`` ### Build and Flash diff --git a/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md b/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md index a170437d6bb3..93478a0c73da 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md +++ b/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | See README.md in the parent directory diff --git a/examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c b/examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c index f5571b09e296..e7a1690c4848 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c +++ b/examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c @@ -14,34 +14,15 @@ #include "driver/spi_master.h" #include "esp_serial_slave_link/essl_spi.h" -//Pin setting -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////// Please update the following configuration according to your Hardware spec ///////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////// #define GPIO_MOSI 11 #define GPIO_MISO 13 #define GPIO_SCLK 12 #define GPIO_CS 10 -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 -#define GPIO_MOSI 7 -#define GPIO_MISO 2 -#define GPIO_SCLK 6 -#define GPIO_CS 10 - -#elif CONFIG_IDF_TARGET_ESP32C6 -#define GPIO_MOSI 19 -#define GPIO_MISO 20 -#define GPIO_SCLK 18 -#define GPIO_CS 9 - -#elif CONFIG_IDF_TARGET_ESP32H2 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 5 -#define GPIO_MISO 0 -#define GPIO_SCLK 4 -#define GPIO_CS 1 -#endif - -#define MASTER_HOST SPI2_HOST +#define MASTER_HOST SPI2_HOST #define DMA_CHAN SPI_DMA_CH_AUTO #define TX_SIZE_MIN 40 diff --git a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md index d2553ff6db36..4fc69c16b6ab 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md +++ b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c index 18f61b6c0de8..ad59703d6b9d 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c +++ b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c @@ -15,33 +15,14 @@ #define TIME_IS_OUT(start, end, timeout) (timeout) > ((end)-(start)) ? 0 : 1 -//Pin setting -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////// Please update the following configuration according to your Hardware spec ///////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////// #define GPIO_MOSI 11 #define GPIO_MISO 13 #define GPIO_SCLK 12 #define GPIO_CS 10 -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 -#define GPIO_MOSI 7 -#define GPIO_MISO 2 -#define GPIO_SCLK 6 -#define GPIO_CS 10 - -#elif CONFIG_IDF_TARGET_ESP32C6 -#define GPIO_MOSI 19 -#define GPIO_MISO 20 -#define GPIO_SCLK 18 -#define GPIO_CS 9 - -#elif CONFIG_IDF_TARGET_ESP32H2 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 5 -#define GPIO_MISO 0 -#define GPIO_SCLK 4 -#define GPIO_CS 1 -#endif - #define SLAVE_HOST SPI2_HOST #define DMA_CHAN SPI_DMA_CH_AUTO #define QUEUE_SIZE 4