VectoredIRQ problem on MCB2300(lpc2388 YAGARTO eclipse)

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:)

Since the startup code has an assembler wrapper that is called by the interrupt handler, your interrupt code should be a standard ‘C’ function. Do not use the attribute ((interrupt(“IRQ”))) method of declaring it, or it will not work.

Since I don’t see it in the startup code, you will need to enable interrupts in the CPSR register or you will never get any interrupts. This is usually done in main() after you have set up the VIC.

I would recommend that you join the LPC2000 group on Yahoo, for specific help.

Thank you very much, manton, it’s true IRQ is disabled, after set CPSR in main(), now the vectored interrupt works.