]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/system_MKL46Z4.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_Freescale / TARGET_KLXX / TARGET_KL46Z / system_MKL46Z4.c
1 /*
2 ** ###################################################################
3 **     Processors:          MKL46Z256VLH4
4 **                          MKL46Z128VLH4
5 **                          MKL46Z256VLL4
6 **                          MKL46Z128VLL4
7 **                          MKL46Z256VMC4
8 **                          MKL46Z128VMC4
9 **
10 **     Compilers:           ARM Compiler
11 **                          Freescale C/C++ for Embedded ARM
12 **                          GNU C Compiler
13 **                          IAR ANSI C/C++ Compiler for ARM
14 **
15 **     Reference manual:    KL46P121M48SF4RM, Rev.1 Draft A, Aug 2012
16 **     Version:             rev. 2.0, 2012-12-12
17 **
18 **     Abstract:
19 **         Provides a system configuration function and a global variable that
20 **         contains the system frequency. It configures the device and initializes
21 **         the oscillator (PLL) that is part of the microcontroller device.
22 **
23 **     Copyright: 2012 Freescale, Inc. All Rights Reserved.
24 **
25 **     http:                 www.freescale.com
26 **     mail:                 support@freescale.com
27 **
28 **     Revisions:
29 **     - rev. 1.0 (2012-10-16)
30 **         Initial version.
31 **     - rev. 2.0 (2012-12-12)
32 **         Update to reference manual rev. 1.
33 **
34 ** ###################################################################
35 */
36
37 /**
38  * @file MKL46Z4
39  * @version 2.0
40  * @date 2012-12-12
41  * @brief Device specific configuration file for MKL46Z4 (implementation file)
42  *
43  * Provides a system configuration function and a global variable that contains
44  * the system frequency. It configures the device and initializes the oscillator
45  * (PLL) that is part of the microcontroller device.
46  */
47
48 #include <stdint.h>
49 #include "MKL46Z4.h"
50
51 #define DISABLE_WDOG    1
52
53 #define CLOCK_SETUP     1
54 /* Predefined clock setups
55    0 ... Multipurpose Clock Generator (MCG) in FLL Engaged Internal (FEI) mode
56          Reference clock source for MCG module is the slow internal clock source 32.768kHz
57          Core clock = 41.94MHz, BusClock = 13.98MHz
58    1 ... Multipurpose Clock Generator (MCG) in PLL Engaged External (PEE) mode
59          Reference clock source for MCG module is an external crystal 8MHz
60          Core clock = 48MHz, BusClock = 24MHz
61    2 ... Multipurpose Clock Generator (MCG) in Bypassed Low Power External (BLPE) mode
62          Core clock/Bus clock derived directly from an external crystal 8MHz with no multiplication
63          Core clock = 8MHz, BusClock = 8MHz
64 */
65
66 /*----------------------------------------------------------------------------
67   Define clock source values
68  *----------------------------------------------------------------------------*/
69 #if (CLOCK_SETUP == 0)
70     #define CPU_XTAL_CLK_HZ                 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
71     #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */
72     #define CPU_INT_FAST_CLK_HZ             4000000u /* Value of the fast internal oscillator clock frequency in Hz  */
73     #define DEFAULT_SYSTEM_CLOCK            41943040u /* Default System clock value */
74 #elif (CLOCK_SETUP == 1)
75     #define CPU_XTAL_CLK_HZ                 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
76     #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */
77     #define CPU_INT_FAST_CLK_HZ             4000000u /* Value of the fast internal oscillator clock frequency in Hz  */
78     #define DEFAULT_SYSTEM_CLOCK            48000000u /* Default System clock value */
79 #elif (CLOCK_SETUP == 2)
80     #define CPU_XTAL_CLK_HZ                 8000000u /* Value of the external 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 #endif /* (CLOCK_SETUP == 2) */
85
86
87 /* ----------------------------------------------------------------------------
88    -- Core clock
89    ---------------------------------------------------------------------------- */
90
91 uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
92
93 /* ----------------------------------------------------------------------------
94    -- SystemInit()
95    ---------------------------------------------------------------------------- */
96
97 void SystemInit (void) {
98 #if (DISABLE_WDOG)
99   /* Disable the WDOG module */
100   /* SIM_COPC: COPT=0,COPCLKS=0,COPW=0 */
101   SIM->COPC = (uint32_t)0x00u;
102 #endif /* (DISABLE_WDOG) */
103 #if (CLOCK_SETUP == 0)
104   /* SIM->CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=2,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
105   SIM->CLKDIV1 = (uint32_t)0x00020000UL; /* Update system prescalers */
106   /* Switch to FEI Mode */
107   /* MCG->C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
108   MCG->C1 = (uint8_t)0x06U;
109   /* MCG_C2: LOCRE0=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */
110   MCG->C2 &= (uint8_t)~(uint8_t)0xBFU;
111   /* MCG->C4: DMX32=0,DRST_DRS=1 */
112   MCG->C4 = (uint8_t)((MCG->C4 & (uint8_t)~(uint8_t)0xC0U) | (uint8_t)0x20U);
113   /* OSC0->CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
114   OSC0->CR = (uint8_t)0x80U;
115   /* MCG->C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */
116   MCG->C5 = (uint8_t)0x00U;
117   /* MCG->C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
118   MCG->C6 = (uint8_t)0x00U;
119   while((MCG->S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */
120   }
121   while((MCG->S & 0x0CU) != 0x00U) {    /* Wait until output of the FLL is selected */
122   }
123 #elif (CLOCK_SETUP == 1)
124   /* SIM->SCGC5: PORTA=1 */
125   SIM->SCGC5 |= (uint32_t)0x0200UL;     /* Enable clock gate for ports to enable pin routing */
126   /* SIM->CLKDIV1: OUTDIV1=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
127   SIM->CLKDIV1 = (uint32_t)0x10010000UL; /* Update system prescalers */
128   /* PORTA->PCR18: ISF=0,MUX=0 */
129   PORTA->PCR[18] &= (uint32_t)~0x01000700UL;
130   /* PORTA->PCR19: ISF=0,MUX=0 */
131   PORTA->PCR[19] &= (uint32_t)~0x01000700UL;
132   /* Switch to FBE Mode */
133   /* MCG_C2: LOCRE0=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */
134   MCG->C2 = (uint8_t)((MCG->C2 & (uint8_t)~(uint8_t)0x9BU) | (uint8_t)0x24U);
135   /* OSC0->CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=1,SC4P=0,SC8P=0,SC16P=0 */
136   OSC0->CR = (uint8_t)0x80U;
137   /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
138   MCG->C1 = (uint8_t)0x9AU;
139   /* MCG->C4: DMX32=0,DRST_DRS=0 */
140   MCG->C4 &= (uint8_t)~(uint8_t)0xE0U;
141   /* MCG->C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */
142   MCG->C5 = (uint8_t)0x01U;
143   /* MCG->C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
144   MCG->C6 = (uint8_t)0x00U;
145   while((MCG->S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
146   }
147   while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
148   }
149   /* Switch to PBE Mode */
150   /* MCG->C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */
151   MCG->C6 = (uint8_t)0x40U;
152   while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
153   }
154   while((MCG->S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */
155   }
156   /* Switch to PEE Mode */
157   /* MCG->C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
158   MCG->C1 = (uint8_t)0x1AU;
159   while((MCG->S & 0x0CU) != 0x0CU) {    /* Wait until output of the PLL is selected */
160   }
161 #elif (CLOCK_SETUP == 2)
162   /* SIM->SCGC5: PORTA=1 */
163   SIM->SCGC5 |= (uint32_t)0x0200UL;     /* Enable clock gate for ports to enable pin routing */
164   /* SIM->CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
165   SIM->CLKDIV1 = (uint32_t)0x00000000UL; /* Update system prescalers */
166   /* PORTA->PCR18: ISF=0,MUX=0 */
167   PORTA->PCR[18] &= (uint32_t)~0x01000700UL;
168   /* PORTA->PCR19: ISF=0,MUX=0 */
169   PORTA->PCR[19] &= (uint32_t)~0x01000700UL;
170   /* Switch to FBE Mode */
171   /* MCG->C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */
172   MCG->C2 = (uint8_t)0x24U;
173   /* OSC0->CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=1,SC4P=0,SC8P=0,SC16P=0 */
174   OSC0->CR = (uint8_t)0x80U;
175   /* MCG->C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
176   MCG->C1 = (uint8_t)0x9AU;
177   /* MCG->C4: DMX32=0,DRST_DRS=0 */
178   MCG->C4 &= (uint8_t)~(uint8_t)0xE0U;
179   /* MCG->C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */
180   MCG->C5 = (uint8_t)0x00U;
181   /* MCG->C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
182   MCG->C6 = (uint8_t)0x00U;
183   while((MCG->S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
184   }
185   while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
186   }
187   /* Switch to BLPE Mode */
188   /* MCG_C2: LOCRE0=0,RANGE0=2,HGO0=0,EREFS0=1,LP=1,IRCS=0 */
189   MCG->C2 = (uint8_t)((MCG->C2 & (uint8_t)~(uint8_t)0x99U) | (uint8_t)0x26U);
190   while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
191   }
192 #endif /* (CLOCK_SETUP == 2) */
193 }
194
195 /* ----------------------------------------------------------------------------
196    -- SystemCoreClockUpdate()
197    ---------------------------------------------------------------------------- */
198
199 void SystemCoreClockUpdate (void) {
200   uint32_t MCGOUTClock;                                                        /* Variable to store output clock frequency of the MCG module */
201   uint8_t Divider;
202
203   if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x0u) {
204     /* Output of FLL or PLL is selected */
205     if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) {
206       /* FLL is selected */
207       if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u) {
208         /* External reference clock is selected */
209         MCGOUTClock = CPU_XTAL_CLK_HZ;                                       /* System oscillator drives MCG clock */
210         Divider = (uint8_t)(1u << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
211         MCGOUTClock = (MCGOUTClock / Divider);  /* Calculate the divided FLL reference clock */
212         if ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x0u) {
213           MCGOUTClock /= 32u;                                                  /* If high range is enabled, additional 32 divider is active */
214         } /* ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x0u) */
215       } else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u)) */
216         MCGOUTClock = CPU_INT_SLOW_CLK_HZ;                                     /* The slow internal reference clock is selected */
217       } /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u)) */
218       /* Select correct multiplier to calculate the MCG output clock  */
219       switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) {
220         case 0x0u:
221           MCGOUTClock *= 640u;
222           break;
223         case 0x20u:
224           MCGOUTClock *= 1280u;
225           break;
226         case 0x40u:
227           MCGOUTClock *= 1920u;
228           break;
229         case 0x60u:
230           MCGOUTClock *= 2560u;
231           break;
232         case 0x80u:
233           MCGOUTClock *= 732u;
234           break;
235         case 0xA0u:
236           MCGOUTClock *= 1464u;
237           break;
238         case 0xC0u:
239           MCGOUTClock *= 2197u;
240           break;
241         case 0xE0u:
242           MCGOUTClock *= 2929u;
243           break;
244         default:
245           break;
246       }
247     } else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u)) */
248       /* PLL is selected */
249       Divider = (1u + (MCG->C5 & MCG_C5_PRDIV0_MASK));
250       MCGOUTClock = (uint32_t)(CPU_XTAL_CLK_HZ / Divider);                     /* Calculate the PLL reference clock */
251       Divider = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);
252       MCGOUTClock *= Divider;                       /* Calculate the MCG output clock */
253     } /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u)) */
254   } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x40u) {
255     /* Internal reference clock is selected */
256     if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u) {
257       MCGOUTClock = CPU_INT_SLOW_CLK_HZ;                                       /* Slow internal reference clock selected */
258     } else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u)) */
259       MCGOUTClock = CPU_INT_FAST_CLK_HZ / (1 << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));  /* Fast internal reference clock selected */
260     } /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u)) */
261   } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u) {
262     /* External reference clock is selected */
263     MCGOUTClock = CPU_XTAL_CLK_HZ;                                           /* System oscillator drives MCG clock */
264   } else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u)) */
265     /* Reserved value */
266     return;
267   } /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u)) */
268   SystemCoreClock = (MCGOUTClock / (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)));
269 }