Skip to main content
Osto
Senior
September 24, 2014
Question

HAL_I2C_Mem_Read reads only correct if the parameter is wrong

  • September 24, 2014
  • 11 replies
  • 4269 views
Posted on September 24, 2014 at 13:18

Hi,

I have a STMCube generated project wirh I2C memory 24LC512 with following problem. The line:

Status = HAL_I2C_Mem_Read(&hi2c1, IIC_ADDRESS+1, 0, I2C_MEMADD_SIZE_8BIT, pNVRawData, NVRawDataLen, 1000);

is correct feeded with parameter but reads only 0xff as data.

The line:Status = HAL_I2C_Mem_Read(&hi2c1, IIC_ADDRESS+1, 0, I2C_MEMADD_SIZE_8BIT+5, pNVRawData, NVRawDataLen, 1000);

is not correct because of ''+5'' (any garbage) but is working correct and reads correct value.

I'm using newest Cube & FW.

Why?

Whats wrong?
    This topic has been closed for replies.

    11 replies

    stm322399
    Senior
    September 24, 2014
    Posted on September 24, 2014 at 14:31

    When the second line give you the expected result, I would not say that parameter are wrong, to the contrary they are correct !

    A simplistic answer is:

    * either

    I2C_MEMADD_SIZE_8BIT

    is not the value you think

    * either the value you want to read has been wrongly written to

    I2C_MEMADD_SIZE_8BIT+5

    Of course it is also possible that the HAL function is broken. What's the value of

    NVRawDataLen

    ?

    This case requires further investigation.

    Osto
    OstoAuthor
    Senior
    September 24, 2014
    Posted on September 24, 2014 at 17:02

    Dear Laurent,

    The deffinition of I2C_MEMADD_SIZE_8BIT or I2C_MEMADD_SIZE_16BIT is if the device works with 8 bit or 16 bit memory and the value of I2C_MEMADD_SIZE_8BIT is 1. The value for I2C_MEMADD_SIZE_16BIT is 0x10. So the value 6 has absolutley no meaning and neither bit 0 nor bit 1 is set.

    NVRawDataLen  has a value of 0x39e4 but I tried also with 0x40 which is the page size of the 24LC512.

    I tried also with the interrupt version of it. It's working worse than the polling version. One or 2 block are read and wroten and then it sucks. The transmission dont go on and the complete or error callback is not called. So my programm waits forever.

    Any Idea how I can get an stable situation?

    Thaks,

    Mehrdad

    Montassar BEN ROMDHANE_O
    Visitor II
    September 24, 2014
    Posted on September 24, 2014 at 17:05

    Hi Mehrdad,

    In fact, I'm not sure I fully understand your problem, just find below my remarks:

    • You are receiving 0xFF values from the 24LC512 EEPROM Memory because you've wrote nothing within the EEPROM, so you are getting the default value.
    • Once passing a wrong parameter I2C_MEMADD_SIZE_8BIT+5, the HAL_I2C_Mem_Read() API already calling I2C_RequestMemoryRead() static function, checks if the Memory address size is 8bit, otherwise it's treated as 16bits size.

    Let me know if this helps or if you have further questions.

    Regards,

    Heisenberg.
    stm322399
    Senior
    September 24, 2014
    Posted on September 24, 2014 at 17:35

    My understanding of

    I2C_MEMADD_SIZE_8BIT

    is the following: the size of one EEPROM address (not the width of the data). Of course 24LC512 has 16-bit addresses, so you must use

    I2C_MEMADD_SIZE_16BIT

    .

    Regarding the ''+5'', I agree with Heisenberg, that the HAL function check for

    I2C_MEMADD_SIZE_8BIT

    for 8-bit addreses, otherwise it selects 16-bit addresses: Any value different from

    I2C_MEMADD_SIZE_8BIT

    leads to 16-bit addresses. This is why your ''wring'' parameter allowed you to correctly read the 16-bit addressed EEPROM.

    By the way, Cube (as did SPL before) uses an assert mecanism, that is not perfect, that that would at least catch this mistake, by forcing you to enter

    I2C_MEMADD_SIZE_8BIT

    or

    I2C_MEMADD_SIZE_16BIT

    . In SPL the assert was controlled by a C macro: USE_FULL_ASSERT (I don't if it is the same for Cube)

    Montassar BEN ROMDHANE_O
    Visitor II
    September 25, 2014
    Posted on September 25, 2014 at 10:16

    Hi Laurent,

    In fact, theHAL_I2C_Mem_Read() API contains a check on the MemAddSize parameter. User needs just to activate the assert parameter macro USE_FULL_ASSERT by uncommenting the following line within the HAL configuration file stm32xxx_hal_conf.h:

    /* ########################## Assert Selection ############################## */
    /**
    * @brief Uncomment the line below to expanse the ''assert_param'' macro in the 
    * HAL drivers code
    */
    /* #define USE_FULL_ASSERT 1 */

    This macro can be enabled also from the STM32CubeMX tool before generation the user code, by selecting: Project »Settings »Code Generator tab» HAL Settings» Enable Full Assert, as shown below: 0690X00000603JkQAI.jpg Cheers, Heisenberg.
    stm322399
    Senior
    September 25, 2014
    Posted on September 25, 2014 at 12:54

    Thank you for the clarification.

    I did not yet dive into Cube ... SPL has proved to be good enough for my current projects.

    No doubt your indication will serve me (and others) sooner or later.

    Cheers.

    Osto
    OstoAuthor
    Senior
    September 25, 2014
    Posted on September 25, 2014 at 22:38

    Hi,

    I cant use the FULL_ASSERT because it has a bug when I use complex timers. The application enters assert during the Cube initialisation sequence. If I remoe the timers, my application will not run at all.

    I'm right now hanging and dont know how to go on.

    Regards,

    Mehrdad

    stm322399
    Senior
    September 26, 2014
    Posted on September 26, 2014 at 08:55

    I don't understand where you are hanging ... does the following line work correctly for you ?

    Status = HAL_I2C_Mem_Read(&hi2c1, IIC_ADDRESS+1, 0, I2C_MEMADD_SIZE_16BIT, pNVRawData, NVRawDataLen, 1000);

    If you think there is a bug with complex timers and FULL_ASSERT, this forum is a good place to debate, and try to figure out whether the bug is in HAL or in your code.

    Osto
    OstoAuthor
    Senior
    September 26, 2014
    Posted on September 26, 2014 at 18:16

    Hi,

    Exactly that's my Problem because the 25LC256 has 8-bit Organisation and both 

    I2C_MEMADD_SIZE_16BIT and I2C_MEMADD_SIZE_8BIT deliver only 0xff regardless of the device content.

    stm322399
    Senior
    September 26, 2014
    Posted on September 26, 2014 at 18:39

    Please consider using

    I2C_MEMADD_SIZE_16BIT

    that must return the same result than 

    I2C_MEMADD_SIZE_8BIT

    +5. (because of the way HAL tests this parameter).

    Your EEPROM has 8-bit organization, which means that data is addressed 8-bit per address, and there are 32768 addresses, you need more than 8 bits to write an address, that's why you *must* use

    I2C_MEMADD_SIZE_16BIT

    .

    Double check your datasheet, when you read data from EEPROM, you need to write the read pointer using two bytes, hence

    I2C_MEMADD_SIZE_16BIT

    .