mirror of
https://github.com/openmv/openmv.git
synced 2025-09-26 23:09:13 +08:00
Merge pull request #2746 from openmv/refactor_csi_port_init
Some checks failed
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Has been cancelled
🔥 Firmware Build / build-firmware (DOCKER) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV2) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV3) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV4) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_N6) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Has been cancelled
🔥 Firmware Build / code-size-report (push) Has been cancelled
🔥 Firmware Build / stable-release (push) Has been cancelled
🔥 Firmware Build / development-release (push) Has been cancelled
Some checks failed
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Has been cancelled
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Has been cancelled
🔥 Firmware Build / build-firmware (DOCKER) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV2) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV3) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV4) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_N6) (push) Has been cancelled
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Has been cancelled
🔥 Firmware Build / code-size-report (push) Has been cancelled
🔥 Firmware Build / stable-release (push) Has been cancelled
🔥 Firmware Build / development-release (push) Has been cancelled
ports/all: Refactor CSI port init.
This commit is contained in:
commit
ad751631a1
@ -119,6 +119,7 @@ uint16_t resolution[][2] = {
|
||||
{2592, 1944}, /* WQXGA2 */
|
||||
};
|
||||
|
||||
static omv_i2c_t csi_i2c;
|
||||
omv_csi_t csi_all[OMV_CSI_MAX_DEVICES] = {0};
|
||||
|
||||
__weak void omv_csi_init0() {
|
||||
@ -149,9 +150,73 @@ __weak void omv_csi_init0() {
|
||||
}
|
||||
|
||||
__weak int omv_csi_init() {
|
||||
// Reset the csi state
|
||||
memset(csi_all, 0, sizeof(csi_all));
|
||||
return OMV_CSI_ERROR_CTL_UNSUPPORTED;
|
||||
int ret = 0;
|
||||
|
||||
// List of I2C buses to scan.
|
||||
uint32_t buses[][2] = {
|
||||
{ OMV_CSI_I2C_ID, OMV_CSI_I2C_SPEED },
|
||||
#if defined(OMV_CSI_I2C_ALT_ID)
|
||||
{ OMV_CSI_I2C_ALT_ID, OMV_CSI_I2C_ALT_SPEED },
|
||||
#endif
|
||||
};
|
||||
|
||||
// Configure CSI GPIOs
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
omv_gpio_config(OMV_CSI_RESET_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_FSYNC_PIN)
|
||||
omv_gpio_config(OMV_CSI_FSYNC_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
omv_gpio_config(OMV_CSI_POWER_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
|
||||
// Initialize the CSIs using the port's ops as defaults,
|
||||
// which can be overridden by sensor drivers during probe.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
memset(csi, 0, sizeof(omv_csi_t));
|
||||
csi->i2c = &csi_i2c;
|
||||
csi->fb = framebuffer_get(-1);
|
||||
csi->color_palette = rainbow_table;
|
||||
omv_csi_ops_init(csi);
|
||||
}
|
||||
|
||||
// Configure the csi external clock (XCLK).
|
||||
if (omv_csi_set_clk_frequency(OMV_CSI_CLK_FREQUENCY) != 0) {
|
||||
return OMV_CSI_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
|
||||
// Detect and initialize sensor(s).
|
||||
for (uint32_t i=0, n_buses=OMV_ARRAY_SIZE(buses); i<n_buses; i++) {
|
||||
// Initialize the camera bus.
|
||||
omv_i2c_init(&csi_i2c, buses[i][0], buses[i][1]);
|
||||
|
||||
if (!(ret = omv_csi_probe(&csi_i2c))) {
|
||||
break;
|
||||
}
|
||||
|
||||
omv_i2c_deinit(&csi_i2c);
|
||||
|
||||
// Scan the next bus or fail if this is the last one.
|
||||
if ((i + 1) == n_buses) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Configure the DCMI interface.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
if (omv_csi_config(csi, OMV_CSI_CONFIG_INIT) != 0) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear fb_enabled flag.
|
||||
JPEG_FB()->enabled = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
omv_csi_t *omv_csi_get(int id) {
|
||||
|
@ -400,6 +400,9 @@ void omv_csi_init0();
|
||||
// Initializes CSI struct with default ops.
|
||||
int omv_csi_init();
|
||||
|
||||
// Implemented by ports to set the default CSI ops.
|
||||
int omv_csi_ops_init(omv_csi_t *csi);
|
||||
|
||||
// Return CSI instance.
|
||||
// If id == -1, return the main csi, otherwise look up csi by chip-id.
|
||||
omv_csi_t *omv_csi_get(int id);
|
||||
|
@ -103,6 +103,11 @@ void alif_hal_init(void) {
|
||||
// Configure and enable USB IRQs.
|
||||
NVIC_ClearPendingIRQ(USB_IRQ_IRQn);
|
||||
NVIC_SetPriority(USB_IRQ_IRQn, IRQ_PRI_USB);
|
||||
|
||||
#if MICROPY_PY_CSI
|
||||
// Enable CSI clock and configure pins.
|
||||
alif_hal_csi_init(OMV_CSI_BASE);
|
||||
#endif
|
||||
}
|
||||
|
||||
int alif_hal_i2c_init(uint32_t bus_id) {
|
||||
@ -364,14 +369,15 @@ int alif_hal_pdm_deinit(uint32_t pdm_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alif_hal_csi_init(CPI_Type *cpi, uint32_t mode) {
|
||||
if (mode == 0) {
|
||||
int alif_hal_csi_init(CPI_Type *cpi) {
|
||||
// Enable CPI clock.
|
||||
if (cpi == ((CPI_Type *) CPI_BASE)) {
|
||||
enable_cpi_periph_clk();
|
||||
} else {
|
||||
enable_lpcpi_periph_clk();
|
||||
}
|
||||
|
||||
// Configure camera sensor interface pins
|
||||
// Configure CPI pins.
|
||||
omv_gpio_config(OMV_CSI_D0_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_HIGH, -1);
|
||||
omv_gpio_config(OMV_CSI_D1_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_HIGH, -1);
|
||||
omv_gpio_config(OMV_CSI_D2_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_HIGH, -1);
|
||||
@ -386,18 +392,6 @@ int alif_hal_csi_init(CPI_Type *cpi, uint32_t mode) {
|
||||
omv_gpio_config(OMV_CSI_PXCLK_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_HIGH, -1);
|
||||
omv_gpio_config(OMV_CSI_MXCLK_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_HIGH, -1);
|
||||
|
||||
// Configure DCMI GPIOs
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
omv_gpio_config(OMV_CSI_RESET_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_DOWN, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_FSYNC_PIN)
|
||||
omv_gpio_config(OMV_CSI_FSYNC_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_DOWN, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
omv_gpio_config(OMV_CSI_POWER_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_UP, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
|
||||
NVIC_SetPriority(CAM_IRQ_IRQn, IRQ_PRI_CSI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -40,5 +40,5 @@ int alif_hal_spi_init(uint32_t bus_id, bool nss_enable, uint32_t nss_pol);
|
||||
int alif_hal_spi_deinit(uint32_t bus_id);
|
||||
int alif_hal_pdm_init(uint32_t pdm_id);
|
||||
int alif_hal_pdm_deinit(uint32_t pdm_id);
|
||||
int alif_hal_csi_init(CPI_Type *cpi, uint32_t mode);
|
||||
int alif_hal_csi_init(CPI_Type *cpi);
|
||||
#endif //__ALIF_HAL_H__
|
||||
|
@ -71,6 +71,66 @@
|
||||
CAM_INTR_OUTFIFO_OVERRUN | \
|
||||
CAM_INTR_BRESP_ERR)
|
||||
|
||||
static uint32_t omv_csi_get_fb_offset(omv_csi_t *csi);
|
||||
|
||||
void CAM_IRQHandler(void) {
|
||||
uint32_t mask = 0;
|
||||
omv_csi_t *csi = omv_csi_get(-1);
|
||||
CPI_Type *cpi = csi->base;
|
||||
|
||||
uint32_t status = cpi_get_interrupt_status(cpi);
|
||||
|
||||
if (status & CAM_INTR_VSYNC) {
|
||||
mask |= CAM_INTR_VSYNC;
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_HSYNC) {
|
||||
mask |= CAM_INTR_HSYNC;
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_INFIFO_OVERRUN) {
|
||||
mask |= CAM_INTR_INFIFO_OVERRUN;
|
||||
omv_csi_abort(csi, true, true);
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_OUTFIFO_OVERRUN) {
|
||||
mask |= CAM_INTR_OUTFIFO_OVERRUN;
|
||||
omv_csi_abort(csi, true, true);
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_BRESP_ERR) {
|
||||
mask |= CAM_INTR_BRESP_ERR;
|
||||
omv_csi_abort(csi, true, true);
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_STOP) {
|
||||
mask |= CAM_INTR_STOP;
|
||||
cpi->CAM_CTRL = 0;
|
||||
if (!(status & CPI_ERROR_FLAGS)) {
|
||||
// Release the current framebuffer.
|
||||
framebuffer_get_tail(csi->fb, FB_NO_FLAGS);
|
||||
}
|
||||
|
||||
// Get the current framebuffer (or new tail).
|
||||
vbuffer_t *buffer = framebuffer_get_tail(csi->fb, FB_PEEK);
|
||||
|
||||
if (buffer != NULL) {
|
||||
cpi->CAM_CTRL = 0;
|
||||
cpi->CAM_CTRL = CAM_CTRL_SW_RESET;
|
||||
cpi->CAM_FRAME_ADDR = LocalToGlobal(buffer->data + omv_csi_get_fb_offset(csi));
|
||||
cpi_irq_handler_clear_intr_status(cpi, mask);
|
||||
cpi->CAM_CTRL = (CAM_CTRL_SNAPSHOT | CAM_CTRL_START | CAM_CTRL_FIFO_CLK_SEL);
|
||||
}
|
||||
|
||||
if (csi->frame_cb.fun && !(status & CPI_ERROR_FLAGS)) {
|
||||
csi->frame_cb.fun(csi->frame_cb.arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear interrupts.
|
||||
cpi_irq_handler_clear_intr_status(cpi, mask);
|
||||
}
|
||||
|
||||
int alif_csi_config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
if (config == OMV_CSI_CONFIG_INIT) {
|
||||
CPI_Type *cpi = csi->base;
|
||||
@ -235,13 +295,13 @@ int alif_csi_snapshot(omv_csi_t *csi, image_t *dst_image, uint32_t flags) {
|
||||
cpi_irq_handler_clear_intr_status(cpi, CPI_IRQ_FLAGS);
|
||||
cpi_enable_interrupt(cpi, CPI_IRQ_FLAGS);
|
||||
NVIC_ClearPendingIRQ(CAM_IRQ_IRQn);
|
||||
NVIC_SetPriority(CAM_IRQ_IRQn, IRQ_PRI_CSI);
|
||||
NVIC_EnableIRQ(CAM_IRQ_IRQn);
|
||||
|
||||
// Reset CSI and start the capture.
|
||||
cpi->CAM_CTRL = 0;
|
||||
cpi->CAM_CTRL |= CAM_CTRL_SW_RESET;
|
||||
cpi->CAM_CTRL = CAM_CTRL_SW_RESET;
|
||||
cpi->CAM_CTRL = (CAM_CTRL_SNAPSHOT | CAM_CTRL_START | CAM_CTRL_FIFO_CLK_SEL);
|
||||
//printf("==== reconfigured ===\n");
|
||||
}
|
||||
|
||||
// Let the camera know we want to trigger it now.
|
||||
@ -364,126 +424,11 @@ int alif_csi_snapshot(omv_csi_t *csi, image_t *dst_image, uint32_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omv_csi_init() {
|
||||
int init_ret = 0;
|
||||
static omv_i2c_t i2c;
|
||||
CPI_Type *base = ((CPI_Type *) CPI_BASE);
|
||||
|
||||
alif_hal_csi_init(base, 0);
|
||||
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 0);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
omv_gpio_write(OMV_CSI_RESET_PIN, 0);
|
||||
#endif
|
||||
|
||||
// Initialize the CSIs using this driver's ops as defaults,
|
||||
// which can be overridden by sensor drivers during probe.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
memset(csi, 0, sizeof(omv_csi_t));
|
||||
csi->i2c = &i2c;
|
||||
csi->fb = framebuffer_get(-1);
|
||||
csi->base = base;
|
||||
csi->abort = alif_csi_abort;
|
||||
csi->config = alif_csi_config;
|
||||
csi->snapshot = alif_csi_snapshot;
|
||||
csi->color_palette = rainbow_table;
|
||||
}
|
||||
|
||||
// Configure the CSI external clock.
|
||||
if (omv_csi_set_clk_frequency(OMV_CSI_CLK_FREQUENCY) != 0) {
|
||||
// Failed to initialize the csi clock.
|
||||
return OMV_CSI_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
|
||||
// Initialize the camera bus.
|
||||
omv_i2c_init(&i2c, OMV_CSI_I2C_ID, OMV_CSI_I2C_SPEED);
|
||||
|
||||
// Detect and initialize the image csi.
|
||||
if ((init_ret = omv_csi_probe(&i2c)) != 0) {
|
||||
// csi probe/init failed.
|
||||
return init_ret;
|
||||
}
|
||||
|
||||
// Configure the DCMI interface.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
if (omv_csi_config(csi, OMV_CSI_CONFIG_INIT) != 0) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
|
||||
csi->detected = true;
|
||||
}
|
||||
|
||||
// Clear fb_enabled flag.
|
||||
JPEG_FB()->enabled = 0;
|
||||
|
||||
int omv_csi_ops_init(omv_csi_t *csi) {
|
||||
csi->base = OMV_CSI_BASE;
|
||||
csi->abort = alif_csi_abort;
|
||||
csi->config = alif_csi_config;
|
||||
csi->snapshot = alif_csi_snapshot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CAM_IRQHandler(void) {
|
||||
uint32_t mask = 0;
|
||||
omv_csi_t *csi = omv_csi_get(-1);
|
||||
CPI_Type *cpi = csi->base;
|
||||
|
||||
uint32_t status = cpi_get_interrupt_status(cpi);
|
||||
|
||||
if (status & CAM_INTR_VSYNC) {
|
||||
mask |= CAM_INTR_VSYNC;
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_HSYNC) {
|
||||
mask |= CAM_INTR_HSYNC;
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_INFIFO_OVERRUN) {
|
||||
mask |= CAM_INTR_INFIFO_OVERRUN;
|
||||
omv_csi_abort(csi, true, true);
|
||||
printf("INFIFO_OVERRUN\n");
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_OUTFIFO_OVERRUN) {
|
||||
mask |= CAM_INTR_OUTFIFO_OVERRUN;
|
||||
omv_csi_abort(csi, true, true);
|
||||
printf("OUTFIFO_OVERRUN\n");
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_BRESP_ERR) {
|
||||
mask |= CAM_INTR_BRESP_ERR;
|
||||
omv_csi_abort(csi, true, true);
|
||||
printf("BRESP_ERR %lu\n", cpi->CAM_AXI_ERR_STAT);
|
||||
}
|
||||
|
||||
if (status & CAM_INTR_STOP) {
|
||||
mask |= CAM_INTR_STOP;
|
||||
cpi->CAM_CTRL = 0;
|
||||
if (!(status & CPI_ERROR_FLAGS)) {
|
||||
// Release the current framebuffer.
|
||||
framebuffer_get_tail(csi->fb, FB_NO_FLAGS);
|
||||
}
|
||||
|
||||
// Get the current framebuffer (or new tail).
|
||||
vbuffer_t *buffer = framebuffer_get_tail(csi->fb, FB_PEEK);
|
||||
|
||||
if (buffer != NULL) {
|
||||
cpi->CAM_CTRL = 0;
|
||||
cpi->CAM_CTRL |= CAM_CTRL_SW_RESET;
|
||||
cpi->CAM_FRAME_ADDR = LocalToGlobal(buffer->data + omv_csi_get_fb_offset(csi));
|
||||
cpi_irq_handler_clear_intr_status(cpi, mask);
|
||||
cpi->CAM_CTRL = (CAM_CTRL_SNAPSHOT | CAM_CTRL_START | CAM_CTRL_FIFO_CLK_SEL);
|
||||
}
|
||||
|
||||
if (csi->frame_cb.fun && !(status & CPI_ERROR_FLAGS)) {
|
||||
csi->frame_cb.fun(csi->frame_cb.arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear interrupts.
|
||||
cpi_irq_handler_clear_intr_status(cpi, mask);
|
||||
}
|
||||
#endif // MICROPY_PY_CSI
|
||||
|
@ -107,6 +107,11 @@ void mimxrt_hal_init() {
|
||||
edma_config_t edma_config = {0};
|
||||
EDMA_GetDefaultConfig(&edma_config);
|
||||
EDMA_Init(DMA0, &edma_config);
|
||||
|
||||
#if MICROPY_PY_CSI
|
||||
// Enable CSI clock and configure pins.
|
||||
mimxrt_hal_csi_init(CSI);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mimxrt_hal_bootloader() {
|
||||
@ -118,9 +123,10 @@ void mimxrt_hal_bootloader() {
|
||||
}
|
||||
|
||||
int mimxrt_hal_csi_init(CSI_Type *inst) {
|
||||
// Enable CSI clock.
|
||||
CLOCK_EnableClock(kCLOCK_Csi);
|
||||
|
||||
// Configure DCMI pins.
|
||||
// Configure CSI pins.
|
||||
omv_gpio_config(OMV_CSI_D0_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_MED, -1);
|
||||
omv_gpio_config(OMV_CSI_D1_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_MED, -1);
|
||||
omv_gpio_config(OMV_CSI_D2_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_MED, -1);
|
||||
@ -135,20 +141,6 @@ int mimxrt_hal_csi_init(CSI_Type *inst) {
|
||||
omv_gpio_config(OMV_CSI_VSYNC_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_MED, -1);
|
||||
omv_gpio_config(OMV_CSI_PXCLK_PIN, OMV_GPIO_MODE_ALT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_MED, -1);
|
||||
|
||||
// Configure DCMI GPIOs
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
omv_gpio_config(OMV_CSI_RESET_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_DOWN, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_FSYNC_PIN)
|
||||
omv_gpio_config(OMV_CSI_FSYNC_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_DOWN, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
omv_gpio_config(OMV_CSI_POWER_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_UP, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
|
||||
// Configure IRQ priority.
|
||||
NVIC_SetPriority(CSI_IRQn, IRQ_PRI_CSI);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,8 @@ extern uint8_t _line_buf[OMV_LINE_BUF_SIZE];
|
||||
|
||||
int imx_csi_config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
if (config == OMV_CSI_CONFIG_INIT) {
|
||||
// Reset and configure CSI.
|
||||
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.
|
||||
@ -94,8 +93,11 @@ int imx_csi_config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
}
|
||||
|
||||
static int imx_csi_abort(omv_csi_t *csi, bool fifo_flush, bool in_irq) {
|
||||
NVIC_DisableIRQ(CSI_IRQn);
|
||||
// Disable CSI interrupts.
|
||||
CSI_DisableInterrupts(CSI, CSI_IRQ_FLAGS);
|
||||
NVIC_DisableIRQ(CSI_IRQn);
|
||||
NVIC_ClearPendingIRQ(CSI_IRQn);
|
||||
|
||||
CSI_REG_CR3(CSI) &= ~CSI_CR3_DMA_REQ_EN_RFF_MASK;
|
||||
CSI_REG_CR18(CSI) &= ~CSI_CR18_CSI_ENABLE_MASK;
|
||||
csi->dest_inc = 0;
|
||||
@ -395,8 +397,10 @@ int imx_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
(dma_line_bytes << CSI_IMAG_PARA_IMAGE_WIDTH_SHIFT) |
|
||||
(1 << CSI_IMAG_PARA_IMAGE_HEIGHT_SHIFT);
|
||||
|
||||
// Configure and enable CSI interrupts.
|
||||
// Enable CSI interrupts.
|
||||
CSI_EnableInterrupts(CSI, CSI_IRQ_FLAGS);
|
||||
NVIC_ClearPendingIRQ(CSI_IRQn);
|
||||
NVIC_SetPriority(CSI_IRQn, IRQ_PRI_CSI);
|
||||
NVIC_EnableIRQ(CSI_IRQn);
|
||||
|
||||
// Enable CSI
|
||||
@ -499,60 +503,10 @@ int imx_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omv_csi_init() {
|
||||
int init_ret = 0;
|
||||
static omv_i2c_t i2c;
|
||||
|
||||
mimxrt_hal_csi_init(CSI);
|
||||
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 1);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
omv_gpio_write(OMV_CSI_RESET_PIN, 1);
|
||||
#endif
|
||||
|
||||
// Initialize the CSIs using this driver's ops as defaults,
|
||||
// which can be overridden by sensor drivers during probe.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
memset(csi, 0, sizeof(omv_csi_t));
|
||||
csi->i2c = &i2c;
|
||||
csi->fb = framebuffer_get(-1);
|
||||
csi->abort = imx_csi_abort;
|
||||
csi->config = imx_csi_config;
|
||||
csi->snapshot = imx_csi_snapshot;
|
||||
csi->color_palette = rainbow_table;
|
||||
}
|
||||
|
||||
// Configure the csi external clock (XCLK).
|
||||
if (omv_csi_set_clk_frequency(OMV_CSI_CLK_FREQUENCY) != 0) {
|
||||
// Failed to initialize the csi clock.
|
||||
return OMV_CSI_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
|
||||
// Initialize the camera bus.
|
||||
omv_i2c_init(&i2c, OMV_CSI_I2C_ID, OMV_CSI_I2C_SPEED);
|
||||
|
||||
// Detect and initialize the image sensor.
|
||||
if ((init_ret = omv_csi_probe(&i2c)) != 0) {
|
||||
// Sensor probe/init failed.
|
||||
return init_ret;
|
||||
}
|
||||
|
||||
// Configure the CSI interfaces.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
if (omv_csi_config(csi, OMV_CSI_CONFIG_INIT) != 0) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear fb_enabled flag.
|
||||
JPEG_FB()->enabled = 0;
|
||||
int omv_csi_ops_init(omv_csi_t *csi) {
|
||||
csi->abort = imx_csi_abort;
|
||||
csi->config = imx_csi_config;
|
||||
csi->snapshot = imx_csi_snapshot;
|
||||
return 0;
|
||||
}
|
||||
#endif // MICROPY_PY_CSI
|
||||
|
@ -91,13 +91,19 @@
|
||||
#include "omv_csi.h"
|
||||
#include "mp_utils.h"
|
||||
|
||||
extern uint32_t _heap_start;
|
||||
extern uint32_t _heap_end;
|
||||
|
||||
uint32_t HAL_GetHalVersion() {
|
||||
// Hard-coded because it's not defined in SDK
|
||||
return ((2 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
|
||||
}
|
||||
|
||||
extern uint32_t _heap_start;
|
||||
extern uint32_t _heap_end;
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE
|
||||
static int vfs_mount_and_chdir(mp_obj_t bdev, mp_obj_t mount_point) {
|
||||
@ -142,6 +148,7 @@ soft_reset:
|
||||
machine_init();
|
||||
mp_init();
|
||||
readline_init0();
|
||||
pin_init0();
|
||||
#if MICROPY_PY_MACHINE_SPI
|
||||
spi_init0();
|
||||
#endif
|
||||
@ -163,13 +170,20 @@ soft_reset:
|
||||
#if MICROPY_PY_MACHINE_UART
|
||||
uart_init0();
|
||||
#endif
|
||||
pin_init0();
|
||||
|
||||
fb_alloc_init0();
|
||||
framebuffer_init0();
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_init0();
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_init();
|
||||
// Initialize the csi.
|
||||
if (first_soft_reset) {
|
||||
int ret = omv_csi_init();
|
||||
if (ret != 0 && ret != OMV_CSI_ERROR_ISC_UNDETECTED) {
|
||||
__fatal_error("Failed to init the CSI");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (MICROPY_PY_BLE_NUS == 0) && (MICROPY_HW_USB_CDC == 0)
|
||||
@ -372,7 +386,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
void HardFault_Handler(void) {
|
||||
#if defined(NRF52_SERIES) || defined(NRF91_SERIES)
|
||||
static volatile uint32_t reg;
|
||||
@ -389,12 +402,6 @@ void HardFault_Handler(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
printf("FATAL: uncaught exception %p\n", val);
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t) val);
|
||||
|
@ -206,60 +206,8 @@ static int nrf_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omv_csi_init() {
|
||||
int init_ret = 0;
|
||||
static omv_i2c_t i2c;
|
||||
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
nrf_gpio_cfg_output(OMV_CSI_POWER_PIN);
|
||||
nrf_gpio_pin_write(OMV_CSI_POWER_PIN, 1);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
nrf_gpio_cfg_output(OMV_CSI_RESET_PIN);
|
||||
nrf_gpio_pin_write(OMV_CSI_RESET_PIN, 1);
|
||||
#endif
|
||||
|
||||
// Initialize the CSIs using this driver's ops as defaults,
|
||||
// which can be overridden by sensor drivers during probe.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
memset(csi, 0, sizeof(omv_csi_t));
|
||||
csi->i2c = &i2c;
|
||||
csi->fb = framebuffer_get(-1);
|
||||
csi->abort = NULL;
|
||||
csi->config = nrf_csi_config;
|
||||
csi->snapshot = nrf_csi_snapshot;
|
||||
csi->color_palette = rainbow_table;
|
||||
}
|
||||
|
||||
// Configure the csi external clock (XCLK).
|
||||
if (omv_csi_set_clk_frequency(OMV_CSI_CLK_FREQUENCY) != 0) {
|
||||
// Failed to initialize the csi clock.
|
||||
return OMV_CSI_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
|
||||
// Initialize the camera bus.
|
||||
omv_i2c_init(&i2c, OMV_CSI_I2C_ID, OMV_CSI_I2C_SPEED);
|
||||
|
||||
// Detect and initialize the image sensor.
|
||||
if ((init_ret = omv_csi_probe(&i2c)) != 0) {
|
||||
// Sensor probe/init failed.
|
||||
return init_ret;
|
||||
}
|
||||
|
||||
// Configure the CSI interfaces.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
if (omv_csi_config(csi, OMV_CSI_CONFIG_INIT) != 0) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear fb_enabled flag
|
||||
JPEG_FB()->enabled = 0;
|
||||
|
||||
int omv_csi_ops_init(omv_csi_t *csi) {
|
||||
csi->config = nrf_csi_config;
|
||||
csi->snapshot = nrf_csi_snapshot;
|
||||
return 0;
|
||||
}
|
||||
|
@ -179,14 +179,21 @@ soft_reset:
|
||||
|
||||
fb_alloc_init0();
|
||||
framebuffer_init0();
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_init0();
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_FIR
|
||||
py_fir_init0();
|
||||
#endif // MICROPY_PY_FIR
|
||||
|
||||
#if MICROPY_PY_CSI
|
||||
if (omv_csi_init() != 0) {
|
||||
printf("csi init failed!\n");
|
||||
// Initialize the csi.
|
||||
if (first_soft_reset) {
|
||||
int ret = omv_csi_init();
|
||||
if (ret != 0 && ret != OMV_CSI_ERROR_ISC_UNDETECTED) {
|
||||
__fatal_error("Failed to init the CSI");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -68,6 +68,18 @@ static void dma_irq_handler() {
|
||||
|
||||
static int rp2_csi_config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
if (config == OMV_CSI_CONFIG_INIT) {
|
||||
// PIXCLK
|
||||
gpio_init(OMV_CSI_PXCLK_PIN);
|
||||
gpio_set_dir(OMV_CSI_PXCLK_PIN, GPIO_IN);
|
||||
|
||||
// HSYNC
|
||||
gpio_init(OMV_CSI_HSYNC_PIN);
|
||||
gpio_set_dir(OMV_CSI_HSYNC_PIN, GPIO_IN);
|
||||
|
||||
// VSYNC
|
||||
gpio_init(OMV_CSI_VSYNC_PIN);
|
||||
gpio_set_dir(OMV_CSI_VSYNC_PIN, GPIO_IN);
|
||||
|
||||
// Install new DMA IRQ handler.
|
||||
irq_set_enabled(OMV_CSI_DMA_IRQ, false);
|
||||
|
||||
@ -213,76 +225,10 @@ static int rp2_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omv_csi_init() {
|
||||
int init_ret = 0;
|
||||
static omv_i2c_t i2c;
|
||||
|
||||
// PIXCLK
|
||||
gpio_init(OMV_CSI_PXCLK_PIN);
|
||||
gpio_set_dir(OMV_CSI_PXCLK_PIN, GPIO_IN);
|
||||
|
||||
// HSYNC
|
||||
gpio_init(OMV_CSI_HSYNC_PIN);
|
||||
gpio_set_dir(OMV_CSI_HSYNC_PIN, GPIO_IN);
|
||||
|
||||
// VSYNC
|
||||
gpio_init(OMV_CSI_VSYNC_PIN);
|
||||
gpio_set_dir(OMV_CSI_VSYNC_PIN, GPIO_IN);
|
||||
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
gpio_init(OMV_CSI_POWER_PIN);
|
||||
gpio_set_dir(OMV_CSI_POWER_PIN, GPIO_OUT);
|
||||
gpio_pull_down(OMV_CSI_POWER_PIN);
|
||||
gpio_put(OMV_CSI_POWER_PIN, 1);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
gpio_init(OMV_CSI_RESET_PIN);
|
||||
gpio_set_dir(OMV_CSI_RESET_PIN, GPIO_OUT);
|
||||
gpio_pull_up(OMV_CSI_RESET_PIN);
|
||||
gpio_put(OMV_CSI_RESET_PIN, 1);
|
||||
#endif
|
||||
|
||||
// Initialize the CSIs using this driver's ops as defaults,
|
||||
// which can be overridden by sensor drivers during probe.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
memset(csi, 0, sizeof(omv_csi_t));
|
||||
csi->i2c = &i2c;
|
||||
csi->fb = framebuffer_get(-1);
|
||||
csi->abort = rp2_csi_abort;
|
||||
csi->config = rp2_csi_config;
|
||||
csi->snapshot = rp2_csi_snapshot;
|
||||
csi->color_palette = rainbow_table;
|
||||
}
|
||||
|
||||
// Configure the csi external clock (XCLK).
|
||||
if (omv_csi_set_clk_frequency(OMV_CSI_CLK_FREQUENCY) != 0) {
|
||||
// Failed to initialize the csi clock.
|
||||
return OMV_CSI_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
|
||||
// Initialize the camera bus.
|
||||
omv_i2c_init(&i2c, OMV_CSI_I2C_ID, OMV_CSI_I2C_SPEED);
|
||||
|
||||
// Detect and initialize the image sensor.
|
||||
if ((init_ret = omv_csi_probe(&i2c)) != 0) {
|
||||
// Sensor probe/init failed.
|
||||
return init_ret;
|
||||
}
|
||||
|
||||
// Configure the DCMI interface.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
if (omv_csi_config(csi, OMV_CSI_CONFIG_INIT) != 0) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear fb_enabled flag.
|
||||
JPEG_FB()->enabled = 0;
|
||||
int omv_csi_ops_init(omv_csi_t *csi) {
|
||||
csi->abort = rp2_csi_abort;
|
||||
csi->config = rp2_csi_config;
|
||||
csi->snapshot = rp2_csi_snapshot;
|
||||
return 0;
|
||||
}
|
||||
#endif // MICROPY_PY_CSI
|
||||
|
@ -1067,65 +1067,10 @@ static int stm_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omv_csi_init() {
|
||||
int ret = 0;
|
||||
static omv_i2c_t i2c;
|
||||
|
||||
// List of I2C buses to scan.
|
||||
uint32_t buses[][2] = {
|
||||
{OMV_CSI_I2C_ID, OMV_CSI_I2C_SPEED},
|
||||
#if defined(OMV_CSI_I2C_ALT_ID)
|
||||
{OMV_CSI_I2C_ALT_ID, OMV_CSI_I2C_ALT_SPEED},
|
||||
#endif
|
||||
};
|
||||
|
||||
// Initialize the CSIs using this driver's ops as defaults,
|
||||
// which can be overridden by sensor drivers during probe.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
memset(csi, 0, sizeof(omv_csi_t));
|
||||
csi->i2c = &i2c;
|
||||
csi->fb = framebuffer_get(-1);
|
||||
csi->abort = stm_csi_abort;
|
||||
csi->config = stm_csi_config;
|
||||
csi->shutdown = stm_csi_shutdown;
|
||||
csi->snapshot = stm_csi_snapshot;
|
||||
csi->color_palette = rainbow_table;
|
||||
}
|
||||
|
||||
// Configure the csi external clock (XCLK).
|
||||
if (omv_csi_set_clk_frequency(OMV_CSI_CLK_FREQUENCY) != 0) {
|
||||
return OMV_CSI_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
|
||||
// Detect and initialize sensor(s).
|
||||
for (uint32_t i = 0, n_buses = OMV_ARRAY_SIZE(buses); i < n_buses; i++) {
|
||||
// Initialize the camera bus.
|
||||
omv_i2c_init(&i2c, buses[i][0], buses[i][1]);
|
||||
|
||||
if (!(ret = omv_csi_probe(&i2c))) {
|
||||
break;
|
||||
}
|
||||
|
||||
omv_i2c_deinit(&i2c);
|
||||
|
||||
// Scan the next bus or fail if this is the last one.
|
||||
if ((i + 1) == n_buses) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Configure the DCMI interface.
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
if (omv_csi_config(csi, OMV_CSI_CONFIG_INIT) != 0) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear fb_enabled flag.
|
||||
JPEG_FB()->enabled = 0;
|
||||
int omv_csi_ops_init(omv_csi_t *csi) {
|
||||
csi->abort = stm_csi_abort;
|
||||
csi->config = stm_csi_config;
|
||||
csi->shutdown = stm_csi_shutdown;
|
||||
csi->snapshot = stm_csi_snapshot;
|
||||
return 0;
|
||||
}
|
||||
|
@ -271,16 +271,6 @@ void HAL_MspInit(void) {
|
||||
OMV_AXI_QOS_LTDC_W_SET(OMV_AXI_QOS_LTDC_W_PRI);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_CSI_RESET_PIN)
|
||||
omv_gpio_config(OMV_CSI_RESET_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_DOWN, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_FSYNC_PIN)
|
||||
omv_gpio_config(OMV_CSI_FSYNC_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_DOWN, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
omv_gpio_config(OMV_CSI_POWER_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_UP, OMV_GPIO_SPEED_LOW, -1);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_RESET_PIN)
|
||||
omv_gpio_config(OMV_FIR_LEPTON_RESET_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
|
||||
omv_gpio_write(OMV_FIR_LEPTON_RESET_PIN, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user