Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 29 additions & 15 deletions components/Monitoring/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
)

# Platform-specific GPIO-to-channel mapping
if ("$ENV{IDF_TARGET}" STREQUAL "esp32s3")
if (ADC_SAMPLER_SUPPORTED)
# Common ADC implementation
list(APPEND source_files
"Monitoring/AdcSampler_esp32s3.cpp"
"Monitoring/AdcSampler.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()


Expand Down
42 changes: 9 additions & 33 deletions components/Monitoring/Monitoring/AdcSampler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]";
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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
30 changes: 26 additions & 4 deletions components/Monitoring/Monitoring/AdcSampler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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_;

Expand All @@ -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
{
Expand All @@ -131,4 +153,4 @@ class AdcSampler
return false;
}
};
#endif
#endif // ADC_SAMPLER_SUPPORTED
18 changes: 17 additions & 1 deletion components/Monitoring/Monitoring/AdcSampler_esp32.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
60 changes: 60 additions & 0 deletions components/Monitoring/Monitoring/AdcSampler_esp32s2.cpp
Original file line number Diff line number Diff line change
@@ -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 GPIO1–10 → CH0–CH9
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
19 changes: 18 additions & 1 deletion components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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