Merge branch 'refactor/i2s_driver' into 'master'

driver/i2s: bugfix and refactor for i2s

Closes IDF-3656 and IDF-3738

See merge request espressif/esp-idf!14704
This commit is contained in:
Kevin (Lao Kaiyao) 2021-09-06 02:07:40 +00:00
commit 2991eea97d
19 changed files with 1778 additions and 768 deletions

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@
#include "driver/periph_ctrl.h"
#include "esp_intr_alloc.h"
#if SOC_I2S_SUPPORTS_ADC_DAC
#if SOC_I2S_SUPPORTS_ADC
#include "driver/adc.h"
#endif
@ -355,7 +355,7 @@ esp_err_t i2s_stop(i2s_port_t i2s_num);
*
* @param i2s_num I2S port number
*
* @return
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
@ -430,7 +430,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_
*/
float i2s_get_clk(i2s_port_t i2s_num);
#if SOC_I2S_SUPPORTS_ADC_DAC
#if SOC_I2S_SUPPORTS_ADC
/**
* @brief Set built-in ADC mode for I2S DMA, this function will initialize ADC pad,
* and set ADC parameters.
@ -466,7 +466,9 @@ esp_err_t i2s_adc_enable(i2s_port_t i2s_num);
* - ESP_ERR_INVALID_STATE Driver state error
*/
esp_err_t i2s_adc_disable(i2s_port_t i2s_num);
#endif // SOC_I2S_SUPPORTS_ADC
#if SOC_I2S_SUPPORTS_DAC
/**
* @brief Set I2S dac mode, I2S built-in DAC is disabled by default
*
@ -481,7 +483,7 @@ esp_err_t i2s_adc_disable(i2s_port_t i2s_num);
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode);
#endif //SOC_I2S_SUPPORTS_ADC_DAC
#endif //SOC_I2S_SUPPORTS_DAC
#ifdef __cplusplus

View File

@ -380,11 +380,12 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s]")
i2s_write(I2S_NUM_1, data_wr, sizeof(uint8_t) * 400, &i2s_bytes_write, 1000 / portTICK_PERIOD_MS);
printf("write data size: %d\n", i2s_bytes_write);
int flag = 0; // break loop flag
int end_position = 0;
volatile int end_position = 0;
// write data to slave
while (!flag) {
TEST_ESP_OK(i2s_read(I2S_NUM_0, i2s_read_buff + length, 10000 - length, &bytes_read, 1000 / portTICK_PERIOD_MS));
if (bytes_read > 0) {
printf("read data size: %d\n", bytes_read);
for (int i = length; i < length + bytes_read; i++) {
if (i2s_read_buff[i] == 100) {
flag = 1;
@ -494,7 +495,7 @@ TEST_CASE("I2S APLL clock variation test", "[i2s]")
TEST_ASSERT(initial_size == esp_get_free_heap_size());
}
#if SOC_I2S_SUPPORTS_ADC_DAC
#if SOC_I2S_SUPPORTS_ADC
/* Only ESP32 need I2S adc/dac test */
TEST_CASE("I2S adc test", "[i2s]")
{
@ -560,7 +561,9 @@ TEST_CASE("I2S adc test", "[i2s]")
free(i2sReadBuffer);
i2s_driver_uninstall(I2S_NUM_0);
}
#endif
#if SOC_I2S_SUPPORTS_DAC
TEST_CASE("I2S dac test", "[i2s]")
{
// dac, adc i2s

View File

@ -536,7 +536,7 @@ static unsigned long i2s_lcd_select_periph_clock(i2s_hal_context_t *hal)
#error "invalid LCD peripheral clock source"
#endif
i2s_ll_tx_clk_set_src(hal->dev, clock_source);
i2s_ll_clk_cal_t clk_cal_config = {
i2s_ll_mclk_div_t clk_cal_config = {
.mclk_div = LCD_PERIPH_CLOCK_PRE_SCALE,
.a = 1,
.b = 0,

View File

@ -50,7 +50,7 @@ typedef struct {
uint16_t mclk_div; // I2S module clock devider, Fmclk = Fsclk /(mclk_div+b/a)
uint16_t a;
uint16_t b; // The decimal part of module clock devider, the decimal is: b/a
} i2s_ll_clk_cal_t;
} i2s_ll_mclk_div_t;
/**
* @brief Enable DMA descriptor owner check
@ -98,6 +98,18 @@ static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
}
}
/**
* @brief I2S module disable clock.
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
{
if (hw->clkm_conf.clk_en == 1) {
hw->clkm_conf.clk_en = 0;
}
}
/**
* @brief I2S tx msb right enable
*
@ -272,7 +284,7 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clkm_conf, clkm_div_num, set->mclk_div);
hw->clkm_conf.clkm_div_b = set->b;
@ -296,7 +308,7 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clkm_conf, clkm_div_num, set->mclk_div);
hw->clkm_conf.clkm_div_b = set->b;
@ -713,9 +725,9 @@ static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
* @brief Enable I2S loopback mode
*
* @param hw Peripheral I2S hardware instance address.
* @param loopback_en Set true to enable loopback mode.
* @param loopback_en Set true to share BCK and WS signal for tx module and rx module.
*/
static inline void i2s_ll_enable_loop_back(i2s_dev_t *hw, bool loopback_en)
static inline void i2s_ll_share_bck_ws(i2s_dev_t *hw, bool loopback_en)
{
hw->conf.sig_loopback = loopback_en;
}

View File

@ -44,7 +44,7 @@ typedef struct {
uint16_t mclk_div; // I2S module clock devider, Fmclk = Fsclk /(mclk_div+b/a)
uint16_t a;
uint16_t b; // The decimal part of module clock devider, the decimal is: b/a
} i2s_ll_clk_cal_t;
} i2s_ll_mclk_div_t;
/**
* @brief I2S module general init, enable I2S clock.
@ -56,6 +56,16 @@ static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
hw->tx_clkm_conf.clk_en = 1;
}
/**
* @brief I2S module disable I2S clock.
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
{
hw->tx_clkm_conf.clk_en = 0;
}
/**
* @brief Enable I2S tx module clock
*
@ -201,7 +211,7 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
if (set->a == 0 || set->b == 0) {
hw->tx_clkm_div_conf.tx_clkm_div_x = 0;
@ -240,7 +250,7 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
if (set->a == 0 || set->b == 0) {
hw->rx_clkm_div_conf.rx_clkm_div_x = 0;
@ -781,13 +791,41 @@ static inline void i2s_ll_set_single_data(i2s_dev_t *hw, uint32_t data)
hw->conf_single_data = data;
}
/**
* @brief Enable TX mono mode
* @note MONO in hardware means only one channel got data, but another doesn't
* MONO in software means two channel share same data
* This function aims to use MONO in software meaning
* so 'tx_mono' and 'tx_chan_equal' should be enabled at the same time
*
* @param hw Peripheral I2S hardware instance address.
* @param mono_ena Set true to enable mono mde.
*/
static inline void i2s_ll_tx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
{
hw->tx_conf.tx_mono = mono_ena;
hw->tx_conf.tx_chan_equal = mono_ena;
}
/**
* @brief Enable RX mono mode
*
* @param hw Peripheral I2S hardware instance address.
* @param mono_ena Set true to enable mono mde.
*/
static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
{
hw->rx_conf.rx_mono = mono_ena;
hw->rx_conf.rx_mono_fst_vld = mono_ena;
}
/**
* @brief Enable loopback mode
*
* @param hw Peripheral I2S hardware instance address.
* @param ena Set true to enable loopback mode.
* @param ena Set true to share BCK and WS signal for tx module and rx module.
*/
static inline void i2s_ll_enable_loop_back(i2s_dev_t *hw, bool ena)
static inline void i2s_ll_share_bck_ws(i2s_dev_t *hw, bool ena)
{
hw->tx_conf.sig_loopback = ena;
}

View File

@ -45,7 +45,7 @@ typedef struct {
uint16_t mclk_div; // I2S module clock devider, Fmclk = Fsclk /(mclk_div+b/a)
uint16_t a;
uint16_t b; // The decimal part of module clock devider, the decimal is: b/a
} i2s_ll_clk_cal_t;
} i2s_ll_mclk_div_t;
/**
* @brief I2S module general init, enable I2S clock.
@ -57,6 +57,16 @@ static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
hw->tx_clkm_conf.clk_en = 1;
}
/**
* @brief I2S module disable I2S clock.
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
{
hw->tx_clkm_conf.clk_en = 0;
}
/**
* @brief Enable I2S tx module clock
*
@ -202,7 +212,7 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
if (set->a == 0 || set->b == 0) {
hw->tx_clkm_div_conf.tx_clkm_div_x = 0;
@ -241,7 +251,7 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
if (set->a == 0 || set->b == 0) {
hw->rx_clkm_div_conf.rx_clkm_div_x = 0;
@ -785,9 +795,9 @@ static inline void i2s_ll_set_single_data(i2s_dev_t *hw, uint32_t data)
* @brief Enable loopback mode
*
* @param hw Peripheral I2S hardware instance address.
* @param ena Set true to enable loopback mode.
* @param ena Set true to share BCK and WS signal for tx module and rx module.
*/
static inline void i2s_ll_enable_loop_back(i2s_dev_t *hw, bool ena)
static inline void i2s_ll_share_bck_ws(i2s_dev_t *hw, bool ena)
{
hw->tx_conf.sig_loopback = ena;
}
@ -804,6 +814,34 @@ static inline void i2s_ll_set_pdm2pcm_conv_en(i2s_dev_t *hw, bool val)
}
/**
* @brief Enable TX mono mode
* @note MONO in hardware means only one channel got data, but another doesn't
* MONO in software means two channel share same data
* This function aims to use MONO in software meaning
* so 'tx_mono' and 'tx_chan_equal' should be enabled at the same time
*
* @param hw Peripheral I2S hardware instance address.
* @param mono_ena Set true to enable mono mde.
*/
static inline void i2s_ll_tx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
{
hw->tx_conf.tx_mono = mono_ena;
hw->tx_conf.tx_chan_equal = mono_ena;
}
/**
* @brief Enable RX mono mode
*
* @param hw Peripheral I2S hardware instance address.
* @param mono_ena Set true to enable mono mde.
*/
static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
{
hw->rx_conf.rx_mono = mono_ena;
hw->rx_conf.rx_mono_fst_vld = mono_ena;
}
#ifdef __cplusplus
}
#endif

View File

@ -45,7 +45,7 @@ typedef struct {
uint16_t mclk_div; // I2S module clock devider, Fmclk = Fsclk /(mclk_div+b/a)
uint16_t a;
uint16_t b; // The decimal part of module clock devider, the decimal is: b/a
} i2s_ll_clk_cal_t;
} i2s_ll_mclk_div_t;
#define I2S_LL_EVENT_TX_EOF (1 << 12)
#define I2S_LL_BCK_MAX_PRESCALE (64)
@ -97,6 +97,18 @@ static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
}
}
/**
* @brief I2S module disable clock.
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
{
if (hw->clkm_conf.clk_en == 1) {
hw->clkm_conf.clk_en = 0;
}
}
/**
* @brief I2S tx msb right enable
*
@ -268,7 +280,7 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clkm_conf, clkm_div_num, set->mclk_div);
hw->clkm_conf.clkm_div_b = set->b;
@ -292,7 +304,7 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clkm_conf, clkm_div_num, set->mclk_div);
hw->clkm_conf.clkm_div_b = set->b;
@ -813,9 +825,9 @@ static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
* @brief Enable I2S loopback mode
*
* @param hw Peripheral I2S hardware instance address.
* @param loopback_en Set true to enable loopback mode.
* @param loopback_en Set true to share BCK and WS signal for tx module and rx module.
*/
static inline void i2s_ll_enable_loop_back(i2s_dev_t *hw, bool loopback_en)
static inline void i2s_ll_share_bck_ws(i2s_dev_t *hw, bool loopback_en)
{
hw->conf.sig_loopback = loopback_en;
}

View File

@ -45,7 +45,7 @@ typedef struct {
uint16_t mclk_div; // I2S module clock devider, Fmclk = Fsclk /(mclk_div+b/a)
uint16_t a;
uint16_t b; // The decimal part of module clock devider, the decimal is: b/a
} i2s_ll_clk_cal_t;
} i2s_ll_mclk_div_t;
/**
* @brief I2S module general init, enable I2S clock.
@ -57,6 +57,16 @@ static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
hw->tx_clkm_conf.clk_en = 1;
}
/**
* @brief I2S module disable I2S clock.
*
* @param hw Peripheral I2S hardware instance address.
*/
static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
{
hw->tx_clkm_conf.clk_en = 0;
}
/**
* @brief Enable I2S tx module clock
*
@ -204,7 +214,7 @@ static inline void i2s_ll_tx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_tx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
if (set->a == 0 || set->b == 0) {
hw->tx_clkm_div_conf.tx_clkm_div_x = 0;
@ -243,7 +253,7 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
* @param hw Peripheral I2S hardware instance address.
* @param set Pointer to I2S clock devider configuration paramater
*/
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_clk_cal_t *set)
static inline void i2s_ll_rx_set_clk(i2s_dev_t *hw, i2s_ll_mclk_div_t *set)
{
if (set->a == 0 || set->b == 0) {
hw->rx_clkm_div_conf.rx_clkm_div_x = 0;
@ -806,13 +816,41 @@ static inline void i2s_ll_set_single_data(i2s_dev_t *hw, uint32_t data)
hw->conf_single_data = data;
}
/**
* @brief Enable TX mono mode
* @note MONO in hardware means only one channel got data, but another doesn't
* MONO in software means two channel share same data
* This function aims to use MONO in software meaning
* so 'tx_mono' and 'tx_chan_equal' should be enabled at the same time
*
* @param hw Peripheral I2S hardware instance address.
* @param mono_ena Set true to enable mono mde.
*/
static inline void i2s_ll_tx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
{
hw->tx_conf.tx_mono = mono_ena;
hw->tx_conf.tx_chan_equal = mono_ena;
}
/**
* @brief Enable RX mono mode
*
* @param hw Peripheral I2S hardware instance address.
* @param mono_ena Set true to enable mono mde.
*/
static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena)
{
hw->rx_conf.rx_mono = mono_ena;
hw->rx_conf.rx_mono_fst_vld = mono_ena;
}
/**
* @brief Enable loopback mode
*
* @param hw Peripheral I2S hardware instance address.
* @param ena Set true to enable loopback mode.
* @param ena Set true to share BCK and WS signal for tx module and rx module.
*/
static inline void i2s_ll_enable_loop_back(i2s_dev_t *hw, bool ena)
static inline void i2s_ll_share_bck_ws(i2s_dev_t *hw, bool ena)
{
hw->tx_conf.sig_loopback = ena;
}

View File

@ -19,35 +19,30 @@
#include "soc/soc_caps.h"
#include "hal/i2s_hal.h"
#define I2S_MODE_I2S (I2S_MODE_MASTER|I2S_MODE_SLAVE|I2S_MODE_TX|I2S_MODE_RX) /*!< I2S normal mode*/
/**
* @brief Calculate the closest sample rate clock configuration.
* clock relationship:
* Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a)
*
* @param fsclk I2S source clock freq.
* @param fbck BCK freuency.
* @param bck_div The BCK devider of bck. Generally, set bck_div to 8.
* @param cal Point to `i2s_ll_clk_cal_t` structure.
* @param clk_cfg I2S clock configuration(input)
* @param cal Point to `i2s_ll_mclk_div_t` structure(output).
*/
static void i2s_hal_clk_cal(uint32_t fsclk, uint32_t fbck, int bck_div, i2s_ll_clk_cal_t *cal)
static void i2s_hal_mclk_div_decimal_cal(i2s_hal_clock_cfg_t *clk_cfg, i2s_ll_mclk_div_t *cal)
{
int ma = 0;
int mb = 0;
uint32_t mclk = fbck * bck_div;
cal->mclk_div = fsclk / mclk;
cal->mclk_div = clk_cfg->mclk_div;
cal->a = 1;
cal->b = 0;
uint32_t freq_diff = fsclk - mclk * cal->mclk_div;
uint32_t min = ~0;
if (freq_diff == 0) {
if (!clk_cfg->sclk) {
return;
}
uint32_t freq_diff = clk_cfg->sclk - clk_cfg->mclk * cal->mclk_div;
uint32_t min = ~0;
for (int a = 2; a <= I2S_LL_MCLK_DIVIDER_MAX; a++) {
for (int b = 1; b < a; b++) {
ma = freq_diff * a;
mb = mclk * b;
mb = clk_cfg->mclk * b;
if (ma == mb) {
cal->a = a;
cal->b = b;
@ -68,44 +63,43 @@ void i2s_hal_set_clock_src(i2s_hal_context_t *hal, i2s_clock_src_t sel)
i2s_ll_rx_clk_set_src(hal->dev, sel);
}
void i2s_hal_tx_clock_config(i2s_hal_context_t *hal, uint32_t sclk, uint32_t fbck, int factor)
void i2s_hal_tx_clock_config(i2s_hal_context_t *hal, i2s_hal_clock_cfg_t *clk_cfg)
{
i2s_ll_clk_cal_t clk_set = {0};
i2s_hal_clk_cal(sclk, fbck, factor, &clk_set);
i2s_ll_tx_set_clk(hal->dev, &clk_set);
i2s_ll_tx_set_bck_div_num(hal->dev, factor);
i2s_ll_mclk_div_t mclk_set;
i2s_hal_mclk_div_decimal_cal(clk_cfg, &mclk_set);
i2s_ll_tx_set_clk(hal->dev, &mclk_set);
i2s_ll_tx_set_bck_div_num(hal->dev, clk_cfg->bclk_div);
}
void i2s_hal_rx_clock_config(i2s_hal_context_t *hal, uint32_t sclk, uint32_t fbck, int factor)
void i2s_hal_rx_clock_config(i2s_hal_context_t *hal, i2s_hal_clock_cfg_t *clk_cfg)
{
i2s_ll_clk_cal_t clk_set = {0};
i2s_hal_clk_cal(sclk, fbck, factor, &clk_set);
i2s_ll_rx_set_clk(hal->dev, &clk_set);
i2s_ll_rx_set_bck_div_num(hal->dev, factor);
i2s_ll_mclk_div_t mclk_set;
i2s_hal_mclk_div_decimal_cal(clk_cfg, &mclk_set);
i2s_ll_rx_set_clk(hal->dev, &mclk_set);
i2s_ll_rx_set_bck_div_num(hal->dev, clk_cfg->bclk_div);
}
void i2s_hal_enable_master_fd_mode(i2s_hal_context_t *hal)
{
i2s_ll_tx_set_slave_mod(hal->dev, 0); //TX master
i2s_ll_rx_set_slave_mod(hal->dev, 1); //RX Slave
i2s_ll_tx_set_slave_mod(hal->dev, false); //TX master
i2s_ll_rx_set_slave_mod(hal->dev, true); //RX Slave
}
void i2s_hal_enable_slave_fd_mode(i2s_hal_context_t *hal)
{
i2s_ll_tx_set_slave_mod(hal->dev, 1); //TX Slave
i2s_ll_rx_set_slave_mod(hal->dev, 1); //RX Slave
i2s_ll_tx_set_slave_mod(hal->dev, true); //TX Slave
i2s_ll_rx_set_slave_mod(hal->dev, true); //RX Slave
}
void i2s_hal_init(i2s_hal_context_t *hal, int i2s_num)
{
//Get hardware instance.
/* Get hardware instance */
hal->dev = I2S_LL_GET_HW(i2s_num);
i2s_ll_enable_clock(hal->dev);
}
#if SOC_I2S_SUPPORTS_PDM_TX
void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rate)
{
#if SOC_I2S_SUPPORTS_PDM_TX
/* enable pdm tx mode */
i2s_ll_tx_enable_pdm(hal->dev, true);
/* set pdm tx default presacle */
@ -134,23 +128,23 @@ void i2s_hal_tx_set_pdm_mode_default(i2s_hal_context_t *hal, uint32_t sample_rat
i2s_ll_tx_set_pdm_sd_dither2(hal->dev, 0);
#endif // SOC_I2S_SUPPORTS_PDM_CODEC
#endif // SOC_I2S_SUPPORTS_PDM_TX
}
#endif // SOC_I2S_SUPPORTS_PDM_TX
#if SOC_I2S_SUPPORTS_PDM_RX
void i2s_hal_rx_set_pdm_mode_default(i2s_hal_context_t *hal)
{
#if SOC_I2S_SUPPORTS_PDM_RX
/* enable pdm rx mode */
i2s_ll_rx_enable_pdm(hal->dev, true);
/* set pdm rx downsample number */
i2s_ll_rx_set_pdm_dsr(hal->dev, I2S_PDM_DSR_8S);
#endif // SOC_I2S_SUPPORTS_PDM_RX
}
#endif // SOC_I2S_SUPPORTS_PDM_RX
void i2s_hal_tx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cfg)
{
/* disable pdm tx mode */
/* Disable PDM tx mode and enable TDM mode (if support) */
i2s_ll_tx_enable_pdm(hal->dev, false);
#if SOC_I2S_SUPPORTS_TDM
@ -172,7 +166,7 @@ void i2s_hal_tx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *
void i2s_hal_rx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cfg)
{
/* disable pdm rx mode */
/* Disable PDM rx mode and enable TDM rx mode (if support)*/
i2s_ll_rx_enable_pdm(hal->dev, false);
#if SOC_I2S_SUPPORTS_TDM
@ -208,8 +202,10 @@ static uint32_t i2s_hal_get_ws_bit(i2s_comm_format_t fmt, uint32_t chan_num, uin
void i2s_hal_tx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cfg)
{
uint32_t chan_num = 2;
uint32_t chan_bits = hal_cfg->bits_cfg.chan_bits;
uint32_t data_bits = hal_cfg->bits_cfg.sample_bits;
uint32_t chan_bits = hal_cfg->chan_bits;
uint32_t data_bits = hal_cfg->sample_bits;
bool is_mono = (hal_cfg->chan_fmt == I2S_CHANNEL_FMT_ONLY_RIGHT) ||
(hal_cfg->chan_fmt == I2S_CHANNEL_FMT_ONLY_LEFT);
/* Set channel number and valid data bits */
#if SOC_I2S_SUPPORTS_TDM
@ -217,6 +213,7 @@ 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);
#endif
i2s_ll_tx_set_sample_bit(hal->dev, chan_bits, data_bits);
i2s_ll_tx_enable_mono_mode(hal->dev, is_mono);
/* Set communication format */
bool shift_en = hal_cfg->comm_fmt == I2S_COMM_FORMAT_STAND_I2S ? true : false;
@ -231,14 +228,17 @@ void i2s_hal_tx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t
void i2s_hal_rx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cfg)
{
uint32_t chan_num = 2;
uint32_t chan_bits = hal_cfg->bits_cfg.chan_bits;
uint32_t data_bits = hal_cfg->bits_cfg.sample_bits;
uint32_t chan_bits = hal_cfg->chan_bits;
uint32_t data_bits = hal_cfg->sample_bits;
bool is_mono = (hal_cfg->chan_fmt == I2S_CHANNEL_FMT_ONLY_RIGHT) ||
(hal_cfg->chan_fmt == I2S_CHANNEL_FMT_ONLY_LEFT);
#if SOC_I2S_SUPPORTS_TDM
chan_num = hal_cfg->total_chan;
i2s_ll_rx_set_chan_num(hal->dev, chan_num);
#endif
i2s_ll_rx_set_sample_bit(hal->dev, chan_bits, data_bits);
i2s_ll_rx_enable_mono_mode(hal->dev, is_mono);
/* Set communication format */
bool shift_en = hal_cfg->comm_fmt == I2S_COMM_FORMAT_STAND_I2S ? true : false;
@ -252,30 +252,67 @@ void i2s_hal_rx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t
void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cfg)
{
#if SOC_I2S_SUPPORTS_ADC
if (hal_cfg->mode & I2S_MODE_ADC_BUILT_IN) {
/* In ADC built-in mode, we need to call i2s_set_adc_mode to initialize the specific ADC channel.
* In the current stage, we only support ADC1 and single channel mode.
* In default data mode, the ADC data is in 12-bit resolution mode.
*/
i2s_ll_enable_builtin_adc(hal->dev, true);
return;
}
i2s_ll_enable_builtin_adc(hal->dev, false);
#endif
#if SOC_I2S_SUPPORTS_DAC
if (hal_cfg->mode & I2S_MODE_DAC_BUILT_IN) {
i2s_ll_enable_builtin_dac(hal->dev, true);
return;
}
i2s_ll_enable_builtin_dac(hal->dev, false);
#endif
/* Set configurations for TX mode */
if (hal_cfg->mode & I2S_MODE_TX) {
i2s_ll_tx_stop(hal->dev);
i2s_ll_tx_reset(hal->dev);
i2s_ll_tx_set_slave_mod(hal->dev, (hal_cfg->mode & I2S_MODE_SLAVE) != 0); //TX Slave
#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);
} else {
} else
#endif
{
/* Set tx common mode */
i2s_hal_tx_set_common_mode(hal, hal_cfg);
i2s_hal_tx_set_channel_style(hal, hal_cfg);
}
}
/* Set configurations for RX mode */
if (hal_cfg->mode & I2S_MODE_RX) {
i2s_ll_rx_stop(hal->dev);
i2s_ll_rx_reset(hal->dev);
i2s_ll_rx_set_slave_mod(hal->dev, (hal_cfg->mode & I2S_MODE_SLAVE) != 0); //RX Slave
#if SOC_I2S_SUPPORTS_PDM_RX
if (hal_cfg->mode & I2S_MODE_PDM) {
/* Set rx pdm mode */
i2s_hal_rx_set_pdm_mode_default(hal);
} else {
} else
#endif
{
/* Set rx common mode */
i2s_hal_rx_set_common_mode(hal, hal_cfg);
i2s_hal_rx_set_channel_style(hal, hal_cfg);
}
}
/* Set configurations for full-duplex mode */
if ((hal_cfg->mode & I2S_MODE_RX) && (hal_cfg->mode & I2S_MODE_TX)) {
i2s_ll_share_bck_ws(hal->dev, true);
if (hal_cfg->mode & I2S_MODE_MASTER) {
i2s_hal_enable_master_fd_mode(hal);
} else {
i2s_hal_enable_slave_fd_mode(hal);
}
}
}

View File

@ -33,16 +33,16 @@ extern "C" {
#endif
/**
* @brief I2S channel bits configurations
*
* @brief I2S clock configuration
*/
typedef union {
struct {
uint32_t sample_bits : 16; /*!< I2S sample bits in one channel */
uint32_t chan_bits : 16; /*!< I2S total bits in one channel. Should not be smaller than 'sample_bits', default '0' means equal to 'sample_bits' */
};
uint32_t val; /*!< I2S cannel bits configiration value */
} i2s_hal_bits_cfg_t;
typedef struct {
uint32_t sclk; /*!< I2S module clock */
uint32_t mclk; /*!< I2S master clock */
uint32_t bclk; /*!< I2S bit clock */
uint16_t mclk_div; /*!< I2S master clock division */
uint16_t bclk_div; /*!< I2S bit clock division*/
} i2s_hal_clock_cfg_t;
/**
* @brief I2S HAL configurations
@ -50,17 +50,19 @@ typedef union {
typedef struct {
i2s_mode_t mode; /*!< I2S work mode, using ored mask of `i2s_mode_t`*/
uint32_t sample_rate; /*!< I2S sample rate*/
i2s_channel_t ch; /*!< I2S channels*/
i2s_comm_format_t comm_fmt; /*!< I2S communication format */
i2s_channel_fmt_t chan_fmt; /*!< I2S channel format, there are total 16 channels in TDM mode.*/
i2s_hal_bits_cfg_t bits_cfg; /*!< Channel bits configuration*/
#if SOC_I2S_SUPPORTS_TDM
uint32_t sample_bits; /*!< I2S sample bits in one channel */
uint32_t chan_bits; /*!< I2S total bits in one channel. Should not be smaller than 'sample_bits', default '0' means equal to 'sample_bits' */
uint32_t active_chan; /*!< I2S active channel number */
uint32_t total_chan; /*!< Total number of I2S channels */
#if SOC_I2S_SUPPORTS_TDM
uint32_t chan_mask; /*!< Active channel bit mask, set value in `i2s_channel_t` to enable specific channel, the bit map of active channel can not exceed (0x1<<total_chan_num). */
bool left_align; /*!< Set to enable left aligment */
bool big_edin; /*!< Set to enable big edin */
bool bit_order_msb; /*!< Set to enable msb order */
bool skip_msk; /*!< Set to enable skip mask. If it is enabled, only the data of the enabled channels will be sent, otherwise all data stored in DMA TX buffer will be sent */
bool left_align; /*!< Set to enable left aligment */
bool big_edin; /*!< Set to enable big edin */
bool bit_order_msb; /*!< Set to enable msb order */
bool skip_msk; /*!< Set to enable skip mask. If it is enabled, only the data of the enabled channels will be sent, otherwise all data stored in DMA TX buffer will be sent */
#endif
} i2s_hal_config_t;
@ -72,6 +74,20 @@ typedef struct {
uint32_t version;
} i2s_hal_context_t;
/**
* @brief Enable I2S module clock
*
* @param hal Context of the HAL layer
*/
#define i2s_hal_enable_module_clock(hal) i2s_ll_enable_clock((hal)->dev);
/**
* @brief Disable I2S module clock
*
* @param hal Context of the HAL layer
*/
#define i2s_hal_disable_module_clock(hal) i2s_ll_disable_clock((hal)->dev);
/**
* @brief Reset I2S TX channel
*
@ -101,7 +117,8 @@ typedef struct {
#define i2s_hal_reset_rx_fifo(hal) i2s_ll_rx_reset_fifo((hal)->dev)
/**
* @brief Init the I2S hal. This function should be called first before other hal layer function is called
* @brief Get I2S hardware instance and enable I2S module clock
* @note This function should be called first before other hal layer function is called
*
* @param hal Context of the HAL layer
* @param i2s_num The uart port number, the max port number is (I2S_NUM_MAX -1)
@ -133,7 +150,7 @@ void i2s_hal_tx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t
void i2s_hal_rx_set_channel_style(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cfg);
/**
* @brief Config I2S param
* @brief Initialize I2S hardware
*
* @param hal Context of the HAL layer
* @param hal_cfg I2S hal configuration structer, refer to `i2s_hal_config_t`
@ -212,46 +229,56 @@ void i2s_hal_enable_slave_fd_mode(i2s_hal_context_t *hal);
* @brief Configure I2S TX module clock devider
*
* @param hal Context of the HAL layer
* @param sclk I2S source clock freq
* @param fbck I2S bck freq
* @param factor bck factor, factor=sclk/fbck
* @param clk_cfg I2S clock configuration
*/
void i2s_hal_tx_clock_config(i2s_hal_context_t *hal, uint32_t sclk, uint32_t fbck, int factor);
void i2s_hal_tx_clock_config(i2s_hal_context_t *hal, i2s_hal_clock_cfg_t *clk_cfg);
/**
* @brief Configure I2S RX module clock devider
*
* @param hal Context of the HAL layer
* @param sclk I2S source clock freq
* @param fbck I2S bck freq
* @param factor bck factor, factor=sclk/fbck
* @param clk_cfg I2S clock configuration
*/
void i2s_hal_rx_clock_config(i2s_hal_context_t *hal, uint32_t sclk, uint32_t fbck, int factor);
#if SOC_I2S_SUPPORTS_PCM
/**
* @brief Configure I2S TX PCM encoder or decoder.
*
* @param hal Context of the HAL layer
* @param cfg PCM configure paramater, refer to `i2s_pcm_compress_t`
*/
#define i2s_hal_tx_pcm_cfg(hal, cfg) i2s_ll_tx_set_pcm_type((hal)->dev, cfg)
void i2s_hal_rx_clock_config(i2s_hal_context_t *hal, i2s_hal_clock_cfg_t *clk_cfg);
/**
* @brief Configure I2S RX PCM encoder or decoder.
* @brief Set I2S tx clock source
*
* @param hal Context of the HAL layer
* @param cfg PCM configure paramater, refer to `i2s_pcm_compress_t`
* @param clk_src i2s tx clock source (see 'i2s_clock_src_t')
*/
#define i2s_hal_rx_pcm_cfg(hal, cfg) i2s_ll_rx_set_pcm_type((hal)->dev, cfg)
#endif
#define i2s_hal_tx_set_clock_source(hal, clk_src) i2s_ll_tx_clk_set_src((hal)->dev, clk_src)
/**
* @brief Set I2S rx clock source
*
* @param hal Context of the HAL layer
* @param clk_src i2s rx clock source (see 'i2s_clock_src_t')
*/
#define i2s_hal_rx_set_clock_source(hal, clk_src) i2s_ll_rx_clk_set_src((hal)->dev, clk_src)
/**
* @brief Enable I2S tx slave mode
*
* @param hal Context of the HAL layer
* @param enable set 'true' to enable tx slave mode
*/
#define i2s_hal_tx_enable_slave_mode(hal, enable) i2s_ll_tx_set_slave_mod((hal)->dev, enable)
/**
* @brief Enable I2S rx slave mode
*
* @param hal Context of the HAL layer
* @param enable set 'true' to enable rx slave mode
*/
#define i2s_hal_rx_enable_slave_mode(hal, enable) i2s_ll_rx_set_slave_mod((hal)->dev, enable)
/**
* @brief Enable loopback mode
*
* @param hal Context of the HAL layer
*/
#define i2s_hal_enable_sig_loopback(hal) i2s_ll_enable_loop_back((hal)->dev, true)
#define i2s_hal_enable_sig_loopback(hal) i2s_ll_share_bck_ws((hal)->dev, true)
/**
* @brief Set I2S configuration for common TX mode
@ -271,6 +298,24 @@ void i2s_hal_tx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *
*/
void i2s_hal_rx_set_common_mode(i2s_hal_context_t *hal, const i2s_hal_config_t *hal_cfg);
#if SOC_I2S_SUPPORTS_PCM
/**
* @brief Configure I2S TX PCM encoder or decoder.
*
* @param hal Context of the HAL layer
* @param cfg PCM configure paramater, refer to `i2s_pcm_compress_t`
*/
#define i2s_hal_tx_pcm_cfg(hal, cfg) i2s_ll_tx_set_pcm_type((hal)->dev, cfg)
/**
* @brief Configure I2S RX PCM encoder or decoder.
*
* @param hal Context of the HAL layer
* @param cfg PCM configure paramater, refer to `i2s_pcm_compress_t`
*/
#define i2s_hal_rx_pcm_cfg(hal, cfg) i2s_ll_rx_set_pcm_type((hal)->dev, cfg)
#endif
#if SOC_I2S_SUPPORTS_PDM_TX
/**
* @brief Configure I2S TX PDM sample rate
@ -470,7 +515,7 @@ void i2s_hal_rx_set_pdm_mode_default(i2s_hal_context_t *hal);
#define i2s_hal_get_in_eof_des_addr(hal, addr) i2s_ll_rx_get_eof_des_addr((hal)->dev, addr)
#endif
#if SOC_I2S_SUPPORTS_ADC_DAC
#if SOC_I2S_SUPPORTS_ADC
/**
* @brief Enable Builtin DAC
*
@ -485,13 +530,6 @@ void i2s_hal_rx_set_pdm_mode_default(i2s_hal_context_t *hal);
*/
#define i2s_hal_enable_builtin_adc(hal) i2s_ll_enable_builtin_adc((hal)->dev, true);
/**
* @brief Disable Builtin DAC
*
* @param hal Context of the HAL layer
*/
#define i2s_hal_disable_builtin_dac(hal) i2s_ll_enable_builtin_dac((hal)->dev, false);
/**
* @brief Disable Builtin ADC
*
@ -500,6 +538,15 @@ void i2s_hal_rx_set_pdm_mode_default(i2s_hal_context_t *hal);
#define i2s_hal_disable_builtin_adc(hal) i2s_ll_enable_builtin_adc((hal)->dev, false);
#endif
#if SOC_I2S_SUPPORTS_DAC
/**
* @brief Disable Builtin DAC
*
* @param hal Context of the HAL layer
*/
#define i2s_hal_disable_builtin_dac(hal) i2s_ll_enable_builtin_dac((hal)->dev, false);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -107,8 +107,8 @@ typedef enum {
I2S_CHANNEL_FMT_RIGHT_LEFT, /*!< Separated left and right channel */
I2S_CHANNEL_FMT_ALL_RIGHT, /*!< Load right channel data in both two channels */
I2S_CHANNEL_FMT_ALL_LEFT, /*!< Load left channel data in both two channels */
I2S_CHANNEL_FMT_ONLY_RIGHT, /*!< Only load data in right channel */
I2S_CHANNEL_FMT_ONLY_LEFT, /*!< Only load data in left channel */
I2S_CHANNEL_FMT_ONLY_RIGHT, /*!< Only load data in right channel (mono mode) */
I2S_CHANNEL_FMT_ONLY_LEFT, /*!< Only load data in left channel (mono mode) */
#if SOC_I2S_SUPPORTS_TDM
// Multiple channels are available with TDM feature
I2S_CHANNEL_FMT_MULTIPLE, /*!< More than two channels are used */
@ -123,11 +123,13 @@ typedef enum {
I2S_MODE_SLAVE = (0x1 << 1), /*!< Slave mode*/
I2S_MODE_TX = (0x1 << 2), /*!< TX mode*/
I2S_MODE_RX = (0x1 << 3), /*!< RX mode*/
#if SOC_I2S_SUPPORTS_ADC_DAC
#if SOC_I2S_SUPPORTS_DAC
//built-in DAC functions are only supported on I2S0 for ESP32 chip.
I2S_MODE_DAC_BUILT_IN = (0x1 << 4), /*!< Output I2S data to built-in DAC, no matter the data format is 16bit or 32 bit, the DAC module will only take the 8bits from MSB*/
#endif // SOC_I2S_SUPPORTS_DAC
#if SOC_I2S_SUPPORTS_ADC
I2S_MODE_ADC_BUILT_IN = (0x1 << 5), /*!< Input I2S data from built-in ADC, each data can be 12-bit width at most*/
#endif
#endif // SOC_I2S_SUPPORTS_ADC
// PDM functions are only supported on I2S0 (all chips).
I2S_MODE_PDM = (0x1 << 6), /*!< I2S PDM mode*/
} i2s_mode_t;
@ -152,7 +154,7 @@ typedef enum {
I2S_MCLK_MULTIPLE_384 = 384, /*!< mclk = sample_rate * 384 */
} i2s_mclk_multiple_t;
#if SOC_I2S_SUPPORTS_ADC_DAC
#if SOC_I2S_SUPPORTS_DAC
/**
* @brief I2S DAC mode for i2s_set_dac_mode.
*
@ -165,7 +167,7 @@ typedef enum {
I2S_DAC_CHANNEL_BOTH_EN = 0x3, /*!< Enable both of the I2S built-in DAC channels.*/
I2S_DAC_CHANNEL_MAX = 0x4, /*!< I2S built-in DAC mode max index*/
} i2s_dac_mode_t;
#endif //SOC_I2S_SUPPORTS_ADC_DAC
#endif //SOC_I2S_SUPPORTS_DAC
#if SOC_I2S_SUPPORTS_PCM
/**

View File

@ -21,23 +21,39 @@
const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
{
.mck_out_sig = -1, // Unavailable
.rx_bck_sig = I2S0I_BCK_IN_IDX,
.tx_bck_sig = I2S0O_BCK_OUT_IDX,
.tx_ws_sig = I2S0O_WS_OUT_IDX,
.rx_ws_sig = I2S0I_WS_IN_IDX,
.m_tx_bck_sig = I2S0O_BCK_OUT_IDX,
.m_rx_bck_sig = I2S0I_BCK_OUT_IDX,
.m_tx_ws_sig = I2S0O_WS_OUT_IDX,
.m_rx_ws_sig = I2S0I_WS_OUT_IDX,
.s_tx_bck_sig = I2S0O_BCK_IN_IDX,
.s_rx_bck_sig = I2S0I_BCK_IN_IDX,
.s_tx_ws_sig = I2S0O_WS_IN_IDX,
.s_rx_ws_sig = I2S0I_WS_IN_IDX,
.data_out_sig = I2S0O_DATA_OUT23_IDX,
.data_in_sig = I2S0I_DATA_IN15_IDX,
.irq = ETS_I2S0_INTR_SOURCE,
.module = PERIPH_I2S0_MODULE,
},
{
.mck_out_sig = -1, // Unavailable
.rx_bck_sig = I2S1I_BCK_IN_IDX,
.tx_bck_sig = I2S1O_BCK_OUT_IDX,
.tx_ws_sig = I2S1O_WS_OUT_IDX,
.rx_ws_sig = I2S1I_WS_IN_IDX,
.m_tx_bck_sig = I2S1O_BCK_OUT_IDX,
.m_rx_bck_sig = I2S1I_BCK_OUT_IDX,
.m_tx_ws_sig = I2S1O_WS_OUT_IDX,
.m_rx_ws_sig = I2S1I_WS_OUT_IDX,
.s_tx_bck_sig = I2S1O_BCK_IN_IDX,
.s_rx_bck_sig = I2S1I_BCK_IN_IDX,
.s_tx_ws_sig = I2S1O_WS_IN_IDX,
.s_rx_ws_sig = I2S1I_WS_IN_IDX,
.data_out_sig = I2S1O_DATA_OUT23_IDX,
.data_in_sig = I2S1I_DATA_IN15_IDX,
.irq = ETS_I2S1_INTR_SOURCE,
.module = PERIPH_I2S1_MODULE,
}

View File

@ -137,7 +137,8 @@
#define SOC_I2S_NUM (2)
#define SOC_I2S_SUPPORTS_PDM_TX (1)
#define SOC_I2S_SUPPORTS_PDM_RX (1)
#define SOC_I2S_SUPPORTS_ADC_DAC (1) // ESP32 support ADC and DAC
#define SOC_I2S_SUPPORTS_ADC (1) // ESP32 support ADC and DAC
#define SOC_I2S_SUPPORTS_DAC (1)
#define SOC_I2S_SUPPORTS_APLL (1)// ESP32 support APLL
#define SOC_I2S_APLL_MIN_FREQ (250000000)

View File

@ -21,12 +21,20 @@
const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
{
.mck_out_sig = I2S_MCLK_OUT_IDX,
.rx_bck_sig = I2SI_BCK_IN_IDX,
.tx_bck_sig = I2SO_BCK_OUT_IDX,
.tx_ws_sig = I2SO_WS_OUT_IDX,
.rx_ws_sig = I2SI_WS_IN_IDX,
.m_tx_bck_sig = I2SO_BCK_OUT_IDX,
.m_rx_bck_sig = I2SI_BCK_OUT_IDX,
.m_tx_ws_sig = I2SO_WS_OUT_IDX,
.m_rx_ws_sig = I2SI_WS_OUT_IDX,
.s_tx_bck_sig = I2SO_BCK_IN_IDX,
.s_rx_bck_sig = I2SI_BCK_IN_IDX,
.s_tx_ws_sig = I2SO_WS_IN_IDX,
.s_rx_ws_sig = I2SI_WS_IN_IDX,
.data_out_sig = I2SO_SD_OUT_IDX,
.data_in_sig = I2SI_SD_IN_IDX,
.irq = -1,
.module = PERIPH_I2S1_MODULE,
}

View File

@ -21,12 +21,20 @@
const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
{
.mck_out_sig = CLK_I2S_MUX_IDX,
.rx_bck_sig = I2S0I_BCK_IN_IDX,
.tx_bck_sig = I2S0O_BCK_OUT_IDX,
.tx_ws_sig = I2S0O_WS_OUT_IDX,
.rx_ws_sig = I2S0I_WS_IN_IDX,
.m_tx_bck_sig = I2S0O_BCK_OUT_IDX,
.m_rx_bck_sig = I2S0I_BCK_OUT_IDX,
.m_tx_ws_sig = I2S0O_WS_OUT_IDX,
.m_rx_ws_sig = I2S0I_WS_OUT_IDX,
.s_tx_bck_sig = I2S0O_BCK_IN_IDX,
.s_rx_bck_sig = I2S0I_BCK_IN_IDX,
.s_tx_ws_sig = I2S0O_WS_IN_IDX,
.s_rx_ws_sig = I2S0I_WS_IN_IDX,
.data_out_sig = I2S0O_DATA_OUT23_IDX,
.data_in_sig = I2S0I_DATA_IN15_IDX,
.irq = ETS_I2S0_INTR_SOURCE,
.module = PERIPH_I2S0_MODULE,
}

View File

@ -21,23 +21,39 @@
const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
{
.mck_out_sig = I2S0_MCLK_OUT_IDX,
.rx_bck_sig = I2S0I_BCK_IN_IDX,
.tx_bck_sig = I2S0O_BCK_OUT_IDX,
.tx_ws_sig = I2S0O_WS_OUT_IDX,
.rx_ws_sig = I2S0I_WS_IN_IDX,
.m_tx_bck_sig = I2S0O_BCK_OUT_IDX,
.m_rx_bck_sig = I2S0I_BCK_OUT_IDX,
.m_tx_ws_sig = I2S0O_WS_OUT_IDX,
.m_rx_ws_sig = I2S0I_WS_OUT_IDX,
.s_tx_bck_sig = I2S0O_BCK_IN_IDX,
.s_rx_bck_sig = I2S0I_BCK_IN_IDX,
.s_tx_ws_sig = I2S0O_WS_IN_IDX,
.s_rx_ws_sig = I2S0I_WS_IN_IDX,
.data_out_sig = I2S0O_SD_OUT_IDX,
.data_in_sig = I2S0I_SD_IN_IDX,
.irq = -1,
.module = PERIPH_I2S0_MODULE,
},
{
.mck_out_sig = I2S1_MCLK_OUT_IDX,
.rx_bck_sig = I2S1I_BCK_IN_IDX,
.tx_bck_sig = I2S1O_BCK_OUT_IDX,
.tx_ws_sig = I2S1O_WS_OUT_IDX,
.rx_ws_sig = I2S1I_WS_IN_IDX,
.m_tx_bck_sig = I2S1O_BCK_OUT_IDX,
.m_rx_bck_sig = I2S1I_BCK_OUT_IDX,
.m_tx_ws_sig = I2S1O_WS_OUT_IDX,
.m_rx_ws_sig = I2S1I_WS_OUT_IDX,
.s_tx_bck_sig = I2S1O_BCK_IN_IDX,
.s_rx_bck_sig = I2S1I_BCK_IN_IDX,
.s_tx_ws_sig = I2S1O_WS_IN_IDX,
.s_rx_ws_sig = I2S1I_WS_IN_IDX,
.data_out_sig = I2S1O_SD_OUT_IDX,
.data_in_sig = I2S1I_SD_IN_IDX,
.irq = -1,
.module = PERIPH_I2S1_MODULE,
}

View File

@ -28,12 +28,20 @@ extern "C" {
*/
typedef struct {
const uint8_t mck_out_sig;
const uint8_t tx_bck_sig;
const uint8_t rx_bck_sig;
const uint8_t tx_ws_sig;
const uint8_t rx_ws_sig;
const uint8_t m_tx_bck_sig;
const uint8_t m_rx_bck_sig;
const uint8_t m_tx_ws_sig;
const uint8_t m_rx_ws_sig;
const uint8_t s_tx_bck_sig;
const uint8_t s_rx_bck_sig;
const uint8_t s_tx_ws_sig;
const uint8_t s_rx_ws_sig;
const uint8_t data_out_sig;
const uint8_t data_in_sig;
const uint8_t irq;
const periph_module_t module;
} i2s_signal_conn_t;

View File

@ -166,11 +166,11 @@ Application Example
A code example for the I2S driver can be found in the directory :example:`peripherals/i2s`.
.. only:: SOC_I2S_SUPPORTS_ADC_DAC
.. only:: SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC
In addition, there are two short configuration examples for the I2S driver.
.. only:: not SOC_I2S_SUPPORTS_ADC_DAC
.. only:: not SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC
In addition, there is a short configuration examples for the I2S driver.
@ -310,7 +310,7 @@ Example for general usage.
i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver
.. only:: SOC_I2S_SUPPORTS_ADC_DAC
.. only:: SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC
Configuring I2S to use internal DAC for analog output
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^