Skip to main content
Visitor II
October 23, 2017
Question

I2C slave with no clock stretch

  • October 23, 2017
  • 5 replies
  • 6547 views
Posted on October 23, 2017 at 12:33

Hello,

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 :)

regards

Daniel

    This topic has been closed for replies.

    5 replies

    Technical Moderator
    October 23, 2017
    Posted on October 23, 2017 at 16:55

    Hi

    lengen.daniel

    ‌,

    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).

    -Amel

    Visitor II
    October 24, 2017
    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.

    void

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

          

    if

    (TransferDirection == 0x00) {

                

    //Write Access

                osSemaphoreRelease(semI2Cid);

          }

         

     else

          {

                

    //Read Access

                uint8_t test[1];

                test[0]=0xBB;

                HAL_I2C_Slave_Sequential_Transmit_IT(&hi2c1,test,1,I2C_FIRST_AND_LAST_FRAME);

        

            while

    (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);

                HAL_I2C_EnableListen_IT(&hi2c1);

       }

    }

    With clock stretching:

    0690X00000608ipQAA.png

    Without clock stretching:

    0690X00000608L7QAI.png

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

    Thanks for your support.

    Daniel

    Visitor II
    October 27, 2017
    Posted on October 27, 2017 at 16:12

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

    0690X00000604B2QAI.jpg
    Visitor II
    May 16, 2018
    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?

    Visitor II
    May 16, 2018
    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.

    regards

    daniel

    Visitor II
    May 17, 2018
    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.
    Visitor II
    May 17, 2018
    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 

    HAL_I2C_Slave_Receive_IT()

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