EEPROM Reading Problems-At24c512

Thread Starter

hanmant

Joined Sep 29, 2017
14
Hi All,

I'm working with LPC2148 and i interface eeprom at24c512 using I2C;I have used 3K7 for pull up resistors and eeprom voltage is 5v and WP pin is floating.I have Successfully interfaced and im writting and reading very successfully of my eeprom;but problem is sometimes my eeprom reads the garbage data that are shown below

"255255,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,255,21,0,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;"
"255255,???????????????????????????????????????,????????????????????????????????????????????????????????,255,21,0,????????????????????;"

this problem is coming hardly after 2-3 days but i didnt find why this problem is coming .Please help me to sort this issue
 

Ian Rogers

Joined Dec 12, 2012
663
You may need to "up" your house keeping delay.. If you are writing lots of bytes AFTER the delay you'll hit problems..
( I noticed the 0 ~ 10000 loop is disabled... )

Every time you write a single byte you need a 15ms housekeeping delay... If you block write a page. then you can send a maximum of 128 bytes per write.

so.. Looking at your code.. If you want to fill all 512k byte locations you will need 4092 page writes with 15ms between them.

There is no main in your code so I assume this is just a downloaded I2C library..
 

Thread Starter

hanmant

Joined Sep 29, 2017
14
You may need to "up" your house keeping delay.. If you are writing lots of bytes AFTER the delay you'll hit problems..
( I noticed the 0 ~ 10000 loop is disabled... )

Every time you write a single byte you need a 15ms housekeeping delay... If you block write a page. then you can send a maximum of 128 bytes per write.

so.. Looking at your code.. If you want to fill all 512k byte locations you will need 4092 page writes with 15ms between them.

There is no main in your code so I assume this is just a downloaded I2C library..

( I noticed the 0 ~ 10000 loop is disabled... )Yes! i disabled because ,i did not its useful so i disabled .Is i need to uncomment that loop?
and EEPROM have self writting delay its about 5ms per bytes right, by considering this delay i have added my delay .
 

Thread Starter

hanmant

Joined Sep 29, 2017
14
Hi ,@Ian Rogers ,
Still that Issue comes and memory is reading garbage data 1911092553465535,65535,255255255255255255,255255,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ.please help to sort
 

Ian Rogers

Joined Dec 12, 2012
663
Personally that I2C library is a bit of a mess..
It created read and write routines, then doesn't use them.... Returning zero values for no reason..

If I were you I'd grab a better library from somewhere else... That copy looks like a bad upgrade from an 8 bit 24c04 chip..
 

Ian Rogers

Joined Dec 12, 2012
663
Here is the code I linked in the PM
C:
#define I2EN (1<<6) //Enable/Disable bit
#define STA (1<<5) //Start Set/Clear bit
#define STO (1<<4) //Stop bit
#define SI (1<<3) //Serial Interrupt Flag Clear bit
#define AA   (1<<2) //Assert Acknowledge Set/Clear bit
#define checkStatus(statusCode) \
if(I2C0STAT!=statusCode) \
{ \
printf("Error! Expected status code: %i(decimal), Got: %i(decimal)\n",statusCode,I2C0STAT); \
I2C0SendStop(); return false; \
}
void I2C0Init(void)
{
PINSEL0 |= (0<<7)|(1<<6)|(0<<5)|(1<<4); //Select SCL0(P0.2) and SDA0(P0.3)
I2C0SCLL = 300;
I2C0SCLH = 300; //I2C0 @ 100Khz, given PCLK @ 60Mhz
I2C0CONCLR = STA | STO | SI | AA; //Clear these bits
I2C0CONSET = I2EN; //Enable I2C0
//After this we are ready to communicate with any other device connected to the same bus.
}
bool I2C0WaitForSI(void) //Wait till I2C0 block sets SI
{
int timeout = 0;
while ( !(I2C0CONSET & SI) ) //Wait till SI bit is set. This is important!
{
timeout++;
if (timeout > 10000) return false; //In case we have some error on bus
}
return return; //SI has been set
}
void I2C0SendStart(void)
{
I2C0CONCLR = STA | STO | SI | AA; //Clear everything
I2C0CONSET = STA; //Set start bit to send a start condition
I2C0WaitForSI(); //Wait till the SI bit is set
}
void I2C0SendStop(void)
{
int timeout = 0;
I2C0CONSET = STO ; //Set stop bit to send a stop condition
I2C0CONCLR = SI;
while (I2C0CONSET & STO) //Wait till STOP is send. This is important!
{
timeout++;
if (timeout > 10000) //In case we have some error on bus
{
printf("STOP timeout!\n");
return;
}
}
}
void I2C0TX_Byte(unsigned char data)
{
I2C0DAT = data;
I2C0CONCLR = STA | STO | SI; //Clear These to TX data
I2C0WaitForSI(); //wait till TX is finished
}
unsigned char I2C0RX_Byte(bool isLast)
{
if(isLast) I2C0CONCLR = AA; //Send NACK to stop; I2C block will send a STOP automatically, so no need to send STOP thereafter.
else I2C0CONSET = AA; //Send ACK to continue
I2C0CONCLR = SI; //Clear SI to Start RX
I2C0WaitForSI(); //wait till RX is finished
return I2C0DAT;
}
bool I2C0WriteEEPROM(unsigned int startDataAddress, unsigned char *data, int length)
{
for(int count=0 ; count< length ; count++ ) { I2C0SendStart(); //Send START on the Bus to Enter Master Mode checkStatus(0x08); //START sent I2C0TX_Byte(I2CSlaveAddr & 0xFE); //Send SlaveAddress + 0 to indicate a write. checkStatus(0x18);//SLA+W sent and ack recevied I2C0TX_Byte((startDataAddress & 0xFF00)>>8); //Send Word Address High byte first. (24xx64 needs 2 word address bytes)
  checkStatus(0x28); //High byte has been sent and ACK recevied
  I2C0TX_Byte(startDataAddress & 0xFF); //Now send the Low byte of word Address
  checkStatus(0x28); //Low byte has been sent and ACK recevied
  I2C0TX_Byte(data[count]); //Finally send the data byte.
  checkStatus(0x28); //Data Byte has been sent and ACK recevied
  startDataAddress++; //Increment to next address
I2C0SendStop(); //Send STOP since we are done.

//Now initiate write acknowledge polling as given on page 9 of 24LC64's datasheet
const int retryTimeout = 100;
for(int i=0; i < retryTimeout; i++)
{
I2C0SendStart();
checkStatus(0x08);
I2C0TX_Byte(I2CSlaveAddr & 0xFE);
if(I2C0STAT == 0x18) //ACK recieved which indicates completion of write cycle
{
I2C0SendStop();
//printf("Write Completed! for data = %c\n",data[count]);
goto OUT;
}
I2C0SendStop();
}
I2C0SendStop();
  printf("Warning: Write Poll Timeout! for data = %c\n",data[count]);
  OUT:; //Get us out of the loop.
}
return true;
}
bool I2C0ReadEEPROM(unsigned int startDataAddress, unsigned char *data , int length)
{
unsigned char RXData = 0;
for(int i=0; i < length;i++) { I2C0SendStart(); //Send START on the Bus to Enter Master Mode checkStatus(0x08); //START sent I2C0TX_Byte(I2CSlaveAddr & 0xFE); //Send SlaveAddress + 0 to indicate a write. checkStatus(0x18);//SLA+W sent and ACK recevied I2C0TX_Byte((startDataAddress & 0xFF00)>>8); //Send Word Address High byte first. (24xx64 needs 2 word address bytes)
  checkStatus(0x28); //High byte has been sent and ACK recevied
  I2C0TX_Byte(startDataAddress & 0xFF); //Now send the Low byte of word Address
  checkStatus(0x28); //Low byte has been sent and ACK recevied
  startDataAddress++; //Increment to next address  
  I2C0SendStart(); //Send Repeat START, since we are already in Master mode
  checkStatus(0x10); //Repeat START sent
  I2C0TX_Byte(I2CSlaveAddr | 0x01); //This makes SLA-RW bit to 1 which indicates read.
  checkStatus(0x40); //SLA-R has been Transmitted and ACK received.
  if(i != length-1) RXData = I2C0RX_Byte(false); //Send NACK for last byte to indicate we want to stop
else RXData = I2C0RX_Byte(true); //Send ACK for byte other than last byte to indicate we want to continue.

data[count++] = RXData; //Write recieved data to buffer
printf("Data='%c' ",RXData);

}
return true;
}
 
Top