1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016 - 2020, NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_CLOCK_H_
10 #define _FSL_CLOCK_H_
11 
12 #include "fsl_common.h"
13 
14 /*! @addtogroup clock */
15 /*! @{ */
16 
17 /*! @file */
18 
19 /*******************************************************************************
20  * Configurations
21  ******************************************************************************/
22 
23 /*! @brief Configures whether to check a parameter in a function.
24  *
25  * Some MCG settings must be changed with conditions, for example:
26  *  1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when
27  *     MCGIRCLK is used as a system clock source.
28  *  2. MCG_C7[OSCSEL] should not be changed  when the external reference clock is used
29  *     as a system clock source. For example, in FBE/BLPE/PBE modes.
30  *  3. The users should only switch between the supported clock modes.
31  *
32  * MCG functions check the parameter and MCG status before setting, if not allowed
33  * to change, the functions return error. The parameter checking increases code size,
34  * if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to
35  * disable parameter checking.
36  */
37 #ifndef MCG_CONFIG_CHECK_PARAM
38 #define MCG_CONFIG_CHECK_PARAM 0U
39 #endif
40 
41 /*! @brief Configure whether driver controls clock
42  *
43  * When set to 0, peripheral drivers will enable clock in initialize function
44  * and disable clock in de-initialize function. When set to 1, peripheral
45  * driver will not control the clock, application could control the clock out of
46  * the driver.
47  *
48  * @note All drivers share this feature switcher. If it is set to 1, application
49  * should handle clock enable and disable for all drivers.
50  */
51 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
52 #define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
53 #endif
54 
55 /*******************************************************************************
56  * Definitions
57  ******************************************************************************/
58 
59 /*! @name Driver version */
60 /*@{*/
61 /*! @brief CLOCK driver version 2.5.1. */
62 #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 5, 1))
63 /*@}*/
64 
65 /*! @brief External XTAL0 (OSC0) clock frequency.
66  *
67  * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
68  * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
69  * if XTAL0 is 8 MHz:
70  * @code
71  * Set up the OSC0
72  * CLOCK_InitOsc0(...);
73  * Set the XTAL0 value to the clock driver.
74  * CLOCK_SetXtal0Freq(80000000);
75  * @endcode
76  *
77  * This is important for the multicore platforms where only one core needs to set up the
78  * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
79  * to get a valid clock frequency.
80  */
81 extern volatile uint32_t g_xtal0Freq;
82 
83 /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
84  *
85  * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the
86  * function CLOCK_SetXtal32Freq to set the value in the clock driver.
87  *
88  * This is important for the multicore platforms where only one core needs to set up
89  * the clock. All other cores need to call the CLOCK_SetXtal32Freq
90  * to get a valid clock frequency.
91  */
92 extern volatile uint32_t g_xtal32Freq;
93 
94 /*! @brief IRC48M clock frequency in Hz. */
95 #define MCG_INTERNAL_IRC_48M 48000000U
96 
97 #if (defined(OSC) && !(defined(OSC0)))
98 #define OSC0 OSC
99 #endif
100 
101 /* Definition for delay API in clock driver, users can redefine it to the real application. */
102 #ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
103 #define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (120000000UL)
104 #endif
105 
106 /*! @brief Clock ip name array for DMAMUX. */
107 #define DMAMUX_CLOCKS  \
108     {                  \
109         kCLOCK_Dmamux0 \
110     }
111 
112 /*! @brief Clock ip name array for RTC. */
113 #define RTC_CLOCKS  \
114     {               \
115         kCLOCK_Rtc0 \
116     }
117 
118 /*! @brief Clock ip name array for SAI. */
119 #define SAI_CLOCKS  \
120     {               \
121         kCLOCK_Sai0 \
122     }
123 
124 /*! @brief Clock ip name array for PORT. */
125 #define PORT_CLOCKS                                                          \
126     {                                                                        \
127         kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \
128     }
129 
130 /*! @brief Clock ip name array for FLEXBUS. */
131 #define FLEXBUS_CLOCKS  \
132     {                   \
133         kCLOCK_Flexbus0 \
134     }
135 
136 /*! @brief Clock ip name array for EWM. */
137 #define EWM_CLOCKS  \
138     {               \
139         kCLOCK_Ewm0 \
140     }
141 
142 /*! @brief Clock ip name array for PIT. */
143 #define PIT_CLOCKS  \
144     {               \
145         kCLOCK_Pit0 \
146     }
147 
148 /*! @brief Clock ip name array for DSPI. */
149 #define DSPI_CLOCKS                           \
150     {                                         \
151         kCLOCK_Spi0, kCLOCK_Spi1, kCLOCK_Spi2 \
152     }
153 
154 /*! @brief Clock ip name array for EMVSIM. */
155 #define EMVSIM_CLOCKS                  \
156     {                                  \
157         kCLOCK_Emvsim0, kCLOCK_Emvsim1 \
158     }
159 
160 /*! @brief Clock ip name array for QSPI. */
161 #define QSPI_CLOCKS  \
162     {                \
163         kCLOCK_Qspi0 \
164     }
165 
166 /*! @brief Clock ip name array for LPTMR. */
167 #define LPTMR_CLOCKS                 \
168     {                                \
169         kCLOCK_Lptmr0, kCLOCK_Lptmr1 \
170     }
171 
172 /*! @brief Clock ip name array for SDHC. */
173 #define SDHC_CLOCKS  \
174     {                \
175         kCLOCK_Sdhc0 \
176     }
177 
178 /*! @brief Clock ip name array for FTM. */
179 #define FTM_CLOCKS                                         \
180     {                                                      \
181         kCLOCK_Ftm0, kCLOCK_Ftm1, kCLOCK_Ftm2, kCLOCK_Ftm3 \
182     }
183 
184 /*! @brief Clock ip name array for EDMA. */
185 #define EDMA_CLOCKS \
186     {               \
187         kCLOCK_Dma0 \
188     }
189 
190 /*! @brief Clock ip name array for LPUART. */
191 #define LPUART_CLOCKS                                                                  \
192     {                                                                                  \
193         kCLOCK_Lpuart0, kCLOCK_Lpuart1, kCLOCK_Lpuart2, kCLOCK_Lpuart3, kCLOCK_Lpuart4 \
194     }
195 
196 /*! @brief Clock ip name array for DAC. */
197 #define DAC_CLOCKS  \
198     {               \
199         kCLOCK_Dac0 \
200     }
201 
202 /*! @brief Clock ip name array for ADC16. */
203 #define ADC16_CLOCKS \
204     {                \
205         kCLOCK_Adc0  \
206     }
207 
208 /*! @brief Clock ip name array for SDRAM. */
209 #define SDRAM_CLOCKS   \
210     {                  \
211         kCLOCK_Sdramc0 \
212     }
213 
214 /*! @brief Clock ip name array for TRNG. */
215 #define TRNG_CLOCKS  \
216     {                \
217         kCLOCK_Trng0 \
218     }
219 
220 /*! @brief Clock ip name array for MPU. */
221 #define SYSMPU_CLOCKS  \
222     {                  \
223         kCLOCK_Sysmpu0 \
224     }
225 
226 /*! @brief Clock ip name array for FLEXIO. */
227 #define FLEXIO_CLOCKS  \
228     {                  \
229         kCLOCK_Flexio0 \
230     }
231 
232 /*! @brief Clock ip name array for VREF. */
233 #define VREF_CLOCKS  \
234     {                \
235         kCLOCK_Vref0 \
236     }
237 
238 /*! @brief Clock ip name array for CMT. */
239 #define CMT_CLOCKS  \
240     {               \
241         kCLOCK_Cmt0 \
242     }
243 
244 /*! @brief Clock ip name array for TPM. */
245 #define TPM_CLOCKS                                 \
246     {                                              \
247         kCLOCK_IpInvalid, kCLOCK_Tpm1, kCLOCK_Tpm2 \
248     }
249 
250 /*! @brief Clock ip name array for TSI. */
251 #define TSI_CLOCKS  \
252     {               \
253         kCLOCK_Tsi0 \
254     }
255 
256 /*! @brief Clock ip name array for CRC. */
257 #define CRC_CLOCKS  \
258     {               \
259         kCLOCK_Crc0 \
260     }
261 
262 /*! @brief Clock ip name array for I2C. */
263 #define I2C_CLOCKS                                         \
264     {                                                      \
265         kCLOCK_I2c0, kCLOCK_I2c1, kCLOCK_I2c2, kCLOCK_I2c3 \
266     }
267 
268 /*! @brief Clock ip name array for PDB. */
269 #define PDB_CLOCKS  \
270     {               \
271         kCLOCK_Pdb0 \
272     }
273 
274 /*! @brief Clock ip name array for FTF. */
275 #define FTF_CLOCKS  \
276     {               \
277         kCLOCK_Ftf0 \
278     }
279 
280 /*! @brief Clock ip name array for CMP. */
281 #define CMP_CLOCKS               \
282     {                            \
283         kCLOCK_Cmp0, kCLOCK_Cmp1 \
284     }
285 
286 /*!
287  * @brief LPO clock frequency.
288  */
289 #define LPO_CLK_FREQ 1000U
290 
291 /*! @brief Peripherals clock source definition. */
292 #define SYS_CLK kCLOCK_CoreSysClk
293 #define BUS_CLK kCLOCK_BusClk
294 
295 #define I2C0_CLK_SRC BUS_CLK
296 #define I2C1_CLK_SRC BUS_CLK
297 #define I2C2_CLK_SRC BUS_CLK
298 #define I2C3_CLK_SRC BUS_CLK
299 #define DSPI0_CLK_SRC BUS_CLK
300 #define DSPI1_CLK_SRC BUS_CLK
301 #define DSPI2_CLK_SRC BUS_CLK
302 
303 /*! @brief Clock name used to get clock frequency. */
304 typedef enum _clock_name
305 {
306 
307     /* ----------------------------- System layer clock -------------------------------*/
308     kCLOCK_CoreSysClk,    /*!< Core/system clock                                         */
309     kCLOCK_PlatClk,       /*!< Platform clock                                            */
310     kCLOCK_BusClk,        /*!< Bus clock                                                 */
311     kCLOCK_FlexBusClk,    /*!< FlexBus clock                                             */
312     kCLOCK_FlashClk,      /*!< Flash clock                                               */
313     kCLOCK_FastPeriphClk, /*!< Fast peripheral clock                                     */
314     kCLOCK_PllFllSelClk,  /*!< The clock after SIM[PLLFLLSEL].                           */
315 
316     /* ---------------------------------- OSC clock -----------------------------------*/
317     kCLOCK_Er32kClk,       /*!< External reference 32K clock (ERCLK32K)                   */
318     kCLOCK_Osc0ErClk,      /*!< OSC0 external reference clock (OSC0ERCLK)                 */
319     kCLOCK_Osc1ErClk,      /*!< OSC1 external reference clock (OSC1ERCLK)                 */
320     kCLOCK_Osc0ErClkUndiv, /*!< OSC0 external reference undivided clock(OSC0ERCLK_UNDIV). */
321 
322     /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/
323     kCLOCK_McgFixedFreqClk,   /*!< MCG fixed frequency clock (MCGFFCLK)                      */
324     kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK)                   */
325     kCLOCK_McgFllClk,         /*!< MCGFLLCLK                                                 */
326     kCLOCK_McgPll0Clk,        /*!< MCGPLL0CLK                                                */
327     kCLOCK_McgPll1Clk,        /*!< MCGPLL1CLK                                                */
328     kCLOCK_McgExtPllClk,      /*!< EXT_PLLCLK                                                */
329     kCLOCK_McgPeriphClk,      /*!< MCG peripheral clock (MCGPCLK)                            */
330     kCLOCK_McgIrc48MClk,      /*!< MCG IRC48M clock                                          */
331 
332     /* --------------------------------- Other clock ----------------------------------*/
333     kCLOCK_LpoClk, /*!< LPO clock                                                 */
334 
335 } clock_name_t;
336 
337 /*! @brief USB clock source definition. */
338 typedef enum _clock_usb_src
339 {
340     kCLOCK_UsbSrcPll0   = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0.      */
341     kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M.    */
342     kCLOCK_UsbSrcExt    = SIM_SOPT2_USBSRC(0U)                            /*!< Use USB_CLKIN. */
343 } clock_usb_src_t;
344 /*------------------------------------------------------------------------------
345 
346  clock_gate_t definition:
347 
348  31                              16                              0
349  -----------------------------------------------------------------
350  | SIM_SCGC register offset       |   control bit offset in SCGC |
351  -----------------------------------------------------------------
352 
353  For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the
354  SIM_SCGC3 offset in SIM is 0x1030, then kClockGateSdhc0 is defined as
355 
356               kClockGateSdhc0 = (0x1030 << 16) | 17;
357 
358 ------------------------------------------------------------------------------*/
359 
360 #define CLK_GATE_REG_OFFSET_SHIFT 16U
361 #define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U
362 #define CLK_GATE_BIT_SHIFT_SHIFT 0U
363 #define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU
364 
365 #define CLK_GATE_DEFINE(reg_offset, bit_shift)                                  \
366     ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
367      (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
368 
369 #define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
370 #define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
371 
372 /*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
373 typedef enum _clock_ip_name
374 {
375     kCLOCK_IpInvalid = 0U,
376     kCLOCK_I2c2      = CLK_GATE_DEFINE(0x1028U, 6U),
377     kCLOCK_I2c3      = CLK_GATE_DEFINE(0x1028U, 7U),
378 
379     kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x102CU, 4U),
380     kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x102CU, 5U),
381     kCLOCK_Lpuart2 = CLK_GATE_DEFINE(0x102CU, 6U),
382     kCLOCK_Lpuart3 = CLK_GATE_DEFINE(0x102CU, 7U),
383     kCLOCK_Tpm1    = CLK_GATE_DEFINE(0x102CU, 9U),
384     kCLOCK_Tpm2    = CLK_GATE_DEFINE(0x102CU, 10U),
385     kCLOCK_Dac0    = CLK_GATE_DEFINE(0x102CU, 12U),
386     kCLOCK_Emvsim0 = CLK_GATE_DEFINE(0x102CU, 20U),
387     kCLOCK_Emvsim1 = CLK_GATE_DEFINE(0x102CU, 21U),
388     kCLOCK_Lpuart4 = CLK_GATE_DEFINE(0x102CU, 22U),
389     kCLOCK_Qspi0   = CLK_GATE_DEFINE(0x102CU, 26U),
390     kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x102CU, 31U),
391 
392     kCLOCK_Trng0 = CLK_GATE_DEFINE(0x1030U, 0U),
393     kCLOCK_Spi2  = CLK_GATE_DEFINE(0x1030U, 12U),
394     kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U),
395     kCLOCK_Ftm3  = CLK_GATE_DEFINE(0x1030U, 25U),
396 
397     kCLOCK_Ewm0   = CLK_GATE_DEFINE(0x1034U, 1U),
398     kCLOCK_Cmt0   = CLK_GATE_DEFINE(0x1034U, 2U),
399     kCLOCK_I2c0   = CLK_GATE_DEFINE(0x1034U, 6U),
400     kCLOCK_I2c1   = CLK_GATE_DEFINE(0x1034U, 7U),
401     kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
402     kCLOCK_Cmp0   = CLK_GATE_DEFINE(0x1034U, 19U),
403     kCLOCK_Cmp1   = CLK_GATE_DEFINE(0x1034U, 19U),
404     kCLOCK_Vref0  = CLK_GATE_DEFINE(0x1034U, 20U),
405 
406     kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
407     kCLOCK_Lptmr1 = CLK_GATE_DEFINE(0x1038U, 4U),
408     kCLOCK_Tsi0   = CLK_GATE_DEFINE(0x1038U, 5U),
409     kCLOCK_PortA  = CLK_GATE_DEFINE(0x1038U, 9U),
410     kCLOCK_PortB  = CLK_GATE_DEFINE(0x1038U, 10U),
411     kCLOCK_PortC  = CLK_GATE_DEFINE(0x1038U, 11U),
412     kCLOCK_PortD  = CLK_GATE_DEFINE(0x1038U, 12U),
413     kCLOCK_PortE  = CLK_GATE_DEFINE(0x1038U, 13U),
414 
415     kCLOCK_Ftf0    = CLK_GATE_DEFINE(0x103CU, 0U),
416     kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
417     kCLOCK_Spi0    = CLK_GATE_DEFINE(0x103CU, 12U),
418     kCLOCK_Spi1    = CLK_GATE_DEFINE(0x103CU, 13U),
419     kCLOCK_Sai0    = CLK_GATE_DEFINE(0x103CU, 15U),
420     kCLOCK_Crc0    = CLK_GATE_DEFINE(0x103CU, 18U),
421     kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U),
422     kCLOCK_Pdb0    = CLK_GATE_DEFINE(0x103CU, 22U),
423     kCLOCK_Pit0    = CLK_GATE_DEFINE(0x103CU, 23U),
424     kCLOCK_Ftm0    = CLK_GATE_DEFINE(0x103CU, 24U),
425     kCLOCK_Ftm1    = CLK_GATE_DEFINE(0x103CU, 25U),
426     kCLOCK_Ftm2    = CLK_GATE_DEFINE(0x103CU, 26U),
427     kCLOCK_Adc0    = CLK_GATE_DEFINE(0x103CU, 27U),
428     kCLOCK_Rtc0    = CLK_GATE_DEFINE(0x103CU, 29U),
429 
430     kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U),
431     kCLOCK_Dma0     = CLK_GATE_DEFINE(0x1040U, 1U),
432     kCLOCK_Sysmpu0  = CLK_GATE_DEFINE(0x1040U, 2U),
433     kCLOCK_Sdramc0  = CLK_GATE_DEFINE(0x1040U, 3U),
434 } clock_ip_name_t;
435 
436 /*!@brief SIM configuration structure for clock setting. */
437 typedef struct _sim_clock_config
438 {
439     uint8_t pllFllSel;  /*!< PLL/FLL/IRC48M selection.         */
440     uint8_t pllFllDiv;  /*!< PLLFLLSEL clock divider divisor.  */
441     uint8_t pllFllFrac; /*!< PLLFLLSEL clock divider fraction. */
442     uint8_t er32kSrc;   /*!< ERCLK32K source selection.        */
443     uint32_t clkdiv1;   /*!< SIM_CLKDIV1.                      */
444 } sim_clock_config_t;
445 
446 /*! @brief OSC work mode. */
447 typedef enum _osc_mode
448 {
449     kOSC_ModeExt = 0U, /*!< Use an external clock.   */
450 #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
451     kOSC_ModeOscLowPower = MCG_C2_EREFS_MASK, /*!< Oscillator low power. */
452 #else
453     kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */
454 #endif
455     kOSC_ModeOscHighGain = 0U
456 #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
457                            | MCG_C2_EREFS_MASK
458 #else
459                            | MCG_C2_EREFS0_MASK
460 #endif
461 #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
462                            | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
463 #else
464                            | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
465 #endif
466 } osc_mode_t;
467 
468 /*! @brief Oscillator capacitor load setting.*/
469 enum _osc_cap_load
470 {
471     kOSC_Cap2P  = OSC_CR_SC2P_MASK, /*!< 2  pF capacitor load */
472     kOSC_Cap4P  = OSC_CR_SC4P_MASK, /*!< 4  pF capacitor load */
473     kOSC_Cap8P  = OSC_CR_SC8P_MASK, /*!< 8  pF capacitor load */
474     kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
475 };
476 
477 /*! @brief OSCERCLK enable mode. */
478 enum _oscer_enable_mode
479 {
480     kOSC_ErClkEnable       = OSC_CR_ERCLKEN_MASK, /*!< Enable.              */
481     kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
482 };
483 
484 /*! @brief OSC configuration for OSCERCLK. */
485 typedef struct _oscer_config
486 {
487     uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of @ref _oscer_enable_mode. */
488 
489     uint8_t erclkDiv; /*!< Divider for OSCERCLK.*/
490 } oscer_config_t;
491 
492 /*!
493  * @brief OSC Initialization Configuration Structure
494  *
495  * Defines the configuration data structure to initialize the OSC.
496  * When porting to a new board, set the following members
497  * according to the board setting:
498  * 1. freq: The external frequency.
499  * 2. workMode: The OSC module mode.
500  */
501 typedef struct _osc_config
502 {
503     uint32_t freq;              /*!< External clock frequency.    */
504     uint8_t capLoad;            /*!< Capacitor load setting.      */
505     osc_mode_t workMode;        /*!< OSC work mode setting.       */
506     oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK.  */
507 } osc_config_t;
508 
509 /*! @brief MCG FLL reference clock source select. */
510 typedef enum _mcg_fll_src
511 {
512     kMCG_FllSrcExternal, /*!< External reference clock is selected          */
513     kMCG_FllSrcInternal  /*!< The slow internal reference clock is selected */
514 } mcg_fll_src_t;
515 
516 /*! @brief MCG internal reference clock select */
517 typedef enum _mcg_irc_mode
518 {
519     kMCG_IrcSlow, /*!< Slow internal reference clock selected */
520     kMCG_IrcFast  /*!< Fast internal reference clock selected */
521 } mcg_irc_mode_t;
522 
523 /*! @brief MCG DCO Maximum Frequency with 32.768 kHz Reference */
524 typedef enum _mcg_dmx32
525 {
526     kMCG_Dmx32Default, /*!< DCO has a default range of 25% */
527     kMCG_Dmx32Fine     /*!< DCO is fine-tuned for maximum frequency with 32.768 kHz reference */
528 } mcg_dmx32_t;
529 
530 /*! @brief MCG DCO range select */
531 typedef enum _mcg_drs
532 {
533     kMCG_DrsLow,     /*!< Low frequency range       */
534     kMCG_DrsMid,     /*!< Mid frequency range       */
535     kMCG_DrsMidHigh, /*!< Mid-High frequency range  */
536     kMCG_DrsHigh     /*!< High frequency range      */
537 } mcg_drs_t;
538 
539 /*! @brief MCG PLL reference clock select */
540 typedef enum _mcg_pll_ref_src
541 {
542     kMCG_PllRefOsc0, /*!< Selects OSC0 as PLL reference clock                 */
543     kMCG_PllRefOsc1  /*!< Selects OSC1 as PLL reference clock                 */
544 } mcg_pll_ref_src_t;
545 
546 /*! @brief MCGOUT clock source. */
547 typedef enum _mcg_clkout_src
548 {
549     kMCG_ClkOutSrcOut,      /*!< Output of the FLL is selected (reset default)  */
550     kMCG_ClkOutSrcInternal, /*!< Internal reference clock is selected           */
551     kMCG_ClkOutSrcExternal, /*!< External reference clock is selected           */
552 } mcg_clkout_src_t;
553 
554 /*! @brief MCG Automatic Trim Machine Select */
555 typedef enum _mcg_atm_select
556 {
557     kMCG_AtmSel32k, /*!< 32 kHz Internal Reference Clock selected  */
558     kMCG_AtmSel4m   /*!< 4 MHz Internal Reference Clock selected   */
559 } mcg_atm_select_t;
560 
561 /*! @brief MCG OSC Clock Select */
562 typedef enum _mcg_oscsel
563 {
564     kMCG_OscselOsc, /*!< Selects System Oscillator (OSCCLK) */
565     kMCG_OscselRtc, /*!< Selects 32 kHz RTC Oscillator      */
566     kMCG_OscselIrc  /*!< Selects 48 MHz IRC Oscillator      */
567 } mcg_oscsel_t;
568 
569 /*! @brief MCG PLLCS select */
570 typedef enum _mcg_pll_clk_select
571 {
572     kMCG_PllClkSelPll0, /*!< PLL0 output clock is selected  */
573     kMCG_PllClkSelPll1  /* PLL1 output clock is selected    */
574 } mcg_pll_clk_select_t;
575 
576 /*! @brief MCG clock monitor mode. */
577 typedef enum _mcg_monitor_mode
578 {
579     kMCG_MonitorNone, /*!< Clock monitor is disabled.         */
580     kMCG_MonitorInt,  /*!< Trigger interrupt when clock lost. */
581     kMCG_MonitorReset /*!< System reset when clock lost.      */
582 } mcg_monitor_mode_t;
583 
584 /*! @brief MCG status. Enumeration _mcg_status */
585 enum
586 {
587     kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0U),       /*!< Can't switch to target mode. */
588     kStatus_MCG_ModeInvalid     = MAKE_STATUS(kStatusGroup_MCG, 1U),       /*!< Current mode invalid for the specific
589                                                                                function. */
590     kStatus_MCG_AtmBusClockInvalid    = MAKE_STATUS(kStatusGroup_MCG, 2U), /*!< Invalid bus clock for ATM. */
591     kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3U), /*!< Invalid desired frequency for ATM. */
592     kStatus_MCG_AtmIrcUsed            = MAKE_STATUS(kStatusGroup_MCG, 4U), /*!< IRC is used when using ATM. */
593     kStatus_MCG_AtmHardwareFail       = MAKE_STATUS(kStatusGroup_MCG, 5U), /*!< Hardware fail occurs during ATM. */
594     kStatus_MCG_SourceUsed            = MAKE_STATUS(kStatusGroup_MCG, 6U)  /*!< Can't change the clock source because
595                                                                                it is in use. */
596 };
597 
598 /*! @brief MCG status flags. Enumeration _mcg_status_flags_t */
599 enum
600 {
601     kMCG_Osc0LostFlag   = (1U << 0U), /*!< OSC0 lost.         */
602     kMCG_Osc0InitFlag   = (1U << 1U), /*!< OSC0 crystal initialized. */
603     kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost.      */
604     kMCG_Pll0LostFlag   = (1U << 5U), /*!< PLL0 lost.         */
605     kMCG_Pll0LockFlag   = (1U << 6U), /*!< PLL0 locked.       */
606 };
607 
608 /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. Enumeration _mcg_irclk_enable_mode */
609 enum
610 {
611     kMCG_IrclkEnable       = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable.              */
612     kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
613 };
614 
615 /*! @brief MCG PLL clock enable mode definition. Enumeration _mcg_pll_enable_mode */
616 enum
617 {
618     kMCG_PllEnableIndependent = MCG_C5_PLLCLKEN0_MASK, /*!< MCGPLLCLK enable independent of the
619                                                            MCG clock mode. Generally, the PLL
620                                                            is disabled in FLL modes
621                                                            (FEI/FBI/FEE/FBE). Setting the PLL clock
622                                                            enable independent, enables the
623                                                            PLL in the FLL modes.          */
624     kMCG_PllEnableInStop = MCG_C5_PLLSTEN0_MASK        /*!< MCGPLLCLK enable in STOP mode. */
625 };
626 
627 /*! @brief MCG mode definitions */
628 typedef enum _mcg_mode
629 {
630     kMCG_ModeFEI = 0U, /*!< FEI   - FLL Engaged Internal         */
631     kMCG_ModeFBI,      /*!< FBI   - FLL Bypassed Internal        */
632     kMCG_ModeBLPI,     /*!< BLPI  - Bypassed Low Power Internal  */
633     kMCG_ModeFEE,      /*!< FEE   - FLL Engaged External         */
634     kMCG_ModeFBE,      /*!< FBE   - FLL Bypassed External        */
635     kMCG_ModeBLPE,     /*!< BLPE  - Bypassed Low Power External  */
636     kMCG_ModePBE,      /*!< PBE   - PLL Bypassed External        */
637     kMCG_ModePEE,      /*!< PEE   - PLL Engaged External         */
638     kMCG_ModeError     /*!< Unknown mode                         */
639 } mcg_mode_t;
640 
641 /*! @brief MCG PLL configuration. */
642 typedef struct _mcg_pll_config
643 {
644     uint8_t enableMode; /*!< Enable mode. OR'ed value of enumeration _mcg_pll_enable_mode. */
645     uint8_t prdiv;      /*!< Reference divider PRDIV.    */
646     uint8_t vdiv;       /*!< VCO divider VDIV.           */
647 } mcg_pll_config_t;
648 
649 /*! @brief MCG mode change configuration structure
650  *
651  * When porting to a new board, set the following members
652  * according to the board setting:
653  * 1. frdiv: If the FLL uses the external reference clock, set this
654  *    value to ensure that the external reference clock divided by frdiv is
655  *    in the 31.25 kHz to 39.0625 kHz range.
656  * 2. The PLL reference clock divider PRDIV: PLL reference clock frequency after
657  *    PRDIV should be in the FSL_FEATURE_MCG_PLL_REF_MIN to
658  *    FSL_FEATURE_MCG_PLL_REF_MAX range.
659  */
660 typedef struct _mcg_config
661 {
662     mcg_mode_t mcgMode; /*!< MCG mode.                   */
663 
664     /* ----------------------- MCGIRCCLK settings ------------------------ */
665     uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode.       */
666     mcg_irc_mode_t ircs;     /*!< Source, MCG_C2[IRCS].       */
667     uint8_t fcrdiv;          /*!< Divider, MCG_SC[FCRDIV].    */
668 
669     /* ------------------------ MCG FLL settings ------------------------- */
670     uint8_t frdiv;       /*!< Divider MCG_C1[FRDIV].      */
671     mcg_drs_t drs;       /*!< DCO range MCG_C4[DRST_DRS]. */
672     mcg_dmx32_t dmx32;   /*!< MCG_C4[DMX32].              */
673     mcg_oscsel_t oscsel; /*!< OSC select MCG_C7[OSCSEL].  */
674 
675     /* ------------------------ MCG PLL settings ------------------------- */
676     mcg_pll_config_t pll0Config; /*!< MCGPLL0CLK configuration.   */
677 
678 } mcg_config_t;
679 
680 /*******************************************************************************
681  * API
682  ******************************************************************************/
683 
684 #if defined(__cplusplus)
685 extern "C" {
686 #endif /* __cplusplus */
687 
688 /*!
689  * @brief Enable the clock for specific IP.
690  *
691  * @param name  Which clock to enable, see \ref clock_ip_name_t.
692  */
CLOCK_EnableClock(clock_ip_name_t name)693 static inline void CLOCK_EnableClock(clock_ip_name_t name)
694 {
695     uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
696     (*(volatile uint32_t *)regAddr) |= (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
697 }
698 
699 /*!
700  * @brief Disable the clock for specific IP.
701  *
702  * @param name  Which clock to disable, see \ref clock_ip_name_t.
703  */
CLOCK_DisableClock(clock_ip_name_t name)704 static inline void CLOCK_DisableClock(clock_ip_name_t name)
705 {
706     uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
707     (*(volatile uint32_t *)regAddr) &= ~(1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
708 }
709 
710 /*!
711  * @brief Set ERCLK32K source.
712  *
713  * @param src The value to set ERCLK32K clock source.
714  */
CLOCK_SetEr32kClock(uint32_t src)715 static inline void CLOCK_SetEr32kClock(uint32_t src)
716 {
717     SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src));
718 }
719 
720 /*!
721  * @brief Set SDHC0 clock source.
722  *
723  * @param src The value to set SDHC0 clock source.
724  */
CLOCK_SetSdhc0Clock(uint32_t src)725 static inline void CLOCK_SetSdhc0Clock(uint32_t src)
726 {
727     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_SDHCSRC_MASK) | SIM_SOPT2_SDHCSRC(src));
728 }
729 
730 /*!
731  * @brief Set EMVSIM clock source.
732  *
733  * @param src The value to set EMVSIM clock source.
734  */
CLOCK_SetEmvsimClock(uint32_t src)735 static inline void CLOCK_SetEmvsimClock(uint32_t src)
736 {
737     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_EMVSIMSRC_MASK) | SIM_SOPT2_EMVSIMSRC(src));
738 }
739 
740 /*!
741  * @brief Set LPUART clock source.
742  *
743  * @param src The value to set LPUART clock source.
744  */
CLOCK_SetLpuartClock(uint32_t src)745 static inline void CLOCK_SetLpuartClock(uint32_t src)
746 {
747     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUARTSRC_MASK) | SIM_SOPT2_LPUARTSRC(src));
748 }
749 
750 /*!
751  * @brief Set TPM clock source.
752  *
753  * @param src The value to set TPM clock source.
754  */
CLOCK_SetTpmClock(uint32_t src)755 static inline void CLOCK_SetTpmClock(uint32_t src)
756 {
757     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(src));
758 }
759 
760 /*!
761  * @brief Set FLEXIO clock source.
762  *
763  * @param src The value to set FLEXIO clock source.
764  */
CLOCK_SetFlexio0Clock(uint32_t src)765 static inline void CLOCK_SetFlexio0Clock(uint32_t src)
766 {
767     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_FLEXIOSRC_MASK) | SIM_SOPT2_FLEXIOSRC(src));
768 }
769 
770 /*!
771  * @brief Set debug trace clock source.
772  *
773  * @param src The value to set debug trace clock source.
774  * @param divValue  Trace clock divider divisor.
775  * @param fracValue Trace clock divider fraction.
776  */
CLOCK_SetTraceClock(uint32_t src,uint32_t divValue,uint32_t fracValue)777 static inline void CLOCK_SetTraceClock(uint32_t src, uint32_t divValue, uint32_t fracValue)
778 {
779     SIM->SOPT2   = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src));
780     SIM->CLKDIV4 = SIM_CLKDIV4_TRACEDIV(divValue) | SIM_CLKDIV4_TRACEFRAC(fracValue);
781 }
782 
783 /*!
784  * @brief Set PLLFLLSEL clock source.
785  *
786  * @param src       The value to set PLLFLLSEL clock source.
787  * @param divValue  PLLFLL clock divider divisor.
788  * @param fracValue PLLFLL clock divider fraction.
789  */
CLOCK_SetPllFllSelClock(uint32_t src,uint32_t divValue,uint32_t fracValue)790 static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue)
791 {
792     SIM->SOPT2   = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src));
793     SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue);
794 }
795 
796 /*!
797  * @brief Set CLKOUT source.
798  *
799  * @param src The value to set CLKOUT source.
800  */
CLOCK_SetClkOutClock(uint32_t src)801 static inline void CLOCK_SetClkOutClock(uint32_t src)
802 {
803     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src));
804 }
805 
806 /*!
807  * @brief Set RTC_CLKOUT source.
808  *
809  * @param src The value to set RTC_CLKOUT source.
810  */
CLOCK_SetRtcClkOutClock(uint32_t src)811 static inline void CLOCK_SetRtcClkOutClock(uint32_t src)
812 {
813     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RTCCLKOUTSEL_MASK) | SIM_SOPT2_RTCCLKOUTSEL(src));
814 }
815 /*! @brief Enable USB FS clock.
816  *
817  * @param src  USB FS clock source.
818  * @param freq The frequency specified by src.
819  * @retval true The clock is set successfully.
820  * @retval false The clock source is invalid to get proper USB FS clock.
821  */
822 bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq);
823 
824 /*! @brief Disable USB FS clock.
825  *
826  * Disable USB FS clock.
827  */
CLOCK_DisableUsbfs0Clock(void)828 static inline void CLOCK_DisableUsbfs0Clock(void)
829 {
830     CLOCK_DisableClock(kCLOCK_Usbfs0);
831 }
832 
833 /*!
834  * @brief System clock divider
835  *
836  * Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV2], SIM_CLKDIV1[OUTDIV3], SIM_CLKDIV1[OUTDIV4].
837  *
838  * @param outdiv1 Clock 1 output divider value.
839  *
840  * @param outdiv2 Clock 2 output divider value.
841  *
842  * @param outdiv3 Clock 3 output divider value.
843  *
844  * @param outdiv4 Clock 4 output divider value.
845  */
CLOCK_SetOutDiv(uint32_t outdiv1,uint32_t outdiv2,uint32_t outdiv3,uint32_t outdiv4)846 static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv2, uint32_t outdiv3, uint32_t outdiv4)
847 {
848     SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2) | SIM_CLKDIV1_OUTDIV3(outdiv3) |
849                    SIM_CLKDIV1_OUTDIV4(outdiv4);
850 }
851 
852 /*!
853  * @brief Gets the clock frequency for a specific clock name.
854  *
855  * This function checks the current clock configurations and then calculates
856  * the clock frequency for a specific clock name defined in clock_name_t.
857  * The MCG must be properly configured before using this function.
858  *
859  * @param clockName Clock names defined in clock_name_t
860  * @return Clock frequency value in Hertz
861  */
862 uint32_t CLOCK_GetFreq(clock_name_t clockName);
863 
864 /*!
865  * @brief Get the core clock or system clock frequency.
866  *
867  * @return Clock frequency in Hz.
868  */
869 uint32_t CLOCK_GetCoreSysClkFreq(void);
870 
871 /*!
872  * @brief Get the platform clock frequency.
873  *
874  * @return Clock frequency in Hz.
875  */
876 uint32_t CLOCK_GetPlatClkFreq(void);
877 
878 /*!
879  * @brief Get the bus clock frequency.
880  *
881  * @return Clock frequency in Hz.
882  */
883 uint32_t CLOCK_GetBusClkFreq(void);
884 
885 /*!
886  * @brief Get the flexbus clock frequency.
887  *
888  * @return Clock frequency in Hz.
889  */
890 uint32_t CLOCK_GetFlexBusClkFreq(void);
891 
892 /*!
893  * @brief Get the flash clock frequency.
894  *
895  * @return Clock frequency in Hz.
896  */
897 uint32_t CLOCK_GetFlashClkFreq(void);
898 
899 /*!
900  * @brief Get the output clock frequency selected by SIM[PLLFLLSEL].
901  *
902  * @return Clock frequency in Hz.
903  */
904 uint32_t CLOCK_GetPllFllSelClkFreq(void);
905 
906 /*!
907  * @brief Get the external reference 32K clock frequency (ERCLK32K).
908  *
909  * @return Clock frequency in Hz.
910  */
911 uint32_t CLOCK_GetEr32kClkFreq(void);
912 
913 /*!
914  * @brief Get the OSC0 external reference undivided clock frequency (OSC0ERCLK_UNDIV).
915  *
916  * @return Clock frequency in Hz.
917  */
918 uint32_t CLOCK_GetOsc0ErClkUndivFreq(void);
919 
920 /*!
921  * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
922  *
923  * @return Clock frequency in Hz.
924  */
925 uint32_t CLOCK_GetOsc0ErClkFreq(void);
926 
927 /*!
928  * @brief Get the OSC0 external reference divided clock frequency.
929  *
930  * @return Clock frequency in Hz.
931  */
932 uint32_t CLOCK_GetOsc0ErClkDivFreq(void);
933 
934 /*!
935  * @brief Set the clock configure in SIM module.
936  *
937  * This function sets system layer clock settings in SIM module.
938  *
939  * @param config Pointer to the configure structure.
940  */
941 void CLOCK_SetSimConfig(sim_clock_config_t const *config);
942 
943 /*!
944  * @brief Set the system clock dividers in SIM to safe value.
945  *
946  * The system level clocks (core clock, bus clock, flexbus clock and flash clock)
947  * must be in allowed ranges. During MCG clock mode switch, the MCG output clock
948  * changes then the system level clocks may be out of range. This function could
949  * be used before MCG mode change, to make sure system level clocks are in allowed
950  * range.
951  *
952  */
CLOCK_SetSimSafeDivs(void)953 static inline void CLOCK_SetSimSafeDivs(void)
954 {
955     SIM->CLKDIV1 = 0x01140000U;
956 }
957 
958 /*! @name MCG frequency functions. */
959 /*@{*/
960 
961 /*!
962  * @brief Gets the MCG output clock (MCGOUTCLK) frequency.
963  *
964  * This function gets the MCG output clock frequency in Hz based on the current MCG
965  * register value.
966  *
967  * @return The frequency of MCGOUTCLK.
968  */
969 uint32_t CLOCK_GetOutClkFreq(void);
970 
971 /*!
972  * @brief Gets the MCG FLL clock (MCGFLLCLK) frequency.
973  *
974  * This function gets the MCG FLL clock frequency in Hz based on the current MCG
975  * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and
976  * disabled in low power state in other modes.
977  *
978  * @return The frequency of MCGFLLCLK.
979  */
980 uint32_t CLOCK_GetFllFreq(void);
981 
982 /*!
983  * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
984  *
985  * This function gets the MCG internal reference clock frequency in Hz based
986  * on the current MCG register value.
987  *
988  * @return The frequency of MCGIRCLK.
989  */
990 uint32_t CLOCK_GetInternalRefClkFreq(void);
991 
992 /*!
993  * @brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency.
994  *
995  * This function gets the MCG fixed frequency clock frequency in Hz based
996  * on the current MCG register value.
997  *
998  * @return The frequency of MCGFFCLK.
999  */
1000 uint32_t CLOCK_GetFixedFreqClkFreq(void);
1001 
1002 /*!
1003  * @brief Gets the MCG PLL0 clock (MCGPLL0CLK) frequency.
1004  *
1005  * This function gets the MCG PLL0 clock frequency in Hz based on the current MCG
1006  * register value.
1007  *
1008  * @return The frequency of MCGPLL0CLK.
1009  */
1010 uint32_t CLOCK_GetPll0Freq(void);
1011 
1012 /*@}*/
1013 
1014 /*! @name MCG clock configuration. */
1015 /*@{*/
1016 
1017 /*!
1018  * @brief Enables or disables the MCG low power.
1019  *
1020  * Enabling the MCG low power disables the PLL and FLL in bypass modes. In other words,
1021  * in FBE and PBE modes, enabling low power sets the MCG to BLPE mode. In FBI and
1022  * PBI modes, enabling low power sets the MCG to BLPI mode.
1023  * When disabling the MCG low power, the PLL or FLL are enabled based on MCG settings.
1024  *
1025  * @param enable True to enable MCG low power, false to disable MCG low power.
1026  */
CLOCK_SetLowPowerEnable(bool enable)1027 static inline void CLOCK_SetLowPowerEnable(bool enable)
1028 {
1029     if (enable)
1030     {
1031         MCG->C2 |= MCG_C2_LP_MASK;
1032     }
1033     else
1034     {
1035         MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
1036     }
1037 }
1038 
1039 /*!
1040  * @brief Configures the Internal Reference clock (MCGIRCLK).
1041  *
1042  * This function sets the \c MCGIRCLK base on parameters. It also selects the IRC
1043  * source. If the fast IRC is used, this function sets the fast IRC divider.
1044  * This function also sets whether the \c MCGIRCLK is enabled in stop mode.
1045  * Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result,
1046  * using the function in these modes it is not allowed.
1047  *
1048  * @param enableMode MCGIRCLK enable mode, OR'ed value of the enumeration _mcg_irclk_enable_mode.
1049  * @param ircs       MCGIRCLK clock source, choose fast or slow.
1050  * @param fcrdiv     Fast IRC divider setting (\c FCRDIV).
1051  * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
1052  * the configuration should not be changed. Otherwise, a glitch occurs.
1053  * @retval kStatus_Success MCGIRCLK configuration finished successfully.
1054  */
1055 status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
1056 
1057 /*!
1058  * @brief Selects the MCG external reference clock.
1059  *
1060  * Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL],
1061  * and waits for the clock source to be stable. Because the external reference
1062  * clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes.
1063  *
1064  * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
1065  * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
1066  * the configuration should not be changed. Otherwise, a glitch occurs.
1067  * @retval kStatus_Success External reference clock set successfully.
1068  */
1069 status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
1070 
1071 /*!
1072  * @brief Set the FLL external reference clock divider value.
1073  *
1074  * Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV].
1075  *
1076  * @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV].
1077  */
CLOCK_SetFllExtRefDiv(uint8_t frdiv)1078 static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
1079 {
1080     MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
1081 }
1082 
1083 /*!
1084  * @brief Enables the PLL0 in FLL mode.
1085  *
1086  * This function sets us the PLL0 in FLL mode and reconfigures
1087  * the PLL0. Ensure that the PLL reference
1088  * clock is enabled before calling this function and that the PLL0 is not used as a clock source.
1089  * The function CLOCK_CalcPllDiv gets the correct PLL
1090  * divider values.
1091  *
1092  * @param config Pointer to the configuration structure.
1093  */
1094 void CLOCK_EnablePll0(mcg_pll_config_t const *config);
1095 
1096 /*!
1097  * @brief Disables the PLL0 in FLL mode.
1098  *
1099  * This function disables the PLL0 in FLL mode. It should be used together with the
1100  * @ref CLOCK_EnablePll0.
1101  */
CLOCK_DisablePll0(void)1102 static inline void CLOCK_DisablePll0(void)
1103 {
1104     MCG->C5 &= (uint8_t)(~(MCG_C5_PLLCLKEN0_MASK | MCG_C5_PLLSTEN0_MASK));
1105 }
1106 
1107 /*!
1108  * @brief Calculates the PLL divider setting for a desired output frequency.
1109  *
1110  * This function calculates the correct reference clock divider (\c PRDIV) and
1111  * VCO divider (\c VDIV) to generate a desired PLL output frequency. It returns the
1112  * closest frequency match with the corresponding \c PRDIV/VDIV
1113  * returned from parameters. If a desired frequency is not valid, this function
1114  * returns 0.
1115  *
1116  * @param refFreq    PLL reference clock frequency.
1117  * @param desireFreq Desired PLL output frequency.
1118  * @param prdiv      PRDIV value to generate desired PLL frequency.
1119  * @param vdiv       VDIV value to generate desired PLL frequency.
1120  * @return Closest frequency match that the PLL was able generate.
1121  */
1122 uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv);
1123 
1124 /*@}*/
1125 
1126 /*! @name MCG clock lock monitor functions. */
1127 /*@{*/
1128 
1129 /*!
1130  * @brief Sets the OSC0 clock monitor mode.
1131  *
1132  * This function sets the OSC0 clock monitor mode. See @ref mcg_monitor_mode_t for details.
1133  *
1134  * @param mode Monitor mode to set.
1135  */
1136 void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
1137 
1138 /*!
1139  * @brief Sets the RTC OSC clock monitor mode.
1140  *
1141  * This function sets the RTC OSC clock monitor mode. See @ref mcg_monitor_mode_t for details.
1142  *
1143  * @param mode Monitor mode to set.
1144  */
1145 void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode);
1146 
1147 /*!
1148  * @brief Sets the PLL0 clock monitor mode.
1149  *
1150  * This function sets the PLL0 clock monitor mode. See @ref mcg_monitor_mode_t for details.
1151  *
1152  * @param mode Monitor mode to set.
1153  */
1154 void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode);
1155 
1156 /*!
1157  * @brief Gets the MCG status flags.
1158  *
1159  * This function gets the MCG clock status flags. All status flags are
1160  * returned as a logical OR of the enumeration refer to _mcg_status_flags_t. To
1161  * check a specific flag, compare the return value with the flag.
1162  *
1163  * Example:
1164  * @code
1165  * To check the clock lost lock status of OSC0 and PLL0.
1166  * uint32_t mcgFlags;
1167  *
1168  * mcgFlags = CLOCK_GetStatusFlags();
1169  *
1170  * if (mcgFlags & kMCG_Osc0LostFlag)
1171  * {
1172  *     OSC0 clock lock lost. Do something.
1173  * }
1174  * if (mcgFlags & kMCG_Pll0LostFlag)
1175  * {
1176  *     PLL0 clock lock lost. Do something.
1177  * }
1178  * @endcode
1179  *
1180  * @return  Logical OR value of the enumeration _mcg_status_flags_t.
1181  */
1182 uint32_t CLOCK_GetStatusFlags(void);
1183 
1184 /*!
1185  * @brief Clears the MCG status flags.
1186  *
1187  * This function clears the MCG clock lock lost status. The parameter is a logical
1188  * OR value of the flags to clear. See the enumeration _mcg_status_flags_t.
1189  *
1190  * Example:
1191  * @code
1192  * To clear the clock lost lock status flags of OSC0 and PLL0.
1193  *
1194  * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
1195  * @endcode
1196  *
1197  * @param mask The status flags to clear. This is a logical OR of members of the
1198  *             enumeration _mcg_status_flags_t.
1199  */
1200 void CLOCK_ClearStatusFlags(uint32_t mask);
1201 
1202 /*@}*/
1203 
1204 /*!
1205  * @name OSC configuration
1206  * @{
1207  */
1208 
1209 /*!
1210  * @brief Configures the OSC external reference clock (OSCERCLK).
1211  *
1212  * This function configures the OSC external reference clock (OSCERCLK).
1213  * This is an example to enable the OSCERCLK in normal and stop modes and also set
1214  * the output divider to 1:
1215  *
1216    @code
1217    oscer_config_t config =
1218    {
1219        .enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop,
1220        .erclkDiv   = 1U,
1221    };
1222 
1223    OSC_SetExtRefClkConfig(OSC, &config);
1224    @endcode
1225  *
1226  * @param base   OSC peripheral address.
1227  * @param config Pointer to the configuration structure.
1228  */
OSC_SetExtRefClkConfig(OSC_Type * base,oscer_config_t const * config)1229 static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config)
1230 {
1231     uint8_t reg = base->CR;
1232 
1233     reg &= (uint8_t)(~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK));
1234     reg |= config->enableMode;
1235 
1236     base->CR = reg;
1237 
1238     base->DIV = OSC_DIV_ERPS(config->erclkDiv);
1239 }
1240 
1241 /*!
1242  * @brief Sets the capacitor load configuration for the oscillator.
1243  *
1244  * This function sets the specified capacitors configuration for the oscillator.
1245  * This should be done in the early system level initialization function call
1246  * based on the system configuration.
1247  *
1248  * @param base   OSC peripheral address.
1249  * @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load.
1250  *
1251  * Example:
1252    @code
1253    To enable only 2 pF and 8 pF capacitor load, please use like this.
1254    OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
1255    @endcode
1256  */
OSC_SetCapLoad(OSC_Type * base,uint8_t capLoad)1257 static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad)
1258 {
1259     uint8_t reg = base->CR;
1260 
1261     reg &= (uint8_t)(~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK));
1262     reg |= capLoad;
1263 
1264     base->CR = reg;
1265 }
1266 
1267 /*!
1268  * @brief Initializes the OSC0.
1269  *
1270  * This function initializes the OSC0 according to the board configuration.
1271  *
1272  * @param  config Pointer to the OSC0 configuration structure.
1273  */
1274 void CLOCK_InitOsc0(osc_config_t const *config);
1275 
1276 /*!
1277  * @brief Deinitializes the OSC0.
1278  *
1279  * This function deinitializes the OSC0.
1280  */
1281 void CLOCK_DeinitOsc0(void);
1282 
1283 /* @} */
1284 
1285 /*!
1286  * @name External clock frequency
1287  * @{
1288  */
1289 
1290 /*!
1291  * @brief Sets the XTAL0 frequency based on board settings.
1292  *
1293  * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
1294  */
CLOCK_SetXtal0Freq(uint32_t freq)1295 static inline void CLOCK_SetXtal0Freq(uint32_t freq)
1296 {
1297     g_xtal0Freq = freq;
1298 }
1299 
1300 /*!
1301  * @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings.
1302  *
1303  * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
1304  */
CLOCK_SetXtal32Freq(uint32_t freq)1305 static inline void CLOCK_SetXtal32Freq(uint32_t freq)
1306 {
1307     g_xtal32Freq = freq;
1308 }
1309 /* @} */
1310 
1311 /*!
1312  * @name IRCs frequency
1313  * @{
1314  */
1315 
1316 /*!
1317  * @brief Set the Slow IRC frequency based on the trimmed value
1318  *
1319  * @param freq The Slow IRC frequency input clock frequency in Hz.
1320  */
1321 void CLOCK_SetSlowIrcFreq(uint32_t freq);
1322 
1323 /*!
1324  * @brief Set the Fast IRC frequency based on the trimmed value
1325  *
1326  * @param freq The Fast IRC frequency input clock frequency in Hz.
1327  */
1328 void CLOCK_SetFastIrcFreq(uint32_t freq);
1329 /* @} */
1330 
1331 /*!
1332  * @name MCG auto-trim machine.
1333  * @{
1334  */
1335 
1336 /*!
1337  * @brief Auto trims the internal reference clock.
1338  *
1339  * This function trims the internal reference clock by using the external clock. If
1340  * successful, it returns the kStatus_Success and the frequency after
1341  * trimming is received in the parameter @p actualFreq. If an error occurs,
1342  * the error code is returned.
1343  *
1344  * @param extFreq      External clock frequency, which should be a bus clock.
1345  * @param desireFreq   Frequency to trim to.
1346  * @param actualFreq   Actual frequency after trimming.
1347  * @param atms         Trim fast or slow internal reference clock.
1348  * @retval kStatus_Success ATM success.
1349  * @retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM.
1350  * @retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency.
1351  * @retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source.
1352  * @retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming.
1353  */
1354 status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms);
1355 /* @} */
1356 
1357 /*! @name MCG mode functions. */
1358 /*@{*/
1359 
1360 /*!
1361  * @brief Gets the current MCG mode.
1362  *
1363  * This function checks the MCG registers and determines the current MCG mode.
1364  *
1365  * @return Current MCG mode or error code; See @ref mcg_mode_t.
1366  */
1367 mcg_mode_t CLOCK_GetMode(void);
1368 
1369 /*!
1370  * @brief Sets the MCG to FEI mode.
1371  *
1372  * This function sets the MCG to FEI mode. If setting to FEI mode fails
1373  * from the current mode, this function returns an error.
1374  *
1375  * @param       dmx32  DMX32 in FEI mode.
1376  * @param       drs The DCO range selection.
1377  * @param       fllStableDelay Delay function to  ensure that the FLL is stable. Passing
1378  *              NULL does not cause a delay.
1379  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1380  * @retval kStatus_Success Switched to the target mode successfully.
1381  * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1382  * to a frequency above 32768 Hz.
1383  */
1384 status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1385 
1386 /*!
1387  * @brief Sets the MCG to FEE mode.
1388  *
1389  * This function sets the MCG to FEE mode. If setting to FEE mode fails
1390  * from the current mode, this function returns an error.
1391  *
1392  * @param   frdiv  FLL reference clock divider setting, FRDIV.
1393  * @param   dmx32  DMX32 in FEE mode.
1394  * @param   drs    The DCO range selection.
1395  * @param   fllStableDelay Delay function to make sure FLL is stable. Passing
1396  *          NULL does not cause a delay.
1397  *
1398  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1399  * @retval kStatus_Success Switched to the target mode successfully.
1400  */
1401 status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1402 
1403 /*!
1404  * @brief Sets the MCG to FBI mode.
1405  *
1406  * This function sets the MCG to FBI mode. If setting to FBI mode fails
1407  * from the current mode, this function returns an error.
1408  *
1409  * @param  dmx32  DMX32 in FBI mode.
1410  * @param  drs  The DCO range selection.
1411  * @param  fllStableDelay Delay function to make sure FLL is stable. If the FLL
1412  *         is not used in FBI mode, this parameter can be NULL. Passing
1413  *         NULL does not cause a delay.
1414  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1415  * @retval kStatus_Success Switched to the target mode successfully.
1416  * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1417  * to frequency above 32768 Hz.
1418  */
1419 status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1420 
1421 /*!
1422  * @brief Sets the MCG to FBE mode.
1423  *
1424  * This function sets the MCG to FBE mode. If setting to FBE mode fails
1425  * from the current mode, this function returns an error.
1426  *
1427  * @param   frdiv  FLL reference clock divider setting, FRDIV.
1428  * @param   dmx32  DMX32 in FBE mode.
1429  * @param   drs    The DCO range selection.
1430  * @param   fllStableDelay Delay function to make sure FLL is stable. If the FLL
1431  *          is not used in FBE mode, this parameter can be NULL. Passing NULL
1432  *          does not cause a delay.
1433  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1434  * @retval kStatus_Success Switched to the target mode successfully.
1435  */
1436 status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1437 
1438 /*!
1439  * @brief Sets the MCG to BLPI mode.
1440  *
1441  * This function sets the MCG to BLPI mode. If setting to BLPI mode fails
1442  * from the current mode, this function returns an error.
1443  *
1444  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1445  * @retval kStatus_Success Switched to the target mode successfully.
1446  */
1447 status_t CLOCK_SetBlpiMode(void);
1448 
1449 /*!
1450  * @brief Sets the MCG to BLPE mode.
1451  *
1452  * This function sets the MCG to BLPE mode. If setting to BLPE mode fails
1453  * from the current mode, this function returns an error.
1454  *
1455  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1456  * @retval kStatus_Success Switched to the target mode successfully.
1457  */
1458 status_t CLOCK_SetBlpeMode(void);
1459 
1460 /*!
1461  * @brief Sets the MCG to PBE mode.
1462  *
1463  * This function sets the MCG to PBE mode. If setting to PBE mode fails
1464  * from the current mode, this function returns an error.
1465  *
1466  * @param   pllcs  The PLL selection, PLLCS.
1467  * @param   config Pointer to the PLL configuration.
1468  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1469  * @retval kStatus_Success Switched to the target mode successfully.
1470  *
1471  * @note
1472  * 1. The parameter \c pllcs selects the PLL. For platforms with
1473  * only one PLL, the parameter pllcs is kept for interface compatibility.
1474  * 2. The parameter \c config is the PLL configuration structure. On some
1475  * platforms,  it is possible to choose the external PLL directly, which renders the
1476  * configuration structure not necessary. In this case, pass in NULL.
1477  * For example: CLOCK_SetPbeMode(kMCG_OscselOsc, kMCG_PllClkSelExtPll, NULL);
1478  */
1479 status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config);
1480 
1481 /*!
1482  * @brief Sets the MCG to PEE mode.
1483  *
1484  * This function sets the MCG to PEE mode.
1485  *
1486  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1487  * @retval kStatus_Success Switched to the target mode successfully.
1488  *
1489  * @note This function only changes the CLKS to use the PLL/FLL output. If the
1490  *       PRDIV/VDIV are different than in the PBE mode, set them up
1491  *       in PBE mode and wait. When the clock is stable, switch to PEE mode.
1492  */
1493 status_t CLOCK_SetPeeMode(void);
1494 
1495 /*!
1496  * @brief Switches the MCG to FBE mode from the external mode.
1497  *
1498  * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
1499  * The external clock is used as the system clock source and PLL is disabled. However,
1500  * the FLL settings are not configured. This is a lite function with a small code size, which is useful
1501  * during the mode switch. For example, to switch from PEE mode to FEI mode:
1502  *
1503  * @code
1504  * CLOCK_ExternalModeToFbeModeQuick();
1505  * CLOCK_SetFeiMode(...);
1506  * @endcode
1507  *
1508  * @retval kStatus_Success Switched successfully.
1509  * @retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function.
1510  */
1511 status_t CLOCK_ExternalModeToFbeModeQuick(void);
1512 
1513 /*!
1514  * @brief Switches the MCG to FBI mode from internal modes.
1515  *
1516  * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
1517  * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
1518  * FLL settings are not configured. This is a lite function with a small code size, which is useful
1519  * during the mode switch. For example, to switch from PEI mode to FEE mode:
1520  *
1521  * @code
1522  * CLOCK_InternalModeToFbiModeQuick();
1523  * CLOCK_SetFeeMode(...);
1524  * @endcode
1525  *
1526  * @retval kStatus_Success Switched successfully.
1527  * @retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function.
1528  */
1529 status_t CLOCK_InternalModeToFbiModeQuick(void);
1530 
1531 /*!
1532  * @brief Sets the MCG to FEI mode during system boot up.
1533  *
1534  * This function sets the MCG to FEI mode from the reset mode. It can also be used to
1535  * set up MCG during system boot up.
1536  *
1537  * @param  dmx32  DMX32 in FEI mode.
1538  * @param  drs The DCO range selection.
1539  * @param  fllStableDelay Delay function to ensure that the FLL is stable.
1540  *
1541  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1542  * @retval kStatus_Success Switched to the target mode successfully.
1543  * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1544  * to frequency above 32768 Hz.
1545  */
1546 status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1547 
1548 /*!
1549  * @brief Sets the MCG to FEE mode during system bootup.
1550  *
1551  * This function sets MCG to FEE mode from the reset mode. It can also be used to
1552  * set up the MCG during system boot up.
1553  *
1554  * @param   oscsel OSC clock select, OSCSEL.
1555  * @param   frdiv  FLL reference clock divider setting, FRDIV.
1556  * @param   dmx32  DMX32 in FEE mode.
1557  * @param   drs    The DCO range selection.
1558  * @param   fllStableDelay Delay function to ensure that the FLL is stable.
1559  *
1560  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1561  * @retval kStatus_Success Switched to the target mode successfully.
1562  */
1563 status_t CLOCK_BootToFeeMode(
1564     mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1565 
1566 /*!
1567  * @brief Sets the MCG to BLPI mode during system boot up.
1568  *
1569  * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
1570  * set up the MCG during system boot up.
1571  *
1572  * @param  fcrdiv Fast IRC divider, FCRDIV.
1573  * @param  ircs   The internal reference clock to select, IRCS.
1574  * @param  ircEnableMode  The MCGIRCLK enable mode, OR'ed value of the enumeration _mcg_irclk_enable_mode.
1575  *
1576  * @retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting.
1577  * @retval kStatus_Success Switched to the target mode successfully.
1578  */
1579 status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
1580 
1581 /*!
1582  * @brief Sets the MCG to BLPE mode during system boot up.
1583  *
1584  * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
1585  * set up the MCG during system boot up.
1586  *
1587  * @param  oscsel OSC clock select, MCG_C7[OSCSEL].
1588  *
1589  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1590  * @retval kStatus_Success Switched to the target mode successfully.
1591  */
1592 status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel);
1593 
1594 /*!
1595  * @brief Sets the MCG to PEE mode during system boot up.
1596  *
1597  * This function sets the MCG to PEE mode from reset mode. It can also be used to
1598  * set up the MCG during system boot up.
1599  *
1600  * @param   oscsel OSC clock select, MCG_C7[OSCSEL].
1601  * @param   pllcs  The PLL selection, PLLCS.
1602  * @param   config Pointer to the PLL configuration.
1603  *
1604  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1605  * @retval kStatus_Success Switched to the target mode successfully.
1606  */
1607 status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config);
1608 
1609 /*!
1610  * @brief Sets the MCG to a target mode.
1611  *
1612  * This function sets MCG to a target mode defined by the configuration
1613  * structure. If switching to the target mode fails, this function
1614  * chooses the correct path.
1615  *
1616  * @param  config Pointer to the target MCG mode configuration structure.
1617  * @return Return kStatus_Success if switched successfully; Otherwise, it returns an error code _mcg_status.
1618  *
1619  * @note If the external clock is used in the target mode, ensure that it is
1620  * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this
1621  * function.
1622  */
1623 status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
1624 
1625 /*@}*/
1626 
1627 #if defined(__cplusplus)
1628 }
1629 #endif /* __cplusplus */
1630 
1631 /*! @} */
1632 
1633 #endif /* _FSL_CLOCK_H_ */
1634