1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #include "fsl_hsadc.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.hsadc"
17 #endif
18
19 /*
20 * Define the MACROs to help calculating the position of register field for specific sample index.
21 */
22 /* ZXCTRL1 & ZXCTRL2. */
23 #define HSADC_ZXCTRL_ZCE_MASK(index) ((uint16_t)3U << (2U * ((uint16_t)(index))))
24 #define HSADC_ZXCTRL_ZCE(index, value) (uint16_t)(((uint16_t)(value)) << (2U * ((uint16_t)(index))))
25 /* CLIST1 & CLIST2 & CLIST3 & CLIST4 */
26 #define HSADC_CLIST_SAMPLE_MASK(index) ((uint16_t)0xFU << (4U * ((uint16_t)(index))))
27 #define HSADC_CLIST_SAMPLE(index, value) (uint16_t)(((uint16_t)(value)) << (4U * ((uint16_t)(index))))
28
29 /*******************************************************************************
30 * Prototypes
31 ******************************************************************************/
32 /*!
33 * @brief Get instance number for HSADC module.
34 *
35 * @param base HSADC peripheral base address.
36 */
37 static uint32_t HSADC_GetInstance(HSADC_Type *base);
38
39 /*!
40 * @brief Set channel 6/7's sub mux channel number.
41 *
42 * When channel number is 6/7, it represents to configure converterA's channel 6/7 sub multiplex channel number.
43 * When channel number is 14/15, it represents to configure converterB's channel 6/7 sub multiplex channel number.
44 * In other cases, this function won't be functional.
45 *
46 * @param base HSADC peripheral base address.
47 * @param channelNumber Channel number.
48 * @param muxNumber Channel 6/7's sub multiplex channel number.
49 * @param enableDifferentialPair Enable channel 6/7 to be differential pair or not.
50 */
51 static void HSADC_SetChannel67Mux(HSADC_Type *base,
52 uint16_t channelNumber,
53 uint16_t muxNumber,
54 bool enableDifferentialPair);
55
56 /*******************************************************************************
57 * Variables
58 ******************************************************************************/
59 /*! @brief Pointers to HSADC bases for each instance. */
60 static HSADC_Type *const s_hsadcBases[] = HSADC_BASE_PTRS;
61
62 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
63 /*! @brief Pointers to HSADC clocks for each instance. */
64 static const clock_ip_name_t s_hsadcClocks[] = HSADC_CLOCKS;
65 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
66
67 /*******************************************************************************
68 * Code
69 ******************************************************************************/
HSADC_GetInstance(HSADC_Type * base)70 static uint32_t HSADC_GetInstance(HSADC_Type *base)
71 {
72 uint32_t instance;
73
74 /* Find the instance index from base address mappings. */
75 for (instance = 0; instance < ARRAY_SIZE(s_hsadcBases); instance++)
76 {
77 if (s_hsadcBases[instance] == base)
78 {
79 break;
80 }
81 }
82
83 assert(instance < ARRAY_SIZE(s_hsadcBases));
84
85 return instance;
86 }
87
88 /*!
89 * brief Initializes the HSADC module.
90 *
91 * This function initializes the HSADC module.
92 * The operations are:
93 * - Enable the clock for HSADC.
94 * - Set the global settings for HSADC converter.
95 *
96 * param base HSADC peripheral base address.
97 * param config Pointer to configuration structure. See the "hsadc_config_t".
98 */
HSADC_Init(HSADC_Type * base,const hsadc_config_t * config)99 void HSADC_Init(HSADC_Type *base, const hsadc_config_t *config)
100 {
101 assert(NULL != config);
102 assert(config->powerUpDelayCount <= (HSADC_PWR_PUDELAY_MASK >> HSADC_PWR_PUDELAY_SHIFT));
103
104 uint16_t tmp16;
105
106 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
107 /* Enable module clock. */
108 CLOCK_EnableClock(s_hsadcClocks[HSADC_GetInstance(base)]);
109 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
110
111 /* CTRL1 */
112 tmp16 = (uint16_t)(base->CTRL1 & ~HSADC_CTRL1_SMODE_MASK);
113 tmp16 |= HSADC_CTRL1_SMODE(config->dualConverterScanMode);
114 base->CTRL1 = tmp16;
115
116 /* CTRL2 */
117 tmp16 = (uint16_t)(base->CTRL2 & ~HSADC_CTRL2_SIMULT_MASK);
118 if (config->enableSimultaneousMode)
119 {
120 tmp16 |= HSADC_CTRL2_SIMULT_MASK;
121 }
122 base->CTRL2 = tmp16;
123
124 /* CTRL3 */
125 tmp16 = (uint16_t)(base->CTRL3 & ~(HSADC_CTRL3_ADCRES_MASK | HSADC_CTRL3_DMASRC_MASK));
126 tmp16 |= (HSADC_CTRL3_ADCRES(config->resolution) | HSADC_CTRL3_DMASRC(config->DMATriggerSoruce));
127 base->CTRL3 = tmp16;
128
129 /* PWR */
130 tmp16 = (uint16_t)(base->PWR & ~(HSADC_PWR_ASB_MASK | HSADC_PWR_APD_MASK | HSADC_PWR_PUDELAY_MASK));
131 switch (config->idleWorkMode)
132 {
133 case kHSADC_IdleKeepNormal:
134 break;
135 case kHSADC_IdleAutoStandby:
136 tmp16 |= HSADC_PWR_ASB_MASK;
137 break;
138 case kHSADC_IdleAutoPowerDown:
139 tmp16 |= HSADC_PWR_APD_MASK;
140 break;
141 default:
142 assert(false);
143 break;
144 }
145 tmp16 |= HSADC_PWR_PUDELAY(config->powerUpDelayCount);
146 base->PWR = tmp16;
147 }
148
149 /*!
150 * brief Gets an available pre-defined settings for module's configuration.
151 *
152 * This function initializes the module's configuration structure with an available settings.
153 * The default value are:
154 * code
155 * config->dualConverterScanMode = kHSADC_DualConverterWorkAsTriggeredParallel;
156 * config->enableSimultaneousMode = true;
157 * config->resolution = kHSADC_Resolution12Bit;
158 * config->DMATriggerSoruce = kHSADC_DMATriggerSourceAsEndOfScan;
159 * config->idleWorkMode = kHSADC_IdleKeepNormal;
160 * config->powerUpDelay = 18U;
161 * endcode
162 * param config Pointer to configuration structure. See the "hsadc_config_t"
163 */
HSADC_GetDefaultConfig(hsadc_config_t * config)164 void HSADC_GetDefaultConfig(hsadc_config_t *config)
165 {
166 assert(NULL != config);
167
168 /* Initializes the configure structure to zero. */
169 (void)memset(config, 0, sizeof(*config));
170
171 config->dualConverterScanMode = kHSADC_DualConverterWorkAsTriggeredParallel;
172 config->enableSimultaneousMode = true;
173 config->resolution = kHSADC_Resolution12Bit;
174 config->DMATriggerSoruce = kHSADC_DMATriggerSourceAsEndOfScan;
175 config->idleWorkMode = kHSADC_IdleKeepNormal;
176 config->powerUpDelayCount = 18U;
177 }
178
179 /*!
180 * brief De-initializes the HSADC module.
181 *
182 * This function de-initializes the HSADC module.
183 * The operations are:
184 * - Power down both converters.
185 * - Disable the clock for HSADC.
186 *
187 * param base HSADC peripheral base address.
188 */
HSADC_Deinit(HSADC_Type * base)189 void HSADC_Deinit(HSADC_Type *base)
190 {
191 /* Power down both converter. */
192 base->PWR &= (uint16_t)(~(HSADC_PWR_PDA_MASK | HSADC_PWR_PDB_MASK));
193
194 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
195 /* Disable module clock. */
196 CLOCK_DisableClock(s_hsadcClocks[HSADC_GetInstance(base)]);
197 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
198 }
199
200 /*!
201 * brief Configures the converter.
202 *
203 * param base HSADC peripheral base address.
204 * param converterMask Mask for converters to be configured. See the "_hsadc_converter_id".
205 * param config Pointer to configuration structure. See the "hsadc_converter_config_t".
206 */
HSADC_SetConverterConfig(HSADC_Type * base,uint16_t converterMask,const hsadc_converter_config_t * config)207 void HSADC_SetConverterConfig(HSADC_Type *base, uint16_t converterMask, const hsadc_converter_config_t *config)
208 {
209 assert(NULL != config);
210 /* Check the divisor value's range. */
211 assert((config->clockDivisor >= 2U) &&
212 (config->clockDivisor <= ((HSADC_CTRL2_DIVA_MASK >> HSADC_CTRL2_DIVA_SHIFT) + 1U)));
213
214 uint16_t tmp16;
215
216 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
217 {
218 assert(config->samplingTimeCount <= (HSADC_SAMPTIM_SAMPT_A_MASK >> HSADC_SAMPTIM_SAMPT_A_SHIFT));
219
220 /* CTRL2 */
221 tmp16 = (uint16_t)(base->CTRL2 & ~HSADC_CTRL2_DIVA_MASK);
222 tmp16 |= HSADC_CTRL2_DIVA(config->clockDivisor - 1U);
223 base->CTRL2 = tmp16;
224
225 /* SAMPTIM */
226 tmp16 = (uint16_t)(base->SAMPTIM & ~HSADC_SAMPTIM_SAMPT_A_MASK);
227 tmp16 |= HSADC_SAMPTIM_SAMPT_A(config->samplingTimeCount);
228 base->SAMPTIM = tmp16;
229
230 /* CALIB */
231 tmp16 = (uint16_t)(base->CALIB & ~(HSADC_CALIB_REQSINGA_MASK | HSADC_CALIB_REQDIFA_MASK));
232 if ((uint16_t)kHSADC_CalibrationModeSingleEnded ==
233 ((uint16_t)kHSADC_CalibrationModeSingleEnded & config->powerUpCalibrationModeMask))
234 {
235 tmp16 |= HSADC_CALIB_REQSINGA_MASK;
236 }
237 if ((uint16_t)kHSADC_CalibrationModeDifferential ==
238 ((uint16_t)kHSADC_CalibrationModeDifferential & config->powerUpCalibrationModeMask))
239 {
240 tmp16 |= HSADC_CALIB_REQDIFA_MASK;
241 }
242 base->CALIB = tmp16;
243 }
244
245 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
246 {
247 assert(config->samplingTimeCount <= (HSADC_SAMPTIM_SAMPT_B_MASK >> HSADC_SAMPTIM_SAMPT_B_SHIFT));
248
249 /* PWR2 */
250 tmp16 = (uint16_t)(base->PWR2 & ~HSADC_PWR2_DIVB_MASK);
251 tmp16 |= HSADC_PWR2_DIVB(config->clockDivisor - 1U);
252 base->PWR2 = tmp16;
253
254 /* SAMPTIM */
255 tmp16 = (uint16_t)(base->SAMPTIM & ~HSADC_SAMPTIM_SAMPT_B_MASK);
256 tmp16 |= HSADC_SAMPTIM_SAMPT_B(config->samplingTimeCount);
257 base->SAMPTIM = tmp16;
258
259 /* CALIB */
260 tmp16 = (uint16_t)(base->CALIB & ~(HSADC_CALIB_REQSINGB_MASK | HSADC_CALIB_REQDIFB_MASK));
261 if ((uint16_t)kHSADC_CalibrationModeSingleEnded ==
262 ((uint16_t)kHSADC_CalibrationModeSingleEnded & config->powerUpCalibrationModeMask))
263 {
264 tmp16 |= HSADC_CALIB_REQSINGB_MASK;
265 }
266 if ((uint16_t)kHSADC_CalibrationModeDifferential ==
267 ((uint16_t)kHSADC_CalibrationModeDifferential & config->powerUpCalibrationModeMask))
268 {
269 tmp16 |= HSADC_CALIB_REQDIFB_MASK;
270 }
271 base->CALIB = tmp16;
272 }
273 }
274
275 /*!
276 * brief Gets an available pre-defined settings for each converter's configuration.
277 *
278 * This function initializes each converter's configuration structure with available settings.
279 * The default value are:
280 * code
281 * config->clockDivisor = 4U;
282 * config->samplingTimeCount = 0U;
283 * config->enablePowerUpCalibration = false;
284 * config->powerUpCalibrationModeMask = kHSADC_CalibrationModeSingleEnded;
285 * endcode
286 * param config Pointer to configuration structure. See the "hsadc_converter_config_t"
287 */
HSADC_GetDefaultConverterConfig(hsadc_converter_config_t * config)288 void HSADC_GetDefaultConverterConfig(hsadc_converter_config_t *config)
289 {
290 assert(NULL != config);
291
292 config->clockDivisor = 5U;
293 config->samplingTimeCount = 0U;
294 config->powerUpCalibrationModeMask = 0U;
295 }
296
297 /*!
298 * brief Enables the converter's conversion.
299 *
300 * This function enables the converter's conversion by making the converter exit stop mode. The conversion should
301 * only be launched after the converter is enabled. When this feature is asserted to be "false", the current scan is
302 * stopped and no further scans can start. All the software and hardware triggers are ignored.
303 *
304 * param base HSADC peripheral base address.
305 * param converterMask Mask for converters to be operated. See the "_hsadc_converter_id".
306 * param enable Enable or disable the feature.
307 */
HSADC_EnableConverter(HSADC_Type * base,uint16_t converterMask,bool enable)308 void HSADC_EnableConverter(HSADC_Type *base, uint16_t converterMask, bool enable)
309 {
310 /* CTRL1 */
311 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
312 {
313 if (true == enable)
314 {
315 base->CTRL1 &= ~(uint16_t)HSADC_CTRL1_STOPA_MASK;
316 }
317 else
318 {
319 base->CTRL1 |= HSADC_CTRL1_STOPA_MASK;
320 }
321 }
322 /* CTRL2 */
323 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
324 {
325 if (true == enable)
326 {
327 base->CTRL2 &= ~(uint16_t)HSADC_CTRL2_STOPB_MASK;
328 }
329 else
330 {
331 base->CTRL2 |= HSADC_CTRL2_STOPB_MASK;
332 }
333 }
334 }
335
336 /*!
337 * brief Enables the input of an external sync signal.
338 *
339 * This function enables the input of the external sync signal. The external sync signal could be used to trigger the
340 * conversion if the hardware trigger-related setting is used.
341 * Note: When in "Once" scan mode, this gate is off automatically after an available sync is received.
342 * Enable the input again manually if another sync signal is needed.
343 *
344 * param base HSADC peripheral base address.
345 * param converterMask Mask for converters to be operated. See the "_hsadc_converter_id".
346 * param enable Enable or disable the feature.
347 */
HSADC_EnableConverterSyncInput(HSADC_Type * base,uint16_t converterMask,bool enable)348 void HSADC_EnableConverterSyncInput(HSADC_Type *base, uint16_t converterMask, bool enable)
349 {
350 /* CTRL1 */
351 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
352 {
353 if (true == enable)
354 {
355 base->CTRL1 |= HSADC_CTRL1_SYNCA_MASK;
356 }
357 else
358 {
359 base->CTRL1 &= ~(uint16_t)HSADC_CTRL1_SYNCA_MASK;
360 }
361 }
362 /* CTRL2 */
363 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
364 {
365 if (true == enable)
366 {
367 base->CTRL2 |= HSADC_CTRL2_SYNCB_MASK;
368 }
369 else
370 {
371 base->CTRL2 &= ~(uint16_t)HSADC_CTRL2_SYNCB_MASK;
372 }
373 }
374 }
375
376 /*!
377 * brief Enables power for the converter.
378 *
379 * This function enables the power for the converter. The converter should be powered on before conversion. Once
380 * this API is called, the converter is powered on after a few moments (so-called power up delay) to make the
381 * power stable.
382 *
383 * param base HSADC peripheral base address.
384 * param converterMask Mask for converters to be operated. See the "_hsadc_converter_id".
385 * param enable Enable or disable the feature.
386 */
HSADC_EnableConverterPower(HSADC_Type * base,uint16_t converterMask,bool enable)387 void HSADC_EnableConverterPower(HSADC_Type *base, uint16_t converterMask, bool enable)
388 {
389 /* PWR */
390 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
391 {
392 if (true == enable)
393 {
394 base->PWR &= ~(uint16_t)HSADC_PWR_PDA_MASK;
395 }
396 else
397 {
398 base->PWR |= HSADC_PWR_PDA_MASK;
399 }
400 }
401 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
402 {
403 if (true == enable)
404 {
405 base->PWR &= ~(uint16_t)HSADC_PWR_PDB_MASK;
406 }
407 else
408 {
409 base->PWR |= HSADC_PWR_PDB_MASK;
410 }
411 }
412 }
413
414 /*!
415 * brief Triggers the converter by using the software trigger.
416 *
417 * This function triggers the converter using a software trigger. The software trigger can be used to start a
418 * conversion
419 * sequence.
420 *
421 * param base HSADC peripheral base address.
422 * param converterMask Mask for converters to be operated. See the "_hsadc_converter_id".
423 */
HSADC_DoSoftwareTriggerConverter(HSADC_Type * base,uint16_t converterMask)424 void HSADC_DoSoftwareTriggerConverter(HSADC_Type *base, uint16_t converterMask)
425 {
426 /* CTRL1 */
427 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
428 {
429 base->CTRL1 |= HSADC_CTRL1_STARTA_MASK;
430 }
431 /* CTRL2 */
432 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
433 {
434 base->CTRL2 |= HSADC_CTRL2_STARTB_MASK;
435 }
436 }
437
438 /*!
439 * brief Enables the DMA feature.
440 *
441 * param base HSADC peripheral base address.
442 * param converterMask Mask for converters to be operated. See the "_hsadc_converter_id".
443 * param enable Enable or disable the feature.
444 */
HSADC_EnableConverterDMA(HSADC_Type * base,uint16_t converterMask,bool enable)445 void HSADC_EnableConverterDMA(HSADC_Type *base, uint16_t converterMask, bool enable)
446 {
447 /* CTRL1 */
448 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
449 {
450 if (true == enable)
451 {
452 base->CTRL1 |= HSADC_CTRL1_DMAENA_MASK;
453 }
454 else
455 {
456 base->CTRL1 &= (uint16_t)(~HSADC_CTRL1_DMAENA_MASK);
457 }
458 }
459 /* CTRL2 */
460 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
461 {
462 if (true == enable)
463 {
464 base->CTRL2 |= HSADC_CTRL2_DMAENB_MASK;
465 }
466 else
467 {
468 base->CTRL2 &= (uint16_t)(~HSADC_CTRL2_DMAENB_MASK);
469 }
470 }
471 }
472
473 /*!
474 * brief Enables the interrupts.
475 *
476 * param base HSADC peripheral base address.
477 * param mask Mask value for interrupt events. See the "_hsadc_interrupt_enable".
478 */
HSADC_EnableInterrupts(HSADC_Type * base,uint16_t mask)479 void HSADC_EnableInterrupts(HSADC_Type *base, uint16_t mask)
480 {
481 uint16_t tmp16;
482
483 /* CTRL1 */
484 tmp16 = base->CTRL1;
485 if ((uint16_t)kHSADC_ZeroCrossingInterruptEnable == ((uint16_t)kHSADC_ZeroCrossingInterruptEnable & mask))
486 {
487 tmp16 |= HSADC_CTRL1_ZCIE_MASK;
488 }
489 if ((uint16_t)kHSADC_HighLimitInterruptEnable == ((uint16_t)kHSADC_HighLimitInterruptEnable & mask))
490 {
491 tmp16 |= HSADC_CTRL1_HLMTIE_MASK;
492 }
493 if ((uint16_t)kHSADC_LowLimitInterruptEnable == ((uint16_t)kHSADC_LowLimitInterruptEnable & mask))
494 {
495 tmp16 |= HSADC_CTRL1_LLMTIE_MASK;
496 }
497 if ((uint16_t)kHSADC_ConverterAEndOfScanInterruptEnable ==
498 ((uint16_t)kHSADC_ConverterAEndOfScanInterruptEnable & mask))
499 {
500 tmp16 |= HSADC_CTRL1_EOSIEA_MASK;
501 }
502 base->CTRL1 = tmp16;
503
504 /* CTRL2 */
505 if ((uint16_t)kHSADC_ConverterBEndOfScanInterruptEnable ==
506 ((uint16_t)kHSADC_ConverterBEndOfScanInterruptEnable & mask))
507 {
508 base->CTRL2 |= HSADC_CTRL2_EOSIEB_MASK;
509 }
510
511 /* CALIB */
512 tmp16 = base->CALIB;
513 if ((uint16_t)kHSADC_ConverterAEndOfCalibrationInterruptEnable ==
514 ((uint16_t)kHSADC_ConverterAEndOfCalibrationInterruptEnable & mask))
515 {
516 tmp16 |= HSADC_CALIB_EOCALIEA_MASK;
517 }
518 if ((uint16_t)kHSADC_ConverterBEndOfCalibrationInterruptEnable ==
519 ((uint16_t)kHSADC_ConverterBEndOfCalibrationInterruptEnable & mask))
520 {
521 tmp16 |= HSADC_CALIB_EOCALIEB_MASK;
522 }
523 base->CALIB = tmp16;
524 }
525
526 /*!
527 * brief Disables the interrupts.
528 *
529 * param base HSADC peripheral base address.
530 * param mask Mask value for interrupt events. See the "_hsadc_interrupt_enable".
531 */
HSADC_DisableInterrupts(HSADC_Type * base,uint16_t mask)532 void HSADC_DisableInterrupts(HSADC_Type *base, uint16_t mask)
533 {
534 uint16_t tmp16;
535
536 /* CTRL1 */
537 tmp16 = base->CTRL1;
538 if ((uint16_t)kHSADC_ZeroCrossingInterruptEnable == ((uint16_t)kHSADC_ZeroCrossingInterruptEnable & mask))
539 {
540 tmp16 &= HSADC_CTRL1_ZCIE_MASK;
541 }
542 if ((uint16_t)kHSADC_HighLimitInterruptEnable == ((uint16_t)kHSADC_HighLimitInterruptEnable & mask))
543 {
544 tmp16 &= HSADC_CTRL1_HLMTIE_MASK;
545 }
546 if ((uint16_t)kHSADC_LowLimitInterruptEnable == ((uint16_t)kHSADC_LowLimitInterruptEnable & mask))
547 {
548 tmp16 &= HSADC_CTRL1_LLMTIE_MASK;
549 }
550 if ((uint16_t)kHSADC_ConverterAEndOfScanInterruptEnable ==
551 ((uint16_t)kHSADC_ConverterAEndOfScanInterruptEnable & mask))
552 {
553 tmp16 &= HSADC_CTRL1_EOSIEA_MASK;
554 }
555 base->CTRL1 = tmp16;
556
557 /* CTRL2 */
558 if ((uint16_t)kHSADC_ConverterBEndOfScanInterruptEnable ==
559 ((uint16_t)kHSADC_ConverterBEndOfScanInterruptEnable & mask))
560 {
561 base->CTRL2 &= (uint16_t)(~HSADC_CTRL2_EOSIEB_MASK);
562 }
563
564 /* CALIB */
565 tmp16 = base->CALIB;
566 if ((uint16_t)kHSADC_ConverterAEndOfCalibrationInterruptEnable ==
567 ((uint16_t)kHSADC_ConverterAEndOfCalibrationInterruptEnable & mask))
568 {
569 tmp16 &= HSADC_CALIB_EOCALIEA_MASK;
570 }
571 if ((uint16_t)kHSADC_ConverterBEndOfCalibrationInterruptEnable ==
572 ((uint16_t)kHSADC_ConverterBEndOfCalibrationInterruptEnable & mask))
573 {
574 tmp16 &= HSADC_CALIB_EOCALIEB_MASK;
575 }
576 base->CALIB = tmp16;
577 }
578
579 /*!
580 * brief Gets the status flags.
581 *
582 * param base HSADC peripheral base address.
583 *
584 * return Mask value for the event flags. See the "_hsadc_status_flags".
585 */
HSADC_GetStatusFlags(HSADC_Type * base)586 uint16_t HSADC_GetStatusFlags(HSADC_Type *base)
587 {
588 uint16_t tmp16;
589 uint16_t status = 0U;
590
591 /* STAT */
592 tmp16 = base->STAT;
593 if (HSADC_STAT_ZCI_MASK == (tmp16 & HSADC_STAT_ZCI_MASK))
594 {
595 status |= (uint16_t)kHSADC_ZeroCrossingFlag;
596 }
597 if (HSADC_STAT_HLMTI_MASK == (tmp16 & HSADC_STAT_HLMTI_MASK))
598 {
599 status |= (uint16_t)kHSADC_HighLimitFlag;
600 }
601 if (HSADC_STAT_LLMTI_MASK == (tmp16 & HSADC_STAT_LLMTI_MASK))
602 {
603 status |= (uint16_t)kHSADC_LowLimitFlag;
604 }
605 if (HSADC_STAT_EOSIA_MASK == (tmp16 & HSADC_STAT_EOSIA_MASK))
606 {
607 status |= (uint16_t)kHSADC_ConverterAEndOfScanFlag;
608 }
609 if (HSADC_STAT_EOSIB_MASK == (tmp16 & HSADC_STAT_EOSIB_MASK))
610 {
611 status |= (uint16_t)kHSADC_ConverterBEndOfScanFlag;
612 }
613 if (HSADC_STAT_EOCALIA_MASK == (tmp16 & HSADC_STAT_EOCALIA_MASK))
614 {
615 status |= (uint16_t)kHSADC_ConverterAEndOfCalibrationFlag;
616 }
617 if (HSADC_STAT_EOCALIB_MASK == (tmp16 & HSADC_STAT_EOCALIB_MASK))
618 {
619 status |= (uint16_t)kHSADC_ConverterBEndOfCalibrationFlag;
620 }
621 if (HSADC_STAT_CIPA_MASK == (tmp16 & HSADC_STAT_CIPA_MASK))
622 {
623 status |= (uint16_t)kHSADC_ConverterAConvertingFlag;
624 }
625 if (HSADC_STAT_CIPB_MASK == (tmp16 & HSADC_STAT_CIPB_MASK))
626 {
627 status |= (uint16_t)kHSADC_ConverterBConvertingFlag;
628 }
629 if (HSADC_STAT_DUMMYA_MASK == (tmp16 & HSADC_STAT_DUMMYA_MASK))
630 {
631 status |= (uint16_t)kHSADC_ConverterADummyConvertingFlag;
632 }
633 if (HSADC_STAT_DUMMYB_MASK == (tmp16 & HSADC_STAT_DUMMYB_MASK))
634 {
635 status |= (uint16_t)kHSADC_ConverterBDummyConvertingFlag;
636 }
637 if (HSADC_STAT_CALONA_MASK == (tmp16 & HSADC_STAT_CALONA_MASK))
638 {
639 status |= (uint16_t)kHSADC_ConverterACalibratingFlag;
640 }
641 if (HSADC_STAT_CALONB_MASK == (tmp16 & HSADC_STAT_CALONB_MASK))
642 {
643 status |= (uint16_t)kHSADC_ConverterBCalibratingFlag;
644 }
645
646 /* PWR */
647 tmp16 = base->PWR;
648 if (HSADC_PWR_PSTSA_MASK == (tmp16 & HSADC_PWR_PSTSA_MASK))
649 {
650 status |= (uint16_t)kHSADC_ConverterAPowerDownFlag;
651 }
652 if (HSADC_PWR_PSTSB_MASK == (tmp16 & HSADC_PWR_PSTSB_MASK))
653 {
654 status |= (uint16_t)kHSADC_ConverterBPowerDownFlag;
655 }
656
657 return status;
658 }
659
660 /*!
661 * brief Clears the status flags.
662 *
663 * param base HSADC peripheral base address.
664 * param flags Mask value for the event flags to be cleared. See the "_hsadc_status_flags".
665 */
HSADC_ClearStatusFlags(HSADC_Type * base,uint16_t mask)666 void HSADC_ClearStatusFlags(HSADC_Type *base, uint16_t mask)
667 {
668 uint16_t tmp16;
669
670 if ((uint16_t)kHSADC_ZeroCrossingFlag == (mask & (uint16_t)kHSADC_ZeroCrossingFlag))
671 {
672 base->ZXSTAT = 0xFFFFU;
673 }
674 if ((uint16_t)kHSADC_HighLimitFlag == (mask & (uint16_t)kHSADC_HighLimitFlag))
675 {
676 base->HILIMSTAT = 0xFFFFU;
677 }
678 if ((uint16_t)kHSADC_LowLimitFlag == (mask & (uint16_t)kHSADC_LowLimitFlag))
679 {
680 base->LOLIMSTAT = 0xFFFFU;
681 }
682 /* STAT */
683 tmp16 = base->STAT;
684 if ((uint16_t)kHSADC_ConverterAEndOfScanFlag == (mask & (uint16_t)kHSADC_ConverterAEndOfScanFlag))
685 {
686 tmp16 |= HSADC_STAT_EOSIA_MASK;
687 }
688 if ((uint16_t)kHSADC_ConverterBEndOfScanFlag == (mask & (uint16_t)kHSADC_ConverterBEndOfScanFlag))
689 {
690 tmp16 |= HSADC_STAT_EOSIB_MASK;
691 }
692 if ((uint16_t)kHSADC_ConverterAEndOfCalibrationFlag == (mask & (uint16_t)kHSADC_ConverterAEndOfCalibrationFlag))
693 {
694 tmp16 |= HSADC_STAT_EOCALIA_MASK;
695 }
696 if ((uint16_t)kHSADC_ConverterBEndOfCalibrationFlag == (mask & (uint16_t)kHSADC_ConverterBEndOfCalibrationFlag))
697 {
698 tmp16 |= HSADC_STAT_EOCALIB_MASK;
699 }
700 base->STAT = tmp16;
701 }
702
HSADC_SetChannel67Mux(HSADC_Type * base,uint16_t channelNumber,uint16_t muxNumber,bool enableDifferentialPair)703 static void HSADC_SetChannel67Mux(HSADC_Type *base,
704 uint16_t channelNumber,
705 uint16_t muxNumber,
706 bool enableDifferentialPair)
707 {
708 uint16_t tmp16;
709
710 /* MUX67_SEL */
711 /* When channel number is 6/7, it represents converterA's channel 6/7. */
712 /* When channel number is 14/15, it represents converterB's channel 6/7. */
713 tmp16 = base->MUX67_SEL;
714 /* For differential mode. */
715 if (true == enableDifferentialPair)
716 {
717 switch (channelNumber)
718 {
719 case 6U:
720 case 7U:
721 tmp16 &= ~((uint16_t)HSADC_MUX67_SEL_CH6_SELA_MASK | (uint16_t)HSADC_MUX67_SEL_CH7_SELA_MASK);
722 tmp16 |= (HSADC_MUX67_SEL_CH6_SELA(muxNumber) | HSADC_MUX67_SEL_CH7_SELA(muxNumber));
723 break;
724 case 14U:
725 case 15U:
726 tmp16 &= ~((uint16_t)HSADC_MUX67_SEL_CH6_SELB_MASK | (uint16_t)HSADC_MUX67_SEL_CH7_SELB_MASK);
727 tmp16 |= (HSADC_MUX67_SEL_CH6_SELB(muxNumber) | HSADC_MUX67_SEL_CH7_SELB(muxNumber));
728 break;
729 default:
730 tmp16 = base->MUX67_SEL;
731 break;
732 }
733 }
734 else /* For single ended mode. */
735 {
736 switch (channelNumber)
737 {
738 case 6U:
739 tmp16 &= ~(uint16_t)HSADC_MUX67_SEL_CH6_SELA_MASK;
740 tmp16 |= HSADC_MUX67_SEL_CH6_SELA(muxNumber);
741 break;
742 case 7U:
743 tmp16 &= ~(uint16_t)HSADC_MUX67_SEL_CH7_SELA_MASK;
744 tmp16 |= HSADC_MUX67_SEL_CH7_SELA(muxNumber);
745 break;
746 case 14U:
747 tmp16 &= ~(uint16_t)HSADC_MUX67_SEL_CH6_SELB_MASK;
748 tmp16 |= HSADC_MUX67_SEL_CH6_SELB(muxNumber);
749 break;
750 case 15U:
751 tmp16 &= ~(uint16_t)HSADC_MUX67_SEL_CH7_SELB_MASK;
752 tmp16 |= HSADC_MUX67_SEL_CH7_SELB(muxNumber);
753 break;
754 default:
755 tmp16 = base->MUX67_SEL;
756 break;
757 }
758 }
759 base->MUX67_SEL = tmp16;
760 }
761
762 /*
763 * Mask table for channel differential pair setting.
764 * The item's value would be set into CTRL1[CHNCFG_L] or CTRL2[CHNCFG_H].
765 */
766 static const uint16_t g_HSADCChannelConfigDifferentialMask[] = {
767 0x0010U, /* CHN0-1, ANA0-ANA1, CTRL1[CHNCFG_L]. */
768 0x0020U, /* CHN2-3, ANA2-ANA3. CTRL1[CHNCFG_L]. */
769 0x0080U, /* CHN4-5, ANA4-ANA5. CTRL2[CHNCFG_H]. */
770 0x0100U, /* CHN6-7, ANA6-ANA7. CTRL2[CHNCFG_H]. */
771 0x0040U, /* CHN8-9, ANB0-ANB1. CTRL1[CHNCFG_L]. */
772 0x0080U, /* CHN10-11, ANB2-ANB3. CTRL1[CHNCFG_L]. */
773 0x0200U, /* CHN12-13, ANB4-ANB5. CTRL2[CHNCFG_H]. */
774 0x0400U /* CHN14-15, ANB6-ANB7. CTRL2[CHNCFG_H]. */
775 };
776 /*!
777 * brief Configures the sample slot.
778 *
779 * A sample list in this module works like a conversion sequence. Each sample slot can be used to designate to sample
780 * which channel is in converter A and converter B. The detail mapping relationship between sample slot and converter's
781 * channel can be found in the SoC reference manual.
782 *
783 * param base HSADC peripheral base address.
784 * param sampleIndex Index of sample slot in conversion sequence. Available range is 0-15.
785 * param config Pointer to configuration structure. See the "hsadc_sample_config_t".
786 */
HSADC_SetSampleConfig(HSADC_Type * base,uint16_t sampleIndex,const hsadc_sample_config_t * config)787 void HSADC_SetSampleConfig(HSADC_Type *base, uint16_t sampleIndex, const hsadc_sample_config_t *config)
788 {
789 assert(sampleIndex < HSADC_RSLT_COUNT);
790 assert(NULL != config);
791
792 uint16_t tmp16;
793
794 /* Configure the differential conversion channel. */
795 if ((config->channelNumber < 4U) || ((config->channelNumber >= 8U) && (config->channelNumber < 12U)))
796 {
797 if (config->enableDifferentialPair)
798 {
799 base->CTRL1 |= g_HSADCChannelConfigDifferentialMask[config->channelNumber / 2U];
800 }
801 else
802 {
803 base->CTRL1 &= (uint16_t)(~g_HSADCChannelConfigDifferentialMask[config->channelNumber / 2U]);
804 }
805 }
806 else if (((config->channelNumber >= 4U) && (config->channelNumber < 8U)) ||
807 ((config->channelNumber >= 12U) && (config->channelNumber < 16U)))
808 {
809 if (config->enableDifferentialPair)
810 {
811 base->CTRL2 |= g_HSADCChannelConfigDifferentialMask[config->channelNumber / 2U];
812 }
813 else
814 {
815 base->CTRL2 &= (uint16_t)(~g_HSADCChannelConfigDifferentialMask[config->channelNumber / 2U]);
816 }
817 }
818 else
819 {
820 /* To avoid MISRA rule 14.10 error. */
821 }
822
823 /* Configure the zero crossing mode. */
824 if (sampleIndex < 8U)
825 {
826 tmp16 = base->ZXCTRL1 & ~HSADC_ZXCTRL_ZCE_MASK(sampleIndex);
827 tmp16 |= HSADC_ZXCTRL_ZCE(sampleIndex, config->zeroCrossingMode);
828 base->ZXCTRL1 = tmp16;
829 }
830 else if (sampleIndex < 16U)
831 {
832 sampleIndex -= 8U;
833 tmp16 = base->ZXCTRL2 & ~HSADC_ZXCTRL_ZCE_MASK(sampleIndex);
834 tmp16 |= HSADC_ZXCTRL_ZCE(sampleIndex, config->zeroCrossingMode);
835 base->ZXCTRL2 = tmp16;
836 sampleIndex += 8U;
837 }
838 else
839 {
840 /* To avoid MISRA rule 14.10 error. */
841 }
842
843 /* Fill the conversion channel into sample slot. */
844 if (sampleIndex < 4U)
845 {
846 tmp16 = base->CLIST1 & ~HSADC_CLIST_SAMPLE_MASK(sampleIndex);
847 tmp16 |= HSADC_CLIST_SAMPLE(sampleIndex, config->channelNumber);
848 base->CLIST1 = tmp16;
849 }
850 else if (sampleIndex < 8U)
851 {
852 sampleIndex -= 4U;
853 tmp16 = base->CLIST2 & ~HSADC_CLIST_SAMPLE_MASK(sampleIndex);
854 tmp16 |= HSADC_CLIST_SAMPLE(sampleIndex, config->channelNumber);
855 base->CLIST2 = tmp16;
856 sampleIndex += 4U;
857 }
858 else if (sampleIndex < 12U)
859 {
860 sampleIndex -= 8U;
861 tmp16 = base->CLIST3 & ~HSADC_CLIST_SAMPLE_MASK(sampleIndex);
862 tmp16 |= HSADC_CLIST_SAMPLE(sampleIndex, config->channelNumber);
863 base->CLIST3 = tmp16;
864 sampleIndex += 8U;
865 }
866 else if (sampleIndex < 16U)
867 {
868 sampleIndex -= 12U;
869 tmp16 = base->CLIST4 & ~HSADC_CLIST_SAMPLE_MASK(sampleIndex);
870 tmp16 |= HSADC_CLIST_SAMPLE(sampleIndex, config->channelNumber);
871 base->CLIST4 = tmp16;
872 sampleIndex += 12U;
873 }
874 else
875 {
876 /* To avoid MISRA rule 14.10 error. */
877 }
878
879 /* Configure the hardware compare. */
880 base->LOLIM[sampleIndex] = config->lowLimitValue;
881 base->HILIM[sampleIndex] = config->highLimitValue;
882 base->OFFST[sampleIndex] = config->offsetValue;
883
884 /* Configure the hardware trigger. */
885 /* SCTRL. */
886 if (config->enableWaitSync)
887 {
888 base->SCTRL |= ((uint16_t)1U << sampleIndex);
889 }
890 else
891 {
892 base->SCTRL &= ~((uint16_t)1U << sampleIndex);
893 }
894
895 /* Configure the channel 6/7's additional multiplex selector. */
896 HSADC_SetChannel67Mux(base, config->channelNumber, config->channel67MuxNumber, config->enableDifferentialPair);
897 }
898
899 /*!
900 * brief Gets the default sample configuration.
901 *
902 * This function initializes each sample's configuration structure with an available settings.
903 * The default values are:
904 * code
905 * config->channelNumber = 0U;
906 * config->channel6MuxNumber = 0U;
907 * config->channel7MuxNumber = 0U;
908 * config->enableDifferentialPair = false;
909 * config->zeroCrossingMode = kHSADC_ZeroCorssingDisabled;
910 * config->highLimitValue = 0x7FF8U;
911 * config->lowLimitValue = 0U;
912 * config->offsetValue = 0U;
913 * config->enableWaitSync = false;
914 * endcode
915 * param config Pointer to configuration structure. See the "hsadc_sample_config_t".
916 */
HSADC_GetDefaultSampleConfig(hsadc_sample_config_t * config)917 void HSADC_GetDefaultSampleConfig(hsadc_sample_config_t *config)
918 {
919 assert(NULL != config);
920
921 config->channelNumber = 0U;
922 config->channel67MuxNumber = 0U;
923 config->enableDifferentialPair = false;
924 config->zeroCrossingMode = kHSADC_ZeroCorssingDisabled;
925 config->highLimitValue = 0x7FF8U;
926 config->lowLimitValue = 0U;
927 config->offsetValue = 0U;
928 config->enableWaitSync = false;
929 }
930
931 /*!
932 * brief Starts the hardware calibration.
933 *
934 * This function starts the single ended calibration and differential calibration for converter A and converter B
935 * at the same time.
936 * Note that this is a non blocking function. End of Scan flag and End of Calibration flag are both be set after the
937 * calibration process. As a result, the user should check these two flags by using the function HSADC_GetStatusFlags()
938 * to wait for the
939 * calibration process to complete.
940 *
941 * param base HSADC peripheral base address.
942 * param converterMask Mask for converters to be operated. See the "_hsadc_converter_id".
943 * param calibrationModeMask Mask for calibration mode to be operated. See the "_hsadc_calibration_mode". Shouldn't be
944 * zero.
945 */
HSADC_DoAutoCalibration(HSADC_Type * base,uint16_t converterMask,uint16_t calibrationModeMask)946 void HSADC_DoAutoCalibration(HSADC_Type *base, uint16_t converterMask, uint16_t calibrationModeMask)
947 {
948 assert(0U != calibrationModeMask);
949
950 /* CALIB */
951 /* Set the calibration mode.
952 * Hardware requires that the bit REQSINGA, REQDIFA, REQA, REQSINGB, REQDIFB, REQB in CALIB register can't be set
953 * at the same time. They must be set as the sequency description in the reference manual.
954 */
955 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
956 {
957 if ((uint16_t)kHSADC_CalibrationModeSingleEnded ==
958 ((uint16_t)kHSADC_CalibrationModeSingleEnded & calibrationModeMask))
959 {
960 base->CALIB |= HSADC_CALIB_REQSINGA_MASK;
961 }
962 if ((uint16_t)kHSADC_CalibrationModeDifferential ==
963 ((uint16_t)kHSADC_CalibrationModeDifferential & calibrationModeMask))
964 {
965 base->CALIB |= HSADC_CALIB_REQDIFA_MASK;
966 }
967 base->CALIB |= HSADC_CALIB_CAL_REQA_MASK;
968 }
969 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
970 {
971 if ((uint16_t)kHSADC_CalibrationModeSingleEnded ==
972 ((uint16_t)kHSADC_CalibrationModeSingleEnded & calibrationModeMask))
973 {
974 base->CALIB |= HSADC_CALIB_REQSINGB_MASK;
975 }
976 if ((uint16_t)kHSADC_CalibrationModeDifferential ==
977 ((uint16_t)kHSADC_CalibrationModeDifferential & calibrationModeMask))
978 {
979 base->CALIB |= HSADC_CALIB_REQDIFB_MASK;
980 }
981 base->CALIB |= HSADC_CALIB_CAL_REQB_MASK;
982 }
983
984 /* Trigger the calibration. */
985 HSADC_DoSoftwareTriggerConverter(base, converterMask);
986 }
987
988 /*!
989 * brief Gets the calibration result value.
990 *
991 * This function returns the single ended calibration value and differential calibration value for converter A and
992 * converter B. The calibration value of each calibration mode for each converter can be received from this function's
993 * return value by using the mask and shift definition from HSADC_CALIBRATION_VALUE_A_SINGLE_ENDED_MASK to
994 * HSADC_CALIBRATION_VALUE_B_DIFFERENTIAL_SHIFT.
995 *
996 * param base HSADC peripheral base address.
997 * return Calibration value for converter A and converter B.
998 */
HSADC_GetCalibrationResultValue(HSADC_Type * base)999 uint32_t HSADC_GetCalibrationResultValue(HSADC_Type *base)
1000 {
1001 uint32_t calValA = ((uint32_t)(base->CALVAL_A) << 16U);
1002 return (calValA + base->CALVAL_B);
1003 }
1004
1005 /*!
1006 * brief Enables or disables the calibration result value.
1007 *
1008 * This function enables or disables converter A and converter B to use the calibration values to obtain the final
1009 * conversion result by calibration sum operation.
1010 *
1011 * param base HSADC peripheral base address.
1012 * param converterMask Mask for converters to be operated. See the "_hsadc_converter_id".
1013 * param enable Enable or disable the feature.
1014 */
HSADC_EnableCalibrationResultValue(HSADC_Type * base,uint16_t converterMask,bool enable)1015 void HSADC_EnableCalibrationResultValue(HSADC_Type *base, uint16_t converterMask, bool enable)
1016 {
1017 /* CALIB */
1018 /* Enable means not to bypass the calibration operation. */
1019 if ((uint16_t)kHSADC_ConverterA == ((uint16_t)kHSADC_ConverterA & converterMask))
1020 {
1021 if (true == enable)
1022 {
1023 base->CALIB &= ~(uint16_t)HSADC_CALIB_BYPA_MASK;
1024 }
1025 else
1026 {
1027 base->CALIB |= HSADC_CALIB_BYPA_MASK;
1028 }
1029 }
1030 if ((uint16_t)kHSADC_ConverterB == ((uint16_t)kHSADC_ConverterB & converterMask))
1031 {
1032 if (true == enable)
1033 {
1034 base->CALIB &= ~(uint16_t)HSADC_CALIB_BYPB_MASK;
1035 }
1036 else
1037 {
1038 base->CALIB |= HSADC_CALIB_BYPB_MASK;
1039 }
1040 }
1041 }
1042