View previous topic :: View next topic |
Author |
Message |
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
Will interrupt be serviced if it fires whilst DI and then EI |
Posted: Sun Jul 14, 2013 8:08 am |
|
|
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: 19546
|
|
Posted: Sun Jul 14, 2013 10:55 am |
|
|
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
|
|
Posted: Sun Jul 14, 2013 10:56 am |
|
|
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
|
|
Posted: Sun Jul 14, 2013 12:37 pm |
|
|
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
|
|
Posted: Sun Jul 14, 2013 2:08 pm |
|
|
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. |
|
|
|