mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'bugfix/workaround_of_i2s_half_sample_rate_issue' into 'master'
fix(i2s): fix i2s half sample rate issue Closes IDF-11278 See merge request espressif/esp-idf!33837
This commit is contained in:
commit
97b114643f
@ -23,7 +23,7 @@ static const char *TAG = "i2s_multi_dev_test";
|
||||
|
||||
#define TEST_I2S_FRAME_SIZE (128) // Frame numbers in every writing / reading
|
||||
#define TEST_I2S_ARRAY_LENGTH (1024) // The loop data length for verification
|
||||
#define TEST_I2S_MAX_DATA (256) // The maximum data value in the data buffer
|
||||
#define TEST_I2S_MAX_DATA (128) // The maximum data value in the data buffer
|
||||
#define TEST_I2S_MAX_FAIL_CNT (3) // Max broken packet count
|
||||
#define TEST_I2S_FRAME_TIMEOUT_SEC (10.0f) // Timeout seconds of waiting for a correct frame
|
||||
|
||||
|
@ -350,11 +350,6 @@ static inline void i2s_ll_set_raw_mclk_div(i2s_dev_t *hw, uint32_t mclk_div, uin
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that unlike to calculate from the regular decimal */
|
||||
i2s_ll_set_raw_mclk_div(hw, 7, 47, 3);
|
||||
i2s_ll_set_raw_mclk_div(hw, mclk_div->integer, mclk_div->denominator, mclk_div->numerator);
|
||||
}
|
||||
|
||||
@ -659,7 +654,7 @@ static inline void i2s_ll_tx_set_bits_mod(i2s_dev_t *hw, uint32_t val)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure TX chan bit and audio data bit, on ESP32, sample_bit should equals to data_bit
|
||||
* @brief Configure TX chan bit and audio data bit, on ESP32, sample_bit should equals to data_bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
@ -672,7 +667,7 @@ static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure RX chan bit and audio data bit, on ESP32, sample_bit should equals to data_bit
|
||||
* @brief Configure RX chan bit and audio data bit, on ESP32, sample_bit should equals to data_bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -285,15 +285,21 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
/* Set the integer part of mclk division */
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_clkm_conf, tx_clkm_div_num, 2);
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_yn1 = 0;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_y = 1;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_z = 0;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_yn1 = yn1;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_z = z;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_y = y;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_clkm_conf, tx_clkm_div_num, div_int);
|
||||
/* Set the decimal part of the mclk division */
|
||||
typeof(hw->tx_clkm_div_conf) div = {};
|
||||
div.tx_clkm_div_x = x;
|
||||
div.tx_clkm_div_y = y;
|
||||
div.tx_clkm_div_z = z;
|
||||
div.tx_clkm_div_yn1 = yn1;
|
||||
hw->tx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,15 +314,21 @@ static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
/* Set the integer part of mclk division */
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_clkm_conf, rx_clkm_div_num, 2);
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_yn1 = 0;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_y = 1;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_z = 0;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_yn1 = yn1;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_z = z;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_y = y;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_clkm_conf, rx_clkm_div_num, div_int);
|
||||
/* Set the decimal part of the mclk division */
|
||||
typeof(hw->rx_clkm_div_conf) div = {};
|
||||
div.rx_clkm_div_x = x;
|
||||
div.rx_clkm_div_y = y;
|
||||
div.rx_clkm_div_z = z;
|
||||
div.rx_clkm_div_yn1 = yn1;
|
||||
hw->rx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,12 +339,6 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_tx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -367,12 +373,6 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_rx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -467,7 +467,7 @@ static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, int eof_num)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure TX chan bit and audio data bit
|
||||
* @brief Configure TX chan bit and audio data bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
@ -480,7 +480,7 @@ static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure RX chan bit and audio data bit
|
||||
* @brief Configure RX chan bit and audio data bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
@ -880,11 +880,11 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2S TX PDM fp configuration paramater
|
||||
* @brief Get I2S TX PDM fp configuration parameter
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @return
|
||||
* - fp configuration paramater
|
||||
* - fp configuration parameter
|
||||
*/
|
||||
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
||||
{
|
||||
@ -892,11 +892,11 @@ static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2S TX PDM fs configuration paramater
|
||||
* @brief Get I2S TX PDM fs configuration parameter
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @return
|
||||
* - fs configuration paramater
|
||||
* - fs configuration parameter
|
||||
*/
|
||||
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
||||
{
|
||||
@ -922,7 +922,7 @@ static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw, bool pdm_enable)
|
||||
* @brief Configura TX a/u-law decompress or compress
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param pcm_cfg PCM configuration paramater
|
||||
* @param pcm_cfg PCM configuration parameter
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||
{
|
||||
@ -934,7 +934,7 @@ static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_
|
||||
* @brief Configure RX a/u-law decompress or compress
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param pcm_cfg PCM configuration paramater
|
||||
* @param pcm_cfg PCM configuration parameter
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||
{
|
||||
@ -1106,7 +1106,7 @@ static inline void i2s_ll_tx_pdm_dma_take_mode(i2s_dev_t *hw, bool is_mono, bool
|
||||
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
||||
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
||||
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
||||
* @param mask The slot mask to selet the slot
|
||||
* @param mask The slot mask to select the slot
|
||||
*/
|
||||
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
||||
{
|
||||
|
@ -316,13 +316,21 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
(void)hw;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_tx_clkm_conf, i2s_tx_clkm_div_num, 2);
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_yn1 = 0;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_y = 1;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_z = 0;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_z = z;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_y = y;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_tx_clkm_conf, i2s_tx_clkm_div_num, div_int);
|
||||
typeof(PCR.i2s_tx_clkm_div_conf) div = {};
|
||||
div.i2s_tx_clkm_div_x = x;
|
||||
div.i2s_tx_clkm_div_y = y;
|
||||
div.i2s_tx_clkm_div_z = z;
|
||||
div.i2s_tx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_tx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,13 +346,21 @@ static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
(void)hw;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_rx_clkm_conf, i2s_rx_clkm_div_num, 2);
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_yn1 = 0;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_y = 1;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_z = 0;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_z = z;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_y = y;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_rx_clkm_conf, i2s_rx_clkm_div_num, div_int);
|
||||
typeof(PCR.i2s_rx_clkm_div_conf) div = {};
|
||||
div.i2s_rx_clkm_div_x = x;
|
||||
div.i2s_rx_clkm_div_y = y;
|
||||
div.i2s_rx_clkm_div_z = z;
|
||||
div.i2s_rx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_rx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -355,12 +371,6 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_tx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -395,12 +405,6 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_rx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
|
@ -306,13 +306,21 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
(void)hw;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_tx_clkm_conf, i2s_tx_clkm_div_num, 2);
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_yn1 = 0;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_y = 1;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_z = 0;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_z = z;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_y = y;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_tx_clkm_conf, i2s_tx_clkm_div_num, div_int);
|
||||
typeof(PCR.i2s_tx_clkm_div_conf) div = {};
|
||||
div.i2s_tx_clkm_div_x = x;
|
||||
div.i2s_tx_clkm_div_y = y;
|
||||
div.i2s_tx_clkm_div_z = z;
|
||||
div.i2s_tx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_tx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,13 +336,21 @@ static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
(void)hw;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_rx_clkm_conf, i2s_rx_clkm_div_num, 2);
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_yn1 = 0;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_y = 1;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_z = 0;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_z = z;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_y = y;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_rx_clkm_conf, i2s_rx_clkm_div_num, div_int);
|
||||
typeof(PCR.i2s_rx_clkm_div_conf) div = {};
|
||||
div.i2s_rx_clkm_div_x = x;
|
||||
div.i2s_rx_clkm_div_y = y;
|
||||
div.i2s_rx_clkm_div_z = z;
|
||||
div.i2s_rx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_rx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -345,12 +361,6 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_tx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -385,12 +395,6 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_rx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
|
@ -313,13 +313,21 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
(void)hw;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_tx_clkm_conf, i2s_tx_clkm_div_num, 2);
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_yn1 = 0;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_y = 1;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_z = 0;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_z = z;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_y = y;
|
||||
PCR.i2s_tx_clkm_div_conf.i2s_tx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_tx_clkm_conf, i2s_tx_clkm_div_num, div_int);
|
||||
typeof(PCR.i2s_tx_clkm_div_conf) div = {};
|
||||
div.i2s_tx_clkm_div_x = x;
|
||||
div.i2s_tx_clkm_div_y = y;
|
||||
div.i2s_tx_clkm_div_z = z;
|
||||
div.i2s_tx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_tx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -335,13 +343,21 @@ static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
(void)hw;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_rx_clkm_conf, i2s_rx_clkm_div_num, 2);
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_yn1 = 0;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_y = 1;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_z = 0;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_z = z;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_y = y;
|
||||
PCR.i2s_rx_clkm_div_conf.i2s_rx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.i2s_rx_clkm_conf, i2s_rx_clkm_div_num, div_int);
|
||||
typeof(PCR.i2s_rx_clkm_div_conf) div = {};
|
||||
div.i2s_rx_clkm_div_x = x;
|
||||
div.i2s_rx_clkm_div_y = y;
|
||||
div.i2s_rx_clkm_div_z = z;
|
||||
div.i2s_rx_clkm_div_yn1 = yn1;
|
||||
PCR.i2s_rx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,12 +368,6 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_tx_set_raw_clk_div(hw, 8, 1, 1, 73, 1);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -392,12 +402,6 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_rx_set_raw_clk_div(hw, 8, 1, 1, 73, 1);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
|
@ -498,25 +498,52 @@ static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
// Note: this function involves HP_SYS_CLKRST register which is shared with other peripherals, need lock in upper layer
|
||||
switch (I2S_LL_GET_ID(hw)) {
|
||||
case 0:
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl13, reg_i2s0_tx_div_n, div_int);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_tx_div_x = x;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_z = z;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl13, reg_i2s0_tx_div_n, 2);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_yn1 = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_y = 1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_z = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_tx_div_x = 0;
|
||||
/* Set the target mclk division coefficients */
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_yn1 = yn1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_z = z;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl14.reg_i2s0_tx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_tx_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl13, reg_i2s0_tx_div_n, div_int);
|
||||
return;
|
||||
case 1:
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl16, reg_i2s1_tx_div_n, div_int);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl16.reg_i2s1_tx_div_x = x;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl16.reg_i2s1_tx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s1_tx_div_z = z;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl16, reg_i2s1_tx_div_n, 2);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s1_tx_div_yn1 = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl16.reg_i2s1_tx_div_y = 1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s1_tx_div_z = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl16.reg_i2s1_tx_div_x = 0;
|
||||
/* Set the target mclk division coefficients */
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s1_tx_div_yn1 = yn1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s1_tx_div_z = z;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl16.reg_i2s1_tx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl16.reg_i2s1_tx_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl16, reg_i2s1_tx_div_n, div_int);
|
||||
return;
|
||||
case 2:
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl18, reg_i2s2_tx_div_n, div_int);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_x = x;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_z = z;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl18, reg_i2s2_tx_div_n, 2);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_yn1 = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_y = 1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_z = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_x = 0;
|
||||
/* Set the target mclk division coefficients */
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_yn1 = yn1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_z = z;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl19.reg_i2s2_tx_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl18, reg_i2s2_tx_div_n, div_int);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -536,25 +563,52 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
// Note: this function involves HP_SYS_CLKRST register which is shared with other peripherals, need lock in upper layer
|
||||
switch (I2S_LL_GET_ID(hw)) {
|
||||
case 0:
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl12, reg_i2s0_rx_div_n, div_int);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl12.reg_i2s0_rx_div_x = x;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl12.reg_i2s0_rx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_rx_div_z = z;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl12, reg_i2s0_rx_div_n, 2);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_rx_div_yn1 = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl12.reg_i2s0_rx_div_y = 1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_rx_div_z = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl12.reg_i2s0_rx_div_x = 0;
|
||||
/* Set the target mclk division coefficients */
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_rx_div_yn1 = yn1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl13.reg_i2s0_rx_div_z = z;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl12.reg_i2s0_rx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl12.reg_i2s0_rx_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl12, reg_i2s0_rx_div_n, div_int);
|
||||
return;
|
||||
case 1:
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl14, reg_i2s1_rx_div_n, div_int);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_x = x;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_z = z;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl14, reg_i2s1_rx_div_n, 2);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_yn1 = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_y = 1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_z = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_x = 0;
|
||||
/* Set the target mclk division coefficients */
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_yn1 = yn1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_z = z;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl15.reg_i2s1_rx_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl14, reg_i2s1_rx_div_n, div_int);
|
||||
return;
|
||||
case 2:
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl17, reg_i2s2_rx_div_n, div_int);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s2_rx_div_x = x;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_z = z;
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl17, reg_i2s2_rx_div_n, 2);
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_yn1 = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_y = 1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_z = 0;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s2_rx_div_x = 0;
|
||||
/* Set the target mclk division coefficients */
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_yn1 = yn1;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_z = z;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl18.reg_i2s2_rx_div_y = y;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl17.reg_i2s2_rx_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl17, reg_i2s2_rx_div_n, div_int);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -567,12 +621,6 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void _i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_tx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -611,12 +659,6 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void _i2s_ll_rx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_rx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
|
@ -341,11 +341,6 @@ static inline void i2s_ll_set_raw_mclk_div(i2s_dev_t *hw, uint32_t mclk_div, uin
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that unlike to calculate from the regular decimal */
|
||||
i2s_ll_set_raw_mclk_div(hw, 7, 47, 3);
|
||||
i2s_ll_set_raw_mclk_div(hw, mclk_div->integer, mclk_div->denominator, mclk_div->numerator);
|
||||
}
|
||||
|
||||
@ -682,7 +677,7 @@ static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, uint32_t eof_num)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure TX chan bit and audio data bit, on ESP32-S2, sample_bit should equals to data_bit
|
||||
* @brief Configure TX chan bit and audio data bit, on ESP32-S2, sample_bit should equals to data_bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
@ -695,7 +690,7 @@ static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure RX chan bit and audio data bit, on ESP32-S2, sample_bit should equals to data_bit
|
||||
* @brief Configure RX chan bit and audio data bit, on ESP32-S2, sample_bit should equals to data_bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -291,15 +291,21 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
/* Set the integer part of mclk division */
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_clkm_conf, tx_clkm_div_num, 2);
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_yn1 = 0;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_y = 1;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_z = 0;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_yn1 = yn1;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_z = z;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_y = y;
|
||||
hw->tx_clkm_div_conf.tx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_clkm_conf, tx_clkm_div_num, div_int);
|
||||
/* Set the decimal part of the mclk division */
|
||||
typeof(hw->tx_clkm_div_conf) div = {};
|
||||
div.tx_clkm_div_x = x;
|
||||
div.tx_clkm_div_y = y;
|
||||
div.tx_clkm_div_z = z;
|
||||
div.tx_clkm_div_yn1 = yn1;
|
||||
hw->tx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,15 +320,21 @@ static inline void i2s_ll_tx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, uint32_t x, uint32_t y, uint32_t z, uint32_t yn1)
|
||||
{
|
||||
/* Set the integer part of mclk division */
|
||||
/* Workaround for the double division issue.
|
||||
* The division coefficients must be set in particular sequence.
|
||||
* And it has to switch to a small division first before setting the target division. */
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_clkm_conf, rx_clkm_div_num, 2);
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_yn1 = 0;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_y = 1;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_z = 0;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_x = 0;
|
||||
|
||||
/* Set the target mclk division coefficients */
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_yn1 = yn1;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_z = z;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_y = y;
|
||||
hw->rx_clkm_div_conf.rx_clkm_div_x = x;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_clkm_conf, rx_clkm_div_num, div_int);
|
||||
/* Set the decimal part of the mclk division */
|
||||
typeof(hw->rx_clkm_div_conf) div = {};
|
||||
div.rx_clkm_div_x = x;
|
||||
div.rx_clkm_div_y = y;
|
||||
div.rx_clkm_div_z = z;
|
||||
div.rx_clkm_div_yn1 = yn1;
|
||||
hw->rx_clkm_div_conf.val = div.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -333,12 +345,6 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_tx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -373,12 +379,6 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
* otherwise the clock division might be inaccurate.
|
||||
* the general idea is to set a value that impossible to calculate from the regular decimal */
|
||||
i2s_ll_rx_set_raw_clk_div(hw, 7, 317, 7, 3, 0);
|
||||
|
||||
uint32_t div_x = 0;
|
||||
uint32_t div_y = 0;
|
||||
uint32_t div_z = 0;
|
||||
@ -474,7 +474,7 @@ static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, int eof_num)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure TX chan bit and audio data bit
|
||||
* @brief Configure TX chan bit and audio data bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
@ -487,7 +487,7 @@ static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Congfigure RX chan bit and audio data bit
|
||||
* @brief Configure RX chan bit and audio data bit
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param chan_bit The chan bit width
|
||||
@ -790,11 +790,11 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2S TX PDM fp configuration paramater
|
||||
* @brief Get I2S TX PDM fp configuration parameter
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @return
|
||||
* - fp configuration paramater
|
||||
* - fp configuration parameter
|
||||
*/
|
||||
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
||||
{
|
||||
@ -802,11 +802,11 @@ static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get I2S TX PDM fs configuration paramater
|
||||
* @brief Get I2S TX PDM fs configuration parameter
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @return
|
||||
* - fs configuration paramater
|
||||
* - fs configuration parameter
|
||||
*/
|
||||
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
||||
{
|
||||
@ -927,7 +927,7 @@ static inline void i2s_ll_tx_set_pdm_sd_dither2(i2s_dev_t *hw, uint32_t dither2)
|
||||
* @brief Configure RX PDM downsample
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param dsr PDM downsample configuration paramater
|
||||
* @param dsr PDM downsample configuration parameter
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_pdm_dsr(i2s_dev_t *hw, i2s_pdm_dsr_t dsr)
|
||||
{
|
||||
@ -949,7 +949,7 @@ static inline void i2s_ll_rx_get_pdm_dsr(i2s_dev_t *hw, i2s_pdm_dsr_t *dsr)
|
||||
* @brief Configura TX a/u-law decompress or compress
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param pcm_cfg PCM configuration paramater
|
||||
* @param pcm_cfg PCM configuration parameter
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||
{
|
||||
@ -961,7 +961,7 @@ static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_
|
||||
* @brief Configure RX a/u-law decompress or compress
|
||||
*
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param pcm_cfg PCM configuration paramater
|
||||
* @param pcm_cfg PCM configuration parameter
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||
{
|
||||
@ -1133,7 +1133,7 @@ static inline void i2s_ll_tx_pdm_dma_take_mode(i2s_dev_t *hw, bool is_mono, bool
|
||||
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
||||
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
||||
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
||||
* @param mask The slot mask to selet the slot
|
||||
* @param mask The slot mask to select the slot
|
||||
*/
|
||||
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user