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

Merge branch 'bugfix/no_more_public_adc2_dma_on_c3_s3' into 'master'

esp_adc: no longer support ADC2 continuous (DMA) mode on esp32c3 and esp32s3

Closes FCS-982 and IDFGH-8691

See merge request espressif/esp-idf!19656
Armando (Dou Yiwen) 3 лет назад
Родитель
Сommit
6569be485b

+ 5 - 2
components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c

@@ -66,6 +66,9 @@
 #define ADC1_TEST_CHAN0          ADC1_CHANNEL_2
 #endif
 
+//ESP32C3 ADC2 oneshot mode is not supported anymore
+#define ADC_TEST_ADC2    ((SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3)
+
 const __attribute__((unused)) static char *TAG = "TEST_ADC_LEGACY";
 
 
@@ -94,7 +97,7 @@ TEST_CASE("Legacy ADC oneshot high/low test", "[legacy_adc_oneshot]")
     //ADC1 config
     TEST_ESP_OK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT));
     TEST_ESP_OK(adc1_config_channel_atten(ADC1_TEST_CHAN0, ADC_ATTEN_DB_11));
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if ADC_TEST_ADC2
     //ADC2 config
     TEST_ESP_OK(adc2_config_channel_atten(ADC2_TEST_CHAN0, ADC_ATTEN_DB_11));
 #endif
@@ -109,7 +112,7 @@ TEST_CASE("Legacy ADC oneshot high/low test", "[legacy_adc_oneshot]")
     ESP_LOGI(TAG, "ADC%d Channel %d raw: %d\n", ADC_UNIT_1, ADC1_TEST_CHAN0, adc_raw);
     TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw);
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if ADC_TEST_ADC2
     test_adc_set_io_level(ADC_UNIT_2, (adc2_channel_t)ADC2_TEST_CHAN0, 0);
     TEST_ESP_OK(adc2_get_raw(ADC2_TEST_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc_raw));
     ESP_LOGI(TAG, "ADC%d Channel %d raw: %d\n", ADC_UNIT_2, ADC2_TEST_CHAN0, adc_raw);

+ 20 - 0
components/esp_adc/Kconfig

@@ -55,5 +55,25 @@ menu "ADC and ADC Calibration"
 
             Disable this option so as to measure the output of DAC by internal ADC, for test usage.
 
+    config ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3
+        depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
+        bool "Force use ADC2 continumous mode on ESP32S3 or ESP32C3"
+        default n
+        help
+            On ESP32C3 and ESP32S3, ADC2 Digital Controller is not stable. Therefore,
+            ADC2 continuous mode is not suggested on ESP32S3 and ESP32C3
+
+            If you stick to this, you can enable this option to force use ADC2 under above conditions.
+            For more details, you can search for errata on espressif website.
+
+    config ADC_ONESHOT_FORCE_USE_ADC2_ON_C3
+        depends on IDF_TARGET_ESP32C3
+        bool "Force use ADC2 oneshot mode on ESP32C3"
+        default n
+        help
+            On ESP32C3, ADC2 Digital Controller is not stable. Therefore,
+            ADC2 oneshot mode is not suggested on ESP32C3
 
+            If you stick to this, you can enable this option to force use ADC2 under above conditions.
+            For more details, you can search for errata on espressif website.
 endmenu

+ 16 - 5
components/esp_adc/adc_continuous.c

@@ -530,16 +530,27 @@ esp_err_t adc_continuous_config(adc_continuous_handle_t handle, const adc_contin
 
     //Pattern related check
     ESP_RETURN_ON_FALSE(config->pattern_num <= SOC_ADC_PATT_LEN_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "Max pattern num is %d", SOC_ADC_PATT_LEN_MAX);
-#if CONFIG_IDF_TARGET_ESP32
     for (int i = 0; i < config->pattern_num; i++) {
         ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width >= SOC_ADC_DIGI_MIN_BITWIDTH && config->adc_pattern->bit_width <= SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported");
-        ESP_RETURN_ON_FALSE(config->adc_pattern[i].unit == 0, ESP_ERR_INVALID_ARG, ADC_TAG, "Only support using ADC1 DMA mode");
     }
-#else
+
     for (int i = 0; i < config->pattern_num; i++) {
-        ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width == SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported");
+#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
+        //we add this error log to hint users what happened
+        if (SOC_ADC_DIG_SUPPORTED_UNIT(config->adc_pattern[i].unit) == 0) {
+            ESP_LOGE(ADC_TAG, "ADC2 continuous mode is no longer supported, please use ADC1. Search for errata on espressif website for more details. You can enable CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 to force use ADC2");
+        }
+#endif  //CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
+
+#if !CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3
+        /**
+         * On all continuous mode supported chips, we will always check the unit to see if it's a continuous mode supported unit.
+         * However, on ESP32C3 and ESP32S3, we will jump this check, if `CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3` is enabled.
+         */
+        ESP_RETURN_ON_FALSE(SOC_ADC_DIG_SUPPORTED_UNIT(config->adc_pattern[i].unit), ESP_ERR_INVALID_ARG, ADC_TAG, "Only support using ADC1 DMA mode");
+#endif  //#if !CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3
     }
-#endif
+
     ESP_RETURN_ON_FALSE(config->sample_freq_hz <= SOC_ADC_SAMPLE_FREQ_THRES_HIGH && config->sample_freq_hz >= SOC_ADC_SAMPLE_FREQ_THRES_LOW, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC sampling frequency out of range");
 
 #if CONFIG_IDF_TARGET_ESP32

+ 7 - 0
components/esp_adc/adc_oneshot.c

@@ -77,6 +77,13 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
     adc_oneshot_unit_ctx_t *unit = NULL;
     ESP_GOTO_ON_FALSE(init_config && ret_unit, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument: null pointer");
     ESP_GOTO_ON_FALSE(init_config->unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, err, TAG, "invalid unit");
+#if CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3
+    /**
+     * We only check this on ESP32C3, because other adc units are no longer supported on later chips
+     * If CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 is enabled, we jump this check
+     */
+    ESP_GOTO_ON_FALSE(SOC_ADC_DIG_SUPPORTED_UNIT(init_config->unit_id), ESP_ERR_INVALID_ARG, err, TAG, "adc unit not supported");
+#endif
 
     unit = heap_caps_calloc(1, sizeof(adc_oneshot_unit_ctx_t), ADC_MEM_ALLOC_CAPS);
     ESP_GOTO_ON_FALSE(unit, ESP_ERR_NO_MEM, err, TAG, "no mem for unit");

+ 16 - 12
components/esp_adc/test_apps/adc/main/test_adc.c

@@ -35,6 +35,9 @@ static const char *TAG_CH[2][10] = {{"ADC1_CH2", "ADC1_CH3"}, {"ADC2_CH0"}};
 /*---------------------------------------------------------------
         ADC Oneshot High / Low test
 ---------------------------------------------------------------*/
+//ESP32C3 ADC2 oneshot mode is not supported anymore
+#define ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2    ((SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3)
+
 TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
 {
     static int adc_raw[2][10];
@@ -47,7 +50,7 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
     };
     TEST_ESP_OK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
     //-------------ADC2 Init---------------//
     adc_oneshot_unit_handle_t adc2_handle;
     adc_oneshot_unit_init_cfg_t init_config2 = {
@@ -55,7 +58,7 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
         .ulp_mode = ADC_ULP_MODE_DISABLE,
     };
     TEST_ESP_OK(adc_oneshot_new_unit(&init_config2, &adc2_handle));
-#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
 
     //-------------ADC1 TEST Channel 0 Config---------------//
     adc_oneshot_chan_cfg_t config = {
@@ -67,10 +70,10 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
     //-------------ADC1 TEST Channel 1 Config---------------//
     TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, ADC1_TEST_CHAN1, &config));
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
     //-------------ADC2 TEST Channel 0 Config---------------//
     TEST_ESP_OK(adc_oneshot_config_channel(adc2_handle, ADC2_TEST_CHAN0, &config));
-#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
 
     test_adc_set_io_level(ADC_UNIT_1, ADC1_TEST_CHAN0, 0);
     TEST_ESP_OK(adc_oneshot_read(adc1_handle, ADC1_TEST_CHAN0, &adc_raw[0][0]));
@@ -82,12 +85,12 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
     ESP_LOGI(TAG_CH[0][1], "raw  data: %d", adc_raw[0][1]);
     TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw[0][1]);
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
     test_adc_set_io_level(ADC_UNIT_2, ADC2_TEST_CHAN0, 0);
     TEST_ESP_OK(adc_oneshot_read(adc2_handle, ADC2_TEST_CHAN0, &adc_raw[1][0]));
     ESP_LOGI(TAG_CH[1][0], "raw  data: %d", adc_raw[1][0]);
     TEST_ASSERT_INT_WITHIN(ADC_TEST_LOW_THRESH, ADC_TEST_LOW_VAL, adc_raw[1][0]);
-#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
 
 
     test_adc_set_io_level(ADC_UNIT_1, ADC1_TEST_CHAN0, 1);
@@ -100,18 +103,18 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
     ESP_LOGI(TAG_CH[0][1], "raw  data: %d", adc_raw[0][1]);
     TEST_ASSERT_INT_WITHIN(ADC_TEST_LOW_THRESH, ADC_TEST_LOW_VAL, adc_raw[0][1]);
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
     test_adc_set_io_level(ADC_UNIT_2, ADC2_TEST_CHAN0, 1);
     TEST_ESP_OK(adc_oneshot_read(adc2_handle, ADC2_TEST_CHAN0, &adc_raw[1][0]));
     ESP_LOGI(TAG_CH[1][0], "raw  data: %d", adc_raw[1][0]);
     TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw[1][0]);
-#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
 
 
     TEST_ESP_OK(adc_oneshot_del_unit(adc1_handle));
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
     TEST_ESP_OK(adc_oneshot_del_unit(adc2_handle));
-#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
 }
 
 
@@ -251,11 +254,12 @@ TEST_CASE("test ADC1 Single Read with Light Sleep", "[adc][manul][ignore]")
     s_adc_oneshot_with_sleep(ADC_UNIT_1, ADC1_SLEEP_TEST_CHAN);
 }
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
+//ESP32C3 ADC2 oneshot mode is not supported anymore
 TEST_CASE("test ADC2 Single Read with Light Sleep", "[adc][manul][ignore]")
 {
     s_adc_oneshot_with_sleep(ADC_UNIT_2, ADC2_SLEEP_TEST_CHAN);
 }
-#endif  //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif  //#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
 
 #endif  //#if SOC_ADC_CALIBRATION_V1_SUPPORTED

+ 4 - 1
components/esp_adc/test_apps/adc/main/test_adc2_wifi.c

@@ -18,7 +18,10 @@
 #include "test_common_adc.h"
 #include "test_utils.h"
 
-#if (SOC_ADC_PERIPH_NUM > 1)
+/**
+ * On ESP32C3, ADC2 is no longer supported, due to its HW limitation.
+ */
+#if (SOC_ADC_PERIPH_NUM > 1) && !CONFIG_IDF_TARGET_ESP32C3
 
 static const char* TAG = "test_adc2";
 

+ 3 - 2
components/esp_adc/test_apps/adc/main/test_adc_performance.c

@@ -282,11 +282,12 @@ TEST_CASE("ADC1 Calibration Speed", "[adc][ignore][manual]")
     s_adc_cali_speed(ADC_UNIT_1, ADC1_CALI_SPEED_TEST_CHAN0);
 }
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
+//ESP32C3 ADC2 oneshot mode is not supported anymore
 TEST_CASE("ADC2 Calibration Speed", "[adc][ignore][manual]")
 {
     s_adc_cali_speed(ADC_UNIT_2, ADC2_CALI_SPEED_TEST_CHAN0);
 }
-#endif  //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif  //#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
 
 #endif  //#if CONFIG_IDF_TARGET_ESP32 ||  SOC_ADC_CALIBRATION_V1_SUPPORTED

+ 1 - 0
components/soc/esp32/include/soc/soc_caps.h

@@ -107,6 +107,7 @@
 #define SOC_ADC_RTC_CTRL_SUPPORTED              1
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
 #define SOC_ADC_DMA_SUPPORTED                   1
+#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        ((UNIT == 0) ? 1 : 0)
 #define SOC_ADC_PERIPH_NUM                      (2)
 #define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         ((PERIPH_NUM==0)? 8: 10)
 #define SOC_ADC_MAX_CHANNEL_NUM                 (10)

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

@@ -52,6 +52,7 @@
 #define SOC_ADC_DIG_CTRL_SUPPORTED              1
 #define SOC_ADC_FILTER_SUPPORTED                1
 #define SOC_ADC_MONITOR_SUPPORTED               1
+#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        1    //Digital controller supported ADC unit
 #define SOC_ADC_PERIPH_NUM                      (1U)
 #define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         (5)
 #define SOC_ADC_MAX_CHANNEL_NUM                 (5)

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

@@ -78,6 +78,7 @@
 #define SOC_ADC_FILTER_SUPPORTED                1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
+#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        ((UNIT == 0) ? 1 : 0)    //Digital controller supported ADC unit
 #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)

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

@@ -79,6 +79,7 @@
 #define SOC_ADC_FILTER_SUPPORTED                1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
+#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        ((UNIT == 0) ? 1 : 0)    //Digital controller supported ADC unit
 #define SOC_ADC_PERIPH_NUM                      (1U)
 #define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         (5)
 #define SOC_ADC_MAX_CHANNEL_NUM                 (5)

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

@@ -88,8 +88,9 @@
 #define SOC_ADC_FILTER_SUPPORTED                1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
+#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        1    //Digital controller supported ADC unit
 #define SOC_ADC_PERIPH_NUM                      (2)
-#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         (10)
+#define SOC_ADC_CHANNEL_NUM(UNIT)               (10)
 #define SOC_ADC_MAX_CHANNEL_NUM                 (10)
 #define SOC_ADC_ATTEN_NUM                       (4)
 

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

@@ -81,6 +81,7 @@
 #define SOC_ADC_FILTER_SUPPORTED                1
 #define SOC_ADC_MONITOR_SUPPORTED               1
 #define SOC_ADC_DMA_SUPPORTED                   1
+#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT)        ((UNIT == 0) ? 1 : 0)    //Digital controller supported ADC unit
 #define SOC_ADC_PERIPH_NUM                      (2)
 #define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         (10)
 #define SOC_ADC_MAX_CHANNEL_NUM                 (10)

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

@@ -209,7 +209,7 @@ Hardware Limitations
 
 - Random Number Generator uses ADC as an input source. When ADC continuous mode driver works, the random number generated from RNG will be less random.
 
-.. only:: esp32 or esp32s2 or esp32c3 or esp32s3
+.. only:: esp32 or esp32s2
 
     - ADC2 is also used by the Wi-Fi. :cpp:func:`adc_continuous_start` has provided the protection between Wi-Fi driver and ADC continuous mode driver.
 
@@ -225,6 +225,14 @@ Hardware Limitations
 
     - ADC continuous mode driver uses SPI3 peripheral as hardware DMA fifo. Therefore, if SPI3 is in use already, the :cpp:func:`adc_continuous_new_handle` will return :c:macro:`ESP_ERR_NOT_FOUND`.
 
+.. only:: esp32c3
+
+    - ADC2 continuous mode is no longer supported, due to hardware limitation. The results are not stable. This issue can be found in `ESP32C3 Errata <https://www.espressif.com/sites/default/files/documentation/esp32-c3_errata_en.pdf>`. For compatibility, you can enable :ref:`CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3` to force use ADC2.
+
+.. only:: esp32s3
+
+    - ADC2 continuous mode is no longer supported, due to hardware limitation. The results are not stable. This issue can be found in `ESP32S3 Errata <https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf>`. For compatibility, you can enable :ref:`CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3` to force use ADC2.
+
 
 Power Management
 ^^^^^^^^^^^^^^^^
@@ -255,4 +263,4 @@ Application Examples
 API Reference
 -------------
 
-.. include-build-file:: inc/adc_continuous.inc
+.. include-build-file:: inc/adc_continuous.inc

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

@@ -154,10 +154,14 @@ Hardware Limitations
 
     - A specific ADC unit can only work under one operating mode at any one time, either continuous mode or oneshot mode. :cpp:func:`adc_oneshot_read` has provided the protection.
 
-.. only:: esp32 or esp32s2 or esp32c3 or esp32s3
+.. only:: esp32 or esp32s2 or esp32s3
 
     - ADC2 is also used by the Wi-Fi. :cpp:func:`adc_oneshot_read` has provided the protection between Wi-Fi driver and ADC oneshot mode driver.
 
+.. only:: esp32c3
+
+    - ADC2 oneshot mode is no longer supported, due to hardware limitation. The results are not stable. This issue can be found in `ESP32C3 Errata <https://www.espressif.com/sites/default/files/documentation/esp32-c3_errata_en.pdf>`. For compatibility, you can enable :ref:`CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3` to force use ADC2.
+
 .. only:: esp32
 
     - ESP32 DevKitC: GPIO 0 cannot be used due to external auto program circuits.

+ 28 - 44
examples/peripherals/adc/continuous_read/main/continuous_read_main.c

@@ -14,30 +14,19 @@
 #include "esp_adc/adc_continuous.h"
 
 #define EXAMPLE_READ_LEN   256
-#define GET_UNIT(x)        ((x>>3) & 0x1)
+#define EXAMPLE_ADC_CONV_MODE           ADC_CONV_SINGLE_UNIT_1
 
-#if CONFIG_IDF_TARGET_ESP32
-#define ADC_CONV_MODE       ADC_CONV_SINGLE_UNIT_1  //ESP32 only supports ADC1 DMA mode
-#define ADC_OUTPUT_TYPE     ADC_DIGI_OUTPUT_FORMAT_TYPE1
-#elif CONFIG_IDF_TARGET_ESP32S2
-#define ADC_CONV_MODE       ADC_CONV_BOTH_UNIT
-#define ADC_OUTPUT_TYPE     ADC_DIGI_OUTPUT_FORMAT_TYPE2
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
-#define ADC_CONV_MODE       ADC_CONV_ALTER_UNIT     //ESP32C3 only supports alter mode
-#define ADC_OUTPUT_TYPE     ADC_DIGI_OUTPUT_FORMAT_TYPE2
-#elif CONFIG_IDF_TARGET_ESP32S3
-#define ADC_CONV_MODE       ADC_CONV_BOTH_UNIT
-#define ADC_OUTPUT_TYPE     ADC_DIGI_OUTPUT_FORMAT_TYPE2
+#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
+#else
+#define EXAMPLE_ADC_OUTPUT_TYPE         ADC_DIGI_OUTPUT_FORMAT_TYPE2
 #endif
 
-#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
-static adc_channel_t channel[3] = {ADC_CHANNEL_2, ADC_CHANNEL_3, (ADC_CHANNEL_0 | 1 << 3)};
-#endif
-#if CONFIG_IDF_TARGET_ESP32S2
-static adc_channel_t channel[3] = {ADC_CHANNEL_2, ADC_CHANNEL_3, (ADC_CHANNEL_0 | 1 << 3)};
-#endif
 #if CONFIG_IDF_TARGET_ESP32
-static adc_channel_t channel[1] = {ADC_CHANNEL_7};
+static adc_channel_t channel[2] = {ADC_CHANNEL_6, ADC_CHANNEL_7};
+#else
+static adc_channel_t channel[2] = {ADC_CHANNEL_2, ADC_CHANNEL_3};
 #endif
 
 static TaskHandle_t s_task_handle;
@@ -65,14 +54,14 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc
 
     adc_continuous_config_t dig_cfg = {
         .sample_freq_hz = 20 * 1000,
-        .conv_mode = ADC_CONV_MODE,
-        .format = ADC_OUTPUT_TYPE,
+        .conv_mode = EXAMPLE_ADC_CONV_MODE,
+        .format = EXAMPLE_ADC_OUTPUT_TYPE,
     };
 
     adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
     dig_cfg.pattern_num = channel_num;
     for (int i = 0; i < channel_num; i++) {
-        uint8_t unit = GET_UNIT(channel[i]);
+        uint8_t unit = ADC_UNIT_1;
         uint8_t ch = channel[i] & 0x7;
         adc_pattern[i].atten = ADC_ATTEN_DB_0;
         adc_pattern[i].channel = ch;
@@ -89,16 +78,20 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc
     *out_handle = handle;
 }
 
-#if !CONFIG_IDF_TARGET_ESP32
 static bool check_valid_data(const adc_digi_output_data_t *data)
 {
-    const unsigned int unit = data->type2.unit;
-    if (unit > 2) return false;
-    if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) return false;
+#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;
 }
-#endif
 
 void app_main(void)
 {
@@ -136,24 +129,15 @@ void app_main(void)
                 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 CONFIG_IDF_TARGET_ESP32
-                    ESP_LOGI(TAG, "Unit: %d, Channel: %d, Value: %x", 1, p->type1.channel, p->type1.data);
-        #else
-                    if (ADC_CONV_MODE == ADC_CONV_BOTH_UNIT || ADC_CONV_MODE == ADC_CONV_ALTER_UNIT) {
-                        if (check_valid_data(p)) {
-                            ESP_LOGI(TAG, "Unit: %d,_Channel: %d, Value: %x", p->type2.unit+1, p->type2.channel, p->type2.data);
-                        } else {
-                            ESP_LOGI(TAG, "Invalid data [%d_%d_%x]", p->type2.unit+1, p->type2.channel, p->type2.data);
-                        }
-                    }
-        #if CONFIG_IDF_TARGET_ESP32S2
-                    else if (ADC_CONV_MODE == ADC_CONV_SINGLE_UNIT_2) {
-                        ESP_LOGI(TAG, "Unit: %d, Channel: %d, Value: %x", 2, p->type1.channel, p->type1.data);
-                    } else if (ADC_CONV_MODE == ADC_CONV_SINGLE_UNIT_1) {
+                    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
+                    } else {
+                        ESP_LOGI(TAG, "Invalid data");
                     }
-        #endif  //#if CONFIG_IDF_TARGET_ESP32S2
-        #endif
                 }
                 /**
                  * Because printing is slow, so every time you call `ulTaskNotifyTake`, it will immediately return.

+ 16 - 8
examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c

@@ -28,14 +28,22 @@ const static char *TAG = "EXAMPLE";
 #define EXAMPLE_ADC1_CHAN1          ADC_CHANNEL_3
 #endif
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
+/**
+ * On ESP32C3, ADC2 is no longer supported, due to its HW limitation.
+ * Search for errata on espressif website for more details.
+ */
+#define EXAMPLE_USE_ADC2            1
+#endif
+
+#if EXAMPLE_USE_ADC2
 //ADC2 Channels
 #if CONFIG_IDF_TARGET_ESP32
 #define EXAMPLE_ADC2_CHAN0          ADC_CHANNEL_0
 #else
 #define EXAMPLE_ADC2_CHAN0          ADC_CHANNEL_0
 #endif
-#endif
+#endif  //#if EXAMPLE_USE_ADC2
 
 #define EXAMPLE_ADC_ATTEN           ADC_ATTEN_DB_11
 
@@ -67,7 +75,7 @@ void app_main(void)
     bool do_calibration1 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC_ATTEN, &adc1_cali_handle);
 
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if EXAMPLE_USE_ADC2
     //-------------ADC2 Init---------------//
     adc_oneshot_unit_handle_t adc2_handle;
     adc_oneshot_unit_init_cfg_t init_config2 = {
@@ -82,7 +90,7 @@ void app_main(void)
 
     //-------------ADC2 Config---------------//
     ESP_ERROR_CHECK(adc_oneshot_config_channel(adc2_handle, EXAMPLE_ADC2_CHAN0, &config));
-#endif  //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif  //#if EXAMPLE_USE_ADC2
 
     while (1) {
         ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0]));
@@ -101,7 +109,7 @@ void app_main(void)
         }
         vTaskDelay(pdMS_TO_TICKS(1000));
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if EXAMPLE_USE_ADC2
         ESP_ERROR_CHECK(adc_oneshot_read(adc2_handle, EXAMPLE_ADC2_CHAN0, &adc_raw[1][0]));
         ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_2 + 1, EXAMPLE_ADC2_CHAN0, adc_raw[1][0]);
         if (do_calibration2) {
@@ -109,7 +117,7 @@ void app_main(void)
             ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_2 + 1, EXAMPLE_ADC2_CHAN0, voltage[1][0]);
         }
         vTaskDelay(pdMS_TO_TICKS(1000));
-#endif  //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif  //#if EXAMPLE_USE_ADC2
     }
 
     //Tear Down
@@ -118,12 +126,12 @@ void app_main(void)
         example_adc_calibration_deinit(adc1_cali_handle);
     }
 
-#if (SOC_ADC_PERIPH_NUM >= 2)
+#if EXAMPLE_USE_ADC2
     ESP_ERROR_CHECK(adc_oneshot_del_unit(adc2_handle));
     if (do_calibration2) {
         example_adc_calibration_deinit(adc2_cali_handle);
     }
-#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
+#endif //#if EXAMPLE_USE_ADC2
 }