Skip to content

Commit c7d69e9

Browse files
committed
video: stm32_dcmi: cleanup recovery code
WIP - will squash once I verify that snapshot is working And then will remove some debug outputs
1 parent dd4de94 commit c7d69e9

File tree

1 file changed

+40
-41
lines changed

1 file changed

+40
-41
lines changed

drivers/video/video_stm32_dcmi.c

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct video_stm32_dcmi_data {
4646
struct k_fifo fifo_out;
4747
struct video_buffer *vbuf;
4848
bool snapshot_mode : 1;
49-
bool restart_dma : 1;
49+
bool dma_error_detected : 1;
5050
};
5151

5252
struct video_stm32_dcmi_config {
@@ -63,8 +63,25 @@ static void stm32_dcmi_process_dma_error(DCMI_HandleTypeDef *hdcmi)
6363
struct video_stm32_dcmi_data *dev_data =
6464
CONTAINER_OF(hdcmi, struct video_stm32_dcmi_data, hdcmi);
6565

66-
dev_data->restart_dma = true;
67-
k_fifo_cancel_wait(&dev_data->fifo_out);
66+
if (dev_data->snapshot_mode) {
67+
dev_data->dma_error_detected = true;
68+
k_fifo_cancel_wait(&dev_data->fifo_out);
69+
} else {
70+
LOG_ERR("Restart DMA after Error!");
71+
/* Lets try to recover by stopping and maybe restart */
72+
if (HAL_DCMI_Stop(&dev_data->hdcmi) != HAL_OK) {
73+
LOG_WRN("HAL_DCMI_Stop FAILED!");
74+
return;
75+
}
76+
77+
/* error on last transfer try to restart it */
78+
if (HAL_DCMI_Start_DMA(&dev_data->hdcmi, DCMI_MODE_CONTINUOUS,
79+
(uint32_t)dev_data->vbuf->buffer,
80+
dev_data->vbuf->size / 4) != HAL_OK) {
81+
LOG_WRN("Continuous: HAL_DCMI_Start_DMA FAILED!");
82+
return;
83+
}
84+
}
6885
}
6986

7087
void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
@@ -85,6 +102,7 @@ void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
85102
dev_data->vbuf = NULL;
86103
vbuf->timestamp = k_uptime_get_32();
87104
k_fifo_put(&dev_data->fifo_out, vbuf);
105+
LOG_DBG("event SH put: %p", vbuf);
88106
return;
89107
}
90108

@@ -270,7 +288,7 @@ static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable,
270288
return 0;
271289
}
272290

273-
if (!config->snapshot_mode && (CONFIG_VIDEO_BUFFER_POOL_NUM_MAX != 1)) {
291+
if (!data->snapshot_mode && (CONFIG_VIDEO_BUFFER_POOL_NUM_MAX != 1)) {
274292
data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT);
275293

276294
if (data->vbuf == NULL) {
@@ -315,42 +333,17 @@ static int video_stm32_dcmi_enqueue(const struct device *dev, struct video_buffe
315333
return 0;
316334
}
317335

318-
static int video_stm32_restart_dma_after_error(struct video_stm32_dcmi_data *data)
319-
{
320-
LOG_DBG("Restart DMA after Error!");
321-
/* Lets try to recover by stopping and maybe restart */
322-
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
323-
LOG_WRN("HAL_DCMI_Stop FAILED!");
324-
}
325-
326-
if (data->snapshot_mode) {
327-
if (data->vbuf != NULL) {
328-
k_fifo_put(&data->fifo_in, data->vbuf);
329-
data->vbuf = NULL;
330-
}
331-
} else {
332-
/* error on last transfer try to restart it */
333-
if (HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS,
334-
(uint32_t)data->vbuf->buffer,
335-
data->vbuf->size / 4) != HAL_OK) {
336-
LOG_WRN("Snapshot: HAL_DCMI_Start_DMA FAILED!");
337-
return -EIO;
338-
}
339-
}
340-
data->restart_dma = false;
341-
return 0;
342-
}
343-
344336
static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffer **vbuf,
345337
k_timeout_t timeout)
346338
{
347339
struct video_stm32_dcmi_data *data = dev->data;
348-
int err;
349340

350341
if (data->snapshot_mode) {
342+
printk("dequeue snapshot: %p %llu\n", data->vbuf, timeout.ticks);
351343
/* See if we were already called and have an active buffer */
352344
if (data->vbuf == NULL) {
353345
data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT);
346+
printk("\tcamera buf: %p\n", data->vbuf);
354347
if (data->vbuf == NULL) {
355348
LOG_WRN("Snapshot: No Buffers available!");
356349
return -ENOMEM;
@@ -365,19 +358,25 @@ static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffe
365358
} else {
366359
LOG_DBG("Snapshot: restart after timeout");
367360
}
368-
} else {
369-
err = video_stm32_restart_dma_after_error(data);
370-
if (err < 0) {
371-
return err;
372-
}
373361
}
374362

375363
*vbuf = k_fifo_get(&data->fifo_out, timeout);
364+
printk("k_fifo_get returned: %p\n", *vbuf);
376365

377-
if (data->restart_dma) {
378-
err = video_stm32_restart_dma_after_error(data);
379-
if (err < 0) {
380-
return err;
366+
if (data->dma_error_detected) {
367+
data->dma_error_detected = false;
368+
printk("\tDMA Error detected\n");
369+
370+
/* Should only happen in snapshot mode */
371+
if (data->snapshot_mode) {
372+
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
373+
LOG_WRN("HAL_DCMI_Stop FAILED!");
374+
}
375+
if (data->vbuf != NULL) {
376+
printk("\treturn buffer: %p\n", data->vbuf);
377+
k_fifo_put(&data->fifo_in, data->vbuf);
378+
data->vbuf = NULL;
379+
}
381380
}
382381
}
383382

@@ -647,7 +646,7 @@ static int video_stm32_dcmi_init(const struct device *dev)
647646
}
648647

649648
/* See if we should initialize to only support snapshot mode or not */
650-
data->restart_dma = false;
649+
data->dma_error_detected = false;
651650
data->snapshot_mode = config->snapshot_mode;
652651
if (CONFIG_VIDEO_BUFFER_POOL_NUM_MAX == 1) {
653652
LOG_DBG("Only one buffer so snapshot mode only");

0 commit comments

Comments
 (0)