mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-29 18:27:20 +02:00
Merge branch 'bugfix/no_more_public_adc2_dma_on_c3_s3_v5.0' into 'release/v5.0'
adc: no longer support adc2 continuous mode on esp32c3 and esp32s3 (v5.0) See merge request espressif/esp-idf!21645
This commit is contained in:
@ -66,6 +66,9 @@
|
||||
#define ADC1_TEST_CHAN0 ADC1_CHANNEL_2
|
||||
#endif
|
||||
|
||||
//ESP32C3 ADC2 oneshot mode is not supported anymore
|
||||
#define ADC_TEST_ADC2 ((SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3)
|
||||
|
||||
const __attribute__((unused)) static char *TAG = "TEST_ADC_LEGACY";
|
||||
|
||||
|
||||
@ -94,7 +97,7 @@ TEST_CASE("Legacy ADC oneshot high/low test", "[legacy_adc_oneshot]")
|
||||
//ADC1 config
|
||||
TEST_ESP_OK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT));
|
||||
TEST_ESP_OK(adc1_config_channel_atten(ADC1_TEST_CHAN0, ADC_ATTEN_DB_11));
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if ADC_TEST_ADC2
|
||||
//ADC2 config
|
||||
TEST_ESP_OK(adc2_config_channel_atten(ADC2_TEST_CHAN0, ADC_ATTEN_DB_11));
|
||||
#endif
|
||||
@ -109,7 +112,7 @@ TEST_CASE("Legacy ADC oneshot high/low test", "[legacy_adc_oneshot]")
|
||||
ESP_LOGI(TAG, "ADC%d Channel %d raw: %d\n", ADC_UNIT_1, ADC1_TEST_CHAN0, adc_raw);
|
||||
TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw);
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if ADC_TEST_ADC2
|
||||
test_adc_set_io_level(ADC_UNIT_2, (adc2_channel_t)ADC2_TEST_CHAN0, 0);
|
||||
TEST_ESP_OK(adc2_get_raw(ADC2_TEST_CHAN0, ADC_WIDTH_BIT_DEFAULT, &adc_raw));
|
||||
ESP_LOGI(TAG, "ADC%d Channel %d raw: %d\n", ADC_UNIT_2, ADC2_TEST_CHAN0, adc_raw);
|
||||
|
@ -55,5 +55,25 @@ menu "ADC and ADC Calibration"
|
||||
|
||||
Disable this option so as to measure the output of DAC by internal ADC, for test usage.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
@ -530,16 +530,27 @@ esp_err_t adc_continuous_config(adc_continuous_handle_t handle, const adc_contin
|
||||
|
||||
//Pattern related check
|
||||
ESP_RETURN_ON_FALSE(config->pattern_num <= SOC_ADC_PATT_LEN_MAX, ESP_ERR_INVALID_ARG, ADC_TAG, "Max pattern num is %d", SOC_ADC_PATT_LEN_MAX);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
for (int i = 0; i < config->pattern_num; i++) {
|
||||
ESP_RETURN_ON_FALSE((config->adc_pattern[i].bit_width >= SOC_ADC_DIGI_MIN_BITWIDTH && config->adc_pattern->bit_width <= SOC_ADC_DIGI_MAX_BITWIDTH), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC bitwidth not supported");
|
||||
ESP_RETURN_ON_FALSE(config->adc_pattern[i].unit == 0, ESP_ERR_INVALID_ARG, ADC_TAG, "Only support using ADC1 DMA mode");
|
||||
}
|
||||
#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
|
||||
|
||||
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
|
||||
|
@ -77,6 +77,13 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
|
||||
adc_oneshot_unit_ctx_t *unit = NULL;
|
||||
ESP_GOTO_ON_FALSE(init_config && ret_unit, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument: null pointer");
|
||||
ESP_GOTO_ON_FALSE(init_config->unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, err, TAG, "invalid unit");
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3
|
||||
/**
|
||||
* We only check this on ESP32C3, because other adc units are no longer supported on later chips
|
||||
* If CONFIG_ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 is enabled, we jump this check
|
||||
*/
|
||||
ESP_GOTO_ON_FALSE(SOC_ADC_DIG_SUPPORTED_UNIT(init_config->unit_id), ESP_ERR_INVALID_ARG, err, TAG, "adc unit not supported");
|
||||
#endif
|
||||
|
||||
unit = heap_caps_calloc(1, sizeof(adc_oneshot_unit_ctx_t), ADC_MEM_ALLOC_CAPS);
|
||||
ESP_GOTO_ON_FALSE(unit, ESP_ERR_NO_MEM, err, TAG, "no mem for unit");
|
||||
|
@ -35,6 +35,9 @@ static const char *TAG_CH[2][10] = {{"ADC1_CH2", "ADC1_CH3"}, {"ADC2_CH0"}};
|
||||
/*---------------------------------------------------------------
|
||||
ADC Oneshot High / Low test
|
||||
---------------------------------------------------------------*/
|
||||
//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)
|
||||
|
||||
TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
|
||||
{
|
||||
static int adc_raw[2][10];
|
||||
@ -47,7 +50,7 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
|
||||
};
|
||||
TEST_ESP_OK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
//-------------ADC2 Init---------------//
|
||||
adc_oneshot_unit_handle_t adc2_handle;
|
||||
adc_oneshot_unit_init_cfg_t init_config2 = {
|
||||
@ -55,7 +58,7 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
|
||||
.ulp_mode = ADC_ULP_MODE_DISABLE,
|
||||
};
|
||||
TEST_ESP_OK(adc_oneshot_new_unit(&init_config2, &adc2_handle));
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
|
||||
//-------------ADC1 TEST Channel 0 Config---------------//
|
||||
adc_oneshot_chan_cfg_t config = {
|
||||
@ -67,10 +70,10 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
|
||||
//-------------ADC1 TEST Channel 1 Config---------------//
|
||||
TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, ADC1_TEST_CHAN1, &config));
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
//-------------ADC2 TEST Channel 0 Config---------------//
|
||||
TEST_ESP_OK(adc_oneshot_config_channel(adc2_handle, ADC2_TEST_CHAN0, &config));
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
|
||||
test_adc_set_io_level(ADC_UNIT_1, ADC1_TEST_CHAN0, 0);
|
||||
TEST_ESP_OK(adc_oneshot_read(adc1_handle, ADC1_TEST_CHAN0, &adc_raw[0][0]));
|
||||
@ -82,12 +85,12 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
|
||||
ESP_LOGI(TAG_CH[0][1], "raw data: %d", adc_raw[0][1]);
|
||||
TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw[0][1]);
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
test_adc_set_io_level(ADC_UNIT_2, ADC2_TEST_CHAN0, 0);
|
||||
TEST_ESP_OK(adc_oneshot_read(adc2_handle, ADC2_TEST_CHAN0, &adc_raw[1][0]));
|
||||
ESP_LOGI(TAG_CH[1][0], "raw data: %d", adc_raw[1][0]);
|
||||
TEST_ASSERT_INT_WITHIN(ADC_TEST_LOW_THRESH, ADC_TEST_LOW_VAL, adc_raw[1][0]);
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
|
||||
|
||||
test_adc_set_io_level(ADC_UNIT_1, ADC1_TEST_CHAN0, 1);
|
||||
@ -100,18 +103,18 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]")
|
||||
ESP_LOGI(TAG_CH[0][1], "raw data: %d", adc_raw[0][1]);
|
||||
TEST_ASSERT_INT_WITHIN(ADC_TEST_LOW_THRESH, ADC_TEST_LOW_VAL, adc_raw[0][1]);
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
test_adc_set_io_level(ADC_UNIT_2, ADC2_TEST_CHAN0, 1);
|
||||
TEST_ESP_OK(adc_oneshot_read(adc2_handle, ADC2_TEST_CHAN0, &adc_raw[1][0]));
|
||||
ESP_LOGI(TAG_CH[1][0], "raw data: %d", adc_raw[1][0]);
|
||||
TEST_ASSERT_INT_WITHIN(ADC_TEST_HIGH_THRESH, ADC_TEST_HIGH_VAL, adc_raw[1][0]);
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
|
||||
|
||||
TEST_ESP_OK(adc_oneshot_del_unit(adc1_handle));
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
TEST_ESP_OK(adc_oneshot_del_unit(adc2_handle));
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
|
||||
}
|
||||
|
||||
|
||||
@ -252,8 +255,12 @@ TEST_CASE("test ADC1 Single Read with Light Sleep", "[adc][manul][ignore]")
|
||||
s_adc_oneshot_with_sleep(ADC_UNIT_1, ADC1_SLEEP_TEST_CHAN);
|
||||
}
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
|
||||
//ESP32C3 ADC2 oneshot mode is not supported anymore
|
||||
TEST_CASE("test ADC2 Single Read with Light Sleep", "[adc][manul][ignore]")
|
||||
{
|
||||
s_adc_oneshot_with_sleep(ADC_UNIT_2, ADC2_SLEEP_TEST_CHAN);
|
||||
}
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
|
@ -18,7 +18,10 @@
|
||||
#include "test_common_adc.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM > 1)
|
||||
/**
|
||||
* On ESP32C3, ADC2 is no longer supported, due to its HW limitation.
|
||||
*/
|
||||
#if (SOC_ADC_PERIPH_NUM > 1) && !CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
static const char* TAG = "test_adc2";
|
||||
|
||||
|
@ -292,8 +292,12 @@ TEST_CASE("ADC1 Calibration Speed", "[adc][ignore][manual]")
|
||||
s_adc_cali_speed(ADC_UNIT_1, ADC1_CALI_SPEED_TEST_CHAN0);
|
||||
}
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
|
||||
//ESP32C3 ADC2 oneshot mode is not supported anymore
|
||||
TEST_CASE("ADC2 Calibration Speed", "[adc][ignore][manual]")
|
||||
{
|
||||
s_adc_cali_speed(ADC_UNIT_2, ADC2_CALI_SPEED_TEST_CHAN0);
|
||||
}
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
#endif //#if CONFIG_IDF_TARGET_ESP32 || SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
|
@ -105,6 +105,7 @@
|
||||
#define SOC_ADC_RTC_CTRL_SUPPORTED 1
|
||||
#define SOC_ADC_DIG_CTRL_SUPPORTED 1
|
||||
#define SOC_ADC_DMA_SUPPORTED 1
|
||||
#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) ((UNIT == 0) ? 1 : 0)
|
||||
#define SOC_ADC_PERIPH_NUM (2)
|
||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 8: 10)
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||
|
@ -50,6 +50,7 @@
|
||||
#define SOC_ADC_DIG_CTRL_SUPPORTED 1
|
||||
#define SOC_ADC_FILTER_SUPPORTED 1
|
||||
#define SOC_ADC_MONITOR_SUPPORTED 1
|
||||
#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) 1 //Digital controller supported ADC unit
|
||||
#define SOC_ADC_PERIPH_NUM (1U)
|
||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (5)
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (5)
|
||||
|
@ -76,6 +76,7 @@
|
||||
#define SOC_ADC_FILTER_SUPPORTED 1
|
||||
#define SOC_ADC_MONITOR_SUPPORTED 1
|
||||
#define SOC_ADC_DMA_SUPPORTED 1
|
||||
#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) ((UNIT == 0) ? 1 : 0) //Digital controller supported ADC unit
|
||||
#define SOC_ADC_PERIPH_NUM (2)
|
||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 5 : 1)
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (5)
|
||||
|
@ -77,6 +77,7 @@
|
||||
#define SOC_ADC_FILTER_SUPPORTED 1
|
||||
#define SOC_ADC_MONITOR_SUPPORTED 1
|
||||
#define SOC_ADC_DMA_SUPPORTED 1
|
||||
#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) ((UNIT == 0) ? 1 : 0) //Digital controller supported ADC unit
|
||||
#define SOC_ADC_PERIPH_NUM (1U)
|
||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (5)
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (5)
|
||||
|
@ -86,8 +86,9 @@
|
||||
#define SOC_ADC_FILTER_SUPPORTED 1
|
||||
#define SOC_ADC_MONITOR_SUPPORTED 1
|
||||
#define SOC_ADC_DMA_SUPPORTED 1
|
||||
#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) 1 //Digital controller supported ADC unit
|
||||
#define SOC_ADC_PERIPH_NUM (2)
|
||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
|
||||
#define SOC_ADC_CHANNEL_NUM(UNIT) (10)
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||
#define SOC_ADC_ATTEN_NUM (4)
|
||||
|
||||
|
@ -79,6 +79,7 @@
|
||||
#define SOC_ADC_FILTER_SUPPORTED 1
|
||||
#define SOC_ADC_MONITOR_SUPPORTED 1
|
||||
#define SOC_ADC_DMA_SUPPORTED 1
|
||||
#define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) ((UNIT == 0) ? 1 : 0) //Digital controller supported ADC unit
|
||||
#define SOC_ADC_PERIPH_NUM (2)
|
||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||
|
@ -207,7 +207,7 @@ Hardware Limitations
|
||||
|
||||
- Random Number Generator uses ADC as an input source. When ADC continuous mode driver works, the random number generated from RNG will be less random.
|
||||
|
||||
.. only:: esp32s2 or esp32c3 or esp32s3
|
||||
.. only:: esp32 or esp32s2
|
||||
|
||||
- ADC2 is also used by the Wi-Fi. :cpp:func:`adc_continuous_start` has provided the protection between Wi-Fi driver and ADC continuous mode driver.
|
||||
|
||||
@ -223,6 +223,14 @@ Hardware Limitations
|
||||
|
||||
- ADC continuous mode driver uses SPI3 peripheral as hardware DMA fifo. Therefore, if SPI3 is in use already, the :cpp:func:`adc_continuous_new_handle` will return :c:macro:`ESP_ERR_NOT_FOUND`.
|
||||
|
||||
.. only:: esp32c3
|
||||
|
||||
- ADC2 continuous 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.
|
||||
|
||||
|
||||
Power Management
|
||||
^^^^^^^^^^^^^^^^
|
||||
@ -253,4 +261,4 @@ Application Examples
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/adc_continuous.inc
|
||||
.. include-build-file:: inc/adc_continuous.inc
|
||||
|
@ -156,10 +156,14 @@ Hardware Limitations
|
||||
|
||||
- A specific ADC unit can only work under one operating mode at any one time, either Continuous Mode or Oneshot Mode. :cpp:func:`adc_oneshot_read` has provided the protection.
|
||||
|
||||
.. only:: esp32s2 or esp32c3 or esp32s3
|
||||
.. only:: esp32 or esp32s2 or esp32s3
|
||||
|
||||
- ADC2 is also used by the Wi-Fi. :cpp:func:`adc_oneshot_read` has provided the protection between Wi-Fi driver and ADC continuous mode driver.
|
||||
|
||||
.. 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.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
- ESP32 DevKitC: GPIO 0 cannot be used due to external auto program circuits.
|
||||
@ -207,4 +211,4 @@ API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/adc_types.inc
|
||||
.. include-build-file:: inc/adc_oneshot.inc
|
||||
.. include-build-file:: inc/adc_oneshot.inc
|
||||
|
@ -14,30 +14,19 @@
|
||||
#include "esp_adc/adc_continuous.h"
|
||||
|
||||
#define EXAMPLE_READ_LEN 256
|
||||
#define GET_UNIT(x) ((x>>3) & 0x1)
|
||||
#define EXAMPLE_ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
#define EXAMPLE_ADC_USE_OUTPUT_TYPE1 1
|
||||
#define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
|
||||
#else
|
||||
#define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1 //ESP32 only supports ADC1 DMA mode
|
||||
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#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 || CONFIG_IDF_TARGET_ESP32C2
|
||||
#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_CONV_MODE ADC_CONV_BOTH_UNIT
|
||||
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2
|
||||
static adc_channel_t channel[3] = {ADC_CHANNEL_2, ADC_CHANNEL_3, (ADC_CHANNEL_0 | 1 << 3)};
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
static adc_channel_t channel[3] = {ADC_CHANNEL_2, ADC_CHANNEL_3, (ADC_CHANNEL_0 | 1 << 3)};
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static adc_channel_t channel[1] = {ADC_CHANNEL_7};
|
||||
static adc_channel_t channel[2] = {ADC_CHANNEL_6, ADC_CHANNEL_7};
|
||||
#else
|
||||
static adc_channel_t channel[2] = {ADC_CHANNEL_2, ADC_CHANNEL_3};
|
||||
#endif
|
||||
|
||||
static TaskHandle_t s_task_handle;
|
||||
@ -65,14 +54,14 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc
|
||||
|
||||
adc_continuous_config_t dig_cfg = {
|
||||
.sample_freq_hz = 20 * 1000,
|
||||
.conv_mode = ADC_CONV_MODE,
|
||||
.format = ADC_OUTPUT_TYPE,
|
||||
.conv_mode = EXAMPLE_ADC_CONV_MODE,
|
||||
.format = EXAMPLE_ADC_OUTPUT_TYPE,
|
||||
};
|
||||
|
||||
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
|
||||
dig_cfg.pattern_num = channel_num;
|
||||
for (int i = 0; i < channel_num; i++) {
|
||||
uint8_t unit = GET_UNIT(channel[i]);
|
||||
uint8_t unit = ADC_UNIT_1;
|
||||
uint8_t ch = channel[i] & 0x7;
|
||||
adc_pattern[i].atten = ADC_ATTEN_DB_0;
|
||||
adc_pattern[i].channel = ch;
|
||||
@ -89,16 +78,20 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc
|
||||
*out_handle = handle;
|
||||
}
|
||||
|
||||
#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
|
||||
if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(ADC_UNIT_1)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
@ -136,24 +129,15 @@ void app_main(void)
|
||||
ESP_LOGI("TASK", "ret is %x, ret_num is %"PRIu32, ret, ret_num);
|
||||
for (int i = 0; i < ret_num; i += SOC_ADC_DIGI_RESULT_BYTES) {
|
||||
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 {
|
||||
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", 1, p->type2.channel, p->type2.data);
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Invalid data");
|
||||
}
|
||||
#endif //#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* Because printing is slow, so every time you call `ulTaskNotifyTake`, it will immediately return.
|
||||
|
@ -28,14 +28,22 @@ const static char *TAG = "EXAMPLE";
|
||||
#define EXAMPLE_ADC1_CHAN1 ADC_CHANNEL_3
|
||||
#endif
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
|
||||
/**
|
||||
* On ESP32C3, ADC2 is no longer supported, due to its HW limitation.
|
||||
* Search for errata on espressif website for more details.
|
||||
*/
|
||||
#define EXAMPLE_USE_ADC2 1
|
||||
#endif
|
||||
|
||||
#if EXAMPLE_USE_ADC2
|
||||
//ADC2 Channels
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define EXAMPLE_ADC2_CHAN0 ADC_CHANNEL_0
|
||||
#else
|
||||
#define EXAMPLE_ADC2_CHAN0 ADC_CHANNEL_0
|
||||
#endif
|
||||
#endif
|
||||
#endif //#if EXAMPLE_USE_ADC2
|
||||
|
||||
static int adc_raw[2][10];
|
||||
static int voltage[2][10];
|
||||
@ -65,7 +73,7 @@ void app_main(void)
|
||||
bool do_calibration1 = example_adc_calibration_init(ADC_UNIT_1, ADC_ATTEN_DB_11, &adc1_cali_handle);
|
||||
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if EXAMPLE_USE_ADC2
|
||||
//-------------ADC2 Init---------------//
|
||||
adc_oneshot_unit_handle_t adc2_handle;
|
||||
adc_oneshot_unit_init_cfg_t init_config2 = {
|
||||
@ -80,7 +88,7 @@ void app_main(void)
|
||||
|
||||
//-------------ADC2 Config---------------//
|
||||
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc2_handle, EXAMPLE_ADC2_CHAN0, &config));
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if EXAMPLE_USE_ADC2
|
||||
|
||||
while (1) {
|
||||
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0]));
|
||||
@ -99,7 +107,7 @@ void app_main(void)
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if EXAMPLE_USE_ADC2
|
||||
ESP_ERROR_CHECK(adc_oneshot_read(adc2_handle, EXAMPLE_ADC2_CHAN0, &adc_raw[1][0]));
|
||||
ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_2 + 1, EXAMPLE_ADC2_CHAN0, adc_raw[1][0]);
|
||||
if (do_calibration2) {
|
||||
@ -107,7 +115,7 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_2 + 1, EXAMPLE_ADC2_CHAN0, voltage[1][0]);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if EXAMPLE_USE_ADC2
|
||||
}
|
||||
|
||||
//Tear Down
|
||||
@ -116,12 +124,12 @@ void app_main(void)
|
||||
example_adc_calibration_deinit(adc1_cali_handle);
|
||||
}
|
||||
|
||||
#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#if EXAMPLE_USE_ADC2
|
||||
ESP_ERROR_CHECK(adc_oneshot_del_unit(adc2_handle));
|
||||
if (do_calibration2) {
|
||||
example_adc_calibration_deinit(adc2_cali_handle);
|
||||
}
|
||||
#endif //#if (SOC_ADC_PERIPH_NUM >= 2)
|
||||
#endif //#if EXAMPLE_USE_ADC2
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user