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