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

Will interrupt be serviced if it fires whilst DI and then EI

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



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

Will interrupt be serviced if it fires whilst DI and then EI
PostPosted: Sun Jul 14, 2013 8:08 am     Reply with quote

I am using a timer interrupt to keep a microsecond time value updated. The code below seems to work fine.

However as I turn the timers IE off whilst I compute the time value to be sure I don't get a corrupt value I was wondering what would happen when I re-enable the interrupt at the end.

i.e. If the interrupt fires whilst the interrupt is disabled will it be serviced after I enable it again ? I couldn't find an explicit answer in the datasheet.

I am using v4.141 and the PIC18F26K80.

Code:
// Timer2 Interrupt Enable Flag
#bit TMR2IE_FLAG=GETENV("BIT:TMR2IE")

// No of interrupts for the time given in useconds.
#define TT_INT_TM(us)   (us/200)

static int32 tt_us;
static int16 tt=TT_INT_TM(1000000);

// 200us Interrupt from T2
#int_timer2
void isr_timer2(void)
{
   // Keep the number us
   tt_us+=200;
   if(--tt) {
      if(tt==TT_INT_TM(500000)) {
         Sw1Led(LED_RED);
      }
   } else {
      Sw1Led(LED_GRN);
      tt=TT_INT_TM(1000000);
   }
}

// Get tick time as microseconds
// NOTE : no interrupt disable so possible value error if not disabled first
int32 tt_get_nodi()
{
   int32 us;
   us = tt_us + get_timer2();
   return(us);
}

// Get tick time as microseconds
// NOTE:disables interrupt
int32 tt_get()
{
   int32 us;
   boolean ie ;

   // Read the IE flag
   ie = TMR2IE_FLAG;

   // Turn interrupt off to be sure
   disable_interrupts(INT_TIMER2);

   // Compute the time in microseconds
   us = tt_us + get_timer2();

   // If interrupt was on turn it back on after
   if(ie) {
      enable_interrupts(INT_TIMER2);
   }
   return(us);
}

// Setup the tick timer
void tt_init()
{
   //setup up timer2 to interrupt every 200us if using 64Mhz clock
   // counter increments every 1us.
   setup_timer_2(T2_DIV_BY_16,199,1);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Sun Jul 14, 2013 10:55 am     Reply with quote

Yes.
It is in the data sheet. Key is that the enable, only enables 'servicing', not the actual interrupt flag. Hence you can have the interrupt completely turned 'off', but the interrupt flag will still become set. This is how you can poll the flags.
The handler is only called when the global enable is set, the individual enable is set, and the flag is set, but each enable does not affect the other layers. The timer interrupt flag is set, whatever the state of the enables, when the timer wraps.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 14, 2013 10:56 am     Reply with quote

Quote:
// Turn interrupt off to be sure
disable_interrupts(INT_TIMER2);

// Compute the time in microseconds
us = tt_us + get_timer2();

// If interrupt was on turn it back on after
if(ie) {
enable_interrupts(INT_TIMER2);


I was wondering what would happen when I re-enable the interrupt at the
end. If the interrupt fires whilst the interrupt is disabled will it be serviced
after I enable it again ?


If Timer2 overflows, the Timer2 interrupt flag will be set. Which means
latched. While the overflow itself is a transient condition, the fact that it
occurred is latched and held in the TMR2IF bit. So when your code above
executes the enable_interrupts(INT_TIMER2) line, the interrupt will occur.
The PIC will jump to the interrupt handler code and enter your #int_timer2
code.

Here's the pertinent section from the 18F26K80 data sheet. The operative
word is "latched":
Quote:
15.2 Timer2 Interrupt
Timer2 can also generate an optional device interrupt.
The Timer2 output signal (TMR2 to PR2 match) provides
the input for the four-bit output counter/postscaler. This
counter generates the TMR2 match interrupt flag, which
is latched in TMR2IF (PIR1<1>).


I notice Ttelmah beat me by 1 minute. I'll leave mine up anyway.


Last edited by PCM programmer on Sun Jul 14, 2013 10:58 am; edited 1 time in total
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Sun Jul 14, 2013 12:37 pm     Reply with quote

One additional comment - depending on timing etc, you need to be careful that it has not overflowed multiple times while servicing was disabled since you will then lose count - the interrupt request flag only says it has been set, not how many times it has been set.

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

PostPosted: Sun Jul 14, 2013 2:08 pm     Reply with quote

Thanks for the confirmation guys, thats save me having to scratch me head to think how to test this. Just goes to show how carefully you have to read datasheets before you can infer a meaning.
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