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

I2c eeprom - works fine but odd problem with code or me?

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



Joined: 16 Aug 2014
Posts: 7

View user's profile Send private message

I2c eeprom - works fine but odd problem with code or me?
PostPosted: Thu Jun 28, 2018 8:56 am     Reply with quote

I have been testing CCS with I2c and a 24LC64 eeprom.
The I2c is working perfectly, I can write a byte to a memory location and read it back. Using a logic analyser, I can see that this works correctly. I am sending some debugging data over rs232 to a terminal and I am unsure whether the problem lies here or in my code. (I could just be dim today).
The program calls LCWrite and stores a character in location 5, it then calls LCRead to read location 5 which it does correctly. The value read is then returned to the main function where it always ends up as [00h], I guess this is Null. Where am I being dim?

Here's the terminal output when the program is run, the last item is always zero when it should be 'Z'):

Writing data Z 5 (store character 'Z' to location 5)
Reading data from 5 (read fromn location 5)
data is Z (the data read is 'Z')
Returned Data is [00] (the value returned to the main function)

_____________________________________________________
And here's the code:
Code:

#include <24LC64.h>

#use rs232(uart1, baud = 9600,xmit=PIN_C6,rcv=PIN_C7))
#use I2C(master,sda=PIN_C4,scl=PIN_C3)
#use delay(clock = 20000000)

BYTE LCRead(unsigned int);
void LCWrite(unsigned int , BYTE );
byte sendchar='Z';
byte recvchar='X';
unsigned int Addr=5;

//********************************************

void main()
{

LCWrite(Addr,sendchar);
recvchar=LCRead(Addr);
printf("%s %c","\nReturned Data is ",recvchar); // always gets null incorrectly

}

//*******************************************

void LCWrite(unsigned int Addr, BYTE data)
{
BYTE AddrHi,AddrLo;

AddrHi=(BYTE) (Addr/256);

AddrLo=(BYTE) (Addr-(Addr*256));

printf("%s %c %u","\nWriting data  ",data,Addr);  //reports correctly

i2c_start();
i2c_write(0xA0);     // Device address
i2c_write(AddrHi);
i2c_write(AddrLo);
i2c_write(data);
i2c_stop();

delay_ms(20);

}

//***************************************

BYTE LCRead(unsigned int Addr)
{
BYTE data='_';
BYTE AddrHi,AddrLo;

AddrHi=(BYTE)(Addr/256);
AddrLo=(BYTE) (Addr-(AddrHi*256));

printf("%s %u","\nReading data  from",Addr);  // reports correctly

i2c_start();
i2c_write(0xA0);
i2c_write(AddrHi);
i2c_write(AddrLo);
i2c_start();
i2c_write(0xA1);     // Device address

data=i2c_read();

i2c_stop();

delay_ms(10);

printf("%s %c","\ndata is",data); // reports the correctly read character

return(data);  // always ends up as null in the main function

}
HnC



Joined: 28 Jun 2018
Posts: 2
Location: India

View user's profile Send private message

Re: I2c eeprom - works fine but odd problem with code or me?
PostPosted: Thu Jun 28, 2018 9:46 am     Reply with quote

Maybe casting from byte to char is needed.
_________________
HnC
skywest



Joined: 16 Aug 2014
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 10:02 am     Reply with quote

Thanks, yes I have tried that, no luck there. As the printf in i2cRead displays the correctly read value, something is going wrong when it returns that value to the main function where it ends up as null. I've tried using pointers etc, nothing changes. I'm missing something simple.
HnC



Joined: 28 Jun 2018
Posts: 2
Location: India

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 10:25 am     Reply with quote

skywest wrote:
Thanks, yes I have tried that, no luck there. As the printf in i2cRead displays the correctly read value, something is going wrong when it returns that value to the main function where it ends up as null. I've tried using pointers etc, nothing changes. I'm missing something simple.


zip and post complete project files. I will test it here by debugging.
_________________
HnC
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: I2c eeprom - works fine but odd problem with code or me?
PostPosted: Thu Jun 28, 2018 10:40 am     Reply with quote

skywest wrote:

unsigned int Addr=5;

This is wrong. You're using an 18F4520 (I asssume this from your
previous thread on May 13). For the PCH compiler, an unsigned int
holds 8 bits, which is 0 to 255. Your address requires 16 bits, so you
should use int16.

skywest wrote:

void main()
{
LCWrite(Addr,sendchar);
recvchar=LCRead(Addr);
printf("%s %c","\nReturned Data is ",recvchar); // always gets null incorrectly

}

You need to put while(TRUE); at the end of main(). If you don't, the PIC
will hit a hidden Sleep instruction (inserted by the compiler) and the PIC
will shut down before it sends all the serial data. Your output will appear
to be cut off.


skywest wrote:

void LCWrite(unsigned int Addr, BYTE data)
{

Again, fix the 'Addr' declaration.

skywest wrote:

BYTE AddrHi,AddrLo;

AddrHi=(BYTE) (Addr/256);

AddrLo=(BYTE) (Addr-(Addr*256));

This is overly complicated.
It could be done like this:
Code:
AddrHi = (Addr >> 8);
AddrLo = (int8)Addr;

or, by using the CCS make8() function:
Code:

AddrHi = make8(Addr, 1);
AddrHi = make8(Addr, 0);


skywest wrote:

delay_ms(20);

It doesn't take 20 ms to do a write operation. Per the 24LC64 data sheet,
it takes a maxium of 5 ms.




Regarding the read routine:
skywest wrote:

BYTE LCRead(unsigned int Addr)
{

Fix the size for 'Addr'.

Quote:
AddrHi=(BYTE)(Addr/256);
AddrLo=(BYTE) (Addr-(AddrHi*256));

Simplify this.

Quote:
printf("%s %u","\nReading data from",Addr);

The %u must be changed to %lu when you change 'Addr' to int16.

Quote:

i2c_start();
i2c_write(0xA0);
i2c_write(AddrHi);
i2c_write(AddrLo);
i2c_start();
i2c_write(0xA1); // Device address

data=i2c_read();

i2c_stop();

delay_ms(10);

The last i2c_read() in a read operation must do a NACK. This is specified
in CCS by using a 0 parameter in i2c_read(). Edit that line to fix this.
Also, there is no delay required after a read. You are just slowing down
your code. Remove the delay.
skywest



Joined: 16 Aug 2014
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 11:54 am     Reply with quote

Thanks, that's really useful stuff and seems to reflect many of the software issues I have been seeing.

This is based old code I wrote in 2003, I'm trying to port from my old compiler (wiz c) which was used with an 18f452. Worked fine there, but I guess that was because it was an 18f452?.
What has been throwing me, is that when I stick a logic analyser on the bus, it is perfect, the write is good and the timing protocol is perfect, correct data is read back. Weird.
Anyway, I will make all the changes you suggest and hopefully it will fix it up.
Ttelmah



Joined: 11 Mar 2010
Posts: 19551

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 12:02 pm     Reply with quote

No. The same problems would have been there on the 452. Were you using the same size EEPROM?. The code would have basicically 99% worked for something like a 2408 rather than a 64.
skywest



Joined: 16 Aug 2014
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 12:58 pm     Reply with quote

Yes, in fact the devices I'm using I have pulled from those old boards. Worked fine and also similar for reading and writing a DS1307 registers and it's internal memory. Just for interest, this is the working wiz-C code I'm trying to port. I'll make your suggested changes to the CCS code tomorrow, I think that will move me forward.
Code:

//***********************************************************
// Read Data From memory
//***********************************************************

BYTE LCRead(unsigned int Addr)
{

BYTE AddrHi,AddrLo,data;

AddrHi=(BYTE)(Addr/256);
AddrLo=(BYTE) (Addr-(AddrHi*256));

QuickStop();

TRISC&=~(1<<SDABit);

IIWrite(0xA0,IISTART|IIACK);
IIWrite(AddrHi,IIACK);
IIWrite(AddrLo,IIACK|IISTOP);

IIWrite(0xA1,IISTART|IIACK);
TRISC|=(1<<SDABit);

data=IIRead(!IIACK|IISTOP);

Wait(READDELAY);

return(data);

}

// *************************************************************
// write data to memory
//***********************************************************

void LCWrite(unsigned int Addr, BYTE data)
{
BYTE AddrHi,AddrLo;

AddrHi=(BYTE) (Addr/256);

AddrLo=(BYTE) (Addr-(Addr*256));

QuickStop();

TRISC&=~(1<<SDABit);

IIWrite(0xA0,IISTART|IIACK);
IIWrite(AddrHi,IIACK);
IIWrite(AddrLo,IIACK);

IIWrite(data,IIACK|IISTOP);

Wait(WRITEDELAY);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19551

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 1:10 pm     Reply with quote

OK. Obviously the default size for an integer in Wiz-C is an int16. That would then have allowed the code to 99% possibly work, however the old code must have had something that generated the NACK. Missed in translation somewhere.

Yes. That is what this does:

(!IIACK|IISTOP)

The !IIACK tells the command to send a NACK. 'Not acknowledge'.
skywest



Joined: 16 Aug 2014
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 2:54 pm     Reply with quote

Thanks so much Ttelmah for all your help.

Changed the ints to 16 bit
Added the NACK
Added the while(TRUE);

Now works fine.!
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jun 28, 2018 3:41 pm     Reply with quote

just a comment... but CCS does supply several 'drivers', 2432.c comes to mind as a possible 'look see how it's done' ?

Jay
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