Просмотр исходного кода

esp_adc: added adc digital filter feature

Armando 2 лет назад
Родитель
Сommit
3afa671069
38 измененных файлов с 1040 добавлено и 410 удалено
  1. 4 0
      components/esp_adc/CMakeLists.txt
  2. 1 34
      components/esp_adc/adc_continuous.c
  3. 87 0
      components/esp_adc/adc_continuous_internal.h
  4. 158 0
      components/esp_adc/adc_filter.c
  5. 1 4
      components/esp_adc/include/esp_adc/adc_continuous.h
  6. 88 0
      components/esp_adc/include/esp_adc/adc_filter.h
  7. 2 2
      components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c
  8. 256 65
      components/esp_adc/test_apps/adc/main/test_adc_performance.c
  9. 31 1
      components/esp_adc/test_apps/adc/main/test_common_adc.c
  10. 18 0
      components/esp_adc/test_apps/adc/main/test_common_adc.h
  11. 59 28
      components/hal/esp32c2/include/hal/adc_ll.h
  12. 56 45
      components/hal/esp32c3/include/hal/adc_ll.h
  13. 52 41
      components/hal/esp32c6/include/hal/adc_ll.h
  14. 57 45
      components/hal/esp32h4/include/hal/adc_ll.h
  15. 22 37
      components/hal/esp32s2/include/hal/adc_ll.h
  16. 54 35
      components/hal/esp32s3/include/hal/adc_ll.h
  17. 19 0
      components/hal/include/hal/adc_types.h
  18. 0 49
      components/hal/include/hal/adc_types_private.h
  19. 3 0
      components/idf_test/include/esp32/idf_performance_target.h
  20. 2 0
      components/idf_test/include/esp32c2/idf_performance_target.h
  21. 8 0
      components/idf_test/include/esp32c3/idf_performance_target.h
  22. 7 0
      components/idf_test/include/esp32c6/idf_performance_target.h
  23. 8 0
      components/idf_test/include/esp32s2/idf_performance_target.h
  24. 8 0
      components/idf_test/include/esp32s3/idf_performance_target.h
  25. 2 2
      components/soc/esp32c2/include/soc/Kconfig.soc_caps.in
  26. 2 2
      components/soc/esp32c2/include/soc/soc_caps.h
  27. 2 2
      components/soc/esp32c3/include/soc/Kconfig.soc_caps.in
  28. 2 2
      components/soc/esp32c3/include/soc/soc_caps.h
  29. 2 2
      components/soc/esp32c6/include/soc/Kconfig.soc_caps.in
  30. 2 2
      components/soc/esp32c6/include/soc/soc_caps.h
  31. 2 2
      components/soc/esp32h2/include/soc/Kconfig.soc_caps.in
  32. 2 2
      components/soc/esp32h2/include/soc/soc_caps.h
  33. 2 2
      components/soc/esp32h4/include/soc/Kconfig.soc_caps.in
  34. 2 2
      components/soc/esp32h4/include/soc/soc_caps.h
  35. 9 1
      components/soc/esp32s2/include/soc/Kconfig.soc_caps.in
  36. 3 1
      components/soc/esp32s2/include/soc/soc_caps.h
  37. 5 1
      components/soc/esp32s3/include/soc/Kconfig.soc_caps.in
  38. 2 1
      components/soc/esp32s3/include/soc/soc_caps.h

+ 4 - 0
components/esp_adc/CMakeLists.txt

@@ -17,6 +17,10 @@ if(CONFIG_SOC_ADC_DMA_SUPPORTED)
     list(APPEND srcs "adc_continuous.c")
 endif()
 
+if(CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED)
+    list(APPEND srcs "adc_filter.c")
+endif()
+
 # line fitting scheme
 if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}/adc_cali_line_fitting.c")
     list(APPEND srcs "${target}/adc_cali_line_fitting.c")

+ 1 - 34
components/esp_adc/adc_continuous.c

@@ -28,6 +28,7 @@
 #include "hal/adc_hal.h"
 #include "hal/dma_types.h"
 #include "esp_memory_utils.h"
+#include "adc_continuous_internal.h"
 //For DMA
 #if SOC_GDMA_SUPPORTED
 #include "esp_private/gdma.h"
@@ -51,40 +52,6 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi
 
 #define INTERNAL_BUF_NUM      5
 
-typedef enum {
-    ADC_FSM_INIT,
-    ADC_FSM_STARTED,
-} adc_fsm_t;
-
-/*---------------------------------------------------------------
-            Continuous Mode Driverr Context
----------------------------------------------------------------*/
-typedef struct adc_continuous_ctx_t {
-    uint8_t                         *rx_dma_buf;                //dma buffer
-    adc_hal_dma_ctx_t               hal;                        //hal context
-#if SOC_GDMA_SUPPORTED
-    gdma_channel_handle_t           rx_dma_channel;             //dma rx channel handle
-#elif CONFIG_IDF_TARGET_ESP32S2
-    spi_host_device_t               spi_host;                   //ADC uses this SPI DMA
-#elif CONFIG_IDF_TARGET_ESP32
-    i2s_port_t                      i2s_host;                   //ADC uses this I2S DMA
-#endif
-    intr_handle_t                   dma_intr_hdl;               //DMA Interrupt handler
-    RingbufHandle_t                 ringbuf_hdl;                //RX ringbuffer handler
-    void*                           ringbuf_storage;            //Ringbuffer storage buffer
-    void*                           ringbuf_struct;             //Ringbuffer structure buffer
-    intptr_t                        rx_eof_desc_addr;           //eof descriptor address of RX channel
-    adc_fsm_t                       fsm;                        //ADC continuous mode driver internal states
-    bool                            use_adc1;                   //1: ADC unit1 will be used; 0: ADC unit1 won't be used.
-    bool                            use_adc2;                   //1: ADC unit2 will be used; 0: ADC unit2 won't be used. This determines whether to acquire sar_adc2_mutex lock or not.
-    adc_atten_t                     adc1_atten;                 //Attenuation for ADC1. On this chip each ADC can only support one attenuation.
-    adc_atten_t                     adc2_atten;                 //Attenuation for ADC2. On this chip each ADC can only support one attenuation.
-    adc_hal_digi_ctrlr_cfg_t        hal_digi_ctrlr_cfg;         //Hal digital controller configuration
-    adc_continuous_evt_cbs_t    cbs;                        //Callbacks
-    void                            *user_data;                 //User context
-    esp_pm_lock_handle_t            pm_lock;                    //For power management
-} adc_continuous_ctx_t;
-
 #ifdef CONFIG_PM_ENABLE
 //Only for deprecated API
 extern esp_pm_lock_handle_t adc_digi_arbiter_lock;

+ 87 - 0
components/esp_adc/adc_continuous_internal.h

@@ -0,0 +1,87 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdkconfig.h"
+#include "esp_pm.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/ringbuf.h"
+#include "hal/adc_types.h"
+#include "hal/adc_hal.h"
+//For DMA
+#if SOC_GDMA_SUPPORTED
+#include "esp_private/gdma.h"
+#elif CONFIG_IDF_TARGET_ESP32S2
+#include "hal/spi_types.h"
+#elif CONFIG_IDF_TARGET_ESP32
+#include "driver/i2s_types.h"
+#endif
+
+#include "esp_adc/adc_filter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    ADC_FSM_INIT,
+    ADC_FSM_STARTED,
+} adc_fsm_t;
+
+/*---------------------------------------------------------------
+            Driver Context
+---------------------------------------------------------------*/
+typedef struct adc_iir_filter_t adc_iir_filter_t;
+typedef struct adc_continuous_ctx_t adc_continuous_ctx_t;
+
+/**
+ * @brief ADC iir filter context
+ */
+struct adc_iir_filter_t {
+    adc_digi_iir_filter_t filter_id;                            // Filter ID
+    adc_continuous_iir_filter_config_t  cfg;                    //filter configuration
+    adc_continuous_ctx_t                *continuous_ctx;        //ADC continuous driver context
+};
+
+/**
+ * @brief ADC continuous driver context
+ */
+struct adc_continuous_ctx_t {
+    uint8_t                         *rx_dma_buf;                //dma buffer
+    adc_hal_dma_ctx_t               hal;                        //hal context
+#if SOC_GDMA_SUPPORTED
+    gdma_channel_handle_t           rx_dma_channel;             //dma rx channel handle
+#elif CONFIG_IDF_TARGET_ESP32S2
+    spi_host_device_t               spi_host;                   //ADC uses this SPI DMA
+#elif CONFIG_IDF_TARGET_ESP32
+    i2s_port_t                      i2s_host;                   //ADC uses this I2S DMA
+#endif
+    intr_handle_t                   dma_intr_hdl;               //DMA Interrupt handler
+    RingbufHandle_t                 ringbuf_hdl;                //RX ringbuffer handler
+    void*                           ringbuf_storage;            //Ringbuffer storage buffer
+    void*                           ringbuf_struct;             //Ringbuffer structure buffer
+    intptr_t                        rx_eof_desc_addr;           //eof descriptor address of RX channel
+    adc_fsm_t                       fsm;                        //ADC continuous mode driver internal states
+    bool                            use_adc1;                   //1: ADC unit1 will be used; 0: ADC unit1 won't be used.
+    bool                            use_adc2;                   //1: ADC unit2 will be used; 0: ADC unit2 won't be used. This determines whether to acquire sar_adc2_mutex lock or not.
+    adc_atten_t                     adc1_atten;                 //Attenuation for ADC1. On this chip each ADC can only support one attenuation.
+    adc_atten_t                     adc2_atten;                 //Attenuation for ADC2. On this chip each ADC can only support one attenuation.
+    adc_hal_digi_ctrlr_cfg_t        hal_digi_ctrlr_cfg;         //Hal digital controller configuration
+    adc_continuous_evt_cbs_t        cbs;                        //Callbacks
+    void                            *user_data;                 //User context
+    esp_pm_lock_handle_t            pm_lock;                    //For power management
+#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+    adc_iir_filter_t                *iir_filter[SOC_ADC_DIGI_IIR_FILTER_NUM];  //ADC IIR filter context
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif

+ 158 - 0
components/esp_adc/adc_filter.c

@@ -0,0 +1,158 @@
+/*
+ * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdatomic.h>
+#include "esp_types.h"
+#include "sdkconfig.h"
+#include "esp_log.h"
+#include "esp_check.h"
+#include "esp_heap_caps.h"
+#include "freertos/FreeRTOS.h"
+#include "hal/adc_types.h"
+#include "hal/adc_hal.h"
+#include "adc_continuous_internal.h"
+#include "esp_adc/adc_filter.h"
+
+static const char *TAG = "adc_filter";
+static portMUX_TYPE s_filter_spinlock = portMUX_INITIALIZER_UNLOCKED;
+
+
+#if SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED
+static atomic_bool s_adc_filter_claimed[SOC_ADC_PERIPH_NUM] = {ATOMIC_VAR_INIT(false),
+#if (SOC_ADC_PERIPH_NUM >= 2)
+ATOMIC_VAR_INIT(false)
+#endif
+};
+
+static esp_err_t s_adc_filter_claim(adc_continuous_handle_t handle, adc_iir_filter_t *filter_ctx, adc_unit_t unit)
+{
+    assert(handle && filter_ctx);
+    esp_err_t ret = ESP_ERR_NOT_FOUND;
+    bool false_var = false;
+    if (atomic_compare_exchange_strong(&s_adc_filter_claimed[unit], &false_var, true)) {
+        ret = ESP_OK;
+        filter_ctx->filter_id = unit;
+        handle->iir_filter[unit] = filter_ctx;
+    }
+
+    return ret;
+}
+
+static esp_err_t s_adc_filter_free(adc_iir_filter_t *filter_ctx)
+{
+    assert(filter_ctx);
+    esp_err_t ret = ESP_ERR_NOT_FOUND;
+    bool true_var = true;
+    if (atomic_compare_exchange_strong(&s_adc_filter_claimed[filter_ctx->cfg.unit], &true_var, false)) {
+        ret = ESP_OK;
+        filter_ctx->continuous_ctx->iir_filter[filter_ctx->filter_id] = NULL;
+    }
+
+    return ret;
+}
+
+#else
+static esp_err_t s_adc_filter_claim(adc_continuous_handle_t handle, adc_iir_filter_t *filter_ctx, adc_unit_t unit)
+{
+    (void)unit;
+    assert(handle && filter_ctx);
+    for (int i = 0; i < SOC_ADC_DIGI_IIR_FILTER_NUM; i++) {
+        portENTER_CRITICAL(&s_filter_spinlock);
+        bool found = !handle->iir_filter[i];
+        handle->iir_filter[i] = filter_ctx;
+        filter_ctx->filter_id = i;
+        portEXIT_CRITICAL(&s_filter_spinlock);
+        if (found) {
+            return ESP_OK;
+        }
+    }
+
+    return ESP_ERR_NOT_FOUND;
+}
+
+static esp_err_t s_adc_filter_free(adc_iir_filter_t *filter_ctx)
+{
+    assert(filter_ctx);
+    portENTER_CRITICAL(&s_filter_spinlock);
+    filter_ctx->continuous_ctx->iir_filter[filter_ctx->filter_id] = NULL;
+    portEXIT_CRITICAL(&s_filter_spinlock);
+
+    return ESP_OK;
+}
+#endif
+
+
+
+
+esp_err_t adc_new_continuous_iir_filter(adc_continuous_handle_t handle, const adc_continuous_iir_filter_config_t *config, adc_iir_filter_handle_t *ret_hdl)
+{
+    esp_err_t ret = ESP_FAIL;
+    ESP_RETURN_ON_FALSE(handle && config && ret_hdl, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
+    ESP_RETURN_ON_FALSE(handle->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "ADC continuous driver should be in init state");
+    ESP_RETURN_ON_FALSE(config->unit < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid unit");
+
+    adc_iir_filter_t *filter_ctx = heap_caps_calloc(1, sizeof(adc_iir_filter_t), MALLOC_CAP_DEFAULT);
+    ESP_RETURN_ON_FALSE(filter_ctx, ESP_ERR_NO_MEM, TAG, "no mem");
+
+    //claim a filter
+#if SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED
+    ESP_GOTO_ON_ERROR(s_adc_filter_claim(handle, filter_ctx, config->unit), err, TAG, "filter already in use");
+#else
+    ESP_GOTO_ON_ERROR(s_adc_filter_claim(handle, filter_ctx, config->unit), err, TAG, "no free filter");
+#endif
+
+    filter_ctx->cfg.unit = config->unit;
+    filter_ctx->cfg.channel = config->channel;
+    filter_ctx->cfg.coeff = config->coeff;
+    filter_ctx->continuous_ctx = handle;
+
+    *ret_hdl = filter_ctx;
+
+    return ESP_OK;
+
+err:
+    free(filter_ctx);
+
+    return ret;
+}
+
+esp_err_t adc_continuous_iir_filter_enable(adc_iir_filter_handle_t filter_hdl)
+{
+    ESP_RETURN_ON_FALSE(filter_hdl, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
+    ESP_RETURN_ON_FALSE(filter_hdl->continuous_ctx->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "ADC continuous driver should be in init state");
+
+    portENTER_CRITICAL(&s_filter_spinlock);
+    adc_ll_digi_filter_reset(filter_hdl->filter_id, filter_hdl->cfg.unit);
+    adc_ll_digi_filter_set_factor(filter_hdl->filter_id, filter_hdl->cfg.unit, filter_hdl->cfg.channel, filter_hdl->cfg.coeff);
+    adc_ll_digi_filter_enable(filter_hdl->filter_id, filter_hdl->cfg.unit, true);
+    portEXIT_CRITICAL(&s_filter_spinlock);
+
+    return ESP_OK;
+}
+
+esp_err_t adc_continuous_iir_filter_disable(adc_iir_filter_handle_t filter_hdl)
+{
+    ESP_RETURN_ON_FALSE(filter_hdl, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
+    ESP_RETURN_ON_FALSE(filter_hdl->continuous_ctx->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "ADC continuous driver should be in init state");
+
+    portENTER_CRITICAL(&s_filter_spinlock);
+    adc_ll_digi_filter_enable(filter_hdl->filter_id, filter_hdl->cfg.unit, false);
+    portEXIT_CRITICAL(&s_filter_spinlock);
+
+    return ESP_OK;
+}
+
+esp_err_t adc_del_continuous_iir_filter(adc_iir_filter_handle_t filter_hdl)
+{
+    ESP_RETURN_ON_FALSE(filter_hdl, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
+    ESP_RETURN_ON_FALSE(filter_hdl->continuous_ctx->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "ADC continuous driver should be in init state");
+
+    ESP_RETURN_ON_ERROR(s_adc_filter_free(filter_hdl), TAG, "filter isn't in use");
+
+    free(filter_hdl);
+
+    return ESP_OK;
+}

+ 1 - 4
components/esp_adc/include/esp_adc/adc_continuous.h

@@ -16,7 +16,6 @@
 extern "C" {
 #endif
 
-#if SOC_ADC_DMA_SUPPORTED
 
 /**
  * @brief Driver Backgrounds
@@ -130,7 +129,7 @@ esp_err_t adc_continuous_config(adc_continuous_handle_t handle, const adc_contin
 /**
  * @brief Register callbacks
  *
- * @note User can deregister a previously registered callback by calling this function and setting the to-be-deregistered callback member int
+ * @note User can deregister a previously registered callback by calling this function and setting the to-be-deregistered callback member in
  *       the `cbs` structure to NULL.
  * @note When CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
  *       Involved variables (including `user_data`) should be in internal RAM as well.
@@ -224,8 +223,6 @@ esp_err_t adc_continuous_io_to_channel(int io_num, adc_unit_t *unit_id, adc_chan
  */
 esp_err_t adc_continuous_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, int *io_num);
 
-#endif  //  #if SOC_ADC_DMA_SUPPORTED
-
 
 #ifdef __cplusplus
 }

+ 88 - 0
components/esp_adc/include/esp_adc/adc_filter.h

@@ -0,0 +1,88 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "sdkconfig.h"
+#include "esp_err.h"
+#include "esp_adc/adc_continuous.h"
+#include "hal/adc_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Type of adc iir filter handle
+ */
+typedef struct adc_iir_filter_t *adc_iir_filter_handle_t;
+
+/**
+ * @brief Filter Configuration
+ */
+typedef struct {
+    adc_unit_t unit;                    ///< ADC unit
+    adc_channel_t channel;              ///< An ADC channel to be filtered. Note for ESP32S2, you should only set only one channel in pattern table, per ADC unit. See programming guide for more details.
+    adc_digi_iir_filter_coeff_t coeff;  ///< ADC filter coefficient
+} adc_continuous_iir_filter_config_t;
+
+
+/**
+ * @brief New a ADC continuous mode IIR filter
+ *
+ * @param[in]   handle   ADC continuous mode driver handle
+ * @param[in]   config   Filter configuration
+ * @param[out]  ret_hdl  Returned IIR filter handle
+ *
+ * @return
+ *        - ESP_OK
+ *        - ESP_ERR_INVALID_ARG:    Invalid argument
+ *        - ESP_ERR_INVALID_STATE:  Invalid state
+ *        - ESP_ERR_NO_MEM:         No memory
+ */
+esp_err_t adc_new_continuous_iir_filter(adc_continuous_handle_t handle, const adc_continuous_iir_filter_config_t *config, adc_iir_filter_handle_t *ret_hdl);
+
+/**
+ * @brief Enable an IIR filter
+ *
+ * @param[in] filter_hdl  ADC IIR filter handle
+ *
+ * @return
+ *        - ESP_OK
+ *        - ESP_ERR_INVALID_ARG:    Invalid argument
+ *        - ESP_ERR_INVALID_STATE:  Invalid state
+ */
+esp_err_t adc_continuous_iir_filter_enable(adc_iir_filter_handle_t filter_hdl);
+
+/**
+ * @brief Disable an IIR filter
+ *
+ * @param[in] filter_hdl  ADC IIR filter handle
+ *
+ * @return
+ *        - ESP_OK
+ *        - ESP_ERR_INVALID_ARG:    Invalid argument
+ *        - ESP_ERR_INVALID_STATE:  Invalid state
+ */
+esp_err_t adc_continuous_iir_filter_disable(adc_iir_filter_handle_t filter_hdl);
+
+/**
+ * @brief Delete the IIR filter
+ *
+ * @param[in] filter_hdl  ADC IIR filter handle
+ *
+ * @return
+ *        - ESP_OK
+ *        - ESP_ERR_INVALID_ARG:    Invalid argument
+ *        - ESP_ERR_INVALID_STATE:  Invalid state
+ */
+esp_err_t adc_del_continuous_iir_filter(adc_iir_filter_handle_t filter_hdl);
+
+#ifdef __cplusplus
+}
+#endif

+ 2 - 2
components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -156,7 +156,7 @@ TEST_CASE("ADC oneshot fast work with ISR and Flash", "[adc_oneshot]")
 #endif
 
 #define ADC_TEST_FREQ_HZ        (50 * 1000)
-#define ADC_TEST_PKG_SIZE       100
+#define ADC_TEST_PKG_SIZE       512
 static bool IRAM_ATTR NOINLINE_ATTR s_conv_done_cb(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data)
 {
     test_adc_iram_ctx_t *test_ctx = (test_adc_iram_ctx_t *)user_data;

+ 256 - 65
components/esp_adc/test_apps/adc/main/test_adc_performance.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -15,19 +15,21 @@
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "esp_adc/adc_oneshot.h"
+#include "esp_adc/adc_continuous.h"
+#include "esp_adc/adc_filter.h"
 #include "test_common_adc.h"
-
-#if CONFIG_IDF_TARGET_ESP32 ||  SOC_ADC_CALIBRATION_V1_SUPPORTED
+#include "idf_performance.h"
 
 __attribute__((unused)) static const char *TAG = "TEST_ADC";
 
-/*---------------------------------------------------------------
-        ADC Oneshot Average / STD_Deviation Test
----------------------------------------------------------------*/
-#define TEST_COUNT               (1<<SOC_ADC_RTC_MAX_BITWIDTH)
-#define MAX_ARRAY_SIZE           (1<<SOC_ADC_RTC_MAX_BITWIDTH)
+#if CONFIG_IDF_TARGET_ESP32
+#define TEST_STD_ADC1_CHANNEL0    ADC_CHANNEL_5
+#else
+#define TEST_STD_ADC1_CHANNEL0    ADC_CHANNEL_2
+#endif
 
-static int s_adc_count[MAX_ARRAY_SIZE]={};
+static int s_adc_count_size;
+static int *s_p_adc_count;
 static int s_adc_offset = -1;
 
 static int s_insert_point(uint32_t value)
@@ -36,40 +38,50 @@ static int s_insert_point(uint32_t value)
 
     if (s_adc_offset < 0) {
         if (fixed_size) {
-            TEST_ASSERT_GREATER_OR_EQUAL(4096, MAX_ARRAY_SIZE);
+            TEST_ASSERT_GREATER_OR_EQUAL(4096, s_adc_count_size);
             s_adc_offset = 0;   //Fixed to 0 because the array can hold all the data in 12 bits
         } else {
-            s_adc_offset = MAX((int)value - MAX_ARRAY_SIZE/2, 0);
+            s_adc_offset = MAX((int)value - s_adc_count_size/2, 0);
         }
     }
 
-    if (!fixed_size && (value < s_adc_offset || value >= s_adc_offset + MAX_ARRAY_SIZE)) {
+    if (!fixed_size && (value < s_adc_offset || value >= s_adc_offset + s_adc_count_size)) {
         TEST_ASSERT_GREATER_OR_EQUAL(s_adc_offset, value);
-        TEST_ASSERT_LESS_THAN(s_adc_offset + MAX_ARRAY_SIZE, value);
+        TEST_ASSERT_LESS_THAN(s_adc_offset + s_adc_count_size, value);
     }
 
-    s_adc_count[value - s_adc_offset] ++;
+    s_p_adc_count[value - s_adc_offset] ++;
     return value - s_adc_offset;
 }
 
-static void s_reset_array(void)
+static void s_reset_array(int array_size)
 {
-    memset(s_adc_count, 0, sizeof(s_adc_count));
+    s_adc_count_size = array_size;
+    s_p_adc_count = (int *)heap_caps_calloc(1, s_adc_count_size * sizeof(int), MALLOC_CAP_INTERNAL);
+    TEST_ASSERT(s_p_adc_count);
     s_adc_offset = -1;
 }
 
+static void s_destroy_array(void)
+{
+    free(s_p_adc_count);
+    s_p_adc_count = NULL;
+    s_adc_count_size = 0;
+}
+
+__attribute__((unused))
 static uint32_t s_get_average(void)
 {
     uint32_t sum = 0;
     int count = 0;
-    for (int i = 0; i < MAX_ARRAY_SIZE; i++) {
-        sum += s_adc_count[i] * (s_adc_offset+i);
-        count += s_adc_count[i];
+    for (int i = 0; i < s_adc_count_size; i++) {
+        sum += s_p_adc_count[i] * (s_adc_offset+i);
+        count += s_p_adc_count[i];
     }
     return sum/count;
 }
 
-static void s_print_summary(bool figure)
+static float s_print_summary(bool figure)
 {
     const int MAX_WIDTH=20;
     int max_count = 0;
@@ -77,53 +89,220 @@ static void s_print_summary(bool figure)
     int end = -1;
     uint32_t sum = 0;
     int count = 0;
-    for (int i = 0; i < MAX_ARRAY_SIZE; i++) {
-        if (s_adc_count[i] > max_count) {
-            max_count = s_adc_count[i];
+    for (int i = 0; i < s_adc_count_size; i++) {
+        if (s_p_adc_count[i] > max_count) {
+            max_count = s_p_adc_count[i];
         }
-        if (s_adc_count[i] > 0 && start < 0) {
+        if (s_p_adc_count[i] > 0 && start < 0) {
             start = i;
         }
-        if (s_adc_count[i] > 0) {
+        if (s_p_adc_count[i] > 0) {
             end = i;
         }
-        count += s_adc_count[i];
-        sum += s_adc_count[i] * (s_adc_offset+i);
+        count += s_p_adc_count[i];
+        sum += s_p_adc_count[i] * (s_adc_offset+i);
     }
 
     if (figure) {
         for (int i = start; i <= end; i++) {
             printf("%4d ", i+s_adc_offset);
-            int count = s_adc_count[i] * MAX_WIDTH / max_count;
+            int count = s_p_adc_count[i] * MAX_WIDTH / max_count;
             for (int j = 0; j < count; j++) {
                 putchar('|');
             }
-            printf("    %d\n", s_adc_count[i]);
+            printf("    %d\n", s_p_adc_count[i]);
         }
     }
     float average = (float)sum/count;
 
     float variation_square = 0;
     for (int i = start; i <= end; i ++) {
-        if (s_adc_count[i] == 0) {
+        if (s_p_adc_count[i] == 0) {
             continue;
         }
         float delta = i + s_adc_offset - average;
-        variation_square += (delta * delta) * s_adc_count[i];
+        variation_square += (delta * delta) * s_p_adc_count[i];
     }
 
     printf("%d points.\n", count);
     printf("average: %.1f\n", (float)sum/count);
     printf("std: %.2f\n", sqrt(variation_square/count));
+
+    return sqrt(variation_square/count);
 }
 
-#if CONFIG_IDF_TARGET_ESP32
-#define TEST_STD_ADC1_CHANNEL0    ADC_CHANNEL_6
+#if SOC_ADC_DMA_SUPPORTED
+/*---------------------------------------------------------------
+        ADC Continuous Average / STD_Deviation Test
+---------------------------------------------------------------*/
+#if (SOC_ADC_DIGI_RESULT_BYTES == 2)
+#define ADC_TEST_OUTPUT_TYPE                ADC_DIGI_OUTPUT_FORMAT_TYPE1
+#define EXAMPLE_ADC_GET_CHANNEL(result)     ((result).type1.channel)
+#define EXAMPLE_ADC_GET_DATA(result)        ((result).type1.data)
 #else
-#define TEST_STD_ADC1_CHANNEL0    ADC_CHANNEL_2
+#define ADC_TEST_OUTPUT_TYPE                ADC_DIGI_OUTPUT_FORMAT_TYPE2
+#define EXAMPLE_ADC_GET_CHANNEL(result)     ((result).type2.channel)
+#define EXAMPLE_ADC_GET_DATA(result)        ((result).type2.data)
+#endif
+#define ADC_TEST_FREQ_HZ        (50 * 1000)
+#define ADC_TEST_PKG_SIZE       512
+#define ADC_TEST_CNT            4096
+
+
+static bool IRAM_ATTR s_conv_done_cb(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data)
+{
+    BaseType_t mustYield = pdFALSE;
+    TaskHandle_t task_handle = *(TaskHandle_t *)(user_data);
+    //Notify that ADC continuous driver has done enough number of conversions
+    vTaskNotifyGiveFromISR(task_handle, &mustYield);
+
+    return (mustYield == pdTRUE);
+}
+
+static float test_adc_continuous_std(adc_atten_t atten, bool filter_en, int filter_coeff, bool is_performance_test)
+{
+    uint8_t *result = heap_caps_calloc(1, ADC_TEST_CNT * SOC_ADC_DIGI_RESULT_BYTES, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_32BIT);
+    TEST_ASSERT(result);
+    bool print_figure = false;
+    TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
+
+    //-------------ADC Init---------------//
+    adc_continuous_handle_t handle = NULL;
+    adc_continuous_handle_cfg_t adc_config = {
+        .max_store_buf_size = 4096,
+        .conv_frame_size = ADC_TEST_PKG_SIZE,
+    };
+    TEST_ESP_OK(adc_continuous_new_handle(&adc_config, &handle));
+
+    adc_continuous_evt_cbs_t cbs = {
+        .on_conv_done = s_conv_done_cb,
+    };
+    TEST_ESP_OK(adc_continuous_register_event_callbacks(handle, &cbs, &task_handle));
+
+    //-------------ADC Config---------------//
+    adc_continuous_config_t dig_cfg = {
+        .sample_freq_hz = ADC_TEST_FREQ_HZ,
+        .conv_mode = ADC_CONV_SINGLE_UNIT_1,
+        .format = ADC_TEST_OUTPUT_TYPE,
+    };
+    adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
+    adc_pattern[0].atten = atten;
+    adc_pattern[0].channel = TEST_STD_ADC1_CHANNEL0;
+    adc_pattern[0].unit = ADC_UNIT_1;
+    adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
+    dig_cfg.adc_pattern = adc_pattern;
+    dig_cfg.pattern_num = 1;
+    TEST_ESP_OK(adc_continuous_config(handle, &dig_cfg));
+
+#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+    adc_iir_filter_handle_t filter_hdl = NULL;
+    if (filter_en) {
+        adc_continuous_iir_filter_config_t filter_config = {
+            .unit = ADC_UNIT_1,
+            .channel = TEST_STD_ADC1_CHANNEL0,
+            .coeff = filter_coeff,
+        };
+        TEST_ESP_OK(adc_new_continuous_iir_filter(handle, &filter_config, &filter_hdl));
+        TEST_ESP_OK(adc_continuous_iir_filter_enable(filter_hdl));
+    }
+#endif
+
+    if (is_performance_test) {
+        test_adc_set_io_middle(ADC_UNIT_1, TEST_STD_ADC1_CHANNEL0);
+    }
+
+    if (filter_en) {
+        ESP_LOGI("TEST_ADC", "Test with atten: %d, filter coeff: %d", atten, filter_coeff);
+    } else {
+        ESP_LOGI("TEST_ADC", "Test with atten: %d, no filter", atten);
+    }
+
+    s_reset_array((1 << SOC_ADC_DIGI_MAX_BITWIDTH));
+    TEST_ESP_OK(adc_continuous_start(handle));
+
+    int remain_count = ADC_TEST_CNT;
+    while (remain_count) {
+        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
+        int already_got = ADC_TEST_CNT - remain_count;
+        uint32_t ret_num = 0;
+        TEST_ESP_OK(adc_continuous_read(handle, result + already_got * SOC_ADC_DIGI_RESULT_BYTES, ADC_TEST_PKG_SIZE, &ret_num, 0));
+        remain_count -= ret_num / SOC_ADC_DIGI_RESULT_BYTES;
+    }
+
+    adc_digi_output_data_t *p = (void*)result;
+    for (int i = 0; i < ADC_TEST_CNT; i++) {
+        TEST_ASSERT_EQUAL(TEST_STD_ADC1_CHANNEL0, EXAMPLE_ADC_GET_CHANNEL(p[i]));
+        s_insert_point(EXAMPLE_ADC_GET_DATA(p[i]));
+    }
+    float std = s_print_summary(print_figure);
+
+    TEST_ESP_OK(adc_continuous_stop(handle));
+#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+    if (filter_en) {
+        TEST_ESP_OK(adc_continuous_iir_filter_disable(filter_hdl));
+        TEST_ESP_OK(adc_del_continuous_iir_filter(filter_hdl));
+    }
+#endif
+    TEST_ESP_OK(adc_continuous_deinit(handle));
+    ulTaskNotifyTake(pdTRUE, 0);
+    s_destroy_array();
+    free(result);
+
+    return std;
+}
+
+TEST_CASE("ADC1 continuous raw average and std_deviation", "[adc_continuous][manual]")
+{
+    for (int i = 0; i < TEST_ATTEN_NUMS; i ++) {
+#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+        //filter disabled
+        test_adc_continuous_std(g_test_atten[i], false, 0, false);
+        //filter with different coeffs
+        for (int j = 0; j < TEST_FILTER_COEFF_NUMS; j ++) {
+            test_adc_continuous_std(g_test_atten[i], true, g_test_filter_coeff[j], false);
+        }
+#else
+        //filter disabled
+        test_adc_continuous_std(g_test_atten[i], false, 0, false);
 #endif
+    }
+}
 
-TEST_CASE("ADC1 oneshot raw average / std_deviation", "[adc_oneshot][ignore][manual]")
+TEST_CASE("ADC1 continuous std deviation performance, no filter", "[adc_continuous][performance]")
+{
+    float std = test_adc_continuous_std(ADC_ATTEN_DB_11, false, 0, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER, "%.2f", std);
+}
+
+#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+TEST_CASE("ADC1 continuous std deviation performance, with filter", "[adc_continuous][performance]")
+{
+    float std = test_adc_continuous_std(ADC_ATTEN_DB_11, false, 0, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER, "%.2f", std);
+
+    std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_2, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_2, "%.2f", std);
+
+    std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_4, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_4, "%.2f", std);
+
+    std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_8, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_8, "%.2f", std);
+
+    std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_16, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_16, "%.2f", std);
+
+    std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_64, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_64, "%.2f", std);
+}
+#endif  //#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+#endif  //#if SOC_ADC_DMA_SUPPORTED
+
+#if CONFIG_IDF_TARGET_ESP32 ||  SOC_ADC_CALIBRATION_V1_SUPPORTED
+/*---------------------------------------------------------------
+        ADC Oneshot Average / STD_Deviation Test
+---------------------------------------------------------------*/
+static float test_adc_oneshot_std(adc_atten_t atten, bool is_performance_test)
 {
     adc_channel_t channel = TEST_STD_ADC1_CHANNEL0;
     int raw = 0;
@@ -144,50 +323,62 @@ TEST_CASE("ADC1 oneshot raw average / std_deviation", "[adc_oneshot][ignore][man
 
     //-------------ADC Calibration Init---------------//
     bool do_calibration = false;
-    adc_cali_handle_t cali_handle[TEST_ATTEN_NUMS] = {};
-    for (int i = 0; i < TEST_ATTEN_NUMS; i++) {
-        do_calibration = test_adc_calibration_init(ADC_UNIT_1, g_test_atten[i], ADC_BITWIDTH_DEFAULT, &cali_handle[i]);
-    }
+    adc_cali_handle_t cali_handle = NULL;
+    do_calibration = test_adc_calibration_init(ADC_UNIT_1, atten, ADC_BITWIDTH_DEFAULT, &cali_handle);
     if (!do_calibration) {
         ESP_LOGW(TAG, "calibration fail, jump calibration\n");
     }
 
-    for (int i = 0; i < TEST_ATTEN_NUMS; i++) {
-
-        //-------------ADC1 Channel Config---------------//
-        config.atten = g_test_atten[i];
-        TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, channel, &config));
-        ESP_LOGI("TEST_ADC", "Test with atten: %d", g_test_atten[i]);
+    //-------------ADC1 Channel Config---------------//
+    config.atten = atten;
+    TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, channel, &config));
+    ESP_LOGI("TEST_ADC", "Test with atten: %d", atten);
 
-        while (1) {
+    s_reset_array((1 << SOC_ADC_RTC_MAX_BITWIDTH));
 
-            s_reset_array();
+    if (is_performance_test) {
+        test_adc_set_io_middle(ADC_UNIT_1, TEST_STD_ADC1_CHANNEL0);
+    }
 
-            for (int i = 0; i < TEST_COUNT; i++) {
-                TEST_ESP_OK(adc_oneshot_read(adc1_handle, channel, &raw));
-                s_insert_point(raw);
-            }
-            s_print_summary(print_figure);
-            break;
+    float std;
+    while (1) {
+        for (int i = 0; i < s_adc_count_size; i++) {
+            TEST_ESP_OK(adc_oneshot_read(adc1_handle, channel, &raw));
+            s_insert_point(raw);
         }
+        std = s_print_summary(print_figure);
+        break;
+    }
 
-        if (do_calibration) {
-            uint32_t raw = s_get_average();
-            int voltage_mv = 0;
-            TEST_ESP_OK(adc_cali_raw_to_voltage(cali_handle[i], raw, &voltage_mv));
-            printf("Voltage = %d mV\n", voltage_mv);
-        }
+    if (do_calibration) {
+        uint32_t raw = s_get_average();
+        int voltage_mv = 0;
+        TEST_ESP_OK(adc_cali_raw_to_voltage(cali_handle, raw, &voltage_mv));
+        printf("Voltage = %d mV\n", voltage_mv);
     }
 
+    s_destroy_array();
+
     TEST_ESP_OK(adc_oneshot_del_unit(adc1_handle));
-    for (int i = 0; i < TEST_ATTEN_NUMS; i++) {
-        if (cali_handle[i]) {
-            test_adc_calibration_deinit(cali_handle[i]);
-        }
+    if (cali_handle) {
+        test_adc_calibration_deinit(cali_handle);
     }
+
+    return std;
 }
 
+TEST_CASE("ADC1 oneshot raw average and std_deviation", "[adc_oneshot][manual]")
+{
+    for (int i = 0; i < TEST_ATTEN_NUMS; i++) {
+        test_adc_oneshot_std(g_test_atten[i], false);
+    }
+}
 
+TEST_CASE("ADC1 oneshot std_deviation performance", "[adc_oneshot][performance]")
+{
+    float std = test_adc_oneshot_std(ADC_ATTEN_DB_11, true);
+    TEST_PERFORMANCE_LESS_THAN(ADC_ONESHOT_STD_ATTEN3, "%.2f", std);
+}
 /*---------------------------------------------------------------
         ADC Calibration Speed
 ---------------------------------------------------------------*/
@@ -277,14 +468,14 @@ static void s_adc_cali_speed(adc_unit_t unit_id, adc_channel_t channel)
     }
 }
 
-TEST_CASE("ADC1 Calibration Speed", "[adc][ignore][manual]")
+TEST_CASE("ADC1 Calibration Speed", "[adc][manual]")
 {
     s_adc_cali_speed(ADC_UNIT_1, ADC1_CALI_SPEED_TEST_CHAN0);
 }
 
 #if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
 //ESP32C3 ADC2 oneshot mode is not supported anymore
-TEST_CASE("ADC2 Calibration Speed", "[adc][ignore][manual]")
+TEST_CASE("ADC2 Calibration Speed", "[adc][manual]")
 {
     s_adc_cali_speed(ADC_UNIT_2, ADC2_CALI_SPEED_TEST_CHAN0);
 }

+ 31 - 1
components/esp_adc/test_apps/adc/main/test_common_adc.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Unlicense OR CC0-1.0
  */
@@ -7,6 +7,8 @@
 #include <stdlib.h>
 #include "unity.h"
 #include "esp_log.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
 #include "driver/gpio.h"
 #include "driver/rtc_io.h"
 #include "soc/adc_periph.h"
@@ -23,6 +25,16 @@ adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_11};
 adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_2_5, ADC_ATTEN_DB_6, ADC_ATTEN_DB_11};
 #endif
 
+#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+adc_digi_iir_filter_coeff_t g_test_filter_coeff[TEST_FILTER_COEFF_NUMS] = {
+    ADC_DIGI_IIR_FILTER_COEFF_2,
+    ADC_DIGI_IIR_FILTER_COEFF_4,
+    ADC_DIGI_IIR_FILTER_COEFF_8,
+    ADC_DIGI_IIR_FILTER_COEFF_16,
+    ADC_DIGI_IIR_FILTER_COEFF_64,
+};
+#endif
+
 
 /*---------------------------------------------------------------
         ADC Calibration
@@ -102,3 +114,21 @@ void test_adc_set_io_level(adc_unit_t unit, adc_channel_t channel, bool level)
     TEST_ESP_OK(gpio_set_pull_mode(io_num, (level ? GPIO_PULLUP_ONLY: GPIO_PULLDOWN_ONLY)));
 #endif
 }
+
+
+void test_adc_set_io_middle(adc_unit_t unit, adc_channel_t channel)
+{
+    TEST_ASSERT(channel < SOC_ADC_CHANNEL_NUM(unit) && "invalid channel");
+
+    uint32_t io_num = ADC_GET_IO_NUM(unit, channel);
+
+#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
+    TEST_ESP_OK(gpio_set_pull_mode(io_num, GPIO_PULLUP_PULLDOWN));
+#else
+    TEST_ESP_OK(rtc_gpio_init(io_num));
+    TEST_ESP_OK(rtc_gpio_pullup_en(io_num));
+    TEST_ESP_OK(rtc_gpio_pulldown_en(io_num));
+    TEST_ESP_OK(rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_DISABLED));
+#endif
+    vTaskDelay(10 / portTICK_PERIOD_MS);
+}

+ 18 - 0
components/esp_adc/test_apps/adc/main/test_common_adc.h

@@ -92,6 +92,13 @@ extern adc_atten_t g_test_atten[TEST_ATTEN_NUMS];
 extern adc_atten_t g_test_atten[TEST_ATTEN_NUMS];
 #endif
 
+/*---------------------------------------------------------------
+        ADC Filter
+---------------------------------------------------------------*/
+#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+#define TEST_FILTER_COEFF_NUMS          5
+extern adc_digi_iir_filter_coeff_t g_test_filter_coeff[TEST_FILTER_COEFF_NUMS];
+#endif
 
 /*---------------------------------------------------------------
         ADC Calibration
@@ -127,6 +134,17 @@ void test_adc_calibration_deinit(adc_cali_handle_t handle);
  */
 void test_adc_set_io_level(adc_unit_t unit, adc_channel_t channel, bool level);
 
+/**
+ * @brief Set ADC IO to a middle level
+ *
+ * @note We don't expect this IO to have a fixed level among different chips.
+ *       We just need the IO to be stable at a certain level, which is neither 0 nor overflow.
+ *
+ * @param[in] unit      ADC unit
+ * @param[in] channel   ADC channel
+ */
+void test_adc_set_io_middle(adc_unit_t unit, adc_channel_t channel);
+
 #ifdef __cplusplus
 }
 #endif

+ 59 - 28
components/hal/esp32c2/include/hal/adc_ll.h

@@ -161,46 +161,77 @@ static inline void adc_ll_digi_controller_clk_disable(void)
 /**
  * Reset adc digital controller filter.
  *
+ * @param idx   Filter index
  * @param adc_n ADC unit.
  */
-static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
+static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
 {
+    (void)adc_n;
     APB_SARADC.saradc_filter_ctrl0.saradc_filter_reset = 1;
-}
-
-/**
- * Set adc digital controller filter factor.
- *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param idx ADC filter unit.
- * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
-{
-    abort();
-}
+    APB_SARADC.saradc_filter_ctrl0.saradc_filter_reset = 0;
+}
+
+/**
+ * Set adc digital controller filter coeff.
+ *
+ * @param idx      filter index
+ * @param adc_n    adc unit
+ * @param channel  adc channel
+ * @param coeff    filter coeff
+ */
+static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
+{
+    uint32_t factor_reg_val = 0;
+    switch (coeff) {
+        case ADC_DIGI_IIR_FILTER_COEFF_2:
+            factor_reg_val = 1;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_4:
+            factor_reg_val = 2;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_8:
+            factor_reg_val = 3;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_16:
+            factor_reg_val = 4;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_64:
+            factor_reg_val = 6;
+            break;
+        default:
+            HAL_ASSERT(false);
+    }
 
-/**
- * Get adc digital controller filter factor.
- *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
-{
-    abort();
+    if (idx == ADC_DIGI_IIR_FILTER_0) {
+        APB_SARADC.saradc_filter_ctrl0.saradc_filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.saradc_filter_ctrl1.saradc_filter_factor0 = factor_reg_val;
+    } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+        APB_SARADC.saradc_filter_ctrl0.saradc_filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.saradc_filter_ctrl1.saradc_filter_factor1 = factor_reg_val;
+    }
 }
 
 /**
- * Disable adc digital controller filter.
+ * Enable adc digital controller filter.
  * Filtering the ADC data to obtain smooth data at higher sampling rates.
  *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param adc_n ADC unit.
+ * @param idx      filter index
+ * @param adc_n    ADC unit
+ * @param enable   Enable / Disable
  */
-static inline void adc_ll_digi_filter_disable(adc_digi_filter_idx_t idx)
+static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
 {
-    abort();
+    (void)adc_n;
+    if (!enable) {
+        if (idx == ADC_DIGI_IIR_FILTER_0) {
+            APB_SARADC.saradc_filter_ctrl0.saradc_filter_channel0 = 0xF;
+            APB_SARADC.saradc_filter_ctrl1.saradc_filter_factor0 = 0;
+        } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+            APB_SARADC.saradc_filter_ctrl0.saradc_filter_channel1 = 0xF;
+            APB_SARADC.saradc_filter_ctrl1.saradc_filter_factor1 = 0;
+        }
+    }
+    //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled.
 }
 
 /**

+ 56 - 45
components/hal/esp32c3/include/hal/adc_ll.h

@@ -304,66 +304,77 @@ static inline void adc_ll_digi_controller_clk_disable(void)
 /**
  * Reset adc digital controller filter.
  *
+ * @param idx   Filter index
  * @param adc_n ADC unit.
  */
-static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
+static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
 {
+    (void)adc_n;
     APB_SARADC.filter_ctrl0.filter_reset = 1;
-}
-
-/**
- * Set adc digital controller filter factor.
- *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param idx ADC filter unit.
- * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
-{
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        APB_SARADC.filter_ctrl0.filter_channel0 = (filter->adc_unit << 3) | (filter->channel & 0x7);
-        APB_SARADC.filter_ctrl1.filter_factor0 = filter->mode;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        APB_SARADC.filter_ctrl0.filter_channel1 = (filter->adc_unit << 3) | (filter->channel & 0x7);
-        APB_SARADC.filter_ctrl1.filter_factor1 = filter->mode;
+    APB_SARADC.filter_ctrl0.filter_reset = 0;
+}
+
+/**
+ * Set adc digital controller filter coeff.
+ *
+ * @param idx      filter index
+ * @param adc_n    adc unit
+ * @param channel  adc channel
+ * @param coeff    filter coeff
+ */
+static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
+{
+    uint32_t factor_reg_val = 0;
+    switch (coeff) {
+        case ADC_DIGI_IIR_FILTER_COEFF_2:
+            factor_reg_val = 1;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_4:
+            factor_reg_val = 2;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_8:
+            factor_reg_val = 3;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_16:
+            factor_reg_val = 4;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_64:
+            factor_reg_val = 6;
+            break;
+        default:
+            HAL_ASSERT(false);
     }
-}
 
-/**
- * Get adc digital controller filter factor.
- *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
-{
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        filter->adc_unit = (APB_SARADC.filter_ctrl0.filter_channel0 >> 3) & 0x1;
-        filter->channel = APB_SARADC.filter_ctrl0.filter_channel0 & 0x7;
-        filter->mode = APB_SARADC.filter_ctrl1.filter_factor0;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        filter->adc_unit = (APB_SARADC.filter_ctrl0.filter_channel1 >> 3) & 0x1;
-        filter->channel = APB_SARADC.filter_ctrl0.filter_channel1 & 0x7;
-        filter->mode = APB_SARADC.filter_ctrl1.filter_factor1;
+    if (idx == ADC_DIGI_IIR_FILTER_0) {
+        APB_SARADC.filter_ctrl0.filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.filter_ctrl1.filter_factor0 = factor_reg_val;
+    } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+        APB_SARADC.filter_ctrl0.filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.filter_ctrl1.filter_factor1 = factor_reg_val;
     }
 }
 
 /**
- * Disable adc digital controller filter.
+ * Enable adc digital controller filter.
  * Filtering the ADC data to obtain smooth data at higher sampling rates.
  *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param adc_n ADC unit.
+ * @param idx      filter index
+ * @param adc_n    ADC unit
+ * @param enable   Enable / Disable
  */
-static inline void adc_ll_digi_filter_disable(adc_digi_filter_idx_t idx)
+static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
 {
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        APB_SARADC.filter_ctrl0.filter_channel0 = 0xF;
-        APB_SARADC.filter_ctrl1.filter_factor0 = 0;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        APB_SARADC.filter_ctrl0.filter_channel1 = 0xF;
-        APB_SARADC.filter_ctrl1.filter_factor1 = 0;
+    (void)adc_n;
+    if (!enable) {
+        if (idx == ADC_DIGI_IIR_FILTER_0) {
+            APB_SARADC.filter_ctrl0.filter_channel0 = 0xF;
+            APB_SARADC.filter_ctrl1.filter_factor0 = 0;
+        } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+            APB_SARADC.filter_ctrl0.filter_channel1 = 0xF;
+            APB_SARADC.filter_ctrl1.filter_factor1 = 0;
+        }
     }
+    //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled.
 }
 
 /**

+ 52 - 41
components/hal/esp32c6/include/hal/adc_ll.h

@@ -313,66 +313,77 @@ static inline void adc_ll_digi_controller_clk_disable(void)
 /**
  * Reset adc digital controller filter.
  *
+ * @param idx   Filter index
  * @param adc_n ADC unit.
  */
-static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
+static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
 {
+    (void)adc_n;
     APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_reset = 1;
+    APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_reset = 0;
 }
 
 /**
- * Set adc digital controller filter factor.
+ * Set adc digital controller filter coeff.
  *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param idx ADC filter unit.
- * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
+ * @param idx      filter index
+ * @param adc_n    adc unit
+ * @param channel  adc channel
+ * @param coeff    filter coeff
  */
-static inline void adc_ll_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
+static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
 {
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = (filter->adc_unit << 3) | (filter->channel & 0x7);
-        APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = filter->mode;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = (filter->adc_unit << 3) | (filter->channel & 0x7);
-        APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = filter->mode;
+    uint32_t factor_reg_val = 0;
+    switch (coeff) {
+        case ADC_DIGI_IIR_FILTER_COEFF_2:
+            factor_reg_val = 1;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_4:
+            factor_reg_val = 2;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_8:
+            factor_reg_val = 3;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_16:
+            factor_reg_val = 4;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_64:
+            factor_reg_val = 6;
+            break;
+        default:
+            HAL_ASSERT(false);
     }
-}
 
-/**
- * Get adc digital controller filter factor.
- *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
-{
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        filter->adc_unit = (APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 >> 3) & 0x1;
-        filter->channel = APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 & 0x7;
-        filter->mode = APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        filter->adc_unit = (APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 >> 3) & 0x1;
-        filter->channel = APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 & 0x7;
-        filter->mode = APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1;
+    if (idx == ADC_DIGI_IIR_FILTER_0) {
+        APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = factor_reg_val;
+    } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+        APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = factor_reg_val;
     }
 }
 
 /**
- * Disable adc digital controller filter.
+ * Enable adc digital controller filter.
  * Filtering the ADC data to obtain smooth data at higher sampling rates.
  *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param adc_n ADC unit.
- */
-static inline void adc_ll_digi_filter_disable(adc_digi_filter_idx_t idx)
-{
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = 0xF;
-        APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = 0;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = 0xF;
-        APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = 0;
+ * @param idx      filter index
+ * @param adc_n    ADC unit
+ * @param enable   Enable / Disable
+ */
+static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
+{
+    (void)adc_n;
+    if (!enable) {
+        if (idx == ADC_DIGI_IIR_FILTER_0) {
+            APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = 0xF;
+            APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = 0;
+        } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+            APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = 0xF;
+            APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = 0;
+        }
     }
+    //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled.
 }
 
 /**

+ 57 - 45
components/hal/esp32h4/include/hal/adc_ll.h

@@ -18,6 +18,7 @@
 #include "soc/rtc_cntl_reg.h"
 #include "soc/clk_tree_defs.h"
 #include "hal/misc.h"
+#include "hal/assert.h"
 #include "hal/regi2c_ctrl.h"
 
 #include "soc/regi2c_saradc.h"
@@ -310,66 +311,77 @@ static inline void adc_ll_digi_controller_clk_disable(void)
 /**
  * Reset adc digital controller filter.
  *
+ * @param idx   Filter index
  * @param adc_n ADC unit.
  */
-static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
+static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
 {
+    (void)adc_n;
     APB_SARADC.filter_ctrl0.filter_reset = 1;
-}
-
-/**
- * Set adc digital controller filter factor.
- *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param idx ADC filter unit.
- * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
-{
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        APB_SARADC.filter_ctrl0.filter_channel0 = (filter->adc_unit << 3) | (filter->channel & 0x7);
-        APB_SARADC.filter_ctrl1.filter_factor0 = filter->mode;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        APB_SARADC.filter_ctrl0.filter_channel1 = (filter->adc_unit << 3) | (filter->channel & 0x7);
-        APB_SARADC.filter_ctrl1.filter_factor1 = filter->mode;
+    APB_SARADC.filter_ctrl0.filter_reset = 0;
+}
+
+/**
+ * Set adc digital controller filter coeff.
+ *
+ * @param idx      filter index
+ * @param adc_n    adc unit
+ * @param channel  adc channel
+ * @param coeff    filter coeff
+ */
+static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
+{
+    uint32_t factor_reg_val = 0;
+    switch (coeff) {
+        case ADC_DIGI_IIR_FILTER_COEFF_2:
+            factor_reg_val = 1;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_4:
+            factor_reg_val = 2;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_8:
+            factor_reg_val = 3;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_16:
+            factor_reg_val = 4;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_64:
+            factor_reg_val = 6;
+            break;
+        default:
+            HAL_ASSERT(false);
     }
-}
 
-/**
- * Get adc digital controller filter factor.
- *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
-{
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        filter->adc_unit = (APB_SARADC.filter_ctrl0.filter_channel0 >> 3) & 0x1;
-        filter->channel = APB_SARADC.filter_ctrl0.filter_channel0 & 0x7;
-        filter->mode = APB_SARADC.filter_ctrl1.filter_factor0;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        filter->adc_unit = (APB_SARADC.filter_ctrl0.filter_channel1 >> 3) & 0x1;
-        filter->channel = APB_SARADC.filter_ctrl0.filter_channel1 & 0x7;
-        filter->mode = APB_SARADC.filter_ctrl1.filter_factor1;
+    if (idx == ADC_DIGI_IIR_FILTER_0) {
+        APB_SARADC.filter_ctrl0.filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.filter_ctrl1.filter_factor0 = factor_reg_val;
+    } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+        APB_SARADC.filter_ctrl0.filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.filter_ctrl1.filter_factor1 = factor_reg_val;
     }
 }
 
 /**
- * Disable adc digital controller filter.
+ * Enable adc digital controller filter.
  * Filtering the ADC data to obtain smooth data at higher sampling rates.
  *
- * @note If the channel info is not supported, the filter function will not be enabled.
- * @param adc_n ADC unit.
+ * @param idx      filter index
+ * @param adc_n    ADC unit
+ * @param enable   Enable / Disable
  */
-static inline void adc_ll_digi_filter_disable(adc_digi_filter_idx_t idx)
+static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
 {
-    if (idx == ADC_DIGI_FILTER_IDX0) {
-        APB_SARADC.filter_ctrl0.filter_channel0 = 0xF;
-        APB_SARADC.filter_ctrl1.filter_factor0 = 0;
-    } else if (idx == ADC_DIGI_FILTER_IDX1) {
-        APB_SARADC.filter_ctrl0.filter_channel1 = 0xF;
-        APB_SARADC.filter_ctrl1.filter_factor1 = 0;
+    (void)adc_n;
+    if (!enable) {
+        if (idx == ADC_DIGI_IIR_FILTER_0) {
+            APB_SARADC.filter_ctrl0.filter_channel0 = 0xF;
+            APB_SARADC.filter_ctrl1.filter_factor0 = 0;
+        } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+            APB_SARADC.filter_ctrl0.filter_channel1 = 0xF;
+            APB_SARADC.filter_ctrl1.filter_factor1 = 0;
+        }
     }
+    //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled.
 }
 
 /**

+ 22 - 37
components/hal/esp32s2/include/hal/adc_ll.h

@@ -357,10 +357,12 @@ static inline void adc_ll_digi_controller_clk_disable(void)
 /**
  * Reset adc digital controller filter.
  *
+ * @param idx   Filter index
  * @param adc_n ADC unit.
  */
-static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
+static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
 {
+    (void)idx;
     if (adc_n == ADC_UNIT_1) {
         APB_SARADC.filter_ctrl.adc1_filter_reset = 1;
         APB_SARADC.filter_ctrl.adc1_filter_reset = 0;
@@ -371,20 +373,24 @@ static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
 }
 
 /**
- * Set adc digital controller filter factor.
+ * Set adc digital controller filter coeff.
  *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
+ * @param idx      filter index
+ * @param adc_n    adc unit
+ * @param channel  adc channel
+ * @param coeff    filter coeff
  */
-static inline void adc_ll_digi_filter_set_factor(adc_unit_t adc_n, adc_digi_filter_mode_t factor)
+static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
 {
+    (void)idx;
+    (void)channel;
     int mode = 0;
-    switch (factor) {
-    case ADC_DIGI_FILTER_IIR_2:  mode = 2;  break;
-    case ADC_DIGI_FILTER_IIR_4:  mode = 4;  break;
-    case ADC_DIGI_FILTER_IIR_8:  mode = 8;  break;
-    case ADC_DIGI_FILTER_IIR_16: mode = 16; break;
-    case ADC_DIGI_FILTER_IIR_64: mode = 64; break;
+    switch (coeff) {
+    case ADC_DIGI_IIR_FILTER_COEFF_2:  mode = 2;  break;
+    case ADC_DIGI_IIR_FILTER_COEFF_4:  mode = 4;  break;
+    case ADC_DIGI_IIR_FILTER_COEFF_8:  mode = 8;  break;
+    case ADC_DIGI_IIR_FILTER_COEFF_16: mode = 16; break;
+    case ADC_DIGI_IIR_FILTER_COEFF_64: mode = 64; break;
     default: mode = 8; break;
     }
     if (adc_n == ADC_UNIT_1) {
@@ -394,39 +400,18 @@ static inline void adc_ll_digi_filter_set_factor(adc_unit_t adc_n, adc_digi_filt
     }
 }
 
-/**
- * Get adc digital controller filter factor.
- *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_get_factor(adc_unit_t adc_n, adc_digi_filter_mode_t *factor)
-{
-    int mode = 0;
-    if (adc_n == ADC_UNIT_1) {
-        mode = APB_SARADC.filter_ctrl.adc1_filter_factor;
-    } else { // adc_n == ADC_UNIT_2
-        mode = APB_SARADC.filter_ctrl.adc2_filter_factor;
-    }
-    switch (mode) {
-    case 2:  *factor = ADC_DIGI_FILTER_IIR_2;  break;
-    case 4:  *factor = ADC_DIGI_FILTER_IIR_4;  break;
-    case 8:  *factor = ADC_DIGI_FILTER_IIR_8;  break;
-    case 16: *factor = ADC_DIGI_FILTER_IIR_16; break;
-    case 64: *factor = ADC_DIGI_FILTER_IIR_64; break;
-    default: *factor = ADC_DIGI_FILTER_IIR_MAX;    break;
-    }
-}
-
 /**
  * Enable/disable adc digital controller filter.
  * Filtering the ADC data to obtain smooth data at higher sampling rates.
  *
  * @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
- * @param adc_n ADC unit.
+ * @param idx    Filter index
+ * @param adc_n  ADC unit
+ * @param enable Enable / Disable
  */
-static inline void adc_ll_digi_filter_enable(adc_unit_t adc_n, bool enable)
+static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
 {
+    (void)idx;
     if (adc_n == ADC_UNIT_1) {
         APB_SARADC.filter_ctrl.adc1_filter_en = enable;
     } else { // adc_n == ADC_UNIT_2

+ 54 - 35
components/hal/esp32s3/include/hal/adc_ll.h

@@ -362,58 +362,77 @@ static inline void adc_ll_digi_controller_clk_disable(void)
 /**
  * Reset adc digital controller filter.
  *
+ * @param idx   Filter index
  * @param adc_n ADC unit.
  */
-static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
+static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
 {
-    abort();
+    (void)adc_n;
+    APB_SARADC.filter_ctrl0.filter_reset = 1;
+    APB_SARADC.filter_ctrl0.filter_reset = 0;
 }
 
 /**
- * Set adc digital controller filter factor.
+ * Set adc digital controller filter coeff.
  *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
+ * @param idx      filter index
+ * @param adc_n    adc unit
+ * @param channel  adc channel
+ * @param coeff    filter coeff
  */
-static inline void adc_ll_digi_filter_set_factor(adc_unit_t adc_n, adc_digi_filter_mode_t factor)
+static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
 {
-    abort();
-}
+    uint32_t factor_reg_val = 0;
+    switch (coeff) {
+        case ADC_DIGI_IIR_FILTER_COEFF_2:
+            factor_reg_val = 1;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_4:
+            factor_reg_val = 2;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_8:
+            factor_reg_val = 3;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_16:
+            factor_reg_val = 4;
+            break;
+        case ADC_DIGI_IIR_FILTER_COEFF_64:
+            factor_reg_val = 6;
+            break;
+        default:
+            HAL_ASSERT(false);
+    }
 
-/**
- * Get adc digital controller filter factor.
- *
- * @param adc_n ADC unit.
- * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
- */
-static inline void adc_ll_digi_filter_get_factor(adc_unit_t adc_n, adc_digi_filter_mode_t *factor)
-{
-    abort();
+    if (idx == ADC_DIGI_IIR_FILTER_0) {
+        APB_SARADC.filter_ctrl0.filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.filter_ctrl1.filter_factor0 = factor_reg_val;
+    } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+        APB_SARADC.filter_ctrl0.filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7);
+        APB_SARADC.filter_ctrl1.filter_factor1 = factor_reg_val;
+    }
 }
 
 /**
- * Enable/disable adc digital controller filter.
+ * Enable adc digital controller filter.
  * Filtering the ADC data to obtain smooth data at higher sampling rates.
  *
- * @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
- * @param adc_n ADC unit.
+ * @param idx      filter index
+ * @param adc_n    ADC unit
+ * @param enable   Enable / Disable
  */
-static inline void adc_ll_digi_filter_enable(adc_unit_t adc_n, bool enable)
+static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
 {
-    abort();
-}
-
-/**
- * Get the filtered data of adc digital controller filter.
- * The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
- *
- * @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
- * @param adc_n ADC unit.
- * @return Filtered data.
- */
-static inline uint32_t adc_ll_digi_filter_read_data(adc_unit_t adc_n)
-{
-    abort();
+    (void)adc_n;
+    if (!enable) {
+        if (idx == ADC_DIGI_IIR_FILTER_0) {
+            APB_SARADC.filter_ctrl0.filter_channel0 = 0xF;
+            APB_SARADC.filter_ctrl1.filter_factor0 = 0;
+        } else if (idx == ADC_DIGI_IIR_FILTER_1) {
+            APB_SARADC.filter_ctrl0.filter_channel1 = 0xF;
+            APB_SARADC.filter_ctrl1.filter_factor1 = 0;
+        }
+    }
+    //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled.
 }
 
 /**

+ 19 - 0
components/hal/include/hal/adc_types.h

@@ -97,6 +97,25 @@ typedef struct {
     uint8_t bit_width;  ///< ADC output bit width
 } adc_digi_pattern_config_t;
 
+/**
+ * @brief ADC IIR Filter ID
+ */
+typedef enum {
+    ADC_DIGI_IIR_FILTER_0,  ///< Filter 0
+    ADC_DIGI_IIR_FILTER_1,  ///< Filter 1
+} adc_digi_iir_filter_t;
+
+/**
+ * @brief IIR Filter Coefficient
+ */
+typedef enum {
+    ADC_DIGI_IIR_FILTER_COEFF_2,     ///< The filter coefficient is 2
+    ADC_DIGI_IIR_FILTER_COEFF_4,     ///< The filter coefficient is 4
+    ADC_DIGI_IIR_FILTER_COEFF_8,     ///< The filter coefficient is 8
+    ADC_DIGI_IIR_FILTER_COEFF_16,    ///< The filter coefficient is 16
+    ADC_DIGI_IIR_FILTER_COEFF_64,    ///< The filter coefficient is 64
+} adc_digi_iir_filter_coeff_t;
+
 /*---------------------------------------------------------------
                     Output Format
 ---------------------------------------------------------------*/

+ 0 - 49
components/hal/include/hal/adc_types_private.h

@@ -47,55 +47,6 @@ typedef struct {
 }
 #endif  //#if SOC_ADC_ARBITER_SUPPORTED
 
-
-#if SOC_ADC_FILTER_SUPPORTED
-/*---------------------------------------------------------------
-                    Filter
----------------------------------------------------------------*/
-/**
- * @brief ADC digital controller (DMA mode) filter index options.
- *
- * @note  For ESP32-S2, The filter object of the ADC is fixed.
- */
-typedef enum {
-    ADC_DIGI_FILTER_IDX0 = 0, /*!<The filter index 0.
-                                  For ESP32-S2, It can only be used to filter all enabled channels of ADC1 unit at the same time. */
-    ADC_DIGI_FILTER_IDX1,     /*!<The filter index 1.
-                                  For ESP32-S2, It can only be used to filter all enabled channels of ADC2 unit at the same time. */
-    ADC_DIGI_FILTER_IDX_MAX
-} adc_digi_filter_idx_t;
-
-/**
- * @brief ADC digital controller (DMA mode) filter type options.
- *        Expression: filter_data = (k-1)/k * last_data + new_data / k.
- */
-typedef enum {
-#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
-    ADC_DIGI_FILTER_DIS = -1,  /*!< Disable filter */
-#endif
-    ADC_DIGI_FILTER_IIR_2 = 0, /*!<The filter mode is first-order IIR filter. The coefficient is 2. */
-    ADC_DIGI_FILTER_IIR_4,     /*!<The filter mode is first-order IIR filter. The coefficient is 4. */
-    ADC_DIGI_FILTER_IIR_8,     /*!<The filter mode is first-order IIR filter. The coefficient is 8. */
-    ADC_DIGI_FILTER_IIR_16,    /*!<The filter mode is first-order IIR filter. The coefficient is 16. */
-    ADC_DIGI_FILTER_IIR_64,    /*!<The filter mode is first-order IIR filter. The coefficient is 64. */
-    ADC_DIGI_FILTER_IIR_MAX
-} adc_digi_filter_mode_t;
-
-/**
- * @brief ADC digital controller (DMA mode) filter configuration.
- *
- * @note  For ESP32-S2, The filter object of the ADC is fixed.
- * @note  For ESP32-S2, The filter object is always all enabled channels.
- */
-typedef struct {
-    adc_unit_t adc_unit;        /*!<Set adc unit number for filter.
-                                    For ESP32-S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. */
-    adc_channel_t channel;      /*!<Set adc channel number for filter.
-                                    For ESP32-S2, it's always `ADC_CHANNEL_MAX` */
-    adc_digi_filter_mode_t mode;/*!<Set adc filter mode for filter. See ``adc_digi_filter_mode_t``. */
-} adc_digi_filter_t;
-#endif  // #if SOC_ADC_FILTER_SUPPORTED
-
 #if SOC_ADC_MONITOR_SUPPORTED
 /*---------------------------------------------------------------
                     Monitor

+ 3 - 0
components/idf_test/include/esp32/idf_performance_target.h

@@ -41,3 +41,6 @@
 // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround)
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV                                      70
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT                                     140
+
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER                 3
+#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3                              3

+ 2 - 0
components/idf_test/include/esp32c2/idf_performance_target.h

@@ -35,3 +35,5 @@
 // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround)
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV                                      70
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT                                     140
+
+#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3                              3

+ 8 - 0
components/idf_test/include/esp32c3/idf_performance_target.h

@@ -39,3 +39,11 @@
 // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround)
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV                                      70
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT                                     140
+
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER                 5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2                  5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4                  5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8                  5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16                 5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64                 5
+#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3                              5

+ 7 - 0
components/idf_test/include/esp32c6/idf_performance_target.h

@@ -19,3 +19,10 @@
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               17
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     32
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
+
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER                 6
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2                  5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4                  5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8                  5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16                 5
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64                 5

+ 8 - 0
components/idf_test/include/esp32s2/idf_performance_target.h

@@ -27,3 +27,11 @@
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            32
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     30
+
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER                 3
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2                  3
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4                  3
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8                  3
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16                 3
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64                 3
+#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3                              6

+ 8 - 0
components/idf_test/include/esp32s3/idf_performance_target.h

@@ -29,3 +29,11 @@
 // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround)
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV                                      70
 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT                                     140
+
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER                 4
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2                  4
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4                  4
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8                  4
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16                 4
+#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64                 4
+#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3                              4

+ 2 - 2
components/soc/esp32c2/include/soc/Kconfig.soc_caps.in

@@ -99,7 +99,7 @@ config SOC_ADC_DIG_CTRL_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_DIG_IIR_FILTER_SUPPORTED
     bool
     default y
 
@@ -135,7 +135,7 @@ config SOC_ADC_DIGI_MAX_BITWIDTH
     int
     default 12
 
-config SOC_ADC_DIGI_FILTER_NUM
+config SOC_ADC_DIGI_IIR_FILTER_NUM
     int
     default 2
 

+ 2 - 2
components/soc/esp32c2/include/soc/soc_caps.h

@@ -54,7 +54,7 @@
 /*-------------------------- ADC CAPS -------------------------------*/
 /*!< SAR ADC Module*/
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
-#define SOC_ADC_FILTER_SUPPORTED                1
+#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED        1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        1    //Digital controller supported ADC unit
 #define SOC_ADC_PERIPH_NUM                      (1U)
@@ -67,7 +67,7 @@
 #define SOC_ADC_PATT_LEN_MAX                    (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */
 #define SOC_ADC_DIGI_MIN_BITWIDTH               (12)
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
-#define SOC_ADC_DIGI_FILTER_NUM                 (2)
+#define SOC_ADC_DIGI_IIR_FILTER_NUM             (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
 /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval<= 4095 */
 #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH          83333

+ 2 - 2
components/soc/esp32c3/include/soc/Kconfig.soc_caps.in

@@ -167,7 +167,7 @@ config SOC_ADC_ARBITER_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_DIG_IIR_FILTER_SUPPORTED
     bool
     default y
 
@@ -215,7 +215,7 @@ config SOC_ADC_DIGI_DATA_BYTES_PER_CONV
     int
     default 4
 
-config SOC_ADC_DIGI_FILTER_NUM
+config SOC_ADC_DIGI_IIR_FILTER_NUM
     int
     default 2
 

+ 2 - 2
components/soc/esp32c3/include/soc/soc_caps.h

@@ -79,7 +79,7 @@
 /*!< SAR ADC Module*/
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
 #define SOC_ADC_ARBITER_SUPPORTED               1
-#define SOC_ADC_FILTER_SUPPORTED                1
+#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED        1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        ((UNIT == 0) ? 1 : 0)    //Digital controller supported ADC unit
@@ -95,7 +95,7 @@
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #define SOC_ADC_DIGI_RESULT_BYTES               (4)
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)
-#define SOC_ADC_DIGI_FILTER_NUM                 (2)
+#define SOC_ADC_DIGI_IIR_FILTER_NUM             (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
 /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval <= 4095 */
 #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH          83333

+ 2 - 2
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -187,7 +187,7 @@ config SOC_ADC_DIG_CTRL_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_DIG_IIR_FILTER_SUPPORTED
     bool
     default y
 
@@ -227,7 +227,7 @@ config SOC_ADC_DIGI_MIN_BITWIDTH
     int
     default 12
 
-config SOC_ADC_DIGI_FILTER_NUM
+config SOC_ADC_DIGI_IIR_FILTER_NUM
     int
     default 2
 

+ 2 - 2
components/soc/esp32c6/include/soc/soc_caps.h

@@ -82,7 +82,7 @@
 /*-------------------------- ADC CAPS -------------------------------*/
 /*!< SAR ADC Module*/
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
-#define SOC_ADC_FILTER_SUPPORTED                1
+#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED        1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        1    //Digital controller supported ADC unit
 #define SOC_ADC_DMA_SUPPORTED                   1
@@ -96,7 +96,7 @@
 #define SOC_ADC_PATT_LEN_MAX                    (8) /*!< Two pattern tables, each contains 4 items. Each item takes 1 byte */
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #define SOC_ADC_DIGI_MIN_BITWIDTH               (12)
-#define SOC_ADC_DIGI_FILTER_NUM                 (2)
+#define SOC_ADC_DIGI_IIR_FILTER_NUM             (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
 #define SOC_ADC_DIGI_RESULT_BYTES               (4)
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)

+ 2 - 2
components/soc/esp32h2/include/soc/Kconfig.soc_caps.in

@@ -127,7 +127,7 @@ config SOC_ADC_ARBITER_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_DIG_IIR_FILTER_SUPPORTED
     bool
     default y
 
@@ -159,7 +159,7 @@ config SOC_ADC_DIGI_MAX_BITWIDTH
     int
     default 12
 
-config SOC_ADC_DIGI_FILTER_NUM
+config SOC_ADC_DIGI_IIR_FILTER_NUM
     int
     default 2
 

+ 2 - 2
components/soc/esp32h2/include/soc/soc_caps.h

@@ -81,7 +81,7 @@
 /*!< SAR ADC Module*/
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
 #define SOC_ADC_ARBITER_SUPPORTED               1
-#define SOC_ADC_FILTER_SUPPORTED                1
+#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED        1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_PERIPH_NUM                      (1U)
 #define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         ((PERIPH_NUM==0)? 5 : 1)
@@ -92,7 +92,7 @@
 #define SOC_ADC_DIGI_CONTROLLER_NUM             (1U)
 #define SOC_ADC_PATT_LEN_MAX                    (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
-#define SOC_ADC_DIGI_FILTER_NUM                 (2)
+#define SOC_ADC_DIGI_IIR_FILTER_NUM             (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
 /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval<= 4095 */
 #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH          83333

+ 2 - 2
components/soc/esp32h4/include/soc/Kconfig.soc_caps.in

@@ -151,7 +151,7 @@ config SOC_ADC_ARBITER_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_DIG_IIR_FILTER_SUPPORTED
     bool
     default y
 
@@ -199,7 +199,7 @@ config SOC_ADC_DIGI_DATA_BYTES_PER_CONV
     int
     default 4
 
-config SOC_ADC_DIGI_FILTER_NUM
+config SOC_ADC_DIGI_IIR_FILTER_NUM
     int
     default 2
 

+ 2 - 2
components/soc/esp32h4/include/soc/soc_caps.h

@@ -80,7 +80,7 @@
 /*!< SAR ADC Module*/
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
 #define SOC_ADC_ARBITER_SUPPORTED               1
-#define SOC_ADC_FILTER_SUPPORTED                1
+#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED        1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        ((UNIT == 0) ? 1 : 0)    //Digital controller supported ADC unit
@@ -96,7 +96,7 @@
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #define SOC_ADC_DIGI_RESULT_BYTES               (4)
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)
-#define SOC_ADC_DIGI_FILTER_NUM                 (2)
+#define SOC_ADC_DIGI_IIR_FILTER_NUM             (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
 /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval<= 4095 */
 #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH          83333

+ 9 - 1
components/soc/esp32s2/include/soc/Kconfig.soc_caps.in

@@ -183,7 +183,11 @@ config SOC_ADC_ARBITER_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_DIG_IIR_FILTER_SUPPORTED
+    bool
+    default y
+
+config SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED
     bool
     default y
 
@@ -223,6 +227,10 @@ config SOC_ADC_DIGI_MAX_BITWIDTH
     int
     default 12
 
+config SOC_ADC_DIGI_IIR_FILTER_NUM
+    int
+    default 2
+
 config SOC_ADC_DIGI_RESULT_BYTES
     int
     default 2

+ 3 - 1
components/soc/esp32s2/include/soc/soc_caps.h

@@ -89,7 +89,8 @@
 #define SOC_ADC_RTC_CTRL_SUPPORTED              1
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
 #define SOC_ADC_ARBITER_SUPPORTED               1
-#define SOC_ADC_FILTER_SUPPORTED                1
+#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED        1
+#define SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED      1    //ADC filter is binded with the ADC unit
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        1    //Digital controller supported ADC unit
@@ -103,6 +104,7 @@
 #define SOC_ADC_PATT_LEN_MAX                    (32) /*!< Two pattern table, each contains 16 items. Each item takes 1 byte */
 #define SOC_ADC_DIGI_MIN_BITWIDTH               (12)
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
+#define SOC_ADC_DIGI_IIR_FILTER_NUM             (2)
 #define SOC_ADC_DIGI_RESULT_BYTES               (2)
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (2)
 /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval<= 4095 */

+ 5 - 1
components/soc/esp32s3/include/soc/Kconfig.soc_caps.in

@@ -223,7 +223,7 @@ config SOC_ADC_ARBITER_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_DIG_IIR_FILTER_SUPPORTED
     bool
     default y
 
@@ -271,6 +271,10 @@ config SOC_ADC_DIGI_DATA_BYTES_PER_CONV
     int
     default 4
 
+config SOC_ADC_DIGI_IIR_FILTER_NUM
+    int
+    default 2
+
 config SOC_ADC_SAMPLE_FREQ_THRES_HIGH
     int
     default 83333

+ 2 - 1
components/soc/esp32s3/include/soc/soc_caps.h

@@ -82,7 +82,7 @@
 #define SOC_ADC_RTC_CTRL_SUPPORTED              1
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
 #define SOC_ADC_ARBITER_SUPPORTED               1
-#define SOC_ADC_FILTER_SUPPORTED                1
+#define SOC_ADC_DIG_IIR_FILTER_SUPPORTED        1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        ((UNIT == 0) ? 1 : 0)    //Digital controller supported ADC unit
@@ -98,6 +98,7 @@
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #define SOC_ADC_DIGI_RESULT_BYTES               (4)
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)
+#define SOC_ADC_DIGI_IIR_FILTER_NUM             (2)
 /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval<= 4095 */
 #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH          83333
 #define SOC_ADC_SAMPLE_FREQ_THRES_LOW           611