diff --git a/components/Monitoring/CMakeLists.txt b/components/Monitoring/CMakeLists.txt index d2a5703..7d2d5d5 100644 --- a/components/Monitoring/CMakeLists.txt +++ b/components/Monitoring/CMakeLists.txt @@ -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" - ) - -# 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() diff --git a/components/Monitoring/Monitoring/AdcSampler.cpp b/components/Monitoring/Monitoring/AdcSampler.cpp index 2afe2c6..03671ce 100644 --- a/components/Monitoring/Monitoring/AdcSampler.cpp +++ b/components/Monitoring/Monitoring/AdcSampler.cpp @@ -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 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 diff --git a/components/Monitoring/Monitoring/AdcSampler.hpp b/components/Monitoring/Monitoring/AdcSampler.hpp index 21b4e45..7fcb085 100644 --- a/components/Monitoring/Monitoring/AdcSampler.hpp +++ b/components/Monitoring/Monitoring/AdcSampler.hpp @@ -20,7 +20,17 @@ #include #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 #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 diff --git a/components/Monitoring/Monitoring/AdcSampler_esp32.cpp b/components/Monitoring/Monitoring/AdcSampler_esp32.cpp index 140c5c8..d6648ff 100644 --- a/components/Monitoring/Monitoring/AdcSampler_esp32.cpp +++ b/components/Monitoring/Monitoring/AdcSampler_esp32.cpp @@ -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 diff --git a/components/Monitoring/Monitoring/AdcSampler_esp32s2.cpp b/components/Monitoring/Monitoring/AdcSampler_esp32s2.cpp new file mode 100644 index 0000000..56c994b --- /dev/null +++ b/components/Monitoring/Monitoring/AdcSampler_esp32s2.cpp @@ -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(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 diff --git a/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp b/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp index e115f27..efe3d6c 100644 --- a/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp +++ b/components/Monitoring/Monitoring/AdcSampler_esp32s3.cpp @@ -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