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