diff --git a/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h b/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h index 02198f4241..fa63b5fc04 100644 --- a/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h +++ b/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h @@ -32,8 +32,11 @@ typedef struct { int lane_bit_rate_mbps; ///< Lane bit rate in Mbps mipi_csi_color_t input_data_color_type; ///< Input color type mipi_csi_color_t output_data_color_type; ///< Output color type - bool byte_swap_en; ///< Enable byte swap int queue_items; ///< Queue items + struct { + uint32_t byte_swap_en : 1; ///< Enable byte swap + uint32_t bk_buffer_dis : 1; ///< Disable backup buffer + }; ///< Boolean Flags } esp_cam_ctlr_csi_config_t; /** diff --git a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c index dd2947e749..1136273da0 100644 --- a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c +++ b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c @@ -154,16 +154,19 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_ ctlr->fb_size_in_bytes = fb_size_in_bits / 8; ESP_LOGD(TAG, "ctlr->fb_size_in_bytes=%d", ctlr->fb_size_in_bytes); - size_t dma_alignment = 4; //TODO: IDF-9126, replace with dwgdma alignment API - size_t cache_alignment = 1; - ESP_GOTO_ON_ERROR(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &cache_alignment), err, TAG, "failed to get cache alignment"); - size_t alignment = MAX(cache_alignment, dma_alignment); - ESP_LOGD(TAG, "alignment: 0x%x\n", alignment); + ctlr->bk_buffer_dis = config->bk_buffer_dis; + if (!ctlr->bk_buffer_dis) { + size_t dma_alignment = 4; //TODO: IDF-9126, replace with dwgdma alignment API + size_t cache_alignment = 1; + ESP_GOTO_ON_ERROR(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &cache_alignment), err, TAG, "failed to get cache alignment"); + size_t alignment = MAX(cache_alignment, dma_alignment); + ESP_LOGD(TAG, "alignment: 0x%x\n", alignment); - ctlr->backup_buffer = heap_caps_aligned_alloc(alignment, ctlr->fb_size_in_bytes, MALLOC_CAP_SPIRAM); - ESP_GOTO_ON_FALSE(ctlr->backup_buffer, ESP_ERR_NO_MEM, err, TAG, "no mem for backup buffer"); - ESP_LOGD(TAG, "ctlr->backup_buffer: %p\n", ctlr->backup_buffer); - esp_cache_msync((void *)(ctlr->backup_buffer), ctlr->fb_size_in_bytes, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + ctlr->backup_buffer = heap_caps_aligned_alloc(alignment, ctlr->fb_size_in_bytes, MALLOC_CAP_SPIRAM); + ESP_GOTO_ON_FALSE(ctlr->backup_buffer, ESP_ERR_NO_MEM, err, TAG, "no mem for backup buffer"); + ESP_LOGD(TAG, "ctlr->backup_buffer: %p\n", ctlr->backup_buffer); + esp_cache_msync((void *)(ctlr->backup_buffer), ctlr->fb_size_in_bytes, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + } mipi_csi_hal_config_t hal_config; hal_config.frame_height = config->h_res; @@ -246,7 +249,9 @@ esp_err_t s_del_csi_ctlr(csi_controller_t *ctlr) PERIPH_RCC_ATOMIC() { mipi_csi_ll_enable_phy_config_clock(ctlr->csi_id, 0); } - free(ctlr->backup_buffer); + if (!ctlr->bk_buffer_dis) { + free(ctlr->backup_buffer); + } vQueueDeleteWithCaps(ctlr->trans_que); free(ctlr); @@ -330,7 +335,7 @@ static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_ } else { csi_dma_transfer_config.dst.addr = (uint32_t)(new_trans.buffer); } - } else { + } else if (!ctlr->bk_buffer_dis) { use_backup = true; } @@ -339,6 +344,8 @@ static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_ new_trans.buflen = ctlr->fb_size_in_bytes; ESP_EARLY_LOGD(TAG, "no new buffer or no long enough new buffer, use driver internal buffer"); csi_dma_transfer_config.dst.addr = (uint32_t)ctlr->backup_buffer; + } else { + assert(false && "no new buffer, and no driver internal buffer"); } ESP_EARLY_LOGD(TAG, "new_trans.buffer: %p, new_trans.buflen: %d", new_trans.buffer, new_trans.buflen); @@ -422,9 +429,11 @@ esp_err_t s_ctlr_csi_start(esp_cam_ctlr_handle_t handle) if (ctlr->cbs.on_get_new_trans) { ctlr->cbs.on_get_new_trans(handle, &trans, ctlr->cbs_user_data); ESP_RETURN_ON_FALSE(trans.buffer, ESP_ERR_INVALID_STATE, TAG, "no ready transaction, cannot start"); - } else { + } else if (!ctlr->bk_buffer_dis) { trans.buffer = ctlr->backup_buffer; trans.buflen = ctlr->fb_size_in_bytes; + } else { + ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "no ready transaction, and no backup buffer"); } ESP_LOGD(TAG, "trans.buffer: %p, trans.buflen: %d", trans.buffer, trans.buflen); diff --git a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h index 7d9eb56fb5..0a8a7508d5 100644 --- a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h +++ b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h @@ -56,6 +56,7 @@ struct csi_controller_t { 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 + bool bk_buffer_dis; //Allow to not malloc backup_buffer QueueHandle_t trans_que; //transaction queue esp_cam_ctlr_evt_cbs_t cbs; //user callbacks void *cbs_user_data; //callback userdata diff --git a/components/esp_driver_cam/esp_cam_ctlr.c b/components/esp_driver_cam/esp_cam_ctlr.c index 88c27822ff..51a1b3c308 100644 --- a/components/esp_driver_cam/esp_cam_ctlr.c +++ b/components/esp_driver_cam/esp_cam_ctlr.c @@ -71,8 +71,9 @@ esp_err_t esp_cam_ctlr_get_frame_buffer(esp_cam_ctlr_handle_t handle, uint32_t f va_list args; va_start(args, fb0); - return handle->get_internal_buffer(handle, fb_num, fb0, args); + esp_err_t ret = handle->get_internal_buffer(handle, fb_num, fb0, args); va_end(args); + return ret; } esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len)