|
|
View previous topic :: View next topic |
Author |
Message |
corbico
Joined: 23 Jan 2007 Posts: 3
|
ssp interrupt latency |
Posted: Tue May 08, 2007 7:27 pm |
|
|
I'm using the following code to read spi input using an interrupt. The interrupt latency appears to be about 4.5uS from the last rising edge of the scl to the falling edge of the TEST1 pin in the isr.
Is there a way to reduce this time?
Code: | #include <18F8722.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40M, oscillator=10M)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
#use spi(BITS=8,MSB_FIRST)
int8 instr;
#define TEST1 PIN_B2
#int_ssp
void ssp_isr(void)
{
output_low(TEST1);
instr = spi_read();
output_high(TEST1);
}
void init_pic (void) {
// setup TRI-State registers
set_tris_b(0b11000101); output_b(0b11100111);
set_tris_c(0b10011000); output_c(0b11111111);
setup_spi(spi_slave | spi_h_to_l);
printf("\r\nCompiled, %s %s\r\n", __DATE__, __TIME__);
}
void main(void)
{
init_pic();
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(true)
{
output_low(TEST1);
output_high(TEST1);
}
} |
|
|
|
Ttelmah Guest
|
|
Posted: Wed May 09, 2007 2:32 am |
|
|
Yes, but it means _you_ will need to go through the assembler generated by the routines inside the assembler, and work out which registers must be saved.
When an interrupt occurs, on the very next instruction (assuming interrupts are not disabled), the int_global handler is called. This is normally provided for you by the compiler, and it then saves every register that may be 'in use', and once this is done, proceeds to test the interrupt flags of every enabled interrupt (in the order they are defined, or in the order set by #priority, if present). This code then vectors to the defined 'handler'. So you get the overhead, of saving all the registers, and the extra 'testing'. Typically about 30 to 40 instructions on the 18chips!. Now, provided no other interrupt handler is being used, the 'test' is unecessary, and you can write your code directly into the #int_global routine. You can also use 'retfie 1' on this, so that the basic W register, status, and bank select register are saved/restored by the hardware. However you still need to save any other registers that are used. Typical ones are things like the table read registers, if any array access, or 'switch' statement is used. In your simple example, I'd suspect you will be OK (you only access one variable, not using an array), so all you should need to do, would be to transfer the value from the SSP register to the temporary store, _clear the interrupt_ (remember in int_global, _you_ need to do this), and perform a retfie 1. I'd suggest it'd probably be fractionally faster, to simply read the contents of the SSP data register, rather than using the 'ssp_read' function. The CCS code, checks to see if data is available before reading, and in an interrupt handler, this isn't necessary, since the fact that the interrupt has triggered, implies that the data is available!...
You should be able to get the total latency below half a uSec this way.
Best Wishes |
|
|
|
|
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
|