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