| 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 | |