feat(csi): add API to expose internal backup_buffer

This commit is contained in:
wanlei
2024-04-17 10:48:11 +08:00
parent cf055a625b
commit af86df7f02
6 changed files with 120 additions and 1 deletions
@@ -42,6 +42,8 @@ static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_
static esp_err_t s_del_csi_ctlr(csi_controller_t *ctlr);
static esp_err_t s_ctlr_del(esp_cam_ctlr_t *cam_ctlr);
static esp_err_t s_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_data);
static esp_err_t s_csi_ctlr_get_internal_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...);
static esp_err_t s_csi_ctlr_get_buffer_length(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len);
static esp_err_t s_csi_ctlr_enable(esp_cam_ctlr_handle_t ctlr);
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);
@@ -212,6 +214,8 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
ctlr->base.disable = s_csi_ctlr_disable;
ctlr->base.receive = s_ctlr_csi_receive;
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;
*ret_handle = &(ctlr->base);
@@ -256,6 +260,36 @@ static esp_err_t s_ctlr_del(esp_cam_ctlr_t *cam_ctlr)
return ESP_OK;
}
static esp_err_t s_csi_ctlr_get_internal_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...)
{
csi_controller_t *csi_ctlr = __containerof(handle, csi_controller_t, base);
ESP_RETURN_ON_FALSE((csi_ctlr->csi_fsm >= CSI_FSM_INIT) && (csi_ctlr->backup_buffer), ESP_ERR_INVALID_STATE, TAG, "driver don't initialized or back_buffer not available");
ESP_RETURN_ON_FALSE(fb_num && fb_num <= 1, ESP_ERR_INVALID_ARG, TAG, "invalid frame buffer number");
csi_ctlr->bk_buffer_exposed = true;
const void **fb_itor = fb0;
va_list args;
va_start(args, fb0);
for (uint32_t i = 0; i < fb_num; i++) {
if (fb_itor) {
*fb_itor = csi_ctlr->backup_buffer;
fb_itor = va_arg(args, const void **);
}
}
va_end(args);
return ESP_OK;
}
static esp_err_t s_csi_ctlr_get_buffer_length(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len)
{
csi_controller_t *csi_ctlr = __containerof(handle, csi_controller_t, base);
ESP_RETURN_ON_FALSE((csi_ctlr->csi_fsm >= CSI_FSM_INIT) && (csi_ctlr->backup_buffer), ESP_ERR_INVALID_STATE, TAG, "driver don't initialized or back_buffer not available");
*ret_fb_len = csi_ctlr->fb_size_in_bytes;
return ESP_OK;
}
static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data)
{
bool need_yield = false;
@@ -311,7 +345,7 @@ static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_
dw_gdma_channel_config_transfer(chan, &csi_dma_transfer_config);
dw_gdma_channel_enable_ctrl(chan, true);
if (ctlr->trans.buffer != ctlr->backup_buffer) {
if ((ctlr->trans.buffer != ctlr->backup_buffer) || ctlr->bk_buffer_exposed) {
esp_err_t ret = esp_cache_msync((void *)(ctlr->trans.buffer), ctlr->trans.received_size, ESP_CACHE_MSYNC_FLAG_INVALIDATE);
assert(ret == ESP_OK);
assert(ctlr->cbs.on_trans_finished);
@@ -55,6 +55,7 @@ struct csi_controller_t {
size_t fb_size_in_bytes; //Frame buffer size, in bytes
esp_cam_ctlr_trans_t trans; //Saved done transaction to be given out to callers
void *backup_buffer; //backup buffer to make csi bridge can work to avoid wrong state
bool bk_buffer_exposed; //status of if back_buffer is exposed to users
QueueHandle_t trans_que; //transaction queue
esp_cam_ctlr_evt_cbs_t cbs; //user callbacks
void *cbs_user_data; //callback userdata