Merge pull request #32 from m-RNA/update/AdcSampler

refactor(Monitoring): abstract platform-specific ADC code and add ESP32-S2 support
This commit is contained in:
Lorow
2026-02-05 23:25:44 +01:00
committed by GitHub
6 changed files with 159 additions and 54 deletions

View File

@@ -9,14 +9,30 @@
# +-----------------------+
# | ESP-IDF ADC HAL | ← Espressif official driver
# +-----------------------+
#
# Supported platforms (must support ESP-CAM):
# - ESP32: Tested
# - ESP32-S3: Tested
# - ESP32-S2: UNTESTED - Based on datasheet
set(
requires
Helpers
)
# List of supported ADC platforms (aligned with ESP_CAMERA_SUPPORTED)
set(ADC_SUPPORTED_TARGETS "esp32" "esp32s3" "esp32s2")
# Check if current target supports ADC
list(FIND ADC_SUPPORTED_TARGETS "$ENV{IDF_TARGET}" ADC_TARGET_INDEX)
if (NOT ADC_TARGET_INDEX EQUAL -1)
set(ADC_SAMPLER_SUPPORTED TRUE)
else()
set(ADC_SAMPLER_SUPPORTED FALSE)
endif()
# Platform-specific dependencies
if ("$ENV{IDF_TARGET}" STREQUAL "esp32s3" OR "$ENV{IDF_TARGET}" STREQUAL "esp32")
if (ADC_SAMPLER_SUPPORTED)
list(APPEND requires
driver
esp_adc
@@ -32,22 +48,20 @@ set(
)
# BSP Layer: ADC sampler implementation
if ("$ENV{IDF_TARGET}" STREQUAL "esp32s3" OR "$ENV{IDF_TARGET}" STREQUAL "esp32")
# Common ADC implementation
list(APPEND source_files
"Monitoring/AdcSampler.cpp"
if (ADC_SAMPLER_SUPPORTED)
# Common ADC implementation
list(APPEND source_files
"Monitoring/AdcSampler.cpp"
)
# Platform-specific GPIO-to-channel mapping
if ("$ENV{IDF_TARGET}" STREQUAL "esp32s3")
list(APPEND source_files
"Monitoring/AdcSampler_esp32s3.cpp"
)
elseif ("$ENV{IDF_TARGET}" STREQUAL "esp32")
list(APPEND source_files
"Monitoring/AdcSampler_esp32.cpp"
)
endif()
# Platform-specific GPIO-to-channel mapping and calibration
if ("$ENV{IDF_TARGET}" STREQUAL "esp32s3")
list(APPEND source_files "Monitoring/AdcSampler_esp32s3.cpp")
elseif ("$ENV{IDF_TARGET}" STREQUAL "esp32s2")
list(APPEND source_files "Monitoring/AdcSampler_esp32s2.cpp")
elseif ("$ENV{IDF_TARGET}" STREQUAL "esp32")
list(APPEND source_files "Monitoring/AdcSampler_esp32.cpp")
endif()
endif()

View File

@@ -3,14 +3,15 @@
* @brief BSP Layer - Common ADC sampling implementation
*
* This file contains platform-independent ADC sampling logic.
* Platform-specific GPIO-to-channel mapping is in separate files:
* - AdcSampler_esp32.cpp
* - AdcSampler_esp32s3.cpp
* Platform-specific implementations are in separate files:
* - AdcSampler_esp32.cpp (Tested)
* - AdcSampler_esp32s3.cpp (Tested)
* - AdcSampler_esp32s2.cpp (UNTESTED)
*/
#include "AdcSampler.hpp"
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32)
#if ADC_SAMPLER_SUPPORTED
#include <esp_log.h>
static const char* TAG = "[AdcSampler]";
@@ -22,11 +23,7 @@ AdcSampler::~AdcSampler()
{
if (cali_handle_)
{
#if defined(CONFIG_IDF_TARGET_ESP32S3)
adc_cali_delete_scheme_curve_fitting(cali_handle_);
#elif defined(CONFIG_IDF_TARGET_ESP32)
adc_cali_delete_scheme_line_fitting(cali_handle_);
#endif
delete_calibration(cali_handle_);
cali_handle_ = nullptr;
}
}
@@ -66,29 +63,8 @@ bool AdcSampler::init(int gpio, adc_atten_t atten, adc_bitwidth_t bitwidth, size
}
// Try calibration (requires eFuse data)
// ESP32-S3 uses curve-fitting, ESP32 uses line-fitting
esp_err_t cal_err = ESP_FAIL;
#if defined(CONFIG_IDF_TARGET_ESP32S3)
// ESP32-S3 curve fitting calibration
adc_cali_curve_fitting_config_t cal_cfg = {
.unit_id = unit_,
.chan = channel_,
.atten = atten_,
.bitwidth = bitwidth_,
};
cal_err = adc_cali_create_scheme_curve_fitting(&cal_cfg, &cali_handle_);
#elif defined(CONFIG_IDF_TARGET_ESP32)
// ESP32 line-fitting calibration is per-unit, not per-channel
adc_cali_line_fitting_config_t cal_cfg = {
.unit_id = unit_,
.atten = atten_,
.bitwidth = bitwidth_,
};
cal_err = adc_cali_create_scheme_line_fitting(&cal_cfg, &cali_handle_);
#endif
if (cal_err == ESP_OK)
// Platform-specific: ESP32-S3/S2 use curve-fitting, ESP32 uses line-fitting
if (create_calibration(&cali_handle_))
{
cali_inited_ = true;
ESP_LOGI(TAG, "ADC calibration initialized");
@@ -193,4 +169,4 @@ bool AdcSampler::configure_channel(int gpio, adc_atten_t atten, adc_bitwidth_t b
return true;
}
#endif // CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32
#endif // ADC_SAMPLER_SUPPORTED

View File

@@ -20,7 +20,17 @@
#include <cstdint>
#include "sdkconfig.h"
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32)
// Supported ESP32 platforms with ADC1 oneshot driver
// - ESP32: Tested
// - ESP32-S3: Tested
// - ESP32-S2: UNTESTED - GPIO mapping based on datasheet
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#define ADC_SAMPLER_SUPPORTED 1
#else
#define ADC_SAMPLER_SUPPORTED 0
#endif
#if ADC_SAMPLER_SUPPORTED
#include <vector>
#include "esp_adc/adc_cali.h"
#include "esp_adc/adc_cali_scheme.h"
@@ -86,10 +96,22 @@ class AdcSampler
/**
* @brief Platform-specific GPIO to ADC channel mapping
* @note Implemented separately in AdcSampler_esp32.cpp and AdcSampler_esp32s3.cpp
* @note Implemented in AdcSampler_esp32.cpp, AdcSampler_esp32s3 and AdcSampler_esp32s2.cpp
*/
static bool map_gpio_to_channel(int gpio, adc_unit_t& unit, adc_channel_t& channel);
/**
* @brief Platform-specific ADC calibration initialization
* @note Implemented in AdcSampler_esp32.cpp, AdcSampler_esp32s3 and AdcSampler_esp32s2.cpp
*/
bool create_calibration(adc_cali_handle_t* handle);
/**
* @brief Platform-specific ADC calibration cleanup
* @note Implemented in AdcSampler_esp32.cpp, AdcSampler_esp32s3 and AdcSampler_esp32s2.cpp
*/
void delete_calibration(adc_cali_handle_t handle);
// Shared ADC1 oneshot handle (single instance for all AdcSampler objects)
static adc_oneshot_unit_handle_t shared_unit_;
@@ -109,7 +131,7 @@ class AdcSampler
int filtered_mv_{0};
};
#else
#else // !ADC_SAMPLER_SUPPORTED
// Stub for unsupported targets to keep interfaces consistent
class AdcSampler
{
@@ -131,4 +153,4 @@ class AdcSampler
return false;
}
};
#endif
#endif // ADC_SAMPLER_SUPPORTED

View File

@@ -1,6 +1,6 @@
/**
* @file AdcSampler_esp32.cpp
* @brief BSP Layer - ESP32 specific GPIO to ADC channel mapping
* @brief BSP Layer - ESP32 specific ADC implementation
*
* ESP32 ADC1 GPIO mapping:
* - GPIO32 → ADC1_CH4
@@ -56,4 +56,20 @@ bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t& unit, adc_channel_t&
}
}
bool AdcSampler::create_calibration(adc_cali_handle_t* handle)
{
// ESP32 uses line fitting calibration (per-unit, not per-channel)
adc_cali_line_fitting_config_t cal_cfg = {
.unit_id = unit_,
.atten = atten_,
.bitwidth = bitwidth_,
};
return adc_cali_create_scheme_line_fitting(&cal_cfg, handle) == ESP_OK;
}
void AdcSampler::delete_calibration(adc_cali_handle_t handle)
{
adc_cali_delete_scheme_line_fitting(handle);
}
#endif // CONFIG_IDF_TARGET_ESP32

View File

@@ -0,0 +1,60 @@
/**
* @file AdcSampler_esp32s2.cpp
* @brief BSP Layer - ESP32-S2 specific ADC implementation
*
* UNTESTED - This implementation is based on ESP32-S2 datasheet.
* Please verify on actual hardware before production use.
*
* ESP32-S2 ADC1 GPIO mapping:
* - GPIO1 → ADC1_CH0
* - GPIO2 → ADC1_CH1
* - GPIO3 → ADC1_CH2
* - GPIO4 → ADC1_CH3
* - GPIO5 → ADC1_CH4
* - GPIO6 → ADC1_CH5
* - GPIO7 → ADC1_CH6
* - GPIO8 → ADC1_CH7
* - GPIO9 → ADC1_CH8
* - GPIO10 → ADC1_CH9
*
* Note: ADC2 is not used to avoid conflicts with Wi-Fi.
* Same as ESP32-S3 implementation.
*/
#include "AdcSampler.hpp"
#if defined(CONFIG_IDF_TARGET_ESP32S2)
bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t& unit, adc_channel_t& channel)
{
unit = ADC_UNIT_1; // Only use ADC1 to avoid Wi-Fi conflict
// ESP32-S2: ADC1 on GPIO110 → CH0CH9
if (gpio >= 1 && gpio <= 10)
{
channel = static_cast<adc_channel_t>(gpio - 1);
return true;
}
channel = ADC_CHANNEL_0;
return false;
}
bool AdcSampler::create_calibration(adc_cali_handle_t* handle)
{
// ESP32-S2 uses curve fitting calibration
adc_cali_curve_fitting_config_t cal_cfg = {
.unit_id = unit_,
.chan = channel_,
.atten = atten_,
.bitwidth = bitwidth_,
};
return adc_cali_create_scheme_curve_fitting(&cal_cfg, handle) == ESP_OK;
}
void AdcSampler::delete_calibration(adc_cali_handle_t handle)
{
adc_cali_delete_scheme_curve_fitting(handle);
}
#endif // CONFIG_IDF_TARGET_ESP32S2

View File

@@ -1,6 +1,6 @@
/**
* @file AdcSampler_esp32s3.cpp
* @brief BSP Layer - ESP32-S3 specific GPIO to ADC channel mapping
* @brief BSP Layer - ESP32-S3 specific ADC implementation
*
* ESP32-S3 ADC1 GPIO mapping:
* - GPIO1 → ADC1_CH0
@@ -36,4 +36,21 @@ bool AdcSampler::map_gpio_to_channel(int gpio, adc_unit_t& unit, adc_channel_t&
return false;
}
bool AdcSampler::create_calibration(adc_cali_handle_t* handle)
{
// ESP32-S3 uses curve fitting calibration
adc_cali_curve_fitting_config_t cal_cfg = {
.unit_id = unit_,
.chan = channel_,
.atten = atten_,
.bitwidth = bitwidth_,
};
return adc_cali_create_scheme_curve_fitting(&cal_cfg, handle) == ESP_OK;
}
void AdcSampler::delete_calibration(adc_cali_handle_t handle)
{
adc_cali_delete_scheme_curve_fitting(handle);
}
#endif // CONFIG_IDF_TARGET_ESP32S3