1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright (c) 2016 - 2017 , NXP
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  *
9  * o Redistributions of source code must retain the above copyright notice, this list
10  *   of conditions and the following disclaimer.
11  *
12  * o Redistributions in binary form must reproduce the above copyright notice, this
13  *   list of conditions and the following disclaimer in the documentation and/or
14  *   other materials provided with the distribution.
15  *
16  * o Neither the name of copyright holder nor the names of its
17  *   contributors may be used to endorse or promote products derived from this
18  *   software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _FSL_CLOCK_H_
33 #define _FSL_CLOCK_H_
34 
35 #include "fsl_common.h"
36 
37 /*! @addtogroup clock */
38 /*! @{ */
39 
40 /*! @file */
41 
42 /*******************************************************************************
43  * Configurations
44  ******************************************************************************/
45 
46 /*! @brief Configures whether to check a parameter in a function.
47  *
48  * Some MCG settings must be changed with conditions, for example:
49  *  1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when
50  *     MCGIRCLK is used as a system clock source.
51  *  2. MCG_C7[OSCSEL] should not be changed  when the external reference clock is used
52  *     as a system clock source. For example, in FBE/BLPE/PBE modes.
53  *  3. The users should only switch between the supported clock modes.
54  *
55  * MCG functions check the parameter and MCG status before setting, if not allowed
56  * to change, the functions return error. The parameter checking increases code size,
57  * if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to
58  * disable parameter checking.
59  */
60 #ifndef MCG_CONFIG_CHECK_PARAM
61 #define MCG_CONFIG_CHECK_PARAM 0U
62 #endif
63 
64 /*! @brief Configure whether driver controls clock
65  *
66  * When set to 0, peripheral drivers will enable clock in initialize function
67  * and disable clock in de-initialize function. When set to 1, peripheral
68  * driver will not control the clock, application could contol the clock out of
69  * the driver.
70  *
71  * @note All drivers share this feature switcher. If it is set to 1, application
72  * should handle clock enable and disable for all drivers.
73  */
74 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
75 #define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
76 #endif
77 
78 /*******************************************************************************
79  * Definitions
80  ******************************************************************************/
81 
82 /*! @name Driver version */
83 /*@{*/
84 /*! @brief CLOCK driver version 2.2.1. */
85 #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 1))
86 /*@}*/
87 
88 /*! @brief External XTAL0 (OSC0) clock frequency.
89  *
90  * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
91  * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
92  * if XTAL0 is 8 MHz:
93  * @code
94  * CLOCK_InitOsc0(...); // Set up the OSC0
95  * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver.
96  * @endcode
97  *
98  * This is important for the multicore platforms where only one core needs to set up the
99  * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
100  * to get a valid clock frequency.
101  */
102 extern uint32_t g_xtal0Freq;
103 
104 /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
105  *
106  * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the
107  * function CLOCK_SetXtal32Freq to set the value in the clock driver.
108  *
109  * This is important for the multicore platforms where only one core needs to set up
110  * the clock. All other cores need to call the CLOCK_SetXtal32Freq
111  * to get a valid clock frequency.
112  */
113 extern uint32_t g_xtal32Freq;
114 
115 #if (defined(OSC) && !(defined(OSC0)))
116 #define OSC0 OSC
117 #endif
118 
119 /*! @brief Clock ip name array for DMAMUX. */
120 #define DMAMUX_CLOCKS  \
121     {                  \
122         kCLOCK_Dmamux0 \
123     }
124 
125 /*! @brief Clock ip name array for RTC. */
126 #define RTC_CLOCKS  \
127     {               \
128         kCLOCK_Rtc0 \
129     }
130 
131 /*! @brief Clock ip name array for SPI. */
132 #define SPI_CLOCKS               \
133     {                            \
134         kCLOCK_Spi0, kCLOCK_Spi1 \
135     }
136 
137 /*! @brief Clock ip name array for PIT. */
138 #define PIT_CLOCKS  \
139     {               \
140         kCLOCK_Pit0 \
141     }
142 
143 /*! @brief Clock ip name array for PORT. */
144 #define PORT_CLOCKS                                                          \
145     {                                                                        \
146         kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \
147     }
148 
149 /*! @brief Clock ip name array for TSI. */
150 #define TSI_CLOCKS  \
151     {               \
152         kCLOCK_Tsi0 \
153     }
154 
155 /*! @brief Clock ip name array for DAC. */
156 #define DAC_CLOCKS  \
157     {               \
158         kCLOCK_Dac0 \
159     }
160 
161 /*! @brief Clock ip name array for LPTMR. */
162 #define LPTMR_CLOCKS  \
163     {                 \
164         kCLOCK_Lptmr0 \
165     }
166 
167 /*! @brief Clock ip name array for ADC16. */
168 #define ADC16_CLOCKS \
169     {                \
170         kCLOCK_Adc0  \
171     }
172 
173 /*! @brief Clock ip name array for DMA. */
174 #define DMA_CLOCKS  \
175     {               \
176         kCLOCK_Dma0 \
177     }
178 
179 /*! @brief Clock ip name array for LPSCI/UART0. */
180 #define UART0_CLOCKS \
181     {                \
182         kCLOCK_Uart0 \
183     }
184 
185 /*! @brief Clock ip name array for UART. */
186 #define UART_CLOCKS                                  \
187     {                                                \
188         kCLOCK_IpInvalid, kCLOCK_Uart1, kCLOCK_Uart2 \
189     }
190 
191 /*! @brief Clock ip name array for TPM. */
192 #define TPM_CLOCKS                            \
193     {                                         \
194         kCLOCK_Tpm0, kCLOCK_Tpm1, kCLOCK_Tpm2 \
195     }
196 
197 /*! @brief Clock ip name array for I2C. */
198 #define I2C_CLOCKS               \
199     {                            \
200         kCLOCK_I2c0, kCLOCK_I2c1 \
201     }
202 
203 /*! @brief Clock ip name array for FTF. */
204 #define FTF_CLOCKS  \
205     {               \
206         kCLOCK_Ftf0 \
207     }
208 
209 /*! @brief Clock ip name array for CMP. */
210 #define CMP_CLOCKS  \
211     {               \
212         kCLOCK_Cmp0 \
213     }
214 
215 /*!
216  * @brief LPO clock frequency.
217  */
218 #define LPO_CLK_FREQ 1000U
219 
220 /*! @brief Peripherals clock source definition. */
221 #define SYS_CLK kCLOCK_CoreSysClk
222 #define BUS_CLK kCLOCK_BusClk
223 
224 #define I2C0_CLK_SRC BUS_CLK
225 #define I2C1_CLK_SRC BUS_CLK
226 #define SPI0_CLK_SRC BUS_CLK
227 #define SPI1_CLK_SRC SYS_CLK
228 #define UART1_CLK_SRC BUS_CLK
229 #define UART2_CLK_SRC BUS_CLK
230 
231 /*! @brief Clock name used to get clock frequency. */
232 typedef enum _clock_name
233 {
234 
235     /* ----------------------------- System layer clock -------------------------------*/
236     kCLOCK_CoreSysClk,   /*!< Core/system clock                                         */
237     kCLOCK_PlatClk,      /*!< Platform clock                                            */
238     kCLOCK_BusClk,       /*!< Bus clock                                                 */
239     kCLOCK_FlexBusClk,   /*!< FlexBus clock                                             */
240     kCLOCK_FlashClk,     /*!< Flash clock                                               */
241     kCLOCK_PllFllSelClk, /*!< The clock after SIM[PLLFLLSEL].                           */
242 
243     /* ---------------------------------- OSC clock -----------------------------------*/
244     kCLOCK_Er32kClk,  /*!< External reference 32K clock (ERCLK32K)                   */
245     kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK)                 */
246 
247     /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/
248     kCLOCK_McgFixedFreqClk,   /*!< MCG fixed frequency clock (MCGFFCLK)                      */
249     kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK)                   */
250     kCLOCK_McgFllClk,         /*!< MCGFLLCLK                                                 */
251     kCLOCK_McgPll0Clk,        /*!< MCGPLL0CLK                                                */
252     kCLOCK_McgExtPllClk,      /*!< EXT_PLLCLK                                                */
253 
254     /* --------------------------------- Other clock ----------------------------------*/
255     kCLOCK_LpoClk, /*!< LPO clock                                                 */
256 
257 } clock_name_t;
258 
259 /*! @brief USB clock source definition. */
260 typedef enum _clock_usb_src
261 {
262     kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0.      */
263     kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U)                             /*!< Use USB_CLKIN. */
264 } clock_usb_src_t;
265 
266 /*------------------------------------------------------------------------------
267 
268  clock_gate_t definition:
269 
270  31                              16                              0
271  -----------------------------------------------------------------
272  | SIM_SCGC register offset       |   control bit offset in SCGC |
273  -----------------------------------------------------------------
274 
275  For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the
276  SIM_SCGC3 offset in SIM is 0x1030, then kCLOCK_GateSdhc0 is defined as
277 
278               kCLOCK_GateSdhc0 = (0x1030 << 16) | 17;
279 
280 ------------------------------------------------------------------------------*/
281 
282 #define CLK_GATE_REG_OFFSET_SHIFT 16U
283 #define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U
284 #define CLK_GATE_BIT_SHIFT_SHIFT 0U
285 #define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU
286 
287 #define CLK_GATE_DEFINE(reg_offset, bit_shift)                                  \
288     ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
289      (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
290 
291 #define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
292 #define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
293 
294 /*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
295 typedef enum _clock_ip_name
296 {
297     kCLOCK_IpInvalid = 0U,
298     kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
299     kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
300     kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U),
301     kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U),
302     kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
303     kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
304     kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
305     kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U),
306     kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U),
307 
308     kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
309     kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U),
310     kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
311     kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
312     kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
313     kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
314     kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
315 
316     kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
317     kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
318     kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
319     kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U),
320     kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U),
321     kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U),
322     kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
323     kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
324     kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U),
325 
326     kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U),
327 } clock_ip_name_t;
328 
329 /*!@brief SIM configuration structure for clock setting. */
330 typedef struct _sim_clock_config
331 {
332     uint8_t pllFllSel;
333     uint8_t er32kSrc; /*!< ERCLK32K source selection.   */
334     uint32_t clkdiv1; /*!< SIM_CLKDIV1.                 */
335 } sim_clock_config_t;
336 
337 /*! @brief OSC work mode. */
338 typedef enum _osc_mode
339 {
340     kOSC_ModeExt = 0U, /*!< Use an external clock.   */
341 #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
342     kOSC_ModeOscLowPower = MCG_C2_EREFS_MASK, /*!< Oscillator low power. */
343 #else
344     kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */
345 #endif
346     kOSC_ModeOscHighGain = 0U
347 #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
348                            |
349                            MCG_C2_EREFS_MASK
350 #else
351                            |
352                            MCG_C2_EREFS0_MASK
353 #endif
354 #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
355                            |
356                            MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
357 #else
358                            |
359                            MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
360 #endif
361 } osc_mode_t;
362 
363 /*! @brief Oscillator capacitor load setting.*/
364 enum _osc_cap_load
365 {
366     kOSC_Cap2P = OSC_CR_SC2P_MASK,  /*!< 2  pF capacitor load */
367     kOSC_Cap4P = OSC_CR_SC4P_MASK,  /*!< 4  pF capacitor load */
368     kOSC_Cap8P = OSC_CR_SC8P_MASK,  /*!< 8  pF capacitor load */
369     kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
370 };
371 
372 /*! @brief OSCERCLK enable mode. */
373 enum _oscer_enable_mode
374 {
375     kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK,       /*!< Enable.              */
376     kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
377 };
378 
379 /*! @brief OSC configuration for OSCERCLK. */
380 typedef struct _oscer_config
381 {
382     uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of @ref _oscer_enable_mode. */
383 
384 } oscer_config_t;
385 
386 /*!
387  * @brief OSC Initialization Configuration Structure
388  *
389  * Defines the configuration data structure to initialize the OSC.
390  * When porting to a new board, set the following members
391  * according to the board setting:
392  * 1. freq: The external frequency.
393  * 2. workMode: The OSC module mode.
394  */
395 typedef struct _osc_config
396 {
397     uint32_t freq;              /*!< External clock frequency.    */
398     uint8_t capLoad;            /*!< Capacitor load setting.      */
399     osc_mode_t workMode;        /*!< OSC work mode setting.       */
400     oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK.  */
401 } osc_config_t;
402 
403 /*! @brief MCG FLL reference clock source select. */
404 typedef enum _mcg_fll_src
405 {
406     kMCG_FllSrcExternal, /*!< External reference clock is selected          */
407     kMCG_FllSrcInternal  /*!< The slow internal reference clock is selected */
408 } mcg_fll_src_t;
409 
410 /*! @brief MCG internal reference clock select */
411 typedef enum _mcg_irc_mode
412 {
413     kMCG_IrcSlow, /*!< Slow internal reference clock selected */
414     kMCG_IrcFast  /*!< Fast internal reference clock selected */
415 } mcg_irc_mode_t;
416 
417 /*! @brief MCG DCO Maximum Frequency with 32.768 kHz Reference */
418 typedef enum _mcg_dmx32
419 {
420     kMCG_Dmx32Default, /*!< DCO has a default range of 25% */
421     kMCG_Dmx32Fine     /*!< DCO is fine-tuned for maximum frequency with 32.768 kHz reference */
422 } mcg_dmx32_t;
423 
424 /*! @brief MCG DCO range select */
425 typedef enum _mcg_drs
426 {
427     kMCG_DrsLow,     /*!< Low frequency range       */
428     kMCG_DrsMid,     /*!< Mid frequency range       */
429     kMCG_DrsMidHigh, /*!< Mid-High frequency range  */
430     kMCG_DrsHigh     /*!< High frequency range      */
431 } mcg_drs_t;
432 
433 /*! @brief MCG PLL reference clock select */
434 typedef enum _mcg_pll_ref_src
435 {
436     kMCG_PllRefOsc0, /*!< Selects OSC0 as PLL reference clock                 */
437     kMCG_PllRefOsc1  /*!< Selects OSC1 as PLL reference clock                 */
438 } mcg_pll_ref_src_t;
439 
440 /*! @brief MCGOUT clock source. */
441 typedef enum _mcg_clkout_src
442 {
443     kMCG_ClkOutSrcOut,      /*!< Output of the FLL is selected (reset default)  */
444     kMCG_ClkOutSrcInternal, /*!< Internal reference clock is selected           */
445     kMCG_ClkOutSrcExternal, /*!< External reference clock is selected           */
446 } mcg_clkout_src_t;
447 
448 /*! @brief MCG Automatic Trim Machine Select */
449 typedef enum _mcg_atm_select
450 {
451     kMCG_AtmSel32k, /*!< 32 kHz Internal Reference Clock selected  */
452     kMCG_AtmSel4m   /*!< 4 MHz Internal Reference Clock selected   */
453 } mcg_atm_select_t;
454 
455 /*! @brief MCG OSC Clock Select */
456 typedef enum _mcg_oscsel
457 {
458     kMCG_OscselOsc, /*!< Selects System Oscillator (OSCCLK) */
459     kMCG_OscselRtc, /*!< Selects 32 kHz RTC Oscillator      */
460 } mcg_oscsel_t;
461 
462 /*! @brief MCG PLLCS select */
463 typedef enum _mcg_pll_clk_select
464 {
465     kMCG_PllClkSelPll0, /*!< PLL0 output clock is selected  */
466     kMCG_PllClkSelPll1  /* PLL1 output clock is selected    */
467 } mcg_pll_clk_select_t;
468 
469 /*! @brief MCG clock monitor mode. */
470 typedef enum _mcg_monitor_mode
471 {
472     kMCG_MonitorNone, /*!< Clock monitor is disabled.         */
473     kMCG_MonitorInt,  /*!< Trigger interrupt when clock lost. */
474     kMCG_MonitorReset /*!< System reset when clock lost.      */
475 } mcg_monitor_mode_t;
476 
477 /*! @brief MCG status. */
478 enum _mcg_status
479 {
480     kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0),       /*!< Can't switch to target mode. */
481     kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1),           /*!< Current mode invalid for the specific
482                                                                                function. */
483     kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2),    /*!< Invalid bus clock for ATM. */
484     kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */
485     kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4),            /*!< IRC is used when using ATM. */
486     kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5),       /*!< Hardware fail occurs during ATM. */
487     kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6)             /*!< Can't change the clock source because
488                                                                                it is in use. */
489 };
490 
491 /*! @brief MCG status flags. */
492 enum _mcg_status_flags_t
493 {
494     kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost.         */
495     kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */
496     kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost.         */
497     kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked.       */
498 };
499 
500 /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
501 enum _mcg_irclk_enable_mode
502 {
503     kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK,       /*!< MCGIRCLK enable.              */
504     kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
505 };
506 
507 /*! @brief MCG PLL clock enable mode definition. */
508 enum _mcg_pll_enable_mode
509 {
510     kMCG_PllEnableIndependent = MCG_C5_PLLCLKEN0_MASK, /*!< MCGPLLCLK enable independent of the
511                                                            MCG clock mode. Generally, the PLL
512                                                            is disabled in FLL modes
513                                                            (FEI/FBI/FEE/FBE). Setting the PLL clock
514                                                            enable independent, enables the
515                                                            PLL in the FLL modes.          */
516     kMCG_PllEnableInStop = MCG_C5_PLLSTEN0_MASK        /*!< MCGPLLCLK enable in STOP mode. */
517 };
518 
519 /*! @brief MCG mode definitions */
520 typedef enum _mcg_mode
521 {
522     kMCG_ModeFEI = 0U, /*!< FEI   - FLL Engaged Internal         */
523     kMCG_ModeFBI,      /*!< FBI   - FLL Bypassed Internal        */
524     kMCG_ModeBLPI,     /*!< BLPI  - Bypassed Low Power Internal  */
525     kMCG_ModeFEE,      /*!< FEE   - FLL Engaged External         */
526     kMCG_ModeFBE,      /*!< FBE   - FLL Bypassed External        */
527     kMCG_ModeBLPE,     /*!< BLPE  - Bypassed Low Power External  */
528     kMCG_ModePBE,      /*!< PBE   - PLL Bypassed External        */
529     kMCG_ModePEE,      /*!< PEE   - PLL Engaged External         */
530     kMCG_ModeError     /*!< Unknown mode                         */
531 } mcg_mode_t;
532 
533 /*! @brief MCG PLL configuration. */
534 typedef struct _mcg_pll_config
535 {
536     uint8_t enableMode; /*!< Enable mode. OR'ed value of @ref _mcg_pll_enable_mode. */
537     uint8_t prdiv;      /*!< Reference divider PRDIV.    */
538     uint8_t vdiv;       /*!< VCO divider VDIV.           */
539 } mcg_pll_config_t;
540 
541 /*! @brief MCG mode change configuration structure
542  *
543  * When porting to a new board, set the following members
544  * according to the board setting:
545  * 1. frdiv: If the FLL uses the external reference clock, set this
546  *    value to ensure that the external reference clock divided by frdiv is
547  *    in the 31.25 kHz to 39.0625 kHz range.
548  * 2. The PLL reference clock divider PRDIV: PLL reference clock frequency after
549  *    PRDIV should be in the FSL_FEATURE_MCG_PLL_REF_MIN to
550  *    FSL_FEATURE_MCG_PLL_REF_MAX range.
551  */
552 typedef struct _mcg_config
553 {
554     mcg_mode_t mcgMode; /*!< MCG mode.                   */
555 
556     /* ----------------------- MCGIRCCLK settings ------------------------ */
557     uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode.       */
558     mcg_irc_mode_t ircs;     /*!< Source, MCG_C2[IRCS].       */
559     uint8_t fcrdiv;          /*!< Divider, MCG_SC[FCRDIV].    */
560 
561     /* ------------------------ MCG FLL settings ------------------------- */
562     uint8_t frdiv;     /*!< Divider MCG_C1[FRDIV].      */
563     mcg_drs_t drs;     /*!< DCO range MCG_C4[DRST_DRS]. */
564     mcg_dmx32_t dmx32; /*!< MCG_C4[DMX32].              */
565 
566     /* ------------------------ MCG PLL settings ------------------------- */
567     mcg_pll_config_t pll0Config; /*!< MCGPLL0CLK configuration.   */
568 
569 } mcg_config_t;
570 
571 /*******************************************************************************
572  * API
573  ******************************************************************************/
574 
575 #if defined(__cplusplus)
576 extern "C" {
577 #endif /* __cplusplus */
578 
579 /*!
580  * @brief Enable the clock for specific IP.
581  *
582  * @param name  Which clock to enable, see \ref clock_ip_name_t.
583  */
CLOCK_EnableClock(clock_ip_name_t name)584 static inline void CLOCK_EnableClock(clock_ip_name_t name)
585 {
586     uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
587     (*(volatile uint32_t *)regAddr) |= (1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
588 }
589 
590 /*!
591  * @brief Disable the clock for specific IP.
592  *
593  * @param name  Which clock to disable, see \ref clock_ip_name_t.
594  */
CLOCK_DisableClock(clock_ip_name_t name)595 static inline void CLOCK_DisableClock(clock_ip_name_t name)
596 {
597     uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
598     (*(volatile uint32_t *)regAddr) &= ~(1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
599 }
600 
601 /*! @brief Set ERCLK32K source. */
CLOCK_SetEr32kClock(uint32_t src)602 static inline void CLOCK_SetEr32kClock(uint32_t src)
603 {
604     SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src));
605 }
606 
607 /*! @brief Set PLLFLLSEL clock source. */
CLOCK_SetPllFllSelClock(uint32_t src)608 static inline void CLOCK_SetPllFllSelClock(uint32_t src)
609 {
610     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src));
611 }
612 
613 /*! @brief Set TPM clock source. */
CLOCK_SetTpmClock(uint32_t src)614 static inline void CLOCK_SetTpmClock(uint32_t src)
615 {
616     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(src));
617 }
618 
619 /*! @brief Set LPSCI0 (UART0) clock source. */
CLOCK_SetLpsci0Clock(uint32_t src)620 static inline void CLOCK_SetLpsci0Clock(uint32_t src)
621 {
622     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_UART0SRC_MASK) | SIM_SOPT2_UART0SRC(src));
623 }
624 
625 /*! @brief Enable USB FS clock.
626  *
627  * @param src  USB FS clock source.
628  * @param freq The frequency specified by src.
629  * @retval true The clock is set successfully.
630  * @retval false The clock source is invalid to get proper USB FS clock.
631  */
632 bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq);
633 
634 /*! @brief Disable USB FS clock.
635  *
636  * Disable USB FS clock.
637  */
CLOCK_DisableUsbfs0Clock(void)638 static inline void CLOCK_DisableUsbfs0Clock(void)
639 {
640     CLOCK_DisableClock(kCLOCK_Usbfs0);
641 }
642 
643 /*! @brief Set CLKOUT source. */
CLOCK_SetClkOutClock(uint32_t src)644 static inline void CLOCK_SetClkOutClock(uint32_t src)
645 {
646     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src));
647 }
648 
649 /*! @brief Set RTC_CLKOUT source. */
CLOCK_SetRtcClkOutClock(uint32_t src)650 static inline void CLOCK_SetRtcClkOutClock(uint32_t src)
651 {
652     SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RTCCLKOUTSEL_MASK) | SIM_SOPT2_RTCCLKOUTSEL(src));
653 }
654 
655 /*!
656  * @brief
657  * Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV4].
658  */
CLOCK_SetOutDiv(uint32_t outdiv1,uint32_t outdiv4)659 static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv4)
660 {
661     SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV4(outdiv4);
662 }
663 
664 /*!
665  * @brief Gets the clock frequency for a specific clock name.
666  *
667  * This function checks the current clock configurations and then calculates
668  * the clock frequency for a specific clock name defined in clock_name_t.
669  * The MCG must be properly configured before using this function.
670  *
671  * @param clockName Clock names defined in clock_name_t
672  * @return Clock frequency value in Hertz
673  */
674 uint32_t CLOCK_GetFreq(clock_name_t clockName);
675 
676 /*!
677  * @brief Get the core clock or system clock frequency.
678  *
679  * @return Clock frequency in Hz.
680  */
681 uint32_t CLOCK_GetCoreSysClkFreq(void);
682 
683 /*!
684  * @brief Get the platform clock frequency.
685  *
686  * @return Clock frequency in Hz.
687  */
688 uint32_t CLOCK_GetPlatClkFreq(void);
689 
690 /*!
691  * @brief Get the bus clock frequency.
692  *
693  * @return Clock frequency in Hz.
694  */
695 uint32_t CLOCK_GetBusClkFreq(void);
696 
697 /*!
698  * @brief Get the flash clock frequency.
699  *
700  * @return Clock frequency in Hz.
701  */
702 uint32_t CLOCK_GetFlashClkFreq(void);
703 
704 /*!
705  * @brief Get the output clock frequency selected by SIM[PLLFLLSEL].
706  *
707  * @return Clock frequency in Hz.
708  */
709 uint32_t CLOCK_GetPllFllSelClkFreq(void);
710 
711 /*!
712  * @brief Get the external reference 32K clock frequency (ERCLK32K).
713  *
714  * @return Clock frequency in Hz.
715  */
716 uint32_t CLOCK_GetEr32kClkFreq(void);
717 
718 /*!
719  * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
720  *
721  * @return Clock frequency in Hz.
722  */
723 uint32_t CLOCK_GetOsc0ErClkFreq(void);
724 
725 /*!
726  * @brief Set the clock configure in SIM module.
727  *
728  * This function sets system layer clock settings in SIM module.
729  *
730  * @param config Pointer to the configure structure.
731  */
732 void CLOCK_SetSimConfig(sim_clock_config_t const *config);
733 
734 /*!
735  * @brief Set the system clock dividers in SIM to safe value.
736  *
737  * The system level clocks (core clock, bus clock, flexbus clock and flash clock)
738  * must be in allowed ranges. During MCG clock mode switch, the MCG output clock
739  * changes then the system level clocks may be out of range. This function could
740  * be used before MCG mode change, to make sure system level clocks are in allowed
741  * range.
742  *
743  * @param config Pointer to the configure structure.
744  */
CLOCK_SetSimSafeDivs(void)745 static inline void CLOCK_SetSimSafeDivs(void)
746 {
747     SIM->CLKDIV1 = 0x10030000U;
748 }
749 
750 /*! @name MCG frequency functions. */
751 /*@{*/
752 
753 /*!
754  * @brief Gets the MCG output clock (MCGOUTCLK) frequency.
755  *
756  * This function gets the MCG output clock frequency in Hz based on the current MCG
757  * register value.
758  *
759  * @return The frequency of MCGOUTCLK.
760  */
761 uint32_t CLOCK_GetOutClkFreq(void);
762 
763 /*!
764  * @brief Gets the MCG FLL clock (MCGFLLCLK) frequency.
765  *
766  * This function gets the MCG FLL clock frequency in Hz based on the current MCG
767  * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and
768  * disabled in low power state in other modes.
769  *
770  * @return The frequency of MCGFLLCLK.
771  */
772 uint32_t CLOCK_GetFllFreq(void);
773 
774 /*!
775  * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
776  *
777  * This function gets the MCG internal reference clock frequency in Hz based
778  * on the current MCG register value.
779  *
780  * @return The frequency of MCGIRCLK.
781  */
782 uint32_t CLOCK_GetInternalRefClkFreq(void);
783 
784 /*!
785  * @brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency.
786  *
787  * This function gets the MCG fixed frequency clock frequency in Hz based
788  * on the current MCG register value.
789  *
790  * @return The frequency of MCGFFCLK.
791  */
792 uint32_t CLOCK_GetFixedFreqClkFreq(void);
793 
794 /*!
795  * @brief Gets the MCG PLL0 clock (MCGPLL0CLK) frequency.
796  *
797  * This function gets the MCG PLL0 clock frequency in Hz based on the current MCG
798  * register value.
799  *
800  * @return The frequency of MCGPLL0CLK.
801  */
802 uint32_t CLOCK_GetPll0Freq(void);
803 
804 /*@}*/
805 
806 /*! @name MCG clock configuration. */
807 /*@{*/
808 
809 /*!
810  * @brief Enables or disables the MCG low power.
811  *
812  * Enabling the MCG low power disables the PLL and FLL in bypass modes. In other words,
813  * in FBE and PBE modes, enabling low power sets the MCG to BLPE mode. In FBI and
814  * PBI modes, enabling low power sets the MCG to BLPI mode.
815  * When disabling the MCG low power, the PLL or FLL are enabled based on MCG settings.
816  *
817  * @param enable True to enable MCG low power, false to disable MCG low power.
818  */
CLOCK_SetLowPowerEnable(bool enable)819 static inline void CLOCK_SetLowPowerEnable(bool enable)
820 {
821     if (enable)
822     {
823         MCG->C2 |= MCG_C2_LP_MASK;
824     }
825     else
826     {
827         MCG->C2 &= ~MCG_C2_LP_MASK;
828     }
829 }
830 
831 /*!
832  * @brief Configures the Internal Reference clock (MCGIRCLK).
833  *
834  * This function sets the \c MCGIRCLK base on parameters. It also selects the IRC
835  * source. If the fast IRC is used, this function sets the fast IRC divider.
836  * This function also sets whether the \c MCGIRCLK is enabled in stop mode.
837  * Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result,
838  * using the function in these modes it is not allowed.
839  *
840  * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
841  * @param ircs       MCGIRCLK clock source, choose fast or slow.
842  * @param fcrdiv     Fast IRC divider setting (\c FCRDIV).
843  * @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source,
844  * the confuration should not be changed. Otherwise, a glitch occurs.
845  * @retval kStatus_Success MCGIRCLK configuration finished successfully.
846  */
847 status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
848 
849 /*!
850  * @brief Selects the MCG external reference clock.
851  *
852  * Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL],
853  * and waits for the clock source to be stable. Because the external reference
854  * clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes.
855  *
856  * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
857  * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
858  * the confuration should not be changed. Otherwise, a glitch occurs.
859  * @retval kStatus_Success External reference clock set successfully.
860  */
861 status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
862 
863 /*!
864  * @brief Set the FLL external reference clock divider value.
865  *
866  * Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV].
867  *
868  * @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV].
869  */
CLOCK_SetFllExtRefDiv(uint8_t frdiv)870 static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
871 {
872     MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv);
873 }
874 
875 /*!
876  * @brief Enables the PLL0 in FLL mode.
877  *
878  * This function sets us the PLL0 in FLL mode and reconfigures
879  * the PLL0. Ensure that the PLL reference
880  * clock is enabled before calling this function and that the PLL0 is not used as a clock source.
881  * The function CLOCK_CalcPllDiv gets the correct PLL
882  * divider values.
883  *
884  * @param config Pointer to the configuration structure.
885  */
886 void CLOCK_EnablePll0(mcg_pll_config_t const *config);
887 
888 /*!
889  * @brief Disables the PLL0 in FLL mode.
890  *
891  * This function disables the PLL0 in FLL mode. It should be used together with the
892  * @ref CLOCK_EnablePll0.
893  */
CLOCK_DisablePll0(void)894 static inline void CLOCK_DisablePll0(void)
895 {
896     MCG->C5 &= ~(MCG_C5_PLLCLKEN0_MASK | MCG_C5_PLLSTEN0_MASK);
897 }
898 
899 /*!
900  * @brief Calculates the PLL divider setting for a desired output frequency.
901  *
902  * This function calculates the correct reference clock divider (\c PRDIV) and
903  * VCO divider (\c VDIV) to generate a desired PLL output frequency. It returns the
904  * closest frequency match with the corresponding \c PRDIV/VDIV
905  * returned from parameters. If a desired frequency is not valid, this function
906  * returns 0.
907  *
908  * @param refFreq    PLL reference clock frequency.
909  * @param desireFreq Desired PLL output frequency.
910  * @param prdiv      PRDIV value to generate desired PLL frequency.
911  * @param vdiv       VDIV value to generate desired PLL frequency.
912  * @return Closest frequency match that the PLL was able generate.
913  */
914 uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv);
915 
916 /*@}*/
917 
918 /*! @name MCG clock lock monitor functions. */
919 /*@{*/
920 
921 /*!
922  * @brief Sets the OSC0 clock monitor mode.
923  *
924  * This function sets the OSC0 clock monitor mode. See @ref mcg_monitor_mode_t for details.
925  *
926  * @param mode Monitor mode to set.
927  */
928 void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
929 
930 /*!
931  * @brief Sets the PLL0 clock monitor mode.
932  *
933  * This function sets the PLL0 clock monitor mode. See @ref mcg_monitor_mode_t for details.
934  *
935  * @param mode Monitor mode to set.
936  */
937 void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode);
938 
939 /*!
940  * @brief Gets the MCG status flags.
941  *
942  * This function gets the MCG clock status flags. All status flags are
943  * returned as a logical OR of the enumeration @ref _mcg_status_flags_t. To
944  * check a specific flag, compare the return value with the flag.
945  *
946  * Example:
947  * @code
948    // To check the clock lost lock status of OSC0 and PLL0.
949    uint32_t mcgFlags;
950 
951    mcgFlags = CLOCK_GetStatusFlags();
952 
953    if (mcgFlags & kMCG_Osc0LostFlag)
954    {
955        // OSC0 clock lock lost. Do something.
956    }
957    if (mcgFlags & kMCG_Pll0LostFlag)
958    {
959        // PLL0 clock lock lost. Do something.
960    }
961    @endcode
962  *
963  * @return  Logical OR value of the @ref _mcg_status_flags_t.
964  */
965 uint32_t CLOCK_GetStatusFlags(void);
966 
967 /*!
968  * @brief Clears the MCG status flags.
969  *
970  * This function clears the MCG clock lock lost status. The parameter is a logical
971  * OR value of the flags to clear. See @ref _mcg_status_flags_t.
972  *
973  * Example:
974  * @code
975    // To clear the clock lost lock status flags of OSC0 and PLL0.
976 
977    CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
978    @endcode
979  *
980  * @param mask The status flags to clear. This is a logical OR of members of the
981  *             enumeration @ref _mcg_status_flags_t.
982  */
983 void CLOCK_ClearStatusFlags(uint32_t mask);
984 
985 /*@}*/
986 
987 /*!
988  * @name OSC configuration
989  * @{
990  */
991 
992 /*!
993  * @brief Configures the OSC external reference clock (OSCERCLK).
994  *
995  * This function configures the OSC external reference clock (OSCERCLK).
996  * This is an example to enable the OSCERCLK in normal and stop modes and also set
997  * the output divider to 1:
998  *
999    @code
1000    oscer_config_t config =
1001    {
1002        .enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop,
1003        .erclkDiv   = 1U,
1004    };
1005 
1006    OSC_SetExtRefClkConfig(OSC, &config);
1007    @endcode
1008  *
1009  * @param base   OSC peripheral address.
1010  * @param config Pointer to the configuration structure.
1011  */
OSC_SetExtRefClkConfig(OSC_Type * base,oscer_config_t const * config)1012 static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config)
1013 {
1014     uint8_t reg = base->CR;
1015 
1016     reg &= ~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK);
1017     reg |= config->enableMode;
1018 
1019     base->CR = reg;
1020 }
1021 
1022 /*!
1023  * @brief Sets the capacitor load configuration for the oscillator.
1024  *
1025  * This function sets the specified capacitors configuration for the oscillator.
1026  * This should be done in the early system level initialization function call
1027  * based on the system configuration.
1028  *
1029  * @param base   OSC peripheral address.
1030  * @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load.
1031  *
1032  * Example:
1033    @code
1034    // To enable only 2 pF and 8 pF capacitor load, please use like this.
1035    OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
1036    @endcode
1037  */
OSC_SetCapLoad(OSC_Type * base,uint8_t capLoad)1038 static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad)
1039 {
1040     uint8_t reg = base->CR;
1041 
1042     reg &= ~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK);
1043     reg |= capLoad;
1044 
1045     base->CR = reg;
1046 }
1047 
1048 /*!
1049  * @brief Initializes the OSC0.
1050  *
1051  * This function initializes the OSC0 according to the board configuration.
1052  *
1053  * @param  config Pointer to the OSC0 configuration structure.
1054  */
1055 void CLOCK_InitOsc0(osc_config_t const *config);
1056 
1057 /*!
1058  * @brief Deinitializes the OSC0.
1059  *
1060  * This function deinitializes the OSC0.
1061  */
1062 void CLOCK_DeinitOsc0(void);
1063 
1064 /* @} */
1065 
1066 /*!
1067  * @name External clock frequency
1068  * @{
1069  */
1070 
1071 /*!
1072  * @brief Sets the XTAL0 frequency based on board settings.
1073  *
1074  * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
1075  */
CLOCK_SetXtal0Freq(uint32_t freq)1076 static inline void CLOCK_SetXtal0Freq(uint32_t freq)
1077 {
1078     g_xtal0Freq = freq;
1079 }
1080 
1081 /*!
1082  * @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings.
1083  *
1084  * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
1085  */
CLOCK_SetXtal32Freq(uint32_t freq)1086 static inline void CLOCK_SetXtal32Freq(uint32_t freq)
1087 {
1088     g_xtal32Freq = freq;
1089 }
1090 /* @} */
1091 
1092 /*!
1093  * @name MCG auto-trim machine.
1094  * @{
1095  */
1096 
1097 /*!
1098  * @brief Auto trims the internal reference clock.
1099  *
1100  * This function trims the internal reference clock by using the external clock. If
1101  * successful, it returns the kStatus_Success and the frequency after
1102  * trimming is received in the parameter @p actualFreq. If an error occurs,
1103  * the error code is returned.
1104  *
1105  * @param extFreq      External clock frequency, which should be a bus clock.
1106  * @param desireFreq   Frequency to trim to.
1107  * @param actualFreq   Actual frequency after trimming.
1108  * @param atms         Trim fast or slow internal reference clock.
1109  * @retval kStatus_Success ATM success.
1110  * @retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM.
1111  * @retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency.
1112  * @retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source.
1113  * @retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming.
1114  */
1115 status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms);
1116 /* @} */
1117 
1118 /*! @name MCG mode functions. */
1119 /*@{*/
1120 
1121 /*!
1122  * @brief Gets the current MCG mode.
1123  *
1124  * This function checks the MCG registers and determines the current MCG mode.
1125  *
1126  * @return Current MCG mode or error code; See @ref mcg_mode_t.
1127  */
1128 mcg_mode_t CLOCK_GetMode(void);
1129 
1130 /*!
1131  * @brief Sets the MCG to FEI mode.
1132  *
1133  * This function sets the MCG to FEI mode. If setting to FEI mode fails
1134  * from the current mode, this function returns an error.
1135  *
1136  * @param       dmx32  DMX32 in FEI mode.
1137  * @param       drs The DCO range selection.
1138  * @param       fllStableDelay Delay function to  ensure that the FLL is stable. Passing
1139  *              NULL does not cause a delay.
1140  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1141  * @retval kStatus_Success Switched to the target mode successfully.
1142  * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1143  * to a frequency above 32768 Hz.
1144  */
1145 status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1146 
1147 /*!
1148  * @brief Sets the MCG to FEE mode.
1149  *
1150  * This function sets the MCG to FEE mode. If setting to FEE mode fails
1151  * from the current mode, this function returns an error.
1152  *
1153  * @param   frdiv  FLL reference clock divider setting, FRDIV.
1154  * @param   dmx32  DMX32 in FEE mode.
1155  * @param   drs    The DCO range selection.
1156  * @param   fllStableDelay Delay function to make sure FLL is stable. Passing
1157  *          NULL does not cause a delay.
1158  *
1159  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1160  * @retval kStatus_Success Switched to the target mode successfully.
1161  */
1162 status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1163 
1164 /*!
1165  * @brief Sets the MCG to FBI mode.
1166  *
1167  * This function sets the MCG to FBI mode. If setting to FBI mode fails
1168  * from the current mode, this function returns an error.
1169  *
1170  * @param  dmx32  DMX32 in FBI mode.
1171  * @param  drs  The DCO range selection.
1172  * @param  fllStableDelay Delay function to make sure FLL is stable. If the FLL
1173  *         is not used in FBI mode, this parameter can be NULL. Passing
1174  *         NULL does not cause a delay.
1175  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1176  * @retval kStatus_Success Switched to the target mode successfully.
1177  * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1178  * to frequency above 32768 Hz.
1179  */
1180 status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1181 
1182 /*!
1183  * @brief Sets the MCG to FBE mode.
1184  *
1185  * This function sets the MCG to FBE mode. If setting to FBE mode fails
1186  * from the current mode, this function returns an error.
1187  *
1188  * @param   frdiv  FLL reference clock divider setting, FRDIV.
1189  * @param   dmx32  DMX32 in FBE mode.
1190  * @param   drs    The DCO range selection.
1191  * @param   fllStableDelay Delay function to make sure FLL is stable. If the FLL
1192  *          is not used in FBE mode, this parameter can be NULL. Passing NULL
1193  *          does not cause a delay.
1194  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1195  * @retval kStatus_Success Switched to the target mode successfully.
1196  */
1197 status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1198 
1199 /*!
1200  * @brief Sets the MCG to BLPI mode.
1201  *
1202  * This function sets the MCG to BLPI mode. If setting to BLPI mode fails
1203  * from the current mode, this function returns an error.
1204  *
1205  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1206  * @retval kStatus_Success Switched to the target mode successfully.
1207  */
1208 status_t CLOCK_SetBlpiMode(void);
1209 
1210 /*!
1211  * @brief Sets the MCG to BLPE mode.
1212  *
1213  * This function sets the MCG to BLPE mode. If setting to BLPE mode fails
1214  * from the current mode, this function returns an error.
1215  *
1216  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1217  * @retval kStatus_Success Switched to the target mode successfully.
1218  */
1219 status_t CLOCK_SetBlpeMode(void);
1220 
1221 /*!
1222  * @brief Sets the MCG to PBE mode.
1223  *
1224  * This function sets the MCG to PBE mode. If setting to PBE mode fails
1225  * from the current mode, this function returns an error.
1226  *
1227  * @param   pllcs  The PLL selection, PLLCS.
1228  * @param   config Pointer to the PLL configuration.
1229  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1230  * @retval kStatus_Success Switched to the target mode successfully.
1231  *
1232  * @note
1233  * 1. The parameter \c pllcs selects the PLL. For platforms with
1234  * only one PLL, the parameter pllcs is kept for interface compatibility.
1235  * 2. The parameter \c config is the PLL configuration structure. On some
1236  * platforms,  it is possible to choose the external PLL directly, which renders the
1237  * configuration structure not necessary. In this case, pass in NULL.
1238  * For example: CLOCK_SetPbeMode(kMCG_OscselOsc, kMCG_PllClkSelExtPll, NULL);
1239  */
1240 status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config);
1241 
1242 /*!
1243  * @brief Sets the MCG to PEE mode.
1244  *
1245  * This function sets the MCG to PEE mode.
1246  *
1247  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1248  * @retval kStatus_Success Switched to the target mode successfully.
1249  *
1250  * @note This function only changes the CLKS to use the PLL/FLL output. If the
1251  *       PRDIV/VDIV are different than in the PBE mode, set them up
1252  *       in PBE mode and wait. When the clock is stable, switch to PEE mode.
1253  */
1254 status_t CLOCK_SetPeeMode(void);
1255 
1256 /*!
1257  * @brief Switches the MCG to FBE mode from the external mode.
1258  *
1259  * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
1260  * The external clock is used as the system clock souce and PLL is disabled. However,
1261  * the FLL settings are not configured. This is a lite function with a small code size, which is useful
1262  * during the mode switch. For example, to switch from PEE mode to FEI mode:
1263  *
1264  * @code
1265  * CLOCK_ExternalModeToFbeModeQuick();
1266  * CLOCK_SetFeiMode(...);
1267  * @endcode
1268  *
1269  * @retval kStatus_Success Switched successfully.
1270  * @retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function.
1271  */
1272 status_t CLOCK_ExternalModeToFbeModeQuick(void);
1273 
1274 /*!
1275  * @brief Switches the MCG to FBI mode from internal modes.
1276  *
1277  * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
1278  * The MCGIRCLK is used as the system clock souce and PLL is disabled. However,
1279  * FLL settings are not configured. This is a lite function with a small code size, which is useful
1280  * during the mode switch. For example, to switch from PEI mode to FEE mode:
1281  *
1282  * @code
1283  * CLOCK_InternalModeToFbiModeQuick();
1284  * CLOCK_SetFeeMode(...);
1285  * @endcode
1286  *
1287  * @retval kStatus_Success Switched successfully.
1288  * @retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function.
1289  */
1290 status_t CLOCK_InternalModeToFbiModeQuick(void);
1291 
1292 /*!
1293  * @brief Sets the MCG to FEI mode during system boot up.
1294  *
1295  * This function sets the MCG to FEI mode from the reset mode. It can also be used to
1296  * set up MCG during system boot up.
1297  *
1298  * @param  dmx32  DMX32 in FEI mode.
1299  * @param  drs The DCO range selection.
1300  * @param  fllStableDelay Delay function to ensure that the FLL is stable.
1301  *
1302  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1303  * @retval kStatus_Success Switched to the target mode successfully.
1304  * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
1305  * to frequency above 32768 Hz.
1306  */
1307 status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1308 
1309 /*!
1310  * @brief Sets the MCG to FEE mode during system bootup.
1311  *
1312  * This function sets MCG to FEE mode from the reset mode. It can also be used to
1313  * set up the MCG during system boot up.
1314  *
1315  * @param   oscsel OSC clock select, OSCSEL.
1316  * @param   frdiv  FLL reference clock divider setting, FRDIV.
1317  * @param   dmx32  DMX32 in FEE mode.
1318  * @param   drs    The DCO range selection.
1319  * @param   fllStableDelay Delay function to ensure that the FLL is stable.
1320  *
1321  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1322  * @retval kStatus_Success Switched to the target mode successfully.
1323  */
1324 status_t CLOCK_BootToFeeMode(
1325     mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void));
1326 
1327 /*!
1328  * @brief Sets the MCG to BLPI mode during system boot up.
1329  *
1330  * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
1331  * set up the MCG during sytem boot up.
1332  *
1333  * @param  fcrdiv Fast IRC divider, FCRDIV.
1334  * @param  ircs   The internal reference clock to select, IRCS.
1335  * @param  ircEnableMode  The MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
1336  *
1337  * @retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting.
1338  * @retval kStatus_Success Switched to the target mode successfully.
1339  */
1340 status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
1341 
1342 /*!
1343  * @brief Sets the MCG to BLPE mode during sytem boot up.
1344  *
1345  * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
1346  * set up the MCG during sytem boot up.
1347  *
1348  * @param  oscsel OSC clock select, MCG_C7[OSCSEL].
1349  *
1350  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1351  * @retval kStatus_Success Switched to the target mode successfully.
1352  */
1353 status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel);
1354 
1355 /*!
1356  * @brief Sets the MCG to PEE mode during system boot up.
1357  *
1358  * This function sets the MCG to PEE mode from reset mode. It can also be used to
1359  * set up the MCG during system boot up.
1360  *
1361  * @param   oscsel OSC clock select, MCG_C7[OSCSEL].
1362  * @param   pllcs  The PLL selection, PLLCS.
1363  * @param   config Pointer to the PLL configuration.
1364  *
1365  * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
1366  * @retval kStatus_Success Switched to the target mode successfully.
1367  */
1368 status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config);
1369 
1370 /*!
1371  * @brief Sets the MCG to a target mode.
1372  *
1373  * This function sets MCG to a target mode defined by the configuration
1374  * structure. If switching to the target mode fails, this function
1375  * chooses the correct path.
1376  *
1377  * @param  config Pointer to the target MCG mode configuration structure.
1378  * @return Return kStatus_Success if switched successfully; Otherwise, it returns an error code #_mcg_status.
1379  *
1380  * @note If the external clock is used in the target mode, ensure that it is
1381  * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this
1382  * function.
1383  */
1384 status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
1385 
1386 /*@}*/
1387 
1388 #if defined(__cplusplus)
1389 }
1390 #endif /* __cplusplus */
1391 
1392 /*! @} */
1393 
1394 #endif /* _FSL_CLOCK_H_ */
1395