/* * Copyright 2018-2021, NXP * All rights reserved. * * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_anactrl.h" /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.anactrl" #endif /******************************************************************************* * Prototypes ******************************************************************************/ /*! * @brief Get instance number for ANACTRL module. * * @param base ANACTRL peripheral base address */ static uint32_t ANACTRL_GetInstance(ANACTRL_Type *base); /******************************************************************************* * Variables ******************************************************************************/ /*! @brief Pointers to ANACTRL bases for each instance. */ static ANACTRL_Type *const s_anactrlBases[] = ANACTRL_BASE_PTRS; #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to ANACTRL clocks for each instance. */ static const clock_ip_name_t s_anactrlClocks[] = ANALOGCTRL_CLOCKS; #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code ******************************************************************************/ /*! * brief Get the ANACTRL instance from peripheral base address. * * param base ANACTRL peripheral base address. * return ANACTRL instance. */ static uint32_t ANACTRL_GetInstance(ANACTRL_Type *base) { uint32_t instance; /* Find the instance index from base address mappings. */ for (instance = 0; instance < ARRAY_SIZE(s_anactrlBases); instance++) { if (s_anactrlBases[instance] == base) { break; } } assert(instance < ARRAY_SIZE(s_anactrlBases)); return instance; } /*! * brief Initializes the ANACTRL mode, the module's clock will be enabled by invoking this function. * * param base ANACTRL peripheral base address. */ void ANACTRL_Init(ANACTRL_Type *base) { assert(NULL != base); #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the clock for ANACTRL instance. */ CLOCK_EnableClock(s_anactrlClocks[ANACTRL_GetInstance(base)]); #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } /*! * brief De-initializes ANACTRL module, the module's clock will be disabled by invoking this function. * * param base ANACTRL peripheral base address. */ void ANACTRL_Deinit(ANACTRL_Type *base) { assert(NULL != base); #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable the clock for ANACTRL instance. */ CLOCK_DisableClock(s_anactrlClocks[ANACTRL_GetInstance(base)]); #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } /*! * brief Configs the on-chip high-speed Free Running Oscillator(FRO192M), such as enabling/disabling 12 MHZ clock output * and enable/disable 96MHZ clock output. * * param base ANACTRL peripheral base address. * param config Pointer to FRO192M configuration structure. Refer to anactrl_fro192M_config_t structure. */ void ANACTRL_SetFro192M(ANACTRL_Type *base, const anactrl_fro192M_config_t *config) { assert(NULL != config); uint32_t tmp32 = base->FRO192M_CTRL; tmp32 &= ~(ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK); if (config->enable12MHzClk) { tmp32 |= ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK; } if (config->enable96MHzClk) { tmp32 |= ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK; } base->FRO192M_CTRL |= tmp32; } /*! * brief Gets the default configuration of FRO192M. * The default values are: * code config->enable12MHzClk = true; config->enable96MHzClk = false; endcode * param config Pointer to FRO192M configuration structure. Refer to anactrl_fro192M_config_t structure. */ void ANACTRL_GetDefaultFro192MConfig(anactrl_fro192M_config_t *config) { assert(NULL != config); /* Initializes the configure structure to zero. */ (void)memset(config, 0, sizeof(*config)); config->enable12MHzClk = true; config->enable96MHzClk = false; } /*! * brief Configs the 32 MHz Crystal oscillator(High-speed crystal oscillator), such as enable/disable output to CPU * system, and so on. * * param base ANACTRL peripheral base address. * param config Pointer to XO32M configuration structure. Refer to anactrl_xo32M_config_t structure. */ void ANACTRL_SetXo32M(ANACTRL_Type *base, const anactrl_xo32M_config_t *config) { assert(NULL != config); uint32_t tmp32 = base->XO32M_CTRL; tmp32 &= ~(ANACTRL_XO32M_CTRL_ACBUF_PASS_ENABLE_MASK | ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK); /* Set XO32M CTRL. */ #if !(defined(FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD) && \ FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD) tmp32 &= ~ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK; if (config->enablePllUsbOutput) { tmp32 |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK; } #endif /* FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD */ if (config->enableACBufferBypass) { tmp32 |= ANACTRL_XO32M_CTRL_ACBUF_PASS_ENABLE_MASK; } if (config->enableSysCLkOutput) { tmp32 |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; } base->XO32M_CTRL = tmp32; #if (defined(FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD) && \ FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD) if (config->enableADCOutput) { base->DUMMY_CTRL |= ANACTRL_DUMMY_CTRL_XO32M_ADC_CLK_MODE_MASK; } else { base->DUMMY_CTRL &= ~ANACTRL_DUMMY_CTRL_XO32M_ADC_CLK_MODE_MASK; } #endif /* FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD */ } /*! * brief Gets the default configuration of XO32M. * The default values are: * code config->enableSysCLkOutput = false; config->enableACBufferBypass = false; endcode * param config Pointer to XO32M configuration structure. Refer to anactrl_xo32M_config_t structure. */ void ANACTRL_GetDefaultXo32MConfig(anactrl_xo32M_config_t *config) { assert(NULL != config); /* Initializes the configure structure to zero. */ (void)memset(config, 0, sizeof(*config)); #if !(defined(FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD) && \ FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD) config->enablePllUsbOutput = false; #endif /* FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD */ config->enableSysCLkOutput = false; config->enableACBufferBypass = false; #if (defined(FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD) && \ FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD) config->enableADCOutput = true; #endif /* FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD */ } #if !(defined(FSL_FEATURE_ANACTRL_HAS_NO_FREQ_ME_CTRL) && FSL_FEATURE_ANACTRL_HAS_NO_FREQ_ME_CTRL) /*! * brief Measures the frequency of the target clock source. * * This function measures target frequency according to a accurate reference frequency.The formula is: * Ftarget = (CAPVAL * Freference) / ((1<= 2U); uint32_t targetClkFreq = 0U; uint32_t capval = 0U; /* Init a measurement cycle. */ base->FREQ_ME_CTRL = ANACTRL_FREQ_ME_CTRL_PROG_MASK + ANACTRL_FREQ_ME_CTRL_CAPVAL_SCALE(scale); while (ANACTRL_FREQ_ME_CTRL_PROG_MASK == (base->FREQ_ME_CTRL & ANACTRL_FREQ_ME_CTRL_PROG_MASK)) { } /* Calculate the target clock frequency. */ capval = (base->FREQ_ME_CTRL & ANACTRL_FREQ_ME_CTRL_CAPVAL_SCALE_MASK); targetClkFreq = (uint32_t)(uint64_t)(((uint64_t)capval * (uint64_t)refClkFreq) / ((1ULL << scale) - 1ULL)); return targetClkFreq; } #endif /* FSL_FEATURE_ANACTRL_HAS_NO_FREQ_ME_CTRL */