35f00b6c |
1 | /* Teensyduino Core Library |
2 | * http://www.pjrc.com/teensy/ |
3 | * Copyright (c) 2013 PJRC.COM, LLC. |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining |
6 | * a copy of this software and associated documentation files (the |
7 | * "Software"), to deal in the Software without restriction, including |
8 | * without limitation the rights to use, copy, modify, merge, publish, |
9 | * distribute, sublicense, and/or sell copies of the Software, and to |
10 | * permit persons to whom the Software is furnished to do so, subject to |
11 | * the following conditions: |
12 | * |
13 | * 1. The above copyright notice and this permission notice shall be |
14 | * included in all copies or substantial portions of the Software. |
15 | * |
16 | * 2. If the Software is incorporated into a build system that allows |
17 | * selection among a list of target devices, then similar target |
18 | * devices manufactured by PJRC.COM must be included in the list of |
19 | * target devices and selectable in the same manner. |
20 | * |
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
23 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
25 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
26 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
28 | * SOFTWARE. |
29 | */ |
30 | |
31 | #include "mk20dx128.h" |
32 | |
33 | |
34 | extern unsigned long _stext; |
35 | extern unsigned long _etext; |
36 | extern unsigned long _sdata; |
37 | extern unsigned long _edata; |
38 | extern unsigned long _sbss; |
39 | extern unsigned long _ebss; |
40 | extern unsigned long _estack; |
41 | //extern void __init_array_start(void); |
42 | //extern void __init_array_end(void); |
43 | extern int main (void); |
44 | void ResetHandler(void); |
45 | void _init_Teensyduino_internal_(void); |
46 | void __libc_init_array(void); |
47 | |
48 | |
49 | void fault_isr(void) |
50 | { |
51 | while (1) { |
52 | // keep polling some communication while in fault |
53 | // mode, so we don't completely die. |
54 | if (SIM_SCGC4 & SIM_SCGC4_USBOTG) usb_isr(); |
55 | if (SIM_SCGC4 & SIM_SCGC4_UART0) uart0_status_isr(); |
56 | if (SIM_SCGC4 & SIM_SCGC4_UART1) uart1_status_isr(); |
57 | if (SIM_SCGC4 & SIM_SCGC4_UART2) uart2_status_isr(); |
58 | } |
59 | } |
60 | |
61 | void unused_isr(void) |
62 | { |
63 | fault_isr(); |
64 | } |
65 | |
66 | extern volatile uint32_t systick_millis_count; |
67 | void systick_default_isr(void) |
68 | { |
69 | systick_millis_count++; |
70 | } |
71 | |
72 | void nmi_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
73 | void hard_fault_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
74 | void memmanage_fault_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
75 | void bus_fault_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
76 | void usage_fault_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
77 | void svcall_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
78 | void debugmonitor_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
79 | void pendablesrvreq_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
80 | void systick_isr(void) __attribute__ ((weak, alias("systick_default_isr"))); |
81 | |
82 | void dma_ch0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
83 | void dma_ch1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
84 | void dma_ch2_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
85 | void dma_ch3_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
86 | void dma_ch4_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
87 | void dma_ch5_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
88 | void dma_ch6_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
89 | void dma_ch7_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
90 | void dma_ch8_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
91 | void dma_ch9_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
92 | void dma_ch10_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
93 | void dma_ch11_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
94 | void dma_ch12_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
95 | void dma_ch13_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
96 | void dma_ch14_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
97 | void dma_ch15_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
98 | void dma_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
99 | void mcm_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
100 | void flash_cmd_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
101 | void flash_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
102 | void low_voltage_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
103 | void wakeup_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
104 | void watchdog_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
105 | void i2c0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
106 | void i2c1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
107 | void i2c2_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
108 | void spi0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
109 | void spi1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
110 | void spi2_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
111 | void sdhc_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
112 | void can0_message_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
113 | void can0_bus_off_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
114 | void can0_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
115 | void can0_tx_warn_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
116 | void can0_rx_warn_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
117 | void can0_wakeup_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
118 | void i2s0_tx_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
119 | void i2s0_rx_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
120 | void uart0_lon_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
121 | void uart0_status_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
122 | void uart0_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
123 | void uart1_status_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
124 | void uart1_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
125 | void uart2_status_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
126 | void uart2_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
127 | void uart3_status_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
128 | void uart3_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
129 | void uart4_status_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
130 | void uart4_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
131 | void uart5_status_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
132 | void uart5_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
133 | void adc0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
134 | void adc1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
135 | void cmp0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
136 | void cmp1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
137 | void cmp2_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
138 | void ftm0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
139 | void ftm1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
140 | void ftm2_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
141 | void ftm3_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
142 | void cmt_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
143 | void rtc_alarm_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
144 | void rtc_seconds_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
145 | void pit0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
146 | void pit1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
147 | void pit2_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
148 | void pit3_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
149 | void pdb_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
150 | void usb_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
151 | void usb_charge_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
152 | void dac0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
153 | void dac1_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
154 | void tsi0_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
155 | void mcg_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
156 | void lptmr_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
157 | void porta_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
158 | void portb_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
159 | void portc_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
160 | void portd_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
161 | void porte_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
162 | void software_isr(void) __attribute__ ((weak, alias("unused_isr"))); |
163 | |
164 | |
165 | // TODO: create AVR-stype ISR() macro, with default linkage to undefined handler |
166 | // |
167 | __attribute__ ((section(".vectors"), used)) |
168 | void (* const gVectors[])(void) = |
169 | { |
170 | (void (*)(void))((unsigned long)&_estack), // 0 ARM: Initial Stack Pointer |
171 | ResetHandler, // 1 ARM: Initial Program Counter |
172 | nmi_isr, // 2 ARM: Non-maskable Interrupt (NMI) |
173 | hard_fault_isr, // 3 ARM: Hard Fault |
174 | memmanage_fault_isr, // 4 ARM: MemManage Fault |
175 | bus_fault_isr, // 5 ARM: Bus Fault |
176 | usage_fault_isr, // 6 ARM: Usage Fault |
177 | fault_isr, // 7 -- |
178 | fault_isr, // 8 -- |
179 | fault_isr, // 9 -- |
180 | fault_isr, // 10 -- |
181 | svcall_isr, // 11 ARM: Supervisor call (SVCall) |
182 | debugmonitor_isr, // 12 ARM: Debug Monitor |
183 | fault_isr, // 13 -- |
184 | pendablesrvreq_isr, // 14 ARM: Pendable req serv(PendableSrvReq) |
185 | systick_isr, // 15 ARM: System tick timer (SysTick) |
186 | #if defined(__MK20DX128__) |
187 | dma_ch0_isr, // 16 DMA channel 0 transfer complete |
188 | dma_ch1_isr, // 17 DMA channel 1 transfer complete |
189 | dma_ch2_isr, // 18 DMA channel 2 transfer complete |
190 | dma_ch3_isr, // 19 DMA channel 3 transfer complete |
191 | dma_error_isr, // 20 DMA error interrupt channel |
192 | unused_isr, // 21 DMA -- |
193 | flash_cmd_isr, // 22 Flash Memory Command complete |
194 | flash_error_isr, // 23 Flash Read collision |
195 | low_voltage_isr, // 24 Low-voltage detect/warning |
196 | wakeup_isr, // 25 Low Leakage Wakeup |
197 | watchdog_isr, // 26 Both EWM and WDOG interrupt |
198 | i2c0_isr, // 27 I2C0 |
199 | spi0_isr, // 28 SPI0 |
200 | i2s0_tx_isr, // 29 I2S0 Transmit |
201 | i2s0_rx_isr, // 30 I2S0 Receive |
202 | uart0_lon_isr, // 31 UART0 CEA709.1-B (LON) status |
203 | uart0_status_isr, // 32 UART0 status |
204 | uart0_error_isr, // 33 UART0 error |
205 | uart1_status_isr, // 34 UART1 status |
206 | uart1_error_isr, // 35 UART1 error |
207 | uart2_status_isr, // 36 UART2 status |
208 | uart2_error_isr, // 37 UART2 error |
209 | adc0_isr, // 38 ADC0 |
210 | cmp0_isr, // 39 CMP0 |
211 | cmp1_isr, // 40 CMP1 |
212 | ftm0_isr, // 41 FTM0 |
213 | ftm1_isr, // 42 FTM1 |
214 | cmt_isr, // 43 CMT |
215 | rtc_alarm_isr, // 44 RTC Alarm interrupt |
216 | rtc_seconds_isr, // 45 RTC Seconds interrupt |
217 | pit0_isr, // 46 PIT Channel 0 |
218 | pit1_isr, // 47 PIT Channel 1 |
219 | pit2_isr, // 48 PIT Channel 2 |
220 | pit3_isr, // 49 PIT Channel 3 |
221 | pdb_isr, // 50 PDB Programmable Delay Block |
222 | usb_isr, // 51 USB OTG |
223 | usb_charge_isr, // 52 USB Charger Detect |
224 | tsi0_isr, // 53 TSI0 |
225 | mcg_isr, // 54 MCG |
226 | lptmr_isr, // 55 Low Power Timer |
227 | porta_isr, // 56 Pin detect (Port A) |
228 | portb_isr, // 57 Pin detect (Port B) |
229 | portc_isr, // 58 Pin detect (Port C) |
230 | portd_isr, // 59 Pin detect (Port D) |
231 | porte_isr, // 60 Pin detect (Port E) |
232 | software_isr, // 61 Software interrupt |
233 | #elif defined(__MK20DX256__) |
234 | dma_ch0_isr, // 16 DMA channel 0 transfer complete |
235 | dma_ch1_isr, // 17 DMA channel 1 transfer complete |
236 | dma_ch2_isr, // 18 DMA channel 2 transfer complete |
237 | dma_ch3_isr, // 19 DMA channel 3 transfer complete |
238 | dma_ch4_isr, // 20 DMA channel 4 transfer complete |
239 | dma_ch5_isr, // 21 DMA channel 5 transfer complete |
240 | dma_ch6_isr, // 22 DMA channel 6 transfer complete |
241 | dma_ch7_isr, // 23 DMA channel 7 transfer complete |
242 | dma_ch8_isr, // 24 DMA channel 8 transfer complete |
243 | dma_ch9_isr, // 25 DMA channel 9 transfer complete |
244 | dma_ch10_isr, // 26 DMA channel 10 transfer complete |
245 | dma_ch11_isr, // 27 DMA channel 10 transfer complete |
246 | dma_ch12_isr, // 28 DMA channel 10 transfer complete |
247 | dma_ch13_isr, // 29 DMA channel 10 transfer complete |
248 | dma_ch14_isr, // 30 DMA channel 10 transfer complete |
249 | dma_ch15_isr, // 31 DMA channel 10 transfer complete |
250 | dma_error_isr, // 32 DMA error interrupt channel |
251 | unused_isr, // 33 -- |
252 | flash_cmd_isr, // 34 Flash Memory Command complete |
253 | flash_error_isr, // 35 Flash Read collision |
254 | low_voltage_isr, // 36 Low-voltage detect/warning |
255 | wakeup_isr, // 37 Low Leakage Wakeup |
256 | watchdog_isr, // 38 Both EWM and WDOG interrupt |
257 | unused_isr, // 39 -- |
258 | i2c0_isr, // 40 I2C0 |
259 | i2c1_isr, // 41 I2C1 |
260 | spi0_isr, // 42 SPI0 |
261 | spi1_isr, // 43 SPI1 |
262 | unused_isr, // 44 -- |
263 | can0_message_isr, // 45 CAN OR'ed Message buffer (0-15) |
264 | can0_bus_off_isr, // 46 CAN Bus Off |
265 | can0_error_isr, // 47 CAN Error |
266 | can0_tx_warn_isr, // 48 CAN Transmit Warning |
267 | can0_rx_warn_isr, // 49 CAN Receive Warning |
268 | can0_wakeup_isr, // 50 CAN Wake Up |
269 | i2s0_tx_isr, // 51 I2S0 Transmit |
270 | i2s0_rx_isr, // 52 I2S0 Receive |
271 | unused_isr, // 53 -- |
272 | unused_isr, // 54 -- |
273 | unused_isr, // 55 -- |
274 | unused_isr, // 56 -- |
275 | unused_isr, // 57 -- |
276 | unused_isr, // 58 -- |
277 | unused_isr, // 59 -- |
278 | uart0_lon_isr, // 60 UART0 CEA709.1-B (LON) status |
279 | uart0_status_isr, // 61 UART0 status |
280 | uart0_error_isr, // 62 UART0 error |
281 | uart1_status_isr, // 63 UART1 status |
282 | uart1_error_isr, // 64 UART1 error |
283 | uart2_status_isr, // 65 UART2 status |
284 | uart2_error_isr, // 66 UART2 error |
285 | unused_isr, // 67 -- |
286 | unused_isr, // 68 -- |
287 | unused_isr, // 69 -- |
288 | unused_isr, // 70 -- |
289 | unused_isr, // 71 -- |
290 | unused_isr, // 72 -- |
291 | adc0_isr, // 73 ADC0 |
292 | adc1_isr, // 74 ADC1 |
293 | cmp0_isr, // 75 CMP0 |
294 | cmp1_isr, // 76 CMP1 |
295 | cmp2_isr, // 77 CMP2 |
296 | ftm0_isr, // 78 FTM0 |
297 | ftm1_isr, // 79 FTM1 |
298 | ftm2_isr, // 80 FTM2 |
299 | cmt_isr, // 81 CMT |
300 | rtc_alarm_isr, // 82 RTC Alarm interrupt |
301 | rtc_seconds_isr, // 83 RTC Seconds interrupt |
302 | pit0_isr, // 84 PIT Channel 0 |
303 | pit1_isr, // 85 PIT Channel 1 |
304 | pit2_isr, // 86 PIT Channel 2 |
305 | pit3_isr, // 87 PIT Channel 3 |
306 | pdb_isr, // 88 PDB Programmable Delay Block |
307 | usb_isr, // 89 USB OTG |
308 | usb_charge_isr, // 90 USB Charger Detect |
309 | unused_isr, // 91 -- |
310 | unused_isr, // 92 -- |
311 | unused_isr, // 93 -- |
312 | unused_isr, // 94 -- |
313 | unused_isr, // 95 -- |
314 | unused_isr, // 96 -- |
315 | dac0_isr, // 97 DAC0 |
316 | unused_isr, // 98 -- |
317 | tsi0_isr, // 99 TSI0 |
318 | mcg_isr, // 100 MCG |
319 | lptmr_isr, // 101 Low Power Timer |
320 | unused_isr, // 102 -- |
321 | porta_isr, // 103 Pin detect (Port A) |
322 | portb_isr, // 104 Pin detect (Port B) |
323 | portc_isr, // 105 Pin detect (Port C) |
324 | portd_isr, // 106 Pin detect (Port D) |
325 | porte_isr, // 107 Pin detect (Port E) |
326 | unused_isr, // 108 -- |
327 | unused_isr, // 109 -- |
328 | software_isr, // 110 Software interrupt |
329 | #endif |
330 | }; |
331 | |
332 | //void usb_isr(void) |
333 | //{ |
334 | //} |
335 | |
336 | __attribute__ ((section(".flashconfig"), used)) |
337 | const uint8_t flashconfigbytes[16] = { |
338 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
339 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF |
340 | }; |
341 | |
342 | |
343 | // Automatically initialize the RTC. When the build defines the compile |
344 | // time, and the user has added a crystal, the RTC will automatically |
345 | // begin at the time of the first upload. |
346 | #ifndef TIME_T |
347 | #define TIME_T 1349049600 // default 1 Oct 2012 (never used, Arduino sets this) |
348 | #endif |
349 | extern void rtc_set(unsigned long t); |
350 | |
351 | |
352 | static void startup_default_early_hook(void) { WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; } |
353 | static void startup_default_late_hook(void) {} |
354 | void startup_early_hook(void) __attribute__ ((weak, alias("startup_default_early_hook"))); |
355 | void startup_late_hook(void) __attribute__ ((weak, alias("startup_default_late_hook"))); |
356 | |
357 | __attribute__ ((section(".startup"))) |
358 | void ResetHandler(void) |
359 | { |
360 | uint32_t *src = &_etext; |
361 | uint32_t *dest = &_sdata; |
362 | unsigned int i; |
363 | |
364 | WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; |
365 | WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; |
366 | asm volatile ("nop"); |
367 | asm volatile ("nop"); |
368 | // programs using the watchdog timer or needing to initialize hardware as |
369 | // early as possible can implement startup_early_hook() |
370 | startup_early_hook(); |
371 | |
372 | // enable clocks to always-used peripherals |
373 | #if defined(__MK20DX128__) |
374 | SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO |
375 | SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL; |
376 | #elif defined(__MK20DX256__) |
377 | SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2; |
378 | SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO |
379 | SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL; |
380 | #endif |
381 | |
382 | // if the RTC oscillator isn't enabled, get it started early |
383 | if (!(RTC_CR & RTC_CR_OSCE)) { |
384 | RTC_SR = 0; |
385 | RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE; |
386 | } |
387 | |
388 | // release I/O pins hold, if we woke up from VLLS mode |
389 | if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO; |
390 | |
391 | // TODO: do this while the PLL is waiting to lock.... |
392 | while (dest < &_edata) *dest++ = *src++; |
393 | dest = &_sbss; |
394 | while (dest < &_ebss) *dest++ = 0; |
395 | SCB_VTOR = 0; // use vector table in flash |
396 | |
397 | // default all interrupts to medium priority level |
398 | for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128); |
399 | |
400 | // start in FEI mode |
401 | // enable capacitors for crystal |
402 | OSC0_CR = OSC_SC8P | OSC_SC2P; |
403 | // enable osc, 8-32 MHz range, low power mode |
404 | MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS; |
405 | // switch to crystal as clock source, FLL input = 16 MHz / 512 |
406 | MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4); |
407 | // wait for crystal oscillator to begin |
408 | while ((MCG_S & MCG_S_OSCINIT0) == 0) ; |
409 | // wait for FLL to use oscillator |
410 | while ((MCG_S & MCG_S_IREFST) != 0) ; |
411 | // wait for MCGOUT to use oscillator |
412 | while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; |
413 | // now we're in FBE mode |
414 | // config PLL input for 16 MHz Crystal / 4 = 4 MHz |
415 | MCG_C5 = MCG_C5_PRDIV0(3); |
416 | // config PLL for 96 MHz output |
417 | MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); |
418 | // wait for PLL to start using xtal as its input |
419 | while (!(MCG_S & MCG_S_PLLST)) ; |
420 | // wait for PLL to lock |
421 | while (!(MCG_S & MCG_S_LOCK0)) ; |
422 | // now we're in PBE mode |
423 | #if F_CPU == 96000000 |
424 | // config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash |
425 | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); |
426 | #elif F_CPU == 48000000 |
427 | // config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash |
428 | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); |
429 | #elif F_CPU == 24000000 |
430 | // config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash |
431 | SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3); |
432 | #else |
433 | #error "Error, F_CPU must be 96000000, 48000000, or 24000000" |
434 | #endif |
435 | // switch to PLL as clock source, FLL input = 16 MHz / 512 |
436 | MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4); |
437 | // wait for PLL clock to be used |
438 | while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; |
439 | // now we're in PEE mode |
440 | // configure USB for 48 MHz clock |
441 | SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2 |
442 | // USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0 |
443 | SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6); |
444 | |
445 | // initialize the SysTick counter |
446 | SYST_RVR = (F_CPU / 1000) - 1; |
447 | SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE; |
448 | |
449 | //init_pins(); |
450 | __enable_irq(); |
451 | |
452 | _init_Teensyduino_internal_(); |
453 | if (RTC_SR & RTC_SR_TIF) rtc_set(TIME_T); |
454 | |
455 | __libc_init_array(); |
456 | |
457 | /* |
458 | for (ptr = &__init_array_start; ptr < &__init_array_end; ptr++) { |
459 | (*ptr)(); |
460 | } |
461 | */ |
462 | startup_late_hook(); |
463 | main(); |
464 | while (1) ; |
465 | } |
466 | |
467 | // TODO: is this needed for c++ and where does it come from? |
468 | /* |
469 | void _init(void) |
470 | { |
471 | } |
472 | */ |
473 | |
474 | char *__brkval = (char *)&_ebss; |
475 | |
476 | void * _sbrk(int incr) |
477 | { |
478 | //static char *heap_end = (char *)&_ebss; |
479 | //char *prev = heap_end; |
480 | //heap_end += incr; |
481 | |
482 | char *prev = __brkval; |
483 | __brkval += incr; |
484 | return prev; |
485 | } |
486 | |
487 | __attribute__((weak)) |
488 | int _read(int file, char *ptr, int len) |
489 | { |
490 | return 0; |
491 | } |
492 | |
493 | /* moved to Print.cpp, to support Print::printf() |
494 | __attribute__((weak)) |
495 | int _write(int file, char *ptr, int len) |
496 | { |
497 | return 0; |
498 | } |
499 | */ |
500 | |
501 | __attribute__((weak)) |
502 | int _close(int fd) |
503 | { |
504 | return -1; |
505 | } |
506 | |
507 | #include <sys/stat.h> |
508 | |
509 | __attribute__((weak)) |
510 | int _fstat(int fd, struct stat *st) |
511 | { |
512 | st->st_mode = S_IFCHR; |
513 | return 0; |
514 | } |
515 | |
516 | __attribute__((weak)) |
517 | int _isatty(int fd) |
518 | { |
519 | return 1; |
520 | } |
521 | |
522 | __attribute__((weak)) |
523 | int _lseek(int fd, long long offset, int whence) |
524 | { |
525 | return -1; |
526 | } |
527 | |
528 | __attribute__((weak)) |
529 | void _exit(int status) |
530 | { |
531 | while (1); |
532 | } |
533 | |
534 | __attribute__((weak)) |
535 | void __cxa_pure_virtual() |
536 | { |
537 | while (1); |
538 | } |
539 | |
540 | __attribute__((weak)) |
541 | int __cxa_guard_acquire (char *g) |
542 | { |
543 | return !(*g); |
544 | } |
545 | |
546 | __attribute__((weak)) |
547 | void __cxa_guard_release(char *g) |
548 | { |
549 | *g = 1; |
550 | } |
551 | |
552 | int nvic_execution_priority(void) |
553 | { |
554 | int priority=256; |
555 | uint32_t primask, faultmask, basepri, ipsr; |
556 | |
557 | // full algorithm in ARM DDI0403D, page B1-639 |
558 | // this isn't quite complete, but hopefully good enough |
559 | asm volatile("mrs %0, faultmask\n" : "=r" (faultmask)::); |
560 | if (faultmask) return -1; |
561 | asm volatile("mrs %0, primask\n" : "=r" (primask)::); |
562 | if (primask) return 0; |
563 | asm volatile("mrs %0, ipsr\n" : "=r" (ipsr)::); |
564 | if (ipsr) { |
565 | if (ipsr < 16) priority = 0; // could be non-zero |
566 | else priority = NVIC_GET_PRIORITY(ipsr - 16); |
567 | } |
568 | asm volatile("mrs %0, basepri\n" : "=r" (basepri)::); |
569 | if (basepri > 0 && basepri < priority) priority = basepri; |
570 | return priority; |
571 | } |
572 | |