Kinetis MCUXpresso: Update the clock drivers

Updated driver includes
1. Bug fixes
2. Formatting updates.
3. Fix for warnings
4. Better code commenting

Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
pull/11023/head
Mahesh Mahadevan 2019-06-28 09:55:50 -05:00 committed by Evelyne Donnaes
parent d65a7d36dc
commit 24efeb84fe
20 changed files with 7847 additions and 3051 deletions

View File

@ -1,32 +1,9 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright (c) 2016 - 2017 , NXP * Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
@ -65,7 +42,7 @@
* *
* When set to 0, peripheral drivers will enable clock in initialize function * When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral * and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could contol the clock out of * driver will not control the clock, application could control the clock out of
* the driver. * the driver.
* *
* @note All drivers share this feature switcher. If it is set to 1, application * @note All drivers share this feature switcher. If it is set to 1, application
@ -81,25 +58,32 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CLOCK driver version 2.2.2. */ /*! @brief CLOCK driver version 2.3.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 2)) #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/ /*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (180000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8 MHz: * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Set up the OSC0 * Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. * CLOCK_InitOsc0(...);
* Set the XTAL0 value to the clock driver.
* CLOCK_SetXtal0Freq(80000000);
* @endcode * @endcode
* *
* This is important for the multicore platforms where only one core needs to set up the * This is important for the multicore platforms where only one core needs to set up the
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
@ -110,7 +94,7 @@ extern uint32_t g_xtal0Freq;
* the clock. All other cores need to call the CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
/*! @brief IRC48M clock frequency in Hz. */ /*! @brief IRC48M clock frequency in Hz. */
#define MCG_INTERNAL_IRC_48M 48000000U #define MCG_INTERNAL_IRC_48M 48000000U
@ -358,12 +342,12 @@ typedef enum _clock_name
/*! @brief USB clock source definition. */ /*! @brief USB clock source definition. */
typedef enum _clock_usb_src typedef enum _clock_usb_src
{ {
kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */
kCLOCK_UsbSrcUsbPfd = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(2U), /*!< Use USBPFDCLK. */ kCLOCK_UsbSrcUsbPfd = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(2U), /*!< Use USBPFDCLK. */
kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */ kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U), /*!< Use USB_CLKIN. */ kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U), /*!< Use USB_CLKIN. */
kCLOCK_UsbSrcUnused = 0xFFFFFFFFU, /*!< Used when the function does not kCLOCK_UsbSrcUnused = (int)0xFFFFFFFFU, /*!< Used when the function does not
care the clock source. */ care the clock source. */
} clock_usb_src_t; } clock_usb_src_t;
/*! @brief Source of the USB HS PHY. */ /*! @brief Source of the USB HS PHY. */
@ -375,10 +359,10 @@ typedef enum _clock_usb_phy_src
/*! @brief Source of the USB HS PFD clock (USB1PFDCLK) */ /*! @brief Source of the USB HS PFD clock (USB1PFDCLK) */
typedef enum _clock_usb_pfd_src typedef enum _clock_usb_pfd_src
{ {
kCLOCK_UsbPfdSrcExt = 0U, /*!< Use external crystal. */ kCLOCK_UsbPfdSrcExt = 0U, /*!< Use external crystal. */
kCLOCK_UsbPfdSrcFracDivBy4 = 1U, /*!< Use PFD_FRAC output divided by 4. */ kCLOCK_UsbPfdSrcFracDivBy4 = 1U, /*!< Use PFD_FRAC output divided by 4. */
kCLOCK_UsbPfdSrcFracDivBy2 = 2U, /*!< Use PFD_FRAC output divided by 2. */ kCLOCK_UsbPfdSrcFracDivBy2 = 2U, /*!< Use PFD_FRAC output divided by 2. */
kCLOCK_UsbPfdSrcFrac = 3U, /*!< Use PFD_FRAC output. */ kCLOCK_UsbPfdSrcFrac = 3U, /*!< Use PFD_FRAC output. */
} clock_usb_pfd_src_t; } clock_usb_pfd_src_t;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
@ -413,70 +397,70 @@ typedef enum _clock_usb_pfd_src
typedef enum _clock_ip_name typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U), kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U),
kCLOCK_I2c3 = CLK_GATE_DEFINE(0x1028U, 7U), kCLOCK_I2c3 = CLK_GATE_DEFINE(0x1028U, 7U),
kCLOCK_Uart4 = CLK_GATE_DEFINE(0x1028U, 10U), kCLOCK_Uart4 = CLK_GATE_DEFINE(0x1028U, 10U),
kCLOCK_Enet0 = CLK_GATE_DEFINE(0x102CU, 0U), kCLOCK_Enet0 = CLK_GATE_DEFINE(0x102CU, 0U),
kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x102CU, 4U), kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x102CU, 4U),
kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x102CU, 9U), kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x102CU, 9U),
kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x102CU, 10U), kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x102CU, 10U),
kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U), kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U),
kCLOCK_Dac1 = CLK_GATE_DEFINE(0x102CU, 13U), kCLOCK_Dac1 = CLK_GATE_DEFINE(0x102CU, 13U),
kCLOCK_Rnga0 = CLK_GATE_DEFINE(0x1030U, 0U), kCLOCK_Rnga0 = CLK_GATE_DEFINE(0x1030U, 0U),
kCLOCK_Usbhs0 = CLK_GATE_DEFINE(0x1030U, 1U), kCLOCK_Usbhs0 = CLK_GATE_DEFINE(0x1030U, 1U),
kCLOCK_UsbhsPhy0 = CLK_GATE_DEFINE(0x1030U, 2U), kCLOCK_UsbhsPhy0 = CLK_GATE_DEFINE(0x1030U, 2U),
kCLOCK_UsbhsDcd0 = CLK_GATE_DEFINE(0x1030U, 3U), kCLOCK_UsbhsDcd0 = CLK_GATE_DEFINE(0x1030U, 3U),
kCLOCK_Flexcan1 = CLK_GATE_DEFINE(0x1030U, 4U), kCLOCK_Flexcan1 = CLK_GATE_DEFINE(0x1030U, 4U),
kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U), kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U),
kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U), kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U),
kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U), kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U),
kCLOCK_Adc1 = CLK_GATE_DEFINE(0x1030U, 27U), kCLOCK_Adc1 = CLK_GATE_DEFINE(0x1030U, 27U),
kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U), kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U),
kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U), kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U),
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U), kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U),
kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U), kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U),
kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U), kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
kCLOCK_Uart3 = CLK_GATE_DEFINE(0x1034U, 13U), kCLOCK_Uart3 = CLK_GATE_DEFINE(0x1034U, 13U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp3 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp3 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U), kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Flexcan0 = CLK_GATE_DEFINE(0x103CU, 4U), kCLOCK_Flexcan0 = CLK_GATE_DEFINE(0x103CU, 4U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U),
kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U),
kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U), kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U),
kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U), kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U), kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U),
kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U), kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U),
kCLOCK_Sdramc0 = CLK_GATE_DEFINE(0x1040U, 3U), kCLOCK_Sdramc0 = CLK_GATE_DEFINE(0x1040U, 3U),
} clock_ip_name_t; } clock_ip_name_t;
/*!@brief SIM configuration structure for clock setting. */ /*!@brief SIM configuration structure for clock setting. */
@ -500,34 +484,30 @@ typedef enum _osc_mode
#endif #endif
kOSC_ModeOscHighGain = 0U kOSC_ModeOscHighGain = 0U
#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
| | MCG_C2_EREFS_MASK
MCG_C2_EREFS_MASK
#else #else
| | MCG_C2_EREFS0_MASK
MCG_C2_EREFS0_MASK
#endif #endif
#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
| | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
#else #else
| | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
#endif #endif
} osc_mode_t; } osc_mode_t;
/*! @brief Oscillator capacitor load setting.*/ /*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load enum _osc_cap_load
{ {
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
}; };
/*! @brief OSCERCLK enable mode. */ /*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode enum _oscer_enable_mode
{ {
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
}; };
@ -635,31 +615,31 @@ typedef enum _mcg_monitor_mode
enum _mcg_status enum _mcg_status
{ {
kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */
kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific
function. */ function. */
kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */
kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */
kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */
kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */
kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because
it is in use. */ it is in use. */
}; };
/*! @brief MCG status flags. */ /*! @brief MCG status flags. */
enum _mcg_status_flags_t enum _mcg_status_flags_t
{ {
kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */ kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */
kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */ kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */
kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */ kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */
kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */ kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */
kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */ kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */
kMCG_ExtPllLostFlag = (1U << 9U), /*!< External PLL lost. */ kMCG_ExtPllLostFlag = (1U << 9U), /*!< External PLL lost. */
}; };
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcg_irclk_enable_mode enum _mcg_irclk_enable_mode
{ {
kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -827,18 +807,20 @@ static inline void CLOCK_SetTpmClock(uint32_t src)
*/ */
static inline void CLOCK_SetTraceClock(uint32_t src, uint32_t divValue, uint32_t fracValue) static inline void CLOCK_SetTraceClock(uint32_t src, uint32_t divValue, uint32_t fracValue)
{ {
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src)); SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src));
SIM->CLKDIV4 = SIM_CLKDIV4_TRACEDIV(divValue) | SIM_CLKDIV4_TRACEFRAC(fracValue); SIM->CLKDIV4 = SIM_CLKDIV4_TRACEDIV(divValue) | SIM_CLKDIV4_TRACEFRAC(fracValue);
} }
/*! /*!
* @brief Set PLLFLLSEL clock source. * @brief Set PLLFLLSEL clock source.
* *
* @param src The value to set PLLFLLSEL clock source. * @param src The value to set PLLFLLSEL clock source.
* @param divValue PLLFLL clock divider divisor.
* @param fracValue PLLFLL clock divider fraction.
*/ */
static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue) static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue)
{ {
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src)); SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src));
SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue); SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue);
} }
@ -1026,6 +1008,13 @@ uint32_t CLOCK_GetEr32kClkFreq(void);
*/ */
uint32_t CLOCK_GetOsc0ErClkFreq(void); uint32_t CLOCK_GetOsc0ErClkFreq(void);
/*!
* @brief Get the OSC0 external reference divided clock frequency.
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetOsc0ErClkDivFreq(void);
/*! /*!
* @brief Get the OSC0 external reference undivided clock frequency (OSC0ERCLK_UNDIV). * @brief Get the OSC0 external reference undivided clock frequency (OSC0ERCLK_UNDIV).
* *
@ -1156,7 +1145,7 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
} }
else else
{ {
MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
} }
} }
@ -1172,8 +1161,8 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
* @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
* @param ircs MCGIRCLK clock source, choose fast or slow. * @param ircs MCGIRCLK clock source, choose fast or slow.
* @param fcrdiv Fast IRC divider setting (\c FCRDIV). * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
* @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success MCGIRCLK configuration finished successfully. * @retval kStatus_Success MCGIRCLK configuration finished successfully.
*/ */
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
@ -1187,7 +1176,7 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
* *
* @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success External reference clock set successfully. * @retval kStatus_Success External reference clock set successfully.
*/ */
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
@ -1201,7 +1190,7 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
*/ */
static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv) static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
{ {
MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv); MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
} }
/*! /*!
@ -1255,6 +1244,15 @@ uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv,
*/ */
void CLOCK_SetPllClkSel(mcg_pll_clk_select_t pllcs); void CLOCK_SetPllClkSel(mcg_pll_clk_select_t pllcs);
/*!
* brief Sets the OSC0 clock monitor mode.
*
* This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
/*@}*/ /*@}*/
/*! @name MCG clock lock monitor functions. */ /*! @name MCG clock lock monitor functions. */
@ -1306,20 +1304,20 @@ void CLOCK_SetExtPllMonitorMode(mcg_monitor_mode_t mode);
* *
* Example: * Example:
* @code * @code
// To check the clock lost lock status of OSC0 and PLL0. * To check the clock lost lock status of OSC0 and PLL0.
uint32_t mcgFlags; * uint32_t mcgFlags;
*
mcgFlags = CLOCK_GetStatusFlags(); * mcgFlags = CLOCK_GetStatusFlags();
*
if (mcgFlags & kMCG_Osc0LostFlag) * if (mcgFlags & kMCG_Osc0LostFlag)
{ * {
// OSC0 clock lock lost. Do something. * OSC0 clock lock lost. Do something.
} * }
if (mcgFlags & kMCG_Pll0LostFlag) * if (mcgFlags & kMCG_Pll0LostFlag)
{ * {
// PLL0 clock lock lost. Do something. * PLL0 clock lock lost. Do something.
} * }
@endcode * @endcode
* *
* @return Logical OR value of the @ref _mcg_status_flags_t. * @return Logical OR value of the @ref _mcg_status_flags_t.
*/ */
@ -1333,10 +1331,10 @@ uint32_t CLOCK_GetStatusFlags(void);
* *
* Example: * Example:
* @code * @code
// To clear the clock lost lock status flags of OSC0 and PLL0. * To clear the clock lost lock status flags of OSC0 and PLL0.
*
CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
@endcode * @endcode
* *
* @param mask The status flags to clear. This is a logical OR of members of the * @param mask The status flags to clear. This is a logical OR of members of the
* enumeration @ref _mcg_status_flags_t. * enumeration @ref _mcg_status_flags_t.
@ -1394,7 +1392,7 @@ static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *
* *
* Example: * Example:
@code @code
// To enable only 2 pF and 8 pF capacitor load, please use like this. To enable only 2 pF and 8 pF capacitor load, please use like this.
OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
@endcode @endcode
*/ */
@ -1620,7 +1618,7 @@ status_t CLOCK_SetPeeMode(void);
* @brief Switches the MCG to FBE mode from the external mode. * @brief Switches the MCG to FBE mode from the external mode.
* *
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock souce and PLL is disabled. However, * The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful * the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode: * during the mode switch. For example, to switch from PEE mode to FEI mode:
* *
@ -1638,7 +1636,7 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void);
* @brief Switches the MCG to FBI mode from internal modes. * @brief Switches the MCG to FBI mode from internal modes.
* *
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock souce and PLL is disabled. However, * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful * FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode: * during the mode switch. For example, to switch from PEI mode to FEE mode:
* *
@ -1691,7 +1689,7 @@ status_t CLOCK_BootToFeeMode(
* @brief Sets the MCG to BLPI mode during system boot up. * @brief Sets the MCG to BLPI mode during system boot up.
* *
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param fcrdiv Fast IRC divider, FCRDIV. * @param fcrdiv Fast IRC divider, FCRDIV.
* @param ircs The internal reference clock to select, IRCS. * @param ircs The internal reference clock to select, IRCS.
@ -1703,10 +1701,10 @@ status_t CLOCK_BootToFeeMode(
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
/*! /*!
* @brief Sets the MCG to BLPE mode during sytem boot up. * @brief Sets the MCG to BLPE mode during system boot up.
* *
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param oscsel OSC clock select, MCG_C7[OSCSEL].
* *
@ -1746,6 +1744,16 @@ status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mc
*/ */
status_t CLOCK_SetMcgConfig(mcg_config_t const *config); status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
/*!
* @brief Use DWT to delay at least for some time.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/*@}*/ /*@}*/
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -1,31 +1,9 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
@ -39,14 +17,32 @@
/*! @file */ /*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Configurations
******************************************************************************/ ******************************************************************************/
/*! @brief Configures whether to check a parameter in a function.
*
* Some MCG settings must be changed with conditions, for example:
* 1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when
* MCGIRCLK is used as a system clock source.
* 2. MCG_C7[OSCSEL] should not be changed when the external reference clock is used
* as a system clock source. For example, in FBE/BLPE/PBE modes.
* 3. The users should only switch between the supported clock modes.
*
* MCG functions check the parameter and MCG status before setting, if not allowed
* to change, the functions return error. The parameter checking increases code size,
* if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to
* disable parameter checking.
*/
#ifndef MCG_CONFIG_CHECK_PARAM
#define MCG_CONFIG_CHECK_PARAM 0U
#endif
/*! @brief Configure whether driver controls clock /*! @brief Configure whether driver controls clock
* *
* When set to 0, peripheral drivers will enable clock in initialize function * When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral * and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could contol the clock out of * driver will not control the clock, application could control the clock out of
* the driver. * the driver.
* *
* @note All drivers share this feature switcher. If it is set to 1, application * @note All drivers share this feature switcher. If it is set to 1, application
@ -56,27 +52,38 @@
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0 #define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif #endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CLOCK driver version 2.2.0. */ /*! @brief CLOCK driver version 2.3.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/ /*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (120000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8 MHz: * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Set up the OSC0 * Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. * CLOCK_InitOsc0(...);
* Set the XTAL0 value to the clock driver.
* CLOCK_SetXtal0Freq(80000000);
* @endcode * @endcode
* *
* This is important for the multicore platforms where only one core needs to set up the * This is important for the multicore platforms where only one core needs to set up the
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
@ -87,7 +94,7 @@ extern uint32_t g_xtal0Freq;
* the clock. All other cores need to call the CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
/*! @brief IRC48M clock frequency in Hz. */ /*! @brief IRC48M clock frequency in Hz. */
#define MCG_INTERNAL_IRC_48M 48000000U #define MCG_INTERNAL_IRC_48M 48000000U
@ -211,9 +218,9 @@ extern uint32_t g_xtal32Freq;
} }
/*! @brief Clock ip name array for MPU. */ /*! @brief Clock ip name array for MPU. */
#define MPU_CLOCKS \ #define MPU_CLOCKS \
{ \ { \
kCLOCK_Mpu0 \ kCLOCK_Sysmpu0 \
} }
/*! @brief Clock ip name array for FLEXIO. */ /*! @brief Clock ip name array for FLEXIO. */
@ -336,9 +343,9 @@ typedef enum _clock_name
/*! @brief USB clock source definition. */ /*! @brief USB clock source definition. */
typedef enum _clock_usb_src typedef enum _clock_usb_src
{ {
kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */
kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */ kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
} clock_usb_src_t; } clock_usb_src_t;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
@ -372,65 +379,65 @@ typedef enum _clock_usb_src
typedef enum _clock_ip_name typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U), kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U),
kCLOCK_I2c3 = CLK_GATE_DEFINE(0x1028U, 7U), kCLOCK_I2c3 = CLK_GATE_DEFINE(0x1028U, 7U),
kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x102CU, 4U), kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x102CU, 4U),
kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x102CU, 5U), kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x102CU, 5U),
kCLOCK_Lpuart2 = CLK_GATE_DEFINE(0x102CU, 6U), kCLOCK_Lpuart2 = CLK_GATE_DEFINE(0x102CU, 6U),
kCLOCK_Lpuart3 = CLK_GATE_DEFINE(0x102CU, 7U), kCLOCK_Lpuart3 = CLK_GATE_DEFINE(0x102CU, 7U),
kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x102CU, 9U), kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x102CU, 9U),
kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x102CU, 10U), kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x102CU, 10U),
kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U), kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U),
kCLOCK_Ltc0 = CLK_GATE_DEFINE(0x102CU, 17U), kCLOCK_Ltc0 = CLK_GATE_DEFINE(0x102CU, 17U),
kCLOCK_Emvsim0 = CLK_GATE_DEFINE(0x102CU, 20U), kCLOCK_Emvsim0 = CLK_GATE_DEFINE(0x102CU, 20U),
kCLOCK_Emvsim1 = CLK_GATE_DEFINE(0x102CU, 21U), kCLOCK_Emvsim1 = CLK_GATE_DEFINE(0x102CU, 21U),
kCLOCK_Lpuart4 = CLK_GATE_DEFINE(0x102CU, 22U), kCLOCK_Lpuart4 = CLK_GATE_DEFINE(0x102CU, 22U),
kCLOCK_Qspi0 = CLK_GATE_DEFINE(0x102CU, 26U), kCLOCK_Qspi0 = CLK_GATE_DEFINE(0x102CU, 26U),
kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x102CU, 31U), kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x102CU, 31U),
kCLOCK_Trng0 = CLK_GATE_DEFINE(0x1030U, 0U), kCLOCK_Trng0 = CLK_GATE_DEFINE(0x1030U, 0U),
kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U), kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U),
kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U), kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U),
kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U), kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U),
kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U), kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U),
kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U), kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U),
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_Lptmr1 = CLK_GATE_DEFINE(0x1038U, 4U), kCLOCK_Lptmr1 = CLK_GATE_DEFINE(0x1038U, 4U),
kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U), kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U),
kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U),
kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U), kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U),
kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U), kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U), kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U),
kCLOCK_Mpu0 = CLK_GATE_DEFINE(0x1040U, 2U), kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U),
kCLOCK_Sdramc0 = CLK_GATE_DEFINE(0x1040U, 3U), kCLOCK_Sdramc0 = CLK_GATE_DEFINE(0x1040U, 3U),
} clock_ip_name_t; } clock_ip_name_t;
/*!@brief SIM configuration structure for clock setting. */ /*!@brief SIM configuration structure for clock setting. */
@ -454,34 +461,30 @@ typedef enum _osc_mode
#endif #endif
kOSC_ModeOscHighGain = 0U kOSC_ModeOscHighGain = 0U
#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
| | MCG_C2_EREFS_MASK
MCG_C2_EREFS_MASK
#else #else
| | MCG_C2_EREFS0_MASK
MCG_C2_EREFS0_MASK
#endif #endif
#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
| | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
#else #else
| | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
#endif #endif
} osc_mode_t; } osc_mode_t;
/*! @brief Oscillator capacitor load setting.*/ /*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load enum _osc_cap_load
{ {
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
}; };
/*! @brief OSCERCLK enable mode. */ /*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode enum _oscer_enable_mode
{ {
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
}; };
@ -589,30 +592,30 @@ typedef enum _mcg_monitor_mode
enum _mcg_status enum _mcg_status
{ {
kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */
kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific
function. */ function. */
kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */
kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */
kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */
kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */
kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because
it is in use. */ it is in use. */
}; };
/*! @brief MCG status flags. */ /*! @brief MCG status flags. */
enum _mcg_status_flags_t enum _mcg_status_flags_t
{ {
kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */ kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */
kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */ kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */
kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */ kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */
kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */ kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */
kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */ kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */
}; };
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcg_irclk_enable_mode enum _mcg_irclk_enable_mode
{ {
kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -778,18 +781,20 @@ static inline void CLOCK_SetFlexio0Clock(uint32_t src)
*/ */
static inline void CLOCK_SetTraceClock(uint32_t src, uint32_t divValue, uint32_t fracValue) static inline void CLOCK_SetTraceClock(uint32_t src, uint32_t divValue, uint32_t fracValue)
{ {
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src)); SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src));
SIM->CLKDIV4 = SIM_CLKDIV4_TRACEDIV(divValue) | SIM_CLKDIV4_TRACEFRAC(fracValue); SIM->CLKDIV4 = SIM_CLKDIV4_TRACEDIV(divValue) | SIM_CLKDIV4_TRACEFRAC(fracValue);
} }
/*! /*!
* @brief Set PLLFLLSEL clock source. * @brief Set PLLFLLSEL clock source.
* *
* @param src The value to set PLLFLLSEL clock source. * @param src The value to set PLLFLLSEL clock source.
* @param divValue PLLFLL clock divider divisor.
* @param fracValue PLLFLL clock divider fraction.
*/ */
static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue) static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue)
{ {
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src)); SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src));
SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue); SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue);
} }
@ -925,6 +930,13 @@ uint32_t CLOCK_GetOsc0ErClkUndivFreq(void);
*/ */
uint32_t CLOCK_GetOsc0ErClkFreq(void); uint32_t CLOCK_GetOsc0ErClkFreq(void);
/*!
* @brief Get the OSC0 external reference divided clock frequency.
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetOsc0ErClkDivFreq(void);
/*! /*!
* @brief Set the clock configure in SIM module. * @brief Set the clock configure in SIM module.
* *
@ -1027,7 +1039,7 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
} }
else else
{ {
MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
} }
} }
@ -1043,8 +1055,8 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
* @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
* @param ircs MCGIRCLK clock source, choose fast or slow. * @param ircs MCGIRCLK clock source, choose fast or slow.
* @param fcrdiv Fast IRC divider setting (\c FCRDIV). * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
* @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success MCGIRCLK configuration finished successfully. * @retval kStatus_Success MCGIRCLK configuration finished successfully.
*/ */
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
@ -1058,7 +1070,7 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
* *
* @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success External reference clock set successfully. * @retval kStatus_Success External reference clock set successfully.
*/ */
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
@ -1072,7 +1084,7 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
*/ */
static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv) static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
{ {
MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv); MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
} }
/*! /*!
@ -1116,6 +1128,15 @@ static inline void CLOCK_DisablePll0(void)
*/ */
uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv); uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv);
/*!
* brief Sets the OSC0 clock monitor mode.
*
* This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
/*@}*/ /*@}*/
/*! @name MCG clock lock monitor functions. */ /*! @name MCG clock lock monitor functions. */
@ -1157,20 +1178,20 @@ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode);
* *
* Example: * Example:
* @code * @code
// To check the clock lost lock status of OSC0 and PLL0. * To check the clock lost lock status of OSC0 and PLL0.
uint32_t mcgFlags; * uint32_t mcgFlags;
*
mcgFlags = CLOCK_GetStatusFlags(); * mcgFlags = CLOCK_GetStatusFlags();
*
if (mcgFlags & kMCG_Osc0LostFlag) * if (mcgFlags & kMCG_Osc0LostFlag)
{ * {
// OSC0 clock lock lost. Do something. * OSC0 clock lock lost. Do something.
} * }
if (mcgFlags & kMCG_Pll0LostFlag) * if (mcgFlags & kMCG_Pll0LostFlag)
{ * {
// PLL0 clock lock lost. Do something. * PLL0 clock lock lost. Do something.
} * }
@endcode * @endcode
* *
* @return Logical OR value of the @ref _mcg_status_flags_t. * @return Logical OR value of the @ref _mcg_status_flags_t.
*/ */
@ -1184,10 +1205,10 @@ uint32_t CLOCK_GetStatusFlags(void);
* *
* Example: * Example:
* @code * @code
// To clear the clock lost lock status flags of OSC0 and PLL0. * To clear the clock lost lock status flags of OSC0 and PLL0.
*
CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
@endcode * @endcode
* *
* @param mask The status flags to clear. This is a logical OR of members of the * @param mask The status flags to clear. This is a logical OR of members of the
* enumeration @ref _mcg_status_flags_t. * enumeration @ref _mcg_status_flags_t.
@ -1245,7 +1266,7 @@ static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *
* *
* Example: * Example:
@code @code
// To enable only 2 pF and 8 pF capacitor load, please use like this. To enable only 2 pF and 8 pF capacitor load, please use like this.
OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
@endcode @endcode
*/ */
@ -1471,7 +1492,7 @@ status_t CLOCK_SetPeeMode(void);
* @brief Switches the MCG to FBE mode from the external mode. * @brief Switches the MCG to FBE mode from the external mode.
* *
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock souce and PLL is disabled. However, * The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful * the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode: * during the mode switch. For example, to switch from PEE mode to FEI mode:
* *
@ -1489,7 +1510,7 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void);
* @brief Switches the MCG to FBI mode from internal modes. * @brief Switches the MCG to FBI mode from internal modes.
* *
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock souce and PLL is disabled. However, * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful * FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode: * during the mode switch. For example, to switch from PEI mode to FEE mode:
* *
@ -1542,7 +1563,7 @@ status_t CLOCK_BootToFeeMode(
* @brief Sets the MCG to BLPI mode during system boot up. * @brief Sets the MCG to BLPI mode during system boot up.
* *
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param fcrdiv Fast IRC divider, FCRDIV. * @param fcrdiv Fast IRC divider, FCRDIV.
* @param ircs The internal reference clock to select, IRCS. * @param ircs The internal reference clock to select, IRCS.
@ -1554,10 +1575,10 @@ status_t CLOCK_BootToFeeMode(
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
/*! /*!
* @brief Sets the MCG to BLPE mode during sytem boot up. * @brief Sets the MCG to BLPE mode during system boot up.
* *
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param oscsel OSC clock select, MCG_C7[OSCSEL].
* *
@ -1597,6 +1618,16 @@ status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mc
*/ */
status_t CLOCK_SetMcgConfig(mcg_config_t const *config); status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
/*!
* @brief Use DWT to delay at least for some time.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/*@}*/ /*@}*/
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -1,40 +1,22 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "fsl_common.h"
#include "fsl_clock.h" #include "fsl_clock.h"
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.clock"
#endif
#if (defined(OSC) && !(defined(OSC0))) #if (defined(OSC) && !(defined(OSC0)))
#define OSC0 OSC #define OSC0 OSC
#endif #endif
@ -57,10 +39,9 @@
******************************************************************************/ ******************************************************************************/
/* External XTAL0 (OSC0) clock frequency. */ /* External XTAL0 (OSC0) clock frequency. */
uint32_t g_xtal0Freq; volatile uint32_t g_xtal0Freq;
/* External XTAL32K clock frequency. */ /* External XTAL32K clock frequency. */
uint32_t g_xtal32Freq; volatile uint32_t g_xtal32Freq;
/******************************************************************************* /*******************************************************************************
* Prototypes * Prototypes
@ -126,6 +107,11 @@ static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq)
return range; return range;
} }
/*!
* brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetOsc0ErClkFreq(void) uint32_t CLOCK_GetOsc0ErClkFreq(void)
{ {
if (OSC0->CR & OSC_CR_ERCLKEN_MASK) if (OSC0->CR & OSC_CR_ERCLKEN_MASK)
@ -140,6 +126,11 @@ uint32_t CLOCK_GetOsc0ErClkFreq(void)
} }
} }
/*!
* brief Get the external reference 32K clock frequency (ERCLK32K).
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetEr32kClkFreq(void) uint32_t CLOCK_GetEr32kClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -164,11 +155,21 @@ uint32_t CLOCK_GetEr32kClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the platform clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetPlatClkFreq(void) uint32_t CLOCK_GetPlatClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
} }
/*!
* brief Get the flash clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetFlashClkFreq(void) uint32_t CLOCK_GetFlashClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -179,6 +180,11 @@ uint32_t CLOCK_GetFlashClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the bus clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetBusClkFreq(void) uint32_t CLOCK_GetBusClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -189,11 +195,26 @@ uint32_t CLOCK_GetBusClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the core clock or system clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetCoreSysClkFreq(void) uint32_t CLOCK_GetCoreSysClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
} }
/*!
* brief Gets the clock frequency for a specific clock name.
*
* This function checks the current clock configurations and then calculates
* the clock frequency for a specific clock name defined in clock_name_t.
* The MCG must be properly configured before using this function.
*
* param clockName Clock names defined in clock_name_t
* return Clock frequency value in Hertz
*/
uint32_t CLOCK_GetFreq(clock_name_t clockName) uint32_t CLOCK_GetFreq(clock_name_t clockName)
{ {
uint32_t freq; uint32_t freq;
@ -233,12 +254,26 @@ uint32_t CLOCK_GetFreq(clock_name_t clockName)
return freq; return freq;
} }
/*!
* brief Set the clock configure in SIM module.
*
* This function sets system layer clock settings in SIM module.
*
* param config Pointer to the configure structure.
*/
void CLOCK_SetSimConfig(sim_clock_config_t const *config) void CLOCK_SetSimConfig(sim_clock_config_t const *config)
{ {
SIM->CLKDIV1 = config->clkdiv1; SIM->CLKDIV1 = config->clkdiv1;
CLOCK_SetEr32kClock(config->er32kSrc); CLOCK_SetEr32kClock(config->er32kSrc);
} }
/*! brief Enable USB FS clock.
*
* param src USB FS clock source.
* param freq The frequency specified by src.
* retval true The clock is set successfully.
* retval false The clock source is invalid to get proper USB FS clock.
*/
bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
{ {
bool ret = true; bool ret = true;
@ -265,6 +300,14 @@ bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
return ret; return ret;
} }
/*!
* brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
*
* This function gets the MCG_Lite internal reference clock frequency in Hz based
* on the current MCG register value.
*
* return The frequency of MCGIRCLK.
*/
uint32_t CLOCK_GetInternalRefClkFreq(void) uint32_t CLOCK_GetInternalRefClkFreq(void)
{ {
uint8_t divider1 = MCG_SC_FCRDIV_VAL; uint8_t divider1 = MCG_SC_FCRDIV_VAL;
@ -273,6 +316,14 @@ uint32_t CLOCK_GetInternalRefClkFreq(void)
return CLOCK_GetLircClkFreq() >> (divider1 + divider2); return CLOCK_GetLircClkFreq() >> (divider1 + divider2);
} }
/*
* brief Gets the current MCGPCLK frequency.
*
* This function gets the MCGPCLK frequency in Hz based on the current MCG_Lite
* register settings.
*
* return The frequency of MCGPCLK.
*/
uint32_t CLOCK_GetPeriphClkFreq(void) uint32_t CLOCK_GetPeriphClkFreq(void)
{ {
/* Check whether the HIRC is enabled. */ /* Check whether the HIRC is enabled. */
@ -286,6 +337,14 @@ uint32_t CLOCK_GetPeriphClkFreq(void)
} }
} }
/*!
* brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency.
*
* This function gets the MCG_Lite output clock frequency in Hz based on the current
* MCG_Lite register value.
*
* return The frequency of MCGOUTCLK.
*/
uint32_t CLOCK_GetOutClkFreq(void) uint32_t CLOCK_GetOutClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -311,6 +370,13 @@ uint32_t CLOCK_GetOutClkFreq(void)
return freq; return freq;
} }
/*!
* brief Gets the current MCG_Lite mode.
*
* This function checks the MCG_Lite registers and determines the current MCG_Lite mode.
*
* return The current MCG_Lite mode or error code.
*/
mcglite_mode_t CLOCK_GetMode(void) mcglite_mode_t CLOCK_GetMode(void)
{ {
mcglite_mode_t mode; mcglite_mode_t mode;
@ -341,6 +407,15 @@ mcglite_mode_t CLOCK_GetMode(void)
return mode; return mode;
} }
/*!
* brief Sets the MCG_Lite configuration.
*
* This function configures the MCG_Lite, includes the output clock source, MCGIRCLK
* settings, HIRC settings, and so on. See ref mcglite_config_t for details.
*
* param targetConfig Pointer to the target MCG_Lite mode configuration structure.
* return Error code.
*/
status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig) status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig)
{ {
assert(targetConfig); assert(targetConfig);
@ -383,6 +458,13 @@ status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Initializes the OSC0.
*
* This function initializes the OSC0 according to the board configuration.
*
* param config Pointer to the OSC0 configuration structure.
*/
void CLOCK_InitOsc0(osc_config_t const *config) void CLOCK_InitOsc0(osc_config_t const *config)
{ {
uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq); uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq);
@ -401,8 +483,39 @@ void CLOCK_InitOsc0(osc_config_t const *config)
} }
} }
/*!
* brief Deinitializes the OSC0.
*
* This function deinitializes the OSC0.
*/
void CLOCK_DeinitOsc0(void) void CLOCK_DeinitOsc0(void)
{ {
OSC0->CR = 0U; OSC0->CR = 0U;
MCG->C2 &= MCG_C2_IRCS_MASK; MCG->C2 &= MCG_C2_IRCS_MASK;
} }
/*!
* brief Delay at least for several microseconds.
* Please note that, this API will calculate the microsecond period with the maximum devices
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* param delay_us Delay time in unit of microsecond.
*/
__attribute__((weak)) void SDK_DelayAtLeastUs(uint32_t delay_us)
{
assert(0U != delay_us);
uint32_t count = (uint32_t)USEC_TO_COUNT(delay_us, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
/*
* Calculate the real delay count depend on the excute instructions cycles,
* users can change the divider value to adapt to the real IDE optimise level.
*/
count = (count / 4U);
for (; count > 0UL; count--)
{
__NOP();
}
}

View File

@ -1,77 +1,80 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
#define _FSL_CLOCK_H_ #define _FSL_CLOCK_H_
#include "fsl_device_registers.h" #include "fsl_common.h"
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
/*! @addtogroup clock */ /*! @addtogroup clock */
/*! @{ */ /*! @{ */
/*! @file */
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Configure whether driver controls clock
*
* When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could control the clock out of
* the driver.
*
* @note All drivers share this feature switcher. If it is set to 1, application
* should handle clock enable and disable for all drivers.
*/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @brief Clock driver version. */ /*! @name Driver version */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ /*@{*/
/*! @brief CLOCK driver version 2.2.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (48000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz, when the clock is setup, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in to clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8MHz, * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Setup the OSC0 * CLOCK_InitOsc0(...); // Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to clock driver. * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to clock driver.
* @endcode * @endcode
* *
* This is important for the multicore platforms, only one core needs to setup * This is important for the multicore platforms where one core needs to set up the
* OSC0 using CLOCK_InitOsc0, all other cores need to call CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief The external XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
* The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz, when the clock is setup, use the * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal32Freq to set the value in to clock driver. * function CLOCK_SetXtal32Freq to set the value in the clock driver.
* *
* This is important for the multicore platforms, only one core needs to setup * This is important for the multicore platforms where one core needs to set up
* the clock, all other cores need to call CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
/*! @brief Clock ip name array for DMAMUX. */ /*! @brief Clock ip name array for DMAMUX. */
#define DMAMUX_CLOCKS \ #define DMAMUX_CLOCKS \
@ -170,9 +173,9 @@ extern uint32_t g_xtal32Freq;
} }
/*! @brief Clock ip name array for CMP. */ /*! @brief Clock ip name array for CMP. */
#define CMP_CLOCKS \ #define CMP_CLOCKS \
{ \ { \
kCLOCK_Cmp0, kCLOCK_Cmp1, kCLOCK_Cmp2 \ kCLOCK_Cmp0 \
} }
/*! /*!
@ -228,7 +231,7 @@ typedef enum _clock_name
typedef enum _clock_usb_src typedef enum _clock_usb_src
{ {
kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U), /*!< Use IRC48M. */ kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U), /*!< Use IRC48M. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
} clock_usb_src_t; } clock_usb_src_t;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
@ -262,36 +265,34 @@ typedef enum _clock_usb_src
typedef enum _clock_ip_name typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U), kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U), kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U),
kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U), kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U),
kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U), kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U),
} clock_ip_name_t; } clock_ip_name_t;
@ -306,30 +307,30 @@ typedef struct _sim_clock_config
/*! @brief Oscillator capacitor load setting.*/ /*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load enum _osc_cap_load
{ {
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
}; };
/*! @brief OSCERCLK enable mode. */ /*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode enum _oscer_enable_mode
{ {
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
}; };
/*! @brief OSC configuration for OSCERCLK. */ /*! @brief The OSC configuration for OSCERCLK. */
typedef struct _oscer_config typedef struct _oscer_config
{ {
uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of \ref _oscer_enable_mode. */ uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of \ref _oscer_enable_mode. */
} oscer_config_t; } oscer_config_t;
/*! @brief OSC work mode. */ /*! @brief The OSC work mode. */
typedef enum _osc_mode typedef enum _osc_mode
{ {
kOSC_ModeExt = 0U, /*!< Use external clock. */ kOSC_ModeExt = 0U, /*!< Use external clock. */
kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */ kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */
kOSC_ModeOscHighGain = MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */ kOSC_ModeOscHighGain = MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
} osc_mode_t; } osc_mode_t;
@ -339,7 +340,7 @@ typedef enum _osc_mode
* *
* Defines the configuration data structure to initialize the OSC. * Defines the configuration data structure to initialize the OSC.
* When porting to a new board, set the following members * When porting to a new board, set the following members
* according to board settings: * according to the board settings:
* 1. freq: The external frequency. * 1. freq: The external frequency.
* 2. workMode: The OSC module mode. * 2. workMode: The OSC module mode.
*/ */
@ -363,8 +364,8 @@ typedef enum _mcglite_clkout_src
/*! @brief MCG_Lite LIRC select. */ /*! @brief MCG_Lite LIRC select. */
typedef enum _mcglite_lirc_mode typedef enum _mcglite_lirc_mode
{ {
kMCGLITE_Lirc2M, /*!< Slow internal reference(LIRC) 2MHz clock selected */ kMCGLITE_Lirc2M, /*!< Slow internal reference(LIRC) 2 MHz clock selected */
kMCGLITE_Lirc8M, /*!< Slow internal reference(LIRC) 8MHz clock selected */ kMCGLITE_Lirc8M, /*!< Slow internal reference(LIRC) 8 MHz clock selected */
} mcglite_lirc_mode_t; } mcglite_lirc_mode_t;
/*! @brief MCG_Lite divider factor selection for clock source*/ /*! @brief MCG_Lite divider factor selection for clock source*/
@ -393,7 +394,7 @@ typedef enum _mcglite_mode
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcglite_irclk_enable_mode enum _mcglite_irclk_enable_mode
{ {
kMCGLITE_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCGLITE_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCGLITE_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCGLITE_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -416,26 +417,6 @@ typedef struct _mcglite_config
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*!
* @brief Set the XTAL0 frequency based on board setting.
*
* @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal0Freq(uint32_t freq)
{
g_xtal0Freq = freq;
}
/*!
* @brief Set the XTAL32/RTC_CLKIN frequency based on board setting.
*
* @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal32Freq(uint32_t freq)
{
g_xtal32Freq = freq;
}
/*! /*!
* @brief Enable the clock for specific IP. * @brief Enable the clock for specific IP.
* *
@ -647,7 +628,7 @@ static inline void CLOCK_SetSimSafeDivs(void)
/*! /*!
* @brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency. * @brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency.
* *
* This function gets the MCG_Lite output clock frequency (Hz) based on the current * This function gets the MCG_Lite output clock frequency in Hz based on the current
* MCG_Lite register value. * MCG_Lite register value.
* *
* @return The frequency of MCGOUTCLK. * @return The frequency of MCGOUTCLK.
@ -657,7 +638,7 @@ uint32_t CLOCK_GetOutClkFreq(void);
/*! /*!
* @brief Gets the MCG internal reference clock (MCGIRCLK) frequency. * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
* *
* This function gets the MCG_Lite internal reference clock frequency (Hz) based * This function gets the MCG_Lite internal reference clock frequency in Hz based
* on the current MCG register value. * on the current MCG register value.
* *
* @return The frequency of MCGIRCLK. * @return The frequency of MCGIRCLK.
@ -665,13 +646,13 @@ uint32_t CLOCK_GetOutClkFreq(void);
uint32_t CLOCK_GetInternalRefClkFreq(void); uint32_t CLOCK_GetInternalRefClkFreq(void);
/*! /*!
* @brief Gets the current MCGPCLK frequency. * @brief Gets the current MCGPCLK frequency.
* *
* This function gets the MCGPCLK frequency (Hertz) based on the current MCG_Lite * This function gets the MCGPCLK frequency in Hz based on the current MCG_Lite
* register settings. * register settings.
* *
* @return The frequency of MCGPCLK. * @return The frequency of MCGPCLK.
*/ */
uint32_t CLOCK_GetPeriphClkFreq(void); uint32_t CLOCK_GetPeriphClkFreq(void);
/*! @}*/ /*! @}*/
@ -686,15 +667,15 @@ uint32_t CLOCK_GetPeriphClkFreq(void);
* *
* This function checks the MCG_Lite registers and determines the current MCG_Lite mode. * This function checks the MCG_Lite registers and determines the current MCG_Lite mode.
* *
* @return Current MCG_Lite mode or error code. * @return The current MCG_Lite mode or error code.
*/ */
mcglite_mode_t CLOCK_GetMode(void); mcglite_mode_t CLOCK_GetMode(void);
/*! /*!
* @brief Sets the MCG_Lite configuration. * @brief Sets the MCG_Lite configuration.
* *
* This function configures the MCG_Lite, include output clock source, MCGIRCLK * This function configures the MCG_Lite, includes the output clock source, MCGIRCLK
* setting, HIRC setting and so on, see @ref mcglite_config_t for details. * settings, HIRC settings, and so on. See @ref mcglite_config_t for details.
* *
* @param targetConfig Pointer to the target MCG_Lite mode configuration structure. * @param targetConfig Pointer to the target MCG_Lite mode configuration structure.
* @return Error code. * @return Error code.
@ -712,8 +693,8 @@ status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig);
* @brief Configures the OSC external reference clock (OSCERCLK). * @brief Configures the OSC external reference clock (OSCERCLK).
* *
* This function configures the OSC external reference clock (OSCERCLK). * This function configures the OSC external reference clock (OSCERCLK).
* For example, to enable the OSCERCLK in normal mode and stop mode, and also set * This is an example to enable the OSCERCLK in normal mode and stop mode, and set
* the output divider to 1, as follows: * the output divider to 1.
* *
@code @code
oscer_config_t config = oscer_config_t config =
@ -741,12 +722,12 @@ static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *
/*! /*!
* @brief Sets the capacitor load configuration for the oscillator. * @brief Sets the capacitor load configuration for the oscillator.
* *
* This function sets the specified capacitors configuration for the oscillator. * This function sets the specified capacitor configuration for the oscillator.
* This should be done in the early system level initialization function call * This should be done in the early system level initialization function call
* based on the system configuration. * based on the system configuration.
* *
* @param base OSC peripheral address. * @param base OSC peripheral address.
* @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load. * @param capLoad OR'ed value for the capacitor load option.See \ref _osc_cap_load.
* *
* Example: * Example:
@code @code
@ -766,7 +747,7 @@ static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad)
} }
/*! /*!
* @brief Initialize OSC0. * @brief Initializes the OSC0.
* *
* This function initializes the OSC0 according to the board configuration. * This function initializes the OSC0 according to the board configuration.
* *
@ -783,6 +764,43 @@ void CLOCK_DeinitOsc0(void);
/*! @}*/ /*! @}*/
/*!
* @name External clock frequency
* @{
*/
/*!
* @brief Sets the XTAL0 frequency based on board settings.
*
* @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal0Freq(uint32_t freq)
{
g_xtal0Freq = freq;
}
/*!
* @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings.
*
* @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal32Freq(uint32_t freq)
{
g_xtal32Freq = freq;
}
/*!
* @brief Delay at least for several microseconds.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/* @} */
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -1,40 +1,22 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "fsl_common.h"
#include "fsl_clock.h" #include "fsl_clock.h"
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.clock"
#endif
#if (defined(OSC) && !(defined(OSC0))) #if (defined(OSC) && !(defined(OSC0)))
#define OSC0 OSC #define OSC0 OSC
#endif #endif
@ -57,10 +39,9 @@
******************************************************************************/ ******************************************************************************/
/* External XTAL0 (OSC0) clock frequency. */ /* External XTAL0 (OSC0) clock frequency. */
uint32_t g_xtal0Freq; volatile uint32_t g_xtal0Freq;
/* External XTAL32K clock frequency. */ /* External XTAL32K clock frequency. */
uint32_t g_xtal32Freq; volatile uint32_t g_xtal32Freq;
/******************************************************************************* /*******************************************************************************
* Prototypes * Prototypes
@ -126,6 +107,11 @@ static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq)
return range; return range;
} }
/*!
* brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetOsc0ErClkFreq(void) uint32_t CLOCK_GetOsc0ErClkFreq(void)
{ {
if (OSC0->CR & OSC_CR_ERCLKEN_MASK) if (OSC0->CR & OSC_CR_ERCLKEN_MASK)
@ -140,6 +126,11 @@ uint32_t CLOCK_GetOsc0ErClkFreq(void)
} }
} }
/*!
* brief Get the external reference 32K clock frequency (ERCLK32K).
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetEr32kClkFreq(void) uint32_t CLOCK_GetEr32kClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -164,11 +155,21 @@ uint32_t CLOCK_GetEr32kClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the platform clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetPlatClkFreq(void) uint32_t CLOCK_GetPlatClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
} }
/*!
* brief Get the flash clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetFlashClkFreq(void) uint32_t CLOCK_GetFlashClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -179,6 +180,11 @@ uint32_t CLOCK_GetFlashClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the bus clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetBusClkFreq(void) uint32_t CLOCK_GetBusClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -189,11 +195,26 @@ uint32_t CLOCK_GetBusClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the core clock or system clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetCoreSysClkFreq(void) uint32_t CLOCK_GetCoreSysClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
} }
/*!
* brief Gets the clock frequency for a specific clock name.
*
* This function checks the current clock configurations and then calculates
* the clock frequency for a specific clock name defined in clock_name_t.
* The MCG must be properly configured before using this function.
*
* param clockName Clock names defined in clock_name_t
* return Clock frequency value in Hertz
*/
uint32_t CLOCK_GetFreq(clock_name_t clockName) uint32_t CLOCK_GetFreq(clock_name_t clockName)
{ {
uint32_t freq; uint32_t freq;
@ -233,12 +254,26 @@ uint32_t CLOCK_GetFreq(clock_name_t clockName)
return freq; return freq;
} }
/*!
* brief Set the clock configure in SIM module.
*
* This function sets system layer clock settings in SIM module.
*
* param config Pointer to the configure structure.
*/
void CLOCK_SetSimConfig(sim_clock_config_t const *config) void CLOCK_SetSimConfig(sim_clock_config_t const *config)
{ {
SIM->CLKDIV1 = config->clkdiv1; SIM->CLKDIV1 = config->clkdiv1;
CLOCK_SetEr32kClock(config->er32kSrc); CLOCK_SetEr32kClock(config->er32kSrc);
} }
/*! brief Enable USB FS clock.
*
* param src USB FS clock source.
* param freq The frequency specified by src.
* retval true The clock is set successfully.
* retval false The clock source is invalid to get proper USB FS clock.
*/
bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
{ {
bool ret = true; bool ret = true;
@ -265,6 +300,14 @@ bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
return ret; return ret;
} }
/*!
* brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
*
* This function gets the MCG_Lite internal reference clock frequency in Hz based
* on the current MCG register value.
*
* return The frequency of MCGIRCLK.
*/
uint32_t CLOCK_GetInternalRefClkFreq(void) uint32_t CLOCK_GetInternalRefClkFreq(void)
{ {
uint8_t divider1 = MCG_SC_FCRDIV_VAL; uint8_t divider1 = MCG_SC_FCRDIV_VAL;
@ -273,6 +316,14 @@ uint32_t CLOCK_GetInternalRefClkFreq(void)
return CLOCK_GetLircClkFreq() >> (divider1 + divider2); return CLOCK_GetLircClkFreq() >> (divider1 + divider2);
} }
/*
* brief Gets the current MCGPCLK frequency.
*
* This function gets the MCGPCLK frequency in Hz based on the current MCG_Lite
* register settings.
*
* return The frequency of MCGPCLK.
*/
uint32_t CLOCK_GetPeriphClkFreq(void) uint32_t CLOCK_GetPeriphClkFreq(void)
{ {
/* Check whether the HIRC is enabled. */ /* Check whether the HIRC is enabled. */
@ -286,6 +337,14 @@ uint32_t CLOCK_GetPeriphClkFreq(void)
} }
} }
/*!
* brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency.
*
* This function gets the MCG_Lite output clock frequency in Hz based on the current
* MCG_Lite register value.
*
* return The frequency of MCGOUTCLK.
*/
uint32_t CLOCK_GetOutClkFreq(void) uint32_t CLOCK_GetOutClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -311,6 +370,13 @@ uint32_t CLOCK_GetOutClkFreq(void)
return freq; return freq;
} }
/*!
* brief Gets the current MCG_Lite mode.
*
* This function checks the MCG_Lite registers and determines the current MCG_Lite mode.
*
* return The current MCG_Lite mode or error code.
*/
mcglite_mode_t CLOCK_GetMode(void) mcglite_mode_t CLOCK_GetMode(void)
{ {
mcglite_mode_t mode; mcglite_mode_t mode;
@ -341,6 +407,15 @@ mcglite_mode_t CLOCK_GetMode(void)
return mode; return mode;
} }
/*!
* brief Sets the MCG_Lite configuration.
*
* This function configures the MCG_Lite, includes the output clock source, MCGIRCLK
* settings, HIRC settings, and so on. See ref mcglite_config_t for details.
*
* param targetConfig Pointer to the target MCG_Lite mode configuration structure.
* return Error code.
*/
status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig) status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig)
{ {
assert(targetConfig); assert(targetConfig);
@ -383,6 +458,13 @@ status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Initializes the OSC0.
*
* This function initializes the OSC0 according to the board configuration.
*
* param config Pointer to the OSC0 configuration structure.
*/
void CLOCK_InitOsc0(osc_config_t const *config) void CLOCK_InitOsc0(osc_config_t const *config)
{ {
uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq); uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq);
@ -401,8 +483,39 @@ void CLOCK_InitOsc0(osc_config_t const *config)
} }
} }
/*!
* brief Deinitializes the OSC0.
*
* This function deinitializes the OSC0.
*/
void CLOCK_DeinitOsc0(void) void CLOCK_DeinitOsc0(void)
{ {
OSC0->CR = 0U; OSC0->CR = 0U;
MCG->C2 &= MCG_C2_IRCS_MASK; MCG->C2 &= MCG_C2_IRCS_MASK;
} }
/*!
* brief Delay at least for several microseconds.
* Please note that, this API will calculate the microsecond period with the maximum devices
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* param delay_us Delay time in unit of microsecond.
*/
__attribute__((weak)) void SDK_DelayAtLeastUs(uint32_t delay_us)
{
assert(0U != delay_us);
uint32_t count = (uint32_t)USEC_TO_COUNT(delay_us, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
/*
* Calculate the real delay count depend on the excute instructions cycles,
* users can change the divider value to adapt to the real IDE optimise level.
*/
count = (count / 4U);
for (; count > 0UL; count--)
{
__NOP();
}
}

View File

@ -1,77 +1,79 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
#define _FSL_CLOCK_H_ #define _FSL_CLOCK_H_
#include "fsl_device_registers.h" #include "fsl_common.h"
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
/*! @addtogroup mcglite */ /*! @addtogroup clock */
/*! @{ */ /*! @{ */
/*! @file */
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Configure whether driver controls clock
*
* When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could control the clock out of
* the driver.
*
* @note All drivers share this feature switcher. If it is set to 1, application
* should handle clock enable and disable for all drivers.
*/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @brief Clock driver version. */ /*! @name Driver version */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ /*@{*/
/*! @brief CLOCK driver version 2.2.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*@}*/
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY 48000000
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz, when the clock is setup, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in to clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8MHz, * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Setup the OSC0 * CLOCK_InitOsc0(...); // Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to clock driver. * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to clock driver.
* @endcode * @endcode
* *
* This is important for the multicore platforms, only one core needs to setup * This is important for the multicore platforms where one core needs to set up the
* OSC0 using CLOCK_InitOsc0, all other cores need to call CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief The external XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
* The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz, when the clock is setup, use the * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal32Freq to set the value in to clock driver. * function CLOCK_SetXtal32Freq to set the value in the clock driver.
* *
* This is important for the multicore platforms, only one core needs to setup * This is important for the multicore platforms where one core needs to set up
* the clock, all other cores need to call CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
/*! @brief Clock ip name array for DMAMUX. */ /*! @brief Clock ip name array for DMAMUX. */
#define DMAMUX_CLOCKS \ #define DMAMUX_CLOCKS \
@ -182,9 +184,9 @@ extern uint32_t g_xtal32Freq;
} }
/*! @brief Clock ip name array for CMP. */ /*! @brief Clock ip name array for CMP. */
#define CMP_CLOCKS \ #define CMP_CLOCKS \
{ \ { \
kCLOCK_Cmp0, kCLOCK_Cmp1, kCLOCK_Cmp2 \ kCLOCK_Cmp0 \
} }
/*! /*!
@ -240,7 +242,7 @@ typedef enum _clock_name
typedef enum _clock_usb_src typedef enum _clock_usb_src
{ {
kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U), /*!< Use IRC48M. */ kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U), /*!< Use IRC48M. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
} clock_usb_src_t; } clock_usb_src_t;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
@ -274,38 +276,36 @@ typedef enum _clock_usb_src
typedef enum _clock_ip_name typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U), kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Slcd0 = CLK_GATE_DEFINE(0x1038U, 19U), kCLOCK_Slcd0 = CLK_GATE_DEFINE(0x1038U, 19U),
kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U), kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U),
kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U), kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U),
kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U), kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U), kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U),
} clock_ip_name_t; } clock_ip_name_t;
@ -320,30 +320,30 @@ typedef struct _sim_clock_config
/*! @brief Oscillator capacitor load setting.*/ /*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load enum _osc_cap_load
{ {
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
}; };
/*! @brief OSCERCLK enable mode. */ /*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode enum _oscer_enable_mode
{ {
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
}; };
/*! @brief OSC configuration for OSCERCLK. */ /*! @brief The OSC configuration for OSCERCLK. */
typedef struct _oscer_config typedef struct _oscer_config
{ {
uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of \ref _oscer_enable_mode. */ uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of \ref _oscer_enable_mode. */
} oscer_config_t; } oscer_config_t;
/*! @brief OSC work mode. */ /*! @brief The OSC work mode. */
typedef enum _osc_mode typedef enum _osc_mode
{ {
kOSC_ModeExt = 0U, /*!< Use external clock. */ kOSC_ModeExt = 0U, /*!< Use external clock. */
kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */ kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */
kOSC_ModeOscHighGain = MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */ kOSC_ModeOscHighGain = MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
} osc_mode_t; } osc_mode_t;
@ -353,7 +353,7 @@ typedef enum _osc_mode
* *
* Defines the configuration data structure to initialize the OSC. * Defines the configuration data structure to initialize the OSC.
* When porting to a new board, set the following members * When porting to a new board, set the following members
* according to board settings: * according to the board settings:
* 1. freq: The external frequency. * 1. freq: The external frequency.
* 2. workMode: The OSC module mode. * 2. workMode: The OSC module mode.
*/ */
@ -377,8 +377,8 @@ typedef enum _mcglite_clkout_src
/*! @brief MCG_Lite LIRC select. */ /*! @brief MCG_Lite LIRC select. */
typedef enum _mcglite_lirc_mode typedef enum _mcglite_lirc_mode
{ {
kMCGLITE_Lirc2M, /*!< Slow internal reference(LIRC) 2MHz clock selected */ kMCGLITE_Lirc2M, /*!< Slow internal reference(LIRC) 2 MHz clock selected */
kMCGLITE_Lirc8M, /*!< Slow internal reference(LIRC) 8MHz clock selected */ kMCGLITE_Lirc8M, /*!< Slow internal reference(LIRC) 8 MHz clock selected */
} mcglite_lirc_mode_t; } mcglite_lirc_mode_t;
/*! @brief MCG_Lite divider factor selection for clock source*/ /*! @brief MCG_Lite divider factor selection for clock source*/
@ -407,7 +407,7 @@ typedef enum _mcglite_mode
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcglite_irclk_enable_mode enum _mcglite_irclk_enable_mode
{ {
kMCGLITE_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCGLITE_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCGLITE_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCGLITE_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -430,26 +430,6 @@ typedef struct _mcglite_config
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*!
* @brief Set the XTAL0 frequency based on board setting.
*
* @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal0Freq(uint32_t freq)
{
g_xtal0Freq = freq;
}
/*!
* @brief Set the XTAL32/RTC_CLKIN frequency based on board setting.
*
* @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal32Freq(uint32_t freq)
{
g_xtal32Freq = freq;
}
/*! /*!
* @brief Enable the clock for specific IP. * @brief Enable the clock for specific IP.
* *
@ -661,7 +641,7 @@ static inline void CLOCK_SetSimSafeDivs(void)
/*! /*!
* @brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency. * @brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency.
* *
* This function gets the MCG_Lite output clock frequency (Hz) based on the current * This function gets the MCG_Lite output clock frequency in Hz based on the current
* MCG_Lite register value. * MCG_Lite register value.
* *
* @return The frequency of MCGOUTCLK. * @return The frequency of MCGOUTCLK.
@ -671,7 +651,7 @@ uint32_t CLOCK_GetOutClkFreq(void);
/*! /*!
* @brief Gets the MCG internal reference clock (MCGIRCLK) frequency. * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
* *
* This function gets the MCG_Lite internal reference clock frequency (Hz) based * This function gets the MCG_Lite internal reference clock frequency in Hz based
* on the current MCG register value. * on the current MCG register value.
* *
* @return The frequency of MCGIRCLK. * @return The frequency of MCGIRCLK.
@ -679,13 +659,13 @@ uint32_t CLOCK_GetOutClkFreq(void);
uint32_t CLOCK_GetInternalRefClkFreq(void); uint32_t CLOCK_GetInternalRefClkFreq(void);
/*! /*!
* @brief Gets the current MCGPCLK frequency. * @brief Gets the current MCGPCLK frequency.
* *
* This function gets the MCGPCLK frequency (Hertz) based on the current MCG_Lite * This function gets the MCGPCLK frequency in Hz based on the current MCG_Lite
* register settings. * register settings.
* *
* @return The frequency of MCGPCLK. * @return The frequency of MCGPCLK.
*/ */
uint32_t CLOCK_GetPeriphClkFreq(void); uint32_t CLOCK_GetPeriphClkFreq(void);
/*! @}*/ /*! @}*/
@ -700,15 +680,15 @@ uint32_t CLOCK_GetPeriphClkFreq(void);
* *
* This function checks the MCG_Lite registers and determines the current MCG_Lite mode. * This function checks the MCG_Lite registers and determines the current MCG_Lite mode.
* *
* @return Current MCG_Lite mode or error code. * @return The current MCG_Lite mode or error code.
*/ */
mcglite_mode_t CLOCK_GetMode(void); mcglite_mode_t CLOCK_GetMode(void);
/*! /*!
* @brief Sets the MCG_Lite configuration. * @brief Sets the MCG_Lite configuration.
* *
* This function configures the MCG_Lite, include output clock source, MCGIRCLK * This function configures the MCG_Lite, includes the output clock source, MCGIRCLK
* setting, HIRC setting and so on, see @ref mcglite_config_t for details. * settings, HIRC settings, and so on. See @ref mcglite_config_t for details.
* *
* @param targetConfig Pointer to the target MCG_Lite mode configuration structure. * @param targetConfig Pointer to the target MCG_Lite mode configuration structure.
* @return Error code. * @return Error code.
@ -726,8 +706,8 @@ status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig);
* @brief Configures the OSC external reference clock (OSCERCLK). * @brief Configures the OSC external reference clock (OSCERCLK).
* *
* This function configures the OSC external reference clock (OSCERCLK). * This function configures the OSC external reference clock (OSCERCLK).
* For example, to enable the OSCERCLK in normal mode and stop mode, and also set * This is an example to enable the OSCERCLK in normal mode and stop mode, and set
* the output divider to 1, as follows: * the output divider to 1.
* *
@code @code
oscer_config_t config = oscer_config_t config =
@ -755,12 +735,12 @@ static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *
/*! /*!
* @brief Sets the capacitor load configuration for the oscillator. * @brief Sets the capacitor load configuration for the oscillator.
* *
* This function sets the specified capacitors configuration for the oscillator. * This function sets the specified capacitor configuration for the oscillator.
* This should be done in the early system level initialization function call * This should be done in the early system level initialization function call
* based on the system configuration. * based on the system configuration.
* *
* @param base OSC peripheral address. * @param base OSC peripheral address.
* @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load. * @param capLoad OR'ed value for the capacitor load option.See \ref _osc_cap_load.
* *
* Example: * Example:
@code @code
@ -780,7 +760,7 @@ static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad)
} }
/*! /*!
* @brief Initialize OSC0. * @brief Initializes the OSC0.
* *
* This function initializes the OSC0 according to the board configuration. * This function initializes the OSC0 according to the board configuration.
* *
@ -797,6 +777,42 @@ void CLOCK_DeinitOsc0(void);
/*! @}*/ /*! @}*/
/*!
* @name External clock frequency
* @{
*/
/*!
* @brief Sets the XTAL0 frequency based on board settings.
*
* @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal0Freq(uint32_t freq)
{
g_xtal0Freq = freq;
}
/*!
* @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings.
*
* @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal32Freq(uint32_t freq)
{
g_xtal32Freq = freq;
}
/* @} */
/*!
* @brief Delay at least for several microseconds.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -1,71 +1,89 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
#define _FSL_CLOCK_H_ #define _FSL_CLOCK_H_
#include "fsl_device_registers.h" #include "fsl_common.h"
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
/*! @addtogroup clock */ /*! @addtogroup clock */
/*! @{ */ /*! @{ */
/*! @file */ /*! @file */
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Configures whether to check a parameter in a function.
*
* Some MCG settings must be changed with conditions, for example:
* 1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when
* MCGIRCLK is used as a system clock source.
* 2. MCG_C7[OSCSEL] should not be changed when the external reference clock is used
* as a system clock source. For example, in FBE/BLPE/PBE modes.
* 3. The users should only switch between the supported clock modes.
*
* MCG functions check the parameter and MCG status before setting, if not allowed
* to change, the functions return error. The parameter checking increases code size,
* if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to
* disable parameter checking.
*/
#ifndef MCG_CONFIG_CHECK_PARAM
#define MCG_CONFIG_CHECK_PARAM 0U
#endif
/*! @brief Configure whether driver controls clock
*
* When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could control the clock out of
* the driver.
*
* @note All drivers share this feature switcher. If it is set to 1, application
* should handle clock enable and disable for all drivers.
*/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CLOCK driver version 2.2.0. */ /*! @brief CLOCK driver version 2.3.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/ /*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (48000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8 MHz: * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Set up the OSC0 * Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. * CLOCK_InitOsc0(...);
* Set the XTAL0 value to the clock driver.
* CLOCK_SetXtal0Freq(80000000);
* @endcode * @endcode
* *
* This is important for the multicore platforms where only one core needs to set up the * This is important for the multicore platforms where only one core needs to set up the
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
@ -76,7 +94,7 @@ extern uint32_t g_xtal0Freq;
* the clock. All other cores need to call the CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
/*! @brief IRC48M clock frequency in Hz. */ /*! @brief IRC48M clock frequency in Hz. */
#define MCG_INTERNAL_IRC_48M 48000000U #define MCG_INTERNAL_IRC_48M 48000000U
@ -170,9 +188,9 @@ extern uint32_t g_xtal32Freq;
} }
/*! @brief Clock ip name array for MPU. */ /*! @brief Clock ip name array for MPU. */
#define MPU_CLOCKS \ #define MPU_CLOCKS \
{ \ { \
kCLOCK_Mpu0 \ kCLOCK_Sysmpu0 \
} }
/*! @brief Clock ip name array for FLEXIO. */ /*! @brief Clock ip name array for FLEXIO. */
@ -280,9 +298,9 @@ typedef enum _clock_name
/*! @brief USB clock source definition. */ /*! @brief USB clock source definition. */
typedef enum _clock_usb_src typedef enum _clock_usb_src
{ {
kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */
kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */ kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
} clock_usb_src_t; } clock_usb_src_t;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
@ -318,49 +336,49 @@ typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U), kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U),
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_Secreg0 = CLK_GATE_DEFINE(0x1038U, 3U), kCLOCK_Secreg0 = CLK_GATE_DEFINE(0x1038U, 3U),
kCLOCK_Lptmr1 = CLK_GATE_DEFINE(0x1038U, 4U), kCLOCK_Lptmr1 = CLK_GATE_DEFINE(0x1038U, 4U),
kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U), kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Emvsim0 = CLK_GATE_DEFINE(0x1038U, 14U), kCLOCK_Emvsim0 = CLK_GATE_DEFINE(0x1038U, 14U),
kCLOCK_Emvsim1 = CLK_GATE_DEFINE(0x1038U, 15U), kCLOCK_Emvsim1 = CLK_GATE_DEFINE(0x1038U, 15U),
kCLOCK_Ltc0 = CLK_GATE_DEFINE(0x1038U, 17U), kCLOCK_Ltc0 = CLK_GATE_DEFINE(0x1038U, 17U),
kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U), kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U),
kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U), kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U),
kCLOCK_Lpuart2 = CLK_GATE_DEFINE(0x1038U, 22U), kCLOCK_Lpuart2 = CLK_GATE_DEFINE(0x1038U, 22U),
kCLOCK_Qspi0 = CLK_GATE_DEFINE(0x1038U, 26U), kCLOCK_Qspi0 = CLK_GATE_DEFINE(0x1038U, 26U),
kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U), kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U),
kCLOCK_Nvm0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Nvm0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Intmux0 = CLK_GATE_DEFINE(0x103CU, 4U), kCLOCK_Intmux0 = CLK_GATE_DEFINE(0x103CU, 4U),
kCLOCK_Trng0 = CLK_GATE_DEFINE(0x103CU, 5U), kCLOCK_Trng0 = CLK_GATE_DEFINE(0x103CU, 5U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U),
kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Rtc_Rf0 = CLK_GATE_DEFINE(0x103CU, 30U), kCLOCK_Rtc_Rf0 = CLK_GATE_DEFINE(0x103CU, 30U),
kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U), kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U),
kCLOCK_Mpu0 = CLK_GATE_DEFINE(0x1040U, 2U), kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U),
} clock_ip_name_t; } clock_ip_name_t;
/*!@brief SIM configuration structure for clock setting. */ /*!@brief SIM configuration structure for clock setting. */
@ -384,34 +402,30 @@ typedef enum _osc_mode
#endif #endif
kOSC_ModeOscHighGain = 0U kOSC_ModeOscHighGain = 0U
#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
| | MCG_C2_EREFS_MASK
MCG_C2_EREFS_MASK
#else #else
| | MCG_C2_EREFS0_MASK
MCG_C2_EREFS0_MASK
#endif #endif
#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
| | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
#else #else
| | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
#endif #endif
} osc_mode_t; } osc_mode_t;
/*! @brief Oscillator capacitor load setting.*/ /*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load enum _osc_cap_load
{ {
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
}; };
/*! @brief OSCERCLK enable mode. */ /*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode enum _oscer_enable_mode
{ {
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
}; };
@ -519,30 +533,30 @@ typedef enum _mcg_monitor_mode
enum _mcg_status enum _mcg_status
{ {
kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */
kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific
function. */ function. */
kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */
kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */
kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */
kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */
kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because
it is in use. */ it is in use. */
}; };
/*! @brief MCG status flags. */ /*! @brief MCG status flags. */
enum _mcg_status_flags_t enum _mcg_status_flags_t
{ {
kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */ kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */
kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */ kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */
kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */ kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */
kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */ kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */
kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */ kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */
}; };
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcg_irclk_enable_mode enum _mcg_irclk_enable_mode
{ {
kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -694,11 +708,13 @@ static inline void CLOCK_SetFlexio0Clock(uint32_t src)
/*! /*!
* @brief Set PLLFLLSEL clock source. * @brief Set PLLFLLSEL clock source.
* *
* @param src The value to set PLLFLLSEL clock source. * @param src The value to set PLLFLLSEL clock source.
* @param divValue PLLFLL clock divider divisor.
* @param fracValue PLLFLL clock divider fraction.
*/ */
static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue) static inline void CLOCK_SetPllFllSelClock(uint32_t src, uint32_t divValue, uint32_t fracValue)
{ {
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src)); SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src));
SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue); SIM->CLKDIV3 = SIM_CLKDIV3_PLLFLLDIV(divValue) | SIM_CLKDIV3_PLLFLLFRAC(fracValue);
} }
@ -834,6 +850,13 @@ uint32_t CLOCK_GetOsc0ErClkUndivFreq(void);
*/ */
uint32_t CLOCK_GetOsc0ErClkFreq(void); uint32_t CLOCK_GetOsc0ErClkFreq(void);
/*!
* @brief Get the OSC0 external reference divided clock frequency.
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetOsc0ErClkDivFreq(void);
/*! /*!
* @brief Set the clock configure in SIM module. * @brief Set the clock configure in SIM module.
* *
@ -936,7 +959,7 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
} }
else else
{ {
MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
} }
} }
@ -952,8 +975,8 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
* @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
* @param ircs MCGIRCLK clock source, choose fast or slow. * @param ircs MCGIRCLK clock source, choose fast or slow.
* @param fcrdiv Fast IRC divider setting (\c FCRDIV). * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
* @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success MCGIRCLK configuration finished successfully. * @retval kStatus_Success MCGIRCLK configuration finished successfully.
*/ */
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
@ -967,11 +990,23 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
* *
* @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success External reference clock set successfully. * @retval kStatus_Success External reference clock set successfully.
*/ */
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
/*!
* @brief Set the FLL external reference clock divider value.
*
* Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV].
*
* @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV].
*/
static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
{
MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
}
/*! /*!
* @brief Enables the PLL0 in FLL mode. * @brief Enables the PLL0 in FLL mode.
* *
@ -1013,6 +1048,15 @@ static inline void CLOCK_DisablePll0(void)
*/ */
uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv); uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv);
/*!
* brief Sets the OSC0 clock monitor mode.
*
* This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
/*@}*/ /*@}*/
/*! @name MCG clock lock monitor functions. */ /*! @name MCG clock lock monitor functions. */
@ -1054,20 +1098,20 @@ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode);
* *
* Example: * Example:
* @code * @code
// To check the clock lost lock status of OSC0 and PLL0. * To check the clock lost lock status of OSC0 and PLL0.
uint32_t mcgFlags; * uint32_t mcgFlags;
*
mcgFlags = CLOCK_GetStatusFlags(); * mcgFlags = CLOCK_GetStatusFlags();
*
if (mcgFlags & kMCG_Osc0LostFlag) * if (mcgFlags & kMCG_Osc0LostFlag)
{ * {
// OSC0 clock lock lost. Do something. * OSC0 clock lock lost. Do something.
} * }
if (mcgFlags & kMCG_Pll0LostFlag) * if (mcgFlags & kMCG_Pll0LostFlag)
{ * {
// PLL0 clock lock lost. Do something. * PLL0 clock lock lost. Do something.
} * }
@endcode * @endcode
* *
* @return Logical OR value of the @ref _mcg_status_flags_t. * @return Logical OR value of the @ref _mcg_status_flags_t.
*/ */
@ -1081,10 +1125,10 @@ uint32_t CLOCK_GetStatusFlags(void);
* *
* Example: * Example:
* @code * @code
// To clear the clock lost lock status flags of OSC0 and PLL0. * To clear the clock lost lock status flags of OSC0 and PLL0.
*
CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
@endcode * @endcode
* *
* @param mask The status flags to clear. This is a logical OR of members of the * @param mask The status flags to clear. This is a logical OR of members of the
* enumeration @ref _mcg_status_flags_t. * enumeration @ref _mcg_status_flags_t.
@ -1142,7 +1186,7 @@ static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *
* *
* Example: * Example:
@code @code
// To enable only 2 pF and 8 pF capacitor load, please use like this. To enable only 2 pF and 8 pF capacitor load, please use like this.
OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
@endcode @endcode
*/ */
@ -1368,7 +1412,7 @@ status_t CLOCK_SetPeeMode(void);
* @brief Switches the MCG to FBE mode from the external mode. * @brief Switches the MCG to FBE mode from the external mode.
* *
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock souce and PLL is disabled. However, * The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful * the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode: * during the mode switch. For example, to switch from PEE mode to FEI mode:
* *
@ -1386,7 +1430,7 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void);
* @brief Switches the MCG to FBI mode from internal modes. * @brief Switches the MCG to FBI mode from internal modes.
* *
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock souce and PLL is disabled. However, * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful * FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode: * during the mode switch. For example, to switch from PEI mode to FEE mode:
* *
@ -1439,7 +1483,7 @@ status_t CLOCK_BootToFeeMode(
* @brief Sets the MCG to BLPI mode during system boot up. * @brief Sets the MCG to BLPI mode during system boot up.
* *
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param fcrdiv Fast IRC divider, FCRDIV. * @param fcrdiv Fast IRC divider, FCRDIV.
* @param ircs The internal reference clock to select, IRCS. * @param ircs The internal reference clock to select, IRCS.
@ -1451,10 +1495,10 @@ status_t CLOCK_BootToFeeMode(
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
/*! /*!
* @brief Sets the MCG to BLPE mode during sytem boot up. * @brief Sets the MCG to BLPE mode during system boot up.
* *
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param oscsel OSC clock select, MCG_C7[OSCSEL].
* *
@ -1494,6 +1538,16 @@ status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mc
*/ */
status_t CLOCK_SetMcgConfig(mcg_config_t const *config); status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
/*!
* @brief Delay at least for several microseconds.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/*@}*/ /*@}*/
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -1,71 +1,89 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
#define _FSL_CLOCK_H_ #define _FSL_CLOCK_H_
#include "fsl_device_registers.h" #include "fsl_common.h"
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
/*! @addtogroup clock */ /*! @addtogroup clock */
/*! @{ */ /*! @{ */
/*! @file */ /*! @file */
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Configures whether to check a parameter in a function.
*
* Some MCG settings must be changed with conditions, for example:
* 1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when
* MCGIRCLK is used as a system clock source.
* 2. MCG_C7[OSCSEL] should not be changed when the external reference clock is used
* as a system clock source. For example, in FBE/BLPE/PBE modes.
* 3. The users should only switch between the supported clock modes.
*
* MCG functions check the parameter and MCG status before setting, if not allowed
* to change, the functions return error. The parameter checking increases code size,
* if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to
* disable parameter checking.
*/
#ifndef MCG_CONFIG_CHECK_PARAM
#define MCG_CONFIG_CHECK_PARAM 0U
#endif
/*! @brief Configure whether driver controls clock
*
* When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could control the clock out of
* the driver.
*
* @note All drivers share this feature switcher. If it is set to 1, application
* should handle clock enable and disable for all drivers.
*/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CLOCK driver version 2.2.0. */ /*! @brief CLOCK driver version 2.3.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/ /*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (120000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8 MHz: * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Set up the OSC0 * Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. * CLOCK_InitOsc0(...);
* Set the XTAL0 value to the clock driver.
* CLOCK_SetXtal0Freq(80000000);
* @endcode * @endcode
* *
* This is important for the multicore platforms where only one core needs to set up the * This is important for the multicore platforms where only one core needs to set up the
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
@ -76,7 +94,7 @@ extern uint32_t g_xtal0Freq;
* the clock. All other cores need to call the CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
#if (defined(OSC) && !(defined(OSC0))) #if (defined(OSC) && !(defined(OSC0)))
#define OSC0 OSC #define OSC0 OSC
@ -247,7 +265,7 @@ typedef enum _clock_name
typedef enum _clock_usb_src typedef enum _clock_usb_src
{ {
kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
} clock_usb_src_t; } clock_usb_src_t;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
@ -282,41 +300,41 @@ typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U), kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U),
kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U), kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U),
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U), kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U),
kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U), kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U),
kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U), kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Rnga0 = CLK_GATE_DEFINE(0x103CU, 9U), kCLOCK_Rnga0 = CLK_GATE_DEFINE(0x103CU, 9U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U),
kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U),
kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U), kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U),
kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U), kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U), kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U),
} clock_ip_name_t; } clock_ip_name_t;
@ -340,34 +358,30 @@ typedef enum _osc_mode
#endif #endif
kOSC_ModeOscHighGain = 0U kOSC_ModeOscHighGain = 0U
#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
| | MCG_C2_EREFS_MASK
MCG_C2_EREFS_MASK
#else #else
| | MCG_C2_EREFS0_MASK
MCG_C2_EREFS0_MASK
#endif #endif
#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
| | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
#else #else
| | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
#endif #endif
} osc_mode_t; } osc_mode_t;
/*! @brief Oscillator capacitor load setting.*/ /*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load enum _osc_cap_load
{ {
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
}; };
/*! @brief OSCERCLK enable mode. */ /*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode enum _oscer_enable_mode
{ {
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
}; };
@ -473,30 +487,30 @@ typedef enum _mcg_monitor_mode
enum _mcg_status enum _mcg_status
{ {
kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */
kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific
function. */ function. */
kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */
kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */
kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */
kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */
kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because
it is in use. */ it is in use. */
}; };
/*! @brief MCG status flags. */ /*! @brief MCG status flags. */
enum _mcg_status_flags_t enum _mcg_status_flags_t
{ {
kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */ kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */
kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */ kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */
kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */ kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */
kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */ kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */
kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */ kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */
}; };
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcg_irclk_enable_mode enum _mcg_irclk_enable_mode
{ {
kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -842,7 +856,7 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
} }
else else
{ {
MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
} }
} }
@ -858,8 +872,8 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
* @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
* @param ircs MCGIRCLK clock source, choose fast or slow. * @param ircs MCGIRCLK clock source, choose fast or slow.
* @param fcrdiv Fast IRC divider setting (\c FCRDIV). * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
* @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success MCGIRCLK configuration finished successfully. * @retval kStatus_Success MCGIRCLK configuration finished successfully.
*/ */
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
@ -873,11 +887,23 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
* *
* @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success External reference clock set successfully. * @retval kStatus_Success External reference clock set successfully.
*/ */
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
/*!
* @brief Set the FLL external reference clock divider value.
*
* Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV].
*
* @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV].
*/
static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
{
MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
}
/*! /*!
* @brief Enables the PLL0 in FLL mode. * @brief Enables the PLL0 in FLL mode.
* *
@ -919,6 +945,15 @@ static inline void CLOCK_DisablePll0(void)
*/ */
uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv); uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv);
/*!
* brief Sets the OSC0 clock monitor mode.
*
* This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
/*@}*/ /*@}*/
/*! @name MCG clock lock monitor functions. */ /*! @name MCG clock lock monitor functions. */
@ -960,20 +995,20 @@ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode);
* *
* Example: * Example:
* @code * @code
// To check the clock lost lock status of OSC0 and PLL0. * To check the clock lost lock status of OSC0 and PLL0.
uint32_t mcgFlags; * uint32_t mcgFlags;
*
mcgFlags = CLOCK_GetStatusFlags(); * mcgFlags = CLOCK_GetStatusFlags();
*
if (mcgFlags & kMCG_Osc0LostFlag) * if (mcgFlags & kMCG_Osc0LostFlag)
{ * {
// OSC0 clock lock lost. Do something. * OSC0 clock lock lost. Do something.
} * }
if (mcgFlags & kMCG_Pll0LostFlag) * if (mcgFlags & kMCG_Pll0LostFlag)
{ * {
// PLL0 clock lock lost. Do something. * PLL0 clock lock lost. Do something.
} * }
@endcode * @endcode
* *
* @return Logical OR value of the @ref _mcg_status_flags_t. * @return Logical OR value of the @ref _mcg_status_flags_t.
*/ */
@ -987,10 +1022,10 @@ uint32_t CLOCK_GetStatusFlags(void);
* *
* Example: * Example:
* @code * @code
// To clear the clock lost lock status flags of OSC0 and PLL0. * To clear the clock lost lock status flags of OSC0 and PLL0.
*
CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
@endcode * @endcode
* *
* @param mask The status flags to clear. This is a logical OR of members of the * @param mask The status flags to clear. This is a logical OR of members of the
* enumeration @ref _mcg_status_flags_t. * enumeration @ref _mcg_status_flags_t.
@ -1046,7 +1081,7 @@ static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *
* *
* Example: * Example:
@code @code
// To enable only 2 pF and 8 pF capacitor load, please use like this. To enable only 2 pF and 8 pF capacitor load, please use like this.
OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
@endcode @endcode
*/ */
@ -1272,7 +1307,7 @@ status_t CLOCK_SetPeeMode(void);
* @brief Switches the MCG to FBE mode from the external mode. * @brief Switches the MCG to FBE mode from the external mode.
* *
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock souce and PLL is disabled. However, * The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful * the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode: * during the mode switch. For example, to switch from PEE mode to FEI mode:
* *
@ -1290,7 +1325,7 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void);
* @brief Switches the MCG to FBI mode from internal modes. * @brief Switches the MCG to FBI mode from internal modes.
* *
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock souce and PLL is disabled. However, * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful * FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode: * during the mode switch. For example, to switch from PEI mode to FEE mode:
* *
@ -1343,7 +1378,7 @@ status_t CLOCK_BootToFeeMode(
* @brief Sets the MCG to BLPI mode during system boot up. * @brief Sets the MCG to BLPI mode during system boot up.
* *
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param fcrdiv Fast IRC divider, FCRDIV. * @param fcrdiv Fast IRC divider, FCRDIV.
* @param ircs The internal reference clock to select, IRCS. * @param ircs The internal reference clock to select, IRCS.
@ -1355,10 +1390,10 @@ status_t CLOCK_BootToFeeMode(
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
/*! /*!
* @brief Sets the MCG to BLPE mode during sytem boot up. * @brief Sets the MCG to BLPE mode during system boot up.
* *
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param oscsel OSC clock select, MCG_C7[OSCSEL].
* *
@ -1398,6 +1433,16 @@ status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mc
*/ */
status_t CLOCK_SetMcgConfig(mcg_config_t const *config); status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
/*!
* @brief Use DWT to delay at least for some time.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/*@}*/ /*@}*/
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -1,31 +1,9 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
@ -38,31 +16,74 @@
/*! @file */ /*! @file */
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Configures whether to check a parameter in a function.
*
* Some MCG settings must be changed with conditions, for example:
* 1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when
* MCGIRCLK is used as a system clock source.
* 2. MCG_C7[OSCSEL] should not be changed when the external reference clock is used
* as a system clock source. For example, in FBE/BLPE/PBE modes.
* 3. The users should only switch between the supported clock modes.
*
* MCG functions check the parameter and MCG status before setting, if not allowed
* to change, the functions return error. The parameter checking increases code size,
* if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to
* disable parameter checking.
*/
#ifndef MCG_CONFIG_CHECK_PARAM
#define MCG_CONFIG_CHECK_PARAM 0U
#endif
/*! @brief Configure whether driver controls clock
*
* When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could control the clock out of
* the driver.
*
* @note All drivers share this feature switcher. If it is set to 1, application
* should handle clock enable and disable for all drivers.
*/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CLOCK driver version 2.2.0. */ /*! @brief CLOCK driver version 2.3.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/ /*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (120000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8 MHz: * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Set up the OSC0 * Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. * CLOCK_InitOsc0(...);
* Set the XTAL0 value to the clock driver.
* CLOCK_SetXtal0Freq(80000000);
* @endcode * @endcode
* *
* This is important for the multicore platforms where only one core needs to set up the * This is important for the multicore platforms where only one core needs to set up the
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
@ -73,7 +94,7 @@ extern uint32_t g_xtal0Freq;
* the clock. All other cores need to call the CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
#if (defined(OSC) && !(defined(OSC0))) #if (defined(OSC) && !(defined(OSC0)))
#define OSC0 OSC #define OSC0 OSC
@ -221,10 +242,8 @@ typedef enum _clock_name
kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */ kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */
/* ----------------------------- MCG and MCG-Lite clock ---------------------------*/ /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/
kCLOCK_McgFixedFreqClk, /*!< MCG fixed frequency clock (MCGFFCLK) */
kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */ kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */
kCLOCK_McgFllClk, /*!< MCGFLLCLK */ kCLOCK_McgFllClk, /*!< MCGFLLCLK */
kCLOCK_McgPeriphClk, /*!< MCG peripheral clock (MCGPCLK) */
/* --------------------------------- Other clock ----------------------------------*/ /* --------------------------------- Other clock ----------------------------------*/
kCLOCK_LpoClk, /*!< LPO clock */ kCLOCK_LpoClk, /*!< LPO clock */
@ -264,39 +283,39 @@ typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U), kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U),
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U), kCLOCK_Tsi0 = CLK_GATE_DEFINE(0x1038U, 5U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U), kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U),
kCLOCK_Aesa = CLK_GATE_DEFINE(0x1038U, 24U), kCLOCK_Aesa = CLK_GATE_DEFINE(0x1038U, 24U),
kCLOCK_Ltc0 = CLK_GATE_DEFINE(0x1038U, 24U), kCLOCK_Ltc0 = CLK_GATE_DEFINE(0x1038U, 24U),
kCLOCK_Rsim = CLK_GATE_DEFINE(0x1038U, 25U), kCLOCK_Rsim = CLK_GATE_DEFINE(0x1038U, 25U),
kCLOCK_Dcdc0 = CLK_GATE_DEFINE(0x1038U, 26U), kCLOCK_Dcdc0 = CLK_GATE_DEFINE(0x1038U, 26U),
kCLOCK_Btll = CLK_GATE_DEFINE(0x1038U, 27U), kCLOCK_Btll = CLK_GATE_DEFINE(0x1038U, 27U),
kCLOCK_PhyDig = CLK_GATE_DEFINE(0x1038U, 28U), kCLOCK_PhyDig = CLK_GATE_DEFINE(0x1038U, 28U),
kCLOCK_ZigBee = CLK_GATE_DEFINE(0x1038U, 29U), kCLOCK_ZigBee = CLK_GATE_DEFINE(0x1038U, 29U),
kCLOCK_GenFsk = CLK_GATE_DEFINE(0x1038U, 31U), kCLOCK_GenFsk = CLK_GATE_DEFINE(0x1038U, 31U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Trng0 = CLK_GATE_DEFINE(0x103CU, 9U), kCLOCK_Trng0 = CLK_GATE_DEFINE(0x103CU, 9U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U), kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U),
} clock_ip_name_t; } clock_ip_name_t;
@ -322,18 +341,14 @@ typedef enum _osc_mode
#endif #endif
kOSC_ModeOscHighGain = 0U kOSC_ModeOscHighGain = 0U
#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
| | MCG_C2_EREFS_MASK
MCG_C2_EREFS_MASK
#else #else
| | MCG_C2_EREFS0_MASK
MCG_C2_EREFS0_MASK
#endif #endif
#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
| | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
#else #else
| | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
#endif #endif
} osc_mode_t; } osc_mode_t;
@ -430,13 +445,13 @@ typedef enum _mcg_monitor_mode
enum _mcg_status enum _mcg_status
{ {
kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */
kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific
function. */ function. */
kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */
kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */
kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */
kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */
kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because
it is in use. */ it is in use. */
}; };
@ -449,7 +464,7 @@ enum _mcg_status_flags_t
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcg_irclk_enable_mode enum _mcg_irclk_enable_mode
{ {
kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -724,7 +739,7 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
} }
else else
{ {
MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
} }
} }
@ -740,8 +755,8 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
* @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
* @param ircs MCGIRCLK clock source, choose fast or slow. * @param ircs MCGIRCLK clock source, choose fast or slow.
* @param fcrdiv Fast IRC divider setting (\c FCRDIV). * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
* @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success MCGIRCLK configuration finished successfully. * @retval kStatus_Success MCGIRCLK configuration finished successfully.
*/ */
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
@ -755,7 +770,7 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
* *
* @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success External reference clock set successfully. * @retval kStatus_Success External reference clock set successfully.
*/ */
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
@ -769,9 +784,18 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
*/ */
static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv) static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
{ {
MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv); MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
} }
/*!
* brief Sets the OSC0 clock monitor mode.
*
* This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
/*@}*/ /*@}*/
/*! @name MCG clock lock monitor functions. */ /*! @name MCG clock lock monitor functions. */
@ -795,20 +819,20 @@ void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode);
* *
* Example: * Example:
* @code * @code
// To check the clock lost lock status of OSC0 and PLL0. * To check the clock lost lock status of OSC0 and PLL0.
uint32_t mcgFlags; * uint32_t mcgFlags;
*
mcgFlags = CLOCK_GetStatusFlags(); * mcgFlags = CLOCK_GetStatusFlags();
*
if (mcgFlags & kMCG_Osc0LostFlag) * if (mcgFlags & kMCG_Osc0LostFlag)
{ * {
// OSC0 clock lock lost. Do something. * OSC0 clock lock lost. Do something.
} * }
if (mcgFlags & kMCG_Pll0LostFlag) * if (mcgFlags & kMCG_Pll0LostFlag)
{ * {
// PLL0 clock lock lost. Do something. * PLL0 clock lock lost. Do something.
} * }
@endcode * @endcode
* *
* @return Logical OR value of the @ref _mcg_status_flags_t. * @return Logical OR value of the @ref _mcg_status_flags_t.
*/ */
@ -822,10 +846,10 @@ uint32_t CLOCK_GetStatusFlags(void);
* *
* Example: * Example:
* @code * @code
// To clear the clock lost lock status flags of OSC0 and PLL0. * To clear the clock lost lock status flags of OSC0 and PLL0.
*
CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
@endcode * @endcode
* *
* @param mask The status flags to clear. This is a logical OR of members of the * @param mask The status flags to clear. This is a logical OR of members of the
* enumeration @ref _mcg_status_flags_t. * enumeration @ref _mcg_status_flags_t.
@ -1016,7 +1040,7 @@ status_t CLOCK_SetBlpeMode(void);
* @brief Switches the MCG to FBE mode from the external mode. * @brief Switches the MCG to FBE mode from the external mode.
* *
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock souce and PLL is disabled. However, * The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful * the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode: * during the mode switch. For example, to switch from PEE mode to FEI mode:
* *
@ -1034,7 +1058,7 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void);
* @brief Switches the MCG to FBI mode from internal modes. * @brief Switches the MCG to FBI mode from internal modes.
* *
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock souce and PLL is disabled. However, * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful * FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode: * during the mode switch. For example, to switch from PEI mode to FEE mode:
* *
@ -1087,7 +1111,7 @@ status_t CLOCK_BootToFeeMode(
* @brief Sets the MCG to BLPI mode during system boot up. * @brief Sets the MCG to BLPI mode during system boot up.
* *
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param fcrdiv Fast IRC divider, FCRDIV. * @param fcrdiv Fast IRC divider, FCRDIV.
* @param ircs The internal reference clock to select, IRCS. * @param ircs The internal reference clock to select, IRCS.
@ -1099,10 +1123,10 @@ status_t CLOCK_BootToFeeMode(
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
/*! /*!
* @brief Sets the MCG to BLPE mode during sytem boot up. * @brief Sets the MCG to BLPE mode during system boot up.
* *
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param oscsel OSC clock select, MCG_C7[OSCSEL].
* *
@ -1127,6 +1151,16 @@ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel);
*/ */
status_t CLOCK_SetMcgConfig(mcg_config_t const *config); status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
/*!
* @brief Use DWT to delay at least for some time.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/*@}*/ /*@}*/
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -1,32 +1,9 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright (c) 2016 - 2017 , NXP * Copyright 2016 - 2019, NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * SPDX-License-Identifier: BSD-3-Clause
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
@ -65,7 +42,7 @@
* *
* When set to 0, peripheral drivers will enable clock in initialize function * When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral * and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could contol the clock out of * driver will not control the clock, application could control the clock out of
* the driver. * the driver.
* *
* @note All drivers share this feature switcher. If it is set to 1, application * @note All drivers share this feature switcher. If it is set to 1, application
@ -81,25 +58,32 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CLOCK driver version 2.2.1. */ /*! @brief CLOCK driver version 2.3.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 1)) #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/ /*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (120000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
* *
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8 MHz: * if XTAL0 is 8 MHz:
* @code * @code
* CLOCK_InitOsc0(...); // Set up the OSC0 * Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. * CLOCK_InitOsc0(...);
* Set the XTAL0 value to the clock driver.
* CLOCK_SetXtal0Freq(80000000);
* @endcode * @endcode
* *
* This is important for the multicore platforms where only one core needs to set up the * This is important for the multicore platforms where only one core needs to set up the
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
@ -110,7 +94,7 @@ extern uint32_t g_xtal0Freq;
* the clock. All other cores need to call the CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
/*! @brief IRC48M clock frequency in Hz. */ /*! @brief IRC48M clock frequency in Hz. */
#define MCG_INTERNAL_IRC_48M 48000000U #define MCG_INTERNAL_IRC_48M 48000000U
@ -328,9 +312,9 @@ typedef enum _clock_name
/*! @brief USB clock source definition. */ /*! @brief USB clock source definition. */
typedef enum _clock_usb_src typedef enum _clock_usb_src
{ {
kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */
kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */ kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
} clock_usb_src_t; } clock_usb_src_t;
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
@ -364,59 +348,59 @@ typedef enum _clock_usb_src
typedef enum _clock_ip_name typedef enum _clock_ip_name
{ {
kCLOCK_IpInvalid = 0U, kCLOCK_IpInvalid = 0U,
kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U), kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U),
kCLOCK_Uart4 = CLK_GATE_DEFINE(0x1028U, 10U), kCLOCK_Uart4 = CLK_GATE_DEFINE(0x1028U, 10U),
kCLOCK_Uart5 = CLK_GATE_DEFINE(0x1028U, 11U), kCLOCK_Uart5 = CLK_GATE_DEFINE(0x1028U, 11U),
kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U), kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U),
kCLOCK_Dac1 = CLK_GATE_DEFINE(0x102CU, 13U), kCLOCK_Dac1 = CLK_GATE_DEFINE(0x102CU, 13U),
kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U), kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U),
kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U), kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U),
kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U), kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U),
kCLOCK_Adc1 = CLK_GATE_DEFINE(0x1030U, 27U), kCLOCK_Adc1 = CLK_GATE_DEFINE(0x1030U, 27U),
kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U), kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U),
kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U), kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U),
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U), kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U),
kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U), kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U),
kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U), kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
kCLOCK_Uart3 = CLK_GATE_DEFINE(0x1034U, 13U), kCLOCK_Uart3 = CLK_GATE_DEFINE(0x1034U, 13U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Flexcan0 = CLK_GATE_DEFINE(0x103CU, 4U), kCLOCK_Flexcan0 = CLK_GATE_DEFINE(0x103CU, 4U),
kCLOCK_Rnga0 = CLK_GATE_DEFINE(0x103CU, 9U), kCLOCK_Rnga0 = CLK_GATE_DEFINE(0x103CU, 9U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U),
kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U),
kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U), kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U),
kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U), kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U), kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U), kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U), kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U), kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U),
kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U), kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U),
} clock_ip_name_t; } clock_ip_name_t;
/*!@brief SIM configuration structure for clock setting. */ /*!@brief SIM configuration structure for clock setting. */
@ -438,34 +422,30 @@ typedef enum _osc_mode
#endif #endif
kOSC_ModeOscHighGain = 0U kOSC_ModeOscHighGain = 0U
#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
| | MCG_C2_EREFS_MASK
MCG_C2_EREFS_MASK
#else #else
| | MCG_C2_EREFS0_MASK
MCG_C2_EREFS0_MASK
#endif #endif
#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) #if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK)))
| | MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO_MASK, /*!< Oscillator high gain. */
#else #else
| | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
#endif #endif
} osc_mode_t; } osc_mode_t;
/*! @brief Oscillator capacitor load setting.*/ /*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load enum _osc_cap_load
{ {
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
}; };
/*! @brief OSCERCLK enable mode. */ /*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode enum _oscer_enable_mode
{ {
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
}; };
@ -572,30 +552,30 @@ typedef enum _mcg_monitor_mode
enum _mcg_status enum _mcg_status
{ {
kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */
kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific
function. */ function. */
kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */
kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */
kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */
kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */
kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because
it is in use. */ it is in use. */
}; };
/*! @brief MCG status flags. */ /*! @brief MCG status flags. */
enum _mcg_status_flags_t enum _mcg_status_flags_t
{ {
kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */ kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */
kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */ kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */
kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */ kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */
kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */ kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */
kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */ kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */
}; };
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ /*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcg_irclk_enable_mode enum _mcg_irclk_enable_mode
{ {
kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
}; };
@ -954,7 +934,7 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
} }
else else
{ {
MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 &= ~(uint8_t)MCG_C2_LP_MASK;
} }
} }
@ -970,8 +950,8 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
* @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
* @param ircs MCGIRCLK clock source, choose fast or slow. * @param ircs MCGIRCLK clock source, choose fast or slow.
* @param fcrdiv Fast IRC divider setting (\c FCRDIV). * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
* @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success MCGIRCLK configuration finished successfully. * @retval kStatus_Success MCGIRCLK configuration finished successfully.
*/ */
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
@ -985,7 +965,7 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
* *
* @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success External reference clock set successfully. * @retval kStatus_Success External reference clock set successfully.
*/ */
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
@ -999,7 +979,7 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
*/ */
static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv) static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv)
{ {
MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv); MCG->C1 = (uint8_t)((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
} }
/*! /*!
@ -1043,6 +1023,15 @@ static inline void CLOCK_DisablePll0(void)
*/ */
uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv); uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv);
/*!
* brief Sets the OSC0 clock monitor mode.
*
* This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode);
/*@}*/ /*@}*/
/*! @name MCG clock lock monitor functions. */ /*! @name MCG clock lock monitor functions. */
@ -1084,20 +1073,20 @@ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode);
* *
* Example: * Example:
* @code * @code
// To check the clock lost lock status of OSC0 and PLL0. * To check the clock lost lock status of OSC0 and PLL0.
uint32_t mcgFlags; * uint32_t mcgFlags;
*
mcgFlags = CLOCK_GetStatusFlags(); * mcgFlags = CLOCK_GetStatusFlags();
*
if (mcgFlags & kMCG_Osc0LostFlag) * if (mcgFlags & kMCG_Osc0LostFlag)
{ * {
// OSC0 clock lock lost. Do something. * OSC0 clock lock lost. Do something.
} * }
if (mcgFlags & kMCG_Pll0LostFlag) * if (mcgFlags & kMCG_Pll0LostFlag)
{ * {
// PLL0 clock lock lost. Do something. * PLL0 clock lock lost. Do something.
} * }
@endcode * @endcode
* *
* @return Logical OR value of the @ref _mcg_status_flags_t. * @return Logical OR value of the @ref _mcg_status_flags_t.
*/ */
@ -1111,10 +1100,10 @@ uint32_t CLOCK_GetStatusFlags(void);
* *
* Example: * Example:
* @code * @code
// To clear the clock lost lock status flags of OSC0 and PLL0. * To clear the clock lost lock status flags of OSC0 and PLL0.
*
CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); * CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
@endcode * @endcode
* *
* @param mask The status flags to clear. This is a logical OR of members of the * @param mask The status flags to clear. This is a logical OR of members of the
* enumeration @ref _mcg_status_flags_t. * enumeration @ref _mcg_status_flags_t.
@ -1170,7 +1159,7 @@ static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *
* *
* Example: * Example:
@code @code
// To enable only 2 pF and 8 pF capacitor load, please use like this. To enable only 2 pF and 8 pF capacitor load, please use like this.
OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
@endcode @endcode
*/ */
@ -1396,7 +1385,7 @@ status_t CLOCK_SetPeeMode(void);
* @brief Switches the MCG to FBE mode from the external mode. * @brief Switches the MCG to FBE mode from the external mode.
* *
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock souce and PLL is disabled. However, * The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful * the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode: * during the mode switch. For example, to switch from PEE mode to FEI mode:
* *
@ -1414,7 +1403,7 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void);
* @brief Switches the MCG to FBI mode from internal modes. * @brief Switches the MCG to FBI mode from internal modes.
* *
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock souce and PLL is disabled. However, * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful * FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode: * during the mode switch. For example, to switch from PEI mode to FEE mode:
* *
@ -1467,7 +1456,7 @@ status_t CLOCK_BootToFeeMode(
* @brief Sets the MCG to BLPI mode during system boot up. * @brief Sets the MCG to BLPI mode during system boot up.
* *
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param fcrdiv Fast IRC divider, FCRDIV. * @param fcrdiv Fast IRC divider, FCRDIV.
* @param ircs The internal reference clock to select, IRCS. * @param ircs The internal reference clock to select, IRCS.
@ -1479,10 +1468,10 @@ status_t CLOCK_BootToFeeMode(
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
/*! /*!
* @brief Sets the MCG to BLPE mode during sytem boot up. * @brief Sets the MCG to BLPE mode during system boot up.
* *
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param oscsel OSC clock select, MCG_C7[OSCSEL].
* *
@ -1522,6 +1511,16 @@ status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mc
*/ */
status_t CLOCK_SetMcgConfig(mcg_config_t const *config); status_t CLOCK_SetMcgConfig(mcg_config_t const *config);
/*!
* @brief Use DWT to delay at least for some time.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/*@}*/ /*@}*/
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -1,31 +1,10 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright (c) 2016 - 2017 , NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* *
* o Redistributions of source code must retain the above copyright notice, this list * SPDX-License-Identifier: BSD-3-Clause
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "fsl_clock.h" #include "fsl_clock.h"
@ -33,6 +12,10 @@
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.clock"
#endif
/* Macro definition remap workaround. */ /* Macro definition remap workaround. */
#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK)))
@ -118,9 +101,9 @@ static uint32_t s_slowIrcFreq = 32768U;
static uint32_t s_fastIrcFreq = 4000000U; static uint32_t s_fastIrcFreq = 4000000U;
/* External XTAL0 (OSC0) clock frequency. */ /* External XTAL0 (OSC0) clock frequency. */
uint32_t g_xtal0Freq; volatile uint32_t g_xtal0Freq;
/* External XTAL32K clock frequency. */ /* External XTAL32K clock frequency. */
uint32_t g_xtal32Freq; volatile uint32_t g_xtal32Freq;
/******************************************************************************* /*******************************************************************************
* Prototypes * Prototypes
@ -189,6 +172,7 @@ static uint32_t CLOCK_GetPll0RefFreq(void);
*/ */
static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq); static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq);
#ifndef MCG_USER_CONFIG_FLL_STABLE_DELAY_EN
/*! /*!
* @brief Delay function to wait FLL stable. * @brief Delay function to wait FLL stable.
* *
@ -196,11 +180,33 @@ static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq);
* 1ms. Every time changes FLL setting, should wait this time for FLL stable. * 1ms. Every time changes FLL setting, should wait this time for FLL stable.
*/ */
static void CLOCK_FllStableDelay(void); static void CLOCK_FllStableDelay(void);
#endif
/******************************************************************************* /*******************************************************************************
* Code * Code
******************************************************************************/ ******************************************************************************/
#ifndef MCG_USER_CONFIG_FLL_STABLE_DELAY_EN
static void CLOCK_FllStableDelay(void)
{
/*
Should wait at least 1ms. Because in these modes, the core clock is 100MHz
at most, so this function could obtain the 1ms delay.
*/
volatile uint32_t i = 30000U;
while (i--)
{
__NOP();
}
}
#else /* With MCG_USER_CONFIG_FLL_STABLE_DELAY_EN defined. */
/* Once user defines the MCG_USER_CONFIG_FLL_STABLE_DELAY_EN to use their own delay function, he has to
* create his own CLOCK_FllStableDelay() function in application code. Since the clock functions in this
* file would call the CLOCK_FllStableDelay() regardless how it is defined.
*/
extern void CLOCK_FllStableDelay(void);
#endif /* MCG_USER_CONFIG_FLL_STABLE_DELAY_EN */
static uint32_t CLOCK_GetMcgExtClkFreq(void) static uint32_t CLOCK_GetMcgExtClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -336,19 +342,11 @@ static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq)
return range; return range;
} }
static void CLOCK_FllStableDelay(void) /*!
{ * brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
/* *
Should wait at least 1ms. Because in these modes, the core clock is 100MHz * return Clock frequency in Hz.
at most, so this function could obtain the 1ms delay. */
*/
volatile uint32_t i = 30000U;
while (i--)
{
__NOP();
}
}
uint32_t CLOCK_GetOsc0ErClkFreq(void) uint32_t CLOCK_GetOsc0ErClkFreq(void)
{ {
if (OSC0->CR & OSC_CR_ERCLKEN_MASK) if (OSC0->CR & OSC_CR_ERCLKEN_MASK)
@ -363,6 +361,11 @@ uint32_t CLOCK_GetOsc0ErClkFreq(void)
} }
} }
/*!
* brief Get the external reference 32K clock frequency (ERCLK32K).
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetEr32kClkFreq(void) uint32_t CLOCK_GetEr32kClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -387,6 +390,11 @@ uint32_t CLOCK_GetEr32kClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the output clock frequency selected by SIM[PLLFLLSEL].
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetPllFllSelClkFreq(void) uint32_t CLOCK_GetPllFllSelClkFreq(void)
{ {
uint32_t freq; uint32_t freq;
@ -410,31 +418,66 @@ uint32_t CLOCK_GetPllFllSelClkFreq(void)
return freq; return freq;
} }
/*!
* brief Get the platform clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetPlatClkFreq(void) uint32_t CLOCK_GetPlatClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
} }
/*!
* brief Get the flash clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetFlashClkFreq(void) uint32_t CLOCK_GetFlashClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV4_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV4_VAL + 1);
} }
/*!
* brief Get the flexbus clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetFlexBusClkFreq(void) uint32_t CLOCK_GetFlexBusClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV3_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV3_VAL + 1);
} }
/*!
* brief Get the bus clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetBusClkFreq(void) uint32_t CLOCK_GetBusClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV2_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV2_VAL + 1);
} }
/*!
* brief Get the core clock or system clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetCoreSysClkFreq(void) uint32_t CLOCK_GetCoreSysClkFreq(void)
{ {
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
} }
/*!
* brief Gets the clock frequency for a specific clock name.
*
* This function checks the current clock configurations and then calculates
* the clock frequency for a specific clock name defined in clock_name_t.
* The MCG must be properly configured before using this function.
*
* param clockName Clock names defined in clock_name_t
* return Clock frequency value in Hertz
*/
uint32_t CLOCK_GetFreq(clock_name_t clockName) uint32_t CLOCK_GetFreq(clock_name_t clockName)
{ {
uint32_t freq; uint32_t freq;
@ -489,6 +532,13 @@ uint32_t CLOCK_GetFreq(clock_name_t clockName)
return freq; return freq;
} }
/*!
* brief Set the clock configure in SIM module.
*
* This function sets system layer clock settings in SIM module.
*
* param config Pointer to the configure structure.
*/
void CLOCK_SetSimConfig(sim_clock_config_t const *config) void CLOCK_SetSimConfig(sim_clock_config_t const *config)
{ {
SIM->CLKDIV1 = config->clkdiv1; SIM->CLKDIV1 = config->clkdiv1;
@ -496,6 +546,13 @@ void CLOCK_SetSimConfig(sim_clock_config_t const *config)
CLOCK_SetEr32kClock(config->er32kSrc); CLOCK_SetEr32kClock(config->er32kSrc);
} }
/*! brief Enable USB FS clock.
*
* param src USB FS clock source.
* param freq The frequency specified by src.
* retval true The clock is set successfully.
* retval false The clock source is invalid to get proper USB FS clock.
*/
bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
{ {
bool ret = true; bool ret = true;
@ -540,6 +597,14 @@ bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
return ret; return ret;
} }
/*!
* brief Gets the MCG output clock (MCGOUTCLK) frequency.
*
* This function gets the MCG output clock frequency in Hz based on the current MCG
* register value.
*
* return The frequency of MCGOUTCLK.
*/
uint32_t CLOCK_GetOutClkFreq(void) uint32_t CLOCK_GetOutClkFreq(void)
{ {
uint32_t mcgoutclk; uint32_t mcgoutclk;
@ -566,6 +631,15 @@ uint32_t CLOCK_GetOutClkFreq(void)
return mcgoutclk; return mcgoutclk;
} }
/*!
* brief Gets the MCG FLL clock (MCGFLLCLK) frequency.
*
* This function gets the MCG FLL clock frequency in Hz based on the current MCG
* register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and
* disabled in low power state in other modes.
*
* return The frequency of MCGFLLCLK.
*/
uint32_t CLOCK_GetFllFreq(void) uint32_t CLOCK_GetFllFreq(void)
{ {
static const uint16_t fllFactorTable[4][2] = {{640, 732}, {1280, 1464}, {1920, 2197}, {2560, 2929}}; static const uint16_t fllFactorTable[4][2] = {{640, 732}, {1280, 1464}, {1920, 2197}, {2560, 2929}};
@ -592,6 +666,14 @@ uint32_t CLOCK_GetFllFreq(void)
return freq * fllFactorTable[drs][dmx32]; return freq * fllFactorTable[drs][dmx32];
} }
/*!
* brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
*
* This function gets the MCG internal reference clock frequency in Hz based
* on the current MCG register value.
*
* return The frequency of MCGIRCLK.
*/
uint32_t CLOCK_GetInternalRefClkFreq(void) uint32_t CLOCK_GetInternalRefClkFreq(void)
{ {
/* If MCGIRCLK is gated. */ /* If MCGIRCLK is gated. */
@ -603,6 +685,14 @@ uint32_t CLOCK_GetInternalRefClkFreq(void)
return CLOCK_GetInternalRefClkSelectFreq(); return CLOCK_GetInternalRefClkSelectFreq();
} }
/*!
* brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency.
*
* This function gets the MCG fixed frequency clock frequency in Hz based
* on the current MCG register value.
*
* return The frequency of MCGFFCLK.
*/
uint32_t CLOCK_GetFixedFreqClkFreq(void) uint32_t CLOCK_GetFixedFreqClkFreq(void)
{ {
uint32_t freq = CLOCK_GetFllRefClkFreq(); uint32_t freq = CLOCK_GetFllRefClkFreq();
@ -618,6 +708,14 @@ uint32_t CLOCK_GetFixedFreqClkFreq(void)
} }
} }
/*!
* brief Gets the MCG PLL0 clock (MCGPLL0CLK) frequency.
*
* This function gets the MCG PLL0 clock frequency in Hz based on the current MCG
* register value.
*
* return The frequency of MCGPLL0CLK.
*/
uint32_t CLOCK_GetPll0Freq(void) uint32_t CLOCK_GetPll0Freq(void)
{ {
uint32_t mcgpll0clk; uint32_t mcgpll0clk;
@ -642,6 +740,18 @@ uint32_t CLOCK_GetPll0Freq(void)
return mcgpll0clk; return mcgpll0clk;
} }
/*!
* brief Selects the MCG external reference clock.
*
* Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL],
* and waits for the clock source to be stable. Because the external reference
* clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes.
*
* param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the configuration should not be changed. Otherwise, a glitch occurs.
* retval kStatus_Success External reference clock set successfully.
*/
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel) status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel)
{ {
bool needDelay; bool needDelay;
@ -666,16 +776,6 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel)
} }
MCG->C7 = (MCG->C7 & ~MCG_C7_OSCSEL_MASK) | MCG_C7_OSCSEL(oscsel); MCG->C7 = (MCG->C7 & ~MCG_C7_OSCSEL_MASK) | MCG_C7_OSCSEL(oscsel);
if (kMCG_OscselOsc == oscsel)
{
if (MCG->C2 & MCG_C2_EREFS_MASK)
{
while (!(MCG->S & MCG_S_OSCINIT0_MASK))
{
}
}
}
if (needDelay) if (needDelay)
{ {
/* ERR009878 Delay at least 50 micro-seconds for external clock change valid. */ /* ERR009878 Delay at least 50 micro-seconds for external clock change valid. */
@ -689,6 +789,22 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Configures the Internal Reference clock (MCGIRCLK).
*
* This function sets the \c MCGIRCLK base on parameters. It also selects the IRC
* source. If the fast IRC is used, this function sets the fast IRC divider.
* This function also sets whether the \c MCGIRCLK is enabled in stop mode.
* Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result,
* using the function in these modes it is not allowed.
*
* param enableMode MCGIRCLK enable mode, OR'ed value of ref _mcg_irclk_enable_mode.
* param ircs MCGIRCLK clock source, choose fast or slow.
* param fcrdiv Fast IRC divider setting (\c FCRDIV).
* retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the configuration should not be changed. Otherwise, a glitch occurs.
* retval kStatus_Success MCGIRCLK configuration finished successfully.
*/
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv) status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv)
{ {
uint32_t mcgOutClkState = MCG_S_CLKST_VAL; uint32_t mcgOutClkState = MCG_S_CLKST_VAL;
@ -737,6 +853,21 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Calculates the PLL divider setting for a desired output frequency.
*
* This function calculates the correct reference clock divider (\c PRDIV) and
* VCO divider (\c VDIV) to generate a desired PLL output frequency. It returns the
* closest frequency match with the corresponding \c PRDIV/VDIV
* returned from parameters. If a desired frequency is not valid, this function
* returns 0.
*
* param refFreq PLL reference clock frequency.
* param desireFreq Desired PLL output frequency.
* param prdiv PRDIV value to generate desired PLL frequency.
* param vdiv VDIV value to generate desired PLL frequency.
* return Closest frequency match that the PLL was able generate.
*/
uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv) uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv)
{ {
uint8_t ret_prdiv; /* PRDIV to return. */ uint8_t ret_prdiv; /* PRDIV to return. */
@ -745,7 +876,7 @@ uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv,
uint8_t prdiv_max; /* Max PRDIV value to make reference clock in allowed range. */ uint8_t prdiv_max; /* Max PRDIV value to make reference clock in allowed range. */
uint8_t prdiv_cur; /* PRDIV value for iteration. */ uint8_t prdiv_cur; /* PRDIV value for iteration. */
uint8_t vdiv_cur; /* VDIV value for iteration. */ uint8_t vdiv_cur; /* VDIV value for iteration. */
uint32_t ret_freq = 0U; /* PLL output fequency to return. */ uint32_t ret_freq = 0U; /* PLL output frequency to return. */
uint32_t diff = 0xFFFFFFFFU; /* Difference between desireFreq and return frequency. */ uint32_t diff = 0xFFFFFFFFU; /* Difference between desireFreq and return frequency. */
uint32_t ref_div; /* Reference frequency after PRDIV. */ uint32_t ref_div; /* Reference frequency after PRDIV. */
@ -834,6 +965,17 @@ uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv,
} }
} }
/*!
* brief Enables the PLL0 in FLL mode.
*
* This function sets us the PLL0 in FLL mode and reconfigures
* the PLL0. Ensure that the PLL reference
* clock is enabled before calling this function and that the PLL0 is not used as a clock source.
* The function CLOCK_CalcPllDiv gets the correct PLL
* divider values.
*
* param config Pointer to the configuration structure.
*/
void CLOCK_EnablePll0(mcg_pll_config_t const *config) void CLOCK_EnablePll0(mcg_pll_config_t const *config)
{ {
assert(config); assert(config);
@ -854,6 +996,13 @@ void CLOCK_EnablePll0(mcg_pll_config_t const *config)
} }
} }
/*!
* brief Sets the OSC0 clock monitor mode.
*
* This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode) void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode)
{ {
/* Clear the previous flag, MCG_SC[LOCS0]. */ /* Clear the previous flag, MCG_SC[LOCS0]. */
@ -877,6 +1026,13 @@ void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode)
} }
} }
/*!
* brief Sets the RTC OSC clock monitor mode.
*
* This function sets the RTC OSC clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode) void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode)
{ {
uint8_t mcg_c8 = MCG->C8; uint8_t mcg_c8 = MCG->C8;
@ -894,6 +1050,13 @@ void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode)
MCG->C8 = mcg_c8; MCG->C8 = mcg_c8;
} }
/*!
* brief Sets the PLL0 clock monitor mode.
*
* This function sets the PLL0 clock monitor mode. See ref mcg_monitor_mode_t for details.
*
* param mode Monitor mode to set.
*/
void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode) void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode)
{ {
uint8_t mcg_c8; uint8_t mcg_c8;
@ -924,6 +1087,32 @@ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode)
} }
} }
/*!
* brief Gets the MCG status flags.
*
* This function gets the MCG clock status flags. All status flags are
* returned as a logical OR of the enumeration ref _mcg_status_flags_t. To
* check a specific flag, compare the return value with the flag.
*
* Example:
* code
// To check the clock lost lock status of OSC0 and PLL0.
uint32_t mcgFlags;
mcgFlags = CLOCK_GetStatusFlags();
if (mcgFlags & kMCG_Osc0LostFlag)
{
// OSC0 clock lock lost. Do something.
}
if (mcgFlags & kMCG_Pll0LostFlag)
{
// PLL0 clock lock lost. Do something.
}
endcode
*
* return Logical OR value of the ref _mcg_status_flags_t.
*/
uint32_t CLOCK_GetStatusFlags(void) uint32_t CLOCK_GetStatusFlags(void)
{ {
uint32_t ret = 0U; uint32_t ret = 0U;
@ -952,6 +1141,22 @@ uint32_t CLOCK_GetStatusFlags(void)
return ret; return ret;
} }
/*!
* brief Clears the MCG status flags.
*
* This function clears the MCG clock lock lost status. The parameter is a logical
* OR value of the flags to clear. See ref _mcg_status_flags_t.
*
* Example:
* code
// To clear the clock lost lock status flags of OSC0 and PLL0.
CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag);
endcode
*
* param mask The status flags to clear. This is a logical OR of members of the
* enumeration ref _mcg_status_flags_t.
*/
void CLOCK_ClearStatusFlags(uint32_t mask) void CLOCK_ClearStatusFlags(uint32_t mask)
{ {
uint8_t reg; uint8_t reg;
@ -971,6 +1176,13 @@ void CLOCK_ClearStatusFlags(uint32_t mask)
} }
} }
/*!
* brief Initializes the OSC0.
*
* This function initializes the OSC0 according to the board configuration.
*
* param config Pointer to the OSC0 configuration structure.
*/
void CLOCK_InitOsc0(osc_config_t const *config) void CLOCK_InitOsc0(osc_config_t const *config)
{ {
uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq); uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq);
@ -989,12 +1201,35 @@ void CLOCK_InitOsc0(osc_config_t const *config)
} }
} }
/*!
* brief Deinitializes the OSC0.
*
* This function deinitializes the OSC0.
*/
void CLOCK_DeinitOsc0(void) void CLOCK_DeinitOsc0(void)
{ {
OSC0->CR = 0U; OSC0->CR = 0U;
MCG->C2 &= ~OSC_MODE_MASK; MCG->C2 &= ~OSC_MODE_MASK;
} }
/*!
* brief Auto trims the internal reference clock.
*
* This function trims the internal reference clock by using the external clock. If
* successful, it returns the kStatus_Success and the frequency after
* trimming is received in the parameter p actualFreq. If an error occurs,
* the error code is returned.
*
* param extFreq External clock frequency, which should be a bus clock.
* param desireFreq Frequency to trim to.
* param actualFreq Actual frequency after trimming.
* param atms Trim fast or slow internal reference clock.
* retval kStatus_Success ATM success.
* retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM.
* retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency.
* retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source.
* retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming.
*/
status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms) status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms)
{ {
uint32_t multi; /* extFreq / desireFreq */ uint32_t multi; /* extFreq / desireFreq */
@ -1071,6 +1306,13 @@ status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Gets the current MCG mode.
*
* This function checks the MCG registers and determines the current MCG mode.
*
* return Current MCG mode or error code; See ref mcg_mode_t.
*/
mcg_mode_t CLOCK_GetMode(void) mcg_mode_t CLOCK_GetMode(void)
{ {
mcg_mode_t mode = kMCG_ModeError; mcg_mode_t mode = kMCG_ModeError;
@ -1171,6 +1413,21 @@ mcg_mode_t CLOCK_GetMode(void)
return mode; return mode;
} }
/*!
* brief Sets the MCG to FEI mode.
*
* This function sets the MCG to FEI mode. If setting to FEI mode fails
* from the current mode, this function returns an error.
*
* param dmx32 DMX32 in FEI mode.
* param drs The DCO range selection.
* param fllStableDelay Delay function to ensure that the FLL is stable. Passing
* NULL does not cause a delay.
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
* note If p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
* to a frequency above 32768 Hz.
*/
status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
uint8_t mcg_c4; uint8_t mcg_c4;
@ -1231,6 +1488,21 @@ status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDela
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to FEE mode.
*
* This function sets the MCG to FEE mode. If setting to FEE mode fails
* from the current mode, this function returns an error.
*
* param frdiv FLL reference clock divider setting, FRDIV.
* param dmx32 DMX32 in FEE mode.
* param drs The DCO range selection.
* param fllStableDelay Delay function to make sure FLL is stable. Passing
* NULL does not cause a delay.
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
uint8_t mcg_c4; uint8_t mcg_c4;
@ -1264,6 +1536,17 @@ status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
| MCG_C1_FRDIV(frdiv) /* FRDIV */ | MCG_C1_FRDIV(frdiv) /* FRDIV */
| MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */
/* If use external crystal as clock source, wait for it stable. */
if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK))
{
if (MCG->C2 & MCG_C2_EREFS_MASK)
{
while (!(MCG->S & MCG_S_OSCINIT0_MASK))
{
}
}
}
/* Wait and check status. */ /* Wait and check status. */
while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL)
{ {
@ -1298,6 +1581,22 @@ status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to FBI mode.
*
* This function sets the MCG to FBI mode. If setting to FBI mode fails
* from the current mode, this function returns an error.
*
* param dmx32 DMX32 in FBI mode.
* param drs The DCO range selection.
* param fllStableDelay Delay function to make sure FLL is stable. If the FLL
* is not used in FBI mode, this parameter can be NULL. Passing
* NULL does not cause a delay.
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
* note If p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
* to frequency above 32768 Hz.
*/
status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
uint8_t mcg_c4; uint8_t mcg_c4;
@ -1362,6 +1661,21 @@ status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDela
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to FBE mode.
*
* This function sets the MCG to FBE mode. If setting to FBE mode fails
* from the current mode, this function returns an error.
*
* param frdiv FLL reference clock divider setting, FRDIV.
* param dmx32 DMX32 in FBE mode.
* param drs The DCO range selection.
* param fllStableDelay Delay function to make sure FLL is stable. If the FLL
* is not used in FBE mode, this parameter can be NULL. Passing NULL
* does not cause a delay.
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
uint8_t mcg_c4; uint8_t mcg_c4;
@ -1406,6 +1720,17 @@ status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
| MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */ | MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */
| MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */
/* If use external crystal as clock source, wait for it stable. */
if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK))
{
if (MCG->C2 & MCG_C2_EREFS_MASK)
{
while (!(MCG->S & MCG_S_OSCINIT0_MASK))
{
}
}
}
/* Wait for Reference clock Status bit to clear */ /* Wait for Reference clock Status bit to clear */
while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL)
{ {
@ -1434,6 +1759,15 @@ status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to BLPI mode.
*
* This function sets the MCG to BLPI mode. If setting to BLPI mode fails
* from the current mode, this function returns an error.
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_SetBlpiMode(void) status_t CLOCK_SetBlpiMode(void)
{ {
#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM)
@ -1449,6 +1783,15 @@ status_t CLOCK_SetBlpiMode(void)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to BLPE mode.
*
* This function sets the MCG to BLPE mode. If setting to BLPE mode fails
* from the current mode, this function returns an error.
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_SetBlpeMode(void) status_t CLOCK_SetBlpeMode(void)
{ {
#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM)
@ -1464,6 +1807,25 @@ status_t CLOCK_SetBlpeMode(void)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to PBE mode.
*
* This function sets the MCG to PBE mode. If setting to PBE mode fails
* from the current mode, this function returns an error.
*
* param pllcs The PLL selection, PLLCS.
* param config Pointer to the PLL configuration.
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*
* note
* 1. The parameter \c pllcs selects the PLL. For platforms with
* only one PLL, the parameter pllcs is kept for interface compatibility.
* 2. The parameter \c config is the PLL configuration structure. On some
* platforms, it is possible to choose the external PLL directly, which renders the
* configuration structure not necessary. In this case, pass in NULL.
* For example: CLOCK_SetPbeMode(kMCG_OscselOsc, kMCG_PllClkSelExtPll, NULL);
*/
status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config)
{ {
assert(config); assert(config);
@ -1505,6 +1867,18 @@ status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *co
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to PEE mode.
*
* This function sets the MCG to PEE mode.
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*
* note This function only changes the CLKS to use the PLL/FLL output. If the
* PRDIV/VDIV are different than in the PBE mode, set them up
* in PBE mode and wait. When the clock is stable, switch to PEE mode.
*/
status_t CLOCK_SetPeeMode(void) status_t CLOCK_SetPeeMode(void)
{ {
#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM)
@ -1526,6 +1900,22 @@ status_t CLOCK_SetPeeMode(void)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Switches the MCG to FBE mode from the external mode.
*
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode:
*
* code
* CLOCK_ExternalModeToFbeModeQuick();
* CLOCK_SetFeiMode(...);
* endcode
*
* retval kStatus_Success Switched successfully.
* retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function.
*/
status_t CLOCK_ExternalModeToFbeModeQuick(void) status_t CLOCK_ExternalModeToFbeModeQuick(void)
{ {
#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM)
@ -1552,6 +1942,22 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Switches the MCG to FBI mode from internal modes.
*
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode:
*
* code
* CLOCK_InternalModeToFbiModeQuick();
* CLOCK_SetFeeMode(...);
* endcode
*
* retval kStatus_Success Switched successfully.
* retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function.
*/
status_t CLOCK_InternalModeToFbiModeQuick(void) status_t CLOCK_InternalModeToFbiModeQuick(void)
{ {
#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) #if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM)
@ -1572,11 +1978,41 @@ status_t CLOCK_InternalModeToFbiModeQuick(void)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to FEI mode during system boot up.
*
* This function sets the MCG to FEI mode from the reset mode. It can also be used to
* set up MCG during system boot up.
*
* param dmx32 DMX32 in FEI mode.
* param drs The DCO range selection.
* param fllStableDelay Delay function to ensure that the FLL is stable.
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
* note If p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed
* to frequency above 32768 Hz.
*/
status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
return CLOCK_SetFeiMode(dmx32, drs, fllStableDelay); return CLOCK_SetFeiMode(dmx32, drs, fllStableDelay);
} }
/*!
* brief Sets the MCG to FEE mode during system bootup.
*
* This function sets MCG to FEE mode from the reset mode. It can also be used to
* set up the MCG during system boot up.
*
* param oscsel OSC clock select, OSCSEL.
* param frdiv FLL reference clock divider setting, FRDIV.
* param dmx32 DMX32 in FEE mode.
* param drs The DCO range selection.
* param fllStableDelay Delay function to ensure that the FLL is stable.
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_BootToFeeMode( status_t CLOCK_BootToFeeMode(
mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
@ -1585,6 +2021,19 @@ status_t CLOCK_BootToFeeMode(
return CLOCK_SetFeeMode(frdiv, dmx32, drs, fllStableDelay); return CLOCK_SetFeeMode(frdiv, dmx32, drs, fllStableDelay);
} }
/*!
* brief Sets the MCG to BLPI mode during system boot up.
*
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during system boot up.
*
* param fcrdiv Fast IRC divider, FCRDIV.
* param ircs The internal reference clock to select, IRCS.
* param ircEnableMode The MCGIRCLK enable mode, OR'ed value of ref _mcg_irclk_enable_mode.
*
* retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode) status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode)
{ {
/* If reset mode is FEI mode, set MCGIRCLK and always success. */ /* If reset mode is FEI mode, set MCGIRCLK and always success. */
@ -1602,6 +2051,17 @@ status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEn
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to BLPE mode during system boot up.
*
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during system boot up.
*
* param oscsel OSC clock select, MCG_C7[OSCSEL].
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel) status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel)
{ {
CLOCK_SetExternalRefClkConfig(oscsel); CLOCK_SetExternalRefClkConfig(oscsel);
@ -1611,6 +2071,17 @@ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel)
((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */
| MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */
/* If use external crystal as clock source, wait for it stable. */
if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK))
{
if (MCG->C2 & MCG_C2_EREFS_MASK)
{
while (!(MCG->S & MCG_S_OSCINIT0_MASK))
{
}
}
}
/* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */ /* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */
while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) !=
(MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt))) (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt)))
@ -1623,6 +2094,19 @@ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel)
return kStatus_Success; return kStatus_Success;
} }
/*!
* brief Sets the MCG to PEE mode during system boot up.
*
* This function sets the MCG to PEE mode from reset mode. It can also be used to
* set up the MCG during system boot up.
*
* param oscsel OSC clock select, MCG_C7[OSCSEL].
* param pllcs The PLL selection, PLLCS.
* param config Pointer to the PLL configuration.
*
* retval kStatus_MCG_ModeUnreachable Could not switch to the target mode.
* retval kStatus_Success Switched to the target mode successfully.
*/
status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config)
{ {
assert(config); assert(config);
@ -1669,6 +2153,20 @@ static const mcg_mode_t mcgModeMatrix[8][8] = {
/* FEI FBI BLPI FEE FBE BLPE PBE PEE */ /* FEI FBI BLPI FEE FBE BLPE PBE PEE */
}; };
/*!
* brief Sets the MCG to a target mode.
*
* This function sets MCG to a target mode defined by the configuration
* structure. If switching to the target mode fails, this function
* chooses the correct path.
*
* param config Pointer to the target MCG mode configuration structure.
* return Return kStatus_Success if switched successfully; Otherwise, it returns an error code #_mcg_status.
*
* note If the external clock is used in the target mode, ensure that it is
* enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this
* function.
*/
status_t CLOCK_SetMcgConfig(const mcg_config_t *config) status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
{ {
mcg_mode_t next_mode; mcg_mode_t next_mode;
@ -1680,10 +2178,10 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
if (MCG_C7_OSCSEL_VAL != config->oscsel) if (MCG_C7_OSCSEL_VAL != config->oscsel)
{ {
/* If external clock is in use, change to FEI first. */ /* If external clock is in use, change to FEI first. */
if (!(MCG->S & MCG_S_IRCST_MASK)) if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL)
{ {
CLOCK_ExternalModeToFbeModeQuick(); CLOCK_ExternalModeToFbeModeQuick();
CLOCK_SetFeiMode(config->dmx32, config->drs, (void (*)(void))0); CLOCK_SetFeiMode(config->dmx32, config->drs, NULL);
} }
CLOCK_SetExternalRefClkConfig(config->oscsel); CLOCK_SetExternalRefClkConfig(config->oscsel);
@ -1717,10 +2215,10 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
status = CLOCK_SetFeeMode(config->frdiv, config->dmx32, config->drs, CLOCK_FllStableDelay); status = CLOCK_SetFeeMode(config->frdiv, config->dmx32, config->drs, CLOCK_FllStableDelay);
break; break;
case kMCG_ModeFBI: case kMCG_ModeFBI:
status = CLOCK_SetFbiMode(config->dmx32, config->drs, (void (*)(void))0); status = CLOCK_SetFbiMode(config->dmx32, config->drs, NULL);
break; break;
case kMCG_ModeFBE: case kMCG_ModeFBE:
status = CLOCK_SetFbeMode(config->frdiv, config->dmx32, config->drs, (void (*)(void))0); status = CLOCK_SetFbeMode(config->frdiv, config->dmx32, config->drs, NULL);
break; break;
case kMCG_ModeBLPI: case kMCG_ModeBLPI:
status = CLOCK_SetBlpiMode(); status = CLOCK_SetBlpiMode();

View File

@ -1,31 +1,10 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright (c) 2016 - 2017 , NXP
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* *
* o Redistributions of source code must retain the above copyright notice, this list * SPDX-License-Identifier: BSD-3-Clause
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FSL_CLOCK_H_ #ifndef _FSL_CLOCK_H_
@ -39,14 +18,32 @@
/*! @file */ /*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Configurations
******************************************************************************/ ******************************************************************************/
/*! @brief Configures whether to check a parameter in a function.
*
* Some MCG settings must be changed with conditions, for example:
* 1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when
* MCGIRCLK is used as a system clock source.
* 2. MCG_C7[OSCSEL] should not be changed when the external reference clock is used
* as a system clock source. For example, in FBE/BLPE/PBE modes.
* 3. The users should only switch between the supported clock modes.
*
* MCG functions check the parameter and MCG status before setting, if not allowed
* to change, the functions return error. The parameter checking increases code size,
* if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to
* disable parameter checking.
*/
#ifndef MCG_CONFIG_CHECK_PARAM
#define MCG_CONFIG_CHECK_PARAM 0U
#endif
/*! @brief Configure whether driver controls clock /*! @brief Configure whether driver controls clock
* *
* When set to 0, peripheral drivers will enable clock in initialize function * When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral * and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could contol the clock out of * driver will not control the clock, application could control the clock out of
* the driver. * the driver.
* *
* @note All drivers share this feature switcher. If it is set to 1, application * @note All drivers share this feature switcher. If it is set to 1, application
@ -56,10 +53,14 @@
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0 #define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif #endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CLOCK driver version 2.2.0. */ /*! @brief CLOCK driver version 2.2.1. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) #define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 1))
/*@}*/ /*@}*/
/*! @brief External XTAL0 (OSC0) clock frequency. /*! @brief External XTAL0 (OSC0) clock frequency.
@ -76,7 +77,7 @@
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal0Freq; extern volatile uint32_t g_xtal0Freq;
/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency.
* *
@ -87,7 +88,7 @@ extern uint32_t g_xtal0Freq;
* the clock. All other cores need to call the CLOCK_SetXtal32Freq * the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency. * to get a valid clock frequency.
*/ */
extern uint32_t g_xtal32Freq; extern volatile uint32_t g_xtal32Freq;
/*! @brief IRC48M clock frequency in Hz. */ /*! @brief IRC48M clock frequency in Hz. */
#define MCG_INTERNAL_IRC_48M 48000000U #define MCG_INTERNAL_IRC_48M 48000000U
@ -194,7 +195,7 @@ extern uint32_t g_xtal32Freq;
/*! @brief Clock ip name array for MPU. */ /*! @brief Clock ip name array for MPU. */
#define SYSMPU_CLOCKS \ #define SYSMPU_CLOCKS \
{ \ { \
kCLOCK_Sysmpu0 \ kCLOCK_Sysmpu0 \
} }
@ -982,8 +983,8 @@ static inline void CLOCK_SetLowPowerEnable(bool enable)
* @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode.
* @param ircs MCGIRCLK clock source, choose fast or slow. * @param ircs MCGIRCLK clock source, choose fast or slow.
* @param fcrdiv Fast IRC divider setting (\c FCRDIV). * @param fcrdiv Fast IRC divider setting (\c FCRDIV).
* @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success MCGIRCLK configuration finished successfully. * @retval kStatus_Success MCGIRCLK configuration finished successfully.
*/ */
status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv);
@ -997,7 +998,7 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
* *
* @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL].
* @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source,
* the confuration should not be changed. Otherwise, a glitch occurs. * the configuration should not be changed. Otherwise, a glitch occurs.
* @retval kStatus_Success External reference clock set successfully. * @retval kStatus_Success External reference clock set successfully.
*/ */
status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel);
@ -1408,7 +1409,7 @@ status_t CLOCK_SetPeeMode(void);
* @brief Switches the MCG to FBE mode from the external mode. * @brief Switches the MCG to FBE mode from the external mode.
* *
* This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly.
* The external clock is used as the system clock souce and PLL is disabled. However, * The external clock is used as the system clock source and PLL is disabled. However,
* the FLL settings are not configured. This is a lite function with a small code size, which is useful * the FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEE mode to FEI mode: * during the mode switch. For example, to switch from PEE mode to FEI mode:
* *
@ -1426,7 +1427,7 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void);
* @brief Switches the MCG to FBI mode from internal modes. * @brief Switches the MCG to FBI mode from internal modes.
* *
* This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly.
* The MCGIRCLK is used as the system clock souce and PLL is disabled. However, * The MCGIRCLK is used as the system clock source and PLL is disabled. However,
* FLL settings are not configured. This is a lite function with a small code size, which is useful * FLL settings are not configured. This is a lite function with a small code size, which is useful
* during the mode switch. For example, to switch from PEI mode to FEE mode: * during the mode switch. For example, to switch from PEI mode to FEE mode:
* *
@ -1479,7 +1480,7 @@ status_t CLOCK_BootToFeeMode(
* @brief Sets the MCG to BLPI mode during system boot up. * @brief Sets the MCG to BLPI mode during system boot up.
* *
* This function sets the MCG to BLPI mode from the reset mode. It can also be used to * This function sets the MCG to BLPI mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param fcrdiv Fast IRC divider, FCRDIV. * @param fcrdiv Fast IRC divider, FCRDIV.
* @param ircs The internal reference clock to select, IRCS. * @param ircs The internal reference clock to select, IRCS.
@ -1491,10 +1492,10 @@ status_t CLOCK_BootToFeeMode(
status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode);
/*! /*!
* @brief Sets the MCG to BLPE mode during sytem boot up. * @brief Sets the MCG to BLPE mode during system boot up.
* *
* This function sets the MCG to BLPE mode from the reset mode. It can also be used to * This function sets the MCG to BLPE mode from the reset mode. It can also be used to
* set up the MCG during sytem boot up. * set up the MCG during system boot up.
* *
* @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param oscsel OSC clock select, MCG_C7[OSCSEL].
* *