LPC1768 EXT0 interrupt huge lag

Started by navman June 23, 2011
Hi,
I've setup LPC1768 for external falling edge interrupt on EINT0 pin and in
the interrupt handler, I just clear the interrupt flag and make a pin
(P0.0) low and immediately high again. When I check the EINT0 pin and the
output pin P0.0 on an oscilloscope, there is a huge lag, about 520ns
between the falling edge of EINT0 & the P0.0 becoming low.

I use the LPCxpresso complier and I confirm the LPC is running at full
100MHz (from the clkout pin). 

Here is the interrupt handler: 

=======================================================
void EINT0_IRQHandler (void)
{
	// Clear interrupt
	LPC_SC->EXTINT = EINT0_CLR;


	LPC_GPIO0->FIOCLR0|=0x01;//make P0.0 low 
	LPC_GPIO0->FIOSET0|=0x01;//make P0.0 high
}
=======================================================


Here is the disassembly from the compiler:

=======================================================
000001d8 <EINT0_IRQHandler>:

void EINT0_IRQHandler (void)
{
	// Clear interrupt
	LPC_SC->EXTINT = EINT0_CLR;
 1d8:	4b06      	ldr	r3, [pc, #24]	(1f4 <EINT0_IRQHandler+0x1c>)
 1da:	2201      	movs	r2, #1
 1dc:	f8c3 2140 	str.w	r2, [r3, #320]

	LPC_GPIO0->FIOCLR0|=0x01;//make P0.0 low

 1e0:	4a05      	ldr	r2, [pc, #20]	(1f8 <EINT0_IRQHandler+0x20>)
 1e2:	7f13      	ldrb	r3, [r2, #28]
 1e4:	f043 0301 	orr.w	r3, r3, #1	; 0x1
 1e8:	7713      	strb	r3, [r2, #28]
	LPC_GPIO0->FIOSET0|=0x01;//make P0.0 high
 1ea:	7e13      	ldrb	r3, [r2, #24]
 1ec:	f043 0301 	orr.w	r3, r3, #1	; 0x1
 1f0:	7613      	strb	r3, [r2, #24]
}
 1f2:	4770      	bx	lr
=======================================================

I cannot find out why it is taking so long. The number of instructions do
not add up to anywhere close to 500ns. Any ideas? 

	   
					
---------------------------------------		
Posted through http://www.EmbeddedRelated.com
On 06/23/2011 07:50 PM, navman wrote:

> I've setup LPC1768 for external falling edge interrupt on EINT0 pin and in > the interrupt handler, I just clear the interrupt flag and make a pin > (P0.0) low and immediately high again. When I check the EINT0 pin and the > output pin P0.0 on an oscilloscope, there is a huge lag, about 520ns > between the falling edge of EINT0& the P0.0 becoming low. > > I use the LPCxpresso complier and I confirm the LPC is running at full > 100MHz (from the clkout pin). > > Here is the interrupt handler: > > ======================================================= > void EINT0_IRQHandler (void) > { > // Clear interrupt > LPC_SC->EXTINT = EINT0_CLR; > > > LPC_GPIO0->FIOCLR0|=0x01;//make P0.0 low > LPC_GPIO0->FIOSET0|=0x01;//make P0.0 high > }
I don't know why it's taking so long, but you don't need to do a read-modify-write on the CLR and SET ports. The point of those ports is that you can clear and set bits by just writing the mask to them. So FIOCLR0 = 0x01 will clear a bit, and FIOSET0 = 0x01 will set it. Do you have other interrupts running ?
"navman" wrote:
>I've setup LPC1768 for external falling edge interrupt on EINT0 pin and in >the interrupt handler, I just clear the interrupt flag and make a pin >(P0.0) low and immediately high again. When I check the EINT0 pin and the >output pin P0.0 on an oscilloscope, there is a huge lag, about 520ns >between the falling edge of EINT0 & the P0.0 becoming low. >... >I cannot find out why it is taking so long. The number of instructions do >not add up to anywhere close to 500ns. Any ideas?
How long does it take to save the processor state before entering the ISR? -- Roberto Waltman [ Please reply to the group. Return address is invalid ]
On Thu, 23 Jun 2011 12:50:41 -0500, navman wrote:

> Hi, > I've setup LPC1768 for external falling edge interrupt on EINT0 pin and > in the interrupt handler, I just clear the interrupt flag and make a pin > (P0.0) low and immediately high again. When I check the EINT0 pin and > the output pin P0.0 on an oscilloscope, there is a huge lag, about 520ns > between the falling edge of EINT0 & the P0.0 becoming low. > > I use the LPCxpresso complier and I confirm the LPC is running at full > 100MHz (from the clkout pin). > > Here is the interrupt handler: > > ======================================================= void > EINT0_IRQHandler (void) > { > // Clear interrupt > LPC_SC->EXTINT = EINT0_CLR; > > > LPC_GPIO0->FIOCLR0|=0x01;//make P0.0 low > LPC_GPIO0->FIOSET0|=0x01;//make P0.0 high > } > ======================================================= > > > Here is the disassembly from the compiler: > > ======================================================= 000001d8 > <EINT0_IRQHandler>: > > void EINT0_IRQHandler (void) > { > // Clear interrupt > LPC_SC->EXTINT = EINT0_CLR; > 1d8: 4b06 ldr r3, [pc, #24] (1f4 <EINT0_IRQHandler
+0x1c>) 1da:
> 2201 movs r2, #1 > 1dc: f8c3 2140 str.w r2, [r3, #320] > > LPC_GPIO0->FIOCLR0|=0x01;//make P0.0 low > > 1e0: 4a05 ldr r2, [pc, #20] (1f8 <EINT0_IRQHandler
+0x20>) 1e2:
> 7f13 ldrb r3, [r2, #28] > 1e4: f043 0301 orr.w r3, r3, #1 ; 0x1 1e8: 7713
strb r3, [r2,
> #28] > LPC_GPIO0->FIOSET0|=0x01;//make P0.0 high > 1ea: 7e13 ldrb r3, [r2, #24] > 1ec: f043 0301 orr.w r3, r3, #1 ; 0x1 1f0: 7613
strb r3, [r2,
> #24] > } > 1f2: 4770 bx lr > ======================================================= > > I cannot find out why it is taking so long. The number of instructions > do not add up to anywhere close to 500ns. Any ideas? > > > > --------------------------------------- Posted through > http://www.EmbeddedRelated.com
You are going to loose 12 cycles just to get into the ISR. Plus another 4ns (or more) at the interrupt pin to recoginze the level. If you are using the standard LPCXpresso options your flash config is probably 6, so that is 60ns to read in a flash block. But that should only be on the first time into the ISR if nothing else is running to flush the flash cache. Driving the P0 io pin is going to take 3 to 5 ns plus what ever load you have on it. Still does not add up to 540 but start looking at external factors. Is your main loop just sitting in a loop waiting for the external interrupt or did you cob this test code into a more complex system?
Roberto Waltman <usenet@rwaltman.com> wrote:
> "navman" wrote: >>I've setup LPC1768 for external falling edge interrupt on EINT0 pin and in >>the interrupt handler, I just clear the interrupt flag and make a pin >>(P0.0) low and immediately high again. When I check the EINT0 pin and the >>output pin P0.0 on an oscilloscope, there is a huge lag, about 520ns >>between the falling edge of EINT0 & the P0.0 becoming low. >>... >>I cannot find out why it is taking so long. The number of instructions do >>not add up to anywhere close to 500ns. Any ideas? > > How long does it take to save the processor state before entering the > ISR?
The Cortex-M3 does that automatically, and IIRC takes 12 cycles if the RAM runs at full speed. At 100 MHz there will be some added latency from flash wait states (so if latency is critical you may not want to run these chips at full speed). The LPC1700 also has a prefetch buffer intended to hide some of the flash latency, but I don't know if it has any impact on interrupt latencies. -a
Just to answers questions above,

- No other interrupts are enabled.

- Its a standard LPCxpresso demo code modified to make P0.0 low-high inside
the interrupt. It is the "RDB1768cmsis_ExtInt" example found here:
http://support.code-red-tech.com/CodeRedWiki/RDB1768cmsisExampleProjects

- The code enables the interrupts sends a "Started" message to UART and
stays inside  while(1). 	   
					
---------------------------------------		
Posted through http://www.EmbeddedRelated.com
On Fri, 24 Jun 2011 05:54:26 -0500, "navman"
<naveen_pn@n_o_s_p_a_m.yahoo.com> wrote:

>Just to answers questions above, > >- No other interrupts are enabled. > >- Its a standard LPCxpresso demo code modified to make P0.0 low-high inside >the interrupt. It is the "RDB1768cmsis_ExtInt" example found here: >http://support.code-red-tech.com/CodeRedWiki/RDB1768cmsisExampleProjects > >- The code enables the interrupts sends a "Started" message to UART and >stays inside while(1).
FWIW, I'm seeing comparable delay on a 96 MHz LPC1768 with Rowley's CrossWorks compiler. I'd guess that it's a consequence of flushing the pipeline, though it would be interesting to see numbers from a non-gcc based compiler. -- Rich Webb Norfolk, VA
Is there any workaround/ideas to circumvent this lag? I feel cheated by the
Cortex-M3 spec which claims "12 cycles interrupt latency". 	   
					
---------------------------------------		
Posted through http://www.EmbeddedRelated.com
On 06/26/2011 06:26 AM, navman wrote:
> Is there any workaround/ideas to circumvent this lag? I feel cheated by the > Cortex-M3 spec which claims "12 cycles interrupt latency".
Try putting the ISR in RAM. Maybe the delay is caused by the flash access time.
Strictly for learning, you might use your assembler and set an interupt 
that puts a single pulse on one pin then exits. Put a loop in the main 
code that does nothing toggle another pin forever. Then use a scope to 
view both pins and, hopefully, get a clear idea of the delays both into 
and out of an interupt.

Hul

navman <naveen_pn@n_o_s_p_a_m.yahoo.com> wrote:
> Is there any workaround/ideas to circumvent this lag? I feel cheated by the > Cortex-M3 spec which claims "12 cycles interrupt latency". > > --------------------------------------- > Posted through http://www.EmbeddedRelated.com