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 slave isr too slow?

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







I2C slave isr too slow?
PostPosted: Wed Oct 18, 2006 10:00 am     Reply with quote

Has anybody found the I2C slave isr to take too long on a 16C717, working at 4MHz with a 100KHz bus?

I experienced problems using an I2C slave interface a little bit more complex than the EX_SLAVE.C example. I went through some debugging and tests, arriving at the original example not working properly either on my platform.

The behavoir is that after a couple of tries sending write messages of three bytes (addr+index+data) there is a NACK and it doesn't work any more.

For a 100KHz I2C bus, there is about 100uS from byte to byte. I've put some pin signaling and the isr user code starts executing 40 or 65 uS after the byte reception is completed, and the isr takes 80uS the first time and about 35 uS the following. Of course, these timmings include some overhead due to the output_high() and output_low() calls, but still there seems not to be enough margin to assure the byte readings to be done in time, and the SSP reception buffer overflows.

--Should we expect the isr code to start 65 instruction cycles after the event, and take 80 cycles to execute, when only 100 cycles are avaliable?

--I'm using ICE2000, could the problem be at the emulator, or may be a compiler user code) problem?

I would really appreciate any comments on your experiences with slave i2c at 4MHz PIC16CXXX, or any opinion on this problem. The exact example is attached.


Thanks,
Santi

Code:

#include <16C717.h>

#fuses INTRC_IO, NOWDT, MCLR
#use delay(clock=4000000)
#use i2c(SLAVE, SCL=PIN_B2, SDA=PIN_B4, FORCE_HW, SLOW, ADDRESS=0x68)
#use fixed_io(b_outputs=PIN_B7)

BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt ()
{
   BYTE incoming, state;

   output_high(PIN_B7);
   state = i2c_isr_state();
   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte is address
         address = incoming;
      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
   output_low(PIN_B7);

}

void main ()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while (TRUE) {}
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 18, 2006 11:55 am     Reply with quote

Look at the .LST file. I count at least 50 instruction cycles just to get
in and out of the isr. At 4 MHz, that's 50 usec. (The interrupt dispatcher
code starts at 0x0004).

I don't know why it takes 65 usec to get into the ISR. I only count
about 30 instruction cycles in the "entry" portion of the CCS interrupt
dispatcher code. (And about 20 cycles on the "return" side).

It's possible that there is some bug in the ICE. There are some,
as shown in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=21731
Guest








PostPosted: Thu Oct 19, 2006 9:56 am     Reply with quote

Thanks for your cycle counting. I tried using the trace and trigger output of the ICE2000, and interesting things came out.

First of all:

Quote:
It's possible that there is some bug in the ICE.


We've programmed an OTP device and it behaves exactly the same.

After tracing and scoping:

Where it takes much longer than expected is to execute the first i2c_read() because the BF flag of SSPSTAT is not set, despite the address has already been received. The i2c_read() therefore waits for the next byte, instead of processing the address (doing nothing) and leaving the isr.

The BF is not set, because for some reason i2c_isr_state() is already reading SSPBUF (testing the R/W bit instead of doing this in SSPSTAT) and therefore the BF flag goes zero before the i2c_read().

I've already posted the customer support about this, and I wonder whether it could it be that the i2c built in functions have changed and no reading has to be done after the address reception?

What do you think about this?
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