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 Problems

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



Joined: 30 Mar 2008
Posts: 109
Location: New Jersey

View user's profile Send private message

I2C Problems
PostPosted: Thu Feb 11, 2010 10:04 am     Reply with quote

Hi. I'm having a problem with using the 18F6723 as an I2C slave. Here is the relevant code:

Code:

#use i2c (slave, sda=PIN_C4, scl=PIN_C3, address=0xA0, FORCE_HW, stream=IC_PHASE)


Code:

#INT_SSP
void I2C_PhaseInterrupt ()
{
  int    state;

  state = i2c_isr_state (IC_PHASE);

  if (state < 0x80)    // Master is sending data
      bPhaseChange = true;
  else                      // Master is requesting data from slave
      i2c_write (IC_PHASE, 0);  // master should never request data
                                // but send something if it does...
}


Then in the main loop when the flag is found to be set:

Code:

  int    word [3];
  SINT   i = 0;
  long   t;

  for (t=0; t < 10000; ++t) {
      if (i2c_poll (IC_PHASE)) {
          word [i] = i2c_read (IC_PHASE);
          ++i;
      }
      if (i > 2)    // expecting 3 bytes
            break;
  }


First, I don't always get an interrupt when I send the data. Sometimes the interrupt is every other time, other times I can have to send data several times before I get the interrupt. I can make no sense of this.

Second, when I do get an interrupt, very often the first i2c_poll returns true, as expected, but then hangs forever when i2c_read is called.

Sometimes I get only one byte, and very rarely all three. I do have pullups on the I2C lines, and in addition the data I do get is always correct, so I don't think it is a hardware problem on the bus.

I am sending the data via a USB to I2C device called "USB to I2C Pro", made by a company called I2C Tools. The API call I am using is called I2CWriteByte, and it expects the address, a sub address, and a data byte. I expected to only receive two bytes, the sub address and data bytes, but it turns out that (when it works) I get 3 bytes, the address, the sub address, and the data byte.

Is it normal that I would actually receive the address value? I thought the I2C interrupt on address match would consume the address value and only deliver subsequent data bytes?

Can anyone shed any light on why the i2c_poll function returns true but then there is no data, or why there would be no data in the first place once an interrupt is received???

Thanks, Russ
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 11, 2010 12:59 pm     Reply with quote

Use the i2c slave program shown in this post. See if your adapter will
work with this code:
http://www.ccsinfo.com/forum/viewtopic.php?t=39242&start=6
Ttelmah
Guest







PostPosted: Thu Feb 11, 2010 3:30 pm     Reply with quote

As for 'why', to start the transaction, the master must send the slave address (you don't show this). The slave then interrupts, with the address byte _waiting to be read_. You are not reading this byte. This then leaves the slave in an invalid state. Basically, like any device dealing with hardware, you _must_ perform the expected service for the data being handled. If you look at the CCS example, you will see that it reads the address byte, allowing the code to progress to the next stage.

Best Wishes
russk2txb



Joined: 30 Mar 2008
Posts: 109
Location: New Jersey

View user's profile Send private message

I2C Problems
PostPosted: Thu Feb 11, 2010 6:51 pm     Reply with quote

Ttelmah, thanks. I don't show the master code because it is not in a PIC. It is sent from a PC through the USB to I2C converter. But it is obvious that the address is being sent, else I would not get an interrupt.

Also, I am reading the address byte. I am reading 3 bytes. The only thing I am doing different is to do the actual reads outside of the interrupt handler. Interrupt handlers should be fast, so I just set a flag and then do the actual reading when the main program loop detects the flag.

My question was why the address was there to be read. I can see no reason for it, since we already know what address was received - else we would not have gotten the interrupt. So I did not expect this. All I really wanted was confirmation that the address byte is expected.

Also the example code does not indicate that the byte being read (in the interrupt handler) is the address. So I thought it was reading a data byte.

None of this explains why the program hangs trying to do i2c_read, after getting a true return from i2c_poll.

Tomorrow I am going to get a good storage scope hooked up on the bus so I can see exactly what is being sent. That may give me some clues.

Thanks again, Russ
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