Monday, January 28, 2013

Fast Interrupt Request on LPC2148

In this blog post, we shall be looking at how to use the Fast Interrupt reQuest (FIQ) on the NXP ARM micro-controller LPC2148. If you are new to interrupts on LPC2148, then please go through the previous post which describes the basic Interrupt mechanism and goes in depth into Vectored Interrupt Requests and Non-Vectored Interrupt Requests.

Implementing FIQs using Keil uVision is a little more complicated compared to Vectored and Non-vectored IRQs because the IDE defines a default (dummy) Interrupt Service Routine for FIQs. This can be seen in the startup.s file that is created when a new project is made. In order to replace this with a custom ISR, follow the steps mentioned below.
  1. Configure the Interrupt as FIQ - Set the bit corresponding to the desired interrupt to 1 in VICIntEnable (to enable the interrupt) and VICIntSelect (to configure as FIQ) registers. Also modify the GPIO registers and the concerned peripheral registers accordingly.
  2. Defining the ISR - Make a new function in the main.c file with no arguments and a void return value. This will act as the ISR. Let the function prototype be void FIQ_ISR (void);
  3. Add the ISR to startup.s file - Search for the following portion of the code in startup.s
Vectors         LDR     PC, Reset_Addr         
                LDR     PC, Undef_Addr
                LDR     PC, SWI_Addr
                LDR     PC, PAbt_Addr
                LDR     PC, DAbt_Addr
                NOP                            ; Reserved Vector 
;               LDR     PC, IRQ_Addr
                LDR     PC, [PC, #-0x0FF0]     ; Vector from VicVectAddr
                LDR     PC, FIQ_Addr

Reset_Addr      DCD     Reset_Handler
Undef_Addr      DCD     Undef_Handler
SWI_Addr        DCD     SWI_Handler
PAbt_Addr       DCD     PAbt_Handler
DAbt_Addr       DCD     DAbt_Handler
                DCD     0                      ; Reserved Address 
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler

Undef_Handler   B       Undef_Handler
SWI_Handler     B       SWI_Handler
PAbt_Handler    B       PAbt_Handler
DAbt_Handler    B       DAbt_Handler
IRQ_Handler     B       IRQ_Handler
FIQ_Handler     B       FIQ_Handler
The line FIQ_Addr DCD FIQ_Handler (line 18 above) gives the name of the default address for the FIQ ISR. The following changes need to be made to the file in order to use the custom ISR.
  • Replace the name FIQ_Handler with the name of the ISR in the code. In our case the name is FIQ_ISR.
  • Since the compiler does not know the location of FIQ_ISR during compilation, we need to indicate that it is located in some other file in the project and can be found during linking. we use the IMPORT directive (anywhere before the FIQ_Addr) for this purpose.
The modified file looks as follows:
Vectors         LDR     PC, Reset_Addr         
                LDR     PC, Undef_Addr
                LDR     PC, SWI_Addr
                LDR     PC, PAbt_Addr
                LDR     PC, DAbt_Addr
                NOP                            ; Reserved Vector 
;               LDR     PC, IRQ_Addr
                LDR     PC, [PC, #-0x0FF0]     ; Vector from VicVectAddr
                LDR     PC, FIQ_Addr

    IMPORT FIQ_ISR
Reset_Addr      DCD     Reset_Handler
Undef_Addr      DCD     Undef_Handler
SWI_Addr        DCD     SWI_Handler
PAbt_Addr       DCD     PAbt_Handler
DAbt_Addr       DCD     DAbt_Handler
                DCD     0                      ; Reserved Address 
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_ISR

Undef_Handler   B       Undef_Handler
SWI_Handler     B       SWI_Handler
PAbt_Handler    B       PAbt_Handler
DAbt_Handler    B       DAbt_Handler
IRQ_Handler     B       IRQ_Handler
FIQ_Handler     B       FIQ_Handler 
Note the tab before the IMPORT statement. The compiler gives a syntax error in the absence of the tab.

Save the file, build the code and you are all set to go!

No comments:

Post a Comment