1 /*
2 * Copyright 2018-2020, NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #include "fsl_anactrl.h"
9
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.anactrl"
13 #endif
14
15 /*******************************************************************************
16 * Prototypes
17 ******************************************************************************/
18 /*!
19 * @brief Get instance number for ANACTRL module.
20 *
21 * @param base ANACTRL peripheral base address
22 */
23 static uint32_t ANACTRL_GetInstance(ANACTRL_Type *base);
24
25 /*******************************************************************************
26 * Variables
27 ******************************************************************************/
28 /*! @brief Pointers to ANACTRL bases for each instance. */
29 static ANACTRL_Type *const s_anactrlBases[] = ANACTRL_BASE_PTRS;
30 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
31 /*! @brief Pointers to ANACTRL clocks for each instance. */
32 static const clock_ip_name_t s_anactrlClocks[] = ANALOGCTRL_CLOCKS;
33 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
34
35 /*******************************************************************************
36 * Code
37 ******************************************************************************/
38 /*!
39 * brief Get the ANACTRL instance from peripheral base address.
40 *
41 * param base ANACTRL peripheral base address.
42 * return ANACTRL instance.
43 */
ANACTRL_GetInstance(ANACTRL_Type * base)44 static uint32_t ANACTRL_GetInstance(ANACTRL_Type *base)
45 {
46 uint32_t instance;
47
48 /* Find the instance index from base address mappings. */
49 for (instance = 0; instance < ARRAY_SIZE(s_anactrlBases); instance++)
50 {
51 if (s_anactrlBases[instance] == base)
52 {
53 break;
54 }
55 }
56
57 assert(instance < ARRAY_SIZE(s_anactrlBases));
58
59 return instance;
60 }
61
62 /*!
63 * brief Initializes the ANACTRL mode, the module's clock will be enabled by invoking this function.
64 *
65 * param base ANACTRL peripheral base address.
66 */
ANACTRL_Init(ANACTRL_Type * base)67 void ANACTRL_Init(ANACTRL_Type *base)
68 {
69 assert(NULL != base);
70
71 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
72 /* Enable the clock for ANACTRL instance. */
73 CLOCK_EnableClock(s_anactrlClocks[ANACTRL_GetInstance(base)]);
74 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
75 }
76
77 /*!
78 * brief De-initializes ANACTRL module, the module's clock will be disabled by invoking this function.
79 *
80 * param base ANACTRL peripheral base address.
81 */
ANACTRL_Deinit(ANACTRL_Type * base)82 void ANACTRL_Deinit(ANACTRL_Type *base)
83 {
84 assert(NULL != base);
85
86 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
87 /* Disable the clock for ANACTRL instance. */
88 CLOCK_DisableClock(s_anactrlClocks[ANACTRL_GetInstance(base)]);
89 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
90 }
91
92 /*!
93 * brief Configs the on-chip high-speed Free Running Oscillator(FRO192M), such as enabling/disabling 12 MHZ clock output
94 * and enable/disable 96MHZ clock output.
95 *
96 * param base ANACTRL peripheral base address.
97 * param config Pointer to FRO192M configuration structure. Refer to anactrl_fro192M_config_t structure.
98 */
ANACTRL_SetFro192M(ANACTRL_Type * base,const anactrl_fro192M_config_t * config)99 void ANACTRL_SetFro192M(ANACTRL_Type *base, const anactrl_fro192M_config_t *config)
100 {
101 assert(NULL != config);
102
103 uint32_t tmp32 = base->FRO192M_CTRL;
104
105 tmp32 &= ~(ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK);
106
107 if (config->enable12MHzClk)
108 {
109 tmp32 |= ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK;
110 }
111 if (config->enable96MHzClk)
112 {
113 tmp32 |= ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK;
114 }
115
116 base->FRO192M_CTRL |= tmp32;
117 }
118
119 /*!
120 * brief Gets the default configuration of FRO192M.
121 * The default values are:
122 * code
123 config->enable12MHzClk = true;
124 config->enable96MHzClk = false;
125 endcode
126 * param config Pointer to FRO192M configuration structure. Refer to anactrl_fro192M_config_t structure.
127 */
ANACTRL_GetDefaultFro192MConfig(anactrl_fro192M_config_t * config)128 void ANACTRL_GetDefaultFro192MConfig(anactrl_fro192M_config_t *config)
129 {
130 assert(NULL != config);
131
132 /* Initializes the configure structure to zero. */
133 (void)memset(config, 0, sizeof(*config));
134
135 config->enable12MHzClk = true;
136 config->enable96MHzClk = false;
137 }
138
139 /*!
140 * brief Configs the 32 MHz Crystal oscillator(High-speed crystal oscillator), such as enable/disable output to CPU
141 * system, and so on.
142 *
143 * param base ANACTRL peripheral base address.
144 * param config Pointer to XO32M configuration structure. Refer to anactrl_xo32M_config_t structure.
145 */
ANACTRL_SetXo32M(ANACTRL_Type * base,const anactrl_xo32M_config_t * config)146 void ANACTRL_SetXo32M(ANACTRL_Type *base, const anactrl_xo32M_config_t *config)
147 {
148 assert(NULL != config);
149
150 uint32_t tmp32 = base->XO32M_CTRL;
151
152 tmp32 &= ~(ANACTRL_XO32M_CTRL_ACBUF_PASS_ENABLE_MASK | ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK);
153
154 /* Set XO32M CTRL. */
155 #if !(defined(FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD) && \
156 FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD)
157 tmp32 &= ~ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK;
158 if (config->enablePllUsbOutput)
159 {
160 tmp32 |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK;
161 }
162 #endif /* FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD */
163
164 if (config->enableACBufferBypass)
165 {
166 tmp32 |= ANACTRL_XO32M_CTRL_ACBUF_PASS_ENABLE_MASK;
167 }
168
169 if (config->enableSysCLkOutput)
170 {
171 tmp32 |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK;
172 }
173 base->XO32M_CTRL = tmp32;
174
175 #if (defined(FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD) && \
176 FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD)
177 if (config->enableADCOutput)
178 {
179 base->DUMMY_CTRL |= ANACTRL_DUMMY_CTRL_XO32M_ADC_CLK_MODE_MASK;
180 }
181 else
182 {
183 base->DUMMY_CTRL &= ~ANACTRL_DUMMY_CTRL_XO32M_ADC_CLK_MODE_MASK;
184 }
185 #endif /* FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD */
186 }
187
188 /*!
189 * brief Gets the default configuration of XO32M.
190 * The default values are:
191 * code
192 config->enableSysCLkOutput = false;
193 config->enableACBufferBypass = false;
194 endcode
195 * param config Pointer to XO32M configuration structure. Refer to anactrl_xo32M_config_t structure.
196 */
ANACTRL_GetDefaultXo32MConfig(anactrl_xo32M_config_t * config)197 void ANACTRL_GetDefaultXo32MConfig(anactrl_xo32M_config_t *config)
198 {
199 assert(NULL != config);
200
201 /* Initializes the configure structure to zero. */
202 (void)memset(config, 0, sizeof(*config));
203
204 #if !(defined(FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD) && \
205 FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD)
206 config->enablePllUsbOutput = false;
207 #endif /* FSL_FEATURE_ANACTRL_HAS_NO_ENABLE_PLL_USB_OUT_BIT_FIELD */
208 config->enableSysCLkOutput = false;
209 config->enableACBufferBypass = false;
210 #if (defined(FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD) && \
211 FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD)
212 config->enableADCOutput = true;
213 #endif /* FSL_FEATURE_ANACTRL_HAS_XO32M_ADC_CLK_MODE_BIF_FIELD */
214 }
215
216 /*!
217 * brief Measures the frequency of the target clock source.
218 *
219 * This function measures target frequency according to a accurate reference frequency.The formula is:
220 * Ftarget = (CAPVAL * Freference) / ((1<<SCALE)-1)
221 *
222 * note Both tartget and reference clocks are selectable by programming the target clock select FREQMEAS_TARGET register
223 * in INPUTMUX and reference clock select FREQMEAS_REF register in INPUTMUX.
224 *
225 * param base ANACTRL peripheral base address.
226 * param scale Define the power of 2 count that ref counter counts to during measurement, ranges from 2 to 31.
227 * param refClkFreq frequency of the reference clock.
228 *
229 * return frequency of the target clock.
230 */
ANACTRL_MeasureFrequency(ANACTRL_Type * base,uint8_t scale,uint32_t refClkFreq)231 uint32_t ANACTRL_MeasureFrequency(ANACTRL_Type *base, uint8_t scale, uint32_t refClkFreq)
232 {
233 assert(scale >= 2U);
234
235 uint32_t targetClkFreq = 0U;
236 uint32_t capval = 0U;
237
238 /* Init a measurement cycle. */
239 base->FREQ_ME_CTRL = ANACTRL_FREQ_ME_CTRL_PROG_MASK + ANACTRL_FREQ_ME_CTRL_CAPVAL_SCALE(scale);
240 while (ANACTRL_FREQ_ME_CTRL_PROG_MASK == (base->FREQ_ME_CTRL & ANACTRL_FREQ_ME_CTRL_PROG_MASK))
241 {
242 }
243
244 /* Calculate the target clock frequency. */
245 capval = (base->FREQ_ME_CTRL & ANACTRL_FREQ_ME_CTRL_CAPVAL_SCALE_MASK);
246 targetClkFreq = (capval * refClkFreq) / ((1UL << scale) - 1UL);
247
248 return targetClkFreq;
249 }
250