feat(dma): added a helper api to check buffer is dma aligned

This commit is contained in:
Armando
2023-10-10 15:06:54 +08:00
committed by Armando (Dou Yiwen)
parent 4eaf233bb8
commit 7879b29b0c
2 changed files with 62 additions and 0 deletions

View File

@ -11,6 +11,7 @@
#include "esp_check.h" #include "esp_check.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "esp_memory_utils.h"
#include "esp_dma_utils.h" #include "esp_dma_utils.h"
#include "esp_private/esp_cache_private.h" #include "esp_private/esp_cache_private.h"
#include "soc/soc_caps.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; 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;
}

View File

@ -7,6 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "esp_err.h" #include "esp_err.h"
#ifdef __cplusplus #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); 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 #ifdef __cplusplus
} }
#endif #endif