LIVE FEED
What the community is building
Real-time telemetry, build milestones, technical Q&A, and squad recruitment across all tracks.
QuestionAeroGlide UAV
StudentMaker
Recovering from bus lockups on shared I2C bus with BNO085 and MS5611 at 400kHz?
When polling the BNO085 IMU and MS5611 altimeter over the same STM32 I2C1 peripheral at 400kHz, the bus occasionally hangs with SDA held low indefinitely after a clock stretch. What is the cleanest hardware/firmware recovery sequence without rebooting the whole flight controller?
void i2c_check_sda_stuck(I2C_TypeDef *i2c) {
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == GPIO_PIN_RESET) {
// SDA line is held low by peripheral
i2c_manual_clock_toggle();
}
}Accepted answer
Arjun Menon
Firmware Dev
Generate 9 manual SCL clock pulses in GPIO bit-bang mode to clock out the stuck slave state machine, followed by a standard STOP condition. Here is the verified recovery routine we run on the KisanSense sensor nodes:
void i2c_bus_recover(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
for (int i = 0; i < 9; i++) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
delay_us(5);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
delay_us(5);
}
// Generate STOP
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
delay_us(5);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
delay_us(5);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
}#stm32#embedded-c#i2c#sensors
19reactions5comments
View project →