Remove hard-coded cambus pins used for bus recovery.

This commit is contained in:
iabdalkader 2021-01-01 16:04:38 +02:00
parent dfe4aa81d9
commit f387f58053
4 changed files with 58 additions and 25 deletions

View File

@ -102,6 +102,18 @@
#define FIR_I2C_SDA_PIN (31)
#define FIR_I2C_SPEED (CAMBUS_SPEED_FULL)
// I2C0
#define TWI0_ID (0)
#define TWI0_SCL_PIN (2)
#define TWI0_SDA_PIN (31)
#define TWI0_SPEED (CAMBUS_SPEED_FULL)
// I2C1
#define TWI1_ID (1)
#define TWI1_SCL_PIN (15)
#define TWI1_SDA_PIN (14)
#define TWI1_SPEED (CAMBUS_SPEED_FULL)
// PDM/MIC
#define PDM_DIN_PIN (25)
#define PDM_CLK_PIN (26)

View File

@ -23,17 +23,19 @@ int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed)
{
bus->id = bus_id;
bus->speed = speed;
bus->scl_pin = FIR_I2C_SCL_PIN;
bus->sda_pin = FIR_I2C_SDA_PIN;
bus->initialized = false;
switch (bus_id) {
case 0: {
bus->scl_pin = TWI0_SCL_PIN;
bus->sda_pin = TWI0_SDA_PIN;
nrfx_twi_t _twi = NRFX_TWI_INSTANCE(0);
memcpy(&bus->twi, &_twi, sizeof(nrfx_twi_t));
break;
}
case 1: {
bus->scl_pin = TWI1_SCL_PIN;
bus->sda_pin = TWI1_SDA_PIN;
nrfx_twi_t _twi = NRFX_TWI_INSTANCE(1);
memcpy(&bus->twi, &_twi, sizeof(nrfx_twi_t));
break;
@ -43,8 +45,8 @@ int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed)
}
nrfx_twi_config_t config = {
.scl = FIR_I2C_SCL_PIN,
.sda = FIR_I2C_SDA_PIN,
.scl = bus->scl_pin,
.sda = bus->sda_pin,
.frequency = speed,
.interrupt_priority = 4,
.hold_bus_uninit = false

View File

@ -92,6 +92,21 @@ int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed)
return -1;
}
// Our code only knows about these two I2Cs instances.
if (bus->i2c->Instance == FIR_I2C) {
bus->port = FIR_I2C_PORT;
bus->scl_pin = FIR_I2C_SCL_PIN;
bus->sda_pin = FIR_I2C_SDA_PIN;
} else if (bus->i2c->Instance == ISC_I2C) {
bus->port = ISC_I2C_PORT;
bus->scl_pin = ISC_I2C_SCL_PIN;
bus->sda_pin = ISC_I2C_SDA_PIN;
} else {
bus->port = NULL;
bus->scl_pin = 0;
bus->sda_pin = 0;
}
// Configure the I2C handle
bus->i2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
#if !defined(STM32F4)
@ -111,7 +126,8 @@ int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed)
HAL_I2C_DeInit(bus->i2c);
if (HAL_I2C_Init(bus->i2c) != HAL_OK) {
/* Initialization Error */
bus->i2c = NULL;
bus->port = NULL;
return -1;
}
@ -197,6 +213,7 @@ int cambus_deinit(cambus_t *bus)
bus->i2c->Instance = NULL;
}
bus->i2c = NULL;
bus->port = NULL;
return 0;
}
@ -390,29 +407,28 @@ i2c_error:
return ret;
}
// TODO this is only used by the FIR code, hard-code pin/port for now.
int cambus_pulse_scl(cambus_t *bus)
{
#if defined(FIR_I2C_SCL_PIN)
// Configure SCL as GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pin = FIR_I2C_SCL_PIN;
HAL_GPIO_Init(FIR_I2C_PORT, &GPIO_InitStructure);
if (bus->port) {
// Configure SCL as GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pin = bus->scl_pin;
HAL_GPIO_Init(bus->port, &GPIO_InitStructure);
// Pulse SCL to recover stuck device.
for (int i=0; i<10000; i++) {
HAL_GPIO_WritePin(FIR_I2C_PORT, FIR_I2C_SCL_PIN, GPIO_PIN_SET);
mp_hal_delay_us(10);
HAL_GPIO_WritePin(FIR_I2C_PORT, FIR_I2C_SCL_PIN, GPIO_PIN_RESET);
mp_hal_delay_us(10);
// Pulse SCL to recover stuck device.
for (int i=0; i<10000; i++) {
HAL_GPIO_WritePin(bus->port, bus->scl_pin, GPIO_PIN_SET);
mp_hal_delay_us(10);
HAL_GPIO_WritePin(bus->port, bus->scl_pin, GPIO_PIN_RESET);
mp_hal_delay_us(10);
}
// Clear ARLO flag if it's set.
__HAL_I2C_CLEAR_FLAG(bus->i2c, I2C_FLAG_ARLO);
debug_printf("reset stuck i2c device\n");
}
// Clear ARLO flag if it's set.
__HAL_I2C_CLEAR_FLAG(bus->i2c, I2C_FLAG_ARLO);
debug_printf("reset stuck i2c device\n");
#endif
return 0;
}

View File

@ -36,6 +36,9 @@ typedef enum _cambus_speed {
typedef struct _cambus {
uint32_t id;
uint32_t speed;
uint32_t scl_pin;
uint32_t sda_pin;
GPIO_TypeDef *port;
// This pointer will be set to its respective I2C handle defined in MicroPython
// because all I2C IRQs are defined in stm32_it.c and handled by MicroPython.
I2C_HandleTypeDef *i2c;