From 7879b29b0cedf230879f5b83d6c993c358b40bd0 Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 10 Oct 2023 15:06:54 +0800 Subject: [PATCH] feat(dma): added a helper api to check buffer is dma aligned --- components/esp_hw_support/dma/esp_dma_utils.c | 40 +++++++++++++++++++ .../esp_hw_support/include/esp_dma_utils.h | 22 ++++++++++ 2 files changed, 62 insertions(+) diff --git a/components/esp_hw_support/dma/esp_dma_utils.c b/components/esp_hw_support/dma/esp_dma_utils.c index 4309a69cc4..5db42309c2 100644 --- a/components/esp_hw_support/dma/esp_dma_utils.c +++ b/components/esp_hw_support/dma/esp_dma_utils.c @@ -11,6 +11,7 @@ #include "esp_check.h" #include "esp_log.h" #include "esp_heap_caps.h" +#include "esp_memory_utils.h" #include "esp_dma_utils.h" #include "esp_private/esp_cache_private.h" #include "soc/soc_caps.h" @@ -67,3 +68,42 @@ esp_err_t esp_dma_calloc(size_t n, size_t size, uint32_t flags, void **out_ptr, return ret; } + +bool esp_dma_is_buffer_aligned(const void *ptr, size_t size, esp_dma_buf_location_t location) +{ + assert(ptr); + uint32_t flags = ESP_CACHE_MALLOC_FLAG_DMA; + + if (location == ESP_DMA_BUF_LOCATION_INTERNAL) { + if (!esp_ptr_dma_capable(ptr) || !esp_ptr_dma_capable(ptr + size - 1)) { + return false; + } + } else { +#if !SOC_PSRAM_DMA_CAPABLE + return false; +#endif + if (!esp_ptr_external_ram(ptr) || !esp_ptr_external_ram(ptr + size - 1)) { + return false; + } + + flags |= ESP_DMA_MALLOC_FLAG_PSRAM; + } + + bool is_aligned = false; + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + size_t cache_alignment = 0; + esp_err_t ret = esp_cache_get_alignment(flags, &cache_alignment); + assert(ret == ESP_OK); + if (((intptr_t)ptr % cache_alignment == 0) && (size % cache_alignment == 0)) { + is_aligned = true; + } +#else + (void)size; + if ((intptr_t)ptr % 4 == 0) { + is_aligned = true; + } +#endif + + return is_aligned; +} diff --git a/components/esp_hw_support/include/esp_dma_utils.h b/components/esp_hw_support/include/esp_dma_utils.h index 3d4435b7cc..3c59db9008 100644 --- a/components/esp_hw_support/include/esp_dma_utils.h +++ b/components/esp_hw_support/include/esp_dma_utils.h @@ -7,6 +7,7 @@ #include #include +#include #include "esp_err.h" #ifdef __cplusplus @@ -52,6 +53,27 @@ esp_err_t esp_dma_malloc(size_t size, uint32_t flags, void **out_ptr, size_t *ac */ esp_err_t esp_dma_calloc(size_t n, size_t size, uint32_t flags, void **out_ptr, size_t *actual_size); +/** + * @brief DMA buffer location + */ +typedef enum { + ESP_DMA_BUF_LOCATION_INTERNAL, ///< DMA buffer is in internal memory + ESP_DMA_BUF_LOCATION_PSRAM, ///< DMA buffer is in PSRAM +} esp_dma_buf_location_t; + +/** + * @brief Helper function to check if a buffer meets DMA alignment requirements + * + * @param[in] ptr Pointer to the buffer + * @param[in] size Size of the buffer + * @param[in] location Location of the DMA buffer, see `esp_dma_buf_location_t` + * + * @return + * - True: Buffer is aligned + * - False: Buffer is not aligned, or buffer is not DMA capable + */ +bool esp_dma_is_buffer_aligned(const void *ptr, size_t size, esp_dma_buf_location_t location); + #ifdef __cplusplus } #endif