From 5f6fab3dde4d6f9a99dcf30ef7cbad24bb390564 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Thu, 15 Jan 2026 15:41:12 +0100 Subject: [PATCH] change(lp_adc): Cleanup LP ADC driver and example --- .../shared/ulp_lp_core_lp_adc_shared.c | 94 +++++++++++++++---- .../ulp/lp_core/lp_adc/main/lp_adc_main.c | 2 +- .../ulp/lp_core/lp_adc/main/lp_core/main.c | 2 + 3 files changed, 77 insertions(+), 21 deletions(-) diff --git a/components/ulp/lp_core/shared/ulp_lp_core_lp_adc_shared.c b/components/ulp/lp_core/shared/ulp_lp_core_lp_adc_shared.c index 5b2e00ff8d..9b630aeb57 100644 --- a/components/ulp/lp_core/shared/ulp_lp_core_lp_adc_shared.c +++ b/components/ulp/lp_core/shared/ulp_lp_core_lp_adc_shared.c @@ -19,18 +19,48 @@ #define INV_ATTEN_6DB (1996) /* Inverse of 10^(-6/20) * 1000 */ #define INV_ATTEN_12DB (3984) /* Inverse of 10^(-12/20) * 1000 */ -adc_oneshot_unit_handle_t s_adc1_handle; +/* ADC unit handles - one for each supported ADC unit */ +static adc_oneshot_unit_handle_t s_adc_unit_handles[SOC_ADC_PERIPH_NUM] = {NULL}; -esp_err_t lp_core_lp_adc_init(adc_unit_t unit_id) +/************************************************** Static Helper Functions **************************************************/ + +static esp_err_t lp_adc_validate_unit(adc_unit_t unit_id) { + /* Currently, LP ADC2 does not work during sleep (DIG-396) + * TODO: Remove this check once DIG-396 is fixed + */ if (unit_id != ADC_UNIT_1) { - // TODO: LP ADC2 does not work during sleep (DIG-396) - // For now, we do not allow LP ADC2 usage. return ESP_ERR_INVALID_ARG; } + /* Verify unit ID is within valid range */ + if (unit_id >= SOC_ADC_PERIPH_NUM) { + return ESP_ERR_INVALID_ARG; + } + + return ESP_OK; +} + +static esp_err_t lp_adc_validate_channel(adc_unit_t unit_id, adc_channel_t channel) +{ + if (channel >= SOC_ADC_CHANNEL_NUM(unit_id)) { + return ESP_ERR_INVALID_ARG; + } + + return ESP_OK; +} + +/************************************************** Public API **************************************************/ + +esp_err_t lp_core_lp_adc_init(adc_unit_t unit_id) +{ + esp_err_t ret = lp_adc_validate_unit(unit_id); + if (ret != ESP_OK) { + return ret; + } + #if IS_ULP_COCPU - // Not supported + // Not supported from LP core return ESP_ERR_NOT_SUPPORTED; #else /* LP ADC is being initialized from the HP core. @@ -43,33 +73,39 @@ esp_err_t lp_core_lp_adc_init(adc_unit_t unit_id) .ulp_mode = ADC_ULP_MODE_LP_CORE, // LP Core will use the ADC }; - return (adc_oneshot_new_unit(&init_config, &s_adc1_handle)); + return (adc_oneshot_new_unit(&init_config, &s_adc_unit_handles[unit_id])); #endif /* IS_ULP_COCPU */ } esp_err_t lp_core_lp_adc_deinit(adc_unit_t unit_id) { - if (unit_id != ADC_UNIT_1) { - return ESP_ERR_INVALID_ARG; + esp_err_t ret = lp_adc_validate_unit(unit_id); + if (ret != ESP_OK) { + return ret; } #if IS_ULP_COCPU - // Not supported + // Not supported from LP core return ESP_ERR_NOT_SUPPORTED; #else - return (adc_oneshot_del_unit(s_adc1_handle)); + return (adc_oneshot_del_unit(s_adc_unit_handles[unit_id])); #endif /* IS_ULP_COCPU */ } esp_err_t lp_core_lp_adc_config_channel(adc_unit_t unit_id, adc_channel_t channel, const lp_core_lp_adc_chan_cfg_t *chan_config) { - if (unit_id != ADC_UNIT_1) { - // TODO: LP ADC2 does not work during sleep (DIG-396) - // For now, we do not allow LP ADC2 usage. - return ESP_ERR_INVALID_ARG; + esp_err_t ret = lp_adc_validate_unit(unit_id); + if (ret != ESP_OK) { + return ret; } + + ret = lp_adc_validate_channel(unit_id, channel); + if (ret != ESP_OK) { + return ret; + } + #if IS_ULP_COCPU - // Not supported + // Not supported from LP core return ESP_ERR_NOT_SUPPORTED; #else adc_oneshot_chan_cfg_t config = { @@ -94,10 +130,20 @@ esp_err_t lp_core_lp_adc_config_channel(adc_unit_t unit_id, adc_channel_t channe esp_err_t lp_core_lp_adc_read_channel_raw(adc_unit_t unit_id, adc_channel_t channel, int *adc_raw) { - if (unit_id != ADC_UNIT_1 || adc_raw == NULL) { + if (adc_raw == NULL) { return ESP_ERR_INVALID_ARG; } + esp_err_t ret = lp_adc_validate_unit(unit_id); + if (ret != ESP_OK) { + return ret; + } + + ret = lp_adc_validate_channel(unit_id, channel); + if (ret != ESP_OK) { + return ret; + } + #if IS_ULP_COCPU uint32_t event = ADC_LL_EVENT_ADC1_ONESHOT_DONE; @@ -114,7 +160,7 @@ esp_err_t lp_core_lp_adc_read_channel_raw(adc_unit_t unit_id, adc_channel_t chan adc_oneshot_ll_disable_all_unit(); #else - return (adc_oneshot_read(s_adc1_handle, channel, adc_raw)); + return (adc_oneshot_read(s_adc_unit_handles[unit_id], channel, adc_raw)); #endif /* IS_ULP_COCPU */ return ESP_OK; @@ -122,12 +168,20 @@ esp_err_t lp_core_lp_adc_read_channel_raw(adc_unit_t unit_id, adc_channel_t chan esp_err_t lp_core_lp_adc_read_channel_converted(adc_unit_t unit_id, adc_channel_t channel, int *voltage_mv) { - esp_err_t ret = ESP_OK; - - if (unit_id != ADC_UNIT_1 || voltage_mv == NULL) { + if (voltage_mv == NULL) { return ESP_ERR_INVALID_ARG; } + esp_err_t ret = lp_adc_validate_unit(unit_id); + if (ret != ESP_OK) { + return ret; + } + + ret = lp_adc_validate_channel(unit_id, channel); + if (ret != ESP_OK) { + return ret; + } + /* Read the raw ADC value */ int adc_raw; ret = lp_core_lp_adc_read_channel_raw(unit_id, channel, &adc_raw); diff --git a/examples/system/ulp/lp_core/lp_adc/main/lp_adc_main.c b/examples/system/ulp/lp_core/lp_adc/main/lp_adc_main.c index e7bd6d6e67..f20bd6fd23 100644 --- a/examples/system/ulp/lp_core/lp_adc/main/lp_adc_main.c +++ b/examples/system/ulp/lp_core/lp_adc/main/lp_adc_main.c @@ -33,7 +33,7 @@ static void lp_uart_init(void) static void lp_core_init(void) { - /* Set LP core wakeup source as the HP CPU */ + /* Set LP core wakeup source as the LP timer */ ulp_lp_core_cfg_t cfg = { .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER, .lp_timer_sleep_duration_us = 1000000, diff --git a/examples/system/ulp/lp_core/lp_adc/main/lp_core/main.c b/examples/system/ulp/lp_core/lp_adc/main/lp_core/main.c index 67f85a58c9..5d8b682edf 100644 --- a/examples/system/ulp/lp_core/lp_adc/main/lp_core/main.c +++ b/examples/system/ulp/lp_core/lp_adc/main/lp_core/main.c @@ -8,6 +8,7 @@ #include "sdkconfig.h" #include "ulp_lp_core_print.h" #include "ulp_lp_core_lp_adc_shared.h" +#include "ulp_lp_core_uart.h" #define EXAMPLE_LP_ADC1_CHAN0 CONFIG_EXAMPLE_LP_ADC1_CHANNEL_0_SELECT #define EXAMPLE_LP_ADC1_CHAN1 CONFIG_EXAMPLE_LP_ADC1_CHANNEL_1_SELECT @@ -28,6 +29,7 @@ int main (void) lp_core_printf("lpadc1 chan1 converted value = %d mV\r\n", adc_converted_value[1]); lp_core_printf("\n"); + lp_core_uart_tx_flush(LP_UART_NUM_0); return 0; }