
I have run into a similiar problem with the ATMEL AT24C64AN parts (it works fine with the AT24C64N parts...)
A read of a block of data breaks off at the first odd byte read and from there reads 0xff. It seems EXACTLY like the problem you encounter (last SDA=1).
I will further investigate your idea of a fix and if it helps here, I can make a proper patch of it.
-----Ursprüngliche Nachricht----- Von: u-boot-users-admin@lists.sourceforge.net [mailto:u-boot-users-admin@lists.sourceforge.net] Im Auftrag von Andrew Dyer Gesendet: Dienstag, 12. Juli 2005 01:05 An: uboot Betreff: [U-Boot-Users] ack problem in common/soft_i2c.c?
I am working with the soft i2c code on my target and I believe there is a problem in the send_ack() function.
My hardware (au1550) uses standard push-pull drivers which can be tri-stated by changing them to inputs, so I have I2C_ACTIVE and I2C_TRISTATE defined as per the README.
When reading the real time clock (ST M41T60) on my board I could never get 8 successive reads of the device to complete. Somewhere in the middle of reading the data the clock would start returning 0xff. If I read the registers one at a time, it worked fine.
read_byte() leaves the clock high at the end of shifting in the read data. usually the internal state of the data out register on the CPU was low from generating the last ack and the data line is tristate on the CPU (done at the start of read_byte()). The physical data line is in an unknown state depending on the last data bit read.
Looking at the beginning of the send_ack() code it goes:
I2C_ACTIVE; I2C_SCL(0); I2C_DELAY;
If the external data line is high and the internal register for the I/O on the CPU is low, this will generate a repeated start condition. It might be missed by a lot of parts since the edges happen with minimal delay in between.
In my case changing the order to:
I2C_SCL(0); I2C_DELAY; I2C_ACTIVE;
seems to fix my issues. Unfortunately due to internal CVS/firewall/VPN issues I can't get a patch together easily right now.