mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/fix_adc-dma_reading_gap_for_esp32' into 'master'
bugfix(adc): missing ranges of ADC-DMA codes in ESP32 Closes DIG-53 See merge request espressif/esp-idf!10521
This commit is contained in:
commit
ecca44df93
@ -335,9 +335,16 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
|
||||
}
|
||||
|
||||
i2s_stop(i2s_num);
|
||||
|
||||
i2s_hal_set_tx_mode(&(p_i2s_obj[i2s_num]->hal), ch, bits);
|
||||
#if SOC_I2S_SUPPORTS_ADC_DAC
|
||||
/* I2S-ADC only support single channel format. */
|
||||
if (!(p_i2s_obj[i2s_num]->mode & I2S_MODE_ADC_BUILT_IN)) {
|
||||
i2s_hal_set_rx_mode(&(p_i2s_obj[i2s_num]->hal), ch, bits);
|
||||
}
|
||||
#else
|
||||
i2s_hal_set_rx_mode(&(p_i2s_obj[i2s_num]->hal), ch, bits);
|
||||
#endif
|
||||
i2s_hal_set_tx_mode(&(p_i2s_obj[i2s_num]->hal), ch, bits);
|
||||
|
||||
if (p_i2s_obj[i2s_num]->channel_num != ch) {
|
||||
p_i2s_obj[i2s_num]->channel_num = (ch == 2) ? 2 : 1;
|
||||
}
|
||||
|
@ -299,6 +299,7 @@ float i2s_get_clk(i2s_port_t i2s_num);
|
||||
/**
|
||||
* @brief Set built-in ADC mode for I2S DMA, this function will initialize ADC pad,
|
||||
* and set ADC parameters.
|
||||
* @note In this mode, the ADC maximum sampling rate is 150KHz. Set the sampling rate through ``i2s_config_t``.
|
||||
* @param adc_unit SAR ADC unit index
|
||||
* @param adc_channel ADC channel index
|
||||
* @return
|
||||
|
@ -35,32 +35,25 @@
|
||||
* ADC DMA testcase
|
||||
*/
|
||||
#include "driver/i2s.h"
|
||||
#include "test/test_common_adc.h"
|
||||
|
||||
//i2s number
|
||||
#define EXAMPLE_I2S_NUM (0)
|
||||
//i2s sample rate
|
||||
#define EXAMPLE_I2S_SAMPLE_RATE (16000)
|
||||
#define EXAMPLE_I2S_SAMPLE_RATE (150000)
|
||||
//i2s data bits
|
||||
#define EXAMPLE_I2S_SAMPLE_BITS (16)
|
||||
//enable display buffer for debug
|
||||
#define EXAMPLE_I2S_BUF_DEBUG (0)
|
||||
//I2S read buffer length
|
||||
#define EXAMPLE_I2S_READ_LEN (16 * 1024)
|
||||
//I2S data format
|
||||
#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT)
|
||||
//I2S channel number
|
||||
#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1))
|
||||
//I2S data format, ADC-I2S only support mono.
|
||||
#define EXAMPLE_I2S_FORMAT I2S_CHANNEL_FMT_ONLY_RIGHT
|
||||
//I2S built-in ADC unit
|
||||
#define I2S_ADC_UNIT ADC_UNIT_1
|
||||
//I2S built-in ADC channel
|
||||
#define I2S_ADC_CHANNEL ADC1_CHANNEL_4
|
||||
|
||||
//flash record size, for recording 5 seconds' data
|
||||
#define FLASH_RECORD_SIZE (EXAMPLE_I2S_CHANNEL_NUM * EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_SAMPLE_BITS / 8 * 5)
|
||||
#define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE)
|
||||
//sector size of flash
|
||||
#define FLASH_SECTOR_SIZE (0x1000)
|
||||
|
||||
/**
|
||||
* @brief I2S ADC/DAC mode init.
|
||||
*/
|
||||
@ -68,15 +61,16 @@ static void example_i2s_init(void)
|
||||
{
|
||||
int i2s_num = EXAMPLE_I2S_NUM;
|
||||
i2s_config_t i2s_config = {
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN,
|
||||
.sample_rate = EXAMPLE_I2S_SAMPLE_RATE,
|
||||
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
|
||||
.channel_format = EXAMPLE_I2S_FORMAT,
|
||||
.intr_alloc_flags = 0,
|
||||
.dma_buf_count = 2,
|
||||
.dma_buf_len = 1024,
|
||||
.use_apll = 1,
|
||||
.use_apll = 0,
|
||||
};
|
||||
|
||||
//install and start i2s driver
|
||||
TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) );
|
||||
//init ADC pad
|
||||
@ -93,34 +87,73 @@ static void example_i2s_deinit(void)
|
||||
*/
|
||||
static void example_disp_buf(uint8_t *buf, int length)
|
||||
{
|
||||
printf("======\n");
|
||||
for (int i = 0; i < length; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
if ((i + 1) % 8 == 0) {
|
||||
printf("\n");
|
||||
printf("\n======");
|
||||
for (int i = 0; i < length; i += 2) {
|
||||
uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i];
|
||||
adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data;
|
||||
if ((i) % 16 == 0) printf("\n");
|
||||
printf("[%d_%d] ", p->type1.channel, p->type1.data);
|
||||
}
|
||||
printf("\n======\n");
|
||||
}
|
||||
|
||||
static esp_err_t adc_dma_data_check(uint8_t *buf, int length, int ideal_level)
|
||||
{
|
||||
for (int i = 0; i < length; i += 2) {
|
||||
uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i];
|
||||
adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data;
|
||||
if (p->type1.channel != I2S_ADC_CHANNEL) {
|
||||
TEST_FAIL_MESSAGE("I2S-DMA data channel error!");
|
||||
}
|
||||
if (ideal_level == 1) { // high level 3.3v
|
||||
TEST_ASSERT_EQUAL( 0xFFF, p->type1.data );
|
||||
} else if (ideal_level == 0) { // low level 0v
|
||||
TEST_ASSERT_LESS_THAN( 10, p->type1.data );
|
||||
} else if (ideal_level == 2) { // middle level 1.4v
|
||||
TEST_ASSERT_INT_WITHIN( 128, 1666, p->type1.data );
|
||||
} else if (ideal_level == 3) { // normal level
|
||||
} else { // no check
|
||||
}
|
||||
}
|
||||
printf("======\n");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void adc_dma_read(uint8_t *buf, int length)
|
||||
{
|
||||
size_t bytes_read = 0;
|
||||
int flash_wr_size = 0;
|
||||
|
||||
vTaskDelay(pdTICKS_TO_MS(100));
|
||||
while (flash_wr_size < length) {
|
||||
//read data from I2S bus, in this case, from ADC.
|
||||
TEST_ESP_OK( i2s_read(EXAMPLE_I2S_NUM, (void *) buf + flash_wr_size, length - flash_wr_size, &bytes_read, portMAX_DELAY) );
|
||||
flash_wr_size += bytes_read;
|
||||
example_disp_buf((uint8_t *) buf, 128);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ADC DMA read", "[adc dma]")
|
||||
{
|
||||
example_i2s_init();
|
||||
|
||||
int i2s_read_len = EXAMPLE_I2S_READ_LEN;
|
||||
int flash_wr_size = 0;
|
||||
size_t bytes_read;
|
||||
|
||||
char *i2s_read_buff = (char *) calloc(i2s_read_len, sizeof(char));
|
||||
|
||||
example_i2s_init();
|
||||
TEST_ESP_OK( i2s_adc_enable(EXAMPLE_I2S_NUM) );
|
||||
while (flash_wr_size < FLASH_RECORD_SIZE) {
|
||||
//read data from I2S bus, in this case, from ADC.
|
||||
TEST_ESP_OK( i2s_read(EXAMPLE_I2S_NUM, (void *) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY) );
|
||||
example_disp_buf((uint8_t *) i2s_read_buff, 64);
|
||||
//save original data from I2S(ADC) into flash.
|
||||
flash_wr_size += i2s_read_len;
|
||||
esp_rom_printf("Sound recording %u%%\n", flash_wr_size * 100 / FLASH_RECORD_SIZE);
|
||||
}
|
||||
|
||||
adc_fake_tie_low(I2S_ADC_UNIT, I2S_ADC_CHANNEL);
|
||||
adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len);
|
||||
adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 0);
|
||||
|
||||
adc_fake_tie_middle(I2S_ADC_UNIT, I2S_ADC_CHANNEL);
|
||||
adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len);
|
||||
adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 2);
|
||||
|
||||
adc_fake_tie_high(I2S_ADC_UNIT, I2S_ADC_CHANNEL);
|
||||
adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len);
|
||||
adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 1);
|
||||
|
||||
adc_io_normal(I2S_ADC_UNIT, I2S_ADC_CHANNEL);
|
||||
|
||||
TEST_ESP_OK( i2s_adc_disable(EXAMPLE_I2S_NUM) );
|
||||
if (i2s_read_buff) {
|
||||
free(i2s_read_buff);
|
||||
|
@ -57,14 +57,6 @@
|
||||
//I2S channel number
|
||||
#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1))
|
||||
|
||||
//flash record size, for recording 5 seconds' data
|
||||
#define FLASH_RECORD_SIZE (EXAMPLE_I2S_CHANNEL_NUM * EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_SAMPLE_BITS / 8 * 5)
|
||||
#define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE)
|
||||
//sector size of flash
|
||||
#define FLASH_SECTOR_SIZE (0x1000)
|
||||
//flash read / write address
|
||||
#define FLASH_ADDR (0x200000)
|
||||
|
||||
/**
|
||||
* @brief I2S ADC/DAC mode init.
|
||||
*/
|
||||
@ -72,23 +64,24 @@ static void example_i2s_init(void)
|
||||
{
|
||||
int i2s_num = EXAMPLE_I2S_NUM;
|
||||
i2s_config_t i2s_config = {
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
|
||||
.sample_rate = EXAMPLE_I2S_SAMPLE_RATE,
|
||||
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
|
||||
.channel_format = EXAMPLE_I2S_FORMAT,
|
||||
.intr_alloc_flags = 0,
|
||||
.dma_buf_count = 2,
|
||||
.dma_buf_len = 1024,
|
||||
.use_apll = 1,
|
||||
.use_apll = 0,
|
||||
};
|
||||
//install and start i2s driver
|
||||
TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) );
|
||||
//init DAC pad
|
||||
TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN) );
|
||||
TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN) );
|
||||
}
|
||||
|
||||
static void example_i2s_deinit(void)
|
||||
{
|
||||
TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_DISABLE) );
|
||||
TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) );
|
||||
}
|
||||
|
||||
@ -149,15 +142,16 @@ static void example_reset_play_mode(void)
|
||||
|
||||
TEST_CASE("DAC DMA output", "[dac]")
|
||||
{
|
||||
example_i2s_init();
|
||||
|
||||
size_t bytes_written;
|
||||
int i2s_read_len = EXAMPLE_I2S_READ_LEN;
|
||||
uint8_t *i2s_write_buff = (uint8_t *) calloc(i2s_read_len, sizeof(char));
|
||||
printf("Playing file example: \n");
|
||||
int offset = 0;
|
||||
int tot_size = sizeof(audio_table);
|
||||
printf("Playing file example: \n");
|
||||
|
||||
example_i2s_init();
|
||||
example_set_file_play_mode();
|
||||
|
||||
while (offset < tot_size) {
|
||||
int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset);
|
||||
int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t *)(audio_table + offset), play_len);
|
||||
@ -165,7 +159,7 @@ TEST_CASE("DAC DMA output", "[dac]")
|
||||
offset += play_len;
|
||||
example_disp_buf((uint8_t *) i2s_write_buff, 32);
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
example_reset_play_mode();
|
||||
free(i2s_write_buff);
|
||||
|
||||
|
@ -242,6 +242,9 @@ void i2s_hal_config_param(i2s_hal_context_t *hal, const i2s_config_t *i2s_config
|
||||
}
|
||||
if (i2s_config->mode & I2S_MODE_ADC_BUILT_IN) {
|
||||
i2s_ll_build_in_adc_ena(hal->dev);
|
||||
i2s_ll_set_rx_chan_mod(hal->dev, 1);
|
||||
i2s_ll_set_rx_fifo_mod(hal->dev, 1);
|
||||
i2s_ll_set_rx_mono(hal->dev, 0);
|
||||
}
|
||||
// Buildin ADC and DAC have nothing to do with communication format configuration.
|
||||
return;
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define SOC_ADC_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (1)
|
||||
|
||||
#define SOC_ADC_FSM_RSTB_WAIT_DEFAULT (8)
|
||||
#define SOC_ADC_FSM_START_WAIT_DEFAULT (5)
|
||||
#define SOC_ADC_FSM_START_WAIT_DEFAULT (SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT * 2)
|
||||
#define SOC_ADC_FSM_STANDBY_WAIT_DEFAULT (100)
|
||||
#define ADC_FSM_SAMPLE_CYCLE_DEFAULT (2)
|
||||
|
||||
@ -28,4 +28,4 @@
|
||||
|
||||
#define SOC_ADC_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (2)
|
||||
|
||||
#define SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT (2)
|
||||
#define SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT (16)
|
Loading…
Reference in New Issue
Block a user