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