Forums

FIQ - How to setup it on LPC210x?

Started by Telmo Friesen July 22, 2009
Hi all,

I am trying to make a fast interrupt work on the LPC2101..
It sens that all interruptions are disabled in the startup code, but I could
not find a way to enable it in my C code. And I could not find how to tell
the GCC where my handler is too (the handler has to be on 0x1c but how do I
tell this to GCC?).
I tryed some ways but no one worked..
Can someone help me please? Is there an initialization code for FIQ like the
code below for Vectored IRQs?
Thanks..

- a piece of my startup code:

(...)

// Stack Sizes
.set UND_STACK_SIZE, 0x00000004
.set ABT_STACK_SIZE, 0x00000004
.set FIQ_STACK_SIZE, 0x00000004
.set IRQ_STACK_SIZE, 0X00000080
.set SVC_STACK_SIZE, 0x00000004

// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
.set MODE_USR, 0x10 // User Mode
.set MODE_FIQ, 0x11 // FIQ Mode
.set MODE_IRQ, 0x12 // IRQ Mode
.set MODE_SVC, 0x13 // Supervisor Mode
.set MODE_ABT, 0x17 // Abort Mode
.set MODE_UND, 0x1B // Undefined Mode
.set MODE_SYS, 0x1F // System Mode

(...)

// Runtime Interrupt Vectors
// -------------------------
Vectors:
b _start // reset - _start
ldr pc,_undf // undefined - _undf
ldr pc,_swi // SWI - _swi
ldr pc,_pabt // program abort - _pabt
ldr pc,_dabt // data abort - _dabt
nop // reserved
ldr pc,[pc,#-0xFF0] // IRQ - read the VIC
ldr pc,_fiq // FIQ - _fiq

#if 0
// Use this group for production
_undf: .word _reset // undefined - _reset
_swi: .word _reset // SWI - _reset
_pabt: .word _reset // program abort - _reset
_dabt: .word _reset // data abort - _reset
_irq: .word _reset // IRQ - _reset
_fiq: .word _reset // FIQ - _reset

#else
// Use this group for development
_undf: .word __undf // undefined
_swi: .word __swi // SWI
_pabt: .word __pabt // program abort
_dabt: .word __dabt // data abort
_irq: .word __irq // IRQ
_fiq: .word __fiq // FIQ

__undf: b . // undefined
__swi: b . // SWI
__pabt: b . // program abort
__dabt: b . // data abort
__irq: b . // IRQ
__fiq: b . // FIQ - I put pwm_out_handler here
but it did not work.
#endif

(...)

// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in System Mode with Interrupts Disabled
// -----------
ldr r0,=_stack
msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
mov sp,r0
sub r0,r0,#UND_STACK_SIZE
msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
mov sp,r0
sub r0,r0,#ABT_STACK_SIZE
msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
mov sp,r0
sub r0,r0,#FIQ_STACK_SIZE
msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
mov sp,r0
sub r0,r0,#IRQ_STACK_SIZE
msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
mov sp,r0
sub r0,r0,#SVC_STACK_SIZE
msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
mov sp,r0

(...)

- a piece of my C code:

(...)

void __attribute__ ((interrupt("FIQ"))) pwm_out_handler(void);
void pwm_out_init(void);

(...)

int main(void){
(...)
pwm_out_init();
(...)
}

void pwm_out_handler(void){
print_string("FIQ\t");
VICVectAddr = 0;
}

void pwm_out_init(void){
PINSEL0 |= 0x00028000;

//VICVectAddr15 = (unsigned int) &pwm_out_handler; //Setting the
interrupt handler location
VICIntSelect |= 0x04000000;//Timer 2 as FIQ
//VICVectCntl15 = 0x3A; //Vectored Interrupt slot 15 enabled with source
#26 (TIMER2)
VICIntEnable |= 0x04000000;//source #26 enabled as FIQ or IRQ

T2MR0 = 20000;//20ms

T2MCR |= 0x03;//reset and interrupt on match;
T2PC = 0;//Prescale = 0
T2PR = 0xD;//Prescale increments in 14 cclk cycles
T2TC = 0;//Reset T2
T2TCR = 1;//enable T2
}
- Vectored IRQ Initialization code that I found and that works.

static inline unsigned asm_get_cpsr(void)
{
unsigned long retval;
asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ );
return retval;
}

static inline void asm_set_cpsr(unsigned val)
{
asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) );
}

unsigned enableIRQ(void)
{
unsigned _cpsr;

_cpsr = asm_get_cpsr();
asm_set_cpsr(_cpsr & ~IRQ_MASK);
return _cpsr;
}
Best regards,
Telmo Friesen


An Engineer's Guide to the LPC2100 Series