1 /*
2 ** ###################################################################
3 ** Processors: MKL25Z128VFM4
4 ** MKL25Z128VFT4
5 ** MKL25Z128VLH4
6 ** MKL25Z128VLK4
7 ** MKL25Z32VFM4
8 ** MKL25Z32VFT4
9 ** MKL25Z32VLH4
10 ** MKL25Z32VLK4
11 ** MKL25Z64VFM4
12 ** MKL25Z64VFT4
13 ** MKL25Z64VLH4
14 ** MKL25Z64VLK4
15 **
16 ** Compilers: Keil ARM C/C++ Compiler
17 ** Freescale C/C++ for Embedded ARM
18 ** GNU C Compiler
19 ** IAR ANSI C/C++ Compiler for ARM
20 ** MCUXpresso Compiler
21 **
22 ** Reference manual: KL25P80M48SF0RM, Rev.3, Sep 2012
23 ** Version: rev. 2.5, 2015-02-19
24 ** Build: b170112
25 **
26 ** Abstract:
27 ** Provides a system configuration function and a global variable that
28 ** contains the system frequency. It configures the device and initializes
29 ** the oscillator (PLL) that is part of the microcontroller device.
30 **
31 ** Copyright (c) 2016 Freescale Semiconductor, Inc.
32 ** Copyright 2016 - 2017 NXP
33 ** Redistribution and use in source and binary forms, with or without modification,
34 ** are permitted provided that the following conditions are met:
35 **
36 ** o Redistributions of source code must retain the above copyright notice, this list
37 ** of conditions and the following disclaimer.
38 **
39 ** o Redistributions in binary form must reproduce the above copyright notice, this
40 ** list of conditions and the following disclaimer in the documentation and/or
41 ** other materials provided with the distribution.
42 **
43 ** o Neither the name of the copyright holder nor the names of its
44 ** contributors may be used to endorse or promote products derived from this
45 ** software without specific prior written permission.
46 **
47 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
48 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
51 ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
54 ** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
56 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 **
58 ** http: www.nxp.com
59 ** mail: support@nxp.com
60 **
61 ** Revisions:
62 ** - rev. 1.0 (2012-06-13)
63 ** Initial version.
64 ** - rev. 1.1 (2012-06-21)
65 ** Update according to reference manual rev. 1.
66 ** - rev. 1.2 (2012-08-01)
67 ** Device type UARTLP changed to UART0.
68 ** - rev. 1.3 (2012-10-04)
69 ** Update according to reference manual rev. 3.
70 ** - rev. 1.4 (2012-11-22)
71 ** MCG module - bit LOLS in MCG_S register renamed to LOLS0.
72 ** NV registers - bit EZPORT_DIS in NV_FOPT register removed.
73 ** - rev. 1.5 (2013-04-05)
74 ** Changed start of doxygen comment.
75 ** - rev. 2.0 (2013-10-29)
76 ** Register accessor macros added to the memory map.
77 ** Symbols for Processor Expert memory map compatibility added to the memory map.
78 ** Startup file for gcc has been updated according to CMSIS 3.2.
79 ** System initialization updated.
80 ** - rev. 2.1 (2014-07-16)
81 ** Module access macro module_BASES replaced by module_BASE_PTRS.
82 ** System initialization and startup updated.
83 ** - rev. 2.2 (2014-08-22)
84 ** System initialization updated - default clock config changed.
85 ** - rev. 2.3 (2014-08-28)
86 ** Update of startup files - possibility to override DefaultISR added.
87 ** - rev. 2.4 (2014-10-14)
88 ** Interrupt INT_LPTimer renamed to INT_LPTMR0.
89 ** - rev. 2.5 (2015-02-19)
90 ** Renamed interrupt vector LLW to LLWU.
91 **
92 ** ###################################################################
93 */
94
95 /*!
96 * @file MKL25Z4
97 * @version 2.5
98 * @date 2015-02-19
99 * @brief Device specific configuration file for MKL25Z4 (implementation file)
100 *
101 * Provides a system configuration function and a global variable that contains
102 * the system frequency. It configures the device and initializes the oscillator
103 * (PLL) that is part of the microcontroller device.
104 */
105
106 #include <stdint.h>
107 #include "fsl_device_registers.h"
108
109
110
111 /* ----------------------------------------------------------------------------
112 -- Core clock
113 ---------------------------------------------------------------------------- */
114
115 uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
116
117 /* ----------------------------------------------------------------------------
118 -- SystemInit()
119 ---------------------------------------------------------------------------- */
120
SystemInit(void)121 void SystemInit (void) {
122 #if (DISABLE_WDOG)
123 /* SIM_COPC: COPT=0,COPCLKS=0,COPW=0 */
124 SIM->COPC = (uint32_t)0x00u;
125 #endif /* (DISABLE_WDOG) */
126
127 }
128
129 /* ----------------------------------------------------------------------------
130 -- SystemCoreClockUpdate()
131 ---------------------------------------------------------------------------- */
132
SystemCoreClockUpdate(void)133 void SystemCoreClockUpdate (void) {
134 uint32_t MCGOUTClock; /* Variable to store output clock frequency of the MCG module */
135 uint16_t Divider;
136
137 if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x00U) {
138 /* Output of FLL or PLL is selected */
139 if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U) {
140 /* FLL is selected */
141 if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U) {
142 /* External reference clock is selected */
143 MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */
144 if ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x00U) {
145 switch (MCG->C1 & MCG_C1_FRDIV_MASK) {
146 case 0x38U:
147 Divider = 1536U;
148 break;
149 case 0x30U:
150 Divider = 1280U;
151 break;
152 default:
153 Divider = (uint16_t)(32LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
154 break;
155 }
156 } else {/* ((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) */
157 Divider = (uint16_t)(1LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
158 }
159 MCGOUTClock = (MCGOUTClock / Divider); /* Calculate the divided FLL reference clock */
160 } else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */
161 MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* The slow internal reference clock is selected */
162 } /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */
163 /* Select correct multiplier to calculate the MCG output clock */
164 switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) {
165 case 0x00U:
166 MCGOUTClock *= 640U;
167 break;
168 case 0x20U:
169 MCGOUTClock *= 1280U;
170 break;
171 case 0x40U:
172 MCGOUTClock *= 1920U;
173 break;
174 case 0x60U:
175 MCGOUTClock *= 2560U;
176 break;
177 case 0x80U:
178 MCGOUTClock *= 732U;
179 break;
180 case 0xA0U:
181 MCGOUTClock *= 1464U;
182 break;
183 case 0xC0U:
184 MCGOUTClock *= 2197U;
185 break;
186 case 0xE0U:
187 MCGOUTClock *= 2929U;
188 break;
189 default:
190 break;
191 }
192 } else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */
193 /* PLL is selected */
194 Divider = (((uint16_t)MCG->C5 & MCG_C5_PRDIV0_MASK) + 0x01U);
195 MCGOUTClock = (uint32_t)(CPU_XTAL_CLK_HZ / Divider); /* Calculate the PLL reference clock */
196 Divider = (((uint16_t)MCG->C6 & MCG_C6_VDIV0_MASK) + 24U);
197 MCGOUTClock *= Divider; /* Calculate the MCG output clock */
198 } /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */
199 } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x40U) {
200 /* Internal reference clock is selected */
201 if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U) {
202 MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* Slow internal reference clock selected */
203 } else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */
204 Divider = (uint16_t)(0x01LU << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));
205 MCGOUTClock = (uint32_t) (CPU_INT_FAST_CLK_HZ / Divider); /* Fast internal reference clock selected */
206 } /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */
207 } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U) {
208 /* External reference clock is selected */
209 MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */
210 } else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */
211 /* Reserved value */
212 return;
213 } /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */
214 SystemCoreClock = (MCGOUTClock / (0x01U + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)));
215 }
216