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