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