Skip to main content
Visitor II
May 31, 2017
Solved

I2C Receive getting extra invalid byte using HAL

  • May 31, 2017
  • 13 replies
  • 6872 views

Posted on May 31, 2017 at 19:33

I am using an stm32f030x8. I am using the HAL. Normal operation I can use I2C reads/writes with no problems; however, I can occasionally have errors in the receive data when more activity is taking place on the MCU. I scoped the lines and the bytes on the line are correct/as expected. While step debugging, I can see that the data seemingly gets shifted by a byte when this occurs (i.e. byte 0 in the receive array is some garbage value that was not actually on the bus (verified from scoping the lines), byte 1, 2 etc are the expected data. 

Things to note: using synchronous reads here, interrupts are not in play. this system uses single priority interrupts (no nesting)

Things I have verified:

  • The actual data on the physical line is correct (scope + logic analyzer verifies this)
  • I verified that the pointer address for the buffer being passed in does not get changed (rules out memory corruption of that pointer)
  • Verified that the bad data byte is being read out of the rx hw register. The following line shows that RXDR is holding the 'garbage' byte during step debug: (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
  • Verified that worse case memory does not corrupt stack/heap (this was my initial thought since we are pretty close to utilizing the full RAM capabilities of this device). We have ~800 bytes to spare between heap/stack region in worse case scenario.♯

    This topic has been closed for replies.
    Best answer by Ross Yeager
    Posted on June 20, 2017 at 09:25

    Turns out the solution here was to flush the stale byte out of the data register.  Seems like it may be a HAL or HW bug that that byte was not cleared during previous reads, but reading the data register before making the call to the HAL_I2C_Master_Read() call gets it to work as expected.

    13 replies

    Explorer
    July 29, 2020

    Hi Nicholas,

    thanks for sharing ST's answer!

    I am also still not sure if I can skip the dummy read which I left in all my projects, since I had no more issues.

    static void EEprom_ReadI2C_Page(void)
    {
     uint32_t x;
     
     aCommand[0]=0;
     Eeprom.Init=HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, (uint8_t *)aCommand, 1, 2);
     x=hi2c1.Instance->RXDR; // dummy read -> bugfix // todo ???
     Eeprom.Response=HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS, (uint8_t *)EEpromData, 256, 100);
    }

    Maybe it was never necessary in L4xx family.

    My current hardware is a STM32L431. Halversion is defined:

    #define STM32L4XX_HAL_VERSION_MAIN  (0x01U) /*!< [31:24] main version */

    #define STM32L4XX_HAL_VERSION_SUB1  (0x0BU) /*!< [23:16] sub1 version */

    #define STM32L4XX_HAL_VERSION_SUB2  (0x01U) /*!< [15:8] sub2 version */

    does this expand to v1.11.1 ? (STM32F0xx has v1.7.3)

    a few days ago with CubeMX 6 it got updated to

    #define STM32L4XX_HAL_VERSION_MAIN  (0x01U) /*!< [31:24] main version */

    #define STM32L4XX_HAL_VERSION_SUB1  (0x0CU) /*!< [23:16] sub1 version */

    #define STM32L4XX_HAL_VERSION_SUB2  (0x00U) /*!< [15:8] sub2 version */

    but I feel a bit reluctant to update right now to this latest version,

    Werner

    Graduate
    July 29, 2020

    ​I removed the dummy reads from my code and ran it over night with the updated HAL libraries and so far no failures.  Encouraging results.

    Visitor II
    July 29, 2020

    That's very encouraging, indeed. It was my main concern should I change my old working code on live projects or not. I will probably leave is as it is and do a rework for newer versions and other projects. Anyway I am really glad that there is some light at the end of that tunel. :) Take care guys!

    Graduate
    August 3, 2020

    ​Been testing for almost a week non-stop now and the I2C has not failed.  We are calling it fixed by the newest release of HAL libraries.

    Visitor II
    August 3, 2020

    Great to hear that! Thanks for letting us know! Take care!