1 /***************************************************************************//**
2 * \file cy_adcmic.c
3 * \version 1.10
4 *
5 * Provides an API implementation of the ADCMic driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2022 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 *     http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24 
25 #include "cy_device.h"
26 
27 #if defined (CY_IP_MXS40ADCMIC)
28 
29 #include "cy_adcmic.h"
30 
31 /** \cond */
32 #define CY_ADCMIC_MIC_16      ((uint32_t)CY_ADCMIC_MIC)
33 #define CY_ADCMIC_PDM_16      ((uint32_t)CY_ADCMIC_PDM)
34 #define CY_ADCMIC_SR8M        (2UL) /* The sample rate 8ksps modifier */
35 #define CY_ADCMIC_MIC_8       ((uint32_t)CY_ADCMIC_MIC + CY_ADCMIC_SR8M)
36 #define CY_ADCMIC_PDM_8       ((uint32_t)CY_ADCMIC_PDM + CY_ADCMIC_SR8M)
37 
38 #define CY_ADCMIC_PD_DC       (MXS40ADCMIC_ADC_PD_CTRL_ADC_EN_VBAT_Msk | \
39                                MXS40ADCMIC_ADC_PD_CTRL_ADC_PWRUP_Msk | \
40                                MXS40ADCMIC_ADC_PD_CTRL_ADC_REF_PWRUP_Msk | \
41                                MXS40ADCMIC_ADC_PD_CTRL_ADC_CORE_PWRUP_Msk)
42 
43 #define CY_ADCMIC_PD_MIC      (CY_ADCMIC_PD_DC | \
44                                MXS40ADCMIC_ADC_PD_CTRL_MIC_PWRUP_Msk | \
45                                MXS40ADCMIC_ADC_PD_CTRL_MICBIAS_PWRUP_Msk | \
46                                MXS40ADCMIC_ADC_PD_CTRL_ADC_MODE_Msk)
47 
48 #define MXS40ADCMIC_ADCMIC_CTRL_ADC_DIV_RATIO_2             (0x02UL << MXS40ADCMIC_ADCMIC_CTRL_ADC_DIV_RATIO_Pos)   /* Default adc_div_ratio value */
49 #define MXS40ADCMIC_ADCMIC_CTRL_PDM_DIV_RATIO_10            (0x0AUL << MXS40ADCMIC_ADCMIC_CTRL_PDM_DIV_RATIO_Pos)   /* Default pdm_div_ratio value */
50 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_OFF         (0x00UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_Pos) /* No clocks selected - clock is gated off */
51 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_DIV     (0x01UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_Pos) /* clk_adc from local clk_divider is selected */
52 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_DIV_INV (0x02UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_Pos) /* Inverted clk_adc from local clk_divider is selected */
53 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_ADC     (0x04UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_Pos) /* clk_adc received from adc is used */
54 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_ADC_INV (0x08UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_Pos) /* Inverted clk_adc received from adc is used */
55 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_PDM     (0x10UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_Pos) /* clk_pdm_int is used as clk_adc */
56 
57 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_OFF         (0x0UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_Pos) /* No clocks selected - clock is gated off */
58 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_DIV     (0x1UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_Pos) /* clk_pdm from local clk_divider is selected for external clk_pdm */
59 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_DIV_INV (0x2UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_Pos) /* Inverted clk_pdm from local clk_divider is selected for external clk_pdm */
60 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_ADC     (0x4UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_Pos) /* clk_pdm from local clk_divider is selected as internal clk_adc to latch pdm_data */
61 #define MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_ADC_INV (0x8UL << MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_Pos) /* Inverted clk_pdm from local clk_divider is selected as internal clk_adc to latch pdm_data */
62 
63 #define MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_HF              (0x1UL << MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_Pos) /* Controls clk_hf clock gate */
64 #define MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_ADC             (0x2UL << MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_Pos) /* Controls the clk_adc_syn from the ADC block */
65 
66 #define CY_ADCMIC_MODE_VALID(mode)  ((CY_ADCMIC_DC  == (mode)) || \
67                                      (CY_ADCMIC_MIC == (mode)) || \
68                                      (CY_ADCMIC_PDM == (mode)))
69 
70 #define CY_ADCMIC_SAMPLE_RATE_VALID(sr) ((CY_ADCMIC_8KSPS   == (sr)) || \
71                                          (CY_ADCMIC_16KSPS  == (sr)))
72 
73 #define CY_ADCMIC_DC_CHAN_VALID(dc)     ((CY_ADCMIC_REFGND == (dc)) || \
74                                          (CY_ADCMIC_BGREF  == (dc)) || \
75                                          (CY_ADCMIC_VDDC   == (dc)) || \
76                                          (CY_ADCMIC_VDDIO  == (dc)) || \
77                                          (CY_ADCMIC_GPIO7  == (dc)) || \
78                                          (CY_ADCMIC_GPIO6  == (dc)) || \
79                                          (CY_ADCMIC_GPIO5  == (dc)) || \
80                                          (CY_ADCMIC_GPIO4  == (dc)) || \
81                                          (CY_ADCMIC_GPIO3  == (dc)) || \
82                                          (CY_ADCMIC_GPIO2  == (dc)) || \
83                                          (CY_ADCMIC_GPIO1  == (dc)) || \
84                                          (CY_ADCMIC_GPIO0  == (dc)))
85 
86 #define CY_ADCMIC_RETMODE_VALID(retMode) ((CY_ADCMIC_RETURN_STATUS   == (retMode)) || \
87                                           (CY_ADCMIC_WAIT_FOR_RESULT == (retMode)))
88 
89 #define CY_ADCMIC_DC_RANGE(base) (_FLD2BOOL(MXS40ADCMIC_ADC_CORE_CTRL_ADC_DCINPUT_RANGE, (base)->ADC_CORE_CTRL) ? CY_ADCMIC_DC_RANGE_1_8V : CY_ADCMIC_DC_RANGE_3_6V)
90 #define CY_ADCMIC_DC_GAIN(base)  ((CY_ADCMIC_DC_RANGE_3_6V == CY_ADCMIC_DC_RANGE(base)) ? CY_ADCMIC_DC_3_6_GAIN : CY_ADCMIC_DC_1_8_GAIN)
91 #define CY_ADCMIC_INST(base)     ((CY_IP_MXS40ADCMIC_INSTANCES == 1U) ? 0U : (MXS40ADCMIC0 == (base)) ? 0U : 1U)
92 #define CY_ADCMIC_MV  (1000L)      /* 1 Volt in millivolts */
93 #define CY_ADCMIC_UV  (1000000L)   /* 1 Volt in microvolts */
94 /** \endcond */
95 
Cy_ADCMic_Init(MXS40ADCMIC_Type * base,cy_stc_adcmic_config_t const * config,cy_en_adcmic_mode_t mode)96 cy_en_adcmic_status_t Cy_ADCMic_Init(MXS40ADCMIC_Type * base, cy_stc_adcmic_config_t const * config, cy_en_adcmic_mode_t mode)
97 {
98     cy_en_adcmic_status_t retVal = CY_ADCMIC_BAD_PARAM;
99 
100     if ((NULL != base) &&
101         (NULL != config) &&
102         CY_ADCMIC_MODE_VALID(mode))
103     {
104         base->ADCMIC_PAD_CTRL = 0UL;
105         base->ADC_PD_CTRL = 0UL;
106         CY_REG32_CLR_SET(base->AUXADC_CTRL, MXS40ADCMIC_AUXADC_CTRL_DFMODE, mode);
107 
108         switch (mode)
109         {
110             case CY_ADCMIC_MIC:
111                 if (NULL != config->micConfig)
112                 {
113                     cy_stc_adcmic_mic_config_t const * locMicCgf = config->micConfig;
114 
115                     base->ADCMIC_CTRL = MXS40ADCMIC_ADCMIC_CTRL_ADC_DIV_RATIO_2 |
116                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_ADC |
117                                         MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_ADC |
118                                         MXS40ADCMIC_ADCMIC_CTRL_ADC_RESET_Msk |
119                                         MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_HF |
120                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_DIV |
121                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_ADC;
122                     base->ADC_MIC_BIAS_PGA_CTRL = _VAL2FLD(MXS40ADCMIC_ADC_MIC_BIAS_PGA_CTRL_MIC_BIAS_CTRL, locMicCgf->micBias) |
123                                                  _BOOL2FLD(MXS40ADCMIC_ADC_MIC_BIAS_PGA_CTRL_MIC_BIAS_LZ, locMicCgf->micBiasLz) |
124                                                   _VAL2FLD(MXS40ADCMIC_ADC_MIC_BIAS_PGA_CTRL_MIC_PGA_GAIN_CTRL, locMicCgf->pgaGain) |
125                                                   _VAL2FLD(MXS40ADCMIC_ADC_MIC_BIAS_PGA_CTRL_MIC_PGA_INCM_CTRL, locMicCgf->pgaInCm) |
126                                                   _VAL2FLD(MXS40ADCMIC_ADC_MIC_BIAS_PGA_CTRL_MIC_PGA_OUTCM_CTRL, locMicCgf->pgaOutCm);
127                     base->ADC_PD_CTRL = _BOOL2FLD(MXS40ADCMIC_ADC_PD_CTRL_MIC_CLAMP_EN, locMicCgf->micClamp);
128                     base->AUXADC_CIC_STATUS = 0UL;
129                     base->ADCMIC_TRIGGER_MASK = _BOOL2FLD(MXS40ADCMIC_ADCMIC_TRIGGER_TR_DATA, locMicCgf->fifoTrigger);
130                     base->ADCMIC_FIFO_CTRL = MXS40ADCMIC_ADCMIC_FIFO_CTRL_FIFO_RESET_Msk |
131                                     _VAL2FLD(MXS40ADCMIC_ADCMIC_FIFO_CTRL_PGMBLE_FULL,  locMicCgf->fifoFull) |
132                                     _VAL2FLD(MXS40ADCMIC_ADCMIC_FIFO_CTRL_PGMBLE_EMPTY, locMicCgf->fifoEmpty);
133                     base->ADC_CLK_CTRL = MXS40ADCMIC_ADC_CLK_CTRL_ADC_CLK_GATE_EN_Msk;
134 
135                     if (NULL != locMicCgf->biQuadConfig)
136                     {
137                         Cy_ADCMic_InitBiquad(base, locMicCgf->biQuadConfig);
138                         Cy_ADCMic_BiquadBypass(base, false); /* Unbypass the biquad filter */
139                     }
140                     else
141                     {
142                         Cy_ADCMic_BiquadBypass(base, true); /* Bypass the biquad filter */
143                     }
144 
145                     retVal = Cy_ADCMic_SetSampleRate(base, locMicCgf->sampleRate);
146                 }
147                 break;
148 
149             case CY_ADCMIC_PDM:
150                 if (NULL != config->pdmConfig)
151                 {
152                     cy_stc_adcmic_pdm_config_t const * locPdmCgf = config->pdmConfig;
153 
154                     base->ADCMIC_CTRL = MXS40ADCMIC_ADCMIC_CTRL_ADC_DIV_RATIO_2 |
155                                         MXS40ADCMIC_ADCMIC_CTRL_PDM_DIV_RATIO_10 |
156                               _BOOL2FLD(MXS40ADCMIC_ADCMIC_CTRL_PDM_LATCH_NEG_EDGE, locPdmCgf->clockInv) |
157                                _VAL2FLD(MXS40ADCMIC_ADCMIC_CTRL_PDM_LATCH_DELAY,    locPdmCgf->latchDelay) |
158                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_DIV |
159                                         MXS40ADCMIC_ADCMIC_CTRL_ADC_RESET_Msk |
160                                         MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_HF |
161                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_DIV |
162                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_ADC;
163                     base->AUXADC_CIC_STATUS = 0UL;
164                     base->ADCMIC_TRIGGER_MASK = _BOOL2FLD(MXS40ADCMIC_ADCMIC_TRIGGER_TR_DATA, locPdmCgf->fifoTrigger);
165                     base->ADCMIC_FIFO_CTRL = MXS40ADCMIC_ADCMIC_FIFO_CTRL_FIFO_RESET_Msk |
166                                     _VAL2FLD(MXS40ADCMIC_ADCMIC_FIFO_CTRL_PGMBLE_FULL,  locPdmCgf->fifoFull) |
167                                     _VAL2FLD(MXS40ADCMIC_ADCMIC_FIFO_CTRL_PGMBLE_EMPTY, locPdmCgf->fifoEmpty);
168                     base->ADC_CLK_CTRL = 0UL;
169                     base->ADCMIC_PAD_CTRL = MXS40ADCMIC_ADCMIC_PAD_CTRL_CLK_PDM_OE_Msk;
170 
171                     if (NULL != locPdmCgf->biQuadConfig)
172                     {
173                         Cy_ADCMic_InitBiquad(base, locPdmCgf->biQuadConfig);
174                         Cy_ADCMic_BiquadBypass(base, false); /* Unbypass the biquad filter */
175                     }
176                     else
177                     {
178                         Cy_ADCMic_BiquadBypass(base, true); /* Bypass the biquad filter */
179                     }
180 
181                     retVal = Cy_ADCMic_SetSampleRate(base, locPdmCgf->sampleRate);
182                 }
183                 break;
184 
185             default: /* CY_ADCMIC_DC */
186                 if (NULL != config->dcConfig)
187                 {
188                     cy_stc_adcmic_dc_config_t const * locDcCgf = config->dcConfig;
189 
190                     base->ADCMIC_CTRL = MXS40ADCMIC_ADCMIC_CTRL_ADC_DIV_RATIO_2 |
191                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_ADC_CLK_ADC |
192                                         MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_ADC |
193                                         MXS40ADCMIC_ADCMIC_CTRL_ADC_RESET_Msk |
194                                         MXS40ADCMIC_ADCMIC_CTRL_CLK_GATE_EN_HF |
195                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_DIV |
196                                         MXS40ADCMIC_ADCMIC_CTRL_CLKS_ACTIVE_PDM_CLK_ADC;
197                     base->ADC_CORE_CTRL = _VAL2FLD(MXS40ADCMIC_ADC_CORE_CTRL_ADC_DCINPUT_RANGE, locDcCgf->range);
198                     base->ADC_GPIO_CTRL = _VAL2FLD(MXS40ADCMIC_ADC_GPIO_CTRL_ADC_DCIN_MUX, locDcCgf->channel);
199 
200                     base->AUXADC_CIC_STATUS = MXS40ADCMIC_AUXADC_CIC_STATUS_LATCH_ON_TIMER_Msk;
201                     base->ADCMIC_TRIGGER_MASK = MXS40ADCMIC_ADCMIC_TRIGGER_TR_DC_Msk;
202                     base->ADCMIC_FIFO_CTRL &= ~MXS40ADCMIC_ADCMIC_FIFO_CTRL_FIFO_RESET_Msk;
203                     base->ADCMIC_TRIG_INTRPT_TIMER_CTRL = MXS40ADCMIC_ADCMIC_TRIG_INTRPT_TIMER_CTRL_TIMER_CLR_Msk |
204                                                  _VAL2FLD(MXS40ADCMIC_ADCMIC_TRIG_INTRPT_TIMER_CTRL_TIMER_LIMIT, locDcCgf->timerPeriod) |
205                                                  _VAL2FLD(MXS40ADCMIC_ADCMIC_TRIG_INTRPT_TIMER_CTRL_TIMER_INC,   locDcCgf->timerInput);
206                     base->ADC_CLK_CTRL = MXS40ADCMIC_ADC_CLK_CTRL_ADC_CLK_GATE_EN_Msk;
207 
208                     Cy_ADCMic_SetDcOffset(CY_ADCMIC_DC_OFFSET, locDcCgf->context);
209                     Cy_ADCMic_SetDcGain(CY_ADCMIC_DC_GAIN(base), locDcCgf->context);
210 
211                     retVal = CY_ADCMIC_SUCCESS;
212                 }
213                 break;
214         }
215 
216         if (CY_ADCMIC_SUCCESS == retVal)
217         {
218 
219         }
220     }
221 
222     return (retVal);
223 }
224 
Cy_ADCMic_InitBiquad(MXS40ADCMIC_Type * base,cy_stc_adcmic_biquad_config_t const * biQuadConfig)225 void Cy_ADCMic_InitBiquad(MXS40ADCMIC_Type * base, cy_stc_adcmic_biquad_config_t const * biQuadConfig)
226 {
227     base->AUXADC_BIQUAD0_COEFF_0 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD0_COEFF_0_BQ0_NUM1_COEFF, biQuadConfig->bq0_num1_coeff) |
228                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD0_COEFF_0_BQ0_NUM2_COEFF, biQuadConfig->bq0_num2_coeff);
229     base->AUXADC_BIQUAD0_COEFF_1 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD0_COEFF_1_BQ0_NUM3_COEFF, biQuadConfig->bq0_num3_coeff);
230     base->AUXADC_BIQUAD0_COEFF_2 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD0_COEFF_2_BQ0_DEN2_COEFF, biQuadConfig->bq0_den2_coeff) |
231                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD0_COEFF_2_BQ0_DEN3_COEFF, biQuadConfig->bq0_den3_coeff);
232     base->AUXADC_BIQUAD1_COEFF_0 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD1_COEFF_0_BQ1_NUM1_COEFF, biQuadConfig->bq1_num1_coeff) |
233                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD1_COEFF_0_BQ1_NUM2_COEFF, biQuadConfig->bq1_num2_coeff);
234     base->AUXADC_BIQUAD1_COEFF_1 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD1_COEFF_1_BQ1_NUM3_COEFF, biQuadConfig->bq1_num3_coeff);
235     base->AUXADC_BIQUAD1_COEFF_2 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD1_COEFF_2_BQ1_DEN2_COEFF, biQuadConfig->bq1_den2_coeff) |
236                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD1_COEFF_2_BQ1_DEN3_COEFF, biQuadConfig->bq1_den3_coeff);
237     base->AUXADC_BIQUAD2_COEFF_0 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD2_COEFF_0_BQ2_NUM1_COEFF, biQuadConfig->bq2_num1_coeff) |
238                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD2_COEFF_0_BQ2_NUM2_COEFF, biQuadConfig->bq2_num2_coeff);
239     base->AUXADC_BIQUAD2_COEFF_1 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD2_COEFF_1_BQ2_NUM3_COEFF, biQuadConfig->bq2_num3_coeff);
240     base->AUXADC_BIQUAD2_COEFF_2 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD2_COEFF_2_BQ2_DEN2_COEFF, biQuadConfig->bq2_den2_coeff) |
241                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD2_COEFF_2_BQ2_DEN3_COEFF, biQuadConfig->bq2_den3_coeff);
242     base->AUXADC_BIQUAD3_COEFF_0 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD3_COEFF_0_BQ3_NUM1_COEFF, biQuadConfig->bq3_num1_coeff) |
243                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD3_COEFF_0_BQ3_NUM2_COEFF, biQuadConfig->bq3_num2_coeff);
244     base->AUXADC_BIQUAD3_COEFF_1 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD3_COEFF_1_BQ3_NUM3_COEFF, biQuadConfig->bq3_num3_coeff);
245     base->AUXADC_BIQUAD3_COEFF_2 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD3_COEFF_2_BQ3_DEN2_COEFF, biQuadConfig->bq3_den2_coeff) |
246                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD3_COEFF_2_BQ3_DEN3_COEFF, biQuadConfig->bq3_den3_coeff);
247     base->AUXADC_BIQUAD4_COEFF_0 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD4_COEFF_0_BQ4_NUM1_COEFF, biQuadConfig->bq4_num1_coeff) |
248                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD4_COEFF_0_BQ4_NUM2_COEFF, biQuadConfig->bq4_num2_coeff);
249     base->AUXADC_BIQUAD4_COEFF_1 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD4_COEFF_1_BQ4_NUM3_COEFF, biQuadConfig->bq4_num3_coeff);
250     base->AUXADC_BIQUAD4_COEFF_2 = _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD4_COEFF_2_BQ4_DEN2_COEFF, biQuadConfig->bq4_den2_coeff) |
251                                    _VAL2FLD(MXS40ADCMIC_AUXADC_BIQUAD4_COEFF_2_BQ4_DEN3_COEFF, biQuadConfig->bq4_den3_coeff);
252 }
253 
Cy_ADCMic_IsEndConversion(MXS40ADCMIC_Type * base,cy_en_adcmic_return_mode_t retMode)254 cy_en_adcmic_status_t Cy_ADCMic_IsEndConversion(MXS40ADCMIC_Type * base, cy_en_adcmic_return_mode_t retMode)
255 {
256     CY_ASSERT_L3(CY_ADCMIC_RETMODE_VALID(retMode));
257 
258     cy_en_adcmic_status_t result;
259 
260     uint32_t wdt = 0x1555555UL; /* Watchdog timer for blocking while loop */
261     uint32_t mask = CY_ADCMIC_INTR_DC;
262     uint32_t intr = mask & Cy_ADCMic_GetInterruptStatus(base);
263 
264     if (CY_ADCMIC_WAIT_FOR_RESULT == retMode)
265     {
266         while ((0UL == intr) && (0UL != wdt))
267         {
268             intr = mask & Cy_ADCMic_GetInterruptStatus(base);
269             wdt--;
270         }
271     }
272 
273     /* Clear the EOS bit */
274     if (mask == intr)
275     {
276         result = CY_ADCMIC_SUCCESS;
277         Cy_ADCMic_ClearInterrupt(base, mask);
278     }
279     else if (0UL == wdt)
280     {
281         result = CY_ADCMIC_TIMEOUT;
282     }
283     else
284     {
285         result = CY_ADCMIC_CONVERSION_NOT_COMPLETE;
286     }
287 
288     return result;
289 }
290 
Cy_ADCMic_EnableInterrupt(MXS40ADCMIC_Type * base,uint32_t intrMask)291 void Cy_ADCMic_EnableInterrupt(MXS40ADCMIC_Type * base, uint32_t intrMask)
292 {
293     uint32_t interruptState = Cy_SysLib_EnterCriticalSection();
294     Cy_ADCMic_SetInterruptMask(base, (intrMask & CY_ADCMIC_INTR) | Cy_ADCMic_GetInterruptMask(base));
295     Cy_SysLib_ExitCriticalSection(interruptState);
296 }
297 
Cy_ADCMic_DisableInterrupt(MXS40ADCMIC_Type * base,uint32_t intrMask)298 void Cy_ADCMic_DisableInterrupt(MXS40ADCMIC_Type * base, uint32_t intrMask)
299 {
300     uint32_t interruptState = Cy_SysLib_EnterCriticalSection();
301     Cy_ADCMic_SetInterruptMask(base, (~intrMask & CY_ADCMIC_INTR) & Cy_ADCMic_GetInterruptMask(base));
302     Cy_SysLib_ExitCriticalSection(interruptState);
303 }
304 
Cy_ADCMic_SetPgaGain(MXS40ADCMIC_Type * base,cy_en_adcmic_pga_gain_t gain)305 cy_en_adcmic_status_t Cy_ADCMic_SetPgaGain(MXS40ADCMIC_Type *  base, cy_en_adcmic_pga_gain_t gain)
306 {
307     cy_en_adcmic_status_t retVal = CY_ADCMIC_BAD_PARAM;
308 
309     if ((uint32_t)CY_ADCMIC_PGA_GAIN_42 >= (uint32_t)gain)
310     {
311         CY_REG32_CLR_SET(base->ADC_MIC_BIAS_PGA_CTRL, MXS40ADCMIC_ADC_MIC_BIAS_PGA_CTRL_MIC_PGA_GAIN_CTRL, gain);
312         retVal = CY_ADCMIC_SUCCESS;
313     }
314 
315     return (retVal);
316 }
317 
Cy_ADCMic_Enable(MXS40ADCMIC_Type * base)318 void Cy_ADCMic_Enable (MXS40ADCMIC_Type * base)
319 {
320     uint32_t locDfMode = _FLD2VAL(MXS40ADCMIC_AUXADC_CTRL_DFMODE, base->AUXADC_CTRL);
321 
322     base->ADC_PD_CTRL &= MXS40ADCMIC_ADC_PD_CTRL_MIC_CLAMP_EN_Msk; /* Clear all except clamp to save its value */
323 
324     if ((uint32_t)CY_ADCMIC_DC == locDfMode)
325     {
326         base->ADC_PD_CTRL |= CY_ADCMIC_PD_DC;
327     }
328     else if (((uint32_t)CY_ADCMIC_MIC_8  == locDfMode) ||
329              ((uint32_t)CY_ADCMIC_MIC_16 == locDfMode))
330     {
331         base->ADC_PD_CTRL |= CY_ADCMIC_PD_MIC;
332     }
333     else /* PDM */
334     {
335         /* Do nothing */
336     }
337 
338     base->ADCMIC_CTRL |= MXS40ADCMIC_ADCMIC_CTRL_ADCMIC_EN_Msk;
339     base->AUXADC_CTRL |= MXS40ADCMIC_AUXADC_CTRL_EN_Msk;
340 }
341 
Cy_ADCMic_Disable(MXS40ADCMIC_Type * base)342 void Cy_ADCMic_Disable(MXS40ADCMIC_Type * base)
343 {
344     base->AUXADC_CTRL &= ~MXS40ADCMIC_AUXADC_CTRL_EN_Msk;
345     base->ADCMIC_CTRL &= ~MXS40ADCMIC_ADCMIC_CTRL_ADCMIC_EN_Msk;
346     base->ADC_PD_CTRL &=  MXS40ADCMIC_ADC_PD_CTRL_MIC_CLAMP_EN_Msk; /* Clear all except clamp to save its value */
347 }
348 
Cy_ADCMic_SetSampleRate(MXS40ADCMIC_Type * base,cy_en_adcmic_sample_rate_t sampleRate)349 cy_en_adcmic_status_t Cy_ADCMic_SetSampleRate(MXS40ADCMIC_Type * base, cy_en_adcmic_sample_rate_t sampleRate)
350 {
351     cy_en_adcmic_status_t retVal = CY_ADCMIC_BAD_PARAM;
352 
353     if (CY_ADCMIC_SAMPLE_RATE_VALID(sampleRate))
354     {
355         uint32_t locDfMode = _FLD2VAL(MXS40ADCMIC_AUXADC_CTRL_DFMODE, base->AUXADC_CTRL);
356 
357         if (CY_ADCMIC_MIC_16 <= locDfMode)
358         {
359             if (CY_ADCMIC_8KSPS == sampleRate)
360             {
361                 locDfMode += CY_ADCMIC_SR8M;
362             }
363 
364             CY_REG32_CLR_SET(base->AUXADC_CTRL, MXS40ADCMIC_AUXADC_CTRL_DFMODE, locDfMode);
365             retVal = CY_ADCMIC_SUCCESS;
366         }
367     }
368 
369     return (retVal);
370 }
371 
Cy_ADCMic_ReadFifoAll(MXS40ADCMIC_Type const * base,uint16_t * data)372 uint8_t Cy_ADCMic_ReadFifoAll(MXS40ADCMIC_Type const * base, uint16_t * data)
373 {
374     uint8_t retVal = 0U; /* data counter */
375     uint8_t locStatus = Cy_ADCMic_GetFifoStatus(base);
376     while (0U == (CY_ADCMIC_FIFO_EMPTY & locStatus))
377     {
378         uint32_t locData = Cy_ADCMic_ReadFifo(base);
379         data[retVal++] = (uint16_t)_FLD2VAL(CY_ADCMIC_FIFO_FIRST_SAMPLE, locData);
380         data[retVal++] = (uint16_t)_FLD2VAL(CY_ADCMIC_FIFO_SECOND_SAMPLE, locData);
381         locStatus = Cy_ADCMic_GetFifoStatus(base);
382     }
383     return (retVal);
384 }
385 
Cy_ADCMic_SelectDcChannel(MXS40ADCMIC_Type * base,cy_en_adcmic_dc_channel_t channel)386 void Cy_ADCMic_SelectDcChannel(MXS40ADCMIC_Type * base, cy_en_adcmic_dc_channel_t channel)
387 {
388     CY_ASSERT_L3(CY_ADCMIC_DC_CHAN_VALID(channel));
389     CY_REG32_CLR_SET(base->ADC_GPIO_CTRL, MXS40ADCMIC_ADC_GPIO_CTRL_ADC_DCIN_MUX, channel);
390 }
391 
392 
393 /* DC voltage calculation / calibration */
Cy_ADCMic_SetDcOffset(int16_t offset,cy_stc_adcmic_context_t * context)394 void Cy_ADCMic_SetDcOffset(int16_t offset, cy_stc_adcmic_context_t * context)
395 {
396     if (NULL != context)
397     {
398         context->offset = offset;
399     }
400 }
401 
Cy_ADCMic_SetDcGain(int16_t gain,cy_stc_adcmic_context_t * context)402 void Cy_ADCMic_SetDcGain(int16_t gain, cy_stc_adcmic_context_t * context)
403 {
404     if (NULL != context)
405     {
406         context->gain = gain;
407     }
408 }
409 
Cy_ADCMic_CountsTo_uVolts(int16_t adcCounts,cy_stc_adcmic_context_t const * context)410 int32_t Cy_ADCMic_CountsTo_uVolts(int16_t adcCounts, cy_stc_adcmic_context_t const * context)
411 {
412     return ((int32_t)(((int64_t)adcCounts - (int64_t)context->offset) * CY_ADCMIC_UV / (int64_t)context->gain));
413 }
414 
Cy_ADCMic_CountsTo_mVolts(int16_t adcCounts,cy_stc_adcmic_context_t const * context)415 int16_t Cy_ADCMic_CountsTo_mVolts(int16_t adcCounts, cy_stc_adcmic_context_t const * context)
416 {
417     return ((int16_t)(((int32_t)adcCounts - (int32_t)context->offset) * CY_ADCMIC_MV / (int32_t)context->gain));
418 }
419 
Cy_ADCMic_CountsTo_Volts(int16_t adcCounts,cy_stc_adcmic_context_t const * context)420 float Cy_ADCMic_CountsTo_Volts (int16_t adcCounts, cy_stc_adcmic_context_t const * context)
421 {
422     return (((float)adcCounts - (float)context->offset) / (float)context->gain);
423 }
424 
425 #endif /* CY_IP_MXS40ADCMIC */
426