1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2020, 2022 NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10 #ifndef _FSL_CLOCK_H_
11 #define _FSL_CLOCK_H_
12
13 #include "fsl_common.h"
14
15 /*! @addtogroup clock */
16 /*! @{ */
17
18 /*! @file */
19
20 /*******************************************************************************
21 * Configurations
22 ******************************************************************************/
23
24 /*! @brief Configures whether to check a parameter in a function.
25 *
26 * Some ICS settings must be changed with conditions, for example:
27 * 1. ICSIRCLK settings, such as the source, divider, and the trim value should not change when
28 * ICSIRCLK is used as a system clock source.
29 * 2. ICS_C7[OSCSEL] should not be changed when the external reference clock is used
30 * as a system clock source. For example, in FBE/BELP/PBE modes.
31 * 3. The users should only switch between the supported clock modes.
32 *
33 * ICS functions check the parameter and ICS status before setting, if not allowed
34 * to change, the functions return error. The parameter checking increases code size,
35 * if code size is a critical requirement, change #ICS_CONFIG_CHECK_PARAM to 0 to
36 * disable parameter checking.
37 */
38 #ifndef ICS_CONFIG_CHECK_PARAM
39 #define ICS_CONFIG_CHECK_PARAM 0U
40 #endif
41
42 /*! @brief Configure whether driver controls clock
43 *
44 * When set to 0, peripheral drivers will enable clock in initialize function
45 * and disable clock in de-initialize function. When set to 1, peripheral
46 * driver will not control the clock, application could control the clock out of
47 * the driver.
48 *
49 * @note All drivers share this feature switcher. If it is set to 1, application
50 * should handle clock enable and disable for all drivers.
51 */
52 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
53 #define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
54 #endif
55
56 /*******************************************************************************
57 * Definitions
58 ******************************************************************************/
59
60 /*! @name Driver version */
61 /*@{*/
62 /*! @brief CLOCK driver version 2.2.3. */
63 #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 3))
64 /*@}*/
65
66 /* Definition for delay API in clock driver, users can redefine it to the real application. */
67 #ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
68 #define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (40000000UL)
69 #endif
70
71 /*! @brief External XTAL0 (OSC0) clock frequency.
72 *
73 * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
74 * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
75 * if XTAL0 is 8 MHz:
76 * @code
77 * CLOCK_InitOsc0(...);
78 * CLOCK_SetXtal0Freq(80000000)
79 * @endcode
80 *
81 * This is important for the multicore platforms where only one core needs to set up the
82 * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
83 * to get a valid clock frequency.
84 */
85 extern volatile uint32_t g_xtal0Freq;
86
87 #if (defined(OSC) && !(defined(OSC0)))
88 #define OSC0 OSC
89 #endif
90
91 /*! @brief Clock ip name array for UART. */
92 #define UART_CLOCKS \
93 { \
94 kCLOCK_Uart0, kCLOCK_Uart1, kCLOCK_Uart2 \
95 }
96
97 /*! @brief Clock ip name array for ADC16. */
98 #define ADC_CLOCKS \
99 { \
100 kCLOCK_Adc0 \
101 }
102
103 /*! @brief Clock ip name array for IRQ. */
104 #define IRQ_CLOCKS \
105 { \
106 kCLOCK_Irq0 \
107 }
108
109 /*! @brief Clock ip name array for KBI. */
110 #define KBI_CLOCKS \
111 { \
112 kCLOCK_Kbi0, kCLOCK_Kbi1 \
113 }
114
115 /*! @brief Clock ip name array for SPI. */
116 #define SPI_CLOCKS \
117 { \
118 kCLOCK_Spi0, kCLOCK_Spi1 \
119 }
120
121 /*! @brief Clock ip name array for I2C. */
122 #define I2C_CLOCKS \
123 { \
124 kCLOCK_I2c0 \
125 }
126
127 /*! @brief Clock ip name array for FTM. */
128 #define FTM_CLOCKS \
129 { \
130 kCLOCK_Ftm0, kCLOCK_Ftm1, kCLOCK_Ftm2 \
131 }
132
133 /*! @brief Clock ip name array for CMP. */
134 #define ACMP_CLOCKS \
135 { \
136 kCLOCK_Acmp0, kCLOCK_Acmp1 \
137 }
138
139 /*! @brief Clock ip name array for CRC. */
140 #define CRC_CLOCKS \
141 { \
142 kCLOCK_Crc0, \
143 }
144
145 /*! @brief Clock ip name array for PIT. */
146 #define PIT_CLOCKS \
147 { \
148 kCLOCK_Pit0, \
149 }
150
151 /*! @brief Clock ip name array for RTC. */
152 #define RTC_CLOCKS \
153 { \
154 kCLOCK_Rtc0, \
155 }
156
157 /*!
158 * @brief LPO clock frequency.
159 */
160 #define LPO_CLK_FREQ 1000U
161
162 /*! @brief Clock name used to get clock frequency. */
163 typedef enum _clock_name
164 {
165
166 /* ----------------------------- System layer clock -------------------------------*/
167 kCLOCK_CoreSysClk, /*!< Core/system clock */
168 kCLOCK_PlatClk, /*!< Platform clock */
169 kCLOCK_BusClk, /*!< Bus clock */
170 kCLOCK_FlashClk, /*!< Flash clock */
171
172 /* ---------------------------------- OSC clock -----------------------------------*/
173 kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */
174
175 /* ----------------------------- ICS and ICS-Lite clock ---------------------------*/
176 kCLOCK_ICSFixedFreqClk, /*!< ICS fixed frequency clock (ICSFFCLK) */
177 kCLOCK_ICSInternalRefClk, /*!< ICS internal reference clock (ICSIRCLK) */
178 kCLOCK_ICSFllClk, /*!< ICSFLLCLK */
179 kCLOCK_ICSOutClk, /*!< ICS Output clock */
180
181 /* --------------------------------- Other clock ----------------------------------*/
182 kCLOCK_LpoClk, /*!< LPO clock */
183
184 } clock_name_t;
185
186 /*------------------------------------------------------------------------------
187
188 clock_gate_t definition:
189
190 31 16 0
191 -----------------------------------------------------------------
192 | SIM_SCGC register offset | control bit offset in SCGC |
193 -----------------------------------------------------------------
194
195 For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the
196 SIM_SCGC3 offset in SIM is 0x1030, then kCLOCK_GateSdhc0 is defined as
197
198 kCLOCK_GateSdhc0 = (0x1030 << 16) | 17;
199
200 ------------------------------------------------------------------------------*/
201
202 #define CLK_GATE_REG_OFFSET_SHIFT 16U
203 #define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U
204 #define CLK_GATE_BIT_SHIFT_SHIFT 0U
205 #define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU
206
207 #define CLK_GATE_DEFINE(reg_offset, bit_shift) \
208 ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
209 (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
210
211 #define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
212 #define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
213
214 /*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
215 typedef enum _clock_ip_name
216 {
217 kCLOCK_IpInvalid = 0U,
218
219 kCLOCK_I2c0 = CLK_GATE_DEFINE(0xCU, 17U),
220
221 kCLOCK_Uart0 = CLK_GATE_DEFINE(0xCU, 20U),
222 kCLOCK_Uart1 = CLK_GATE_DEFINE(0xCU, 21U),
223 kCLOCK_Uart2 = CLK_GATE_DEFINE(0xCU, 22U),
224
225 kCLOCK_Acmp0 = CLK_GATE_DEFINE(0xCU, 30U),
226 kCLOCK_Acmp1 = CLK_GATE_DEFINE(0xCU, 31U),
227
228 kCLOCK_Spi0 = CLK_GATE_DEFINE(0xCU, 18U),
229 kCLOCK_Spi1 = CLK_GATE_DEFINE(0xCU, 19U),
230
231 kCLOCK_Irq0 = CLK_GATE_DEFINE(0xCU, 27U),
232
233 kCLOCK_Kbi0 = CLK_GATE_DEFINE(0xCU, 24U),
234 kCLOCK_Kbi1 = CLK_GATE_DEFINE(0xCU, 25U),
235
236 kCLOCK_Adc0 = CLK_GATE_DEFINE(0xCU, 29U),
237
238 kCLOCK_Crc0 = CLK_GATE_DEFINE(0xCU, 10U),
239
240 kCLOCK_Ftm0 = CLK_GATE_DEFINE(0xCU, 5U),
241 kCLOCK_Ftm1 = CLK_GATE_DEFINE(0xCU, 6U),
242 kCLOCK_Ftm2 = CLK_GATE_DEFINE(0xCU, 7U),
243
244 kCLOCK_Pit0 = CLK_GATE_DEFINE(0xCU, 1U),
245 kCLOCK_Rtc0 = CLK_GATE_DEFINE(0xCU, 0U),
246 } clock_ip_name_t;
247
248 /*!@brief SIM configuration structure for clock setting. */
249 typedef struct _sim_clock_config
250 {
251 uint32_t busDiv; /*!< SIM_BUSDIV. */
252 uint8_t busClkPrescaler; /*!< A option prescaler for bus clock */
253 } sim_clock_config_t;
254
255 /*! @brief OSC work mode. */
256 enum _osc_work_mode
257 {
258 kOSC_ModeExt = 0U, /*!< OSC source from external clock. */
259 kOSC_ModeOscLowPower = OSC_CR_OSCOS_MASK, /*!< Oscillator low freq low power. */
260 kOSC_ModeOscHighGain = OSC_CR_HGO_MASK | OSC_CR_OSCOS_MASK, /*!< Oscillator low freq high gain. */
261 };
262
263 /*! @brief OSC enable mode. */
264 enum _osc_enable_mode
265 {
266 kOSC_Enable = OSC_CR_OSCEN_MASK, /*!< Enable. */
267 kOSC_EnableInStop = OSC_CR_OSCSTEN_MASK /*!< Enable in stop mode. */
268 };
269
270 /*!
271 * @brief OSC Initialization Configuration Structure
272 *
273 * Defines the configuration data structure to initialize the OSC.
274 * When porting to a new board, set the following members
275 * according to the board setting:
276 * 1. freq: The external frequency.
277 * 2. workMode: The OSC module mode.
278 * 3. enableMode: The OSC enable mode.
279 */
280 typedef struct _osc_config
281 {
282 uint32_t freq; /*!< External clock frequency. */
283 uint8_t workMode; /*!< OSC work mode setting. */
284 uint8_t enableMode; /*!< Configuration for OSCERCLK. */
285 } osc_config_t;
286
287 /*! @brief ICS FLL reference clock source select. */
288 typedef enum _ics_fll_src
289 {
290 kICS_FllSrcExternal, /*!< External reference clock is selected */
291 kICS_FllSrcInternal /*!< The slow internal reference clock is selected */
292 } ics_fll_src_t;
293
294 /*! @brief ICSOUT clock source. */
295 typedef enum _ics_clkout_src
296 {
297 kICS_ClkOutSrcFll, /*!< Output of the FLL is selected (reset default) */
298 kICS_ClkOutSrcInternal, /*!< Internal reference clock is selected, FLL is bypassed */
299 kICS_ClkOutSrcExternal, /*!< External reference clock is selected, FLL is bypassed */
300 } ics_clkout_src_t;
301
302 /*! @brief ICS status.
303 @anchor _ics_status.
304 */
305 enum
306 {
307 kStatus_ICS_ModeUnreachable = MAKE_STATUS(kStatusGroup_ICS, 0), /*!< Can't switch to target mode. */
308 kStatus_ICS_SourceUsed = MAKE_STATUS(kStatusGroup_ICS, 1) /*!< Can't change the clock source because
309 it is in use. */
310 };
311
312 /*! @brief ICS internal reference clock (ICSIRCLK) enable mode definition. */
313 enum _ics_irclk_enable_mode
314 {
315 kICS_IrclkDisable = 0U, /*!< ICSIRCLK disable. */
316 kICS_IrclkEnable = ICS_C1_IRCLKEN_MASK, /*!< ICSIRCLK enable. */
317 kICS_IrclkEnableInStop = ICS_C1_IREFSTEN_MASK /*!< ICSIRCLK enable in stop mode. */
318 };
319
320 /*! @brief ICS mode definitions */
321 typedef enum _ics_mode
322 {
323 kICS_ModeFEI = 0U, /*!< FEI - FLL Engaged Internal */
324 kICS_ModeFBI, /*!< FBI - FLL Bypassed Internal */
325 kICS_ModeBILP, /*!< BILP - Bypassed Low Power Internal */
326 kICS_ModeFEE, /*!< FEE - FLL Engaged External */
327 kICS_ModeFBE, /*!< FBE - FLL Bypassed External */
328 kICS_ModeBELP, /*!< BELP - Bypassed Low Power External */
329 kICS_ModeError /*!< Unknown mode */
330 } ics_mode_t;
331
332 /*! @brief ICS configuration structure
333 *
334 * When porting to a new board, set the following members
335 * according to the board setting:
336 * 1. icsMode: ICS mode
337 * 2. irClkEnableMode: ICSIRCLK enable mode
338 * 3. rDiv: If the FLL uses the external reference clock, set this
339 * value to ensure that the external reference clock divided by rDiv is
340 * in the 31.25 kHz to 39.0625 kHz range.
341 * 4. bDiv, this divider determine the ISCOUT clock
342 */
343 typedef struct _ics_config
344 {
345 ics_mode_t icsMode; /*!< ICS mode. */
346 uint8_t irClkEnableMode; /*!< ICSIRCLK enable mode. */
347 uint8_t rDiv; /*!< Divider for external reference clock, ICS_C1[RDIV]. */
348 uint8_t bDiv; /*!< Divider for ICS output clock ICS_C2[BDIV]. */
349 } ics_config_t;
350
351 /*******************************************************************************
352 * API
353 ******************************************************************************/
354
355 #if defined(__cplusplus)
356 extern "C" {
357 #endif /* __cplusplus */
358
359 /*!
360 * @brief Enable the clock for specific IP.
361 *
362 * @param name Which clock to enable, see \ref clock_ip_name_t.
363 */
CLOCK_EnableClock(clock_ip_name_t name)364 static inline void CLOCK_EnableClock(clock_ip_name_t name)
365 {
366 uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
367 (*(volatile uint32_t *)regAddr) |= (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
368 }
369
370 /*!
371 * @brief Disable the clock for specific IP.
372 *
373 * @param name Which clock to disable, see \ref clock_ip_name_t.
374 */
CLOCK_DisableClock(clock_ip_name_t name)375 static inline void CLOCK_DisableClock(clock_ip_name_t name)
376 {
377 uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
378 (*(volatile uint32_t *)regAddr) &= ~(1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
379 }
380
381 /*!
382 * @brief clock divider
383 *
384 * Set the SIM_BUSDIV.
385 * Carefully configure the SIM_BUSDIV to avoid bus/flash clock frequency higher
386 * than 24MHZ.
387 * @param busDiv bus clock output divider value.
388 */
CLOCK_SetBusClkDiv(uint32_t busDiv)389 static inline void CLOCK_SetBusClkDiv(uint32_t busDiv)
390 {
391 SIM->BUSDIV = SIM_BUSDIV_BUSDIV(busDiv);
392 }
393
394 /*!
395 * @brief Gets the clock frequency for a specific clock name.
396 *
397 * This function checks the current clock configurations and then calculates
398 * the clock frequency for a specific clock name defined in clock_name_t.
399 * The ICS must be properly configured before using this function.
400 *
401 * @param clockName Clock names defined in clock_name_t
402 * @return Clock frequency value in Hertz
403 */
404 uint32_t CLOCK_GetFreq(clock_name_t clockName);
405
406 /*!
407 * @brief Get the core clock or system clock frequency.
408 *
409 * @return Clock frequency in Hz.
410 */
411 uint32_t CLOCK_GetCoreSysClkFreq(void);
412
413 /*!
414 * @brief Get the bus clock frequency.
415 *
416 * @return Clock frequency in Hz.
417 */
418 uint32_t CLOCK_GetBusClkFreq(void);
419
420 /*!
421 * @brief Get the flash clock frequency.
422 *
423 * @return Clock frequency in Hz.
424 */
425 uint32_t CLOCK_GetFlashClkFreq(void);
426
427 /*!
428 * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
429 *
430 * @return Clock frequency in Hz.
431 */
432 uint32_t CLOCK_GetOsc0ErClkFreq(void);
433
434 /*!
435 * @brief Set the clock configure in SIM module.
436 *
437 * This function sets system layer clock settings in SIM module.
438 *
439 * @param config Pointer to the configure structure.
440 */
441 void CLOCK_SetSimConfig(sim_clock_config_t const *config);
442
443 /*!
444 * @brief Set the system clock dividers in SIM to safe value.
445 *
446 * The system level clocks (core clock, bus clock, and flash clock)
447 * must be in allowed ranges. During ICS clock mode switch, the ICS output clock
448 * changes then the system level clocks may be out of range. This function could
449 * be used before ICS mode change, to make sure system level clocks are in allowed
450 * range.
451 *
452 */
CLOCK_SetSimSafeDivs(void)453 static inline void CLOCK_SetSimSafeDivs(void)
454 {
455 SIM->BUSDIV = 0x1U;
456 }
457
458 /*! @name ICS frequency functions. */
459 /*@{*/
460
461 /*!
462 * @brief Gets the ICS output clock (ICSOUTCLK) frequency.
463 *
464 * This function gets the ICS output clock frequency in Hz based on the current ICS
465 * register value.
466 *
467 * @return The frequency of ICSOUTCLK.
468 */
469 uint32_t CLOCK_GetICSOutClkFreq(void);
470
471 /*!
472 * @brief Gets the ICS FLL clock (ICSFLLCLK) frequency.
473 *
474 * This function gets the ICS FLL clock frequency in Hz based on the current ICS
475 * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and
476 * disabled in low power state in other modes.
477 *
478 * @return The frequency of ICSFLLCLK.
479 */
480 uint32_t CLOCK_GetFllFreq(void);
481
482 /*!
483 * @brief Gets the ICS internal reference clock (ICSIRCLK) frequency.
484 *
485 * This function gets the ICS internal reference clock frequency in Hz based
486 * on the current ICS register value.
487 *
488 * @return The frequency of ICSIRCLK.
489 */
490 uint32_t CLOCK_GetInternalRefClkFreq(void);
491
492 /*!
493 * @brief Gets the ICS fixed frequency clock (ICSFFCLK) frequency.
494 *
495 * This function gets the ICS fixed frequency clock frequency in Hz based
496 * on the current ICS register value.
497 *
498 * @return The frequency of ICSFFCLK.
499 */
500 uint32_t CLOCK_GetICSFixedFreqClkFreq(void);
501
502 /*@}*/
503
504 /*! @name ICS clock configuration. */
505 /*@{*/
506
507 /*!
508 * @brief Enables or disables the ICS low power.
509 *
510 * Enabling the ICS low power disables the PLL and FLL in bypass modes. In other words,
511 * in FBE and PBE modes, enabling low power sets the ICS to BELP mode. In FBI and
512 * PBI modes, enabling low power sets the ICS to BILP mode.
513 * When disabling the ICS low power, the PLL or FLL are enabled based on ICS settings.
514 *
515 * @param enable True to enable ICS low power, false to disable ICS low power.
516 */
CLOCK_SetLowPowerEnable(bool enable)517 static inline void CLOCK_SetLowPowerEnable(bool enable)
518 {
519 if (enable)
520 {
521 ICS->C2 |= ICS_C2_LP_MASK;
522 }
523 else
524 {
525 ICS->C2 &= (uint8_t)(~ICS_C2_LP_MASK);
526 }
527 }
528
529 /*!
530 * @brief Configures the Internal Reference clock (ICSIRCLK).
531 *
532 * This function sets the ICSIRCLK base on parameters.
533 * This function also sets whether the \c ICSIRCLK is enabled in stop mode.
534 *
535 * @param enableMode ICSIRCLK enable mode, OR'ed value of _ICS_irclk_enable_mode.
536 * @retval kStatus_ICS_SourceUsed Because the internal reference clock is used as a clock source,
537 * the configuration should not be changed. Otherwise, a glitch occurs.
538 * @retval kStatus_Success ICSIRCLK configuration finished successfully.
539 */
CLOCK_SetInternalRefClkConfig(uint8_t enableMode)540 static inline void CLOCK_SetInternalRefClkConfig(uint8_t enableMode)
541 {
542 /* Set internal reference clock selection. */
543 ICS->C1 = (uint8_t)((ICS->C1 & ~(ICS_C1_IRCLKEN_MASK | ICS_C1_IREFSTEN_MASK)) | (uint8_t)enableMode);
544 }
545
546 /*!
547 * @brief Set the FLL external reference clock divider value.
548 *
549 * Sets the FLL external reference clock divider value, the register ICS_C1[RDIV].
550 * Resulting frequency must be in the range 31.25KHZ to 39.0625KHZ.
551 *
552 * @param rdiv The FLL external reference clock divider value, ICS_C1[RDIV].
553 */
CLOCK_SetFllExtRefDiv(uint8_t rdiv)554 static inline void CLOCK_SetFllExtRefDiv(uint8_t rdiv)
555 {
556 ICS->C1 = (uint8_t)((ICS->C1 & ~ICS_C1_RDIV_MASK) | ICS_C1_RDIV(rdiv));
557 }
558
559 /*@}*/
560
561 /*! @name ICS clock lock monitor functions. */
562 /*@{*/
563
564 /*!
565 * @brief Sets the OSC0 clock monitor mode.
566 *
567 * This function sets the OSC0 clock monitor mode. See ics_monitor_mode_t for details.
568 *
569 * @param enable True to enable clock monitor, false to disable clock monitor.
570 */
CLOCK_SetOsc0MonitorMode(bool enable)571 static inline void CLOCK_SetOsc0MonitorMode(bool enable)
572 {
573 if (enable)
574 {
575 ICS->C4 |= ICS_C4_CME_MASK;
576 }
577 else
578 {
579 ICS->C4 &= (uint8_t)(~ICS_C4_CME_MASK);
580 }
581 }
582
583 /*@}*/
584
585 /*!
586 * @name OSC configuration
587 * @{
588 */
589
590 /*!
591 * @brief Initializes the OSC0.
592 *
593 * This function initializes the OSC0 according to the board configuration.
594 *
595 * @param config Pointer to the OSC0 configuration structure.
596 */
597 void CLOCK_InitOsc0(osc_config_t const *config);
598
599 /*!
600 * @brief Deinitializes the OSC0.
601 *
602 * This function deinitializes the OSC0.
603 */
604 void CLOCK_DeinitOsc0(void);
605
606 /* @} */
607
608 /*!
609 * @name External clock frequency
610 * @{
611 */
612
613 /*!
614 * @brief Sets the XTAL0 frequency based on board settings.
615 *
616 * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
617 */
CLOCK_SetXtal0Freq(uint32_t freq)618 static inline void CLOCK_SetXtal0Freq(uint32_t freq)
619 {
620 g_xtal0Freq = freq;
621 }
622
623 /*!
624 * @brief Sets the OSC enable.
625 *
626 * @param enable osc enable mode.
627 */
CLOCK_SetOsc0Enable(uint8_t enable)628 static inline void CLOCK_SetOsc0Enable(uint8_t enable)
629 {
630 OSC0->CR |= (uint8_t)((OSC0->CR & (~(OSC_CR_OSCSTEN_MASK | OSC_CR_OSCEN_MASK))) | enable);
631 }
632
633 /* @} */
634
635 /*! @name ICS mode functions. */
636 /*@{*/
637
638 /*!
639 * @brief Gets the current ICS mode.
640 *
641 * This function checks the ICS registers and determines the current ICS mode.
642 *
643 * @return Current ICS mode or error code; See @ref ics_mode_t.
644 */
645 ics_mode_t CLOCK_GetMode(void);
646
647 /*!
648 * @brief Sets the ICS to FEI mode.
649 *
650 * This function sets the ICS to FEI mode. If setting to FEI mode fails
651 * from the current mode, this function returns an error.
652 *
653 * @param bDiv bus clock divider
654 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
655 * @retval kStatus_Success Switched to the target mode successfully.
656 */
657 status_t CLOCK_SetFeiMode(uint8_t bDiv);
658
659 /*!
660 * @brief Sets the ICS to FEE mode.
661 *
662 * This function sets the ICS to FEE mode. If setting to FEE mode fails
663 * from the current mode, this function returns an error.
664 *
665 * @param bDiv bus clock divider
666 * @param rDiv FLL reference clock divider setting, RDIV.
667 *
668 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
669 * @retval kStatus_Success Switched to the target mode successfully.
670 */
671 status_t CLOCK_SetFeeMode(uint8_t bDiv, uint8_t rDiv);
672
673 /*!
674 * @brief Sets the ICS to FBI mode.
675 *
676 * This function sets the ICS to FBI mode. If setting to FBI mode fails
677 * from the current mode, this function returns an error.
678 *
679 * @param bDiv bus clock divider
680 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
681 * @retval kStatus_Success Switched to the target mode successfully.s
682 */
683 status_t CLOCK_SetFbiMode(uint8_t bDiv);
684
685 /*!
686 * @brief Sets the ICS to FBE mode.
687 *
688 * This function sets the ICS to FBE mode. If setting to FBE mode fails
689 * from the current mode, this function returns an error.
690 *
691 * @param bDiv bus clock divider
692 * @param rDiv FLL reference clock divider setting, RDIV.
693 *
694 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
695 * @retval kStatus_Success Switched to the target mode successfully.
696 */
697 status_t CLOCK_SetFbeMode(uint8_t bDiv, uint8_t rDiv);
698
699 /*!
700 * @brief Sets the ICS to BILP mode.
701 *
702 * This function sets the ICS to BILP mode. If setting to BILP mode fails
703 * from the current mode, this function returns an error.
704 *
705 * @param bDiv bus clock divider
706 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
707 * @retval kStatus_Success Switched to the target mode successfully.
708 */
709 status_t CLOCK_SetBilpMode(uint8_t bDiv);
710
711 /*!
712 * @brief Sets the ICS to BELP mode.
713 *
714 * This function sets the ICS to BELP mode. If setting to BELP mode fails
715 * from the current mode, this function returns an error.
716 *
717 * @param bDiv bus clock divider
718 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
719 * @retval kStatus_Success Switched to the target mode successfully.
720 */
721 status_t CLOCK_SetBelpMode(uint8_t bDiv);
722
723 /*!
724 * @brief Sets the ICS to FEI mode during system boot up.
725 *
726 * This function sets the ICS to FEI mode from the reset mode. It can also be used to
727 * set up ICS during system boot up.
728 *
729 * @param bDiv bus clock divider.
730 *
731 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
732 * @retval kStatus_Success Switched to the target mode successfully.
733 */
734 status_t CLOCK_BootToFeiMode(uint8_t bDiv);
735
736 /*!
737 * @brief Sets the ICS to FEE mode during system bootup.
738 *
739 * This function sets ICS to FEE mode from the reset mode. It can also be used to
740 * set up the ICS during system boot up.
741 *
742 * @param bDiv bus clock divider.
743 * @param rDiv FLL reference clock divider setting, RDIV.
744 *
745 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
746 * @retval kStatus_Success Switched to the target mode successfully.
747 */
748 status_t CLOCK_BootToFeeMode(uint8_t bDiv, uint8_t rDiv);
749
750 /*!
751 * @brief Sets the ICS to BILP mode during system boot up.
752 *
753 * This function sets the ICS to BILP mode from the reset mode. It can also be used to
754 * set up the ICS during system boot up.
755 *
756 * @param bDiv bus clock divider.
757 * @retval kStatus_ICS_SourceUsed Could not change ICSIRCLK setting.
758 * @retval kStatus_Success Switched to the target mode successfully.
759 */
760 status_t CLOCK_BootToBilpMode(uint8_t bDiv);
761
762 /*!
763 * @brief Sets the ICS to BELP mode during system boot up.
764 *
765 * This function sets the ICS to BELP mode from the reset mode. It can also be used to
766 * set up the ICS during system boot up.
767 *
768 * @param bDiv bus clock divider.
769 * @retval kStatus_ICS_ModeUnreachable Could not switch to the target mode.
770 * @retval kStatus_Success Switched to the target mode successfully.
771 */
772 status_t CLOCK_BootToBelpMode(uint8_t bDiv);
773
774 /*!
775 * @brief Sets the ICS to a target mode.
776 *
777 * This function sets ICS to a target mode defined by the configuration
778 * structure. If switching to the target mode fails, this function
779 * chooses the correct path.
780 *
781 * @param config Pointer to the target ICS mode configuration structure.
782 * @return Return kStatus_Success if switched successfully; Otherwise, it returns an error code _ICS_status.
783 *
784 * @note If the external clock is used in the target mode, ensure that it is
785 * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this
786 * function.
787 */
788 status_t CLOCK_SetIcsConfig(ics_config_t const *config);
789
790 /*@}*/
791
792 #if defined(__cplusplus)
793 }
794 #endif /* __cplusplus */
795
796 /*! @} */
797
798 #endif /* _FSL_CLOCK_H_ */
799