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 support@ccsinfo.com

External interrupt queueing

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



Joined: 07 Feb 2006
Posts: 16

View user's profile Send private message Send e-mail AIM Address

External interrupt queueing
PostPosted: Sun Oct 26, 2008 5:54 pm     Reply with quote

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








PostPosted: Sun Oct 26, 2008 7:58 pm     Reply with quote

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.
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