Skip to content

Commit f69aecc

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 6f86747 commit f69aecc

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

@@ -278,7 +296,7 @@ static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable,
278296
return 0;
279297
}
280298

281-
if (!config->snapshot_mode && (CONFIG_VIDEO_BUFFER_POOL_NUM_MAX != 1)) {
299+
if (!data->snapshot_mode && (CONFIG_VIDEO_BUFFER_POOL_NUM_MAX != 1)) {
282300
data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT);
283301

284302
if (data->vbuf == NULL) {
@@ -323,42 +341,17 @@ static int video_stm32_dcmi_enqueue(const struct device *dev, struct video_buffe
323341
return 0;
324342
}
325343

326-
static int video_stm32_restart_dma_after_error(struct video_stm32_dcmi_data *data)
327-
{
328-
LOG_DBG("Restart DMA after Error!");
329-
/* Lets try to recover by stopping and maybe restart */
330-
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
331-
LOG_WRN("HAL_DCMI_Stop FAILED!");
332-
}
333-
334-
if (data->snapshot_mode) {
335-
if (data->vbuf != NULL) {
336-
k_fifo_put(&data->fifo_in, data->vbuf);
337-
data->vbuf = NULL;
338-
}
339-
} else {
340-
/* error on last transfer try to restart it */
341-
if (HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS,
342-
(uint32_t)data->vbuf->buffer,
343-
data->vbuf->size / 4) != HAL_OK) {
344-
LOG_WRN("Snapshot: HAL_DCMI_Start_DMA FAILED!");
345-
return -EIO;
346-
}
347-
}
348-
data->restart_dma = false;
349-
return 0;
350-
}
351-
352344
static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffer **vbuf,
353345
k_timeout_t timeout)
354346
{
355347
struct video_stm32_dcmi_data *data = dev->data;
356-
int err;
357348

358349
if (data->snapshot_mode) {
350+
printk("dequeue snapshot: %p %llu\n", data->vbuf, timeout.ticks);
359351
/* See if we were already called and have an active buffer */
360352
if (data->vbuf == NULL) {
361353
data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT);
354+
printk("\tcamera buf: %p\n", data->vbuf);
362355
if (data->vbuf == NULL) {
363356
LOG_WRN("Snapshot: No Buffers available!");
364357
return -ENOMEM;
@@ -373,19 +366,25 @@ static int video_stm32_dcmi_dequeue(const struct device *dev, struct video_buffe
373366
} else {
374367
LOG_DBG("Snapshot: restart after timeout");
375368
}
376-
} else {
377-
err = video_stm32_restart_dma_after_error(data);
378-
if (err < 0) {
379-
return err;
380-
}
381369
}
382370

383371
*vbuf = k_fifo_get(&data->fifo_out, timeout);
372+
printk("k_fifo_get returned: %p\n", *vbuf);
384373

385-
if (data->restart_dma) {
386-
err = video_stm32_restart_dma_after_error(data);
387-
if (err < 0) {
388-
return err;
374+
if (data->dma_error_detected) {
375+
data->dma_error_detected = false;
376+
printk("\tDMA Error detected\n");
377+
378+
/* Should only happen in snapshot mode */
379+
if (data->snapshot_mode) {
380+
if (HAL_DCMI_Stop(&data->hdcmi) != HAL_OK) {
381+
LOG_WRN("HAL_DCMI_Stop FAILED!");
382+
}
383+
if (data->vbuf != NULL) {
384+
printk("\treturn buffer: %p\n", data->vbuf);
385+
k_fifo_put(&data->fifo_in, data->vbuf);
386+
data->vbuf = NULL;
387+
}
389388
}
390389
}
391390

@@ -652,7 +651,7 @@ static int video_stm32_dcmi_init(const struct device *dev)
652651
}
653652

654653
/* See if we should initialize to only support snapshot mode or not */
655-
data->restart_dma = false;
654+
data->dma_error_detected = false;
656655
data->snapshot_mode = config->snapshot_mode;
657656
if (CONFIG_VIDEO_BUFFER_POOL_NUM_MAX == 1) {
658657
LOG_DBG("Only one buffer so snapshot mode only");

0 commit comments

Comments
 (0)