1 /***************************************************************************//**
2 * \file cy_pdm_pcm_v2.c
3 * \version 1.10
4 *
5 * The source code file for the PDM_PCM driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2019-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_MXPDM)
28 
29 #include "cy_pdm_pcm_v2.h"
30 
31 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 14.3', 14, \
32 'Checked manually, passed 1 or 0 in _BOOL2FLD for appropriate functionality.')
33 
34 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.1', 1, \
35 'Checked manually, passed 1 or 0 in _BOOL2FLD for appropriate functionality.')
36 
37 /**
38 * \addtogroup group_pdm_pcm_functions_v2
39 * \{
40 */
41 
42 /******************************************************************************
43 * Function Name: Cy_PDM_PCM_Channel_Init
44 ***************************************************************************//**
45 *
46 * Initialize the PDM-PCM Channel
47 *
48 * \pre Make sure PDM-PCM is intialized before calling this function. \ref Cy_PDM_PCM_Init
49 *
50 * \param  base The pointer to the PDM-PCM instance address
51 * \param  channel_config The pointer to a configuration structure.
52 * \param  channel_num The channel number to be initialized.
53 * \return error / status code. See \ref cy_en_pdm_pcm_status_t.
54 *
55 * \funcusage
56 * \snippet pdm_pcmv2/snippet/main.c snippet_Cy_PDM_PCM_Channel_Init
57 *
58 *******************************************************************************/
Cy_PDM_PCM_Channel_Init(PDM_Type * base,cy_stc_pdm_pcm_channel_config_t const * channel_config,uint8_t channel_num)59 cy_en_pdm_pcm_status_t Cy_PDM_PCM_Channel_Init(PDM_Type * base, cy_stc_pdm_pcm_channel_config_t const * channel_config, uint8_t channel_num)
60 {
61     cy_en_pdm_pcm_status_t ret = CY_PDM_PCM_BAD_PARAM;
62 
63     if((NULL != base) && (NULL != channel_config))
64     {
65         CY_ASSERT_L2(CY_PDM_PCM_IS_WORD_SIZE_VALID(channel_config->wordSize));
66         CY_ASSERT_L2(CY_PDM_PCM_IS_SIGNEXTENSION_VALID(channel_config->signExtension));
67         CY_ASSERT_L2(CY_PDM_PCM_IS_TRIG_LEVEL(channel_config->rxFifoTriggerLevel));
68         CY_ASSERT_L2(CY_PDM_PCM_IS_SCALE_VALID(channel_config->fir0_scale));
69         CY_ASSERT_L2(CY_PDM_PCM_IS_SCALE_VALID(channel_config->fir1_scale));
70 
71 
72         ret = CY_PDM_PCM_SUCCESS;
73 
74 
75         PDM_PCM_RX_FIFO_CTL(base, channel_num) = _VAL2FLD(PDM_CH_RX_FIFO_CTL_TRIGGER_LEVEL, channel_config->rxFifoTriggerLevel);
76 
77 
78         PDM_PCM_CH_CTL(base, channel_num) = _VAL2FLD(PDM_CH_CTL_WORD_SIZE, channel_config->wordSize) |
79                                   _BOOL2FLD(PDM_CH_CTL_WORD_SIGN_EXTEND, channel_config->signExtension) |
80                                   _BOOL2FLD(PDM_CH_CTL_ENABLED, CY_PDM_PCM_ENABLE);
81 
82         PDM_PCM_CH_IF_CTL(base, channel_num) = _VAL2FLD(PDM_CH_IF_CTL_SAMPLE_DELAY,      channel_config->sampledelay);
83 
84 
85         PDM_PCM_CH_CIC_CTL(base, channel_num) = ((uint32_t)channel_config->cic_decim_code);
86 
87         PDM_PCM_CH_FIR0_CTL(base, channel_num) = _VAL2FLD(PDM_CH_FIR0_CTL_DECIM3,  channel_config->fir0_decim_code) |
88                                        _VAL2FLD(PDM_CH_FIR0_CTL_SCALE,        channel_config->fir0_scale) |
89                                        _VAL2FLD(PDM_CH_FIR0_CTL_ENABLED,     channel_config->fir0_enable);
90 
91         PDM_PCM_CH_FIR1_CTL(base, channel_num) = _VAL2FLD(PDM_CH_FIR1_CTL_DECIM2,  channel_config->fir1_decim_code) |
92                                        _VAL2FLD(PDM_CH_FIR1_CTL_SCALE,        channel_config->fir1_scale) |
93                                        _VAL2FLD(PDM_CH_FIR1_CTL_ENABLED,     CY_PDM_PCM_ENABLE);
94         if(!channel_config->dc_block_disable)
95         {
96             PDM_PCM_CH_DC_BLOCK_CTL(base, channel_num) = _VAL2FLD(PDM_CH_DC_BLOCK_CTL_CODE,    channel_config->dc_block_code) |
97                                            _VAL2FLD(PDM_CH_DC_BLOCK_CTL_ENABLED, CY_PDM_PCM_ENABLE);
98         }
99         else
100         {
101             PDM_PCM_CH_DC_BLOCK_CTL(base, channel_num) = _VAL2FLD(PDM_CH_DC_BLOCK_CTL_ENABLED, CY_PDM_PCM_DISABLE);
102         }
103 
104     }
105     return ret;
106 }
107 
108 /******************************************************************************
109 * Function Name: Cy_PDM_PCM_Init
110 ***************************************************************************//**
111 *
112 * Initializes the PDM-PCM module
113 *
114 * \param  base The pointer to the PDM-PCM instance address
115 * \param  config The pointer to a configuration structure. \ref cy_stc_pdm_pcm_config_v2_t
116 * \return error / status code. See \ref cy_en_pdm_pcm_status_t.
117 *
118 * \funcusage
119 * \snippet pdm_pcmv2/snippet/main.c snippet_Cy_PDM_PCM_Init
120 *
121 *******************************************************************************/
Cy_PDM_PCM_Init(PDM_Type * base,cy_stc_pdm_pcm_config_v2_t const * config)122 cy_en_pdm_pcm_status_t Cy_PDM_PCM_Init(PDM_Type * base, cy_stc_pdm_pcm_config_v2_t const * config)
123 {
124     cy_en_pdm_pcm_status_t ret = CY_PDM_PCM_BAD_PARAM;
125 
126     if((NULL != base) && (NULL != config))
127     {
128         CY_ASSERT_L2(CY_PDM_PCM_IS_CLK_SEL_VALID(config->clksel));
129         CY_ASSERT_L2(CY_PDM_PCM_IS_HALVE_RATE_SET_VALID(config->halverate));
130         CY_ASSERT_L2(CY_PDM_PCM_IS_ROUTE_VALID(config->route));
131 
132         ret = CY_PDM_PCM_SUCCESS;
133 
134         /* The clock setting */
135         PDM_PCM_CLOCK_CTL(base) = _VAL2FLD(PDM_CLOCK_CTL_CLOCK_DIV, config->clkDiv) |
136                                   _VAL2FLD(PDM_CLOCK_CTL_CLOCK_SEL, config->clksel) |
137                                   _VAL2FLD(PDM_CLOCK_CTL_HALVE,     config->halverate);
138 
139         /* PDM-PCM ROUTE setting */
140         PDM_PCM_ROUTE_CTL(base) = _VAL2FLD(PDM_ROUTE_CTL_DATA_SEL,  config->route);
141 
142         if(config->fir0_coeff_user_value != 0U)
143         {
144             PDM_PCM_FIR0_COEFF0(base) = _VAL2FLD(PDM_FIR0_COEFF0_DATA0, config->fir0_coeff[0].coeff_data0) |
145                                  _VAL2FLD(PDM_FIR0_COEFF0_DATA1,     config->fir0_coeff[0].coeff_data1);
146 
147             PDM_PCM_FIR0_COEFF1(base) = _VAL2FLD(PDM_FIR0_COEFF1_DATA0, config->fir0_coeff[1].coeff_data0) |
148                                  _VAL2FLD(PDM_FIR0_COEFF1_DATA1,     config->fir0_coeff[1].coeff_data1);
149 
150             PDM_PCM_FIR0_COEFF2(base) = _VAL2FLD(PDM_FIR0_COEFF2_DATA0, config->fir0_coeff[2].coeff_data0) |
151                                  _VAL2FLD(PDM_FIR0_COEFF2_DATA1,     config->fir0_coeff[2].coeff_data1);
152 
153             PDM_PCM_FIR0_COEFF3(base) = _VAL2FLD(PDM_FIR0_COEFF3_DATA0, config->fir0_coeff[3].coeff_data0) |
154                                  _VAL2FLD(PDM_FIR0_COEFF3_DATA1,     config->fir0_coeff[3].coeff_data1);
155 
156             PDM_PCM_FIR0_COEFF4(base) = _VAL2FLD(PDM_FIR0_COEFF4_DATA0, config->fir0_coeff[4].coeff_data0) |
157                                  _VAL2FLD(PDM_FIR0_COEFF4_DATA1,     config->fir0_coeff[4].coeff_data1);
158 
159             PDM_PCM_FIR0_COEFF5(base) = _VAL2FLD(PDM_FIR0_COEFF5_DATA0, config->fir0_coeff[5].coeff_data0) |
160                                  _VAL2FLD(PDM_FIR0_COEFF5_DATA1,     config->fir0_coeff[5].coeff_data1);
161 
162             PDM_PCM_FIR0_COEFF6(base) = _VAL2FLD(PDM_FIR0_COEFF6_DATA0, config->fir0_coeff[6].coeff_data0) |
163                                  _VAL2FLD(PDM_FIR0_COEFF6_DATA1,     config->fir0_coeff[6].coeff_data1);
164 
165             PDM_PCM_FIR0_COEFF7(base) = _VAL2FLD(PDM_FIR0_COEFF7_DATA0, config->fir0_coeff[7].coeff_data0) |
166                                  _VAL2FLD(PDM_FIR0_COEFF7_DATA1,     config->fir0_coeff[7].coeff_data1);
167         }
168 
169         if(config->fir1_coeff_user_value != 0U)
170         {
171             PDM_PCM_FIR1_COEFF0(base) = _VAL2FLD(PDM_FIR1_COEFF0_DATA0, config->fir1_coeff[0].coeff_data0) |
172                                  _VAL2FLD(PDM_FIR1_COEFF0_DATA1,     config->fir1_coeff[0].coeff_data1);
173 
174             PDM_PCM_FIR1_COEFF1(base) = _VAL2FLD(PDM_FIR1_COEFF1_DATA0, config->fir1_coeff[1].coeff_data0) |
175                                  _VAL2FLD(PDM_FIR1_COEFF1_DATA1,     config->fir1_coeff[1].coeff_data1);
176 
177             PDM_PCM_FIR1_COEFF2(base) = _VAL2FLD(PDM_FIR1_COEFF2_DATA0, config->fir1_coeff[2].coeff_data0) |
178                                  _VAL2FLD(PDM_FIR1_COEFF2_DATA1,     config->fir1_coeff[2].coeff_data1);
179 
180             PDM_PCM_FIR1_COEFF3(base) = _VAL2FLD(PDM_FIR1_COEFF3_DATA0, config->fir1_coeff[3].coeff_data0) |
181                                  _VAL2FLD(PDM_FIR1_COEFF3_DATA1,     config->fir1_coeff[3].coeff_data1);
182 
183             PDM_PCM_FIR1_COEFF4(base) = _VAL2FLD(PDM_FIR1_COEFF4_DATA0, config->fir1_coeff[4].coeff_data0) |
184                                  _VAL2FLD(PDM_FIR1_COEFF4_DATA1,     config->fir1_coeff[4].coeff_data1);
185 
186             PDM_PCM_FIR1_COEFF5(base) = _VAL2FLD(PDM_FIR1_COEFF5_DATA0, config->fir1_coeff[5].coeff_data0) |
187                                  _VAL2FLD(PDM_FIR1_COEFF5_DATA1,     config->fir1_coeff[5].coeff_data1);
188 
189             PDM_PCM_FIR1_COEFF6(base) = _VAL2FLD(PDM_FIR1_COEFF6_DATA0, config->fir1_coeff[6].coeff_data0) |
190                                  _VAL2FLD(PDM_FIR1_COEFF6_DATA1,     config->fir1_coeff[6].coeff_data1);
191 
192             PDM_PCM_FIR1_COEFF7(base) = _VAL2FLD(PDM_FIR1_COEFF7_DATA0, config->fir1_coeff[7].coeff_data0) |
193                                  _VAL2FLD(PDM_FIR1_COEFF7_DATA1,     config->fir1_coeff[7].coeff_data1);
194 
195             PDM_PCM_FIR1_COEFF8(base) = _VAL2FLD(PDM_FIR1_COEFF8_DATA0, config->fir1_coeff[8].coeff_data0) |
196                                  _VAL2FLD(PDM_FIR1_COEFF8_DATA1,     config->fir1_coeff[8].coeff_data1);
197 
198             PDM_PCM_FIR1_COEFF9(base) = _VAL2FLD(PDM_FIR1_COEFF9_DATA0, config->fir1_coeff[9].coeff_data0) |
199                                  _VAL2FLD(PDM_FIR1_COEFF9_DATA1,     config->fir1_coeff[9].coeff_data1);
200 
201             PDM_PCM_FIR1_COEFF10(base) = _VAL2FLD(PDM_FIR1_COEFF10_DATA0, config->fir1_coeff[10].coeff_data0) |
202                                  _VAL2FLD(PDM_FIR1_COEFF10_DATA1,     config->fir1_coeff[10].coeff_data1);
203 
204             PDM_PCM_FIR1_COEFF11(base) = _VAL2FLD(PDM_FIR1_COEFF11_DATA0, config->fir1_coeff[11].coeff_data0) |
205                                  _VAL2FLD(PDM_FIR1_COEFF11_DATA1,     config->fir1_coeff[11].coeff_data1);
206 
207             PDM_PCM_FIR1_COEFF12(base) = _VAL2FLD(PDM_FIR1_COEFF12_DATA0, config->fir1_coeff[12].coeff_data0) |
208                                  _VAL2FLD(PDM_FIR1_COEFF12_DATA1,     config->fir1_coeff[12].coeff_data1);
209 
210             PDM_PCM_FIR1_COEFF13(base) = _VAL2FLD(PDM_FIR1_COEFF13_DATA0, config->fir1_coeff[13].coeff_data0) |
211                                  _VAL2FLD(PDM_FIR1_COEFF13_DATA1,     config->fir1_coeff[13].coeff_data1);
212 
213         }
214 
215     }
216 
217     return (ret);
218 }
219 
220 /******************************************************************************
221 * Function Name: Cy_PDM_PCM_test_Init
222 ***************************************************************************//**
223 *
224 * Initializes the PDM-PCM module test mode.
225 *
226 * \param  base The pointer to the PDM-PCM instance address
227 * \param  config The pointer to a configuration structure. \ref cy_stc_pdm_pcm_config_v2_t
228 * \param test_config test  Mode configuration. \ref cy_stc_test_config_t
229 * \return error / status code. See \ref cy_en_pdm_pcm_status_t.
230 *
231 *******************************************************************************/
Cy_PDM_PCM_test_Init(PDM_Type * base,cy_stc_pdm_pcm_config_v2_t const * config,cy_stc_test_config_t const * test_config)232 cy_en_pdm_pcm_status_t Cy_PDM_PCM_test_Init(PDM_Type * base, cy_stc_pdm_pcm_config_v2_t const * config, cy_stc_test_config_t const * test_config)
233 {
234     cy_en_pdm_pcm_status_t ret = CY_PDM_PCM_BAD_PARAM;
235 
236     if((NULL != base) && (NULL != config) && (NULL != test_config) )
237     {
238         if(!test_config->enable)
239         {
240             return ret;
241         }
242         CY_ASSERT_L2(CY_PDM_PCM_IS_CLK_SEL_VALID(config->clksel));
243         CY_ASSERT_L2(CY_PDM_PCM_IS_HALVE_RATE_SET_VALID(config->halverate));
244         CY_ASSERT_L2(CY_PDM_PCM_IS_ROUTE_VALID(config->route));
245 
246         ret = CY_PDM_PCM_SUCCESS;
247 
248         PDM_PCM_TEST_CTL(base) = _VAL2FLD(PDM_TEST_CTL_DRIVE_DELAY_HI, test_config->drive_delay_hi) |
249                              _VAL2FLD(PDM_TEST_CTL_DRIVE_DELAY_LO,     test_config->drive_delay_lo);
250         PDM_PCM_TEST_CTL(base) |= _VAL2FLD(PDM_TEST_CTL_MODE_HI,            test_config->mode_hi) |
251                              _VAL2FLD(PDM_TEST_CTL_MODE_LO,            test_config->mode_lo);
252         PDM_PCM_TEST_CTL(base) |= _VAL2FLD(PDM_TEST_CTL_AUDIO_FREQ_DIV,     test_config->audio_freq_div) |
253                              _BOOL2FLD(PDM_TEST_CTL_CH_ENABLED,        test_config->enable);
254 
255     }
256 
257     return (ret);
258 }
259 
260 
261 /*******************************************************************************
262 * Function Name: Cy_PDM_PCM_Channel_DeInit
263 ****************************************************************************//**
264 *
265 * Uninitializes the PDM-PCM channel.
266 *
267 * \param base The pointer to the PDM-PCM instance address.
268 * \param channel_num channel number to be de initialized.
269 *
270 * \funcusage
271 * \snippet pdm_pcmv2/snippet/main.c snippet_Cy_PDM_PCM_Channel_DeInit
272 *
273 *******************************************************************************/
Cy_PDM_PCM_Channel_DeInit(PDM_Type * base,uint8_t channel_num)274 void Cy_PDM_PCM_Channel_DeInit(PDM_Type * base, uint8_t channel_num)
275 {
276     PDM_PCM_CH_IF_CTL(base, channel_num) = CY_PDM_PCM_CH_IF_CTL_DEFAULT;/* Channel interface control default value */
277     PDM_PCM_CH_CTL(base, channel_num) = CY_PDM_PCM_CH_CTL_DEFAULT; /* Channel control default values */
278     PDM_PCM_CH_CIC_CTL(base, channel_num) = CY_PDM_PCM_CH_CIC_DECIM_CODE_DEFAULT;
279     PDM_PCM_CH_FIR1_CTL(base, channel_num) = CY_PDM_PCM_CH_FIR1_DEFAULT;
280     PDM_PCM_CH_DC_BLOCK_CTL(base, channel_num) = CY_PDM_PCM_CH_DCBLOCK_DEFAULT;
281     PDM_PCM_CH_FIR0_CTL(base, channel_num) = 0UL;
282     PDM_PCM_INTR_RX_MASK(base, channel_num) = 0UL; /* Disable interrupts */
283     PDM_PCM_RX_FIFO_CTL(base, channel_num) = 0UL;
284     PDM_PCM_CTL_CLR(base) = (1UL << channel_num);
285 
286 }
287 
288 
289 /*******************************************************************************
290 * Function Name: Cy_PDM_PCM_DeInit
291 ****************************************************************************//**
292 *
293 * Uninitializes the PDM-PCM module.
294 *
295 * \param base The pointer to the PDM-PCM instance address.
296 *
297 * \funcusage
298 * \snippet pdm_pcmv2/snippet/main.c snippet_Cy_PDM_PCM_DeInit
299 *
300 *******************************************************************************/
Cy_PDM_PCM_DeInit(PDM_Type * base)301 void Cy_PDM_PCM_DeInit(PDM_Type * base)
302 {
303     PDM_PCM_ROUTE_CTL(base) = 0UL; /* Default Route settings */
304     PDM_PCM_TEST_CTL(base) = CY_PDM_PCM_TEST_CTL_DEFAULT; /* Default Test settings */
305     PDM_PCM_CTL(base) = 0UL; /* Disable the PDM_PCM IP block */
306     PDM_PCM_CLOCK_CTL(base) = CY_PDM_PCM_CLK_CTL_DEFAULT; /* The default clock settings */
307 }
308 
309 /** \} group_pdm_pcm_functions_v2 */
310 
311 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 10.1')
312 
313 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 14.3')
314 
315 #endif /* CY_IP_MXPDM */
316 
317 /* [] END OF FILE */
318