Hi every one, it was many day that I try to execute an FIQ Subroutine, but I couldn't, Finally I Found The Way.
every one who want to use FIQ routine in LPC23xx should follow this instruction as below:
1.Set The VICVectAddr[n] Register 2.Enable Interrupt by using VICIntEnable 3.Enable the module Interrupt 4.Select this interrupt as FIQ By VICIntSelect Register 4.Modify the LP2300.s as blow:
;----------------------------------------------------------------------- ; LPC2300.s Original File 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, #-0x0120] ; 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 EXPORT Reset_Handler Reset_Handler
;----------------------------------------------------------------------- ; LPC2300.s Modified File 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, #-0x0120] ; Vector from VicVectAddr LDR PC, [PC,#- relation address of VICVectAddr[n] from current PC Value by two address later] 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 ; This Line Should Be Commented 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 ; This Line Should Be Commented EXPORT Reset_Handler Reset_Handler
//--------------------------------------------------------------- !.For Example Set UART0 Interrupt routine as FIQ
//-- In C File
VICVectAddr6 = (DWORD)FIQ_Routin; //-- Set Handler Name U0IER |= 1; //-- Enable UART0 peripheral interrupt VICIntSelect |= 1<<6; //-- Select UART0 interrupt as FIQ VICIntEnable |= 1<<6; //-- Enable UART0 interrupt signal
now you need to calculate the relative address between the current PC Address And VICVectAdd6 address:
When an FIQ happens the ProgramCounterRegister(PC) jump to Address Of 0x1C and the Address Of VICVectAddr6 is 0xFFFFF118 so the relative address is: (calculation is in signed integer area) ("2*4" means that the addressing is 4-Byte Boundary so to address later is 2*4 Byte) ("-" means that the jump is backward so 2 step later has positive sign) 0x1C - 0xFFFFF118 + (2*4) = 0xF0C Now you just need to substitute LDR PC, FIQ_Addr
By
LDR PC, [PC, #-0x0F0C]
Caution: Do Not Forget To Write: VICVectAddr=0; At the end of FIQ routine this Line Code Say The uContoroller that the Interrupt Routine Is Terminated And You Can go Back To System\User Mode
So The FIQ_Routin is like below:
void FIQ_Routin()__irq { . . . . VICVectAddr=0; }