From 4b8cf89d3ef650a2f7c6f312765fbaba8f0d53e2 Mon Sep 17 00:00:00 2001 From: Armin Kessler Date: Tue, 17 Sep 2024 15:02:04 +0200 Subject: [PATCH] drivers: video: esp32s3: Add set_signal video api function This PR implements the set_signal callback from the video API. A signal registered on VIDEO_EP_OUT raises once a new image has been received completely. Signed-off-by: Armin Kessler --- drivers/video/video_esp32_dvp.c | 46 ++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/drivers/video/video_esp32_dvp.c b/drivers/video/video_esp32_dvp.c index 54a480e5424d091..57c997adc81277a 100644 --- a/drivers/video/video_esp32_dvp.c +++ b/drivers/video/video_esp32_dvp.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,16 @@ LOG_MODULE_REGISTER(video_esp32_lcd_cam, CONFIG_VIDEO_LOG_LEVEL); #define VIDEO_ESP32_DMA_BUFFER_MAX_SIZE 4095 +#define VIDEO_ESP32_VSYNC_MASK 0x04 + +#ifdef CONFIG_POLL +#define VIDEO_ESP32_RAISE_OUT_SIG_IF_ENABLED(result) \ + if (data->signal_out) { \ + k_poll_signal_raise(data->signal_out, result); \ + } +#else +#define VIDEO_ESP32_RAISE_OUT_SIG_IF_ENABLED(result) +#endif enum video_esp32_cam_clk_sel_values { VIDEO_ESP32_CAM_CLK_SEL_NONE = 0, @@ -57,6 +68,9 @@ struct video_esp32_data { struct k_fifo fifo_in; struct k_fifo fifo_out; struct dma_block_config dma_blocks[CONFIG_DMA_ESP32_MAX_DESCRIPTOR_NUM]; +#ifdef CONFIG_POLL + struct k_poll_signal *signal_out; +#endif }; static int video_esp32_reload_dma(struct video_esp32_data *data) @@ -89,7 +103,6 @@ void video_esp32_dma_rx_done(const struct device *dev, void *user_data, uint32_t int status) { struct video_esp32_data *data = user_data; - int ret = 0; if (status == DMA_STATUS_BLOCK) { LOG_DBG("received block"); @@ -97,20 +110,24 @@ void video_esp32_dma_rx_done(const struct device *dev, void *user_data, uint32_t } if (status != DMA_STATUS_COMPLETE) { + VIDEO_ESP32_RAISE_OUT_SIG_IF_ENABLED(VIDEO_BUF_ERROR) LOG_ERR("DMA error: %d", status); return; } if (data->active_vbuf == NULL) { + VIDEO_ESP32_RAISE_OUT_SIG_IF_ENABLED(VIDEO_BUF_ERROR) LOG_ERR("No video buffer available. Enque some buffers first."); return; } k_fifo_put(&data->fifo_out, data->active_vbuf); + VIDEO_ESP32_RAISE_OUT_SIG_IF_ENABLED(VIDEO_BUF_DONE) data->active_vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT); if (data->active_vbuf == NULL) { LOG_WRN("Frame dropped. No buffer available"); + VIDEO_ESP32_RAISE_OUT_SIG_IF_ENABLED(VIDEO_BUF_ERROR) return; } video_esp32_reload_dma(data); @@ -197,7 +214,6 @@ static int video_esp32_stream_start(const struct device *dev) if (video_stream_start(cfg->source_dev)) { return -EIO; } - data->is_streaming = true; return 0; @@ -278,7 +294,6 @@ static int video_esp32_set_fmt(const struct device *dev, enum video_endpoint_id static int video_esp32_enqueue(const struct device *dev, enum video_endpoint_id ep, struct video_buffer *vbuf) { - const struct video_esp32_config *cfg = dev->config; struct video_esp32_data *data = dev->data; if (ep != VIDEO_EP_OUT) { @@ -324,6 +339,23 @@ static int video_esp32_get_ctrl(const struct device *dev, unsigned int cid, void return video_get_ctrl(cfg->source_dev, cid, value); } +#ifdef CONFIG_POLL +int video_esp32_set_signal(const struct device *dev, enum video_endpoint_id ep, + struct k_poll_signal *signal) +{ + struct video_esp32_data *data = dev->data; + + if (ep == VIDEO_EP_OUT) { + data->signal_out = signal; + return 0; + } + + LOG_ERR("Invalid endpoint id"); + + return -EINVAL; +} +#endif + static void video_esp32_cam_ctrl_init(const struct device *dev) { const struct video_esp32_config *cfg = dev->config; @@ -375,7 +407,9 @@ static const struct video_driver_api esp32_driver_api = { .flush = NULL, .set_ctrl = video_esp32_set_ctrl, .get_ctrl = video_esp32_get_ctrl, - .set_signal = NULL, +#ifdef CONFIG_POLL + .set_signal = video_esp32_set_signal, +#endif }; PINCTRL_DT_INST_DEFINE(0); @@ -399,8 +433,8 @@ static const struct video_esp32_config esp32_config = { static struct video_esp32_data esp32_data = {0}; -DEVICE_DT_INST_DEFINE(0, video_esp32_init, NULL, &esp32_data, &esp32_config, - POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &esp32_driver_api); +DEVICE_DT_INST_DEFINE(0, video_esp32_init, NULL, &esp32_data, &esp32_config, POST_KERNEL, + CONFIG_VIDEO_INIT_PRIORITY, &esp32_driver_api); static int video_esp32_cam_init_master_clock(void) {