Skip to content

Commit 288ea61

Browse files
committed
video: stm32_dcmi: When to do what in recovery
@josuah, @avolmat-st @pillo79 and all - This commit is giving a couple different options on what should be done when we detect a USB failure. The previous one, when the callback for DMA error happens, I stopped the HDMA DMA and in some case restarted it there. But I found when I started doing the Snapshot earlier, I found it would hang more often when it was done there, so I did it when the call came back to get a buffer in the dequeue... So the new option is to detect the error and set a state saying we are in an error condition and when we return and are in the dequeue function, if we see that that we errored out it process it then. In the case of not being in snapshot mode there are two place. Again when: ``` *vbuf = k_fifo_get(&data->fifo_out, timeout); ``` returns in this condition. So we do it there. Or if we call dequeue and the error happened while we were not in dequeue, like we have two buffers. And we already dequeue one and maybe we re drawing it on the display and the camera is still active reading in the next frame. Once I know which way you would all prefer, will then remove the others and squash the commits. Signed-off-by: Kurt Eckhardt <[email protected]>
1 parent 8afa5a4 commit 288ea61

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

drivers/video/video_stm32_dcmi.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
#define DT_DRV_COMPAT st_stm32_dcmi
88

9+
/* *** Experiment to see when best to stop/start in error *** */
10+
/*
11+
*#define STOP_DMA_IN_ERROR_CBS
12+
*/
913
#include <errno.h>
1014

1115
#include <zephyr/kernel.h>
@@ -66,6 +70,7 @@ static void stm32_dcmi_process_dma_error(DCMI_HandleTypeDef *hdcmi)
6670
return;
6771
}
6872

73+
#ifdef STOP_DMA_IN_ERROR_CBS
6974
/* Lets try to recover by stopping and maybe restart */
7075
if (HAL_DCMI_Stop(hdcmi) != HAL_OK) {
7176
LOG_WRN("HAL_DCMI_Stop FAILED!");
@@ -82,12 +87,16 @@ static void stm32_dcmi_process_dma_error(DCMI_HandleTypeDef *hdcmi)
8287
}
8388
/* also cancel timeout on the fifo_out to speed up recovery */
8489
k_fifo_cancel_wait(&dev_data->fifo_out);
90+
#else
91+
dev_data->restart_dma = true;
92+
k_fifo_cancel_wait(&dev_data->fifo_out);
93+
#endif
8594
}
8695

8796
void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
8897
{
8998
LOG_WRN("%s %p", __func__, hdcmi);
90-
/*stm32_dcmi_process_dma_error(hdcmi); */
99+
stm32_dcmi_process_dma_error(hdcmi);
91100
}
92101

93102
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
@@ -348,6 +357,7 @@ static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffe
348357
if (data->vbuf == NULL) {
349358
data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT);
350359
if (data->vbuf == NULL) {
360+
LOG_WRN("Snapshot: No Buffers available!");
351361
return -ENOMEM;
352362
}
353363

@@ -363,6 +373,12 @@ static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffe
363373
} else {
364374
if (data->restart_dma) {
365375
/* error on last transfer try to restart it */
376+
LOG_INF("Dequeue recover at start");
377+
#ifndef STOP_DMA_IN_ERROR_CBS
378+
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
379+
LOG_WRN("HAL_DCMI_Stop FAILED!");
380+
}
381+
#endif
366382
if (HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS,
367383
(uint32_t)data->vbuf->buffer,
368384
data->vbuf->size / 4) != HAL_OK) {
@@ -375,6 +391,31 @@ static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffe
375391

376392
*vbuf = k_fifo_get(&data->fifo_out, timeout);
377393

394+
#ifndef STOP_DMA_IN_ERROR_CBS
395+
if (data->restart_dma) {
396+
LOG_INF("Dequeue recover after k_fifo_get");
397+
/* Lets try to recover by stopping and maybe restart */
398+
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
399+
LOG_WRN("HAL_DCMI_Stop FAILED!");
400+
}
401+
402+
if (data->snapshot_mode) {
403+
if (data->vbuf != NULL) {
404+
k_fifo_put(&data->fifo_in, data->vbuf);
405+
data->vbuf = NULL;
406+
}
407+
} else {
408+
/* error on last transfer try to restart it */
409+
if (HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS,
410+
(uint32_t)data->vbuf->buffer,
411+
data->vbuf->size / 4) != HAL_OK) {
412+
LOG_WRN("Snapshot: HAL_DCMI_Start_DMA FAILED!");
413+
return -EIO;
414+
}
415+
}
416+
data->restart_dma = false;
417+
}
418+
#endif
378419
if (*vbuf == NULL) {
379420
return -EAGAIN;
380421
}
@@ -384,7 +425,6 @@ static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffe
384425
LOG_WRN("Snapshot: HAL_DCMI_Stop FAILED!");
385426
}
386427
}
387-
388428
return 0;
389429
}
390430

0 commit comments

Comments
 (0)