feat(spi): Add helper function for alignment reqiured memory allocation

This commit is contained in:
wanlei 2024-04-09 11:58:11 +08:00 committed by Wan Lei
parent c82ea4311e
commit cb86a3e2a2
2 changed files with 36 additions and 3 deletions

View File

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

View File

@ -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) {