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 Read problem. First read = junk. Second is fine!

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



Joined: 11 Jan 2004
Posts: 45

View user's profile Send private message Visit poster's website

I2C Read problem. First read = junk. Second is fine!
PostPosted: Sun Apr 04, 2004 7:46 pm     Reply with quote

PIC: 16F876
i2c device: TEA5768HL, a Phillips FM receiver IC

I'm having some trouble getting the proper response from the phillips IC the first time i read from it. After i complete the first read i print out the values i received and then i try it again. The second time it works properly.

I don't seem to have any problems writing to the device.

Also, this behavior only happens on the first read in the program which gets the initial status of the chip. After that first read all subsequent reads work fine.

Circuit details: i also have an i2c eeprom on the i2c bus which works perfectly.

PULLUPS: are only 1k ohm. I found on the forum looking for an answer to my problem that they should be at least 1.6k. (i used 1k because of the following ccs faq )

Code:

#define RADIO_I2C_WRITE_ADDR 0xC0
#define RADIO_I2C_READ_ADDR 0xC1

main()
{
    init_ext_eeprom();
    delay_ms(100);
   
    readRadioSettings();
    printRadioSettings(); // <-- prints FF for each of the 5 data bytes

    readRadioSettings();
    printRadioSettings(); // <-- prints valid data
}


#use i2c (Master, sda = PIN_C4, scl = PIN_C5, SLOW)

void init_ext_eeprom(void)
{
output_float(PIN_C4);
output_float(PIN_C5);
}

void readRadioSettings()
{
   i2c_start();
   radio.readAck = i2c_write(RADIO_I2C_READ_ADDR);
   radio.readDataByte1 = i2c_read(1);
   radio.readDataByte2 = i2c_read(1);
   radio.readDataByte3 = i2c_read(1);
   radio.readDataByte4 = i2c_read(1);
   radio.readDataByte5 = i2c_read(1);

   //i2c_stop();   // no stop bit for the TEA5768hl on reads
   return;
}



Is this a problem that could really be caused by pullup resistors or possibly a compiler bug?

Thanks,
~blake
_________________
"Everything should be made as simple as possible, but not one bit simpler" -- Albert Einstein

http://www.blakerobertson.com
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 04, 2004 9:49 pm     Reply with quote

This routine is wrong:

void readRadioSettings()
{
i2c_start();
radio.readAck = i2c_write(RADIO_I2C_READ_ADDR);
radio.readDataByte1 = i2c_read(1);
radio.readDataByte2 = i2c_read(1);
radio.readDataByte3 = i2c_read(1);
radio.readDataByte4 = i2c_read(1);
radio.readDataByte5 = i2c_read(1);

//i2c_stop(); // no stop bit for the TEA5768hl on reads
return;
}

It should be like this, I would think. The data sheet is very poor.
It doesn't give bit diagrams for the i2c transactions. What it does
have, is incomplete. Try this:
Code:
void readRadioSettings()
{
   i2c_start();
   radio.readAck = i2c_write(RADIO_I2C_READ_ADDR);
   radio.readDataByte1 = i2c_read();
   radio.readDataByte2 = i2c_read();
   radio.readDataByte3 = i2c_read();
   radio.readDataByte4 = i2c_read();
   radio.readDataByte5 = i2c_read(0);   // Note the 0 parameter.
   i2c_stop();                // Yes, you need a stop.
}


Also, you should not let your programs fall off the end of main().
They will hit a Sleep instruction that CCS inserts there. Add a while(1)
statement to prevent this. See below.

main()
{
init_ext_eeprom();
delay_ms(100);

readRadioSettings();
printRadioSettings();

readRadioSettings();
printRadioSettings();
while(1); // Add this line.
}

Additional comments:
1. Normally, you would use pins C4 and C3 for i2c. This gives you
the option to use hardware i2c, if you decide to do that later.
2. Make sure you have NOLVP at the end of your #fuses statement.
(Unless you are using low voltage programming -- but most people
don't).
blak3r



Joined: 11 Jan 2004
Posts: 45

View user's profile Send private message Visit poster's website

PostPosted: Mon Apr 05, 2004 12:43 am     Reply with quote

The Philips datasheet is lacking indeed!

I'll have to check my notes that are at the lab but i originally had the code like you listed below.

I think including the stop bit caused it to read the next data byte incorrectly (the first data byte of the second read). I got to the current version of code based on what seemed to work the best.


Quote:

(PIC1687x Datasheet)

RC3/SCK/SCL bit3 ST RC3 can also be the synchronous serial clock for both SPIand I2C modes.

RC4/SDI/SDA bit4 ST RC4 can also be the SPI Data In (SPI mode) or data I/O (I2C mode).

RC5/SDO bit5 ST Input/output port pin or Synchronous Serial Port data output.


grr! I meant to use hardware spi but apparently i misread the datasheet. The "can also" i think through me off and since RC5 pin says Synchronous so i guess i just glanced over the rest of it assuming it was referring to a clock pin not a serial transfer method.

Thanks for pointing that out!
_________________
"Everything should be made as simple as possible, but not one bit simpler" -- Albert Einstein

http://www.blakerobertson.com
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