|
|
View previous topic :: View next topic |
Author |
Message |
Santi Guest
|
I2C slave isr too slow? |
Posted: Wed Oct 18, 2006 10:00 am |
|
|
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
|
|
Posted: Wed Oct 18, 2006 11:55 am |
|
|
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
|
|
Posted: Thu Oct 19, 2006 9:56 am |
|
|
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? |
|
|
|
|
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
|