This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

FIQ Problem

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;
}

0