cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Slave hangs on low SCL signal

Pico Grenning
Associate II
Posted on May 08, 2018 at 08:45

Hello guys,

I use the STM32F030R8 as I2C slave with clock stretching. It is able to receive and send data based on interrupts. The transmission of the slave to the master works as long as the master and the slave know the same length of the data to be transmitted. I am currently looking for error handling if there is a misinterpretation, e.g. if slave and master expect different lengths during transmission from slave to master.

Therefore I have two cases.

l_m (data length that master expects to receive)

l_s (data length that is transferred from the slave)

1)  l_m >  l_s

2) l_m < l_s

Implementation of case 1) The bus hangs on a low SCL signal. This is because after the last byte transmitted by the slave, the master acknowledges it with an ACK instead of NACK and the slave thinks it must send more and because the clock streching is activated, the clock signal is forced to low and remains there.

Is there a way to handle this state on the slave side or even on the master side or do I have to reset the hardware?

#i2c #low #scl #clock-stretching #different-length
4 REPLIES 4
AvaTar
Lead
Posted on May 08, 2018 at 10:01

Is there a way to handle this state on the slave side or even on the master side or do I have to reset the hardware?

This depends very much on the slave.

But quite often, their I2C interface is a 'dumb' and static state machine.

An approved method is to switch the master I2C pins back into GPIO mode, and then pulse clocks out until the slave releases the bus.

Posted on May 11, 2018 at 10:15

Thanks for the reply

What do you mean, depends very much on the slave.

Another approach would be simply to use a timer and reset all I2C communication.

But then the communication does not work as hoped, the slave responds with a NACK after the first data byte.

Execution of I2C turn-off after expiry of the timer:

' HAL_I2C_DisableListen_IT(&hi2c1);

     I2C_RESET_CR2(&hi2c1);

     hi2c1.Instance->TXDR = 0x00U;

     hi2c1.Instance->RXDR = 0x00U;

     communicationErrorDetected = 0;

     

         if (HAL_I2C_DeInit(&hi2c1) != HAL_OK)

     {

        _Error_Handler(__FILE__, __LINE__);

     }

'

Is anything missing before I initialize it again?

Posted on May 14, 2018 at 07:32

What do you mean, depends very much on the slave.

It's complexity, anf how it reacts on error conditions like interrupted/corrupted transfers and transfer sequences. Many slaves are obvious static designs - the master could pause in the middle of a transfer indefinitely, and then finish it sucessfully later.

Another approach would be simply to use a timer and reset all I2C communication.

But then the communication does not work as hoped, the slave responds with a NACK after the first data byte.

Because many slaves do not automatically (self) reset into an initial state after said errors.

Quite often, I2C is a PITA.

ashah.16
Associate II

Hi,

I'm Wondering if you could fix your problem using the HAL library? I have two STM32 MCUs. One STM32L0 as slave and one STM32U5 as master. The master after sending one byte, keeps SCL low. I tried different ways such as changing the location of GPIO clock before i2c_init() function.

@AvaTar @Pico Grenning