Hi,
I am now trying Vectored IRQ on MCB2300(LPC2388) with YAGARTO tool chain in Eclipse. But it always doesn’t work.
I have already suceeded in trying FIQ, it works, is there anybody can give me some advice? Thanks!
Code in main.c :
#include “LPC23xx.h” /* LPC23xx definitions */
#include “target.h”
#include “type.h”
// function prototype --------------------------------------------------
void delay(unsigned int nCount);
//void Fiq_Handler (void) attribute ((interrupt(“FIQ”)));
/* fiq interrupt handler*/
attribute ((interrupt(“IRQ”))) void VectoredIRQ(void){
FIO2CLR = 0xFF;
// FIO2SET = 0xFF;
EXTINT = 0x01; //Clear the peripheral interrupt flag
VICVectAddr = 0xFFFFFFFF; /* Acknowledge Interrupt */
}
// main function--------------------------------------------------------
int main (void) {
// TargetResetInit();
PINSEL10 = 0; /* Disable ETM interface, enable LEDs */
FIO2DIR = 0x000000FF; /* P2.0…7 defined as Outputs */
FIO2MASK = 0x00000000;
FIO2CLR = 0xFF; /* Turn off all LEDs */
FIO2SET = (0xFF); /* Turn on requested LEDs */
PINSEL4 |= (1<<20); /* External interrupt function selected*/
VICVectAddr14 = (unsigned long)VectoredIRQ; /* Set Interrupt Vector */
VICVectCntl14 = 1; /* use it for EINT0 Interrupt */
// VICIntSelect = (1 << 14); /* Enable EINT0 Interrupt */
VICIntEnable = (1 << 14); /* Enable EINT0 Interrupt */
while(1)
FIO2SET = (0xFF);
// asm(“NOP”);
}
/* time delay function*/
void delay(unsigned int nCount) {
for(; nCount != 0; nCount–)
asm(“NOP”);
}
In Startup Code Startup.s:
@ Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1B
.equ Mode_SYS, 0x1F
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
@// Stack Configuration (Stack Sizes in Bytes)
@// Undefined Mode <0x0-0xFFFFFFFF:8>
@// Supervisor Mode <0x0-0xFFFFFFFF:8>
@// Abort Mode <0x0-0xFFFFFFFF:8>
@// Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
@// Interrupt Mode <0x0-0xFFFFFFFF:8>
@// User/System Mode <0x0-0xFFFFFFFF:8>
@//
.equ UND_Stack_Size, 0x00000000
.equ SVC_Stack_Size, 0x00000100
.equ ABT_Stack_Size, 0x00000000
.equ FIQ_Stack_Size, 0x00000000
.equ IRQ_Stack_Size, 0x00000100
.equ USR_Stack_Size, 0x00000200
.equ Stack_Size, (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)
@@ AREA STACK, NOINIT, READWRITE, ALIGN=3
@@
@@Stack_Mem SPACE Stack_Size
@@Stack_Top EQU Stack_Mem + Stack_Size
.arm
.section .STACK, “w”
.align 3
Stack_Mem:
.space Stack_Size
.equ Stack_Top, Stack_Mem + Stack_Size
@// Heap Configuration
@// Heap Size (in Bytes) <0x0-0xFFFFFFFF>
@//
@@Heap_Size EQU 0x00000000
@@ AREA HEAP, NOINIT, READWRITE, ALIGN=3
@@Heap_Mem SPACE Heap_Size
.equ Heap_Size, 0x00000000
.section .HEAP, “w”
.align 3
HeapMem:
.if (Heap_Size>0)
.space Heap_Size
.endif
@ Area Definition and Entry Point
@ Startup Code must be linked first at Address at which it expects to run.
@@ AREA RESET, CODE, READONLY
@@ ARM
.section .RESET, “ax”
.arm
@ Exception Vectors
@ Mapped to Address 0.
@ Absolute addressing mode must be used.
@ Dummy Handlers are implemented as infinite loops which can be modified.
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: .word Reset_Handler
Undef_Addr: .word Undef_Handler
SWI_Addr: .word SWI_Handler
PAbt_Addr: .word PAbt_Handler
DAbt_Addr: .word DAbt_Handler
.word 0xB9206E28 @ Reserved Address
IRQ_Addr: .word IRQ_Handler
FIQ_Addr: .word FIQ_Handler
Undef_Handler: B Undef_Handler
SWI_Handler: B SWI_Handler
.extern SoftwareInterrupt
@@SWI_Handler: B SoftwareInterrupt @ see swi_handler.S
PAbt_Handler: B PAbt_Handler
DAbt_Handler: B DAbt_Handler
@@ handled thru assembler wrapper (see below)
@@ IRQ_Handler: B IRQ_Handler
FIQ_Handler: B FIQ_Handler
@ Reset Handler
@ EXPORT Reset_Handler
.global Reset_handler
Reset_Handler:
@ Call low-level init C-function
@ IMPORT TargetResetInit
@ BL TargetResetInit
.extern TargetResetInit
ldr SP, =Stack_Top @ temporary stack at Stack_Top
LDR R0, =TargetResetInit
MOV LR, PC
BX R0
@ Setup Stack for each mode
LDR R0, =Stack_Top
@ Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND | I_Bit | F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
@ Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT | I_Bit | F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
@ Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ | I_Bit | F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
@ Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ | I_Bit | F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
@ Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC | I_Bit | F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
@ Enter User Mode and set its Stack Pointer
@ mt: MSR CPSR_c, #Mode_USR
MSR CPSR_c, #Mode_USR | I_Bit
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
@ mt: Start application in USR-mode with IRQ-exceptions disabled.
@ They can be enabled at runtime thru IntEnable in swi.h/swi_handler.S.
@ Relocate .data section (Copy from ROM to RAM)
LDR R1, =_etext
LDR R2, =_data
LDR R3, =_edata
CMP R2, R3
BEQ DataIsEmpty
LoopRel: CMP R2, R3
LDRLO R0, [R1], #4
STRLO R0, [R2], #4
BLO LoopRel
DataIsEmpty:
@ Clear .bss section (Zero init)
MOV R0, #0
LDR R1, =bss_start
LDR R2, =bss_end
CMP R1,R2
BEQ BSSIsEmpty
LoopZI: CMP R1, R2
STRLO R0, [R1], #4
BLO LoopZI
BSSIsEmpty:
@ Enter the C code
@ IMPORT __main
@ LDR R0, =__main
.extern main
LDR R0, =main
BX R0
@ User Initial Stack & Heap (not used in GNU port)
@@ AREA |.text|, CODE, READONLY
@@ IMPORT __use_two_region_memory
@@ EXPORT __user_initial_stackheap
@@__user_initial_stackheap
@@ LDR R0, = Heap_Mem
@@ LDR R1, =(Stack_Mem + USR_Stack_Size)
@@ LDR R2, = (Heap_Mem + Heap_Size)
@@ LDR R3, = Stack_Mem
@@ BX LR
@@ IRQ_Wrapper based on Examples for
@@ AT91-ARM7TDMI AIC from Atmel,
@@ adapted to LPC23xx/24xx VIC by M. Thomas
@@ This wrapper avoids compiler-dependencies.
.set LPC_BASE_VIC, 0xFFFFF000
.set VIC_VectAddr, 0xF00
.arm
IRQ_Handler:
@- Manage Exception Entry
@- Adjust and save LR_irq in IRQ stack
sub lr, lr, #4
stmfd sp!, {lr}
@- Save SPSR need to be saved for nested interrupt
mrs r14, SPSR
stmfd sp!, {r14}
@- Save and r0 in IRQ stack
stmfd sp!, {r0}
@- Load the ISR-Address from VICVectAddr
ldr r14, =LPC_BASE_VIC
ldr r0 , [r14, #VIC_VectAddr]
@- Enable Interrupt and Switch in Supervisor Mode
msr CPSR_c, #Mode_SVC
@- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, r14 }
@- Branch to the routine pointed by the VIC_VectAddr
mov r14, pc
bx r0
@- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, r14 }
@- Disable Interrupt and switch back in IRQ mode
msr CPSR_c, #I_Bit | Mode_IRQ
@- Mark the End of Interrupt on the VIC
@ by writing to VICVectAddr - not needed
@ here since already done in the ISRs
@@ ldr r14, =LPC_BASE_VIC
@@ str r14, [r14, #VIC_VectAddr]
@- Restore R0
ldmia sp!, {r0}
@- Restore SPSR_irq and r0 from IRQ stack
ldmia sp!, {r14}
msr SPSR_cxsf, r14
@- Restore adjusted LR_irq from IRQ stack directly in the PC
ldmia sp!, {pc}^
@ END
.end
I think maybe the problem is in the startup code, I copy it from another project on internet written by T.Martin, IRQ_handler is rewritten in the end. “LDR PC, [PC, #-0x0120] @ Vector from VicVectAddr” is commented out. But I didn’t find out where the error is. Looking forward to getting some advice:)