Dear all, I try to get the fast interrupt to run by using the GNU toolchain. In C source I defined a function with the extension __attribute__ ((interrupt("FIQ"))) as the fast interrupt service routine. Currently the program stucks at the dummy handler of the "startup.s" and I don't know how to bring the handler and the service routine together to run. Thank you, Best regards, Detlef Weidner
Hi Detlef, I use the LPC2129 and GNU Toolchain too. My application needs a Timer Interrupt with highest priority, it works very fine with FIQ. The ISR is called "Timer1ISR" for example. First of all, you have to change the startup code (startup.s) to put your specified ISR-Address to the FIQ-Vector (FIQ_Handler: B Timer1ISR) and you have to make this symbol public for other files and maybe the linker (.global Timer1ISR). Please have a look on the following code snippet to see the 2 changes in comparison to the original startup.s: from startup.s:
......................... # Starupt Code must be linked first at Address at which it expects to run. .text .arm .global Timer1ISR /* FIQ ISR in my application */ .global _startup .func _startup _startup: # 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, #-0x0FF0] /* Vector from VIC */ 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 0 /* Reserved Address */ IRQ_Addr: .word IRQ_Handler FIQ_Addr: .word 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 Timer1ISR /* FIQ ISR Address */ # Reset Handler Reset_Handler: /* Programm starts here after RESET */ .........................
//----------------------------------------------------- // Interrupt Service Routines void Timer1ISR (void) __attribute__ ((interrupt("FIQ"))); //----------------------------------------------------- void Timer1ISR ( void ) { ++gTimerTick; // global Timer Tick 1 ms T1IR = 1; // Clear interrupt flag } // VICVectAddr dummy write not needed in this case //----------------------------------------------------- void init_timer1 ( void ) { // the pclk is 15 MHz PCONP |= (0x01 << 2); // power up Timer1 Peripheral T1TCR = 2; // T1TC, T1PC Reset on next pclk T1MR0 = 14999; // 1 ms = 15.000-1 counts T1MCR = 3; // Interrupt and Reset on MR0 VICIntSelect |= (0x01 << 5); // Timer1 Interrupt is FIQ Type VICIntEnable = (0x01 << 5); // Enable Timer1 Interrupt gTimerTick = 0; // clear interrupt counter T1TCR = 1; // Timer1 Enable } //-----------------------------------------------------
Thank you Dietmar, that helped me! my failure was the missing global definition in "startup.s" Best regards Detlef Weidner