mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
Merge branch 'feat/ulp_adc_multi_channel' into 'master'
feat(ulp): add multi-channel ADC init for ULP Closes IDFGH-9831 and IDF-15815 See merge request espressif/esp-idf!49671
This commit is contained in:
@@ -471,6 +471,28 @@ TEST_CASE("ULP ADC can init-deinit-init", "[ulp]")
|
||||
TEST_ASSERT_EQUAL(ESP_OK, ulp_adc_deinit());
|
||||
}
|
||||
|
||||
TEST_CASE("ULP ADC can init multiple channels", "[ulp]")
|
||||
{
|
||||
/* Initialize the ADC unit and configure the first channel */
|
||||
ulp_adc_cfg_t riscv_adc_cfg = {
|
||||
.adc_n = ADC_UNIT,
|
||||
.channel = ADC_CHANNEL_5,
|
||||
.width = WIDTH,
|
||||
.atten = ADC_ATTEN_DB_2_5,
|
||||
.ulp_mode = ADC_ULP_MODE_FSM,
|
||||
};
|
||||
TEST_ASSERT_EQUAL(ESP_OK, ulp_adc_init(&riscv_adc_cfg));
|
||||
|
||||
/* Configure an additional channel on the same ADC unit */
|
||||
ulp_adc_chan_cfg_t chan_cfg = {
|
||||
.atten = ADC_ATTEN_DB_12,
|
||||
.bitwidth = WIDTH,
|
||||
};
|
||||
TEST_ASSERT_EQUAL(ESP_OK, ulp_adc_config_channel(ADC_UNIT, ADC_CHANNEL_6, &chan_cfg));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, ulp_adc_deinit());
|
||||
}
|
||||
|
||||
TEST_CASE("Test ULP RISCV delay", "[ulp]")
|
||||
{
|
||||
int64_t start, diff;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "hal/adc_types.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_adc/adc_oneshot.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -21,14 +22,42 @@ typedef struct {
|
||||
adc_ulp_mode_t ulp_mode; // ADC ULP Mode
|
||||
} ulp_adc_cfg_t; // ULP FSM ADC configuration parameters
|
||||
|
||||
/**
|
||||
* @brief ULP ADC channel configuration parameters
|
||||
*/
|
||||
typedef adc_oneshot_chan_cfg_t ulp_adc_chan_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize and calibrate the ADC for use by ULP FSM
|
||||
*
|
||||
* @note Initializes the ADC unit for ULP use and configures the channel
|
||||
* specified in cfg->channel. To monitor multiple channels, call
|
||||
* ulp_adc_config_channel() afterwards to configure additional channels.
|
||||
*
|
||||
* @param cfg Configuration parameters
|
||||
* @return esp_err_t ESP_OK for successful.
|
||||
*/
|
||||
esp_err_t ulp_adc_init(const ulp_adc_cfg_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Configure and calibrate an additional ADC channel for use by ULP
|
||||
*
|
||||
* Configures a channel on an ADC unit that has already been initialized by
|
||||
* ulp_adc_init(). This can be called multiple times to configure multiple
|
||||
* channels on the same ADC unit.
|
||||
*
|
||||
* @note HW calibration parameters are stored per attenuation, but only one set
|
||||
* is active in the ADC unit at a time. If channels use different
|
||||
* attenuations, readings on channels whose attenuation differs from the
|
||||
* last configured one may be less accurate.
|
||||
*
|
||||
* @param adc_n ADC unit (must already be initialized via ulp_adc_init())
|
||||
* @param channel ADC channel to configure
|
||||
* @param chan_cfg Channel configuration (attenuation and bit width)
|
||||
* @return esp_err_t ESP_OK for successful.
|
||||
*/
|
||||
esp_err_t ulp_adc_config_channel(adc_unit_t adc_n, adc_channel_t channel, const ulp_adc_chan_cfg_t *chan_cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ADC after use with ULP, allowing it to be reclaimed
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,6 +17,27 @@
|
||||
static const char *TAG = "ulp_adc";
|
||||
static adc_oneshot_unit_handle_t s_adc_handle = NULL;
|
||||
|
||||
esp_err_t ulp_adc_config_channel(adc_unit_t adc_n, adc_channel_t channel, const ulp_adc_chan_cfg_t *chan_cfg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
ESP_RETURN_ON_FALSE(chan_cfg, ESP_ERR_INVALID_ARG, TAG, "chan_cfg == NULL");
|
||||
ESP_RETURN_ON_FALSE(s_adc_handle, ESP_ERR_INVALID_STATE, TAG, "ADC unit not initialized");
|
||||
|
||||
//-------------ADC Config---------------//
|
||||
ret = adc_oneshot_config_channel(s_adc_handle, channel, chan_cfg);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Calibrate the ADC
|
||||
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
adc_set_hw_calibration_code(adc_n, chan_cfg->atten);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t ulp_adc_init(const ulp_adc_cfg_t *cfg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
@@ -47,6 +68,8 @@ esp_err_t ulp_adc_init(const ulp_adc_cfg_t *cfg)
|
||||
};
|
||||
ret = adc_oneshot_config_channel(s_adc_handle, cfg->channel, &config);
|
||||
if (ret != ESP_OK) {
|
||||
adc_oneshot_del_unit(s_adc_handle);
|
||||
s_adc_handle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ int32_t ulp_riscv_adc_read_channel(adc_unit_t adc_n, int channel)
|
||||
adc_oneshot_ll_clear_event(event);
|
||||
adc_oneshot_ll_disable_all_unit();
|
||||
adc_oneshot_ll_enable(adc_n);
|
||||
/* Force SW control of the channel bitmap; deep-sleep entry can clear it, which would
|
||||
* otherwise make the channel selection below take no effect. */
|
||||
adc_ll_set_controller(adc_n, ADC_LL_CTRL_RTC);
|
||||
adc_oneshot_ll_set_channel(adc_n, channel);
|
||||
|
||||
adc_oneshot_ll_start(adc_n);
|
||||
|
||||
Reference in New Issue
Block a user