2 ** ###################################################################
3 ** Compilers: ARM Compiler
4 ** Freescale C/C++ for Embedded ARM
6 ** IAR ANSI C/C++ Compiler for ARM
10 ** Version: rev. 1.0, 2011-12-15
13 ** Provides a system configuration function and a global variable that
14 ** contains the system frequency. It configures the device and initializes
15 ** the oscillator (PLL) that is part of the microcontroller device.
17 ** Copyright: 2015 Freescale Semiconductor, Inc. All Rights Reserved.
19 ** http: www.freescale.com
20 ** mail: support@freescale.com
23 ** - rev. 1.0 (2011-12-15)
26 ** ###################################################################
33 * @brief Device specific configuration file for MK20DX256 (implementation file)
35 * Provides a system configuration function and a global variable that contains
36 * the system frequency. It configures the device and initializes the oscillator
37 * (PLL) that is part of the microcontroller device.
41 #include "MK20DX256.h"
43 #define DISABLE_WDOG 1
46 /* Predefined clock setups
47 0 ... Multipurpose Clock Generator (MCG) in FLL Engaged Internal (FEI) mode
48 Reference clock source for MCG module is the slow internal clock source 32.768kHz
49 Core clock = 41.94MHz, BusClock = 41.94MHz
50 This works on Teensy3.1
51 1 ... Multipurpose Clock Generator (MCG) in PLL Engaged External (PEE) mode
52 Reference clock source for MCG module is an external crystal 8MHz
53 Core clock = 48MHz, BusClock = 48MHz
54 2 ... Multipurpose Clock Generator (MCG) in Bypassed Low Power External (BLPE) mode
55 Core clock/Bus clock derived directly from an external crystal 8MHz with no multiplication
56 Core clock = 8MHz, BusClock = 8MHz
57 3 ... Multipurpose Clock Generator (MCG) in PLL Engaged External (PEE) mode
58 Reference clock source for MCG module is an external crystal 16MHz
59 Core clock = 72MHz, BusClock = 48MHz
60 This is the default Teensy3.1 72Mhz set up
63 /*----------------------------------------------------------------------------
64 Define clock source values
65 *----------------------------------------------------------------------------*/
66 #if (CLOCK_SETUP == 0)
67 #define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
68 #define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */
69 #define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
70 #define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
71 #define DEFAULT_SYSTEM_CLOCK 41943040u /* Default System clock value */
72 #elif (CLOCK_SETUP == 1)
73 #define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
74 #define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */
75 #define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
76 #define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
77 #define DEFAULT_SYSTEM_CLOCK 48000000u /* Default System clock value */
78 #elif (CLOCK_SETUP == 2)
79 #define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
80 #define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */
81 #define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
82 #define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
83 #define DEFAULT_SYSTEM_CLOCK 8000000u /* Default System clock value */
84 #elif (CLOCK_SETUP == 3)
85 #define CPU_XTAL_CLK_HZ 16000000u /* Value of the external crystal or oscillator clock frequency in Hz */
86 #define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */
87 #define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
88 #define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
89 #define DEFAULT_SYSTEM_CLOCK 72000000u /* Default System clock value */
90 #endif /* (CLOCK_SETUP == 2) */
93 /* ----------------------------------------------------------------------------
95 ---------------------------------------------------------------------------- */
97 uint32_t SystemCoreClock
= DEFAULT_SYSTEM_CLOCK
;
99 /* ----------------------------------------------------------------------------
101 ---------------------------------------------------------------------------- */
102 void SystemInit (void) {
103 /* SystemInit MUST NOT use any variables from the .data section, as this section is not loaded yet! */
106 /* Disable the WDOG module */
107 /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */
108 WDOG
->UNLOCK
= (uint16_t)0xC520u
; /* Key 1 */
109 /* WDOG_UNLOCK : WDOGUNLOCK=0xD928 */
110 WDOG
->UNLOCK
= (uint16_t)0xD928u
; /* Key 2 */
111 /* WDOG_STCTRLH: DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,STNDBYEN=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */
112 WDOG
->STCTRLH
= (uint16_t)0x01D2u
;
113 #endif /* (DISABLE_WDOG) */
115 #if (CLOCK_SETUP == 0)
116 /* SIM->CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV4=1 Set Prescalers 41.94MHz cpu, 41.94MHz system, 20.97MHz flash*/
117 SIM
->CLKDIV1
= SIM_CLKDIV1_OUTDIV4(1);
118 /* Switch to FEI Mode */
119 /* MCG->C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
120 MCG
->C1
= MCG_C1_IREFS_MASK
| MCG_C1_IRCLKEN_MASK
;
121 /* MCG->C2: LOCKRE0=0,RANGE0=0,HGO=0,EREFS=0,LP=0,IRCS=0 */
122 MCG
->C2
= (uint8_t)0x00u
;
123 /* MCG_C4: DMX32=0,DRST_DRS=1 */
124 MCG
->C4
= (uint8_t)((MCG
->C4
& (uint8_t)~(uint8_t)0xC0u
) | (uint8_t)0x20u
);
125 /* MCG->C5: PLLCLKEN=0,PLLSTEN=0,PRDIV0=0 */
126 MCG
->C5
= (uint8_t)0x00u
;
127 /* MCG->C6: LOLIE=0,PLLS=0,CME=0,VDIV0=0 */
128 MCG
->C6
= (uint8_t)0x00u
;
129 while((MCG
->S
& MCG_S_IREFST_MASK
) == 0u) { } /* Check that the source of the FLL reference clock is the internal reference clock. */
130 while((MCG
->S
& 0x0Cu
) != 0x00u
) { } /* Wait until output of the FLL is selected */
132 #elif (CLOCK_SETUP == 1)
133 /* SIM->CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV4=1 Set Prescalers 48MHz cpu, 48MHz system, 24MHz flash*/
134 SIM
->CLKDIV1
= SIM_CLKDIV1_OUTDIV4(1);
135 /* Switch to FBE Mode */
136 /* OSC0->CR: ERCLKEN=0,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
137 OSC0
->CR
= (uint8_t)0x00u
;
138 /* MCG->C7: OSCSEL=0 */
139 MCG
->C7
= (uint8_t)0x00u
;
140 /* MCG->C2: LOCKRE0=0,RANGE0=2,HGO=0,EREFS=1,LP=0,IRCS=0 */
141 MCG
->C2
= MCG_C2_RANGE0(2);
142 /* MCG->C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
143 MCG
->C1
= MCG_C1_CLKS(2) | MCG_C1_FRDIV(3) | MCG_C1_IRCLKEN_MASK
;
144 /* MCG->C4: DMX32=0,DRST_DRS=0 */
145 MCG
->C4
&= (uint8_t)~(uint8_t)0xE0u
;
146 /* MCG->C5: PLLCLKEN=0,PLLSTEN=0,PRDIV0=3 */
147 MCG
->C5
= MCG_C5_PRDIV0(3);
148 /* MCG->C6: LOLIE=0,PLLS=0,CME=0,VDIV0=0 */
149 MCG
->C6
= (uint8_t)0x00u
;
150 while((MCG
->S
& MCG_S_OSCINIT0_MASK
) == 0u) { } /* Check that the oscillator is running */
151 while((MCG
->S
& 0x0Cu
) != 0x08u
) { } /* Wait until external reference clock is selected as MCG output */
152 /* Switch to PBE Mode */
153 /* MCG_C5: PLLCLKEN=0,PLLSTEN=0,PRDIV0=3 */
154 MCG
->C5
= MCG_C5_PRDIV0(3);
155 /* MCG->C6: LOLIE=0,PLLS=1,CME=0,VDIV0=0 */
156 MCG
->C6
= MCG_C6_PLLS_MASK
;
157 while((MCG
->S
& MCG_S_PLLST_MASK
) == 0u) { } /* Wait until the source of the PLLS clock has switched to the PLL */
158 while((MCG
->S
& MCG_S_LOCK0_MASK
) == 0u) { } /* Wait until locked */
159 /* Switch to PEE Mode */
160 /* MCG->C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
161 MCG
->C1
= MCG_C1_FRDIV(3) | MCG_C1_IRCLKEN_MASK
;
162 while((MCG
->S
& 0x0Cu
) != 0x0Cu
) { } /* Wait until output of the PLL is selected */
163 while((MCG
->S
& MCG_S_LOCK0_MASK
) == 0u) { } /* Wait until locked */
165 #elif (CLOCK_SETUP == 2)
166 /* SIM->CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV4=1 Set Prescalers 8MHz cpu, 8MHz system, 8MHz flash*/
167 SIM
->CLKDIV1
= SIM_CLKDIV1_OUTDIV4(1);
168 /* Switch to FBE Mode */
169 /* OSC0->CR: ERCLKEN=0,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
170 OSC0
->CR
= (uint8_t)0x00u
;
171 /* MCG->C7: OSCSEL=0 */
172 MCG
->C7
= (uint8_t)0x00u
;
173 /* MCG->C2: LOCKRE0=0,RANGE0=2,HGO=0,EREFS=1,LP=0,IRCS=0 */
174 MCG
->C2
= MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK
;
175 /* MCG->C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
176 MCG
->C1
= MCG_C1_CLKS(2) | MCG_C1_FRDIV(3) | MCG_C1_IRCLKEN_MASK
;
177 /* MCG->C4: DMX32=0,DRST_DRS=0 */
178 MCG
->C4
&= (uint8_t)~(uint8_t)0xE0u
;
179 /* MCG->C5: PLLCLKEN=0,PLLSTEN=0,PRDIV0=0 */
180 MCG
->C5
= (uint8_t)0x00u
;
181 /* MCG->C6: LOLIE=0,PLLS=0,CME=0,VDIV0=0 */
182 MCG
->C6
= (uint8_t)0x00u
;
183 while((MCG
->S
& MCG_S_OSCINIT0_MASK
) == 0u) { } /* Check that the oscillator is running */
184 while((MCG
->S
& 0x0CU
) != 0x08u
) { } /* Wait until external reference clock is selected as MCG output */
185 /* Switch to BLPE Mode */
186 /* MCG->C2: LOCKRE0=0,RANGE0=2,HGO=0,EREFS=1,LP=0,IRCS=0 */
187 MCG
->C2
= MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK
;
189 #elif (CLOCK_SETUP == 3)
190 /* SIM->CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV4=1 Set Prescalers 72MHz cpu, 72MHz system, 36MHz flash*/
191 SIM
->CLKDIV1
= SIM_CLKDIV1_OUTDIV4(1);
192 /* SIM->CLKDIV2: USBDIV=2,USBFRAC=1 Divide 72MHz system clock for USB 48MHz */
193 SIM
->CLKDIV2
= SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC_MASK
;
194 /* OSC0->CR: ERCLKEN=0,EREFSTEN=0,SC2P=1,SC4P=0,SC8P=1,SC16P=0 10pF loading capacitors for 16MHz system oscillator*/
195 OSC0
->CR
= OSC_CR_SC8P_MASK
| OSC_CR_SC2P_MASK
;
196 /* Switch to FBE Mode */
197 /* MCG->C7: OSCSEL=0 */
198 MCG
->C7
= (uint8_t)0x00u
;
199 /* MCG->C2: LOCKRE0=0,RANGE0=2,HGO=0,EREFS=1,LP=0,IRCS=0 */
200 MCG
->C2
= MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK
;
201 //MCG->C2 = (uint8_t)0x24u;
202 /* MCG->C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
203 MCG
->C1
= MCG_C1_CLKS(2) | MCG_C1_FRDIV(3) | MCG_C1_IRCLKEN_MASK
;
204 /* MCG->C4: DMX32=0,DRST_DRS=0,FCTRIM=0,SCFTRIM=0 */
205 MCG
->C4
&= (uint8_t)~(uint8_t)0xE0u
;
206 /* MCG->C5: PLLCLKEN=0,PLLSTEN=0,PRDIV0=7 */
207 MCG
->C5
= MCG_C5_PRDIV0(7);
208 /* MCG->C6: LOLIE=0,PLLS=0,CME=0,VDIV0=0 */
209 MCG
->C6
= (uint8_t)0x00u
;
210 while((MCG
->S
& MCG_S_OSCINIT0_MASK
) == 0u) { } /* Check that the oscillator is running */
211 while((MCG
->S
& 0x0Cu
) != 0x08u
) { } /* Wait until external reference clock is selected as MCG output */
212 /* Switch to PBE Mode */
213 /* MCG_C5: PLLCLKEN=0,PLLSTEN=0,PRDIV0=5 */
214 MCG
->C5
= MCG_C5_PRDIV0(5);
215 /* MCG->C6: LOLIE=0,PLLS=1,CME=0,VDIV0=3 */
216 MCG
->C6
= MCG_C6_PLLS_MASK
| MCG_C6_VDIV0(3);
217 while((MCG
->S
& MCG_S_PLLST_MASK
) == 0u) { } /* Wait until the source of the PLLS clock has switched to the PLL */
218 while((MCG
->S
& MCG_S_LOCK0_MASK
) == 0u) { } /* Wait until locked */
219 /* Switch to PEE Mode */
220 /* MCG->C1: CLKS=0,FRDIV=2,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
221 MCG
->C1
= MCG_C1_FRDIV(2) | MCG_C1_IRCLKEN_MASK
;
222 while((MCG
->S
& 0x0Cu
) != 0x0Cu
) { } /* Wait until output of the PLL is selected */
223 while((MCG
->S
& MCG_S_LOCK0_MASK
) == 0u) { } /* Wait until locked */
224 #endif /* (CLOCK_SETUP) */
227 /* ----------------------------------------------------------------------------
228 -- SystemCoreClockUpdate()
229 ---------------------------------------------------------------------------- */
231 void SystemCoreClockUpdate (void) {
232 uint32_t MCGOUTClock
; /* Variable to store output clock frequency of the MCG module */
235 if ((MCG
->C1
& MCG_C1_CLKS_MASK
) == 0x0u
) {
236 /* Output of FLL or PLL is selected */
237 if ((MCG
->C6
& MCG_C6_PLLS_MASK
) == 0x0u
) {
238 /* FLL is selected */
239 if ((MCG
->C1
& MCG_C1_IREFS_MASK
) == 0x0u
) {
240 /* External reference clock is selected */
241 if ((MCG
->C7
& MCG_C7_OSCSEL_MASK
) == 0x0u
) {
242 MCGOUTClock
= CPU_XTAL_CLK_HZ
; /* System oscillator drives MCG clock */
243 } else { /* (!((MCG->C7 & MCG_C7_OSCSEL_MASK) == 0x0u)) */
244 MCGOUTClock
= CPU_XTAL32k_CLK_HZ
; /* RTC 32 kHz oscillator drives MCG clock */
245 } /* (!((MCG->C7 & MCG_C7_OSCSEL_MASK) == 0x0u)) */
246 Divider
= (uint8_t)(1u << ((MCG
->C1
& MCG_C1_FRDIV_MASK
) >> MCG_C1_FRDIV_SHIFT
));
247 MCGOUTClock
= (MCGOUTClock
/ Divider
); /* Calculate the divided FLL reference clock */
248 if ((MCG
->C2
& MCG_C2_RANGE0_MASK
) != 0x0u
) {
249 MCGOUTClock
/= 32u; /* If high range is enabled, additional 32 divider is active */
250 } /* ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x0u) */
251 } else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u)) */
252 MCGOUTClock
= CPU_INT_SLOW_CLK_HZ
; /* The slow internal reference clock is selected */
253 } /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u)) */
254 /* Select correct multiplier to calculate the MCG output clock */
255 switch (MCG
->C4
& (MCG_C4_DMX32_MASK
| MCG_C4_DRST_DRS_MASK
)) {
260 MCGOUTClock
*= 1280u;
263 MCGOUTClock
*= 1920u;
266 MCGOUTClock
*= 2560u;
272 MCGOUTClock
*= 1464u;
275 MCGOUTClock
*= 2197u;
278 MCGOUTClock
*= 2929u;
283 } else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u)) */
284 /* PLL is selected */
285 Divider
= (1u + (MCG
->C5
& MCG_C5_PRDIV0_MASK
));
286 MCGOUTClock
= (uint32_t)(CPU_XTAL_CLK_HZ
/ Divider
); /* Calculate the PLL reference clock */
287 Divider
= ((MCG
->C6
& MCG_C6_VDIV0_MASK
) + 24u);
288 MCGOUTClock
*= Divider
; /* Calculate the MCG output clock */
289 } /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u)) */
290 } else if ((MCG
->C1
& MCG_C1_CLKS_MASK
) == 0x40u
) {
291 /* Internal reference clock is selected */
292 if ((MCG
->C2
& MCG_C2_IRCS_MASK
) == 0x0u
) {
293 MCGOUTClock
= CPU_INT_SLOW_CLK_HZ
; /* Slow internal reference clock selected */
294 } else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u)) */
295 MCGOUTClock
= CPU_INT_FAST_CLK_HZ
/ (1 << ((MCG
->SC
& MCG_SC_FCRDIV_MASK
) >> MCG_SC_FCRDIV_SHIFT
)); /* Fast internal reference clock selected */
296 } /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u)) */
297 } else if ((MCG
->C1
& MCG_C1_CLKS_MASK
) == 0x80u
) {
298 /* External reference clock is selected */
299 if ((MCG
->C7
& MCG_C7_OSCSEL_MASK
) == 0x0u
) {
300 MCGOUTClock
= CPU_XTAL_CLK_HZ
; /* System oscillator drives MCG clock */
301 } else { /* (!((MCG->C7 & MCG_C7_OSCSEL_MASK) == 0x0u)) */
302 MCGOUTClock
= CPU_XTAL32k_CLK_HZ
; /* RTC 32 kHz oscillator drives MCG clock */
303 } /* (!((MCG->C7 & MCG_C7_OSCSEL_MASK) == 0x0u)) */
304 } else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u)) */
307 } /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u)) */
308 SystemCoreClock
= (MCGOUTClock
/ (1u + ((SIM
->CLKDIV1
& SIM_CLKDIV1_OUTDIV1_MASK
) >> SIM_CLKDIV1_OUTDIV1_SHIFT
)));