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

Question about I2C between pics and SSP Interrupt blocking

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



Joined: 03 May 2007
Posts: 42

View user's profile Send private message

Question about I2C between pics and SSP Interrupt blocking
PostPosted: Thu Oct 30, 2008 4:03 pm     Reply with quote

SO TO SUM UP:

I HAVE to respond to an input within 2msec. My SSP on my slave device takes about 25mSec in its SSP_ISR to respond.

What ideas do you have to get around this so that even if the slave PIC is in the middle of its 25mSec response, I can poll the input pin within 2mSec and not miss it changing state?





Hello All,

I have a question for you:

I have a PIC18F65J10 which works perfectly with a PIC18F44J10 using I2C except for one problem:


Whenever the PIC18F65J10 asks the PIC18F44J10 for data, the ISR() on the PIC18F44J10 takes too long to respond, too long being about 25mSeconds to send 1 byte of data. The 25mSeconds isn't really the problem--the problem is that I must react within 4mSec to an input pin going high. When the SSP gets pinged, the main program loop gets blocked and because the response takes 25mSec, I miss my input pulse sometimes.


The PIC18F65J10 uses the software I2C on the hardware pins (not using the force_hw.)


The PIC18F44J10 is set to be a slave and is using the SSP_isr().


Is there a way that I can have the PIC18F44J10 NOT use the SSP_isr() and still get my data back to the PIC18F65J10?

My problem is that the ssp_isr() is interrupting my main routine which polls an I/O pin.

The I/O pin timing is critical and the PIC18F44J10 must respond to it within 1-2msec, the i2c timing is not critical at all and can take whole seconds to pass data.

can I do something like:


Code:

unsigned int address = 0x80;
unsigned int data = 0xFF;
unsigned int temp;
BOOLEAN one_msec_flag = FALSE;

#INT_TIMER0
void timer0_isr()
{   //when this expires 1 millisecond has passed
   one_msec_flag = TRUE;
}




#INT_SSP
void i2c_isr()
{
   temp = i2c_isr_state();
}




while(1)
{
   if (one_msec_flag)
   {
      task_scheduler();
   }
}



void task_scheduler(void)
{   
   //THIS CHECKING OF INPUT B2 IS TIME CRITICAL.
   if(input(PIN_B2))
   {
      output_bit(PIN_D1, 0);
   }
   else
   {
      output_bit(PIN_D1, 1);
   }

   //THIS DATA RESPONSE TO THE MASTER IS NOT TIME CRITICAL
   if (i2c_poll())
   {   //if we have been asked for data, respond.
      if (temp == address)
      {   //our address has been pinged and the master wants a  data response
         i2c_write(data);
      }
   }
   one_msec_flag = FALSE;
}
Ttelmah
Guest







PostPosted: Thu Oct 30, 2008 4:29 pm     Reply with quote

Are you sure you mean mSec, not uSec?....

Don't call an ISR at all. Assuming you do mean 'uSec', probably 50% of the time involved, is actually getting into, and out of the ISR, not what you are doing inside it.
You will need to enable the option on the slave I2C, to implement 'clock stretching'. Look in the data sheet, I don't know how this is done in the 65J chip. Then have the I2C interrupt _disabled_, and in the main loop, as often as you can, poll the interrupt flag, at times when you are going to be able to service it. When it sets, call your 'handler' for the I2C.
The clock stretching option, means the I2C transaction will be 'held', pending service.

Best Wishes
davefromnj



Joined: 03 May 2007
Posts: 42

View user's profile Send private message

PostPosted: Thu Oct 30, 2008 4:34 pm     Reply with quote

Ttelmah wrote:
Are you sure you mean mSec, not uSec?....

Don't call an ISR at all. Assuming you do mean 'uSec', probably 50% of the time involved, is actually getting into, and out of the ISR, not what you are doing inside it.
You will need to enable the option on the slave I2C, to implement 'clock stretching'. Look in the data sheet, I don't know how this is done in the 65J chip. Then have the I2C interrupt _disabled_, and in the main loop, as often as you can, poll the interrupt flag, at times when you are going to be able to service it. When it sets, call your 'handler' for the I2C.
The clock stretching option, means the I2C transaction will be 'held', pending service.

Best Wishes



Sadly... I mean mSec.

If I issue a command that gets ACK'd to the Slave ISR lasts for about 20uSeconds.


If I issue a command to request data, the Slave ISR lasts for 25mSeconds.


The master unit is using the software I2C on the hardware I2C pins.
The slave unit is using the hardware I2C and the SSP_ISR.
davefromnj



Joined: 03 May 2007
Posts: 42

View user's profile Send private message

PostPosted: Thu Oct 30, 2008 4:41 pm     Reply with quote

Ttelmah wrote:
Are you sure you mean mSec, not uSec?....

Don't call an ISR at all. Assuming you do mean 'uSec', probably 50% of the time involved, is actually getting into, and out of the ISR, not what you are doing inside it.
You will need to enable the option on the slave I2C, to implement 'clock stretching'. Look in the data sheet, I don't know how this is done in the 65J chip. Then have the I2C interrupt _disabled_, and in the main loop, as often as you can, poll the interrupt flag, at times when you are going to be able to service it. When it sets, call your 'handler' for the I2C.
The clock stretching option, means the I2C transaction will be 'held', pending service.

Best Wishes





I get what you're saying, but doesn't that mean that the Master unit is now locked (stuck in its I2C_ISR) until the slave lets go of the clock pin?

Or since the master is using the software I2C, will it's own timers expire appropriately---

Basically, one pin on the master and slave will get toggled potentially at random, for 2 msec. Both the master and slave PICs must respond to it.

However, the Master also needs to get the status of the slave, and to send it other commands.

Sending commands only ties up the slave's ISR for about 20uSeconds.

Asking it for data takes like 25mSec.

But BOTH the master PIC and slave PIC must respond to the timecritical input pin.
davefromnj



Joined: 03 May 2007
Posts: 42

View user's profile Send private message

i2C_POLL()
PostPosted: Thu Nov 13, 2008 10:02 am     Reply with quote

hello all,

I am having some trouble with the i2c_poll() funciton.

I don't want to use the SSP_ISR because it ties up my slave processor too long.

So I wrote a really quick slave routine that looks like:

Code:



// The master sends the following, once per second:

i2c_start();
i2c_write(0xA2);
i2c_write(0x22);  //This is a command asking the slave for status.
i2c_start();
i2c_write(0xA3);
test_byte = i2c_read();
i2c_stop();




// Note, I have not enabled the I2C interrupts because I don't want to use them on the slave. 
//The slave Address is 0xA2.

while(1)
{
     test_func();
}

void test_func(void)
{
   int test_dat = 0;
   CKP = 1;
   if (i2c_poll())
   {   
      test_dat = i2c_read();
      if (test_dat == 0xA3)
      {
         printf("0xA3 \r\n");
         printf("R/w = %X \r\n", RW);
         printf("D/A = %X \r\n", DA);
         i2c_write(0x00);
         i2c_stop();
      }
      else if (test_dat == 0xA2)
      {
         printf("0xA2 \r\n");
         printf("R/w = %X \r\n", RW);
         printf("D/A = %X \r\n", DA);
      }
      else
      {

      }







Can anyone tell me why the R/W bit in the SSPxSTAT always reads "0" and so does the D/A bit?

Shouldn't the D/A bit change state when i2c_poll() returns 0xA2, or 0xA3?

Shouldn't the R/W bit change state?

What am I missing?[/code]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 13, 2008 10:15 am     Reply with quote

Quote:
// The master sends the following, once per second:

i2c_start();
i2c_write(0xA2);
i2c_write(0x22); //This is a command asking the slave for status.
i2c_start();
i2c_write(0xA3);
test_byte = i2c_read();
i2c_stop();

You must do a 'NAK' on the last read. It's part of the i2c spec.
Add a 0 parameter to that call.
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