mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 04:34:31 +02:00
adc: no longer support adc2 continuous mode on esp32c3 and esp32s3
Due to HW limitation, we don't support this anymore. On s3 and 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-s3_errata_en.pdf https://www.espressif.com/sites/default/files/documentation/esp32-c3_errata_en.pdf
This commit is contained in:
@@ -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 || 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.
|
||||
|
||||
endmenu # ADC Configuration
|
||||
|
||||
menu "MCPWM configuration"
|
||||
|
@@ -569,8 +569,21 @@ esp_err_t adc_digi_controller_configure(const adc_digi_configuration_t *config)
|
||||
#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
|
||||
#endif //#if CONFIG_IDF_TARGET_ESP32
|
||||
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
|
||||
ESP_RETURN_ON_FALSE(config->conv_limit_en == 1, ESP_ERR_INVALID_ARG, ADC_TAG, "`conv_limit_en` should be set to 1");
|
||||
|
@@ -126,9 +126,16 @@ 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``.
|
||||
|
||||
.. only:: esp32c3
|
||||
|
||||
- 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
|
||||
|
||||
- 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.
|
||||
|
||||
Driver Usage
|
||||
------------
|
||||
|
||||
|
@@ -17,41 +17,37 @@
|
||||
#define GET_UNIT(x) ((x>>3) & 0x1)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define ADC_RESULT_BYTE 2
|
||||
#define ADC_CONV_LIMIT_EN 1 //For ESP32, this should always be set to 1
|
||||
#define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1 //ESP32 only supports ADC1 DMA mode
|
||||
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
|
||||
#define ADC_RESULT_BYTE 2
|
||||
#define ADC_CONV_LIMIT_EN 1 //For ESP32, this should always be set to 1
|
||||
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
|
||||
#define EXAMPLE_ADC_USE_OUTPUT_TYPE1 1
|
||||
#define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define ADC_RESULT_BYTE 2
|
||||
#define ADC_CONV_LIMIT_EN 0
|
||||
#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_ESP32H2
|
||||
#define ADC_RESULT_BYTE 4
|
||||
#define ADC_CONV_LIMIT_EN 0
|
||||
#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_RESULT_BYTE 4
|
||||
#define ADC_CONV_LIMIT_EN 0
|
||||
#define ADC_CONV_MODE ADC_CONV_BOTH_UNIT
|
||||
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
|
||||
#define ADC_RESULT_BYTE 2
|
||||
#define ADC_CONV_LIMIT_EN 0
|
||||
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
|
||||
#define ADC_CONV_MODE ADC_CONV_BOTH_UNIT
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define ADC_RESULT_BYTE 4
|
||||
#define ADC_CONV_LIMIT_EN 0
|
||||
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
|
||||
#define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
|
||||
static uint16_t adc1_chan_mask = BIT(2) | BIT(3);
|
||||
static uint16_t adc2_chan_mask = BIT(0);
|
||||
static adc_channel_t channel[3] = {ADC1_CHANNEL_2, ADC1_CHANNEL_3, (ADC2_CHANNEL_0 | 1 << 3)};
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
static uint16_t adc1_chan_mask = BIT(2) | BIT(3);
|
||||
static uint16_t adc2_chan_mask = BIT(0);
|
||||
static adc_channel_t channel[3] = {ADC1_CHANNEL_2, ADC1_CHANNEL_3, (ADC2_CHANNEL_0 | 1 << 3)};
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static uint16_t adc1_chan_mask = BIT(7);
|
||||
static uint16_t adc2_chan_mask = 0;
|
||||
static adc_channel_t channel[1] = {ADC1_CHANNEL_7};
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
static uint16_t adc1_chan_mask = BIT(2) | BIT(3);
|
||||
static uint16_t adc2_chan_mask = BIT(0);
|
||||
static adc_channel_t channel[3] = {ADC1_CHANNEL_2, ADC1_CHANNEL_3, (ADC2_CHANNEL_0 | 1 << 3)};
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
|
||||
static uint16_t adc1_chan_mask = BIT(2) | BIT(3);
|
||||
static uint16_t adc2_chan_mask = 0;
|
||||
static adc_channel_t channel[2] = {ADC1_CHANNEL_2, ADC1_CHANNEL_3};
|
||||
#endif
|
||||
|
||||
static const char *TAG = "ADC DMA";
|
||||
@@ -92,16 +88,24 @@ static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask
|
||||
ESP_ERROR_CHECK(adc_digi_controller_configure(&dig_cfg));
|
||||
}
|
||||
|
||||
#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
|
||||
int unit = data->type2.unit;
|
||||
if (unit >= ADC_UNIT_2) {
|
||||
return false;
|
||||
}
|
||||
if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
@@ -137,25 +141,15 @@ void app_main(void)
|
||||
ESP_LOGI("TASK:", "ret is %x, ret_num is %d", ret, ret_num);
|
||||
for (int i = 0; i < ret_num; i += ADC_RESULT_BYTE) {
|
||||
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 {
|
||||
// abort();
|
||||
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", p->type2.unit + 1, p->type2.channel, p->type2.data);
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Invalid data");
|
||||
}
|
||||
#endif //#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#endif
|
||||
}
|
||||
//See `note 1`
|
||||
vTaskDelay(1);
|
||||
|
Reference in New Issue
Block a user