Skip to main content
thomfischer
Senior
May 18, 2016
Solved

STM32 FW_F7_V1.3.1 I2C HAL_I2C_Master_Receive() BUG

  • May 18, 2016
  • 3 replies
  • 2428 views
Posted on May 18, 2016 at 14:18

i tried to port software from F4 to F7 but got HAL_TIMEOUT and wrong reading of data

from functio

n

HAL_I2C_Master_Receive()

i changed the following code

--- stm32f7xx_hal_i2c.c Tue Dec 22 14:36:08 2015
 +++ my_stm32f7xx_hal_i2c.c Wed May 18 11:59:02 2016
 @@ -197,15 +197,17 @@
 * @{
*/
#define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFF) /*<! I2C TIMING clear register Mask */
-#define I2C_TIMEOUT_ADDR ((uint32_t)10000) /* 10 s */
-#define I2C_TIMEOUT_BUSY ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_DIR ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_RXNE ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_STOPF ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_TC ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_TCR ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_TXIS ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_FLAG ((uint32_t)25) /* 25 ms */
+
+#define I2C_TIMEOUT_ADDR ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_BUSY ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_DIR ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_RXNE ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_STOPF ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_TC ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_TCR ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_TXIS ((uint32_t)100) /* 100 ms */
+#define I2C_TIMEOUT_FLAG ((uint32_t)100) /* 100 ms */
+
/**
* @}
*/ 
@@ -613,6 +615,7 @@
 }
}
+
/**
* @brief Receives in master mode an amount of data in blocking mode. 
* @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
@@ -627,6 +630,7 @@
 {
uint32_t sizetmp = 0;
+
if(hi2c->State == HAL_I2C_STATE_READY)
{ 
if((pData == NULL ) || (Size == 0)) 
@@ -659,19 +663,15 @@
 sizetmp = Size;
}
+ /* Clear RXNE Flag */
+ uint8_t dummy=hi2c->Instance->RXDR;
+
do
{
/* Wait until RXNE flag is set */
- if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, I2C_FLAG_RXNE) != HAL_OK) 
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)
{
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- return HAL_ERROR;
- }
- else
- {
return HAL_TIMEOUT;
- }
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

/* Write data to RXDR */

problem was that function

I2C_WaitOnRXNEFlagUntilTimeout(hi2c, I2C_FLAG_RXNE) is called with a flag as timeout value and that it returned because a stop flag was detected ,

with

hi2c->

ErrorCode

= HAL_I2C_ERROR_NONE

and return= HAL_ERROR

so function

HAL_I2C_Master_Receive()

returned with HAL_TIMEOUT and leaving RXNE flag set.

next read returned wrong values because RXNE flag was still set.

best regards

    This topic has been closed for replies.
    Best answer by Amel NASRI
    Posted on January 09, 2017 at 14:45

    Hi

    Soans.Joel

    ‌,

    The reported bug is already fixed in I2C driver available in the last

    http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef7.html

    version.

    -Amel-

    PS: As general recommendation, please use English for your posts.

    3 replies

    Amel NASRI
    Technical Moderator
    May 19, 2016
    Posted on May 19, 2016 at 11:25

    Hi thomas.004,

    Thanks for highlighting this issue.

    It is reported internally to be fixed in a coming release.

    -Mayla-

    To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
    Joel Soans
    Visitor II
    January 5, 2017
    Posted on January 05, 2017 at 15:57

    Hallo Thomas,

    Ich habe dieselbe Problem. Kannst du den ganzen Code (

    my_stm32f7xx_hal_i2c.c

    ) hier posten.

    Beste Grüße,

    Joel

    Amel NASRI
    Amel NASRIBest answer
    Technical Moderator
    January 9, 2017
    Posted on January 09, 2017 at 14:45

    Hi

    Soans.Joel

    ‌,

    The reported bug is already fixed in I2C driver available in the last

    http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef7.html

    version.

    -Amel-

    PS: As general recommendation, please use English for your posts.

    To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
    David Littell
    Senior II
    October 17, 2017
    Posted on October 17, 2017 at 17:44

    Please note that this problem is definitely not fixed as of F7 v1.8.0.  There's a race in I2C_WaitOnRXNEFlagUntilTimeout() due to it attempting to do more than is needed in support of HAL_I2C_Master_Receive().  The behavior in HAL_I2C_Mem_Read() (which doesn't use the broken I2C_WaitOnRXNEFlagUntilTimeout()) is more correct.

    Ralf Ebeling
    Visitor II
    February 19, 2018
    Posted on February 19, 2018 at 09:27

    Hi,

    I just run into the same issue with a STM32F030, F070, F091 as reported here - I get a STOPF error while waiting for the last byte of a polled master receive operation. The race condition mentioned here doesn't seem to be fixed within I2C_WaitOnRXNEFlagUntilTimeout() and boils down to multiple reads of the ISR register to check different flags:

    1. read ISR, check for RXNE set
    2. read ISR again, check for NACKF set (within I2C_IsAcknowledgeFailed())
    3. read ISR again, check for STOPF set
    4. start over with 1.

    I guess it is obvious what happens, if the ISR register is updated (by hardware) e.g. between step 1 and step 3. RXNE and STOPF may become set at the same time, but STOPF is evaluated only. A possible solution:

    1. read ISR register into local variable
    2. checklocal variable for RXNE set
    3. checklocal variable for STOPF set
    4. start over with 1.

    Replacing the call of I2C_WaitOnRXNEFlagUntilTimeout() with I2C_WaitOnFlagUntilTimeout() of course hides

    this race condition, but also removes the check for NACKF and STOPF...

    Regards

    Ralf