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.
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.
- 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.
- 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);
- 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_HandlerThe 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_HandlerNote 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!