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