1 /*
2 * Copyright 2024 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #ifndef _FSL_CLOCK_H_
9 #define _FSL_CLOCK_H_
10
11 #include "fsl_common.h"
12
13 /*! @addtogroup clock */
14 /*! @{ */
15
16 /*! @file */
17
18 /*******************************************************************************
19 * Configurations
20 ******************************************************************************/
21
22 /*! @brief Configure whether driver controls clock
23 *
24 * When set to 0, peripheral drivers will enable clock in initialize function
25 * and disable clock in de-initialize function. When set to 1, peripheral
26 * driver will not control the clock, application could control the clock out of
27 * the driver.
28 *
29 * @note All drivers share this feature switcher. If it is set to 1, application
30 * should handle clock enable and disable for all drivers.
31 */
32 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
33 #define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
34 #endif
35
36 /*******************************************************************************
37 * Definitions
38 ******************************************************************************/
39
40 /*! @name Driver version */
41 /*@{*/
42 /*! @brief CLOCK driver version 2.0.0. */
43 #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
44 /*@}*/
45
46 /*! @brief External XTAL0 (OSC0) clock frequency.
47 *
48 * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
49 * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
50 * if XTAL0 is 8 MHz:
51 * @code
52 * CLOCK_InitOsc0(...);
53 * CLOCK_SetXtal0Freq(80000000);
54 * @endcode
55 *
56 * This is important for the multicore platforms where one core needs to set up the
57 * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
58 * to get a valid clock frequency.
59 */
60 extern volatile uint32_t g_xtal0Freq;
61
62 /*! @brief The external XTAL32/EXTAL32/RTC_CLKIN clock frequency.
63 *
64 * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the
65 * function CLOCK_SetXtal32Freq to set the value in the clock driver.
66 *
67 * This is important for the multicore platforms where one core needs to set up
68 * the clock. All other cores need to call the CLOCK_SetXtal32Freq
69 * to get a valid clock frequency.
70 */
71 extern volatile uint32_t g_xtal32Freq;
72
73 /* Definition for delay API in clock driver, users can redefine it to the real application. */
74 #ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
75 #define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (48000000UL)
76 #endif
77 /*! @brief Clock ip name array for DMAMUX. */
78 #define DMAMUX_CLOCKS \
79 { \
80 kCLOCK_Dmamux0 \
81 }
82
83 /*! @brief Clock ip name array for RTC. */
84 #define RTC_CLOCKS \
85 { \
86 kCLOCK_Rtc0 \
87 }
88
89 /*! @brief Clock ip name array for SAI. */
90 #define SAI_CLOCKS \
91 { \
92 kCLOCK_Sai0 \
93 }
94
95 /*! @brief Clock ip name array for SPI. */
96 #define SPI_CLOCKS \
97 { \
98 kCLOCK_Spi0, kCLOCK_Spi1 \
99 }
100
101 /*! @brief Clock ip name array for SLCD. */
102 #define SLCD_CLOCKS \
103 { \
104 kCLOCK_Slcd0 \
105 }
106
107 /*! @brief Clock ip name array for PIT. */
108 #define PIT_CLOCKS \
109 { \
110 kCLOCK_Pit0 \
111 }
112
113 /*! @brief Clock ip name array for PORT. */
114 #define PORT_CLOCKS \
115 { \
116 kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \
117 }
118
119 /*! @brief Clock ip name array for LPUART. */
120 #define LPUART_CLOCKS \
121 { \
122 kCLOCK_Lpuart0, kCLOCK_Lpuart1 \
123 }
124
125 /*! @brief Clock ip name array for DAC. */
126 #define DAC_CLOCKS \
127 { \
128 kCLOCK_Dac0 \
129 }
130
131 /*! @brief Clock ip name array for LPTMR. */
132 #define LPTMR_CLOCKS \
133 { \
134 kCLOCK_Lptmr0 \
135 }
136
137 /*! @brief Clock ip name array for ADC16. */
138 #define ADC16_CLOCKS \
139 { \
140 kCLOCK_Adc0 \
141 }
142
143 /*! @brief Clock ip name array for FLEXIO. */
144 #define FLEXIO_CLOCKS \
145 { \
146 kCLOCK_Flexio0 \
147 }
148
149 /*! @brief Clock ip name array for VREF. */
150 #define VREF_CLOCKS \
151 { \
152 kCLOCK_Vref0 \
153 }
154
155 /*! @brief Clock ip name array for DMA. */
156 #define DMA_CLOCKS \
157 { \
158 kCLOCK_Dma0 \
159 }
160
161 /*! @brief Clock ip name array for UART. */
162 #define UART_CLOCKS \
163 { \
164 kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_Uart2 \
165 }
166
167 /*! @brief Clock ip name array for TPM. */
168 #define TPM_CLOCKS \
169 { \
170 kCLOCK_Tpm0, kCLOCK_Tpm1, kCLOCK_Tpm2 \
171 }
172
173 /*! @brief Clock ip name array for I2C. */
174 #define I2C_CLOCKS \
175 { \
176 kCLOCK_I2c0, kCLOCK_I2c1 \
177 }
178
179 /*! @brief Clock ip name array for FTF. */
180 #define FTF_CLOCKS \
181 { \
182 kCLOCK_Ftf0 \
183 }
184
185 /*! @brief Clock ip name array for CMP. */
186 #define CMP_CLOCKS \
187 { \
188 kCLOCK_Cmp0 \
189 }
190
191 /*!
192 * @brief LPO clock frequency.
193 */
194 #define LPO_CLK_FREQ 1000U
195
196 /*! @brief Peripherals clock source definition. */
197 #define SYS_CLK kCLOCK_CoreSysClk
198 #define BUS_CLK kCLOCK_BusClk
199
200 #define I2C0_CLK_SRC SYS_CLK
201 #define I2C1_CLK_SRC SYS_CLK
202 #define SPI0_CLK_SRC BUS_CLK
203 #define SPI1_CLK_SRC SYS_CLK
204 #define UART2_CLK_SRC BUS_CLK
205
206 /*! @brief Clock name used to get clock frequency. */
207 typedef enum _clock_name
208 {
209
210 /* ----------------------------- System layer clock -------------------------------*/
211 kCLOCK_CoreSysClk, /*!< Core/system clock */
212 kCLOCK_PlatClk, /*!< Platform clock */
213 kCLOCK_BusClk, /*!< Bus clock */
214 kCLOCK_FlexBusClk, /*!< FlexBus clock */
215 kCLOCK_FlashClk, /*!< Flash clock */
216 kCLOCK_FastPeriphClk, /*!< Fast peripheral clock */
217 kCLOCK_PllFllSelClk, /*!< The clock after SIM[PLLFLLSEL]. */
218
219 /* ---------------------------------- OSC clock -----------------------------------*/
220 kCLOCK_Er32kClk, /*!< External reference 32K clock (ERCLK32K) */
221 kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */
222 kCLOCK_Osc1ErClk, /*!< OSC1 external reference clock (OSC1ERCLK) */
223 kCLOCK_Osc0ErClkUndiv, /*!< OSC0 external reference undivided clock(OSC0ERCLK_UNDIV). */
224
225 /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/
226 kCLOCK_McgFixedFreqClk, /*!< MCG fixed frequency clock (MCGFFCLK) */
227 kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */
228 kCLOCK_McgFllClk, /*!< MCGFLLCLK */
229 kCLOCK_McgPll0Clk, /*!< MCGPLL0CLK */
230 kCLOCK_McgPll1Clk, /*!< MCGPLL1CLK */
231 kCLOCK_McgExtPllClk, /*!< EXT_PLLCLK */
232 kCLOCK_McgPeriphClk, /*!< MCG peripheral clock (MCGPCLK) */
233 kCLOCK_McgIrc48MClk, /*!< MCG IRC48M clock */
234
235 /* --------------------------------- Other clock ----------------------------------*/
236 kCLOCK_LpoClk, /*!< LPO clock */
237
238 } clock_name_t;
239
240 /*! @brief USB clock source definition. */
241 typedef enum _clock_usb_src
242 {
243 kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U), /*!< Use IRC48M. */
244 kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
245 } clock_usb_src_t;
246 /*------------------------------------------------------------------------------
247
248 clock_gate_t definition:
249
250 31 16 0
251 -----------------------------------------------------------------
252 | SIM_SCGC register offset | control bit offset in SCGC |
253 -----------------------------------------------------------------
254
255 For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the
256 SIM_SCGC3 offset in SIM is 0x1030, then kCLOCK_GateSdhc0 is defined as
257
258 kCLOCK_GateSdhc0 = (0x1030 << 16) | 17;
259
260 ------------------------------------------------------------------------------*/
261
262 #define CLK_GATE_REG_OFFSET_SHIFT 16U
263 #define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U
264 #define CLK_GATE_BIT_SHIFT_SHIFT 0U
265 #define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU
266
267 #define CLK_GATE_DEFINE(reg_offset, bit_shift) \
268 ((((uint32_t)(reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
269 (((uint32_t)(bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
270
271 #define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
272 #define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
273
274 /*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
275 typedef enum _clock_ip_name
276 {
277 kCLOCK_IpInvalid = 0U,
278 kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
279 kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
280 kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
281 kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
282 kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
283 kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
284 kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U),
285 kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U),
286
287 kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
288 kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
289 kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
290 kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
291 kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
292 kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
293 kCLOCK_Slcd0 = CLK_GATE_DEFINE(0x1038U, 19U),
294 kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U),
295 kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U),
296 kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U),
297
298 kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
299 kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
300 kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U),
301 kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
302 kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U),
303 kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U),
304 kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U),
305 kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
306 kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
307 kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U),
308
309 kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U),
310 } clock_ip_name_t;
311
312 /*!@brief SIM configuration structure for clock setting. */
313 typedef struct _sim_clock_config
314 {
315 uint8_t er32kSrc; /*!< ERCLK32K source selection. */
316 uint32_t clkdiv1; /*!< SIM_CLKDIV1. */
317 } sim_clock_config_t;
318
319 /*! @brief Oscillator capacitor load setting.*/
320 enum _osc_cap_load
321 {
322 kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
323 kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
324 kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
325 kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
326 };
327
328 /*! @brief OSCERCLK enable mode. */
329 enum _oscer_enable_mode
330 {
331 kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
332 kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
333 };
334
335 /*! @brief The OSC configuration for OSCERCLK. */
336 typedef struct _oscer_config
337 {
338 uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of \ref _oscer_enable_mode. */
339
340 } oscer_config_t;
341
342 /*! @brief The OSC work mode. */
343 typedef enum _osc_mode
344 {
345 kOSC_ModeExt = 0U, /*!< Use external clock. */
346 kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */
347 kOSC_ModeOscHighGain = MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
348 } osc_mode_t;
349
350 /*!
351 * @brief OSC Initialization Configuration Structure
352 *
353 * Defines the configuration data structure to initialize the OSC.
354 * When porting to a new board, set the following members
355 * according to the board settings:
356 * 1. freq: The external frequency.
357 * 2. workMode: The OSC module mode.
358 */
359 typedef struct _osc_config
360 {
361 uint32_t freq; /*!< External clock frequency. */
362 uint8_t capLoad; /*!< Capacitor load setting. */
363 osc_mode_t workMode; /*!< OSC work mode setting. */
364 oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK. */
365 } osc_config_t;
366
367 /*! @brief MCG_Lite clock source selection. */
368 typedef enum _mcglite_clkout_src
369 {
370 kMCGLITE_ClkSrcHirc, /*!< MCGOUTCLK source is HIRC */
371 kMCGLITE_ClkSrcLirc, /*!< MCGOUTCLK source is LIRC */
372 kMCGLITE_ClkSrcExt, /*!< MCGOUTCLK source is external clock source */
373 kMCGLITE_ClkSrcReserved
374 } mcglite_clkout_src_t;
375
376 /*! @brief MCG_Lite LIRC select. */
377 typedef enum _mcglite_lirc_mode
378 {
379 kMCGLITE_Lirc2M, /*!< Slow internal reference(LIRC) 2 MHz clock selected */
380 kMCGLITE_Lirc8M, /*!< Slow internal reference(LIRC) 8 MHz clock selected */
381 } mcglite_lirc_mode_t;
382
383 /*! @brief MCG_Lite divider factor selection for clock source*/
384 typedef enum _mcglite_lirc_div
385 {
386 kMCGLITE_LircDivBy1 = 0U, /*!< Divider is 1 */
387 kMCGLITE_LircDivBy2, /*!< Divider is 2 */
388 kMCGLITE_LircDivBy4, /*!< Divider is 4 */
389 kMCGLITE_LircDivBy8, /*!< Divider is 8 */
390 kMCGLITE_LircDivBy16, /*!< Divider is 16 */
391 kMCGLITE_LircDivBy32, /*!< Divider is 32 */
392 kMCGLITE_LircDivBy64, /*!< Divider is 64 */
393 kMCGLITE_LircDivBy128 /*!< Divider is 128 */
394 } mcglite_lirc_div_t;
395
396 /*! @brief MCG_Lite clock mode definitions */
397 typedef enum _mcglite_mode
398 {
399 kMCGLITE_ModeHirc48M, /*!< Clock mode is HIRC 48 M */
400 kMCGLITE_ModeLirc8M, /*!< Clock mode is LIRC 8 M */
401 kMCGLITE_ModeLirc2M, /*!< Clock mode is LIRC 2 M */
402 kMCGLITE_ModeExt, /*!< Clock mode is EXT */
403 kMCGLITE_ModeError /*!< Unknown mode */
404 } mcglite_mode_t;
405
406 /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
407 enum _mcglite_irclk_enable_mode
408 {
409 kMCGLITE_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
410 kMCGLITE_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
411 };
412
413 /*! @brief MCG_Lite configure structure for mode change. */
414 typedef struct _mcglite_config
415 {
416 mcglite_clkout_src_t outSrc; /*!< MCGOUT clock select. */
417 uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode, OR'ed value of _mcglite_irclk_enable_mode. */
418 mcglite_lirc_mode_t ircs; /*!< MCG_C2[IRCS]. */
419 mcglite_lirc_div_t fcrdiv; /*!< MCG_SC[FCRDIV]. */
420 mcglite_lirc_div_t lircDiv2; /*!< MCG_MC[LIRC_DIV2]. */
421 bool hircEnableInNotHircMode; /*!< HIRC enable when not in HIRC mode. */
422 } mcglite_config_t;
423
424 /*******************************************************************************
425 * API
426 ******************************************************************************/
427
428 #if defined(__cplusplus)
429 extern "C" {
430 #endif /* __cplusplus */
431
432 /*!
433 * @brief Enable the clock for specific IP.
434 *
435 * @param name Which clock to enable, see \ref clock_ip_name_t.
436 */
CLOCK_EnableClock(clock_ip_name_t name)437 static inline void CLOCK_EnableClock(clock_ip_name_t name)
438 {
439 uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
440 (*(volatile uint32_t *)regAddr) |= (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
441 }
442
443 /*!
444 * @brief Disable the clock for specific IP.
445 *
446 * @param name Which clock to disable, see \ref clock_ip_name_t.
447 */
CLOCK_DisableClock(clock_ip_name_t name)448 static inline void CLOCK_DisableClock(clock_ip_name_t name)
449 {
450 uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
451 (*(volatile uint32_t *)regAddr) &= ~(1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
452 }
453
454 /*!
455 * @brief Set ERCLK32K source.
456 *
457 * @param src The value to set ERCLK32K clock source.
458 */
CLOCK_SetEr32kClock(uint32_t src)459 static inline void CLOCK_SetEr32kClock(uint32_t src)
460 {
461 SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src));
462 }
463
464 /*!
465 * @brief Set LPUART0 clock source.
466 *
467 * @param src The value to set LPUART0 clock source.
468 */
CLOCK_SetLpuart0Clock(uint32_t src)469 static inline void CLOCK_SetLpuart0Clock(uint32_t src)
470 {
471 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUART0SRC_MASK) | SIM_SOPT2_LPUART0SRC(src));
472 }
473
474 /*!
475 * @brief Set LPUART1 clock source.
476 *
477 * @param src The value to set LPUART1 clock source.
478 */
CLOCK_SetLpuart1Clock(uint32_t src)479 static inline void CLOCK_SetLpuart1Clock(uint32_t src)
480 {
481 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUART1SRC_MASK) | SIM_SOPT2_LPUART1SRC(src));
482 }
483
484 /*!
485 * @brief Set TPM clock source.
486 *
487 * @param src The value to set TPM clock source.
488 */
CLOCK_SetTpmClock(uint32_t src)489 static inline void CLOCK_SetTpmClock(uint32_t src)
490 {
491 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(src));
492 }
493
494 /*!
495 * @brief Set FLEXIO clock source.
496 *
497 * @param src The value to set FLEXIO clock source.
498 */
CLOCK_SetFlexio0Clock(uint32_t src)499 static inline void CLOCK_SetFlexio0Clock(uint32_t src)
500 {
501 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_FLEXIOSRC_MASK) | SIM_SOPT2_FLEXIOSRC(src));
502 }
503
504 #if defined(FSL_FEATURE_SOC_USB_COUNT) && FSL_FEATURE_SOC_USB_COUNT
505 /*! @brief Enable USB FS clock.
506 *
507 * @param src USB FS clock source.
508 * @param freq The frequency specified by src.
509 * @retval true The clock is set successfully.
510 * @retval false The clock source is invalid to get proper USB FS clock.
511 */
512 bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq);
513
514 /*! @brief Disable USB FS clock.
515 *
516 * Disable USB FS clock.
517 */
CLOCK_DisableUsbfs0Clock(void)518 static inline void CLOCK_DisableUsbfs0Clock(void)
519 {
520 CLOCK_DisableClock(kCLOCK_Usbfs0);
521 }
522 #endif
523
524 /*!
525 * @brief Set CLKOUT source.
526 *
527 * @param src The value to set CLKOUT source.
528 */
CLOCK_SetClkOutClock(uint32_t src)529 static inline void CLOCK_SetClkOutClock(uint32_t src)
530 {
531 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src));
532 }
533
534 /*!
535 * @brief Set RTC_CLKOUT source.
536 *
537 * @param src The value to set RTC_CLKOUT source.
538 */
CLOCK_SetRtcClkOutClock(uint32_t src)539 static inline void CLOCK_SetRtcClkOutClock(uint32_t src)
540 {
541 SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RTCCLKOUTSEL_MASK) | SIM_SOPT2_RTCCLKOUTSEL(src));
542 }
543
544 /*!
545 * @brief System clock divider
546 *
547 * Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV4].
548 *
549 * @param outdiv1 Clock 1 output divider value.
550 *
551 * @param outdiv4 Clock 4 output divider value.
552 */
CLOCK_SetOutDiv(uint32_t outdiv1,uint32_t outdiv4)553 static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv4)
554 {
555 SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV4(outdiv4);
556 }
557
558 /*!
559 * @brief Gets the clock frequency for a specific clock name.
560 *
561 * This function checks the current clock configurations and then calculates
562 * the clock frequency for a specific clock name defined in clock_name_t.
563 * The MCG must be properly configured before using this function.
564 *
565 * @param clockName Clock names defined in clock_name_t
566 * @return Clock frequency value in Hertz
567 */
568 uint32_t CLOCK_GetFreq(clock_name_t clockName);
569
570 /*!
571 * @brief Get the core clock or system clock frequency.
572 *
573 * @return Clock frequency in Hz.
574 */
575 uint32_t CLOCK_GetCoreSysClkFreq(void);
576
577 /*!
578 * @brief Get the platform clock frequency.
579 *
580 * @return Clock frequency in Hz.
581 */
582 uint32_t CLOCK_GetPlatClkFreq(void);
583
584 /*!
585 * @brief Get the bus clock frequency.
586 *
587 * @return Clock frequency in Hz.
588 */
589 uint32_t CLOCK_GetBusClkFreq(void);
590
591 /*!
592 * @brief Get the flash clock frequency.
593 *
594 * @return Clock frequency in Hz.
595 */
596 uint32_t CLOCK_GetFlashClkFreq(void);
597
598 /*!
599 * @brief Get the external reference 32K clock frequency (ERCLK32K).
600 *
601 * @return Clock frequency in Hz.
602 */
603 uint32_t CLOCK_GetEr32kClkFreq(void);
604
605 /*!
606 * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
607 *
608 * @return Clock frequency in Hz.
609 */
610 uint32_t CLOCK_GetOsc0ErClkFreq(void);
611
612 /*!
613 * @brief Set the clock configure in SIM module.
614 *
615 * This function sets system layer clock settings in SIM module.
616 *
617 * @param config Pointer to the configure structure.
618 */
619 void CLOCK_SetSimConfig(sim_clock_config_t const *config);
620
621 /*!
622 * @brief Set the system clock dividers in SIM to safe value.
623 *
624 * The system level clocks (core clock, bus clock, flexbus clock and flash clock)
625 * must be in allowed ranges. During MCG clock mode switch, the MCG output clock
626 * changes then the system level clocks may be out of range. This function could
627 * be used before MCG mode change, to make sure system level clocks are in allowed
628 * range.
629 */
CLOCK_SetSimSafeDivs(void)630 static inline void CLOCK_SetSimSafeDivs(void)
631 {
632 SIM->CLKDIV1 = 0x10030000U;
633 }
634
635 /*!
636 * @name MCG_Lite clock frequency
637 * @{
638 */
639
640 /*!
641 * @brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency.
642 *
643 * This function gets the MCG_Lite output clock frequency in Hz based on the current
644 * MCG_Lite register value.
645 *
646 * @return The frequency of MCGOUTCLK.
647 */
648 uint32_t CLOCK_GetOutClkFreq(void);
649
650 /*!
651 * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
652 *
653 * This function gets the MCG_Lite internal reference clock frequency in Hz based
654 * on the current MCG register value.
655 *
656 * @return The frequency of MCGIRCLK.
657 */
658 uint32_t CLOCK_GetInternalRefClkFreq(void);
659
660 /*!
661 * @brief Gets the current MCGPCLK frequency.
662 *
663 * This function gets the MCGPCLK frequency in Hz based on the current MCG_Lite
664 * register settings.
665 *
666 * @return The frequency of MCGPCLK.
667 */
668 uint32_t CLOCK_GetPeriphClkFreq(void);
669
670 /*! @}*/
671
672 /*!
673 * @name MCG_Lite mode.
674 * @{
675 */
676
677 /*!
678 * @brief Gets the current MCG_Lite mode.
679 *
680 * This function checks the MCG_Lite registers and determines the current MCG_Lite mode.
681 *
682 * @return The current MCG_Lite mode or error code.
683 */
684 mcglite_mode_t CLOCK_GetMode(void);
685
686 /*!
687 * @brief Sets the MCG_Lite configuration.
688 *
689 * This function configures the MCG_Lite, includes the output clock source, MCGIRCLK
690 * settings, HIRC settings, and so on. See @ref mcglite_config_t for details.
691 *
692 * @param targetConfig Pointer to the target MCG_Lite mode configuration structure.
693 * @return Error code.
694 */
695 status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig);
696
697 /*! @}*/
698
699 /*!
700 * @name OSC configuration
701 * @{
702 */
703
704 /*!
705 * @brief Configures the OSC external reference clock (OSCERCLK).
706 *
707 * This function configures the OSC external reference clock (OSCERCLK).
708 * This is an example to enable the OSCERCLK in normal mode and stop mode, and set
709 * the output divider to 1.
710 *
711 @code
712 oscer_config_t config =
713 {
714 .enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop,
715 .erclkDiv = 1U,
716 };
717
718 OSC_SetExtRefClkConfig(OSC, &config);
719 @endcode
720 *
721 * @param base OSC peripheral address.
722 * @param config Pointer to the configuration structure.
723 */
OSC_SetExtRefClkConfig(OSC_Type * base,oscer_config_t const * config)724 static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config)
725 {
726 uint8_t reg = base->CR;
727
728 reg &= (uint8_t)(~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK));
729 reg |= config->enableMode;
730
731 base->CR = reg;
732 }
733
734 /*!
735 * @brief Sets the capacitor load configuration for the oscillator.
736 *
737 * This function sets the specified capacitor configuration for the oscillator.
738 * This should be done in the early system level initialization function call
739 * based on the system configuration.
740 *
741 * @param base OSC peripheral address.
742 * @param capLoad OR'ed value for the capacitor load option.See \ref _osc_cap_load.
743 *
744 * Example:
745 @code
746 OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
747 @endcode
748 */
749
OSC_SetCapLoad(OSC_Type * base,uint8_t capLoad)750 static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad)
751 {
752 uint8_t reg = base->CR;
753
754 reg &= (uint8_t)(~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK));
755 reg |= capLoad;
756
757 base->CR = reg;
758 }
759
760 /*!
761 * @brief Initializes the OSC0.
762 *
763 * This function initializes the OSC0 according to the board configuration.
764 *
765 * @param config Pointer to the OSC0 configuration structure.
766 */
767 void CLOCK_InitOsc0(osc_config_t const *config);
768
769 /*!
770 * @brief Deinitializes the OSC0.
771 *
772 * This function deinitializes the OSC0.
773 */
774 void CLOCK_DeinitOsc0(void);
775
776 /*! @}*/
777
778 /*!
779 * @name External clock frequency
780 * @{
781 */
782
783 /*!
784 * @brief Sets the XTAL0 frequency based on board settings.
785 *
786 * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
787 */
CLOCK_SetXtal0Freq(uint32_t freq)788 static inline void CLOCK_SetXtal0Freq(uint32_t freq)
789 {
790 g_xtal0Freq = freq;
791 }
792
793 /*!
794 * @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings.
795 *
796 * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
797 */
CLOCK_SetXtal32Freq(uint32_t freq)798 static inline void CLOCK_SetXtal32Freq(uint32_t freq)
799 {
800 g_xtal32Freq = freq;
801 }
802 /* @} */
803
804 #if defined(__cplusplus)
805 }
806 #endif /* __cplusplus */
807
808 /*! @} */
809
810 #endif /* _FSL_CLOCK_H_ */
811