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

How can a slave determine the end of the I2C transaction?

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



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

How can a slave determine the end of the I2C transaction?
PostPosted: Wed Apr 09, 2008 2:58 am     Reply with quote

Colleagues,

Slave PIC is receiving a handful of different commands from the master. Commands have parameters that are transmitted with them, and different commands have different amount of parameters (different number of bytes). The slave needs to trigger the execution of the command as soon as command+parameters are received. SSP hardware causes an interrupt on each byte. Is it legal to sample the SDA and SCL lines at the end of the SSP ISR? For example (I’m trying this code as I write this post):

Code:

#INT_SSP
void ssp_interupt()
{
   iI2Cstate = i2c_isr_state();
   if (0 < iI2Cstate && iI2Cstate < 0x80)
   {
      g_sI2Cin.buff[i] = i2c_read();
      if (input(SDA) && input(SCL))      // End?
         g_iFlag = 1;      // main() has a fast loop.  It will quickly pick up this flag and execute the command
   }
   // ...
}


P.S. I already see a problem. By the time the SSP ISR is complete, the original transaction could be over, but the new one was started, and both I2C lines are not high. Is there another way (except transmitting the lengths or hard-coding it into the slave)?
_________________
Read the label, before opening a can of worms.
Matro
Guest







PostPosted: Wed Apr 09, 2008 3:14 am     Reply with quote

Look if the stop bit of SSPSTAT register is set.
But I think that is better to put in the code the length of each command for checking purpose.

Matro
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Wed Apr 09, 2008 3:30 am     Reply with quote

Matro wrote:
Look if the stop bit of SSPSTAT register is set.

Thanks, Matro! Checking the bit definitely sounds like less of a hack, than sampling the SCL and SDA.

Out of curiosity. There’s a function i2c_isr_state(), which returns a byte. The MSbit behaves like a R/W# bit of the SSPSTAT. The lower 7 bits behave like a counter, which increments with each byte received or sent. Does this counter exist in hardware or software?

Matro wrote:
But I think that is better to put in the code the length of each command for checking purpose.

I know, but I want to keep the length of the command to a minimum.
_________________
Read the label, before opening a can of worms.
Matro
Guest







PostPosted: Wed Apr 09, 2008 3:47 am     Reply with quote

kender wrote:
Matro wrote:
Look if the stop bit of SSPSTAT register is set.

Thanks, Matro! Checking the bit definitely sounds like less of a hack, than sampling the SCL and SDA.

Out of curiosity. There’s a function i2c_isr_state(), which returns a byte. The MSbit behaves like a R/W# bit of the SSPSTAT. The lower 7 bits behave like a counter, which increments with each byte received or sent. Does this counter exist in hardware or software?

The counter is purely software and is generated by the CCS "i2c_isr_state()" function.

Quote:

Matro wrote:
But I think that is better to put in the code the length of each command for checking purpose.

I know, but I want to keep the length of the command to a minimum.

The classical way is just to store data in an array and set/clear a flag in the isr. Then data processing is done in the main() function. ;-)
CCS i2c isr generation sometimes causes troubles because the interrupt flag is cleared when isr exits. You can avoid that by coding your isr like that:
Code:

#int_SSP NOCLEAR
void i2c_isr(void)
{
  clear_interrupt(int_SSP);
  //code continues
}


Matro.[/code]
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Wed Apr 09, 2008 4:04 am     Reply with quote

Matro wrote:
Code:

#int_SSP NOCLEAR
void i2c_isr(void)
{
  clear_interrupt(int_SSP);
  //code continues
}


I didn’t realize that such a tight control over the interrupt flag is possible.

Is it possible to receive the whole I2C transaction with just one interrupt? The interrupt would occur when the address is received, then the bytes are read in the loop until the stop condition. Just thinking outloud.
_________________
Read the label, before opening a can of worms.
Matro
Guest







PostPosted: Wed Apr 09, 2008 4:15 am     Reply with quote

kender wrote:
Matro wrote:
Code:

#int_SSP NOCLEAR
void i2c_isr(void)
{
  clear_interrupt(int_SSP);
  //code continues
}


I didn’t realize that such a tight control over the interrupt flag is possible.

Is it possible to receive the whole I2C transaction with just one interrupt? The interrupt would occur when the address is received, then the bytes are read in the loop until the stop condition. Just thinking outloud.

That's possible but I don't think it's the way to do because with such a way all code execution will be locked during i2c receiving. Neither the main application nor other interrupt(s) can execute during the time you are waiting for the stop condition.

Matro.
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