Hi,
i encounter a strange issue with MBED and a AT24C64 I2C EEPROM. The issue only appear on I2C write operation and only for the EEPROM, not on other I2C peripherals. The target is STM32L451CEU6, the I2C port used is PA9, PA10 with external 4.7K pullups.
I tried two different AT24C64 EEPROM with same result, for good measure i also tested an AT24C04, same error, so EEPROM error is not the cause here. There is a bunch of other I2C peripheral on this bus, none of these have any issue / error during write or read operations. To ensure it was not a incompatibiity issue i tested with an unpopulated PCB, so the only peripheral on the bus was this EEPROM, same issue. The I2C address is correct (incorrect address leads to NACK).
When the EEPROM is written there is a debug message from MBED API : TIMEOUT or error in i2c_write, a callback is also called : HAL error callback, with a cause 4 and index 0.
Depite the error, EEPROM is actually written correctly (checked by reading the content back, all data written on EEPROM are correct).
There is no error on read operations.
I captured 4 write + 4 read operations with logic analyzer, (data 0x20,0x21,0x22,0x23 written at address 0x0000,0x0001,0x0002,0x0003 and read back).
The weird look of the trace is due to the 2000 uS delay added in I2C_API I2C_write function to avoid the error.

first write operation


repeated 4 times in total.
first read operation


reapeated 4 times in total
The only difference i can see is that clock line is held high between the two operation on top and low between the two operations on bottom.
Here is the 2000 uS delay i added in I2C_API::i2c_write to avoid the HAL error:


With this modification there is no error, however it is not an option nor a fix since it does affects the whole I2C API effectively adding a 2mS delay after each I2C which impact all I2C peripherals otherwise working fine. If the delay is less than 2000 uS the write operation fail.
I have tested with I2C bus frequency from 100KHz to 1Mhz, and I2C mode ASYNC set to 1 or 0 (so with DMA or IRQ) no difference, the error is always thrown.
Here is the debug trace on write operation:
[EEPROM] ID:AT24C64 address:0xa0 size:8192 bytes
HAL_I2C_ErrorCallback:4, index=0
TIMEOUT or error in i2c_write
timeout:4/6000uS
xfer:FIRST_AND_LAST_FRAME
event:I2C_EVENT_ERROR
HAL_I2C_ErrorCallback:4, index=0
TIMEOUT or error in i2c_write
timeout:4/6000uS
xfer:FIRST_AND_LAST_FRAME
event:I2C_EVENT_ERROR
[EEPROM] ok - W/R pass
So the timout counter is only 4 uS on 6000 -> no timeout issue.
the xfer flag is FIRST_AND_LAST_FRAME -> what it should be
I2C event flag is EVENT_ERROR -> wrong, it should be I2C_EVENT_TRANSFER_COMPLETE.
When i add the 2000 uS delay, then the I2C event flag is I2C_EVENT_TRANSFER_COMPLETE.
With or without this delay, data are correctly written, that is why the write/read test passes anyway. Also when the delay is 1 uS and write operation fails the debug message add still more delay between write operations so it makes sense that the actual writing is ok. Tha also shows the issue is on the MBED/HAL side, the EEPROM seems to be happy with the write transaction.
Given the cross checks already made i am not sure what to try or investigate next, this driver has been written on the Nucleo L476 board and there was no issue as far as i can recall, however I2C debug was likely not enabled so issue not noticed, also the I2C bus was different (I2C1 cannot be PA9-PA10 on STM32L476RG contrary to STM32L451CEU6).
Hi, i encounter a strange issue with MBED and a AT24C64 I2C EEPROM. The issue only appear on I2C write operation and only for the EEPROM, not on other I2C peripherals. The target is STM32L451CEU6, the I2C port used is PA9, PA10 with external 4.7K pullups.
I tried two different AT24C64 EEPROM with same result, for good measure i also tested an AT24C04, same error, so EEPROM error is not the cause here. There is a bunch of other I2C peripheral on this bus, none of these have any issue / error during write or read operations. To ensure it was not a incompatibiity issue i tested with an unpopulated PCB, so the only peripheral on the bus was this EEPROM, same issue. The I2C address is correct (incorrect address leads to NACK).
When the EEPROM is written there is a debug message from MBED API : TIMEOUT or error in i2c_write, a callback is also called : HAL error callback, with a cause 4 and index 0. Depite the error, EEPROM is actually written correctly (checked by reading the content back, all data written on EEPROM are correct). There is no error on read operations.
I captured 4 write + 4 read operations with logic analyzer, (data 0x20,0x21,0x22,0x23 written at address 0x0000,0x0001,0x0002,0x0003 and read back). The weird look of the trace is due to the 2000 uS delay added in I2C_API I2C_write function to avoid the error.

first write operation
 
repeated 4 times in total.
first read operation
 
reapeated 4 times in total
The only difference i can see is that clock line is held high between the two operation on top and low between the two operations on bottom.
Here is the 2000 uS delay i added in I2C_API::i2c_write to avoid the HAL error:  
With this modification there is no error, however it is not an option nor a fix since it does affects the whole I2C API effectively adding a 2mS delay after each I2C which impact all I2C peripherals otherwise working fine. If the delay is less than 2000 uS the write operation fail.
I have tested with I2C bus frequency from 100KHz to 1Mhz, and I2C mode ASYNC set to 1 or 0 (so with DMA or IRQ) no difference, the error is always thrown.
Here is the debug trace on write operation:
So the timout counter is only 4 uS on 6000 -> no timeout issue.
the xfer flag is FIRST_AND_LAST_FRAME -> what it should be
I2C event flag is EVENT_ERROR -> wrong, it should be I2C_EVENT_TRANSFER_COMPLETE.
When i add the 2000 uS delay, then the I2C event flag is I2C_EVENT_TRANSFER_COMPLETE. With or without this delay, data are correctly written, that is why the write/read test passes anyway. Also when the delay is 1 uS and write operation fails the debug message add still more delay between write operations so it makes sense that the actual writing is ok. Tha also shows the issue is on the MBED/HAL side, the EEPROM seems to be happy with the write transaction.
Given the cross checks already made i am not sure what to try or investigate next, this driver has been written on the Nucleo L476 board and there was no issue as far as i can recall, however I2C debug was likely not enabled so issue not noticed, also the I2C bus was different (I2C1 cannot be PA9-PA10 on STM32L476RG contrary to STM32L451CEU6).