mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
bugfix(i2s): fix driver ut i2s
* Add test support for ESP32S2 * Add loop back test * Support chip internal connection, no external wiring required. * Delete the relevant codes of PDM of ESP32-S2 ll layer. * fix dac dma mode issue
This commit is contained in:
parent
bfc37ab43f
commit
faf898b659
@ -110,7 +110,7 @@ static esp_err_t i2s_reset_fifo(i2s_port_t i2s_num)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
inline static void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv)
|
||||
static inline void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv)
|
||||
{
|
||||
//if pin = -1, do not need to configure
|
||||
if (gpio != -1) {
|
||||
@ -120,7 +120,7 @@ inline static void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, boo
|
||||
}
|
||||
}
|
||||
|
||||
inline static void gpio_matrix_in_check(uint32_t gpio, uint32_t signal_idx, bool inv)
|
||||
static inline void gpio_matrix_in_check(uint32_t gpio, uint32_t signal_idx, bool inv)
|
||||
{
|
||||
if (gpio != -1) {
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
|
||||
@ -403,14 +403,14 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
|
||||
//Rate as given to this function is the intended sample rate;
|
||||
//According to the TRM, WS clk equals to the sample rate, and bclk is double the speed of WS
|
||||
uint32_t b_clk = rate * I2S_AD_BCK_FACTOR;
|
||||
fi2s_clk /= I2S_AD_BCK_FACTOR;
|
||||
fi2s_clk /= 2;
|
||||
int factor2 = 60;
|
||||
mclk = b_clk * factor2;
|
||||
clkmdiv = ((double) I2S_BASE_CLK) / mclk;
|
||||
clkmInteger = clkmdiv;
|
||||
clkmDecimals = (clkmdiv - clkmInteger) / denom;
|
||||
bck = mclk / b_clk;
|
||||
#if SOC_I2S_SUPPORT_PDM
|
||||
#if I2S_SUPPORTS_PDM
|
||||
} 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) {
|
||||
@ -697,11 +697,11 @@ esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode)
|
||||
}
|
||||
|
||||
if (dac_mode & I2S_DAC_CHANNEL_RIGHT_EN) {
|
||||
//DAC1, right channel, GPIO25
|
||||
//DAC1, right channel
|
||||
dac_output_enable(DAC_CHANNEL_1);
|
||||
}
|
||||
if (dac_mode & I2S_DAC_CHANNEL_LEFT_EN) {
|
||||
//DAC2, left channel, GPIO26
|
||||
//DAC2, left channel
|
||||
dac_output_enable(DAC_CHANNEL_2);
|
||||
}
|
||||
return ESP_OK;
|
||||
@ -803,7 +803,7 @@ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate)
|
||||
return i2s_set_clk(i2s_num, rate, p_i2s_obj[i2s_num]->bits_per_sample, p_i2s_obj[i2s_num]->channel_num);
|
||||
}
|
||||
|
||||
#if SOC_I2S_SUPPORT_PDM
|
||||
#if I2S_SUPPORTS_PDM
|
||||
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);
|
||||
@ -818,7 +818,8 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
|
||||
I2S_CHECK((i2s_config), "param null", ESP_ERR_INVALID_ARG);
|
||||
I2S_CHECK(!((i2s_config->mode & I2S_MODE_ADC_BUILT_IN) && (i2s_num != I2S_NUM_0)), "I2S ADC built-in only support on I2S0", ESP_ERR_INVALID_ARG);
|
||||
I2S_CHECK(!((i2s_config->mode & I2S_MODE_DAC_BUILT_IN) && (i2s_num != I2S_NUM_0)), "I2S DAC built-in only support on I2S0", ESP_ERR_INVALID_ARG);
|
||||
#if SOC_I2S_SUPPORT_PDM
|
||||
I2S_CHECK(((i2s_config->communication_format & I2S_COMM_FORMAT_I2S) || (i2s_config->communication_format & I2S_COMM_FORMAT_PCM)), "I2S communication format invalid.", ESP_ERR_INVALID_ARG);
|
||||
#if I2S_SUPPORTS_PDM
|
||||
I2S_CHECK(!((i2s_config->mode & I2S_MODE_PDM) && (i2s_num != I2S_NUM_0)), "I2S DAC PDM only support on I2S0", ESP_ERR_INVALID_ARG);
|
||||
#endif
|
||||
periph_module_enable(i2s_periph_signal[i2s_num].module);
|
||||
|
@ -54,7 +54,7 @@ typedef intr_handle_t i2s_isr_handle_t;
|
||||
*/
|
||||
esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin);
|
||||
|
||||
#if SOC_I2S_SUPPORT_PDM
|
||||
#if I2S_SUPPORTS_PDM
|
||||
/**
|
||||
* @brief Set PDM mode down-sample rate
|
||||
* In PDM RX mode, there would be 2 rounds of downsample process in hardware.
|
||||
|
@ -1,6 +1,7 @@
|
||||
/**
|
||||
* I2S test environment UT_T1_I2S:
|
||||
* connect GPIO18 and GPIO19, GPIO25 and GPIO26, GPIO21 and GPIO22
|
||||
* We use internal signals instead of external wiring, but please keep the following IO connections, or connect nothing to prevent the signal from being disturbed.
|
||||
* connect GPIO18 and GPIO19, GPIO25(ESP32)/GPIO17(ESP32-S2) and GPIO26, GPIO21 and GPIO22(ESP32)/GPIO20(ESP32-S2)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -28,6 +29,63 @@
|
||||
|
||||
#define PERCENT_DIFF 0.0001
|
||||
|
||||
// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loopback
|
||||
// Since ESP32-S2 has only one I2S, only loop back test can be tested.
|
||||
static void i2s_test_io_config(int mode)
|
||||
{
|
||||
// Connect internal signals using IO matrix.
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[MASTER_BCK_IO], PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[DATA_OUT_IO], PIN_FUNC_GPIO);
|
||||
|
||||
gpio_set_direction(MASTER_BCK_IO, GPIO_MODE_INPUT_OUTPUT);
|
||||
gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT);
|
||||
gpio_set_direction(DATA_OUT_IO, GPIO_MODE_INPUT_OUTPUT);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
switch (mode) {
|
||||
case 0: {
|
||||
gpio_matrix_out(MASTER_BCK_IO, I2S0I_BCK_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(MASTER_BCK_IO, I2S1O_BCK_IN_IDX, 0);
|
||||
|
||||
gpio_matrix_out(MASTER_WS_IO, I2S0I_WS_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(MASTER_WS_IO, I2S1O_WS_IN_IDX, 0);
|
||||
|
||||
gpio_matrix_out(DATA_OUT_IO, I2S1O_DATA_OUT23_IDX, 0, 0);
|
||||
gpio_matrix_in(DATA_OUT_IO, I2S0I_DATA_IN15_IDX, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
gpio_matrix_out(MASTER_BCK_IO, I2S0O_BCK_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(MASTER_BCK_IO, I2S1I_BCK_IN_IDX, 0);
|
||||
|
||||
gpio_matrix_out(MASTER_WS_IO, I2S0O_WS_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(MASTER_WS_IO, I2S1I_WS_IN_IDX, 0);
|
||||
|
||||
gpio_matrix_out(DATA_OUT_IO, I2S0O_DATA_OUT23_IDX, 0, 0);
|
||||
gpio_matrix_in(DATA_OUT_IO, I2S1I_DATA_IN15_IDX, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
gpio_matrix_out(DATA_OUT_IO, I2S0O_DATA_OUT23_IDX, 0, 0);
|
||||
gpio_matrix_in(DATA_OUT_IO, I2S0I_DATA_IN15_IDX, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (mode) {
|
||||
case 2: {
|
||||
gpio_matrix_out(DATA_OUT_IO, I2S0O_DATA_OUT23_IDX, 0, 0);
|
||||
gpio_matrix_in(DATA_OUT_IO, I2S0I_DATA_IN15_IDX, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* i2s initialize test
|
||||
* 1. i2s_driver_install
|
||||
@ -52,6 +110,7 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]")
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL));
|
||||
//for internal DAC, this will enable both of the internal channels
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, NULL));
|
||||
i2s_test_io_config(1);
|
||||
//stop & destroy i2s driver
|
||||
TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0));
|
||||
|
||||
@ -64,6 +123,7 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]")
|
||||
};
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &pin_config));
|
||||
i2s_test_io_config(1);
|
||||
TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0));
|
||||
|
||||
//error param test
|
||||
@ -76,9 +136,72 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]")
|
||||
TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0));
|
||||
}
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP32S2)
|
||||
/* ESP32S2 has only single I2S port and hence following test cases are not applicable */
|
||||
TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s][test_env=UT_T1_I2S]")
|
||||
{
|
||||
// master driver installed and send data
|
||||
i2s_config_t master_i2s_config = {
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX,
|
||||
.sample_rate = SAMPLE_RATE,
|
||||
.bits_per_sample = SAMPLE_BITS,
|
||||
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
|
||||
.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
|
||||
.dma_buf_count = 6,
|
||||
.dma_buf_len = 100,
|
||||
.use_apll = 0,
|
||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 ,
|
||||
};
|
||||
i2s_pin_config_t master_pin_config = {
|
||||
.bck_io_num = MASTER_BCK_IO,
|
||||
.ws_io_num = MASTER_WS_IO,
|
||||
.data_out_num = DATA_OUT_IO,
|
||||
.data_in_num = DATA_IN_IO
|
||||
};
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config));
|
||||
i2s_test_io_config(2);
|
||||
printf("\r\nheap size: %d\n", esp_get_free_heap_size());
|
||||
|
||||
uint8_t* data_wr = (uint8_t*)malloc(sizeof(uint8_t)*400);
|
||||
size_t i2s_bytes_write = 0;
|
||||
size_t bytes_read = 0;
|
||||
int length = 0;
|
||||
uint8_t *i2s_read_buff = (uint8_t*)malloc(sizeof(uint8_t)*10000);
|
||||
|
||||
for(int i=0; i<100; i++) {
|
||||
data_wr[i] = i+1;
|
||||
}
|
||||
int flag=0; // break loop flag
|
||||
int end_position = 0;
|
||||
// write data to slave
|
||||
i2s_write(I2S_NUM_0, data_wr, sizeof(uint8_t)*400, &i2s_bytes_write, 1000 / portTICK_PERIOD_MS);
|
||||
while(!flag){
|
||||
if (length >= 10000 - 500) {
|
||||
break;
|
||||
}
|
||||
i2s_read(I2S_NUM_0, i2s_read_buff + length, sizeof(uint8_t)*500, &bytes_read, 1000/portMAX_DELAY);
|
||||
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;
|
||||
end_position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
length = length + bytes_read;
|
||||
}
|
||||
// test the readed data right or not
|
||||
for(int i=end_position-99; i<=end_position; i++) {
|
||||
TEST_ASSERT(*(i2s_read_buff + i) == (i-end_position+100));
|
||||
}
|
||||
free(data_wr);
|
||||
free(i2s_read_buff);
|
||||
i2s_driver_uninstall(I2S_NUM_0);
|
||||
}
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP32S2)
|
||||
/* ESP32S2BETA has only single I2S port and hence following test cases are not applicable */
|
||||
TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s][test_env=UT_T1_I2S]")
|
||||
{
|
||||
// master driver installed and send data
|
||||
@ -101,6 +224,7 @@ TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s][test_env=UT_
|
||||
};
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config));
|
||||
i2s_test_io_config(1);
|
||||
printf("\r\nheap size: %d\n", esp_get_free_heap_size());
|
||||
|
||||
i2s_config_t slave_i2s_config = {
|
||||
@ -123,6 +247,7 @@ TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s][test_env=UT_
|
||||
// slave driver installed and receive data
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_1, &slave_i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_1, &slave_pin_config));
|
||||
i2s_test_io_config(1);
|
||||
printf("\r\nheap size: %d\n", esp_get_free_heap_size());
|
||||
|
||||
uint8_t* data_wr = (uint8_t*)malloc(sizeof(uint8_t)*400);
|
||||
@ -173,7 +298,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s][test_env=UT_
|
||||
.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
|
||||
.dma_buf_count = 6,
|
||||
.dma_buf_len = 100,
|
||||
.use_apll = 0,
|
||||
.use_apll = 1,
|
||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 ,
|
||||
};
|
||||
i2s_pin_config_t master_pin_config = {
|
||||
@ -184,6 +309,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s][test_env=UT_
|
||||
};
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config));
|
||||
i2s_test_io_config(0);
|
||||
printf("\r\nheap size: %d\n", esp_get_free_heap_size());
|
||||
|
||||
i2s_config_t slave_i2s_config = {
|
||||
@ -194,7 +320,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s][test_env=UT_
|
||||
.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
|
||||
.dma_buf_count = 6,
|
||||
.dma_buf_len = 100,
|
||||
.use_apll = 0,
|
||||
.use_apll = 1,
|
||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 ,
|
||||
};
|
||||
i2s_pin_config_t slave_pin_config = {
|
||||
@ -206,6 +332,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s][test_env=UT_
|
||||
// slave driver installed and receive data
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_1, &slave_i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_1, &slave_pin_config));
|
||||
i2s_test_io_config(0);
|
||||
|
||||
uint8_t* data_wr = (uint8_t*)malloc(sizeof(uint8_t)*400);
|
||||
size_t i2s_bytes_write = 0;
|
||||
@ -244,7 +371,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s][test_env=UT_
|
||||
i2s_driver_uninstall(I2S_NUM_0);
|
||||
i2s_driver_uninstall(I2S_NUM_1);
|
||||
}
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32 */
|
||||
#endif
|
||||
|
||||
TEST_CASE("I2S memory leaking test", "[i2s]")
|
||||
{
|
||||
@ -268,12 +395,14 @@ TEST_CASE("I2S memory leaking test", "[i2s]")
|
||||
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config));
|
||||
i2s_test_io_config(1);
|
||||
i2s_driver_uninstall(I2S_NUM_0);
|
||||
int initial_size = esp_get_free_heap_size();
|
||||
|
||||
for(int i=0; i<100; i++) {
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config));
|
||||
i2s_test_io_config(1);
|
||||
i2s_driver_uninstall(I2S_NUM_0);
|
||||
TEST_ASSERT(initial_size == esp_get_free_heap_size());
|
||||
}
|
||||
@ -309,6 +438,7 @@ TEST_CASE("I2S APLL clock variation test", "[i2s]")
|
||||
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &pin_config));
|
||||
i2s_test_io_config(1);
|
||||
TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0));
|
||||
int initial_size = esp_get_free_heap_size();
|
||||
|
||||
@ -322,6 +452,7 @@ TEST_CASE("I2S APLL clock variation test", "[i2s]")
|
||||
|
||||
TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL));
|
||||
TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &pin_config));
|
||||
i2s_test_io_config(1);
|
||||
TEST_ASSERT((fabs((i2s_get_clk(I2S_NUM_0) - sample_rate_arr[i]))/(sample_rate_arr[i]))*100 < PERCENT_DIFF);
|
||||
TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0));
|
||||
TEST_ASSERT(initial_size == esp_get_free_heap_size());
|
||||
|
@ -158,6 +158,7 @@ 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 I2S_SUPPORTS_PDM
|
||||
/**
|
||||
* @brief Get I2S tx pdm
|
||||
*
|
||||
@ -166,6 +167,7 @@ void i2s_hal_set_in_link(i2s_hal_context_t *hal, uint32_t rx_eof_num, uint32_t a
|
||||
* @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
|
||||
@ -246,6 +248,7 @@ void i2s_hal_stop_tx(i2s_hal_context_t *hal);
|
||||
*/
|
||||
void i2s_hal_stop_rx(i2s_hal_context_t *hal);
|
||||
|
||||
#if I2S_SUPPORTS_PDM
|
||||
/**
|
||||
* @brief Set I2S pdm rx down sample
|
||||
*
|
||||
@ -253,6 +256,7 @@ void i2s_hal_stop_rx(i2s_hal_context_t *hal);
|
||||
* @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
|
||||
|
@ -26,7 +26,14 @@ extern "C" {
|
||||
/**
|
||||
* @brief I2S port number, the max port number is (I2S_NUM_MAX -1).
|
||||
*/
|
||||
typedef int i2s_port_t;
|
||||
typedef enum {
|
||||
I2S_NUM_0 = 0, /*!< I2S port 0 */
|
||||
#if SOC_I2S_NUM > 1
|
||||
I2S_NUM_1 = 1, /*!< I2S port 1 */
|
||||
#endif
|
||||
I2S_NUM_MAX, /*!< I2S port max */
|
||||
} i2s_port_t;
|
||||
|
||||
|
||||
#define I2S_PIN_NO_CHANGE (-1) /*!< Use in i2s_pin_config_t for pins which should not be changed */
|
||||
|
||||
@ -75,6 +82,7 @@ typedef enum {
|
||||
I2S_CHANNEL_FMT_ONLY_LEFT,
|
||||
} i2s_channel_fmt_t;
|
||||
|
||||
#if I2S_SUPPORTS_PDM
|
||||
/**
|
||||
* @brief PDM sample rate ratio, measured in Hz.
|
||||
*
|
||||
@ -92,6 +100,7 @@ typedef enum {
|
||||
PDM_PCM_CONV_ENABLE,
|
||||
PDM_PCM_CONV_DISABLE,
|
||||
} pdm_pcm_conv_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief I2S Mode, defaut is I2S_MODE_MASTER | I2S_MODE_TX
|
||||
@ -106,7 +115,7 @@ typedef enum {
|
||||
I2S_MODE_RX = 8,
|
||||
I2S_MODE_DAC_BUILT_IN = 16, /*!< 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*/
|
||||
I2S_MODE_ADC_BUILT_IN = 32, /*!< Input I2S data from built-in ADC, each data can be 12-bit width at most*/
|
||||
#if SOC_I2S_SUPPORT_PDM
|
||||
#if I2S_SUPPORTS_PDM
|
||||
I2S_MODE_PDM = 64,
|
||||
#endif
|
||||
} i2s_mode_t;
|
||||
@ -173,7 +182,7 @@ typedef struct {
|
||||
int data_in_num; /*!< DATA in pin*/
|
||||
} i2s_pin_config_t;
|
||||
|
||||
#if SOC_I2S_SUPPORT_PDM
|
||||
#if I2S_SUPPORTS_PDM
|
||||
/**
|
||||
* @brief I2S PDM RX downsample mode
|
||||
*/
|
||||
|
@ -26,12 +26,9 @@ extern "C" {
|
||||
#define I2S_BASE_CLK (2*APB_CLK_FREQ)
|
||||
|
||||
// ESP32 have 2 I2S
|
||||
#define I2S_NUM_0 (0) /*!< I2S port 0 */
|
||||
#define I2S_NUM_1 (1) /*!< I2S port 1 */
|
||||
#define I2S_NUM_MAX (2) /*!< I2S port max */
|
||||
#define SOC_I2S_NUM (I2S_NUM_MAX)
|
||||
#define SOC_I2S_NUM (2)
|
||||
|
||||
#define SOC_I2S_SUPPORT_PDM (1) //ESP32 support PDM
|
||||
#define I2S_SUPPORTS_PDM (1) //ESP32 support PDM
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -17,14 +17,12 @@
|
||||
#define APLL_MIN_FREQ (250000000)
|
||||
#define APLL_MAX_FREQ (500000000)
|
||||
#define APLL_I2S_MIN_RATE (10675) //in Hz, I2S Clock rate limited by hardware
|
||||
#define I2S_AD_BCK_FACTOR (2)
|
||||
#define I2S_AD_BCK_FACTOR (1)
|
||||
#define I2S_PDM_BCK_FACTOR (64)
|
||||
#define I2S_MAX_BUFFER_SIZE (4 * 1024 * 1024) //the maximum RAM can be allocated
|
||||
#define I2S_BASE_CLK (2*APB_CLK_FREQ)
|
||||
|
||||
// ESP32-S2 have 1 I2S
|
||||
#define I2S_NUM_0 (0) /*!< I2S port 0 */
|
||||
#define I2S_NUM_MAX (1) /*!< I2S port max */
|
||||
#define SOC_I2S_NUM (I2S_NUM_MAX)
|
||||
// ESP32-S2 have 2 I2S
|
||||
#define SOC_I2S_NUM (1)
|
||||
|
||||
#define SOC_I2S_SUPPORT_PDM (0) // ESP32-S2 do not support PDM
|
||||
#define I2S_SUPPORTS_PDM (0) // ESP32-S2 do not support PDM
|
||||
|
@ -386,61 +386,6 @@ static inline void i2s_ll_set_rx_eof_num(i2s_dev_t *hw, uint32_t val)
|
||||
hw->rx_eof_num = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
@ -529,17 +474,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
|
||||
*
|
||||
@ -573,50 +507,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 msb shift
|
||||
*
|
||||
@ -793,17 +683,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
|
||||
*
|
||||
|
@ -50,11 +50,13 @@ void i2s_hal_set_in_link(i2s_hal_context_t *hal, uint32_t bytes_num, uint32_t ad
|
||||
i2s_ll_set_rx_eof_num(hal->dev, bytes_num);
|
||||
}
|
||||
|
||||
#if I2S_SUPPORTS_PDM
|
||||
void i2s_hal_get_tx_pdm(i2s_hal_context_t *hal, int *fp, int *fs)
|
||||
{
|
||||
i2s_ll_get_tx_pdm_fp(hal->dev, (uint32_t *)fp);
|
||||
i2s_ll_get_tx_pdm_fs(hal->dev, (uint32_t *)fs);
|
||||
}
|
||||
#endif
|
||||
|
||||
void i2s_hal_set_clk_div(i2s_hal_context_t *hal, int div_num, int div_a, int div_b, int tx_bck_div, int rx_bck_div)
|
||||
{
|
||||
@ -121,8 +123,10 @@ void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_config_t *i2s_config
|
||||
|
||||
i2s_ll_set_lcd_en(hal->dev, 0);
|
||||
i2s_ll_set_camera_en(hal->dev, 0);
|
||||
#if I2S_SUPPORTS_PDM
|
||||
i2s_ll_set_pcm2pdm_conv_en(hal->dev, 0);
|
||||
i2s_ll_set_pdm2pcm_conv_en(hal->dev, 0);
|
||||
#endif
|
||||
|
||||
i2s_ll_set_dscr_en(hal->dev, 0);
|
||||
|
||||
@ -168,7 +172,7 @@ void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_config_t *i2s_config
|
||||
i2s_ll_set_camera_en(hal->dev, 0);
|
||||
}
|
||||
|
||||
#if SOC_I2S_SUPPORT_PDM
|
||||
#if I2S_SUPPORTS_PDM
|
||||
if (i2s_config->mode & I2S_MODE_PDM) {
|
||||
i2s_ll_set_rx_fifo_mod_force_en(hal->dev, 1);
|
||||
i2s_ll_set_tx_fifo_mod_force_en(hal->dev, 1);
|
||||
@ -190,11 +194,8 @@ void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_config_t *i2s_config
|
||||
i2s_ll_set_rx_pdm_en(hal->dev, 0);
|
||||
i2s_ll_set_tx_pdm_en(hal->dev, 0);
|
||||
}
|
||||
#else
|
||||
i2s_ll_set_rx_pdm_en(hal->dev, 0);
|
||||
i2s_ll_set_tx_pdm_en(hal->dev, 0);
|
||||
#endif
|
||||
if (i2s_config->communication_format & I2S_COMM_FORMAT_I2S || i2s_config->communication_format & I2S_COMM_FORMAT_I2S_MSB || i2s_config->communication_format & I2S_COMM_FORMAT_I2S_LSB) {
|
||||
if (i2s_config->communication_format & I2S_COMM_FORMAT_I2S) {
|
||||
i2s_ll_set_tx_short_sync(hal->dev, 0);
|
||||
i2s_ll_set_rx_short_sync(hal->dev, 0);
|
||||
i2s_ll_set_tx_msb_shift(hal->dev, 1);
|
||||
@ -209,7 +210,7 @@ void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_config_t *i2s_config
|
||||
}
|
||||
}
|
||||
|
||||
if (i2s_config->communication_format & I2S_COMM_FORMAT_PCM || i2s_config->communication_format & I2S_COMM_FORMAT_PCM_LONG || i2s_config->communication_format & I2S_COMM_FORMAT_PCM_SHORT) {
|
||||
if (i2s_config->communication_format & I2S_COMM_FORMAT_PCM) {
|
||||
i2s_ll_set_tx_msb_shift(hal->dev, 0);
|
||||
i2s_ll_set_rx_msb_shift(hal->dev, 0);
|
||||
i2s_ll_set_tx_short_sync(hal->dev, 0);
|
||||
|
@ -682,13 +682,14 @@ void app_main(void)
|
||||
i2s_config_t i2s_config = {
|
||||
#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
|
||||
.communication_format = I2S_COMM_FORMAT_PCM,
|
||||
#else
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_TX, // Only TX
|
||||
.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
|
||||
#endif
|
||||
.sample_rate = 44100,
|
||||
.bits_per_sample = 16,
|
||||
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels
|
||||
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
|
||||
.dma_buf_count = 6,
|
||||
.dma_buf_len = 60,
|
||||
.intr_alloc_flags = 0, //Default interrupt priority
|
||||
|
@ -2,6 +2,6 @@
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(SUPPORTED_TARGETS esp32)
|
||||
set(SUPPORTED_TARGETS esp32 esp32s2beta)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(i2s-adc-dac)
|
||||
|
@ -9,7 +9,9 @@
|
||||
#include "driver/i2s.h"
|
||||
#include "driver/adc.h"
|
||||
#include "audio_example_file.h"
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp_adc_cal.h"
|
||||
#endif
|
||||
|
||||
static const char* TAG = "ad/da";
|
||||
#define V_REF 1100
|
||||
@ -63,10 +65,10 @@ void example_i2s_init(void)
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
|
||||
.sample_rate = EXAMPLE_I2S_SAMPLE_RATE,
|
||||
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
|
||||
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
|
||||
.communication_format = I2S_COMM_FORMAT_PCM,
|
||||
.channel_format = EXAMPLE_I2S_FORMAT,
|
||||
.intr_alloc_flags = 0,
|
||||
.dma_buf_count = 2,
|
||||
.dma_buf_count = 4,
|
||||
.dma_buf_len = 1024,
|
||||
.use_apll = 1,
|
||||
};
|
||||
@ -270,11 +272,17 @@ void adc_read_task(void* arg)
|
||||
{
|
||||
adc1_config_width(ADC_WIDTH_12Bit);
|
||||
adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_11db);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
esp_adc_cal_characteristics_t characteristics;
|
||||
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, V_REF, &characteristics);
|
||||
#endif
|
||||
while(1) {
|
||||
uint32_t voltage;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
esp_adc_cal_get_voltage(ADC1_TEST_CHANNEL, &characteristics, &voltage);
|
||||
#else
|
||||
voltage = adc1_get_raw(ADC1_TEST_CHANNEL) * (3300.0 / 4095); // At 11 dB attenuation the maximum voltage is limited by VDD_A(3300 mV), not the full scale voltage.
|
||||
#endif
|
||||
ESP_LOGI(TAG, "%d mV", voltage);
|
||||
vTaskDelay(200 / portTICK_RATE_MS);
|
||||
}
|
||||
|
@ -460,6 +460,12 @@ UT_026:
|
||||
- UT_T1_I2S
|
||||
- psram
|
||||
|
||||
UT_027:
|
||||
extends: .unit_test_template
|
||||
tags:
|
||||
- ESP32S2BETA_IDF
|
||||
- UT_T1_I2S
|
||||
|
||||
UT_028:
|
||||
extends: .unit_test_template
|
||||
tags:
|
||||
|
Loading…
Reference in New Issue
Block a user