kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'bugfix/fix_incorrect_i2s_pdm_clk_issue' into 'master'
Bugfix(I2S): Fix I2S PDM clock incorrect issue when using APLL. Closes IDFGH-3423 and IDFGH-3106 See merge request espressif/esp-idf!9101pull/5682/merge
commit
c7264f04c6
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue