Hi,
Ok I am doing several writings... It's not exactly what you are doing.
Quote:
Finally correct me if I am wrong, but your code appears to disable writing in the EEPROM during the read sequence (w_dis = 1). You are looking for read operations that are being converted into write operations when they shouldn't be. If /WC is high then you will never see the issue... Notice how I have tied /WC low in my schematic diagram.
You are doing this in your code... on p26. But on the schematic, this pin is not connected. But the behaviour is the same if I connect this pin to the ground.
In your code there are these two lines:
while(eeprom.write(EEPROMAddress, Buffer, 2, true))
eeprom.read(EEPROMAddress, Data, Length, false);
It seems to me that there is a ";" missing at the end of the while.
Finally, I took your code (with your mbed library: 28) and I have added a ";" after the while. First, I have reduced the frequency at 100KHz. There is no problem at this frequency. Until 300KHz there is no problem for me. After, I observe this third byte 0x80...
I did a test program with your two "key functions" to write or read the eeprom and it works for me even at 400kHz.
#include "mbed.h"
Serial pc(USBTX, USBRX);
I2C eeprom(p28, p27);
DigitalOut trigger(p22);
DigitalOut w_dis(p21);
#define EEPROMAddress 0xa0
#define uint32 unsigned long
#define uint16 unsigned short
#define byte char
void Read( uint16 Address, byte * Data, int length);
void Write( uint16 Address, byte * Data, int length);
char Buffer[2];
char Data[4];
void Read (
uint16 Address, // address to start reading from
byte *Data, // location to store data
int Length // number of bytes to read
)
{
// address in big-endian format
Buffer[0] = (Address >> 8) & 0xFF;
Buffer[1] = Address & 0xFF;
while(eeprom.write(EEPROMAddress, Buffer, 2, true));
eeprom.read(EEPROMAddress, Data, Length, false);
}
void Write
(
uint16 Address, // address to start writing to
byte *Data, // data to write
int Length // number of bytes to write
)
{
// enable writing
//w_dis = 0;
// address in big-endian format
Buffer[0] = (Address >> 8) & 0xFF;
Buffer[1] = Address & 0xFF;
// data
for (int i = 0; i < Length; i++)
{
Buffer[2 + i] = Data[i];
}
// write
while(eeprom.write(EEPROMAddress, Buffer, Length + 2, false));
// disable writing
//w_dis = 1;
}
int main() {
char write0[4] = {0x02, 0x11, 0x78, 0x05};
char write1[4] = {0x06, 0xaa, 0xe4, 0xae};
char write2[4] = {0x08, 0x1d, 0x78, 0x59};
pc.printf("\x1B[2J");
pc.printf("\x1B[H");
pc.printf("hello!\r\n");
trigger = 0;
eeprom.frequency(400000);
Write(100, write0, 4);
Write(200, write1, 4);
Write(300, write2, 4);
while (1) {
Read(100, Data, 4);
for(int i = 0; i < 4; i++)
if(Data[i] != write0[i])
{
trigger = 1;
pc.printf("fail1\r\n");
while(1);
}
Read(200, Data, 4);
for(int i = 0; i < 4; i++)
if(Data[i] != write1[i])
{
trigger = 1;
pc.printf("fail2\r\n");
while(1);
}
Read(300, Data, 4);
for(int i = 0; i < 4; i++)
if(Data[i] != write2[i])
{
trigger = 1;
pc.printf("fail3\r\n");
while(1);
}
}
}
This code is exactly what you are doing. 3 writings and then I read as fast as I can.
In an infinite loop in the main function I am continually reading four bytes from a M24C64-W I2C EEPROM using pins P27 and P28. It seems like some of the reads send a third byte with the address and it is always 80H. Here is my code:
As you can see this writes two bytes (the address) to the EEPROM, then sends a repeated start, then reads a set of bytes from the device.
Here is what happens some of the time:
It shows the address (0x0C00) and instead of the repeated start the microcontroller sends a third byte. Fortunately I have the writing disabled on the EEPROM so it NACKs the byte, but this causes the read to fail.
Here is a capture of the previous read of this same address, which was successful and occurred 388.58us before the failed read:
As you can see the 16-bit address 0x0C00 is sent and then the four bytes 0x06, 0x00, 0x00, 0x00 are successfully read.
Any ideas what the problem might be? Is the source code to the I2C library available somewhere?
thanks, Andy