cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 I2C SCL forced low

CuSynth_
Visitor

Hello, ewryone!

I'm working on a project with a custom STM32F405 board. My project utilizes two independent I2C buses, both configured for Fast Mode (400 kHz):

  • I2C2: Connected to three INA226 sensors and an MMC5883 magnetometer.
  • I2C3: Connected to three INA226 sensors and an ICM20689 IMU.

 

 

Most of the time, everything works fine. However, sometimes HAL_I2C_Master_Transmit starts to return a HAL_BUSY status on both lines independently. In both cases, it gets stuck in I2C_WaitOnFlagUntilTimeout waiting on the BUSY flag.

In these situations, the I2C SDA line is always high while the SCL line is low. I tried switching the SCL GPIO from Alternate Function mode to an output and forcing it to a high level. But when I switch it back to Alternate Function (I2C SCL) mode, it immediately goes low again. I also tried disconnecting all the slave devices, and the SCL line was still held low. Therefore, I think it is a problem with the I2C master peripheral in my STM32F4.

So, the question is: what is happening here, and how can I fix this problem?

3 REPLIES 3
TDK
Super User

When you try to force the output high, is the pin still in open-drain mode? If it is, and the pin is still low, a slave is to blame, not the master.

Could be a slave device still holding the line low or could be the master has gotten into a bad state. If it's a slave, there is no recovery apart from power cycle. If it's the master, you can reset the entire I2C peripheral using the HAL_RCC_I2Cx_FORCE/RELEASE_RESET macros and then reset the software state machine.

If you feel a post has answered your question, please click "Accept as Solution".

@TDK wrote:

When you try to force the output high, is the pin still in open-drain mode?


I tried both open-drain and push-pull modes, and the pin was high in both cases.

I also tried to reset the slaves by power-cycling them, but that didn't help.

 


@TDK wrote:

 then reset the software state machine


What 'software state machine' did you mean? Are you referring to the internal HAL state machine or my own software logic?

I tried both open-drain and push-pull modes, and the pin was high in both cases.

Then it's probably the master. The STM32F4's I2C peripheral is a bear. I wouldn't be surprised if it occasionally gets into a weird state. In this case, if SCL is low, it's probably waiting for a new byte to be sent or for a stop condition to be generated.

> What 'software state machine' did you mean?

The HAL handle. Probably setting its state to *_RESET and then re-initializing would do it.

If you feel a post has answered your question, please click "Accept as Solution".