Merge pull request #1397 from openmv/cambus_alt

Allow boards to define an alternate cambus to scan.
This commit is contained in:
Ibrahim Abd Elkader 2021-07-16 00:16:51 +02:00 committed by GitHub
commit 78f4a03f6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 10 deletions

View File

@ -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;

View File

@ -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

View File

@ -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();