Menu

#727 STM32 I2Cv1 driver broken when receiving 1 single byte

16.1.5
closed-rejected
STM32-HAL
High
16.1.4
False
2018-01-16
2016-03-25
No

I found this bug in the I2Cv1 LLD driver for the STM32F1 platform, which doesn't exactly comply with the reference manual (RM0008).

The problem happens when using the function i2cMasterTransmitTimeout to read exactly 1 byte from a I2C slave using the "read-through-write" paradigm, that is passing rxbytes = 1. The problem is that after receiving the expected byte, the master keeps the bus clocked for one more byte. This can cause unexpected behavior on the slave (I'm using this with an Invensense MPU-6050 mems gyro/accelerometer).

The reference manual explains how to handle the special case where a single char is expected, which is not done in the driver properly.

There is also a debug check that breaks when rxbytes is exactly 1, as mentioned in the forums.

This patch against i2c_lld.c fixed both problems for me:

270c270,272
<     if (dmaStreamGetTransactionSize(i2cp->dmarx) < 2)
---
>     if (dmaStreamGetTransactionSize(i2cp->dmarx) < 2) {
>       (void)dp->SR2;          // RM0008, p756: case of single char -> clear ADDR (read SR2)
>       dp->CR1 |= I2C_CR1_STOP;    // ... program STOP bit
271a274
>     }
801c804
<   osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));
---
>   osalDbgCheck((rxbytes == 0) || ((rxbytes >= 1) && (rxbuf != NULL)));    // http://forum.chibios.org/phpbb/viewtopic.php?f=2&t=357

Discussion

  • Giovanni Di Sirio

    • Component: --> STM32-HAL
     
  • barthess

    barthess - 2016-03-28

    I can not reproduce fix on my OLIMEX_STM32_103STK board. Code works when I step using debugger but locks inside I2C interrupt handler when I leave it running free. I suppose that Javier Martin has newer F1x silicon with updated I2C cell (like in F4x). If so that just disabling debug check for F1x should fix problem. Could you check this solution?

     
  • Giovanni Di Sirio

    The status is not clear to me. Is the fix at least harmless for old silicons? we could introduce it and disable the assertion with an explicit switch: STM32_I2C_DISABLE_F1_CHECK.

     
  • barthess

    barthess - 2016-04-24

    This patch is harmful for old silicons (all I have). Are there errata updates about this I2C improvement? I can not found any. Compile time check looks like acceptable solution.

     
  • Javier Martin

    Javier Martin - 2016-04-24

    Sorry about the delay, I haven't had much time to come back to this. Here is some more info: the chip I tested the patch on is an STM32F103C8T6 revision "X".

    Disabling the debug check by itself doesn't fix the problem. I need to do the two additional steps in I2C_EV6_MASTER_REC_MODE_SELECTED as described in the patch (clear ADDR followed by program STOP), as described in RM0008.

    Also, I found this on CD00190234.pdf (ST's errata doc for STM32F10xxx devices affecting rev. X among others), chapter 2.13.1, "When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not managed before the current byte is being transferred, problems may be encountered such as receiving an extra byte, reading the same data twice or missing data.".

    Maybe this is related to the problem I'm seeing?

     
  • Giovanni Di Sirio

    • status: open --> closed-rejected
     

Log in to post a comment.