2023-03-14 07:35 AM
I made an I2C communication between STM32U585 uC to an I2C EEPROM and it works
I do the following
but if I remove the HAL_Delay(10) or minimizes it to less than 10msec things are not working well, the second call I2C_Master_Transmit fails.
Is there's a way to call the I2C_ISR register or anything else, in order to check if the writing process was completed before proceeding with the communication?
Thanks!
Solved! Go to Solution.
2023-03-14 08:40 PM
Yes, these functions ignore the LSB and set it as appropriate. This is how the 2nd Master_Transmit() works with read address.
If the target device is eeprom, IIRC instead of fixed HAL_Delay poll the device until it responds.
I. e. call HAL_I2C_IsDeviceReady with needed timeout. If the device becomes ready sooner, it may return sooner.
2023-03-14 08:21 AM
Hello @bmn,
Before starting a new communication transfer, you need to check the current state of the peripheral; if it’s busy you need to wait for the end of current transfer before starting a new one.
You can add this function :
while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY)
{
}
Foued
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-03-14 08:23 AM
Thank you so much! I tried it, as shown below
And it didn't work for me. Only after bringing back the HAL_Delay(10) the program worked properly, without it, again the second call to HAL_I2C_Master_Transmit fails.
Am I using it in the wrong way?
2023-03-14 08:25 AM
You are welcome :smiling_face_with_smiling_eyes:
When your question is answered, please close this topic by choosing Select as Best the answer that answered your question or solved your problem. This will help other users find that answer faster.
Foued
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-03-14 10:05 AM
A little premature :)
What do you mean "second call fails"? Does it return something other than HAL_OK? Or does it return HAL_OK but doesn't send the data to the EEPROM? Or does it send data to the EEPROM but it doesn't do what you expect it to do?
If you are trying to access an EEPROM, why not use HAL_I2C_Mem_Write() and HAL_I2C_Mem_Read(). Those functions encapsulate the writing of device address and memory address then repeated start (if needed) and reading/writing data.
I presume M4_ADDRESS_READ has the 7-bit address in the upper 7 bits and the LSB=1. That is not the format that the HAL_I2C_Master_Transmit/Receive functions expect. They expect the LSB=0 (or just plain ignore the LSB), and they set/clear the LSB based on whether you call a Transmit or Receive function (I think - I do not use those functions).
2023-03-14 08:40 PM
Yes, these functions ignore the LSB and set it as appropriate. This is how the 2nd Master_Transmit() works with read address.
If the target device is eeprom, IIRC instead of fixed HAL_Delay poll the device until it responds.
I. e. call HAL_I2C_IsDeviceReady with needed timeout. If the device becomes ready sooner, it may return sooner.
2023-03-15 12:53 AM
I tried it and added the part "And it didn't work.." only after his "You are welcome" so it came out weird.
Be nice.
2023-03-15 06:06 AM
Hi, thanks for the reply. "second call fails" means that it returns HAL_ERROR.
I switched according to your advise to the HAL_I2C_Mem_Read/Write() functions and called HAL_I2C_IsDeviceReady with a while empty loop. I found that it is the right choice here, since the state HAL_I2C_STATE_READY which is the one I would wait for by calling HAL_I2C_GetState() does not necessarily mean that the device is not busy, as can be understood from the HAL I2C code below:
So the code which is working as I would expect is:
ret = HAL_I2C_Mem_Write(&hi2c1, M24_ADDRESS_WRITE, MemAddress, MemAddressSize, buf_out, DataSize, HAL_MAX_DELAY);
while(HAL_I2C_IsDeviceReady(&hi2c1, M24_ADDRESS_WRITE, 1, HAL_MAX_DELAY) != HAL_OK)
{
}
if( ret == HAL_OK)
{
ret = HAL_I2C_Mem_Read(&hi2c1, M24_ADDRESS_READ, MemAddress, MemAddressSize, buf_in, DataSize, HAL_MAX_DELAY);
if( ret == HAL_OK)
{
Thanks a lot!
2023-03-15 07:13 AM
SW delays kills the average bit rate and performance.
You should only need the delay after writing (transmitting) the data, the EEPROM will need 5 msec or less to be ready for a read, or another page write.
Actually, if you want to minimize the delay, you can try to read data after write, the slave will ACK, yet the data will be NACKED. loop up to 5 msec in 1 msec per loop delay and the lag will be minimal.