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