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