High level interface for interacting with the pulse-density modulation to pulse-code modulation (PDM/PCM) converter.
The PDM/PCM converter is a asynchronous operation. A PDM-PCM converter is used to convert 1-bit digital audio streaming data to PCM data. The sample rate, word size, and channels can all be configured.
Initialize a PDM/PCM converter instance using the cyhal_pdm_pcm_init and provide the clock and data pins.
See Snippet 1: PDM/PCM Initialization and Configuration for example initialization.
This snippet initializes a PCM/PCM resource for conversion and assigns the pins.
This snippet shows how to receive data in the background using cyhal_pdm_pcm_read_async. Notification of the asynchronous read completion is achieved by using cyhal_pdm_pcm_register_callback to register a callback function and cyhal_pdm_pcm_enable_event to enable callling the callback when an synchonous read completes.
Code examples (Github)
API Reference | |
PDM/PCM HAL Results | |
PDM/PCM specific return codes. | |
Data Structures | |
struct | cyhal_pdm_pcm_cfg_t |
Describes the current configuration of a PDM/PCM. More... | |
Typedefs | |
typedef void(* | cyhal_pdm_pcm_event_callback_t) (void *handler_arg, cyhal_pdm_pcm_event_t event) |
Handler for PDM/PCM interrupts. | |
Enumerations | |
enum | cyhal_pdm_pcm_event_t { CYHAL_PDM_PCM_RX_HALF_FULL = 0x01 , CYHAL_PDM_PCM_RX_NOT_EMPTY = 0x02 , CYHAL_PDM_PCM_RX_OVERFLOW = 0x04 , CYHAL_PDM_PCM_RX_UNDERFLOW = 0x08 , CYHAL_PDM_PCM_ASYNC_COMPLETE = 0x10 } |
PDM/PCM interrupt triggers. More... | |
enum | cyhal_pdm_pcm_mode_t { CYHAL_PDM_PCM_MODE_LEFT , CYHAL_PDM_PCM_MODE_RIGHT , CYHAL_PDM_PCM_MODE_STEREO } |
PDM/PCM channel select. More... | |
Functions | |
cy_rslt_t | cyhal_pdm_pcm_init (cyhal_pdm_pcm_t *obj, cyhal_gpio_t pin_data, cyhal_gpio_t pin_clk, const cyhal_clock_t *clk_source, const cyhal_pdm_pcm_cfg_t *cfg) |
Initialize the PDM/PCM peripheral. More... | |
cy_rslt_t | cyhal_pdm_pcm_init_cfg (cyhal_pdm_pcm_t *obj, const cyhal_pdm_pcm_configurator_t *cfg) |
Initialize the PDM/PCM out peripheral using a configurator generated configuration struct. More... | |
void | cyhal_pdm_pcm_free (cyhal_pdm_pcm_t *obj) |
Release a PDM/PCM object, behavior is undefined if an asynchronous read is in progress. More... | |
cy_rslt_t | cyhal_pdm_pcm_start (cyhal_pdm_pcm_t *obj) |
Start the PDM/PCM operation. More... | |
cy_rslt_t | cyhal_pdm_pcm_stop (cyhal_pdm_pcm_t *obj) |
Stop the PDM/PCM operation. More... | |
bool | cyhal_pdm_pcm_is_enabled (cyhal_pdm_pcm_t *obj) |
Checks if the specified PDM/PCM peripheral is enabled (regardless of whether any unread data has been received). More... | |
cy_rslt_t | cyhal_pdm_pcm_set_gain (cyhal_pdm_pcm_t *obj, int16_t gain_left, int16_t gain_right) |
Updates the PDM/PCM channel gains. More... | |
cy_rslt_t | cyhal_pdm_pcm_clear (cyhal_pdm_pcm_t *obj) |
Clears the hardware buffer. More... | |
cy_rslt_t | cyhal_pdm_pcm_read (cyhal_pdm_pcm_t *obj, void *data, size_t *length) |
Reads data synchronously. More... | |
cy_rslt_t | cyhal_pdm_pcm_read_async (cyhal_pdm_pcm_t *obj, void *data, size_t length) |
Begin asynchronous PDM/PCM read. More... | |
bool | cyhal_pdm_pcm_is_pending (cyhal_pdm_pcm_t *obj) |
Checks if an async read operation is pending. More... | |
cy_rslt_t | cyhal_pdm_pcm_abort_async (cyhal_pdm_pcm_t *obj) |
Abort an PDM/PCM operation started by cyhal_pdm_pcm_read_async function. More... | |
void | cyhal_pdm_pcm_register_callback (cyhal_pdm_pcm_t *obj, cyhal_pdm_pcm_event_callback_t callback, void *callback_arg) |
Register a PDM/PCM event handler. More... | |
void | cyhal_pdm_pcm_enable_event (cyhal_pdm_pcm_t *obj, cyhal_pdm_pcm_event_t event, uint8_t intr_priority, bool enable) |
Configure PDM/PCM event enablement. More... | |
cy_rslt_t | cyhal_pdm_pcm_set_async_mode (cyhal_pdm_pcm_t *obj, cyhal_async_mode_t mode, uint8_t dma_priority) |
Set the mechanism that is used to perform PDM/PCM asynchronous operation. More... | |
struct cyhal_pdm_pcm_cfg_t |
Data Fields | ||
---|---|---|
uint32_t | sample_rate | Sample rate in Hz. |
uint8_t | decimation_rate | PDM decimation rate. |
cyhal_pdm_pcm_mode_t | mode | left, right, or stereo |
uint8_t | word_length | PCM word length in bits, see the implementation specific documentation for valid range. |
int16_t | left_gain |
PGA in 0.5 dB increment, for example a value of 5 would mean +2.5 dB. The closest fit value will be used, see the implementation specific documentation for valid ranges. This may be negative if the implementation supports it. |
int16_t | right_gain |
PGA in 0.5 dB increment, for example a value of 5 would mean +2.5 dB. The closest fit value will be used, see the implementation specific documentation for valid ranges. This may be negative if the implementation supports it. |
PDM/PCM interrupt triggers.
enum cyhal_pdm_pcm_mode_t |
cy_rslt_t cyhal_pdm_pcm_init | ( | cyhal_pdm_pcm_t * | obj, |
cyhal_gpio_t | pin_data, | ||
cyhal_gpio_t | pin_clk, | ||
const cyhal_clock_t * | clk_source, | ||
const cyhal_pdm_pcm_cfg_t * | cfg | ||
) |
Initialize the PDM/PCM peripheral.
Configures the pins used by PDM/PCM converter, sets a default format and frequency, and enables the peripheral
[out] | obj | Pointer to a PDM/PCM object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | pin_data | The pin to use for PDM input |
[in] | pin_clk | The pin to use for PDM clock output |
[in] | clk_source | The clock source for PDM/PCM block |
[in] | cfg | The configuration for the PDM/PCM block |
cy_rslt_t cyhal_pdm_pcm_init_cfg | ( | cyhal_pdm_pcm_t * | obj, |
const cyhal_pdm_pcm_configurator_t * | cfg | ||
) |
Initialize the PDM/PCM out peripheral using a configurator generated configuration struct.
[out] | obj | Pointer to a PDM/PCM object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | cfg | Configuration structure generated by a configurator. |
void cyhal_pdm_pcm_free | ( | cyhal_pdm_pcm_t * | obj | ) |
Release a PDM/PCM object, behavior is undefined if an asynchronous read is in progress.
Return the peripheral, pins and clock owned by the PDM/PCM object to their reset state
[in,out] | obj | The PDM/PCM object to deinitialize |
cy_rslt_t cyhal_pdm_pcm_start | ( | cyhal_pdm_pcm_t * | obj | ) |
Start the PDM/PCM operation.
[in] | obj | The PDM/PCM object to start |
cy_rslt_t cyhal_pdm_pcm_stop | ( | cyhal_pdm_pcm_t * | obj | ) |
Stop the PDM/PCM operation.
[in] | obj | The PDM/PCM object to start |
bool cyhal_pdm_pcm_is_enabled | ( | cyhal_pdm_pcm_t * | obj | ) |
Checks if the specified PDM/PCM peripheral is enabled (regardless of whether any unread data has been received).
The PDM/PCM peripheral can be enabled by calling cyhal_pdm_pcm_start and disabled by calling cyhal_pdm_pcm_stop
[in] | obj | The I2S peripheral to check |
cy_rslt_t cyhal_pdm_pcm_set_gain | ( | cyhal_pdm_pcm_t * | obj, |
int16_t | gain_left, | ||
int16_t | gain_right | ||
) |
Updates the PDM/PCM channel gains.
Each integer increment represent a 0.5 dB value. For example: a gain value of 5 would mean +2.5 dB. If the exact gain value requested is not supported, it will be rounded to the nearest legal value. See the implementation specific documentation for valid ranges.
[in] | obj | The PDM/PCM object to configure |
[in] | gain_left | The gain of the left channel in units of 0.5 dB |
[in] | gain_right | The gain of the right channel in units of 0.5 dB |
cy_rslt_t cyhal_pdm_pcm_clear | ( | cyhal_pdm_pcm_t * | obj | ) |
Clears the hardware buffer.
[in] | obj | The PDM/PCM peripheral |
cy_rslt_t cyhal_pdm_pcm_read | ( | cyhal_pdm_pcm_t * | obj, |
void * | data, | ||
size_t * | length | ||
) |
Reads data synchronously.
This will read either length
words or the number of words that are currently available in the receive buffer, whichever is less, then return. The value pointed to by length
will be updated to reflect the number of words that were actually read. If there are less data in FIFO than length, length will be update with number of words read.
[in] | obj | The PDM/PCM peripheral |
[out] | data | Pointer to word array where incoming data will be stored. Buffer must be aligned to word-size. Each word will be aligned to the next largest power of 2. For example, if the word length is 16 bits, each word will consume two bytes. But if the word length is 20, each word will consume 32 bits. Negative value will use sign-extension. -1 with 24-bit word length will have 32-bit value of 0xFFFFFFFF. |
[in,out] | length | Number of 32-bit words to read, updated with the number actually read |
cy_rslt_t cyhal_pdm_pcm_read_async | ( | cyhal_pdm_pcm_t * | obj, |
void * | data, | ||
size_t | length | ||
) |
Begin asynchronous PDM/PCM read.
This will transfer length
words into the buffer pointed to by data
in the background. When the requested quantity of data has been read, the CYHAL_PDM_PCM_ASYNC_COMPLETE event will be raised. See cyhal_pdm_pcm_register_callback and cyhal_pdm_pcm_enable_event.
cyhal_pdm_pcm_set_async_mode can be used to control whether this uses DMA or a CPU-driven transfer.
Refer to DCACHE_Management for more information.
[in] | obj | The PDM/PCM object |
[out] | data | Pointer to word array where incoming data will be stored. Buffer must be aligned to word-size. Each word will be aligned to the next largest power of 2. For example, if the word length is 16 bits, each word will consume two bytes. But if the word length is 20, each word will consume 32 bits. Negative value will use sign-extension. -1 with 24-bit word length will have 32-bit value of 0xFFFFFFFF. |
[in] | length | Number of words to read |
bool cyhal_pdm_pcm_is_pending | ( | cyhal_pdm_pcm_t * | obj | ) |
Checks if an async read operation is pending.
[in] | obj | The PDM/PCM peripheral to check |
cy_rslt_t cyhal_pdm_pcm_abort_async | ( | cyhal_pdm_pcm_t * | obj | ) |
Abort an PDM/PCM operation started by cyhal_pdm_pcm_read_async function.
[in] | obj | The PDM/PCM peripheral to stop |
void cyhal_pdm_pcm_register_callback | ( | cyhal_pdm_pcm_t * | obj, |
cyhal_pdm_pcm_event_callback_t | callback, | ||
void * | callback_arg | ||
) |
Register a PDM/PCM event handler.
This function will be called when one of the events enabled by cyhal_pdm_pcm_enable_event occurs.
[in] | obj | The PDM/PCM object |
[in] | callback | The callback handler which will be invoked when the interrupt fires |
[in] | callback_arg | Generic argument that will be provided to the callback when called |
void cyhal_pdm_pcm_enable_event | ( | cyhal_pdm_pcm_t * | obj, |
cyhal_pdm_pcm_event_t | event, | ||
uint8_t | intr_priority, | ||
bool | enable | ||
) |
Configure PDM/PCM event enablement.
[in] | obj | The PDM/PCM object |
[in] | event | The PDM/PCM event type |
[in] | intr_priority | The priority for NVIC interrupt events |
[in] | enable | True to turn on events, False to turn off |
cy_rslt_t cyhal_pdm_pcm_set_async_mode | ( | cyhal_pdm_pcm_t * | obj, |
cyhal_async_mode_t | mode, | ||
uint8_t | dma_priority | ||
) |
Set the mechanism that is used to perform PDM/PCM asynchronous operation.
The default is SW.
When an enabled event occurs, the function specified by cyhal_pdm_pcm_register_callback will be called.
[in] | obj | The PDM/PCM object |
[in] | mode | The transfer mode |
[in] | dma_priority | The priority, if DMA is used. Valid values are the same as for cyhal_dma_init. If DMA is not selected, the only valid value is CYHAL_DMA_PRIORITY_DEFAULT, and no guarantees are made about prioritization. |