adc: support ADC on esp32c6 (driver/test/example)

This commit is contained in:
laokaiyao 2022-12-05 16:01:34 +08:00
parent e27f3e3128
commit 5333ac81bf
50 changed files with 363 additions and 331 deletions

View File

@ -40,9 +40,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:

View File

@ -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();

View File

@ -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 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

View File

@ -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

View File

@ -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',

View File

@ -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

View File

@ -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

View File

@ -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 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

View File

@ -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

View File

@ -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',

View File

@ -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")

View File

@ -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);

View File

@ -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")

View File

@ -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:

View File

@ -13,6 +13,7 @@
#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"
@ -46,12 +47,6 @@ typedef enum {
ADC_LL_CTRL_PWDET = 3, ///< For ADC2. Select PWDET controller.
} adc_ll_controller_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/**
* @brief ADC digital controller (DMA mode) work mode.
*

View File

@ -51,12 +51,6 @@ typedef enum {
ADC_LL_CTRL_DIG = 0, ///< For ADC1. Select DIG controller.
} adc_ll_controller_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
@ -150,9 +144,9 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
*
* @param clk_src clock source for ADC digital controller.
*/
static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
{
APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = (clk_src == ADC_DIGI_CLK_SRC_XTAL);
APB_SARADC.saradc_apb_adc_clkm_conf.saradc_reg_clk_sel = 2;
APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1;
}

View File

@ -36,8 +36,8 @@ 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 {
@ -59,21 +59,15 @@ typedef enum {
ADC_LL_CTRL_ARB = 1, ///< For ADC2. The controller is selected by the arbiter.
} adc_ll_controller_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/**
* @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 {
@ -166,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
}
/**
@ -292,10 +286,10 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
*
* @param clk_src clock source for ADC digital controller.
*/
static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
{
// Only support APB clock, should always set to 0
APB_SARADC.apb_adc_clkm_conf.clk_sel = 0;
// 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;
}
@ -647,6 +641,60 @@ 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)
{
if (en) {
REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 3);
SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 2);
SET_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN);
SET_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_GRANT_FORCE);
SET_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_APB_FORCE);
APB_SARADC.sar_patt_tab[0].sar_patt_tab1 = 0xFFFFFF;
APB_SARADC.sar_patt_tab[1].sar_patt_tab1 = 0xFFFFFF;
APB_SARADC.onetime_sample.adc1_onetime_sample = 1;
APB_SARADC.onetime_sample.onetime_channel = channel;
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU);
if (adc == ADC_UNIT_1) {
/* Config test mux to route v_ref to ADC1 Channels */
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 1);
} else {
/* Config test mux to route v_ref to ADC2 Channels */
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
}
} else {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
APB_SARADC.onetime_sample.adc1_onetime_sample = 0;
APB_SARADC.onetime_sample.onetime_channel = 0xf;
REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0);
REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 0);
CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN);
CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_GRANT_FORCE);
CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_APB_FORCE);
}
}
/*---------------------------------------------------------------
Oneshot Read
---------------------------------------------------------------*/

View File

@ -10,7 +10,7 @@
Single Read
---------------------------------------------------------------*/
#define ADC_HAL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0)
#define ADC_HAL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) ((PERIPH_NUM==0)? 2 : 1)
#define ADC_HAL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (2)
/*---------------------------------------------------------------
DMA Read

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -20,6 +20,7 @@
#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"
@ -36,49 +37,30 @@ 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 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_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_RTC_DATA_OK = 0,
ADC_RTC_CTRL_UNSELECTED = 1,
ADC_RTC_CTRL_BREAK = 2,
ADC_RTC_DATA_FAIL = -1,
} adc_ll_rtc_raw_data_t;
typedef enum {
ADC_LL_CTRL_DIG = 0, ///< Only support ADC1, i.e. only digital controller available.
ADC_LL_CTRL_DIG = 0, ///< ADC digital controller
} adc_ll_controller_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/**
* @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.
* 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_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 {
@ -123,9 +105,7 @@ static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wa
*/
static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
{
// TODO: [adc_c6] Maybe this REG I2C for peripheral needs a reference lock
/* Should be called before writing I2C registers. */
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
/* Peripheral reg i2c has powered up in rtc_init, write directly */
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle);
}
@ -137,7 +117,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);
}
@ -166,18 +146,18 @@ static inline void adc_ll_digi_convert_limit_enable(bool enable)
/**
* Set adc conversion mode for digital controller.
*
* @note ESP32C3 only support ADC1 single mode.
* @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)
{
//ESP32C3 only supports ADC_CONV_ALTER_UNIT 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 8 items, in which channel selection,
* 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.
*
@ -191,7 +171,7 @@ static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t
/**
* Set pattern table for digital controller.
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 8 items, in which channel selection,
* 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.
*
@ -208,15 +188,15 @@ static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t patt
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
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
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
}
}
@ -252,8 +232,6 @@ 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
} else { // adc_n == ADC_UNIT_2
APB_SARADC.saradc_ctrl2.saradc_saradc_sar2_inv = inv_en; // Enable / Disable ADC data invert
}
}
@ -305,7 +283,7 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
*
* @param clk_src clock source for ADC digital controller.
*/
static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
{
switch (clk_src) {
case ADC_DIGI_CLK_SRC_XTAL:
@ -318,10 +296,10 @@ static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
PCR.saradc_clkm_conf.saradc_clkm_sel = 2;
break;
default:
PCR.saradc_clkm_conf.saradc_clkm_sel = 1;
HAL_ASSERT(false && "unsupported clock");
}
// Enable ADC_CTRL_CLK (i.e. digital domain clock)
PCR.saradc_clkm_conf.saradc_clkm_en = 1;
APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 1;
}
/**
@ -329,7 +307,7 @@ static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
*/
static inline void adc_ll_digi_controller_clk_disable(void)
{
PCR.saradc_clkm_conf.saradc_clkm_en = 0;
APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0;
}
/**
@ -480,9 +458,7 @@ static inline void adc_ll_digi_reset(void)
*/
static inline void adc_ll_pwdet_set_cct(uint32_t cct)
{
/* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
// RTCCNTL.sensor_ctrl.sar2_pwdet_cct = cct;
// TODO: [adc_c6] check cct validation on C6
(void)cct;
}
/**
@ -493,9 +469,6 @@ static inline void adc_ll_pwdet_set_cct(uint32_t cct)
*/
static inline uint32_t adc_ll_pwdet_get_cct(void)
{
/* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
// return RTCCNTL.sensor_ctrl.sar2_pwdet_cct;
// TODO: [adc_c6] check cct validation on C6
return 0;
}
@ -512,13 +485,13 @@ 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) {
PCR.saradc_clkm_conf.saradc_clkm_en = 1;
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) {
PCR.saradc_clkm_conf.saradc_clkm_en = 1;
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) {
PCR.saradc_clkm_conf.saradc_clkm_en = 0;
APB_SARADC.saradc_ctrl.saradc_saradc_sar_clk_gated = 0;
APB_SARADC.saradc_ctrl.saradc_saradc_xpd_sar_force = 2;
}
}
@ -536,11 +509,8 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c
__attribute__((always_inline))
static inline void adc_ll_calibration_init(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1);
} else {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_DREF_ADDR, 1);
}
HAL_ASSERT(adc_n == ADC_UNIT_1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1);
}
/**
@ -554,19 +524,12 @@ static inline void adc_ll_calibration_init(adc_unit_t adc_n)
*/
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 (adc_n == ADC_UNIT_1) {
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);
}
if (internal_gnd) {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1);
} else {
if (internal_gnd) {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 1);
} else {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
}
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
}
}
@ -577,11 +540,8 @@ static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gn
*/
static inline void adc_ll_calibration_finish(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
} else {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
}
HAL_ASSERT(adc_n == ADC_UNIT_1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
}
/**
@ -594,17 +554,12 @@ static inline void adc_ll_calibration_finish(adc_unit_t adc_n)
__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;
if (adc_n == ADC_UNIT_1) {
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);
} else {
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, msb);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, lsb);
}
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);
}
/* Temp code end. */
/*---------------------------------------------------------------
Oneshot Read
@ -612,13 +567,13 @@ static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param
/**
* Set adc output data format for oneshot mode
*
* @note ESP32C3 Oneshot mode only supports 12bit.
* @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)
{
//ESP32C3 only supports 12bit, leave here for compatibility
//ESP32C6 only supports 12bit, leave here for compatibility
HAL_ASSERT(bits == ADC_BITWIDTH_12 || bits == ADC_BITWIDTH_DEFAULT);
}
@ -632,6 +587,7 @@ static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth
*/
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);
}
@ -644,11 +600,8 @@ static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t ch
*/
static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | 0xF);
} else { // adc_n == ADC_UNIT_2
APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | 0x1);
}
HAL_ASSERT(adc_n == ADC_UNIT_1);
APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_channel = ((adc_n << 3) | 0xF);
}
/**
@ -688,7 +641,7 @@ static inline bool adc_oneshot_ll_get_event(uint32_t event_mask)
}
/**
* Get the converted value for each ADCn for RTC controller.
* Get the converted value for each ADCn for controller.
*
* @param adc_n ADC unit.
* @return
@ -696,12 +649,9 @@ static inline bool adc_oneshot_ll_get_event(uint32_t event_mask)
*/
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;
if (adc_n == ADC_UNIT_1) {
ret_val = APB_SARADC.saradc_sar1data_status.saradc_apb_saradc1_data & 0xfff;
} else { // adc_n == ADC_UNIT_2
ret_val = APB_SARADC.saradc_sar2data_status.saradc_apb_saradc2_data & 0xfff;
}
ret_val = APB_SARADC.saradc_sar1data_status.saradc_apb_saradc1_data & 0xfff;
return ret_val;
}
@ -717,15 +667,7 @@ static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n)
*/
static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data)
{
if (adc_n == ADC_UNIT_1) {
return true;
}
//The raw data API returns value without channel information. Read value directly from the register
if (((APB_SARADC.saradc_sar2data_status.saradc_apb_saradc2_data >> 13) & 0xF) > 9) {
return false;
}
HAL_ASSERT(adc_n == ADC_UNIT_1);
return true;
}
@ -737,7 +679,7 @@ static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw
*/
static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en)
{
(void)adc_n;
HAL_ASSERT(adc_n == ADC_UNIT_1);
(void)inv_en;
//For compatibility
}
@ -749,11 +691,8 @@ static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en)
*/
static inline void adc_oneshot_ll_enable(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 1;
} else {
APB_SARADC.saradc_onetime_sample.saradc_saradc2_onetime_sample = 1;
}
HAL_ASSERT(adc_n == ADC_UNIT_1);
APB_SARADC.saradc_onetime_sample.saradc_saradc1_onetime_sample = 1;
}
/**
@ -776,7 +715,7 @@ static inline void adc_oneshot_ll_disable_all_unit(void)
*/
static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten)
{
(void)adc_n;
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;
@ -792,7 +731,7 @@ static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t chan
__attribute__((always_inline))
static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t channel)
{
(void)adc_n;
HAL_ASSERT(adc_n == ADC_UNIT_1);
(void)channel;
return (adc_atten_t)APB_SARADC.saradc_onetime_sample.saradc_saradc_onetime_atten;
}

View File

@ -54,21 +54,15 @@ typedef enum {
ADC_LL_CTRL_ARB = 1, ///< For ADC2. The controller is selected by the arbiter.
} adc_ll_controller_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/**
* @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
@ -172,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
}
/**
@ -298,7 +292,7 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
*
* @param clk_src clock source for ADC digital controller.
*/
static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
{
// TODO: temporary support
APB_SARADC.apb_adc_clkm_conf.clk_sel = 0;

View File

@ -14,6 +14,7 @@
#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"
@ -56,12 +57,6 @@ typedef enum {
ADC_LL_CTRL_ARB = 3, ///< For ADC2. The controller is selected by the arbiter.
} adc_ll_controller_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/**
* @brief ADC digital controller (DMA mode) work mode.
*
@ -344,7 +339,7 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
*
* @param clk_src clock source for ADC digital controller.
*/
static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
{
APB_SARADC.apb_adc_clkm_conf.clk_sel = (clk_src == ADC_DIGI_CLK_SRC_APLL) ? 1 : 2;
APB_SARADC.ctrl.sar_clk_gated = 1;

View File

@ -57,12 +57,6 @@ typedef enum {
ADC_LL_CTRL_ARB = 3, ///< For ADC2. The controller is selected by the arbiter.
} adc_ll_controller_t;
/**
* @brief Clock source of ADC digital controller
* @note Not public as it always uses a default value for now
*/
typedef soc_periph_adc_digi_clk_src_t adc_ll_digi_clk_src_t;
/**
* @brief ADC digital controller (DMA mode) work mode.
*
@ -350,7 +344,7 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
*
* @param clk_src clock source for ADC digital controller.
*/
static inline void adc_ll_digi_clk_sel(adc_ll_digi_clk_src_t clk_src)
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
{
APB_SARADC.apb_adc_clkm_conf.clk_sel = (clk_src == ADC_DIGI_CLK_SRC_APB) ? 2 : 1;
APB_SARADC.ctrl.sar_clk_gated = 1;

View File

@ -9,6 +9,7 @@
#include <stdint.h>
#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; /*!<Raw data value */
};
} adc_digi_output_data_t;
#elif CONFIG_IDF_TARGET_ESP32C6
/**
* @brief ADC digital controller (DMA mode) output data format.
* Used to analyze the acquired ADC (DMA) data.
*/
typedef struct {
union {
struct {
uint32_t data: 12; /*!<ADC real output data info. Resolution: 12 bit. */
uint32_t reserved12: 1; /*!<Reserved12. */
uint32_t channel: 4; /*!<ADC channel index info.
If (channel < ADC_CHANNEL_MAX), The data is valid.
If (channel > ADC_CHANNEL_MAX), The data is invalid. */
uint32_t reserved17_31: 15; /*!<Reserved 17-31. */
} type2; /*!<When the configured output format is 12bit. */
uint32_t val; /*!<Raw data value */
};
} adc_digi_output_data_t;
#endif
#if CONFIG_IDF_TARGET_ESP32S2

View File

@ -142,7 +142,7 @@ typedef struct {
adc_channel_t channel; /*!<Set adc channel number for monitor.
For ESP32-S2, it's always `ADC_CHANNEL_MAX` */
adc_digi_monitor_mode_t mode; /*!<Set adc monitor mode. See ``adc_digi_monitor_mode_t``. */
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
#if SOC_ADC_DIGI_SEGMENTED_THRESH
uint32_t h_threshold; /*!<Set monitor threshold of adc digital controller. */
uint32_t l_threshold; /*!<Set monitor threshold of adc digital controller. */
#else

View File

@ -337,19 +337,32 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of ADC digital controller
*/
#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_APLL, SOC_MOD_CLK_PLL_D2}
#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_APLL, SOC_MOD_CLK_PLL_F160M}
/**
* @brief ADC digital controller clock source
* @note ADC digital controller is clocked from I2S on ESP32
* @note ADC DMA mode is clocked from I2S on ESP32, using `ADC_DIGI_` here for compatibility
* Its clock source is same as I2S
*/
typedef enum {
ADC_DIGI_CLK_SRC_F160M = SOC_MOD_CLK_PLL_D2,
ADC_DIGI_CLK_SRC_APLL = SOC_MOD_CLK_APLL,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_D2,
ADC_DIGI_CLK_SRC_PLL_F160M = SOC_MOD_CLK_PLL_F160M, /*!< Select F160M as the source clock */
ADC_DIGI_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select F160M as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
/**
* @brief Array initializer for all supported clock sources of ADC RTC controller
*/
#define SOC_ADC_RTC_CLKS {SOC_MOD_CLK_RC_FAST}
/**
* @brief ADC RTC controller clock source
*/
typedef enum {
ADC_RTC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the default clock choice */
} soc_periph_adc_rtc_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -103,6 +103,10 @@ config SOC_ADC_ATTEN_NUM
int
default 4
config SOC_ADC_DIGI_SEGMENTED_THRESH
bool
default y
config SOC_ADC_DIGI_CONTROLLER_NUM
int
default 1

View File

@ -194,9 +194,9 @@ typedef enum {
* @brief Type of I2C clock source.
*/
typedef enum {
I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
I2C_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
I2C_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
} soc_periph_i2c_clk_src_t;
//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
@ -210,9 +210,9 @@ typedef enum {
* @brief ADC digital controller clock source
*/
typedef enum {
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
ADC_DIGI_CLK_SRC_F80M = SOC_MOD_CLK_PLL_F80M,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
#ifdef __cplusplus

View File

@ -59,6 +59,7 @@
#define SOC_ADC_ATTEN_NUM (4)
/*!< Digital */
#define SOC_ADC_DIGI_SEGMENTED_THRESH 1
#define SOC_ADC_DIGI_CONTROLLER_NUM (1U)
#define SOC_ADC_PATT_LEN_MAX (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */
#define SOC_ADC_DIGI_MIN_BITWIDTH (12)

View File

@ -175,6 +175,10 @@ config SOC_ADC_ATTEN_NUM
int
default 4
config SOC_ADC_DIGI_SEGMENTED_THRESH
bool
default y
config SOC_ADC_DIGI_CONTROLLER_NUM
int
default 1

View File

@ -284,8 +284,8 @@ typedef enum {
* @brief ADC digital controller clock source
*/
typedef enum {
ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,
ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
#ifdef __cplusplus

View File

@ -85,6 +85,7 @@
#define SOC_ADC_ATTEN_NUM (4)
/*!< Digital */
#define SOC_ADC_DIGI_SEGMENTED_THRESH 1
#define SOC_ADC_DIGI_CONTROLLER_NUM (1U)
#define SOC_ADC_PATT_LEN_MAX (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */
#define SOC_ADC_DIGI_MIN_BITWIDTH (12)

View File

@ -139,6 +139,10 @@ config SOC_ADC_MONITOR_SUPPORTED
bool
default y
config SOC_ADC_DMA_SUPPORTED
bool
default y
config SOC_ADC_PERIPH_NUM
int
default 1
@ -151,6 +155,10 @@ config SOC_ADC_ATTEN_NUM
int
default 4
config SOC_ADC_DIGI_SEGMENTED_THRESH
bool
default y
config SOC_ADC_DIGI_CONTROLLER_NUM
int
default 1
@ -163,6 +171,10 @@ config SOC_ADC_DIGI_MAX_BITWIDTH
int
default 12
config SOC_ADC_DIGI_MIN_BITWIDTH
int
default 12
config SOC_ADC_DIGI_FILTER_NUM
int
default 2
@ -171,6 +183,14 @@ config SOC_ADC_DIGI_MONITOR_NUM
int
default 2
config SOC_ADC_DIGI_RESULT_BYTES
int
default 4
config SOC_ADC_DIGI_DATA_BYTES_PER_CONV
int
default 4
config SOC_ADC_SAMPLE_FREQ_THRES_HIGH
int
default 83333

View File

@ -325,10 +325,10 @@ typedef enum {
* @brief ADC digital controller clock source
*/
typedef enum {
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M,
ADC_DIGI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
ADC_DIGI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
#ifdef __cplusplus

View File

@ -77,17 +77,23 @@
#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_DMA_SUPPORTED 1
#define SOC_ADC_PERIPH_NUM (1U)
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (7)
#define SOC_ADC_MAX_CHANNEL_NUM (7)
#define SOC_ADC_ATTEN_NUM (4)
/*!< Digital */
#define SOC_ADC_DIGI_SEGMENTED_THRESH 1
#define SOC_ADC_DIGI_CONTROLLER_NUM (1U)
#define SOC_ADC_PATT_LEN_MAX (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */
#define SOC_ADC_PATT_LEN_MAX (8) /*!< Two pattern tables, each contains 4 items. Each item takes 1 byte */
#define SOC_ADC_DIGI_MAX_BITWIDTH (12)
#define SOC_ADC_DIGI_MIN_BITWIDTH (12)
#define SOC_ADC_DIGI_FILTER_NUM (2)
#define SOC_ADC_DIGI_MONITOR_NUM (2)
#define SOC_ADC_DIGI_RESULT_BYTES (4)
#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (4)
/*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interval <= 4095 */
#define SOC_ADC_SAMPLE_FREQ_THRES_HIGH 83333
#define SOC_ADC_SAMPLE_FREQ_THRES_LOW 611

View File

@ -351,12 +351,12 @@ typedef enum {
*/
// TODO: temporary support, need to check while supporting
typedef enum {
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
ADC_DIGI_CLK_SRC_F80M = SOC_MOD_CLK_PLL_F80M,
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
#if CONFIG_IDF_ENV_FPGA
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
#else
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */
#endif
} soc_periph_adc_digi_clk_src_t;

View File

@ -163,6 +163,10 @@ config SOC_ADC_ATTEN_NUM
int
default 4
config SOC_ADC_DIGI_SEGMENTED_THRESH
bool
default y
config SOC_ADC_DIGI_CONTROLLER_NUM
int
default 1

View File

@ -112,6 +112,7 @@ typedef enum {
// For digital domain: peripherals, WIFI, BLE
SOC_MOD_CLK_AHB, /*< AHB_CLK sources from CPU with a configurable divider */
SOC_MOD_CLK_APB, /*< APB_CLK source is derived from AHB clock */
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */
SOC_MOD_CLK_XTAL32K, /*< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*< RC_FAST_CLK comes from the internal 8MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*< XTAL_CLK comes from the external 32MHz crystal */
@ -283,20 +284,16 @@ typedef enum {
* @brief Array initializer for all supported clock sources of ADC digital controller
*/
// TODO: temporary support, need to check while supporting
#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_APB}
#define SOC_ADC_DIGI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M}
/**
* @brief ADC digital controller clock source
*/
// TODO: temporary support, need to check while supporting
typedef enum {
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
ADC_DIGI_CLK_SRC_F80M = SOC_MOD_CLK_APB,
#if CONFIG_IDF_ENV_FPGA
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
#else
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,
#endif
ADC_DIGI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
ADC_DIGI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
#ifdef __cplusplus

View File

@ -87,6 +87,7 @@
#define SOC_ADC_ATTEN_NUM (4)
/*!< Digital */
#define SOC_ADC_DIGI_SEGMENTED_THRESH 1
#define SOC_ADC_DIGI_CONTROLLER_NUM (1U)
#define SOC_ADC_PATT_LEN_MAX (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */
#define SOC_ADC_DIGI_MIN_BITWIDTH (12)

View File

@ -331,11 +331,24 @@ typedef enum {
* @brief ADC digital controller clock source
*/
typedef enum {
ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB,
ADC_DIGI_CLK_SRC_APLL = SOC_MOD_CLK_APLL,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,
ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
ADC_DIGI_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
/**
* @brief Array initializer for all supported clock sources of ADC RTC controller
*/
#define SOC_ADC_RTC_CLKS {SOC_MOD_CLK_RC_FAST}
/**
* @brief ADC RTC controller clock source
*/
typedef enum {
ADC_RTC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the default clock choice */
} soc_periph_adc_rtc_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -329,11 +329,24 @@ typedef enum {
* @brief ADC digital controller clock source
*/
typedef enum {
ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB,
ADC_DIGI_CLK_SRC_PLL_D2 = SOC_MOD_CLK_PLL_D2,
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,
ADC_DIGI_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
ADC_DIGI_CLK_SRC_PLL_F240M = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 (default value PLL_F240M) as the source clock */
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
/**
* @brief Array initializer for all supported clock sources of ADC RTC controller
*/
#define SOC_ADC_RTC_CLKS {SOC_MOD_CLK_RC_FAST}
/**
* @brief ADC RTC controller clock source
*/
typedef enum {
ADC_RTC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the default clock choice */
} soc_periph_adc_rtc_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -8,23 +8,7 @@
#include "soc/soc.h"
#include "soc/soc_caps.h"
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310
#include "soc/syscon_struct.h"
#endif
#if SOC_ADC_RTC_CTRL_SUPPORTED
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#endif
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#include "soc/rtc_io_struct.h"
#endif
#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5310
#include "soc/rtc_cntl_struct.h"
#endif
#include "soc/adc_channel.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {

View File

@ -91,8 +91,6 @@ api-reference/storage/sdmmc
api-reference/storage/mass_mfg
api-reference/storage/index
api-reference/peripherals
api-reference/peripherals/adc_continuous
api-reference/peripherals/adc_oneshot
api-reference/peripherals/usb_host
api-reference/peripherals/hmac
api-reference/peripherals/usb_device

View File

@ -1,13 +1,14 @@
Analog to Digital Converter (ADC) Continuous Mode Driver
========================================================
{IDF_TARGET_ADC_NUM:default="two", esp32c2="one", esp32c6="one", esp32h4="one"}
Introduction
------------
The Analog to Digital Converter is an on-chip sensor which is able to measure analog signals from specific analog IO pads.
The ADC on {IDF_TARGET_NAME} can be used in scenario(s) like:
{IDF_TARGET_NAME} has {IDF_TARGET_ADC_NUM} ADC unit(s), which can be used in scenario(s) like:
- Generate one-shot ADC conversion result
- Generate continuous ADC conversion results

View File

@ -1,13 +1,14 @@
Analog to Digital Converter (ADC) Oneshot Mode Driver
=====================================================
{IDF_TARGET_ADC_NUM:default="two", esp32c2="one", esp32c6="one", esp32h4="one"}
Introduction
------------
The Analog to Digital Converter is an on-chip sensor which is able to measure analog signals from dedicated analog IO pads.
The ADC on {IDF_TARGET_NAME} can be used in scenario(s) like:
{IDF_TARGET_NAME} has {IDF_TARGET_ADC_NUM} ADC unit(s), which can be used in scenario(s) like:
- Generate one-shot ADC conversion result

View File

@ -2,15 +2,11 @@
examples/peripherals/adc/continuous_read:
disable:
- if: IDF_TARGET == "esp32c2" or IDF_TARGET == "esp32c6"
temporary: true
reason: adc dma mode isn't supported on these targets
- if: SOC_ADC_DMA_SUPPORTED != 1
examples/peripherals/adc/oneshot_read:
disable:
- if: IDF_TARGET == "esp32c6"
temporary: true
reason: target esp32c6 is not supported yet
- if: SOC_ADC_SUPPORTED != 1
examples/peripherals/dac:
disable:

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# ADC DMA Example
@ -39,24 +39,25 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
Running this example, you will see the following log output on the serial monitor:
```
I (338) ADC DMA: adc_pattern[0].atten is :0
I (348) ADC DMA: adc_pattern[0].channel is :2
I (348) ADC DMA: adc_pattern[0].unit is :0
I (358) ADC DMA: adc_pattern[1].atten is :0
I (358) ADC DMA: adc_pattern[1].channel is :3
I (368) ADC DMA: adc_pattern[1].unit is :0
I (368) ADC DMA: adc_pattern[2].atten is :0
I (378) ADC DMA: adc_pattern[2].channel is :0
I (378) ADC DMA: adc_pattern[2].unit is :1
I (388) TASK: ret is 0, ret_num is 256
I (388) ADC DMA: Unit: 1,_Channel: 2, Value: bec
I (398) ADC DMA: Unit: 2,_Channel: 0, Value: 9cb
I (398) ADC DMA: Unit: 1,_Channel: 3, Value: acb
I (408) ADC DMA: Unit: 2,_Channel: 0, Value: 966
I (408) ADC DMA: Unit: 1,_Channel: 2, Value: b63
I (418) ADC DMA: Unit: 2,_Channel: 0, Value: 8ff
I (418) ADC DMA: Unit: 1,_Channel: 3, Value: a6b
I (428) ADC DMA: Unit: 2,_Channel: 0, Value: 8a2
I (367) EXAMPLE: adc_pattern[0].atten is :0
I (377) EXAMPLE: adc_pattern[0].channel is :2
I (377) EXAMPLE: adc_pattern[0].unit is :0
I (387) EXAMPLE: adc_pattern[1].atten is :0
I (387) EXAMPLE: adc_pattern[1].channel is :3
I (397) EXAMPLE: adc_pattern[1].unit is :0
I (397) gpio: GPIO[3]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (407) gpio: GPIO[4]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (417) TASK: ret is 0, ret_num is 256
I (427) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 819
I (427) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 7b9
I (437) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 7ab
I (437) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 74b
I (447) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 74d
I (447) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 6e5
I (457) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 6ee
I (467) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 680
I (467) EXAMPLE: Unit: ADC-1, Channel: 2, Value: 69a
I (477) EXAMPLE: Unit: ADC-1, Channel: 3, Value: 62f
...
```

View File

@ -13,16 +13,25 @@
#include "freertos/semphr.h"
#include "esp_adc/adc_continuous.h"
#define EXAMPLE_READ_LEN 256
#define EXAMPLE_ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
#define EXAMPLE_ADC_UNIT ADC_UNIT_1
#define _EXAMPLE_ADC_UNIT_STR(unit) #unit
#define EXAMPLE_ADC_UNIT_STR(unit) _EXAMPLE_ADC_UNIT_STR(unit)
#define EXAMPLE_ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_0
#define EXAMPLE_ADC_BIT_WIDTH SOC_ADC_DIGI_MAX_BITWIDTH
#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
#define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
#define EXAMPLE_ADC_GET_CHANNEL(p_data) ((p_data)->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);
}
}
/**

View File

@ -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+)')

View File

@ -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

View File

@ -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)