forked from espressif/esp-idf
Merge branch 'csi/add_no_backup_buffer_usage_flag' into 'master'
feat(csi): add a flag to allow no backup buffer usage Closes IDF-9571 See merge request espressif/esp-idf!30185
This commit is contained in:
@@ -32,8 +32,11 @@ typedef struct {
|
|||||||
int lane_bit_rate_mbps; ///< Lane bit rate in Mbps
|
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 input_data_color_type; ///< Input color type
|
||||||
mipi_csi_color_t output_data_color_type; ///< Output 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
|
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;
|
} esp_cam_ctlr_csi_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -154,6 +154,8 @@ 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;
|
ctlr->fb_size_in_bytes = fb_size_in_bits / 8;
|
||||||
ESP_LOGD(TAG, "ctlr->fb_size_in_bytes=%d", ctlr->fb_size_in_bytes);
|
ESP_LOGD(TAG, "ctlr->fb_size_in_bytes=%d", ctlr->fb_size_in_bytes);
|
||||||
|
|
||||||
|
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 dma_alignment = 4; //TODO: IDF-9126, replace with dwgdma alignment API
|
||||||
size_t cache_alignment = 1;
|
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");
|
ESP_GOTO_ON_ERROR(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &cache_alignment), err, TAG, "failed to get cache alignment");
|
||||||
@@ -164,6 +166,7 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
|
|||||||
ESP_GOTO_ON_FALSE(ctlr->backup_buffer, ESP_ERR_NO_MEM, err, TAG, "no mem for backup buffer");
|
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_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);
|
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;
|
mipi_csi_hal_config_t hal_config;
|
||||||
hal_config.frame_height = config->h_res;
|
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() {
|
PERIPH_RCC_ATOMIC() {
|
||||||
mipi_csi_ll_enable_phy_config_clock(ctlr->csi_id, 0);
|
mipi_csi_ll_enable_phy_config_clock(ctlr->csi_id, 0);
|
||||||
}
|
}
|
||||||
|
if (!ctlr->bk_buffer_dis) {
|
||||||
free(ctlr->backup_buffer);
|
free(ctlr->backup_buffer);
|
||||||
|
}
|
||||||
vQueueDeleteWithCaps(ctlr->trans_que);
|
vQueueDeleteWithCaps(ctlr->trans_que);
|
||||||
free(ctlr);
|
free(ctlr);
|
||||||
|
|
||||||
@@ -330,7 +335,7 @@ static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_
|
|||||||
} else {
|
} else {
|
||||||
csi_dma_transfer_config.dst.addr = (uint32_t)(new_trans.buffer);
|
csi_dma_transfer_config.dst.addr = (uint32_t)(new_trans.buffer);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!ctlr->bk_buffer_dis) {
|
||||||
use_backup = true;
|
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;
|
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");
|
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;
|
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);
|
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) {
|
if (ctlr->cbs.on_get_new_trans) {
|
||||||
ctlr->cbs.on_get_new_trans(handle, &trans, ctlr->cbs_user_data);
|
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");
|
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.buffer = ctlr->backup_buffer;
|
||||||
trans.buflen = ctlr->fb_size_in_bytes;
|
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);
|
ESP_LOGD(TAG, "trans.buffer: %p, trans.buflen: %d", trans.buffer, trans.buflen);
|
||||||
|
@@ -56,6 +56,7 @@ struct csi_controller_t {
|
|||||||
esp_cam_ctlr_trans_t trans; //Saved done transaction to be given out to callers
|
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
|
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_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
|
QueueHandle_t trans_que; //transaction queue
|
||||||
esp_cam_ctlr_evt_cbs_t cbs; //user callbacks
|
esp_cam_ctlr_evt_cbs_t cbs; //user callbacks
|
||||||
void *cbs_user_data; //callback userdata
|
void *cbs_user_data; //callback userdata
|
||||||
|
@@ -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_list args;
|
||||||
va_start(args, fb0);
|
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);
|
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)
|
esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len)
|
||||||
|
@@ -34,3 +34,30 @@ TEST_CASE("TEST CSI driver allocation", "[csi]")
|
|||||||
TEST_ASSERT_EQUAL((csi_config.h_res * csi_config.v_res * 2), bk_buffer_len); // out type RGB565 using 2 byte / pixel
|
TEST_ASSERT_EQUAL((csi_config.h_res * csi_config.v_res * 2), bk_buffer_len); // out type RGB565 using 2 byte / pixel
|
||||||
TEST_ESP_OK(esp_cam_del_ctlr(handle));
|
TEST_ESP_OK(esp_cam_del_ctlr(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("TEST CSI driver no backup buffer usage", "[csi]")
|
||||||
|
{
|
||||||
|
esp_cam_ctlr_csi_config_t csi_config = {
|
||||||
|
.ctlr_id = 0,
|
||||||
|
.h_res = 800,
|
||||||
|
.v_res = 640,
|
||||||
|
.lane_bit_rate_mbps = 200,
|
||||||
|
.input_data_color_type = MIPI_CSI_COLOR_RAW8,
|
||||||
|
.output_data_color_type = MIPI_CSI_COLOR_RGB565,
|
||||||
|
.data_lane_num = 2,
|
||||||
|
.byte_swap_en = false,
|
||||||
|
.queue_items = 1,
|
||||||
|
.bk_buffer_dis = 1,
|
||||||
|
};
|
||||||
|
esp_cam_ctlr_handle_t handle = NULL;
|
||||||
|
TEST_ESP_OK(esp_cam_new_csi_ctlr(&csi_config, &handle));
|
||||||
|
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_cam_new_csi_ctlr(&csi_config, &handle));
|
||||||
|
|
||||||
|
uint8_t *bk_buffer = NULL;
|
||||||
|
size_t bk_buffer_len = 0;
|
||||||
|
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_cam_ctlr_get_frame_buffer(handle, 1, (const void **)&bk_buffer));
|
||||||
|
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_cam_ctlr_get_frame_buffer_len(handle, &bk_buffer_len));
|
||||||
|
TEST_ASSERT_NULL(bk_buffer);
|
||||||
|
TEST_ASSERT_EQUAL(0, bk_buffer_len);
|
||||||
|
TEST_ESP_OK(esp_cam_del_ctlr(handle));
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user