ports/all: Add a sensor function to reconfigure hardware if/when needed.

sensor_dcmi_config function was called every time the pixel format changed,
and typically reconfigured the capture interface. This originated from the
stm32 port, which required reconfiguring the DCMI if the pixel format changed.
However, most ports only require configuring the capture interface once
during initialization (for example nrf, rp2 and mimxrt ports).
The new sensor_config function is called after a setting that may require
reconfiguring the hardware changes, such as such as window size, frame size,
or pixel format. The exact setting that has changed is passed to the function,
allowing ports to decide whether to do a full reconfiguration of the hardware,
or just ignore it based on the changed setting.
This commit is contained in:
iabdalkader 2024-02-12 17:32:31 +01:00
parent 262eb98e43
commit ebc4c6c831
7 changed files with 190 additions and 162 deletions

View File

@ -73,38 +73,39 @@ PIXEL_LOOP:
.wrap
% c-sdk {
int sensor_dcmi_config(uint32_t pixformat)
{
uint offset;
pio_sm_config config;
int sensor_config(sensor_config_t config) {
if (config == SENSOR_CONFIG_PIXFORMAT) {
uint offset;
pio_sm_config config;
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, false);
pio_sm_clear_fifos(OMV_CSI_PIO, OMV_CSI_SM);
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, false);
pio_sm_clear_fifos(OMV_CSI_PIO, OMV_CSI_SM);
for(uint i=OMV_CSI_D0_PIN; i<OMV_CSI_D0_PIN+7; i++) {
pio_gpio_init(OMV_CSI_PIO, i);
for(uint i=OMV_CSI_D0_PIN; i<OMV_CSI_D0_PIN+7; i++) {
pio_gpio_init(OMV_CSI_PIO, i);
}
pio_sm_set_consecutive_pindirs(OMV_CSI_PIO, OMV_CSI_SM, OMV_CSI_D0_PIN, 7, false);
if (sensor.pixformat == PIXFORMAT_GRAYSCALE) {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_odd_byte_program);
config = dcmi_odd_byte_program_get_default_config(offset);
} else {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_default_program);
config = dcmi_default_program_get_default_config(offset);
}
sm_config_set_clkdiv(&config, 1);
sm_config_set_in_pins(&config, OMV_CSI_D0_PIN);
gpio_init(OMV_CSI_D7_PIN);
gpio_set_dir(OMV_CSI_D7_PIN, GPIO_IN);
sm_config_set_jmp_pin(&config, OMV_CSI_D7_PIN);
sm_config_set_in_shift(&config, true, true, 32);
pio_sm_init(OMV_CSI_PIO, OMV_CSI_SM, offset, &config);
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, true);
}
pio_sm_set_consecutive_pindirs(OMV_CSI_PIO, OMV_CSI_SM, OMV_CSI_D0_PIN, 7, false);
if (pixformat == PIXFORMAT_GRAYSCALE) {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_odd_byte_program);
config = dcmi_odd_byte_program_get_default_config(offset);
} else {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_default_program);
config = dcmi_default_program_get_default_config(offset);
}
sm_config_set_clkdiv(&config, 1);
sm_config_set_in_pins(&config, OMV_CSI_D0_PIN);
gpio_init(OMV_CSI_D7_PIN);
gpio_set_dir(OMV_CSI_D7_PIN, GPIO_IN);
sm_config_set_jmp_pin(&config, OMV_CSI_D7_PIN);
sm_config_set_in_shift(&config, true, true, 32);
pio_sm_init(OMV_CSI_PIO, OMV_CSI_SM, offset, &config);
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, true);
return 0;
}
%}

View File

@ -57,32 +57,33 @@ PIXEL_LOOP:
.wrap
% c-sdk {
int sensor_dcmi_config(uint32_t pixformat)
{
uint offset;
pio_sm_config config;
int sensor_config(sensor_config_t config) {
if (config == SENSOR_CONFIG_PIXFORMAT) {
uint offset;
pio_sm_config config;
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, false);
pio_sm_clear_fifos(OMV_CSI_PIO, OMV_CSI_SM);
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, false);
pio_sm_clear_fifos(OMV_CSI_PIO, OMV_CSI_SM);
for(uint i=OMV_CSI_D0_PIN; i<OMV_CSI_D0_PIN+8; i++) {
pio_gpio_init(OMV_CSI_PIO, i);
for(uint i=OMV_CSI_D0_PIN; i<OMV_CSI_D0_PIN+8; i++) {
pio_gpio_init(OMV_CSI_PIO, i);
}
pio_sm_set_consecutive_pindirs(OMV_CSI_PIO, OMV_CSI_SM, OMV_CSI_D0_PIN, 8, false);
if (sensor.pixformat == PIXFORMAT_GRAYSCALE) {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_odd_byte_program);
config = dcmi_odd_byte_program_get_default_config(offset);
} else {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_default_program);
config = dcmi_default_program_get_default_config(offset);
}
sm_config_set_clkdiv(&config, 1);
sm_config_set_in_pins(&config, OMV_CSI_D0_PIN);
sm_config_set_in_shift(&config, true, true, 32);
pio_sm_init(OMV_CSI_PIO, OMV_CSI_SM, offset, &config);
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, true);
}
pio_sm_set_consecutive_pindirs(OMV_CSI_PIO, OMV_CSI_SM, OMV_CSI_D0_PIN, 8, false);
if (pixformat == PIXFORMAT_GRAYSCALE) {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_odd_byte_program);
config = dcmi_odd_byte_program_get_default_config(offset);
} else {
offset = pio_add_program(OMV_CSI_PIO, &dcmi_default_program);
config = dcmi_default_program_get_default_config(offset);
}
sm_config_set_clkdiv(&config, 1);
sm_config_set_in_pins(&config, OMV_CSI_D0_PIN);
sm_config_set_in_shift(&config, true, true, 32);
pio_sm_init(OMV_CSI_PIO, OMV_CSI_SM, offset, &config);
pio_sm_set_enabled(OMV_CSI_PIO, OMV_CSI_SM, true);
return 0;
}
%}

View File

@ -181,7 +181,7 @@ typedef enum {
SENSOR_ERROR_ISC_INIT_FAILED = -5,
SENSOR_ERROR_TIM_INIT_FAILED = -6,
SENSOR_ERROR_DMA_INIT_FAILED = -7,
SENSOR_ERROR_DCMI_INIT_FAILED = -8,
SENSOR_ERROR_CSI_INIT_FAILED = -8,
SENSOR_ERROR_IO_ERROR = -9,
SENSOR_ERROR_CAPTURE_FAILED = -10,
SENSOR_ERROR_CAPTURE_TIMEOUT = -11,
@ -196,20 +196,27 @@ typedef enum {
SENSOR_ERROR_JPEG_OVERFLOW = -20,
} sensor_error_t;
typedef enum {
SENSOR_CONFIG_INIT = (1 << 0),
SENSOR_CONFIG_FRAMESIZE = (1 << 1),
SENSOR_CONFIG_PIXFORMAT = (1 << 2),
SENSOR_CONFIG_WINDOWING = (1 << 3),
} sensor_config_t;
// Bayer patterns.
// NOTE: These must match the Bayer subformats in imlib.h
//
// BGGR matches the bayer pattern of BGBG... etc. coming out of the sensor.
// GRGR... etc.
// BGGR matches the bayer pattern of BGBG...
// GRGR...
//
// GBRG matches the bayer pattern of GBGB... etc. coming out of the sensor.
// RGRG... etc.
// GBRG matches the bayer pattern of GBGB...
// RGRG...
//
// GRBG matches the bayer pattern of GRGR... etc. coming out of the sensor.
// BGBG... etc.
// GRBG matches the bayer pattern of GRGR...
// BGBG...
//
// RGGB matches the bayer pattern of RGRG... etc. coming out of the sensor.
// GBGB... etc.
// RGGB matches the bayer pattern of RGRG...
// GBGB...
//
#define SENSOR_HW_FLAGS_BAYER_BGGR (SUBFORMAT_ID_BGGR)
#define SENSOR_HW_FLAGS_BAYER_GBRG (SUBFORMAT_ID_GBRG)
@ -324,8 +331,9 @@ int sensor_init();
// Detect and initialize the image sensor.
int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed);
// Configure DCMI hardware interface.
int sensor_dcmi_config(uint32_t pixformat);
// This function is called after a setting that may require reconfiguring
// the hardware changes, such as window size, frame size, or pixel format.
int sensor_config(sensor_config_t config);
// Abort frame capture and disable IRQs, DMA etc..
int sensor_abort(bool fifo_flush, bool in_irq);

View File

@ -457,6 +457,10 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed) {
return 0;
}
__weak int sensor_config(sensor_config_t config) {
return 0;
}
__weak int sensor_get_id() {
return sensor.chip_id_w;
}
@ -599,8 +603,8 @@ __weak int sensor_set_pixformat(pixformat_t pixformat) {
// Pickout a good buffer count for the user.
framebuffer_auto_adjust_buffers();
// Reconfigure the DCMI if needed.
return sensor_dcmi_config(pixformat);
// Reconfigure the hardware if needed.
return sensor_config(SENSOR_CONFIG_PIXFORMAT);
}
__weak int sensor_set_framesize(framesize_t framesize) {
@ -643,7 +647,8 @@ __weak int sensor_set_framesize(framesize_t framesize) {
// Pickout a good buffer count for the user.
framebuffer_auto_adjust_buffers();
return 0;
// Reconfigure the hardware if needed.
return sensor_config(SENSOR_CONFIG_FRAMESIZE);
}
__weak int sensor_set_framerate(int framerate) {
@ -752,7 +757,8 @@ __weak int sensor_set_windowing(int x, int y, int w, int h) {
// Pickout a good buffer count for the user.
framebuffer_auto_adjust_buffers();
return 0;
// Reconfigure the hardware if needed.
return sensor_config(SENSOR_CONFIG_WINDOWING);
}
__weak int sensor_set_contrast(int level) {
@ -1344,9 +1350,9 @@ const char *sensor_strerror(int error) {
"Failed to detect the image sensor or image sensor is detached.",
"The detected image sensor is not supported.",
"Failed to initialize the image sensor.",
"Failed to initialize the image sensor clock.",
"Failed to initialize the image sensor DMA.",
"Failed to initialize the image sensor DCMI.",
"Failed to initialize the external clock.",
"Failed to initialize the CSI DMA.",
"Failed to initialize the CSI interface.",
"An low level I/O error has occurred.",
"Frame capture has failed.",
"Frame capture has timed out.",

View File

@ -84,6 +84,12 @@ int sensor_init() {
return init_ret;
}
// Configure the CSI interface.
if (sensor_config(SENSOR_CONFIG_INIT) != 0) {
// CSI config failed
return SENSOR_ERROR_CSI_INIT_FAILED;
}
// Set default color palette.
sensor.color_palette = rainbow_table;
@ -99,40 +105,42 @@ int sensor_init() {
return 0;
}
int sensor_dcmi_config(uint32_t pixformat) {
CSI_Reset(CSI);
NVIC_DisableIRQ(CSI_IRQn);
int sensor_config(sensor_config_t config) {
if (config == SENSOR_CONFIG_INIT) {
CSI_Reset(CSI);
NVIC_DisableIRQ(CSI_IRQn);
// CSI_Reset does not zero CR1.
CSI_REG_CR1(CSI) = 0;
// CSI mode: HSYNC, VSYNC, and PIXCLK signals are used.
CSI_REG_CR1(CSI) |= CSI_CR1_GCLK_MODE(1U);
// Synchronous FIFO clear.
// RXFIFO and STATFIFO are cleared on every SOF.
CSI_REG_CR1(CSI) |= CSI_CR1_FCC_MASK;
// CSI_Reset does not zero CR1.
CSI_REG_CR1(CSI) = 0;
// CSI mode: HSYNC, VSYNC, and PIXCLK signals are used.
CSI_REG_CR1(CSI) |= CSI_CR1_GCLK_MODE(1U);
// Synchronous FIFO clear.
// RXFIFO and STATFIFO are cleared on every SOF.
CSI_REG_CR1(CSI) |= CSI_CR1_FCC_MASK;
// Configure VSYNC, HSYNC and PIXCLK signals.
CSI_REG_CR1(CSI) |= CSI_CR1_EXT_VSYNC_MASK;
CSI_REG_CR1(CSI) |= !sensor.hw_flags.vsync ? CSI_CR1_SOF_POL_MASK : 0;
CSI_REG_CR1(CSI) |= !sensor.hw_flags.hsync ? CSI_CR1_HSYNC_POL_MASK : 0;
CSI_REG_CR1(CSI) |= sensor.hw_flags.pixck ? CSI_CR1_REDGE_MASK : 0;
// Configure VSYNC, HSYNC and PIXCLK signals.
CSI_REG_CR1(CSI) |= CSI_CR1_EXT_VSYNC_MASK;
CSI_REG_CR1(CSI) |= !sensor.hw_flags.vsync ? CSI_CR1_SOF_POL_MASK : 0;
CSI_REG_CR1(CSI) |= !sensor.hw_flags.hsync ? CSI_CR1_HSYNC_POL_MASK : 0;
CSI_REG_CR1(CSI) |= sensor.hw_flags.pixck ? CSI_CR1_REDGE_MASK : 0;
// Stride config: No stride.
CSI_REG_FBUF_PARA(CSI) = 0;
// Reset frame counter
CSI_REG_CR3(CSI) |= CSI_CR3_FRMCNT_RST_MASK;
// Stride config: No stride.
CSI_REG_FBUF_PARA(CSI) = 0;
// Reset frame counter
CSI_REG_CR3(CSI) |= CSI_CR3_FRMCNT_RST_MASK;
// Configure CSI FIFO depth and DMA burst size.
CSI_REG_CR2(CSI) |= CSI_CR2_DMA_BURST_TYPE_RFF(3U);
CSI_REG_CR3(CSI) |= 7U << CSI_CR3_RxFF_LEVEL_SHIFT;
// Configure CSI FIFO depth and DMA burst size.
CSI_REG_CR2(CSI) |= CSI_CR2_DMA_BURST_TYPE_RFF(3U);
CSI_REG_CR3(CSI) |= 7U << CSI_CR3_RxFF_LEVEL_SHIFT;
// Configure DMA buffers.
CSI_REG_DMASA_FB1(CSI) = (uint32_t) (&_line_buf[OMV_LINE_BUF_SIZE * 0]);
CSI_REG_DMASA_FB2(CSI) = (uint32_t) (&_line_buf[OMV_LINE_BUF_SIZE / 2]);
// Configure DMA buffers.
CSI_REG_DMASA_FB1(CSI) = (uint32_t) (&_line_buf[OMV_LINE_BUF_SIZE * 0]);
CSI_REG_DMASA_FB2(CSI) = (uint32_t) (&_line_buf[OMV_LINE_BUF_SIZE / 2]);
// Write to memory from first completed frame.
// DMA CSI addr switch at dma transfer done.
CSI_REG_CR18(CSI) |= CSI_CR18_MASK_OPTION(0);
// Write to memory from first completed frame.
// DMA CSI addr switch at dma transfer done.
CSI_REG_CR18(CSI) |= CSI_CR18_MASK_OPTION(0);
}
return 0;
}

View File

@ -82,11 +82,10 @@ int sensor_init() {
return init_ret;
}
// Configure the DCMI interface.
if (sensor_dcmi_config(PIXFORMAT_INVALID) != 0) {
// DCMI config failed
return SENSOR_ERROR_DCMI_INIT_FAILED;
// Configure the CSI interface.
if (sensor_config(SENSOR_CONFIG_INIT) != 0) {
// CSI config failed
return SENSOR_ERROR_CSI_INIT_FAILED;
}
// Clear fb_enabled flag
@ -105,34 +104,36 @@ int sensor_init() {
return 0;
}
int sensor_dcmi_config(uint32_t pixformat) {
uint32_t dcmi_pins[] = {
OMV_CSI_D0_PIN,
OMV_CSI_D1_PIN,
OMV_CSI_D2_PIN,
OMV_CSI_D3_PIN,
OMV_CSI_D4_PIN,
OMV_CSI_D5_PIN,
OMV_CSI_D6_PIN,
OMV_CSI_D7_PIN,
OMV_CSI_VSYNC_PIN,
OMV_CSI_HSYNC_PIN,
OMV_CSI_PXCLK_PIN,
};
int sensor_config(sensor_config_t config) {
if (config == SENSOR_CONFIG_INIT) {
uint32_t csi_pins[] = {
OMV_CSI_D0_PIN,
OMV_CSI_D1_PIN,
OMV_CSI_D2_PIN,
OMV_CSI_D3_PIN,
OMV_CSI_D4_PIN,
OMV_CSI_D5_PIN,
OMV_CSI_D6_PIN,
OMV_CSI_D7_PIN,
OMV_CSI_VSYNC_PIN,
OMV_CSI_HSYNC_PIN,
OMV_CSI_PXCLK_PIN,
};
// Configure DCMI input pins
for (int i = 0; i < sizeof(dcmi_pins) / sizeof(dcmi_pins[0]); i++) {
nrf_gpio_cfg_input(dcmi_pins[i], NRF_GPIO_PIN_PULLUP);
// Configure CSI input pins
for (int i = 0; i < sizeof(csi_pins) / sizeof(csi_pins[0]); i++) {
nrf_gpio_cfg_input(csi_pins[i], NRF_GPIO_PIN_PULLUP);
}
_vsyncMask = digitalPinToBitMask(OMV_CSI_VSYNC_PIN);
_hrefMask = digitalPinToBitMask(OMV_CSI_HSYNC_PIN);
_pclkMask = digitalPinToBitMask(OMV_CSI_PXCLK_PIN);
_vsyncPort = portInputRegister(digitalPinToPort(OMV_CSI_VSYNC_PIN));
_hrefPort = portInputRegister(digitalPinToPort(OMV_CSI_HSYNC_PIN));
_pclkPort = portInputRegister(digitalPinToPort(OMV_CSI_PXCLK_PIN));
}
_vsyncMask = digitalPinToBitMask(OMV_CSI_VSYNC_PIN);
_hrefMask = digitalPinToBitMask(OMV_CSI_HSYNC_PIN);
_pclkMask = digitalPinToBitMask(OMV_CSI_PXCLK_PIN);
_vsyncPort = portInputRegister(digitalPinToPort(OMV_CSI_VSYNC_PIN));
_hrefPort = portInputRegister(digitalPinToPort(OMV_CSI_HSYNC_PIN));
_pclkPort = portInputRegister(digitalPinToPort(OMV_CSI_PXCLK_PIN));
return 0;
}

View File

@ -159,9 +159,9 @@ int sensor_init() {
}
// Configure the DCMI interface.
if (sensor_dcmi_config(PIXFORMAT_INVALID) != 0) {
if (sensor_config(SENSOR_CONFIG_INIT) != 0) {
// DCMI config failed
return SENSOR_ERROR_DCMI_INIT_FAILED;
return SENSOR_ERROR_CSI_INIT_FAILED;
}
// Clear fb_enabled flag
@ -177,41 +177,44 @@ int sensor_init() {
return 0;
}
int sensor_dcmi_config(uint32_t pixformat) {
// VSYNC clock polarity
DCMIHandle.Init.VSPolarity = sensor.hw_flags.vsync ? DCMI_VSPOLARITY_HIGH : DCMI_VSPOLARITY_LOW;
// HSYNC clock polarity
DCMIHandle.Init.HSPolarity = sensor.hw_flags.hsync ? DCMI_HSPOLARITY_HIGH : DCMI_HSPOLARITY_LOW;
// PXCLK clock polarity
DCMIHandle.Init.PCKPolarity = sensor.hw_flags.pixck ? DCMI_PCKPOLARITY_RISING : DCMI_PCKPOLARITY_FALLING;
int sensor_config(sensor_config_t config) {
if (config == SENSOR_CONFIG_INIT) {
// VSYNC clock polarity
DCMIHandle.Init.VSPolarity = sensor.hw_flags.vsync ? DCMI_VSPOLARITY_HIGH : DCMI_VSPOLARITY_LOW;
// HSYNC clock polarity
DCMIHandle.Init.HSPolarity = sensor.hw_flags.hsync ? DCMI_HSPOLARITY_HIGH : DCMI_HSPOLARITY_LOW;
// PXCLK clock polarity
DCMIHandle.Init.PCKPolarity = sensor.hw_flags.pixck ? DCMI_PCKPOLARITY_RISING : DCMI_PCKPOLARITY_FALLING;
// Setup capture parameters.
DCMIHandle.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; // Enable Hardware synchronization
DCMIHandle.Init.CaptureRate = DCMI_CR_ALL_FRAME; // Capture rate all frames
DCMIHandle.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; // Capture 8 bits on every pixel clock
// Set JPEG Mode
DCMIHandle.Init.JPEGMode = (pixformat == PIXFORMAT_JPEG) ?
DCMI_JPEG_ENABLE : DCMI_JPEG_DISABLE;
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
DCMIHandle.Init.ByteSelectMode = DCMI_BSM_ALL; // Capture all received bytes
DCMIHandle.Init.ByteSelectStart = DCMI_OEBS_ODD; // Ignored
DCMIHandle.Init.LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
DCMIHandle.Init.LineSelectStart = DCMI_OELS_ODD; // Ignored
#endif
// Setup capture parameters.
DCMIHandle.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; // Enable Hardware synchronization
DCMIHandle.Init.CaptureRate = DCMI_CR_ALL_FRAME; // Capture rate all frames
DCMIHandle.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; // Capture 8 bits on every pixel clock
DCMIHandle.Init.JPEGMode = DCMI_JPEG_DISABLE;
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
DCMIHandle.Init.ByteSelectMode = DCMI_BSM_ALL; // Capture all received bytes
DCMIHandle.Init.ByteSelectStart = DCMI_OEBS_ODD; // Ignored
DCMIHandle.Init.LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
DCMIHandle.Init.LineSelectStart = DCMI_OELS_ODD; // Ignored
#endif
// Associate the DMA handle to the DCMI handle
__HAL_LINKDMA(&DCMIHandle, DMA_Handle, DMAHandle);
// Associate the DMA handle to the DCMI handle
__HAL_LINKDMA(&DCMIHandle, DMA_Handle, DMAHandle);
// Initialize the DCMI
HAL_DCMI_DeInit(&DCMIHandle);
if (HAL_DCMI_Init(&DCMIHandle) != HAL_OK) {
// Initialization Error
return -1;
// Initialize the DCMI
HAL_DCMI_DeInit(&DCMIHandle);
if (HAL_DCMI_Init(&DCMIHandle) != HAL_OK) {
// Initialization Error
return -1;
}
// Configure and enable DCMI IRQ Channel
NVIC_SetPriority(DCMI_IRQn, IRQ_PRI_DCMI);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
} else if (config == SENSOR_CONFIG_PIXFORMAT) {
DCMI->CR &= ~(DCMI_CR_JPEG_Msk << DCMI_CR_JPEG_Pos);
DCMI->CR |= (sensor.pixformat == PIXFORMAT_JPEG) ? DCMI_JPEG_ENABLE : DCMI_JPEG_DISABLE;
}
// Configure and enable DCMI IRQ Channel
NVIC_SetPriority(DCMI_IRQn, IRQ_PRI_DCMI);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
return 0;
}
@ -337,7 +340,7 @@ int sensor_shutdown(int enable) {
omv_gpio_write(OMV_CSI_POWER_PIN, 1);
}
#endif
ret = sensor_dcmi_config(sensor.pixformat);
ret = sensor_config(SENSOR_CONFIG_INIT);
}
mp_hal_delay_ms(10);