Check my understanding of LPC2000 interrupts

Been studying the user manuals and things don’t seem to be laid out as plainly as I would hope, or maybe everything is right in front of me and I’m just not seeing it. Anyway, this is my understanding of LPC2000 interrupts and the VIC. Please comment and/or correct.

The ARM core still just has the two HW interrupts, FIQ and IRQ, with vectors to those interrupts living in low memory (skipping over any memory remapping for now). But all the LPC2000 interrupt sources can only reach one of the two ARM interrupt routines via the VIC. Any interrupt source can be mapped in the VIC as an FIQ, a vectored IRQ or a non-vectored IRQ.

On an interrupt the VIC passes the interrupt request to the ARM core as either a FIQ or IRQ, depending on how that interrupt was configured. At the same time, for IRQs, it makes the previously-supplied address of the interrupt handler available via VICVectAddr. It is up to the IRQ routine to read this address and branch to the handler code. After the handler code is finished, I suppose it can either do the interrupt return itself or return to the IRQ code which does the interrupt return.

Lastly, my understanding is that I can set up my FIQ and IRQ handlers either in asm or in C (gcc) using e.g.

void f () attribute ((interrupt (“IRQ”)));

I’ll stop here and wait for some feedback. Many thanks for any comments.

Mike

kk6gm:
Anyway, this is my understanding of LPC2000 interrupts and the VIC.

Which particular devices are you planning to use? 'LPC2000' may be too general for the level of detail that you are discussing. While the general principles are similar there are specific differences when using the VIC in LPC21xx/22xx MCUs compared to using the VIC in LPC23xx/24xx MCUs.

While the NXP User Manuals are indispensable as reference guides, Application Notes etc. are more useful for explanations of the concepts involved. For example:

  • An overview of interrupt handling is included in NXP Application Note AN10381 “Nesting of Interrupts in the LPC2000”.

  • A summary of VIC changes is included in NXP Application Note AN10576 “Migration to the LPC2300/2400 Family”.

Both of these can be downloaded from:

http://www.standardics.nxp.com/support/ … pe=appnote

  • Straightforward explanations of LC2xxx features like the VIC are included in the Hitex ‘Insider’s Guides’ that you can download from:

http://www.hitex.com/index.php?id=downl … ers-guides

Sorry for the lack of clarity. Right now I’ve got an LPC2294 board I want to experiment with, and I’m also looking at designing some hardware around the LPC2103.

I’ll go take a look at Hitex site, thanks for the pointer.

Mike

kk6gm:
The ARM core still just has the two HW interrupts, FIQ and IRQ, with vectors to those interrupts living in low memory (skipping over any memory remapping for now). But all the LPC2000 interrupt sources can only reach one of the two ARM interrupt routines via the VIC. Any interrupt source can be mapped in the VIC as an FIQ, a vectored IRQ or a non-vectored IRQ.

This is correct, there are only two hardware interrupt channels, and the VIC is responsible for handing out the vector to the appropriate routine to service it.

kk6gm:
On an interrupt the VIC passes the interrupt request to the ARM core as either a FIQ or IRQ, depending on how that interrupt was configured. At the same time, for IRQs, it makes the previously-supplied address of the interrupt handler available via VICVectAddr. It is up to the IRQ routine to read this address and branch to the handler code. After the handler code is finished, I suppose it can either do the interrupt return itself or return to the IRQ code which does the interrupt return.

Usually you would not vector the FIQ, as the point to it is to service it as quickly as possible. Usually you would only map one interrupt to the FIQ, and not fetch the vector from the VIC, instead you would just branch to the appropriate routine directly. Usually you would see an assembler instruction in the startup code like this in place of the IRQ vector (this is for a LPC2148, and I suspect yours would be the same):

ldr pc,[pc,#-0xFF0] // IRQ - read the VIC

This actually reads the vector from the VIC, and branches to it. So in essence, your VIC priority dispatcher is a single instruction. At the end of the interrupt routine, the PC register is restored from the LR (link register), which causes a return to mainline code.

kk6gm:
Lastly, my understanding is that I can set up my FIQ and IRQ handlers either in asm or in C (gcc) using e.g.

void f () attribute ((interrupt (“IRQ”)));

I wouldn’t recommend using this, unless you do not use optimization, as there is a well know bug in gcc that causes this to fail, sometimes… I can’t remember if maybe this is also only a problem with interworking enabled. It is better to use an assembler stub to just call a standard ‘C’ function (which can then be ARM or Thumb code). If this is done correctly, the stub function can also allow nested interrupts to be serviced. Join the LPC2000 group on Yahoo groups, as these topics are discussed regularly. The interrupt stub issue has been discussed many times, and there are even some code examples if you search the message archives.