CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem using i2c with 24lc256
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bill147



Joined: 26 Oct 2004
Posts: 13

View user's profile Send private message

Problem using i2c with 24lc256
PostPosted: Tue Oct 26, 2004 10:39 am     Reply with quote

I am using a 18f452 with a 24lc256 eeprom. The i2c code is basically from the 24256.c file except it is modified to do a sequencial read of 64 bytes.

The unit will run ok for several hours then when a read of 64 bytes is done all 64 bytes in the eeprom get changed to 255.

I am using 2.2k pullup resistors. The problem is seen using different eeproms and is also seen using different circuit boards and different 18f452s.

I have made a test program that constantly reads 64 bytes from the same eeprom location so I can see the error without waiting hours. It seems to read the data ok for several thousand times before the problem shows up.

If I disable all interrupts the problem seems to be worse. If I use slow i2c mode it takes longer for the problem to show up.

I have also inserted a 50ms delay between reads but this did not help.
I have also tried to read the bytes by looping to read 1 byte at a time. With this test the bytes that changed were random in the block of 64 bytes.

Also this same circuit board has been used with a 16f877 and a 24c65. In this case the code was written in assembly not with a compiler and no problem was ever reported in 2 years.

Any ideas.

Bill
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 26, 2004 11:48 am     Reply with quote

It could be any number of things, depending on the version of the
compiler or the silicon rev of the 18F452.

It seems to me that you have too many variables to narrow it
down to any particular part, at this point. For example, you said it
worked previously, but that was with a 24c65. If you could take
the same 24LC256 chip, and make it work with the PCM compiler
and a 16F877, then we'd know that the EEPROM was OK. Then it
could be either the 18F452 or PCH. This assumes that the same
test board was used, as well. The goal is to narrow it down to one
specific thing, and then study it in detail, until the problem is found.

Can you post the version of your compiler, and a short test program
that shows the problem ? Please post all compiler directives and
pre-processor statements, as well.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 26, 2004 2:35 pm     Reply with quote

A highly suspect
Quote:
The i2c code is basically from the 24256.c file except it is modified to do a sequencial read of 64 bytes
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Tue Oct 26, 2004 3:45 pm     Reply with quote

Quote:

I have made a test program that constantly reads 64 bytes from the
same eeprom location so I can see the error without waiting hours. It
seems to read the data ok for several thousand times before the problem
shows


Could you pls post your test code, the hardware involved in such tests
and the way you retrieve, compare and validate the readed data from the
external EEPROM?

Humberto
Guest








PostPosted: Wed Oct 27, 2004 3:23 am     Reply with quote

I had similar problems when WP-pin was left floating. Manual says you can left it floating but in my board wires from Pic to eeprom were 10cm long and causes errors occasionally. WP connected to ground solved problem. Also address pins can do same with long wires.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Oct 27, 2004 6:49 am     Reply with quote

The WP shouldn't cause strange data to be written to the eeprom. It could toggle between write and write protect but that's not going to write data. Now if the I2C lines had noise, then that's another problem.
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed Oct 27, 2004 8:29 am     Reply with quote

Make sure that your eeprom ACK's before you try to read from it. If you simply send a i2c_start() and then a i2c_write() without checking if it ACK'd then you will get garbage. Make something like an if() statement, something like:

i2c_start();
if(!i2c_write(address))// address is the eeprom address
{
// insert the rest of the code to read the eeprom here
}

This will check to see if the i2c_write() returned an ACK, if it doesn't then have it loop around and try again until it does. There might be noise or something that is causing the eeprom to receive the incorrect data and not think that it was addressed. If this is the case then you will read 255 for each read. If you do a i2c_write() always check to see if the device ACK'd. Don't simply continue on and assume that it did.

Ronald
bill147



Joined: 26 Oct 2004
Posts: 13

View user's profile Send private message

PostPosted: Wed Oct 27, 2004 10:34 am     Reply with quote

Thankyou for the replies.
My compiler version is 3.180
What makes this hard is that the unit runs ok for an hour or more before the problem shows up.

This unit has a LCD display that is used to show the data read from the eeprom. Also I am using an ICD debugger so I can see the data read.

I have used a 24lc256 with a different batch number and also I have tested with a 24lc65 all with the same results.

The following is some of my code:
Code:

#use delay(clock=8000000)
#fuses NOWDT,WDT128, HS, BROWNOUT, BORV27, PUT, STVREN, NOLVP
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors)
#use i2c(Master,slow,sda=PIN_A4,scl=PIN_A5)

port_b_pullups(TRUE);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF); // set to OFF for testing
   setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_TIMER3);
   enable_interrupts(INT_RDA);

void read_ext_eeprom_blk(long int address, char *buf, byte eep) {
   // read 64 bytes from eeprom
   
   byte data;
   int i;
   eep <<= 1;
   i2c_start();
   i2c_write(0xa0+eep);
   i2c_write(address>>8);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1+eep);
   for(i=0;i<63;i++) buf[i]=i2c_read();
   buf[i]=i2c_read(0);
   i2c_stop();
   init_ext_eeprom();
}



This is my test program
Code:

for(j=0;j<256;j++) // check and compare buffers for call change
      {
       restart_wdt();
       ladr=192;
       read_ext_eeprom_blk(ladr,bufe,0);
       delay_ms(10);


I have used this same pcboard with a single line LCD display for over 2 years and this problem was never seen. With this single line display unit all code was written in assembly instead of using a compiler.

I also have a 16f870 connected to the same eeprom with its io port set as input. As I said above the single line display unit never showed this problem.

I am now using the compiler to change this unit to a 4 line display version with additional features, that is why I am using the 18f452.

On this new version I also used the compiler for the code in this 16f870.
It now seems that this may be where the problem is. I have removed this IC and now the unit has been running over 10 hours without the problem. The 16f870 is used to add another serial port for the purpose of programming the eeprom. Of course I have handshaking lines between the 2 processors to control access to the eeprom. I am now going to work with the code in the 16f870 to try to solve this problem.

Bill
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Oct 27, 2004 10:47 am     Reply with quote

So you have 2 devices connected to the eeprom?? If so, then definitely your code needs some work. There is no error checking at all. You are also not checking for an ACK from the device when attempting to communicate with it.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Oct 27, 2004 12:21 pm     Reply with quote

Quote:

#fuses NOWDT,WDT128,

You are setting NO WATCH DOG TIMEOUT
AND then WATCH DOG TIMEOUT every 128ms
the compiler take the last one only


Quote:

enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER3);
enable_interrupts(INT_RDA);


I would disable all this timers while testing external EEPROM


Quote:

for(j=0;j<256;j++) // check and compare buffers for call change
{
restart_wdt();
ladr=192;
read_ext_eeprom_blk(ladr,bufe,0);
delay_ms(10);


I guess that this function return a byte:
read_ext_eeprom_blk(ladr,bufe,0);
Where do you store the readed data? Are you store them in a buffer?

hope this help,

Humberto
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Oct 27, 2004 12:28 pm     Reply with quote

He stores them in the buffer passed in
Code:
void read_ext_eeprom_blk(long int address, char *buf, byte eep) {
bill147



Joined: 26 Oct 2004
Posts: 13

View user's profile Send private message

PostPosted: Wed Oct 27, 2004 1:34 pm     Reply with quote

I have used the code from the file 24256.c
It seems that from the posts that this is not good code.
I gather from what is written that the first i2c_write after the start bit should make sure an ACK is returned. I do not know what other error checking could be done. My problem is not reading incorrect data but it is that the data inside the eeprom is getting changed during the read. But this only happens maybe once in an hour.

I have tried disableing the interrupts but if any thing the problem got worse.

I am using setup_wdt(WDT_OFF) to disable WDT for testing.
I have thought that WDT128 sets the watchdog clock to divide by 128.

It now seems to me that the second processor at times is putting some noise on the line. I am now thinking I should write code to use the 2 handshaking lines between the processors to transfer data so that only 1 processor will read and write to the eeprom. I can then disconnect the other processor from the eeprom.

Bill
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 27, 2004 2:02 pm     Reply with quote

Quote:
I have used the code from the file 24256.c
It seems that from the posts that this is not good code.

I wouldn't say that. But you're running a Multi-Master situation,
which you didn't initially tell us. So you have possible bus contention.


One other thing. In a post above, you said you're using a 18F452.
In this line, I see a possible problem:
#fuses NOWDT,WDT128, HS, BROWNOUT, BORV27, PUT, STVREN, NOLVP
The BORV27 implies that your Vdd voltage is 3.3v. Is it ?
If so, the 18F452 data sheet says that you must use the "LF" version
of the PIC, to run at that voltage. See Figures 22-1 and 22-2:
http://ww1.microchip.com/downloads/en/DeviceDoc/39564b.pdf
The lowest voltage that you can run with the non-LF version of
the PIC is 4.2v.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Oct 27, 2004 2:38 pm     Reply with quote

With one master, you don't really have to worry about bus collisions. In a multi-master you do since both devices could be talking at the same time.

Now think about this. What is the real difference between reading 64 bytes of data and writing them. A 1 on the end of the device address. Lets suppose some other device pulled the line low during this bit. The result would be the data line held high and 64 bytes being clocked. This would write 0xFF to 64 bytes in the eeprom. If you want to test this theory, you could set your read to a smaller amount and see if the number of 0xFF's decreases. You can also increase the number of reads and the 0xFF's should remain at 64 bytes since that is the largest page write. You could also offset the data to not be aligned with the page boundries. You can read across pages but not write across them. The pointer will wrap and the data in front should get corrupted in theory.
bill147



Joined: 26 Oct 2004
Posts: 13

View user's profile Send private message

PostPosted: Thu Oct 28, 2004 8:25 am     Reply with quote

I have now found my problem. The 16f870 processor had a problem which caused it output pulses to the eeprom every couple of seconds.
After this was corrected it all works fine now.

Thankyou for all your replys.

Bill
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group