📄 at91.lst
字号:
72
73 // Commuting from 16Mhz to PLL @ 32MHz
74 __APMC_CGMR = 0x032F8102; // CSS = 2, MUL = 1
75
76 // Now the Master clock is the output of PLL @ 32MHz
77 }
78 #endif
79
\ In segment CODE, align 4, keep-with-next
80 void AT91EnablePeripheralClocks()
81 {
82 #if AT91_EB40 || AT91_EB40A
83 // Switch on clocks to all peripherals.
84 __PS_PCER = 0x00017c;
\ AT91EnablePeripheralClocks:
\ 00000000 FB00E0E3 MVN R0,#+251
\ 00000004 BF0CC0E3 BIC R0,R0,#0xBF00
\ 00000008 5F1FA0E3 MOV R1,#+380
\ 0000000C 001080E5 STR R1,[R0, #+0]
85 #else
86 // Switch on clocks to all peripherals.
87 __APMC_PCER = 0x0007effc;
88 #endif
89 }
\ 00000010 1EFF2FE1 BX LR ;; return
90
91
92 //
93 // Interrupt handlers.
94 //
95
96 /* Timer interrupt handler */
\ In segment CODE, align 4, keep-with-next
97 __irq __arm void heartbeat_irq(void)
98 {
\ heartbeat_irq:
\ 00000000 04E04EE2 SUB LR,LR,#+4
\ 00000004 0F502DE9 PUSH {R0-R3,R12,LR}
99 // Called at 1000 Hz rate.
100 __AIC_IVR = 0; // Debug variant of vector read, protected mode is used.
\ 00000008 FFE0E0E3 MVN LR,#+255
\ 0000000C E0EECEE3 BIC LR,LR,#0xE00
\ 00000010 0000A0E3 MOV R0,#+0
\ 00000014 00008EE5 STR R0,[LR, #+0]
101
102 (*timer_function)(); // Call timer callback function.
\ 00000018 ........ LDR R0,??DataTable3 ;; timer_function
\ 0000001C 000090E5 LDR R0,[R0, #+0]
\ 00000020 0FE0A0E1 MOV LR,PC
\ 00000024 10FF2FE1 BX R0
103
104 __TC_SRC0; // Read timer/counter 0 status register.
\ 00000028 ........ LDR R0,??DataTable5 ;; 0xfffffffffffe0020
\ 0000002C 00E090E5 LDR LR,[R0, #+0]
105 __AIC_EOICR = 0; // Signal end of interrupt to AIC.
\ 00000030 CF00E0E3 MVN R0,#+207
\ 00000034 E00EC0E3 BIC R0,R0,#0xE00
\ 00000038 0010A0E3 MOV R1,#+0
\ 0000003C 001080E5 STR R1,[R0, #+0]
106 }
\ 00000040 0F90FDE8 LDM SP!,{R0-R3,R12,PC}^ ;; return
107
108
109 /* Serial port RX interrupt handler */
\ In segment CODE, align 4, keep-with-next
110 __irq __arm void usart0_rxrdy_interrupt(void)
111 {
\ usart0_rxrdy_interrupt:
\ 00000000 04E04EE2 SUB LR,LR,#+4
\ 00000004 0F502DE9 PUSH {R0-R3,R12,LR}
112 __AIC_IVR = 0; // Debug variant of vector read, protected mode is used.
\ 00000008 FFE0E0E3 MVN LR,#+255
\ 0000000C E0EECEE3 BIC LR,LR,#0xE00
\ 00000010 0000A0E3 MOV R0,#+0
\ 00000014 00008EE5 STR R0,[LR, #+0]
113
114 (*rxrdy_function)(); // Call RX callback function.
\ 00000018 ........ LDR R0,??DataTable4 ;; rxrdy_function
\ 0000001C 000090E5 LDR R0,[R0, #+0]
\ 00000020 0FE0A0E1 MOV LR,PC
\ 00000024 10FF2FE1 BX R0
115
116 __AIC_EOICR = 0; // Signal end of interrupt to AIC.
\ 00000028 CF00E0E3 MVN R0,#+207
\ 0000002C E00EC0E3 BIC R0,R0,#0xE00
\ 00000030 0010A0E3 MOV R1,#+0
\ 00000034 001080E5 STR R1,[R0, #+0]
117 }
\ 00000038 0F90FDE8 LDM SP!,{R0-R3,R12,PC}^ ;; return
118
119
120 /* Undefined interrupt handler */
\ In segment CODE, align 4, keep-with-next
121 __irq __arm void undefined_irq(void)
122 {
\ undefined_irq:
\ 00000000 03002DE9 PUSH {R0,R1}
123 __AIC_IVR = 0; // Debug variant of vector read, protected mode is used.
\ 00000004 FF00E0E3 MVN R0,#+255
\ 00000008 E00EC0E3 BIC R0,R0,#0xE00
\ 0000000C 0010A0E3 MOV R1,#+0
\ 00000010 001080E5 STR R1,[R0, #+0]
124
125 // Do nothing.
126
127 __AIC_EOICR = 0; // Signal end of interrupt to AIC.
\ 00000014 CF00E0E3 MVN R0,#+207
\ 00000018 E00EC0E3 BIC R0,R0,#0xE00
\ 0000001C 0010A0E3 MOV R1,#+0
\ 00000020 001080E5 STR R1,[R0, #+0]
128 }
\ 00000024 0300BDE8 POP {R0,R1}
\ 00000028 04F05EE2 SUBS PC,LR,#+4 ;; return
129
130
131 //
132 // Interrupt functions.
133 //
134
\ In segment CODE, align 4, keep-with-next
135 void AT91InitInterrupt(void(*timer_func)(), void(*rxrdy_func)())
136 {
137 #if !ANGEL
138 int irq_id ;
139 #endif // ANGEL
140
141 timer_function = timer_func;
\ AT91InitInterrupt:
\ 00000000 ........ LDR R2,??DataTable3 ;; timer_function
\ 00000004 000082E5 STR R0,[R2, #+0]
142 rxrdy_function = rxrdy_func;
\ 00000008 ........ LDR R0,??DataTable4 ;; rxrdy_function
\ 0000000C 001080E5 STR R1,[R0, #+0]
143
144 #if !ANGEL
145 // Disable all interrupts.
146 __AIC_IDCR = 0xFFFFFFFF;
\ 00000010 DB00E0E3 MVN R0,#+219
\ 00000014 E00EC0E3 BIC R0,R0,#0xE00
\ 00000018 0010E0E3 MVN R1,#+0
\ 0000001C 001080E5 STR R1,[R0, #+0]
147 // Clear all interrupts.
148 __AIC_ICCR = 0xFFFFFFFF;
\ 00000020 D700E0E3 MVN R0,#+215
\ 00000024 E00EC0E3 BIC R0,R0,#0xE00
\ 00000028 0010E0E3 MVN R1,#+0
\ 0000002C 001080E5 STR R1,[R0, #+0]
149
150 // For each priority level.
151 for (irq_id = 0; irq_id < 8; irq_id++)
\ 00000030 0000A0E3 MOV R0,#+0
\ 00000034 040000EA B ??AT91InitInterrupt_0
152 {
153 // Unstack a level by writting in AIC_EOICR.
154 // Value written has no effect.
155 __AIC_EOICR = 0;
\ ??AT91InitInterrupt_1:
\ 00000038 CF10E0E3 MVN R1,#+207
\ 0000003C E01EC1E3 BIC R1,R1,#0xE00
\ 00000040 0020A0E3 MOV R2,#+0
\ 00000044 002081E5 STR R2,[R1, #+0]
156 }
\ 00000048 010090E2 ADDS R0,R0,#+1
\ ??AT91InitInterrupt_0:
\ 0000004C 080050E3 CMP R0,#+8
\ 00000050 F8FFFFBA BLT ??AT91InitInterrupt_1
157
158 {
159 // For each interrupt source.
160 __REG32 volatile* aic_smr_base = &__AIC_SMR0;
\ 00000054 FF10E0E3 MVN R1,#+255
\ 00000058 F01EC1E3 BIC R1,R1,#0xF00
161 __REG32 volatile* aic_svr_base = &__AIC_SVR0;
\ 0000005C 7F20E0E3 MVN R2,#+127
\ 00000060 F02EC2E3 BIC R2,R2,#0xF00
162 for (irq_id = 0; irq_id < 32; irq_id++)
\ 00000064 0000A0E3 MOV R0,#+0
\ 00000068 080000EA B ??AT91InitInterrupt_2
163 {
164 // Priority is lowest.
165 aic_smr_base[irq_id] = 0 ;
\ ??AT91InitInterrupt_3:
\ 0000006C 0430A0E3 MOV R3,#+4
\ 00000070 93102CE0 MLA R12,R3,R0,R1
\ 00000074 0030A0E3 MOV R3,#+0
\ 00000078 00308CE5 STR R3,[R12, #+0]
166 // Interrupt routine is undefined.
167 aic_svr_base[irq_id] = (unsigned long)&undefined_irq;
\ 0000007C 0430A0E3 MOV R3,#+4
\ 00000080 93202CE0 MLA R12,R3,R0,R2
\ 00000084 44309FE5 LDR R3,??AT91InitInterrupt_4 ;; undefined_irq
\ 00000088 00308CE5 STR R3,[R12, #+0]
168 }
\ 0000008C 010090E2 ADDS R0,R0,#+1
\ ??AT91InitInterrupt_2:
\ 00000090 200050E3 CMP R0,#+32
\ 00000094 F4FFFFBA BLT ??AT91InitInterrupt_3
169 }
170
171 __AIC_SPU = (unsigned long)&undefined_irq; // Spurious interrupt vector.
\ 00000098 CB00E0E3 MVN R0,#+203
\ 0000009C E00EC0E3 BIC R0,R0,#0xE00
\ 000000A0 28109FE5 LDR R1,??AT91InitInterrupt_4 ;; undefined_irq
\ 000000A4 001080E5 STR R1,[R0, #+0]
172 __SF_PMR = 0x27a80020; // Run AIC in protected mode.
\ 000000A8 24009FE5 LDR R0,??AT91InitInterrupt_4+0x4 ;; 0xfffffffffff00018
\ 000000AC 24109FE5 LDR R1,??AT91InitInterrupt_4+0x8 ;; 0x27a80020
\ 000000B0 001080E5 STR R1,[R0, #+0]
173 __SF_PMR = 0x27a80020; // Run AIC in protected mode. EB40A requires this twice.
\ 000000B4 18009FE5 LDR R0,??AT91InitInterrupt_4+0x4 ;; 0xfffffffffff00018
\ 000000B8 18109FE5 LDR R1,??AT91InitInterrupt_4+0x8 ;; 0x27a80020
\ 000000BC 001080E5 STR R1,[R0, #+0]
174 // Initialize ARM IRQ vector to map to interrupt controller.
175 *(unsigned long *)0x18 = 0xe51fff20; // ldr pc,[pc,#-0xf20]
\ 000000C0 1800A0E3 MOV R0,#+24
\ 000000C4 10109FE5 LDR R1,??AT91InitInterrupt_4+0xC ;; 0xffffffffe51fff20
\ 000000C8 001080E5 STR R1,[R0, #+0]
176 #endif // ANGEL
177
178 #if ANGEL
179 // The Angel ROM monitor code is written to allow AIC
180 // protected mode. That means that from tis point it is
181 // safe to look at the AIC registers from the memory and
182 // register windows. Take care not to start up C-SPY with
183 // AIC display active since the ROM monitor itself does not
184 // Enable protected mode.
185 __SF_PMR = 0x27a80020; // Run AIC in protected mode.
186 #endif // ANGEL
187 }
\ 000000CC 1EFF2FE1 BX LR ;; return
\ ??AT91InitInterrupt_4:
\ 000000D0 ........ DC32 undefined_irq
\ 000000D4 1800F0FF DC32 0xfffffffffff00018
\ 000000D8 2000A827 DC32 0x27a80020
\ 000000DC 20FF1FE5 DC32 0xffffffffe51fff20
188
189
190 //
191 // Timer functions.
192 //
193
\ In segment CODE, align 4, keep-with-next
194 void AT91InitTimer()
195 {
196 __TC_IDRC0 = 0xff; // Disable all timer/counter 0 interrupts.
\ AT91InitTimer:
\ 00000000 AC009FE5 LDR R0,??AT91InitTimer_0 ;; 0xfffffffffffe0028
\ 00000004 FF10A0E3 MOV R1,#+255
\ 00000008 001080E5 STR R1,[R0, #+0]
197 #if AT91_EB40 || AT91_EB40A
198 __AIC_SVR4 = (unsigned long)&heartbeat_irq;
\ 0000000C 6F00E0E3 MVN R0,#+111
\ 00000010 F00EC0E3 BIC R0,R0,#0xF00
\ 00000014 9C109FE5 LDR R1,??AT91InitTimer_0+0x4 ;; heartbeat_irq
\ 00000018 001080E5 STR R1,[R0, #+0]
199 __AIC_SMR4 = 0x26;
\ 0000001C EF00E0E3 MVN R0,#+239
\ 00000020 F00EC0E3 BIC R0,R0,#0xF00
\ 00000024 2610A0E3 MOV R1,#+38
\ 00000028 001080E5 STR R1,[R0, #+0]
200 #else
201 __AIC_SVR6 = (unsigned long)&heartbeat_irq; // Timer/counter 0 interrupt vector.
202 __AIC_SMR6 = 0x26; // SRCTYPE=1, PRIOR=6. Timer/counter 0 interrupt edge-triggered at prio 6.
203 #endif
204 __AIC_ICCR_bit.tc0irq = 1; // Clears timer/counter 0 interrupt.
\ 0000002C D700E0E3 MVN R0,#+215
\ 00000030 E00EC0E3 BIC R0,R0,#0xE00
\ 00000034 D710E0E3 MVN R1,#+215
\ 00000038 E01EC1E3 BIC R1,R1,#0xE00
\ 0000003C 001091E5 LDR R1,[R1, #+0]
\ 00000040 101091E3 ORRS R1,R1,#0x10
\ 00000044 001080E5 STR R1,[R0, #+0]
205 __AIC_IECR_bit.tc0irq = 1; // Enable timer/counter 0 interrupt.
\ 00000048 DF00E0E3 MVN R0,#+223
\ 0000004C E00EC0E3 BIC R0,R0,#0xE00
\ 00000050 DF10E0E3 MVN R1,#+223
\ 00000054 E01EC1E3 BIC R1,R1,#0xE00
\ 00000058 001091E5 LDR R1,[R1, #+0]
\ 0000005C 101091E3 ORRS R1,R1,#0x10
\ 00000060 001080E5 STR R1,[R0, #+0]
206
207 __TC_CMRC0 = 0x00004002; // Capture mode, CPCTRG=1, TCCLKS=2 (/32).
\ 00000064 50009FE5 LDR R0,??AT91InitTimer_0+0x8 ;; 0xfffffffffffe0004
\ 00000068 0210A0E3 MOV R1,#+2
\ 0000006C 401C81E3 ORR R1,R1,#0x4000
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -