From f4a6c4003b8d6f1ba6fc3ade9f8a8c9d957053fe Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 15 Jul 2021 23:50:58 +0200 Subject: [PATCH] Allow boards to define an alternate cambus to scan. --- src/omv/ports/stm32/cambus.c | 12 ++++++--- src/omv/ports/stm32/sensor.c | 33 ++++++++++++++++++++----- src/omv/ports/stm32/stm32fxxx_hal_msp.c | 24 ++++++++++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/omv/ports/stm32/cambus.c b/src/omv/ports/stm32/cambus.c index f5c62bc63..2df9449a3 100644 --- a/src/omv/ports/stm32/cambus.c +++ b/src/omv/ports/stm32/cambus.c @@ -76,6 +76,7 @@ static const uint32_t cambus_timing[CAMBUS_SPEED_MAX] = { int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed) { bus->id = bus_id; + bus->speed = speed; bus->i2c = NULL; bus->initialized = false; bus->scl_pin = (omv_gpio_t) {0, 0}; @@ -116,8 +117,6 @@ int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed) if (speed < 0 || speed >= CAMBUS_SPEED_MAX) { return -1; - } else { - bus->speed = cambus_timing[speed]; } // Our code only knows about these two I2Cs instances. @@ -127,14 +126,19 @@ int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed) } else if (bus->i2c->Instance == ISC_I2C) { bus->scl_pin = (omv_gpio_t) {ISC_I2C_SCL_PIN, ISC_I2C_PORT}; bus->sda_pin = (omv_gpio_t) {ISC_I2C_SDA_PIN, ISC_I2C_PORT}; + #if defined(ISC_I2C_ALT) + } else if (bus->i2c->Instance == ISC_I2C_ALT) { + bus->scl_pin = (omv_gpio_t) {ISC_I2C_ALT_SCL_PIN, ISC_I2C_ALT_PORT}; + bus->sda_pin = (omv_gpio_t) {ISC_I2C_ALT_SDA_PIN, ISC_I2C_ALT_PORT}; + #endif } // Configure the I2C handle bus->i2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; #if !defined(STM32F4) - bus->i2c->Init.Timing = bus->speed; + bus->i2c->Init.Timing = cambus_timing[speed]; #else - bus->i2c->Init.ClockSpeed = bus->speed; + bus->i2c->Init.ClockSpeed = cambus_timing[speed]; bus->i2c->Init.DutyCycle = I2C_DUTYCYCLE_2; #endif bus->i2c->Init.DualAddressMode = I2C_DUALADDRESS_DISABLED; diff --git a/src/omv/ports/stm32/sensor.c b/src/omv/ports/stm32/sensor.c index 457b91047..7c2dd841e 100644 --- a/src/omv/ports/stm32/sensor.c +++ b/src/omv/ports/stm32/sensor.c @@ -24,6 +24,7 @@ #define DMA_MAX_XFER_SIZE_DBL ((DMA_MAX_XFER_SIZE)*2) #define DMA_LENGTH_ALIGNMENT (16) #define SENSOR_TIMEOUT_MS (3000) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) // Higher performance complete MDMA offload. #if (OMV_ENABLE_SENSOR_MDMA == 1) @@ -105,9 +106,12 @@ void sensor_init0() { sensor_abort(); - // Always reinit cambus after soft reset which could have terminated the cambus in the middle - // of an I2C read/write. - cambus_init(&sensor.bus, ISC_I2C_ID, ISC_I2C_SPEED); + // Re-init cambus to reset the bus state after soft reset, which + // could have interrupted the bus in the middle of a transfer. + if (sensor.bus.initialized) { + // Reinitialize the bus using the last used id and speed. + cambus_init(&sensor.bus, sensor.bus.id, sensor.bus.speed); + } // Disable VSYNC IRQ and callback sensor_set_vsync_callback(NULL); @@ -120,6 +124,14 @@ int sensor_init() { int init_ret = 0; + // List of cambus I2C buses to scan. + uint32_t buses[][2] = { + {ISC_I2C_ID, ISC_I2C_SPEED}, + #if defined(ISC_I2C_ALT) + {ISC_I2C_ALT_ID, ISC_I2C_ALT_SPEED}, + #endif + }; + // Reset the sesnor state memset(&sensor, 0, sizeof(sensor_t)); @@ -134,9 +146,18 @@ int sensor_init() } // Detect and initialize the image sensor. - if ((init_ret = sensor_probe_init(ISC_I2C_ID, ISC_I2C_SPEED)) != 0) { - // Sensor probe/init failed. - return init_ret; + for (uint32_t i=0, n_buses = ARRAY_SIZE(buses); i < n_buses; i++) { + uint32_t id = buses[i][0], speed = buses[i][1]; + if ((init_ret = sensor_probe_init(id, speed)) == 0) { + // Sensor was detected on the current bus. + break; + } + cambus_deinit(&sensor.bus); + // Scan the next bus or fail if this is the last one. + if ((i+1) == n_buses) { + // Sensor probe/init failed. + return init_ret; + } } // Configure the DCMI DMA Stream diff --git a/src/omv/ports/stm32/stm32fxxx_hal_msp.c b/src/omv/ports/stm32/stm32fxxx_hal_msp.c index 2f7be05d5..313423638 100644 --- a/src/omv/ports/stm32/stm32fxxx_hal_msp.c +++ b/src/omv/ports/stm32/stm32fxxx_hal_msp.c @@ -273,6 +273,24 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) GPIO_InitStructure.Pin = ISC_I2C_SDA_PIN; HAL_GPIO_Init(ISC_I2C_PORT, &GPIO_InitStructure); + #if defined(ISC_I2C_ALT) + } else if (hi2c->Instance == ISC_I2C_ALT) { + /* Enable I2C clock */ + ISC_I2C_ALT_CLK_ENABLE(); + + /* Configure ISC GPIOs */ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; + GPIO_InitStructure.Alternate = ISC_I2C_ALT_AF; + + GPIO_InitStructure.Pin = ISC_I2C_ALT_SCL_PIN; + HAL_GPIO_Init(ISC_I2C_ALT_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = ISC_I2C_ALT_SDA_PIN; + HAL_GPIO_Init(ISC_I2C_ALT_PORT, &GPIO_InitStructure); + #endif } else if (hi2c->Instance == FIR_I2C) { /* Enable I2C clock */ FIR_I2C_CLK_ENABLE(); @@ -299,6 +317,12 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) ISC_I2C_FORCE_RESET(); ISC_I2C_RELEASE_RESET(); ISC_I2C_CLK_DISABLE(); + #if defined(ISC_I2C_ALT) + } else if (hi2c->Instance == ISC_I2C_ALT) { + ISC_I2C_ALT_FORCE_RESET(); + ISC_I2C_ALT_RELEASE_RESET(); + ISC_I2C_ALT_CLK_DISABLE(); + #endif } else if (hi2c->Instance == FIR_I2C) { FIR_I2C_FORCE_RESET(); FIR_I2C_RELEASE_RESET();