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