1 /*
2  * Copyright 2021-2022 NXP
3  *
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef _FSL_CLOCK_H_
9 #define _FSL_CLOCK_H_
10 
11 #include "fsl_common.h"
12 
13 /*! @addtogroup clock */
14 /*! @{ */
15 
16 /*! @file */
17 
18 /*******************************************************************************
19  * Configurations
20  ******************************************************************************/
21 
22 /*! @brief Configure whether driver controls clock
23  *
24  * When set to 0, peripheral drivers will enable clock in initialize function
25  * and disable clock in de-initialize function. When set to 1, peripheral
26  * driver will not control the clock, application could control the clock out of
27  * the driver.
28  *
29  * @note All drivers share this feature switcher. If it is set to 1, application
30  * should handle clock enable and disable for all drivers.
31  */
32 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
33 #define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
34 #endif
35 
36 /*******************************************************************************
37  * Definitions
38  ******************************************************************************/
39 
40 /*! @name Driver version */
41 /*@{*/
42 /*! @brief CLOCK driver version 2.2.2. */
43 #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 2))
44 /*@}*/
45 
46 /* Definition for delay API in clock driver, users can redefine it to the real application. */
47 #ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
48 #if defined(IS_RADIO_CORE) && (IS_RADIO_CORE == 1U)
49 #define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (32000000UL)
50 #else
51 #define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (96000000UL)
52 #endif
53 #endif
54 
55 /*! @brief External XTAL0 (OSC0/SYSOSC) clock frequency.
56  *
57  * The XTAL0/EXTAL0 (OSC0/SYSOSC) clock frequency in Hz. When the clock is set up, use the
58  * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
59  * if XTAL0 is 8 MHz:
60  * @code
61  * CLOCK_InitSysOsc(...);
62  * CLOCK_SetXtal0Freq(80000000);
63  * @endcode
64  *
65  * This is important for the multicore platforms where only one core needs to set up the
66  * OSC0/SYSOSC using CLOCK_InitSysOsc. All other cores need to call the CLOCK_SetXtal0Freq
67  * to get a valid clock frequency.
68  */
69 extern volatile uint32_t g_xtal0Freq;
70 
71 /*! @brief External XTAL32/EXTAL32 clock frequency.
72  *
73  * The XTAL32/EXTAL32 clock frequency in Hz. When the clock is set up, use the
74  * function CLOCK_SetXtal32Freq to set the value in the clock driver.
75  *
76  * This is important for the multicore platforms where only one core needs to set up
77  * the clock. All other cores need to call the CLOCK_SetXtal32Freq
78  * to get a valid clock frequency.
79  */
80 extern volatile uint32_t g_xtal32Freq;
81 
82 /*! @brief Clock ip name array for EDMA. */
83 #define EDMA_CLOCKS \
84     {               \
85         kCLOCK_Dma0 \
86     }
87 
88 /*! @brief Clock ip name array for SYSPM. */
89 #define SYSPM_CLOCKS  \
90     {                 \
91         kCLOCK_Syspm0 \
92     }
93 
94 /*! @brief Clock ip name array for SFA. */
95 #define SFA_CLOCKS                 \
96     {                              \
97         kCLOCK_Sfa0, kCLOCK_NOGATE \
98     }
99 
100 /*! @brief Clock ip name array for CRC. */
101 #define CRC_CLOCKS  \
102     {               \
103         kCLOCK_Crc0 \
104     }
105 
106 /*! @brief Clock ip name array for TPM. */
107 #define TPM_CLOCKS                              \
108     {                                           \
109         kCLOCK_Tpm0, kCLOCK_Tpm1, kCLOCK_NOGATE \
110     }
111 
112 /*! @brief Clock ip name array for LPI2C. */
113 #define LPI2C_CLOCKS                 \
114     {                                \
115         kCLOCK_Lpi2c0, kCLOCK_Lpi2c1 \
116     }
117 
118 /*! @brief Clock ip name array for I3C. */
119 #define I3C_CLOCKS  \
120     {               \
121         kCLOCK_I3c0 \
122     }
123 
124 /*! @brief Clock ip name array for LPSPI. */
125 #define LPSPI_CLOCKS                 \
126     {                                \
127         kCLOCK_Lpspi0, kCLOCK_Lpspi1 \
128     }
129 
130 /*! @brief Clock ip name array for LPUART. */
131 #define LPUART_CLOCKS                  \
132     {                                  \
133         kCLOCK_Lpuart0, kCLOCK_Lpuart1 \
134     }
135 
136 /*! @brief Clock ip name array for PORT. */
137 #define PORT_CLOCKS                                             \
138     {                                                           \
139         kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_NOGATE \
140     }
141 
142 /*! @brief Clock ip name array for LPADC. */
143 #define LPADC_CLOCKS  \
144     {                 \
145         kCLOCK_Lpadc0 \
146     }
147 
148 /*! @brief Clock ip name array for LPCMP. */
149 #define LPCMP_CLOCKS                 \
150     {                                \
151         kCLOCK_Lpcmp0, kCLOCK_Lpcmp1 \
152     }
153 
154 /*! @brief Clock ip name array for VREF. */
155 #define VREF_CLOCKS  \
156     {                \
157         kCLOCK_Vref0 \
158     }
159 
160 /*! @brief Clock ip name array for GPIO. */
161 #define GPIO_CLOCKS                                             \
162     {                                                           \
163         kCLOCK_GpioA, kCLOCK_GpioB, kCLOCK_GpioC, kCLOCK_NOGATE \
164     }
165 
166 /*! @brief Clock ip name array for LPIT. */
167 #define LPIT_CLOCKS  \
168     {                \
169         kCLOCK_Lpit0 \
170     }
171 
172 /*! @brief Clock ip name array for RF. */
173 #define RF_CLOCKS             \
174     {                         \
175         kCLOCK_Rf_2p4ghz_bist \
176     }
177 
178 /*! @brief Clock ip name array for WDOG. */
179 #define WDOG_CLOCKS                \
180     {                              \
181         kCLOCK_Wdog0, kCLOCK_Wdog1 \
182     }
183 
184 /*! @brief Clock ip name array for FLEXCAN. */
185 #define FLEXCAN_CLOCKS           \
186     {                            \
187         kCLOCK_Can0, kCLOCK_Can1 \
188     }
189 
190 /*! @brief Clock ip name array for FLEXIO. */
191 #define FLEXIO_CLOCKS  \
192     {                  \
193         kCLOCK_Flexio0 \
194     }
195 
196 /*! @brief Clock ip name array for TSTMR. */
197 #define TSTMR_CLOCKS  \
198     {                 \
199         kCLOCK_Tstmr0 \
200     }
201 
202 /*! @brief Clock ip name array for EWM. */
203 #define EWM_CLOCKS  \
204     {               \
205         kCLOCK_Ewm0 \
206     }
207 
208 /*! @brief Clock ip name array for SEMA42. */
209 #define SEMA42_CLOCKS \
210     {                 \
211         kCLOCK_Sema0  \
212     }
213 
214 /*! @brief Clock ip name array for MU. */
215 #define MU_CLOCKS       \
216     {                   \
217         kCLOCK_DSP0_MUA \
218     }
219 
220 /*! @brief Clock name used to get clock frequency.
221  *
222  * These clocks source would be generated from SCG module.
223  */
224 typedef enum _clock_name
225 {
226     /* ----------------------------- System layer clock -------------------------------*/
227     kCLOCK_CoreSysClk, /*!< Cortex M33 clock. */
228     kCLOCK_SlowClk,    /*!< SLOW_CLK with DIVSLOW. */
229     kCLOCK_PlatClk,    /*!< PLAT_CLK. */
230     kCLOCK_SysClk,     /*!< SYS_CLK. */
231     kCLOCK_BusClk,     /*!< BUS_CLK with DIVBUS. */
232 
233     /* For SCG CLK intput */
234     kCLOCK_ScgSysOscClk, /*!< SCG system OSC clock.                               */
235     kCLOCK_ScgSircClk,   /*!< SCG SIRC clock.                                     */
236     kCLOCK_ScgFircClk,   /*!< SCG FIRC clock.                                     */
237     kCLOCK_RtcOscClk,    /*!< RTC OSC clock.                                      */
238 } clock_name_t;
239 
240 /*!
241  * @brief Clock source for peripherals that support various clock selections.
242  *
243  * These options are for MRCC->XX[CC]
244  */
245 typedef enum _clock_ip_control
246 {
247     kCLOCK_IpClkControl_fun0 = 0U, /*!< Peripheral clocks are disabled, module does not stall low power mode entry. */
248     kCLOCK_IpClkControl_fun1 = 1U, /*!< Peripheral clocks are enabled, module does not stall low power mode entry. */
249     kCLOCK_IpClkControl_fun2 = 2U, /*!< Peripherals clocks are enabled unless peripheral is idle, low power mode entry
250                                       will stall until peripheral is idle. */
251     kCLOCK_IpClkControl_fun3 =
252         3U, /*!<  Peripheral clocks are enabled unless in SLEEP mode (or lower), low power mode entry will stall until
253                peripheral is idle Peripheral functional clocks that remain enabled in SLEEP mode are enabled and do not
254                stall low power mode entry unless entering DEEPSLEEP mode (or lower) */
255 } clock_ip_control_t;
256 
257 /*!
258  * @brief Clock source for peripherals that support various clock selections.
259  *
260  * These options are for MRCC->XX[MUX].
261  */
262 typedef enum _clock_ip_src
263 {
264     kCLOCK_IpSrcFro6M   = 2U, /*!< FRO 6M clock. */
265     kCLOCK_IpSrcFro192M = 3U, /*!< FRO 192M clock. */
266     kCLOCK_IpSrcSoscClk = 4U, /*!< OSC RF clock. */
267     kCLOCK_IpSrc32kClk  = 5U, /*!< 32k Clk clock. */
268 } clock_ip_src_t;
269 
270 /*!
271  * @brief Clock source for TPM2.
272  *
273  * These options are for RF_CMC1->TPM2_CFG[CLK_MUX_SEL].
274  */
275 typedef enum _tpm2_ip_src
276 {
277     kCLOCK_Tpm2SrcCoreClk = 1U, /*!< Core Clock. */
278     kCLOCK_Tpm2SrcSoscClk = 2U, /*!< Radio Oscillator. */
279 } tpm2_src_t;
280 
281 /*!
282  * @brief "IP Connector name difinition used for clock gate, clock source
283  * and clock divider setting. It is defined as the corresponding register address.
284  */
285 #define MAKE_MRCC_REGADDR(base, offset) ((base) + (offset))
286 
287 #if defined(FSL_SDK_FORCE_CLK_DRIVER_NS_ACCESS) && FSL_SDK_FORCE_CLK_DRIVER_NS_ACCESS
288 #define CLOCK_REG(name) ((*(volatile uint32_t *)((uint32_t)(name) & ~0x10000000UL)))
289 #else
290 #define CLOCK_REG(name) (*(volatile uint32_t *)((uint32_t)(name)))
291 #endif
292 
293 /*!
294  * @brief Clock IP name.
295  */
296 typedef enum _clock_ip_name
297 {
298     kCLOCK_NOGATE           = 0U,                                  /*!< No clock gate for the IP in MRCC */
299     kCLOCK_Ewm0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0x4C),  /*!< Clock ewm0 */
300     kCLOCK_Syspm0           = MAKE_MRCC_REGADDR(MRCC_BASE, 0x5C),  /*!< Clock syspm0 */
301     kCLOCK_Wdog0            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x68),  /*!< Clock wdog0 */
302     kCLOCK_Wdog1            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x6C),  /*!< Clock wdog1 */
303     kCLOCK_Sfa0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0x74),  /*!< Clock sfa0 */
304     kCLOCK_Crc0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0x8C),  /*!< Clock crc0 */
305     kCLOCK_Secsubsys        = MAKE_MRCC_REGADDR(MRCC_BASE, 0x90),  /*!< Clock secsubsys */
306     kCLOCK_Lpit0            = MAKE_MRCC_REGADDR(MRCC_BASE, 0xBC),  /*!< Clock lpit0 */
307     kCLOCK_Tstmr0           = MAKE_MRCC_REGADDR(MRCC_BASE, 0xC0),  /*!< Clock tstmr0 */
308     kCLOCK_Tpm0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0xC4),  /*!< Clock tpm0 */
309     kCLOCK_Tpm1             = MAKE_MRCC_REGADDR(MRCC_BASE, 0xC8),  /*!< Clock tpm1 */
310     kCLOCK_Lpi2c0           = MAKE_MRCC_REGADDR(MRCC_BASE, 0xCC),  /*!< Clock lpi2c0 */
311     kCLOCK_Lpi2c1           = MAKE_MRCC_REGADDR(MRCC_BASE, 0xD0),  /*!< Clock lpi2c1 */
312     kCLOCK_I3c0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0xD4),  /*!< Clock i3c */
313     kCLOCK_Lpspi0           = MAKE_MRCC_REGADDR(MRCC_BASE, 0xD8),  /*!< Clock lpspi0 */
314     kCLOCK_Lpspi1           = MAKE_MRCC_REGADDR(MRCC_BASE, 0xDC),  /*!< Clock lpspi1 */
315     kCLOCK_Lpuart0          = MAKE_MRCC_REGADDR(MRCC_BASE, 0xE0),  /*!< Clock lpuart0 */
316     kCLOCK_Lpuart1          = MAKE_MRCC_REGADDR(MRCC_BASE, 0xE4),  /*!< Clock lpuart1 */
317     kCLOCK_Flexio0          = MAKE_MRCC_REGADDR(MRCC_BASE, 0xE8),  /*!< Clock Flexio0 */
318     kCLOCK_Can0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0xEC),  /*!< Clock Can0 */
319     kCLOCK_Sema0            = MAKE_MRCC_REGADDR(MRCC_BASE, 0xFC),  /*!< Clock Sema0 */
320     kCLOCK_Data_stream_2p4  = MAKE_MRCC_REGADDR(MRCC_BASE, 0x104), /*!< Clock data_stream_2p4 */
321     kCLOCK_PortA            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x108), /*!< Clock portA */
322     kCLOCK_PortB            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x10C), /*!< Clock portB */
323     kCLOCK_PortC            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x110), /*!< Clock portC */
324     kCLOCK_Lpadc0           = MAKE_MRCC_REGADDR(MRCC_BASE, 0x11C), /*!< Clock lpadc0 */
325     kCLOCK_Lpcmp0           = MAKE_MRCC_REGADDR(MRCC_BASE, 0x120), /*!< Clock lpcmp0 */
326     kCLOCK_Lpcmp1           = MAKE_MRCC_REGADDR(MRCC_BASE, 0x124), /*!< Clock lpcmp1 */
327     kCLOCK_Vref0            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x128), /*!< Clock verf0 */
328     kCLOCK_Mtr_master       = MAKE_MRCC_REGADDR(MRCC_BASE, 0x134), /*!< Clock mtr_master */
329     kCLOCK_Can1             = MAKE_MRCC_REGADDR(MRCC_BASE, 0x13C), /*!< Clock Can1 */
330     kCLOCK_GpioA            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x404), /*!< Clock gpioA */
331     kCLOCK_GpioB            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x408), /*!< Clock gpioB */
332     kCLOCK_GpioC            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x40C), /*!< Clock gpioC */
333     kCLOCK_Dma0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0x410), /*!< Clock dma0 */
334     kCLOCK_Pflexnvm         = MAKE_MRCC_REGADDR(MRCC_BASE, 0x414), /*!< Clock pflexnvm */
335     kCLOCK_Sram0            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x41C), /*!< Clock Sram0 */
336     kCLOCK_Sram1            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x420), /*!< Clock Sram1 */
337     kCLOCK_Sram2            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x424), /*!< Clock Sram2 */
338     kCLOCK_Sram3            = MAKE_MRCC_REGADDR(MRCC_BASE, 0x428), /*!< Clock Sram3 */
339     kCLOCK_Sram0_NOECC      = MAKE_MRCC_REGADDR(MRCC_BASE, 0x42C), /*!< Clock Sram0 NOECC */
340     kCLOCK_DSP0             = MAKE_MRCC_REGADDR(MRCC_BASE, 0x430), /*!< Clock DSPV */
341     kCLOCK_DSP0_MUA         = MAKE_MRCC_REGADDR(MRCC_BASE, 0x434), /*!< Clock DSPV MUA */
342     kCLOCK_Sram1_NOECC      = MAKE_MRCC_REGADDR(MRCC_BASE, 0x438), /*!< Clock Sram1 NOECC */
343     kCLOCK_Rf_2p4ghz_bist   = MAKE_MRCC_REGADDR(MRCC_BASE, 0x43C), /*!< Clock rf_2p4ghz_bist */
344     kCLOCK_Lptmr0_wake2vsys = MAKE_MRCC_REGADDR(MRCC_BASE, 0x440), /*!< Clock LPTMR0 IPG clk erclk wake2vsys */
345     kCLOCK_Lptmr1_wake2vsys = MAKE_MRCC_REGADDR(MRCC_BASE, 0x444), /*!< Clock LPTMR1 IPG clk erclk wake2vsys */
346     kCLOCK_Lptmr2_wake2vsys = MAKE_MRCC_REGADDR(MRCC_BASE, 0x448), /*!< Clock LPTMR2 IPG clk erclk wake2vsys */
347     kCLOCK_Sirc_vsys_gating = MAKE_MRCC_REGADDR(MRCC_BASE, 0x44C), /*!< Clock SIRC vsys gating */
348 } clock_ip_name_t;
349 
350 /*!
351  * @brief SCG status return codes.
352  */
353 enum _scg_status
354 {
355     kStatus_SCG_Busy       = MAKE_STATUS(kStatusGroup_SCG, 1), /*!< Clock is busy.  */
356     kStatus_SCG_InvalidSrc = MAKE_STATUS(kStatusGroup_SCG, 2)  /*!< Invalid source. */
357 };
358 
359 /*!
360  * @brief SCG system clock type.
361  */
362 typedef enum _scg_sys_clk
363 {
364     kSCG_SysClkSlow,     /*!< System slow clock. */
365     kSCG_SysClkBus,      /*!< Bus clock.         */
366     kSCG_SysClkPlatform, /*!< Platform clock.    */
367     kSCG_SysClkCore,     /*!< Core clock.        */
368 } scg_sys_clk_t;
369 
370 /*!
371  * @brief SCG system clock source.
372  */
373 typedef enum _scg_sys_clk_src
374 {
375     kSCG_SysClkSrcSysOsc = 1U, /*!< System OSC. */
376     kSCG_SysClkSrcSirc   = 2U, /*!< Slow IRC.   */
377     kSCG_SysClkSrcFirc   = 3U, /*!< Fast IRC.   */
378     kSCG_SysClkSrcRosc   = 4U, /*!< RTC OSC. */
379 } scg_sys_clk_src_t;
380 
381 /*!
382  * @brief SCG system clock divider value.
383  */
384 typedef enum _scg_sys_clk_div
385 {
386     kSCG_SysClkDivBy1  = 0U,  /*!< Divided by 1.  */
387     kSCG_SysClkDivBy2  = 1U,  /*!< Divided by 2.  */
388     kSCG_SysClkDivBy3  = 2U,  /*!< Divided by 3.  */
389     kSCG_SysClkDivBy4  = 3U,  /*!< Divided by 4.  */
390     kSCG_SysClkDivBy5  = 4U,  /*!< Divided by 5.  */
391     kSCG_SysClkDivBy6  = 5U,  /*!< Divided by 6.  */
392     kSCG_SysClkDivBy7  = 6U,  /*!< Divided by 7.  */
393     kSCG_SysClkDivBy8  = 7U,  /*!< Divided by 8.  */
394     kSCG_SysClkDivBy9  = 8U,  /*!< Divided by 9.  */
395     kSCG_SysClkDivBy10 = 9U,  /*!< Divided by 10. */
396     kSCG_SysClkDivBy11 = 10U, /*!< Divided by 11. */
397     kSCG_SysClkDivBy12 = 11U, /*!< Divided by 12. */
398     kSCG_SysClkDivBy13 = 12U, /*!< Divided by 13. */
399     kSCG_SysClkDivBy14 = 13U, /*!< Divided by 14. */
400     kSCG_SysClkDivBy15 = 14U, /*!< Divided by 15. */
401     kSCG_SysClkDivBy16 = 15U  /*!< Divided by 16. */
402 } scg_sys_clk_div_t;
403 
404 /*!
405  * @brief SCG system clock configuration.
406  */
407 typedef struct _scg_sys_clk_config
408 {
409     uint32_t divSlow : 4; /*!< Slow clock divider, see @ref scg_sys_clk_div_t. */
410     uint32_t divBus : 4;  /*!< Bus clock divider, see @ref scg_sys_clk_div_t.  */
411     uint32_t : 8;         /*!< Reserved. */
412     uint32_t divCore : 4; /*!< Core clock divider, see @ref scg_sys_clk_div_t. */
413     uint32_t : 4;         /*!< Reserved. */
414     uint32_t src : 3;     /*!< System clock source, see @ref scg_sys_clk_src_t. */
415     uint32_t : 5;         /*!< reserved. */
416 } scg_sys_clk_config_t;
417 
418 /*!
419  * @brief SCG clock out configuration (CLKOUTSEL).
420  */
421 typedef enum _clock_clkout_src
422 {
423     kClockClkoutSelScgSlow   = 0U, /*!< SCG Slow clock. */
424     kClockClkoutSelSosc      = 1U, /*!< System OSC.     */
425     kClockClkoutSelSirc      = 2U, /*!< Slow IRC.       */
426     kClockClkoutSelFirc      = 3U, /*!< Fast IRC.       */
427     kClockClkoutSelScgRtcOsc = 4U, /*!< SCG RTC OSC clock. */
428 } clock_clkout_src_t;
429 
430 /*!
431  * @brief SCG system OSC monitor mode.
432  */
433 typedef enum _scg_sosc_monitor_mode
434 {
435     kSCG_SysOscMonitorDisable = 0U,                         /*!< Monitor disabled. */
436     kSCG_SysOscMonitorInt     = SCG_SOSCCSR_SOSCCM_MASK,    /*!< Interrupt when the SOSC error is detected. */
437     kSCG_SysOscMonitorReset =
438         SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK /*!< Reset when the SOSC error is detected.     */
439 } scg_sosc_monitor_mode_t;
440 
441 /*! @brief SOSC enable mode. */
442 enum
443 {
444     kSCG_SoscDisable       = 0,                         /*!< Disable SOSC clock.             */
445     kSCG_SoscEnable        = SCG_SOSCCSR_SOSCEN_MASK,   /*!< Enable SOSC clock.              */
446     kSCG_SoscEnableInSleep = SCG_SOSCCSR_SOSCSTEN_MASK, /*!< Enable SOSC in sleep mode.      */
447 };
448 
449 /*!
450  * @brief SCG system OSC configuration.
451  */
452 typedef struct _scg_sosc_config
453 {
454     uint32_t freq;                       /*!< System OSC frequency. */
455     uint32_t enableMode;                 /*!< Enable mode, OR'ed value of _scg_sosc_enable_mode.  */
456     scg_sosc_monitor_mode_t monitorMode; /*!< Clock monitor mode selected.     */
457 } scg_sosc_config_t;
458 
459 /*!
460  * @brief SCG ROSC monitor mode.
461  */
462 typedef enum _scg_rosc_monitor_mode
463 {
464     kSCG_RoscMonitorDisable = 0U,                           /*!< Monitor disabled. */
465     kSCG_RoscMonitorInt     = SCG_ROSCCSR_ROSCCM_MASK,      /*!< Interrupt when the RTC OSC error is detected. */
466     kSCG_RoscMonitorReset =
467         SCG_ROSCCSR_ROSCCM_MASK | SCG_ROSCCSR_ROSCCMRE_MASK /*!< Reset when the RTC OSC error is detected. */
468 } scg_rosc_monitor_mode_t;
469 
470 /*!
471  * @brief SCG ROSC configuration.
472  */
473 typedef struct _scg_rosc_config
474 {
475     scg_rosc_monitor_mode_t monitorMode; /*!< Clock monitor mode selected.     */
476 } scg_rosc_config_t;
477 
478 /*! @brief SIRC enable mode. */
479 typedef enum _scg_sirc_enable_mode
480 {
481     kSCG_SircDisableInSleep = 0,                         /*!< Disable SIRC clock.             */
482     kSCG_SircEnableInSleep  = SCG_SIRCCSR_SIRCSTEN_MASK, /*!< Enable SIRC in sleep mode.      */
483 } scg_sirc_enable_mode_t;
484 
485 /*!
486  * @brief SCG slow IRC clock configuration.
487  */
488 typedef struct _scg_sirc_config
489 {
490     scg_sirc_enable_mode_t enableMode; /*!< Enable mode, OR'ed value of _scg_sirc_enable_mode. */
491 } scg_sirc_config_t;
492 
493 /*!
494  * @brief SCG fast IRC trim mode.
495  */
496 typedef enum _scg_firc_trim_mode
497 {
498     kSCG_FircTrimNonUpdate = SCG_FIRCCSR_FIRCTREN_MASK,
499     /*!< FIRC trim enable but not enable trim value update. In this mode, the
500      trim value is fixed to the initialized value which is defined by
501      trimCoar and trimFine in configure structure \ref scg_firc_trim_config_t.*/
502 
503     kSCG_FircTrimUpdate = SCG_FIRCCSR_FIRCTREN_MASK | SCG_FIRCCSR_FIRCTRUP_MASK
504     /*!< FIRC trim enable and trim value update enable. In this mode, the trim
505      value is auto update. */
506 
507 } scg_firc_trim_mode_t;
508 
509 /*!
510  * @brief SCG fast IRC trim source.
511  */
512 typedef enum _scg_firc_trim_src
513 {
514     kSCG_FircTrimSrcSysOsc = 2U, /*!< System OSC.                 */
515     kSCG_FircTrimSrcRtcOsc = 3U, /*!< RTC OSC (32.768 kHz).       */
516 } scg_firc_trim_src_t;
517 
518 /*!
519  * @brief SCG fast IRC clock trim configuration.
520  */
521 typedef struct _scg_firc_trim_config
522 {
523     scg_firc_trim_mode_t trimMode; /*!< FIRC trim mode.                       */
524     scg_firc_trim_src_t trimSrc;   /*!< Trim source.                          */
525     uint16_t trimDiv;              /*!< Divider of SOSC for FIRC.             */
526 
527     uint8_t trimCoar;              /*!< Trim coarse value; Irrelevant if trimMode is kSCG_FircTrimUpdate. */
528     uint8_t trimFine;              /*!< Trim fine value; Irrelevant if trimMode is kSCG_FircTrimUpdate. */
529 } scg_firc_trim_config_t;
530 
531 /*! @brief FIRC enable mode. */
532 enum
533 {
534     kSCG_FircDisable       = 0,                         /*!< Disable FIRC clock.             */
535     kSCG_FircEnable        = SCG_FIRCCSR_FIRCEN_MASK,   /*!< Enable FIRC clock.              */
536     kSCG_FircEnableInSleep = SCG_FIRCCSR_FIRCSTEN_MASK, /*!< Enable FIRC in sleep mode.      */
537 };
538 
539 /*!
540  * @brief SCG fast IRC clock frequency range.
541  */
542 typedef enum _scg_firc_range
543 {
544     kSCG_FircRange48M,  /*!< Fast IRC is trimmed to 48 MHz. */
545     kSCG_FircRange64M,  /*!< Fast IRC is trimmed to 64 MHz. */
546     kSCG_FircRange96M,  /*!< Fast IRC is trimmed to 96 MHz. */
547     kSCG_FircRange192M, /*!< Fast IRC is trimmed to 192 MHz. */
548 } scg_firc_range_t;
549 
550 /*!
551  * @brief SCG fast IRC clock configuration.
552  */
553 typedef struct _scg_firc_config_t
554 {
555     uint32_t enableMode;                      /*!< Enable mode. */
556     scg_firc_range_t range;                   /*!< Fast IRC frequency range. */
557 
558     const scg_firc_trim_config_t *trimConfig; /*!< Pointer to the FIRC trim configuration; set NULL to disable trim. */
559 } scg_firc_config_t;
560 
561 /*!
562  * @brief FRO192M RF clock frequency range.
563  */
564 typedef enum _fro192m_rf_range
565 {
566     kFro192M_Range16M, /*!< FRO192M output frequenc 16 MHz. */
567     kFro192M_Range24M, /*!< FRO192M output frequenc 24 MHz. */
568     kFro192M_Range32M, /*!< FRO192M output frequenc 32 MHz. */
569     kFro192M_Range48M, /*!< FRO192M output frequenc 48 MHz. */
570     kFro192M_Range64M, /*!< FRO192M output frequenc 64 MHz. */
571 } fro192m_rf_range_t;
572 
573 /*!
574  * @brief RF Flash APB and RF_CMC clock divide.
575  */
576 typedef enum _fro192m_rf_clk_div
577 {
578     kFro192M_ClkDivBy1 = 0U, /*!< Divided by 1. */
579     kFro192M_ClkDivBy2 = 1U, /*!< Divided by 2. */
580     kFro192M_ClkDivBy4 = 2U, /*!< Divided by 4. */
581     kFro192M_ClkDivBy8 = 3U, /*!< Divided by 8. */
582 } fro192m_rf_clk_div_t;
583 
584 /*!
585  * @brief FRO192M RF clock configuration.
586  */
587 typedef struct _fro192m_rf_clk_config
588 {
589     fro192m_rf_range_t range;           /*!< FRO192M RF clock frequency range. */
590     fro192m_rf_clk_div_t apb_rfcmc_div; /*!< RF Flash APB and RF_CMC clock divide. */
591 } fro192m_rf_clk_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     if (kCLOCK_NOGATE == name)
609     {
610         return;
611     }
612 
613     uint32_t reg = CLOCK_REG(name);
614 
615     if (0x0u != (reg & MRCC_CC_MASK))
616     {
617         return;
618     }
619 
620     CLOCK_REG(name) &= (~MRCC_CC_MASK);
621     CLOCK_REG(name) |= (MRCC_CC_MASK & (uint32_t)kCLOCK_IpClkControl_fun1);
622 
623     if ((CLOCK_REG(name) & MRCC_PR_MASK) == MRCC_PR_MASK)
624     {
625         CLOCK_REG(name) |= MRCC_RSTB_MASK;
626     }
627 
628     /* Make sure enable clock finished */
629     __ISB();
630     __DSB();
631 }
632 
633 /*!
634  * @brief Enable the TPM2 clock.
635  */
CLOCK_EnableTPM2(void)636 static inline void CLOCK_EnableTPM2(void)
637 {
638     RF_CMC1->TPM2_CFG |= RF_CMC1_TPM2_CFG_CGC(1U);
639 }
640 
641 /*!
642  * @brief Enable the clock for specific IP in low power mode.
643  *
644  * @param name  Which clock to enable, see \ref clock_ip_name_t.
645  * @param control  Clock Config, see \ref clock_ip_control_t.
646  */
CLOCK_EnableClockLPMode(clock_ip_name_t name,clock_ip_control_t control)647 static inline void CLOCK_EnableClockLPMode(clock_ip_name_t name, clock_ip_control_t control)
648 {
649     if (kCLOCK_NOGATE == name)
650     {
651         return;
652     }
653 
654     assert(kCLOCK_IpClkControl_fun1 == control || kCLOCK_IpClkControl_fun2 == control ||
655            kCLOCK_IpClkControl_fun3 == control);
656 
657     CLOCK_REG(name) &= (~MRCC_CC_MASK);
658     CLOCK_REG(name) |= (MRCC_CC_MASK & (uint32_t)control);
659 
660     if ((CLOCK_REG(name) & MRCC_PR_MASK) == MRCC_PR_MASK)
661     {
662         CLOCK_REG(name) |= MRCC_RSTB_MASK;
663     }
664 
665     /* Make sure enable clock finished */
666     __ISB();
667     __DSB();
668 }
669 
670 /*!
671  * @brief Disable the clock for specific IP.
672  *
673  * @param name  Which clock to disable, see \ref clock_ip_name_t.
674  */
CLOCK_DisableClock(clock_ip_name_t name)675 static inline void CLOCK_DisableClock(clock_ip_name_t name)
676 {
677     if (kCLOCK_NOGATE == name)
678     {
679         return;
680     }
681 
682     CLOCK_REG(name) &= (uint32_t)kCLOCK_IpClkControl_fun0;
683 
684     if ((CLOCK_REG(name) & MRCC_PR_MASK) == MRCC_PR_MASK)
685     {
686         CLOCK_REG(name) &= ~MRCC_RSTB_MASK;
687     }
688 }
689 
690 /*!
691  * @brief Disable the TPM2 clock.
692  */
CLOCK_DisableTPM2(void)693 static inline void CLOCK_DisableTPM2(void)
694 {
695     RF_CMC1->TPM2_CFG &= ~RF_CMC1_TPM2_CFG_CGC(1U);
696 }
697 
698 /*!
699  * @brief Set the clock source for specific IP module.
700  *
701  * Set the clock source for specific IP, not all modules need to set the
702  * clock source, should only use this function for the modules need source
703  * setting.
704  *
705  * @param name Which peripheral to check, see \ref clock_ip_name_t.
706  * @param src Clock source to set.
707  */
CLOCK_SetIpSrc(clock_ip_name_t name,clock_ip_src_t src)708 static inline void CLOCK_SetIpSrc(clock_ip_name_t name, clock_ip_src_t src)
709 {
710     if (kCLOCK_NOGATE == name)
711     {
712         return;
713     }
714 
715     uint32_t reg = CLOCK_REG(name);
716 
717     assert(reg & MRCC_PR_MASK);
718 
719     reg = (reg & (~MRCC_MUX_MASK)) | MRCC_MUX(src);
720 
721     /*
722      * If clock is already enabled, first disable it, then set the clock
723      * source and re-enable it.
724      */
725     CLOCK_REG(name) = reg & (~MRCC_CC_MASK);
726     CLOCK_REG(name) = reg;
727 }
728 
729 /*!
730  * @brief Set the clock source for TPM2.
731  *
732  * @param src Clock source to set.
733  */
CLOCK_SetTpm2Src(tpm2_src_t src)734 static inline void CLOCK_SetTpm2Src(tpm2_src_t src)
735 {
736     uint32_t reg = RF_CMC1->TPM2_CFG;
737 
738     reg &= ~RF_CMC1_TPM2_CFG_CLK_MUX_SEL_MASK;
739 
740     reg |= RF_CMC1_TPM2_CFG_CLK_MUX_SEL(src);
741 
742     RF_CMC1->TPM2_CFG = reg;
743 }
744 
745 /*!
746  * @brief Set the clock source and divider for specific IP module.
747  *
748  * Set the clock source and divider for specific IP, not all modules need to
749  * set the clock source and divider, should only use this function for the
750  * modules need source and divider setting.
751  *
752  * Divider output clock = Divider input clock / (divValue+1)]).
753  *
754  * @param name Which peripheral to check, see \ref clock_ip_name_t.
755  * @param divValue  The divider value.
756  */
CLOCK_SetIpSrcDiv(clock_ip_name_t name,uint8_t divValue)757 static inline void CLOCK_SetIpSrcDiv(clock_ip_name_t name, uint8_t divValue)
758 {
759     if (kCLOCK_NOGATE == name)
760     {
761         return;
762     }
763 
764     uint32_t reg = CLOCK_REG(name);
765 
766     assert(reg & MRCC_PR_MASK);
767 
768     reg = (reg & (~MRCC_DIV_MASK)) | MRCC_DIV(divValue);
769 
770     /*
771      * If clock is already enabled, first disable it, then set the clock
772      * source and re-enable it.
773      */
774     CLOCK_REG(name) = reg & (~MRCC_CC_MASK);
775     CLOCK_REG(name) = reg;
776 }
777 
778 /*!
779  * @brief Gets the clock frequency for a specific clock name.
780  *
781  * This function checks the current clock configurations and then calculates
782  * the clock frequency for a specific clock name defined in clock_name_t.
783  *
784  * @param clockName Clock names defined in clock_name_t
785  * @return Clock frequency value in hertz
786  */
787 uint32_t CLOCK_GetFreq(clock_name_t clockName);
788 
789 /*!
790  * @brief Get the core clock or system clock frequency.
791  *
792  * @return Clock frequency in Hz.
793  */
794 uint32_t CLOCK_GetCoreSysClkFreq(void);
795 
796 /*!
797  * @brief Get the platform clock frequency.
798  *
799  * @return Clock frequency in Hz.
800  */
801 uint32_t CLOCK_GetPlatClkFreq(void);
802 
803 /*!
804  * @brief Get the bus clock frequency.
805  *
806  * @return Clock frequency in Hz.
807  */
808 uint32_t CLOCK_GetBusClkFreq(void);
809 
810 /*!
811  * @brief Get the flash clock frequency.
812  *
813  * @return Clock frequency in Hz.
814  */
815 uint32_t CLOCK_GetFlashClkFreq(void);
816 
817 /*!
818  * @brief Gets the functional clock frequency for a specific IP module.
819  *
820  * This function gets the IP module's functional clock frequency based on MRCC
821  * registers. It is only used for the IP modules which could select clock source
822  * by MRCC[PCS].
823  *
824  * @param name Which peripheral to get, see \ref clock_ip_name_t.
825  * @return Clock frequency value in Hz
826  */
827 uint32_t CLOCK_GetIpFreq(clock_ip_name_t name);
828 
829 /*!
830  * @name MCU System Clock.
831  * @{
832  */
833 
834 /*!
835  * @brief Gets the SCG system clock frequency.
836  *
837  * This function gets the SCG system clock frequency. These clocks are used for
838  * core, platform, external, and bus clock domains.
839  *
840  * @param type     Which type of clock to get, core clock or slow clock.
841  * @return  Clock frequency.
842  */
843 uint32_t CLOCK_GetSysClkFreq(scg_sys_clk_t type);
844 
845 /*!
846  * @brief Sets the system clock configuration for RUN mode.
847  *
848  * This function sets the system clock configuration for RUN mode.
849  *
850  * @param config Pointer to the configuration.
851  */
CLOCK_SetRunModeSysClkConfig(const scg_sys_clk_config_t * config)852 static inline void CLOCK_SetRunModeSysClkConfig(const scg_sys_clk_config_t *config)
853 {
854     assert(config);
855 
856     union
857     {
858         scg_sys_clk_config_t config;
859         uint32_t u32;
860     } scgSysClkConfig;
861 
862     scgSysClkConfig.config = *config;
863     CLOCK_REG(&SCG0->RCCR) = scgSysClkConfig.u32;
864 }
865 
866 /*!
867  * @brief Gets the system clock configuration in the current power mode.
868  *
869  * This function gets the system configuration in the current power mode.
870  *
871  * @param config Pointer to the configuration.
872  */
CLOCK_GetCurSysClkConfig(scg_sys_clk_config_t * config)873 static inline void CLOCK_GetCurSysClkConfig(scg_sys_clk_config_t *config)
874 {
875     assert(config);
876 
877     union
878     {
879         scg_sys_clk_config_t config;
880         uint32_t u32;
881     } scgSysClkConfig;
882 
883     scgSysClkConfig.u32 = CLOCK_REG(&SCG0->CSR);
884     *config             = scgSysClkConfig.config;
885 }
886 
887 /*!
888  * @brief Sets the clock out selection.
889  *
890  * This function sets the clock out selection (CLKOUTSEL).
891  *
892  * @param setting The selection to set.
893  */
CLOCK_SetClkOutSel(clock_clkout_src_t setting)894 static inline void CLOCK_SetClkOutSel(clock_clkout_src_t setting)
895 {
896     CLOCK_REG(&SCG0->CLKOUTCNFG) = SCG_CLKOUTCNFG_CLKOUTSEL(setting);
897 }
898 /* @} */
899 
900 /*!
901  * @name SCG System OSC Clock.
902  * @{
903  */
904 
905 /*!
906  * @brief Initializes the SCG system OSC.
907  *
908  * This function enables the SCG system OSC clock according to the
909  * configuration.
910  *
911  * @param config   Pointer to the configuration structure.
912  * @retval kStatus_Success System OSC is initialized.
913  * @retval kStatus_SCG_Busy System OSC has been enabled and is used by the system clock.
914  * @retval kStatus_ReadOnly System OSC control register is locked.
915  *
916  * @note This function can't detect whether the system OSC has been enabled and
917  * used by an IP.
918  */
919 status_t CLOCK_InitSysOsc(const scg_sosc_config_t *config);
920 
921 /*!
922  * @brief De-initializes the SCG system OSC.
923  *
924  * This function disables the SCG system OSC clock.
925  *
926  * @retval kStatus_Success System OSC is deinitialized.
927  * @retval kStatus_SCG_Busy System OSC is used by the system clock.
928  * @retval kStatus_ReadOnly System OSC control register is locked.
929  *
930  * @note This function can't detect whether the system OSC is used by an IP.
931  */
932 status_t CLOCK_DeinitSysOsc(void);
933 
934 /*!
935  * @brief Gets the SCG system OSC clock frequency (SYSOSC).
936  *
937  * @return  Clock frequency; If the clock is invalid, returns 0.
938  */
939 uint32_t CLOCK_GetSysOscFreq(void);
940 
941 /*!
942  * @brief Checks whether the system OSC clock error occurs.
943  *
944  * @return  True if the error occurs, false if not.
945  */
CLOCK_IsSysOscErr(void)946 static inline bool CLOCK_IsSysOscErr(void)
947 {
948     return (bool)(CLOCK_REG(&SCG0->SOSCCSR) & SCG_SOSCCSR_SOSCERR_MASK);
949 }
950 
951 /*!
952  * @brief Clears the system OSC clock error.
953  */
CLOCK_ClearSysOscErr(void)954 static inline void CLOCK_ClearSysOscErr(void)
955 {
956     CLOCK_REG(&SCG0->SOSCCSR) |= SCG_SOSCCSR_SOSCERR_MASK;
957 }
958 
959 /*!
960  * @brief Sets the system OSC monitor mode.
961  *
962  * This function sets the system OSC monitor mode. The mode can be disabled,
963  * it can generate an interrupt when the error is disabled, or reset when the error is detected.
964  *
965  * @param mode Monitor mode to set.
966  */
CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode)967 static inline void CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode)
968 {
969     uint32_t reg = CLOCK_REG(&SCG0->SOSCCSR);
970 
971     reg &= ~(SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK);
972 
973     reg |= (uint32_t)mode;
974 
975     CLOCK_REG(&SCG0->SOSCCSR) = reg;
976 }
977 
978 /*!
979  * @brief Checks whether the system OSC clock is valid.
980  *
981  * @return  True if clock is valid, false if not.
982  */
CLOCK_IsSysOscValid(void)983 static inline bool CLOCK_IsSysOscValid(void)
984 {
985     return (bool)(CLOCK_REG(&SCG0->SOSCCSR) & SCG_SOSCCSR_SOSCVLD_MASK);
986 }
987 
988 /*!
989  * @brief Unlock the SOSCCSR control status register.
990  */
CLOCK_UnlockSysOscControlStatusReg(void)991 static inline void CLOCK_UnlockSysOscControlStatusReg(void)
992 {
993     CLOCK_REG(&SCG0->SOSCCSR) &= ~(SCG_SOSCCSR_LK_MASK);
994 }
995 
996 /*!
997  * @brief Lock the SOSCCSR control status register.
998  */
CLOCK_LockSysOscControlStatusReg(void)999 static inline void CLOCK_LockSysOscControlStatusReg(void)
1000 {
1001     CLOCK_REG(&SCG0->SOSCCSR) |= SCG_SOSCCSR_LK_MASK;
1002 }
1003 
1004 /* @} */
1005 
1006 /*!
1007  * @name SCG Slow IRC Clock.
1008  * @{
1009  */
1010 
1011 /*!
1012  * @brief Initializes the SCG slow IRC clock.
1013  *
1014  * This function enables the SCG slow IRC clock according to the
1015  * configuration.
1016  *
1017  * @param config   Pointer to the configuration structure.
1018  * @retval kStatus_Success SIRC is initialized.
1019  * @retval kStatus_SCG_Busy SIRC has been enabled and is used by system clock.
1020  * @retval kStatus_ReadOnly SIRC control register is locked.
1021  *
1022  * @note This function can't detect whether the system OSC has been enabled and
1023  * used by an IP.
1024  */
1025 status_t CLOCK_InitSirc(const scg_sirc_config_t *config);
1026 
1027 /*!
1028  * @brief De-initializes the SCG slow IRC.
1029  *
1030  * This function disables the SCG slow IRC.
1031  *
1032  * @retval kStatus_Success SIRC is deinitialized.
1033  * @retval kStatus_SCG_Busy SIRC is used by system clock.
1034  * @retval kStatus_ReadOnly SIRC control register is locked.
1035  *
1036  * @note This function can't detect whether the SIRC is used by an IP.
1037  */
1038 status_t CLOCK_DeinitSirc(void);
1039 
1040 /*!
1041  * @brief Gets the SCG SIRC clock frequency.
1042  *
1043  * @return  Clock frequency; If the clock is invalid, returns 0.
1044  */
1045 uint32_t CLOCK_GetSircFreq(void);
1046 
1047 /*!
1048  * @brief Checks whether the SIRC clock is valid.
1049  *
1050  * @return  True if clock is valid, false if not.
1051  */
CLOCK_IsSircValid(void)1052 static inline bool CLOCK_IsSircValid(void)
1053 {
1054     return (bool)(CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK);
1055 }
1056 
1057 /*!
1058  * @brief Unlock the SIRCCSR control status register.
1059  */
CLOCK_UnlockSircControlStatusReg(void)1060 static inline void CLOCK_UnlockSircControlStatusReg(void)
1061 {
1062     CLOCK_REG(&SCG0->SIRCCSR) &= ~(SCG_SIRCCSR_LK_MASK);
1063 }
1064 
1065 /*!
1066  * @brief Lock the SIRCCSR control status register.
1067  */
CLOCK_LockSircControlStatusReg(void)1068 static inline void CLOCK_LockSircControlStatusReg(void)
1069 {
1070     CLOCK_REG(&SCG0->SIRCCSR) |= SCG_SIRCCSR_LK_MASK;
1071 }
1072 
1073 /* @} */
1074 
1075 /*!
1076  * @name SCG Fast IRC Clock.
1077  * @{
1078  */
1079 
1080 /*!
1081  * @brief Initializes the SCG fast IRC clock.
1082  *
1083  * This function enables the SCG fast IRC clock according to the configuration.
1084  *
1085  * @param config   Pointer to the configuration structure.
1086  * @retval kStatus_Success FIRC is initialized.
1087  * @retval kStatus_SCG_Busy FIRC has been enabled and is used by the system clock.
1088  * @retval kStatus_ReadOnly FIRC control register is locked.
1089  *
1090  * @note This function can't detect whether the FIRC has been enabled and
1091  * used by an IP.
1092  */
1093 status_t CLOCK_InitFirc(const scg_firc_config_t *config);
1094 
1095 /*!
1096  * @brief De-initializes the SCG fast IRC.
1097  *
1098  * This function disables the SCG fast IRC.
1099  *
1100  * @retval kStatus_Success FIRC is deinitialized.
1101  * @retval kStatus_SCG_Busy FIRC is used by the system clock.
1102  * @retval kStatus_ReadOnly FIRC control register is locked.
1103  *
1104  * @note This function can't detect whether the FIRC is used by an IP.
1105  */
1106 status_t CLOCK_DeinitFirc(void);
1107 
1108 /*!
1109  * @brief Gets the SCG FIRC clock frequency.
1110  *
1111  * @return  Clock frequency; If the clock is invalid, returns 0.
1112  */
1113 uint32_t CLOCK_GetFircFreq(void);
1114 
1115 /*!
1116  * @brief Checks whether the FIRC clock error occurs.
1117  *
1118  * @return  True if the error occurs, false if not.
1119  */
CLOCK_IsFircErr(void)1120 static inline bool CLOCK_IsFircErr(void)
1121 {
1122     return (bool)(CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCERR_MASK);
1123 }
1124 
1125 /*!
1126  * @brief Clears the FIRC clock error.
1127  */
CLOCK_ClearFircErr(void)1128 static inline void CLOCK_ClearFircErr(void)
1129 {
1130     CLOCK_REG(&SCG0->FIRCCSR) |= SCG_FIRCCSR_FIRCERR_MASK;
1131 }
1132 
1133 /*!
1134  * @brief Checks whether the FIRC clock is valid.
1135  *
1136  * @return  True if clock is valid, false if not.
1137  */
CLOCK_IsFircValid(void)1138 static inline bool CLOCK_IsFircValid(void)
1139 {
1140     return (bool)(CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCVLD_MASK);
1141 }
1142 
1143 /*!
1144  * @brief Unlock the FIRCCSR control status register.
1145  */
CLOCK_UnlockFircControlStatusReg(void)1146 static inline void CLOCK_UnlockFircControlStatusReg(void)
1147 {
1148     CLOCK_REG(&SCG0->FIRCCSR) &= ~(SCG_FIRCCSR_LK_MASK);
1149 }
1150 
1151 /*!
1152  * @brief Lock the FIRCCSR control status register.
1153  */
CLOCK_LockFircControlStatusReg(void)1154 static inline void CLOCK_LockFircControlStatusReg(void)
1155 {
1156     CLOCK_REG(&SCG0->FIRCCSR) |= SCG_FIRCCSR_LK_MASK;
1157 }
1158 
1159 /*!
1160  * brief Initializes the SCG ROSC.
1161  *
1162  * This function enables the SCG ROSC clock according to the
1163  * configuration.
1164  *
1165  * param config   Pointer to the configuration structure.
1166  * retval kStatus_Success ROSC is initialized.
1167  * retval kStatus_SCG_Busy ROSC has been enabled and is used by the system clock.
1168  * retval kStatus_ReadOnly ROSC control register is locked.
1169  *
1170  * note This function can't detect whether the system OSC has been enabled and
1171  * used by an IP.
1172  */
1173 status_t CLOCK_InitRosc(const scg_rosc_config_t *config);
1174 
1175 /*!
1176  * brief De-initializes the SCG ROSC.
1177  *
1178  * This function disables the SCG ROSC clock.
1179  *
1180  * retval kStatus_Success System OSC is deinitialized.
1181  * retval kStatus_SCG_Busy System OSC is used by the system clock.
1182  * retval kStatus_ReadOnly System OSC control register is locked.
1183  *
1184  * note This function can't detect whether the ROSC is used by an IP.
1185  */
1186 status_t CLOCK_DeinitRosc(void);
1187 
1188 /*!
1189  * @brief Gets the SCG RTC OSC clock frequency.
1190  *
1191  * @return  Clock frequency; If the clock is invalid, returns 0.
1192  */
1193 uint32_t CLOCK_GetRtcOscFreq(void);
1194 
1195 /*!
1196  * @brief Initializes the FRO192M clock for the Radio Mode Controller.
1197  *
1198  * This function configure the RF FRO192M clock according to the configuration.
1199  *
1200  * @param config   Pointer to the configuration structure.
1201  * @retval kStatus_Success RF FRO192M is configured.
1202  */
1203 status_t CLOCK_InitRfFro192M(const fro192m_rf_clk_config_t *config);
1204 
1205 /*!
1206  * @brief Gets the FRO192M clock frequency.
1207  *
1208  * @return  Clock frequency; If the clock is invalid, returns 0.
1209  */
1210 uint32_t CLOCK_GetRfFro192MFreq(void);
1211 
1212 /*!
1213  * @brief Checks whether the ROSC clock error occurs.
1214  *
1215  * @return  True if the error occurs, false if not.
1216  */
CLOCK_IsRoscErr(void)1217 static inline bool CLOCK_IsRoscErr(void)
1218 {
1219     return (bool)(CLOCK_REG(&SCG0->ROSCCSR) & SCG_ROSCCSR_ROSCERR_MASK);
1220 }
1221 
1222 /*!
1223  * @brief Clears the ROSC clock error.
1224  */
CLOCK_ClearRoscErr(void)1225 static inline void CLOCK_ClearRoscErr(void)
1226 {
1227     CLOCK_REG(&SCG0->ROSCCSR) |= SCG_ROSCCSR_ROSCERR_MASK;
1228 }
1229 
1230 /*!
1231  * @brief Sets the ROSC monitor mode.
1232  *
1233  * This function sets the ROSC monitor mode. The mode can be disabled,
1234  * it can generate an interrupt when the error is disabled, or reset when the error is detected.
1235  *
1236  * @param mode Monitor mode to set.
1237  */
CLOCK_SetRoscMonitorMode(scg_rosc_monitor_mode_t mode)1238 static inline void CLOCK_SetRoscMonitorMode(scg_rosc_monitor_mode_t mode)
1239 {
1240     uint32_t reg = CLOCK_REG(&SCG0->ROSCCSR);
1241 
1242     reg &= ~(SCG_ROSCCSR_ROSCCM_MASK | SCG_ROSCCSR_ROSCCMRE_MASK);
1243 
1244     reg |= (uint32_t)mode;
1245 
1246     CLOCK_REG(&SCG0->ROSCCSR) = reg;
1247 }
1248 
1249 /*!
1250  * @brief Checks whether the ROSC clock is valid.
1251  *
1252  * @return  True if clock is valid, false if not.
1253  */
CLOCK_IsRoscValid(void)1254 static inline bool CLOCK_IsRoscValid(void)
1255 {
1256     return (bool)(CLOCK_REG(&SCG0->ROSCCSR) & SCG_ROSCCSR_ROSCVLD_MASK);
1257 }
1258 
1259 /*!
1260  * @brief Unlock the ROSCCSR control status register.
1261  */
CLOCK_UnlockRoscControlStatusReg(void)1262 static inline void CLOCK_UnlockRoscControlStatusReg(void)
1263 {
1264     CLOCK_REG(&SCG0->ROSCCSR) &= ~(SCG_ROSCCSR_LK_MASK);
1265 }
1266 
1267 /*!
1268  * @brief Lock the ROSCCSR control status register.
1269  */
CLOCK_LockRoscControlStatusReg(void)1270 static inline void CLOCK_LockRoscControlStatusReg(void)
1271 {
1272     CLOCK_REG(&SCG0->ROSCCSR) |= SCG_ROSCCSR_LK_MASK;
1273 }
1274 
1275 /*!
1276  * @name External clock frequency
1277  * @{
1278  */
1279 
1280 /*!
1281  * @brief Sets the XTAL0 frequency based on board settings.
1282  *
1283  * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
1284  */
CLOCK_SetXtal0Freq(uint32_t freq)1285 static inline void CLOCK_SetXtal0Freq(uint32_t freq)
1286 {
1287     g_xtal0Freq = freq;
1288 }
1289 
1290 /*!
1291  * @brief Sets the XTAL32 frequency based on board settings.
1292  *
1293  * @param freq The XTAL32/EXTAL32 input clock frequency in Hz.
1294  */
CLOCK_SetXtal32Freq(uint32_t freq)1295 static inline void CLOCK_SetXtal32Freq(uint32_t freq)
1296 {
1297     g_xtal32Freq = freq;
1298 }
1299 
1300 /* @} */
1301 
1302 #if defined(__cplusplus)
1303 }
1304 #endif /* __cplusplus */
1305 
1306 /*! @} */
1307 
1308 #endif /* _FSL_CLOCK_H_ */
1309