Hi. I have a question about using the nested interrupts. Currently I'am using the starting S-file: ======================================================================== /*---------------------------------------------------------------------- -------- //*- ATMEL Microcontroller Software Support - ROUSSET - //*--------------------------------------------------------------------- --------- //* The software is delivered "AS IS" without warranty or condition of any //* kind, either express, implied or statutory. This includes without //* limitation any warranty or condition with respect to merchantability or //* fitness for any particular purpose, or against the infringements of //* intellectual property rights of others. //*--------------------------------------------------------------------- -------- //*- File source : Cstartup.s //*- Object : Generic CStartup for KEIL and GCC //*- Compilation flag : None //*- //*- 1.0 18/Oct/04 JPP : Creation //*- 1.1 21/Feb/05 JPP : Set Interrupt //*- 1.1 01/Apr/05 JPP : save SPSR //* //*- WinARM/arm-elf-gcc-version by Martin Thomas - Modifications: //* remapping-support, vector-location, stack-position and more... //*--------------------------------------------------------------------- --------*/ /* 20060902 (mth) : moved IRQ-Handler from section .vect* to .init/.fastrun 20061101 (mth) : update IRQ-Handler FIQ-stack init */ /* check configuration-options and map to "assembler symbols": */ #ifdef ROM_RUN .set RAM_MODE, 0 #ifdef VECTORS_IN_RAM .set REMAP, 1 .set VECTREMAPPED, 1 #else .set REMAP, 0 .set VECTREMAPPED, 0 #endif #endif #ifdef RAM_RUN .set RAM_MODE, 1 .set REMAP, 1 .set VECTREMAPPED, 0 #endif .if (RAM_MODE) .print "RAM_MODE enabled" .else .print "ROM_MODE enabled" .endif .if (REMAP) .print "remapping enabled" .endif .if (VECTREMAPPED) .print "Vectors at start of RAM" .else .print "Vectors at start of Code" .endif .equ AIC_IVR, (256) .equ AIC_FVR, (260) .equ AIC_EOICR, (304) .equ AT91C_BASE_AIC, (0xFFFFF000) /*---------------------------------------------------------------------- -------- //*- Exception vectors //*-------------------- //*- These vectors can be read at address 0 or at RAM address //*- They ABSOLUTELY requires to be in relative addresssing mode in order to //*- guarantee a valid jump. For the moment, all are just looping. //*- If an exception occurs before remap, this would result in an infinite loop. //*- To ensure if a exeption occurs before start application to infinite loop. //*--------------------------------------------------------------------- ---------*/ .if (VECTREMAPPED) .print "Vectors in section .vectmapped -> .data" .section .vectmapped, "ax" .else .print "Vectors in section .vectorg -> .text" .section .vectorg, "ax" .endif LDR PC,Reset_Addr /* 0x00 Reset handler */ LDR PC,Undef_Addr /* 0x04 Undefined Instruction */ LDR PC,SWI_Addr /* 0x08 Software Interrupt */ LDR PC,PAbt_Addr /* 0x0C Prefetch Abort */ LDR PC,DAbt_Addr /* 0x10 Data Abort */ NOP /* 0x14 reserved */ LDR PC,IRQ_Addr /* 0x18 IRQ */ fiqvec: /* 0x1c FIQ */ /*---------------------------------------------------------------------- -------- //*- Function : FIQ_Handler_Entry //*- Treatments : FIQ Controller Interrupt Handler. //*- Called Functions : AIC_FVR[interrupt] //*--------------------------------------------------------------------- ---------*/ FIQ_Handler_Entry: /*- Switch in SVC/User Mode to allow User Stack access for C code */ /* because the FIQ is not yet acknowledged*/ /*- Save and r0 in FIQ_Register */ mov r9,r0 ldr r0 , [r8, #AIC_FVR] msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC /*- Save scratch/used registers and LR in User Stack */ stmfd sp!, { r1-r3, r12, lr} /*- Branch to the routine pointed by the AIC_FVR */ mov r14, pc bx r0 /*- Restore scratch/used registers and LR from User Stack */ ldmia sp!, { r1-r3, r12, lr} /*- Leave Interrupts disabled and switch back in FIQ mode */ msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ /*- Restore the R0 ARM_MODE_SVC register */ mov r0,r9 /*- Restore the Program Counter using the LR_fiq directly in the PC */ subs pc,lr,#4 /* end of fiqhandler */ Reset_Addr: .word InitReset Undef_Addr: .word Undef_Handler /* SWI_Addr: .word SWI_Handler */ SWI_Addr: .word SoftwareInterruptASM /* in swi_handler.S */ PAbt_Addr: .word PAbt_Handler DAbt_Addr: .word DAbt_Handler IRQ_Addr: .word IRQ_Handler_Entry Undef_Handler: B Undef_Handler /* SWI_Handler: B SWI_Handler */ PAbt_Handler: B PAbt_Handler DAbt_Handler: B DAbt_Handler .arm .section .init, "ax" .global _startup .func _startup _startup: reset: .if (VECTREMAPPED) /* mthomas: Dummy used during startup */ LDR PC,=Reset_Addr_F NOP NOP NOP NOP NOP /*.word 0xdeadbeef*/ /* Reserved Address */ NOP NOP Reset_Addr_F: .word InitReset .endif .RAM_TOP: .word __TOP_STACK InitReset: /*---------------------------------------------------------------------- -------- /*- Remapping /*---------------------------------------------------------------------- --------*/ .if (VECTREMAPPED) .print "RCR setting for remapping enabled" .equ MC_BASE,0xFFFFFF00 /* MC Base Address */ .equ MC_RCR, 0x00 /* MC_RCR Offset */ /* store first word in RAM into r4 */ ldr r0,=__FIRST_IN_RAM ldr r4,[r0] /* load value at address 0 into R2 */ ldr r1,=0x00000000 ldr r2,[r1] /* xor value from address 0 (flip all bits), store in R3 */ ldr r3,=0xffffffff eor r3, r2, r3 /* write xored value to first word in RAM if already remapped this will also change the value at 0 */ str r3,[r0] /* load from address 0 again into R3 */ ldr r3,[r1] /* restore first value in RAM */ str r4,[r0] /* compare */ cmp r3, r2 bne already_remapped /* if both values have been equal the change of the RAM-value had no effect on the value at 0x00000000 so we are not remapping yet -> remap now: */ LDR R0, =MC_BASE MOV R1, #1 STR R1, [R0, #MC_RCR] already_remapped: .endif /*---------------------------------------------------------------------- -------- /*- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit /*---------------------------------------------------------------------- --------*/ .extern AT91F_LowLevelInit /*- minumum C initialization */ /*- call AT91F_LowLevelInit( void) */ ldr sp, .RAM_TOP /* temporary stack in internal RAM (**) */ /*--Call Low level init function in ABSOLUTE through the Interworking */ ldr r0,=AT91F_LowLevelInit mov lr, pc bx r0 /*---------------------------------------------------------------------- -------- //*- Stack Sizes Definition //*------------------------ //*- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using //*- the vectoring. This assume that the IRQ management. //*- The Interrupt Stack must be adjusted depending on the interrupt handlers. //*- Fast Interrupt not requires stack If in your application it required you must //*- be definehere. //*- The System stack size is not defined and is limited by the free internal //*- SRAM. //*--------------------------------------------------------------------- ---------*/ /*---------------------------------------------------------------------- -------- //*- Top of Stack Definition //*------------------------- //*- Interrupt and Supervisor Stack are located at the top of internal memory in //*- order to speed the exception handling context saving and restoring. //*- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory. //*--------------------------------------------------------------------- ---------*/ .EQU IRQ_STACK_SIZE, (3*8*4) .EQU FIQ_STACK_SIZE, (3*8*4) .EQU ARM_MODE_FIQ, 0x11 .EQU ARM_MODE_IRQ, 0x12 .EQU ARM_MODE_SVC, 0x13 .EQU I_BIT, 0x80 .EQU F_BIT, 0x40 /*---------------------------------------------------------------------- -------- //*- Setup the stack for each mode //*-------------------------------*/ mov r0, sp /* see (**) */ /*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/ msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT mov sp, r0 sub r0, r0, #FIQ_STACK_SIZE /*- Init the FIQ register*/ ldr r8, =AT91C_BASE_AIC /*- Set up Interrupt Mode and set IRQ Mode Stack*/ msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT mov sp, r0 /* Init stack IRQ */ sub r0, r0, #IRQ_STACK_SIZE /*- Set up Supervisor Mode and set Supervisor Mode Stack*/ // /* start with INT and FIQ enabled */ // msr CPSR_c, #ARM_MODE_SVC /* start with INT and FIQ disabled */ msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT mov sp, r0 /* Init stack Sup */ /*- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack*/ /* Relocate .data section (Copy from ROM to RAM) This will also copy the .vectmapped and .fastrun */ LDR R1, =_etext LDR R2, =_data LDR R3, =_edata LoopRel: CMP R2, R3 LDRLO R0, [R1], #4 STRLO R0, [R2], #4 BLO LoopRel /* Clear .bss section (Zero init) */ MOV R0, #0 LDR R1, =__bss_start__ LDR R2, =__bss_end__ LoopZI: CMP R1, R2 STRLO R0, [R1], #4 BLO LoopZI /* call C++ constructors of global objects */ LDR r0, =__ctors_start__ LDR r1, =__ctors_end__ ctor_loop: CMP r0, r1 BEQ ctor_end LDR r2, [r0], #4 STMFD sp!, {r0-r1} MOV lr, pc /* MOV pc, r2 */ BX r2 /* mthomas 8/2006 */ LDMFD sp!, {r0-r1} B ctor_loop ctor_end: /* call main() */ ldr lr,=exit ldr r0,=main bx r0 .size _startup, . - _startup .endfunc /* "exit" dummy added by mthomas to avoid sbrk write read etc. needed by the newlib default "exit" */ .global exit .func exit exit: b . .size exit, . - exit .endfunc /*---------------------------------------------------------------------- -------- //*- Manage exception //*--------------- //*- This module The exception must be ensure in ARM mode //*--------------------------------------------------------------------- --------- //*--------------------------------------------------------------------- --------- //*- Function : IRQ_Handler_Entry //*- Treatments : IRQ Controller Interrupt Handler. //*- Called Functions : AIC_IVR[interrupt] //*--------------------------------------------------------------------- ---------*/ .if (VECTREMAPPED) .print "IRQ_Handler_Entry in section .fastrun -> .data" .section .fastrun, "ax" .else .print "IRQ_Handler_Entry in section .init -> .text" .section .init, "ax" .endif .global IRQ_Handler_Entry .func IRQ_Handler_Entry IRQ_Handler_Entry: /*---- Adjust and save return address on the stack */ sub lr, lr, #4 stmfd sp!, {lr} /*---- Save r0 and SPSR on the stack */ mrs r14, SPSR stmfd sp!, {r0, r14} /*---- Write in the IVR to support Protect mode */ /*---- No effect in Normal Mode */ /*---- De-assert NIRQ and clear the source in Protect mode */ ldr r14, =AT91C_BASE_AIC ldr r0, [r14, #AIC_IVR] str r14, [r14, #AIC_IVR] /*---- Enable nested interrupts and switch to Supervisor mode */ msr CPSR_c, #ARM_MODE_SVC /*---- Save scratch/used registers and LR on the stack */ stmfd sp!, {r1-r3, r12, r14} /*---- Branch to the routine pointed by AIC_IVR */ mov r14, pc bx r0 /*---- Restore scratch/used registers and LR from the stack */ ldmia sp!, {r1-r3, r12, r14} /*---- Disable nested interrupts and switch back to IRQ mode */ msr CPSR_c, #I_BIT | ARM_MODE_IRQ /*---- Acknowledge interrupt by writing AIC_EOICR */ ldr r14, =AT91C_BASE_AIC str r14, [r14, #AIC_EOICR] /*---- Restore SPSR and r0 from the stack */ ldmia sp!, {r0, r14} msr SPSR_cxsf, r14 /*---- Return from interrupt handler */ ldmia sp!, {pc}^ .size IRQ_Handler_Entry, . - IRQ_Handler_Entry .endfunc /*--------------------------------------------------------------- //* ?EXEPTION_VECTOR //* This module is only linked if needed for closing files. //*---------------------------------------------------------------*/ .global AT91F_Default_FIQ_handler .func AT91F_Default_FIQ_handler AT91F_Default_FIQ_handler: b AT91F_Default_FIQ_handler .size AT91F_Default_FIQ_handler, . - AT91F_Default_FIQ_handler .endfunc .global AT91F_Default_IRQ_handler .func AT91F_Default_IRQ_handler AT91F_Default_IRQ_handler: b AT91F_Default_IRQ_handler .size AT91F_Default_IRQ_handler, . - AT91F_Default_IRQ_handler .endfunc .global AT91F_Spurious_handler .func AT91F_Spurious_handler AT91F_Spurious_handler: b AT91F_Spurious_handler .size AT91F_Spurious_handler, . - AT91F_Spurious_handler .endfunc .end ======================================================================== === In the function "IRQ_Handler_Entry:" write /*---- Save r0 and SPSR on the stack */ mrs r14, SPSR stmfd sp!, {r0, r14} . . . /*---- Enable nested interrupts and switch to Supervisor mode */ msr CPSR_c, #ARM_MODE_SVC . . . So, I think I can use nested interrupts. The question is the nested interrupts is default turn-on or turn-off? For example the IRQ PIT function- I want to interrupt this function by interrupt-function with highter priority. void systime_isr(void) /* System Interrupt Handler */ { //INTenable(); <---------- any function to turn on interrupt ??? volatile unsigned long status; static int cnt, cnt2; // Interrupt Acknowledge status = AT91C_BASE_PITC->PITC_PIVR; // any code // } Do I have to turn on (re-enable) the interrupts or it has done default? Can I use this function to re-enable interrupts ?? #define MY_SWI_CALL_RES(MY_SWI_ID, MY_RESULT) \ asm volatile( \ "swi %a1 \n\t" \ "mov %0,r0 \n\t" \ : "=r" (MY_RESULT) : "I" (MY_SWI_ID) : "r0", "lr" ) static inline unsigned long IntEnable(void) { unsigned long res; MY_SWI_CALL_RES(SWI_NUM_IRQ_EN, res); return res; } regards /Adam
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.