mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
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:
parent
262eb98e43
commit
ebc4c6c831
@ -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;
|
||||
}
|
||||
%}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
%}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.",
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user