feat(lp_adc): Added support for LP ADC initialization to the esp_adc oneshot driver

This commit adds support for LP ADC initialization to the esp_adc
oneshot driver, when it is used from the HP core.
This commit is contained in:
Sudeep Mohanty 2024-08-27 11:03:55 +02:00
parent f972cd4bbd
commit d604e09274
8 changed files with 45 additions and 16 deletions

View File

@ -100,16 +100,24 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a
unit->unit_id = init_config->unit_id; unit->unit_id = init_config->unit_id;
unit->ulp_mode = init_config->ulp_mode; unit->ulp_mode = init_config->ulp_mode;
adc_oneshot_clk_src_t clk_src = ADC_DIGI_CLK_SRC_DEFAULT; adc_oneshot_clk_src_t clk_src;
#if SOC_LP_ADC_SUPPORTED
if (init_config->ulp_mode != ADC_ULP_MODE_DISABLE) {
clk_src = LP_ADC_CLK_SRC_LP_DYN_FAST;
} else
#endif /* CONFIG_SOC_LP_ADC_SUPPORTED */
{
clk_src = ADC_DIGI_CLK_SRC_DEFAULT;
if (init_config->clk_src) { if (init_config->clk_src) {
clk_src = init_config->clk_src; clk_src = init_config->clk_src;
} }
}
uint32_t clk_src_freq_hz = 0; uint32_t clk_src_freq_hz = 0;
ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz), err, TAG, "clock source not supported"); ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz), err, TAG, "clock source not supported");
adc_oneshot_hal_cfg_t config = { adc_oneshot_hal_cfg_t config = {
.unit = init_config->unit_id, .unit = init_config->unit_id,
.work_mode = (init_config->ulp_mode == ADC_ULP_MODE_FSM) ? ADC_HAL_ULP_FSM_MODE : ADC_HAL_SINGLE_READ_MODE, .work_mode = (init_config->ulp_mode != ADC_ULP_MODE_DISABLE) ? ADC_HAL_LP_MODE : ADC_HAL_SINGLE_READ_MODE,
.clk_src = clk_src, .clk_src = clk_src,
.clk_src_freq_hz = clk_src_freq_hz, .clk_src_freq_hz = clk_src_freq_hz,
}; };

View File

@ -18,8 +18,8 @@ static adc_ll_controller_t get_controller(adc_unit_t unit, adc_hal_work_mode_t w
{ {
if (unit == ADC_UNIT_1) { if (unit == ADC_UNIT_1) {
switch (work_mode) { switch (work_mode) {
#if SOC_ULP_HAS_ADC #if SOC_ULP_HAS_ADC || SOC_LP_CORE_SUPPORT_LP_ADC
case ADC_HAL_ULP_FSM_MODE: case ADC_HAL_LP_MODE:
return ADC_LL_CTRL_ULP; return ADC_LL_CTRL_ULP;
#endif #endif
case ADC_HAL_SINGLE_READ_MODE: case ADC_HAL_SINGLE_READ_MODE:
@ -35,8 +35,8 @@ static adc_ll_controller_t get_controller(adc_unit_t unit, adc_hal_work_mode_t w
} }
} else { } else {
switch (work_mode) { switch (work_mode) {
#if SOC_ULP_HAS_ADC #if SOC_ULP_HAS_ADC || SOC_LP_CORE_SUPPORT_LP_ADC
case ADC_HAL_ULP_FSM_MODE: case ADC_HAL_LP_MODE:
return ADC_LL_CTRL_ULP; return ADC_LL_CTRL_ULP;
#endif #endif
#if !SOC_ADC_ARBITER_SUPPORTED //No ADC2 arbiter on ESP32 #if !SOC_ADC_ARBITER_SUPPORTED //No ADC2 arbiter on ESP32

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -63,7 +63,15 @@ void adc_oneshot_hal_setup(adc_oneshot_hal_ctx_t *hal, adc_channel_t chan)
adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT); adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT);
adc_ll_digi_set_clk_div(ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT); adc_ll_digi_set_clk_div(ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT);
#else #else
#if SOC_LP_ADC_SUPPORTED
if (hal->work_mode == ADC_HAL_LP_MODE) {
adc_ll_set_sar_clk_div(unit, LP_ADC_LL_SAR_CLK_DIV_DEFAULT(unit));
} else {
adc_ll_set_sar_clk_div(unit, ADC_LL_SAR_CLK_DIV_DEFAULT(unit)); adc_ll_set_sar_clk_div(unit, ADC_LL_SAR_CLK_DIV_DEFAULT(unit));
}
#else
adc_ll_set_sar_clk_div(unit, ADC_LL_SAR_CLK_DIV_DEFAULT(unit));
#endif //SOC_LP_ADC_SUPPORTED
if (unit == ADC_UNIT_2) { if (unit == ADC_UNIT_2) {
adc_ll_pwdet_set_cct(ADC_LL_PWDET_CCT_DEFAULT); adc_ll_pwdet_set_cct(ADC_LL_PWDET_CCT_DEFAULT);
} }

View File

@ -39,6 +39,7 @@ extern "C" {
---------------------------------------------------------------*/ ---------------------------------------------------------------*/
#define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0)
#define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1)
#define LP_ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (2)
#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) #define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0)
/*--------------------------------------------------------------- /*---------------------------------------------------------------
@ -616,8 +617,8 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c
break; break;
case ADC_LL_CTRL_ULP: case ADC_LL_CTRL_ULP:
LP_ADC.meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. LP_ADC.meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control.
LP_ADC.meas1_ctrl2.meas1_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. LP_ADC.meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
LP_ADC.meas1_ctrl2.sar1_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; LP_ADC.meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break; break;
case ADC_LL_CTRL_DIG: case ADC_LL_CTRL_DIG:
LP_ADC.meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control. LP_ADC.meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control.
@ -636,8 +637,8 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c
break; break;
case ADC_LL_CTRL_ULP: case ADC_LL_CTRL_ULP:
LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control. LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control.
LP_ADC.meas2_ctrl2.meas2_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. LP_ADC.meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
LP_ADC.meas2_ctrl2.sar2_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; LP_ADC.meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break; break;
case ADC_LL_CTRL_DIG: case ADC_LL_CTRL_DIG:
LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control. LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control.

View File

@ -26,7 +26,7 @@ typedef enum adc_hal_work_mode_t {
ADC_HAL_SINGLE_READ_MODE, ADC_HAL_SINGLE_READ_MODE,
ADC_HAL_CONTINUOUS_READ_MODE, ADC_HAL_CONTINUOUS_READ_MODE,
ADC_HAL_PWDET_MODE, ADC_HAL_PWDET_MODE,
ADC_HAL_ULP_FSM_MODE, ADC_HAL_LP_MODE,
} adc_hal_work_mode_t; } adc_hal_work_mode_t;
/** /**
@ -61,7 +61,7 @@ void adc_hal_arbiter_config(adc_arbiter_t *config);
/** /**
* @brief Initialize default parameter for the calibration block. * @brief Initialize default parameter for the calibration block.
* *
* @param adc_n ADC index numer * @param adc_n ADC index number
*/ */
void adc_hal_calibration_init(adc_unit_t adc_n); void adc_hal_calibration_init(adc_unit_t adc_n);

View File

@ -64,6 +64,9 @@ typedef enum {
ADC_ULP_MODE_DISABLE = 0, ///< ADC ULP mode is disabled ADC_ULP_MODE_DISABLE = 0, ///< ADC ULP mode is disabled
ADC_ULP_MODE_FSM = 1, ///< ADC is controlled by ULP FSM ADC_ULP_MODE_FSM = 1, ///< ADC is controlled by ULP FSM
ADC_ULP_MODE_RISCV = 2, ///< ADC is controlled by ULP RISCV ADC_ULP_MODE_RISCV = 2, ///< ADC is controlled by ULP RISCV
#if SOC_LP_ADC_SUPPORTED
ADC_ULP_MODE_LP_CORE = 3, ///< ADC is controlled by LP Core
#endif // SOC_LP_ADC_SUPPORTED
} adc_ulp_mode_t; } adc_ulp_mode_t;
/** /**

View File

@ -259,6 +259,10 @@ config SOC_LP_SPI_SUPPORTED
bool bool
default y default y
config SOC_LP_ADC_SUPPORTED
bool
default y
config SOC_SPIRAM_SUPPORTED config SOC_SPIRAM_SUPPORTED
bool bool
default y default y
@ -1926,3 +1930,7 @@ config SOC_LCDCAM_CAM_DATA_WIDTH_MAX
config SOC_LP_CORE_SUPPORT_ETM config SOC_LP_CORE_SUPPORT_ETM
bool bool
default y default y
config SOC_LP_CORE_SUPPORT_LP_ADC
bool
default y

View File

@ -82,9 +82,9 @@
#define SOC_LP_I2C_SUPPORTED 1 #define SOC_LP_I2C_SUPPORTED 1
#define SOC_LP_I2S_SUPPORTED 1 #define SOC_LP_I2S_SUPPORTED 1
#define SOC_LP_SPI_SUPPORTED 1 #define SOC_LP_SPI_SUPPORTED 1
#define SOC_LP_ADC_SUPPORTED 1
#define SOC_SPIRAM_SUPPORTED 1 #define SOC_SPIRAM_SUPPORTED 1
#define SOC_PSRAM_DMA_CAPABLE 1 #define SOC_PSRAM_DMA_CAPABLE 1
// #define SOC_ULP_SUPPORTED 1 //TODO: IDF-7534
#define SOC_SDMMC_HOST_SUPPORTED 1 #define SOC_SDMMC_HOST_SUPPORTED 1
#define SOC_CLK_TREE_SUPPORTED 1 #define SOC_CLK_TREE_SUPPORTED 1
#define SOC_ASSIST_DEBUG_SUPPORTED 1 #define SOC_ASSIST_DEBUG_SUPPORTED 1
@ -738,3 +738,4 @@
/*------------------------------------- ULP CAPS -------------------------------------*/ /*------------------------------------- ULP CAPS -------------------------------------*/
#define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */ #define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */
#define SOC_LP_CORE_SUPPORT_LP_ADC (1) /*!< LP ADC can be accessed from the LP-Core */