mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-26 18:14:11 +00:00
feat(cam): add camera buffer alloc function
This commit is contained in:
@@ -51,6 +51,7 @@ static esp_err_t s_ctlr_csi_start(esp_cam_ctlr_handle_t handle);
|
||||
static esp_err_t s_ctlr_csi_stop(esp_cam_ctlr_handle_t handle);
|
||||
static esp_err_t s_csi_ctlr_disable(esp_cam_ctlr_handle_t ctlr);
|
||||
static esp_err_t s_ctlr_csi_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms);
|
||||
static void *s_csi_ctlr_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps);
|
||||
|
||||
static esp_err_t s_csi_claim_controller(csi_controller_t *controller)
|
||||
{
|
||||
@@ -225,6 +226,7 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
|
||||
ctlr->base.register_event_callbacks = s_register_event_callbacks;
|
||||
ctlr->base.get_internal_buffer = s_csi_ctlr_get_internal_buffer;
|
||||
ctlr->base.get_buffer_len = s_csi_ctlr_get_buffer_length;
|
||||
ctlr->base.alloc_buffer = s_csi_ctlr_alloc_buffer;
|
||||
|
||||
*ret_handle = &(ctlr->base);
|
||||
|
||||
@@ -538,3 +540,23 @@ esp_err_t s_ctlr_csi_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void *s_csi_ctlr_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps)
|
||||
{
|
||||
csi_controller_t *ctlr = __containerof(handle, csi_controller_t, base);
|
||||
|
||||
if (!ctlr) {
|
||||
ESP_LOGE(TAG, "invalid argument: handle is null");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *buffer = heap_caps_calloc(1, size, buf_caps);
|
||||
if (!buffer) {
|
||||
ESP_LOGE(TAG, "failed to allocate buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Allocated camera buffer: %p, size: %zu", buffer, size);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
@@ -29,6 +29,8 @@ typedef struct esp_cam_ctlr_dvp_dma {
|
||||
esp_cam_ctlr_dvp_dma_desc_t *desc; /*!< DVP DMA description buffer */
|
||||
size_t desc_count; /*!< DVP DMA description count */
|
||||
size_t desc_size; /*!< DVP DMA description buffer size in byte */
|
||||
size_t int_mem_align; /*!< DVP DMA internal memory alignment */
|
||||
size_t ext_mem_align; /*!< DVP DMA external memory alignment */
|
||||
} esp_cam_ctlr_dvp_dma_t;
|
||||
|
||||
/**
|
||||
|
@@ -700,6 +700,47 @@ static esp_err_t esp_cam_ctlr_get_dvp_cam_frame_buffer_len(esp_cam_ctlr_handle_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate aligned camera buffer for ESP CAM DVP controller
|
||||
*
|
||||
* @note This function must be called after esp_cam_new_dvp_ctlr
|
||||
*
|
||||
* @param handle ESP CAM controller handle
|
||||
* @param size Buffer size in bytes
|
||||
* @param buf_caps Buffer allocation capabilities (e.g., MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA)
|
||||
*
|
||||
* @return
|
||||
* - Buffer pointer on success
|
||||
* - NULL on failure
|
||||
*/
|
||||
static void *esp_cam_ctlr_dvp_cam_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps)
|
||||
{
|
||||
esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle;
|
||||
|
||||
if (!ctlr) {
|
||||
ESP_LOGE(TAG, "invalid argument: handle is null");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t alignment = 1;
|
||||
|
||||
if (buf_caps & MALLOC_CAP_SPIRAM) {
|
||||
alignment = ctlr->dma.ext_mem_align;
|
||||
} else {
|
||||
alignment = ctlr->dma.int_mem_align;
|
||||
}
|
||||
|
||||
void *buffer = heap_caps_aligned_calloc(alignment, 1, size, buf_caps);
|
||||
if (!buffer) {
|
||||
ESP_LOGE(TAG, "failed to allocate buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Allocated aligned camera buffer: %p, size: %zu, alignment: %zu", buffer, size, alignment);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief New ESP CAM DVP controller
|
||||
*
|
||||
@@ -793,6 +834,7 @@ esp_err_t esp_cam_new_dvp_ctlr(const esp_cam_ctlr_dvp_config_t *config, esp_cam_
|
||||
ctlr->base.register_event_callbacks = esp_cam_ctlr_dvp_cam_register_event_callbacks;
|
||||
ctlr->base.get_internal_buffer = esp_cam_ctlr_dvp_cam_get_internal_buffer;
|
||||
ctlr->base.get_buffer_len = esp_cam_ctlr_get_dvp_cam_frame_buffer_len;
|
||||
ctlr->base.alloc_buffer = esp_cam_ctlr_dvp_cam_alloc_buffer;
|
||||
|
||||
*ret_handle = &ctlr->base;
|
||||
|
||||
|
@@ -105,9 +105,8 @@ esp_err_t esp_cam_ctlr_dvp_dma_init(esp_cam_ctlr_dvp_dma_t *dma, uint32_t burst_
|
||||
.access_ext_mem = true,
|
||||
};
|
||||
ESP_GOTO_ON_ERROR(gdma_config_transfer(dma->dma_chan, &transfer_config), fail1, TAG, "set trans ability failed");
|
||||
size_t int_mem_align = 0;
|
||||
size_t ext_mem_align = 0;
|
||||
gdma_get_alignment_constraints(dma->dma_chan, &int_mem_align, &ext_mem_align);
|
||||
|
||||
gdma_get_alignment_constraints(dma->dma_chan, &dma->int_mem_align, &dma->ext_mem_align);
|
||||
|
||||
dma->desc_count = size / ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE;
|
||||
if (size % ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -91,3 +91,11 @@ esp_err_t esp_cam_ctlr_del(esp_cam_ctlr_handle_t handle)
|
||||
|
||||
return handle->del(handle);
|
||||
}
|
||||
|
||||
void *esp_cam_ctlr_alloc_buffer(esp_cam_ctlr_handle_t handle, size_t size, uint32_t buf_caps)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(handle, NULL, TAG, "invalid argument: null pointer");
|
||||
ESP_RETURN_ON_FALSE(handle->alloc_buffer, NULL, TAG, "alloc_buffer function not supported");
|
||||
|
||||
return handle->alloc_buffer(handle, size, buf_caps);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -132,6 +133,23 @@ esp_err_t esp_cam_ctlr_get_frame_buffer(esp_cam_ctlr_handle_t handle, uint32_t f
|
||||
*/
|
||||
esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len);
|
||||
|
||||
/**
|
||||
* @brief Allocate camera buffer for ESP CAM controller
|
||||
*
|
||||
* @note This function must be called after esp_cam_new_*_ctlr
|
||||
*
|
||||
* @param[in] handle ESP CAM controller handle
|
||||
* @param[in] size Buffer size in bytes
|
||||
* @param[in] buf_caps Buffer allocation capabilities:
|
||||
* - MALLOC_CAP_SPIRAM || MALLOC_CAP_DMA: Memory in external SPI RAM
|
||||
* - MALLOC_CAP_INTERNAL || MALLOC_CAP_DMA: Memory in internal SRAM
|
||||
*
|
||||
* @return
|
||||
* - Buffer pointer on success
|
||||
* - NULL on failure
|
||||
*/
|
||||
void *esp_cam_ctlr_alloc_buffer(esp_cam_ctlr_handle_t handle, size_t size, uint32_t buf_caps);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -133,6 +133,19 @@ struct esp_cam_ctlr_t {
|
||||
*/
|
||||
esp_err_t (*get_buffer_len)(esp_cam_ctlr_t *, size_t *);
|
||||
|
||||
/**
|
||||
* @brief Allocate aligned camera buffer for ESP CAM controller
|
||||
*
|
||||
* @param[in] esp_cam_ctlr_t * ESP CAM controller handle
|
||||
* @param[in] size_t Buffer size in bytes
|
||||
* @param[in] uint32_t Buffer allocation capabilities
|
||||
*
|
||||
* @return
|
||||
* - Buffer pointer on success
|
||||
* - NULL on failure
|
||||
*/
|
||||
void *(*alloc_buffer)(esp_cam_ctlr_t *, size_t, uint32_t);
|
||||
|
||||
void *user_data; ///< User data
|
||||
};
|
||||
|
||||
|
@@ -85,6 +85,7 @@ static esp_err_t s_isp_dvp_start(esp_cam_ctlr_handle_t handle);
|
||||
static esp_err_t s_isp_dvp_stop(esp_cam_ctlr_handle_t handle);
|
||||
static esp_err_t s_isp_dvp_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms);
|
||||
static bool s_dvp_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data);
|
||||
static void *s_isp_dvp_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps);
|
||||
|
||||
esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config, esp_cam_ctlr_handle_t *ret_handle)
|
||||
{
|
||||
@@ -200,6 +201,7 @@ esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctl
|
||||
cam_ctlr->register_event_callbacks = s_isp_dvp_register_event_callbacks;
|
||||
cam_ctlr->get_internal_buffer = s_isp_dvp_get_frame_buffer;
|
||||
cam_ctlr->get_buffer_len = s_isp_dvp_get_frame_buffer_length;
|
||||
cam_ctlr->alloc_buffer = s_isp_dvp_alloc_buffer;
|
||||
*ret_handle = cam_ctlr;
|
||||
|
||||
return ESP_OK;
|
||||
@@ -594,3 +596,23 @@ static esp_err_t s_isp_declaim_dvp_controller(isp_dvp_controller_t *dvp_ctlr)
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void *s_isp_dvp_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps)
|
||||
{
|
||||
isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base);
|
||||
|
||||
if (!dvp_ctlr) {
|
||||
ESP_LOGE(TAG, "invalid argument: handle is null");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *buffer = heap_caps_calloc(1, size, buf_caps);
|
||||
if (!buffer) {
|
||||
ESP_LOGE(TAG, "failed to allocate buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Allocated camera buffer: %p, size: %zu", buffer, size);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
Reference in New Issue
Block a user