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;