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 stable-7da8bae71f 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 = powf(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         //
875         // Need slot number to distinguish between slot results.
876         //
877         ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAEN, AUDADC_DMACFG_DMAEN_DIS);
878     }
879     else
880     {
881         ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAEN, AUDADC_DMACFG_DMAEN_EN);
882     }
883 
884 
885     //
886     // Configure the DMA dynamic priority handling.
887     //
888     ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMADYNPRI, pDMAConfig->bDynamicPriority);
889 
890     //
891     // Configure the DMA static priority.
892     //
893     ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAPRI, pDMAConfig->ePriority);
894 
895     //
896     // Enable the DMA (does not start until AUDADC is enabled and triggered).
897     //
898     ui32Config |= _VAL2FLD(AUDADC_DMACFG_DMAEN, AUDADC_DMACFG_DMAEN_EN);
899 
900     //
901     // Set the DMA configuration.
902     //
903     AUDADCn(ui32Module)->DMACFG = ui32Config;
904 
905     //
906     // Set the DMA transfer count.
907     //
908     AUDADCn(ui32Module)->DMATOTCOUNT_b.TOTCOUNT = pDMAConfig->ui32SampleCount;
909 
910     //
911     // Set the DMA target address.
912     //
913     AUDADCn(ui32Module)->DMATARGADDR = pAUDADCState->ui32BufferPtr;
914 
915     //
916     // Set the DMA trigger on FIFO 75% full.
917     //
918     AUDADCn(ui32Module)->DMATRIGEN = AUDADC_DMATRIGEN_DFIFO75_Msk;
919 
920     //
921     // Return the status.
922     //
923     return AM_HAL_STATUS_SUCCESS;
924 }
925 
926 //*****************************************************************************
927 //
928 //! @brief AUDADC DMA Buffer function
929 //!
930 //! @param pHandle - handle for the module instance.
931 //!
932 //! This function to get DMA Buffer.
933 //!
934 //! @return status - generic or interface specific status.
935 //
936 //*****************************************************************************
937 uint32_t
am_hal_audadc_dma_get_buffer(void * pHandle)938 am_hal_audadc_dma_get_buffer(void *pHandle)
939 {
940     uint32_t ui32BufferPtr;
941     am_hal_audadc_state_t *pState = (am_hal_audadc_state_t *) pHandle;
942 
943     // Invalidate DAXI to make sure CPU sees the new data when loaded.
944     am_hal_daxi_control(AM_HAL_DAXI_CONTROL_INVALIDATE, NULL);
945 
946     ui32BufferPtr = (pState->ui32BufferPtr == pState->ui32BufferPong)? pState->ui32BufferPing: pState->ui32BufferPong;
947 
948     return ui32BufferPtr;
949 }
950 
951 //*****************************************************************************
952 //
953 //! @brief AUDADC device specific control function.
954 //!
955 //! @param pHandle   - handle for the module instance.
956 //! @param eRequest - One of:
957 //!   AM_HAL_AUDADC_REQ_WINDOW_CONFIG
958 //!   AM_HAL_AUDADC_REQ_TEMP_CELSIUS_GET (pArgs is required, see enums).
959 //!   AM_HAL_AUDADC_REQ_TEMP_TRIMS_GET   (pArgs is required, see enums).
960 //!   AM_HAL_AUDADC_REQ_DMA_DISABLE      (pArgs is not required).
961 //! @param pArgs - Pointer to arguments for Control Switch Case
962 //!
963 //! This function provides for special control functions for the AUDADC operation.
964 //!
965 //! @return status      - generic or interface specific status.
966 //
967 //*****************************************************************************
am_hal_audadc_control(void * pHandle,am_hal_audadc_request_e eRequest,void * pArgs)968 uint32_t am_hal_audadc_control(void *pHandle,
969                                am_hal_audadc_request_e eRequest,
970                                void *pArgs)
971 {
972     uint32_t    ui32Module = ((am_hal_audadc_state_t *)pHandle)->ui32Module;
973 
974 #ifndef AM_HAL_DISABLE_API_VALIDATION
975     //
976     // Check the handle.
977     //
978     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
979     {
980         return AM_HAL_STATUS_INVALID_HANDLE;
981     }
982 #endif // AM_HAL_DISABLE_API_VALIDATION
983 
984     switch ( eRequest )
985     {
986         case AM_HAL_AUDADC_REQ_WINDOW_CONFIG:
987         {
988             am_hal_audadc_window_config_t *pWindowConfig = (am_hal_audadc_window_config_t *)pArgs;
989 
990 #ifndef AM_HAL_DISABLE_API_VALIDATION
991             //
992             // Check the window limits.
993             //
994             if ( (pWindowConfig->ui32Upper > AUDADC_WULIM_ULIM_Msk)   ||
995                  (pWindowConfig->ui32Lower > AUDADC_WLLIM_LLIM_Msk) )
996             {
997                 return AM_HAL_STATUS_OUT_OF_RANGE;
998             }
999 #endif // AM_HAL_DISABLE_API_VALIDATION
1000             //
1001             // Set the window comparison upper and lower limits.
1002             //
1003             AUDADCn(ui32Module)->WULIM = _VAL2FLD(AUDADC_WULIM_ULIM, pWindowConfig->ui32Upper);
1004             AUDADCn(ui32Module)->WLLIM = _VAL2FLD(AUDADC_WLLIM_LLIM, pWindowConfig->ui32Lower);
1005 
1006             //
1007             // Set the window scale per precision mode if indicated.
1008             //
1009             AUDADCn(ui32Module)->SCWLIM = _VAL2FLD(AUDADC_SCWLIM_SCWLIMEN,
1010                                                 pWindowConfig->bScaleLimits);
1011         }
1012         break;
1013 
1014         case AM_HAL_AUDADC_REQ_TEMP_CELSIUS_GET:
1015             //
1016             // pArgs must point to an array of 3 floats.  To assure that the
1017             // array is valid, upon calling the 3rd float (pArgs[2]) must be
1018             // set to the value -123.456F.
1019             //
1020             if ( pArgs != NULL )
1021             {
1022                 float *pfArray = (float*)pArgs;
1023                 float fTemp, fCalibration_temp, fCalibration_voltage, fCalibration_offset, fVoltage;
1024 
1025                 if ( pfArray[2] == -123.456F )
1026                 {
1027                     //
1028                     // Get the scaled voltage obtained from the AUDADC sample.
1029                     // The AUDADC sample value is scaled up by the reference voltage
1030                     // (e.g. 1.5F), then divided by 65536.0F.
1031                     //
1032                     fVoltage = pfArray[0];
1033 
1034                     //
1035                     // Get calibration temperature from trimmed values & convert to degrees K.
1036                     //
1037                     fCalibration_temp = priv_temp_trims.flt.fCalibrationTemperature;
1038                     fCalibration_voltage = priv_temp_trims.flt.fCalibrationVoltage;
1039                     fCalibration_offset  = priv_temp_trims.flt.fCalibrationOffset;
1040 
1041                     //
1042                     // Compute the temperature.
1043                     //
1044                     fTemp  = fCalibration_temp;
1045                     fTemp /= (fCalibration_voltage - fCalibration_offset);
1046                     fTemp *= (fVoltage - fCalibration_offset);
1047 
1048                     //
1049                     // Give it back to the caller in Celsius.
1050                     //
1051                     pfArray[1] = fTemp - 273.15f;
1052                 }
1053                 else
1054                 {
1055                     return AM_HAL_STATUS_INVALID_OPERATION;
1056                 }
1057             }
1058             else
1059             {
1060                 return AM_HAL_STATUS_INVALID_ARG;
1061             }
1062             break;
1063 
1064         case AM_HAL_AUDADC_REQ_TEMP_TRIMS_GET:
1065             //
1066             // pArgs must point to an array of 4 floats.  To assure that the
1067             // array is valid, upon calling the 4th float (pArgs[3]) must be
1068             // set to the value -123.456.
1069             // On return, pArgs[3] is set to 1 if the returned values are
1070             //  calibrated, or 0 if default calibration values.
1071             //
1072             if ( pArgs != NULL )
1073             {
1074                 float *pfArray = (float*)pArgs;
1075                 if ( pfArray[3] == -123.456F )
1076                 {
1077                     //
1078                     // Return trim temperature as a float.
1079                     //
1080                     pfArray[0] = priv_temp_trims.flt.fCalibrationTemperature;
1081 
1082                     //
1083                     // Return trim voltage as a float.
1084                     //
1085                     pfArray[1] = priv_temp_trims.flt.fCalibrationVoltage;
1086 
1087                     //
1088                     // Return trim AUDADC offset voltage as a float.
1089                     //
1090                     pfArray[2] = priv_temp_trims.flt.fCalibrationOffset;
1091 
1092                     //
1093                     // Set the calibrated or uncalibrated flag
1094                     //
1095                     ((uint32_t*)pArgs)[3] = priv_temp_trims.ui32.bMeasured;
1096                 }
1097                 else
1098                 {
1099                     return AM_HAL_STATUS_INVALID_OPERATION;
1100                 }
1101             }
1102             else
1103             {
1104                 return AM_HAL_STATUS_INVALID_ARG;
1105             }
1106             break;
1107 
1108         case AM_HAL_AUDADC_REQ_DMA_DISABLE:
1109             //
1110             // Clear DMAEN register
1111             //
1112             AUDADCn(ui32Module)->DMACFG_b.DMAEN = AUDADC_DMACFG_DMAEN_DIS;
1113             break;
1114 
1115         default:
1116             return AM_HAL_STATUS_INVALID_ARG;
1117     }
1118 
1119     //
1120     // Return status.
1121     //
1122     return AM_HAL_STATUS_SUCCESS;
1123 }
1124 
1125 //*****************************************************************************
1126 //
1127 //! @brief AUDADC enable function
1128 //!
1129 //! @param pHandle   - handle for the module instance.
1130 //!
1131 //! This function enables the AUDADC operation.
1132 //!
1133 //! @return status      - generic or interface specific status.
1134 //
1135 //*****************************************************************************
1136 uint32_t
am_hal_audadc_enable(void * pHandle)1137 am_hal_audadc_enable(void *pHandle)
1138 {
1139     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1140     uint32_t            ui32Module = pAUDADCState->ui32Module;
1141 
1142 #ifndef AM_HAL_DISABLE_API_VALIDATION
1143     //
1144     // Check the handle.
1145     //
1146     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1147     {
1148         return AM_HAL_STATUS_INVALID_HANDLE;
1149     }
1150 
1151     if ( pAUDADCState->prefix.s.bEnable )
1152     {
1153         return AM_HAL_STATUS_SUCCESS;
1154     }
1155 #endif // AM_HAL_DISABLE_API_VALIDATION
1156 
1157     //
1158     // Enable the AUDADC.
1159     //
1160     AUDADCn(ui32Module)->CFG_b.ADCEN = 0x1;
1161 
1162     //
1163     // Set flag to indicate module is enabled.
1164     //
1165     pAUDADCState->prefix.s.bEnable = true;
1166 
1167     //
1168     // Return the status.
1169     //
1170     return AM_HAL_STATUS_SUCCESS;
1171 }
1172 
1173 //*****************************************************************************
1174 //
1175 //! @brief AUDADC disable function
1176 //!
1177 //! @param pHandle - handle for the module instance.
1178 //!
1179 //! This function disables the AUDADC operation.
1180 //!
1181 //! @return status - generic or interface specific status.
1182 //
1183 //*****************************************************************************
1184 uint32_t
am_hal_audadc_disable(void * pHandle)1185 am_hal_audadc_disable(void *pHandle)
1186 {
1187     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1188     uint32_t            ui32Module = pAUDADCState->ui32Module;
1189 
1190 #ifndef AM_HAL_DISABLE_API_VALIDATION
1191     //
1192     // Check the handle.
1193     //
1194     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1195     {
1196         return AM_HAL_STATUS_INVALID_HANDLE;
1197     }
1198 #endif // AM_HAL_DISABLE_API_VALIDATION
1199 
1200     //
1201     // Disable the AUDADC.
1202     //
1203     AUDADCn(ui32Module)->CFG_b.ADCEN = 0x0;
1204 
1205     //
1206     // Set flag to indicate module is disabled.
1207     //
1208     pAUDADCState->prefix.s.bEnable = false;
1209 
1210     //
1211     // Return the status.
1212     //
1213     return AM_HAL_STATUS_SUCCESS;
1214 }
1215 
1216 //*****************************************************************************
1217 //
1218 //! @brief AUDADC status function
1219 //!
1220 //! @param pHandle - handle for the interface.
1221 //! @param pStatus - pointer to status
1222 //!
1223 //! This function returns the current status of the DMA operation.
1224 //!
1225 //! @return status - DMA status flags.
1226 //
1227 //*****************************************************************************
1228 uint32_t
am_hal_audadc_status_get(void * pHandle,am_hal_audadc_status_t * pStatus)1229 am_hal_audadc_status_get(void *pHandle, am_hal_audadc_status_t *pStatus )
1230 {
1231     uint32_t    ui32Module = ((am_hal_audadc_state_t *)pHandle)->ui32Module;
1232 
1233 #ifndef AM_HAL_DISABLE_API_VALIDATION
1234     //
1235     // Check the handle.
1236     //
1237     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1238     {
1239         return AM_HAL_STATUS_INVALID_HANDLE;
1240     }
1241 #endif // AM_HAL_DISABLE_API_VALIDATION
1242 
1243     //
1244     // Get the power status.
1245     //
1246     pStatus->bPoweredOn = (AUDADCn(ui32Module)->STAT & AUDADC_STAT_PWDSTAT_Msk) ==
1247                           _VAL2FLD(AUDADC_STAT_PWDSTAT, AUDADC_STAT_PWDSTAT_ON);
1248 
1249     //
1250     // Get the low power mode 1 status.
1251     //
1252     pStatus->bLPMode1 = (AUDADCn(ui32Module)->STAT & AUDADC_STAT_PWDSTAT_Msk) ==
1253                         _VAL2FLD(AUDADC_STAT_PWDSTAT, AUDADC_STAT_PWDSTAT_POWERED_DOWN);
1254 
1255     //
1256     //  Get the DMA status.
1257     //
1258     pStatus->bErr = ((AUDADCn(ui32Module)->DMASTAT & AUDADC_DMASTAT_DMAERR_Msk) > 0);
1259     pStatus->bCmp = ((AUDADCn(ui32Module)->DMASTAT & AUDADC_DMASTAT_DMACPL_Msk) > 0);
1260     pStatus->bTIP = ((AUDADCn(ui32Module)->DMASTAT & AUDADC_DMASTAT_DMATIP_Msk) > 0);
1261 
1262     //
1263     // Return the status.
1264     //
1265     return AM_HAL_STATUS_SUCCESS;
1266 }
1267 
1268 //*****************************************************************************
1269 //
1270 //! @brief AUDADC enable interrupts function
1271 //!
1272 //! @param pHandle       - handle for the interface.
1273 //! @param ui32IntMask  - AUDADC interrupt mask.
1274 //!
1275 //! This function enables the specific indicated interrupts.
1276 //!
1277 //! @return status      - generic or interface specific status.
1278 //
1279 //*****************************************************************************
1280 uint32_t
am_hal_audadc_interrupt_enable(void * pHandle,uint32_t ui32IntMask)1281 am_hal_audadc_interrupt_enable(void *pHandle, uint32_t ui32IntMask)
1282 {
1283     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1284 
1285 #ifndef AM_HAL_DISABLE_API_VALIDATION
1286     //
1287     // Check the handle.
1288     //
1289     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1290     {
1291         return AM_HAL_STATUS_INVALID_HANDLE;
1292     }
1293 #endif // AM_HAL_DISABLE_API_VALIDATION
1294 
1295     //
1296     // Enable the interrupts.
1297     //
1298     AUDADCn(ui32Module)->INTEN |= ui32IntMask;
1299 
1300     //
1301     // Return the status.
1302     //
1303     return AM_HAL_STATUS_SUCCESS;
1304 }
1305 
1306 //*****************************************************************************
1307 //
1308 //! @brief AUDADC disable interrupts function
1309 //!
1310 //! @param pHandle     - handle for the interface.
1311 //! @param ui32IntMask - AUDADC interrupt mask.
1312 //!
1313 //! This function disable the specific indicated interrupts.
1314 //!
1315 //! @return status     - generic or interface specific status.
1316 //
1317 //*****************************************************************************
1318 uint32_t
am_hal_audadc_interrupt_disable(void * pHandle,uint32_t ui32IntMask)1319 am_hal_audadc_interrupt_disable(void *pHandle, uint32_t ui32IntMask)
1320 {
1321     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1322 
1323 #ifndef AM_HAL_DISABLE_API_VALIDATION
1324     //
1325     // Check the handle.
1326     //
1327     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1328     {
1329         return AM_HAL_STATUS_INVALID_HANDLE;
1330     }
1331 #endif // AM_HAL_DISABLE_API_VALIDATION
1332 
1333     //
1334     // Disable the interrupts.
1335     //
1336     AUDADCn(ui32Module)->INTEN &= ~ui32IntMask;
1337 
1338     //
1339     // Return the status.
1340     //
1341     return AM_HAL_STATUS_SUCCESS;
1342 }
1343 
1344 //*****************************************************************************
1345 //
1346 //! @brief AUDADC interrupt status function
1347 //!
1348 //! @param pHandle      - handle for the interface.
1349 //! @param pui32Status  - pointer to status
1350 //! @param bEnabledOnly - if AUDADC enabled
1351 //!
1352 //! This function returns the specific indicated interrupt status.
1353 //!
1354 //! @return status      - generic or interface specific status.
1355 //
1356 //*****************************************************************************
1357 uint32_t
am_hal_audadc_interrupt_status(void * pHandle,uint32_t * pui32Status,bool bEnabledOnly)1358 am_hal_audadc_interrupt_status(void *pHandle,
1359                                uint32_t  *pui32Status,
1360                                bool bEnabledOnly)
1361 {
1362     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1363 
1364 #ifndef AM_HAL_DISABLE_API_VALIDATION
1365     //
1366     // Check the handle.
1367     //
1368     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1369     {
1370         return AM_HAL_STATUS_INVALID_HANDLE;
1371     }
1372 #endif // AM_HAL_DISABLE_API_VALIDATION
1373 
1374     //
1375     // if requested, only return the interrupts that are enabled.
1376     //
1377     if ( bEnabledOnly )
1378     {
1379         uint32_t ui32RetVal = AUDADCn(ui32Module)->INTSTAT;
1380         *pui32Status = AUDADCn(ui32Module)->INTEN & ui32RetVal;
1381     }
1382     else
1383     {
1384         *pui32Status = AUDADCn(ui32Module)->INTSTAT;
1385     }
1386 
1387     //
1388     // Return the status.
1389     //
1390     return AM_HAL_STATUS_SUCCESS;
1391 }
1392 
1393 //*****************************************************************************
1394 //
1395 //! @brief AUDADC interrupt clear
1396 //!
1397 //! @param pHandle         - handle for the interface.
1398 //! @param ui32IntMask    - uint32_t for interrupts to clear
1399 //!
1400 //! This function clears the interrupts for the given peripheral.
1401 //!
1402 //! @return status      - generic or interface specific status.
1403 //
1404 //*****************************************************************************
1405 uint32_t
am_hal_audadc_interrupt_clear(void * pHandle,uint32_t ui32IntMask)1406 am_hal_audadc_interrupt_clear(void *pHandle, uint32_t ui32IntMask)
1407 {
1408     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1409 
1410 #ifndef AM_HAL_DISABLE_API_VALIDATION
1411     //
1412     // Check the handle.
1413     //
1414     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1415     {
1416         return AM_HAL_STATUS_INVALID_HANDLE;
1417     }
1418 #endif // AM_HAL_DISABLE_API_VALIDATION
1419 
1420     //
1421     // Clear the interrupts.
1422     //
1423     AUDADCn(ui32Module)->INTCLR = ui32IntMask;
1424 
1425     //
1426     // Return the status.
1427     //
1428     return AM_HAL_STATUS_SUCCESS;
1429 }
1430 
1431 //*****************************************************************************
1432 //
1433 //! @brief AUDADC interrupt service
1434 //!
1435 //! @param pHandle       - handle for the interface.
1436 //! @param pDMAConfig   - pointer to DMA configuration
1437 //!
1438 //! Interrupt service routine.
1439 //!
1440 //! @return status      - generic or interface specific status.
1441 //
1442 //*****************************************************************************
1443 uint32_t
am_hal_audadc_interrupt_service(void * pHandle,am_hal_audadc_dma_config_t * pDMAConfig)1444 am_hal_audadc_interrupt_service(void *pHandle, am_hal_audadc_dma_config_t *pDMAConfig)
1445 {
1446     am_hal_audadc_state_t* pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1447     uint32_t ui32Module = pAUDADCState->ui32Module;
1448 
1449     pAUDADCState->ui32BufferPtr = (pAUDADCState->ui32BufferPtr == pAUDADCState->ui32BufferPong)? pAUDADCState->ui32BufferPing: pAUDADCState->ui32BufferPong;
1450 
1451     //
1452     // Set the DMA transfer count.
1453     //
1454     AUDADCn(ui32Module)->DMATOTCOUNT_b.TOTCOUNT = pDMAConfig->ui32SampleCount;
1455 
1456     //
1457     // Set the DMA target address.
1458     //
1459     AUDADCn(ui32Module)->DMATARGADDR = pAUDADCState->ui32BufferPtr;
1460 
1461     //
1462     // Return the status.
1463     //
1464     return AM_HAL_STATUS_SUCCESS;
1465 }
1466 
1467 //*****************************************************************************
1468 //
1469 // AUDADC sample read function
1470 //
1471 // This function reads samples from the AUDADC FIFO or an SRAM sample buffer
1472 // returned by a DMA operation, and calibrates the samples.
1473 //
1474 //*****************************************************************************
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)1475 uint32_t am_hal_audadc_samples_read(void *pHandle,
1476                                     uint32_t *pui32InSampleBuffer,
1477                                     uint32_t *pui32InOutNumberSamples,
1478                                     bool bLowSample, am_hal_audadc_sample_t *pui32LGOutBuffer,
1479                                     bool bHighSample, am_hal_audadc_sample_t *pui32HGOutBuffer,
1480                                     am_hal_offset_cal_coeffs_array_t *pSlotCalib)
1481 {
1482     uint32_t      ui32Sample;
1483     uint32_t      ui32RequestedSamples = *pui32InOutNumberSamples;
1484     int32_t       i32OffsetAdj = 0;
1485 
1486     uint32_t ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1487 
1488 #ifndef AM_HAL_DISABLE_API_VALIDATION
1489     //
1490     // Check the handle.
1491     //
1492     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1493     {
1494         return AM_HAL_STATUS_INVALID_HANDLE;
1495     }
1496 
1497     //
1498     // Check the output sample buffer pointer.
1499     //
1500     if ( (NULL == pui32LGOutBuffer) && (NULL == pui32HGOutBuffer))
1501     {
1502         return AM_HAL_STATUS_INVALID_ARG;
1503     }
1504 #endif // AM_HAL_DISABLE_API_VALIDATION
1505 
1506     *pui32InOutNumberSamples = 0;
1507 
1508     //
1509     // Check if we are reading directly from FIFO or DMA SRAM buffer.
1510     //
1511     if ( NULL == pui32InSampleBuffer )
1512     {
1513         //
1514         // Grab a value from the AUDADC FIFO
1515         //
1516         do
1517         {
1518             ui32Sample = AUDADCn(ui32Module)->FIFOPR;
1519             if ( bLowSample )
1520             {
1521               pui32LGOutBuffer->ui16AudChannel = AM_HAL_AUDADC_FIFO_SLOT(ui32Sample);
1522               pui32LGOutBuffer->int16Sample    = AM_HAL_AUDADC_FIFO_LGDATA(ui32Sample) << 4;
1523               if (pSlotCalib != NULL)
1524               {
1525                   if (pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].bValid)
1526                   {
1527                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].i32DCOffsetAdj << 4;
1528                       if ((pui32LGOutBuffer->int16Sample >= 0) &&
1529                           (i32OffsetAdj > (32767 - pui32LGOutBuffer->int16Sample)))
1530                       {
1531                           pui32LGOutBuffer->int16Sample = 32767; // Saturation
1532                       }
1533                       else if ((pui32LGOutBuffer->int16Sample < 0) &&
1534                                (i32OffsetAdj < (-32768 - pui32LGOutBuffer->int16Sample)))
1535                       {
1536                           pui32LGOutBuffer->int16Sample = -32768; // Saturation
1537                       }
1538                       else
1539                       {
1540                           pui32LGOutBuffer->int16Sample   += i32OffsetAdj;
1541                       }
1542                   }
1543               }
1544               pui32LGOutBuffer++;
1545             }
1546 
1547             if ( bHighSample )
1548             {
1549               pui32HGOutBuffer->ui16AudChannel = AM_HAL_AUDADC_FIFO_SLOT(ui32Sample);
1550               pui32HGOutBuffer->int16Sample    = AM_HAL_AUDADC_FIFO_HGDATA(ui32Sample) << 4;
1551               if (pSlotCalib != NULL)
1552               {
1553                   if (pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].bValid)
1554                   {
1555                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].i32DCOffsetAdj << 4;
1556                       if ((pui32HGOutBuffer->int16Sample >= 0) &&
1557                           (i32OffsetAdj > (32767 - pui32HGOutBuffer->int16Sample)))
1558                       {
1559                           pui32HGOutBuffer->int16Sample = 32767; // Saturation
1560                       }
1561                       else if ((pui32HGOutBuffer->int16Sample < 0) &&
1562                                (i32OffsetAdj < (-32768 - pui32HGOutBuffer->int16Sample)))
1563                       {
1564                           pui32HGOutBuffer->int16Sample = -32768; // Saturation
1565                       }
1566                       else
1567                       {
1568                           pui32HGOutBuffer->int16Sample   += i32OffsetAdj;
1569                       }
1570                   }
1571               }
1572               pui32HGOutBuffer++;
1573             }
1574             (*pui32InOutNumberSamples)++;
1575         } while (!AM_HAL_AUDADC_FIFO_EMPTY(AUDADCn(ui32Module)) &&
1576                  (*pui32InOutNumberSamples < ui32RequestedSamples));
1577     }
1578     else
1579     {
1580         //
1581         // Process the samples from the provided sample buffer
1582         //
1583         do
1584         {
1585             if ( bLowSample )
1586             {
1587               pui32LGOutBuffer->ui16AudChannel = AM_HAL_AUDADC_FIFO_SLOT(*pui32InSampleBuffer);
1588               pui32LGOutBuffer->int16Sample    = AM_HAL_AUDADC_FIFO_LGDATA(*pui32InSampleBuffer) << 4; //extend to 16 bits with sign bit
1589               if (pSlotCalib != NULL)
1590               {
1591                   if (pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].bValid)
1592                   {
1593                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32LGOutBuffer->ui16AudChannel * 2].i32DCOffsetAdj << 4;
1594                       if ((pui32LGOutBuffer->int16Sample >= 0) &&
1595                           (i32OffsetAdj > (32767 - pui32LGOutBuffer->int16Sample)))
1596                       {
1597                           pui32LGOutBuffer->int16Sample = 32767; // Saturation
1598                       }
1599                       else if ((pui32LGOutBuffer->int16Sample < 0) &&
1600                                (i32OffsetAdj < (-32768 - pui32LGOutBuffer->int16Sample)))
1601                       {
1602                           pui32LGOutBuffer->int16Sample = -32768; // Saturation
1603                       }
1604                       else
1605                       {
1606                           pui32LGOutBuffer->int16Sample   += i32OffsetAdj;
1607                       }
1608                   }
1609               }
1610               pui32LGOutBuffer++;
1611             }
1612 
1613             if ( bHighSample )
1614             {
1615               pui32HGOutBuffer->ui16AudChannel  = AM_HAL_AUDADC_FIFO_SLOT(*pui32InSampleBuffer);
1616               pui32HGOutBuffer->int16Sample     = AM_HAL_AUDADC_FIFO_HGDATA(*pui32InSampleBuffer) << 4;
1617               if (pSlotCalib != NULL)
1618               {
1619                   if (pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].bValid)
1620                   {
1621                       i32OffsetAdj = pSlotCalib->sCalibCoeff[pui32HGOutBuffer->ui16AudChannel * 2 + 1].i32DCOffsetAdj << 4;
1622                       if ((pui32HGOutBuffer->int16Sample >= 0) &&
1623                           (i32OffsetAdj > (32767 - pui32HGOutBuffer->int16Sample)))
1624                       {
1625                           pui32HGOutBuffer->int16Sample = 32767; // Saturation
1626                       }
1627                       else if ((pui32HGOutBuffer->int16Sample < 0) &&
1628                                (i32OffsetAdj < (-32768 - pui32HGOutBuffer->int16Sample)))
1629                       {
1630                           pui32HGOutBuffer->int16Sample = -32768; // Saturation
1631                       }
1632                       else
1633                       {
1634                           pui32HGOutBuffer->int16Sample   += i32OffsetAdj;
1635                       }
1636                   }
1637               }
1638               pui32HGOutBuffer++;
1639             }
1640             pui32InSampleBuffer++;
1641             (*pui32InOutNumberSamples)++;
1642         } while (*pui32InOutNumberSamples < ui32RequestedSamples);
1643     }
1644 
1645     //
1646     // Return FIFO valid bits.
1647     //
1648     return AM_HAL_STATUS_SUCCESS;
1649 }
1650 
1651 //*****************************************************************************
1652 //
1653 //! @brief Issue Software Trigger to the AUDADC.
1654 //!
1655 //! @param pHandle   - handle for the module instance.
1656 //!
1657 //! This function triggers the AUDADC operation.
1658 //!
1659 //! @return status      - generic or interface specific status.
1660 //
1661 //*****************************************************************************
1662 uint32_t
am_hal_audadc_sw_trigger(void * pHandle)1663 am_hal_audadc_sw_trigger(void *pHandle)
1664 {
1665     uint32_t    ui32Module = ((am_hal_audadc_state_t*)pHandle)->ui32Module;
1666 
1667 #ifndef AM_HAL_DISABLE_API_VALIDATION
1668     //
1669     // Check the handle.
1670     //
1671     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1672     {
1673         return AM_HAL_STATUS_INVALID_HANDLE;
1674     }
1675 #endif // AM_HAL_DISABLE_API_VALIDATION
1676 
1677     //
1678     // Write to the Software trigger register in the AUDADC.
1679     //
1680     AUDADCn(ui32Module)->SWT = 0x37;
1681 
1682     //am_hal_delay_us(100);
1683 
1684     //
1685     // Return the status.
1686     //
1687     return AM_HAL_STATUS_SUCCESS;
1688 }
1689 
1690 //*****************************************************************************
1691 //
1692 //! @brief AUDADC power control function
1693 //!
1694 //! @param pHandle      - handle for the interface.
1695 //! @param ePowerState  - the desired power state to move the peripheral to.
1696 //! @param bRetainState - flag (if true) to save/restore peripheral state upon
1697 //!                       power state ui32ChanNumge.
1698 //!
1699 //! This function updates the peripheral to a given power state.
1700 //!
1701 //! @return status      - generic or interface specific status.
1702 //
1703 //*****************************************************************************
1704 uint32_t
am_hal_audadc_power_control(void * pHandle,am_hal_sysctrl_power_state_e ePowerState,bool bRetainState)1705 am_hal_audadc_power_control(void *pHandle,
1706                             am_hal_sysctrl_power_state_e ePowerState,
1707                             bool bRetainState)
1708 {
1709     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
1710     uint32_t            ui32Module = pAUDADCState->ui32Module;
1711 
1712 #ifndef AM_HAL_DISABLE_API_VALIDATION
1713     //
1714     // Check the handle.
1715     //
1716     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
1717     {
1718         return AM_HAL_STATUS_INVALID_HANDLE;
1719     }
1720 #endif // AM_HAL_DISABLE_API_VALIDATION
1721 
1722     //
1723     // Decode the requested power state and update ADC operation accordingly.
1724     //
1725     switch (ePowerState)
1726     {
1727         case AM_HAL_SYSCTRL_WAKE:
1728             if ( bRetainState  &&  !pAUDADCState->registerState.bValid )
1729             {
1730                 return AM_HAL_STATUS_INVALID_OPERATION;
1731             }
1732 
1733             //
1734             // Enable the AUDADC power domain.
1735             //
1736             am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_AUDADC);
1737 
1738             if ( bRetainState )
1739             {
1740                 AUDADCn(ui32Module)->SL0CFG = pAUDADCState->registerState.regSL0CFG;
1741                 AUDADCn(ui32Module)->SL1CFG = pAUDADCState->registerState.regSL1CFG;
1742                 AUDADCn(ui32Module)->SL2CFG = pAUDADCState->registerState.regSL2CFG;
1743                 AUDADCn(ui32Module)->SL3CFG = pAUDADCState->registerState.regSL3CFG;
1744                 AUDADCn(ui32Module)->SL4CFG = pAUDADCState->registerState.regSL4CFG;
1745                 AUDADCn(ui32Module)->SL5CFG = pAUDADCState->registerState.regSL5CFG;
1746                 AUDADCn(ui32Module)->SL6CFG = pAUDADCState->registerState.regSL6CFG;
1747                 AUDADCn(ui32Module)->SL7CFG = pAUDADCState->registerState.regSL7CFG;
1748                 AUDADCn(ui32Module)->WULIM  = pAUDADCState->registerState.regWULIM;
1749                 AUDADCn(ui32Module)->WLLIM  = pAUDADCState->registerState.regWLLIM;
1750                 AUDADCn(ui32Module)->INTEN  = pAUDADCState->registerState.regINTEN;
1751                 AUDADCn(ui32Module)->CFG    = pAUDADCState->registerState.regCFG;
1752 
1753                 pAUDADCState->registerState.bValid     = false;
1754             }
1755             break;
1756 
1757         case AM_HAL_SYSCTRL_NORMALSLEEP:
1758         case AM_HAL_SYSCTRL_DEEPSLEEP:
1759             if ( bRetainState )
1760             {
1761                 pAUDADCState->registerState.regSL0CFG  = AUDADCn(ui32Module)->SL0CFG;
1762                 pAUDADCState->registerState.regSL1CFG  = AUDADCn(ui32Module)->SL1CFG;
1763                 pAUDADCState->registerState.regSL2CFG  = AUDADCn(ui32Module)->SL2CFG;
1764                 pAUDADCState->registerState.regSL3CFG  = AUDADCn(ui32Module)->SL3CFG;
1765                 pAUDADCState->registerState.regSL4CFG  = AUDADCn(ui32Module)->SL4CFG;
1766                 pAUDADCState->registerState.regSL5CFG  = AUDADCn(ui32Module)->SL5CFG;
1767                 pAUDADCState->registerState.regSL6CFG  = AUDADCn(ui32Module)->SL6CFG;
1768                 pAUDADCState->registerState.regSL7CFG  = AUDADCn(ui32Module)->SL7CFG;
1769                 pAUDADCState->registerState.regWULIM   = AUDADCn(ui32Module)->WULIM;
1770                 pAUDADCState->registerState.regWLLIM   = AUDADCn(ui32Module)->WLLIM;
1771                 pAUDADCState->registerState.regINTEN   = AUDADCn(ui32Module)->INTEN;
1772                 pAUDADCState->registerState.regCFG     = AUDADCn(ui32Module)->CFG;
1773 
1774                 pAUDADCState->registerState.bValid     = true;
1775             }
1776 
1777             //
1778             // Disable the AUDADC power domain.
1779             //
1780             am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_AUDADC);
1781             break;
1782 
1783         default:
1784             return AM_HAL_STATUS_INVALID_ARG;
1785     }
1786 
1787     //
1788     // Return the status.
1789     //
1790     return AM_HAL_STATUS_SUCCESS;
1791 }
1792 
1793 //*****************************************************************************
1794 //
1795 //! @brief Set PGA gain
1796 //!
1797 //! @param  ui32ChanNum  - PGA ui32ChanNumnel number: 0:A0, 1:A1, 2:B0, 3:B1,
1798 //! @param  in32GaindBx2 - gain in dB. in32GaindBx2 = 2 * gain (dB)
1799 //!
1800 //! This function sets the gain of PGA.
1801 //!
1802 //! @return status       - generic or interface specific status.
1803 //
1804 //*****************************************************************************
1805 uint32_t
am_hal_audadc_gain_set(uint32_t ui32ChanNum,int32_t in32GaindBx2)1806 am_hal_audadc_gain_set(uint32_t ui32ChanNum, int32_t in32GaindBx2)
1807 {
1808     uint32_t temp;
1809     uint32_t ui32BypassStage1;
1810     int32_t in32Gain2Div2 = 0;
1811     int32_t in32Gain1Val;
1812     int32_t in32Gain2Val;
1813 
1814     // add support for -6 dB to -0.5 dB by using PGACH*GAIN2DIV2SEL
1815     if (in32GaindBx2 < 0)
1816     {
1817         in32Gain2Div2 = 1;
1818         in32GaindBx2 += 12; // subsequent calculations with 6 dB (x2) added (should be positive)
1819     }
1820 
1821     //
1822     // Calculate first stage gain.
1823     // Most of the gain comes from the first stage, unless gain < 12 dB.
1824     // If gain < 12 dB, we bypass first stagea
1825     //
1826     if (in32GaindBx2 < 24)
1827     {
1828         ui32BypassStage1 = 1;
1829         in32Gain1Val = 0;
1830         in32Gain2Val = in32GaindBx2;
1831     }
1832     else
1833     {
1834         ui32BypassStage1 = 0;
1835         in32Gain1Val = (in32GaindBx2 - 24) / 6;
1836         //
1837         // however, in32Gain1Val saturates at code 7 (33 dB)
1838         // (0:12, 1:15, 2:18, 3:21, 4:24, 5:27, 6:30, 7:33) dB
1839         //
1840         if (in32Gain1Val > 7)
1841         {
1842             in32Gain1Val = 7;
1843         }
1844 
1845         //
1846         // The remainder of the gain is provided by the second stage
1847         //
1848         in32Gain2Val = in32GaindBx2 - 24 - 6*in32Gain1Val;
1849     }
1850 
1851     switch (ui32ChanNum)
1852     {
1853         case 0:
1854             temp = _FLD2VAL(MCUCTRL_PGACTRL1_PGACHABYPASSEN, MCUCTRL->PGACTRL1) & 0x2; // keep CHA1 bypassen state
1855             temp |= ui32BypassStage1;
1856             temp &= 0x3;
1857             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, temp));
1858             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
1859             //MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPINPDNB, 0x3)); // debug - set to 1
1860             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA0GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA0GAIN1SEL, in32Gain1Val));
1861             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA0GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA0GAIN2SEL, in32Gain2Val));
1862             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA0GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA0GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1863             break;
1864         case 1:
1865             temp = _FLD2VAL(MCUCTRL_PGACTRL1_PGACHABYPASSEN, MCUCTRL->PGACTRL1) & 0x1; // keep CHA0 bypassen state
1866             temp |= ui32BypassStage1 << 1;
1867             temp &= 0x3;
1868             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, temp));
1869             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
1870             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA1GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA1GAIN1SEL, in32Gain1Val));
1871             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA1GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA1GAIN2SEL, in32Gain2Val));
1872             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHA1GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHA1GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1873             break;
1874         case 2:
1875             temp = _FLD2VAL(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, MCUCTRL->PGACTRL2) & 0x2; // keep CHB1 bypassen state
1876             temp |= ui32BypassStage1;
1877             temp &= 0x3;
1878             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, temp));
1879             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
1880             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB0GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB0GAIN1SEL, in32Gain1Val));
1881             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB0GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB0GAIN2SEL, in32Gain2Val));
1882             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB0GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB0GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1883             break;
1884         case 3:
1885             temp = _FLD2VAL(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, MCUCTRL->PGACTRL2) & 0x1; // keep CHB0 bypassen state
1886             temp |= ui32BypassStage1 << 1;
1887             temp &= 0x3;
1888             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, temp));
1889             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
1890             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB1GAIN1SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB1GAIN1SEL, in32Gain1Val));
1891             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB1GAIN2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB1GAIN2SEL, in32Gain2Val));
1892             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHB1GAIN2DIV2SEL_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHB1GAIN2DIV2SEL, in32Gain2Div2 ? 1 : 0));
1893             break;
1894 
1895         default:
1896             return AM_HAL_STATUS_INVALID_ARG;
1897     }
1898 
1899     //
1900     // Return the status.
1901     //
1902     return AM_HAL_STATUS_SUCCESS;
1903 }
1904 
1905 //*****************************************************************************
1906 //
1907 //! @brief Turn on reference
1908 //!
1909 //! This function turn on the reference voltage and current.
1910 //!
1911 //! @return status          - generic or interface specific status.
1912 //
1913 //*****************************************************************************
1914 uint32_t
am_hal_audadc_refgen_powerup(void)1915 am_hal_audadc_refgen_powerup(void)
1916 {
1917     //
1918     // Turn on PGA VREFGEN
1919     //
1920     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENPDNB, 1));
1921 
1922     //
1923     // Turn on PGA IREFGEN
1924     //
1925     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAIREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAIREFGENPDNB, 1));
1926 
1927     //
1928     // Turn on PGA VREFGEN Quick Charge
1929     //
1930     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN, 1));
1931 
1932     //
1933     // Delay 4ms
1934     //
1935     am_hal_delay_us(4000);
1936 
1937     //
1938     // Turn off PGA VREFGEN Quick Charge
1939     //
1940     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENQUICKSTARTEN, 0));
1941 
1942     //
1943     // Return the status.
1944     //
1945     return AM_HAL_STATUS_SUCCESS;
1946 }
1947 
1948 //*****************************************************************************
1949 //
1950 //! @brief Turn off reference
1951 //!
1952 //! This function turn off the reference voltage and current.
1953 //!
1954 //! @return status          - generic or interface specific status.
1955 //
1956 //*****************************************************************************
1957 uint32_t
am_hal_audadc_refgen_powerdown(void)1958 am_hal_audadc_refgen_powerdown(void)
1959 {
1960     g_AUDADCPgaChConfigured = 0x0;
1961     //
1962     // Turn on PGA VREFGEN
1963     //
1964     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAVREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAVREFGENPDNB, 0));
1965 
1966     //
1967     // Turn on PGA IREFGEN
1968     //
1969     MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGAIREFGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGAIREFGENPDNB, 0));
1970 
1971     //
1972     // Return the status.
1973     //
1974     return AM_HAL_STATUS_SUCCESS;
1975 }
1976 //*****************************************************************************
1977 //
1978 //! @brief Turn on PGA
1979 //!
1980 //! @param  ui32ChanNum     - PGA ui32ChanNumnel number: 0:A0, 1:A1, 2:B0, 3:B1,
1981 //!
1982 //! This function turn on PGA.
1983 //!
1984 //! @return status          - generic or interface specific status.
1985 //
1986 //*****************************************************************************
1987 uint32_t
am_hal_audadc_pga_powerup(uint32_t ui32ChanNum)1988 am_hal_audadc_pga_powerup(uint32_t ui32ChanNum)
1989 {
1990     //
1991     // turn on quick charge
1992     //
1993     switch (ui32ChanNum)
1994     {
1995         case 0:
1996             g_AUDADCPgaChConfigured |= 0x01;
1997             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 1));
1998             break;
1999 
2000         case 1:
2001             g_AUDADCPgaChConfigured |= 0x02;
2002             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 1));
2003             break;
2004 
2005         case 2:
2006             g_AUDADCPgaChConfigured |= 0x04;
2007             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 1));
2008             break;
2009 
2010         case 3:
2011             g_AUDADCPgaChConfigured |= 0x08;
2012             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB, 1)) | (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 1));
2013             break;
2014 
2015         default:
2016             return AM_HAL_STATUS_INVALID_ARG;
2017     }
2018 
2019     //
2020     // Delay 4ms
2021     //
2022     am_hal_delay_us(4000 + 400);    // +10% for modeling differences
2023 
2024     //
2025     // turn off quick charge
2026     //
2027     switch (ui32ChanNum)
2028     {
2029         case 0:
2030         //
2031         // Turn on ChA VCMGEN & VCM Quick Charge
2032         //
2033 //        MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 1));
2034 //        MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 1));
2035             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 0));
2036             break;
2037 
2038         case 1:
2039             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENQCHARGEEN, 0));
2040             break;
2041 
2042         case 2:
2043             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 0));
2044             break;
2045 
2046         case 3:
2047             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENQCHARGEEN, 0));
2048             break;
2049 
2050         default:
2051             return AM_HAL_STATUS_INVALID_ARG;
2052     }
2053 
2054     //
2055     // Turn on ChA0/ChA1 opamps
2056     //
2057     switch (ui32ChanNum)
2058     {
2059         case 0:
2060             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, 0x1));
2061             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, 0x1));
2062             break;
2063 
2064         case 1:
2065             MCUCTRL->PGACTRL1 |= (_VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, 0x2));
2066             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, 0x2));
2067             break;
2068 
2069         case 2:
2070             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, 0x1));
2071             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, 0x1));
2072             break;
2073 
2074         case 3:
2075             MCUCTRL->PGACTRL2 |= (_VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, 0x2));
2076             MCUCTRL->PGAADCIFCTRL |= (_VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, 0x2));
2077             break;
2078 
2079         default:
2080             return AM_HAL_STATUS_INVALID_ARG;
2081     }
2082 
2083     //
2084     // Return the status.
2085     //
2086     return AM_HAL_STATUS_SUCCESS;
2087 }
2088 
2089 //*****************************************************************************
2090 //
2091 //! @brief Turn off PGA
2092 //!
2093 //! @param  ui32ChanNum     - PGA ui32ChanNumnel number: 0:A0, 1:A1, 2:B0, 3:B1,
2094 //!
2095 //! This function is to turn off PGA.
2096 //!
2097 //! @return status          - generic or interface specific status.
2098 //
2099 //*****************************************************************************
2100 uint32_t
am_hal_audadc_pga_powerdown(uint32_t ui32ChanNum)2101 am_hal_audadc_pga_powerdown(uint32_t ui32ChanNum)
2102 {
2103     switch (ui32ChanNum)
2104     {
2105         case 0:
2106             g_AUDADCPgaChConfigured &= 0xe;
2107             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, g_AUDADCPgaChConfigured & 0x3));
2108             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, g_AUDADCPgaChConfigured & 0x3));
2109             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, g_AUDADCPgaChConfigured & 0x3));
2110             break;
2111 
2112         case 1:
2113             g_AUDADCPgaChConfigured &= 0xd;
2114             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHABYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHABYPASSEN, g_AUDADCPgaChConfigured & 0x3));
2115             MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAOPAMPOUTPDNB, g_AUDADCPgaChConfigured&0x3));
2116             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHAPDNB, g_AUDADCPgaChConfigured & 0x3));
2117             break;
2118 
2119         case 2:
2120             g_AUDADCPgaChConfigured &= 0xb;
2121             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, (g_AUDADCPgaChConfigured & 0xC)>>2));
2122             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, (g_AUDADCPgaChConfigured & 0xC)>>2));
2123             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, (ui32ChanNum & 0xC) >> 2));
2124             break;
2125 
2126         case 3:
2127             g_AUDADCPgaChConfigured &= 0x7;
2128             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBBYPASSEN_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBBYPASSEN, (g_AUDADCPgaChConfigured & 0xC)>>2));
2129             MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBOPAMPOUTPDNB, (g_AUDADCPgaChConfigured & 0xC)>>2));
2130             MCUCTRL->PGAADCIFCTRL = ((MCUCTRL->PGAADCIFCTRL & ~MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB_Msk) | _VAL2FLD(MCUCTRL_PGAADCIFCTRL_PGAADCIFCHBPDNB, (ui32ChanNum & 0xC) >> 2));
2131             break;
2132 
2133         default:
2134             return AM_HAL_STATUS_INVALID_ARG;
2135     }
2136 
2137     //
2138     // Turn off ChA VCM
2139     //
2140     if ((g_AUDADCPgaChConfigured & 0x3) == 0x0)
2141     {
2142         MCUCTRL->PGACTRL1 = ((MCUCTRL->PGACTRL1 & ~MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL1_PGACHAVCMGENPDNB, 0));
2143     }
2144 
2145     //
2146     // Turn off ChB VCM
2147     //
2148     if ((g_AUDADCPgaChConfigured & 0xC) == 0x0)
2149     {
2150         MCUCTRL->PGACTRL2 = ((MCUCTRL->PGACTRL2 & ~MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB_Msk) | _VAL2FLD(MCUCTRL_PGACTRL2_PGACHBVCMGENPDNB, 0));
2151     }
2152 
2153     //
2154     // Return the status.
2155     //
2156     return AM_HAL_STATUS_SUCCESS;
2157 }
2158 
2159 //*****************************************************************************
2160 //
2161 //! @brief Turn on mic bias voltage to power up the mic
2162 //!
2163 //! @param  ui32VolTrim         - The value to set the output voltage
2164 //!
2165 //! This function sets output of the mic bias voltage.
2166 //!
2167 //*****************************************************************************
am_hal_audadc_micbias_powerup(uint32_t ui32VolTrim)2168 void am_hal_audadc_micbias_powerup(uint32_t ui32VolTrim)
2169 {
2170     MCUCTRL->AUDIO1 = ((MCUCTRL->AUDIO1 & ~MCUCTRL_AUDIO1_MICBIASVOLTAGETRIM_Msk) | _VAL2FLD(MCUCTRL_AUDIO1_MICBIASVOLTAGETRIM, ui32VolTrim & 0x3f));
2171     MCUCTRL->AUDIO1 = ((MCUCTRL->AUDIO1 & ~MCUCTRL_AUDIO1_MICBIASPDNB_Msk) | _VAL2FLD(MCUCTRL_AUDIO1_MICBIASPDNB, 1));
2172     //
2173     // take 1ms to power up
2174     //
2175     am_hal_delay_us(1000);
2176 }
2177 
2178 //*****************************************************************************
2179 //
2180 //! @brief Turn off mic bias voltage to power off the mic
2181 //!
2182 //! This function turns off the mic bias voltage.
2183 //!
2184 //*****************************************************************************
am_hal_audadc_micbias_powerdown(void)2185 void am_hal_audadc_micbias_powerdown(void)
2186 {
2187     MCUCTRL->AUDIO1 = ((MCUCTRL->AUDIO1 & ~MCUCTRL_AUDIO1_MICBIASPDNB_Msk) | _VAL2FLD(MCUCTRL_AUDIO1_MICBIASPDNB, 0));
2188 }
2189 
2190 //*****************************************************************************
2191 //
2192 //! @brief Config internal PGA.
2193 //!
2194 //! @param pHandle      - handle for the interface.
2195 //! @param psGainConfig - pointer to the AUDADC Gain Config
2196 //!
2197 //! This function configures the AUADC Pre-Amplifier Gain.
2198 //!
2199 //! @return status          - generic or interface specific status.
2200 //!
2201 //*****************************************************************************
am_hal_audadc_internal_pga_config(void * pHandle,am_hal_audadc_gain_config_t * psGainConfig)2202 uint32_t am_hal_audadc_internal_pga_config(void *pHandle, am_hal_audadc_gain_config_t* psGainConfig)
2203 {
2204     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
2205     uint32_t ui32Module = pAUDADCState->ui32Module;
2206 
2207 #ifndef AM_HAL_DISABLE_API_VALIDATION
2208     //
2209     // Check the handle.
2210     //
2211     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
2212     {
2213         return AM_HAL_STATUS_INVALID_HANDLE;
2214     }
2215 #endif // AM_HAL_DISABLE_API_VALIDATION
2216 
2217     //
2218     // Set the AUDADC gain codes.
2219     //
2220     AUDADCn(ui32Module)->GAIN =
2221          _VAL2FLD(AUDADC_GAIN_LGA, psGainConfig->ui32LGA)            |
2222          _VAL2FLD(AUDADC_GAIN_HGADELTA, psGainConfig->ui32HGADELTA)  |
2223          _VAL2FLD(AUDADC_GAIN_LGB, psGainConfig->ui32LGB)            |
2224          _VAL2FLD(AUDADC_GAIN_HGBDELTA, psGainConfig->ui32HGBDELTA);
2225 
2226     //
2227     // PGA Gain Configuration
2228     //
2229     AUDADCn(ui32Module)->GAINCFG = _VAL2FLD(AUDADC_GAINCFG_UPDATEMODE, psGainConfig->eUpdateMode) |
2230                                    _VAL2FLD(AUDADC_GAINCFG_PGACTRLEN, 1);
2231 
2232     //
2233     // Return the status.
2234     //
2235     return AM_HAL_STATUS_SUCCESS;
2236 }
2237 
2238 //*****************************************************************************
2239 //
2240 //! @brief Config Saturation Comparator.
2241 //!
2242 //! @param pHandle     - handle for the interface.
2243 //! @param psSATConfig - pointer to the AUDADC Saturation Config
2244 //!
2245 //! This function configures the Saturation Comparator.
2246 //!
2247 //! @return status          - generic or interface specific status.
2248 //!
2249 //*****************************************************************************
am_hal_audadc_saturation_config(void * pHandle,am_hal_audadc_sat_config_t * psSATConfig)2250 uint32_t am_hal_audadc_saturation_config(void *pHandle, am_hal_audadc_sat_config_t* psSATConfig)
2251 {
2252     am_hal_audadc_state_t  *pAUDADCState = (am_hal_audadc_state_t *)pHandle;
2253     uint32_t ui32Module = pAUDADCState->ui32Module;
2254 
2255 #ifndef AM_HAL_DISABLE_API_VALIDATION
2256     //
2257     // Check the handle.
2258     //
2259     if ( !AM_HAL_AUDADC_CHK_HANDLE(pHandle) )
2260     {
2261         return AM_HAL_STATUS_INVALID_HANDLE;
2262     }
2263 #endif // AM_HAL_DISABLE_API_VALIDATION
2264 
2265     AUDADCn(ui32Module)->SATLIM = 0;
2266 
2267     AUDADCn(ui32Module)->SATMAX = 0;
2268 
2269     //
2270     // Saturation Comparator Configuration
2271     //
2272     AUDADCn(ui32Module)->SATCFG = _VAL2FLD(AUDADC_SATCFG_SATCHANSEL, psSATConfig->ui32ChanSel) |
2273                                   _VAL2FLD(AUDADC_SATCFG_SATEN, 1);
2274 
2275     //
2276     // Return the status.
2277     //
2278     return AM_HAL_STATUS_SUCCESS;
2279 }
2280 
2281 //*****************************************************************************
2282 //
2283 // End Doxygen group.
2284 //! @}
2285 //
2286 //*****************************************************************************
2287