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