diff --git a/components/driver/Kconfig b/components/driver/Kconfig index aedad08772..94991dbc9e 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -19,6 +19,28 @@ 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. + + 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 b2312b1767..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; @@ -576,6 +582,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..555b03ba0c 100644 --- a/docs/en/api-reference/peripherals/adc.rst +++ b/docs/en/api-reference/peripherals/adc.rst @@ -58,8 +58,10 @@ 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. + - 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 774a1eaf06..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 @@ -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; @@ -88,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--) { @@ -110,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]); } }