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