Need help with ESP32 ADC DMA continuous read configuration

noemasson
Posts: 3
Joined: Mon May 02, 2022 9:58 am

Need help with ESP32 ADC DMA continuous read configuration

Postby noemasson » Mon May 02, 2022 11:08 am

Hello,

I am trying to read an analog signal through two ADC1 channels. The signal comes from a frequency generator and the idea is to run an FFT with the data acquired. I am using ESP32 with SDK v4.4.1.

When using continuous ADC, I am able to get a buffer containing the data from both channels (channels 6 and 7). However, the total number of outputs from these channels seems to be stuck to 256. The rest of the buffer is filled with data from Channel 0 with value 0. This is the case no matter how I configure the continuous ADC.
Screenshot from 2022-05-02 12-57-54.png
Screenshot from 2022-05-02 12-57-54.png (201.41 KiB) Viewed 4999 times
I did my project following adc_dma_exemple, but I can't find an answer in there or in the documentation.

Here is my code to setup everything :

The configuration :

Code: Select all

#define TIMES              1024
#define SAMPLE_FREQUENCY   80000

#define GET_UNIT(x)        ((x>>3) & 0x1)

#if CONFIG_IDF_TARGET_ESP32
#define ADC_RESULT_BYTE     2
#define ADC_CONV_LIMIT_EN   1                       //For ESP32, this should always be set to 1
#define ADC_CONV_MODE       ADC_CONV_SINGLE_UNIT_1  //ESP32 only supports ADC1 DMA mode
#define ADC_OUTPUT_TYPE     ADC_DIGI_OUTPUT_FORMAT_TYPE1
#endif

#if CONFIG_IDF_TARGET_ESP32
static uint16_t adc1_chan_mask = BIT(6) | BIT(7);
static uint16_t adc2_chan_mask = 0;
static adc_channel_t channel[2] = {ADC1_CHANNEL_6, ADC1_CHANNEL_7};
#endif

static const char *TAG = "ADC DMA";

static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num)
{
    adc_digi_init_config_t adc_dma_config = {
        .max_store_buf_size = 1024,
        .conv_num_each_intr = TIMES,
        .adc1_chan_mask = adc1_chan_mask,
        .adc2_chan_mask = adc2_chan_mask,
    };
    ESP_ERROR_CHECK(adc_digi_initialize(&adc_dma_config));

    adc_digi_configuration_t dig_cfg = {
        .conv_limit_en = ADC_CONV_LIMIT_EN,
        .conv_limit_num = 250,
        .sample_freq_hz = SAMPLE_FREQUENCY,
        .conv_mode = ADC_CONV_MODE,
        .format = ADC_OUTPUT_TYPE,
    };

    adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
    dig_cfg.pattern_num = channel_num;
    for (int i = 0; i < channel_num; i++) {
        uint8_t unit = GET_UNIT(channel[i]);
        uint8_t ch = channel[i] & 0x7;
        adc_pattern[i].atten = ADC_ATTEN_DB_11;
        adc_pattern[i].channel = ch;
        adc_pattern[i].unit = unit;
        adc_pattern[i].bit_width = 12;

        ESP_LOGI(TAG, "adc_pattern[%d].atten is :%d", i, adc_pattern[i].atten);
        ESP_LOGI(TAG, "adc_pattern[%d].channel is :%d", i, adc_pattern[i].channel);
        ESP_LOGI(TAG, "adc_pattern[%d].unit is :%d", i, adc_pattern[i].unit);
    }
    dig_cfg.adc_pattern = adc_pattern;
    ESP_ERROR_CHECK(adc_digi_controller_configure(&dig_cfg));
}

esp_err_t adc_init()
{
    esp_err_t error_code;

    continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t));

    error_code = adc1_config_width(ADC_WIDTH_BIT_12);
    if(error_code != ESP_OK)
    {
        return error_code;
    }
    adc_digi_start();

    return ESP_OK;
}


This function is called every 10ms to get the buffer

Code: Select all

int IRAM_ATTR read_adc_dma(uint32_t *ret_num, uint16_t *result)
{
    esp_err_t ret;
    ret = adc_digi_read_bytes(result, TIMES, ret_num, ADC_MAX_DELAY);
    return ret;
}
I then sort the received buffer into two buffers to run through the FFT and obtain the signal characteristics of both channels

Code: Select all

void sort_dma_data_into_buffers(uint16_t *buff_ch0, uint16_t *buff_ch1, uint32_t ret_num, uint32_t *i0, uint32_t *i1, uint16_t *result)
{
    uint32_t n0 = 0;
    uint32_t n1 = 0;
    for (int i = 0; i < ret_num; i += ADC_RESULT_BYTE) {
        adc_digi_output_data_t *p = (void*)&result[i];
        // printf("3.1\n");
        if(p->type1.channel == ADC1_CHANNEL_6)
        {
            buff_ch0[n0] = p->type1.data;
            n0++;
        }
        else if(p->type1.channel == ADC1_CHANNEL_7)
        {
            buff_ch1[n1] = p->type1.data;
            n1++;
        }
    }
    *i0 = n0;
    *i1 = n1;
}
I would like to increase the size of the buffer to run more data through the FFT.
I hope any of you have a solution.
Thanks !

noemasson
Posts: 3
Joined: Mon May 02, 2022 9:58 am

Re: Need help with ESP32 ADC DMA continuous read configuration

Postby noemasson » Tue May 17, 2022 2:18 pm

Update :

I finally settled for using i2s with DMA for this. However the SDK does not yet allow to use i2s on multiple ADC channels simultaneously. So I used an unmerged topic from github :
https://github.com/espressif/esp-idf/pull/1991

I adapted the code from this for sdk v4.4.1. It allowed me to use i2s channel patterns to setup multiple ADC channels for DMA. These channels are all written is the same buffer so a little bit of work is needed to use the buffer for the FFT I wanted.

If you're interested I can share the modifications I did in the drivers as well as the config I used for my project.

I hope it is useful to you

blackphoenix
Posts: 1
Joined: Wed Aug 03, 2022 2:45 pm

Re: Need help with ESP32 ADC DMA continuous read configuration

Postby blackphoenix » Wed Aug 03, 2022 2:52 pm

noemasson wrote:
If you're interested I can share the modifications I did in the drivers as well as the config I used for my project.
Hi,
I am struggling a bit with the modifications to the SDK. Could you share your work pls.

Thanks

DiemsWO
Posts: 1
Joined: Sun Mar 26, 2023 10:27 pm

Re: Need help with ESP32 ADC DMA continuous read configuration

Postby DiemsWO » Mon Mar 27, 2023 1:46 pm

Hi Noe, could you please inform which libraries are required to run that code you showed in your post?

SerhiiZhylin
Posts: 1
Joined: Thu Aug 03, 2023 11:35 am

Re: Need help with ESP32 ADC DMA continuous read configuration

Postby SerhiiZhylin » Thu Aug 03, 2023 11:54 am

noemasson wrote:
Tue May 17, 2022 2:18 pm
Update :

I finally settled for using i2s with DMA for this.
Hello. Could you, please, share the final working code? :)

Who is online

Users browsing this forum: Baidu [Spider], Majestic-12 [Bot], Marcosss and 105 guests