mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
ports/mimxrt: Add set_framerate support.
This commit is contained in:
parent
baa8a4ee58
commit
b4a57ffca2
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the OpenMV project.
|
* This file is part of the OpenMV project.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2023 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||||
* Copyright (c) 2013-2023 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
* Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||||
*
|
*
|
||||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||||
*
|
*
|
||||||
@ -28,6 +28,9 @@
|
|||||||
sensor_t sensor = {};
|
sensor_t sensor = {};
|
||||||
extern uint8_t _line_buf[OMV_LINE_BUF_SIZE];
|
extern uint8_t _line_buf[OMV_LINE_BUF_SIZE];
|
||||||
|
|
||||||
|
static bool first_line = false;
|
||||||
|
static bool drop_frame = false;
|
||||||
|
|
||||||
#define CSI_IRQ_FLAGS (CSI_CR1_SOF_INTEN_MASK \
|
#define CSI_IRQ_FLAGS (CSI_CR1_SOF_INTEN_MASK \
|
||||||
| CSI_CR1_FB2_DMA_DONE_INTEN_MASK \
|
| CSI_CR1_FB2_DMA_DONE_INTEN_MASK \
|
||||||
| CSI_CR1_FB1_DMA_DONE_INTEN_MASK)
|
| CSI_CR1_FB1_DMA_DONE_INTEN_MASK)
|
||||||
@ -152,6 +155,10 @@ int sensor_abort() {
|
|||||||
NVIC_DisableIRQ(CSI_IRQn);
|
NVIC_DisableIRQ(CSI_IRQn);
|
||||||
CSI_DisableInterrupts(CSI, CSI_IRQ_FLAGS);
|
CSI_DisableInterrupts(CSI, CSI_IRQ_FLAGS);
|
||||||
CSI_REG_CR18(CSI) &= ~(CSI_CR18_CSI_ENABLE_MASK | CSI_CR3_DMA_REQ_EN_RFF_MASK);
|
CSI_REG_CR18(CSI) &= ~(CSI_CR18_CSI_ENABLE_MASK | CSI_CR3_DMA_REQ_EN_RFF_MASK);
|
||||||
|
first_line = false;
|
||||||
|
drop_frame = false;
|
||||||
|
sensor.last_frame_ms = 0;
|
||||||
|
sensor.last_frame_ms_valid = false;
|
||||||
framebuffer_reset_buffers();
|
framebuffer_reset_buffers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -178,10 +185,16 @@ uint32_t sensor_get_xclk_frequency() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sensor_sof_callback() {
|
void sensor_sof_callback() {
|
||||||
|
first_line = false;
|
||||||
|
drop_frame = false;
|
||||||
// Get current framebuffer.
|
// Get current framebuffer.
|
||||||
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
sensor_abort();
|
sensor_abort();
|
||||||
|
// Reset the queue of frames when we start dropping frames.
|
||||||
|
if (!sensor.disable_full_flush) {
|
||||||
|
framebuffer_flush_buffers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (buffer->offset < MAIN_FB()->v) {
|
if (buffer->offset < MAIN_FB()->v) {
|
||||||
// Missed a few lines, reset buffer state and continue.
|
// Missed a few lines, reset buffer state and continue.
|
||||||
@ -190,9 +203,35 @@ void sensor_sof_callback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sensor_line_callback(uint32_t addr) {
|
void sensor_line_callback(uint32_t addr) {
|
||||||
|
if (!first_line) {
|
||||||
|
first_line = true;
|
||||||
|
uint32_t tick = mp_hal_ticks_ms();
|
||||||
|
uint32_t framerate_ms = IM_DIV(1000, sensor.framerate);
|
||||||
|
|
||||||
|
// Drops frames to match the frame rate requested by the user. The frame is NOT copied to
|
||||||
|
// SRAM/SDRAM when dropping to save CPU cycles/energy that would be wasted.
|
||||||
|
// If framerate is zero then this does nothing...
|
||||||
|
if (sensor.last_frame_ms_valid && ((tick - sensor.last_frame_ms) < framerate_ms)) {
|
||||||
|
drop_frame = true;
|
||||||
|
} else if (sensor.last_frame_ms_valid) {
|
||||||
|
sensor.last_frame_ms += framerate_ms;
|
||||||
|
} else {
|
||||||
|
sensor.last_frame_ms = tick;
|
||||||
|
sensor.last_frame_ms_valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get current framebuffer.
|
// Get current framebuffer.
|
||||||
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
||||||
|
|
||||||
|
if (drop_frame) {
|
||||||
|
if (++buffer->offset == MAIN_FB()->v) {
|
||||||
|
buffer->offset = 0;
|
||||||
|
CSI_REG_CR3(CSI) &= ~CSI_CR3_DMA_REQ_EN_RFF_MASK;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy from DMA buffer to framebuffer.
|
// Copy from DMA buffer to framebuffer.
|
||||||
uint32_t bytes_per_pixel = sensor_get_src_bpp();
|
uint32_t bytes_per_pixel = sensor_get_src_bpp();
|
||||||
uint8_t *src = ((uint8_t *) addr) + (MAIN_FB()->x * bytes_per_pixel);
|
uint8_t *src = ((uint8_t *) addr) + (MAIN_FB()->x * bytes_per_pixel);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user