1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016 - 2021, 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.0.0. */
44 #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
45 /*@}*/
46 
47 /*! @brief External XTAL0 (OSC0/SYSOSC) clock frequency.
48  *
49  * The XTAL0/EXTAL0 (OSC0/SYSOSC) 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_InitSysOsc(...);
54  * CLOCK_SetXtal0Freq(80000000);
55  * @endcode
56  *
57  * This is important for the multicore platforms where only one core needs to set up the
58  * OSC0/SYSOSC using CLOCK_InitSysOsc. 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 #ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
64 #define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (72000000UL)
65 #endif
66 
67 /*! @brief Clock ip name array for DMAMUX. */
68 #define DMAMUX_CLOCKS  \
69     {                  \
70         kCLOCK_Dmamux0 \
71     }
72 
73 /*! @brief Clock ip name array for PORT. */
74 #define PORT_CLOCKS                                                          \
75     {                                                                        \
76         kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \
77     }
78 
79 /*! @brief Clock ip name array for LPI2C. */
80 #define LPI2C_CLOCKS  \
81     {                 \
82         kCLOCK_Lpi2c0 \
83     }
84 
85 /*! @brief Clock ip name array for FLEXIO. */
86 #define FLEXIO_CLOCKS  \
87     {                  \
88         kCLOCK_Flexio0 \
89     }
90 
91 /*! @brief Clock ip name array for TSI. */
92 #define TSI_CLOCKS  \
93     {               \
94         kCLOCK_Tsi0 \
95     }
96 
97 /*! @brief Clock ip name array for EDMA. */
98 #define EDMA_CLOCKS \
99     {               \
100         kCLOCK_Dma0 \
101     }
102 
103 /*! @brief Clock ip name array for LPUART. */
104 #define LPUART_CLOCKS                                  \
105     {                                                  \
106         kCLOCK_Lpuart0, kCLOCK_Lpuart1, kCLOCK_Lpuart2 \
107     }
108 
109 /*! @brief Clock ip name array for LPTMR. */
110 #define LPTMR_CLOCKS  \
111     {                 \
112         kCLOCK_Lptmr0 \
113     }
114 
115 /*! @brief Clock ip name array for ADC12. */
116 #define ADC12_CLOCKS \
117     {                \
118         kCLOCK_Adc0  \
119     }
120 
121 /*! @brief Clock ip name array for LPSPI. */
122 #define LPSPI_CLOCKS  \
123     {                 \
124         kCLOCK_Lpspi0 \
125     }
126 
127 /*! @brief Clock ip name array for LPIT. */
128 #define LPIT_CLOCKS  \
129     {                \
130         kCLOCK_Lpit0 \
131     }
132 
133 /*! @brief Clock ip name array for CRC. */
134 #define CRC_CLOCKS  \
135     {               \
136         kCLOCK_Crc0 \
137     }
138 
139 /*! @brief Clock ip name array for CMP. */
140 #define CMP_CLOCKS  \
141     {               \
142         kCLOCK_Cmp0 \
143     }
144 
145 /*! @brief Clock ip name array for FLASH. */
146 #define FLASH_CLOCKS  \
147     {                 \
148         kCLOCK_Flash0 \
149     }
150 
151 /*! @brief Clock ip name array for EWM. */
152 #define EWM_CLOCKS  \
153     {               \
154         kCLOCK_Ewm0 \
155     }
156 
157 /*! @brief Clock ip name array for FLEXTMR. */
158 #define FTM_CLOCKS                            \
159     {                                         \
160         kCLOCK_Ftm0, kCLOCK_Ftm1, kCLOCK_Ftm2 \
161     }
162 
163 /*! @brief Clock ip name array for PWT. */
164 #define PWT_CLOCKS  \
165     {               \
166         kCLOCK_Pwt0 \
167     }
168 
169 /*! @brief Clock ip name array for FLEXIO_TRIG0/1 Aync clock. */
170 #define FLEXIOTRIG_CLOCKS                      \
171     {                                          \
172         kCLOCK_FlexioTrig0, kCLOCK_FlexioTrig1 \
173     }
174 
175 /*!
176  * @brief LPO clock frequency.
177  */
178 #define LPO_CLK_FREQ 128000U
179 
180 /*! @brief Clock name used to get clock frequency. */
181 typedef enum _clock_name
182 {
183     /* ----------------------------- System layer clock -------------------------------*/
184     kCLOCK_CoreSysClk, /*!< Core/system clock                                   */
185     kCLOCK_BusClk,     /*!< Bus clock                                           */
186     kCLOCK_FlashClk,   /*!< Flash clock                                         */
187 
188     /* ------------------------------------ SCG clock ---------------------------------*/
189     kCLOCK_ScgSysOscClk, /*!< SCG system OSC clock. (SYSOSC)                      */
190     kCLOCK_ScgSircClk,   /*!< SCG SIRC clock.                                     */
191     kCLOCK_ScgFircClk,   /*!< SCG FIRC clock.                                     */
192     kCLOCK_ScgLpFllClk,  /*!< SCG low power FLL clock. (LPFLL)                    */
193 
194     kCLOCK_ScgSysOscAsyncDiv2Clk, /*!< SOSCDIV2_CLK.                                   */
195 
196     kCLOCK_ScgSircAsyncDiv2Clk, /*!< SIRCDIV2_CLK.                                   */
197 
198     kCLOCK_ScgFircAsyncDiv2Clk, /*!< FIRCDIV2_CLK.                                   */
199 
200     kCLOCK_ScgLpFllAsyncDiv2Clk, /*!< LPFLLDIV2_CLK.                                   */
201 
202     /* --------------------------------- Other clock ----------------------------------*/
203     kCLOCK_LpoClk, /*!< LPO clock                                           */
204     kCLOCK_ErClk,  /*!< ERCLK. The external reference clock from SCG.       */
205 } clock_name_t;
206 
207 #define kCLOCK_Osc0ErClk       kCLOCK_ErClk
208 #define CLOCK_GetOsc0ErClkFreq CLOCK_GetErClkFreq /*!< For compatible with other MCG platforms. */
209 
210 /*!
211  * @brief Clock source for peripherals that support various clock selections.
212  */
213 typedef enum _clock_ip_src
214 {
215     kCLOCK_IpSrcNoneOrExt   = 0U, /*!< Clock is off or external clock is used. */
216     kCLOCK_IpSrcSysOscAsync = 1U, /*!< System Oscillator async clock.          */
217     kCLOCK_IpSrcSircAsync   = 2U, /*!< Slow IRC async clock.                   */
218     kCLOCK_IpSrcFircAsync   = 3U, /*!< Fast IRC async clock.                   */
219     kCLOCK_IpSrcLpFllAsync  = 5U  /*!< LPFLL async clock.                      */
220 } clock_ip_src_t;
221 
222 /*!
223  * @brief Peripheral clock name difinition used for clock gate, clock source
224  * and clock divider setting. It is defined as the corresponding register address.
225  */
226 typedef enum _clock_ip_name
227 {
228     kCLOCK_IpInvalid = 0U,
229 
230     /* PCC 0 */
231     kCLOCK_Dma0        = 0x40065020U,
232     kCLOCK_Flash0      = 0x40065080U,
233     kCLOCK_Dmamux0     = 0x40065084U,
234     kCLOCK_Lpspi0      = 0x400650B0U,
235     kCLOCK_Crc0        = 0x400650C8U,
236     kCLOCK_Lpit0       = 0x400650DCU,
237     kCLOCK_Ftm0        = 0x400650E0U,
238     kCLOCK_Ftm1        = 0x400650E4U,
239     kCLOCK_Ftm2        = 0x400650E8U,
240     kCLOCK_Adc0        = 0x400650ECU,
241     kCLOCK_Lptmr0      = 0x40065100U,
242     kCLOCK_Tsi0        = 0x40065114U,
243     kCLOCK_PortA       = 0x40065124U,
244     kCLOCK_PortB       = 0x40065128U,
245     kCLOCK_PortC       = 0x4006512CU,
246     kCLOCK_PortD       = 0x40065130U,
247     kCLOCK_PortE       = 0x40065134U,
248     kCLOCK_Pwt0        = 0x40065158U,
249     kCLOCK_Flexio0     = 0x40065168U,
250     kCLOCK_RtcOsc0     = 0x40065180U,
251     kCLOCK_Ewm0        = 0x40065184U,
252     kCLOCK_FlexioTrig0 = 0x40065188U,
253     kCLOCK_FlexioTrig1 = 0x4006518CU,
254     kCLOCK_Lpi2c0      = 0x40065198U,
255     kCLOCK_Lpuart0     = 0x400651A8U,
256     kCLOCK_Lpuart1     = 0x400651ACU,
257     kCLOCK_Lpuart2     = 0x400651B0U,
258     kCLOCK_Cmp0        = 0x400651CCU,
259 } clock_ip_name_t;
260 
261 /*!
262  * @brief SCG status return codes.
263  */
264 enum
265 {
266     kStatus_SCG_Busy       = MAKE_STATUS(kStatusGroup_SCG, 1), /*!< Clock is busy.  */
267     kStatus_SCG_InvalidSrc = MAKE_STATUS(kStatusGroup_SCG, 2)  /*!< Invalid source. */
268 };
269 
270 /*!
271  * @brief SCG system clock type.
272  */
273 typedef enum _scg_sys_clk
274 {
275     kSCG_SysClkSlow, /*!< System slow clock. */
276     kSCG_SysClkCore, /*!< Core clock.        */
277 } scg_sys_clk_t;
278 
279 /*!
280  * @brief SCG system clock source.
281  */
282 typedef enum _scg_sys_clk_src
283 {
284     kSCG_SysClkSrcSysOsc = 1U, /*!< System OSC. */
285     kSCG_SysClkSrcSirc   = 2U, /*!< Slow IRC.   */
286     kSCG_SysClkSrcFirc   = 3U, /*!< Fast IRC.   */
287     kSCG_SysClkSrcLpFll  = 5U, /*!< Low power FLL. */
288 } scg_sys_clk_src_t;
289 
290 /*!
291  * @brief SCG system clock divider value.
292  */
293 typedef enum _scg_sys_clk_div
294 {
295     kSCG_SysClkDivBy1  = 0U,  /*!< Divided by 1.  */
296     kSCG_SysClkDivBy2  = 1U,  /*!< Divided by 2.  */
297     kSCG_SysClkDivBy3  = 2U,  /*!< Divided by 3.  */
298     kSCG_SysClkDivBy4  = 3U,  /*!< Divided by 4.  */
299     kSCG_SysClkDivBy5  = 4U,  /*!< Divided by 5.  */
300     kSCG_SysClkDivBy6  = 5U,  /*!< Divided by 6.  */
301     kSCG_SysClkDivBy7  = 6U,  /*!< Divided by 7.  */
302     kSCG_SysClkDivBy8  = 7U,  /*!< Divided by 8.  */
303     kSCG_SysClkDivBy9  = 8U,  /*!< Divided by 9.  */
304     kSCG_SysClkDivBy10 = 9U,  /*!< Divided by 10. */
305     kSCG_SysClkDivBy11 = 10U, /*!< Divided by 11. */
306     kSCG_SysClkDivBy12 = 11U, /*!< Divided by 12. */
307     kSCG_SysClkDivBy13 = 12U, /*!< Divided by 13. */
308     kSCG_SysClkDivBy14 = 13U, /*!< Divided by 14. */
309     kSCG_SysClkDivBy15 = 14U, /*!< Divided by 15. */
310     kSCG_SysClkDivBy16 = 15U  /*!< Divided by 16. */
311 } scg_sys_clk_div_t;
312 
313 /*!
314  * @brief SCG system clock configuration.
315  */
316 typedef struct _scg_sys_clk_config
317 {
318     uint32_t divSlow : 4; /*!< Slow clock divider, see @ref scg_sys_clk_div_t. */
319     uint32_t : 4;         /*!< Reserved. */
320     uint32_t : 4;         /*!< Reserved. */
321     uint32_t : 4;         /*!< Reserved. */
322     uint32_t divCore : 4; /*!< Core clock divider, see @ref scg_sys_clk_div_t. */
323     uint32_t : 4;         /*!< Reserved. */
324     uint32_t src : 4;     /*!< System clock source, see @ref scg_sys_clk_src_t. */
325     uint32_t : 4;         /*!< reserved. */
326 } scg_sys_clk_config_t;
327 
328 /*!
329  * @brief SCG clock out configuration (CLKOUTSEL).
330  */
331 typedef enum _clock_clkout_src
332 {
333     kClockClkoutSelScgSlow = 0U, /*!< SCG slow clock. */
334     kClockClkoutSelSysOsc  = 1U, /*!< System OSC.     */
335     kClockClkoutSelSirc    = 2U, /*!< Slow IRC.       */
336     kClockClkoutSelFirc    = 3U, /*!< Fast IRC.       */
337     kClockClkoutSelLpFll   = 5U, /*!< Low power FLL.  */
338 } clock_clkout_src_t;
339 
340 /*!
341  * @brief SCG asynchronous clock type.
342  */
343 typedef enum _scg_async_clk
344 {
345     kSCG_AsyncDiv2Clk, /*!< The async clock by DIV2, e.g. SOSCDIV2_CLK, SIRCDIV2_CLK. */
346 } scg_async_clk_t;
347 
348 /*!
349  * @brief SCG asynchronous clock divider value.
350  */
351 typedef enum scg_async_clk_div
352 {
353     kSCG_AsyncClkDisable = 0U, /*!< Clock output is disabled.  */
354     kSCG_AsyncClkDivBy1  = 1U, /*!< Divided by 1.              */
355     kSCG_AsyncClkDivBy2  = 2U, /*!< Divided by 2.              */
356     kSCG_AsyncClkDivBy4  = 3U, /*!< Divided by 4.              */
357     kSCG_AsyncClkDivBy8  = 4U, /*!< Divided by 8.              */
358     kSCG_AsyncClkDivBy16 = 5U, /*!< Divided by 16.             */
359     kSCG_AsyncClkDivBy32 = 6U, /*!< Divided by 32.             */
360     kSCG_AsyncClkDivBy64 = 7U  /*!< Divided by 64.             */
361 } scg_async_clk_div_t;
362 
363 /*!
364  * @brief SCG system OSC monitor mode.
365  */
366 typedef enum _scg_sosc_monitor_mode
367 {
368     kSCG_SysOscMonitorDisable = 0U,                      /*!< Monitor disabled.                          */
369     kSCG_SysOscMonitorInt     = SCG_SOSCCSR_SOSCCM_MASK, /*!< Interrupt when the system OSC error is detected. */
370     kSCG_SysOscMonitorReset =
371         SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK /*!< Reset when the system OSC error is detected.     */
372 } scg_sosc_monitor_mode_t;
373 
374 /*! @brief OSC work mode. */
375 typedef enum _scg_sosc_mode
376 {
377     kSCG_SysOscModeExt         = 0U,                                           /*!< Use external clock.   */
378     kSCG_SysOscModeOscLowPower = SCG_SOSCCFG_EREFS_MASK,                       /*!< Oscillator low power. */
379     kSCG_SysOscModeOscHighGain = SCG_SOSCCFG_EREFS_MASK | SCG_SOSCCFG_HGO_MASK /*!< Oscillator high gain. */
380 } scg_sosc_mode_t;
381 
382 /*! @brief OSC enable mode. */
383 enum
384 {
385     kSCG_SysOscEnable           = SCG_SOSCCSR_SOSCEN_MASK,     /*!< Enable OSC clock. */
386     kSCG_SysOscEnableInStop     = SCG_SOSCCSR_SOSCSTEN_MASK,   /*!< Enable OSC in stop mode. */
387     kSCG_SysOscEnableInLowPower = SCG_SOSCCSR_SOSCLPEN_MASK,   /*!< Enable OSC in low power mode. */
388     kSCG_SysOscEnableErClk      = SCG_SOSCCSR_SOSCERCLKEN_MASK /*!< Enable OSCERCLK. */
389 };
390 
391 /*!
392  * @brief SCG system OSC configuration.
393  */
394 typedef struct _scg_sosc_config
395 {
396     uint32_t freq;                       /*!< System OSC frequency.                    */
397     scg_sosc_monitor_mode_t monitorMode; /*!< Clock monitor mode selected.     */
398     uint8_t enableMode;                  /*!< Enable mode, OR'ed value of _scg_sosc_enable_mode.  */
399 
400     scg_async_clk_div_t div2; /*!< SOSCDIV2 value.                          */
401 
402     scg_sosc_mode_t workMode; /*!< OSC work mode.                           */
403 } scg_sosc_config_t;
404 
405 /*!
406  * @brief SCG slow IRC clock frequency range.
407  */
408 typedef enum _scg_sirc_range
409 {
410     kSCG_SircRangeLow, /*!< Slow IRC low range clock (2 MHz, 4 MHz for i.MX 7 ULP).  */
411     kSCG_SircRangeHigh /*!< Slow IRC high range clock (8 MHz, 16 MHz for i.MX 7 ULP). */
412 } scg_sirc_range_t;
413 
414 /*! @brief SIRC enable mode. */
415 enum
416 {
417     kSCG_SircEnable           = SCG_SIRCCSR_SIRCEN_MASK,   /*!< Enable SIRC clock.             */
418     kSCG_SircEnableInStop     = SCG_SIRCCSR_SIRCSTEN_MASK, /*!< Enable SIRC in stop mode.      */
419     kSCG_SircEnableInLowPower = SCG_SIRCCSR_SIRCLPEN_MASK  /*!< Enable SIRC in low power mode. */
420 };
421 
422 /*!
423  * @brief SCG slow IRC clock configuration.
424  */
425 typedef struct _scg_sirc_config
426 {
427     uint32_t enableMode;      /*!< Enable mode, OR'ed value of _scg_sirc_enable_mode. */
428     scg_async_clk_div_t div2; /*!< SIRCDIV2 value.                          */
429 
430     scg_sirc_range_t range; /*!< Slow IRC frequency range.                */
431 } scg_sirc_config_t;
432 
433 /*!
434  * @brief SCG fast IRC trim mode.
435  */
436 typedef enum _scg_firc_trim_mode
437 {
438     kSCG_FircTrimNonUpdate = SCG_FIRCCSR_FIRCTREN_MASK,
439     /*!< FIRC trim enable but not enable trim value update. In this mode, the
440      trim value is fixed to the initialized value which is defined by
441      trimCoar and trimFine in configure structure \ref scg_firc_trim_config_t.*/
442 
443     kSCG_FircTrimUpdate = SCG_FIRCCSR_FIRCTREN_MASK | SCG_FIRCCSR_FIRCTRUP_MASK
444     /*!< FIRC trim enable and trim value update enable. In this mode, the trim
445      value is auto update. */
446 
447 } scg_firc_trim_mode_t;
448 
449 /*!
450  * @brief SCG fast IRC trim predivided value for system OSC.
451  */
452 typedef enum _scg_firc_trim_div
453 {
454     kSCG_FircTrimDivBy1,    /*!< Divided by 1.    */
455     kSCG_FircTrimDivBy128,  /*!< Divided by 128.  */
456     kSCG_FircTrimDivBy256,  /*!< Divided by 256.  */
457     kSCG_FircTrimDivBy512,  /*!< Divided by 512.  */
458     kSCG_FircTrimDivBy1024, /*!< Divided by 1024. */
459     kSCG_FircTrimDivBy2048  /*!< Divided by 2048. */
460 } scg_firc_trim_div_t;
461 
462 /*!
463  * @brief SCG fast IRC trim source.
464  */
465 typedef enum _scg_firc_trim_src
466 {
467     kSCG_FircTrimSrcSysOsc = 2U, /*!< System OSC.                 */
468 } scg_firc_trim_src_t;
469 
470 /*!
471  * @brief SCG fast IRC clock trim configuration.
472  */
473 typedef struct _scg_firc_trim_config
474 {
475     scg_firc_trim_mode_t trimMode; /*!< FIRC trim mode.                       */
476     scg_firc_trim_src_t trimSrc;   /*!< Trim source.                          */
477     scg_firc_trim_div_t trimDiv;   /*!< Trim predivided value for the system OSC.  */
478 
479     uint8_t trimCoar; /*!< Trim coarse value; Irrelevant if trimMode is kSCG_FircTrimUpdate. */
480     uint8_t trimFine; /*!< Trim fine value; Irrelevant if trimMode is kSCG_FircTrimUpdate. */
481 } scg_firc_trim_config_t;
482 
483 /*!
484  * @brief SCG fast IRC clock frequency range.
485  */
486 typedef enum _scg_firc_range
487 {
488     kSCG_FircRange48M, /*!< Fast IRC is trimmed to 48 MHz.  */
489 } scg_firc_range_t;
490 
491 /*! @brief FIRC enable mode. */
492 enum
493 {
494     kSCG_FircEnable           = SCG_FIRCCSR_FIRCEN_MASK,    /*!< Enable FIRC clock.             */
495     kSCG_FircEnableInStop     = SCG_FIRCCSR_FIRCSTEN_MASK,  /*!< Enable FIRC in stop mode.      */
496     kSCG_FircEnableInLowPower = SCG_FIRCCSR_FIRCLPEN_MASK,  /*!< Enable FIRC in low power mode. */
497     kSCG_FircDisableRegulator = SCG_FIRCCSR_FIRCREGOFF_MASK /*!< Disable regulator.             */
498 };
499 
500 /*!
501  * @brief SCG fast IRC clock configuration.
502  */
503 typedef struct _scg_firc_config_t
504 {
505     uint32_t enableMode; /*!< Enable mode, OR'ed value of _scg_firc_enable_mode. */
506 
507     scg_async_clk_div_t div2; /*!< FIRCDIV2 value.                          */
508 
509     scg_firc_range_t range; /*!< Fast IRC frequency range.                 */
510 
511     const scg_firc_trim_config_t *trimConfig; /*!< Pointer to the FIRC trim configuration; set NULL to disable trim. */
512 } scg_firc_config_t;
513 
514 /*! @brief LPFLL enable mode. */
515 enum
516 {
517     kSCG_LpFllEnable = SCG_LPFLLCSR_LPFLLEN_MASK, /*!< Enable LPFLL clock.             */
518 };
519 
520 /*!
521  * @brief SCG LPFLL clock frequency range.
522  */
523 typedef enum _scg_lpfll_range
524 {
525     kSCG_LpFllRange48M = 0U, /*!< LPFLL is trimmed to 48MHz.  */
526     kSCG_LpFllRange72M = 1U, /*!< LPFLL is trimmed to 72MHz.  */
527 } scg_lpfll_range_t;
528 
529 /*!
530  * @brief SCG LPFLL trim mode.
531  */
532 typedef enum _scg_lpfll_trim_mode
533 {
534     kSCG_LpFllTrimNonUpdate = SCG_LPFLLCSR_LPFLLTREN_MASK,
535     /*!< LPFLL trim is enabled but the trim value update is not enabled. In this mode, the
536      trim value is fixed to the initialized value, which is defined by the Member variable trimValue
537      in the structure @ref scg_lpfll_trim_config_t.*/
538 
539     kSCG_LpFllTrimUpdate = SCG_LPFLLCSR_LPFLLTREN_MASK | SCG_LPFLLCSR_LPFLLTRUP_MASK
540     /*!< FIRC trim is enabled and trim value update is enabled. In this mode, the trim
541      value is automatically updated. */
542 } scg_lpfll_trim_mode_t;
543 
544 /*!
545  * @brief SCG LPFLL trim source.
546  */
547 typedef enum _scg_lpfll_trim_src
548 {
549     kSCG_LpFllTrimSrcSirc   = 0U, /*!< SIRC.                 */
550     kSCG_LpFllTrimSrcFirc   = 1U, /*!< FIRC.                 */
551     kSCG_LpFllTrimSrcSysOsc = 2U, /*!< System OSC.           */
552     kSCG_LpFllTrimSrcRtcOsc = 3U, /*!< RTC OSC (32.768 kHz). */
553 } scg_lpfll_trim_src_t;
554 
555 /*!
556  * @brief SCG LPFLL lock mode.
557  */
558 typedef enum _scg_lpfll_lock_mode
559 {
560     kSCG_LpFllLock1Lsb = 0U, /*!< Lock with 1 LSB. */
561     kSCG_LpFllLock2Lsb = 1U  /*!< Lock with 2 LSB. */
562 } scg_lpfll_lock_mode_t;
563 
564 /*!
565  * @brief SCG LPFLL clock trim configuration.
566  */
567 typedef struct _scg_lpfll_trim_config
568 {
569     scg_lpfll_trim_mode_t trimMode; /*!< Trim mode.            */
570     scg_lpfll_lock_mode_t lockMode; /*!< Lock mode; Irrelevant if the trimMode is kSCG_LpFllTrimNonUpdate. */
571 
572     scg_lpfll_trim_src_t trimSrc; /*!< Trim source.          */
573     uint8_t trimDiv;              /*!< Trim predivideds value, which can be 0 ~ 31.
574                                     [ Trim source frequency / (trimDiv + 1) ] must be 2 MHz or 32768 Hz. */
575 
576     uint8_t trimValue; /*!< Trim value; Irrelevant if trimMode is the kSCG_LpFllTrimUpdate. */
577 } scg_lpfll_trim_config_t;
578 
579 /*!
580  * @brief SCG low power FLL configuration.
581  */
582 typedef struct _scg_lpfll_config
583 {
584     uint8_t enableMode; /*!< Enable mode, OR'ed value of _scg_lpfll_enable_mode */
585 
586     scg_async_clk_div_t div2; /*!< LPFLLDIV2 value.                          */
587 
588     scg_lpfll_range_t range; /*!< LPFLL frequency range.                     */
589 
590     const scg_lpfll_trim_config_t *trimConfig; /*!< Trim configuration; set NULL to disable trim. */
591 } scg_lpfll_config_t;
592 
593 /*******************************************************************************
594  * API
595  ******************************************************************************/
596 
597 #if defined(__cplusplus)
598 extern "C" {
599 #endif /* __cplusplus */
600 
601 /*!
602  * @brief Enable the clock for specific IP.
603  *
604  * @param name  Which clock to enable, see \ref clock_ip_name_t.
605  */
CLOCK_EnableClock(clock_ip_name_t name)606 static inline void CLOCK_EnableClock(clock_ip_name_t name)
607 {
608     assert((*(volatile uint32_t *)((uint32_t)name)) & PCC_CLKCFG_PR_MASK);
609 
610     (*(volatile uint32_t *)((uint32_t)name)) |= PCC_CLKCFG_CGC_MASK;
611 }
612 
613 /*!
614  * @brief Disable the clock for specific IP.
615  *
616  * @param name  Which clock to disable, see \ref clock_ip_name_t.
617  */
CLOCK_DisableClock(clock_ip_name_t name)618 static inline void CLOCK_DisableClock(clock_ip_name_t name)
619 {
620     assert((*(volatile uint32_t *)((uint32_t)name)) & PCC_CLKCFG_PR_MASK);
621 
622     (*(volatile uint32_t *)((uint32_t)name)) &= ~PCC_CLKCFG_CGC_MASK;
623 }
624 
625 /*!
626  * @brief Set the clock source for specific IP module.
627  *
628  * Set the clock source for specific IP, not all modules need to set the
629  * clock source, should only use this function for the modules need source
630  * setting.
631  *
632  * @param name Which peripheral to check, see \ref clock_ip_name_t.
633  * @param src Clock source to set.
634  */
CLOCK_SetIpSrc(clock_ip_name_t name,clock_ip_src_t src)635 static inline void CLOCK_SetIpSrc(clock_ip_name_t name, clock_ip_src_t src)
636 {
637     uint32_t reg = (*(volatile uint32_t *)((uint32_t)name));
638 
639     assert(reg & PCC_CLKCFG_PR_MASK);
640 
641     reg = (reg & ~PCC_CLKCFG_PCS_MASK) | PCC_CLKCFG_PCS(src);
642 
643     /*
644      * If clock is already enabled, first disable it, then set the clock
645      * source and re-enable it.
646      */
647     (*(volatile uint32_t *)((uint32_t)name)) = reg & ~PCC_CLKCFG_CGC_MASK;
648     (*(volatile uint32_t *)((uint32_t)name)) = reg;
649 }
650 
651 /*!
652  * @brief Set the clock source and divider for specific IP module.
653  *
654  * Set the clock source and divider for specific IP, not all modules need to
655  * set the clock source and divider, should only use this function for the
656  * modules need source and divider setting.
657  *
658  * Divider output clock = Divider input clock x [(fracValue+1)/(divValue+1)]).
659  *
660  * @param name Which peripheral to check, see \ref clock_ip_name_t.
661  * @param src Clock source to set.
662  * @param divValue  The divider value.
663  * @param fracValue The fraction multiply value.
664  */
CLOCK_SetIpSrcDiv(clock_ip_name_t name,clock_ip_src_t src,uint16_t divValue,uint8_t fracValue)665 static inline void CLOCK_SetIpSrcDiv(clock_ip_name_t name, clock_ip_src_t src, uint16_t divValue, uint8_t fracValue)
666 {
667     uint32_t reg = (*(volatile uint32_t *)(uint32_t)name);
668 
669     assert((reg & PCC_CLKCFG_PR_MASK) != 0UL);
670 
671     reg = (reg & ~(PCC_CLKCFG_PCS_MASK | PCC_CLKCFG_FRAC_MASK | PCC_CLKCFG_PCD_MASK)) | PCC_CLKCFG_PCS(src) |
672           PCC_CLKCFG_PCD(divValue) | PCC_CLKCFG_FRAC(fracValue);
673 
674     /*
675      * If clock is already enabled, first disable it, then set the clock
676      * source and re-enable it.
677      */
678     (*(volatile uint32_t *)(uint32_t)name) = reg & ~PCC_CLKCFG_CGC_MASK;
679     (*(volatile uint32_t *)(uint32_t)name) = reg;
680 }
681 
682 /*!
683  * @brief Gets the clock frequency for a specific clock name.
684  *
685  * This function checks the current clock configurations and then calculates
686  * the clock frequency for a specific clock name defined in clock_name_t.
687  *
688  * @param clockName Clock names defined in clock_name_t
689  * @return Clock frequency value in hertz
690  */
691 uint32_t CLOCK_GetFreq(clock_name_t clockName);
692 
693 /*!
694  * @brief Get the core clock or system clock frequency.
695  *
696  * @return Clock frequency in Hz.
697  */
698 uint32_t CLOCK_GetCoreSysClkFreq(void);
699 
700 /*!
701  * @brief Get the bus clock frequency.
702  *
703  * @return Clock frequency in Hz.
704  */
705 uint32_t CLOCK_GetBusClkFreq(void);
706 
707 /*!
708  * @brief Get the flash clock frequency.
709  *
710  * @return Clock frequency in Hz.
711  */
712 uint32_t CLOCK_GetFlashClkFreq(void);
713 
714 /*!
715  * @brief Get the external reference clock frequency (ERCLK).
716  *
717  * @return Clock frequency in Hz.
718  */
719 uint32_t CLOCK_GetErClkFreq(void);
720 
721 /*!
722  * @brief Gets the clock frequency for a specific IP module.
723  *
724  * This function gets the IP module clock frequency based on PCC registers. It is
725  * only used for the IP modules which could select clock source by PCC[PCS].
726  *
727  * @param name Which peripheral to get, see \ref clock_ip_name_t.
728  * @return Clock frequency value in hertz
729  */
730 uint32_t CLOCK_GetIpFreq(clock_ip_name_t name);
731 
732 /*!
733  * @name MCU System Clock.
734  * @{
735  */
736 
737 /*!
738  * @brief Gets the SCG system clock frequency.
739  *
740  * This function gets the SCG system clock frequency. These clocks are used for
741  * core, platform, external, and bus clock domains.
742  *
743  * @param type     Which type of clock to get, core clock or slow clock.
744  * @return  Clock frequency.
745  */
746 uint32_t CLOCK_GetSysClkFreq(scg_sys_clk_t type);
747 
748 /*!
749  * @brief Sets the system clock configuration for VLPR mode.
750  *
751  * This function sets the system clock configuration for VLPR mode.
752  *
753  * @param config Pointer to the configuration.
754  */
CLOCK_SetVlprModeSysClkConfig(const scg_sys_clk_config_t * config)755 static inline void CLOCK_SetVlprModeSysClkConfig(const scg_sys_clk_config_t *config)
756 {
757     assert(config);
758     union
759     {
760         const uint32_t *configInt;
761         const scg_sys_clk_config_t *configPtr;
762     } Config;
763 
764     Config.configPtr = config;
765     SCG->VCCR        = *(Config.configInt);
766 }
767 
768 /*!
769  * @brief Sets the system clock configuration for RUN mode.
770  *
771  * This function sets the system clock configuration for RUN mode.
772  *
773  * @param config Pointer to the configuration.
774  */
CLOCK_SetRunModeSysClkConfig(const scg_sys_clk_config_t * config)775 static inline void CLOCK_SetRunModeSysClkConfig(const scg_sys_clk_config_t *config)
776 {
777     assert(config);
778     union
779     {
780         const uint32_t *configInt;
781         const scg_sys_clk_config_t *configPtr;
782     } Config;
783 
784     Config.configPtr = config;
785     SCG->RCCR        = *(Config.configInt);
786 }
787 
788 /*!
789  * @brief Gets the system clock configuration in the current power mode.
790  *
791  * This function gets the system configuration in the current power mode.
792  *
793  * @param config Pointer to the configuration.
794  */
CLOCK_GetCurSysClkConfig(scg_sys_clk_config_t * config)795 static inline void CLOCK_GetCurSysClkConfig(scg_sys_clk_config_t *config)
796 {
797     assert(config);
798     union
799     {
800         uint32_t *configInt;
801         scg_sys_clk_config_t *configPtr;
802     } Config;
803 
804     Config.configPtr    = config;
805     *(Config.configInt) = SCG->CSR;
806 }
807 
808 /*!
809  * @brief Sets the clock out selection.
810  *
811  * This function sets the clock out selection (CLKOUTSEL).
812  *
813  * @param setting The selection to set.
814  * @return  The current clock out selection.
815  */
CLOCK_SetClkOutSel(clock_clkout_src_t setting)816 static inline void CLOCK_SetClkOutSel(clock_clkout_src_t setting)
817 {
818     SCG->CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting);
819 }
820 /* @} */
821 
822 /*!
823  * @name SCG System OSC Clock.
824  * @{
825  */
826 
827 /*!
828  * @brief Initializes the SCG system OSC.
829  *
830  * This function enables the SCG system OSC clock according to the
831  * configuration.
832  *
833  * @param config   Pointer to the configuration structure.
834  * @retval kStatus_Success System OSC is initialized.
835  * @retval kStatus_SCG_Busy System OSC has been enabled and is used by the system clock.
836  * @retval kStatus_ReadOnly System OSC control register is locked.
837  *
838  * @note This function can't detect whether the system OSC has been enabled and
839  * used by an IP.
840  */
841 status_t CLOCK_InitSysOsc(const scg_sosc_config_t *config);
842 
843 /*!
844  * @brief De-initializes the SCG system OSC.
845  *
846  * This function disables the SCG system OSC clock.
847  *
848  * @retval kStatus_Success System OSC is deinitialized.
849  * @retval kStatus_SCG_Busy System OSC is used by the system clock.
850  * @retval kStatus_ReadOnly System OSC control register is locked.
851  *
852  * @note This function can't detect whether the system OSC is used by an IP.
853  */
854 status_t CLOCK_DeinitSysOsc(void);
855 
856 /*!
857  * @brief Set the asynchronous clock divider.
858  *
859  * @param asyncClk Which asynchronous clock to configure.
860  * @param divider The divider value to set.
861  *
862  * @note There might be glitch when changing the asynchronous divider, so make sure
863  * the asynchronous clock is not used while changing divider.
864  */
CLOCK_SetSysOscAsyncClkDiv(scg_async_clk_t asyncClk,scg_async_clk_div_t divider)865 static inline void CLOCK_SetSysOscAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
866 {
867     uint32_t reg = SCG->SOSCDIV;
868 
869     switch (asyncClk)
870     {
871         case kSCG_AsyncDiv2Clk:
872             reg = (reg & ~SCG_SOSCDIV_SOSCDIV2_MASK) | SCG_SOSCDIV_SOSCDIV2(divider);
873             break;
874         default:
875             /* All the cases have been listed above, the default clause should not be reached. */
876             assert(false);
877             break;
878     }
879 
880     SCG->SOSCDIV = reg;
881 }
882 
883 /*!
884  * @brief Gets the SCG system OSC clock frequency (SYSOSC).
885  *
886  * @return  Clock frequency; If the clock is invalid, returns 0.
887  */
888 uint32_t CLOCK_GetSysOscFreq(void);
889 
890 /*!
891  * @brief Gets the SCG asynchronous clock frequency from the system OSC.
892  *
893  * @param type     The asynchronous clock type.
894  * @return  Clock frequency; If the clock is invalid, returns 0.
895  */
896 uint32_t CLOCK_GetSysOscAsyncFreq(scg_async_clk_t type);
897 
898 /*!
899  * @brief Checks whether the system OSC clock error occurs.
900  *
901  * @return  True if the error occurs, false if not.
902  */
CLOCK_IsSysOscErr(void)903 static inline bool CLOCK_IsSysOscErr(void)
904 {
905     return (bool)(SCG->SOSCCSR & SCG_SOSCCSR_SOSCERR_MASK);
906 }
907 
908 /*!
909  * @brief Clears the system OSC clock error.
910  */
CLOCK_ClearSysOscErr(void)911 static inline void CLOCK_ClearSysOscErr(void)
912 {
913     SCG->SOSCCSR |= SCG_SOSCCSR_SOSCERR_MASK;
914 }
915 
916 /*!
917  * @brief Sets the system OSC monitor mode.
918  *
919  * This function sets the system OSC monitor mode. The mode can be disabled,
920  * it can generate an interrupt when the error is disabled, or reset when the error is detected.
921  *
922  * @param mode Monitor mode to set.
923  */
CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode)924 static inline void CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode)
925 {
926     uint32_t reg = SCG->SOSCCSR;
927 
928     reg &= ~(SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK);
929 
930     reg |= (uint32_t)mode;
931 
932     SCG->SOSCCSR = reg;
933 }
934 
935 /*!
936  * @brief Checks whether the system OSC clock is valid.
937  *
938  * @return  True if clock is valid, false if not.
939  */
CLOCK_IsSysOscValid(void)940 static inline bool CLOCK_IsSysOscValid(void)
941 {
942     return (bool)(SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK);
943 }
944 /* @} */
945 
946 /*!
947  * @name SCG Slow IRC Clock.
948  * @{
949  */
950 
951 /*!
952  * @brief Initializes the SCG slow IRC clock.
953  *
954  * This function enables the SCG slow IRC clock according to the
955  * configuration.
956  *
957  * @param config   Pointer to the configuration structure.
958  * @retval kStatus_Success SIRC is initialized.
959  * @retval kStatus_SCG_Busy SIRC has been enabled and is used by system clock.
960  * @retval kStatus_ReadOnly SIRC control register is locked.
961  *
962  * @note This function can't detect whether the system OSC has been enabled and
963  * used by an IP.
964  */
965 status_t CLOCK_InitSirc(const scg_sirc_config_t *config);
966 
967 /*!
968  * @brief De-initializes the SCG slow IRC.
969  *
970  * This function disables the SCG slow IRC.
971  *
972  * @retval kStatus_Success SIRC is deinitialized.
973  * @retval kStatus_SCG_Busy SIRC is used by system clock.
974  * @retval kStatus_ReadOnly SIRC control register is locked.
975  *
976  * @note This function can't detect whether the SIRC is used by an IP.
977  */
978 status_t CLOCK_DeinitSirc(void);
979 
980 /*!
981  * @brief Set the asynchronous clock divider.
982  *
983  * @param asyncClk Which asynchronous clock to configure.
984  * @param divider The divider value to set.
985  *
986  * @note There might be glitch when changing the asynchronous divider, so make sure
987  * the asynchronous clock is not used while changing divider.
988  */
CLOCK_SetSircAsyncClkDiv(scg_async_clk_t asyncClk,scg_async_clk_div_t divider)989 static inline void CLOCK_SetSircAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
990 {
991     uint32_t reg = SCG->SIRCDIV;
992 
993     switch (asyncClk)
994     {
995         case kSCG_AsyncDiv2Clk:
996             reg = (reg & ~SCG_SIRCDIV_SIRCDIV2_MASK) | SCG_SIRCDIV_SIRCDIV2(divider);
997             break;
998         default:
999             /* All the cases have been listed above, the default clause should not be reached. */
1000             assert(false);
1001             break;
1002     }
1003 
1004     SCG->SIRCDIV = reg;
1005 }
1006 
1007 /*!
1008  * @brief Gets the SCG SIRC clock frequency.
1009  *
1010  * @return  Clock frequency; If the clock is invalid, returns 0.
1011  */
1012 uint32_t CLOCK_GetSircFreq(void);
1013 
1014 /*!
1015  * @brief Gets the SCG asynchronous clock frequency from the SIRC.
1016  *
1017  * @param type     The asynchronous clock type.
1018  * @return  Clock frequency; If the clock is invalid, returns 0.
1019  */
1020 uint32_t CLOCK_GetSircAsyncFreq(scg_async_clk_t type);
1021 
1022 /*!
1023  * @brief Checks whether the SIRC clock is valid.
1024  *
1025  * @return  True if clock is valid, false if not.
1026  */
CLOCK_IsSircValid(void)1027 static inline bool CLOCK_IsSircValid(void)
1028 {
1029     return (bool)(SCG->SIRCCSR & SCG_SIRCCSR_SIRCVLD_MASK);
1030 }
1031 /* @} */
1032 
1033 /*!
1034  * @name SCG Fast IRC Clock.
1035  * @{
1036  */
1037 
1038 /*!
1039  * @brief Initializes the SCG fast IRC clock.
1040  *
1041  * This function enables the SCG fast IRC clock according to the configuration.
1042  *
1043  * @param config   Pointer to the configuration structure.
1044  * @retval kStatus_Success FIRC is initialized.
1045  * @retval kStatus_SCG_Busy FIRC has been enabled and is used by the system clock.
1046  * @retval kStatus_ReadOnly FIRC control register is locked.
1047  *
1048  * @note This function can't detect whether the FIRC has been enabled and
1049  * used by an IP.
1050  */
1051 status_t CLOCK_InitFirc(const scg_firc_config_t *config);
1052 
1053 /*!
1054  * @brief De-initializes the SCG fast IRC.
1055  *
1056  * This function disables the SCG fast IRC.
1057  *
1058  * @retval kStatus_Success FIRC is deinitialized.
1059  * @retval kStatus_SCG_Busy FIRC is used by the system clock.
1060  * @retval kStatus_ReadOnly FIRC control register is locked.
1061  *
1062  * @note This function can't detect whether the FIRC is used by an IP.
1063  */
1064 status_t CLOCK_DeinitFirc(void);
1065 
1066 /*!
1067  * @brief Set the asynchronous clock divider.
1068  *
1069  * @param asyncClk Which asynchronous clock to configure.
1070  * @param divider The divider value to set.
1071  *
1072  * @note There might be glitch when changing the asynchronous divider, so make sure
1073  * the asynchronous clock is not used while changing divider.
1074  */
CLOCK_SetFircAsyncClkDiv(scg_async_clk_t asyncClk,scg_async_clk_div_t divider)1075 static inline void CLOCK_SetFircAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
1076 {
1077     uint32_t reg = SCG->FIRCDIV;
1078 
1079     switch (asyncClk)
1080     {
1081         case kSCG_AsyncDiv2Clk:
1082             reg = (reg & ~SCG_FIRCDIV_FIRCDIV2_MASK) | SCG_FIRCDIV_FIRCDIV2(divider);
1083             break;
1084         default:
1085             /* All the cases have been listed above, the default clause should not be reached. */
1086             assert(false);
1087             break;
1088     }
1089 
1090     SCG->FIRCDIV = reg;
1091 }
1092 
1093 /*!
1094  * @brief Gets the SCG FIRC clock frequency.
1095  *
1096  * @return  Clock frequency; If the clock is invalid, returns 0.
1097  */
1098 uint32_t CLOCK_GetFircFreq(void);
1099 
1100 /*!
1101  * @brief Gets the SCG asynchronous clock frequency from the FIRC.
1102  *
1103  * @param type     The asynchronous clock type.
1104  * @return  Clock frequency; If the clock is invalid, returns 0.
1105  */
1106 uint32_t CLOCK_GetFircAsyncFreq(scg_async_clk_t type);
1107 
1108 /*!
1109  * @brief Checks whether the FIRC clock is valid.
1110  *
1111  * @return  True if clock is valid, false if not.
1112  */
CLOCK_IsFircValid(void)1113 static inline bool CLOCK_IsFircValid(void)
1114 {
1115     return (bool)(SCG->FIRCCSR & SCG_FIRCCSR_FIRCVLD_MASK);
1116 }
1117 /* @} */
1118 
1119 /*!
1120  * @name SCG Low Power FLL Clock.
1121  * @{
1122  */
1123 /*!
1124  * @brief Initializes the SCG LPFLL clock.
1125  *
1126  * This function enables the SCG LPFLL clock according to the configuration.
1127  *
1128  * @param config   Pointer to the configuration structure.
1129  * @retval kStatus_Success LPFLL is initialized.
1130  * @retval kStatus_SCG_Busy LPFLL has been enabled and is used by the system clock.
1131  * @retval kStatus_ReadOnly LPFLL control register is locked.
1132  *
1133  * @note This function can't detect whether the LPFLL has been enabled and
1134  * used by an IP.
1135  */
1136 status_t CLOCK_InitLpFll(const scg_lpfll_config_t *config);
1137 
1138 /*!
1139  * @brief De-initializes the SCG LPFLL.
1140  *
1141  * This function disables the SCG LPFLL.
1142  *
1143  * @retval kStatus_Success LPFLL is deinitialized.
1144  * @retval kStatus_SCG_Busy LPFLL is used by the system clock.
1145  * @retval kStatus_ReadOnly LPFLL control register is locked.
1146  *
1147  * @note This function can't detect whether the LPFLL is used by an IP.
1148  */
1149 status_t CLOCK_DeinitLpFll(void);
1150 
1151 /*!
1152  * @brief Set the asynchronous clock divider.
1153  *
1154  * @param asyncClk Which asynchronous clock to configure.
1155  * @param divider The divider value to set.
1156  *
1157  * @note There might be glitch when changing the asynchronous divider, so make sure
1158  * the asynchronous clock is not used while changing divider.
1159  */
CLOCK_SetLpFllAsyncClkDiv(scg_async_clk_t asyncClk,scg_async_clk_div_t divider)1160 static inline void CLOCK_SetLpFllAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
1161 {
1162     uint32_t reg = SCG->LPFLLDIV;
1163 
1164     switch (asyncClk)
1165     {
1166         case kSCG_AsyncDiv2Clk:
1167             reg = (reg & ~SCG_LPFLLDIV_LPFLLDIV2_MASK) | SCG_LPFLLDIV_LPFLLDIV2(divider);
1168             break;
1169         default:
1170             /* All the cases have been listed above, the default clause should not be reached. */
1171             assert(false);
1172             break;
1173     }
1174 
1175     SCG->LPFLLDIV = reg;
1176 }
1177 
1178 /*!
1179  * @brief Gets the SCG LPFLL clock frequency.
1180  *
1181  * @return  Clock frequency in Hz; If the clock is invalid, returns 0.
1182  */
1183 uint32_t CLOCK_GetLpFllFreq(void);
1184 
1185 /*!
1186  * @brief Gets the SCG asynchronous clock frequency from the LPFLL.
1187  *
1188  * @param type     The asynchronous clock type.
1189  * @return  Clock frequency in Hz; If the clock is invalid, returns 0.
1190  */
1191 uint32_t CLOCK_GetLpFllAsyncFreq(scg_async_clk_t type);
1192 
1193 /*!
1194  * @brief Checks whether the LPFLL clock is valid.
1195  *
1196  * @return  True if the clock is valid, false if not.
1197  */
CLOCK_IsLpFllValid(void)1198 static inline bool CLOCK_IsLpFllValid(void)
1199 {
1200     return (bool)(SCG->LPFLLCSR & SCG_LPFLLCSR_LPFLLVLD_MASK);
1201 }
1202 /* @} */
1203 
1204 /*!
1205  * @name External clock frequency
1206  * @{
1207  */
1208 
1209 /*!
1210  * @brief Sets the XTAL0 frequency based on board settings.
1211  *
1212  * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
1213  */
CLOCK_SetXtal0Freq(uint32_t freq)1214 static inline void CLOCK_SetXtal0Freq(uint32_t freq)
1215 {
1216     g_xtal0Freq = freq;
1217 }
1218 
1219 /* @} */
1220 
1221 #if defined(__cplusplus)
1222 }
1223 #endif /* __cplusplus */
1224 
1225 /*! @} */
1226 
1227 #endif /* _FSL_CLOCK_H_ */
1228