The following is based on an STM32F401 Nucleo and the IKSA101 Sensor board.
The HAL function was form anearlier version of HAL but matches that in release 1.16.0
We have been working with the I2C bus on the STM32F401 for a while now and occasionally we see odd behaviour (nothing unusual for I2C). However we think we may have found a flaw in the HAL driver and I wondered what others might think. The symptom is that if you cause a fault on the SDA line (we ground it momentarily) the HAL_I2C_EV_IRQHandler(&hi2c1) starts to execute in 'flat chat', consumes about 83% of the processor and stays stuck like this (we have measured this on a scope using output pins). We have chased the problem to the following :
At the start of the function the following line is executed
uint32_t CurrentMode = hi2c->Mode;
and this Mode has four states
HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
BUT in the function, there is no specific 'if else' for the HAL_I2C_MODE_NONE, which is exactly what we are seeing. So what happens is that we run around the interrupt handler and more or less come straight back in.
We still don't know the root cause of the problem, but it looks as if under a bus fault condition, the controller (which defaults to a slave device) thinks it sees an SB and so interrupts but it has no mode set and hence fails to do much.
I am ashamed to admit that we don't really understand our fix but what we have done is to split out the if-else to handle the HAL_I2C_MODE_NONE and we simply set the hi2c->Mode = HAL_I2C_MODE_MASTER. We now never see the continuous interrupt problem.
Thanks for any comments.