From 9b4986dd2c704df89b44824f946d43c0fed5ea6b Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 16 Dec 2022 12:47:14 +0800 Subject: [PATCH 1/2] adc: no longer support adc2 continuous mode on esp32c3 Due to HW limitation, we don't support this anymore. On c3, ADC2 under continuous mode is not stable. However, you can enable CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 to force use ADC2. Refer to errata to know more details: https://www.espressif.com/sites/default/files/documentation/esp32-c3_errata_en.pdf --- components/driver/Kconfig | 11 +++++++++++ components/driver/esp32c3/adc.c | 15 +++++++++++++++ docs/en/api-reference/peripherals/adc.rst | 5 +++-- .../adc/esp32c3/adc/main/adc_dma_example_main.c | 9 ++++----- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/components/driver/Kconfig b/components/driver/Kconfig index aedad08772..cafb72f6c4 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -19,6 +19,17 @@ menu "Driver configurations" For testing, disable this option so that we can measure the output of DAC by internal ADC. + config ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 + depends on IDF_TARGET_ESP32C3 + bool "Force use ADC2 continumous mode on ESP32C3" + default n + help + On ESP32C3, ADC2 Digital Controller is not stable. Therefore, + ADC2 continuous 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 # ADC Configuration menu "SPI configuration" diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index b2312b1767..58fbbcc923 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -576,6 +576,21 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config) } ADC_CHECK(config->sample_freq_hz <= SOC_ADC_SAMPLE_FREQ_THRES_HIGH && config->sample_freq_hz >= SOC_ADC_SAMPLE_FREQ_THRES_LOW, "ADC sampling frequency out of range", ESP_ERR_INVALID_ARG); +#if !CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 + for (int i = 0; i < config->adc_pattern_len; i++) { + if (config->adc_pattern[i].unit == ADC_NUM_2) { + //we add this error log to hint users what happened + 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"); + /** + * 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_LOGE(ADC_TAG, "Only support using ADC1 DMA mode"); + return ESP_ERR_INVALID_ARG; + } + } +#endif //#if !CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 + s_adc_digi_ctx->digi_controller_config.conv_limit_en = config->conv_limit_en; s_adc_digi_ctx->digi_controller_config.conv_limit_num = config->conv_limit_num; s_adc_digi_ctx->digi_controller_config.adc_pattern_len = config->adc_pattern_len; diff --git a/docs/en/api-reference/peripherals/adc.rst b/docs/en/api-reference/peripherals/adc.rst index f9a5cf8d50..3ad59bc699 100644 --- a/docs/en/api-reference/peripherals/adc.rst +++ b/docs/en/api-reference/peripherals/adc.rst @@ -58,8 +58,9 @@ ADC Limitations .. only:: esp32c3 - A specific ADC module can only work under one operating mode at any one time, either Continuous Read Mode or Single Read Mode. - - ADC1 and ADC2 can not work under Singel Read Mode simultaneously. One of them will get blocked until another one finishes. - - For continuous (DMA) read mode, the ADC sampling frequency (the ``sample_freq_hz`` member of :cpp:type:`adc_digi_config_t`) should be within ``SOC_ADC_SAMPLE_FREQ_THRES_LOW`` and ``SOC_ADC_SAMPLE_FREQ_THRES_HIGH``. + - For continuous (DMA) read mode, the ADC sampling frequency (the ``sample_freq_hz`` member of :cpp:type:`adc_digi_config_t`) should be within ``SOC_ADC_SAMPLE_FREQ_THRES_LOW`` and ``SOC_ADC_SAMPLE_FREQ_THRES_HIGH`` + - ADC2 continuous (DMA) mode is no longer supported, due to hardware limitation. The results are not stable. This issue can be found in `ESP32C3 Errata `. For compatibility, you can enable :ref:`CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3` to force use ADC2. + Driver Usage ------------ diff --git a/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c b/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c index 774a1eaf06..75e8b342ba 100644 --- a/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c +++ b/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c @@ -8,7 +8,7 @@ #define TIMES 256 -static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num) +static void continuous_adc_init(uint16_t adc1_chan_mask, adc_channel_t *channel, uint8_t channel_num) { esp_err_t ret = ESP_OK; assert(ret == ESP_OK); @@ -17,7 +17,7 @@ static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask .max_store_buf_size = 1024, .conv_num_each_intr = 256, .adc1_chan_mask = adc1_chan_mask, - .adc2_chan_mask = adc2_chan_mask, + .adc2_chan_mask = 0, }; ret = adc_digi_initialize(&adc_dma_config); assert(ret == ESP_OK); @@ -61,10 +61,9 @@ static void continuous_read(void *arg) memset(result, 0xcc, TIMES); uint16_t adc1_chan_mask = BIT(0) | BIT(1); - uint16_t adc2_chan_mask = BIT(0); - adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1, (ADC2_CHANNEL_0 | 1 << 3)}; + adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1}; - continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t)); + continuous_adc_init(adc1_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t)); adc_digi_start(); int n = 20; From 984ee9dd38fe29e2beee38d3327d0b02b5fa797c Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 16 Dec 2022 12:53:04 +0800 Subject: [PATCH 2/2] adc: no longer support adc2 oneshot mode on esp32c3 Due to HW limitation, we don't support this anymore. On c3, ADC2 under oneshot mode is not stable. However, you can enable CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 to force use ADC2. Refer to errata to know more details: https://www.espressif.com/sites/default/files/documentation/esp32-c3_errata_en.pdf --- components/driver/Kconfig | 11 +++++++++++ components/driver/esp32c3/adc.c | 6 ++++++ docs/en/api-reference/peripherals/adc.rst | 1 + .../adc/esp32c3/adc/main/adc_dma_example_main.c | 10 +--------- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/components/driver/Kconfig b/components/driver/Kconfig index cafb72f6c4..94991dbc9e 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -30,6 +30,17 @@ menu "Driver configurations" 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 # ADC Configuration menu "SPI configuration" diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index 58fbbcc923..22a0457f29 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -536,6 +536,12 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out) { +#if !CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 + ESP_LOGE(ADC_TAG, "ADC2 is no longer supported, please use ADC1. Search for errata on espressif website for more details. You can enable ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 to force use ADC2"); + ESP_LOGE(ADC_TAG, "adc unit not supported"); + return ESP_ERR_INVALID_ARG; +#endif + //On ESP32C3, the data width is always 12-bits. if (width_bit != ADC_WIDTH_BIT_12) { return ESP_ERR_INVALID_ARG; diff --git a/docs/en/api-reference/peripherals/adc.rst b/docs/en/api-reference/peripherals/adc.rst index 3ad59bc699..555b03ba0c 100644 --- a/docs/en/api-reference/peripherals/adc.rst +++ b/docs/en/api-reference/peripherals/adc.rst @@ -60,6 +60,7 @@ ADC Limitations - A specific ADC module can only work under one operating mode at any one time, either Continuous Read Mode or Single Read Mode. - For continuous (DMA) read mode, the ADC sampling frequency (the ``sample_freq_hz`` member of :cpp:type:`adc_digi_config_t`) should be within ``SOC_ADC_SAMPLE_FREQ_THRES_LOW`` and ``SOC_ADC_SAMPLE_FREQ_THRES_HIGH`` - ADC2 continuous (DMA) mode is no longer supported, due to hardware limitation. The results are not stable. This issue can be found in `ESP32C3 Errata `. For compatibility, you can enable :ref:`CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3` to force use ADC2. + - ADC2 oneshot mode is no longer supported, due to hardware limitation. The results are not stable. This issue can be found in `ESP32C3 Errata `. For compatibility, you can enable :ref:`CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3` to force use ADC2. Driver Usage diff --git a/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c b/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c index 75e8b342ba..e56ce31506 100644 --- a/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c +++ b/examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c @@ -87,17 +87,13 @@ static void continuous_read(void *arg) static void single_read(void *arg) { - esp_err_t ret; int adc1_reading[3] = {0xcc}; - int adc2_reading[1] = {0xcc}; - - const char TAG_CH[][10] = {"ADC1_CH2", "ADC1_CH3","ADC1_CH4", "ADC2_CH0"}; + const char TAG_CH[][10] = {"ADC1_CH2", "ADC1_CH3","ADC1_CH4"}; adc1_config_width(ADC_WIDTH_BIT_DEFAULT); adc1_config_channel_atten(ADC1_CHANNEL_2, ADC_ATTEN_DB_0); adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6); adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); - adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0); int n = 20; while (n--) { @@ -109,10 +105,6 @@ static void single_read(void *arg) for (int i = 0; i < 3; i++) { ESP_LOGI(TAG_CH[i], "%x", adc1_reading[i]); } - - ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]); - assert(ret == ESP_OK); - ESP_LOGI(TAG_CH[3], "%x", adc2_reading[0]); } }