diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 5257ad9b29..2e46d30b02 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -1754,6 +1754,19 @@ - <<: *if-dev-push changes: *patterns-component_ut +.rules:test:component_ut-esp32c6-adc: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32c6 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-target_test-adc + .rules:test:component_ut-esp32h4-i154: rules: - <<: *if-revert-branch @@ -2072,6 +2085,19 @@ - <<: *if-dev-push changes: *patterns-example_test +.rules:test:example_test-esp32c6-adc: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32c6 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-target_test-adc + .rules:test:example_test-esp32s2: rules: - <<: *if-revert-branch diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index aae47c9057..3b0d2c2281 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -336,6 +336,14 @@ example_test_pytest_esp32c2_adc: - build_pytest_examples_esp32c2 tags: [ esp32c2, adc, xtal_26mhz] +example_test_pytest_esp32c6_adc: + extends: + - .pytest_examples_dir_template + - .rules:test:example_test-esp32c6-adc + needs: + - build_pytest_examples_esp32c6 + tags: [ esp32c6, adc ] + .pytest_components_dir_template: extends: .pytest_template variables: @@ -673,6 +681,14 @@ component_ut_pytest_esp32c6_generic_multi_device: - build_pytest_components_esp32c6 tags: [ esp32c6, generic_multi_device ] +component_ut_pytest_esp32c6_adc: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32c6-adc + needs: + - build_pytest_components_esp32c6 + tags: [ esp32c6, adc ] + component_ut_pytest_esp32h4_i154: extends: - .pytest_components_dir_template diff --git a/components/driver/.build-test-rules.yml b/components/driver/.build-test-rules.yml index 4eb414e755..520cd0a6e9 100644 --- a/components/driver/.build-test-rules.yml +++ b/components/driver/.build-test-rules.yml @@ -34,9 +34,7 @@ components/driver/test_apps/ledc: components/driver/test_apps/legacy_adc_driver: disable: - - if: IDF_TARGET == "esp32c6" - temporary: true - reason: target esp32c6 is not supported yet + - if: SOC_ADC_SUPPORTED != 1 components/driver/test_apps/legacy_mcpwm_driver: disable: diff --git a/components/driver/dac/esp32s2/dac_dma.c b/components/driver/dac/esp32s2/dac_dma.c index cc65730ba5..25d9ceaf40 100644 --- a/components/driver/dac/esp32s2/dac_dma.c +++ b/components/driver/dac/esp32s2/dac_dma.c @@ -129,7 +129,7 @@ finish: dac_ll_digi_clk_inv(true); dac_ll_digi_set_trigger_interval(interval); // secondary clock division adc_ll_digi_controller_clk_div(clk_div - 1, b, a); - adc_ll_digi_clk_sel(is_apll); + adc_ll_digi_clk_sel(is_apll ? ADC_DIGI_CLK_SRC_APLL : ADC_DIGI_CLK_SRC_DEFAULT); return ESP_OK; } diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 11c2906756..b7b3e2526e 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -617,11 +617,11 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio) adc_power_acquire(); if (adc_unit == ADC_UNIT_1) { VREF_ENTER(1); - adc_hal_vref_output(ADC_UNIT_1, ch, true); + adc_ll_vref_output(ADC_UNIT_1, ch, true); VREF_EXIT(1); } else if (adc_unit == ADC_UNIT_2) { VREF_ENTER(2); - adc_hal_vref_output(ADC_UNIT_2, ch, true); + adc_ll_vref_output(ADC_UNIT_2, ch, true); VREF_EXIT(2); } @@ -706,11 +706,11 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio) adc_power_acquire(); if (adc_unit == ADC_UNIT_1) { RTC_ENTER_CRITICAL(); - adc_hal_vref_output(ADC_UNIT_1, channel, true); + adc_ll_vref_output(ADC_UNIT_1, channel, true); RTC_EXIT_CRITICAL(); } else { //ADC_UNIT_2 RTC_ENTER_CRITICAL(); - adc_hal_vref_output(ADC_UNIT_2, channel, true); + adc_ll_vref_output(ADC_UNIT_2, channel, true); RTC_EXIT_CRITICAL(); } @@ -756,7 +756,7 @@ int adc1_get_raw(adc1_channel_t channel) periph_module_enable(PERIPH_SARADC_MODULE); adc_power_acquire(); - adc_ll_digi_clk_sel(0); + adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); adc_atten_t atten = s_atten1_single[channel]; #if SOC_ADC_CALIBRATION_V1_SUPPORTED @@ -764,7 +764,7 @@ int adc1_get_raw(adc1_channel_t channel) #endif ADC_REG_LOCK_ENTER(); - adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten); + adc_oneshot_ll_set_atten(ADC_UNIT_1, channel, atten); adc_hal_convert(ADC_UNIT_1, channel, &raw_out); ADC_REG_LOCK_EXIT(); @@ -807,7 +807,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * periph_module_enable(PERIPH_SARADC_MODULE); adc_power_acquire(); - adc_ll_digi_clk_sel(0); + adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); adc_hal_arbiter_config(&config); diff --git a/components/driver/deprecated/driver/adc_types_legacy.h b/components/driver/deprecated/driver/adc_types_legacy.h index 1a2b2a4d55..117d469600 100644 --- a/components/driver/deprecated/driver/adc_types_legacy.h +++ b/components/driver/deprecated/driver/adc_types_legacy.h @@ -61,7 +61,7 @@ typedef enum { ADC1_CHANNEL_9, /*!< ADC1 channel 9 is GPIO10 */ ADC1_CHANNEL_MAX, } adc1_channel_t; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4 typedef enum { ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO0 */ ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO1 */ @@ -70,6 +70,17 @@ typedef enum { ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO4 */ ADC1_CHANNEL_MAX, } adc1_channel_t; +#elif CONFIG_IDF_TARGET_ESP32C6 +typedef enum { + ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO0 */ + ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO1 */ + ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO2 */ + ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO3 */ + ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO4 */ + ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO5 */ + ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO6 */ + ADC1_CHANNEL_MAX, +} adc1_channel_t; #endif // CONFIG_IDF_TARGET_* #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -86,7 +97,8 @@ typedef enum { ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO26 (ESP32), GPIO20 (ESP32-S2) */ ADC2_CHANNEL_MAX, } adc2_channel_t; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4 +// ESP32C6 has no ADC2 typedef enum { ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO5 */ ADC2_CHANNEL_MAX, diff --git a/components/driver/deprecated/esp32s2/dac_legacy.c b/components/driver/deprecated/esp32s2/dac_legacy.c index 3e09d4c869..6f92bce6d0 100644 --- a/components/driver/deprecated/esp32s2/dac_legacy.c +++ b/components/driver/deprecated/esp32s2/dac_legacy.c @@ -82,7 +82,7 @@ esp_err_t dac_digi_controller_config(const dac_digi_config_t *cfg) dac_ll_digi_set_convert_mode(cfg->mode == DAC_CONV_ALTER); dac_ll_digi_set_trigger_interval(cfg->interval); adc_ll_digi_controller_clk_div(cfg->dig_clk.div_num, cfg->dig_clk.div_b, cfg->dig_clk.div_a); - adc_ll_digi_clk_sel(cfg->dig_clk.use_apll); + adc_ll_digi_clk_sel(cfg->dig_clk.use_apll ? ADC_DIGI_CLK_SRC_APLL : ADC_DIGI_CLK_SRC_DEFAULT); DAC_EXIT_CRITICAL(); return ESP_OK; diff --git a/components/driver/test_apps/legacy_adc_driver/README.md b/components/driver/test_apps/legacy_adc_driver/README.md index b5be4985c5..7e7523ec85 100644 --- a/components/driver/test_apps/legacy_adc_driver/README.md +++ b/components/driver/test_apps/legacy_adc_driver/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c index c76a0a8e53..a5b58e9720 100644 --- a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c +++ b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c @@ -53,6 +53,13 @@ #define ADC_TEST_HIGH_VAL 3400 #define ADC_TEST_HIGH_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5312 +#define ADC_TEST_LOW_VAL 2144 +#define ADC_TEST_LOW_THRESH 200 + +#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_THRESH 200 + #endif //ADC Channels diff --git a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py index 00789424d6..081f0d547e 100644 --- a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py +++ b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py @@ -9,6 +9,7 @@ from pytest_embedded import Dut @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c6 @pytest.mark.adc @pytest.mark.parametrize( 'config', diff --git a/components/esp_adc/.build-test-rules.yml b/components/esp_adc/.build-test-rules.yml index 9237324a1a..389eceee9d 100644 --- a/components/esp_adc/.build-test-rules.yml +++ b/components/esp_adc/.build-test-rules.yml @@ -2,6 +2,4 @@ components/esp_adc/test_apps/adc: disable: - - if: IDF_TARGET == "esp32c6" - temporary: true - reason: target esp32c6 is not supported yet + - if: SOC_ADC_SUPPORTED != 1 diff --git a/components/esp_adc/CMakeLists.txt b/components/esp_adc/CMakeLists.txt index fdeaf44f69..6edb190c97 100644 --- a/components/esp_adc/CMakeLists.txt +++ b/components/esp_adc/CMakeLists.txt @@ -32,15 +32,6 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/deprecated/${target}/esp_adc_cal_legacy.c list(APPEND srcs "deprecated/${target}/esp_adc_cal_legacy.c") endif() -# ESP32C6-TODO -if(CONFIG_IDF_TARGET_ESP32C6) - list(REMOVE_ITEM srcs - "adc_cali_curve_fitting.c" # TODO: IDF-5312 - "adc_oneshot.c" # TODO: IDF-5310 - "adc_common.c" - ) -endif() - idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} PRIV_REQUIRES driver efuse diff --git a/components/esp_adc/test_apps/adc/README.md b/components/esp_adc/test_apps/adc/README.md index b5be4985c5..7e7523ec85 100644 --- a/components/esp_adc/test_apps/adc/README.md +++ b/components/esp_adc/test_apps/adc/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.h b/components/esp_adc/test_apps/adc/main/test_common_adc.h index 1deb93c68b..d822404a3f 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.h +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.h @@ -70,6 +70,14 @@ extern "C" { #define ADC_TEST_HIGH_VAL 3400 #define ADC_TEST_HIGH_THRESH 200 + +#elif CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5312 +#define ADC_TEST_LOW_VAL 2144 +#define ADC_TEST_LOW_THRESH 200 + +#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_VAL_DMA 4081 +#define ADC_TEST_HIGH_THRESH 200 #endif diff --git a/components/esp_adc/test_apps/adc/pytest_adc.py b/components/esp_adc/test_apps/adc/pytest_adc.py index 6b87bc81d1..31ce345c8d 100644 --- a/components/esp_adc/test_apps/adc/pytest_adc.py +++ b/components/esp_adc/test_apps/adc/pytest_adc.py @@ -9,6 +9,7 @@ from pytest_embedded import Dut @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c6 @pytest.mark.adc @pytest.mark.parametrize('config', [ 'iram_safe', diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 7a0ac71c50..0d35e41999 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -70,13 +70,6 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_ds.c") endif() - # ESP32C6-TODO - if(CONFIG_IDF_TARGET_ESP32C6) - list(REMOVE_ITEM srcs - "adc_share_hw_ctrl.c" # TODO: IDF-5312 - ) - endif() - else() # Requires "_esp_error_check_failed()" function list(APPEND priv_requires "esp_system") diff --git a/components/esp_hw_support/port/esp32c6/rtc_init.c b/components/esp_hw_support/port/esp32c6/rtc_init.c index 60a77df39a..0d418b5a6a 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_init.c +++ b/components/esp_hw_support/port/esp32c6/rtc_init.c @@ -13,8 +13,10 @@ void rtc_init(rtc_config_t cfg) { + /* Peripheral reg i2c power up */ SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index bb638925e5..234d90d294 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -191,11 +191,6 @@ if(NOT BOOTLOADER_BUILD) "esp32c6/brownout_hal.c" "esp32c6/rtc_cntl_hal.c") - # TODO: IDF-5310 - list(REMOVE_ITEM srcs - "adc_oneshot_hal.c" - "adc_hal_common.c" - ) endif() if(${target} STREQUAL "esp32h2") diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index bc974e706c..7b8dd16237 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -141,11 +141,8 @@ void adc_hal_digi_deinit(adc_hal_dma_ctx_t *hal) ---------------------------------------------------------------*/ static adc_ll_digi_convert_mode_t get_convert_mode(adc_digi_convert_mode_t convert_mode) { -#if CONFIG_IDF_TARGET_ESP32 +#if CONFIG_IDF_TARGET_ESP32 || SOC_ADC_DIGI_CONTROLLER_NUM == 1 return ADC_LL_DIGI_CONV_ONLY_ADC1; -#endif -#if (SOC_ADC_DIGI_CONTROLLER_NUM == 1) - return ADC_LL_DIGI_CONV_ALTER_UNIT; #elif (SOC_ADC_DIGI_CONTROLLER_NUM >= 2) switch (convert_mode) { case ADC_CONV_SINGLE_UNIT_1: @@ -177,7 +174,7 @@ static void adc_hal_digi_sample_freq_config(adc_hal_dma_ctx_t *hal, uint32_t fre adc_ll_digi_set_trigger_interval(interval); //Here we set the clock divider factor to make the digital clock to 5M Hz adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT); - adc_ll_digi_clk_sel(0); //use APB + adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); // use default clock source for ADC digital controller #else i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_SRC_DEFAULT); /*!< Clock from PLL_D2_CLK(160M)*/ uint32_t bclk_div = 16; diff --git a/components/hal/adc_oneshot_hal.c b/components/hal/adc_oneshot_hal.c index 27ee5283a2..3b1c7f3bfa 100644 --- a/components/hal/adc_oneshot_hal.c +++ b/components/hal/adc_oneshot_hal.c @@ -57,7 +57,7 @@ void adc_oneshot_hal_setup(adc_oneshot_hal_ctx_t *hal, adc_channel_t chan) #endif #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - adc_ll_digi_clk_sel(0); + adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); #else adc_ll_set_sar_clk_div(unit, ADC_HAL_SAR_CLK_DIV_DEFAULT(unit)); if (unit == ADC_UNIT_2) { diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index d4dd029acf..0f93dcb607 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -13,8 +13,10 @@ #include "soc/adc_periph.h" #include "soc/rtc_io_struct.h" #include "soc/sens_struct.h" +#include "soc/sens_reg.h" #include "soc/syscon_struct.h" #include "soc/rtc_cntl_struct.h" +#include "soc/clk_tree_defs.h" #ifdef __cplusplus extern "C" { diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index e9d51a288e..89320fc4d1 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -14,6 +14,7 @@ #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" +#include "soc/clk_tree_defs.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -33,9 +34,9 @@ extern "C" { #define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) typedef enum { - ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ - ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ - ADC_POWER_SW_OFF, /*!< ADC XPD controled by SW. power off. */ + ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */ ADC_POWER_MAX, /*!< For parameter check. */ } adc_ll_power_t; @@ -93,7 +94,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) */ static inline void adc_ll_digi_set_clk_div(uint32_t div) { - /* ADC clock devided from digital controller clock clk */ + /* ADC clock divided from digital controller clock clk */ HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl, saradc_saradc_sar_clk_div, div); } @@ -141,15 +142,11 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div /** * Enable clock and select clock source for ADC digital controller. * - * @param use_apll true: use APLL clock; false: use APB clock. + * @param clk_src clock source for ADC digital controller. */ -static inline void adc_ll_digi_clk_sel(bool use_apll) +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) { - if (use_apll) { - APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = 1; // APLL clock - } else { - APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = 2; // APB clock - } + APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = 2; APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1; } diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 399044390d..f76656afb4 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -14,6 +14,7 @@ #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" +#include "soc/clk_tree_defs.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -35,14 +36,14 @@ extern "C" { #define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) #define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) #define ADC_LL_EVENT_THRES0_HIGH BIT(29) -#define ADC_LL_event_THRES1_HIGH BIT(28) -#define ADC_LL_event_THRES0_LOW BIT(27) +#define ADC_LL_EVENT_THRES1_HIGH BIT(28) +#define ADC_LL_EVENT_THRES0_LOW BIT(27) #define ADC_LL_EVENT_THRES1_LOW BIT(26) typedef enum { - ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ - ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ - ADC_POWER_SW_OFF, /*!< ADC XPD controled by SW. power off. */ + ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */ ADC_POWER_MAX, /*!< For parameter check. */ } adc_ll_power_t; @@ -62,11 +63,11 @@ typedef enum { * @brief ADC digital controller (DMA mode) work mode. * * @note The conversion mode affects the sampling frequency: - * ESP32C3 only support ALTER_UNIT mode - * ALTER_UNIT : When the measurement is triggered, ADC1 or ADC2 samples alternately. + * ESP32C3 only support ONLY_ADC1 mode + * SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once. */ typedef enum { - ADC_LL_DIGI_CONV_ALTER_UNIT = 0, // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 ..... + ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion } adc_ll_digi_convert_mode_t; typedef struct { @@ -124,7 +125,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) */ static inline void adc_ll_digi_set_clk_div(uint32_t div) { - /* ADC clock devided from digital controller clock clk */ + /* ADC clock divided from digital controller clock clk */ HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div); } @@ -159,7 +160,7 @@ static inline void adc_ll_digi_convert_limit_enable(bool enable) */ static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode) { - //ESP32C3 only supports ADC_CONV_ALTER_UNIT mode + //ESP32C3 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode } /** @@ -283,15 +284,12 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div /** * Enable clock and select clock source for ADC digital controller. * - * @param use_apll true: use APLL clock; false: use APB clock. + * @param clk_src clock source for ADC digital controller. */ -static inline void adc_ll_digi_clk_sel(bool use_apll) +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) { - if (use_apll) { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 1; // APLL clock - } else { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 2; // APB clock - } + // Only support APB clock, should always set to 1 or 2 + APB_SARADC.apb_adc_clkm_conf.clk_sel = 2; APB_SARADC.ctrl.sar_clk_gated = 1; } diff --git a/components/hal/esp32c6/include/hal/adc_hal_conf.h b/components/hal/esp32c6/include/hal/adc_hal_conf.h new file mode 100644 index 0000000000..1cafdf935f --- /dev/null +++ b/components/hal/esp32c6/include/hal/adc_hal_conf.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/*--------------------------------------------------------------- + Single Read +---------------------------------------------------------------*/ +#define ADC_HAL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_HAL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (2) + +/*--------------------------------------------------------------- + DMA Read +---------------------------------------------------------------*/ +#define ADC_HAL_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_HAL_FSM_RSTB_WAIT_DEFAULT (8) +#define ADC_HAL_FSM_START_WAIT_DEFAULT (5) +#define ADC_HAL_FSM_STANDBY_WAIT_DEFAULT (100) +#define ADC_HAL_SAMPLE_CYCLE_DEFAULT (2) +#define ADC_HAL_DIGI_SAR_CLK_DIV_DEFAULT (1) + +/*--------------------------------------------------------------- + PWDET (Power Detect) +---------------------------------------------------------------*/ +#define ADC_HAL_PWDET_CCT_DEFAULT (4) diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h new file mode 100644 index 0000000000..9dd051b716 --- /dev/null +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -0,0 +1,741 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_attr.h" + +#include "soc/adc_periph.h" +#include "soc/apb_saradc_struct.h" +#include "soc/apb_saradc_reg.h" +#include "soc/pmu_reg.h" +#include "soc/clk_tree_defs.h" +#include "soc/pcr_struct.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/adc_types.h" +#include "hal/adc_types_private.h" +#include "hal/regi2c_ctrl.h" +#include "hal/sar_ctrl_ll.h" + +#include "soc/regi2c_saradc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 + +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) +#define ADC_LL_EVENT_THRES0_HIGH BIT(29) +#define ADC_LL_EVENT_THRES1_HIGH BIT(28) +#define ADC_LL_EVENT_THRES0_LOW BIT(27) +#define ADC_LL_EVENT_THRES1_LOW BIT(26) + +typedef enum { + ADC_POWER_BY_FSM = SAR_CTRL_LL_POWER_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_POWER_SW_ON = SAR_CTRL_LL_POWER_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_POWER_SW_OFF = SAR_CTRL_LL_POWER_OFF, /*!< ADC XPD controlled by SW. power off. */ + ADC_POWER_MAX, /*!< For parameter check. */ +} adc_ll_power_t; + +typedef enum { + ADC_LL_CTRL_DIG = 0, ///< ADC digital controller +} adc_ll_controller_t; + +/** + * @brief ADC digital controller (DMA mode) work mode. + * + * @note The conversion mode affects the sampling frequency: + * ESP32C6 only support ONLY_ADC1 mode + * SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once. + */ +typedef enum { + ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion +} adc_ll_digi_convert_mode_t; + +typedef struct { + union { + struct { + uint8_t atten: 2; + uint8_t channel: 3; + uint8_t unit: 1; + uint8_t reserved: 2; + }; + uint8_t val; + }; +} __attribute__((packed)) adc_ll_digi_pattern_table_t; + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +/** + * Set adc fsm interval parameter for digital controller. These values are fixed for same platforms. + * + * @param rst_wait cycles between DIG ADC controller reset ADC sensor and start ADC sensor. + * @param start_wait Delay time after open xpd. + * @param standby_wait Delay time to close xpd. + */ +static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait) +{ + // Internal FSM reset wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_rstb_wait, rst_wait); + // Internal FSM start wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_xpd_wait, start_wait); + // Internal FSM standby wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_fsm_wait, saradc_saradc_standby_wait, standby_wait); +} + +/** + * Set adc sample cycle for digital controller. + * + * @note Normally, please use default value. + * @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor. + * Range: 2 ~ 0xFF. + */ +static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) +{ + /* Peripheral reg i2c has powered up in rtc_init, write directly */ + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle); +} + +/** + * Set SAR ADC module clock division factor. + * SAR ADC clock divided from digital controller clock. + * + * @param div Division factor. + */ +static inline void adc_ll_digi_set_clk_div(uint32_t div) +{ + /* ADC clock divided from digital controller clock clk */ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl, saradc_saradc_sar_clk_div, div); +} + +/** + * Set adc max conversion number for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param meas_num Max conversion number. Range: 0 ~ 255. + */ +static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_ctrl2, saradc_saradc_max_meas_num, meas_num); +} + +/** + * Enable max conversion number detection for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param enable true: enable; false: disable + */ +static inline void adc_ll_digi_convert_limit_enable(bool enable) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_meas_num_limit = enable; +} + +/** + * Set adc conversion mode for digital controller. + * + * @note ESP32C6 only support ADC1 single mode. + * + * @param mode Conversion mode select. + */ +static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode) +{ + //ESP32C6 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode +} + +/** + * Set pattern table length for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 4 items, in which channel selection, + * and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param patt_len Items range: 1 ~ 8. + */ +static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t patt_len) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_len = patt_len - 1; +} + +/** + * Set pattern table for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 4 items, in which channel selection, + * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param pattern_index Items index. Range: 0 ~ 7. + * @param pattern Stored conversion rules. + */ +static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table) +{ + uint32_t tab; + uint8_t index = pattern_index / 4; + uint8_t offset = (pattern_index % 4) * 6; + adc_ll_digi_pattern_table_t pattern = {0}; + + pattern.val = (table.atten & 0x3) | ((table.channel & 0x7) << 2) | ((table.unit & 0x1) << 5); + if (index == 0) { + tab = APB_SARADC.saradc_sar_patt_tab1.saradc_saradc_sar_patt_tab1; // Read old register value + tab &= (~(0xFC0000 >> offset)); // Clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; // Fill in the new data + APB_SARADC.saradc_sar_patt_tab1.saradc_saradc_sar_patt_tab1 = tab; // Write back + } else { + tab = APB_SARADC.saradc_sar_patt_tab2.saradc_saradc_sar_patt_tab2; // Read old register value + tab &= (~(0xFC0000 >> offset)); // Clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; // Fill in the new data + APB_SARADC.saradc_sar_patt_tab2.saradc_saradc_sar_patt_tab2 = tab; // Write back + } +} + +/** + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_p_clear = 1; + APB_SARADC.saradc_ctrl.saradc_saradc_sar_patt_p_clear = 0; +} + +/** + * Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize. + * + * @note Only ADC2 have arbiter function. + * @param cycle range: 0 ~ 4. + */ +static inline void adc_ll_digi_set_arbiter_stable_cycle(uint32_t cycle) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_wait_arb_cycle = cycle; +} + +/** + * ADC Digital controller output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_ll_digi_output_invert(adc_unit_t adc_n, bool inv_en) +{ + if (adc_n == ADC_UNIT_1) { + APB_SARADC.saradc_ctrl2.saradc_saradc_sar1_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Set the interval clock cycle for the digital controller to trigger the measurement. + * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. + * + * @note The trigger interval should not be smaller than the sampling time of the SAR ADC. + * @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095. + */ +static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_timer_target = cycle; +} + +/** + * Enable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_enable(void) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_timer_en = 1; +} + +/** + * Disable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_disable(void) +{ + APB_SARADC.saradc_ctrl2.saradc_saradc_timer_en = 0; +} + +/** + * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. + * Expression: controller_clk = (APLL or APB) / (div_num + div_a / div_b + 1). + * + * @param div_num Division factor. Range: 0 ~ 255. + * @param div_b Division factor. Range: 1 ~ 63. + * @param div_a Division factor. Range: 0 ~ 63. + */ +static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.saradc_clkm_conf, saradc_clkm_div_num, div_num); + PCR.saradc_clkm_conf.saradc_clkm_div_b = div_b; + PCR.saradc_clkm_conf.saradc_clkm_div_a = div_a; +} + +/** + * Enable clock and select clock source for ADC digital controller. + * + * @param clk_src clock source for ADC digital controller. + */ +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) +{ + switch (clk_src) { + case ADC_DIGI_CLK_SRC_XTAL: + PCR.saradc_clkm_conf.saradc_clkm_sel = 0; + break; + case ADC_DIGI_CLK_SRC_PLL_F80M: + PCR.saradc_clkm_conf.saradc_clkm_sel = 1; + break; + case ADC_DIGI_CLK_SRC_RC_FAST: + PCR.saradc_clkm_conf.saradc_clkm_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock"); + } + // Enable ADC_CTRL_CLK (i.e. digital domain clock) + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1; +} + +/** + * Disable clock for ADC digital controller. + */ +static inline void adc_ll_digi_controller_clk_disable(void) +{ + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0; +} + +/** + * Reset adc digital controller filter. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_filter_reset(adc_unit_t adc_n) +{ + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_reset = 1; +} + +/** + * Set adc digital controller filter factor. + * + * @note If the channel info is not supported, the filter function will not be enabled. + * @param idx ADC filter unit. + * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64). + */ +static inline void adc_ll_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter) +{ + if (idx == ADC_DIGI_FILTER_IDX0) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = (filter->adc_unit << 3) | (filter->channel & 0x7); + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = filter->mode; + } else if (idx == ADC_DIGI_FILTER_IDX1) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = (filter->adc_unit << 3) | (filter->channel & 0x7); + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = filter->mode; + } +} + +/** + * Get adc digital controller filter factor. + * + * @param adc_n ADC unit. + * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64). + */ +static inline void adc_ll_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter) +{ + if (idx == ADC_DIGI_FILTER_IDX0) { + filter->adc_unit = (APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 >> 3) & 0x1; + filter->channel = APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 & 0x7; + filter->mode = APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0; + } else if (idx == ADC_DIGI_FILTER_IDX1) { + filter->adc_unit = (APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 >> 3) & 0x1; + filter->channel = APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 & 0x7; + filter->mode = APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1; + } +} + +/** + * Disable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @note If the channel info is not supported, the filter function will not be enabled. + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_filter_disable(adc_digi_filter_idx_t idx) +{ + if (idx == ADC_DIGI_FILTER_IDX0) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel0 = 0xF; + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor0 = 0; + } else if (idx == ADC_DIGI_FILTER_IDX1) { + APB_SARADC.saradc_filter_ctrl0.saradc_apb_saradc_filter_channel1 = 0xF; + APB_SARADC.saradc_filter_ctrl1.saradc_apb_saradc_filter_factor1 = 0; + } +} + +/** + * Set monitor mode of adc digital controller. + * + * @note If the channel info is not supported, the monitor function will not be enabled. + * @param adc_n ADC unit. + * @param is_larger true: If ADC_OUT > threshold, Generates monitor interrupt. + * false: If ADC_OUT < threshold, Generates monitor interrupt. + */ +static inline void adc_ll_digi_monitor_set_mode(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *cfg) +{ + if (idx == ADC_DIGI_MONITOR_IDX0) { + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7); + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_high = cfg->h_threshold; + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_low = cfg->l_threshold; + } else { // ADC_DIGI_MONITOR_IDX1 + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7); + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_low = cfg->h_threshold; + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_low = cfg->l_threshold; + } +} + +/** + * Enable/disable monitor of adc digital controller. + * + * @note If the channel info is not supported, the monitor function will not be enabled. + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx) +{ + if (idx == ADC_DIGI_MONITOR_IDX0) { + APB_SARADC.saradc_thres0_ctrl.saradc_apb_saradc_thres0_channel = 0xF; + } else { // ADC_DIGI_MONITOR_IDX1 + APB_SARADC.saradc_thres1_ctrl.saradc_apb_saradc_thres1_channel = 0xF; + } +} + +/** + * Set DMA eof num of adc digital controller. + * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. + * + * @param num eof num of DMA. + */ +static inline void adc_ll_digi_dma_set_eof_num(uint32_t num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_dma_conf, saradc_apb_adc_eof_num, num); +} + +/** + * Enable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_enable(void) +{ + APB_SARADC.saradc_dma_conf.saradc_apb_adc_trans = 1; +} + +/** + * Disable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_disable(void) +{ + APB_SARADC.saradc_dma_conf.saradc_apb_adc_trans = 0; +} + +/** + * Reset adc digital controller. + */ +static inline void adc_ll_digi_reset(void) +{ + APB_SARADC.saradc_dma_conf.saradc_apb_adc_reset_fsm = 1; + APB_SARADC.saradc_dma_conf.saradc_apb_adc_reset_fsm = 0; +} + +/*--------------------------------------------------------------- + PWDET(Power detect) controller setting +---------------------------------------------------------------*/ +/** + * Set adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @param cct Range: 0 ~ 7. + */ +static inline void adc_ll_pwdet_set_cct(uint32_t cct) +{ + (void)cct; +} + +/** + * Get adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @return cct Range: 0 ~ 7. + */ +static inline uint32_t adc_ll_pwdet_get_cct(void) +{ + return 0; +} + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ +/** + * Set ADC module power management. + * + * @param manage Set ADC power status. + */ +static inline void adc_ll_set_power_manage(adc_ll_power_t manage) +{ + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_POWER_SW_ON) { + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1; + APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 3; + } else if (manage == ADC_POWER_BY_FSM) { + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1; + APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 0; + } else if (manage == ADC_POWER_SW_OFF) { + APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0; + APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 2; + } +} + +__attribute__((always_inline)) +static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t ctrl) +{ + //Not used on ESP32C6 +} + +/* ADC calibration code. */ +/** + * @brief Set common calibration configuration. Should be shared with other parts (PWDET). + */ +__attribute__((always_inline)) +static inline void adc_ll_calibration_init(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); +} + +/** + * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. + * false: Use IO external voltage as calibration voltage. + */ +static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + /* Enable/disable internal connect GND (for calibration). */ + if (internal_gnd) { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1); + } else { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); + } +} + +/** + * Resume register status after calibration. + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_calibration_finish(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); +} + +/** + * Set the calibration result to ADC. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + */ +__attribute__((always_inline)) +static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + uint8_t msb = param >> 8; + uint8_t lsb = param & 0xFF; + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb); +} + +/*--------------------------------------------------------------- + Oneshot Read +---------------------------------------------------------------*/ +/** + * Set adc output data format for oneshot mode + * + * @note ESP32C6 Oneshot mode only supports 12bit. + * @param adc_n ADC unit. + * @param bits Output data bits width option. + */ +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) +{ + //ESP32C6 only supports 12bit, leave here for compatibility + HAL_ASSERT(bits == ADC_BITWIDTH_12 || bits == ADC_BITWIDTH_DEFAULT); +} + +/** + * Enable adc channel to start convert. + * + * @note Only one channel can be selected for measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | channel); +} + +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | 0xF); +} + +/** + * Start oneshot conversion by software + * + * @param val Usage: set to 1 to start the ADC conversion. The step signal should at least keep 3 ADC digital controller clock cycle, + * otherwise the step signal may not be captured by the ADC digital controller when its frequency is slow. + * This hardware limitation will be removed in future versions. + */ +static inline void adc_oneshot_ll_start(bool val) +{ + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_start = val; +} + +/** + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event_mask) +{ + APB_SARADC.saradc_int_clr.val |= event_mask; +} + +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event + * + * @return + * -true : The conversion process is finish. + * -false : The conversion process is not finish. + */ +static inline bool adc_oneshot_ll_get_event(uint32_t event_mask) +{ + return (APB_SARADC.saradc_int_raw.val & event_mask); +} + +/** + * Get the converted value for each ADCn for controller. + * + * @param adc_n ADC unit. + * @return + * - Converted value. + */ +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + uint32_t ret_val = 0; + ret_val = APB_SARADC.saradc_sar1data_status.saradc_apb_saradc1_data & 0xfff; + return ret_val; +} + +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 1: The data is correct to use. + * - 0: The data is invalid. + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + return true; +} + +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)inv_en; + //For compatibility +} + +/** + * Enable oneshot conversion trigger + * + * @param adc_n ADC unit + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 1; +} + +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) +{ + APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 0; + APB_SARADC.saradc_onetime_sample.saradc_saradc2_onetime_sample = 0; +} + +/** + * Set attenuation + * + * @note Attenuation is for all channels + * + * @param adc_n ADC unit + * @param channel ADC channel + * @param atten ADC attenuation + */ +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)channel; + // Attenuation is for all channels, unit and channel are for compatibility + APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_atten = atten; +} + +/** + * Get the attenuation of a particular channel on ADCn. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. + */ +__attribute__((always_inline)) +static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t channel) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)channel; + return (adc_atten_t)APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_atten; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h4/include/hal/adc_ll.h b/components/hal/esp32h4/include/hal/adc_ll.h index 6db694fc37..a187cfc1fa 100644 --- a/components/hal/esp32h4/include/hal/adc_ll.h +++ b/components/hal/esp32h4/include/hal/adc_ll.h @@ -16,6 +16,7 @@ #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" +#include "soc/clk_tree_defs.h" #include "hal/misc.h" #include "hal/regi2c_ctrl.h" @@ -35,9 +36,9 @@ extern "C" { #define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) typedef enum { - ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ - ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ - ADC_POWER_SW_OFF, /*!< ADC XPD controled by SW. power off. */ + ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */ ADC_POWER_MAX, /*!< For parameter check. */ } adc_ll_power_t; @@ -57,11 +58,11 @@ typedef enum { * @brief ADC digital controller (DMA mode) work mode. * * @note The conversion mode affects the sampling frequency: - * ESP32H4 only support ALTER_UNIT mode - * ALTER_UNIT : When the measurement is triggered, ADC1 or ADC2 samples alternately. + * ESP32H4 only support ONLY_ADC1 mode + * SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once. */ typedef enum { - ADC_LL_DIGI_CONV_ALTER_UNIT = 0, // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 ..... + ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion } adc_ll_digi_convert_mode_t; //These values should be set according to the HW @@ -130,7 +131,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) */ static inline void adc_ll_digi_set_clk_div(uint32_t div) { - /* ADC clock devided from digital controller clock clk */ + /* ADC clock divided from digital controller clock clk */ HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div); } @@ -165,7 +166,7 @@ static inline void adc_ll_digi_convert_limit_enable(bool enable) */ static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode) { - //ESP32H4 only supports ADC_CONV_ALTER_UNIT mode + //ESP32H4 only supports ADC_LL_DIGI_CONV_ONLY_ADC1 mode } /** @@ -289,15 +290,12 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div /** * Enable clock and select clock source for ADC digital controller. * - * @param use_apll true: use APLL clock; false: use APB clock. + * @param clk_src clock source for ADC digital controller. */ -static inline void adc_ll_digi_clk_sel(bool use_apll) +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) { - if (use_apll) { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 1; // APLL clock - } else { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 2; // APB clock - } + // TODO: temporary support + APB_SARADC.apb_adc_clkm_conf.clk_sel = 0; APB_SARADC.ctrl.sar_clk_gated = 1; } @@ -674,22 +672,6 @@ static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param } /* Temp code end. */ -/** - * Output ADCn inter reference voltage to ADC2 channels. - * - * This function routes the internal reference voltage of ADCn to one of - * ADC1's channels. This reference voltage can then be manually measured - * for calibration purposes. - * - * @param[in] adc ADC unit select - * @param[in] channel ADC1 channel number - * @param[in] en Enable/disable the reference voltage output - */ -static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, bool en) -{ - abort(); -} - /*--------------------------------------------------------------- Single Read ---------------------------------------------------------------*/ diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 0120e427e0..fc8f730a05 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -14,10 +14,12 @@ #include "hal/assert.h" #include "soc/apb_saradc_struct.h" #include "soc/sens_struct.h" +#include "soc/sens_reg.h" #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/regi2c_defs.h" +#include "soc/clk_tree_defs.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" @@ -35,9 +37,9 @@ extern "C" { #define ADC_LL_EVENT_ADC2_ONESHOT_DONE (1 << 1) typedef enum { - ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ - ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ - ADC_POWER_SW_OFF, /*!< ADC XPD controled by SW. power off. */ + ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */ ADC_POWER_MAX, /*!< For parameter check. */ } adc_ll_power_t; @@ -145,7 +147,7 @@ static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) */ static inline void adc_ll_digi_set_clk_div(uint32_t div) { - /* ADC clock devided from digital controller clock clk */ + /* ADC clock divided from digital controller clock clk */ HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div); } @@ -335,15 +337,11 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div /** * Enable clock and select clock source for ADC digital controller. * - * @param use_apll true: use APLL clock; false: use APB clock. + * @param clk_src clock source for ADC digital controller. */ -static inline void adc_ll_digi_clk_sel(bool use_apll) +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) { - if (use_apll) { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 1; // APLL clock - } else { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 2; // APB clock - } + APB_SARADC.apb_adc_clkm_conf.clk_sel = (clk_src == ADC_DIGI_CLK_SRC_APLL) ? 1 : 2; APB_SARADC.ctrl.sar_clk_gated = 1; } @@ -568,7 +566,7 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) RTC controller setting ---------------------------------------------------------------*/ /** - * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`. + * ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`. * * @param div Division factor. */ @@ -798,7 +796,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * * When VDD_A is 3.3V: * - * - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V + * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below) @@ -810,7 +808,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: * - * - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV + * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index 7dbd63f665..e0a5e8d03b 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -19,6 +19,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/regi2c_defs.h" +#include "soc/clk_tree_defs.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" @@ -36,9 +37,9 @@ extern "C" { #define ADC_LL_EVENT_ADC2_ONESHOT_DONE (1 << 1) typedef enum { - ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ - ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ - ADC_POWER_SW_OFF, /*!< ADC XPD controled by SW. power off. */ + ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */ ADC_POWER_MAX, /*!< For parameter check. */ } adc_ll_power_t; @@ -341,15 +342,11 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div /** * Enable clock and select clock source for ADC digital controller. * - * @param use_apll true: use APLL clock; false: use APB clock. + * @param clk_src clock source for ADC digital controller. */ -static inline void adc_ll_digi_clk_sel(bool use_apll) +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) { - if (use_apll) { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 1; // APLL clock - } else { - APB_SARADC.apb_adc_clkm_conf.clk_sel = 2; // APB clock - } + APB_SARADC.apb_adc_clkm_conf.clk_sel = (clk_src == ADC_DIGI_CLK_SRC_APB) ? 2 : 1; APB_SARADC.ctrl.sar_clk_gated = 1; } @@ -787,7 +784,7 @@ static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, boo RTC controller setting ---------------------------------------------------------------*/ /** - * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`. + * ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`. * * @param div Division factor. */ @@ -1017,7 +1014,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * * When VDD_A is 3.3V: * - * - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V + * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below) @@ -1029,7 +1026,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: * - * - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV + * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index a88b1e7669..0bb33574b7 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -116,20 +116,6 @@ typedef struct adc_hal_digi_ctrlr_cfg_t { */ #define adc_hal_pwdet_get_cct() adc_ll_pwdet_get_cct() -/** - * Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels. - * - * This function routes the internal reference voltage of ADCn to one of - * ADC2's channels. This reference voltage can then be manually measured - * for calibration purposes. - * - * @note ESP32 only supports output of ADC2's internal reference voltage. - * @param[in] adc ADC unit select - * @param[in] channel ADC2 channel number - * @param[in] en Enable/disable the reference voltage output - */ -#define adc_hal_vref_output(adc, channel, en) adc_ll_vref_output(adc, channel, en) - /*--------------------------------------------------------------- Digital controller setting ---------------------------------------------------------------*/ diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index 9f06cb236f..8568c195c5 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -9,6 +9,7 @@ #include #include "sdkconfig.h" #include "soc/soc_caps.h" +#include "soc/clk_tree_defs.h" #include "esp_attr.h" /** @@ -78,6 +79,14 @@ typedef enum { ADC_DIGI_OUTPUT_FORMAT_TYPE2, ///< See `adc_digi_output_data_t.type2` } adc_digi_output_format_t; +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED +typedef soc_periph_adc_digi_clk_src_t adc_oneshot_clk_src_t; ///< Clock source type of oneshot mode which uses digital controller +typedef soc_periph_adc_digi_clk_src_t adc_continuous_clk_src_t; ///< Clock source type of continuous mode which uses digital controller +#elif SOC_ADC_RTC_CTRL_SUPPORTED +typedef soc_periph_adc_rtc_clk_src_t adc_oneshot_clk_src_t; ///< Clock source type of oneshot mode which uses RTC controller +typedef soc_periph_adc_digi_clk_src_t adc_continuous_clk_src_t; ///< Clock source type of continuous mode which uses digital controller +#endif + /** * @brief ADC digital controller pattern configuration */ @@ -155,6 +164,26 @@ typedef struct { uint32_t val; /*! ADC_CHANNEL_MAX), The data is invalid. */ + uint32_t reserved17_31: 15; /*!type1.channel) +#define EXAMPLE_ADC_GET_DATA(p_data) ((p_data)->type1.data) #else -#define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2 +#define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2 +#define EXAMPLE_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel) +#define EXAMPLE_ADC_GET_DATA(p_data) ((p_data)->type2.data) #endif +#define EXAMPLE_READ_LEN 256 + #if CONFIG_IDF_TARGET_ESP32 static adc_channel_t channel[2] = {ADC_CHANNEL_6, ADC_CHANNEL_7}; #else @@ -61,16 +70,14 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc 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 = ADC_UNIT_1; - uint8_t ch = channel[i] & 0x7; - adc_pattern[i].atten = ADC_ATTEN_DB_0; - adc_pattern[i].channel = ch; - adc_pattern[i].unit = unit; - adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; + adc_pattern[i].atten = EXAMPLE_ADC_ATTEN; + adc_pattern[i].channel = channel[i] & 0x7; + adc_pattern[i].unit = EXAMPLE_ADC_UNIT; + adc_pattern[i].bit_width = EXAMPLE_ADC_BIT_WIDTH; - ESP_LOGI(TAG, "adc_pattern[%d].atten is :%x", i, adc_pattern[i].atten); - ESP_LOGI(TAG, "adc_pattern[%d].channel is :%x", i, adc_pattern[i].channel); - ESP_LOGI(TAG, "adc_pattern[%d].unit is :%x", i, adc_pattern[i].unit); + ESP_LOGI(TAG, "adc_pattern[%d].atten is :%"PRIx8, i, adc_pattern[i].atten); + ESP_LOGI(TAG, "adc_pattern[%d].channel is :%"PRIx8, i, adc_pattern[i].channel); + ESP_LOGI(TAG, "adc_pattern[%d].unit is :%"PRIx8, i, adc_pattern[i].unit); } dig_cfg.adc_pattern = adc_pattern; ESP_ERROR_CHECK(adc_continuous_config(handle, &dig_cfg)); @@ -78,21 +85,6 @@ static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc *out_handle = handle; } -static bool check_valid_data(const adc_digi_output_data_t *data) -{ -#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; -} - void app_main(void) { esp_err_t ret; @@ -123,20 +115,21 @@ void app_main(void) */ ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + char unit[] = EXAMPLE_ADC_UNIT_STR(EXAMPLE_ADC_UNIT); + while (1) { ret = adc_continuous_read(handle, result, EXAMPLE_READ_LEN, &ret_num, 0); if (ret == ESP_OK) { 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 (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 + uint32_t chan_num = EXAMPLE_ADC_GET_CHANNEL(p); + uint32_t data = EXAMPLE_ADC_GET_DATA(p); + /* Check the channel number validation, the data is invalid if the channel num exceed the maximum channel */ + if (chan_num < SOC_ADC_CHANNEL_NUM(EXAMPLE_ADC_UNIT)) { + ESP_LOGI(TAG, "Unit: %s, Channel: %"PRIu32", Value: %"PRIx32, unit, chan_num, data); } else { - ESP_LOGI(TAG, "Invalid data"); + ESP_LOGW(TAG, "Invalid data [%s_%"PRIu32"_%"PRIx32"]", unit, chan_num, data); } } /** diff --git a/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py b/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py index c4156a7865..556ddff5f5 100644 --- a/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py +++ b/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py @@ -9,6 +9,7 @@ from pytest_embedded.dut import Dut @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c6 @pytest.mark.adc def test_adc_continuous(dut: Dut) -> None: res = dut.expect(r'TASK: ret is 0, ret_num is (\d+)') diff --git a/examples/peripherals/adc/oneshot_read/README.md b/examples/peripherals/adc/oneshot_read/README.md index 93700344f8..8cbce51458 100644 --- a/examples/peripherals/adc/oneshot_read/README.md +++ b/examples/peripherals/adc/oneshot_read/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | # ADC Single Read Example diff --git a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py index 8f2c266e99..af2b45cfd1 100644 --- a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py +++ b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py @@ -9,6 +9,7 @@ from pytest_embedded.dut import Dut @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32c3 +@pytest.mark.esp32c6 @pytest.mark.adc def test_adc_oneshot(dut: Dut) -> None: dut.expect(r'EXAMPLE: ADC1 Channel\[(\d+)\] Raw Data: (\d+)', timeout=5)