mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'fix/lp_adc_not_working_on_lp_core_v5.5' into 'release/v5.5'
Fixes for LP ADC to work when used from the LP core (v5.5) See merge request espressif/esp-idf!45763
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "ulp_lp_core_lp_adc_shared.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_ll.h"
|
||||
#include "hal/adc_hal_common.h"
|
||||
#include "esp_private/adc_share_hw_ctrl.h"
|
||||
|
||||
#define VREF (1100) /* Internal Reference voltage in millivolts (1.1V) */
|
||||
#define INV_ATTEN_0DB (1000) /* Inverse of 10^0 * 1000 */
|
||||
@@ -17,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.
|
||||
@@ -41,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 = {
|
||||
@@ -75,16 +113,37 @@ esp_err_t lp_core_lp_adc_config_channel(adc_unit_t unit_id, adc_channel_t channe
|
||||
.bitwidth = chan_config->bitwidth,
|
||||
};
|
||||
|
||||
return (adc_oneshot_config_channel(s_adc1_handle, channel, &config));
|
||||
ret = adc_oneshot_config_channel(s_adc_unit_handles[unit_id], channel, &config);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set the calibration parameters for the ADC unit and channel */
|
||||
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
adc_hal_calibration_init(unit_id);
|
||||
adc_set_hw_calibration_code(unit_id, chan_config->atten);
|
||||
#endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */
|
||||
#endif /* IS_ULP_COCPU */
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -101,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;
|
||||
@@ -109,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);
|
||||
|
||||
@@ -22,8 +22,8 @@ extern const uint8_t lp_core_main_adc_bin_end[] asm("_binary_lp_core_test_app_
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
// Threshold values picked up empirically after manual testing
|
||||
#define ADC_TEST_LOW_VAL 2160
|
||||
#define ADC_TEST_HIGH_VAL 4090
|
||||
#define ADC_TEST_LOW_VAL 1000
|
||||
#define ADC_TEST_HIGH_VAL 3200
|
||||
#else
|
||||
#error "ADC threshold values not defined"
|
||||
#endif
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user