1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019, 2022~2023 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_adc.h"
10 #include "fsl_clock.h"
11
12 /* Component ID definition, used by tools. */
13 #ifndef FSL_COMPONENT_ID
14 #define FSL_COMPONENT_ID "platform.drivers.lpc_adc"
15 #endif
16
17 #if defined(ADC_RSTS)
18 #define ADC_RESETS_ARRAY ADC_RSTS
19 #elif defined(ADC_RSTS_N)
20 #define ADC_RESETS_ARRAY ADC_RSTS_N
21 #endif
22
23 static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS;
24 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
25 static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS;
26 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
27 #if defined(ADC_RESETS_ARRAY)
28 /* Reset array */
29 static const reset_ip_name_t s_adcResets[] = ADC_RESETS_ARRAY;
30 #endif
31
32 #define FREQUENCY_1MHZ (1000000UL)
33
ADC_GetInstance(ADC_Type * base)34 static uint32_t ADC_GetInstance(ADC_Type *base)
35 {
36 uint32_t instance;
37
38 /* Find the instance index from base address mappings. */
39 for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++)
40 {
41 if (s_adcBases[instance] == base)
42 {
43 break;
44 }
45 }
46
47 assert(instance < ARRAY_SIZE(s_adcBases));
48
49 return instance;
50 }
51
52 /*!
53 * brief Initialize the ADC module.
54 *
55 * param base ADC peripheral base address.
56 * param config Pointer to configuration structure, see to #adc_config_t.
57 */
ADC_Init(ADC_Type * base,const adc_config_t * config)58 void ADC_Init(ADC_Type *base, const adc_config_t *config)
59 {
60 assert(config != NULL);
61
62 uint32_t tmp32 = 0U;
63
64 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
65 /* Enable clock. */
66 CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]);
67 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
68
69 #if defined(ADC_RESETS_ARRAY)
70 RESET_ReleasePeripheralReset(s_adcResets[ADC_GetInstance(base)]);
71 #endif
72
73 /* Disable the interrupts. */
74 base->INTEN = 0U; /* Quickly disable all the interrupts. */
75
76 /* Configure the ADC block. */
77 tmp32 = ADC_CTRL_CLKDIV(config->clockDividerNumber);
78
79 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) && FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE)
80 /* Async or Sync clock mode. */
81 switch (config->clockMode)
82 {
83 case kADC_ClockAsynchronousMode:
84 tmp32 |= ADC_CTRL_ASYNMODE_MASK;
85 break;
86 default: /* kADC_ClockSynchronousMode */
87 break;
88 }
89 #endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */
90
91 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) && FSL_FEATURE_ADC_HAS_CTRL_RESOL)
92 /* Resolution. */
93
94 tmp32 |= ADC_CTRL_RESOL(config->resolution);
95 #endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */
96 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) && FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL)
97 /* Bypass calibration. */
98 if (config->enableBypassCalibration)
99 {
100 tmp32 |= ADC_CTRL_BYPASSCAL_MASK;
101 }
102 #endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */
103
104 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) && FSL_FEATURE_ADC_HAS_CTRL_TSAMP)
105 /* Sample time clock count. */
106 #if (defined(FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) && FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL)
107 if (config->clockMode == kADC_ClockAsynchronousMode)
108 {
109 #endif /* FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL */
110 tmp32 |= ADC_CTRL_TSAMP(config->sampleTimeNumber);
111 #if (defined(FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) && FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL)
112 }
113 #endif /* FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL */
114 #endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */
115 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) && FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE)
116 if (config->enableLowPowerMode)
117 {
118 tmp32 |= ADC_CTRL_LPWRMODE_MASK;
119 }
120 #endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */
121
122 base->CTRL = tmp32;
123
124 #if defined(FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN) && FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN
125 base->GPADC_CTRL0 |= ADC_GPADC_CTRL0_LDO_POWER_EN_MASK;
126 if (config->clockMode == kADC_ClockSynchronousMode)
127 {
128 base->GPADC_CTRL0 |= ADC_GPADC_CTRL0_PASS_ENABLE(config->sampleTimeNumber);
129 }
130 SDK_DelayAtLeastUs(300, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
131 #endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN */
132
133 #if defined(FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL) && FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL
134 tmp32 = *(uint32_t *)FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL;
135 if (tmp32 & FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL_VALID)
136 {
137 base->GPADC_CTRL1 = (tmp32 >> 1);
138 }
139 #if !(defined(FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT) && FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT)
140 base->STARTUP = ADC_STARTUP_ADC_ENA_MASK; /* Set the ADC Start bit */
141 #endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL */
142 #endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL */
143
144 #if (defined(FSL_FEATURE_ADC_HAS_TRIM_REG) && FSL_FEATURE_ADC_HAS_TRIM_REG)
145 base->TRM &= ~ADC_TRM_VRANGE_MASK;
146 base->TRM |= ADC_TRM_VRANGE(config->voltageRange);
147 #endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */
148 }
149
150 /*!
151 * brief Gets an available pre-defined settings for initial configuration.
152 *
153 * This function initializes the initial configuration structure with an available settings. The default values are:
154 * code
155 * config->clockMode = kADC_ClockSynchronousMode;
156 * config->clockDividerNumber = 0U;
157 * config->resolution = kADC_Resolution12bit;
158 * config->enableBypassCalibration = false;
159 * config->sampleTimeNumber = 0U;
160 * endcode
161 * param config Pointer to configuration structure.
162 */
ADC_GetDefaultConfig(adc_config_t * config)163 void ADC_GetDefaultConfig(adc_config_t *config)
164 {
165 /* Initializes the configure structure to zero. */
166 (void)memset(config, 0, sizeof(*config));
167
168 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) && FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE)
169
170 config->clockMode = kADC_ClockSynchronousMode;
171 #endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */
172
173 config->clockDividerNumber = 0U;
174 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) && FSL_FEATURE_ADC_HAS_CTRL_RESOL)
175 config->resolution = kADC_Resolution12bit;
176 #endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */
177 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) && FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL)
178 config->enableBypassCalibration = false;
179 #endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */
180 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) && FSL_FEATURE_ADC_HAS_CTRL_TSAMP)
181 config->sampleTimeNumber = 0U;
182 #endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */
183 #if (defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) && FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE)
184 config->enableLowPowerMode = false;
185 #endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */
186 #if (defined(FSL_FEATURE_ADC_HAS_TRIM_REG) && FSL_FEATURE_ADC_HAS_TRIM_REG)
187 config->voltageRange = kADC_HighVoltageRange;
188 #endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */
189 }
190
191 /*!
192 * brief Deinitialize the ADC module.
193 *
194 * param base ADC peripheral base address.
195 */
ADC_Deinit(ADC_Type * base)196 void ADC_Deinit(ADC_Type *base)
197 {
198 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
199 /* Disable the clock. */
200 CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]);
201 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
202 }
203
204 #if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC)
205 #if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG
206 /*!
207 * brief Do the hardware self-calibration.
208 * deprecated Do not use this function. It has been superceded by @ref ADC_DoOffsetCalibration.
209 *
210 * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D
211 * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation.
212 *
213 * param base ADC peripheral base address.
214 * retval true Calibration succeed.
215 * retval false Calibration failed.
216 */
ADC_DoSelfCalibration(ADC_Type * base)217 bool ADC_DoSelfCalibration(ADC_Type *base)
218 {
219 uint32_t frequency = 0U;
220 uint32_t delayUs = 0U;
221 bool ret = true;
222
223 /* Enable the converter. */
224 /* This bit can only be set 1 by software. It is cleared automatically whenever the ADC is powered down.
225 This bit should be set after at least 10 ms after the ADC is powered on. */
226 base->STARTUP = ADC_STARTUP_ADC_ENA_MASK;
227 SDK_DelayAtLeastUs(1U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
228 if (0UL == (base->STARTUP & ADC_STARTUP_ADC_ENA_MASK))
229 {
230 ret = false; /* ADC is not powered up. */
231 }
232
233 /* Get the ADC clock frequency in synchronous mode. */
234 frequency = CLOCK_GetFreq(kCLOCK_BusClk) / (((base->CTRL & ADC_CTRL_CLKDIV_MASK) >> ADC_CTRL_CLKDIV_SHIFT) + 1UL);
235 #if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) && FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
236 /* Get the ADC clock frequency in asynchronous mode. */
237 if (ADC_CTRL_ASYNMODE_MASK == (base->CTRL & ADC_CTRL_ASYNMODE_MASK))
238 {
239 frequency = CLOCK_GetAdcClkFreq();
240 }
241 #endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE */
242 assert(0U != frequency);
243
244 /* If not in by-pass mode, do the calibration. */
245 if ((ADC_CALIB_CALREQD_MASK == (base->CALIB & ADC_CALIB_CALREQD_MASK)) &&
246 (0U == (base->CTRL & ADC_CTRL_BYPASSCAL_MASK)))
247 {
248 /* A calibration cycle requires approximately 81 ADC clocks to complete. */
249 delayUs = (120UL * FREQUENCY_1MHZ) / frequency + 1UL;
250 /* Calibration is needed, do it now. */
251 base->CALIB = ADC_CALIB_CALIB_MASK;
252 SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
253 if (ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK))
254 {
255 ret = false; /* Calibration timeout. */
256 }
257 }
258
259 /* A “dummy” conversion cycle requires approximately 6 ADC clocks */
260 delayUs = (10UL * FREQUENCY_1MHZ) / frequency + 1UL;
261 base->STARTUP |= ADC_STARTUP_ADC_INIT_MASK;
262 SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
263 if (ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK))
264 {
265 ret = false;
266 }
267
268 return ret;
269 }
270
271 /*!
272 * brief Do the hardware offset-calibration.
273 *
274 * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D
275 * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation.
276 *
277 * param base ADC peripheral base address.
278 * param frequency The clock frequency that ADC operates at.
279 * retval true Calibration succeed.
280 * retval false Calibration failed.
281 */
ADC_DoOffsetCalibration(ADC_Type * base,uint32_t frequency)282 bool ADC_DoOffsetCalibration(ADC_Type *base, uint32_t frequency)
283 {
284 assert(frequency != 0U);
285
286 uint32_t delayUs = 0U;
287 uint32_t tmp32 = base->CTRL;
288 /* The maximum ADC clock frequency during calibration is 30 MHz. */
289 const uint32_t maxCalibrationFrequency = 30000000UL;
290 bool ret = true;
291
292 /* Enable the converter. */
293 /* This bit should be set after at least 10 us after the ADC is powered on. */
294 SDK_DelayAtLeastUs(10U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
295 /* This bit can only be set 1 by software. It is cleared automatically whenever the ADC is powered down. */
296 base->STARTUP = ADC_STARTUP_ADC_ENA_MASK;
297
298 if (0UL == (base->STARTUP & ADC_STARTUP_ADC_ENA_MASK))
299 {
300 ret = false; /* ADC is not powered up. */
301 }
302
303 if (frequency >= maxCalibrationFrequency)
304 {
305 /* The divider should round up to ensure the frequency be lower than the maximum frequency. */
306 uint8_t divider = (frequency % maxCalibrationFrequency > 0UL) ?
307 (uint8_t)(frequency / maxCalibrationFrequency + 1UL) :
308 (uint8_t)(frequency / maxCalibrationFrequency);
309 /* Divide the system clock to yield an ADC clock of about 30 MHz. */
310 base->CTRL &= ~ADC_CTRL_CLKDIV_MASK;
311 base->CTRL |= ADC_CTRL_CLKDIV(divider - 1UL);
312 frequency /= divider;
313 }
314
315 /* Launch the calibration cycle or "dummy" conversions. */
316 if (ADC_CALIB_CALREQD_MASK == (base->CALIB & ADC_CALIB_CALREQD_MASK))
317 {
318 /* Calibration is required, do it now. */
319 base->CALIB = ADC_CALIB_CALIB_MASK;
320
321 /* A calibration cycle requires approximately 81 ADC clocks to complete. */
322 delayUs = (120UL * FREQUENCY_1MHZ) / frequency + 1UL;
323 SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
324 if (ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK))
325 {
326 base->CTRL = tmp32;
327 ret = false; /* Calibration timeout. */
328 }
329 }
330 else
331 {
332 /* If a calibration is not performed, launch the conversion cycle. */
333 base->STARTUP |= ADC_STARTUP_ADC_INIT_MASK;
334
335 /* A “dummy” conversion cycle requires approximately 6 ADC clocks */
336 delayUs = (10UL * FREQUENCY_1MHZ) / frequency + 1UL;
337 SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
338 if (ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK))
339 {
340 base->CTRL = tmp32;
341 ret = false; /* Initialization timeout. */
342 }
343 }
344
345 base->CTRL = tmp32;
346 return ret;
347 }
348 #else
349 /*!
350 * brief Do the hardware self-calibration.
351 *
352 * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D
353 * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation.
354 *
355 * param base ADC peripheral base address.
356 * param frequency The clock frequency that ADC operates at.
357 * retval true Calibration succeed.
358 * retval false Calibration failed.
359 */
ADC_DoSelfCalibration(ADC_Type * base,uint32_t frequency)360 bool ADC_DoSelfCalibration(ADC_Type *base, uint32_t frequency)
361 {
362 assert(frequency != 0U);
363
364 uint32_t tmp32 = 0U;
365
366 /* Store the current contents of the ADC CTRL register. */
367 tmp32 = base->CTRL;
368
369 /* Divide the system clock to yield an ADC clock of about 500 kHz. */
370 base->CTRL &= ~ADC_CTRL_CLKDIV_MASK;
371 base->CTRL |= ADC_CTRL_CLKDIV((frequency / 500000U) - 1U);
372
373 /* Clear the LPWR bit. */
374 base->CTRL &= ~ADC_CTRL_LPWRMODE_MASK;
375
376 /* Start ADC self-calibration. */
377 base->CTRL |= ADC_CTRL_CALMODE_MASK;
378 /* Delay for 300 uSec @ 500KHz ADC clock */
379 SDK_DelayAtLeastUs(300U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
380
381 /* Check the completion of calibration. */
382 if (ADC_CTRL_CALMODE_MASK == (base->CTRL & ADC_CTRL_CALMODE_MASK))
383 {
384 /* Restore the contents of the ADC CTRL register. */
385 base->CTRL = tmp32;
386 return false; /* Calibration timeout. */
387 }
388 /* Restore the contents of the ADC CTRL register. */
389 base->CTRL = tmp32;
390
391 return true;
392 }
393 #endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */
394 #endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC*/
395
396 /*!
397 * brief Configure the conversion sequence A.
398 *
399 * param base ADC peripheral base address.
400 * param config Pointer to configuration structure, see to #adc_conv_seq_config_t.
401 */
ADC_SetConvSeqAConfig(ADC_Type * base,const adc_conv_seq_config_t * config)402 void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
403 {
404 assert(config != NULL);
405
406 uint32_t tmp32;
407
408 tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */
409 #if (defined(FSL_FEATURE_ADC_HAS_SEQ_CTRL_TSAMP) && FSL_FEATURE_ADC_HAS_SEQ_CTRL_TSAMP)
410 | ADC_SEQ_CTRL_TSAMP(config->seqSampleTimeNumber) /* Sequence A sampling time.*/
411 #endif /* FSL_FEATURE_ADC_HAS_SEQ_CTRL_TSAMP*/
412 | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */
413
414 /* Polarity for tirgger signal. */
415 switch (config->triggerPolarity)
416 {
417 case kADC_TriggerPolarityPositiveEdge:
418 tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK;
419 break;
420 default: /* kADC_TriggerPolarityNegativeEdge */
421 break;
422 }
423
424 /* Bypass the clock Sync. */
425 if (config->enableSyncBypass)
426 {
427 tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK;
428 }
429
430 /* Interrupt point. */
431 switch (config->interruptMode)
432 {
433 case kADC_InterruptForEachSequence:
434 tmp32 |= ADC_SEQ_CTRL_MODE_MASK;
435 break;
436 default: /* kADC_InterruptForEachConversion */
437 break;
438 }
439
440 /* One trigger for a conversion, or for a sequence. */
441 if (config->enableSingleStep)
442 {
443 tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK;
444 }
445
446 base->SEQ_CTRL[0] = tmp32;
447 }
448
449 #if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ)
450 /*!
451 * brief Configure the conversion sequence B.
452 *
453 * param base ADC peripheral base address.
454 * param config Pointer to configuration structure, see to #adc_conv_seq_config_t.
455 */
ADC_SetConvSeqBConfig(ADC_Type * base,const adc_conv_seq_config_t * config)456 void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
457 {
458 assert(config != NULL);
459
460 uint32_t tmp32;
461
462 tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */
463 #if (defined(FSL_FEATURE_ADC_HAS_SEQ_CTRL_TSAMP) && FSL_FEATURE_ADC_HAS_SEQ_CTRL_TSAMP)
464 | ADC_SEQ_CTRL_TSAMP(config->seqSampleTimeNumber) /* Sequence B sampling time.*/
465 #endif /* FSL_FEATURE_ADC_HAS_SEQ_CTRL_TSAMP*/
466 | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */
467
468 /* Polarity for tirgger signal. */
469 switch (config->triggerPolarity)
470 {
471 case kADC_TriggerPolarityPositiveEdge:
472 tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK;
473 break;
474 default: /* kADC_TriggerPolarityPositiveEdge */
475 break;
476 }
477
478 /* Bypass the clock Sync. */
479 if (config->enableSyncBypass)
480 {
481 tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK;
482 }
483
484 /* Interrupt point. */
485 switch (config->interruptMode)
486 {
487 case kADC_InterruptForEachSequence:
488 tmp32 |= ADC_SEQ_CTRL_MODE_MASK;
489 break;
490 default: /* kADC_InterruptForEachConversion */
491 break;
492 }
493
494 /* One trigger for a conversion, or for a sequence. */
495 if (config->enableSingleStep)
496 {
497 tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK;
498 }
499
500 base->SEQ_CTRL[1] = tmp32;
501 }
502 #endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */
503
504 /*!
505 * brief Get the global ADC conversion infomation of sequence A.
506 *
507 * param base ADC peripheral base address.
508 * param info Pointer to information structure, see to #adc_result_info_t;
509 * retval true The conversion result is ready.
510 * retval false The conversion result is not ready yet.
511 */
ADC_GetConvSeqAGlobalConversionResult(ADC_Type * base,adc_result_info_t * info)512 bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *info)
513 {
514 assert(info != NULL);
515
516 uint32_t tmp32 = base->SEQ_GDAT[0]; /* Read to clear the status. */
517 bool ret = true;
518
519 if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32))
520 {
521 ret = false;
522 }
523
524 info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT;
525 info->thresholdCompareStatus = (adc_threshold_compare_status_t)(uint32_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >>
526 ADC_SEQ_GDAT_THCMPRANGE_SHIFT);
527 info->thresholdCorssingStatus = (adc_threshold_crossing_status_t)(uint32_t)(
528 (tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT);
529 info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT;
530 info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK);
531
532 return ret;
533 }
534
535 #if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ)
536 /*!
537 * brief Get the global ADC conversion infomation of sequence B.
538 *
539 * param base ADC peripheral base address.
540 * param info Pointer to information structure, see to #adc_result_info_t;
541 * retval true The conversion result is ready.
542 * retval false The conversion result is not ready yet.
543 */
ADC_GetConvSeqBGlobalConversionResult(ADC_Type * base,adc_result_info_t * info)544 bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *info)
545 {
546 assert(info != NULL);
547
548 uint32_t tmp32 = base->SEQ_GDAT[1]; /* Read to clear the status. */
549 bool ret = true;
550
551 if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32))
552 {
553 ret = false;
554 }
555
556 info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT;
557 info->thresholdCompareStatus = (adc_threshold_compare_status_t)(uint32_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >>
558 ADC_SEQ_GDAT_THCMPRANGE_SHIFT);
559 info->thresholdCorssingStatus = (adc_threshold_crossing_status_t)(uint32_t)(
560 (tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT);
561 info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT;
562 info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK);
563
564 return ret;
565 }
566 #endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */
567
568 /*!
569 * brief Get the channel's ADC conversion completed under each conversion sequence.
570 *
571 * param base ADC peripheral base address.
572 * param channel The indicated channel number.
573 * param info Pointer to information structure, see to #adc_result_info_t;
574 * retval true The conversion result is ready.
575 * retval false The conversion result is not ready yet.
576 */
ADC_GetChannelConversionResult(ADC_Type * base,uint32_t channel,adc_result_info_t * info)577 bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info)
578 {
579 assert(info != NULL);
580 assert(channel < ADC_DAT_COUNT);
581
582 uint32_t tmp32 = base->DAT[channel]; /* Read to clear the status. */
583 bool ret = true;
584
585 if (0U == (ADC_DAT_DATAVALID_MASK & tmp32))
586 {
587 ret = false;
588 }
589
590 info->result = (tmp32 & ADC_DAT_RESULT_MASK) >> ADC_DAT_RESULT_SHIFT;
591 #if (defined(FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT) && FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT)
592 switch ((base->CTRL & ADC_CTRL_RESOL_MASK) >> ADC_CTRL_RESOL_SHIFT)
593 {
594 case kADC_Resolution10bit:
595 info->result >>= kADC_Resolution10bitInfoResultShift;
596 break;
597 case kADC_Resolution8bit:
598 info->result >>= kADC_Resolution8bitInfoResultShift;
599 break;
600 case kADC_Resolution6bit:
601 info->result >>= kADC_Resolution6bitInfoResultShift;
602 break;
603 default:
604 assert(false);
605 break;
606 }
607 #endif
608 info->thresholdCompareStatus =
609 (adc_threshold_compare_status_t)(uint32_t)((tmp32 & ADC_DAT_THCMPRANGE_MASK) >> ADC_DAT_THCMPRANGE_SHIFT);
610 info->thresholdCorssingStatus =
611 (adc_threshold_crossing_status_t)(uint32_t)((tmp32 & ADC_DAT_THCMPCROSS_MASK) >> ADC_DAT_THCMPCROSS_SHIFT);
612 info->channelNumber = (tmp32 & ADC_DAT_CHANNEL_MASK) >> ADC_DAT_CHANNEL_SHIFT;
613 info->overrunFlag = ((tmp32 & ADC_DAT_OVERRUN_MASK) == ADC_DAT_OVERRUN_MASK);
614
615 return ret;
616 }
617 #if defined(FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP) && (FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP)
ADC_EnableTemperatureSensor(ADC_Type * base,bool enable)618 void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable)
619 {
620 if (enable)
621 {
622 SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE_MASK;
623 ASYNC_SYSCON->TEMPSENSORCTRL = kADC_NoOffsetAdded;
624 ASYNC_SYSCON->TEMPSENSORCTRL |= ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_MASK;
625 base->GPADC_CTRL0 |= (kADC_ADCInUnityGainMode | kADC_Impedance87kOhm);
626 }
627 else
628 {
629 /* if the temperature sensor is not turned on then ASYNCAPBCTRL is likely to be zero
630 * and accessing the registers will cause a memory access error. Test for this */
631 if (SYSCON->ASYNCAPBCTRL == SYSCON_ASYNCAPBCTRL_ENABLE_MASK)
632 {
633 ASYNC_SYSCON->TEMPSENSORCTRL = 0x0;
634 base->GPADC_CTRL0 &= ~(kADC_ADCInUnityGainMode | kADC_Impedance87kOhm);
635 base->GPADC_CTRL0 |= kADC_Impedance55kOhm;
636 }
637 }
638 }
639 #endif
640