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