i2s: fixed pdm rx sample rate doubled issue

Closes: https://github.com/espressif/esp-idf/issues/8660
pull/9624/head^2
laokaiyao 2022-08-05 18:31:37 +08:00
rodzic 482a37612d
commit 76cdab5f42
5 zmienionych plików z 68 dodań i 1 usunięć

Wyświetl plik

@ -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;

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
*

Wyświetl plik

@ -134,7 +134,7 @@ void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rat
i2s_ll_tx_enable_pdm_sd_codec(hal->dev, true);
/* 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
}
@ -275,6 +275,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