mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(csi): add API to expose internal backup_buffer
This commit is contained in:
parent
cf055a625b
commit
af86df7f02
@ -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_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_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_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_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_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_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.disable = s_csi_ctlr_disable;
|
||||||
ctlr->base.receive = s_ctlr_csi_receive;
|
ctlr->base.receive = s_ctlr_csi_receive;
|
||||||
ctlr->base.register_event_callbacks = s_register_event_callbacks;
|
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);
|
*ret_handle = &(ctlr->base);
|
||||||
|
|
||||||
@ -256,6 +260,36 @@ static esp_err_t s_ctlr_del(esp_cam_ctlr_t *cam_ctlr)
|
|||||||
return ESP_OK;
|
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)
|
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;
|
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_config_transfer(chan, &csi_dma_transfer_config);
|
||||||
dw_gdma_channel_enable_ctrl(chan, true);
|
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);
|
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(ret == ESP_OK);
|
||||||
assert(ctlr->cbs.on_trans_finished);
|
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
|
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
|
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
|
||||||
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
|
||||||
|
@ -64,6 +64,25 @@ esp_err_t esp_cam_ctlr_register_event_callbacks(esp_cam_ctlr_handle_t handle, co
|
|||||||
return handle->register_event_callbacks(handle, cbs, user_data);
|
return handle->register_event_callbacks(handle, cbs, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_cam_ctlr_get_frame_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null handle");
|
||||||
|
ESP_RETURN_ON_FALSE(handle->get_internal_buffer, ESP_ERR_NOT_SUPPORTED, TAG, "get buffer function not supported");
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fb0);
|
||||||
|
return handle->get_internal_buffer(handle, fb_num, fb0, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(handle && ret_fb_len, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null handle");
|
||||||
|
ESP_RETURN_ON_FALSE(handle->get_buffer_len, ESP_ERR_NOT_SUPPORTED, TAG, "get buffer length function not supported");
|
||||||
|
|
||||||
|
return handle->get_buffer_len(handle, ret_fb_len);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_cam_del_ctlr(esp_cam_ctlr_handle_t handle)
|
esp_err_t esp_cam_del_ctlr(esp_cam_ctlr_handle_t handle)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
@ -102,6 +102,36 @@ esp_err_t esp_cam_del_ctlr(esp_cam_ctlr_handle_t handle);
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_cam_ctlr_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_data);
|
esp_err_t esp_cam_ctlr_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ESP CAM controller internal malloced backup buffer(s) addr
|
||||||
|
*
|
||||||
|
* @note Generally, data in internal buffer is ready when `on_trans_finished` event
|
||||||
|
*
|
||||||
|
* @param[in] handle ESP CAM controller handle
|
||||||
|
* @param[in] fb_num Number of frame buffer(s) to get. This value must be the same as the number of the followed fbN parameters
|
||||||
|
* @param[out] fb0 Address of the frame buffer 0 (first frame buffer)
|
||||||
|
* @param[out] ... List of other frame buffers if any
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK
|
||||||
|
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||||
|
* - ESP_ERR_INVALID_STATE: Invalid driver state
|
||||||
|
*/
|
||||||
|
esp_err_t esp_cam_ctlr_get_frame_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ESP CAM controller internal backup buffer length
|
||||||
|
*
|
||||||
|
* @param[in] handle ESP CAM controller handle
|
||||||
|
* @param[out] ret_fb_len Optional, The size of each frame buffer, in bytes.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK
|
||||||
|
* - ESP_ERR_INVALID_ARG: NULL ptr
|
||||||
|
* - ESP_ERR_INVALID_STATE: Invalid driver state
|
||||||
|
*/
|
||||||
|
esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -105,6 +105,34 @@ struct esp_cam_ctlr_t {
|
|||||||
*/
|
*/
|
||||||
esp_err_t (*register_event_callbacks)(esp_cam_ctlr_t *ctlr, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_ctx);
|
esp_err_t (*register_event_callbacks)(esp_cam_ctlr_t *ctlr, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ESP CAM controller internal malloced backup buffer(s) addr
|
||||||
|
*
|
||||||
|
* @param[in] esp_cam_ctlr_t * ESP CAM controller handle
|
||||||
|
* @param[in] uint32_t Number of frame buffer(s) to get. This value must be the same as the number of the followed fbN parameters
|
||||||
|
* @param[out] const void ** Address of the frame buffer 0 (first frame buffer)
|
||||||
|
* @param[out] ... List of other frame buffers if any
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK
|
||||||
|
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||||
|
* - ESP_ERR_INVALID_STATE: Invalid driver state
|
||||||
|
*/
|
||||||
|
esp_err_t (*get_internal_buffer)(esp_cam_ctlr_t *, uint32_t, const void **, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ESP CAM controller internal backup buffer length
|
||||||
|
*
|
||||||
|
* @param[in] esp_cam_ctlr_t * ESP CAM controller handle
|
||||||
|
* @param[out] size_t * The size of each frame buffer, in bytes.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK
|
||||||
|
* - ESP_ERR_INVALID_ARG: NULL ptr
|
||||||
|
* - ESP_ERR_INVALID_STATE: Invalid driver state
|
||||||
|
*/
|
||||||
|
esp_err_t (*get_buffer_len)(esp_cam_ctlr_t *, size_t *);
|
||||||
|
|
||||||
void *user_data; ///< User data
|
void *user_data; ///< User data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,5 +25,12 @@ TEST_CASE("TEST CSI driver allocation", "[csi]")
|
|||||||
esp_cam_ctlr_handle_t handle = NULL;
|
esp_cam_ctlr_handle_t handle = NULL;
|
||||||
TEST_ESP_OK(esp_cam_new_csi_ctlr(&csi_config, &handle));
|
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));
|
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_OK(esp_cam_ctlr_get_frame_buffer(handle, 1, (const void **)&bk_buffer));
|
||||||
|
TEST_ESP_OK(esp_cam_ctlr_get_frame_buffer_len(handle, &bk_buffer_len));
|
||||||
|
TEST_ASSERT_NOT_NULL(bk_buffer);
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user