1 /***************************************************************************//**
2 * \file cy_pdm_pcm.h
3 * \version 2.30.1
4 *
5 * The header file of the PDM_PCM driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2016-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 /**
26 * \addtogroup group_pdm_pcm
27 * \{
28 * \note IP Supported: AUDIOSS
29 * \note Device Categories: CAT1A. Please refer <a href="usergroup1.html">Device Catalog</a>.
30 *
31 * The pulse-density modulation to pulse-code modulation (PDM-PCM) driver provides an
32 * API to manage PDM-PCM conversion. A PDM-PCM converter is used
33 * to convert 1-bit digital audio streaming data to PCM data.
34 *
35 * The functions and other declarations used in this driver are in cy_pdm_pcm.h.
36 * You can include cy_pdl.h to get access to all functions
37 * and declarations in the PDL.
38 *
39 * Features:
40 * * Supports FIFO buffer for Incoming Data
41 * * Supports Software Mute Mode
42 * * Programmable Gain Settings
43 * * Programmable Word Length
44 *
45 * Pulse-density modulation, or PDM, represents
46 * an analog signal with a binary signal. In a PDM signal, specific amplitude values
47 * are not encoded into codewords of pulses of different weight as they would be
48 * in pulse-code modulation (PCM); rather, the relative density of the pulses corresponds
49 * to the analog signal's amplitude. The output of a 1-bit DAC is the same
50 * as the PDM encoding of the signal.
51 *
52 * Pulse-code modulation (PCM) is the method used to digitally represent sampled analog signals.
53 * It is the standard form of digital audio in computers, compact discs, digital telephony,
54 * and other digital audio applications. In a PCM stream, the amplitude of the analog signal
55 * is sampled regularly at uniform intervals, and each sample is quantized
56 * to the nearest value within a range of digital steps.
57 *
58 * \section group_pdm_pcm_configuration_considerations Configuration Considerations
59 *
60 * To set up a PDM-PCM, provide the configuration parameters in the
61 * \ref cy_stc_pdm_pcm_config_t structure.
62 *
63 * For example, set dataStreamingEnable to true, configure rxFifoTriggerLevel,
64 * dmaTriggerEnable (depending on whether DMA is going to be used),
65 * provide clock settings (clkDiv, mclkDiv and ckoDiv), set sincDecRate
66 * to the appropriate decimation rate, wordLen, and wordBitExtension.
67 * No other parameters are necessary for this example.
68 *
69 * To initialize the PDM-PCM block, call the \ref Cy_PDM_PCM_Init function, providing the
70 * filled \ref cy_stc_pdm_pcm_config_t structure.
71 *
72 * If you use a DMA, the DMA channel should be previously configured. PDM-PCM interrupts
73 * (if applicable) can be enabled by calling \ref Cy_PDM_PCM_SetInterruptMask.
74 *
75 * For example, if the trigger interrupt is used during operation, the ISR
76 * should call the \ref Cy_PDM_PCM_ReadFifo as many times as required for your
77 * FIFO payload. Then call \ref Cy_PDM_PCM_ClearInterrupt with appropriate parameters.
78 *
79 * If a DMA is used and the DMA channel is properly configured, no CPU activity
80 * (or application code) is needed for PDM-PCM operation.
81 *
82 * \section group_pdm_pcm_more_information More Information
83 * See: the PDM-PCM chapter of the device technical reference manual (TRM);
84 * the PDM_PCM_PDL Component datasheet;
85 * CE219431 - PSOC 6 MCU PDM-TO-PCM EXAMPLE.
86 *
87 * \section group_pdm_pcm_changelog Changelog
88 * <table class="doxtable">
89 * <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
90 * <tr>
91 * <td>2.30.1</td>
92 * <td>Added Note that this driver supports CAT1A devices only. </td>
93 * <td>To avoid misunderstanding of pdm_pcm and pdm_pcm_v2 drivers usage. </td>
94 * </tr>
95 * <tr>
96 * <td>2.30</td>
97 * <td>Fixed MISRA 2012 violations.</td>
98 * <td>MISRA 2012 compliance.</td>
99 * </tr>
100 * <tr>
101 * <td>2.20.2</td>
102 * <td>Minor documentation updates.</td>
103 * <td>Documentation enhancement.</td>
104 * </tr>
105 * <tr>
106 * <td>2.20.1</td>
107 * <td>Snippet updated.</td>
108 * <td>Old snippet outdated.</td>
109 * </tr>
110 * <tr>
111 * <td rowspan="2">2.20</td>
112 * <td>Flattened the organization of the driver source code into the single
113 * source directory and the single include directory.
114 * </td>
115 * <td>Driver library directory-structure simplification.</td>
116 * </tr>
117 * <tr>
118 * <td>Added register access layer. Use register access macros instead
119 * of direct register access using dereferenced pointers.</td>
120 * <td>Makes register access device-independent, so that the PDL does
121 * not need to be recompiled for each supported part number.</td>
122 * </tr>
123 * <tr>
124 * <td>2.10</td>
125 * <td>The gain values in range +4.5...+10.5dB (5 items) of /ref cy_en_pdm_pcm_gain_t are corrected.
126 * Added Low Power Callback section.</td>
127 * <td>Incorrect setting of gain values in limited range.
128 * Documentation update and clarification.</td>
129 * </tr>
130 * <tr>
131 * <td>2.0</td>
132 * <td>Enumeration types for gain and soft mute cycles are added.<br>
133 * Function parameter checks are added.<br>
134 * The next functions are removed:
135 * * Cy_PDM_PCM_EnterLowPowerCallback
136 * * Cy_PDM_PCM_ExitLowPowerCallback
137 * * Cy_PDM_PCM_EnableDataStream
138 * * Cy_PDM_PCM_DisableDataStream
139 * * Cy_PDM_PCM_SetFifoLevel
140 * * Cy_PDM_PCM_GetFifoLevel
141 * * Cy_PDM_PCM_EnableDmaRequest
142 * * Cy_PDM_PCM_DisableDmaRequest
143 *
144 * The next functions behaviour are modified:
145 * * Cy_PDM_PCM_Enable
146 * * Cy_PDM_PCM_Disable
147 * * Cy_PDM_PCM_SetInterruptMask
148 * * Cy_PDM_PCM_GetInterruptMask
149 * * Cy_PDM_PCM_GetInterruptStatusMasked
150 * * Cy_PDM_PCM_GetInterruptStatus
151 * * Cy_PDM_PCM_ClearInterrupt
152 * * Cy_PDM_PCM_SetInterrupt
153 *
154 * The Cy_PDM_PCM_GetFifoNumWords function is renamed to Cy_PDM_PCM_GetNumInFifo.<br>
155 * The Cy_PDM_PCM_GetCurrentState function is added.
156 * </td>
157 * <td>Improvements based on usability feedbacks.<br>
158 * API is reworked for consistency within the PDL.
159 * </td>
160 * </tr>
161 * <tr>
162 * <td>1.0</td>
163 * <td>Initial version</td>
164 * <td></td>
165 * </tr>
166 * </table>
167 *
168 * \defgroup group_pdm_pcm_macros Macros
169 * \defgroup group_pdm_pcm_functions Functions
170 * \{
171 * \defgroup group_pdm_pcm_functions_syspm_callback Low Power Callback
172 * \}
173 * \defgroup group_pdm_pcm_data_structures Data Structures
174 * \defgroup group_pdm_pcm_enums Enumerated Types
175 *
176 */
177
178 #if !defined(CY_PDM_PCM_H__)
179 #define CY_PDM_PCM_H__
180
181 /******************************************************************************/
182 /* Include files */
183 /******************************************************************************/
184
185 #include "cy_device.h"
186
187 #if defined (AUDIOSS_PDM_PRESENT)
188
189 #include "cy_syslib.h"
190 #include "cy_syspm.h"
191 #include <stddef.h>
192 #include <stdbool.h>
193
194 #ifdef __cplusplus
195 extern "C"
196 {
197 #endif
198
199 /******************************************************************************
200 * Global definitions
201 ******************************************************************************/
202
203 /* Macros */
204 /**
205 * \addtogroup group_pdm_pcm_macros
206 * \{
207 */
208
209 /** The driver major version */
210 #define CY_PDM_PCM_DRV_VERSION_MAJOR 2
211
212 /** The driver minor version */
213 #define CY_PDM_PCM_DRV_VERSION_MINOR 30
214
215 /** The PDM-PCM driver identifier */
216 #define CY_PDM_PCM_ID CY_PDL_DRV_ID(0x26u)
217
218 /**
219 * \defgroup group_pdm_pcm_macros_interrupt_masks Interrupt Masks
220 * \{
221 */
222
223 /** Bit 16: More entries in the RX FIFO than specified by Trigger Level. */
224 #define CY_PDM_PCM_INTR_RX_TRIGGER (PDM_INTR_RX_TRIGGER_Msk)
225 /** Bit 18: RX FIFO is not empty. */
226 #define CY_PDM_PCM_INTR_RX_NOT_EMPTY (PDM_INTR_RX_NOT_EMPTY_Msk)
227 /** Bit 21: Attempt to write to a full RX FIFO. */
228 #define CY_PDM_PCM_INTR_RX_OVERFLOW (PDM_INTR_RX_OVERFLOW_Msk)
229 /** Bit 22: Attempt to read from an empty RX FIFO. */
230 #define CY_PDM_PCM_INTR_RX_UNDERFLOW (PDM_INTR_RX_UNDERFLOW_Msk)
231
232 /** \} group_pdm_pcm_macros_interrupt_masks */
233
234 /** \} group_pdm_pcm_macros */
235
236 /**
237 * \addtogroup group_pdm_pcm_enums
238 * \{
239 */
240
241 /** PDM Word Length. */
242 typedef enum
243 {
244 CY_PDM_PCM_WLEN_16_BIT = 0U, /**< Word length: 16 bit. */
245 CY_PDM_PCM_WLEN_18_BIT = 1U, /**< Word length: 18 bit. */
246 CY_PDM_PCM_WLEN_20_BIT = 2U, /**< Word length: 20 bit. */
247 CY_PDM_PCM_WLEN_24_BIT = 3U /**< Word length: 24 bit. */
248 } cy_en_pdm_pcm_word_len_t;
249
250 /** PDM Clock Divider. */
251 typedef enum
252 {
253 CY_PDM_PCM_CLK_DIV_BYPASS = 0U, /**< Clock 1/1. */
254 CY_PDM_PCM_CLK_DIV_1_2 = 1U, /**< Clock 1/2 (no 50% duty cycle). */
255 CY_PDM_PCM_CLK_DIV_1_3 = 2U, /**< Clock 1/3 (no 50% duty cycle). */
256 CY_PDM_PCM_CLK_DIV_1_4 = 3U /**< Clock 1/4 (no 50% duty cycle). */
257 } cy_en_pdm_pcm_clk_div_t;
258
259 /** PDM Output Mode. */
260 typedef enum
261 {
262 CY_PDM_PCM_OUT_CHAN_LEFT = 1U, /**< Channel mono left. */
263 CY_PDM_PCM_OUT_CHAN_RIGHT = 2U, /**< Channel mono right. */
264 CY_PDM_PCM_OUT_STEREO = 3U /**< Channel stereo. */
265 } cy_en_pdm_pcm_out_t;
266
267 /** PDM Channel selector. */
268 typedef enum
269 {
270 CY_PDM_PCM_CHAN_LEFT = 0U, /**< Channel left. */
271 CY_PDM_PCM_CHAN_RIGHT = 1U /**< Channel right. */
272 } cy_en_pdm_pcm_chan_select_t;
273
274 /** PDM Gain. */
275 typedef enum
276 {
277 CY_PDM_PCM_ATTN_12_DB = 0U, /**< -12 dB (attenuation). */
278 CY_PDM_PCM_ATTN_10_5_DB = 1U, /**< -10.5 dB (attenuation). */
279 CY_PDM_PCM_ATTN_9_DB = 2U, /**< -9 dB (attenuation). */
280 CY_PDM_PCM_ATTN_7_5_DB = 3U, /**< -7.5 dB (attenuation). */
281 CY_PDM_PCM_ATTN_6_DB = 4U, /**< -6 dB (attenuation). */
282 CY_PDM_PCM_ATTN_4_5_DB = 5U, /**< -4.5 dB (attenuation). */
283 CY_PDM_PCM_ATTN_3_DB = 6U, /**< -3 dB (attenuation). */
284 CY_PDM_PCM_ATTN_1_5_DB = 7U, /**< -1.5 dB (attenuation). */
285 CY_PDM_PCM_BYPASS = 8U, /**< 0 dB (bypass). */
286 CY_PDM_PCM_GAIN_1_5_DB = 9U, /**< +1.5 dB (amplification). */
287 CY_PDM_PCM_GAIN_3_DB = 10U, /**< +3 dB (amplification). */
288 CY_PDM_PCM_GAIN_4_5_DB = 11U, /**< +4.5 dB (amplification). */
289 CY_PDM_PCM_GAIN_6_DB = 12U, /**< +6 dB (amplification). */
290 CY_PDM_PCM_GAIN_7_5_DB = 13U, /**< +7.5 dB (amplification). */
291 CY_PDM_PCM_GAIN_9_DB = 14U, /**< +9 dB (amplification). */
292 CY_PDM_PCM_GAIN_10_5_DB = 15U /**< +10.5 dB (amplification). */
293 } cy_en_pdm_pcm_gain_t;
294
295
296 /** The time step for gain change during PGA or soft mute operation in
297 * number of 1/a sampling rate. */
298 typedef enum
299 {
300 CY_PDM_PCM_SOFT_MUTE_CYCLES_64 = 0U, /**< 64 steps. */
301 CY_PDM_PCM_SOFT_MUTE_CYCLES_96 = 1U, /**< 96 steps. */
302 CY_PDM_PCM_SOFT_MUTE_CYCLES_128 = 2U, /**< 128 steps. */
303 CY_PDM_PCM_SOFT_MUTE_CYCLES_160 = 3U, /**< 160 steps. */
304 CY_PDM_PCM_SOFT_MUTE_CYCLES_192 = 4U, /**< 192 steps. */
305 CY_PDM_PCM_SOFT_MUTE_CYCLES_256 = 5U, /**< 256 steps. */
306 CY_PDM_PCM_SOFT_MUTE_CYCLES_384 = 6U, /**< 384 steps. */
307 CY_PDM_PCM_SOFT_MUTE_CYCLES_512 = 7U /**< 512 steps. */
308 } cy_en_pdm_pcm_s_cycles_t;
309
310 /** The PDM-PCM status codes. */
311 typedef enum
312 {
313 CY_PDM_PCM_SUCCESS = 0x00UL, /**< Success status code */
314 CY_PDM_PCM_BAD_PARAM = CY_PDM_PCM_ID | CY_PDL_STATUS_ERROR | 0x01UL /**< Bad parameter status code */
315 } cy_en_pdm_pcm_status_t;
316
317 /** \} group_pdm_pcm_enums */
318
319
320 /**
321 * \addtogroup group_pdm_pcm_data_structures
322 * \{
323 */
324
325 /******************************************************************************
326 * Global type definitions
327 ******************************************************************************/
328
329 /** PDM-PCM initialization configuration */
330 typedef struct
331 {
332 cy_en_pdm_pcm_clk_div_t clkDiv; /**< PDM Clock Divider (1st divider), see #cy_en_pdm_pcm_clk_div_t
333 This configures a frequency of PDM CLK. The configured frequency
334 is used to operate PDM core. I.e. the frequency is input to
335 MCLKQ_CLOCK_DIV register. */
336 cy_en_pdm_pcm_clk_div_t mclkDiv; /**< MCLKQ divider (2nd divider), see #cy_en_pdm_pcm_clk_div_t */
337 uint8_t ckoDiv; /**< PDM CKO (FPDM_CKO) clock divider (3rd divider):
338 - if CKO_CLOCK_DIV >= 1 - *F(PDM_CKO) = F(PDM_CLK / (mclkDiv + 1))
339 - if CKO_CLOCK_DIV = 0 - *F(PDM_CKO) = MCLKQ / 2 */
340 uint8_t ckoDelay; /**< Extra PDM_CKO delay to internal sampler:
341 - 0: Three extra PDM_CLK period advance
342 - 1: Two extra PDM_CLK period advance
343 - 2: One extra PDM_CLK period advance
344 - 3: No delay
345 - 4: One extra PDM_CLK period delay
346 - 5: Two extra PDM_CLK period delay
347 - 6: Three extra PDM_CLK period delay
348 - 7: Four extra PDM_CLK clock delay */
349 uint8_t sincDecRate; /**< F(MCLK_L_R) = Fs * 2 * sincDecRate * mclkDiv,
350 Fs is a sampling frequency, 8 kHz - 48 kHz */
351 cy_en_pdm_pcm_out_t chanSelect; /**< see #cy_en_pdm_pcm_out_t */
352 bool chanSwapEnable; /**< Audio channels swapping */
353 uint8_t highPassFilterGain; /**< High pass filter gain:
354 H(Z) = (1 - Z^-1) / (1 - (1 - 2^highPassFilterGain) * Z^-1) */
355 bool highPassDisable; /**< High pass filter disable */
356 cy_en_pdm_pcm_s_cycles_t softMuteCycles; /**< The time step for gain change during PGA or soft mute operation in
357 number of 1/a sampling rate, see #cy_en_pdm_pcm_s_cycles_t. */
358 uint32_t softMuteFineGain; /**< Soft mute fine gain: 0 = 0.13dB, 1 = 0.26dB */
359 bool softMuteEnable; /**< Soft mute enable */
360 cy_en_pdm_pcm_word_len_t wordLen; /**< see #cy_en_pdm_pcm_word_len_t */
361 bool signExtension; /**< Word extension type:
362 - 0: extension by zero
363 - 1: extension by sign bits */
364 cy_en_pdm_pcm_gain_t gainLeft; /**< Gain for left channel, see #cy_en_pdm_pcm_gain_t */
365 cy_en_pdm_pcm_gain_t gainRight; /**< Gain for right channel, see #cy_en_pdm_pcm_gain_t */
366 uint8_t rxFifoTriggerLevel; /**< Fifo interrupt trigger level (in words),
367 range: 0 - 253 for stereo and 0 - 254 for mono mode */
368 bool dmaTriggerEnable; /**< DMA trigger enable */
369 uint32_t interruptMask; /**< Interrupts enable mask */
370 } cy_stc_pdm_pcm_config_t;
371
372 /** \} group_pdm_pcm_data_structures */
373
374
375 /** \cond INTERNAL */
376 /******************************************************************************
377 * Local definitions
378 *******************************************************************************/
379 /** Define bit mask for all available interrupt sources */
380 #define CY_PDM_PCM_INTR_MASK (CY_PDM_PCM_INTR_RX_TRIGGER | \
381 CY_PDM_PCM_INTR_RX_NOT_EMPTY | \
382 CY_PDM_PCM_INTR_RX_OVERFLOW | \
383 CY_PDM_PCM_INTR_RX_UNDERFLOW)
384
385 /* Non-zero default values */
386 #define CY_PDM_PCM_CTL_PGA_R_DEFAULT (0x8U)
387 #define CY_PDM_PCM_CTL_PGA_L_DEFAULT (0x8U)
388 #define CY_PDM_PCM_CTL_STEP_SEL_DEFAULT (0x1U)
389
390 #define CY_PDM_PCM_CTL_DEFAULT (_VAL2FLD(PDM_CTL_PGA_R, CY_PDM_PCM_CTL_PGA_R_DEFAULT) | \
391 _VAL2FLD(PDM_CTL_PGA_L, CY_PDM_PCM_CTL_PGA_L_DEFAULT) | \
392 _VAL2FLD(PDM_CTL_STEP_SEL, CY_PDM_PCM_CTL_STEP_SEL_DEFAULT))
393
394 #define CY_PDM_PCM_CLOCK_CTL_MCLKQ_CLOCK_DIV_DEFAULT (0x1U)
395 #define CY_PDM_PCM_CLOCK_CTL_CKO_CLOCK_DIV_DEFAULT (0x3U)
396 #define CY_PDM_PCM_CLOCK_CTL_SINC_RATE_DEFAULT (0x20U)
397
398 #define CY_PDM_PCM_CLOCK_CTL_DEFAULT (_VAL2FLD(PDM_CLOCK_CTL_MCLKQ_CLOCK_DIV, CY_PDM_PCM_CLOCK_CTL_MCLKQ_CLOCK_DIV_DEFAULT) | \
399 _VAL2FLD(PDM_CLOCK_CTL_CKO_CLOCK_DIV, CY_PDM_PCM_CLOCK_CTL_CKO_CLOCK_DIV_DEFAULT) | \
400 _VAL2FLD(PDM_CLOCK_CTL_SINC_RATE, CY_PDM_PCM_CLOCK_CTL_SINC_RATE_DEFAULT))
401
402 #define CY_PDM_PCM_MODE_CTL_PCM_CH_SET_DEFAULT (0x3U)
403 #define CY_PDM_PCM_MODE_CTL_S_CYCLES_DEFAULT (0x1U)
404 #define CY_PDM_PCM_MODE_CTL_HPF_GAIN_DEFAULT (0xBU)
405 #define CY_PDM_PCM_MODE_CTL_HPF_EN_N_DEFAULT (0x1U)
406
407 #define CY_PDM_PCM_MODE_CTL_DEFAULT (_VAL2FLD(PDM_MODE_CTL_PCM_CH_SET, CY_PDM_PCM_MODE_CTL_PCM_CH_SET_DEFAULT) | \
408 _VAL2FLD(PDM_MODE_CTL_S_CYCLES, CY_PDM_PCM_MODE_CTL_S_CYCLES_DEFAULT) | \
409 _VAL2FLD(PDM_MODE_CTL_HPF_GAIN, CY_PDM_PCM_MODE_CTL_HPF_GAIN_DEFAULT) | \
410 _VAL2FLD(PDM_MODE_CTL_HPF_EN_N, CY_PDM_PCM_MODE_CTL_HPF_EN_N_DEFAULT))
411
412 /* Macros for conditions used by CY_ASSERT calls */
413 #define CY_PDM_PCM_IS_CLK_DIV_VALID(clkDiv) (((clkDiv) == CY_PDM_PCM_CLK_DIV_BYPASS) || \
414 ((clkDiv) == CY_PDM_PCM_CLK_DIV_1_2) || \
415 ((clkDiv) == CY_PDM_PCM_CLK_DIV_1_3) || \
416 ((clkDiv) == CY_PDM_PCM_CLK_DIV_1_4))
417
418 #define CY_PDM_PCM_IS_CH_SET_VALID(chanSelect) (((chanSelect) == CY_PDM_PCM_OUT_CHAN_LEFT) || \
419 ((chanSelect) == CY_PDM_PCM_OUT_CHAN_RIGHT) || \
420 ((chanSelect) == CY_PDM_PCM_OUT_STEREO))
421
422 #define CY_PDM_PCM_IS_GAIN_VALID(gain) (((gain) == CY_PDM_PCM_ATTN_12_DB) || \
423 ((gain) == CY_PDM_PCM_ATTN_10_5_DB) || \
424 ((gain) == CY_PDM_PCM_ATTN_9_DB) || \
425 ((gain) == CY_PDM_PCM_ATTN_7_5_DB) || \
426 ((gain) == CY_PDM_PCM_ATTN_6_DB) || \
427 ((gain) == CY_PDM_PCM_ATTN_4_5_DB) || \
428 ((gain) == CY_PDM_PCM_ATTN_3_DB) || \
429 ((gain) == CY_PDM_PCM_ATTN_1_5_DB) || \
430 ((gain) == CY_PDM_PCM_BYPASS) || \
431 ((gain) == CY_PDM_PCM_GAIN_1_5_DB) || \
432 ((gain) == CY_PDM_PCM_GAIN_3_DB) || \
433 ((gain) == CY_PDM_PCM_GAIN_4_5_DB) || \
434 ((gain) == CY_PDM_PCM_GAIN_6_DB) || \
435 ((gain) == CY_PDM_PCM_GAIN_7_5_DB) || \
436 ((gain) == CY_PDM_PCM_GAIN_9_DB) || \
437 ((gain) == CY_PDM_PCM_GAIN_10_5_DB))
438
439 #define CY_PDM_PCM_IS_WORD_LEN_VALID(wordLen) (((wordLen) == CY_PDM_PCM_WLEN_16_BIT) || \
440 ((wordLen) == CY_PDM_PCM_WLEN_18_BIT) || \
441 ((wordLen) == CY_PDM_PCM_WLEN_20_BIT) || \
442 ((wordLen) == CY_PDM_PCM_WLEN_24_BIT))
443
444 #define CY_PDM_PCM_IS_CHAN_VALID(chan) (((chan) == CY_PDM_PCM_CHAN_LEFT) || \
445 ((chan) == CY_PDM_PCM_CHAN_RIGHT))
446
447 #define CY_PDM_PCM_IS_S_CYCLES_VALID(sCycles) (((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_64) || \
448 ((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_96) || \
449 ((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_128) || \
450 ((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_160) || \
451 ((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_192) || \
452 ((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_256) || \
453 ((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_384) || \
454 ((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_512))
455
456 #define CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt) (0UL == ((interrupt) & ((uint32_t) ~CY_PDM_PCM_INTR_MASK)))
457 #define CY_PDM_PCM_IS_SINC_RATE_VALID(sincRate) ((sincRate) <= 127U)
458 #define CY_PDM_PCM_IS_STEP_SEL_VALID(stepSel) ((stepSel) <= 1UL)
459 #define CY_PDM_PCM_IS_CKO_DELAY_VALID(ckoDelay) ((ckoDelay) <= 7U)
460 #define CY_PDM_PCM_IS_HPF_GAIN_VALID(hpfGain) ((hpfGain) <= 15U)
461 #define CY_PDM_PCM_IS_CKO_CLOCK_DIV_VALID(ckoDiv) (((ckoDiv) >= 1U) && ((ckoDiv) <= 15U))
462 #define CY_PDM_PCM_IS_TRIG_LEVEL(trigLevel, chanSelect) ((trigLevel) <= (((chanSelect) == CY_PDM_PCM_OUT_STEREO)? 253U : 254U))
463 /** \endcond */
464
465 /**
466 * \addtogroup group_pdm_pcm_functions
467 * \{
468 */
469
470 cy_en_pdm_pcm_status_t Cy_PDM_PCM_Init(PDM_Type * base, cy_stc_pdm_pcm_config_t const * config);
471 void Cy_PDM_PCM_DeInit(PDM_Type * base);
472 void Cy_PDM_PCM_SetGain(PDM_Type * base, cy_en_pdm_pcm_chan_select_t chan, cy_en_pdm_pcm_gain_t gain);
473 cy_en_pdm_pcm_gain_t Cy_PDM_PCM_GetGain(PDM_Type const * base, cy_en_pdm_pcm_chan_select_t chan);
474
475 /** \addtogroup group_pdm_pcm_functions_syspm_callback
476 * The driver supports SysPm callback for Deep Sleep transition.
477 * \{
478 */
479 cy_en_syspm_status_t Cy_PDM_PCM_DeepSleepCallback(cy_stc_syspm_callback_params_t const * callbackParams, cy_en_syspm_callback_mode_t mode);
480 /** \} */
481
482 __STATIC_INLINE void Cy_PDM_PCM_Enable(PDM_Type * base);
483 __STATIC_INLINE void Cy_PDM_PCM_Disable(PDM_Type * base);
484 __STATIC_INLINE void Cy_PDM_PCM_SetInterruptMask(PDM_Type * base, uint32_t interrupt);
485 __STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptMask(PDM_Type const * base);
486 __STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatusMasked(PDM_Type const * base);
487 __STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatus(PDM_Type const * base);
488 __STATIC_INLINE void Cy_PDM_PCM_ClearInterrupt(PDM_Type * base, uint32_t interrupt);
489 __STATIC_INLINE void Cy_PDM_PCM_SetInterrupt(PDM_Type * base, uint32_t interrupt);
490 __STATIC_INLINE uint8_t Cy_PDM_PCM_GetNumInFifo(PDM_Type const * base);
491 __STATIC_INLINE void Cy_PDM_PCM_ClearFifo(PDM_Type * base);
492 __STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifo(PDM_Type const * base);
493 __STATIC_INLINE void Cy_PDM_PCM_EnableSoftMute(PDM_Type * base);
494 __STATIC_INLINE void Cy_PDM_PCM_DisableSoftMute(PDM_Type * base);
495 __STATIC_INLINE void Cy_PDM_PCM_FreezeFifo(PDM_Type * base);
496 __STATIC_INLINE void Cy_PDM_PCM_UnfreezeFifo(PDM_Type * base);
497 __STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifoSilent(PDM_Type const * base);
498
499
500 /** \} group_pdm_pcm_functions */
501
502 /**
503 * \addtogroup group_pdm_pcm_functions
504 * \{
505 */
506
507 /******************************************************************************
508 * Function Name: Cy_PDM_PCM_Enable
509 ***************************************************************************//**
510 *
511 * Enables the PDM-PCM data conversion.
512 *
513 * \param base The pointer to the PDM-PCM instance address.
514 *
515 ******************************************************************************/
Cy_PDM_PCM_Enable(PDM_Type * base)516 __STATIC_INLINE void Cy_PDM_PCM_Enable(PDM_Type * base)
517 {
518 PDM_PCM_CMD(base) |= PDM_CMD_STREAM_EN_Msk;
519 }
520
521 /******************************************************************************
522 * Function Name: Cy_PDM_PCM_Disable
523 ***************************************************************************//**
524 *
525 * Disables the PDM-PCM data conversion.
526 *
527 * \param base The pointer to the PDM-PCM instance address.
528 *
529 ******************************************************************************/
Cy_PDM_PCM_Disable(PDM_Type * base)530 __STATIC_INLINE void Cy_PDM_PCM_Disable(PDM_Type * base)
531 {
532 PDM_PCM_CMD(base) &= (uint32_t) ~PDM_CMD_STREAM_EN_Msk;
533 }
534
535
536 /******************************************************************************
537 * Function Name: Cy_PDM_PCM_GetCurrentState
538 ***************************************************************************//**
539 *
540 * Returns the current PDM-PCM state (running/stopped).
541 *
542 * \param base The pointer to the PDM-PCM instance address.
543 * \return The current state (CMD register).
544 *
545 ******************************************************************************/
Cy_PDM_PCM_GetCurrentState(PDM_Type const * base)546 __STATIC_INLINE uint32_t Cy_PDM_PCM_GetCurrentState(PDM_Type const * base)
547 {
548 return (PDM_PCM_CMD(base));
549 }
550
551
552 /******************************************************************************
553 * Function Name: Cy_PDM_PCM_SetInterruptMask
554 ***************************************************************************//**
555 *
556 * Sets one or more PDM-PCM interrupt factor bits (sets the INTR_MASK register).
557 *
558 * \param base The pointer to the PDM-PCM instance address
559 * \param interrupt Interrupt bit mask \ref group_pdm_pcm_macros_interrupt_masks.
560 *
561 ******************************************************************************/
Cy_PDM_PCM_SetInterruptMask(PDM_Type * base,uint32_t interrupt)562 __STATIC_INLINE void Cy_PDM_PCM_SetInterruptMask(PDM_Type * base, uint32_t interrupt)
563 {
564 CY_ASSERT_L2(CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt));
565 PDM_PCM_INTR_MASK(base) = interrupt;
566 }
567
568
569 /******************************************************************************
570 * Function Name: Cy_PDM_PCM_GetInterruptMask
571 ***************************************************************************//**
572 *
573 * Returns the PDM-PCM interrupt mask (a content of the INTR_MASK register).
574 *
575 * \param base The pointer to the PDM-PCM instance address.
576 * \return The interrupt bit mask \ref group_pdm_pcm_macros_interrupt_masks.
577 *
578 ******************************************************************************/
Cy_PDM_PCM_GetInterruptMask(PDM_Type const * base)579 __STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptMask(PDM_Type const * base)
580 {
581 return (PDM_PCM_INTR_MASK(base));
582 }
583
584
585 /******************************************************************************
586 * Function Name: Cy_PDM_PCM_GetInterruptStatusMasked
587 ***************************************************************************//**
588 *
589 * Reports the status of enabled (masked) PDM-PCM interrupt sources.
590 * (an INTR_MASKED register).
591 *
592 * \param base The pointer to the PDM-PCM instance address.
593 * \return The interrupt bit mask \ref group_pdm_pcm_macros_interrupt_masks.
594 *
595 *****************************************************************************/
Cy_PDM_PCM_GetInterruptStatusMasked(PDM_Type const * base)596 __STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatusMasked(PDM_Type const * base)
597 {
598 return (PDM_PCM_INTR_MASKED(base));
599 }
600
601
602 /******************************************************************************
603 * Function Name: Cy_PDM_PCM_GetInterruptStatus
604 ***************************************************************************//**
605 *
606 * Reports the status of PDM-PCM interrupt sources (an INTR register).
607 *
608 * \param base The pointer to the PDM-PCM instance address.
609 * \return The interrupt bit mask \ref group_pdm_pcm_macros_interrupt_masks.
610 *
611 ******************************************************************************/
Cy_PDM_PCM_GetInterruptStatus(PDM_Type const * base)612 __STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatus(PDM_Type const * base)
613 {
614 return (PDM_PCM_INTR(base));
615 }
616
617
618 /******************************************************************************
619 * Function Name: Cy_PDM_PCM_ClearInterrupt
620 ***************************************************************************//**
621 *
622 * Clears one or more PDM-PCM interrupt statuses (sets an INTR register's bits).
623 *
624 * \param base The pointer to the PDM-PCM instance address
625 * \param interrupt
626 * The interrupt bit mask \ref group_pdm_pcm_macros_interrupt_masks.
627 *
628 ******************************************************************************/
Cy_PDM_PCM_ClearInterrupt(PDM_Type * base,uint32_t interrupt)629 __STATIC_INLINE void Cy_PDM_PCM_ClearInterrupt(PDM_Type * base, uint32_t interrupt)
630 {
631 CY_ASSERT_L2(CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt));
632 PDM_PCM_INTR(base) = interrupt;
633 /* This dummy reading is necessary here. It provides a guarantee that interrupt is cleared at returning from this function. */
634 (void) PDM_PCM_INTR(base);
635 }
636
637
638 /******************************************************************************
639 * Function Name: Cy_PDM_PCM_SetInterrupt
640 ***************************************************************************//**
641 *
642 * Sets one or more interrupt source statuses (sets an INTR_SET register).
643 *
644 * \param base The pointer to the PDM-PCM instance address.
645 * \param interrupt
646 * The interrupt bit mask \ref group_pdm_pcm_macros_interrupt_masks.
647 *
648 ******************************************************************************/
Cy_PDM_PCM_SetInterrupt(PDM_Type * base,uint32_t interrupt)649 __STATIC_INLINE void Cy_PDM_PCM_SetInterrupt(PDM_Type * base, uint32_t interrupt)
650 {
651 CY_ASSERT_L2(CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt));
652 PDM_PCM_INTR_SET(base) = interrupt;
653 }
654
655
656 /******************************************************************************
657 * Function Name: Cy_PDM_PCM_GetNumInFifo
658 ***************************************************************************//**
659 *
660 * Reports the current number of used words in the output data FIFO.
661 *
662 * \param base The pointer to the PDM-PCM instance address.
663 * \return The current number of used FIFO words (range is 0 - 254).
664 *
665 ******************************************************************************/
Cy_PDM_PCM_GetNumInFifo(PDM_Type const * base)666 __STATIC_INLINE uint8_t Cy_PDM_PCM_GetNumInFifo(PDM_Type const * base)
667 {
668 return (uint8_t) (_FLD2VAL(PDM_RX_FIFO_STATUS_USED, PDM_PCM_RX_FIFO_STATUS(base)));
669 }
670
671
672 /******************************************************************************
673 * Function Name: Cy_PDM_PCM_ClearFifo
674 ***************************************************************************//**
675 *
676 * Resets the output data FIFO, removing all data words from the FIFO.
677 *
678 * \param base The pointer to the PDM-PCM instance address.
679 *
680 ******************************************************************************/
Cy_PDM_PCM_ClearFifo(PDM_Type * base)681 __STATIC_INLINE void Cy_PDM_PCM_ClearFifo(PDM_Type * base)
682 {
683 PDM_PCM_RX_FIFO_CTL(base) |= PDM_RX_FIFO_CTL_CLEAR_Msk; /* clear FIFO and disable it */
684 PDM_PCM_RX_FIFO_CTL(base) &= (uint32_t) ~PDM_RX_FIFO_CTL_CLEAR_Msk; /* enable FIFO */
685 }
686
687
688 /******************************************************************************
689 * Function Name: Cy_PDM_PCM_ReadFifo
690 ***************************************************************************//**
691 *
692 * Reads ("pops") one word from the output data FIFO.
693 *
694 * \param base The pointer to the PDM-PCM instance address.
695 * \return The data word.
696 *
697 ******************************************************************************/
Cy_PDM_PCM_ReadFifo(PDM_Type const * base)698 __STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifo(PDM_Type const * base)
699 {
700 return (PDM_PCM_RX_FIFO_RD(base));
701 }
702
703
704 /******************************************************************************
705 * Function Name: Cy_PDM_PCM_EnableSoftMute
706 ***************************************************************************//**
707 *
708 * Enables soft mute.
709 *
710 * \param base The pointer to the PDM-PCM instance address.
711 *
712 ******************************************************************************/
Cy_PDM_PCM_EnableSoftMute(PDM_Type * base)713 __STATIC_INLINE void Cy_PDM_PCM_EnableSoftMute(PDM_Type * base)
714 {
715 PDM_PCM_CTL(base) |= PDM_CTL_SOFT_MUTE_Msk;
716 }
717
718
719 /******************************************************************************
720 * Function Name: Cy_PDM_PCM_DisableSoftMute
721 ***************************************************************************//**
722 *
723 * Disables soft mute.
724 *
725 * \param base The pointer to the PDM-PCM instance address.
726 *
727 ******************************************************************************/
Cy_PDM_PCM_DisableSoftMute(PDM_Type * base)728 __STATIC_INLINE void Cy_PDM_PCM_DisableSoftMute(PDM_Type * base)
729 {
730 PDM_PCM_CTL(base) &= (uint32_t) ~PDM_CTL_SOFT_MUTE_Msk;
731 }
732
733
734 /******************************************************************************
735 * Function Name: Cy_PDM_PCM_FreezeFifo
736 ***************************************************************************//**
737 *
738 * Freezes the RX FIFO (Debug purpose).
739 *
740 * \param base The pointer to the PDM-PCM instance address.
741 *
742 ******************************************************************************/
Cy_PDM_PCM_FreezeFifo(PDM_Type * base)743 __STATIC_INLINE void Cy_PDM_PCM_FreezeFifo(PDM_Type * base)
744 {
745 PDM_PCM_RX_FIFO_CTL(base) |= PDM_RX_FIFO_CTL_FREEZE_Msk;
746 }
747
748
749 /******************************************************************************
750 * Function Name: Cy_PDM_PCM_UnfreezeFifo
751 ***************************************************************************//**
752 *
753 * Unfreezes the RX FIFO (Debug purpose).
754 *
755 * \param base The pointer to the PDM-PCM instance address.
756 *
757 ******************************************************************************/
Cy_PDM_PCM_UnfreezeFifo(PDM_Type * base)758 __STATIC_INLINE void Cy_PDM_PCM_UnfreezeFifo(PDM_Type * base)
759 {
760 PDM_PCM_RX_FIFO_CTL(base) &= (uint32_t) ~PDM_RX_FIFO_CTL_FREEZE_Msk;
761 }
762
763
764 /******************************************************************************
765 * Function Name: Cy_PDM_PCM_ReadFifoSilent
766 ***************************************************************************//**
767 *
768 * Reads the RX FIFO silent (without touching the FIFO function).
769 *
770 * \param base Pointer to PDM-PCM instance address.
771 * \return FIFO value.
772 *
773 ******************************************************************************/
Cy_PDM_PCM_ReadFifoSilent(PDM_Type const * base)774 __STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifoSilent(PDM_Type const * base)
775 {
776 return (PDM_PCM_RX_FIFO_RD_SILENT(base));
777 }
778
779 /** \} group_pdm_pcm_functions */
780
781 #ifdef __cplusplus
782 }
783 #endif /* of __cplusplus */
784
785 #endif /* (defined (AUDIOSS_PDM_PRESENT) || defined(CY_DOXYGEN))*/
786
787 #endif /* CY_PDM_PCM_H__ */
788
789 /** \} group_pdm_pcm */
790
791
792 /* [] END OF FILE */
793