Selaa lähdekoodia

Merge branch 'feature/support_adc_on_c6' into 'master'

adc: support adc on c6

Closes IDF-5310, IDF-5311, IDF-5917, and IDF-6567

See merge request espressif/esp-idf!21431
Kevin (Lao Kaiyao) 3 vuotta sitten
vanhempi
sitoutus
4a86240b6e
61 muutettua tiedostoa jossa 1246 lisäystä ja 276 poistoa
  1. 26 0
      .gitlab/ci/rules.yml
  2. 16 0
      .gitlab/ci/target-test.yml
  3. 1 3
      components/driver/.build-test-rules.yml
  4. 1 1
      components/driver/dac/esp32s2/dac_dma.c
  5. 7 7
      components/driver/deprecated/adc_legacy.c
  6. 14 2
      components/driver/deprecated/driver/adc_types_legacy.h
  7. 1 1
      components/driver/deprecated/esp32s2/dac_legacy.c
  8. 2 2
      components/driver/test_apps/legacy_adc_driver/README.md
  9. 7 0
      components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c
  10. 1 0
      components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py
  11. 1 3
      components/esp_adc/.build-test-rules.yml
  12. 0 9
      components/esp_adc/CMakeLists.txt
  13. 2 2
      components/esp_adc/test_apps/adc/README.md
  14. 8 0
      components/esp_adc/test_apps/adc/main/test_common_adc.h
  15. 1 0
      components/esp_adc/test_apps/adc/pytest_adc.py
  16. 0 7
      components/esp_hw_support/CMakeLists.txt
  17. 2 0
      components/esp_hw_support/port/esp32c6/rtc_init.c
  18. 0 5
      components/hal/CMakeLists.txt
  19. 2 5
      components/hal/adc_hal.c
  20. 1 1
      components/hal/adc_oneshot_hal.c
  21. 2 0
      components/hal/esp32/include/hal/adc_ll.h
  22. 8 11
      components/hal/esp32c2/include/hal/adc_ll.h
  23. 15 17
      components/hal/esp32c3/include/hal/adc_ll.h
  24. 28 0
      components/hal/esp32c6/include/hal/adc_hal_conf.h
  25. 741 0
      components/hal/esp32c6/include/hal/adc_ll.h
  26. 13 31
      components/hal/esp32h4/include/hal/adc_ll.h
  27. 12 14
      components/hal/esp32s2/include/hal/adc_ll.h
  28. 10 13
      components/hal/esp32s3/include/hal/adc_ll.h
  29. 0 14
      components/hal/include/hal/adc_hal.h
  30. 29 0
      components/hal/include/hal/adc_types.h
  31. 2 8
      components/hal/include/hal/adc_types_private.h
  32. 31 0
      components/soc/esp32/include/soc/clk_tree_defs.h
  33. 19 3
      components/soc/esp32c2/include/soc/clk_tree_defs.h
  34. 1 1
      components/soc/esp32c2/include/soc/soc_caps.h
  35. 15 0
      components/soc/esp32c3/include/soc/clk_tree_defs.h
  36. 1 1
      components/soc/esp32c3/include/soc/soc_caps.h
  37. 0 5
      components/soc/esp32c6/CMakeLists.txt
  38. 7 5
      components/soc/esp32c6/adc_periph.c
  39. 21 5
      components/soc/esp32c6/include/soc/Kconfig.soc_caps.in
  40. 5 2
      components/soc/esp32c6/include/soc/adc_channel.h
  41. 17 0
      components/soc/esp32c6/include/soc/clk_tree_defs.h
  42. 1 1
      components/soc/esp32c6/include/soc/pcr_struct.h
  43. 11 8
      components/soc/esp32c6/include/soc/soc_caps.h
  44. 22 0
      components/soc/esp32h2/include/soc/clk_tree_defs.h
  45. 1 1
      components/soc/esp32h2/include/soc/soc_caps.h
  46. 19 0
      components/soc/esp32h4/include/soc/clk_tree_defs.h
  47. 1 1
      components/soc/esp32h4/include/soc/soc_caps.h
  48. 29 0
      components/soc/esp32s2/include/soc/clk_tree_defs.h
  49. 1 1
      components/soc/esp32s2/include/soc/soc_caps.h
  50. 29 0
      components/soc/esp32s3/include/soc/clk_tree_defs.h
  51. 1 1
      components/soc/esp32s3/include/soc/soc_caps.h
  52. 0 16
      components/soc/include/soc/adc_periph.h
  53. 0 2
      docs/docs_not_updated/esp32c6.txt
  54. 2 1
      docs/en/api-reference/peripherals/adc_continuous.rst
  55. 2 1
      docs/en/api-reference/peripherals/adc_oneshot.rst
  56. 2 6
      examples/peripherals/.build-test-rules.yml
  57. 21 20
      examples/peripherals/adc/continuous_read/README.md
  58. 30 37
      examples/peripherals/adc/continuous_read/main/continuous_read_main.c
  59. 1 0
      examples/peripherals/adc/continuous_read/pytest_adc_continuous.py
  60. 2 2
      examples/peripherals/adc/oneshot_read/README.md
  61. 1 0
      examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py

+ 26 - 0
.gitlab/ci/rules.yml

@@ -1754,6 +1754,19 @@
     - <<: *if-dev-push
       changes: *patterns-component_ut
 
+.rules:test:component_ut-esp32c6-adc:
+  rules:
+    - <<: *if-revert-branch
+      when: never
+    - <<: *if-protected
+    - <<: *if-label-build-only
+      when: never
+    - <<: *if-label-component_ut
+    - <<: *if-label-component_ut_esp32c6
+    - <<: *if-label-target_test
+    - <<: *if-dev-push
+      changes: *patterns-target_test-adc
+
 .rules:test:component_ut-esp32h4-i154:
   rules:
     - <<: *if-revert-branch
@@ -2072,6 +2085,19 @@
     - <<: *if-dev-push
       changes: *patterns-example_test
 
+.rules:test:example_test-esp32c6-adc:
+  rules:
+    - <<: *if-revert-branch
+      when: never
+    - <<: *if-protected
+    - <<: *if-label-build-only
+      when: never
+    - <<: *if-label-example_test
+    - <<: *if-label-example_test_esp32c6
+    - <<: *if-label-target_test
+    - <<: *if-dev-push
+      changes: *patterns-target_test-adc
+
 .rules:test:example_test-esp32s2:
   rules:
     - <<: *if-revert-branch

+ 16 - 0
.gitlab/ci/target-test.yml

@@ -336,6 +336,14 @@ example_test_pytest_esp32c2_adc:
     - build_pytest_examples_esp32c2
   tags: [ esp32c2, adc, xtal_26mhz]
 
+example_test_pytest_esp32c6_adc:
+  extends:
+    - .pytest_examples_dir_template
+    - .rules:test:example_test-esp32c6-adc
+  needs:
+    - build_pytest_examples_esp32c6
+  tags: [ esp32c6, adc ]
+
 .pytest_components_dir_template:
   extends: .pytest_template
   variables:
@@ -673,6 +681,14 @@ component_ut_pytest_esp32c6_generic_multi_device:
     - build_pytest_components_esp32c6
   tags: [ esp32c6, generic_multi_device ]
 
+component_ut_pytest_esp32c6_adc:
+  extends:
+    - .pytest_components_dir_template
+    - .rules:test:component_ut-esp32c6-adc
+  needs:
+    - build_pytest_components_esp32c6
+  tags: [ esp32c6, adc ]
+
 component_ut_pytest_esp32h4_i154:
   extends:
     - .pytest_components_dir_template

+ 1 - 3
components/driver/.build-test-rules.yml

@@ -34,9 +34,7 @@ components/driver/test_apps/ledc:
 
 components/driver/test_apps/legacy_adc_driver:
   disable:
-    - if: IDF_TARGET == "esp32c6"
-      temporary: true
-      reason: target esp32c6 is not supported yet
+    - if: SOC_ADC_SUPPORTED != 1
 
 components/driver/test_apps/legacy_mcpwm_driver:
   disable:

+ 1 - 1
components/driver/dac/esp32s2/dac_dma.c

@@ -129,7 +129,7 @@ finish:
     dac_ll_digi_clk_inv(true);
     dac_ll_digi_set_trigger_interval(interval); // secondary clock division
     adc_ll_digi_controller_clk_div(clk_div - 1, b, a);
-    adc_ll_digi_clk_sel(is_apll);
+    adc_ll_digi_clk_sel(is_apll ? ADC_DIGI_CLK_SRC_APLL : ADC_DIGI_CLK_SRC_DEFAULT);
     return ESP_OK;
 }
 

+ 7 - 7
components/driver/deprecated/adc_legacy.c

@@ -617,11 +617,11 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
     adc_power_acquire();
     if (adc_unit == ADC_UNIT_1) {
         VREF_ENTER(1);
-        adc_hal_vref_output(ADC_UNIT_1, ch, true);
+        adc_ll_vref_output(ADC_UNIT_1, ch, true);
         VREF_EXIT(1);
     } else if (adc_unit == ADC_UNIT_2) {
         VREF_ENTER(2);
-        adc_hal_vref_output(ADC_UNIT_2, ch, true);
+        adc_ll_vref_output(ADC_UNIT_2, ch, true);
         VREF_EXIT(2);
     }
 
@@ -706,11 +706,11 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
     adc_power_acquire();
     if (adc_unit == ADC_UNIT_1) {
         RTC_ENTER_CRITICAL();
-        adc_hal_vref_output(ADC_UNIT_1, channel, true);
+        adc_ll_vref_output(ADC_UNIT_1, channel, true);
         RTC_EXIT_CRITICAL();
     } else {    //ADC_UNIT_2
         RTC_ENTER_CRITICAL();
-        adc_hal_vref_output(ADC_UNIT_2, channel, true);
+        adc_ll_vref_output(ADC_UNIT_2, channel, true);
         RTC_EXIT_CRITICAL();
     }
 
@@ -756,7 +756,7 @@ int adc1_get_raw(adc1_channel_t channel)
 
     periph_module_enable(PERIPH_SARADC_MODULE);
     adc_power_acquire();
-    adc_ll_digi_clk_sel(0);
+    adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
 
     adc_atten_t atten = s_atten1_single[channel];
 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
@@ -764,7 +764,7 @@ int adc1_get_raw(adc1_channel_t channel)
 #endif
 
     ADC_REG_LOCK_ENTER();
-    adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten);
+    adc_oneshot_ll_set_atten(ADC_UNIT_1, channel, atten);
     adc_hal_convert(ADC_UNIT_1, channel, &raw_out);
     ADC_REG_LOCK_EXIT();
 
@@ -807,7 +807,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
 
     periph_module_enable(PERIPH_SARADC_MODULE);
     adc_power_acquire();
-    adc_ll_digi_clk_sel(0);
+    adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
 
     adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
     adc_hal_arbiter_config(&config);

+ 14 - 2
components/driver/deprecated/driver/adc_types_legacy.h

@@ -61,7 +61,7 @@ typedef enum {
     ADC1_CHANNEL_9,     /*!< ADC1 channel 9 is GPIO10 */
     ADC1_CHANNEL_MAX,
 } adc1_channel_t;
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4
 typedef enum {
     ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO0 */
     ADC1_CHANNEL_1,     /*!< ADC1 channel 1 is GPIO1 */
@@ -70,6 +70,17 @@ typedef enum {
     ADC1_CHANNEL_4,     /*!< ADC1 channel 4 is GPIO4 */
     ADC1_CHANNEL_MAX,
 } adc1_channel_t;
+#elif CONFIG_IDF_TARGET_ESP32C6
+typedef enum {
+    ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO0 */
+    ADC1_CHANNEL_1,     /*!< ADC1 channel 1 is GPIO1 */
+    ADC1_CHANNEL_2,     /*!< ADC1 channel 2 is GPIO2 */
+    ADC1_CHANNEL_3,     /*!< ADC1 channel 3 is GPIO3 */
+    ADC1_CHANNEL_4,     /*!< ADC1 channel 4 is GPIO4 */
+    ADC1_CHANNEL_5,     /*!< ADC1 channel 5 is GPIO5 */
+    ADC1_CHANNEL_6,     /*!< ADC1 channel 6 is GPIO6 */
+    ADC1_CHANNEL_MAX,
+} adc1_channel_t;
 #endif // CONFIG_IDF_TARGET_*
 
 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
@@ -86,7 +97,8 @@ typedef enum {
     ADC2_CHANNEL_9,     /*!< ADC2 channel 9 is GPIO26 (ESP32), GPIO20 (ESP32-S2) */
     ADC2_CHANNEL_MAX,
 } adc2_channel_t;
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4
+// ESP32C6 has no ADC2
 typedef enum {
     ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO5 */
     ADC2_CHANNEL_MAX,

+ 1 - 1
components/driver/deprecated/esp32s2/dac_legacy.c

@@ -82,7 +82,7 @@ esp_err_t dac_digi_controller_config(const dac_digi_config_t *cfg)
     dac_ll_digi_set_convert_mode(cfg->mode == DAC_CONV_ALTER);
     dac_ll_digi_set_trigger_interval(cfg->interval);
     adc_ll_digi_controller_clk_div(cfg->dig_clk.div_num, cfg->dig_clk.div_b, cfg->dig_clk.div_a);
-    adc_ll_digi_clk_sel(cfg->dig_clk.use_apll);
+    adc_ll_digi_clk_sel(cfg->dig_clk.use_apll ? ADC_DIGI_CLK_SRC_APLL : ADC_DIGI_CLK_SRC_DEFAULT);
     DAC_EXIT_CRITICAL();
 
     return ESP_OK;

+ 2 - 2
components/driver/test_apps/legacy_adc_driver/README.md

@@ -1,2 +1,2 @@
-| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
-| ----------------- | ----- | -------- | -------- | -------- | -------- |
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

+ 7 - 0
components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c

@@ -53,6 +53,13 @@
 #define ADC_TEST_HIGH_VAL        3400
 #define ADC_TEST_HIGH_THRESH     200
 
+#elif CONFIG_IDF_TARGET_ESP32C6  // TODO: IDF-5312
+#define ADC_TEST_LOW_VAL         2144
+#define ADC_TEST_LOW_THRESH      200
+
+#define ADC_TEST_HIGH_VAL        4081
+#define ADC_TEST_HIGH_THRESH     200
+
 #endif
 
 //ADC Channels

+ 1 - 0
components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py

@@ -9,6 +9,7 @@ from pytest_embedded import Dut
 @pytest.mark.esp32s2
 @pytest.mark.esp32s3
 @pytest.mark.esp32c3
+@pytest.mark.esp32c6
 @pytest.mark.adc
 @pytest.mark.parametrize(
     'config',

+ 1 - 3
components/esp_adc/.build-test-rules.yml

@@ -2,6 +2,4 @@
 
 components/esp_adc/test_apps/adc:
   disable:
-    - if: IDF_TARGET == "esp32c6"
-      temporary: true
-      reason: target esp32c6 is not supported yet
+    - if: SOC_ADC_SUPPORTED != 1

+ 0 - 9
components/esp_adc/CMakeLists.txt

@@ -32,15 +32,6 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/deprecated/${target}/esp_adc_cal_legacy.c
     list(APPEND srcs "deprecated/${target}/esp_adc_cal_legacy.c")
 endif()
 
-# ESP32C6-TODO
-if(CONFIG_IDF_TARGET_ESP32C6)
-    list(REMOVE_ITEM srcs
-            "adc_cali_curve_fitting.c" # TODO: IDF-5312
-            "adc_oneshot.c"            # TODO: IDF-5310
-            "adc_common.c"
-        )
-endif()
-
 idf_component_register(SRCS ${srcs}
                        INCLUDE_DIRS ${includes}
                        PRIV_REQUIRES driver efuse

+ 2 - 2
components/esp_adc/test_apps/adc/README.md

@@ -1,2 +1,2 @@
-| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
-| ----------------- | ----- | -------- | -------- | -------- | -------- |
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

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

@@ -70,6 +70,14 @@ extern "C" {
 
 #define ADC_TEST_HIGH_VAL        3400
 #define ADC_TEST_HIGH_THRESH     200
+
+#elif CONFIG_IDF_TARGET_ESP32C6  // TODO: IDF-5312
+#define ADC_TEST_LOW_VAL         2144
+#define ADC_TEST_LOW_THRESH      200
+
+#define ADC_TEST_HIGH_VAL        4081
+#define ADC_TEST_HIGH_VAL_DMA    4081
+#define ADC_TEST_HIGH_THRESH     200
 #endif
 
 

+ 1 - 0
components/esp_adc/test_apps/adc/pytest_adc.py

@@ -9,6 +9,7 @@ from pytest_embedded import Dut
 @pytest.mark.esp32s2
 @pytest.mark.esp32s3
 @pytest.mark.esp32c3
+@pytest.mark.esp32c6
 @pytest.mark.adc
 @pytest.mark.parametrize('config', [
     'iram_safe',

+ 0 - 7
components/esp_hw_support/CMakeLists.txt

@@ -70,13 +70,6 @@ if(NOT BOOTLOADER_BUILD)
         list(APPEND srcs "esp_ds.c")
     endif()
 
-    # ESP32C6-TODO
-    if(CONFIG_IDF_TARGET_ESP32C6)
-        list(REMOVE_ITEM srcs
-                "adc_share_hw_ctrl.c" # TODO: IDF-5312
-            )
-    endif()
-
 else()
     # Requires "_esp_error_check_failed()" function
     list(APPEND priv_requires "esp_system")

+ 2 - 0
components/esp_hw_support/port/esp32c6/rtc_init.c

@@ -13,8 +13,10 @@
 
 void rtc_init(rtc_config_t cfg)
 {
+    /* Peripheral reg i2c power up */
     SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB);
     SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
+
     REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1);
     REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1);
     REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);

+ 0 - 5
components/hal/CMakeLists.txt

@@ -191,11 +191,6 @@ if(NOT BOOTLOADER_BUILD)
               "esp32c6/brownout_hal.c"
               "esp32c6/rtc_cntl_hal.c")
 
-        # TODO: IDF-5310
-        list(REMOVE_ITEM srcs
-                "adc_oneshot_hal.c"
-                "adc_hal_common.c"
-                )
     endif()
 
     if(${target} STREQUAL "esp32h2")

+ 2 - 5
components/hal/adc_hal.c

@@ -141,11 +141,8 @@ void adc_hal_digi_deinit(adc_hal_dma_ctx_t *hal)
 ---------------------------------------------------------------*/
 static adc_ll_digi_convert_mode_t get_convert_mode(adc_digi_convert_mode_t convert_mode)
 {
-#if CONFIG_IDF_TARGET_ESP32
+#if CONFIG_IDF_TARGET_ESP32 || SOC_ADC_DIGI_CONTROLLER_NUM == 1
     return ADC_LL_DIGI_CONV_ONLY_ADC1;
-#endif
-#if (SOC_ADC_DIGI_CONTROLLER_NUM == 1)
-    return ADC_LL_DIGI_CONV_ALTER_UNIT;
 #elif (SOC_ADC_DIGI_CONTROLLER_NUM >= 2)
     switch (convert_mode) {
         case ADC_CONV_SINGLE_UNIT_1:
@@ -177,7 +174,7 @@ static void adc_hal_digi_sample_freq_config(adc_hal_dma_ctx_t *hal, uint32_t fre
     adc_ll_digi_set_trigger_interval(interval);
     //Here we set the clock divider factor to make the digital clock to 5M Hz
     adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT);
-    adc_ll_digi_clk_sel(0);   //use APB
+    adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);   // use default clock source for ADC digital controller
 #else
     i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_SRC_DEFAULT);    /*!< Clock from PLL_D2_CLK(160M)*/
     uint32_t bclk_div = 16;

+ 1 - 1
components/hal/adc_oneshot_hal.c

@@ -57,7 +57,7 @@ void adc_oneshot_hal_setup(adc_oneshot_hal_ctx_t *hal, adc_channel_t chan)
 #endif
 
 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
-    adc_ll_digi_clk_sel(0);
+    adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT);
 #else
     adc_ll_set_sar_clk_div(unit, ADC_HAL_SAR_CLK_DIV_DEFAULT(unit));
     if (unit == ADC_UNIT_2) {

+ 2 - 0
components/hal/esp32/include/hal/adc_ll.h

@@ -13,8 +13,10 @@
 #include "soc/adc_periph.h"
 #include "soc/rtc_io_struct.h"
 #include "soc/sens_struct.h"
+#include "soc/sens_reg.h"
 #include "soc/syscon_struct.h"
 #include "soc/rtc_cntl_struct.h"
+#include "soc/clk_tree_defs.h"
 
 #ifdef __cplusplus
 extern "C" {

+ 8 - 11
components/hal/esp32c2/include/hal/adc_ll.h

@@ -14,6 +14,7 @@
 #include "soc/apb_saradc_reg.h"
 #include "soc/rtc_cntl_struct.h"
 #include "soc/rtc_cntl_reg.h"
+#include "soc/clk_tree_defs.h"
 #include "hal/misc.h"
 #include "hal/assert.h"
 #include "hal/adc_types.h"
@@ -33,9 +34,9 @@ extern "C" {
 #define ADC_LL_EVENT_ADC2_ONESHOT_DONE    BIT(30)
 
 typedef enum {
-    ADC_POWER_BY_FSM,   /*!< ADC XPD controled by FSM. Used for polling mode */
-    ADC_POWER_SW_ON,    /*!< ADC XPD controled by SW. power on. Used for DMA mode */
-    ADC_POWER_SW_OFF,   /*!< ADC XPD controled by SW. power off. */
+    ADC_POWER_BY_FSM,   /*!< ADC XPD controlled by FSM. Used for polling mode */
+    ADC_POWER_SW_ON,    /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
+    ADC_POWER_SW_OFF,   /*!< ADC XPD controlled by SW. power off. */
     ADC_POWER_MAX,      /*!< For parameter check. */
 } adc_ll_power_t;
 
@@ -93,7 +94,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
  */
 static inline void adc_ll_digi_set_clk_div(uint32_t div)
 {
-    /* ADC clock devided from digital controller clock clk */
+    /* ADC clock divided from digital controller clock clk */
     HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl, saradc_saradc_sar_clk_div, div);
 }
 
@@ -141,15 +142,11 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
 /**
  * Enable clock and select clock source for ADC digital controller.
  *
- * @param use_apll true: use APLL clock; false: use APB clock.
+ * @param clk_src clock source for ADC digital controller.
  */
-static inline void adc_ll_digi_clk_sel(bool use_apll)
+static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
 {
-    if (use_apll) {
-        APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = 1;   // APLL clock
-    } else {
-        APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = 2;   // APB clock
-    }
+    APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = 2;
     APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1;
 }
 

+ 15 - 17
components/hal/esp32c3/include/hal/adc_ll.h

@@ -14,6 +14,7 @@
 #include "soc/apb_saradc_reg.h"
 #include "soc/rtc_cntl_struct.h"
 #include "soc/rtc_cntl_reg.h"
+#include "soc/clk_tree_defs.h"
 #include "hal/misc.h"
 #include "hal/assert.h"
 #include "hal/adc_types.h"
@@ -35,14 +36,14 @@ extern "C" {
 #define ADC_LL_EVENT_ADC1_ONESHOT_DONE    BIT(31)
 #define ADC_LL_EVENT_ADC2_ONESHOT_DONE    BIT(30)
 #define ADC_LL_EVENT_THRES0_HIGH          BIT(29)
-#define ADC_LL_event_THRES1_HIGH          BIT(28)
-#define ADC_LL_event_THRES0_LOW           BIT(27)
+#define ADC_LL_EVENT_THRES1_HIGH          BIT(28)
+#define ADC_LL_EVENT_THRES0_LOW           BIT(27)
 #define ADC_LL_EVENT_THRES1_LOW           BIT(26)
 
 typedef enum {
-    ADC_POWER_BY_FSM,   /*!< ADC XPD controled by FSM. Used for polling mode */
-    ADC_POWER_SW_ON,    /*!< ADC XPD controled by SW. power on. Used for DMA mode */
-    ADC_POWER_SW_OFF,   /*!< ADC XPD controled by SW. power off. */
+    ADC_POWER_BY_FSM,   /*!< ADC XPD controlled by FSM. Used for polling mode */
+    ADC_POWER_SW_ON,    /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
+    ADC_POWER_SW_OFF,   /*!< ADC XPD controlled by SW. power off. */
     ADC_POWER_MAX,      /*!< For parameter check. */
 } adc_ll_power_t;
 
@@ -62,11 +63,11 @@ typedef enum {
  * @brief ADC digital controller (DMA mode) work mode.
  *
  * @note  The conversion mode affects the sampling frequency:
- *        ESP32C3 only support ALTER_UNIT mode
- *        ALTER_UNIT   : When the measurement is triggered, ADC1 or ADC2 samples alternately.
+ *        ESP32C3 only support ONLY_ADC1 mode
+ *        SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once.
  */
 typedef enum {
-    ADC_LL_DIGI_CONV_ALTER_UNIT = 0,     // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 .....
+    ADC_LL_DIGI_CONV_ONLY_ADC1 = 0,     // Only use ADC1 for conversion
 } adc_ll_digi_convert_mode_t;
 
 typedef struct  {
@@ -124,7 +125,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
  */
 static inline void adc_ll_digi_set_clk_div(uint32_t div)
 {
-    /* ADC clock devided from digital controller clock clk */
+    /* ADC clock divided from digital controller clock clk */
     HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div);
 }
 
@@ -159,7 +160,7 @@ static inline void adc_ll_digi_convert_limit_enable(bool enable)
  */
 static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode)
 {
-    //ESP32C3 only supports ADC_CONV_ALTER_UNIT mode
+    //ESP32C3 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode
 }
 
 /**
@@ -283,15 +284,12 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
 /**
  * Enable clock and select clock source for ADC digital controller.
  *
- * @param use_apll true: use APLL clock; false: use APB clock.
+ * @param clk_src clock source for ADC digital controller.
  */
-static inline void adc_ll_digi_clk_sel(bool use_apll)
+static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
 {
-    if (use_apll) {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 1;   // APLL clock
-    } else {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 2;   // APB clock
-    }
+    // Only support APB clock, should always set to 1 or 2
+    APB_SARADC.apb_adc_clkm_conf.clk_sel = 2;
     APB_SARADC.ctrl.sar_clk_gated = 1;
 }
 

+ 28 - 0
components/hal/esp32c6/include/hal/adc_hal_conf.h

@@ -0,0 +1,28 @@
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+/*---------------------------------------------------------------
+                    Single Read
+---------------------------------------------------------------*/
+#define ADC_HAL_DATA_INVERT_DEFAULT(PERIPH_NUM)         (0)
+#define ADC_HAL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM)         (2)
+
+/*---------------------------------------------------------------
+                    DMA Read
+---------------------------------------------------------------*/
+#define ADC_HAL_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM)    (0)
+#define ADC_HAL_FSM_RSTB_WAIT_DEFAULT                   (8)
+#define ADC_HAL_FSM_START_WAIT_DEFAULT                  (5)
+#define ADC_HAL_FSM_STANDBY_WAIT_DEFAULT                (100)
+#define ADC_HAL_SAMPLE_CYCLE_DEFAULT                    (2)
+#define ADC_HAL_DIGI_SAR_CLK_DIV_DEFAULT                (1)
+
+/*---------------------------------------------------------------
+                    PWDET (Power Detect)
+---------------------------------------------------------------*/
+#define ADC_HAL_PWDET_CCT_DEFAULT                       (4)

+ 741 - 0
components/hal/esp32c6/include/hal/adc_ll.h

@@ -0,0 +1,741 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#pragma once
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include "esp_attr.h"
+
+#include "soc/adc_periph.h"
+#include "soc/apb_saradc_struct.h"
+#include "soc/apb_saradc_reg.h"
+#include "soc/pmu_reg.h"
+#include "soc/clk_tree_defs.h"
+#include "soc/pcr_struct.h"
+#include "hal/misc.h"
+#include "hal/assert.h"
+#include "hal/adc_types.h"
+#include "hal/adc_types_private.h"
+#include "hal/regi2c_ctrl.h"
+#include "hal/sar_ctrl_ll.h"
+
+#include "soc/regi2c_saradc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ADC_LL_CLKM_DIV_NUM_DEFAULT       15
+#define ADC_LL_CLKM_DIV_B_DEFAULT         1
+#define ADC_LL_CLKM_DIV_A_DEFAULT         0
+#define ADC_LL_DEFAULT_CONV_LIMIT_EN      0
+#define ADC_LL_DEFAULT_CONV_LIMIT_NUM     10
+
+#define ADC_LL_EVENT_ADC1_ONESHOT_DONE    BIT(31)
+#define ADC_LL_EVENT_ADC2_ONESHOT_DONE    BIT(30)
+#define ADC_LL_EVENT_THRES0_HIGH          BIT(29)
+#define ADC_LL_EVENT_THRES1_HIGH          BIT(28)
+#define ADC_LL_EVENT_THRES0_LOW           BIT(27)
+#define ADC_LL_EVENT_THRES1_LOW           BIT(26)
+
+typedef enum {
+    ADC_POWER_BY_FSM = SAR_CTRL_LL_POWER_FSM,   /*!< ADC XPD controlled by FSM. Used for polling mode */
+    ADC_POWER_SW_ON = SAR_CTRL_LL_POWER_ON,    /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
+    ADC_POWER_SW_OFF = SAR_CTRL_LL_POWER_OFF,   /*!< ADC XPD controlled by SW. power off. */
+    ADC_POWER_MAX,      /*!< For parameter check. */
+} adc_ll_power_t;
+
+typedef enum {
+    ADC_LL_CTRL_DIG = 0,    ///< ADC digital controller
+} adc_ll_controller_t;
+
+/**
+ * @brief ADC digital controller (DMA mode) work mode.
+ *
+ * @note  The conversion mode affects the sampling frequency:
+ *        ESP32C6 only support ONLY_ADC1 mode
+ *        SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once.
+ */
+typedef enum {
+    ADC_LL_DIGI_CONV_ONLY_ADC1 = 0,     // Only use ADC1 for conversion
+} adc_ll_digi_convert_mode_t;
+
+typedef struct  {
+    union {
+        struct {
+            uint8_t atten:      2;
+            uint8_t channel:    3;
+            uint8_t unit:       1;
+            uint8_t reserved:   2;
+        };
+        uint8_t val;
+    };
+} __attribute__((packed)) adc_ll_digi_pattern_table_t;
+
+/*---------------------------------------------------------------
+                    Digital controller setting
+---------------------------------------------------------------*/
+
+/**
+ * Set adc fsm interval parameter for digital controller. These values are fixed for same platforms.
+ *
+ * @param rst_wait cycles between DIG ADC controller reset ADC sensor and start ADC sensor.
+ * @param start_wait Delay time after open xpd.
+ * @param standby_wait Delay time to close xpd.
+ */
+static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait)
+{
+    // Internal FSM reset wait time
+    HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_rstb_wait, rst_wait);
+    // Internal FSM start wait time
+    HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_xpd_wait, start_wait);
+    // Internal FSM standby wait time
+    HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_standby_wait, standby_wait);
+}
+
+/**
+ * Set adc sample cycle for digital controller.
+ *
+ * @note Normally, please use default value.
+ * @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor.
+ *                     Range: 2 ~ 0xFF.
+ */
+static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
+{
+    /* Peripheral reg i2c has powered up in rtc_init, write directly */
+    REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle);
+}
+
+/**
+ * Set SAR ADC module clock division factor.
+ * SAR ADC clock divided from digital controller clock.
+ *
+ * @param div Division factor.
+ */
+static inline void adc_ll_digi_set_clk_div(uint32_t div)
+{
+    /* ADC clock divided from digital controller clock clk */
+    HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl, saradc_saradc_sar_clk_div, div);
+}
+
+/**
+ * Set adc max conversion number for digital controller.
+ * If the number of ADC conversion is equal to the maximum, the conversion is stopped.
+ *
+ * @param meas_num Max conversion number. Range: 0 ~ 255.
+ */
+static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num)
+{
+    HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl2, saradc_saradc_max_meas_num, meas_num);
+}
+
+/**
+ * Enable max conversion number detection for digital controller.
+ * If the number of ADC conversion is equal to the maximum, the conversion is stopped.
+ *
+ * @param enable  true: enable; false: disable
+ */
+static inline void adc_ll_digi_convert_limit_enable(bool enable)
+{
+    APB_SARADC.saradc_ctrl2.saradc_saradc_meas_num_limit = enable;
+}
+
+/**
+ * Set adc conversion mode for digital controller.
+ *
+ * @note ESP32C6 only support ADC1 single mode.
+ *
+ * @param mode Conversion mode select.
+ */
+static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode)
+{
+    //ESP32C6 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode
+}
+
+/**
+ * Set pattern table length for digital controller.
+ * The pattern table that defines the conversion rules for each SAR ADC. Each table has 4 items, in which channel selection,
+ * and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
+ * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself.
+ *
+ * @param adc_n ADC unit.
+ * @param patt_len Items range: 1 ~ 8.
+ */
+static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t patt_len)
+{
+    APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_len = patt_len - 1;
+}
+
+/**
+ * Set pattern table for digital controller.
+ * The pattern table that defines the conversion rules for each SAR ADC. Each table has 4 items, in which channel selection,
+ * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
+ * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself.
+ *
+ * @param adc_n ADC unit.
+ * @param pattern_index Items index. Range: 0 ~ 7.
+ * @param pattern Stored conversion rules.
+ */
+static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table)
+{
+    uint32_t tab;
+    uint8_t index = pattern_index / 4;
+    uint8_t offset = (pattern_index % 4) * 6;
+    adc_ll_digi_pattern_table_t pattern = {0};
+
+    pattern.val = (table.atten & 0x3) | ((table.channel & 0x7) << 2) | ((table.unit & 0x1) << 5);
+    if (index == 0) {
+        tab = APB_SARADC.saradc_sar_patt_tab1.saradc_saradc_sar_patt_tab1;         // Read old register value
+        tab &= (~(0xFC0000 >> offset));                             // Clear old data
+        tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset;    // Fill in the new data
+        APB_SARADC.saradc_sar_patt_tab1.saradc_saradc_sar_patt_tab1 = tab;         // Write back
+    } else {
+        tab = APB_SARADC.saradc_sar_patt_tab2.saradc_saradc_sar_patt_tab2;         // Read old register value
+        tab &= (~(0xFC0000 >> offset));                             // Clear old data
+        tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset;    // Fill in the new data
+        APB_SARADC.saradc_sar_patt_tab2.saradc_saradc_sar_patt_tab2 = tab;         // Write back
+    }
+}
+
+/**
+ * Reset the pattern table pointer, then take the measurement rule from table header in next measurement.
+ *
+ * @param adc_n ADC unit.
+ */
+static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n)
+{
+    APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_p_clear = 1;
+    APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_p_clear = 0;
+}
+
+/**
+ * Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize.
+ *
+ * @note Only ADC2 have arbiter function.
+ * @param cycle range: 0 ~ 4.
+ */
+static inline void adc_ll_digi_set_arbiter_stable_cycle(uint32_t cycle)
+{
+    APB_SARADC.saradc_ctrl.saradc_saradc_wait_arb_cycle = cycle;
+}
+
+/**
+ * ADC Digital controller output data invert or not.
+ *
+ * @param adc_n ADC unit.
+ * @param inv_en data invert or not.
+ */
+static inline void adc_ll_digi_output_invert(adc_unit_t adc_n, bool inv_en)
+{
+    if (adc_n == ADC_UNIT_1) {
+        APB_SARADC.saradc_ctrl2.saradc_saradc_sar1_inv = inv_en;   // Enable / Disable ADC data invert
+    }
+}
+
+/**
+ * Set the interval clock cycle for the digital controller to trigger the measurement.
+ * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval.
+ *
+ * @note The trigger interval should not be smaller than the sampling time of the SAR ADC.
+ * @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095.
+ */
+static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle)
+{
+    APB_SARADC.saradc_ctrl2.saradc_saradc_timer_target = cycle;
+}
+
+/**
+ * Enable digital controller timer to trigger the measurement.
+ */
+static inline void adc_ll_digi_trigger_enable(void)
+{
+    APB_SARADC.saradc_ctrl2.saradc_saradc_timer_en = 1;
+}
+
+/**
+ * Disable digital controller timer to trigger the measurement.
+ */
+static inline void adc_ll_digi_trigger_disable(void)
+{
+    APB_SARADC.saradc_ctrl2.saradc_saradc_timer_en = 0;
+}
+
+/**
+ * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
+ * Expression: controller_clk = (APLL or APB) / (div_num + div_a / div_b + 1).
+ *
+ * @param div_num Division factor. Range: 0 ~ 255.
+ * @param div_b Division factor. Range: 1 ~ 63.
+ * @param div_a Division factor. Range: 0 ~ 63.
+ */
+static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a)
+{
+    HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.saradc_clkm_conf, saradc_clkm_div_num, div_num);
+    PCR.saradc_clkm_conf.saradc_clkm_div_b = div_b;
+    PCR.saradc_clkm_conf.saradc_clkm_div_a = div_a;
+}
+
+/**
+ * Enable clock and select clock source for ADC digital controller.
+ *
+ * @param clk_src clock source for ADC digital controller.
+ */
+static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
+{
+    switch (clk_src) {
+        case ADC_DIGI_CLK_SRC_XTAL:
+            PCR.saradc_clkm_conf.saradc_clkm_sel = 0;
+            break;
+        case ADC_DIGI_CLK_SRC_PLL_F80M:
+            PCR.saradc_clkm_conf.saradc_clkm_sel = 1;
+            break;
+        case ADC_DIGI_CLK_SRC_RC_FAST:
+            PCR.saradc_clkm_conf.saradc_clkm_sel = 2;
+            break;
+        default:
+            HAL_ASSERT(false && "unsupported clock");
+    }
+    // Enable ADC_CTRL_CLK (i.e. digital domain clock)
+    APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1;
+}
+
+/**
+ * Disable clock for ADC digital controller.
+ */
+static inline void adc_ll_digi_controller_clk_disable(void)
+{
+    APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0;
+}
+
+/**
+ * Reset adc digital controller filter.
+ *
+ * @param adc_n ADC unit.
+ */
+static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n)
+{
+    APB_SARADC.saradc_filter_ctrl0.saradc_apb_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)
+{
+    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;
+    }
+}
+
+/**
+ * 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;
+    }
+}
+
+/**
+ * Disable 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;
+    }
+}
+
+/**
+ * Set monitor mode of adc digital controller.
+ *
+ * @note If the channel info is not supported, the monitor function will not be enabled.
+ * @param adc_n ADC unit.
+ * @param is_larger true:  If ADC_OUT >  threshold, Generates monitor interrupt.
+ *                  false: If ADC_OUT <  threshold, Generates monitor interrupt.
+ */
+static inline void adc_ll_digi_monitor_set_mode(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *cfg)
+{
+    if (idx == ADC_DIGI_MONITOR_IDX0) {
+        APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7);
+        APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_high = cfg->h_threshold;
+        APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_low = cfg->l_threshold;
+    } else { // ADC_DIGI_MONITOR_IDX1
+        APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7);
+        APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_low = cfg->h_threshold;
+        APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_low = cfg->l_threshold;
+    }
+}
+
+/**
+ * Enable/disable monitor of adc digital controller.
+ *
+ * @note If the channel info is not supported, the monitor function will not be enabled.
+ * @param adc_n ADC unit.
+ */
+static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx)
+{
+    if (idx == ADC_DIGI_MONITOR_IDX0) {
+        APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_channel = 0xF;
+    } else { // ADC_DIGI_MONITOR_IDX1
+        APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_channel = 0xF;
+    }
+}
+
+/**
+ * Set DMA eof num of adc digital controller.
+ * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated.
+ *
+ * @param num eof num of DMA.
+ */
+static inline void adc_ll_digi_dma_set_eof_num(uint32_t num)
+{
+    HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_dma_conf, saradc_apb_adc_eof_num, num);
+}
+
+/**
+ * Enable output data to DMA from adc digital controller.
+ */
+static inline void adc_ll_digi_dma_enable(void)
+{
+    APB_SARADC.saradc_dma_conf.saradc_apb_adc_trans = 1;
+}
+
+/**
+ * Disable output data to DMA from adc digital controller.
+ */
+static inline void adc_ll_digi_dma_disable(void)
+{
+    APB_SARADC.saradc_dma_conf.saradc_apb_adc_trans = 0;
+}
+
+/**
+ * Reset adc digital controller.
+ */
+static inline void adc_ll_digi_reset(void)
+{
+    APB_SARADC.saradc_dma_conf.saradc_apb_adc_reset_fsm = 1;
+    APB_SARADC.saradc_dma_conf.saradc_apb_adc_reset_fsm = 0;
+}
+
+/*---------------------------------------------------------------
+                    PWDET(Power detect) controller setting
+---------------------------------------------------------------*/
+/**
+ * Set adc cct for PWDET controller.
+ *
+ * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
+ * @param cct Range: 0 ~ 7.
+ */
+static inline void adc_ll_pwdet_set_cct(uint32_t cct)
+{
+    (void)cct;
+}
+
+/**
+ * Get adc cct for PWDET controller.
+ *
+ * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
+ * @return cct Range: 0 ~ 7.
+ */
+static inline uint32_t adc_ll_pwdet_get_cct(void)
+{
+    return 0;
+}
+
+/*---------------------------------------------------------------
+                    Common setting
+---------------------------------------------------------------*/
+/**
+ * Set ADC module power management.
+ *
+ * @param manage Set ADC power status.
+ */
+static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
+{
+    /* Bit1  0:Fsm  1: SW mode
+       Bit0  0:SW mode power down  1: SW mode power on */
+    if (manage == ADC_POWER_SW_ON) {
+        APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1;
+        APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 3;
+    } else if (manage == ADC_POWER_BY_FSM) {
+        APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1;
+        APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 0;
+    } else if (manage == ADC_POWER_SW_OFF) {
+        APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0;
+        APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 2;
+    }
+}
+
+__attribute__((always_inline))
+static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t ctrl)
+{
+    //Not used on ESP32C6
+}
+
+/* ADC calibration code. */
+/**
+ * @brief Set common calibration configuration. Should be shared with other parts (PWDET).
+ */
+__attribute__((always_inline))
+static inline void adc_ll_calibration_init(adc_unit_t adc_n)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1);
+}
+
+/**
+ * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration.
+ *
+ * @note  Different ADC units and different attenuation options use different calibration data (initial data).
+ *
+ * @param adc_n ADC index number.
+ * @param internal_gnd true:  Disconnect from the IO port and use the internal GND as the calibration voltage.
+ *                     false: Use IO external voltage as calibration voltage.
+ */
+static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    /* Enable/disable internal connect GND (for calibration). */
+    if (internal_gnd) {
+        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1);
+    } else {
+        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
+    }
+}
+
+/**
+ * Resume register status after calibration.
+ *
+ * @param adc_n ADC index number.
+ */
+static inline void adc_ll_calibration_finish(adc_unit_t adc_n)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
+}
+
+/**
+ * Set the calibration result to ADC.
+ *
+ * @note  Different ADC units and different attenuation options use different calibration data (initial data).
+ *
+ * @param adc_n ADC index number.
+ */
+__attribute__((always_inline))
+static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    uint8_t msb = param >> 8;
+    uint8_t lsb = param & 0xFF;
+    REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb);
+    REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb);
+}
+
+/*---------------------------------------------------------------
+                    Oneshot Read
+---------------------------------------------------------------*/
+/**
+ * Set adc output data format for oneshot mode
+ *
+ * @note ESP32C6 Oneshot mode only supports 12bit.
+ * @param adc_n ADC unit.
+ * @param bits  Output data bits width option.
+ */
+static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits)
+{
+    //ESP32C6 only supports 12bit, leave here for compatibility
+    HAL_ASSERT(bits == ADC_BITWIDTH_12 || bits == ADC_BITWIDTH_DEFAULT);
+}
+
+/**
+ * Enable adc channel to start convert.
+ *
+ * @note Only one channel can be selected for measurement.
+ *
+ * @param adc_n   ADC unit.
+ * @param channel ADC channel number for each ADCn.
+ */
+static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | channel);
+}
+
+/**
+ * Disable adc channel to start convert.
+ *
+ * @note Only one channel can be selected in once measurement.
+ *
+ * @param adc_n ADC unit.
+ */
+static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | 0xF);
+}
+
+/**
+ * Start oneshot conversion by software
+ *
+ * @param val Usage: set to 1 to start the ADC conversion. The step signal should at least keep 3 ADC digital controller clock cycle,
+ *            otherwise the step signal may not be captured by the ADC digital controller when its frequency is slow.
+ *            This hardware limitation will be removed in future versions.
+ */
+static inline void adc_oneshot_ll_start(bool val)
+{
+    APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_start = val;
+}
+
+/**
+ * Clear the event for each ADCn for Oneshot mode
+ *
+ * @param event ADC event
+ */
+static inline void adc_oneshot_ll_clear_event(uint32_t event_mask)
+{
+    APB_SARADC.saradc_int_clr.val |= event_mask;
+}
+
+/**
+ * Check the event for each ADCn for Oneshot mode
+ *
+ * @param event ADC event
+ *
+ * @return
+ *      -true  : The conversion process is finish.
+ *      -false : The conversion process is not finish.
+ */
+static inline bool adc_oneshot_ll_get_event(uint32_t event_mask)
+{
+    return (APB_SARADC.saradc_int_raw.val & event_mask);
+}
+
+/**
+ * Get the converted value for each ADCn for controller.
+ *
+ * @param adc_n ADC unit.
+ * @return
+ *      - Converted value.
+ */
+static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    uint32_t ret_val = 0;
+    ret_val = APB_SARADC.saradc_sar1data_status.saradc_apb_saradc1_data & 0xfff;
+    return ret_val;
+}
+
+/**
+ * Analyze whether the obtained raw data is correct.
+ * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data.
+ *
+ * @param adc_n    ADC unit.
+ * @param raw_data ADC raw data input (convert value).
+ * @return
+ *        - 1: The data is correct to use.
+ *        - 0: The data is invalid.
+ */
+static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    return true;
+}
+
+/**
+ * ADC module RTC output data invert or not.
+ *
+ * @param adc_n ADC unit.
+ * @param inv_en data invert or not.
+ */
+static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    (void)inv_en;
+    //For compatibility
+}
+
+/**
+ * Enable oneshot conversion trigger
+ *
+ * @param adc_n  ADC unit
+ */
+static inline void adc_oneshot_ll_enable(adc_unit_t adc_n)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 1;
+}
+
+/**
+ * Disable oneshot conversion trigger for all the ADC units
+ */
+static inline void adc_oneshot_ll_disable_all_unit(void)
+{
+    APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 0;
+    APB_SARADC.saradc_onetime_sample.saradc_saradc2_onetime_sample = 0;
+}
+
+/**
+ * Set attenuation
+ *
+ * @note Attenuation is for all channels
+ *
+ * @param adc_n   ADC unit
+ * @param channel ADC channel
+ * @param atten   ADC attenuation
+ */
+static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    (void)channel;
+    // Attenuation is for all channels, unit and channel are for compatibility
+    APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_atten = atten;
+}
+
+/**
+ * Get the attenuation of a particular channel on ADCn.
+ *
+ * @param adc_n ADC unit.
+ * @param channel ADCn channel number.
+ * @return atten The attenuation option.
+ */
+__attribute__((always_inline))
+static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t channel)
+{
+    HAL_ASSERT(adc_n == ADC_UNIT_1);
+    (void)channel;
+    return (adc_atten_t)APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_atten;
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 13 - 31
components/hal/esp32h4/include/hal/adc_ll.h

@@ -16,6 +16,7 @@
 #include "soc/apb_saradc_reg.h"
 #include "soc/rtc_cntl_struct.h"
 #include "soc/rtc_cntl_reg.h"
+#include "soc/clk_tree_defs.h"
 #include "hal/misc.h"
 #include "hal/regi2c_ctrl.h"
 
@@ -35,9 +36,9 @@ extern "C" {
 #define ADC_LL_EVENT_ADC2_ONESHOT_DONE    BIT(30)
 
 typedef enum {
-    ADC_POWER_BY_FSM,   /*!< ADC XPD controled by FSM. Used for polling mode */
-    ADC_POWER_SW_ON,    /*!< ADC XPD controled by SW. power on. Used for DMA mode */
-    ADC_POWER_SW_OFF,   /*!< ADC XPD controled by SW. power off. */
+    ADC_POWER_BY_FSM,   /*!< ADC XPD controlled by FSM. Used for polling mode */
+    ADC_POWER_SW_ON,    /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
+    ADC_POWER_SW_OFF,   /*!< ADC XPD controlled by SW. power off. */
     ADC_POWER_MAX,      /*!< For parameter check. */
 } adc_ll_power_t;
 
@@ -57,11 +58,11 @@ typedef enum {
  * @brief ADC digital controller (DMA mode) work mode.
  *
  * @note  The conversion mode affects the sampling frequency:
- *        ESP32H4 only support ALTER_UNIT mode
- *        ALTER_UNIT   : When the measurement is triggered, ADC1 or ADC2 samples alternately.
+ *        ESP32H4 only support ONLY_ADC1 mode
+ *        SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once.
  */
 typedef enum {
-    ADC_LL_DIGI_CONV_ALTER_UNIT = 0,     // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 .....
+    ADC_LL_DIGI_CONV_ONLY_ADC1 = 0,     // Only use ADC1 for conversion
 } adc_ll_digi_convert_mode_t;
 
 //These values should be set according to the HW
@@ -130,7 +131,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
  */
 static inline void adc_ll_digi_set_clk_div(uint32_t div)
 {
-    /* ADC clock devided from digital controller clock clk */
+    /* ADC clock divided from digital controller clock clk */
     HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div);
 }
 
@@ -165,7 +166,7 @@ static inline void adc_ll_digi_convert_limit_enable(bool enable)
  */
 static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode)
 {
-    //ESP32H4 only supports ADC_CONV_ALTER_UNIT mode
+    //ESP32H4 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode
 }
 
 /**
@@ -289,15 +290,12 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
 /**
  * Enable clock and select clock source for ADC digital controller.
  *
- * @param use_apll true: use APLL clock; false: use APB clock.
+ * @param clk_src clock source for ADC digital controller.
  */
-static inline void adc_ll_digi_clk_sel(bool use_apll)
+static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
 {
-    if (use_apll) {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 1;   // APLL clock
-    } else {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 2;   // APB clock
-    }
+    // TODO: temporary support
+    APB_SARADC.apb_adc_clkm_conf.clk_sel = 0;
     APB_SARADC.ctrl.sar_clk_gated = 1;
 }
 
@@ -674,22 +672,6 @@ static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param
 }
 /* Temp code end. */
 
-/**
- *  Output ADCn inter reference voltage to ADC2 channels.
- *
- *  This function routes the internal reference voltage of ADCn to one of
- *  ADC1's channels. This reference voltage can then be manually measured
- *  for calibration purposes.
- *
- *  @param[in]  adc ADC unit select
- *  @param[in]  channel ADC1 channel number
- *  @param[in]  en Enable/disable the reference voltage output
- */
-static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, bool en)
-{
-    abort();
-}
-
 /*---------------------------------------------------------------
                     Single Read
 ---------------------------------------------------------------*/

+ 12 - 14
components/hal/esp32s2/include/hal/adc_ll.h

@@ -14,10 +14,12 @@
 #include "hal/assert.h"
 #include "soc/apb_saradc_struct.h"
 #include "soc/sens_struct.h"
+#include "soc/sens_reg.h"
 #include "soc/apb_saradc_reg.h"
 #include "soc/rtc_cntl_struct.h"
 #include "soc/rtc_cntl_reg.h"
 #include "soc/regi2c_defs.h"
+#include "soc/clk_tree_defs.h"
 #include "hal/regi2c_ctrl.h"
 #include "soc/regi2c_saradc.h"
 
@@ -35,9 +37,9 @@ extern "C" {
 #define ADC_LL_EVENT_ADC2_ONESHOT_DONE    (1 << 1)
 
 typedef enum {
-    ADC_POWER_BY_FSM,   /*!< ADC XPD controled by FSM. Used for polling mode */
-    ADC_POWER_SW_ON,    /*!< ADC XPD controled by SW. power on. Used for DMA mode */
-    ADC_POWER_SW_OFF,   /*!< ADC XPD controled by SW. power off. */
+    ADC_POWER_BY_FSM,   /*!< ADC XPD controlled by FSM. Used for polling mode */
+    ADC_POWER_SW_ON,    /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
+    ADC_POWER_SW_OFF,   /*!< ADC XPD controlled by SW. power off. */
     ADC_POWER_MAX,      /*!< For parameter check. */
 } adc_ll_power_t;
 
@@ -145,7 +147,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
  */
 static inline void adc_ll_digi_set_clk_div(uint32_t div)
 {
-    /* ADC clock devided from digital controller clock clk */
+    /* ADC clock divided from digital controller clock clk */
     HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div);
 }
 
@@ -335,15 +337,11 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
 /**
  * Enable clock and select clock source for ADC digital controller.
  *
- * @param use_apll true: use APLL clock; false: use APB clock.
+ * @param clk_src clock source for ADC digital controller.
  */
-static inline void adc_ll_digi_clk_sel(bool use_apll)
+static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
 {
-    if (use_apll) {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 1;   // APLL clock
-    } else {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 2;   // APB clock
-    }
+    APB_SARADC.apb_adc_clkm_conf.clk_sel = (clk_src == ADC_DIGI_CLK_SRC_APLL) ? 1 : 2;
     APB_SARADC.ctrl.sar_clk_gated = 1;
 }
 
@@ -568,7 +566,7 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
                     RTC controller setting
 ---------------------------------------------------------------*/
 /**
- * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`.
+ * ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`.
  *
  * @param div Division factor.
  */
@@ -798,7 +796,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
  *
  * When VDD_A is 3.3V:
  *
- * - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
+ * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
  * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
  * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
  * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
@@ -810,7 +808,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
  *
  * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges:
  *
- * - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV
+ * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV
  * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV
  * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV
  * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV

+ 10 - 13
components/hal/esp32s3/include/hal/adc_ll.h

@@ -19,6 +19,7 @@
 #include "soc/rtc_cntl_struct.h"
 #include "soc/rtc_cntl_reg.h"
 #include "soc/regi2c_defs.h"
+#include "soc/clk_tree_defs.h"
 #include "hal/regi2c_ctrl.h"
 #include "soc/regi2c_saradc.h"
 
@@ -36,9 +37,9 @@ extern "C" {
 #define ADC_LL_EVENT_ADC2_ONESHOT_DONE    (1 << 1)
 
 typedef enum {
-    ADC_POWER_BY_FSM,   /*!< ADC XPD controled by FSM. Used for polling mode */
-    ADC_POWER_SW_ON,    /*!< ADC XPD controled by SW. power on. Used for DMA mode */
-    ADC_POWER_SW_OFF,   /*!< ADC XPD controled by SW. power off. */
+    ADC_POWER_BY_FSM,   /*!< ADC XPD controlled by FSM. Used for polling mode */
+    ADC_POWER_SW_ON,    /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
+    ADC_POWER_SW_OFF,   /*!< ADC XPD controlled by SW. power off. */
     ADC_POWER_MAX,      /*!< For parameter check. */
 } adc_ll_power_t;
 
@@ -341,15 +342,11 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
 /**
  * Enable clock and select clock source for ADC digital controller.
  *
- * @param use_apll true: use APLL clock; false: use APB clock.
+ * @param clk_src clock source for ADC digital controller.
  */
-static inline void adc_ll_digi_clk_sel(bool use_apll)
+static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
 {
-    if (use_apll) {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 1;   // APLL clock
-    } else {
-        APB_SARADC.apb_adc_clkm_conf.clk_sel = 2;   // APB clock
-    }
+    APB_SARADC.apb_adc_clkm_conf.clk_sel = (clk_src == ADC_DIGI_CLK_SRC_APB) ? 2 : 1;
     APB_SARADC.ctrl.sar_clk_gated = 1;
 }
 
@@ -787,7 +784,7 @@ static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, boo
                     RTC controller setting
 ---------------------------------------------------------------*/
 /**
- * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`.
+ * ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`.
  *
  * @param div Division factor.
  */
@@ -1017,7 +1014,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
  *
  * When VDD_A is 3.3V:
  *
- * - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
+ * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
  * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
  * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
  * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
@@ -1029,7 +1026,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
  *
  * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges:
  *
- * - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV
+ * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV
  * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV
  * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV
  * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV

+ 0 - 14
components/hal/include/hal/adc_hal.h

@@ -116,20 +116,6 @@ typedef struct adc_hal_digi_ctrlr_cfg_t {
  */
 #define adc_hal_pwdet_get_cct() adc_ll_pwdet_get_cct()
 
-/**
- *  Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels.
- *
- *  This function routes the internal reference voltage of ADCn to one of
- *  ADC2's channels. This reference voltage can then be manually measured
- *  for calibration purposes.
- *
- *  @note  ESP32 only supports output of ADC2's internal reference voltage.
- *  @param[in]  adc ADC unit select
- *  @param[in]  channel ADC2 channel number
- *  @param[in]  en Enable/disable the reference voltage output
- */
-#define adc_hal_vref_output(adc, channel, en) adc_ll_vref_output(adc, channel, en)
-
 /*---------------------------------------------------------------
                     Digital controller setting
 ---------------------------------------------------------------*/

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

@@ -9,6 +9,7 @@
 #include <stdint.h>
 #include "sdkconfig.h"
 #include "soc/soc_caps.h"
+#include "soc/clk_tree_defs.h"
 #include "esp_attr.h"
 
 /**
@@ -78,6 +79,14 @@ typedef enum {
     ADC_DIGI_OUTPUT_FORMAT_TYPE2,   ///< See `adc_digi_output_data_t.type2`
 } adc_digi_output_format_t;
 
+#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
+typedef soc_periph_adc_digi_clk_src_t    adc_oneshot_clk_src_t;     ///< Clock source type of oneshot mode which uses digital controller
+typedef soc_periph_adc_digi_clk_src_t    adc_continuous_clk_src_t;  ///< Clock source type of continuous mode which uses digital controller
+#elif SOC_ADC_RTC_CTRL_SUPPORTED
+typedef soc_periph_adc_rtc_clk_src_t     adc_oneshot_clk_src_t;     ///< Clock source type of oneshot mode which uses RTC controller
+typedef soc_periph_adc_digi_clk_src_t    adc_continuous_clk_src_t;  ///< Clock source type of continuous mode which uses digital controller
+#endif
+
 /**
  * @brief ADC digital controller pattern configuration
  */
@@ -155,6 +164,26 @@ typedef struct {
         uint32_t val;                   /*!<Raw data value */
     };
 } adc_digi_output_data_t;
+
+#elif CONFIG_IDF_TARGET_ESP32C6
+/**
+ * @brief ADC digital controller (DMA mode) output data format.
+ *        Used to analyze the acquired ADC (DMA) data.
+ */
+typedef struct {
+    union {
+        struct {
+            uint32_t data:          12; /*!<ADC real output data info. Resolution: 12 bit. */
+            uint32_t reserved12:    1;  /*!<Reserved12. */
+            uint32_t channel:       4;  /*!<ADC channel index info.
+                                            If (channel < ADC_CHANNEL_MAX), The data is valid.
+                                            If (channel > ADC_CHANNEL_MAX), The data is invalid. */
+            uint32_t reserved17_31: 15; /*!<Reserved 17-31. */
+        } type2;                        /*!<When the configured output format is 12bit. */
+        uint32_t val;                   /*!<Raw data value */
+    };
+} adc_digi_output_data_t;
+
 #endif
 
 #if CONFIG_IDF_TARGET_ESP32S2

+ 2 - 8
components/hal/include/hal/adc_types_private.h

@@ -133,8 +133,6 @@ typedef enum {
 /**
  * @brief ADC digital controller (DMA mode) monitor configuration.
  *
- * @note  For ESP32-S2, The monitor object of the ADC is fixed.
- * @note  For ESP32-S2, The monitor object is always all enabled channels.
  */
 typedef struct {
     adc_unit_t adc_unit;            /*!<Set adc unit number for monitor.
@@ -142,12 +140,8 @@ typedef struct {
     adc_channel_t channel;          /*!<Set adc channel number for monitor.
                                         For ESP32-S2, it's always `ADC_CHANNEL_MAX` */
     adc_digi_monitor_mode_t mode;   /*!<Set adc monitor mode. See ``adc_digi_monitor_mode_t``. */
-#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
-    uint32_t h_threshold;             /*!<Set monitor threshold of adc digital controller. */
-    uint32_t l_threshold;             /*!<Set monitor threshold of adc digital controller. */
-#else
-    uint32_t threshold;             /*!<Set monitor threshold of adc digital controller. */
-#endif
+    uint32_t h_threshold;           /*!<Set monitor threshold of adc digital controller. */
+    uint32_t l_threshold;           /*!<Set monitor threshold of adc digital controller. */
 } adc_digi_monitor_t;
 #endif  //#if SOC_ADC_MONITOR_SUPPORTED
 

+ 31 - 0
components/soc/esp32/include/soc/clk_tree_defs.h

@@ -332,6 +332,37 @@ typedef enum {
     TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
 } soc_periph_twai_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_APLL, SOC_MOD_CLK_PLL_F160M}
+
+/**
+ * @brief ADC digital controller clock source
+ * @note  ADC DMA mode is clocked from I2S on ESP32, using `ADC_DIGI_` here for compatibility
+ *        Its clock source is same as I2S
+ */
+typedef enum {
+    ADC_DIGI_CLK_SRC_PLL_F160M = SOC_MOD_CLK_PLL_F160M, /*!< Select F160M as the source clock */
+    ADC_DIGI_CLK_SRC_APLL = SOC_MOD_CLK_APLL,           /*!< Select APLL as the source clock */
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M,   /*!< Select F160M as the default clock choice */
+} soc_periph_adc_digi_clk_src_t;
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC RTC controller
+ */
+#define SOC_ADC_RTC_CLKS {SOC_MOD_CLK_RC_FAST}
+
+/**
+ * @brief ADC RTC controller clock source
+ */
+typedef enum {
+    ADC_RTC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,      /*!< Select RC_FAST as the source clock */
+    ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST,      /*!< Select RC_FAST as the default clock choice */
+} soc_periph_adc_rtc_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

+ 19 - 3
components/soc/esp32c2/include/soc/clk_tree_defs.h

@@ -194,11 +194,27 @@ typedef enum {
  * @brief Type of I2C clock source.
  */
 typedef enum {
-    I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
-    I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
-    I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
+    I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,            /*!< Select XTAL as the source clock */
+    I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,      /*!< Select RC_FAST as the source clock */
+    I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,         /*!< Select XTAL as the default clock choice */
 } soc_periph_i2c_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M}
+
+/**
+ * @brief ADC digital controller clock source
+ */
+typedef enum {
+    ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,           /*!< Select XTAL as the source clock */
+    ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M,   /*!< Select PLL_F80M as the source clock */
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,    /*!< Select PLL_F80M as the default clock choice */
+} soc_periph_adc_digi_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

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

@@ -65,7 +65,7 @@
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #define SOC_ADC_DIGI_FILTER_NUM                 (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
-/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */
+/*!< 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
 

+ 15 - 0
components/soc/esp32c3/include/soc/clk_tree_defs.h

@@ -273,6 +273,21 @@ typedef enum {
     TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
 } soc_periph_twai_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_APB}
+
+/**
+ * @brief ADC digital controller clock source
+ */
+typedef enum {
+    ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB,     /*!< Select APB as the source clock */
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
+} soc_periph_adc_digi_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

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

@@ -93,7 +93,7 @@
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)
 #define SOC_ADC_DIGI_FILTER_NUM                 (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
-/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */
+/*!< 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
 

+ 0 - 5
components/soc/esp32c6/CMakeLists.txt

@@ -18,11 +18,6 @@ set(srcs
     "timer_periph.c"
     "twai_periph.c")
 
-# ESP32C6-TODO
-list(REMOVE_ITEM srcs
-        "adc_periph.c"                  # TODO: IDF-5310
-        )
-
 add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
 
 target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")

+ 7 - 5
components/soc/esp32c6/adc_periph.c

@@ -10,10 +10,12 @@
 const int adc_channel_io_map[SOC_ADC_PERIPH_NUM][SOC_ADC_MAX_CHANNEL_NUM] = {
     /* ADC1 */
     {
-        ADC1_CHANNEL_0_GPIO_NUM, ADC1_CHANNEL_1_GPIO_NUM, ADC1_CHANNEL_2_GPIO_NUM, ADC1_CHANNEL_3_GPIO_NUM, ADC1_CHANNEL_4_GPIO_NUM
+        ADC1_CHANNEL_0_GPIO_NUM,
+        ADC1_CHANNEL_1_GPIO_NUM,
+        ADC1_CHANNEL_2_GPIO_NUM,
+        ADC1_CHANNEL_3_GPIO_NUM,
+        ADC1_CHANNEL_4_GPIO_NUM,
+        ADC1_CHANNEL_5_GPIO_NUM,
+        ADC1_CHANNEL_6_GPIO_NUM,
     },
-    /* ADC2 */
-    {
-        ADC2_CHANNEL_0_GPIO_NUM, -1, -1, -1, -1
-    }
 };

+ 21 - 5
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -3,6 +3,10 @@
 # using gen_soc_caps_kconfig.py, do not edit manually
 #####################################################
 
+config SOC_ADC_SUPPORTED
+    bool
+    default y
+
 config SOC_DEDICATED_GPIO_SUPPORTED
     bool
     default y
@@ -127,25 +131,25 @@ config SOC_ADC_DIG_CTRL_SUPPORTED
     bool
     default y
 
-config SOC_ADC_ARBITER_SUPPORTED
+config SOC_ADC_FILTER_SUPPORTED
     bool
     default y
 
-config SOC_ADC_FILTER_SUPPORTED
+config SOC_ADC_MONITOR_SUPPORTED
     bool
     default y
 
-config SOC_ADC_MONITOR_SUPPORTED
+config SOC_ADC_DMA_SUPPORTED
     bool
     default y
 
 config SOC_ADC_PERIPH_NUM
     int
-    default 2
+    default 1
 
 config SOC_ADC_MAX_CHANNEL_NUM
     int
-    default 5
+    default 7
 
 config SOC_ADC_ATTEN_NUM
     int
@@ -163,6 +167,10 @@ config SOC_ADC_DIGI_MAX_BITWIDTH
     int
     default 12
 
+config SOC_ADC_DIGI_MIN_BITWIDTH
+    int
+    default 12
+
 config SOC_ADC_DIGI_FILTER_NUM
     int
     default 2
@@ -171,6 +179,14 @@ config SOC_ADC_DIGI_MONITOR_NUM
     int
     default 2
 
+config SOC_ADC_DIGI_RESULT_BYTES
+    int
+    default 4
+
+config SOC_ADC_DIGI_DATA_BYTES_PER_CONV
+    int
+    default 4
+
 config SOC_ADC_SAMPLE_FREQ_THRES_HIGH
     int
     default 83333

+ 5 - 2
components/soc/esp32c6/include/soc/adc_channel.h

@@ -21,5 +21,8 @@
 #define ADC1_GPIO4_CHANNEL     ADC1_CHANNEL_4
 #define ADC1_CHANNEL_4_GPIO_NUM 4
 
-#define ADC2_GPIO5_CHANNEL      ADC2_CHANNEL_0
-#define ADC2_CHANNEL_0_GPIO_NUM 5
+#define ADC1_GPIO5_CHANNEL     ADC1_CHANNEL_5
+#define ADC1_CHANNEL_5_GPIO_NUM 5
+
+#define ADC1_GPIO6_CHANNEL     ADC1_CHANNEL_6
+#define ADC1_CHANNEL_6_GPIO_NUM 6

+ 17 - 0
components/soc/esp32c6/include/soc/clk_tree_defs.h

@@ -316,6 +316,23 @@ typedef enum {
     TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
 } soc_periph_twai_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST}
+
+/**
+ * @brief ADC digital controller clock source
+ */
+typedef enum {
+    ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,           /*!< Select XTAL as the source clock */
+    ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M,   /*!< Select PLL_F80M as the source clock */
+    ADC_DIGI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,     /*!< Select RC_FAST as the source clock */
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,    /*!< Select PLL_F80M as the default clock choice */
+} soc_periph_adc_digi_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
components/soc/esp32c6/include/soc/pcr_struct.h

@@ -751,7 +751,7 @@ typedef union {
          */
         uint32_t saradc_clkm_div_num:8;
         /** saradc_clkm_sel : R/W; bitpos: [21:20]; default: 0;
-         *  set this field to select clock-source. 0(default): XTAL, 1: 240MHz, 2: FOSC, 3:
+         *  set this field to select clock-source. 0(default): XTAL, 1: 80MHz, 2: FOSC, 3:
          *  reserved.
          */
         uint32_t saradc_clkm_sel:2;

+ 11 - 8
components/soc/esp32c6/include/soc/soc_caps.h

@@ -25,7 +25,7 @@
 #pragma once
 
 /*-------------------------- COMMON CAPS ---------------------------------------*/
-// #define SOC_ADC_SUPPORTED               1 // TODO: IDF-5310
+#define SOC_ADC_SUPPORTED               1
 #define SOC_DEDICATED_GPIO_SUPPORTED    1
 #define SOC_GDMA_SUPPORTED              1
 #define SOC_PCNT_SUPPORTED              1
@@ -72,25 +72,28 @@
 #define SOC_AES_SUPPORT_AES_128 (1)
 #define SOC_AES_SUPPORT_AES_256 (1)
 
-// TODO: IDF-5310 (Copy from esp32c3, need check)
 /*-------------------------- ADC CAPS -------------------------------*/
 /*!< 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_MONITOR_SUPPORTED               1
-#define SOC_ADC_PERIPH_NUM                      (2)
-#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         ((PERIPH_NUM==0)? 5 : 1)
-#define SOC_ADC_MAX_CHANNEL_NUM                 (5)
+#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        1    //Digital controller supported ADC unit
+#define SOC_ADC_DMA_SUPPORTED                   1
+#define SOC_ADC_PERIPH_NUM                      (1U)
+#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         (7)
+#define SOC_ADC_MAX_CHANNEL_NUM                 (7)
 #define SOC_ADC_ATTEN_NUM                       (4)
 
 /*!< Digital */
 #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_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_MONITOR_NUM                (2)
-/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */
+#define SOC_ADC_DIGI_RESULT_BYTES               (4)
+#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)
+/*!< 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
 

+ 22 - 0
components/soc/esp32h2/include/soc/clk_tree_defs.h

@@ -338,6 +338,28 @@ typedef enum {
     TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
 } soc_periph_twai_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+// TODO: temporary support, need to check while supporting
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M}
+
+/**
+ * @brief ADC digital controller clock source
+ */
+// TODO: temporary support, need to check while supporting
+typedef enum {
+    ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,           /*!< Select XTAL as the source clock */
+    ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M,   /*!< Select PLL_F80M as the source clock */
+#if CONFIG_IDF_ENV_FPGA
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,        /*!< Select XTAL as the default clock choice */
+#else
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,    /*!< Select PLL_F80M as the default clock choice */
+#endif
+} soc_periph_adc_digi_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

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

@@ -86,7 +86,7 @@
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #define SOC_ADC_DIGI_FILTER_NUM                 (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
-/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */
+/*!< 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
 

+ 19 - 0
components/soc/esp32h4/include/soc/clk_tree_defs.h

@@ -112,6 +112,7 @@ typedef enum {
     // For digital domain: peripherals, WIFI, BLE
     SOC_MOD_CLK_AHB,                           /*< AHB_CLK sources from CPU with a configurable divider */
     SOC_MOD_CLK_APB,                           /*< APB_CLK source is derived from AHB clock */
+    SOC_MOD_CLK_PLL_F80M,                      /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */
     SOC_MOD_CLK_XTAL32K,                       /*< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
     SOC_MOD_CLK_RC_FAST,                       /*< RC_FAST_CLK comes from the internal 8MHz rc oscillator, passing a clock gating to the peripherals */
     SOC_MOD_CLK_XTAL,                          /*< XTAL_CLK comes from the external 32MHz crystal */
@@ -277,6 +278,24 @@ typedef enum {
     TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
 } soc_periph_twai_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+// TODO: temporary support, need to check while supporting
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M}
+
+/**
+ * @brief ADC digital controller clock source
+ */
+// TODO: temporary support, need to check while supporting
+typedef enum {
+    ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,           /*!< Select XTAL as the source clock */
+    ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M,   /*!< Select PLL_F80M as the source clock */
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,    /*!< Select PLL_F80M as the default clock choice */
+} soc_periph_adc_digi_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

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

@@ -95,7 +95,7 @@
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)
 #define SOC_ADC_DIGI_FILTER_NUM                 (2)
 #define SOC_ADC_DIGI_MONITOR_NUM                (2)
-/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */
+/*!< 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
 

+ 29 - 0
components/soc/esp32s2/include/soc/clk_tree_defs.h

@@ -320,6 +320,35 @@ typedef enum {
     TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
 } soc_periph_twai_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_APLL}
+
+/**
+ * @brief ADC digital controller clock source
+ */
+typedef enum {
+    ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB,         /*!< Select APB as the source clock */
+    ADC_DIGI_CLK_SRC_APLL = SOC_MOD_CLK_APLL,       /*!< Select APLL as the source clock */
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,     /*!< Select APB as the default clock choice */
+} soc_periph_adc_digi_clk_src_t;
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC RTC controller
+ */
+#define SOC_ADC_RTC_CLKS {SOC_MOD_CLK_RC_FAST}
+
+/**
+ * @brief ADC RTC controller clock source
+ */
+typedef enum {
+    ADC_RTC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,  /*!< Select RC_FAST as the source clock */
+    ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST,  /*!< Select RC_FAST as the default clock choice */
+} soc_periph_adc_rtc_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

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

@@ -101,7 +101,7 @@
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #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 <= interva <= 4095 */
+/*!< 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
 

+ 29 - 0
components/soc/esp32s3/include/soc/clk_tree_defs.h

@@ -318,6 +318,35 @@ typedef enum {
     TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
 } soc_periph_twai_clk_src_t;
 
+//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC digital controller
+ */
+#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_PLL_D2}
+
+/**
+ * @brief ADC digital controller clock source
+ */
+typedef enum {
+    ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB,             /*!< Select APB as the source clock */
+    ADC_DIGI_CLK_SRC_PLL_F240M = SOC_MOD_CLK_PLL_D2,    /*!< Select PLL_D2 (default value PLL_F240M) as the source clock */
+    ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,         /*!< Select APB as the default clock choice */
+} soc_periph_adc_digi_clk_src_t;
+
+/**
+ * @brief Array initializer for all supported clock sources of ADC RTC controller
+ */
+#define SOC_ADC_RTC_CLKS {SOC_MOD_CLK_RC_FAST}
+
+/**
+ * @brief ADC RTC controller clock source
+ */
+typedef enum {
+    ADC_RTC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,      /*!< Select RC_FAST as the source clock */
+    ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST,      /*!< Select RC_FAST as the default clock choice */
+} soc_periph_adc_rtc_clk_src_t;
+
 #ifdef __cplusplus
 }
 #endif

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

@@ -94,7 +94,7 @@
 #define SOC_ADC_DIGI_MAX_BITWIDTH               (12)
 #define SOC_ADC_DIGI_RESULT_BYTES               (4)
 #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV        (4)
-/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */
+/*!< 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
 

+ 0 - 16
components/soc/include/soc/adc_periph.h

@@ -8,23 +8,7 @@
 
 #include "soc/soc.h"
 #include "soc/soc_caps.h"
-#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310
-#include "soc/syscon_struct.h"
-#endif
-
-#if SOC_ADC_RTC_CTRL_SUPPORTED
-#include "soc/sens_reg.h"
-#include "soc/sens_struct.h"
-#endif
-
-#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
-#include "soc/rtc_io_struct.h"
-#endif
-#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310
-#include "soc/rtc_cntl_struct.h"
-#endif
 #include "soc/adc_channel.h"
-#include "soc/soc_caps.h"
 
 #ifdef __cplusplus
 extern "C" {

+ 0 - 2
docs/docs_not_updated/esp32c6.txt

@@ -91,8 +91,6 @@ api-reference/storage/sdmmc
 api-reference/storage/mass_mfg
 api-reference/storage/index
 api-reference/peripherals
-api-reference/peripherals/adc_continuous
-api-reference/peripherals/adc_oneshot
 api-reference/peripherals/usb_host
 api-reference/peripherals/hmac
 api-reference/peripherals/usb_device

+ 2 - 1
docs/en/api-reference/peripherals/adc_continuous.rst

@@ -1,13 +1,14 @@
 Analog to Digital Converter (ADC) Continuous Mode Driver
 ========================================================
 
+{IDF_TARGET_ADC_NUM:default="two", esp32c2="one", esp32c6="one", esp32h4="one"}
 
 Introduction
 ------------
 
 The Analog to Digital Converter is an on-chip sensor which is able to measure analog signals from specific analog IO pads.
 
-The ADC on {IDF_TARGET_NAME} can be used in scenario(s) like:
+{IDF_TARGET_NAME} has {IDF_TARGET_ADC_NUM} ADC unit(s), which can be used in scenario(s) like:
 
 - Generate one-shot ADC conversion result
 - Generate continuous ADC conversion results

+ 2 - 1
docs/en/api-reference/peripherals/adc_oneshot.rst

@@ -1,13 +1,14 @@
 Analog to Digital Converter (ADC) Oneshot Mode Driver
 =====================================================
 
+{IDF_TARGET_ADC_NUM:default="two", esp32c2="one", esp32c6="one", esp32h4="one"}
 
 Introduction
 ------------
 
 The Analog to Digital Converter is an on-chip sensor which is able to measure analog signals from dedicated analog IO pads.
 
-The ADC on {IDF_TARGET_NAME} can be used in scenario(s) like:
+{IDF_TARGET_NAME} has {IDF_TARGET_ADC_NUM} ADC unit(s), which can be used in scenario(s) like:
 
 - Generate one-shot ADC conversion result
 

+ 2 - 6
examples/peripherals/.build-test-rules.yml

@@ -2,15 +2,11 @@
 
 examples/peripherals/adc/continuous_read:
   disable:
-    - if: IDF_TARGET == "esp32c2" or IDF_TARGET == "esp32c6"
-      temporary: true
-      reason: adc dma mode isn't supported on these targets
+    - if: SOC_ADC_DMA_SUPPORTED != 1
 
 examples/peripherals/adc/oneshot_read:
   disable:
-    - if: IDF_TARGET == "esp32c6"
-      temporary: true
-      reason: target esp32c6 is not supported yet
+    - if: SOC_ADC_SUPPORTED != 1
 
 examples/peripherals/dac:
   disable:

+ 21 - 20
examples/peripherals/adc/continuous_read/README.md

@@ -1,5 +1,5 @@
-| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
-| ----------------- | ----- | -------- | -------- | -------- |
+| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- |
 
 # ADC DMA Example
 
@@ -39,24 +39,25 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
 
 Running this example, you will see the following log output on the serial monitor:
 ```
-I (338) ADC DMA: adc_pattern[0].atten is :0
-I (348) ADC DMA: adc_pattern[0].channel is :2
-I (348) ADC DMA: adc_pattern[0].unit is :0
-I (358) ADC DMA: adc_pattern[1].atten is :0
-I (358) ADC DMA: adc_pattern[1].channel is :3
-I (368) ADC DMA: adc_pattern[1].unit is :0
-I (368) ADC DMA: adc_pattern[2].atten is :0
-I (378) ADC DMA: adc_pattern[2].channel is :0
-I (378) ADC DMA: adc_pattern[2].unit is :1
-I (388) TASK: ret is 0, ret_num is 256
-I (388) ADC DMA: Unit: 1,_Channel: 2, Value: bec
-I (398) ADC DMA: Unit: 2,_Channel: 0, Value: 9cb
-I (398) ADC DMA: Unit: 1,_Channel: 3, Value: acb
-I (408) ADC DMA: Unit: 2,_Channel: 0, Value: 966
-I (408) ADC DMA: Unit: 1,_Channel: 2, Value: b63
-I (418) ADC DMA: Unit: 2,_Channel: 0, Value: 8ff
-I (418) ADC DMA: Unit: 1,_Channel: 3, Value: a6b
-I (428) ADC DMA: Unit: 2,_Channel: 0, Value: 8a2
+I (367) EXAMPLE: adc_pattern[0].atten is :0
+I (377) EXAMPLE: adc_pattern[0].channel is :2
+I (377) EXAMPLE: adc_pattern[0].unit is :0
+I (387) EXAMPLE: adc_pattern[1].atten is :0
+I (387) EXAMPLE: adc_pattern[1].channel is :3
+I (397) EXAMPLE: adc_pattern[1].unit is :0
+I (397) gpio: GPIO[3]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
+I (407) gpio: GPIO[4]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
+I (417) TASK: ret is 0, ret_num is 256
+I (427) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 819
+I (427) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 7b9
+I (437) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 7ab
+I (437) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 74b
+I (447) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 74d
+I (447) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 6e5
+I (457) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 6ee
+I (467) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 680
+I (467) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 69a
+I (477) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 62f
 ...
 ```
 

+ 30 - 37
examples/peripherals/adc/continuous_read/main/continuous_read_main.c

@@ -13,16 +13,25 @@
 #include "freertos/semphr.h"
 #include "esp_adc/adc_continuous.h"
 
-#define EXAMPLE_READ_LEN   256
-#define EXAMPLE_ADC_CONV_MODE           ADC_CONV_SINGLE_UNIT_1
+#define EXAMPLE_ADC_UNIT                    ADC_UNIT_1
+#define _EXAMPLE_ADC_UNIT_STR(unit)         #unit
+#define EXAMPLE_ADC_UNIT_STR(unit)          _EXAMPLE_ADC_UNIT_STR(unit)
+#define EXAMPLE_ADC_CONV_MODE               ADC_CONV_SINGLE_UNIT_1
+#define EXAMPLE_ADC_ATTEN                   ADC_ATTEN_DB_0
+#define EXAMPLE_ADC_BIT_WIDTH               SOC_ADC_DIGI_MAX_BITWIDTH
 
 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
-#define EXAMPLE_ADC_USE_OUTPUT_TYPE1    1
-#define EXAMPLE_ADC_OUTPUT_TYPE         ADC_DIGI_OUTPUT_FORMAT_TYPE1
+#define EXAMPLE_ADC_OUTPUT_TYPE             ADC_DIGI_OUTPUT_FORMAT_TYPE1
+#define EXAMPLE_ADC_GET_CHANNEL(p_data)     ((p_data)->type1.channel)
+#define EXAMPLE_ADC_GET_DATA(p_data)        ((p_data)->type1.data)
 #else
-#define EXAMPLE_ADC_OUTPUT_TYPE         ADC_DIGI_OUTPUT_FORMAT_TYPE2
+#define EXAMPLE_ADC_OUTPUT_TYPE             ADC_DIGI_OUTPUT_FORMAT_TYPE2
+#define EXAMPLE_ADC_GET_CHANNEL(p_data)     ((p_data)->type2.channel)
+#define EXAMPLE_ADC_GET_DATA(p_data)        ((p_data)->type2.data)
 #endif
 
+#define EXAMPLE_READ_LEN                    256
+
 #if CONFIG_IDF_TARGET_ESP32
 static adc_channel_t channel[2] = {ADC_CHANNEL_6, ADC_CHANNEL_7};
 #else
@@ -61,16 +70,14 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc
     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 = ADC_UNIT_1;
-        uint8_t ch = channel[i] & 0x7;
-        adc_pattern[i].atten = ADC_ATTEN_DB_0;
-        adc_pattern[i].channel = ch;
-        adc_pattern[i].unit = unit;
-        adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
-
-        ESP_LOGI(TAG, "adc_pattern[%d].atten is :%x", i, adc_pattern[i].atten);
-        ESP_LOGI(TAG, "adc_pattern[%d].channel is :%x", i, adc_pattern[i].channel);
-        ESP_LOGI(TAG, "adc_pattern[%d].unit is :%x", i, adc_pattern[i].unit);
+        adc_pattern[i].atten = EXAMPLE_ADC_ATTEN;
+        adc_pattern[i].channel = channel[i] & 0x7;
+        adc_pattern[i].unit = EXAMPLE_ADC_UNIT;
+        adc_pattern[i].bit_width = EXAMPLE_ADC_BIT_WIDTH;
+
+        ESP_LOGI(TAG, "adc_pattern[%d].atten is :%"PRIx8, i, adc_pattern[i].atten);
+        ESP_LOGI(TAG, "adc_pattern[%d].channel is :%"PRIx8, i, adc_pattern[i].channel);
+        ESP_LOGI(TAG, "adc_pattern[%d].unit is :%"PRIx8, i, adc_pattern[i].unit);
     }
     dig_cfg.adc_pattern = adc_pattern;
     ESP_ERROR_CHECK(adc_continuous_config(handle, &dig_cfg));
@@ -78,21 +85,6 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc
     *out_handle = handle;
 }
 
-static bool check_valid_data(const adc_digi_output_data_t *data)
-{
-#if EXAMPLE_ADC_USE_OUTPUT_TYPE1
-    if (data->type1.channel >= SOC_ADC_CHANNEL_NUM(ADC_UNIT_1)) {
-        return false;
-    }
-#else
-    if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(ADC_UNIT_1)) {
-        return false;
-    }
-#endif
-
-    return true;
-}
-
 void app_main(void)
 {
     esp_err_t ret;
@@ -123,20 +115,21 @@ void app_main(void)
          */
         ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 
+        char unit[] = EXAMPLE_ADC_UNIT_STR(EXAMPLE_ADC_UNIT);
+
         while (1) {
             ret = adc_continuous_read(handle, result, EXAMPLE_READ_LEN, &ret_num, 0);
             if (ret == ESP_OK) {
                 ESP_LOGI("TASK", "ret is %x, ret_num is %"PRIu32, ret, ret_num);
                 for (int i = 0; i < ret_num; i += SOC_ADC_DIGI_RESULT_BYTES) {
                     adc_digi_output_data_t *p = (void*)&result[i];
-                    if (check_valid_data(p)) {
-                #if EXAMPLE_ADC_USE_OUTPUT_TYPE1
-                        ESP_LOGI(TAG, "Unit: %d, Channel: %d, Value: %x", 1, p->type1.channel, p->type1.data);
-                #else
-                        ESP_LOGI(TAG, "Unit: %d,_Channel: %d, Value: %x", 1, p->type2.channel, p->type2.data);
-                #endif
+                    uint32_t chan_num = EXAMPLE_ADC_GET_CHANNEL(p);
+                    uint32_t data = EXAMPLE_ADC_GET_DATA(p);
+                    /* Check the channel number validation, the data is invalid if the channel num exceed the maximum channel */
+                    if (chan_num < SOC_ADC_CHANNEL_NUM(EXAMPLE_ADC_UNIT)) {
+                        ESP_LOGI(TAG, "Unit: %s, Channel: %"PRIu32", Value: %"PRIx32, unit, chan_num, data);
                     } else {
-                        ESP_LOGI(TAG, "Invalid data");
+                        ESP_LOGW(TAG, "Invalid data [%s_%"PRIu32"_%"PRIx32"]", unit, chan_num, data);
                     }
                 }
                 /**

+ 1 - 0
examples/peripherals/adc/continuous_read/pytest_adc_continuous.py

@@ -9,6 +9,7 @@ from pytest_embedded.dut import Dut
 @pytest.mark.esp32s2
 @pytest.mark.esp32s3
 @pytest.mark.esp32c3
+@pytest.mark.esp32c6
 @pytest.mark.adc
 def test_adc_continuous(dut: Dut) -> None:
     res = dut.expect(r'TASK: ret is 0, ret_num is (\d+)')

+ 2 - 2
examples/peripherals/adc/oneshot_read/README.md

@@ -1,5 +1,5 @@
-| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
-| ----------------- | ----- | -------- | -------- | -------- | -------- |
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
 
 # ADC Single Read Example
 

+ 1 - 0
examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py

@@ -9,6 +9,7 @@ from pytest_embedded.dut import Dut
 @pytest.mark.esp32s2
 @pytest.mark.esp32s3
 @pytest.mark.esp32c3
+@pytest.mark.esp32c6
 @pytest.mark.adc
 def test_adc_oneshot(dut: Dut) -> None:
     dut.expect(r'EXAMPLE: ADC1 Channel\[(\d+)\] Raw Data: (\d+)', timeout=5)