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