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