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