diff --git a/components/driver/i2s.c b/components/driver/i2s.c index 74f0fa4072..44399e6641 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -413,17 +413,19 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b } else if (p_i2s_obj[i2s_num]->mode & I2S_MODE_PDM) { uint32_t b_clk = 0; if (p_i2s_obj[i2s_num]->mode & I2S_MODE_TX) { - int fp; - int fs; + uint32_t fp, fs; i2s_hal_get_tx_pdm(&(p_i2s_obj[i2s_num]->hal), &fp, &fs); - b_clk = rate * I2S_PDM_BCK_FACTOR * (fp / fs); - fi2s_clk /= (I2S_PDM_BCK_FACTOR * (fp / fs)); + // Recommended set `fp = 960, fs = sample_rate / 100` + fs = rate / 100; + i2s_hal_tx_pdm_cfg(&(p_i2s_obj[i2s_num]->hal), fp, fs); + b_clk = rate * I2S_PDM_BCK_FACTOR * fp / fs; + } else if (p_i2s_obj[i2s_num]->mode & I2S_MODE_RX) { - bool en; - i2s_hal_get_rx_sinc_dsr_16_en(&(p_i2s_obj[i2s_num]->hal), &en); - b_clk = rate * I2S_PDM_BCK_FACTOR * (en ? 2 : 1); - fi2s_clk /= (I2S_PDM_BCK_FACTOR * (en ? 2 : 1)); + uint32_t dsr; + i2s_hal_get_rx_pdm(&(p_i2s_obj[i2s_num]->hal), &dsr); + b_clk = rate * I2S_PDM_BCK_FACTOR * (dsr ? 2 : 1); } + fi2s_clk = b_clk * m_scale; int factor2 = 5 ; mclk = b_clk * factor2; clkmdiv = ((double) I2S_BASE_CLK) / mclk; @@ -818,7 +820,7 @@ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate) esp_err_t i2s_set_pdm_rx_down_sample(i2s_port_t i2s_num, i2s_pdm_dsr_t dsr) { I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG); - i2s_hal_set_pdm_rx_down_sample(&(p_i2s_obj[i2s_num]->hal), dsr); + i2s_hal_rx_pdm_cfg(&(p_i2s_obj[i2s_num]->hal), dsr); return i2s_set_clk(i2s_num, p_i2s_obj[i2s_num]->sample_rate, p_i2s_obj[i2s_num]->bits_per_sample, p_i2s_obj[i2s_num]->channel_num); } #endif diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index 5b7d93bed1..0b2af70efa 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -390,61 +390,6 @@ static inline void i2s_ll_set_rx_eof_num(i2s_dev_t *hw, uint32_t val) hw->rx_eof_num = val / 4; } -/** - * @brief Get I2S tx pdm fp - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to get tx pdm fp - */ -static inline void i2s_ll_get_tx_pdm_fp(i2s_dev_t *hw, uint32_t *val) -{ - *val = hw->pdm_freq_conf.tx_pdm_fp; -} - -/** - * @brief Get I2S tx pdm fs - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to get tx pdm fs - */ -static inline void i2s_ll_get_tx_pdm_fs(i2s_dev_t *hw, uint32_t *val) -{ - *val = hw->pdm_freq_conf.tx_pdm_fs; -} - -/** - * @brief Set I2S tx pdm fp - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set tx pdm fp - */ -static inline void i2s_ll_set_tx_pdm_fp(i2s_dev_t *hw, uint32_t val) -{ - hw->pdm_freq_conf.tx_pdm_fp = val; -} - -/** - * @brief Set I2S tx pdm fs - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set tx pdm fs - */ -static inline void i2s_ll_set_tx_pdm_fs(i2s_dev_t *hw, uint32_t val) -{ - hw->pdm_freq_conf.tx_pdm_fs = val; -} - -/** - * @brief Get I2S rx sinc dsr 16 en - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to get rx sinc dsr 16 en - */ -static inline void i2s_ll_get_rx_sinc_dsr_16_en(i2s_dev_t *hw, bool *val) -{ - *val = hw->pdm_conf.rx_sinc_dsr_16_en; -} - /** * @brief Set I2S clkm div num * @@ -533,17 +478,6 @@ static inline void i2s_ll_set_rx_bits_mod(i2s_dev_t *hw, uint32_t val) hw->sample_rate_conf.rx_bits_mod = val; } -/** - * @brief Set I2S rx sinc dsr 16 en - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set rx sinc dsr 16 en - */ -static inline void i2s_ll_set_rx_sinc_dsr_16_en(i2s_dev_t *hw, bool val) -{ - hw->pdm_conf.rx_sinc_dsr_16_en = val; -} - /** * @brief Set I2S dscr en * @@ -577,50 +511,6 @@ static inline void i2s_ll_set_camera_en(i2s_dev_t *hw, bool val) hw->conf2.camera_en = val; } -/** - * @brief Set I2S pcm2pdm conv en - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set pcm2pdm conv en - */ -static inline void i2s_ll_set_pcm2pdm_conv_en(i2s_dev_t *hw, bool val) -{ - hw->pdm_conf.pcm2pdm_conv_en = val; -} - -/** - * @brief Set I2S pdm2pcm conv en - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set pdm2pcm conv en - */ -static inline void i2s_ll_set_pdm2pcm_conv_en(i2s_dev_t *hw, bool val) -{ - hw->pdm_conf.pdm2pcm_conv_en = val; -} - -/** - * @brief Set I2S rx pdm en - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set rx pdm en - */ -static inline void i2s_ll_set_rx_pdm_en(i2s_dev_t *hw, bool val) -{ - hw->pdm_conf.rx_pdm_en = val; -} - -/** - * @brief Set I2S tx pdm en - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set tx pdm en - */ -static inline void i2s_ll_set_tx_pdm_en(i2s_dev_t *hw, bool val) -{ - hw->pdm_conf.tx_pdm_en = val; -} - /** * @brief Set I2S tx fifo mod force en * @@ -753,17 +643,6 @@ static inline void i2s_ll_set_rx_mono(i2s_dev_t *hw, uint32_t val) hw->conf.rx_mono = val; } -/** - * @brief Set I2S tx sinc osr2 - * - * @param hw Peripheral I2S hardware instance address. - * @param val value to set tx sinc osr2 - */ -static inline void i2s_ll_set_tx_sinc_osr2(i2s_dev_t *hw, uint32_t val) -{ - hw->pdm_conf.tx_sinc_osr2 = val; -} - /** * @brief Set I2S sig loopback * @@ -863,35 +742,6 @@ static inline void i2s_ll_set_rx_pcm_long(i2s_dev_t *hw) hw->conf.rx_msb_shift = 0; } -/** - * @brief Configure I2S TX pdm - * - * @param sample_rate The sample rate to be set. - * @param hw Peripheral I2S hardware instance address. - */ -static inline void i2s_ll_tx_pdm_cfg(i2s_dev_t *hw, uint32_t sample_rate) -{ - uint32_t fp = 96; - uint32_t fs = sample_rate / 1000 * 10; - hw->pdm_freq_conf.tx_pdm_fp = fp; - hw->pdm_freq_conf.tx_pdm_fs = fs; - hw->pdm_conf.tx_sinc_osr2 = fp/fs; - hw->pdm_conf.pcm2pdm_conv_en = 1; - hw->pdm_conf.tx_pdm_en = 1; -} - -/** - * @brief Configure I2S TX pdm - * - * @param hw Peripheral I2S hardware instance address. - */ -static inline void i2s_ll_rx_pdm_cfg(i2s_dev_t *hw) -{ - hw->pdm_conf.rx_sinc_dsr_16_en = 0; - hw->pdm_conf.pdm2pcm_conv_en = 1; - hw->pdm_conf.rx_pdm_en = 1; -} - /** * @brief Enable I2S build in ADC mode * @@ -919,6 +769,82 @@ static inline void i2s_ll_build_in_dac_ena(i2s_dev_t *hw) hw->conf.tx_short_sync = 0; } + +/** + * @brief Enable I2S RX PDM mode + * + * @param hw Peripheral I2S hardware instance address. + * @param pdm_en Set true to enable rx PDM mode + */ +static inline void i2s_ll_set_rx_pdm_en(i2s_dev_t *hw, bool pdm_en) +{ + hw->pdm_conf.rx_pdm_en = pdm_en; +} + +/** + * @brief Enable I2S tx pdm mode + * + * @param hw Peripheral I2S hardware instance address. + * @param pdm_en Set true to enable tx PDM mode + */ +static inline void i2s_ll_set_tx_pdm_en(i2s_dev_t *hw, bool pdm_en) +{ + hw->pdm_conf.tx_pdm_en = pdm_en; +} + +/** + * @brief Configure I2S tx PDM filter module group0 + * + * @param hw Peripheral I2S hardware instance address. + * @param fp The fp value of TX PDM filter module group0. + * @param fs The fs value of TX PDM filter module group0. + */ +static inline void i2s_ll_tx_pdm_cfg(i2s_dev_t *hw, uint32_t fp, uint32_t fs) +{ + hw->pdm_freq_conf.tx_pdm_fp = fp; + hw->pdm_freq_conf.tx_pdm_fs = fs; + hw->pdm_conf.tx_sinc_osr2 = fp/fs; + hw->pdm_conf.pcm2pdm_conv_en = 1; + hw->pdm_conf.tx_pdm_en = 1; +} + +/** + * @brief Configure I2S rx PDM + * + * @param hw Peripheral I2S hardware instance address. + * @param dsr Down-sampling rate value of rx PDM + */ +static inline void i2s_ll_rx_pdm_cfg(i2s_dev_t *hw, uint32_t dsr) +{ + hw->pdm_conf.rx_sinc_dsr_16_en = dsr; + hw->pdm_conf.pdm2pcm_conv_en = 1; + hw->pdm_conf.rx_pdm_en = 1; +} + +/** + * @brief Get I2S tx PDM configuration + * + * @param hw Peripheral I2S hardware instance address. + * @param fp Pointer to store tx PDM fp configuration + * @param fs Pointer to store tx PDM fs configuration + */ +static inline void i2s_ll_get_tx_pdm(i2s_dev_t *hw, uint32_t *fp, uint32_t *fs) +{ + *fp = hw->pdm_freq_conf.tx_pdm_fp; + *fs = hw->pdm_freq_conf.tx_pdm_fs; +} + +/** + * @brief Get I2S rx PDM configuration + * + * @param hw Peripheral I2S hardware instance address. + * @param dsr Pointer to stoe the rx PDM down-sample rate configuration + */ +static inline void i2s_ll_get_rx_pdm(i2s_dev_t *hw, uint32_t *dsr) +{ + *dsr = hw->pdm_conf.rx_sinc_dsr_16_en; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index cf388425aa..149b5f195f 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -17,6 +17,9 @@ #include "soc/soc.h" #include "hal/i2s_hal.h" +#define I2S_TX_PDM_FP_DEF 960 // Set to the recommended value(960) in TRM +#define I2S_RX_PDM_DSR_DEF 0 + void i2s_hal_set_tx_mode(i2s_hal_context_t *hal, i2s_channel_t ch, i2s_bits_per_sample_t bits) { if (bits <= I2S_BITS_PER_SAMPLE_16BIT) { @@ -50,10 +53,24 @@ void i2s_hal_set_in_link(i2s_hal_context_t *hal, uint32_t bytes_num, uint32_t ad } #if SOC_I2S_SUPPORTS_PDM -void i2s_hal_get_tx_pdm(i2s_hal_context_t *hal, int *fp, int *fs) +void i2s_hal_tx_pdm_cfg(i2s_hal_context_t *hal, uint32_t fp, uint32_t fs) { - i2s_ll_get_tx_pdm_fp(hal->dev, (uint32_t *)fp); - i2s_ll_get_tx_pdm_fs(hal->dev, (uint32_t *)fs); + i2s_ll_tx_pdm_cfg(hal->dev, fp, fs); +} + +void i2s_hal_get_tx_pdm(i2s_hal_context_t *hal, uint32_t *fp, uint32_t *fs) +{ + i2s_ll_get_tx_pdm(hal->dev, fp, fs); +} + +void i2s_hal_rx_pdm_cfg(i2s_hal_context_t *hal, uint32_t dsr) +{ + i2s_ll_rx_pdm_cfg(hal->dev, dsr); +} + +void i2s_hal_get_rx_pdm(i2s_hal_context_t *hal, uint32_t *dsr) +{ + i2s_ll_get_rx_pdm(hal->dev, dsr); } #endif @@ -208,10 +225,10 @@ void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_config_t *i2s_config i2s_ll_set_tx_pdm_en(hal->dev, 0); } else { if (i2s_config->mode & I2S_MODE_TX) { - i2s_ll_tx_pdm_cfg(hal->dev, i2s_config->sample_rate); + i2s_ll_tx_pdm_cfg(hal->dev, I2S_TX_PDM_FP_DEF, i2s_config->sample_rate/100); } if(i2s_config->mode & I2S_MODE_RX) { - i2s_ll_rx_pdm_cfg(hal->dev); + i2s_ll_rx_pdm_cfg(hal->dev, I2S_RX_PDM_DSR_DEF); } // PDM mode have nothing to do with communication format configuration. return; diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index cff02d9896..49b3c1a073 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -151,25 +151,6 @@ void i2s_hal_set_rx_mode(i2s_hal_context_t *hal, i2s_channel_t ch, i2s_bits_per_ */ void i2s_hal_set_in_link(i2s_hal_context_t *hal, uint32_t rx_eof_num, uint32_t addr); -#if SOC_I2S_SUPPORTS_PDM -/** - * @brief Get I2S tx pdm - * - * @param hal Context of the HAL layer - * @param fp tx pdm fp - * @param fs tx pdm fs - */ -void i2s_hal_get_tx_pdm(i2s_hal_context_t *hal, int *fp, int *fs); -#endif - -/** - * @brief Get I2S rx sinc dsr 16 en - * - * @param hal Context of the HAL layer - * @param en 0: disable, 1: enable - */ -#define i2s_hal_get_rx_sinc_dsr_16_en(hal, en) i2s_ll_get_rx_sinc_dsr_16_en((hal)->dev, en) - /** * @brief Set I2S clk div * @@ -241,16 +222,6 @@ void i2s_hal_stop_tx(i2s_hal_context_t *hal); */ void i2s_hal_stop_rx(i2s_hal_context_t *hal); -#if SOC_I2S_SUPPORTS_PDM -/** - * @brief Set I2S pdm rx down sample - * - * @param hal Context of the HAL layer - * @param dsr 0:disable, 1: enable - */ -#define i2s_hal_set_pdm_rx_down_sample(hal, dsr) i2s_ll_set_rx_sinc_dsr_16_en((hal)->dev, dsr) -#endif - /** * @brief Config I2S param * @@ -288,6 +259,42 @@ void i2s_hal_enable_slave_mode(i2s_hal_context_t *hal); */ void i2s_hal_init(i2s_hal_context_t *hal, int i2s_num); +#if SOC_I2S_SUPPORTS_PDM +/** + * @brief Set I2S tx pdm + * + * @param hal Context of the HAL layer + * @param fp tx pdm fp + * @param fs tx pdm fs + */ +void i2s_hal_tx_pdm_cfg(i2s_hal_context_t *hal, uint32_t fp, uint32_t fs); + +/** + * @brief Get I2S tx pdm + * + * @param hal Context of the HAL layer + * @param dsr rx pdm dsr + */ +void i2s_hal_rx_pdm_cfg(i2s_hal_context_t *hal, uint32_t dsr); + +/** + * @brief Get I2S tx pdm configuration + * + * @param hal Context of the HAL layer + * @param fp Pointer to receive tx PDM fp configuration + * @param fs Pointer to receive tx PDM fs configuration + */ +void i2s_hal_get_tx_pdm(i2s_hal_context_t *hal, uint32_t *fp, uint32_t *fs); + +/** + * @brief Get I2S rx pdm configuration + * + * @param hal Context of the HAL layer + * @param dsr rx pdm dsr + */ +void i2s_hal_get_rx_pdm(i2s_hal_context_t *hal, uint32_t *dsr); +#endif + #ifdef __cplusplus } #endif