Skip to content

Commit c839423

Browse files
committed
rework psram_mode frame buffer overflow check
- Do this check only in psram_mode - Improve code comment, to make clear that it will stop early on copy operations - Increase fb size by one dma_half_buffer_size in psram_mode Rationale: In psram_mode we will be called after each memory copy operation is completed, by the CAM_IN_SUC_EOF event. Since we cannot predict at this point, if the camera will copy another dma_half_buffer_size into the fb, we need to abort here, if there's not enough size in the fb for the next copy operation. This assumption means, we will abort even if this is indeed the last copy operation the camera did, and the next event will be a CAM_VSYNC, notifying us, that the copy operation is completed. Since we cannot predict this, we need one dma_half_buffer_size more space in the fb in psram_mode to allow images of the same size in psram_mode as in the regular mode.
1 parent b633f87 commit c839423

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

driver/cam_hal.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,18 @@ static void cam_task(void *arg)
262262
&frame_buffer_event->buf[frame_buffer_event->len],
263263
&cam_obj->dma_buffer[(cnt % cam_obj->dma_half_buffer_cnt) * cam_obj->dma_half_buffer_size],
264264
cam_obj->dma_half_buffer_size);
265+
} else {
266+
// stop if the next DMA copy would exceed the framebuffer slot
267+
// size, since we're called only after the copy occurs
268+
// This effectively reduces maximum usable frame buffer size
269+
// by one DMA operation, as we can't predict here, if the next
270+
// cam event will be a VSYNC
271+
if (cnt + 1 >= cam_obj->frame_copy_cnt) {
272+
ESP_LOGE(TAG, "DMA overflow");
273+
ll_cam_stop(cam_obj);
274+
cam_obj->state = CAM_STATE_IDLE;
275+
continue;
276+
}
265277
}
266278

267279
//Check for JPEG SOI in the first buffer. stop if not found
@@ -311,14 +323,6 @@ static void cam_task(void *arg)
311323
}
312324

313325
cnt++;
314-
// stop when too many DMA copies occur so the PSRAM
315-
// framebuffer slot doesn't overflow from runaway transfers
316-
if (cnt >= cam_obj->frame_copy_cnt) {
317-
ESP_LOGE(TAG, "DMA overflow");
318-
ll_cam_stop(cam_obj);
319-
cam_obj->state = CAM_STATE_IDLE;
320-
continue;
321-
}
322326

323327
} else if (cam_event == CAM_VSYNC_EVENT) {
324328
//DBG_PIN_SET(1);
@@ -416,6 +420,9 @@ static esp_err_t cam_dma_config(const camera_config_t *config)
416420

417421
cam_obj->dma_node_cnt = (cam_obj->dma_buffer_size) / cam_obj->dma_node_buffer_size; // Number of DMA nodes
418422
cam_obj->frame_copy_cnt = cam_obj->recv_size / cam_obj->dma_half_buffer_size; // Number of interrupted copies, ping-pong copy
423+
if (cam_obj->psram_mode) {
424+
cam_obj->frame_copy_cnt++;
425+
}
419426

420427
ESP_LOGI(TAG, "buffer_size: %d, half_buffer_size: %d, node_buffer_size: %d, node_cnt: %d, total_cnt: %d",
421428
(int) cam_obj->dma_buffer_size, (int) cam_obj->dma_half_buffer_size, (int) cam_obj->dma_node_buffer_size,
@@ -434,6 +441,7 @@ static esp_err_t cam_dma_config(const camera_config_t *config)
434441
if (cam_obj->fb_size < cam_obj->recv_size) {
435442
fb_size = cam_obj->recv_size;
436443
}
444+
fb_size += cam_obj->dma_half_buffer_size;
437445
}
438446

439447
/* Allocate memory for frame buffer */

0 commit comments

Comments
 (0)