1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2020, 2022 - 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.5.3. */
62 #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 5, 3))
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 PORT. */
113 #define PORT_CLOCKS \
114 { \
115 kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \
116 }
117
118 /*! @brief Clock ip name array for EWM. */
119 #define EWM_CLOCKS \
120 { \
121 kCLOCK_Ewm0 \
122 }
123
124 /*! @brief Clock ip name array for PIT. */
125 #define PIT_CLOCKS \
126 { \
127 kCLOCK_Pit0 \
128 }
129
130 /*! @brief Clock ip name array for DSPI. */
131 #define DSPI_CLOCKS \
132 { \
133 kCLOCK_Spi0 \
134 }
135
136 /*! @brief Clock ip name array for LPTMR. */
137 #define LPTMR_CLOCKS \
138 { \
139 kCLOCK_Lptmr0 \
140 }
141
142 /*! @brief Clock ip name array for FTM. */
143 #define FTM_CLOCKS \
144 { \
145 kCLOCK_Ftm0, kCLOCK_Ftm1, kCLOCK_Ftm2 \
146 }
147
148 /*! @brief Clock ip name array for EDMA. */
149 #define EDMA_CLOCKS \
150 { \
151 kCLOCK_Dma0 \
152 }
153
154 /*! @brief Clock ip name array for DAC. */
155 #define DAC_CLOCKS \
156 { \
157 kCLOCK_Dac0 \
158 }
159
160 /*! @brief Clock ip name array for ADC16. */
161 #define ADC16_CLOCKS \
162 { \
163 kCLOCK_Adc0 \
164 }
165
166 /*! @brief Clock ip name array for VREF. */
167 #define VREF_CLOCKS \
168 { \
169 kCLOCK_Vref0 \
170 }
171
172 /*! @brief Clock ip name array for UART. */
173 #define UART_CLOCKS \
174 { \
175 kCLOCK_Uart0, kCLOCK_Uart1 \
176 }
177
178 /*! @brief Clock ip name array for CRC. */
179 #define CRC_CLOCKS \
180 { \
181 kCLOCK_Crc0 \
182 }
183
184 /*! @brief Clock ip name array for I2C. */
185 #define I2C_CLOCKS \
186 { \
187 kCLOCK_I2c0 \
188 }
189
190 /*! @brief Clock ip name array for FTF. */
191 #define FTF_CLOCKS \
192 { \
193 kCLOCK_Ftf0 \
194 }
195
196 /*! @brief Clock ip name array for PDB. */
197 #define PDB_CLOCKS \
198 { \
199 kCLOCK_Pdb0 \
200 }
201
202 /*! @brief Clock ip name array for CMP. */
203 #define CMP_CLOCKS \
204 { \
205 kCLOCK_Cmp0, kCLOCK_Cmp1 \
206 }
207
208 /*!
209 * @brief LPO clock frequency.
210 */
211 #define LPO_CLK_FREQ 1000U
212
213 /*! @brief Peripherals clock source definition. */
214 #define SYS_CLK kCLOCK_CoreSysClk
215 #define BUS_CLK kCLOCK_BusClk
216 #define FAST_CLK kCLOCK_FastPeriphClk
217
218 #define I2C0_CLK_SRC BUS_CLK
219 #define I2C1_CLK_SRC BUS_CLK
220 #define DSPI0_CLK_SRC BUS_CLK
221 #define DSPI1_CLK_SRC BUS_CLK
222 #define UART0_CLK_SRC SYS_CLK
223 #define UART1_CLK_SRC SYS_CLK
224 #define UART2_CLK_SRC BUS_CLK
225
226 /*! @brief Clock name used to get clock frequency. */
227 typedef enum _clock_name
228 {
229
230 /* ----------------------------- System layer clock -------------------------------*/
231 kCLOCK_CoreSysClk, /*!< Core/system clock */
232 kCLOCK_PlatClk, /*!< Platform clock */
233 kCLOCK_BusClk, /*!< Bus clock */
234 kCLOCK_FlexBusClk, /*!< FlexBus clock */
235 kCLOCK_FlashClk, /*!< Flash clock */
236 kCLOCK_FastPeriphClk, /*!< Fast peripheral clock */
237 kCLOCK_PllFllSelClk, /*!< The clock after SIM[PLLFLLSEL]. */
238
239 /* ---------------------------------- OSC clock -----------------------------------*/
240 kCLOCK_Er32kClk, /*!< External reference 32K clock (ERCLK32K) */
241 kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */
242 kCLOCK_Osc1ErClk, /*!< OSC1 external reference clock (OSC1ERCLK) */
243 kCLOCK_Osc0ErClkUndiv, /*!< OSC0 external reference undivided clock(OSC0ERCLK_UNDIV). */
244
245 /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/
246 kCLOCK_McgFixedFreqClk, /*!< MCG fixed frequency clock (MCGFFCLK) */
247 kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */
248 kCLOCK_McgFllClk, /*!< MCGFLLCLK */
249 kCLOCK_McgPll0Clk, /*!< MCGPLL0CLK */
250 kCLOCK_McgPll1Clk, /*!< MCGPLL1CLK */
251 kCLOCK_McgExtPllClk, /*!< EXT_PLLCLK */
252 kCLOCK_McgPeriphClk, /*!< MCG peripheral clock (MCGPCLK) */
253 kCLOCK_McgIrc48MClk, /*!< MCG IRC48M clock */
254
255 /* --------------------------------- Other clock ----------------------------------*/
256 kCLOCK_LpoClk, /*!< LPO clock */
257
258 } clock_name_t;
259
260 /*------------------------------------------------------------------------------
261
262 clock_gate_t definition:
263
264 31 16 0
265 -----------------------------------------------------------------
266 | SIM_SCGC register offset | control bit offset in SCGC |
267 -----------------------------------------------------------------
268
269 For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the
270 SIM_SCGC3 offset in SIM is 0x1030, then kCLOCK_GateSdhc0 is defined as
271
272 kCLOCK_GateSdhc0 = (0x1030 << 16) | 17;
273
274 ------------------------------------------------------------------------------*/
275
276 #define CLK_GATE_REG_OFFSET_SHIFT 16U
277 #define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U
278 #define CLK_GATE_BIT_SHIFT_SHIFT 0U
279 #define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU
280
281 #define CLK_GATE_DEFINE(reg_offset, bit_shift) \
282 ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
283 (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
284
285 #define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
286 #define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
287
288 /*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
289 typedef enum _clock_ip_name
290 {
291 kCLOCK_IpInvalid = 0U,
292
293 kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U),
294 kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
295 kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U),
296 kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U),
297 kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
298 kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U),
299 kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
300
301 kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
302 kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
303 kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
304 kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
305 kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
306 kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
307
308 kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
309 kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
310 kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U),
311 kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
312 kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U),
313 kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
314 kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U),
315 kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U),
316 kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U),
317 kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
318 kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U),
319
320 kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U),
321 } clock_ip_name_t;
322
323 /*!@brief SIM configuration structure for clock setting. */
324 typedef struct _sim_clock_config
325 {
326 uint8_t pllFllSel; /*!< PLL/FLL/IRC48M selection. */
327 uint8_t er32kSrc; /*!< ERCLK32K source selection. */
328 uint32_t clkdiv1; /*!< SIM_CLKDIV1. */
329 } sim_clock_config_t;
330
331 /*! @brief OSC work mode. */
332 typedef enum _osc_mode
333 {
334 kOSC_ModeExt = 0U, /*!< Use an external clock. */
335 #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
336 kOSC_ModeOscLowPower = MCG_C2_EREFS_MASK, /*!< Oscillator low power. */
337 #else
338 kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */
339 #endif
340 kOSC_ModeOscHighGain = 0U
341 #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
342 | MCG_C2_EREFS_MASK
343 #else
344 | MCG_C2_EREFS0_MASK
345 #endif
346 #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
347 | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
348 #else
349 | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
350 #endif
351 } osc_mode_t;
352
353 /*! @brief Oscillator capacitor load setting.*/
354 enum _osc_cap_load
355 {
356 kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
357 kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
358 kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
359 kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
360 };
361
362 /*! @brief OSCERCLK enable mode. */
363 enum _oscer_enable_mode
364 {
365 kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
366 kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
367 };
368
369 /*! @brief OSC configuration for OSCERCLK. */
370 typedef struct _oscer_config
371 {
372 uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of @ref _oscer_enable_mode. */
373
374 uint8_t erclkDiv; /*!< Divider for OSCERCLK.*/
375 } oscer_config_t;
376
377 /*!
378 * @brief OSC Initialization Configuration Structure
379 *
380 * Defines the configuration data structure to initialize the OSC.
381 * When porting to a new board, set the following members
382 * according to the board setting:
383 * 1. freq: The external frequency.
384 * 2. workMode: The OSC module mode.
385 */
386 typedef struct _osc_config
387 {
388 uint32_t freq; /*!< External clock frequency. */
389 uint8_t capLoad; /*!< Capacitor load setting. */
390 osc_mode_t workMode; /*!< OSC work mode setting. */
391 oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK. */
392 } osc_config_t;
393
394 /*! @brief MCG FLL reference clock source select. */
395 typedef enum _mcg_fll_src
396 {
397 kMCG_FllSrcExternal, /*!< External reference clock is selected */
398 kMCG_FllSrcInternal /*!< The slow internal reference clock is selected */
399 } mcg_fll_src_t;
400
401 /*! @brief MCG internal reference clock select */
402 typedef enum _mcg_irc_mode
403 {
404 kMCG_IrcSlow, /*!< Slow internal reference clock selected */
405 kMCG_IrcFast /*!< Fast internal reference clock selected */
406 } mcg_irc_mode_t;
407
408 /*! @brief MCG DCO Maximum Frequency with 32.768 kHz Reference */
409 typedef enum _mcg_dmx32
410 {
411 kMCG_Dmx32Default, /*!< DCO has a default range of 25% */
412 kMCG_Dmx32Fine /*!< DCO is fine-tuned for maximum frequency with 32.768 kHz reference */
413 } mcg_dmx32_t;
414
415 /*! @brief MCG DCO range select */
416 typedef enum _mcg_drs
417 {
418 kMCG_DrsLow, /*!< Low frequency range */
419 kMCG_DrsMid, /*!< Mid frequency range */
420 kMCG_DrsMidHigh, /*!< Mid-High frequency range */
421 kMCG_DrsHigh /*!< High frequency range */
422 } mcg_drs_t;
423
424 /*! @brief MCG PLL reference clock select */
425 typedef enum _mcg_pll_ref_src
426 {
427 kMCG_PllRefOsc0, /*!< Selects OSC0 as PLL reference clock */
428 kMCG_PllRefOsc1 /*!< Selects OSC1 as PLL reference clock */
429 } mcg_pll_ref_src_t;
430
431 /*! @brief MCGOUT clock source. */
432 typedef enum _mcg_clkout_src
433 {
434 kMCG_ClkOutSrcOut, /*!< Output of the FLL is selected (reset default) */
435 kMCG_ClkOutSrcInternal, /*!< Internal reference clock is selected */
436 kMCG_ClkOutSrcExternal, /*!< External reference clock is selected */
437 } mcg_clkout_src_t;
438
439 /*! @brief MCG Automatic Trim Machine Select */
440 typedef enum _mcg_atm_select
441 {
442 kMCG_AtmSel32k, /*!< 32 kHz Internal Reference Clock selected */
443 kMCG_AtmSel4m /*!< 4 MHz Internal Reference Clock selected */
444 } mcg_atm_select_t;
445
446 /*! @brief MCG OSC Clock Select */
447 typedef enum _mcg_oscsel
448 {
449 kMCG_OscselOsc, /*!< Selects System Oscillator (OSCCLK) */
450 kMCG_OscselRtc, /*!< Selects 32 kHz RTC Oscillator */
451 kMCG_OscselIrc /*!< Selects 48 MHz IRC Oscillator */
452 } mcg_oscsel_t;
453
454 /*! @brief MCG PLLCS select */
455 typedef enum _mcg_pll_clk_select
456 {
457 kMCG_PllClkSelPll0, /*!< PLL0 output clock is selected */
458 kMCG_PllClkSelPll1 /* PLL1 output clock is selected */
459 } mcg_pll_clk_select_t;
460
461 /*! @brief MCG clock monitor mode. */
462 typedef enum _mcg_monitor_mode
463 {
464 kMCG_MonitorNone, /*!< Clock monitor is disabled. */
465 kMCG_MonitorInt, /*!< Trigger interrupt when clock lost. */
466 kMCG_MonitorReset /*!< System reset when clock lost. */
467 } mcg_monitor_mode_t;
468
469 /*! @brief MCG status. Enumeration _mcg_status */
470 enum
471 {
472 kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0U), /*!< Can't switch to target mode. */
473 kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1U), /*!< Current mode invalid for the specific
474 function. */
475 kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2U), /*!< Invalid bus clock for ATM. */
476 kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3U), /*!< Invalid desired frequency for ATM. */
477 kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4U), /*!< IRC is used when using ATM. */
478 kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5U), /*!< Hardware fail occurs during ATM. */
479 kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6U) /*!< Can't change the clock source because
480 it is in use. */
481 };
482
483 /*! @brief MCG status flags. Enumeration _mcg_status_flags_t */
484 enum
485 {
486 kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */
487 kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */
488 };
489
490 /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. Enumeration _mcg_irclk_enable_mode */
491 enum
492 {
493 kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
494 kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
495 };
496
497 /*! @brief MCG mode definitions */
498 typedef enum _mcg_mode
499 {
500 kMCG_ModeFEI = 0U, /*!< FEI - FLL Engaged Internal */
501 kMCG_ModeFBI, /*!< FBI - FLL Bypassed Internal */
502 kMCG_ModeBLPI, /*!< BLPI - Bypassed Low Power Internal */
503 kMCG_ModeFEE, /*!< FEE - FLL Engaged External */
504 kMCG_ModeFBE, /*!< FBE - FLL Bypassed External */
505 kMCG_ModeBLPE, /*!< BLPE - Bypassed Low Power External */
506 kMCG_ModeError /*!< Unknown mode */
507 } mcg_mode_t;
508
509 /*! @brief MCG mode change configuration structure
510 *
511 * When porting to a new board, set the following members
512 * according to the board setting:
513 * 1. frdiv: If the FLL uses the external reference clock, set this
514 * value to ensure that the external reference clock divided by frdiv is
515 * in the 31.25 kHz to 39.0625 kHz range.
516 * 2. The PLL reference clock divider PRDIV: PLL reference clock frequency after
517 * PRDIV should be in the FSL_FEATURE_MCG_PLL_REF_MIN to
518 * FSL_FEATURE_MCG_PLL_REF_MAX range.
519 */
520 typedef struct _mcg_config
521 {
522 mcg_mode_t mcgMode; /*!< MCG mode. */
523
524 /* ----------------------- MCGIRCCLK settings ------------------------ */
525 uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode. */
526 mcg_irc_mode_t ircs; /*!< Source, MCG_C2[IRCS]. */
527 uint8_t fcrdiv; /*!< Divider, MCG_SC[FCRDIV]. */
528
529 /* ------------------------ MCG FLL settings ------------------------- */
530 uint8_t frdiv; /*!< Divider MCG_C1[FRDIV]. */
531 mcg_drs_t drs; /*!< DCO range MCG_C4[DRST_DRS]. */
532 mcg_dmx32_t dmx32; /*!< MCG_C4[DMX32]. */
533 mcg_oscsel_t oscsel; /*!< OSC select MCG_C7[OSCSEL]. */
534
535 /* ------------------------ MCG PLL settings ------------------------- */
536 } mcg_config_t;
537
538 /*******************************************************************************
539 * API
540 ******************************************************************************/
541
542 #if defined(__cplusplus)
543 extern "C" {
544 #endif /* __cplusplus */
545
546 /*!
547 * @brief Enable the clock for specific IP.
548 *
549 * @param name Which clock to enable, see \ref clock_ip_name_t.
550 */
CLOCK_EnableClock(clock_ip_name_t name)551 static inline void CLOCK_EnableClock(clock_ip_name_t name)
552 {
553 uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
554 (*(volatile uint32_t *)regAddr) |= (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
555 }
556
557 /*!
558 * @brief Disable the clock for specific IP.
559 *
560 * @param name Which clock to disable, see \ref clock_ip_name_t.
561 */
CLOCK_DisableClock(clock_ip_name_t name)562 static inline void CLOCK_DisableClock(clock_ip_name_t name)
563 {
564 uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
565 (*(volatile uint32_t *)regAddr) &= ~(1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
566 }
567
568 /*!
569 * @brief Set ERCLK32K source.
570 *
571 * @param src The value to set ERCLK32K clock source.
572 */
CLOCK_SetEr32kClock(uint32_t src)573 static inline void CLOCK_SetEr32kClock(uint32_t src)
574 {
575 SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src));
576 }
577
578 /*!
579 * @brief Set debug trace clock source.
580 *
581 * @param src The value to set debug trace clock source.
582 */
CLOCK_SetTraceClock(uint32_t src)583 static inline void CLOCK_SetTraceClock(uint32_t src)
584 {
585 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src));
586 }
587
588 /*!
589 * @brief Set PLLFLLSEL clock source.
590 *
591 * @param src The value to set PLLFLLSEL clock source.
592 */
CLOCK_SetPllFllSelClock(uint32_t src)593 static inline void CLOCK_SetPllFllSelClock(uint32_t src)
594 {
595 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src));
596 }
597
598 /*!
599 * @brief Set CLKOUT source.
600 *
601 * @param src The value to set CLKOUT source.
602 */
CLOCK_SetClkOutClock(uint32_t src)603 static inline void CLOCK_SetClkOutClock(uint32_t src)
604 {
605 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src));
606 }
607
608 /*!
609 * @brief System clock divider
610 *
611 * Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV2], SIM_CLKDIV1[OUTDIV4].
612 *
613 * @param outdiv1 Clock 1 output divider value.
614 *
615 * @param outdiv2 Clock 2 output divider value.
616 *
617 * @param outdiv4 Clock 4 output divider value.
618 */
CLOCK_SetOutDiv(uint32_t outdiv1,uint32_t outdiv2,uint32_t outdiv4)619 static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv2, uint32_t outdiv4)
620 {
621 SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2) | SIM_CLKDIV1_OUTDIV4(outdiv4);
622 }
623
624 /*!
625 * @brief Gets the clock frequency for a specific clock name.
626 *
627 * This function checks the current clock configurations and then calculates
628 * the clock frequency for a specific clock name defined in clock_name_t.
629 * The MCG must be properly configured before using this function.
630 *
631 * @param clockName Clock names defined in clock_name_t
632 * @return Clock frequency value in Hertz
633 */
634 uint32_t CLOCK_GetFreq(clock_name_t clockName);
635
636 /*!
637 * @brief Get the core clock or system clock frequency.
638 *
639 * @return Clock frequency in Hz.
640 */
641 uint32_t CLOCK_GetCoreSysClkFreq(void);
642
643 /*!
644 * @brief Get the platform clock frequency.
645 *
646 * @return Clock frequency in Hz.
647 */
648 uint32_t CLOCK_GetPlatClkFreq(void);
649
650 /*!
651 * @brief Get the bus clock frequency.
652 *
653 * @return Clock frequency in Hz.
654 */
655 uint32_t CLOCK_GetBusClkFreq(void);
656
657 /*!
658 * @brief Get the flash clock frequency.
659 *
660 * @return Clock frequency in Hz.
661 */
662 uint32_t CLOCK_GetFlashClkFreq(void);
663
664 /*!
665 * @brief Get the output clock frequency selected by SIM[PLLFLLSEL].
666 *
667 * @return Clock frequency in Hz.
668 */
669 uint32_t CLOCK_GetPllFllSelClkFreq(void);
670
671 /*!
672 * @brief Get the external reference 32K clock frequency (ERCLK32K).
673 *
674 * @return Clock frequency in Hz.
675 */
676 uint32_t CLOCK_GetEr32kClkFreq(void);
677
678 /*!
679 * @brief Get the OSC0 external reference undivided clock frequency (OSC0ERCLK_UNDIV).
680 *
681 * @return Clock frequency in Hz.
682 */
683 uint32_t CLOCK_GetOsc0ErClkUndivFreq(void);
684
685 /*!
686 * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
687 *
688 * @return Clock frequency in Hz.
689 */
690 uint32_t CLOCK_GetOsc0ErClkFreq(void);
691
692 /*!
693 * @brief Get the OSC0 external reference divided clock frequency.
694 *
695 * @return Clock frequency in Hz.
696 */
697 uint32_t CLOCK_GetOsc0ErClkDivFreq(void);
698
699 /*!
700 * @brief Set the clock configure in SIM module.
701 *
702 * This function sets system layer clock settings in SIM module.
703 *
704 * @param config Pointer to the configure structure.
705 */
706 void CLOCK_SetSimConfig(sim_clock_config_t const *config);
707
708 /*!
709 * @brief Set the system clock dividers in SIM to safe value.
710 *
711 * The system level clocks (core clock, bus clock, flexbus clock and flash clock)
712 * must be in allowed ranges. During MCG clock mode switch, the MCG output clock
713 * changes then the system level clocks may be out of range. This function could
714 * be used before MCG mode change, to make sure system level clocks are in allowed
715 * range.
716 *
717 * @param config Pointer to the configure structure.
718 */
CLOCK_SetSimSafeDivs(void)719 static inline void CLOCK_SetSimSafeDivs(void)
720 {
721 SIM->CLKDIV1 = 0x11070000U;
722 }
723
724 /*! @name MCG frequency functions. */
725 /*@{*/
726
727 /*!
728 * @brief Gets the MCG output clock (MCGOUTCLK) frequency.
729 *
730 * This function gets the MCG output clock frequency in Hz based on the current MCG
731 * register value.
732 *
733 * @return The frequency of MCGOUTCLK.
734 */
735 uint32_t CLOCK_GetOutClkFreq(void);
736
737 /*!
738 * @brief Gets the MCG FLL clock (MCGFLLCLK) frequency.
739 *
740 * This function gets the MCG FLL clock frequency in Hz based on the current MCG
741 * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and
742 * disabled in low power state in other modes.
743 *
744 * @return The frequency of MCGFLLCLK.
745 */
746 uint32_t CLOCK_GetFllFreq(void);
747
748 /*!
749 * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
750 *
751 * This function gets the MCG internal reference clock frequency in Hz based
752 * on the current MCG register value.
753 *
754 * @return The frequency of MCGIRCLK.
755 */
756 uint32_t CLOCK_GetInternalRefClkFreq(void);
757
758 /*!
759 * @brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency.
760 *
761 * This function gets the MCG fixed frequency clock frequency in Hz based
762 * on the current MCG register value.
763 *
764 * @return The frequency of MCGFFCLK.
765 */
766 uint32_t CLOCK_GetFixedFreqClkFreq(void);
767
768 /*@}*/
769
770 /*! @name MCG clock configuration. */
771 /*@{*/
772
773 /*!
774 * @brief Enables or disables the MCG low power.
775 *
776 * Enabling the MCG low power disables the PLL and FLL in bypass modes. In other words,
777 * in FBE and PBE modes, enabling low power sets the MCG to BLPE mode. In FBI and
778 * PBI modes, enabling low power sets the MCG to BLPI mode.
779 * When disabling the MCG low power, the PLL or FLL are enabled based on MCG settings.
780 *
781 * @param enable True to enable MCG low power, false to disable MCG low power.
782 */
CLOCK_SetLowPowerEnable(bool enable)783 static inline void CLOCK_SetLowPowerEnable(bool enable)
784 {
785 if (enable)
786 {
787 MCG->C2 |= MCG_C2_LP_MASK;
788 }
789 else
790 {
791 MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
792 }
793 }
794
795 /*!
796 * @brief Configures the Internal Reference clock (MCGIRCLK).
797 *
798 * This function sets the \c MCGIRCLK base on parameters. It also selects the IRC
799 * source. If the fast IRC is used, this function sets the fast IRC divider.
800 * This function also sets whether the \c MCGIRCLK is enabled in stop mode.
801 * Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result,
802 * using the function in these modes it is not allowed.
803 *
804 * @param enableMode MCGIRCLK enable mode, OR'ed value of the enumeration _mcg_irclk_enable_mode.
805 * @param ircs MCGIRCLK clock source, choose fast or slow.
806 * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
807 * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
808 * the configuration should not be changed. Otherwise, a glitch occurs.
809 * @retval kStatus_Success MCGIRCLK configuration finished successfully.
810 */
811 status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
812
813 /*!
814 * @brief Selects the MCG external reference clock.
815 *
816 * Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL],
817 * and waits for the clock source to be stable. Because the external reference
818 * clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes.
819 *
820 * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
821 * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
822 * the configuration should not be changed. Otherwise, a glitch occurs.
823 * @retval kStatus_Success External reference clock set successfully.
824 */
825 status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
826
827 /*!
828 * @brief Set the FLL external reference clock divider value.
829 *
830 * Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV].
831 *
832 * @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV].
833 */
CLOCK_SetFllExtRefDiv(uint8_t frdiv)834 static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
835 {
836 MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
837 }
838
839 /*@}*/
840
841 /*! @name MCG clock lock monitor functions. */
842 /*@{*/
843
844 /*!
845 * @brief Sets the OSC0 clock monitor mode.
846 *
847 * This function sets the OSC0 clock monitor mode. See @ref mcg_monitor_mode_t for details.
848 *
849 * @param mode Monitor mode to set.
850 */
851 void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
852
853 /*!
854 * @brief Gets the MCG status flags.
855 *
856 * This function gets the MCG clock status flags. All status flags are
857 * returned as a logical OR of the enumeration refer to _mcg_status_flags_t. To
858 * check a specific flag, compare the return value with the flag.
859 *
860 * Example:
861 * @code
862 * To check the clock lost lock status of OSC0 and PLL0.
863 * uint32_t mcgFlags;
864 *
865 * mcgFlags = CLOCK_GetStatusFlags();
866 *
867 * if (mcgFlags & kMCG_Osc0LostFlag)
868 * {
869 * OSC0 clock lock lost. Do something.
870 * }
871 * if (mcgFlags & kMCG_Pll0LostFlag)
872 * {
873 * PLL0 clock lock lost. Do something.
874 * }
875 * @endcode
876 *
877 * @return Logical OR value of the enumeration _mcg_status_flags_t.
878 */
879 uint32_t CLOCK_GetStatusFlags(void);
880
881 /*!
882 * @brief Clears the MCG status flags.
883 *
884 * This function clears the MCG clock lock lost status. The parameter is a logical
885 * OR value of the flags to clear. See the enumeration _mcg_status_flags_t.
886 *
887 * Example:
888 * @code
889 * To clear the clock lost lock status flags of OSC0 and PLL0.
890 *
891 * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
892 * @endcode
893 *
894 * @param mask The status flags to clear. This is a logical OR of members of the
895 * enumeration _mcg_status_flags_t.
896 */
897 void CLOCK_ClearStatusFlags(uint32_t mask);
898
899 /*@}*/
900
901 /*!
902 * @name OSC configuration
903 * @{
904 */
905
906 /*!
907 * @brief Configures the OSC external reference clock (OSCERCLK).
908 *
909 * This function configures the OSC external reference clock (OSCERCLK).
910 * This is an example to enable the OSCERCLK in normal and stop modes and also set
911 * the output divider to 1:
912 *
913 @code
914 oscer_config_t config =
915 {
916 .enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop,
917 .erclkDiv = 1U,
918 };
919
920 OSC_SetExtRefClkConfig(OSC, &config);
921 @endcode
922 *
923 * @param base OSC peripheral address.
924 * @param config Pointer to the configuration structure.
925 */
OSC_SetExtRefClkConfig(OSC_Type * base,oscer_config_t const * config)926 static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config)
927 {
928 uint8_t reg = base->CR;
929
930 reg &= (uint8_t)(~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK));
931 reg |= config->enableMode;
932
933 base->CR = reg;
934
935 base->DIV = OSC_DIV_ERPS(config->erclkDiv);
936 }
937
938 /*!
939 * @brief Sets the capacitor load configuration for the oscillator.
940 *
941 * This function sets the specified capacitors configuration for the oscillator.
942 * This should be done in the early system level initialization function call
943 * based on the system configuration.
944 *
945 * @param base OSC peripheral address.
946 * @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load.
947 *
948 * Example:
949 @code
950 To enable only 2 pF and 8 pF capacitor load, please use like this.
951 OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
952 @endcode
953 */
OSC_SetCapLoad(OSC_Type * base,uint8_t capLoad)954 static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad)
955 {
956 uint8_t reg = base->CR;
957
958 reg &= (uint8_t)(~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK));
959 reg |= capLoad;
960
961 base->CR = reg;
962 }
963
964 /*!
965 * @brief Initializes the OSC0.
966 *
967 * This function initializes the OSC0 according to the board configuration.
968 *
969 * @param config Pointer to the OSC0 configuration structure.
970 */
971 void CLOCK_InitOsc0(osc_config_t const *config);
972
973 /*!
974 * @brief Deinitializes the OSC0.
975 *
976 * This function deinitializes the OSC0.
977 */
978 void CLOCK_DeinitOsc0(void);
979
980 /* @} */
981
982 /*!
983 * @name External clock frequency
984 * @{
985 */
986
987 /*!
988 * @brief Sets the XTAL0 frequency based on board settings.
989 *
990 * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
991 */
CLOCK_SetXtal0Freq(uint32_t freq)992 static inline void CLOCK_SetXtal0Freq(uint32_t freq)
993 {
994 g_xtal0Freq = freq;
995 }
996
997 /*!
998 * @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings.
999 *
1000 * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
1001 */
CLOCK_SetXtal32Freq(uint32_t freq)1002 static inline void CLOCK_SetXtal32Freq(uint32_t freq)
1003 {
1004 g_xtal32Freq = freq;
1005 }
1006 /* @} */
1007
1008 /*!
1009 * @name IRCs frequency
1010 * @{
1011 */
1012
1013 /*!
1014 * @brief Set the Slow IRC frequency based on the trimmed value
1015 *
1016 * @param freq The Slow IRC frequency input clock frequency in Hz.
1017 */
1018 void CLOCK_SetSlowIrcFreq(uint32_t freq);
1019
1020 /*!
1021 * @brief Set the Fast IRC frequency based on the trimmed value
1022 *
1023 * @param freq The Fast IRC frequency input clock frequency in Hz.
1024 */
1025 void CLOCK_SetFastIrcFreq(uint32_t freq);
1026 /* @} */
1027
1028 /*!
1029 * @name MCG auto-trim machine.
1030 * @{
1031 */
1032
1033 /*!
1034 * @brief Auto trims the internal reference clock.
1035 *
1036 * This function trims the internal reference clock by using the external clock. If
1037 * successful, it returns the kStatus_Success and the frequency after
1038 * trimming is received in the parameter @p actualFreq. If an error occurs,
1039 * the error code is returned.
1040 *
1041 * @param extFreq External clock frequency, which should be a bus clock.
1042 * @param desireFreq Frequency to trim to.
1043 * @param actualFreq Actual frequency after trimming.
1044 * @param atms Trim fast or slow internal reference clock.
1045 * @retval kStatus_Success ATM success.
1046 * @retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM.
1047 * @retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency.
1048 * @retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source.
1049 * @retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming.
1050 */
1051 status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms);
1052 /* @} */
1053
1054 /*! @name MCG mode functions. */
1055 /*@{*/
1056
1057 /*!
1058 * @brief Gets the current MCG mode.
1059 *
1060 * This function checks the MCG registers and determines the current MCG mode.
1061 *
1062 * @return Current MCG mode or error code; See @ref mcg_mode_t.
1063 */
1064 mcg_mode_t CLOCK_GetMode(void);
1065
1066 /*!
1067 * @brief Sets the MCG to FEI mode.
1068 *
1069 * This function sets the MCG to FEI mode. If setting to FEI mode fails
1070 * from the current mode, this function returns an error.
1071 *
1072 * @param dmx32 DMX32 in FEI mode.
1073 * @param drs The DCO range selection.
1074 * @param fllStableDelay Delay function to ensure that the FLL is stable. Passing
1075 * NULL does not cause a delay.
1076 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1077 * @retval kStatus_Success Switched to the target mode successfully.
1078 * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1079 * to a frequency above 32768 Hz.
1080 */
1081 status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1082
1083 /*!
1084 * @brief Sets the MCG to FEE mode.
1085 *
1086 * This function sets the MCG to FEE mode. If setting to FEE mode fails
1087 * from the current mode, this function returns an error.
1088 *
1089 * @param frdiv FLL reference clock divider setting, FRDIV.
1090 * @param dmx32 DMX32 in FEE mode.
1091 * @param drs The DCO range selection.
1092 * @param fllStableDelay Delay function to make sure FLL is stable. Passing
1093 * NULL does not cause a delay.
1094 *
1095 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1096 * @retval kStatus_Success Switched to the target mode successfully.
1097 */
1098 status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1099
1100 /*!
1101 * @brief Sets the MCG to FBI mode.
1102 *
1103 * This function sets the MCG to FBI mode. If setting to FBI mode fails
1104 * from the current mode, this function returns an error.
1105 *
1106 * @param dmx32 DMX32 in FBI mode.
1107 * @param drs The DCO range selection.
1108 * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL
1109 * is not used in FBI mode, this parameter can be NULL. Passing
1110 * NULL does not cause a delay.
1111 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1112 * @retval kStatus_Success Switched to the target mode successfully.
1113 * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1114 * to frequency above 32768 Hz.
1115 */
1116 status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1117
1118 /*!
1119 * @brief Sets the MCG to FBE mode.
1120 *
1121 * This function sets the MCG to FBE mode. If setting to FBE mode fails
1122 * from the current mode, this function returns an error.
1123 *
1124 * @param frdiv FLL reference clock divider setting, FRDIV.
1125 * @param dmx32 DMX32 in FBE mode.
1126 * @param drs The DCO range selection.
1127 * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL
1128 * is not used in FBE mode, this parameter can be NULL. Passing NULL
1129 * does not cause a delay.
1130 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1131 * @retval kStatus_Success Switched to the target mode successfully.
1132 */
1133 status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1134
1135 /*!
1136 * @brief Sets the MCG to BLPI mode.
1137 *
1138 * This function sets the MCG to BLPI mode. If setting to BLPI mode fails
1139 * from the current mode, this function returns an error.
1140 *
1141 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1142 * @retval kStatus_Success Switched to the target mode successfully.
1143 */
1144 status_t CLOCK_SetBlpiMode(void);
1145
1146 /*!
1147 * @brief Sets the MCG to BLPE mode.
1148 *
1149 * This function sets the MCG to BLPE mode. If setting to BLPE mode fails
1150 * from the current mode, this function returns an error.
1151 *
1152 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1153 * @retval kStatus_Success Switched to the target mode successfully.
1154 */
1155 status_t CLOCK_SetBlpeMode(void);
1156
1157 /*!
1158 * @brief Switches the MCG to FBE mode from the external mode.
1159 *
1160 * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
1161 * The external clock is used as the system clock source and PLL is disabled. However,
1162 * the FLL settings are not configured. This is a lite function with a small code size, which is useful
1163 * during the mode switch. For example, to switch from PEE mode to FEI mode:
1164 *
1165 * @code
1166 * CLOCK_ExternalModeToFbeModeQuick();
1167 * CLOCK_SetFeiMode(...);
1168 * @endcode
1169 *
1170 * @retval kStatus_Success Switched successfully.
1171 * @retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function.
1172 */
1173 status_t CLOCK_ExternalModeToFbeModeQuick(void);
1174
1175 /*!
1176 * @brief Switches the MCG to FBI mode from internal modes.
1177 *
1178 * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
1179 * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
1180 * FLL settings are not configured. This is a lite function with a small code size, which is useful
1181 * during the mode switch. For example, to switch from PEI mode to FEE mode:
1182 *
1183 * @code
1184 * CLOCK_InternalModeToFbiModeQuick();
1185 * CLOCK_SetFeeMode(...);
1186 * @endcode
1187 *
1188 * @retval kStatus_Success Switched successfully.
1189 * @retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function.
1190 */
1191 status_t CLOCK_InternalModeToFbiModeQuick(void);
1192
1193 /*!
1194 * @brief Sets the MCG to FEI mode during system boot up.
1195 *
1196 * This function sets the MCG to FEI mode from the reset mode. It can also be used to
1197 * set up MCG during system boot up.
1198 *
1199 * @param dmx32 DMX32 in FEI mode.
1200 * @param drs The DCO range selection.
1201 * @param fllStableDelay Delay function to ensure that the FLL is stable.
1202 *
1203 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1204 * @retval kStatus_Success Switched to the target mode successfully.
1205 * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1206 * to frequency above 32768 Hz.
1207 */
1208 status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1209
1210 /*!
1211 * @brief Sets the MCG to FEE mode during system bootup.
1212 *
1213 * This function sets MCG to FEE mode from the reset mode. It can also be used to
1214 * set up the MCG during system boot up.
1215 *
1216 * @param oscsel OSC clock select, OSCSEL.
1217 * @param frdiv FLL reference clock divider setting, FRDIV.
1218 * @param dmx32 DMX32 in FEE mode.
1219 * @param drs The DCO range selection.
1220 * @param fllStableDelay Delay function to ensure that the FLL is stable.
1221 *
1222 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1223 * @retval kStatus_Success Switched to the target mode successfully.
1224 */
1225 status_t CLOCK_BootToFeeMode(
1226 mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1227
1228 /*!
1229 * @brief Sets the MCG to BLPI mode during system boot up.
1230 *
1231 * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
1232 * set up the MCG during system boot up.
1233 *
1234 * @param fcrdiv Fast IRC divider, FCRDIV.
1235 * @param ircs The internal reference clock to select, IRCS.
1236 * @param ircEnableMode The MCGIRCLK enable mode, OR'ed value of the enumeration _mcg_irclk_enable_mode.
1237 *
1238 * @retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting.
1239 * @retval kStatus_Success Switched to the target mode successfully.
1240 */
1241 status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
1242
1243 /*!
1244 * @brief Sets the MCG to BLPE mode during system boot up.
1245 *
1246 * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
1247 * set up the MCG during system boot up.
1248 *
1249 * @param oscsel OSC clock select, MCG_C7[OSCSEL].
1250 *
1251 * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1252 * @retval kStatus_Success Switched to the target mode successfully.
1253 */
1254 status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel);
1255
1256 /*!
1257 * @brief Sets the MCG to a target mode.
1258 *
1259 * This function sets MCG to a target mode defined by the configuration
1260 * structure. If switching to the target mode fails, this function
1261 * chooses the correct path.
1262 *
1263 * @param config Pointer to the target MCG mode configuration structure.
1264 * @return Return kStatus_Success if switched successfully; Otherwise, it returns an error code _mcg_status.
1265 *
1266 * @note If the external clock is used in the target mode, ensure that it is
1267 * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this
1268 * function.
1269 */
1270 status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
1271
1272 /*@}*/
1273
1274 #if defined(__cplusplus)
1275 }
1276 #endif /* __cplusplus */
1277
1278 /*! @} */
1279
1280 #endif /* _FSL_CLOCK_H_ */
1281