2022-03-13 23:34:46 -04:00
/*
2023-01-31 01:36:21 -05:00
* SPDX - FileCopyrightText : 2022 - 2023 Espressif Systems ( Shanghai ) CO LTD
2022-03-13 23:34:46 -04:00
*
* SPDX - License - Identifier : Apache - 2.0
*/
/**
* This file is specified for I2S PDM communication mode
* Features :
2023-10-10 21:38:28 -04:00
* - Only support PDM TX / RX mode
2022-03-13 23:34:46 -04:00
* - Fixed to 2 slots
* - Data bit width only support 16 bits
*/
# pragma once
# include "hal/i2s_types.h"
2021-08-18 07:45:51 -04:00
# include "hal/gpio_types.h"
2022-04-02 09:31:35 -04:00
# include "driver/i2s_common.h"
2022-03-13 23:34:46 -04:00
# ifdef __cplusplus
extern " C " {
# endif
# if SOC_I2S_SUPPORTS_PDM_RX
2023-08-02 07:21:54 -04:00
# if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
2022-03-13 23:34:46 -04:00
/**
* @ brief PDM format in 2 slots ( RX )
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width , only support 16 bits for PDM mode
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_PDM_RX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-06-20 08:30:31 -04:00
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
I2S_PDM_SLOT_LEFT : I2S_PDM_SLOT_BOTH , \
2023-09-05 22:55:47 -04:00
. hp_en = true , \
. hp_cut_off_freq_hz = 35.5 , \
2023-08-02 07:21:54 -04:00
. amplify_num = 1 , \
2022-03-13 23:34:46 -04:00
}
2023-08-02 07:21:54 -04:00
# else
2023-06-16 03:15:23 -04:00
/**
* @ brief PDM format in 2 slots ( RX )
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width , only support 16 bits for PDM mode
2023-06-16 03:15:23 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_PDM_RX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
. slot_mode = mono_or_stereo , \
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
I2S_PDM_SLOT_LEFT : I2S_PDM_SLOT_BOTH , \
}
# endif // SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
2023-08-02 07:21:54 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S default PDM RX clock configuration
2023-08-02 07:21:54 -04:00
* @ param rate sample rate
*/
# define I2S_PDM_RX_CLK_DEFAULT_CONFIG(rate) { \
. sample_rate_hz = rate , \
. clk_src = I2S_CLK_SRC_DEFAULT , \
. mclk_multiple = I2S_MCLK_MULTIPLE_256 , \
. dn_sample_mode = I2S_PDM_DSR_8S , \
. bclk_div = 8 , \
}
2022-03-13 23:34:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S slot configuration for PDM RX mode
2022-03-13 23:34:46 -04:00
*/
typedef struct {
/* General fields */
i2s_data_bit_width_t data_bit_width ; /*!< I2S sample data bit width (valid data bits per sample), only support 16 bits for PDM mode */
i2s_slot_bit_width_t slot_bit_width ; /*!< I2S slot bit width (total bits per slot) , only support 16 bits for PDM mode */
i2s_slot_mode_t slot_mode ; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */
2022-06-20 08:30:31 -04:00
/* Particular fields */
i2s_pdm_slot_mask_t slot_mask ; /*!< Choose the slots to activate */
2023-06-16 03:15:23 -04:00
# if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
bool hp_en ; /*!< High pass filter enable */
float hp_cut_off_freq_hz ; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */
2023-09-05 22:55:47 -04:00
uint32_t amplify_num ; /*!< The amplification number of the final conversion result.
2023-10-10 21:38:28 -04:00
* The data that have converted from PDM to PCM module , will time ` amplify_num ` additionally to amplify the final result .
2023-09-05 22:55:47 -04:00
* Note that it ' s only a multiplier of the digital PCM data , not the gain of the analog signal
* range 1 ~ 15 , default 1 */
2023-06-16 03:15:23 -04:00
# endif // SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
2022-03-13 23:34:46 -04:00
} i2s_pdm_rx_slot_config_t ;
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S clock configuration for PDM RX mode
2022-03-13 23:34:46 -04:00
*/
typedef struct {
/* General fields */
uint32_t sample_rate_hz ; /*!< I2S sample rate */
i2s_clock_src_t clk_src ; /*!< Choose clock source */
2023-10-10 21:38:28 -04:00
i2s_mclk_multiple_t mclk_multiple ; /*!< The multiple of MCLK to the sample rate */
2022-03-13 23:34:46 -04:00
/* Particular fields */
i2s_pdm_dsr_t dn_sample_mode ; /*!< Down-sampling rate mode */
2023-10-10 21:38:28 -04:00
uint32_t bclk_div ; /*!< The division from MCLK to BCLK. The typical and minimum value is I2S_PDM_RX_BCLK_DIV_MIN.
2023-04-26 04:39:13 -04:00
* It will be set to I2S_PDM_RX_BCLK_DIV_MIN by default if it is smaller than I2S_PDM_RX_BCLK_DIV_MIN */
2022-03-13 23:34:46 -04:00
} i2s_pdm_rx_clk_config_t ;
2021-08-18 07:45:51 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S PDM TX mode GPIO pins configuration
2021-08-18 07:45:51 -04:00
*/
typedef struct {
2022-10-24 05:33:49 -04:00
gpio_num_t clk ; /*!< PDM clk pin, output */
union {
gpio_num_t din ; /*!< DATA pin 0, input */
gpio_num_t dins [ SOC_I2S_PDM_MAX_RX_LINES ] ; /*!< DATA pins, input, only take effect when corresponding I2S_PDM_RX_LINEx_SLOT_xxx is enabled in i2s_pdm_rx_slot_config_t::slot_mask */
} ;
2022-04-07 03:32:46 -04:00
struct {
uint32_t clk_inv : 1 ; /*!< Set 1 to invert the clk output */
} invert_flags ; /*!< GPIO pin invert flags */
2021-08-18 07:45:51 -04:00
} i2s_pdm_rx_gpio_config_t ;
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S PDM RX mode major configuration that including clock / slot / GPIO configuration
2022-04-07 03:32:46 -04:00
*/
typedef struct {
2022-12-22 02:16:26 -05:00
i2s_pdm_rx_clk_config_t clk_cfg ; /*!< PDM RX clock configurations, can be generated by macro I2S_PDM_RX_CLK_DEFAULT_CONFIG */
i2s_pdm_rx_slot_config_t slot_cfg ; /*!< PDM RX slot configurations, can be generated by macro I2S_PDM_RX_SLOT_DEFAULT_CONFIG */
2022-04-07 03:32:46 -04:00
i2s_pdm_rx_gpio_config_t gpio_cfg ; /*!< PDM RX slot configurations, specified by user */
2021-08-18 07:45:51 -04:00
} i2s_pdm_rx_config_t ;
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Initialize I2S channel to PDM RX mode
2022-04-07 03:32:46 -04:00
* @ note Only allowed to be called when the channel state is REGISTERED , ( i . e . , channel has been allocated , but not initialized )
* and the state will be updated to READY if initialization success , otherwise the state will return to REGISTERED .
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S RX channel handler
* @ param [ in ] pdm_rx_cfg Configurations for PDM RX mode , including clock , slot and GPIO
2022-04-07 03:32:46 -04:00
* The clock configuration can be generated by the helper macro ` I2S_PDM_RX_CLK_DEFAULT_CONFIG `
* The slot configuration can be generated by the helper macro ` I2S_PDM_RX_SLOT_DEFAULT_CONFIG `
*
* @ return
* - ESP_OK Initialize successfully
* - ESP_ERR_NO_MEM No memory for storing the channel information
* - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
* - ESP_ERR_INVALID_STATE This channel is not registered
*/
esp_err_t i2s_channel_init_pdm_rx_mode ( i2s_chan_handle_t handle , const i2s_pdm_rx_config_t * pdm_rx_cfg ) ;
2022-04-02 09:31:35 -04:00
2022-04-07 03:32:46 -04:00
/**
* @ brief Reconfigure the I2S clock for PDM RX mode
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to PDM RX mode , i . e . , ` i2s_channel_init_pdm_rx_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S RX channel handler
2022-04-07 03:32:46 -04:00
* @ param [ in ] clk_cfg PDM RX mode clock configuration , can be generated by ` I2S_PDM_RX_CLK_DEFAULT_CONFIG `
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not PDM mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_pdm_rx_clock ( i2s_chan_handle_t handle , const i2s_pdm_rx_clk_config_t * clk_cfg ) ;
2022-04-02 09:31:35 -04:00
2022-04-07 03:32:46 -04:00
/**
* @ brief Reconfigure the I2S slot for PDM RX mode
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to PDM RX mode , i . e . , ` i2s_channel_init_pdm_rx_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S RX channel handler
2022-04-07 03:32:46 -04:00
* @ param [ in ] slot_cfg PDM RX mode slot configuration , can be generated by ` I2S_PDM_RX_SLOT_DEFAULT_CONFIG `
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_NO_MEM No memory for DMA buffer
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not PDM mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_pdm_rx_slot ( i2s_chan_handle_t handle , const i2s_pdm_rx_slot_config_t * slot_cfg ) ;
2022-04-02 09:31:35 -04:00
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Reconfigure the I2S GPIO for PDM RX mode
2022-04-07 03:32:46 -04:00
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to PDM RX mode , i . e . , ` i2s_channel_init_pdm_rx_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S RX channel handler
* @ param [ in ] gpio_cfg PDM RX mode GPIO configuration , specified by user
2022-04-07 03:32:46 -04:00
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not PDM mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_pdm_rx_gpio ( i2s_chan_handle_t handle , const i2s_pdm_rx_gpio_config_t * gpio_cfg ) ;
2022-04-02 09:31:35 -04:00
2022-03-13 23:34:46 -04:00
# endif // SOC_I2S_SUPPORTS_PDM_RX
# if SOC_I2S_SUPPORTS_PDM_TX
# if SOC_I2S_HW_VERSION_2
/**
2023-04-26 04:39:13 -04:00
* @ brief PDM style in 2 slots ( TX ) for codec line mode
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width , only support 16 bits for PDM mode
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
. sd_prescale = 0 , \
. sd_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
2022-06-20 08:30:31 -04:00
. hp_scale = I2S_PDM_SIG_SCALING_DIV_2 , \
2022-03-13 23:34:46 -04:00
. lp_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. sinc_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
2022-06-20 08:30:31 -04:00
. line_mode = I2S_PDM_TX_ONE_LINE_CODEC , \
2022-03-13 23:34:46 -04:00
. hp_en = true , \
2022-06-20 08:30:31 -04:00
. hp_cut_off_freq_hz = 35.5 , \
2022-03-13 23:34:46 -04:00
. sd_dither = 0 , \
2022-06-20 08:30:31 -04:00
. sd_dither2 = 1 , \
2022-03-13 23:34:46 -04:00
}
2023-04-26 04:39:13 -04:00
/**
* @ brief PDM style in 1 slots ( TX ) for DAC line mode
* @ note The noise might be different with different configurations , this macro provides a set of configurations
* that have relatively high SNR ( Signal Noise Ratio ) , you can also adjust them to fit your case .
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width , only support 16 bits for PDM mode
2023-04-26 04:39:13 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_PDM_TX_SLOT_DAC_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
. slot_mode = mono_or_stereo , \
. sd_prescale = 0 , \
. sd_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. hp_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. lp_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. sinc_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. line_mode = ( ( mono_or_stereo ) = = I2S_SLOT_MODE_MONO ? \
I2S_PDM_TX_ONE_LINE_DAC : I2S_PDM_TX_TWO_LINE_DAC ) , \
. hp_en = true , \
. hp_cut_off_freq_hz = 35.5 , \
. sd_dither = 0 , \
. sd_dither2 = 1 , \
}
2022-06-20 08:30:31 -04:00
# else // SOC_I2S_HW_VERSION_2
2022-03-13 23:34:46 -04:00
/**
2023-04-26 04:39:13 -04:00
* @ brief PDM style in 2 slots ( TX ) for codec line mode
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width , only support 16 bits for PDM mode
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-07-04 23:22:27 -04:00
. slot_mask = I2S_PDM_SLOT_BOTH , \
2022-03-13 23:34:46 -04:00
. sd_prescale = 0 , \
. sd_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. hp_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. lp_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
. sinc_scale = I2S_PDM_SIG_SCALING_MUL_1 , \
}
# endif // SOC_I2S_HW_VERSION_2
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S default PDM TX clock configuration for codec line mode
2022-03-13 23:34:46 -04:00
* @ note TX PDM can only be set to the following two up - sampling rate configurations :
* 1 : fp = 960 , fs = sample_rate_hz / 100 , in this case , Fpdm = 128 * 48000
* 2 : fp = 960 , fs = 480 , in this case , Fpdm = 128 * Fpcm = 128 * sample_rate_hz
2023-10-10 21:38:28 -04:00
* If the PDM receiver do not care the PDM serial clock , it ' s recommended set Fpdm = 128 * 48000.
2022-04-07 03:32:46 -04:00
* Otherwise , the second configuration should be adopted .
2022-12-22 02:28:28 -05:00
* @ param rate sample rate ( not suggest to exceed 48000 Hz , otherwise more glitches and noise may appear )
2022-03-13 23:34:46 -04:00
*/
# define I2S_PDM_TX_CLK_DEFAULT_CONFIG(rate) { \
. sample_rate_hz = rate , \
2022-04-07 03:32:46 -04:00
. clk_src = I2S_CLK_SRC_DEFAULT , \
2022-03-13 23:34:46 -04:00
. mclk_multiple = I2S_MCLK_MULTIPLE_256 , \
. up_sample_fp = 960 , \
2022-06-20 08:30:31 -04:00
. up_sample_fs = 480 , \
2023-04-26 04:39:13 -04:00
. bclk_div = 8 , \
}
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S default PDM TX clock configuration for DAC line mode
2023-04-26 04:39:13 -04:00
* @ note TX PDM can only be set to the following two up - sampling rate configurations :
* 1 : fp = 960 , fs = sample_rate_hz / 100 , in this case , Fpdm = 128 * 48000
* 2 : fp = 960 , fs = 480 , in this case , Fpdm = 128 * Fpcm = 128 * sample_rate_hz
2023-10-10 21:38:28 -04:00
* If the PDM receiver do not care the PDM serial clock , it ' s recommended set Fpdm = 128 * 48000.
2023-04-26 04:39:13 -04:00
* Otherwise , the second configuration should be adopted .
* @ note The noise might be different with different configurations , this macro provides a set of configurations
* that have relatively high SNR ( Signal Noise Ratio ) , you can also adjust them to fit your case .
* @ param rate sample rate ( not suggest to exceed 48000 Hz , otherwise more glitches and noise may appear )
*/
# define I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG(rate) { \
. sample_rate_hz = rate , \
. clk_src = I2S_CLK_SRC_DEFAULT , \
. mclk_multiple = I2S_MCLK_MULTIPLE_256 , \
. up_sample_fp = 960 , \
. up_sample_fs = ( rate ) / 100 , \
. bclk_div = 13 , \
2022-03-13 23:34:46 -04:00
}
/*
High Pass Filter Cut - off Frequency Sheet
+ - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - +
| param0 , param5 | cut - off freq ( Hz ) | param0 , param5 | cut - off freq ( Hz ) | param0 , param5 | cut - off freq ( Hz ) |
+ - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - +
| ( 0 , 0 ) | 185 | ( 3 , 3 ) | 115 | ( 5 , 5 ) | 69 |
| ( 0 , 1 ) | 172 | ( 1 , 7 ) | 106 | ( 4 , 7 ) | 63 |
| ( 1 , 1 ) | 160 | ( 2 , 4 ) | 104 | ( 5 , 6 ) | 58 |
| ( 1 , 2 ) | 150 | ( 4 , 4 ) | 92 | ( 5 , 7 ) | 49 |
| ( 2 , 2 ) | 137 | ( 2 , 7 ) | 91.5 | ( 6 , 6 ) | 46 |
| ( 2 , 3 ) | 126 | ( 4 , 5 ) | 81 | ( 6 , 7 ) | 35.5 |
| ( 0 , 3 ) | 120 | ( 3 , 7 ) | 77.2 | ( 7 , 7 ) | 23.3 |
+ - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - +
*/
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S slot configuration for PDM TX mode
2022-03-13 23:34:46 -04:00
*/
typedef struct {
/* General fields */
i2s_data_bit_width_t data_bit_width ; /*!< I2S sample data bit width (valid data bits per sample), only support 16 bits for PDM mode */
i2s_slot_bit_width_t slot_bit_width ; /*!< I2S slot bit width (total bits per slot), only support 16 bits for PDM mode */
2022-06-20 08:30:31 -04:00
i2s_slot_mode_t slot_mode ; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
* For PDM TX mode , mono means the data buffer only contains one slot data ,
* Stereo means the data buffer contains two slots data
*/
2022-03-13 23:34:46 -04:00
/* Particular fields */
2022-07-04 23:22:27 -04:00
# if SOC_I2S_HW_VERSION_1
i2s_pdm_slot_mask_t slot_mask ; /*!< Slot mask to choose left or right slot */
# endif
2022-03-13 23:34:46 -04:00
uint32_t sd_prescale ; /*!< Sigma-delta filter prescale */
i2s_pdm_sig_scale_t sd_scale ; /*!< Sigma-delta filter scaling value */
i2s_pdm_sig_scale_t hp_scale ; /*!< High pass filter scaling value */
i2s_pdm_sig_scale_t lp_scale ; /*!< Low pass filter scaling value */
i2s_pdm_sig_scale_t sinc_scale ; /*!< Sinc filter scaling value */
# if SOC_I2S_HW_VERSION_2
2022-12-22 02:28:28 -05:00
i2s_pdm_tx_line_mode_t line_mode ; /*!< PDM TX line mode, one-line codec, one-line dac, two-line dac mode can be selected */
2023-09-05 22:55:47 -04:00
bool hp_en ; /*!< High pass filter enable */
float hp_cut_off_freq_hz ; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */
2022-03-13 23:34:46 -04:00
uint32_t sd_dither ; /*!< Sigma-delta filter dither */
uint32_t sd_dither2 ; /*!< Sigma-delta filter dither2 */
# endif // SOC_I2S_HW_VERSION_2
} i2s_pdm_tx_slot_config_t ;
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S clock configuration for PDM TX mode
2022-03-13 23:34:46 -04:00
*/
typedef struct {
/* General fields */
2022-12-22 02:28:28 -05:00
uint32_t sample_rate_hz ; /*!< I2S sample rate, not suggest to exceed 48000 Hz, otherwise more glitches and noise may appear */
2022-03-13 23:34:46 -04:00
i2s_clock_src_t clk_src ; /*!< Choose clock source */
2023-10-10 21:38:28 -04:00
i2s_mclk_multiple_t mclk_multiple ; /*!< The multiple of MCLK to the sample rate */
2022-03-13 23:34:46 -04:00
/* Particular fields */
uint32_t up_sample_fp ; /*!< Up-sampling param fp */
2022-12-22 02:28:28 -05:00
uint32_t up_sample_fs ; /*!< Up-sampling param fs, not allowed to be greater than 480 */
2023-10-10 21:38:28 -04:00
uint32_t bclk_div ; /*!< The division from MCLK to BCLK. The minimum value is I2S_PDM_TX_BCLK_DIV_MIN.
2023-04-26 04:39:13 -04:00
* It will be set to I2S_PDM_TX_BCLK_DIV_MIN by default if it is smaller than I2S_PDM_TX_BCLK_DIV_MIN */
2022-03-13 23:34:46 -04:00
} i2s_pdm_tx_clk_config_t ;
2021-08-18 07:45:51 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S PDM TX mode GPIO pins configuration
2021-08-18 07:45:51 -04:00
*/
typedef struct {
gpio_num_t clk ; /*!< PDM clk pin, output */
gpio_num_t dout ; /*!< DATA pin, output */
2022-10-24 05:33:49 -04:00
# if SOC_I2S_PDM_MAX_TX_LINES > 1
2022-06-20 08:30:31 -04:00
gpio_num_t dout2 ; /*!< The second data pin for the DAC dual-line mode,
* only take effect when the line mode is ` I2S_PDM_TX_TWO_LINE_DAC `
*/
# endif
2022-04-07 03:32:46 -04:00
struct {
uint32_t clk_inv : 1 ; /*!< Set 1 to invert the clk output */
} invert_flags ; /*!< GPIO pin invert flags */
2021-08-18 07:45:51 -04:00
} i2s_pdm_tx_gpio_config_t ;
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S PDM TX mode major configuration that including clock / slot / GPIO configuration
2022-04-07 03:32:46 -04:00
*/
typedef struct {
2022-12-22 02:16:26 -05:00
i2s_pdm_tx_clk_config_t clk_cfg ; /*!< PDM TX clock configurations, can be generated by macro I2S_PDM_TX_CLK_DEFAULT_CONFIG */
i2s_pdm_tx_slot_config_t slot_cfg ; /*!< PDM TX slot configurations, can be generated by macro I2S_PDM_TX_SLOT_DEFAULT_CONFIG */
2023-10-10 21:38:28 -04:00
i2s_pdm_tx_gpio_config_t gpio_cfg ; /*!< PDM TX GPIO configurations, specified by user */
2021-08-18 07:45:51 -04:00
} i2s_pdm_tx_config_t ;
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Initialize I2S channel to PDM TX mode
2022-04-07 03:32:46 -04:00
* @ note Only allowed to be called when the channel state is REGISTERED , ( i . e . , channel has been allocated , but not initialized )
* and the state will be updated to READY if initialization success , otherwise the state will return to REGISTERED .
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S TX channel handler
* @ param [ in ] pdm_tx_cfg Configurations for PDM TX mode , including clock , slot and GPIO
2022-04-07 03:32:46 -04:00
* The clock configuration can be generated by the helper macro ` I2S_PDM_TX_CLK_DEFAULT_CONFIG `
* The slot configuration can be generated by the helper macro ` I2S_PDM_TX_SLOT_DEFAULT_CONFIG `
*
* @ return
* - ESP_OK Initialize successfully
* - ESP_ERR_NO_MEM No memory for storing the channel information
* - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
* - ESP_ERR_INVALID_STATE This channel is not registered
*/
esp_err_t i2s_channel_init_pdm_tx_mode ( i2s_chan_handle_t handle , const i2s_pdm_tx_config_t * pdm_tx_cfg ) ;
2022-04-02 09:31:35 -04:00
2022-04-07 03:32:46 -04:00
/**
* @ brief Reconfigure the I2S clock for PDM TX mode
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to PDM TX mode , i . e . , ` i2s_channel_init_pdm_tx_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S TX channel handler
2022-04-07 03:32:46 -04:00
* @ param [ in ] clk_cfg PDM TX mode clock configuration , can be generated by ` I2S_PDM_TX_CLK_DEFAULT_CONFIG `
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not PDM mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_pdm_tx_clock ( i2s_chan_handle_t handle , const i2s_pdm_tx_clk_config_t * clk_cfg ) ;
2022-04-02 09:31:35 -04:00
2022-04-07 03:32:46 -04:00
/**
* @ brief Reconfigure the I2S slot for PDM TX mode
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to PDM TX mode , i . e . , ` i2s_channel_init_pdm_tx_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S TX channel handler
2022-04-07 03:32:46 -04:00
* @ param [ in ] slot_cfg PDM TX mode slot configuration , can be generated by ` I2S_PDM_TX_SLOT_DEFAULT_CONFIG `
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_NO_MEM No memory for DMA buffer
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not PDM mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_pdm_tx_slot ( i2s_chan_handle_t handle , const i2s_pdm_tx_slot_config_t * slot_cfg ) ;
2022-04-02 09:31:35 -04:00
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Reconfigure the I2S GPIO for PDM TX mode
2022-04-07 03:32:46 -04:00
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to PDM TX mode , i . e . , ` i2s_channel_init_pdm_tx_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
2023-10-10 21:38:28 -04:00
* @ param [ in ] handle I2S TX channel handler
* @ param [ in ] gpio_cfg PDM TX mode GPIO configuration , specified by user
2022-04-07 03:32:46 -04:00
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not PDM mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_pdm_tx_gpio ( i2s_chan_handle_t handle , const i2s_pdm_tx_gpio_config_t * gpio_cfg ) ;
2021-08-18 07:45:51 -04:00
2022-03-13 23:34:46 -04:00
# endif // SOC_I2S_SUPPORTS_PDM_TX
# ifdef __cplusplus
}
# endif