From cb86a3e2a2a0b98ae8dfaa2c5ec61d4892c712ca Mon Sep 17 00:00:00 2001 From: wanlei Date: Tue, 9 Apr 2024 11:58:11 +0800 Subject: [PATCH] feat(spi): Add helper function for alignment reqiured memory allocation --- .../include/driver/spi_common.h | 21 ++++++++++++++++++- .../esp_driver_spi/src/gpspi/spi_common.c | 18 ++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/components/esp_driver_spi/include/driver/spi_common.h b/components/esp_driver_spi/include/driver/spi_common.h index 2cb99348d9..d842adc377 100644 --- a/components/esp_driver_spi/include/driver/spi_common.h +++ b/components/esp_driver_spi/include/driver/spi_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -167,6 +167,25 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * */ esp_err_t spi_bus_free(spi_host_device_t host_id); +/** + * @brief Helper function for malloc DMA capable memory for SPI driver + * + * @note This API will take care of the cache and hardware alignment internally. + * To free/release memory allocated by this helper function, simply calling `free()` + * + * @param[in] size Size in bytes, the amount of memory to allocate + * @param[out] out_ptr Pointer to the memory if allocated successfully + * @param[in] extra_heap_caps Extra heap caps based on MALLOC_CAP_DMA + * @param[out] actual_size Optional, Actual size for allocation in bytes, when the size you specified doesn't meet the internal alignment requirements, + * This value might be bigger than the size you specified. Set NULL if don't care this value. + * + * @return + * - ESP_ERR_INVALID_ARG Invalid argument + * - ESP_ERR_NO_MEM No enough memory for allocation + * - ESP_OK on success + */ +esp_err_t spi_bus_dma_memory_malloc(size_t size, void **out_ptr, uint32_t extra_heap_caps, size_t *actual_size); + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 5d29aaf510..e1c9feb3db 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -21,6 +21,7 @@ #include "esp_private/spi_common_internal.h" #include "esp_private/spi_share_hw_ctrl.h" #include "esp_private/esp_cache_private.h" +#include "esp_dma_utils.h" #include "hal/spi_hal.h" #include "hal/gpio_hal.h" #if CONFIG_IDF_TARGET_ESP32 @@ -285,8 +286,12 @@ esp_err_t spicommon_dma_desc_alloc(spi_dma_ctx_t *dma_ctx, int cfg_max_sz, int * dma_desc_ct = 1; //default to 4k when max is not given } - 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); + esp_dma_mem_info_t dma_mem_info = { + .dma_alignment_bytes = DMA_DESC_MEM_ALIGN_SIZE, + }; + esp_dma_capable_malloc(sizeof(spi_dma_desc_t) * dma_desc_ct, &dma_mem_info, (void*)&dma_ctx->dmadesc_tx, NULL); + esp_dma_capable_malloc(sizeof(spi_dma_desc_t) * dma_desc_ct, &dma_mem_info, (void*)&dma_ctx->dmadesc_rx, NULL); + if (dma_ctx->dmadesc_tx == NULL || dma_ctx->dmadesc_rx == NULL) { if (dma_ctx->dmadesc_tx) { free(dma_ctx->dmadesc_tx); @@ -877,6 +882,15 @@ cleanup: return err; } +esp_err_t spi_bus_dma_memory_malloc(size_t size, void **out_ptr, uint32_t extra_heap_caps, size_t *actual_size) +{ + esp_dma_mem_info_t dma_mem_info = { + .extra_heap_caps = extra_heap_caps, + .dma_alignment_bytes = DMA_DESC_MEM_ALIGN_SIZE, + }; + return esp_dma_capable_malloc(size, &dma_mem_info, out_ptr, actual_size); +} + const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id) { if (bus_ctx[host_id] == NULL) {