mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
Merge branch 'bugfix/i2s_slot_sequence_v4.4' into 'release/v4.4'
i2s: fixed pdm rx sample rate doubled issue See merge request espressif/esp-idf!19415
This commit is contained in:
@@ -1092,6 +1092,8 @@ static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_hal_clock_cfg_t *cl
|
||||
|
||||
/* Check if the configuration is correct */
|
||||
ESP_RETURN_ON_FALSE(clk_cfg->mclk <= clk_cfg->sclk, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
|
||||
ESP_LOGD(TAG, "[sclk] %d [mclk] %d [mclk_div] %d [bclk] %d [bclk_div] %d",
|
||||
clk_cfg->sclk, clk_cfg->mclk, clk_cfg->mclk_div, clk_cfg->bclk, clk_cfg->bclk_div);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1620,7 +1622,11 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_
|
||||
cfg->chan_mask = I2S_TDM_ACTIVE_CH0; // right slot mono
|
||||
cfg->chan_fmt = I2S_CHANNEL_FMT_ONLY_RIGHT;
|
||||
}
|
||||
#if SOC_I2S_SUPPORTS_PDM_RX
|
||||
cfg->total_chan = (p_i2s[i2s_num]->hal_cfg.mode & I2S_MODE_PDM) ? 1 : 2;
|
||||
#else
|
||||
cfg->total_chan = 2;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (ch >> 16) {
|
||||
@@ -1673,6 +1679,13 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_
|
||||
ESP_RETURN_ON_FALSE(p_i2s[i2s_num]->tx, ESP_ERR_INVALID_ARG, TAG, "I2S TX DMA object has not initialized yet");
|
||||
/* Waiting for transmit finish */
|
||||
i2s_tx_set_clk_and_channel(i2s_num, &clk_cfg);
|
||||
/* Workaround for ESP32-S3/C3, overwrite with speicial coefficients to lower down the noise */
|
||||
#if SOC_I2S_SUPPORTS_PDM_CODEC
|
||||
if (p_i2s[i2s_num]->hal_cfg.mode & I2S_MODE_PDM) {
|
||||
i2s_ll_tx_set_raw_clk_div(p_i2s[i2s_num]->hal.dev, 1, 1, 0, 0);
|
||||
}
|
||||
#endif // SOC_I2S_SUPPORTS_PDM_TX
|
||||
|
||||
/* If buffer size changed, the DMA buffer need realloc */
|
||||
if (need_realloc) {
|
||||
p_i2s[i2s_num]->tx->buf_size = buf_size;
|
||||
|
@@ -217,6 +217,23 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
hw->tx_conf1.tx_bck_div_num = val - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2S tx raw clock division
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param x div x
|
||||
* @param y div y
|
||||
* @param z div z
|
||||
* @param yn1 yn1
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_x = x;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_y = y;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_z = z;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_yn1 = yn1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2S TX clock devider
|
||||
*
|
||||
@@ -608,11 +625,11 @@ static inline void i2s_ll_tx_enable_pdm_hp_filter(i2s_dev_t *hw, bool enable)
|
||||
* @brief Enable I2S TX PDM sigma-delta codec
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param dither I2S TX PDM sigmadelta dither value
|
||||
* @param enable whether enable sd dac one line mode
|
||||
*/
|
||||
static inline void i2s_ll_tx_enable_pdm_sd_codec(i2s_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = enable;
|
||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = !enable;
|
||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_mode_en = enable;
|
||||
}
|
||||
|
||||
|
@@ -218,6 +218,23 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
hw->tx_conf1.tx_bck_div_num = val - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2S tx raw clock division
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param x div x
|
||||
* @param y div y
|
||||
* @param z div z
|
||||
* @param yn1 yn1
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_x = x;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_y = y;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_z = z;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_yn1 = yn1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2S TX clock devider
|
||||
*
|
||||
@@ -609,11 +626,11 @@ static inline void i2s_ll_tx_enable_pdm_hp_filter(i2s_dev_t *hw, bool enable)
|
||||
* @brief Enable I2S TX PDM sigma-delta codec
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param dither I2S TX PDM sigmadelta dither value
|
||||
* @param enable whether enable sd dac one line mode
|
||||
*/
|
||||
static inline void i2s_ll_tx_enable_pdm_sd_codec(i2s_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = enable;
|
||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = !enable;
|
||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_mode_en = enable;
|
||||
}
|
||||
|
||||
|
@@ -220,6 +220,23 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
hw->tx_conf1.tx_bck_div_num = val - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2S tx raw clock division
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param x div x
|
||||
* @param y div y
|
||||
* @param z div z
|
||||
* @param yn1 yn1
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_x = x;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_y = y;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_z = z;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_yn1 = yn1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2S TX clock devider
|
||||
*
|
||||
@@ -663,11 +680,11 @@ static inline void i2s_ll_tx_enable_pdm_hp_filter(i2s_dev_t *hw, bool enable)
|
||||
* @brief Enable I2S TX PDM sigma-delta codec
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param dither I2S TX PDM sigmadelta dither value
|
||||
* @param enable whether enable sd dac one line mode
|
||||
*/
|
||||
static inline void i2s_ll_tx_enable_pdm_sd_codec(i2s_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->tx_pcm2pdm_conf.tx_dac_2out_en = enable;
|
||||
hw->tx_pcm2pdm_conf.tx_dac_2out_en = !enable;
|
||||
hw->tx_pcm2pdm_conf.tx_dac_mode_en = enable;
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/i2s_hal.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/**
|
||||
* @brief Calculate the closest sample rate clock configuration.
|
||||
@@ -97,7 +98,7 @@ void i2s_hal_init(i2s_hal_context_t *hal, int i2s_num)
|
||||
}
|
||||
|
||||
#if SOC_I2S_SUPPORTS_PDM_TX
|
||||
void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rate)
|
||||
void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rate, bool is_mono)
|
||||
{
|
||||
/* enable pdm tx mode */
|
||||
i2s_ll_tx_enable_pdm(hal->dev, true);
|
||||
@@ -129,11 +130,11 @@ void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rat
|
||||
/* set pdm tx high pass filter parameters */
|
||||
i2s_ll_tx_set_pdm_hp_filter_param0(hal->dev, 6);
|
||||
i2s_ll_tx_set_pdm_hp_filter_param5(hal->dev, 7);
|
||||
/* enable pdm sigma-delta codec */
|
||||
i2s_ll_tx_enable_pdm_sd_codec(hal->dev, true);
|
||||
/* enable pdm sigma-delta dac */
|
||||
i2s_ll_tx_enable_pdm_sd_codec(hal->dev, is_mono);
|
||||
/* set pdm tx sigma-delta codec dither */
|
||||
i2s_ll_tx_set_pdm_sd_dither(hal->dev, 0);
|
||||
i2s_ll_tx_set_pdm_sd_dither2(hal->dev, 0);
|
||||
i2s_ll_tx_set_pdm_sd_dither2(hal->dev, 1);
|
||||
|
||||
#endif // SOC_I2S_SUPPORTS_PDM_CODEC
|
||||
}
|
||||
@@ -180,8 +181,12 @@ void i2s_hal_tx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *
|
||||
i2s_ll_tx_enable_big_endian(hal->dev, hal_cfg->big_edin);
|
||||
i2s_ll_tx_set_bit_order(hal->dev, hal_cfg->bit_order_msb);
|
||||
i2s_ll_tx_set_skip_mask(hal->dev, hal_cfg->skip_msk);
|
||||
#else
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
i2s_ll_tx_enable_msb_right(hal->dev, hal_cfg->sample_bits <= I2S_BITS_PER_SAMPLE_16BIT);
|
||||
#else
|
||||
i2s_ll_tx_enable_msb_right(hal->dev, false);
|
||||
#endif
|
||||
i2s_ll_tx_enable_right_first(hal->dev, false);
|
||||
i2s_ll_tx_force_enable_fifo_mod(hal->dev, true);
|
||||
#endif
|
||||
@@ -204,8 +209,12 @@ void i2s_hal_rx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *
|
||||
i2s_ll_rx_enable_left_align(hal->dev, hal_cfg->left_align);
|
||||
i2s_ll_rx_enable_big_endian(hal->dev, hal_cfg->big_edin);
|
||||
i2s_ll_rx_set_bit_order(hal->dev, hal_cfg->bit_order_msb);
|
||||
#else
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
i2s_ll_rx_enable_msb_right(hal->dev, hal_cfg->sample_bits <= I2S_BITS_PER_SAMPLE_16BIT);
|
||||
#else
|
||||
i2s_ll_rx_enable_msb_right(hal->dev, false);
|
||||
#endif
|
||||
i2s_ll_rx_enable_right_first(hal->dev, false);
|
||||
i2s_ll_rx_force_enable_fifo_mod(hal->dev, true);
|
||||
#endif
|
||||
@@ -240,6 +249,13 @@ void i2s_hal_tx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t
|
||||
i2s_ll_tx_set_chan_num(hal->dev, chan_num);
|
||||
#else
|
||||
i2s_ll_tx_set_chan_mod(hal->dev, hal_cfg->chan_fmt < I2S_CHANNEL_FMT_ONLY_RIGHT ? hal_cfg->chan_fmt : (hal_cfg->chan_fmt >> 1)); // 0-two channel;1-right;2-left;3-righ;4-left
|
||||
#endif
|
||||
#if SOC_I2S_SUPPORTS_PDM_CODEC
|
||||
if (hal_cfg->mode & I2S_MODE_PDM) {
|
||||
// Fixed to 16 while using mono mode and 32 while using stereo mode
|
||||
data_bits = hal_cfg->chan_fmt == I2S_CHANNEL_FMT_RIGHT_LEFT ? 32 : 16;
|
||||
chan_bits = data_bits;
|
||||
}
|
||||
#endif
|
||||
i2s_ll_tx_set_sample_bit(hal->dev, chan_bits, data_bits);
|
||||
i2s_ll_tx_enable_mono_mode(hal->dev, is_mono);
|
||||
@@ -250,7 +266,13 @@ void i2s_hal_tx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t
|
||||
i2s_ll_tx_enable_msb_shift(hal->dev, shift_en);
|
||||
i2s_ll_tx_set_ws_width(hal->dev, ws_width);
|
||||
#if SOC_I2S_SUPPORTS_TDM
|
||||
i2s_ll_tx_set_half_sample_bit(hal->dev, chan_num * chan_bits / 2);
|
||||
uint32_t half_sample_bits = chan_num * chan_bits / 2;
|
||||
#if SOC_I2S_SUPPORTS_PDM_CODEC
|
||||
if (hal_cfg->mode & I2S_MODE_PDM) {
|
||||
half_sample_bits = 16; // Fixed to 16 in PDM mode
|
||||
}
|
||||
#endif
|
||||
i2s_ll_tx_set_half_sample_bit(hal->dev, half_sample_bits);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -266,6 +288,9 @@ void i2s_hal_rx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t
|
||||
chan_num = hal_cfg->total_chan;
|
||||
i2s_ll_rx_set_active_chan_mask(hal->dev, hal_cfg->chan_mask >> 16);
|
||||
i2s_ll_rx_set_chan_num(hal->dev, chan_num);
|
||||
#if SOC_I2S_SUPPORTS_PDM_RX
|
||||
is_mono = (hal_cfg->mode & I2S_MODE_PDM) ? false : true;
|
||||
#endif
|
||||
#else
|
||||
i2s_ll_rx_set_chan_mod(hal->dev, hal_cfg->chan_fmt < I2S_CHANNEL_FMT_ONLY_RIGHT ? hal_cfg->chan_fmt : (hal_cfg->chan_fmt >> 1)); // 0-two channel;1-right;2-left;3-righ;4-left
|
||||
#endif
|
||||
@@ -310,7 +335,7 @@ void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cf
|
||||
#if SOC_I2S_SUPPORTS_PDM_TX
|
||||
if (hal_cfg->mode & I2S_MODE_PDM) {
|
||||
/* Set tx pdm mode */
|
||||
i2s_hal_tx_set_pdm_mode_default(hal, hal_cfg->sample_rate);
|
||||
i2s_hal_tx_set_pdm_mode_default(hal, hal_cfg->sample_rate, hal_cfg->chan_fmt != I2S_CHANNEL_FMT_RIGHT_LEFT);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@@ -352,8 +352,9 @@ void i2s_hal_rx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param sample_rate PDM sample rate
|
||||
* @param is_mono whether is mono
|
||||
*/
|
||||
void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rate);
|
||||
void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rate, bool is_mono);
|
||||
#endif
|
||||
|
||||
#if SOC_I2S_SUPPORTS_PDM_RX
|
||||
|
Reference in New Issue
Block a user