LPC2387 GPIO interrupt latency

Started by "ger...@yahoo.gr [lpc2000]" December 17, 2014
Hi everyone I have found that a GPIO interrupt sharing EXTINT3 with the highest priority has about 60usec. latency instead of EXTINT3 pin.
Can this feature be fixed?Is there any method?
I am trying to interface a barcode reader and I am loosing always the 1st clock.
I am using gcc gnu arm with eclipse IDE.

Thanks In Advance

An Engineer's Guide to the LPC2100 Series

I don't know how you defined your interrupt routine or which compiler you are using but GCC generates quite a bit of preamble code to save and restore a bunch of registers.

So, if you are using GCC, consider having the function prototype include the attribute 'naked'. This eliminates any entrance and exit code. Now you are responsible for saving and restoring any registers that are used. This makes sense if the interrupt code is written in assembly language. Trying to outguess the C compiler on register usage is almost destined to fail.

GCC attributes used in the RTOS implementation http://www.freertos.org/implementation/a00013.html

GCC attributes used in the RTOS implementation http://www.freertos.org/implementation/a00013.html Using GCC attributes to prevent the compiler inserting code into the RTOS interrupt prologue.

View on www.freertos.org http://www.freertos.org/implementation/a00013.html
Preview by Yahoo

Pipelined processors won't necessarily have the lowest possible latency. It depends on how the designers decided to handle the queue. They could abort all instructions in progress (not likely) or just jam a branch instruction into the beginning of the queue instead of the next sequential instruction. I don't have any idea how it is done on the ARM processors. Still, 60 uS seems like a long time.

In the LPC2148, there are two ways to reach a pin: The standard GPIO and the Fast IO. How a pin is connected internally makes a very big difference on the rate at which a pin can be toggled. I don't know if this applies to the interrupt system but it probably does.

The LPC2378 has a similar structure. See if there is something in the User Manual re: Fast IO.

Hi Richard,

Thanks for your response.
All IO pins are configured as FIO. In my assembly startup file I have done some changes in my previous projects (with no time critical interrupts) and all seem to be OK.

I have tried "naked" attribute with ISR_ENTRY() & ISR_EXIT() defs but the same results.

Here is a link with some files of my project:

https://www.sendspace.com/file/7wux9h https://www.sendspace.com/file/7wux9h

In s_irq.c gile in ISR_EINT3 you will see that when the gpio interrupt occurs I disable the Interrpt and after that I am changing the state of an other GPIO. This change takes about 60us from the first clock that comes from the barcode reader. Look at (GPIRQ_DisableInterrupt(KW_CLK_PRT, KW_CLK_PIN);

If some one can help I would be greatful.

Thanks In Advance

What happens if you write the shortest possible piece of code to acknowledge the interrupt and toggle a pin? Get rid of all other code and especially other interrupt code. The new project would probably be less than 100 lines of code INCLUDING crt.s

You have a LOT of interrupt processing going on for other interrupts and I haven't looked to see if they could overlap or if they are of higher priority.

Also, if you aren't using FIQ for your short latency interrupt, you should be. See section 7.5 here:

http://www.nxp.com/documents/data_sheet/LPC2387.pdf http://www.nxp.com/documents/data_sheet/LPC2387.pdf

Good morning Richard,

What happens if you write the shortest possible piece of code to acknowledge the interrupt and toggle a pin? I think I am missing what do you mean.The are 3 or 4 GPIO plus EXTINT (HIGHEST PRIORITY ISR)pin that are sharing the same ISR. The pin toogling is just for testing in osciloscope when I realized that I have long latency
Get rid of all other code and especially other interrupt code.
Each case is an other pin (interrupt) source. If I missunderstand make your code suggestion.
Thank you for your time!
Regards Chris
Somehow I thought you only had one time-critical input. I realize that there are a lot of interrupts in your project.

When I try to troubleshoot things, I strip the code to the fewest possible lines required to demonstrate the problem. One pin, one interrupt, nothing else. That way, I know what the hardware will do in the best case.

BTW, toggling pins is not something the ARM does well even with Fast IO. Try writing a loop and see how fast you can get the pin to change state. You may be surprised that it won't toggle at MHz rates.

It used to be so grim for GPIO that they had to invent the FIO setup.

60 uS has to be some sort of issue with IO. Any reasonable interrupt overhead like pushing registers can't take that long (assuming CCLK is reasonable and you are using internal memory, and you aren't getting interrupted by something else)

I've had cases where the peripheral Clock rate made a difference. Look at peripheral Clock rate for all peripherals you access during the interrupt. And keep peripheral register access to a minimum.
I wonder if you can use a capture timer to determine the real interrupt latency.

An external signal causes the capture register to load the current timer value but, AFAIK, it doesn't stop the timer. This capture event can cause an interrupt if desired (and it is).

Read the time again in the interrupt routine and subtract the captured value. A wee bit of arithmetic and the actual latency will be determined.

Clock rates and prescaler values come into play but it's a start.