Skip to content

Commit 30f3420

Browse files
committed
video: stm32_dcmi: snapshot timeout
Find at times that the camera when started may for some reason not return an image. So added currently hard coded 5 second timeout for a frame. Should be settable. But at least it recovers and starts getting pictures again. Signed-off-by: Kurt Eckhardt <[email protected]>
1 parent 1884f61 commit 30f3420

File tree

2 files changed

+82
-41
lines changed

2 files changed

+82
-41
lines changed

drivers/video/video_stm32_dcmi.c

Lines changed: 76 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct video_stm32_dcmi_data {
4545
struct k_fifo fifo_in;
4646
struct k_fifo fifo_out;
4747
struct video_buffer *vbuf;
48+
uint32_t snapshot_start_time;
4849
bool snapshot_mode;
4950
};
5051

@@ -55,6 +56,7 @@ struct video_stm32_dcmi_config {
5556
const struct device *sensor_dev;
5657
const struct stream dma;
5758
bool snapshot_mode;
59+
int snapshot_timeout;
5860
};
5961

6062
static void stm32_dcmi_process_dma_error(DCMI_HandleTypeDef *hdcmi)
@@ -63,19 +65,19 @@ static void stm32_dcmi_process_dma_error(DCMI_HandleTypeDef *hdcmi)
6365
CONTAINER_OF(hdcmi, struct video_stm32_dcmi_data, hdcmi);
6466

6567
LOG_WRN("Restart DMA after Error!");
66-
/* Lets try to recover by stopping and maybe restart */
68+
69+
/* Lets try to recover by stopping and restart */
6770
if (HAL_DCMI_Stop(&dev_data->hdcmi) != HAL_OK) {
68-
LOG_WRN("HAL_DCMI_Stop FAILED!");
71+
LOG_WRN("HAL_DCMI_Stop FAILED!");
6972
return;
7073
}
7174

72-
/* error on last transfer try to restart it */
7375
if (HAL_DCMI_Start_DMA(&dev_data->hdcmi,
74-
dev_data->snapshot_mode ? DCMI_MODE_SNAPSHOT : DCMI_MODE_CONTINUOUS,
75-
(uint32_t)dev_data->vbuf->buffer,
76-
dev_data->vbuf->size / 4) != HAL_OK) {
77-
LOG_WRN("Continuous: HAL_DCMI_Start_DMA FAILED!");
78-
return;
76+
dev_data->snapshot_mode ? DCMI_MODE_SNAPSHOT : DCMI_MODE_CONTINUOUS,
77+
(uint32_t)dev_data->vbuf->buffer,
78+
dev_data->vbuf->size / 4) != HAL_OK) {
79+
LOG_WRN("Continuous: HAL_DCMI_Start_DMA FAILED!");
80+
return;
7981
}
8082
}
8183

@@ -327,57 +329,90 @@ static int video_stm32_dcmi_enqueue(const struct device *dev, struct video_buffe
327329
return 0;
328330
}
329331

330-
static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffer **vbuf,
331-
k_timeout_t timeout)
332+
static int video_stm32_dcmi_snapshot(const struct device *dev, struct video_buffer **vbuf,
333+
k_timeout_t timeout)
332334
{
333335
struct video_stm32_dcmi_data *data = dev->data;
336+
const struct video_stm32_dcmi_config *config = dev->config;
334337

335-
if (data->snapshot_mode) {
336-
LOG_DBG("dequeue snapshot: %p %llu\n", data->vbuf, timeout.ticks);
337-
/* See if we were already called and have an active buffer */
338-
if (data->vbuf == NULL) {
339-
/* check first to see if we already have a buffer returned */
340-
*vbuf = k_fifo_get(&data->fifo_out, K_NO_WAIT);
341-
if (*vbuf != NULL) {
342-
LOG_DBG("k_fifo_get returned: %p\n", *vbuf);
343-
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
344-
LOG_WRN("Snapshot: HAL_DCMI_Stop FAILED!");
345-
}
346-
return 0;
347-
}
348-
data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT);
349-
LOG_DBG("\tcamera buf: %p\n", data->vbuf);
350-
if (data->vbuf == NULL) {
351-
LOG_WRN("Snapshot: No Buffers available!");
352-
return -ENOMEM;
353-
}
338+
LOG_DBG("dequeue snapshot: %p %llu\n", data->vbuf, timeout.ticks);
354339

355-
if (HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_SNAPSHOT,
356-
(uint32_t)data->vbuf->buffer,
357-
data->vbuf->size / 4) != HAL_OK) {
358-
LOG_WRN("Snapshot: HAL_DCMI_Start_DMA FAILED!");
359-
return -EIO;
340+
/* See if we were already called and have an active buffer */
341+
if (data->vbuf == NULL) {
342+
/* check first to see if we already have a buffer returned */
343+
*vbuf = k_fifo_get(&data->fifo_out, K_NO_WAIT);
344+
if (*vbuf != NULL) {
345+
LOG_DBG("k_fifo_get returned: %p\n", *vbuf);
346+
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
347+
LOG_WRN("Snapshot: HAL_DCMI_Stop FAILED!");
360348
}
361-
} else {
362-
LOG_DBG("Snapshot: restart after timeout");
349+
return 0;
363350
}
351+
data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT);
352+
LOG_DBG("\tcamera buf: %p\n", data->vbuf);
353+
if (data->vbuf == NULL) {
354+
LOG_WRN("Snapshot: No Buffers available!");
355+
return -ENOMEM;
356+
}
357+
358+
if (HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_SNAPSHOT,
359+
(uint32_t)data->vbuf->buffer,
360+
data->vbuf->size / 4) != HAL_OK) {
361+
LOG_WRN("Snapshot: HAL_DCMI_Start_DMA FAILED!");
362+
return -EIO;
363+
}
364+
365+
/* remember when we started this request */
366+
data->snapshot_start_time = k_uptime_get_32();
364367
}
365368

366369
*vbuf = k_fifo_get(&data->fifo_out, timeout);
367370
LOG_DBG("k_fifo_get returned: %p\n", *vbuf);
368371

369372
if (*vbuf == NULL) {
373+
uint32_t time_since_start_time =
374+
(uint32_t)(k_uptime_get_32() - data->snapshot_start_time);
375+
if (time_since_start_time > config->snapshot_timeout) {
376+
LOG_WRN("Snapshot: Timed out!");
377+
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
378+
LOG_WRN("Snapshot: HAL_DCMI_Stop FAILED!");
379+
}
380+
/* verify it did not come in during this procuessing */
381+
*vbuf = k_fifo_get(&data->fifo_out, K_NO_WAIT);
382+
if (*vbuf) {
383+
return 0;
384+
}
385+
386+
if (data->vbuf != NULL) {
387+
k_fifo_put(&data->fifo_in, data->vbuf);
388+
data->vbuf = NULL;
389+
}
390+
}
391+
370392
return -EAGAIN;
371393
}
372394

373-
if (data->snapshot_mode) {
374-
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
375-
LOG_WRN("Snapshot: HAL_DCMI_Stop FAILED!");
376-
}
395+
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
396+
LOG_WRN("Snapshot: HAL_DCMI_Stop FAILED!");
377397
}
378398
return 0;
379399
}
380400

401+
static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffer **vbuf,
402+
k_timeout_t timeout)
403+
{
404+
struct video_stm32_dcmi_data *data = dev->data;
405+
406+
if (data->snapshot_mode) {
407+
return video_stm32_dcmi_snapshot(dev, vbuf, timeout);
408+
}
409+
410+
*vbuf = k_fifo_get(&data->fifo_out, timeout);
411+
LOG_DBG("k_fifo_get returned: %p\n", *vbuf);
412+
413+
return (*vbuf == NULL) ? -EAGAIN : 0;
414+
}
415+
381416
static int video_stm32_dcmi_get_caps(const struct device *dev, struct video_caps *caps)
382417
{
383418
const struct video_stm32_dcmi_config *config = dev->config;
@@ -601,6 +636,7 @@ static const struct video_stm32_dcmi_config video_stm32_dcmi_config_0 = {
601636
.pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
602637
.sensor_dev = SOURCE_DEV(0),
603638
.snapshot_mode = DT_INST_PROP(0, snapshot_mode),
639+
.snapshot_timeout = DT_INST_PROP(0, snapshot_timeout),
604640
DCMI_DMA_CHANNEL(0, PERIPHERAL, MEMORY)
605641
};
606642

dts/bindings/video/st,stm32-dcmi.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ properties:
4848
4949
snapshot-mode:
5050
type: boolean
51-
description: set the driver into snapshot mode, default is off.
51+
description: Set DCMI to Snapshot mode, instead of the default Capture mode.
52+
53+
snapshot-timeout:
54+
type: int
55+
description: Set capture timeout in microseconds, default is 1000.
56+
default: 1000
5257

5358
child-binding:
5459
child-binding:

0 commit comments

Comments
 (0)