1 | void timer1_asm_irq_handler (void)
|
2 | //* Begin
|
3 | {
|
4 |
|
5 | asm volatile(
|
6 | " @---------------------------------------------------------------------\n\t"
|
7 | " @- File source : irq_timer.s \n\t"
|
8 | " @- Object : Assembler timer Interrupt Handler \n\t"
|
9 | " @- Author : AT91 Application Group \n\t"
|
10 | " @---------------------------------------------------------------------\n\t"
|
11 |
|
12 | " .text \n\t"
|
13 | " .equ AIC_BASE, 0xFFFFF000 \n\t"
|
14 | " .equ AIC_IVR, 0x100 \n\t"
|
15 | " .equ AIC_EOICR, 0x130 \n\t"
|
16 |
|
17 | " @- ARM Core Mode and Status Bits \n\t"
|
18 | " .equ ARM_MODE_IRQ, 0x12 \n\t"
|
19 | " .equ ARM_MODE_SYS, 0x1F \n\t"
|
20 | " .equ I_BIT, 0x80 \n\t"
|
21 |
|
22 | ".macro IRQ_ENTRY reg \n\t"
|
23 | " @- Adjust and save LR_irq in IRQ stack \n\t"
|
24 | " sub r14, r14, #4 \n\t"
|
25 | " stmfd sp!, {r14} \n\t"
|
26 |
|
27 | " @- Write in the IVR to support Protect Mode \n\t"
|
28 | " @- No effect in Normal Mode \n\t"
|
29 | " @- De-assert the NIRQ and clear the source in Protect Mode \n\t"
|
30 | " ldr r14, =AIC_BASE \n\t"
|
31 | " str r14, [r14, #AIC_IVR] \n\t"
|
32 |
|
33 | "@- Save SPSR and r0 in IRQ stack \n\t"
|
34 | " mrs r14, SPSR \n\t"
|
35 | " stmfd sp!, {r0, r14} \n\t"
|
36 |
|
37 | "@;- Enable Interrupt and Switch in SYS Mode \n\t"
|
38 | " mrs r0, CPSR \n\t"
|
39 | " bic r0, r0, #I_BIT \n\t"
|
40 | " orr r0, r0, #ARM_MODE_SYS \n\t"
|
41 | " msr CPSR_c, r0 \n\t"
|
42 |
|
43 | "@- Save scratch/used registers and LR in User Stack \n\t"
|
44 | " .ifeq \reg \n\t"
|
45 | " stmfd sp!, { r1-r3, r12, r14} \n\t"
|
46 | " .else \n\t"
|
47 | " stmfd sp!, { r1-r3, $reg, r12, r14} \n\t"
|
48 | " .endif \n\t"
|
49 | ".endm \n\t"
|
50 |
|
51 | ".macro IRQ_EXIT reg \n\t"
|
52 |
|
53 | "@- Restore scratch/used registers and LR from User Stack \n\t"
|
54 | " .ifeq \reg \n\t"
|
55 | " ldmia sp!, { r1-r3, r12, r14} \n\t"
|
56 | " .else \n\t"
|
57 | " ldmia sp!, { r1-r3, $reg, r12, r14} \n\t"
|
58 | " .endif \n\t"
|
59 |
|
60 | "@- Disable Interrupt and switch back in IRQ mode \n\t"
|
61 | " mrs r0, CPSR \n\t"
|
62 | " bic r0, r0, #ARM_MODE_SYS \n\t"
|
63 | " orr r0, r0, #I_BIT:OR:ARM_MODE_IRQ \n\t"
|
64 | " msr CPSR_c, r0 \n\t"
|
65 |
|
66 | "@- Mark the End of Interrupt on the AIC \n\t"
|
67 | " ldr r0, =AIC_BASE \n\t"
|
68 | " str r0, [r0, #AIC_EOICR] \n\t"
|
69 |
|
70 | "@- Restore SPSR_irq and r0 from IRQ stack \n\t"
|
71 | " ldmia sp!, {r0, r14} \n\t"
|
72 | " msr SPSR_cxsf, r14 \n\t"
|
73 |
|
74 | "@- Restore adjusted LR_irq from IRQ stack directly in the PC\n\t"
|
75 | " ldmia sp!, {pc}^ \n\t"
|
76 | ".endm \n\t"
|
77 |
|
78 | "@---------------------------------------------------------------\n\t"
|
79 | "@- Function : timer1_asm_irq_handler \n\t"
|
80 | "@- Treatments : Timer 1 interrupt handler. \n\t"
|
81 | "@- Called Functions : timer1_c_irq_handler \n\t"
|
82 | "@- Called Macros : IRQ_ENTRY, IRQ_EXIT \n\t"
|
83 | "@--------------------------------------------------------------\n\t"
|
84 | " .extern timer1_c_irq_handler \n\t"
|
85 | " .global timer1_asm_irq_handler \n\t"
|
86 | "@- Manage Exception Entry \n\t"
|
87 | " IRQ_ENTRY \n\t"
|
88 | "@- Call the timer Interrupt C handler \n\t"
|
89 | " ldr r1, =timer1_c_irq_handler \n\t"
|
90 | " mov r14, pc \n\t"
|
91 | " bx r1 \n\t"
|
92 | "@- Manage Exception Exit \n\t"
|
93 | " IRQ_EXIT \n\t"
|
94 | ".end \n\t"
|
95 |
|
96 | );
|
97 | }
|