|
|
View previous topic :: View next topic |
Author |
Message |
bretesq
Joined: 07 Feb 2006 Posts: 16
|
External interrupt queueing |
Posted: Sun Oct 26, 2008 5:54 pm |
|
|
Hi,
I am interfacing with an external USB device which will hit an external interrupt on my PIC18F, however I am having a problem with the interrupt being too slow, it is missing other requests that need to be services by the ISR.
If I manually read out the EPIRQ register in my main loop I notice that some of those interrupt bits are still high and awaiting.
Is there a better way of setting up this ISR? Thank you!
Code: |
#int_ext1 NOCLEAR HIGH
void usb_isr(void) {
int8 itest1,itest2;
itest1 = h_read(rEPIRQ); // Check the EPIRQ bits
itest2 = h_read(rUSBIRQ); // Check the USBIRQ bits
debug_usb(debug_putc,"\r\nINT %x %x", itest1, itest2);
if ( (itest1 & bmSUDAVIRQ) ) { usb_check_rxev();} //SETUP tokens to us
if ( (itest1 & bmOUT0DAVIRQ) ) { usb_check_rxev();} //OUT0 tokens to us
if ( (itest1 & bmOUT1DAVIRQ) ) { usb_check_rxev();} //OUT1 tokens to us
if ( (itest1 & bmIN2BAVIRQ) ) { usb_check_txev();} //IN2 token was processed
if ( (itest1 & bmIN3BAVIRQ) ) { usb_check_txev();} //IN3 token was processed
if ( (itest2 & bmURESIRQ) ) { debug_usb(debug_putc,"\r\nURESIRQ");
h_write(rUSBIRQ, bmURESIRQ); } // Clear the IRQ
if ( (itest2 & bmURESDNIRQ) ) { debug_usb(debug_putc,"\r\nURESDNIRQ");
h_write(rUSBIRQ, bmURESDNIRQ); ENABLE_IRQS } // Clear the IRQ (Bus reset clear the IE bits)
if ( (itest2 & bmNOVBUSIRQ) ) { debug_usb(debug_putc,"\r\nNOVBUSIRQ");
h_write(rUSBIRQ, bmNOVBUSIRQ); } // Clear the IRQ
clear_interrupt(INT_EXT1);
}
|
|
|
|
Guest
|
|
Posted: Sun Oct 26, 2008 7:58 pm |
|
|
The quicker you can get out of the ISR, the better, as you cannot enter an ISR while already in one. You can still do all of these operations, but instead of calling them from the ISR, set a flag in the ISR, and then in your while(1) loop, poll the flag. Heres an example:
Code: |
#int_ext1
void ext1_isr()
{
if ( (itest1 & bmSUDAVIRQ) )
{
usb_check_rxev_flag = 1;
}
}
void main ()
{
while(1)
{
if(usb_check_rxev_flag)
{
usb_check_rxev();
}
}
}
|
Also, another suggestion I would make is that you can eliminate several of your if loops. Since there are several possible conditions that should result in calling the same function, you can logically OR the conditions together in one if statement. And since you are checking multiple bits of one byte, you can do a bitwise AND with the number that has all of bits you want to check against as a 1. So if you want to call usb_check_rxev() if certain bits of itest1 (lets say bits 0,1, and 2) are high. You would do something like this:
Code: |
if (itest1 & 0x07)
{
usb_check_rxev();
}
|
now, if atleast one of the bits is high, the expression evaluates to a non-zero value, making it true. This accomplishes the same thing, with less instructions. |
|
|
|
|
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
|