I'm using the interrupt.h and asmfunc.S included in SD card project from Martin THOMAS website. To use a IRQ interrupt i can use: RegisterVector(EINT0_INT, EINT0_Routine, PRI_HIGHEST, CLASS_IRQ); IrqEnable(); but for FIQ i don't know how can i doo that. I've tried RegisterVector(EINT0_INT, EINT0_Routine, PRI_HIGHEST, CLASS_FIQ); FiqEnable(); but don't work. Reading the interrupcao.h i find two procedures: void LoadFiqRegs (long int *regs); void StoreFiqRegs (long *regs); I don't know how can i use this two procedures. Anyone knows how can I use the FIQ interruption with this asmfunc.S?
The startup code in asmfunc.S does not support FIQ. The FIQ vector runs into an infinite loop (Trap) and there is no stack assigned. BTW: You did not mention the controller type.
I changed the asmfunc.S and use a FIQ interruption, but only enter the procedure one time. I clean the flags of interruption but still don't work; I changed in the code: .section .VECTOR, "ax" .arm LDR PC, [PC, #24] @ Reset entry, jump to reset handler LDR PC, [PC, #24] @ Undef entry, trap LDR PC, [PC, #24] @ SWI entry, jump to SWI handler LDR PC, [PC, #24] @ PAbt entry, trap LDR PC, [PC, #24] @ DAbt entry, trap .word 0 @ Check sum (set by flash programmer) LDR PC, [PC, #20] @ IRQ entry, jump to IRQ handler LDR PC, [PC, #20] @ FIQ entry, trap .word Reset_Handler @ Reset handler .word Trap @ Undefined Instruction handler .word SWI_Handler @ Software Interrupt handler .word Trap @ Prefetch Abort handler .word Trap @ Data Abort handler .word IRQ_Handler @ IRQ handler FIQ_Addr: .word FIQ_Routine .... FIQDisable: MRS R0, SPSR ORR R0, R0, #B_Fiq MSR SPSR_c, R0 MOVS PC, LR FIQEnable: MRS R0, SPSR BIC R0, R0, #B_Fiq MSR SPSR_c, R0 MOVS PC, LR In my main function I set the Fiq interruption using: EXTMODE|=1<<0; EXTINT=0x1; VICIntSelect |= 0x00004000; VICIntEnable = 0x00004000; FiqEnable(); and start the while(1) loop that runs infinitaly. When I press the button enter in the Interruptio routine: void FIQ_Routine() { int k; //Força limpeza da interrupção (Caso de travamento) if ((EXTINT==1)&&(T0TC>=tempo+1000)) { EXTINT=0x1; } //Pega o endereço da fonte de interrupção. k=EXTINT; //Verifica se foi Ext0 que interrompeu if(test_bit(k,0)) { LCD_limpaLinha(2,16); LCD_escreveMsgLC(2,1,"Botao apertado."); Timer0_espera(1000); } tempo=T0TC; EXTINT=0x1; } The execution back to main while(1) loop but when I pressed the button again the Interruption doesnt work anymore. Anyone can help me to solve this?
An interrupt handler as defined by the machine is called in a different way as normal C functions are. FIQ handlers too. Normal IRQs are wrapped by the handler code in the asm file, so normal C functions can be used as final IRQ handlers. Your FIQs however are called directly. When a C function is called directly by hardware, the C function must be declared accordingly:
1 | void FIQ_Routine () __attribute__ ((interrupt ("FIQ"))); |
You should also allocate some bytes for the FIQ stack. There is a definition for the FIQ stack size in the asm file, which was set to 0 in the version shown above. Note that interrupts are intended to be fast and short, so slow LCD functions should not be placed withing handlers. Especially if they can interrupt some other LCD output sequence in main program, disturbing state and pin control as well as timing. A simple LED as event indicator for debugging (e.g. toggling) is much safer.
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.