cancel
Showing results for 
Search instead for 
Did you mean: 

CubeHAL I2C slave pulls down clock line and let it not go. Who knows what I can do when wanting to enable clock stretching.

KWuer
Associate II

0690X000008BFf4QAG.png

Hi, I have problem with I2C. I use NUCLO446RE as a slave. STM32Cube FW_F4 V1.24.0 or 24.1. Both versions have the problem. I using also Atollic True Studio for STM32 or STM32CubeIDE 1.0.0. The problem occures with both platforms.

When the master requests 5bytes, the slave (Nucleo446RE) pulls down the clock signal after the first byte of data was send and does not let the line go (see picture). If I set in the file: i2c.c "hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;" -> so turn off clock stretching, then I do not have the problem. But then get triggered the error interrupts. The number of the errorcode is 12. Does one have a similar problem or idea how to solve it? I attached a very simple I2CTest.zip example for Atollic TS.

4 REPLIES 4
S.Ma
Principal

Implement a timeout on SCL low duration like SMBus to prevent such deadlock situation.

Use the EXTI.PR bit to detect any rise/fall edge activity on SCL (the HAL is not helping you, you have to break free of HAL to get it to work).

Manage in the SW to detect when slave is selected and until the STOP bit is received, use EXTI.PR on a timebase (10msec?) to detect when there is an SCL hang.

Timeout will cause SYSCFG reset of the I2C cell.

KWuer
Associate II

Thank you very much for this solution. But the problem is, it occures every time I send bytes to the master. There is maybe something missing in the interrupt routine or I did something wrong. In the I2CTest.zip the example only sends 1 byte to the master. And there I run into the same problem.

S.Ma
Principal

Sounds like an STM32 SW Application Example Wish List right here....

KWuer
Associate II

Ok, I found the problem. 

Was on the one hand my own fault, on the other hand apparently a mistake in the HAL. 

If the slave sends fewer characters than the master requests, no NACK will be sent. This does not trigger a NACK error interrupt which calls I2C_Slave_AD, which in turn calls HAL_I2C_ListenCpltCallback, where it generates a new HAL_I2C_EnableListen_IT.

On the HAL side, this is not detected. In the interrupt handler HAL_I2C_EV_IRQ the code changed to slave receiver mode (transmitter mode should be) and I2C_MasterReceive_BTF (hi2c); is called. This hangs the whole system. The main loop is no longer running, so I can not reset the error here.