sensors/cambus: Support returning multiple devices from scan.

This commit is contained in:
iabdalkader 2022-03-12 00:03:25 +02:00
parent ef275cf29c
commit 2960a803cb
6 changed files with 42 additions and 19 deletions

View File

@ -46,7 +46,7 @@ typedef struct _cambus {
int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed); int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed);
int cambus_deinit(cambus_t *bus); int cambus_deinit(cambus_t *bus);
int cambus_scan(cambus_t *bus); int cambus_scan(cambus_t *bus, uint8_t *list, uint8_t size);
int cambus_enable(cambus_t *bus, bool enable); int cambus_enable(cambus_t *bus, bool enable);
int cambus_gencall(cambus_t *bus, uint8_t cmd); int cambus_gencall(cambus_t *bus, uint8_t cmd);
int cambus_pulse_scl(cambus_t *bus); int cambus_pulse_scl(cambus_t *bus);

View File

@ -201,7 +201,7 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed)
mp_hal_delay_ms(10); mp_hal_delay_ms(10);
// Probe the sensor // Probe the sensor
sensor.slv_addr = cambus_scan(&sensor.bus); sensor.slv_addr = cambus_scan(&sensor.bus, NULL, 0);
if (sensor.slv_addr == 0) { if (sensor.slv_addr == 0) {
/* Sensor has been held in reset, /* Sensor has been held in reset,
so the reset line is active low */ so the reset line is active low */
@ -212,21 +212,21 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed)
mp_hal_delay_ms(10); mp_hal_delay_ms(10);
// Probe again to set the slave addr. // Probe again to set the slave addr.
sensor.slv_addr = cambus_scan(&sensor.bus); sensor.slv_addr = cambus_scan(&sensor.bus, NULL, 0);
if (sensor.slv_addr == 0) { if (sensor.slv_addr == 0) {
sensor.pwdn_pol = ACTIVE_LOW; sensor.pwdn_pol = ACTIVE_LOW;
DCMI_PWDN_HIGH(); DCMI_PWDN_HIGH();
mp_hal_delay_ms(10); mp_hal_delay_ms(10);
sensor.slv_addr = cambus_scan(&sensor.bus); sensor.slv_addr = cambus_scan(&sensor.bus, NULL, 0);
if (sensor.slv_addr == 0) { if (sensor.slv_addr == 0) {
sensor.reset_pol = ACTIVE_HIGH; sensor.reset_pol = ACTIVE_HIGH;
DCMI_RESET_LOW(); DCMI_RESET_LOW();
mp_hal_delay_ms(10); mp_hal_delay_ms(10);
sensor.slv_addr = cambus_scan(&sensor.bus); sensor.slv_addr = cambus_scan(&sensor.bus, NULL, 0);
#ifndef OMV_ENABLE_NONI2CIS #ifndef OMV_ENABLE_NONI2CIS
if (sensor.slv_addr == 0) { if (sensor.slv_addr == 0) {
return SENSOR_ERROR_ISC_UNDETECTED; return SENSOR_ERROR_ISC_UNDETECTED;

View File

@ -317,7 +317,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
if (type == -1) { if (type == -1) {
FIR_SCAN_RETRY: FIR_SCAN_RETRY:
cambus_init(&fir_bus, FIR_I2C_ID, CAMBUS_SPEED_STANDARD); cambus_init(&fir_bus, FIR_I2C_ID, CAMBUS_SPEED_STANDARD);
switch (cambus_scan(&fir_bus)) { switch (cambus_scan(&fir_bus, NULL, 0)) {
#if (OMV_ENABLE_FIR_MLX90621 == 1) #if (OMV_ENABLE_FIR_MLX90621 == 1)
case (MLX90621_ADDR << 1): { case (MLX90621_ADDR << 1): {
type = FIR_MLX90621; type = FIR_MLX90621;

View File

@ -84,17 +84,24 @@ int cambus_deinit(cambus_t *bus)
return 0; return 0;
} }
int cambus_scan(cambus_t *bus) int cambus_scan(cambus_t *bus, uint8_t *list, uint8_t size)
{ {
int idx = 0;
uint8_t data; uint8_t data;
uint32_t xfer_flags = 0; uint32_t xfer_flags = 0;
for (uint8_t addr=0x09; addr<=0x77; addr++) { for (uint8_t addr=0x09; addr<=0x77; addr++) {
nrfx_twi_xfer_desc_t desc = NRFX_TWI_XFER_DESC_RX(addr, &data, 1); nrfx_twi_xfer_desc_t desc = NRFX_TWI_XFER_DESC_RX(addr, &data, 1);
if (nrfx_twi_xfer(&bus->i2c, &desc, xfer_flags) == NRFX_SUCCESS) { if (nrfx_twi_xfer(&bus->i2c, &desc, xfer_flags) == NRFX_SUCCESS) {
return (addr << 1); if (list == NULL || size == 0) {
return (addr << 1);
} else if (idx < size) {
list[idx++] = (addr << 1);
} else {
break;
}
} }
} }
return 0; return idx;
} }
int cambus_enable(cambus_t *bus, bool enable) int cambus_enable(cambus_t *bus, bool enable)

View File

@ -64,14 +64,21 @@ int cambus_deinit(cambus_t *bus)
return 0; return 0;
} }
int cambus_scan(cambus_t *bus) int cambus_scan(cambus_t *bus, uint8_t *list, uint8_t size)
{ {
for (uint8_t addr=0x20, rxdata; addr<=0x48; addr++) { int idx = 0;
for (uint8_t addr=0x20, rxdata; addr<=0x77; addr++) {
if (i2c_read_timeout_us(bus->i2c, addr, &rxdata, 1, false, I2C_SCAN_TIMEOUT) >= 0) { if (i2c_read_timeout_us(bus->i2c, addr, &rxdata, 1, false, I2C_SCAN_TIMEOUT) >= 0) {
return (addr << 1); if (list == NULL || size == 0) {
return (addr << 1);
} else if (idx < size) {
list[idx++] = (addr << 1);
} else {
break;
}
} }
} }
return 0; return idx;
} }
int cambus_enable(cambus_t *bus, bool enable) int cambus_enable(cambus_t *bus, bool enable)

View File

@ -261,21 +261,30 @@ int cambus_deinit(cambus_t *bus)
return 0; return 0;
} }
int cambus_scan(cambus_t *bus) int cambus_scan(cambus_t *bus, uint8_t *list, uint8_t size)
{ {
int idx = 0;
for (uint8_t addr=0x09; addr<=0x77; addr++) { for (uint8_t addr=0x09; addr<=0x77; addr++) {
if (HAL_I2C_IsDeviceReady(bus->i2c, addr << 1, 10, I2C_SCAN_TIMEOUT) == HAL_OK) { if (HAL_I2C_IsDeviceReady(bus->i2c, addr << 1, 10, I2C_SCAN_TIMEOUT) == HAL_OK) {
return (addr << 1); if (list == NULL || size == 0) {
return (addr << 1);
} else if (idx < size) {
list[idx++] = (addr << 1);
} else {
break;
}
} }
} }
#if defined(STM32H7) #if defined(STM32H7)
// After a failed scan the bus can get stuck. Re-initializing the bus fixes // After a failed scan the bus can get stuck. Re-initializing the bus fixes
// it, but it seems disabling and re-enabling the bus is all that's needed. // it, but it seems disabling and re-enabling the bus is all that's needed.
__HAL_I2C_DISABLE(bus->i2c); if (idx == 0) {
mp_hal_delay_ms(10); __HAL_I2C_DISABLE(bus->i2c);
__HAL_I2C_ENABLE(bus->i2c); mp_hal_delay_ms(10);
__HAL_I2C_ENABLE(bus->i2c);
}
#endif #endif
return 0; return idx;
} }
int cambus_enable(cambus_t *bus, bool enable) int cambus_enable(cambus_t *bus, bool enable)