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

Help with external EEPROM code

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PhilWinder



Joined: 16 Apr 2005
Posts: 23

View user's profile Send private message

Help with external EEPROM code
PostPosted: Sat May 14, 2005 8:09 pm     Reply with quote

hi, ive been trying to get some example code working and i cant quite get there. Ive had a play with some simpler code and got it working, but now when i re-wrote it with multi-read it doesnt work even though i have used the same 'bones'.

heres the code and the serial output to look at:

--------------===========Main Code=========----------
Code:


#include <18F458.h>

#fuses HS, NOWDT, NOPROTECT, PUT, NOBROWNOUT, NOLVP, NOWRT
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS, FORCE_SW, INVERT)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)


#include "24x512 Driver.c"






void init_ext_eeprom()
{
   setup_adc_ports(ADC_OFF);
   setup_comparator(NO_ANALOGS);
   Setup_CCP1(CCP_OFF);
   Setup_CCP2(CCP_OFF);

   output_float(PIN_C4);
   output_float(PIN_C3);

}



void main(void) {

char test[20];
char returned[20];
int  testsize,i;

init_ext_eeprom();
delay_ms(500);

strcpy(test,"This is a test!!!");
testsize = sizeof(test);

printf("\n\rWriting to EEPROM: %S, Size = %u",test,testsize);

delay_ms(6);
printf("\n\r%u",WriteExtMem(1,test,testsize,1));
delay_ms(6);
printf("\n\r%u",WriteExtMem(1,test,testsize,2));
delay_ms(6);
printf("\n\r%u",WriteExtMem(1,test,testsize,3));

delay_ms(6);
printf("\n\rReading....");
delay_ms(6);
printf("\n\r%u",ReadExtMem(1,returned,testsize,1));
printf("\n\rData returned: %S",returned);
delay_ms(6);
printf("\n\r%u",ReadExtMem(1,returned,testsize,2));
printf("\n\rData returned: %S",returned);
delay_ms(6);
printf("\n\r%u",ReadExtMem(1,returned,testsize,3));
printf("\n\rData returned: %S",returned);
delay_ms(6);

}


----------=============24x512 Driver===========-----------
Code:

//------------------------------------
// Write to External EE-Prom
//------------------------------------
int WriteExtMem(int16 Address, char *data, int16 length, int chip_number)
{
   int i;
   disable_interrupts(global);
   i2c_start();

   switch (chip_number)
      {
      case 1: if(i2c_write(0b10100000)) return 2;          //Write to Chip 1
              else break;
      case 2: if(i2c_write(0b10100010)) return 3;          //Write to Chip 2
              else break;
      case 3: if(i2c_write(0b10100100)) return 4;          //Write to Chip 3
              else break;
      }

                             
   if (i2c_write(make8(Address,1)) || i2c_write(make8(Address,0))) return 5;
   for (i=0; i<length; i++)         
   {
      if(i2c_Write(*Data++)) Return 6;

   }
   i2c_stop();
   enable_interrupts(global);
   return 1;

}


//------------------------------------
// Read to External EE-Prom
//------------------------------------
int1 ReadExtMem(int16 Address, char *data, int16 length, int chip_number)
{


   int i;
   disable_interrupts(global);
   i2c_start();

   switch (chip_number)
      {
      case 1: if(i2c_write(0b10100000)) return 2;          //Write to Chip 1
              else break;
      case 2: if(i2c_write(0b10100010)) return 3;          //Write to Chip 2
              else break;
      case 3: if(i2c_write(0b10100100)) return 4;          //Write to Chip 3
              else break;
      }

   if (i2c_write(make8(Address,1)) || i2c_write(make8(Address,0))) return 5;
   i2c_start();
   
   switch (chip_number)
      {
      case 1: if(i2c_write(0b10100001)) return 6;          //Read from Chip 1
              else break;
      case 2: if(i2c_write(0b10100011)) return 7;          //Read from Chip 2
              else break;
      case 3: if(i2c_write(0b10100101)) return 8;          //Read from Chip 3
              else break;
      }

   

   for( i = 0; i < length-1 ; i++) *Data++ = i2c_read(1);  //read all but last data byte
   *Data = i2c_read(0);     //read last data byte (with NoACK)
   i2c_stop();
   enable_interrupts(global);
   return 1;
}


----------------===========Terminal Ouput=======---------
Code:

\0A                                                                                 
Writing to EEPROM: This is a test!!!, Size = 20\0A                                 
1\0A                                              \0D                               
1\0A\0D                                                                             
1\0A\0D                                                                             
Reading....


============-------------------------================

as you can see it seems to hang, just as it starts reading.

any ideas?????

cheers, phil
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 15, 2005 1:27 am     Reply with quote

I didn't try to analyze your entire code and find out what's wrong with it,
but in scanning it I did notice a couple things.

1. Your routines are declared to return an "int1", but within the routines,
you're returning all sorts of non-boolean values. You need to change
the routines so they return an "int8".

2. In your R/W routines, you've declared an "int i", which is an unsigned
8-bit value in CCS. Then later in the routines, you're comparing
this 8-bit value to a 16-bit "length" variable. That's not right.

3. Your EEPROM chips have addresses of 0, 1, and 2, but you're
passing chip addresses of 1, 2, and 3 to the routines.

There may be other errors.
-----------
If you want to find out where something is locking up, one quick way
is to insert putc() statements after every important line of code in
your routine. See the lines shown in bold below. Your terminal
window may show something like ABCDEFG, and then you know
that it's locking up at the line after the "G". Then you can investigate
why.

int1 ReadExtMem(int16 Address, char *data, int16 length, int chip_number)
{
int i;
putc('A');
disable_interrupts(global);
putc('B');
i2c_start();
putc('C');
switch (chip_number)
{
case 1: if(i2c_write(0b10100000)) return 2; //Write to Chip 1
else break;
case 2: if(i2c_write(0b10100010)) return 3; //Write to Chip 2
else break;
case 3: if(i2c_write(0b10100100)) return 4; //Write to Chip 3
else break;
}
putc('D');
if (i2c_write(make8(Address,1)) || i2c_write(make8(Address,0))) return 5;
putc('E');
i2c_start();
putc('F');

switch (chip_number)
{
case 1: if(i2c_write(0b10100001)) return 6; //Read from Chip 1
else break;
case 2: if(i2c_write(0b10100011)) return 7; //Read from Chip 2
else break;
case 3: if(i2c_write(0b10100101)) return 8; //Read from Chip 3
else break;
}
putc('G');
for( i = 0; i < length-1 ; i++)
*Data++ = i2c_read(1); //read all but last data byte
putc('H');
*Data = i2c_read(0); //read last data byte (with NoACK)
putc('I');
i2c_stop();
putc('K');
enable_interrupts(global);
putc('L');
return 1;
}
PhilWinder



Joined: 16 Apr 2005
Posts: 23

View user's profile Send private message

PostPosted: Sun May 15, 2005 7:21 am     Reply with quote

Hi, thanks for the reply. Although i have now changed the things you suggested, without the changes, it still worked. whether thats ccs compensating or it never happened to clash i dont know. But just to be sure ;-)

As for the last point, I looked at the chips as "chip number 1" etc. but it just so happened that chip number 1 had an address of 0, chip number two had an address of 1 etc. there a switch select routine in the driver to decide which chip to send it to.

what i did do was put the putc('A') stuff in and i finally managed to find that for some reason, when i took the first chip out of the routines, chips 2 and 3 then suddenly worked perfectly.

i then thought that the wiring was wrong, but it was fine, so the chip must be a dud. wrong again. i swapped a working chip for that and it didnt work again.

basically, whenever i set the address to 000 then it wouldnt work. WHY?????? the datasheet mentions nothing about this fact and says that it should be able to handle 8 address, i.e. 0->7.

does anyone know why?? because i was planning on using as many chips as i possibly could, and it would be silly not to be able to use address 0.

Thanks Mr. Programmer Smile

Phil
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 15, 2005 2:03 pm     Reply with quote

You're right about the case stuff. I was looking a little too hard for bugs.

1. If you put in the code for Chip 0, at what line does it lock-up ?

2. Have checked the hardware for Chip 0 ? Are all three of the
address lines grounded ? Does it have power and ground ?
Have you accidently write-protected the device by tying the
WP pin to Vcc ?
PhilWinder



Joined: 16 Apr 2005
Posts: 23

View user's profile Send private message

PostPosted: Sun May 15, 2005 4:01 pm     Reply with quote

hi again, yeah ive checked the hardware, and its fine. it works as long as i change it to binary 011.

it locks up just before the second start bit ie. i2c_start(); or in your code, point E.

inccidently, why do i have to do the second start bit??? and the second address code???

cheers. this ones baffled me.

phil
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 15, 2005 4:21 pm     Reply with quote

Quote:
inccidently, why do i have to do the second start bit??? and the second address code???

cheers. this ones baffled me.

It's your driver. Mr. Green I was just giving tips on coding problems
that I saw in it.

It appears that you're trying to do some sort of Ack polling at
the start of your write routine. But it doesn't wait in a loop
until you get an Ack, it just bails immediately if you don't get one.

You should look at how CCS does it in their write routine:
Code:
void write_ext_eeprom(long int address, BYTE data)
{
   short int status;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(address>>8);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();

// Wait until the write operation is finished.   Do this by "Ack Polling".
   status=i2c_write(0xa0);
   while(status==1)
   {
   i2c_start();
   status=i2c_write(0xa0);
   }
}
PhilWinder



Joined: 16 Apr 2005
Posts: 23

View user's profile Send private message

PostPosted: Sun May 15, 2005 6:18 pm     Reply with quote

ok, good point, i was looking to do this in a later revision, so thats why i put all the delays in the main() code, so i dont have to take the polling into consideration. And obviously it isnt foolproof, since it just might not work, but this doesnt take into account the fact that the first chip didnt work, the others did, change the address and vuala.

Moving on the actual polling though, would i have to 'poll' every write? or just at the end of all the writes since the ccs driver doesnt write multi-byte's and does the same go for the read?? because again, the ccs version doesnt include polling (in the read)??

cheers again,

phil
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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