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