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
This commit is contained in:
Armando
2022-12-16 12:02:55 +08:00
parent ffb2db586a
commit eab3534c90
5 changed files with 47 additions and 9 deletions

View File

@ -30,6 +30,17 @@ menu "Driver configurations"
If you stick to this, you can enable this option to force use ADC2 under above conditions. 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. 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 endmenu # ADC Configuration
menu "MCPWM configuration" menu "MCPWM configuration"

View File

@ -744,6 +744,11 @@ 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) 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_RETURN_ON_FALSE(SOC_ADC_DIG_SUPPORTED_UNIT(ADC_UNIT_2), ESP_ERR_INVALID_ARG, ADC_TAG, "adc unit not supported");
#endif
//On ESP32C3, the data width is always 12-bits. //On ESP32C3, the data width is always 12-bits.
if (width_bit != ADC_WIDTH_BIT_12) { if (width_bit != ADC_WIDTH_BIT_12) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;

View File

@ -290,6 +290,9 @@ TEST_CASE("test_adc_single", "[adc][ignore][manual]")
/******************************************************************************** /********************************************************************************
* ADC Speed Related Tests * ADC Speed Related Tests
********************************************************************************/ ********************************************************************************/
//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)
#ifdef CONFIG_IDF_TARGET_ESP32 #ifdef CONFIG_IDF_TARGET_ESP32
#define CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ #define CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
@ -374,26 +377,34 @@ TEST_CASE("test_adc_single_cali_time", "[adc][ignore][manual]")
{ {
ESP_LOGI(TAG, "CPU FREQ is %dMHz", CPU_FREQ_MHZ); ESP_LOGI(TAG, "CPU FREQ is %dMHz", CPU_FREQ_MHZ);
uint32_t adc1_time_record[4][TIMES_PER_ATTEN] = {}; uint32_t adc1_time_record[4][TIMES_PER_ATTEN] = {};
uint32_t adc2_time_record[4][TIMES_PER_ATTEN] = {};
int adc1_raw = 0; int adc1_raw = 0;
int adc2_raw = 0;
//atten0 ~ atten3 //atten0 ~ atten3
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
ESP_LOGI(TAG, "----------------atten%d----------------", i); ESP_LOGI(TAG, "----------------atten%d----------------", i);
adc_single_cali_init(ADC_UNIT_1, ADC1_CALI_TEST_CHAN0, i); adc_single_cali_init(ADC_UNIT_1, ADC1_CALI_TEST_CHAN0, i);
for (int j = 0; j < TIMES_PER_ATTEN; j++) {
adc1_raw = adc1_get_raw(ADC1_CALI_TEST_CHAN0);
adc1_time_record[i][j] = get_cali_time_in_ccount(adc1_raw, &adc1_chars);
IDF_LOG_PERFORMANCE("ADC1 Cali time", "%d us", (int)GET_US_BY_CCOUNT(adc1_time_record[i][j]));
}
}
#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
int adc2_raw = 0;
uint32_t adc2_time_record[4][TIMES_PER_ATTEN] = {};
//atten0 ~ atten3
for (int i = 0; i < 4; i++) {
ESP_LOGI(TAG, "----------------atten%d----------------", i);
adc_single_cali_init(ADC_UNIT_2, ADC2_CALI_TEST_CHAN0, i); adc_single_cali_init(ADC_UNIT_2, ADC2_CALI_TEST_CHAN0, i);
for (int j = 0; j < TIMES_PER_ATTEN; j++) { for (int j = 0; j < TIMES_PER_ATTEN; j++) {
adc1_raw = adc1_get_raw(ADC1_CALI_TEST_CHAN0);
TEST_ESP_OK(adc2_get_raw(ADC2_CALI_TEST_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc2_raw)); TEST_ESP_OK(adc2_get_raw(ADC2_CALI_TEST_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc2_raw));
adc1_time_record[i][j] = get_cali_time_in_ccount(adc1_raw, &adc1_chars);
adc2_time_record[i][j] = get_cali_time_in_ccount(adc2_raw, &adc2_chars); adc2_time_record[i][j] = get_cali_time_in_ccount(adc2_raw, &adc2_chars);
IDF_LOG_PERFORMANCE("ADC1 Cali time", "%d us", (int)GET_US_BY_CCOUNT(adc1_time_record[i][j]));
IDF_LOG_PERFORMANCE("ADC2 Cali time", "%d us", (int)GET_US_BY_CCOUNT(adc2_time_record[i][j])); IDF_LOG_PERFORMANCE("ADC2 Cali time", "%d us", (int)GET_US_BY_CCOUNT(adc2_time_record[i][j]));
} }
} }
#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
} }

View File

@ -130,6 +130,8 @@ ADC Limitations
.. only:: esp32c3 .. 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.
- 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 <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. - 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 <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 .. only:: esp32s3

View File

@ -51,7 +51,10 @@ static int adc_raw[2][10];
static const char *TAG = "ADC SINGLE"; static const char *TAG = "ADC SINGLE";
static esp_adc_cal_characteristics_t adc1_chars; static esp_adc_cal_characteristics_t adc1_chars;
#if !CONFIG_IDF_TARGET_ESP32C3
//ESP32C3 ADC2 single mode is no longer supported
static esp_adc_cal_characteristics_t adc2_chars; static esp_adc_cal_characteristics_t adc2_chars;
#endif
static bool adc_calibration_init(void) static bool adc_calibration_init(void)
{ {
@ -66,7 +69,9 @@ static bool adc_calibration_init(void)
} else if (ret == ESP_OK) { } else if (ret == ESP_OK) {
cali_enable = true; cali_enable = true;
esp_adc_cal_characterize(ADC_UNIT_1, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars); esp_adc_cal_characterize(ADC_UNIT_1, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars);
#if !CONFIG_IDF_TARGET_ESP32C3
esp_adc_cal_characterize(ADC_UNIT_2, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc2_chars); esp_adc_cal_characterize(ADC_UNIT_2, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc2_chars);
#endif
} else { } else {
ESP_LOGE(TAG, "Invalid arg"); ESP_LOGE(TAG, "Invalid arg");
} }
@ -76,15 +81,16 @@ static bool adc_calibration_init(void)
void app_main(void) void app_main(void)
{ {
esp_err_t ret = ESP_OK;
uint32_t voltage = 0; uint32_t voltage = 0;
bool cali_enable = adc_calibration_init(); bool cali_enable = adc_calibration_init();
//ADC1 config //ADC1 config
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT)); ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT));
ESP_ERROR_CHECK(adc1_config_channel_atten(ADC1_EXAMPLE_CHAN0, ADC_EXAMPLE_ATTEN)); ESP_ERROR_CHECK(adc1_config_channel_atten(ADC1_EXAMPLE_CHAN0, ADC_EXAMPLE_ATTEN));
#if !CONFIG_IDF_TARGET_ESP32C3
//ADC2 config //ADC2 config
ESP_ERROR_CHECK(adc2_config_channel_atten(ADC2_EXAMPLE_CHAN0, ADC_EXAMPLE_ATTEN)); ESP_ERROR_CHECK(adc2_config_channel_atten(ADC2_EXAMPLE_CHAN0, ADC_EXAMPLE_ATTEN));
#endif
while (1) { while (1) {
adc_raw[0][0] = adc1_get_raw(ADC1_EXAMPLE_CHAN0); adc_raw[0][0] = adc1_get_raw(ADC1_EXAMPLE_CHAN0);
@ -95,6 +101,8 @@ void app_main(void)
} }
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
#if !CONFIG_IDF_TARGET_ESP32C3
esp_err_t ret = ESP_OK;
do { do {
ret = adc2_get_raw(ADC2_EXAMPLE_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc_raw[1][0]); ret = adc2_get_raw(ADC2_EXAMPLE_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc_raw[1][0]);
} while (ret == ESP_ERR_INVALID_STATE); } while (ret == ESP_ERR_INVALID_STATE);
@ -106,5 +114,6 @@ void app_main(void)
ESP_LOGI(TAG_CH[1][0], "cali data: %d mV", voltage); ESP_LOGI(TAG_CH[1][0], "cali data: %d mV", voltage);
} }
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
#endif
} }
} }