1 | /*****************************************************************************
|
2 | Exception handlers and startup code for Atmel AT91SAM7.
|
3 |
|
4 | Copyright (c) 2004 Rowley Associates Limited.
|
5 |
|
6 | This file may be distributed under the terms of the License Agreement
|
7 | provided with this software.
|
8 |
|
9 | THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
|
10 | WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
11 | *****************************************************************************/
|
12 |
|
13 | /*****************************************************************************
|
14 | * Preprocessor Definitions
|
15 | * ------------------------
|
16 | *
|
17 | * VECTORED_IRQ_INTERRUPTS
|
18 | *
|
19 | * Enable vectored IRQ interrupts. If defined, the PC register will be loaded
|
20 | * with the contents of the AIC_IVR register on an IRQ exception.
|
21 | *
|
22 | * STARTUP_FROM_RESET
|
23 | *
|
24 | * If defined, the program will startup from power-on/reset. If not defined
|
25 | * the program will just loop endlessly from power-on/reset.
|
26 | *
|
27 | * This definition is not defined by default on this target because the
|
28 | * debugger is unable to reset this target and maintain control of it over the
|
29 | * JTAG interface. The advantage of doing this is that it allows the debugger
|
30 | * to reset the CPU and run programs from a known reset CPU state on each run.
|
31 | * It also acts as a safety net if you accidently download a program in FLASH
|
32 | * that crashes and prevents the debugger from taking control over JTAG
|
33 | * rendering the target unusable over JTAG. The obvious disadvantage of doing
|
34 | * this is that your application will not startup without the debugger.
|
35 | *
|
36 | * We advise that on this target you keep STARTUP_FROM_RESET undefined whilst
|
37 | * you are developing and only define STARTUP_FROM_RESET when development is
|
38 | * complete.
|
39 | *
|
40 | * MC_FMR_FMCN_VAL
|
41 | *
|
42 | * Override the default Flash Mode Register FMCN value by defining
|
43 | * MC_FMR_FMCN_VAL.
|
44 | *
|
45 | * MC_FMR_FWS_VAL
|
46 | *
|
47 | * Override the default Flash Mode Register FWS value by defining
|
48 | * MC_FMR_FWS_VAL.
|
49 | *
|
50 | * CKGR_MOR_VAL
|
51 | *
|
52 | * Override the default Main Oscillator Register value by defining
|
53 | * CKGR_MOR_VAL.
|
54 | *
|
55 | * CKGR_PLLR_VAL
|
56 | *
|
57 | * Override the default Clock Generator PLL Register value by defining
|
58 | * CKGR_PLLR_VAL.
|
59 | *
|
60 | * NO_WATCHDOG_DISABLE
|
61 | *
|
62 | * If defined, the watchdog will not be disabled.
|
63 | *
|
64 | * NO_USER_RESET
|
65 | *
|
66 | * If defined, user reset will not be enabled.
|
67 | *
|
68 | * NO_PROTECTION_MODE
|
69 | *
|
70 | * If defined, AIC protection mode will not be enabled. AIC protection
|
71 | * mode allows the AIC_IVR register to be accessed by the debugger (for
|
72 | * example through the memory or register window). With protection mode
|
73 | * disabled accesses of the AIC_IVR register by the debugger are likely
|
74 | * to disrupt interrupt behaviour.
|
75 | *
|
76 | *****************************************************************************/
|
77 |
|
78 | #include <targets/AT91SAM7.h>
|
79 |
|
80 | #ifndef MC_FMR_FMCN_VAL
|
81 | #define MC_FMR_FMCN_VAL 72
|
82 | #endif
|
83 |
|
84 | #ifndef MC_FMR_FWS_VAL
|
85 | #define MC_FMR_FWS_VAL 1
|
86 | #endif
|
87 |
|
88 | #ifndef CKGR_MOR_VAL
|
89 | #define CKGR_MOR_VAL (0x40 << CKGR_MOR_OSCOUNT_BIT) | CKGR_MOR_MOSCEN
|
90 | #endif
|
91 |
|
92 | #ifndef CKGR_PLLR_VAL
|
93 | #if OSCILLATOR_CLOCK_FREQUENCY==18432000
|
94 | /* MCK, UDPCK = 18.432MHz * 73 / 14 / 2 = 48.05486MHz */
|
95 | #define CKGR_PLLR_VAL (1 << CKGR_PLLR_USBDIV_BIT) | (72 << CKGR_PLLR_MUL_BIT) | (0 << CKGR_PLLR_OUT_BIT) | (63 << CKGR_PLLR_PLLCOUNT_BIT) | (14 << CKGR_PLLR_DIV_BIT)
|
96 | #else
|
97 | #error OSCILLATOR_CLOCK_FREQUENCY not supported
|
98 | #endif
|
99 | #endif
|
100 |
|
101 | .section .vectors, "ax"
|
102 | .code 32
|
103 | .align 0
|
104 | .global _vectors
|
105 | .global reset_handler
|
106 |
|
107 | /*****************************************************************************
|
108 | Exception Vectors
|
109 | *****************************************************************************/
|
110 | _vectors:
|
111 | #ifdef STARTUP_FROM_RESET
|
112 | ldr pc, [pc, #reset_handler_address - . - 8] /* reset */
|
113 | #else
|
114 | b . /* reset - infinite loop */
|
115 | #endif
|
116 | ldr pc, [pc, #undef_handler_address - . - 8] /* undefined instruction */
|
117 | ldr pc, [pc, #swi_handler_address - . - 8] /* swi handler */
|
118 | ldr pc, [pc, #pabort_handler_address - . - 8] /* abort prefetch */
|
119 | ldr pc, [pc, #dabort_handler_address - . - 8] /* abort data */
|
120 | nop
|
121 | #ifdef VECTORED_IRQ_INTERRUPTS
|
122 | ldr pc, [pc, #-0xF20] /* irq */
|
123 | #else
|
124 | ldr pc, [pc, #irq_handler_address - . - 8] /* irq */
|
125 | #endif
|
126 | ldr pc, [pc, #fiq_handler_address - . - 8] /* fiq */
|
127 |
|
128 | reset_handler_address:
|
129 | .word reset_handler
|
130 | undef_handler_address:
|
131 | .word undef_handler
|
132 | swi_handler_address:
|
133 | .word swi_handler
|
134 | pabort_handler_address:
|
135 | .word pabort_handler
|
136 | dabort_handler_address:
|
137 | .word dabort_handler
|
138 | irq_handler_address:
|
139 | .word irq_handler
|
140 | fiq_handler_address:
|
141 | .word fiq_handler
|
142 |
|
143 | .section .init, "ax"
|
144 | .code 32
|
145 | .align 0
|
146 |
|
147 | /******************************************************************************
|
148 | Reset handler
|
149 | ******************************************************************************/
|
150 | reset_handler:
|
151 | /* Set up FLASH wait state */
|
152 | ldr r1, =MC_BASE
|
153 | #ifdef MC_FMR1_OFFSET
|
154 | ldr r0, =(MC_FMR_FMCN_VAL << MC_FMR0_FMCN_BIT) | (MC_FMR_FWS_VAL << MC_FMR0_FWS_BIT)
|
155 | str r0, [r1, #MC_FMR0_OFFSET]
|
156 | str r0, [r1, #MC_FMR1_OFFSET]
|
157 | #else
|
158 | ldr r0, =(MC_FMR_FMCN_VAL << MC_FMR_FMCN_BIT) | (MC_FMR_FWS_VAL << MC_FMR_FWS_BIT)
|
159 | str r0, [r1, #MC_FMR_OFFSET]
|
160 | #endif
|
161 |
|
162 | #ifndef NO_WATCHDOG_DISABLE
|
163 | /* Disable Watchdog */
|
164 | ldr r1, =WDT_BASE
|
165 | ldr r0, =WDT_MR_WDDIS
|
166 | str r0, [r1, #WDT_MR_OFFSET]
|
167 | #endif
|
168 |
|
169 | #ifndef NO_USER_RESET
|
170 | /* Enable user reset */
|
171 | ldr r1, =RSTC_BASE
|
172 | ldr r0, =0xA5000001
|
173 | str r0, [r1, #RSTC_MR_OFFSET]
|
174 | #endif
|
175 |
|
176 | #ifndef NO_PROTECTION_MODE
|
177 | /* Enable protect mode */
|
178 | ldr r1, =AIC_BASE
|
179 | ldr r0, =0x00000001
|
180 | str r0, [r1, #AIC_DCR_OFFSET]
|
181 | #endif
|
182 |
|
183 | /* Enable the main oscillator */
|
184 | ldr r1, =PMC_BASE
|
185 | ldr r0, =CKGR_MOR_VAL
|
186 | str r0, [r1, #CKGR_MOR_OFFSET]
|
187 |
|
188 | 1:/* Wait for main oscillator to stabilize */
|
189 | ldr r0, [r1, #PMC_SR_OFFSET]
|
190 | tst r0, #PMC_SR_MOSCS
|
191 | beq 1b
|
192 |
|
193 | /* Set up the PLL */
|
194 | ldr r0, =CKGR_PLLR_VAL
|
195 | str r0, [r1, #CKGR_PLLR_OFFSET]
|
196 |
|
197 | 1:/* Wait for PLL to lock */
|
198 | ldr r0, [r1, #PMC_SR_OFFSET]
|
199 | tst r0, #PMC_SR_LOCK
|
200 | beq 1b
|
201 |
|
202 | /* Set the master clock prescaler */
|
203 | ldr r0, =(1 << PMC_MCKR_PRES_BIT)
|
204 | str r0, [r1, #PMC_MCKR_OFFSET]
|
205 |
|
206 | 1:/* Wait for MCKRDY */
|
207 | ldr r0, [r1, #PMC_SR_OFFSET]
|
208 | tst r0, #PMC_SR_MCKRDY
|
209 | beq 1b
|
210 |
|
211 | /* Select PLL as clock source */
|
212 | ldr r0, =((1 << PMC_MCKR_PRES_BIT) | 3 << PMC_MCKR_CSS_BIT)
|
213 | str r0, [r1, #PMC_MCKR_OFFSET]
|
214 |
|
215 | 1:/* Wait for MCKRDY */
|
216 | ldr r0, [r1, #PMC_SR_OFFSET]
|
217 | tst r0, #PMC_SR_MCKRDY
|
218 | beq 1b
|
219 |
|
220 | #ifdef __FLASH_BUILD
|
221 | /* Copy exception vectors into Internal SRAM */
|
222 | mov r8, #0x00200000
|
223 | ldr r9, =_vectors
|
224 | ldmia r9!, {r0-r7}
|
225 | stmia r8!, {r0-r7}
|
226 | ldmia r9!, {r0-r6}
|
227 | stmia r8!, {r0-r6}
|
228 |
|
229 | /* Remap Internal SRAM to 0x00000000 */
|
230 | ldr r1, =MC_BASE
|
231 | ldr r0, =1
|
232 | strb r0, [r1, #MC_RCR_OFFSET]
|
233 | #endif
|
234 |
|
235 | /* Jump to the default C runtime startup code. */
|
236 | b _start
|
237 |
|
238 | /******************************************************************************
|
239 | Default exception handlers
|
240 | (These are declared weak symbols so they can be redefined in user code)
|
241 | ******************************************************************************/
|
242 | undef_handler:
|
243 | b . /* Endless loop */
|
244 |
|
245 | swi_handler:
|
246 | b . /* Endless loop */
|
247 |
|
248 | pabort_handler:
|
249 | b . /* Endless loop */
|
250 |
|
251 | dabort_handler:
|
252 | b . /* Endless loop */
|
253 |
|
254 | irq_handler:
|
255 | b . /* Endless loop */
|
256 |
|
257 | fiq_handler:
|
258 | b . /* Endless loop */
|
259 |
|
260 | .weak undef_handler, swi_handler, pabort_handler, dabort_handler, irq_handler, fiq_handler
|