Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32s3 Interrupt ADC1_DONE_INT in Continuous ADC mode have fixed frequency regardless on the sample rate of the ADC (Is it a hardware bug ?)) (IDFGH-10365) #11623

Open
3 tasks done
5ami opened this issue Jun 8, 2023 · 1 comment
Labels
Status: Selected for Development Issue is selected for development

Comments

@5ami
Copy link

5ami commented Jun 8, 2023

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

General issue report

I am working with the ADC_continous Example from ESP-IDF 5.0 with some modification.

I saw many issues with Continuous ADC sample rate #11604 ,
#10612

I tried to to test myself the sample rate of the ADC and The issue I am facing is that changing .sample_freq_hz doesn't have an effect on the ADC1_DONE_INT Interrupt (check ESP32s3 TRM Register 39.72. APB_SARADC_INT_ENA_REG (0x005C) .

I am checking the sampling rate by toggling a GPIO15 at APB_ADC_INT interrupt. but the Interrupt frequency does not seem to change when I change .sample_freq_hz

This is what I get. the GPIO is toggled inside the interrupt, so the expected behavior's is that the GPIO is toggled at the same frequency I set for the ADC sample rate. But it is always fixed at around 1.4MHZ

Here is my source code and the picture from the scope.

/*
 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <stdio.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_adc/adc_continuous.h"

#include "soc/gpio_periph.h"
#include "soc/soc_caps.h"
#include "hal/gpio_ll.h"
#include "hal/gpio_types.h"
#include "soc/soc.h"    
#include "soc/gpio_sig_map.h"

#include "soc/soc.h"
#include "soc/apb_saradc_reg.h"
#include "rom/ets_sys.h"
#include "xtensa/xtensa_api.h"

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


#define ADC_CONV_MODE       ADC_CONV_BOTH_UNIT
#define ADC_OUTPUT_TYPE     ADC_DIGI_OUTPUT_FORMAT_TYPE2


static adc_channel_t channel[2] = {ADC_CHANNEL_2, (ADC_CHANNEL_0 | 1 << 3)};


uint32_t cb_num = 0; 
static const char *TAG = "EXAMPLE";


void IRAM_ATTR my_int(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data)
{
    //TOGGLE GPIO
    (&GPIO)->out_w1ts = (1 << 15);
    (&GPIO)->out_w1tc = (1 << 15);
    cb_num++; 
}

static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc_continuous_handle_t *out_handle)
{
    adc_continuous_handle_t handle = NULL;

    adc_continuous_handle_cfg_t adc_config = {
        .max_store_buf_size = 32,
        .conv_frame_size = EXAMPLE_READ_LEN,
    };
    adc_continuous_new_handle(&adc_config, &handle);

    adc_continuous_config_t dig_cfg = {
        .sample_freq_hz = 10 * 1000,
        .conv_mode = ADC_CONV_BOTH_UNIT,
        .format = ADC_DIGI_OUTPUT_FORMAT_TYPE2,
    };

    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 = SOC_ADC_DIGI_MAX_BITWIDTH;
    }
    dig_cfg.adc_pattern = adc_pattern;
    
    adc_continuous_config(handle, &dig_cfg);

    *out_handle = handle;
}

static bool check_valid_data(const adc_digi_output_data_t *data)
{
    const unsigned int unit = data->type2.unit;
    if (unit > 2) return false;
    if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) return false;

    return true;
}

void app_main(void)
{
    //Set GPIO as OUTPUT
    (&GPIO)->enable_w1ts = (0x1 << 15);
    esp_err_t ret;
    uint32_t ret_num = 0;
    uint8_t result[EXAMPLE_READ_LEN] = {0};
    memset(result, 0xcc, EXAMPLE_READ_LEN);

    adc_continuous_handle_t handle = NULL;
    continuous_adc_init(channel, sizeof(channel) / sizeof(adc_channel_t), &handle);

    /*Setting up the Interrupt*/
    /*APB_SARADC_ADC1_DONE_INT: Triggered when SAR ADC1 completes one data conversion.*/
    REG_SET_BIT(APB_SARADC_INT_ENA_REG, APB_SARADC_ADC1_DONE_INT_ENA); 
    xt_ints_off(1<<13);
    intr_matrix_set(0, 65, 13);
    xt_ints_on(1<<13);
    xt_set_interrupt_handler(13,  my_int, NULL); 
    

    ESP_ERROR_CHECK(adc_continuous_start(handle));

    while(1) {
        while (1) {
            ret = adc_continuous_read(handle, result, EXAMPLE_READ_LEN, &ret_num, 0);
            
            if (ret == ESP_OK) {
                ESP_LOGI("TASK", "ret is %d, ret_num is %"PRIu32, ret, ret_num);
                ESP_LOGI("TASK", "cb_num %ld" , cb_num);
                for (int i = 0; i < ret_num; i += SOC_ADC_DIGI_RESULT_BYTES) {
                    adc_digi_output_data_t *p = (void*)&result[i];
                    if (ADC_CONV_MODE == ADC_CONV_BOTH_UNIT || ADC_CONV_MODE == ADC_CONV_ALTER_UNIT) {
                        if (check_valid_data(p)) {
                            ESP_LOGI(TAG, "Unit: %d,_Channel: %d, Value: %d", p->type2.unit+1, p->type2.channel, p->type2.data);
                        } else {
                            ESP_LOGI(TAG, "Invalid data [%d_%d_%x]", p->type2.unit+1, p->type2.channel, p->type2.data);
                        }
                    }
                }
                vTaskDelay(1);
            } 
        }
    }  
}

Continous ADC INT DONE

@espressif-bot espressif-bot added the Status: Opened Issue is new label Jun 8, 2023
@github-actions github-actions bot changed the title ESP32s3 Interrupt ADC1_DONE_INT in Continuous ADC mode have fixed frequency regardless on the sample rate of the ADC (Is it a hardware bug ?)) ESP32s3 Interrupt ADC1_DONE_INT in Continuous ADC mode have fixed frequency regardless on the sample rate of the ADC (Is it a hardware bug ?)) (IDFGH-10365) Jun 8, 2023
@espressif-bot espressif-bot added Status: Selected for Development Issue is selected for development and removed Status: Opened Issue is new labels Jun 12, 2023
@lukasfischer83
Copy link

Hi 5ami,
did you try to reset the interrupt flag in your ISR?
REG_SET_BIT(APB_SARADC_INT_CLR_REG, APB_SARADC_ADC1_DONE_INT_CLR);
BR, Lukas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Selected for Development Issue is selected for development
Projects
None yet
Development

No branches or pull requests

3 participants