cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_Mem_Read reads only correct if the parameter is wrong

Osto
Senior
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?
11 REPLIES 11
stm322399
Senior
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
Senior
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

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

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