Showing results for 
Search instead for 
Did you mean: 

I2C slave with no clock stretch

Daniel Lengen
Associate II
Posted on October 23, 2017 at 12:33


I've tried the

I2C_TwoBoard_RestartComIT example in the STM32Cube_FW_L4_V1.9.0. It works fine.

If I disable the clock stretching feature, the slave can still receive messages, but it doesn't transmit back. It confirms the  slave address with an acknoledge, but doesn't transmit the messages back. 

hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;   // disable clock stetching

Is it possible to use I2C in slave mode without clock streetching?

In my current project the I2C master doesn't support clock stretching.

Many thanks in advance 🙂



ST Employee
Posted on October 23, 2017 at 16:55




Yes, the I2C clock stretching is an optional feature in your I2C device it means you can configure it depending on your need and when the connected master supports it.

When clock stretching is disabled, you have to pay attention to timing configuration, mainly the the maximum data hold time (which has to be met if clock stretching isn't supported).


To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on October 24, 2017 at 11:37

Hello Amel

Thank you for your reply.

The timing seems to be ok. I've added the slave responds  directly in the 

HAL_I2C_AddrCallback the I2C Slave respond.


HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {



(TransferDirection == 0x00) {


//Write Access







//Read Access

            uint8_t test[1];





(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);




With clock stretching:


Without clock stretching:


Could it be that the HAL_Library doesn't work without clock stretching in slave mode?

Thanks for your support.


Posted on October 27, 2017 at 16:12

I found the solution to my problem in the reference manual RM0360.

Pico Grenning
Associate II
Posted on May 16, 2018 at 13:46

I have the same behavior as you.

Looking at the oscilloscope I see that the slave transmits 0xFF and jumps directly into the I2C error handler. Seems to be that the data are not ready yet to be transmitted.

How did you solve the problem? Was it really possible to use the HAL libraries generated by CubeMx from STM or did you write your own HAL functions?

You have commented that the data to be transmitted must be set before the start signal from the master appears? Did you use the TXE interrupt flag and set the transmit registers to achieve this?

Daniel Lengen
Associate II
Posted on May 16, 2018 at 14:29

Hello Pico

I use the HAL library. Mainly the function  HAL_I2C_Slave_Sequential_Receive_IT() is used. So I receive sequence for sequence and I write manually in the register I2C1->TXDR the current transmitted value according the reference manual above.

I set the transmitted value in the register after receiving the prior byte.



Pico Grenning
Associate II
Posted on May 17, 2018 at 10:01

Thanks for the response transcription woks well

I have another question.

I mainly use HAL_I2C_Slave_Receive_IT() to receive data from the master (and I removed the ADDR flag in the HAL library because this does not work without clock stretching), but sometimes I can see that the slave returns a NACK at the end of a received data byte.

Additional Info:

The slave always receives a packet of 3 data bytes. A packet is transmitted every 20ms. After some transferred packets (there is no correlation sometimes after 30 packets sometimes after 200 packets) the slave returns a NACK.
Daniel Lengen
Associate II
Posted on May 17, 2018 at 17:18

In general the HAL library works without clock stretching incl. ADDR flag.

I don't know what the problem is, but it seems that you have to care about the timing. If the controller detect a I2C match than you have to call in a specific time the function 


 . If you miss the time slot, than you will get an NACK.