mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #1356 from kwagyeman/kwabena/make_frame_rate_control_work
Add working frame rate control for all sensors to STM32
This commit is contained in:
commit
a7f2a6fcab
@ -180,6 +180,8 @@ typedef struct _sensor {
|
|||||||
pixformat_t pixformat; // Pixel format
|
pixformat_t pixformat; // Pixel format
|
||||||
framesize_t framesize; // Frame size
|
framesize_t framesize; // Frame size
|
||||||
int framerate; // Frame rate
|
int framerate; // Frame rate
|
||||||
|
uint32_t last_frame_ms; // Last sampled frame timestamp in milliseconds.
|
||||||
|
bool last_frame_ms_valid; // Last sampled frame timestamp in milliseconds valid.
|
||||||
gainceiling_t gainceiling; // AGC gainceiling
|
gainceiling_t gainceiling; // AGC gainceiling
|
||||||
bool hmirror; // Horizontal Mirror
|
bool hmirror; // Horizontal Mirror
|
||||||
bool vflip; // Vertical Flip
|
bool vflip; // Vertical Flip
|
||||||
|
|||||||
@ -415,24 +415,26 @@ int sensor_reset()
|
|||||||
framebuffer_reset_buffers();
|
framebuffer_reset_buffers();
|
||||||
|
|
||||||
// Reset the sensor state
|
// Reset the sensor state
|
||||||
sensor.sde = 0;
|
sensor.sde = 0;
|
||||||
sensor.pixformat = 0;
|
sensor.pixformat = 0;
|
||||||
sensor.framesize = 0;
|
sensor.framesize = 0;
|
||||||
sensor.framerate = 0;
|
sensor.framerate = 0;
|
||||||
sensor.gainceiling = 0;
|
sensor.last_frame_ms = 0;
|
||||||
sensor.hmirror = false;
|
sensor.last_frame_ms_valid = false;
|
||||||
sensor.vflip = false;
|
sensor.gainceiling = 0;
|
||||||
sensor.transpose = false;
|
sensor.hmirror = false;
|
||||||
|
sensor.vflip = false;
|
||||||
|
sensor.transpose = false;
|
||||||
#if MICROPY_PY_IMU
|
#if MICROPY_PY_IMU
|
||||||
sensor.auto_rotation = sensor.chip_id == OV7690_ID;
|
sensor.auto_rotation = sensor.chip_id == OV7690_ID;
|
||||||
#else
|
#else
|
||||||
sensor.auto_rotation = false;
|
sensor.auto_rotation = false;
|
||||||
#endif // MICROPY_PY_IMU
|
#endif // MICROPY_PY_IMU
|
||||||
sensor.vsync_callback= NULL;
|
sensor.vsync_callback = NULL;
|
||||||
sensor.frame_callback= NULL;
|
sensor.frame_callback = NULL;
|
||||||
|
|
||||||
// Reset default color palette.
|
// Reset default color palette.
|
||||||
sensor.color_palette = rainbow_table;
|
sensor.color_palette = rainbow_table;
|
||||||
|
|
||||||
sensor.disable_full_flush = false;
|
sensor.disable_full_flush = false;
|
||||||
|
|
||||||
@ -609,13 +611,20 @@ int sensor_set_framerate(int framerate)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the sensor specific function
|
if (framerate < 0) {
|
||||||
if (sensor.set_framerate == NULL
|
|
||||||
|| sensor.set_framerate(&sensor, framerate) != 0) {
|
|
||||||
// Operation not supported
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call the sensor specific function (does not fail if function is not set)
|
||||||
|
if (sensor.set_framerate != NULL) {
|
||||||
|
if (sensor.set_framerate(&sensor, framerate) != 0) {
|
||||||
|
// Operation not supported
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set framerate
|
||||||
|
sensor.framerate = framerate;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,8 @@ static DCMI_HandleTypeDef DCMIHandle = {.Instance = DCMI};
|
|||||||
static MDMA_HandleTypeDef DCMI_MDMA_Handle0 = {.Instance = MDMA_Channel0};
|
static MDMA_HandleTypeDef DCMI_MDMA_Handle0 = {.Instance = MDMA_Channel0};
|
||||||
static MDMA_HandleTypeDef DCMI_MDMA_Handle1 = {.Instance = MDMA_Channel1};
|
static MDMA_HandleTypeDef DCMI_MDMA_Handle1 = {.Instance = MDMA_Channel1};
|
||||||
#endif
|
#endif
|
||||||
|
static bool first_line = false;
|
||||||
|
static bool drop_frame = false;
|
||||||
|
|
||||||
extern uint8_t _line_buf;
|
extern uint8_t _line_buf;
|
||||||
|
|
||||||
@ -236,6 +238,10 @@ static void dcmi_abort()
|
|||||||
#endif
|
#endif
|
||||||
__HAL_DCMI_DISABLE_IT(&DCMIHandle, DCMI_IT_FRAME);
|
__HAL_DCMI_DISABLE_IT(&DCMIHandle, DCMI_IT_FRAME);
|
||||||
__HAL_DCMI_CLEAR_FLAG(&DCMIHandle, DCMI_FLAG_FRAMERI);
|
__HAL_DCMI_CLEAR_FLAG(&DCMIHandle, DCMI_FLAG_FRAMERI);
|
||||||
|
first_line = false;
|
||||||
|
drop_frame = false;
|
||||||
|
sensor.last_frame_ms = 0;
|
||||||
|
sensor.last_frame_ms_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
framebuffer_reset_buffers();
|
framebuffer_reset_buffers();
|
||||||
@ -563,24 +569,26 @@ int sensor_reset()
|
|||||||
dcmi_abort();
|
dcmi_abort();
|
||||||
|
|
||||||
// Reset the sensor state
|
// Reset the sensor state
|
||||||
sensor.sde = 0;
|
sensor.sde = 0;
|
||||||
sensor.pixformat = 0;
|
sensor.pixformat = 0;
|
||||||
sensor.framesize = 0;
|
sensor.framesize = 0;
|
||||||
sensor.framerate = 0;
|
sensor.framerate = 0;
|
||||||
sensor.gainceiling = 0;
|
sensor.last_frame_ms = 0;
|
||||||
sensor.hmirror = false;
|
sensor.last_frame_ms_valid = false;
|
||||||
sensor.vflip = false;
|
sensor.gainceiling = 0;
|
||||||
sensor.transpose = false;
|
sensor.hmirror = false;
|
||||||
|
sensor.vflip = false;
|
||||||
|
sensor.transpose = false;
|
||||||
#if MICROPY_PY_IMU
|
#if MICROPY_PY_IMU
|
||||||
sensor.auto_rotation = sensor.chip_id == OV7690_ID;
|
sensor.auto_rotation = sensor.chip_id == OV7690_ID;
|
||||||
#else
|
#else
|
||||||
sensor.auto_rotation = false;
|
sensor.auto_rotation = false;
|
||||||
#endif // MICROPY_PY_IMU
|
#endif // MICROPY_PY_IMU
|
||||||
sensor.vsync_callback= NULL;
|
sensor.vsync_callback = NULL;
|
||||||
sensor.frame_callback= NULL;
|
sensor.frame_callback = NULL;
|
||||||
|
|
||||||
// Reset default color palette.
|
// Reset default color palette.
|
||||||
sensor.color_palette = rainbow_table;
|
sensor.color_palette = rainbow_table;
|
||||||
|
|
||||||
sensor.disable_full_flush = false;
|
sensor.disable_full_flush = false;
|
||||||
|
|
||||||
@ -725,6 +733,9 @@ int sensor_set_pixformat(pixformat_t pixformat)
|
|||||||
// Skip the first frame.
|
// Skip the first frame.
|
||||||
MAIN_FB()->bpp = -1;
|
MAIN_FB()->bpp = -1;
|
||||||
|
|
||||||
|
// Pickout a good buffer count for the user.
|
||||||
|
framebuffer_auto_adjust_buffers();
|
||||||
|
|
||||||
// Change the JPEG mode.
|
// Change the JPEG mode.
|
||||||
return dcmi_config((pixformat == PIXFORMAT_JPEG) ? DCMI_JPEG_ENABLE : DCMI_JPEG_DISABLE);
|
return dcmi_config((pixformat == PIXFORMAT_JPEG) ? DCMI_JPEG_ENABLE : DCMI_JPEG_DISABLE);
|
||||||
}
|
}
|
||||||
@ -775,13 +786,20 @@ int sensor_set_framerate(int framerate)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the sensor specific function
|
if (framerate < 0) {
|
||||||
if (sensor.set_framerate == NULL
|
|
||||||
|| sensor.set_framerate(&sensor, framerate) != 0) {
|
|
||||||
// Operation not supported
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call the sensor specific function (does not fail if function is not set)
|
||||||
|
if (sensor.set_framerate != NULL) {
|
||||||
|
if (sensor.set_framerate(&sensor, framerate) != 0) {
|
||||||
|
// Operation not supported
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set framerate
|
||||||
|
sensor.framerate = framerate;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,6 +816,7 @@ int sensor_set_windowing(int x, int y, int w, int h)
|
|||||||
|
|
||||||
dcmi_abort();
|
dcmi_abort();
|
||||||
|
|
||||||
|
// Flush previous frame.
|
||||||
framebuffer_update_jpeg_buffer();
|
framebuffer_update_jpeg_buffer();
|
||||||
|
|
||||||
// Skip the first frame.
|
// Skip the first frame.
|
||||||
@ -951,6 +970,8 @@ int sensor_set_hmirror(int enable)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dcmi_abort();
|
||||||
|
|
||||||
/* call the sensor specific function */
|
/* call the sensor specific function */
|
||||||
if (sensor.set_hmirror == NULL
|
if (sensor.set_hmirror == NULL
|
||||||
|| sensor.set_hmirror(&sensor, enable) != 0) {
|
|| sensor.set_hmirror(&sensor, enable) != 0) {
|
||||||
@ -974,6 +995,8 @@ int sensor_set_vflip(int enable)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dcmi_abort();
|
||||||
|
|
||||||
/* call the sensor specific function */
|
/* call the sensor specific function */
|
||||||
if (sensor.set_vflip == NULL
|
if (sensor.set_vflip == NULL
|
||||||
|| sensor.set_vflip(&sensor, enable) != 0) {
|
|| sensor.set_vflip(&sensor, enable) != 0) {
|
||||||
@ -1001,6 +1024,8 @@ int sensor_set_transpose(bool enable)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dcmi_abort();
|
||||||
|
|
||||||
sensor.transpose = enable;
|
sensor.transpose = enable;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1021,6 +1046,8 @@ int sensor_set_auto_rotation(bool enable)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dcmi_abort();
|
||||||
|
|
||||||
sensor.auto_rotation = enable;
|
sensor.auto_rotation = enable;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1263,18 +1290,26 @@ static void sensor_check_buffsize()
|
|||||||
// moving the tail to the next buffer.
|
// moving the tail to the next buffer.
|
||||||
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
|
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
|
||||||
{
|
{
|
||||||
framebuffer_get_tail(FB_NO_FLAGS);
|
// This can be executed at any time since this interrupt has a higher priority than DMA2_Stream1_IRQn.
|
||||||
|
|
||||||
if (sensor.frame_callback) {
|
|
||||||
sensor.frame_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (OMV_ENABLE_SENSOR_MDMA_TOTAL_OFFLOAD == 1)
|
#if (OMV_ENABLE_SENSOR_MDMA_TOTAL_OFFLOAD == 1)
|
||||||
// Clear out any stale flags.
|
// Clear out any stale flags.
|
||||||
DMA2->LIFCR = DMA_FLAG_TCIF1_5 | DMA_FLAG_HTIF1_5;
|
DMA2->LIFCR = DMA_FLAG_TCIF1_5 | DMA_FLAG_HTIF1_5;
|
||||||
// Re-enable the DMA IRQ to catch the next start line.
|
// Re-enable the DMA IRQ to catch the next start line.
|
||||||
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
|
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Reset DCMI_DMAConvCpltUser frame drop state.
|
||||||
|
first_line = false;
|
||||||
|
if (drop_frame) {
|
||||||
|
drop_frame = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
framebuffer_get_tail(FB_NO_FLAGS);
|
||||||
|
|
||||||
|
if (sensor.frame_callback) {
|
||||||
|
sensor.frame_callback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (OMV_ENABLE_SENSOR_MDMA == 1)
|
#if (OMV_ENABLE_SENSOR_MDMA == 1)
|
||||||
@ -1302,6 +1337,35 @@ static void mdma_memcpy(vbuffer_t *buffer, void *dst, void *src, int bpp, bool t
|
|||||||
// DMA transfers the next line to the other half of the line buffer.
|
// DMA transfers the next line to the other half of the line buffer.
|
||||||
void DCMI_DMAConvCpltUser(uint32_t addr)
|
void DCMI_DMAConvCpltUser(uint32_t addr)
|
||||||
{
|
{
|
||||||
|
if (!first_line) {
|
||||||
|
first_line = true;
|
||||||
|
uint32_t tick = HAL_GetTick();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop_frame) {
|
||||||
|
// If we're dropping a frame in full offload mode it's safe to disable this interrupt saving
|
||||||
|
// ourselves from having to service the DMA complete callback.
|
||||||
|
#if (OMV_ENABLE_SENSOR_MDMA_TOTAL_OFFLOAD == 1)
|
||||||
|
if (!sensor.transpose) {
|
||||||
|
HAL_NVIC_DisableIRQ(DMA2_Stream1_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
||||||
|
|
||||||
// If snapshot was not already waiting to receive data then we have missed this frame and have
|
// If snapshot was not already waiting to receive data then we have missed this frame and have
|
||||||
@ -1315,6 +1379,10 @@ void DCMI_DMAConvCpltUser(uint32_t addr)
|
|||||||
#endif
|
#endif
|
||||||
__HAL_DCMI_DISABLE_IT(&DCMIHandle, DCMI_IT_FRAME);
|
__HAL_DCMI_DISABLE_IT(&DCMIHandle, DCMI_IT_FRAME);
|
||||||
__HAL_DCMI_CLEAR_FLAG(&DCMIHandle, DCMI_FLAG_FRAMERI);
|
__HAL_DCMI_CLEAR_FLAG(&DCMIHandle, DCMI_FLAG_FRAMERI);
|
||||||
|
first_line = false;
|
||||||
|
drop_frame = false;
|
||||||
|
sensor.last_frame_ms = 0;
|
||||||
|
sensor.last_frame_ms_valid = false;
|
||||||
// Reset the queue of frames when we start dropping frames.
|
// Reset the queue of frames when we start dropping frames.
|
||||||
if (!sensor.disable_full_flush) {
|
if (!sensor.disable_full_flush) {
|
||||||
framebuffer_flush_buffers();
|
framebuffer_flush_buffers();
|
||||||
|
|||||||
@ -49,15 +49,15 @@ static const uint16_t default_regs[][2] = {
|
|||||||
{0x3064, 0x00},
|
{0x3064, 0x00},
|
||||||
{0x3065, 0x04}, // pad pull 0
|
{0x3065, 0x04}, // pad pull 0
|
||||||
{ANA_Register_17, 0x00}, // Disable internal oscillator
|
{ANA_Register_17, 0x00}, // Disable internal oscillator
|
||||||
|
|
||||||
{BLC_CFG, 0x43}, // BLC_on, IIR
|
{BLC_CFG, 0x43}, // BLC_on, IIR
|
||||||
|
|
||||||
{0x1001, 0x43}, // BLC dithering en
|
{0x1001, 0x43}, // BLC dithering en
|
||||||
{0x1002, 0x43}, // blc_darkpixel_thd
|
{0x1002, 0x43}, // blc_darkpixel_thd
|
||||||
{0x0350, 0x7F}, // Dgain Control
|
{0x0350, 0x7F}, // Dgain Control
|
||||||
{BLI_EN, 0x01}, // BLI enable
|
{BLI_EN, 0x01}, // BLI enable
|
||||||
{0x1003, 0x00}, // BLI Target [Def: 0x20]
|
{0x1003, 0x00}, // BLI Target [Def: 0x20]
|
||||||
|
|
||||||
{DPC_CTRL, 0x01}, // DPC option 0: DPC off 1 : mono 3 : bayer1 5 : bayer2
|
{DPC_CTRL, 0x01}, // DPC option 0: DPC off 1 : mono 3 : bayer1 5 : bayer2
|
||||||
{0x1009, 0xA0}, // cluster hot pixel th
|
{0x1009, 0xA0}, // cluster hot pixel th
|
||||||
{0x100A, 0x60}, // cluster cold pixel th
|
{0x100A, 0x60}, // cluster cold pixel th
|
||||||
@ -77,7 +77,7 @@ static const uint16_t default_regs[][2] = {
|
|||||||
{0x2014, 0x58},
|
{0x2014, 0x58},
|
||||||
{0x2017, 0x00},
|
{0x2017, 0x00},
|
||||||
{0x2018, 0x9B},
|
{0x2018, 0x9B},
|
||||||
|
|
||||||
{AE_CTRL, 0x01}, //Automatic Exposure
|
{AE_CTRL, 0x01}, //Automatic Exposure
|
||||||
{AE_TARGET_MEAN, 0x64}, //AE target mean [Def: 0x3C]
|
{AE_TARGET_MEAN, 0x64}, //AE target mean [Def: 0x3C]
|
||||||
{AE_MIN_MEAN, 0x0A}, //AE min target mean [Def: 0x0A]
|
{AE_MIN_MEAN, 0x0A}, //AE min target mean [Def: 0x0A]
|
||||||
@ -88,16 +88,16 @@ static const uint16_t default_regs[][2] = {
|
|||||||
{MAX_AGAIN_FULL, 0x04}, //Maximum Analog gain in full frame mode [Def: 0x03]
|
{MAX_AGAIN_FULL, 0x04}, //Maximum Analog gain in full frame mode [Def: 0x03]
|
||||||
{MAX_AGAIN_BIN2, 0x04}, //Maximum Analog gain in bin2 mode [Def: 0x04]
|
{MAX_AGAIN_BIN2, 0x04}, //Maximum Analog gain in bin2 mode [Def: 0x04]
|
||||||
{MAX_DGAIN, 0xC0},
|
{MAX_DGAIN, 0xC0},
|
||||||
|
|
||||||
{INTEGRATION_H, 0x01}, //Integration H [Def: 0x01]
|
{INTEGRATION_H, 0x01}, //Integration H [Def: 0x01]
|
||||||
{INTEGRATION_L, 0x08}, //Integration L [Def: 0x08]
|
{INTEGRATION_L, 0x08}, //Integration L [Def: 0x08]
|
||||||
{ANALOG_GAIN, 0x00}, //Analog Global Gain [Def: 0x00]
|
{ANALOG_GAIN, 0x00}, //Analog Global Gain [Def: 0x00]
|
||||||
{DAMPING_FACTOR, 0x20}, //Damping Factor [Def: 0x20]
|
{DAMPING_FACTOR, 0x20}, //Damping Factor [Def: 0x20]
|
||||||
{DIGITAL_GAIN_H, 0x01}, //Digital Gain High [Def: 0x01]
|
{DIGITAL_GAIN_H, 0x01}, //Digital Gain High [Def: 0x01]
|
||||||
{DIGITAL_GAIN_L, 0x00}, //Digital Gain Low [Def: 0x00]
|
{DIGITAL_GAIN_L, 0x00}, //Digital Gain Low [Def: 0x00]
|
||||||
|
|
||||||
{FS_CTRL, 0x00}, //Flicker Control
|
{FS_CTRL, 0x00}, //Flicker Control
|
||||||
|
|
||||||
{FS_60HZ_H, 0x00},
|
{FS_60HZ_H, 0x00},
|
||||||
{FS_60HZ_L, 0x3C},
|
{FS_60HZ_L, 0x3C},
|
||||||
{FS_50HZ_H, 0x00},
|
{FS_50HZ_H, 0x00},
|
||||||
@ -148,7 +148,7 @@ static int reset(sensor_t *sensor)
|
|||||||
|
|
||||||
// Set PCLK polarity.
|
// Set PCLK polarity.
|
||||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, PCLK_POLARITY, (0x20 | PCLK_FALLING_EDGE));
|
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, PCLK_POLARITY, (0x20 | PCLK_FALLING_EDGE));
|
||||||
|
|
||||||
// Set mode to streaming
|
// Set mode to streaming
|
||||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MODE_SELECT, HIMAX_MODE_STREAMING);
|
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MODE_SELECT, HIMAX_MODE_STREAMING);
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
|||||||
default:
|
default:
|
||||||
if (w>320 || h>320)
|
if (w>320 || h>320)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -275,22 +275,14 @@ static int set_framerate(sensor_t *sensor, int framerate)
|
|||||||
highres = true;
|
highres = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (framerate) {
|
if (framerate <= 15) {
|
||||||
case 15:
|
osc_div = (highres == true) ? 0x01 : 0x00;
|
||||||
osc_div = (highres == true) ? 0x01 : 0x00;
|
} else if (framerate <= 30) {
|
||||||
break;
|
osc_div = (highres == true) ? 0x02 : 0x01;
|
||||||
case 30:
|
} else if (framerate <= 60) {
|
||||||
osc_div = (highres == true) ? 0x02 : 0x01;
|
osc_div = (highres == true) ? 0x03 : 0x02;
|
||||||
break;
|
} else {
|
||||||
case 60:
|
osc_div = 0x03; // Set to the max possible FPS at this resolution.
|
||||||
osc_div = (highres == true) ? 0x03 : 0x02;
|
|
||||||
break;
|
|
||||||
case 120:
|
|
||||||
// Set to the max possible FPS at this resolution.
|
|
||||||
osc_div = 0x03;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return cambus_writeb2(&sensor->bus, sensor->slv_addr, OSC_CLK_DIV, 0x08 | osc_div);
|
return cambus_writeb2(&sensor->bus, sensor->slv_addr, OSC_CLK_DIV, 0x08 | osc_div);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user