From 5101e52a36f7875f8a93c8715073e35ed054a6d8 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Tue, 23 Jan 2024 18:47:19 +0800 Subject: [PATCH] fix(adc): workaround to fix adc continuous get less results on c3 --- components/esp_adc/adc_continuous.c | 5 +++++ .../test_apps/adc/main/test_adc_driver.c | 5 +---- components/hal/adc_hal.c | 9 +++++++- components/hal/esp32c3/include/hal/adc_ll.h | 21 ++++++++++++++++++- components/hal/include/hal/adc_hal.h | 9 +++++++- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 12af5c05c3..6d324dac04 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -393,6 +393,11 @@ esp_err_t adc_continuous_stop(adc_continuous_handle_t handle) //stop ADC adc_hal_digi_stop(&handle->hal); +#if ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER + periph_module_reset(PERIPH_SARADC_MODULE); + adc_hal_digi_clr_eof(); +#endif + adc_hal_digi_deinit(&handle->hal); if (handle->use_adc2) { diff --git a/components/esp_adc/test_apps/adc/main/test_adc_driver.c b/components/esp_adc/test_apps/adc/main/test_adc_driver.c index d4284ce2da..308e5ab3f9 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_driver.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_driver.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -142,8 +142,6 @@ TEST_CASE("ADC oneshot fast work with ISR", "[adc_oneshot]") #define ADC_DRIVER_TEST_GET_DATA(p_data) ((p_data)->type2.data) #endif -#if !CONFIG_IDF_TARGET_ESP32C3 //TODO: DIG-270 - #define ADC_RESTART_TEST_SIZE 4096 #define ADC_READ_TEST_COUNT 10 @@ -191,7 +189,6 @@ TEST_CASE("ADC continuous test after restarting", "[adc_continuous]") TEST_ESP_OK(adc_continuous_deinit(handle)); free(result); } -#endif //!CONFIG_IDF_TARGET_ESP32C3 #if SOC_ADC_DIG_IIR_FILTER_SUPPORTED TEST_CASE("ADC filter exhausted allocation", "[adc_oneshot]") diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 053cc5f712..fe8c01683b 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -358,3 +358,10 @@ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal) //disconnect DMA and peripheral adc_ll_digi_dma_disable(); } + +#if ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER +void adc_hal_digi_clr_eof(void) +{ + adc_ll_digi_dma_clr_eof(); +} +#endif diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index f94f45f1fd..4fb9a95b47 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -56,6 +56,13 @@ extern "C" { #define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 #define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 +/** + * Workaround: on ESP32C3, the internal hardware counter that counts ADC samples will not be automatically cleared, + * and there is no dedicated register to manually clear it. (see section 3.2 of the errata document). + * Therefore, traverse from 0 to the value configured last time, so as to clear the ADC sample counter. + */ +#define ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER (1) + /*--------------------------------------------------------------- PWDET (Power Detect) ---------------------------------------------------------------*/ @@ -437,6 +444,18 @@ static inline void adc_ll_digi_dma_set_eof_num(uint32_t num) HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num, num); } +/** + * Clear ADC sample counter of adc digital controller. + */ +static inline void adc_ll_digi_dma_clr_eof(void) +{ + uint32_t eof_num = HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num); + for (int i = 0; i <= eof_num; i++) + { + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num, i); + } +} + /** * Enable output data to DMA from adc digital controller. */ diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index d023ff7dd6..d26efea69d 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -207,6 +207,13 @@ void adc_hal_digi_dis_intr(adc_hal_dma_ctx_t *hal, uint32_t mask); */ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal); +#if ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER +/** + * @brief Clear the ADC sample counter + */ +void adc_hal_digi_clr_eof(void); +#endif + #ifdef __cplusplus } #endif