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