1 //*****************************************************************************
2 //
3 //! @file am_hal_audadc.c
4 //!
5 //! @brief Functions for interfacing with the Audio Analog to Digital Converter.
6 //!
7 //! @addtogroup audadc4_4p AUDADC - Audio Analog-to-Digital Converter
8 //! @ingroup apollo4p_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2023, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 
48 #include <stdint.h>
49 #include <stdbool.h>
50 #include "am_mcu_apollo.h"
51 #include "math.h"
52 
53 //*****************************************************************************
54 //
55 // Private Types.
56 //
57 //*****************************************************************************
58 
59 #define AM_HAL_MAGIC_AUDADC                0xAFAFAF
60 #define AM_HAL_AUDADC_CHK_HANDLE(h)        ((h) && ((am_hal_handle_prefix_t *)(h))->s.bInit && (((am_hal_handle_prefix_t *)(h))->s.magic == AM_HAL_MAGIC_AUDADC))
61 
62 // ****************************************************************************
63 //
64 //! @name Default coefficients (used when trims not provided):
65 //!  TEMP_DEFAULT    = Temperature in deg K (e.g. 299.5 - 273.15 = 26.35)
66 //!  AMBIENT_DEFAULT = Voltage measurement at default temperature.
67 //!  OFFSET_DEFAULT  = Default AUDADC offset at 1v.
68 //! @{
69 //
70 // ****************************************************************************
71 #define AM_HAL_AUDADC_CALIB_TEMP_DEFAULT            (299.5F)
72 #define AM_HAL_AUDADC_CALIB_AMBIENT_DEFAULT         (1.02809F)
73 #define AM_HAL_AUDADC_CALIB_AUDADC_OFFSET_DEFAULT   (-0.004281F)
74 //! @}
75 
76 //
77 //! @brief AUDADC configuration registers structure.
78 //
79 typedef struct
80 {
81     bool          bValid;
82     uint32_t      regCFG;
83     uint32_t      regSL0CFG;
84     uint32_t      regSL1CFG;
85     uint32_t      regSL2CFG;
86     uint32_t      regSL3CFG;
87     uint32_t      regSL4CFG;
88     uint32_t      regSL5CFG;
89     uint32_t      regSL6CFG;
90     uint32_t      regSL7CFG;
91     uint32_t      regWULIM;
92     uint32_t      regWLLIM;
93     uint32_t      regINTEN;
94 } am_hal_audadc_register_state_t;
95 
96 //
97 //! @brief AUDADC State structure.
98 //
99 typedef struct
100 {
101     //
102     //! Handle validation prefix.
103     //
104     am_hal_handle_prefix_t      prefix;
105 
106     //
107     //! Physical module number.
108     //
109     uint32_t                    ui32Module;
110 
111     //
112     //! AUDADC Capabilities.
113     //
114     am_hal_audadc_capabilities_t   capabilities;
115 
116     //
117     //! Power Save-Restore register state
118     //
119     am_hal_audadc_register_state_t registerState;
120 
121     //
122     //! DMA transaction Tranfer Control Buffer.
123     //
124     uint32_t            ui32BufferPing;
125     uint32_t            ui32BufferPong;
126     uint32_t            ui32BufferPtr;
127 
128 } am_hal_audadc_state_t;
129 
130 //*****************************************************************************
131 //
132 //! @brief Private SRAM view of temperature trims.
133 //!
134 //! This static SRAM union is private to the AUDADC HAL functions.
135 //
136 //*****************************************************************************
137 static union
138 {
139     //! These trim values are loaded as uint32_t values.
140     struct
141     {
142               //! Temperature of the package test head (in degrees Kelvin)
143               uint32_t ui32CalibrationTemperature;
144 
145               //! Voltage corresponding to temperature measured on test head.
146               uint32_t ui32CalibrationVoltage;
147 
148               //! AUDADC offset voltage measured on the package test head.
149               uint32_t ui32CalibrationOffset;
150 
151               //! Flag if default (guess) or measured.
152               bool bMeasured;
153     } ui32;
154     //! These trim values are accessed as floats when used in temp calculations.
155     struct
156     {
157               //! Temperature of the package test head in degrees Kelvin
158               float    fCalibrationTemperature;
159 
160               //! Voltage corresponding to temperature measured on test head.
161               float    fCalibrationVoltage;
162 
163               //! AUDADC offset voltage measured on the package test head.
164               float    fCalibrationOffset;
165 
166               //! Flag if default (guess) or measured.
167               float fMeasuredFlag;
168     } flt;
169 } priv_temp_trims;
170 
171 //*****************************************************************************
172 //
173 // Global Variables.
174 //
175 //*****************************************************************************
176 am_hal_audadc_state_t           g_AUDADCState[AM_REG_AUDADC_NUM_MODULES];
177 
178 uint32_t                        g_AUDADCSlotsConfigured;
179 
180 uint32_t                        g_AUDADCSlotTrkCycMin;
181 
182 uint32_t                        g_AUDADCPgaChConfigured;
183 
184 //*****************************************************************************
185 //
186 //! @brief AUDADC initialization function
187 //!
188 //! @param ui32Module - module instance.
189 //! @param ppHandle   - returns the handle for the module instance.
190 //!
191 //! This function accepts a module instance, allocates the interface and then
192 //! returns a handle to be used by the remaining interface functions.
193 //!
194 //! @return status    - generic or interface specific status.
195 //!
196 //! @note A return of AM_HAL_STATUS_SUCCESS does not infer that the
197 //! temperature calibrations are valid. The caller must check the bMeasured
198 //! structure element in order to determine that.
199 //
200 //*****************************************************************************
201 uint32_t
am_hal_audadc_initialize(uint32_t ui32Module,void ** ppHandle)202 am_hal_audadc_initialize(uint32_t ui32Module, void **ppHandle)
203 {
204 
205 #ifndef AM_HAL_DISABLE_API_VALIDATION
206     //
207     // Validate the module number
208     //
209     if ( ui32Module >= AM_REG_AUDADC_NUM_MODULES )
210     {
211         return AM_HAL_STATUS_OUT_OF_RANGE;
212     }
213 
214     //
215     // Check for valid arguements.
216     //
217     if ( !ppHandle )
218     {
219         return AM_HAL_STATUS_INVALID_ARG;
220     }
221 
222     //
223     // Check if the handle is unallocated.
224     //
225     if ( g_AUDADCState[ui32Module].prefix.s.bInit )
226     {
227         return AM_HAL_STATUS_INVALID_OPERATION;
228     }
229 #endif // AM_HAL_DISABLE_API_VALIDATION
230 
231     //
232     // Initialize the handle.
233     //
234     g_AUDADCState[ui32Module].prefix.s.bInit = true;
235     g_AUDADCState[ui32Module].prefix.s.magic = AM_HAL_MAGIC_AUDADC;
236     g_AUDADCState[ui32Module].ui32Module = ui32Module;
237 
238     //
239     // Initialize the number of slots configured.
240     //
241     g_AUDADCSlotsConfigured = 0;
242 
243     //
244     // Return the handle.
245     //
246     *ppHandle = (void *)&g_AUDADCState[ui32Module];
247 
248     //
249     // Before returning, read the temperature trims from INFO1,
250     // which are safely read using am_hal_mram_info_read().
251     //
252     am_hal_mram_info_read(1, AM_REG_INFO1_TEMP_CAL_ATE_O / 4, 1,    // INFO1, word offset, read 1 word
253                           &priv_temp_trims.ui32.ui32CalibrationTemperature);
254     am_hal_mram_info_read(1, AM_REG_INFO1_TEMP_CAL_MEASURED_O / 4, 1,
255                           &priv_temp_trims.ui32.ui32CalibrationVoltage);
256     am_hal_mram_info_read(1, AM_REG_INFO1_TEMP_CAL_ADC_OFFSET_O / 4, 1,
257                           &priv_temp_trims.ui32.ui32CalibrationOffset);
258 
259     if ( (priv_temp_trims.ui32.ui32CalibrationTemperature == 0xffffffff)    ||
260          (priv_temp_trims.ui32.ui32CalibrationVoltage     == 0xffffffff)    ||
261          (priv_temp_trims.ui32.ui32CalibrationOffset      == 0xffffffff) )
262     {
263         //
264         // Since the device has not been calibrated on the tester, we'll load
265         // default calibration values.  These default values should result
266         // in worst-case temperature measurements of +-6 degress C.
267         //
268         priv_temp_trims.flt.fCalibrationTemperature = AM_HAL_AUDADC_CALIB_TEMP_DEFAULT;
269         priv_temp_trims.flt.fCalibrationVoltage     = AM_HAL_AUDADC_CALIB_AMBIENT_DEFAULT;
270         priv_temp_trims.flt.fCalibrationOffset      = AM_HAL_AUDADC_CALIB_AUDADC_OFFSET_DEFAULT;
271         priv_temp_trims.ui32.bMeasured = false;
272     }
273     else
274     {
275         priv_temp_trims.ui32.bMeasured = true;
276     }
277 
278     //
279     // Return the status.
280     //
281     return AM_HAL_STATUS_SUCCESS;
282 }
283 
284 //*****************************************************************************
285 //
286 //! @brief AUDADC deinitialization function
287 //!
288 //! @param pHandle       - returns the handle for the module instance.
289 //!
290 //! This function accepts a handle to an instance and de-initializes the
291 //! interface.
292 //!
293 //! @return status      - generic or interface specific status.
294 //
295 //*****************************************************************************
296 uint32_t
am_hal_audadc_deinitialize(void * pHandle)297 am_hal_audadc_deinitialize(void *pHandle)
298 {
299     uint32_t                status = AM_HAL_STATUS_SUCCESS;
300     am_hal_audadc_state_t    *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
301 
302 #ifndef AM_HAL_DISABLE_API_VALIDATION
303     //
304     // Check the handle.
305     //
306     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
307     {
308         return AM_HAL_STATUS_INVALID_HANDLE;
309     }
310 #endif // AM_HAL_DISABLE_API_VALIDATION
311 
312     if ( pAUDADCState->prefix.s.bEnable )
313     {
314         status = am_hal_audadc_disable(pHandle);
315     }
316 
317     pAUDADCState->prefix.s.bInit = false;
318 
319     //
320     // Return the status.
321     //
322     return status;
323 }
324 
325 //*****************************************************************************
326 //
327 //! @brief AUDADC configuration function
328 //!
329 //! @param pHandle   - handle for the module instance.
330 //! @param psConfig  - pointer to the configuration structure.
331 //!
332 //! This function configures the AUDADC for operation.
333 //!
334 //! @return status      - generic or interface specific status.
335 //
336 //*****************************************************************************
337 uint32_t
am_hal_audadc_configure(void * pHandle,am_hal_audadc_config_t * psConfig)338 am_hal_audadc_configure(void *pHandle,
339                         am_hal_audadc_config_t *psConfig)
340 {
341     uint32_t                ui32Config;
342     am_hal_audadc_state_t   *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
343     uint32_t                ui32Module = pAUDADCState->ui32Module;
344 
345 #ifndef AM_HAL_DISABLE_API_VALIDATION
346     //
347     // Check the handle.
348     //
349     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
350     {
351         return AM_HAL_STATUS_INVALID_HANDLE;
352     }
353 #endif // AM_HAL_DISABLE_API_VALIDATION
354 
355     ui32Config = 0;
356 
357     //
358     // Set the AUDADC clock source.
359     //
360     ui32Config |= _VAL2FLD(AUDADC_CFG_CLKSEL, psConfig->eClock);
361 
362     //
363     // set minimum limit of Trkcyc
364     //
365     if ( psConfig->eClock == AM_HAL_AUDADC_CLKSEL_HFRC_48MHz || psConfig->eClock == AM_HAL_AUDADC_CLKSEL_HFRC2_48MHz )
366     {
367         g_AUDADCSlotTrkCycMin = AM_HAL_AUDADC_MIN_TRKCYC;
368     }
369     else if ( psConfig->eClock == AM_HAL_AUDADC_CLKSEL_XTHS_24MHz )
370     {
371         g_AUDADCSlotTrkCycMin = 19;
372     }
373     else
374     {
375         g_AUDADCSlotTrkCycMin = AM_HAL_AUDADC_MIN_TRKCYC;
376     }
377     //
378     // Set the AUDADC periodic trigger source.
379     //
380     ui32Config |= _VAL2FLD(AUDADC_CFG_RPTTRIGSEL, psConfig->eRepeatTrigger);
381 
382     //
383     // Set the AUDADC trigger polarity.
384     //
385     ui32Config |= _VAL2FLD(AUDADC_CFG_TRIGPOL, psConfig->ePolarity);
386 
387     //
388     // Set the AUDADC trigger.
389     //
390     ui32Config |= _VAL2FLD(AUDADC_CFG_TRIGSEL, psConfig->eTrigger);
391 
392     //
393     // Set the sample mode.
394     //
395     ui32Config |= _VAL2FLD(AUDADC_CFG_SAMPMODE, psConfig->eSampMode);
396 
397     //
398     // Set the Destructive FIFO read.
399     //
400     ui32Config |= _VAL2FLD(AUDADC_CFG_DFIFORDEN, 1);
401 
402     //
403     // Set the AUDADC clock mode.
404     //
405     ui32Config |= _VAL2FLD(AUDADC_CFG_CKMODE, psConfig->eClockMode);
406 
407     //
408     // Set the AUDADC low power mode.
409     //
410     ui32Config |= _VAL2FLD(AUDADC_CFG_LPMODE, psConfig->ePowerMode);
411 
412     //
413     // Set the AUDADC repetition mode.
414     //
415     ui32Config |= _VAL2FLD(AUDADC_CFG_RPTEN, psConfig->eRepeat);
416 
417     //
418     // Set the configuration in the AUDADC peripheral.
419     //
420     AUDADCn(ui32Module)->CFG = ui32Config;
421 
422     //
423     // Add this signed offset to data before being written to the FIFO:
424     // DATA2's complement (12 bit data)
425     //
426     AUDADCn(ui32Module)->DATAOFFSET = ((AUDADC->DATAOFFSET & ~AUDADC_DATAOFFSET_OFFSET_Msk) | _VAL2FLD(AUDADC_DATAOFFSET_OFFSET, 0x1800));
427 
428     //
429     // Return status.
430     //
431     return AM_HAL_STATUS_SUCCESS;
432 }
433 
434 //*****************************************************************************
435 //
436 //! @brief AUDADC slot configuration function
437 //!
438 //! @param pHandle - handle for the module instance.
439 //! @param ui32SlotNumber - AUDADC Slot Number
440 //! @param pSlotConfig    - pointer to the configuration structure.
441 //!
442 //! This function configures the AUDADC slot for operation.
443 //!
444 //! @return status      - generic or interface specific status.
445 //
446 //*****************************************************************************
447 uint32_t
am_hal_audadc_configure_slot(void * pHandle,uint32_t ui32SlotNumber,am_hal_audadc_slot_config_t * pSlotConfig)448 am_hal_audadc_configure_slot(void *pHandle,
449                              uint32_t ui32SlotNumber,
450                              am_hal_audadc_slot_config_t *pSlotConfig)
451 {
452     uint32_t            ui32Config;
453     uint32_t            ui32RegOffset;
454     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
455     uint32_t            ui32Module = pAUDADCState->ui32Module;
456 
457 #ifndef AM_HAL_DISABLE_API_VALIDATION
458     //
459     // Check the handle.
460     //
461     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
462     {
463         return AM_HAL_STATUS_INVALID_HANDLE;
464     }
465 
466     //
467     // Check the slot number.
468     //
469     if ( ui32SlotNumber >= AM_HAL_AUDADC_MAX_SLOTS )
470     {
471         return AM_HAL_STATUS_OUT_OF_RANGE;
472     }
473 
474     //
475     // check the Trkcyc value minimum limit
476     //
477     if ( pSlotConfig->ui32TrkCyc < g_AUDADCSlotTrkCycMin )
478     {
479         return AM_HAL_STATUS_OUT_OF_RANGE;
480     }
481 #endif // AM_HAL_DISABLE_API_VALIDATION
482 
483     ui32Config = 0;
484 
485     //
486     // Set the measurements to average
487     //
488     ui32Config |= _VAL2FLD(AUDADC_SL0CFG_ADSEL0, pSlotConfig->eMeasToAvg);
489 
490     //
491     // Set additional sampling AUDADC clock cycles
492     //
493     if ( pSlotConfig->ui32TrkCyc < g_AUDADCSlotTrkCycMin )
494     {
495         pSlotConfig->ui32TrkCyc = g_AUDADCSlotTrkCycMin;
496     }
497 
498     ui32Config |= _VAL2FLD(AUDADC_SL0CFG_TRKCYC0, pSlotConfig->ui32TrkCyc);
499 
500     //
501     // Set the precision mode.
502     //
503     ui32Config |= _VAL2FLD(AUDADC_SL0CFG_PRMODE0, pSlotConfig->ePrecisionMode);
504 
505     //
506     // Set the ui32ChanNumnel.
507     //
508     ui32Config |= _VAL2FLD(AUDADC_SL0CFG_CHSEL0, pSlotConfig->eChannel);
509 
510     //
511     // Enable window comparison if configured.
512     //
513     ui32Config |= _VAL2FLD(AUDADC_SL0CFG_WCEN0, pSlotConfig->bWindowCompare);
514 
515     //
516     // Enable the slot if configured.
517     //
518     ui32Config |= _VAL2FLD(AUDADC_SL0CFG_SLEN0, pSlotConfig->bEnabled);
519 
520     //
521     // Locate the correct register for this AUDADC slot.
522     //
523     ui32RegOffset = ((uint32_t)&AUDADCn(ui32Module)->SL0CFG) + (4 * ui32SlotNumber);
524 
525     //
526     // Write the register with the caller's configuration value.
527     //
528     AM_REGVAL(ui32RegOffset) = ui32Config;
529 
530     //
531     // Update the nubmer of slots configured.
532     //
533     g_AUDADCSlotsConfigured++;
534 
535     //
536     // Return the status.
537     //
538     return AM_HAL_STATUS_SUCCESS;
539 }
540 
541 //*****************************************************************************
542 //
543 //! @brief Calculate AUDADC slot DC offset
544 //!
545 //! @param pHandle             - handle for the module instance.
546 //! @param ui32SlotTotalNumber - Slot total number.
547 //! @param pSlotCalib          - pointer to the calibration structure.
548 //!
549 //! This function calculates the AUDADC slot DC offset for calibration, must
550 //! be called after calling am_hal_audadc_internal_pga_config() and
551 //! am_hal_audadc_configure_slot().
552 //!
553 //! @return status      - generic or interface specific status.
554 //
555 //*****************************************************************************
556 uint32_t
am_hal_audadc_slot_dc_offset_calculate(void * pHandle,uint32_t ui32SlotTotalNumber,am_hal_offset_cal_coeffs_array_t * pSlotCalib)557 am_hal_audadc_slot_dc_offset_calculate(void *pHandle,
558                                        uint32_t ui32SlotTotalNumber,
559                                        am_hal_offset_cal_coeffs_array_t *pSlotCalib)
560 {
561     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
562     uint32_t            ui32Module = pAUDADCState->ui32Module;
563     uint32_t            ui32AudadcTrims[3] = {0.0f};
564     uint32_t            ui32SlotNumber;
565     float               fSlotGainDB = 0.0f, fOffsetmFS = 0.0f, fLinearGain = 0.0f;
566     uint32_t            ui32LGA = 0, ui32HGADELTA = 0;
567     uint32_t            ui32LGB = 0, ui32HGBDELTA = 0;
568     uint32_t            ui32PreciMode = 0, ui32NumBits = 0;
569     float *             pfTemp;
570 
571 
572 #ifndef AM_HAL_DISABLE_API_VALIDATION
573     //
574     // Check the handle.
575     //
576     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
577     {
578         return AM_HAL_STATUS_INVALID_HANDLE;
579     }
580 
581     //
582     // Check the slot number.
583     //
584     if ( ui32SlotTotalNumber > AM_HAL_AUDADC_MAX_SLOTS )
585     {
586         return AM_HAL_STATUS_OUT_OF_RANGE;
587     }
588 
589 #endif // AM_HAL_DISABLE_API_VALIDATION
590 
591     //
592     // Read trim values from info1
593     //
594     for (ui32SlotNumber = 0; ui32SlotNumber < ui32SlotTotalNumber; ui32SlotNumber++)
595     {
596         am_hal_mram_info_read(1, (AM_REG_INFO1_AUDADC_A0_LG_OFFSET_O + ui32SlotNumber * 4 * 3) / 4, 3, ui32AudadcTrims);
597 
598         if ((ui32AudadcTrims[0] == 0xFFFFFFFF) ||
599             (ui32AudadcTrims[1] == 0xFFFFFFFF) ||
600             (ui32AudadcTrims[2] == 0xFFFFFFFF))
601         {
602             pSlotCalib->sCalibCoeff[ui32SlotNumber].bValid = false;
603             pSlotCalib->sCalibCoeff[ui32SlotNumber].fLGOffset = 0.0f;
604             pSlotCalib->sCalibCoeff[ui32SlotNumber].fHGSlope = 0.0f;
605             pSlotCalib->sCalibCoeff[ui32SlotNumber].fHGIntercept = 0.0f;
606         }
607         else
608         {
609             pSlotCalib->sCalibCoeff[ui32SlotNumber].bValid = true;
610             pfTemp = (float *)&ui32AudadcTrims[0];
611             pSlotCalib->sCalibCoeff[ui32SlotNumber].fLGOffset = *pfTemp;
612             pfTemp = (float *)&ui32AudadcTrims[1];
613             pSlotCalib->sCalibCoeff[ui32SlotNumber].fHGSlope = *pfTemp;
614             pfTemp = (float *)&ui32AudadcTrims[2];
615             pSlotCalib->sCalibCoeff[ui32SlotNumber].fHGIntercept = *pfTemp;
616         }
617 
618         if (!pSlotCalib->sCalibCoeff[ui32SlotNumber].bValid)
619         {
620             pSlotCalib->sCalibCoeff[ui32SlotNumber].i32DCOffsetAdj = 0;
621         }
622         else
623         {
624             switch (ui32SlotNumber)
625             {
626                 case 0:
627                     ui32LGA = AUDADCn(ui32Module)->GAIN_b.LGA;
628                     fSlotGainDB = (float)(ui32LGA - 12) / 2.0f;
629                     ui32PreciMode = AUDADCn(ui32Module)->SL0CFG_b.PRMODE0;
630                 break;
631 
632                 case 1:
633                     ui32LGA = AUDADCn(ui32Module)->GAIN_b.LGA;
634                     ui32HGADELTA = AUDADCn(ui32Module)->GAIN_b.HGADELTA;
635                     fSlotGainDB = (float)(ui32LGA + ui32HGADELTA - 12) / 2.0f;
636                     ui32PreciMode = AUDADCn(ui32Module)->SL1CFG_b.PRMODE1;
637                 break;
638 
639                 case 2:
640                     ui32LGB = AUDADCn(ui32Module)->GAIN_b.LGB;
641                     fSlotGainDB = (float)(ui32LGB - 12) / 2.0f;
642                     ui32PreciMode = AUDADCn(ui32Module)->SL2CFG_b.PRMODE2;
643                 break;
644 
645                 case 3:
646                     ui32LGB = AUDADCn(ui32Module)->GAIN_b.LGA;
647                     ui32HGBDELTA = AUDADCn(ui32Module)->GAIN_b.HGBDELTA;
648                     fSlotGainDB = (float)(ui32LGB + ui32HGBDELTA - 12) / 2.0f;
649                     ui32PreciMode = AUDADCn(ui32Module)->SL3CFG_b.PRMODE3;
650                 break;
651 
652                 default:
653                 break;
654             }
655 
656             switch (ui32PreciMode)
657             {
658                 case 0:
659                 case 1:
660                     ui32NumBits = 12;
661                 break;
662 
663                 case 2:
664                     ui32NumBits = 10;
665                 break;
666 
667                 case 3:
668                     ui32NumBits = 8;
669                 break;
670 
671                 default:
672                 break;
673             }
674 
675             if (fSlotGainDB < 12.0f)
676             {
677                 fOffsetmFS = pSlotCalib->sCalibCoeff[ui32SlotNumber].fLGOffset;
678             }
679             else
680             {
681                 fLinearGain = pow(10, fSlotGainDB / 20);
682                 fOffsetmFS = (pSlotCalib->sCalibCoeff[ui32SlotNumber].fHGSlope * fLinearGain) + pSlotCalib->sCalibCoeff[ui32SlotNumber].fHGIntercept;
683             }
684 
685             pSlotCalib->sCalibCoeff[ui32SlotNumber].i32DCOffsetAdj = -(int32_t)(fOffsetmFS * FULLSCALE_AMPLITUDE * (0x00000001 << (ui32NumBits - 1)) / 1000.0f );
686         }
687     }
688 
689     //
690     // Return the status.
691     //
692     return AM_HAL_STATUS_SUCCESS;
693 }
694 
695 //*****************************************************************************
696 //
697 //! @brief AUDADC internal repeating trigger timer configuration function
698 //!
699 //! @param pHandle - handle for the module instance.
700 //! @param pConfig - pointer to the configuration structure.
701 //!
702 //! This function configures the AUDADC internal trigger timer for operation.
703 //!
704 //! @return status - generic or interface specific status.
705 //
706 //*****************************************************************************
707 uint32_t
am_hal_audadc_configure_irtt(void * pHandle,am_hal_audadc_irtt_config_t * pConfig)708 am_hal_audadc_configure_irtt(void *pHandle,
709                              am_hal_audadc_irtt_config_t *pConfig)
710 {
711     uint32_t    ui32Config;
712     uint32_t    ui32Module = ((am_hal_audadc_state_t *)pHandle)->ui32Module;
713 
714 #ifndef AM_HAL_DISABLE_API_VALIDATION
715     //
716     // Check the handle.
717     //
718     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
719     {
720         return AM_HAL_STATUS_INVALID_HANDLE;
721     }
722 #endif // AM_HAL_DISABLE_API_VALIDATION
723 
724     ui32Config = 0;
725     //
726     // Disable AUDADC internal repeating trigger timer
727     //
728     ui32Config |= _VAL2FLD(AUDADC_INTTRIGTIMER_TIMEREN, 0);
729 
730     //
731     // Set AUDADC internal repeating trigger timer clock division
732     //
733     ui32Config |= _VAL2FLD(AUDADC_INTTRIGTIMER_CLKDIV, pConfig->eClkDiv);
734 
735     //
736     // Set AUDADC internal repeating trigger timer count
737     //
738     ui32Config |= _VAL2FLD(AUDADC_INTTRIGTIMER_TIMERMAX, pConfig->ui32IrttCountMax);
739 
740     //
741     // Set AUDADC internal repeating trigger timer configuration.
742     //
743     AUDADCn(ui32Module)->INTTRIGTIMER = ui32Config;
744 
745     //
746     // Return the status.
747     //
748     return AM_HAL_STATUS_SUCCESS;
749 }
750 
751 //*****************************************************************************
752 //
753 //! @brief AUDADC internal repeating trigger timer enable function
754 //!
755 //! @param pHandle - handle for the module instance.
756 //!
757 //! This function enables internal repeating trigger timer.
758 //!
759 //! @return status - generic or interface specific status.
760 //
761 //*****************************************************************************
762 uint32_t
am_hal_audadc_irtt_enable(void * pHandle)763 am_hal_audadc_irtt_enable(void *pHandle)
764 {
765     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
766     uint32_t            ui32Module = pAUDADCState->ui32Module;
767 
768 #ifndef AM_HAL_DISABLE_API_VALIDATION
769     //
770     // Check the handle.
771     //
772     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
773     {
774         return AM_HAL_STATUS_INVALID_HANDLE;
775     }
776 #endif // AM_HAL_DISABLE_API_VALIDATION
777 
778     //
779     // Enable the AUDADC.
780     //
781     AUDADCn(ui32Module)->INTTRIGTIMER_b.TIMEREN = 0x1;
782 
783     //
784     // Return the status.
785     //
786     return AM_HAL_STATUS_SUCCESS;
787 
788 }
789 
790 //*****************************************************************************
791 //
792 //! @brief AUDADC internal repeating trigger timer disable function
793 //!
794 //! @param pHandle - handle for the module instance.
795 //!
796 //! This function disables internal repeating trigger timer.
797 //!
798 //! @return status - generic or interface specific status.
799 //
800 //*****************************************************************************
801 uint32_t
am_hal_audadc_irtt_disable(void * pHandle)802 am_hal_audadc_irtt_disable(void *pHandle)
803 {
804     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
805     uint32_t            ui32Module = pAUDADCState->ui32Module;
806 
807 #ifndef AM_HAL_DISABLE_API_VALIDATION
808     //
809     // Check the handle.
810     //
811     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
812     {
813         return AM_HAL_STATUS_INVALID_HANDLE;
814     }
815 #endif // AM_HAL_DISABLE_API_VALIDATION
816 
817     //
818     // Enable the AUDADC.
819     //
820     AUDADCn(ui32Module)->INTTRIGTIMER_b.TIMEREN = 0x0;
821 
822     //
823     // Return the status.
824     //
825     return AM_HAL_STATUS_SUCCESS;
826 
827 }
828 
829 //*****************************************************************************
830 //
831 //! @brief AUDADC DMA configuration function
832 //!
833 //! @param pHandle    - handle for the module instance.
834 //! @param pDMAConfig - pointer to the configuration structure.
835 //!
836 //! This function configures the AUDADC DMA for operation.
837 //!
838 //! @return status    - generic or interface specific status.
839 //
840 //*****************************************************************************
841 uint32_t
am_hal_audadc_configure_dma(void * pHandle,am_hal_audadc_dma_config_t * pDMAConfig)842 am_hal_audadc_configure_dma(void *pHandle,
843                             am_hal_audadc_dma_config_t *pDMAConfig)
844 {
845     am_hal_audadc_state_t* pAUDADCState = (am_hal_audadc_state_t *)pHandle;
846     uint32_t ui32Module = pAUDADCState->ui32Module;
847     uint32_t ui32Config;
848 
849 #ifndef AM_HAL_DISABLE_API_VALIDATION
850     //
851     // Check the handle.
852     //
853     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
854     {
855         return AM_HAL_STATUS_INVALID_HANDLE;
856     }
857 #endif // AM_HAL_DISABLE_API_VALIDATION
858 
859     pAUDADCState->ui32BufferPtr = pAUDADCState->ui32BufferPing = pDMAConfig->ui32TargetAddress;
860     pAUDADCState->ui32BufferPong = pDMAConfig->ui32TargetAddressReverse;
861 
862     ui32Config = 0;
863 
864     //
865     // Configure the DMA complete power-off.
866     //
867     ui32Config |= _VAL2FLD(AUDADC_DMACFG_DPWROFF, 0);      // DPWROFF not supported!
868 
869     //
870     // Configure the data to be transferred.
871     //
872     if ( g_AUDADCSlotsConfigured > 1 )
873     {
874         // Need slot number to distinguish between slot results.
875         ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAEN, AUDADC_DMACFG_DMAEN_DIS);
876     }
877     else
878     {
879         ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAEN, AUDADC_DMACFG_DMAEN_EN);
880     }
881 
882     //
883     // Enable DMA Halt on Status (DMAERR or DMACPL) by default. This bit is reserved in apollo4
884     //
885 //    ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAHONSTAT, AUDADC_DMACFG_DMAHONSTAT_EN);
886 
887     //
888     // Configure the DMA dynamic priority handling.
889     //
890     ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMADYNPRI, pDMAConfig->bDynamicPriority);
891 
892     //
893     // Configure the DMA static priority.
894     //
895     ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAPRI, pDMAConfig->ePriority);
896 
897     //
898     // Enable the DMA (does not start until AUDADC is enabled and triggered).
899     //
900     ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAEN, AUDADC_DMACFG_DMAEN_EN);
901 
902     //
903     // Set the DMA configuration.
904     //
905     AUDADCn(ui32Module)->DMACFG = ui32Config;
906 
907     //
908     // Set the DMA transfer count.
909     //
910     AUDADCn(ui32Module)->DMATOTCOUNT_b.TOTCOUNT = pDMAConfig->ui32SampleCount;
911 
912     //
913     // Set the DMA target address.
914     //
915     AUDADCn(ui32Module)->DMATARGADDR = pAUDADCState->ui32BufferPtr;
916 
917     //
918     // Set the DMA trigger on FIFO 75% full.
919     //
920     AUDADCn(ui32Module)->DMATRIGEN = AUDADC_DMATRIGEN_DFIFO75_Msk;
921 
922     //
923     // Return the status.
924     //
925     return AM_HAL_STATUS_SUCCESS;
926 }
927 
928 //*****************************************************************************
929 //
930 //! @brief AUDADC DMA Buffer function
931 //!
932 //! @param pHandle - handle for the module instance.
933 //!
934 //! This function to get DMA Buffer.
935 //!
936 //! @return status - generic or interface specific status.
937 //
938 //*****************************************************************************
939 uint32_t
am_hal_audadc_dma_get_buffer(void * pHandle)940 am_hal_audadc_dma_get_buffer(void *pHandle)
941 {
942     uint32_t ui32BufferPtr;
943     am_hal_audadc_state_t *pState = (am_hal_audadc_state_t *) pHandle;
944 
945     // Invalidate DAXI to make sure CPU sees the new data when loaded.
946     am_hal_daxi_control(AM_HAL_DAXI_CONTROL_INVALIDATE, NULL);
947 
948     ui32BufferPtr = (pState->ui32BufferPtr == pState->ui32BufferPong)? pState->ui32BufferPing: pState->ui32BufferPong;
949 
950     return ui32BufferPtr;
951 }
952 
953 //*****************************************************************************
954 //
955 //! @brief AUDADC device specific control function.
956 //!
957 //! @param pHandle   - handle for the module instance.
958 //! @param eRequest - One of:
959 //!   AM_HAL_AUDADC_REQ_WINDOW_CONFIG
960 //!   AM_HAL_AUDADC_REQ_TEMP_CELSIUS_GET (pArgs is required, see enums).
961 //!   AM_HAL_AUDADC_REQ_TEMP_TRIMS_GET   (pArgs is required, see enums).
962 //!   AM_HAL_AUDADC_REQ_DMA_DISABLE      (pArgs is not required).
963 //! @param pArgs - Pointer to arguments for Control Switch Case
964 //!
965 //! This function provides for special control functions for the AUDADC operation.
966 //!
967 //! @return status      - generic or interface specific status.
968 //
969 //*****************************************************************************
am_hal_audadc_control(void * pHandle,am_hal_audadc_request_e eRequest,void * pArgs)970 uint32_t am_hal_audadc_control(void *pHandle,
971                                am_hal_audadc_request_e eRequest,
972                                void *pArgs)
973 {
974     uint32_t    ui32Module = ((am_hal_audadc_state_t *)pHandle)->ui32Module;
975 
976 #ifndef AM_HAL_DISABLE_API_VALIDATION
977     //
978     // Check the handle.
979     //
980     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
981     {
982         return AM_HAL_STATUS_INVALID_HANDLE;
983     }
984 #endif // AM_HAL_DISABLE_API_VALIDATION
985 
986     switch ( eRequest )
987     {
988         case AM_HAL_AUDADC_REQ_WINDOW_CONFIG:
989         {
990             am_hal_audadc_window_config_t *pWindowConfig = (am_hal_audadc_window_config_t *)pArgs;
991 
992 #ifndef AM_HAL_DISABLE_API_VALIDATION
993             //
994             // Check the window limits.
995             //
996             if ( (pWindowConfig->ui32Upper > AUDADC_WULIM_ULIM_Msk)   ||
997                  (pWindowConfig->ui32Lower > AUDADC_WLLIM_LLIM_Msk) )
998             {
999                 return AM_HAL_STATUS_OUT_OF_RANGE;
1000             }
1001 #endif // AM_HAL_DISABLE_API_VALIDATION
1002             //
1003             // Set the window comparison upper and lower limits.
1004             //
1005             AUDADCn(ui32Module)->WULIM = _VAL2FLD(AUDADC_WULIM_ULIM, pWindowConfig->ui32Upper);
1006             AUDADCn(ui32Module)->WLLIM = _VAL2FLD(AUDADC_WLLIM_LLIM, pWindowConfig->ui32Lower);
1007 
1008             //
1009             // Set the window scale per precision mode if indicated.
1010             //
1011             AUDADCn(ui32Module)->SCWLIM = _VAL2FLD(AUDADC_SCWLIM_SCWLIMEN,
1012                                                 pWindowConfig->bScaleLimits);
1013         }
1014         break;
1015 
1016         case AM_HAL_AUDADC_REQ_TEMP_CELSIUS_GET:
1017             //
1018             // pArgs must point to an array of 3 floats.  To assure that the
1019             // array is valid, upon calling the 3rd float (pArgs[2]) must be
1020             // set to the value -123.456F.
1021             //
1022             if ( pArgs != NULL )
1023             {
1024                 float *pfArray = (float*)pArgs;
1025                 float fTemp, fCalibration_temp, fCalibration_voltage, fCalibration_offset, fVoltage;
1026 
1027                 if ( pfArray[2] == -123.456F )
1028                 {
1029                     //
1030                     // Get the scaled voltage obtained from the AUDADC sample.
1031                     // The AUDADC sample value is scaled up by the reference voltage
1032                     // (e.g. 1.5F), then divided by 65536.0F.
1033                     //
1034                     fVoltage = pfArray[0];
1035 
1036                     //
1037                     // Get calibration temperature from trimmed values & convert to degrees K.
1038                     //
1039                     fCalibration_temp = priv_temp_trims.flt.fCalibrationTemperature;
1040                     fCalibration_voltage = priv_temp_trims.flt.fCalibrationVoltage;
1041                     fCalibration_offset  = priv_temp_trims.flt.fCalibrationOffset;
1042 
1043                     //
1044                     // Compute the temperature.
1045                     //
1046                     fTemp  = fCalibration_temp;
1047                     fTemp /= (fCalibration_voltage - fCalibration_offset);
1048                     fTemp *= (fVoltage - fCalibration_offset);
1049 
1050                     //
1051                     // Give it back to the caller in Celsius.
1052                     //
1053                     pfArray[1] = fTemp - 273.15f;
1054                 }
1055                 else
1056                 {
1057                     return AM_HAL_STATUS_INVALID_OPERATION;
1058                 }
1059             }
1060             else
1061             {
1062                 return AM_HAL_STATUS_INVALID_ARG;
1063             }
1064             break;
1065 
1066         case AM_HAL_AUDADC_REQ_TEMP_TRIMS_GET:
1067             //
1068             // pArgs must point to an array of 4 floats.  To assure that the
1069             // array is valid, upon calling the 4th float (pArgs[3]) must be
1070             // set to the value -123.456.
1071             // On return, pArgs[3] is set to 1 if the returned values are
1072             //  calibrated, or 0 if default calibration values.
1073             //
1074             if ( pArgs != NULL )
1075             {
1076                 float *pfArray = (float*)pArgs;
1077                 if ( pfArray[3] == -123.456F )
1078                 {
1079                     //
1080                     // Return trim temperature as a float.
1081                     //
1082                     pfArray[0] = priv_temp_trims.flt.fCalibrationTemperature;
1083 
1084                     //
1085                     // Return trim voltage as a float.
1086                     //
1087                     pfArray[1] = priv_temp_trims.flt.fCalibrationVoltage;
1088 
1089                     //
1090                     // Return trim AUDADC offset voltage as a float.
1091                     //
1092                     pfArray[2] = priv_temp_trims.flt.fCalibrationOffset;
1093 
1094                     //
1095                     // Set the calibrated or uncalibrated flag
1096                     //
1097                     ((uint32_t*)pArgs)[3] = priv_temp_trims.ui32.bMeasured;
1098                 }
1099                 else
1100                 {
1101                     return AM_HAL_STATUS_INVALID_OPERATION;
1102                 }
1103             }
1104             else
1105             {
1106                 return AM_HAL_STATUS_INVALID_ARG;
1107             }
1108             break;
1109 
1110         case AM_HAL_AUDADC_REQ_DMA_DISABLE:
1111             //
1112             // Clear DMAEN register
1113             //
1114             AUDADCn(ui32Module)->DMACFG_b.DMAEN = AUDADC_DMACFG_DMAEN_DIS;
1115             break;
1116 
1117         default:
1118             return AM_HAL_STATUS_INVALID_ARG;
1119     }
1120 
1121     //
1122     // Return status.
1123     //
1124     return AM_HAL_STATUS_SUCCESS;
1125 }
1126 
1127 //*****************************************************************************
1128 //
1129 //! @brief AUDADC enable function
1130 //!
1131 //! @param pHandle   - handle for the module instance.
1132 //!
1133 //! This function enables the AUDADC operation.
1134 //!
1135 //! @return status      - generic or interface specific status.
1136 //
1137 //*****************************************************************************
1138 uint32_t
am_hal_audadc_enable(void * pHandle)1139 am_hal_audadc_enable(void *pHandle)
1140 {
1141     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1142     uint32_t            ui32Module = pAUDADCState->ui32Module;
1143 
1144 #ifndef AM_HAL_DISABLE_API_VALIDATION
1145     //
1146     // Check the handle.
1147     //
1148     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1149     {
1150         return AM_HAL_STATUS_INVALID_HANDLE;
1151     }
1152 
1153     if ( pAUDADCState->prefix.s.bEnable )
1154     {
1155         return AM_HAL_STATUS_SUCCESS;
1156     }
1157 #endif // AM_HAL_DISABLE_API_VALIDATION
1158 
1159     //
1160     // Enable the AUDADC.
1161     //
1162     AUDADCn(ui32Module)->CFG_b.ADCEN = 0x1;
1163 
1164     //
1165     // Set flag to indicate module is enabled.
1166     //
1167     pAUDADCState->prefix.s.bEnable = true;
1168 
1169     //
1170     // Return the status.
1171     //
1172     return AM_HAL_STATUS_SUCCESS;
1173 }
1174 
1175 //*****************************************************************************
1176 //
1177 //! @brief AUDADC disable function
1178 //!
1179 //! @param pHandle - handle for the module instance.
1180 //!
1181 //! This function disables the AUDADC operation.
1182 //!
1183 //! @return status - generic or interface specific status.
1184 //
1185 //*****************************************************************************
1186 uint32_t
am_hal_audadc_disable(void * pHandle)1187 am_hal_audadc_disable(void *pHandle)
1188 {
1189     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1190     uint32_t            ui32Module = pAUDADCState->ui32Module;
1191 
1192 #ifndef AM_HAL_DISABLE_API_VALIDATION
1193     //
1194     // Check the handle.
1195     //
1196     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1197     {
1198         return AM_HAL_STATUS_INVALID_HANDLE;
1199     }
1200 #endif // AM_HAL_DISABLE_API_VALIDATION
1201 
1202     //
1203     // Disable the AUDADC.
1204     //
1205     AUDADCn(ui32Module)->CFG_b.ADCEN = 0x0;
1206 
1207     //
1208     // Set flag to indicate module is disabled.
1209     //
1210     pAUDADCState->prefix.s.bEnable = false;
1211 
1212     //
1213     // Return the status.
1214     //
1215     return AM_HAL_STATUS_SUCCESS;
1216 }
1217 
1218 //*****************************************************************************
1219 //
1220 //! @brief AUDADC status function
1221 //!
1222 //! @param pHandle - handle for the interface.
1223 //! @param pStatus - pointer to status
1224 //!
1225 //! This function returns the current status of the DMA operation.
1226 //!
1227 //! @return status - DMA status flags.
1228 //
1229 //*****************************************************************************
1230 uint32_t
am_hal_audadc_status_get(void * pHandle,am_hal_audadc_status_t * pStatus)1231 am_hal_audadc_status_get(void *pHandle, am_hal_audadc_status_t *pStatus )
1232 {
1233     uint32_t    ui32Module = ((am_hal_audadc_state_t *)pHandle)->ui32Module;
1234 
1235 #ifndef AM_HAL_DISABLE_API_VALIDATION
1236     //
1237     // Check the handle.
1238     //
1239     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1240     {
1241         return AM_HAL_STATUS_INVALID_HANDLE;
1242     }
1243 #endif // AM_HAL_DISABLE_API_VALIDATION
1244 
1245     //
1246     // Get the power status.
1247     //
1248     pStatus->bPoweredOn = (AUDADCn(ui32Module)->STAT & AUDADC_STAT_PWDSTAT_Msk) ==
1249                           _VAL2FLD(AUDADC_STAT_PWDSTAT, AUDADC_STAT_PWDSTAT_ON);
1250 
1251     //
1252     // Get the low power mode 1 status.
1253     //
1254     pStatus->bLPMode1 = (AUDADCn(ui32Module)->STAT & AUDADC_STAT_PWDSTAT_Msk) ==
1255                         _VAL2FLD(AUDADC_STAT_PWDSTAT, AUDADC_STAT_PWDSTAT_POWERED_DOWN);
1256 
1257     //
1258     //  Get the DMA status.
1259     //
1260     pStatus->bErr = ((AUDADCn(ui32Module)->DMASTAT & AUDADC_DMASTAT_DMAERR_Msk) > 0);
1261     pStatus->bCmp = ((AUDADCn(ui32Module)->DMASTAT & AUDADC_DMASTAT_DMACPL_Msk) > 0);
1262     pStatus->bTIP = ((AUDADCn(ui32Module)->DMASTAT & AUDADC_DMASTAT_DMATIP_Msk) > 0);
1263 
1264     //
1265     // Return the status.
1266     //
1267     return AM_HAL_STATUS_SUCCESS;
1268 }
1269 
1270 //*****************************************************************************
1271 //
1272 //! @brief AUDADC enable interrupts function
1273 //!
1274 //! @param pHandle       - handle for the interface.
1275 //! @param ui32IntMask  - AUDADC interrupt mask.
1276 //!
1277 //! This function enables the specific indicated interrupts.
1278 //!
1279 //! @return status      - generic or interface specific status.
1280 //
1281 //*****************************************************************************
1282 uint32_t
am_hal_audadc_interrupt_enable(void * pHandle,uint32_t ui32IntMask)1283 am_hal_audadc_interrupt_enable(void *pHandle, uint32_t ui32IntMask)
1284 {
1285     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1286 
1287 #ifndef AM_HAL_DISABLE_API_VALIDATION
1288     //
1289     // Check the handle.
1290     //
1291     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1292     {
1293         return AM_HAL_STATUS_INVALID_HANDLE;
1294     }
1295 #endif // AM_HAL_DISABLE_API_VALIDATION
1296 
1297     //
1298     // Enable the interrupts.
1299     //
1300     AUDADCn(ui32Module)->INTEN |= ui32IntMask;
1301 
1302     //
1303     // Return the status.
1304     //
1305     return AM_HAL_STATUS_SUCCESS;
1306 }
1307 
1308 //*****************************************************************************
1309 //
1310 //! @brief AUDADC disable interrupts function
1311 //!
1312 //! @param pHandle     - handle for the interface.
1313 //! @param ui32IntMask - AUDADC interrupt mask.
1314 //!
1315 //! This function disable the specific indicated interrupts.
1316 //!
1317 //! @return status     - generic or interface specific status.
1318 //
1319 //*****************************************************************************
1320 uint32_t
am_hal_audadc_interrupt_disable(void * pHandle,uint32_t ui32IntMask)1321 am_hal_audadc_interrupt_disable(void *pHandle, uint32_t ui32IntMask)
1322 {
1323     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1324 
1325 #ifndef AM_HAL_DISABLE_API_VALIDATION
1326     //
1327     // Check the handle.
1328     //
1329     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1330     {
1331         return AM_HAL_STATUS_INVALID_HANDLE;
1332     }
1333 #endif // AM_HAL_DISABLE_API_VALIDATION
1334 
1335     //
1336     // Disable the interrupts.
1337     //
1338     AUDADCn(ui32Module)->INTEN &= ~ui32IntMask;
1339 
1340     //
1341     // Return the status.
1342     //
1343     return AM_HAL_STATUS_SUCCESS;
1344 }
1345 
1346 //*****************************************************************************
1347 //
1348 //! @brief AUDADC interrupt status function
1349 //!
1350 //! @param pHandle      - handle for the interface.
1351 //! @param pui32Status  - pointer to status
1352 //! @param bEnabledOnly - if AUDADC enabled
1353 //!
1354 //! This function returns the specific indicated interrupt status.
1355 //!
1356 //! @return status      - generic or interface specific status.
1357 //
1358 //*****************************************************************************
1359 uint32_t
am_hal_audadc_interrupt_status(void * pHandle,uint32_t * pui32Status,bool bEnabledOnly)1360 am_hal_audadc_interrupt_status(void *pHandle,
1361                                uint32_t  *pui32Status,
1362                                bool bEnabledOnly)
1363 {
1364     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1365 
1366 #ifndef AM_HAL_DISABLE_API_VALIDATION
1367     //
1368     // Check the handle.
1369     //
1370     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1371     {
1372         return AM_HAL_STATUS_INVALID_HANDLE;
1373     }
1374 #endif // AM_HAL_DISABLE_API_VALIDATION
1375 
1376     //
1377     // if requested, only return the interrupts that are enabled.
1378     //
1379     if ( bEnabledOnly )
1380     {
1381         uint32_t ui32RetVal = AUDADCn(ui32Module)->INTSTAT;
1382         *pui32Status = AUDADCn(ui32Module)->INTEN & ui32RetVal;
1383     }
1384     else
1385     {
1386         *pui32Status = AUDADCn(ui32Module)->INTSTAT;
1387     }
1388 
1389     //
1390     // Return the status.
1391     //
1392     return AM_HAL_STATUS_SUCCESS;
1393 }
1394 
1395 //*****************************************************************************
1396 //
1397 //! @brief AUDADC interrupt clear
1398 //!
1399 //! @param pHandle         - handle for the interface.
1400 //! @param ui32IntMask    - uint32_t for interrupts to clear
1401 //!
1402 //! This function clears the interrupts for the given peripheral.
1403 //!
1404 //! @return status      - generic or interface specific status.
1405 //
1406 //*****************************************************************************
1407 uint32_t
am_hal_audadc_interrupt_clear(void * pHandle,uint32_t ui32IntMask)1408 am_hal_audadc_interrupt_clear(void *pHandle, uint32_t ui32IntMask)
1409 {
1410     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1411 
1412 #ifndef AM_HAL_DISABLE_API_VALIDATION
1413     //
1414     // Check the handle.
1415     //
1416     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1417     {
1418         return AM_HAL_STATUS_INVALID_HANDLE;
1419     }
1420 #endif // AM_HAL_DISABLE_API_VALIDATION
1421 
1422     //
1423     // Clear the interrupts.
1424     //
1425     AUDADCn(ui32Module)->INTCLR = ui32IntMask;
1426 
1427     //
1428     // Return the status.
1429     //
1430     return AM_HAL_STATUS_SUCCESS;
1431 }
1432 
1433 //*****************************************************************************
1434 //
1435 //! @brief AUDADC interrupt service
1436 //!
1437 //! @param pHandle       - handle for the interface.
1438 //! @param pDMAConfig   - pointer to DMA configuration
1439 //!
1440 //! Interrupt service routine.
1441 //!
1442 //! @return status      - generic or interface specific status.
1443 //
1444 //*****************************************************************************
1445 uint32_t
am_hal_audadc_interrupt_service(void * pHandle,am_hal_audadc_dma_config_t * pDMAConfig)1446 am_hal_audadc_interrupt_service(void *pHandle, am_hal_audadc_dma_config_t *pDMAConfig)
1447 {
1448     am_hal_audadc_state_t* pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1449     uint32_t ui32Module = pAUDADCState->ui32Module;
1450 
1451     pAUDADCState->ui32BufferPtr = (pAUDADCState->ui32BufferPtr == pAUDADCState->ui32BufferPong)? pAUDADCState->ui32BufferPing: pAUDADCState->ui32BufferPong;
1452 
1453     //
1454     // Set the DMA transfer count.
1455     //
1456     AUDADCn(ui32Module)->DMATOTCOUNT_b.TOTCOUNT = pDMAConfig->ui32SampleCount;
1457 
1458     //
1459     // Set the DMA target address.
1460     //
1461     AUDADCn(ui32Module)->DMATARGADDR = pAUDADCState->ui32BufferPtr;
1462 
1463     //
1464     // Return the status.
1465     //
1466     return AM_HAL_STATUS_SUCCESS;
1467 }
1468 
1469 //*****************************************************************************
1470 //
1471 // AUDADC sample read function
1472 //
1473 // This function reads samples from the AUDADC FIFO or an SRAM sample buffer
1474 // returned by a DMA operation, and calibrates the samples.
1475 //
1476 //*****************************************************************************
am_hal_audadc_samples_read(void * pHandle,uint32_t * pui32InSampleBuffer,uint32_t * pui32InOutNumberSamples,bool bLowSample,am_hal_audadc_sample_t * pui32LGOutBuffer,bool bHighSample,am_hal_audadc_sample_t * pui32HGOutBuffer,am_hal_offset_cal_coeffs_array_t * pSlotCalib)1477 uint32_t am_hal_audadc_samples_read(void *pHandle,
1478                                     uint32_t *pui32InSampleBuffer,
1479                                     uint32_t *pui32InOutNumberSamples,
1480                                     bool bLowSample, am_hal_audadc_sample_t *pui32LGOutBuffer,
1481                                     bool bHighSample, am_hal_audadc_sample_t *pui32HGOutBuffer,
1482                                     am_hal_offset_cal_coeffs_array_t *pSlotCalib)
1483 {
1484     uint32_t      ui32Sample;
1485     uint32_t      ui32RequestedSamples = *pui32InOutNumberSamples;
1486     int32_t       i32OffsetAdj = 0;
1487 
1488     uint32_t ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1489 
1490 #ifndef AM_HAL_DISABLE_API_VALIDATION
1491     //
1492     // Check the handle.
1493     //
1494     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1495     {
1496         return AM_HAL_STATUS_INVALID_HANDLE;
1497     }
1498 
1499     //
1500     // Check the output sample buffer pointer.
1501     //
1502     if ( (NULL == pui32LGOutBuffer) && (NULL == pui32HGOutBuffer))
1503     {
1504         return AM_HAL_STATUS_INVALID_ARG;
1505     }
1506 #endif // AM_HAL_DISABLE_API_VALIDATION
1507 
1508     *pui32InOutNumberSamples = 0;
1509 
1510     //
1511     // Check if we are reading directly from FIFO or DMA SRAM buffer.
1512     //
1513     if ( NULL == pui32InSampleBuffer )
1514     {
1515         //
1516         // Grab a value from the AUDADC FIFO
1517         //
1518         do
1519         {
1520             ui32Sample = AUDADCn(ui32Module)->FIFOPR;
1521             if ( bLowSample )
1522             {
1523               pui32LGOutBuffer->ui16AudChannel = AM_HAL_AUDADC_FIFO_SLOT(ui32Sample);
1524               pui32LGOutBuffer->int16Sample    = AM_HAL_AUDADC_FIFO_LGDATA(ui32Sample) << 4;
1525               if (pSlotCalib != NULL)
1526               {
1527                   if (pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].bValid)
1528                   {
1529                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].i32DCOffsetAdj << 4;
1530                       if ((pui32LGOutBuffer->int16Sample >= 0) &&
1531                           (i32OffsetAdj > (32767 - pui32LGOutBuffer->int16Sample)))
1532                       {
1533                           pui32LGOutBuffer->int16Sample = 32767; // Saturation
1534                       }
1535                       else if ((pui32LGOutBuffer->int16Sample < 0) &&
1536                                (i32OffsetAdj < (-32768 - pui32LGOutBuffer->int16Sample)))
1537                       {
1538                           pui32LGOutBuffer->int16Sample = -32768; // Saturation
1539                       }
1540                       else
1541                       {
1542                           pui32LGOutBuffer->int16Sample   += i32OffsetAdj;
1543                       }
1544                   }
1545               }
1546               pui32LGOutBuffer++;
1547             }
1548 
1549             if ( bHighSample )
1550             {
1551               pui32HGOutBuffer->ui16AudChannel = AM_HAL_AUDADC_FIFO_SLOT(ui32Sample);
1552               pui32HGOutBuffer->int16Sample    = AM_HAL_AUDADC_FIFO_HGDATA(ui32Sample) << 4;
1553               if (pSlotCalib != NULL)
1554               {
1555                   if (pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].bValid)
1556                   {
1557                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].i32DCOffsetAdj << 4;
1558                       if ((pui32HGOutBuffer->int16Sample >= 0) &&
1559                           (i32OffsetAdj > (32767 - pui32HGOutBuffer->int16Sample)))
1560                       {
1561                           pui32HGOutBuffer->int16Sample = 32767; // Saturation
1562                       }
1563                       else if ((pui32HGOutBuffer->int16Sample < 0) &&
1564                                (i32OffsetAdj < (-32768 - pui32HGOutBuffer->int16Sample)))
1565                       {
1566                           pui32HGOutBuffer->int16Sample = -32768; // Saturation
1567                       }
1568                       else
1569                       {
1570                           pui32HGOutBuffer->int16Sample   += i32OffsetAdj;
1571                       }
1572                   }
1573               }
1574               pui32HGOutBuffer++;
1575             }
1576             (*pui32InOutNumberSamples)++;
1577         } while (!AM_HAL_AUDADC_FIFO_EMPTY(AUDADCn(ui32Module)) &&
1578                  (*pui32InOutNumberSamples < ui32RequestedSamples));
1579     }
1580     else
1581     {
1582         //
1583         // Process the samples from the provided sample buffer
1584         //
1585         do
1586         {
1587             if ( bLowSample )
1588             {
1589               pui32LGOutBuffer->ui16AudChannel = AM_HAL_AUDADC_FIFO_SLOT(*pui32InSampleBuffer);
1590               pui32LGOutBuffer->int16Sample    = AM_HAL_AUDADC_FIFO_LGDATA(*pui32InSampleBuffer) << 4; //extend to 16 bits with sign bit
1591               if (pSlotCalib != NULL)
1592               {
1593                   if (pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].bValid)
1594                   {
1595                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].i32DCOffsetAdj << 4;
1596                       if ((pui32LGOutBuffer->int16Sample >= 0) &&
1597                           (i32OffsetAdj > (32767 - pui32LGOutBuffer->int16Sample)))
1598                       {
1599                           pui32LGOutBuffer->int16Sample = 32767; // Saturation
1600                       }
1601                       else if ((pui32LGOutBuffer->int16Sample < 0) &&
1602                                (i32OffsetAdj < (-32768 - pui32LGOutBuffer->int16Sample)))
1603                       {
1604                           pui32LGOutBuffer->int16Sample = -32768; // Saturation
1605                       }
1606                       else
1607                       {
1608                           pui32LGOutBuffer->int16Sample   += i32OffsetAdj;
1609                       }
1610                   }
1611               }
1612               pui32LGOutBuffer++;
1613             }
1614 
1615             if ( bHighSample )
1616             {
1617               pui32HGOutBuffer->ui16AudChannel  = AM_HAL_AUDADC_FIFO_SLOT(*pui32InSampleBuffer);
1618               pui32HGOutBuffer->int16Sample     = AM_HAL_AUDADC_FIFO_HGDATA(*pui32InSampleBuffer) << 4;
1619               if (pSlotCalib != NULL)
1620               {
1621                   if (pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].bValid)
1622                   {
1623                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].i32DCOffsetAdj << 4;
1624                       if ((pui32HGOutBuffer->int16Sample >= 0) &&
1625                           (i32OffsetAdj > (32767 - pui32HGOutBuffer->int16Sample)))
1626                       {
1627                           pui32HGOutBuffer->int16Sample = 32767; // Saturation
1628                       }
1629                       else if ((pui32HGOutBuffer->int16Sample < 0) &&
1630                                (i32OffsetAdj < (-32768 - pui32HGOutBuffer->int16Sample)))
1631                       {
1632                           pui32HGOutBuffer->int16Sample = -32768; // Saturation
1633                       }
1634                       else
1635                       {
1636                           pui32HGOutBuffer->int16Sample   += i32OffsetAdj;
1637                       }
1638                   }
1639               }
1640               pui32HGOutBuffer++;
1641             }
1642             pui32InSampleBuffer++;
1643             (*pui32InOutNumberSamples)++;
1644         } while (*pui32InOutNumberSamples < ui32RequestedSamples);
1645     }
1646 
1647     //
1648     // Return FIFO valid bits.
1649     //
1650     return AM_HAL_STATUS_SUCCESS;
1651 }
1652 
1653 //*****************************************************************************
1654 //
1655 //! @brief Issue Software Trigger to the AUDADC.
1656 //!
1657 //! @param pHandle   - handle for the module instance.
1658 //!
1659 //! This function triggers the AUDADC operation.
1660 //!
1661 //! @return status      - generic or interface specific status.
1662 //
1663 //*****************************************************************************
1664 uint32_t
am_hal_audadc_sw_trigger(void * pHandle)1665 am_hal_audadc_sw_trigger(void *pHandle)
1666 {
1667     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1668 
1669 #ifndef AM_HAL_DISABLE_API_VALIDATION
1670     //
1671     // Check the handle.
1672     //
1673     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1674     {
1675         return AM_HAL_STATUS_INVALID_HANDLE;
1676     }
1677 #endif // AM_HAL_DISABLE_API_VALIDATION
1678 
1679     //
1680     // Write to the Software trigger register in the AUDADC.
1681     //
1682     AUDADCn(ui32Module)->SWT = 0x37;
1683 
1684     //am_hal_delay_us(100);
1685 
1686     //
1687     // Return the status.
1688     //
1689     return AM_HAL_STATUS_SUCCESS;
1690 }
1691 
1692 //*****************************************************************************
1693 //
1694 //! @brief AUDADC power control function
1695 //!
1696 //! @param pHandle      - handle for the interface.
1697 //! @param ePowerState  - the desired power state to move the peripheral to.
1698 //! @param bRetainState - flag (if true) to save/restore peripheral state upon
1699 //!                       power state ui32ChanNumge.
1700 //!
1701 //! This function updates the peripheral to a given power state.
1702 //!
1703 //! @return status      - generic or interface specific status.
1704 //
1705 //*****************************************************************************
1706 uint32_t
am_hal_audadc_power_control(void * pHandle,am_hal_sysctrl_power_state_e ePowerState,bool bRetainState)1707 am_hal_audadc_power_control(void *pHandle,
1708                             am_hal_sysctrl_power_state_e ePowerState,
1709                             bool bRetainState)
1710 {
1711     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1712     uint32_t            ui32Module = pAUDADCState->ui32Module;
1713 
1714 #ifndef AM_HAL_DISABLE_API_VALIDATION
1715     //
1716     // Check the handle.
1717     //
1718     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1719     {
1720         return AM_HAL_STATUS_INVALID_HANDLE;
1721     }
1722 #endif // AM_HAL_DISABLE_API_VALIDATION
1723 
1724     //
1725     // Decode the requested power state and update ADC operation accordingly.
1726     //
1727     switch (ePowerState)
1728     {
1729         case AM_HAL_SYSCTRL_WAKE:
1730             if ( bRetainState  &&  !pAUDADCState->registerState.bValid )
1731             {
1732                 return AM_HAL_STATUS_INVALID_OPERATION;
1733             }
1734 
1735             //
1736             // Enable the AUDADC power domain.
1737             //
1738             am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_AUDADC);
1739 
1740             if ( bRetainState )
1741             {
1742                 AUDADCn(ui32Module)->SL0CFG = pAUDADCState->registerState.regSL0CFG;
1743                 AUDADCn(ui32Module)->SL1CFG = pAUDADCState->registerState.regSL1CFG;
1744                 AUDADCn(ui32Module)->SL2CFG = pAUDADCState->registerState.regSL2CFG;
1745                 AUDADCn(ui32Module)->SL3CFG = pAUDADCState->registerState.regSL3CFG;
1746                 AUDADCn(ui32Module)->SL4CFG = pAUDADCState->registerState.regSL4CFG;
1747                 AUDADCn(ui32Module)->SL5CFG = pAUDADCState->registerState.regSL5CFG;
1748                 AUDADCn(ui32Module)->SL6CFG = pAUDADCState->registerState.regSL6CFG;
1749                 AUDADCn(ui32Module)->SL7CFG = pAUDADCState->registerState.regSL7CFG;
1750                 AUDADCn(ui32Module)->WULIM  = pAUDADCState->registerState.regWULIM;
1751                 AUDADCn(ui32Module)->WLLIM  = pAUDADCState->registerState.regWLLIM;
1752                 AUDADCn(ui32Module)->INTEN  = pAUDADCState->registerState.regINTEN;
1753                 AUDADCn(ui32Module)->CFG    = pAUDADCState->registerState.regCFG;
1754 
1755                 pAUDADCState->registerState.bValid     = false;
1756             }
1757             break;
1758 
1759         case AM_HAL_SYSCTRL_NORMALSLEEP:
1760         case AM_HAL_SYSCTRL_DEEPSLEEP:
1761             if ( bRetainState )
1762             {
1763                 pAUDADCState->registerState.regSL0CFG  = AUDADCn(ui32Module)->SL0CFG;
1764                 pAUDADCState->registerState.regSL1CFG  = AUDADCn(ui32Module)->SL1CFG;
1765                 pAUDADCState->registerState.regSL2CFG  = AUDADCn(ui32Module)->SL2CFG;
1766                 pAUDADCState->registerState.regSL3CFG  = AUDADCn(ui32Module)->SL3CFG;
1767                 pAUDADCState->registerState.regSL4CFG  = AUDADCn(ui32Module)->SL4CFG;
1768                 pAUDADCState->registerState.regSL5CFG  = AUDADCn(ui32Module)->SL5CFG;
1769                 pAUDADCState->registerState.regSL6CFG  = AUDADCn(ui32Module)->SL6CFG;
1770                 pAUDADCState->registerState.regSL7CFG  = AUDADCn(ui32Module)->SL7CFG;
1771                 pAUDADCState->registerState.regWULIM   = AUDADCn(ui32Module)->WULIM;
1772                 pAUDADCState->registerState.regWLLIM   = AUDADCn(ui32Module)->WLLIM;
1773                 pAUDADCState->registerState.regINTEN   = AUDADCn(ui32Module)->INTEN;
1774                 pAUDADCState->registerState.regCFG     = AUDADCn(ui32Module)->CFG;
1775 
1776                 pAUDADCState->registerState.bValid     = true;
1777             }
1778 
1779             //
1780             // Disable the AUDADC power domain.
1781             //
1782             am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_AUDADC);
1783             break;
1784 
1785         default:
1786             return AM_HAL_STATUS_INVALID_ARG;
1787     }
1788 
1789     //
1790     // Return the status.
1791     //
1792     return AM_HAL_STATUS_SUCCESS;
1793 }
1794 
1795 //*****************************************************************************
1796 //
1797 //! @brief Set PGA gain
1798 //!
1799 //! @param  ui32ChanNum  - PGA ui32ChanNumnel number: 0:A0, 1:A1, 2:B0, 3:B1,
1800 //! @param  in32GaindBx2 - gain in dB. in32GaindBx2 = 2 * gain (dB)
1801 //!
1802 //! This function sets the gain of PGA.
1803 //!
1804 //! @return status       - generic or interface specific status.
1805 //
1806 //*****************************************************************************
1807 uint32_t
am_hal_audadc_gain_set(uint32_t ui32ChanNum,int32_t in32GaindBx2)1808 am_hal_audadc_gain_set(uint32_t ui32ChanNum, int32_t in32GaindBx2)
1809 {
1810     uint32_t temp;
1811     uint32_t ui32BypassStage1;
1812     int32_t in32Gain2Div2 = 0;
1813     int32_t in32Gain1Val;
1814     int32_t in32Gain2Val;
1815 
1816     // add support for -6 dB to -0.5 dB by using PGACH*GAIN2DIV2SEL
1817     if (in32GaindBx2 < 0)
1818     {
1819         in32Gain2Div2 = 1;
1820         in32GaindBx2 += 12; // subsequent calculations with 6 dB (x2) added (should be positive)
1821     }
1822 
1823     //
1824     // Calculate first stage gain.
1825     // Most of the gain comes from the first stage, unless gain < 12 dB.
1826     // If gain < 12 dB, we bypass first stagea
1827     //
1828     if (in32GaindBx2 < 24)
1829     {
1830         ui32BypassStage1 = 1;
1831         in32Gain1Val = 0;
1832         in32Gain2Val = in32GaindBx2;
1833     }
1834     else
1835     {
1836         ui32BypassStage1 = 0;
1837         in32Gain1Val = (in32GaindBx2 - 24) / 6;
1838         //
1839         // however, in32Gain1Val saturates at code 7 (33 dB)
1840         // (0:12, 1:15, 2:18, 3:21, 4:24, 5:27, 6:30, 7:33) dB
1841         //
1842         if (in32Gain1Val > 7)
1843         {
1844             in32Gain1Val = 7;
1845         }
1846 
1847         //
1848         // The remainder of the gain is provided by the second stage
1849         //
1850         in32Gain2Val = in32GaindBx2 - 24 - 6*in32Gain1Val;
1851     }
1852 
1853     switch (ui32ChanNum)
1854     {
1855         case 0:
1856             temp = _FLD2VAL(MCUCTRL_PGACTRL1_PGACHABYPASSEN, MCUCTRL->PGACTRL1) & 0x2; // keep CHA1 bypassen state
1857             temp |= ui32BypassStage1;
1858             temp &= 0x3;
1859             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, temp));
1860             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB, 0x3 & ~temp)); // input stage opamp can be powered off when bypassed to save power
1861             //MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB, 0x3)); // debug - set to 1
1862             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA0GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA0GAIN1SEL, in32Gain1Val));
1863             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA0GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA0GAIN2SEL, in32Gain2Val));
1864             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA0GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA0GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1865             break;
1866         case 1:
1867             temp = _FLD2VAL(MCUCTRL_PGACTRL1_PGACHABYPASSEN, MCUCTRL->PGACTRL1) & 0x1; // keep CHA0 bypassen state
1868             temp |= ui32BypassStage1 << 1;
1869             temp &= 0x3;
1870             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, temp));
1871             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB, 0x3 & ~temp)); // input stage opamp can be powered off when bypassed to save power
1872             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA1GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA1GAIN1SEL, in32Gain1Val));
1873             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA1GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA1GAIN2SEL, in32Gain2Val));
1874             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA1GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA1GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1875             break;
1876         case 2:
1877             temp = _FLD2VAL(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, MCUCTRL->PGACTRL2) & 0x2; // keep CHB1 bypassen state
1878             temp |= ui32BypassStage1;
1879             temp &= 0x3;
1880             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, temp));
1881             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBOPAMPINPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPINPDNB, 0x3 & ~temp)); // input stage opamp can be powered off when bypassed to save power
1882             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB0GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB0GAIN1SEL, in32Gain1Val));
1883             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB0GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB0GAIN2SEL, in32Gain2Val));
1884             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB0GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB0GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1885             break;
1886         case 3:
1887             temp = _FLD2VAL(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, MCUCTRL->PGACTRL2) & 0x1; // keep CHB0 bypassen state
1888             temp |= ui32BypassStage1 << 1;
1889             temp &= 0x3;
1890             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, temp));
1891             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBOPAMPINPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPINPDNB, 0x3 & ~temp)); // input stage opamp can be powered off when bypassed to save power
1892             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB1GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB1GAIN1SEL, in32Gain1Val));
1893             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB1GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB1GAIN2SEL, in32Gain2Val));
1894             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB1GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB1GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1895             break;
1896 
1897         default:
1898             return AM_HAL_STATUS_INVALID_ARG;
1899     }
1900 
1901     //
1902     // Return the status.
1903     //
1904     return AM_HAL_STATUS_SUCCESS;
1905 }
1906 
1907 //*****************************************************************************
1908 //
1909 //! @brief Turn on reference
1910 //!
1911 //! This function turn on the reference voltage and current.
1912 //!
1913 //! @return status          - generic or interface specific status.
1914 //
1915 //*****************************************************************************
1916 uint32_t
am_hal_audadc_refgen_powerup(void)1917 am_hal_audadc_refgen_powerup(void)
1918 {
1919     //
1920     // Turn on PGA VREFGEN
1921     //
1922     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENPDNB, 1));
1923 
1924     //
1925     // Turn on PGA IREFGEN
1926     //
1927     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAIREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAIREFGENPDNB, 1));
1928 
1929     //
1930     // Turn on PGA VREFGEN Quick Charge
1931     //
1932     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN, 1));
1933 
1934     //
1935     // Delay 4ms
1936     //
1937     am_hal_delay_us(4000);
1938 
1939     //
1940     // Turn off PGA VREFGEN Quick Charge
1941     //
1942     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN, 0));
1943 
1944     //
1945     // Return the status.
1946     //
1947     return AM_HAL_STATUS_SUCCESS;
1948 }
1949 
1950 //*****************************************************************************
1951 //
1952 //! @brief Turn off reference
1953 //!
1954 //! This function turn off the reference voltage and current.
1955 //!
1956 //! @return status          - generic or interface specific status.
1957 //
1958 //*****************************************************************************
1959 uint32_t
am_hal_audadc_refgen_powerdown(void)1960 am_hal_audadc_refgen_powerdown(void)
1961 {
1962     g_AUDADCPgaChConfigured = 0x0;
1963     //
1964     // Turn on PGA VREFGEN
1965     //
1966     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENPDNB, 0));
1967 
1968     //
1969     // Turn on PGA IREFGEN
1970     //
1971     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAIREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAIREFGENPDNB, 0));
1972 
1973     //
1974     // Return the status.
1975     //
1976     return AM_HAL_STATUS_SUCCESS;
1977 }
1978 //*****************************************************************************
1979 //
1980 //! @brief Turn on PGA
1981 //!
1982 //! @param  ui32ChanNum     - PGA ui32ChanNumnel number: 0:A0, 1:A1, 2:B0, 3:B1,
1983 //!
1984 //! This function turn on PGA.
1985 //!
1986 //! @return status          - generic or interface specific status.
1987 //
1988 //*****************************************************************************
1989 uint32_t
am_hal_audadc_pga_powerup(uint32_t ui32ChanNum)1990 am_hal_audadc_pga_powerup(uint32_t ui32ChanNum)
1991 {
1992     //
1993     // turn on quick charge
1994     //
1995     switch (ui32ChanNum)
1996     {
1997         case 0:
1998             g_AUDADCPgaChConfigured |= 0x01;
1999             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 1));
2000             break;
2001 
2002         case 1:
2003             g_AUDADCPgaChConfigured |= 0x02;
2004             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 1));
2005             break;
2006 
2007         case 2:
2008             g_AUDADCPgaChConfigured |= 0x04;
2009             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 1));
2010             break;
2011 
2012         case 3:
2013             g_AUDADCPgaChConfigured |= 0x08;
2014             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 1));
2015             break;
2016 
2017         default:
2018             return AM_HAL_STATUS_INVALID_ARG;
2019     }
2020 
2021     //
2022     // Delay 4ms
2023     //
2024     am_hal_delay_us(4000 + 400);    // +10% for modeling differences
2025 
2026     //
2027     // turn off quick charge
2028     //
2029     switch (ui32ChanNum)
2030     {
2031         case 0:
2032         //
2033         // Turn on ChA VCMGEN & VCM Quick Charge
2034         //
2035 //        MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 1));
2036 //        MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 1));
2037             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 0));
2038             break;
2039 
2040         case 1:
2041             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 0));
2042             break;
2043 
2044         case 2:
2045             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 0));
2046             break;
2047 
2048         case 3:
2049             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 0));
2050             break;
2051 
2052         default:
2053             return AM_HAL_STATUS_INVALID_ARG;
2054     }
2055 
2056     //
2057     // Turn on ChA0/ChA1 opamps
2058     //
2059     switch (ui32ChanNum)
2060     {
2061         case 0:
2062             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, 0x1));
2063             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, 0x1));
2064             break;
2065 
2066         case 1:
2067             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, 0x2));
2068             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, 0x2));
2069             break;
2070 
2071         case 2:
2072             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, 0x1));
2073             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, 0x1));
2074             break;
2075 
2076         case 3:
2077             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, 0x2));
2078             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, 0x2));
2079             break;
2080 
2081         default:
2082             return AM_HAL_STATUS_INVALID_ARG;
2083     }
2084 
2085     //
2086     // Return the status.
2087     //
2088     return AM_HAL_STATUS_SUCCESS;
2089 }
2090 
2091 //*****************************************************************************
2092 //
2093 //! @brief Turn off PGA
2094 //!
2095 //! @param  ui32ChanNum     - PGA ui32ChanNumnel number: 0:A0, 1:A1, 2:B0, 3:B1,
2096 //!
2097 //! This function is to turn off PGA.
2098 //!
2099 //! @return status          - generic or interface specific status.
2100 //
2101 //*****************************************************************************
2102 uint32_t
am_hal_audadc_pga_powerdown(uint32_t ui32ChanNum)2103 am_hal_audadc_pga_powerdown(uint32_t ui32ChanNum)
2104 {
2105     switch (ui32ChanNum)
2106     {
2107         case 0:
2108             g_AUDADCPgaChConfigured &= 0xe;
2109             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, g_AUDADCPgaChConfigured & 0x3));
2110             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, g_AUDADCPgaChConfigured & 0x3));
2111             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, g_AUDADCPgaChConfigured & 0x3));
2112             break;
2113 
2114         case 1:
2115             g_AUDADCPgaChConfigured &= 0xd;
2116             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, g_AUDADCPgaChConfigured & 0x3));
2117             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, g_AUDADCPgaChConfigured&0x3));
2118             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, g_AUDADCPgaChConfigured & 0x3));
2119             break;
2120 
2121         case 2:
2122             g_AUDADCPgaChConfigured &= 0xb;
2123             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, (g_AUDADCPgaChConfigured & 0xC)>>2));
2124             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, (g_AUDADCPgaChConfigured & 0xC)>>2));
2125             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, (ui32ChanNum & 0xC) >> 2));
2126             break;
2127 
2128         case 3:
2129             g_AUDADCPgaChConfigured &= 0x7;
2130             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, (g_AUDADCPgaChConfigured & 0xC)>>2));
2131             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, (g_AUDADCPgaChConfigured & 0xC)>>2));
2132             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, (ui32ChanNum & 0xC) >> 2));
2133             break;
2134 
2135         default:
2136             return AM_HAL_STATUS_INVALID_ARG;
2137     }
2138 
2139     //
2140     // Turn off ChA VCM
2141     //
2142     if ((g_AUDADCPgaChConfigured & 0x3) == 0x0)
2143     {
2144         MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 0));
2145     }
2146 
2147     //
2148     // Turn off ChB VCM
2149     //
2150     if ((g_AUDADCPgaChConfigured & 0xC) == 0x0)
2151     {
2152         MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB, 0));
2153     }
2154 
2155     //
2156     // Return the status.
2157     //
2158     return AM_HAL_STATUS_SUCCESS;
2159 }
2160 
2161 //*****************************************************************************
2162 //
2163 //! @brief Turn on mic bias voltage to power up the mic
2164 //!
2165 //! @param  ui32VolTrim         - The value to set the output voltage
2166 //!
2167 //! This function sets output of the mic bias voltage.
2168 //!
2169 //*****************************************************************************
am_hal_audadc_micbias_powerup(uint32_t ui32VolTrim)2170 void am_hal_audadc_micbias_powerup(uint32_t ui32VolTrim)
2171 {
2172     MCUCTRL->AUDIO1 = ((MCUCTRL->AUDIO1 & ~MCUCTRL_AUDIO1_MICBIASVOLTAGETRIM_Msk) | _VAL2FLD(MCUCTRL_AUDIO1_MICBIASVOLTAGETRIM, ui32VolTrim & 0x3f));
2173     MCUCTRL->AUDIO1 = ((MCUCTRL->AUDIO1 & ~MCUCTRL_AUDIO1_MICBIASPDNB_Msk) | _VAL2FLD(MCUCTRL_AUDIO1_MICBIASPDNB, 1));
2174     //
2175     // take 1ms to power up
2176     //
2177     am_hal_delay_us(1000);
2178 }
2179 
2180 //*****************************************************************************
2181 //
2182 //! @brief Turn off mic bias voltage to power off the mic
2183 //!
2184 //! This function turns off the mic bias voltage.
2185 //!
2186 //*****************************************************************************
am_hal_audadc_micbias_powerdown(void)2187 void am_hal_audadc_micbias_powerdown(void)
2188 {
2189     MCUCTRL->AUDIO1 = ((MCUCTRL->AUDIO1 & ~MCUCTRL_AUDIO1_MICBIASPDNB_Msk) | _VAL2FLD(MCUCTRL_AUDIO1_MICBIASPDNB, 0));
2190 }
2191 
2192 //*****************************************************************************
2193 //
2194 //! @brief Config internal PGA.
2195 //!
2196 //! @param pHandle      - handle for the interface.
2197 //! @param psGainConfig - pointer to the AUDADC Gain Config
2198 //!
2199 //! This function configures the AUADC Pre-Amplifier Gain.
2200 //!
2201 //! @return status          - generic or interface specific status.
2202 //!
2203 //*****************************************************************************
am_hal_audadc_internal_pga_config(void * pHandle,am_hal_audadc_gain_config_t * psGainConfig)2204 uint32_t am_hal_audadc_internal_pga_config(void *pHandle, am_hal_audadc_gain_config_t* psGainConfig)
2205 {
2206     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
2207     uint32_t ui32Module = pAUDADCState->ui32Module;
2208 
2209 #ifndef AM_HAL_DISABLE_API_VALIDATION
2210     //
2211     // Check the handle.
2212     //
2213     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
2214     {
2215         return AM_HAL_STATUS_INVALID_HANDLE;
2216     }
2217 #endif // AM_HAL_DISABLE_API_VALIDATION
2218 
2219     //
2220     // Set the AUDADC gain codes.
2221     //
2222     AUDADCn(ui32Module)->GAIN =
2223          _VAL2FLD(AUDADC_GAIN_LGA, psGainConfig->ui32LGA)            |
2224          _VAL2FLD(AUDADC_GAIN_HGADELTA, psGainConfig->ui32HGADELTA)  |
2225          _VAL2FLD(AUDADC_GAIN_LGB, psGainConfig->ui32LGB)            |
2226          _VAL2FLD(AUDADC_GAIN_HGBDELTA, psGainConfig->ui32HGBDELTA);
2227 
2228     //
2229     // PGA Gain Configuration
2230     //
2231     AUDADCn(ui32Module)->GAINCFG = _VAL2FLD(AUDADC_GAINCFG_UPDATEMODE, psGainConfig->eUpdateMode) |
2232                                    _VAL2FLD(AUDADC_GAINCFG_PGACTRLEN, 1);
2233 
2234     //
2235     // Return the status.
2236     //
2237     return AM_HAL_STATUS_SUCCESS;
2238 }
2239 
2240 //*****************************************************************************
2241 //
2242 //! @brief Config Saturation Comparator.
2243 //!
2244 //! @param pHandle     - handle for the interface.
2245 //! @param psSATConfig - pointer to the AUDADC Saturation Config
2246 //!
2247 //! This function configures the Saturation Comparator.
2248 //!
2249 //! @return status          - generic or interface specific status.
2250 //!
2251 //*****************************************************************************
am_hal_audadc_saturation_config(void * pHandle,am_hal_audadc_sat_config_t * psSATConfig)2252 uint32_t am_hal_audadc_saturation_config(void *pHandle, am_hal_audadc_sat_config_t* psSATConfig)
2253 {
2254     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
2255     uint32_t ui32Module = pAUDADCState->ui32Module;
2256 
2257 #ifndef AM_HAL_DISABLE_API_VALIDATION
2258     //
2259     // Check the handle.
2260     //
2261     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
2262     {
2263         return AM_HAL_STATUS_INVALID_HANDLE;
2264     }
2265 #endif // AM_HAL_DISABLE_API_VALIDATION
2266 
2267     AUDADCn(ui32Module)->SATLIM = 0;
2268 
2269     AUDADCn(ui32Module)->SATMAX = 0;
2270 
2271     //
2272     // Saturation Comparator Configuration
2273     //
2274     AUDADCn(ui32Module)->SATCFG = _VAL2FLD(AUDADC_SATCFG_SATCHANSEL, psSATConfig->ui32ChanSel) |
2275                                   _VAL2FLD(AUDADC_SATCFG_SATEN, 1);
2276 
2277     //
2278     // Return the status.
2279     //
2280     return AM_HAL_STATUS_SUCCESS;
2281 }
2282 
2283 //*****************************************************************************
2284 //
2285 // End Doxygen group.
2286 //! @}
2287 //
2288 //*****************************************************************************
2289