Bläddra i källkod

Merge branch 'feature/esp32s2_adc_calib_V1' into 'master'

driver/adc: support for esp32s2 adc calibration scheme (RTC High Priority)

Closes IDFGH-3500

See merge request espressif/esp-idf!10004
Michael (XIAO Xufeng) 5 år sedan
förälder
incheckning
ceb690886e

+ 1 - 1
components/driver/test/CMakeLists.txt

@@ -1,3 +1,3 @@
 idf_component_register(SRC_DIRS . param_test touch_sensor_test adc_dma_test dac_dma_test
                        PRIV_INCLUDE_DIRS include param_test/include touch_sensor_test/include
-                       PRIV_REQUIRES unity test_utils driver nvs_flash esp_serial_slave_link infrared_tools)
+                       PRIV_REQUIRES unity test_utils driver nvs_flash esp_serial_slave_link infrared_tools esp_adc_cal)

+ 58 - 0
components/driver/test/test_dac.c

@@ -2,6 +2,7 @@
  Tests for the dac device driver
 */
 #include "esp_system.h"
+
 #include "driver/adc.h"
 #include "driver/dac.h"
 #include "unity.h"
@@ -13,6 +14,8 @@
 #include "test_utils.h"
 #include "driver/i2s.h"
 
+#include "esp_adc_cal.h"
+
 static const char *TAG = "test_dac";
 
 #ifdef CONFIG_IDF_TARGET_ESP32
@@ -119,3 +122,58 @@ TEST_CASE("DAC cw generator output (RTC) check by adc", "[dac]")
     TEST_ESP_OK( dac_cw_generator_disable() );
     TEST_ESP_OK( dac_output_disable( DAC_TEST_CHANNEL_NUM ) );
 }
+
+#if CONFIG_IDF_TARGET_ESP32S2
+static int helper_calc_dac_output(int mV)
+{
+    return mV * 0.07722;
+}
+static bool subtest_adc_dac(int mV_ref, esp_adc_cal_characteristics_t * chars)
+{
+    dac_output_voltage(DAC_TEST_CHANNEL_NUM, helper_calc_dac_output(mV_ref));
+    vTaskDelay(pdMS_TO_TICKS(80));
+    int raw;
+    adc2_get_raw((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_WIDTH_BIT_13, &raw);
+    uint32_t voltage = esp_adc_cal_raw_to_voltage(raw, chars);
+    TEST_ASSERT_INT_WITHIN( 120, mV_ref, voltage ); // 120 mV error allowance, because both DAC and ADC have error
+    return true;
+}
+
+TEST_CASE("esp32s2 adc2-dac with adc2 calibration", "[adc-dac]")
+{
+    gpio_num_t adc_gpio_num, dac_gpio_num;
+    TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) );
+    TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) );
+    printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
+           DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num );
+    TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) );
+
+    esp_adc_cal_characteristics_t chars;
+
+    printf("Test 0dB atten...\n");
+    adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_0);
+    esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_13, 0, &chars);
+    printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
+    subtest_adc_dac(750, &chars);
+
+    printf("Test 2.5dB atten...\n");
+    adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_2_5);
+    esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_2_5, ADC_WIDTH_BIT_13, 0, &chars);
+    printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
+     subtest_adc_dac(1100, &chars);
+
+    printf("Test 6dB atten...\n");
+    adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_6);
+    esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_6, ADC_WIDTH_BIT_13, 0, &chars);
+    printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
+    subtest_adc_dac(800, &chars);
+    subtest_adc_dac(1250, &chars);
+
+    printf("Test 11dB atten...\n");
+    adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_11);
+    esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_13, 0, &chars);
+    printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
+    subtest_adc_dac(1500, &chars);
+    subtest_adc_dac(2500, &chars);
+}
+#endif

+ 12 - 6
components/esp_adc_cal/CMakeLists.txt

@@ -1,9 +1,15 @@
 idf_build_get_property(target IDF_TARGET)
-# ToDo: re-enable adc-cal for other target
-if(NOT ${target} STREQUAL "esp32")
-    return()
-endif()
 
-idf_component_register(SRCS "esp_adc_cal.c"
+if(${target} STREQUAL "esp32")
+    idf_component_register(SRCS "esp_adc_cal_esp32.c"
+                    INCLUDE_DIRS "include"
+                    REQUIRES driver efuse)
+
+elseif(${target} STREQUAL "esp32s2")
+	idf_component_register(SRCS "esp_adc_cal_esp32s2.c"
                     INCLUDE_DIRS "include"
-                    REQUIRES driver)
+                    REQUIRES driver efuse)
+
+endif()
+
+

+ 4 - 0
components/esp_adc_cal/Kconfig

@@ -1,6 +1,7 @@
 menu "ADC-Calibration"
 
     config ADC_CAL_EFUSE_TP_ENABLE
+        depends on IDF_TARGET_ESP32
         bool "Use Two Point Values"
         default "y"
         help
@@ -9,6 +10,7 @@ menu "ADC-Calibration"
             ADC-Voltage curve using Two Point values if they are available.
 
     config ADC_CAL_EFUSE_VREF_ENABLE
+        depends on IDF_TARGET_ESP32
         bool "Use eFuse Vref"
         default "y"
         help
@@ -17,6 +19,7 @@ menu "ADC-Calibration"
             eFuse Vref if it is available.
 
     config ADC_CAL_LUT_ENABLE
+        depends on IDF_TARGET_ESP32
         bool "Use Lookup Tables"
         default "y"
         help
@@ -24,4 +27,5 @@ menu "ADC-Calibration"
             to correct for non-linear behavior in 11db attenuation. Other attenuations
             do not exhibit non-linear behavior hence will not be affected by this option.
 
+
 endmenu  # ADC-Calibration

+ 3 - 1
components/esp_adc_cal/component.mk

@@ -2,4 +2,6 @@
 # Component Makefile
 #
 
-COMPONENT_ADD_INCLUDEDIRS := include
+COMPONENT_ADD_INCLUDEDIRS := include
+COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o
+

+ 0 - 0
components/esp_adc_cal/esp_adc_cal.c → components/esp_adc_cal/esp_adc_cal_esp32.c


+ 293 - 0
components/esp_adc_cal/esp_adc_cal_esp32s2.c

@@ -0,0 +1,293 @@
+// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdint.h>
+#include "esp_types.h"
+#include "driver/adc.h"
+#include "soc/efuse_periph.h"
+#include "esp_err.h"
+#include "assert.h"
+#include "esp_adc_cal.h"
+#include "esp_efuse.h"
+
+#define ADC_CAL_CHECK(cond, ret) ({                                         \
+            if(!(cond)){                                                    \
+                return ret;                                                 \
+            }                                                               \
+})
+/* ------------------------ Characterization Constants ---------------------- */
+#define ADC_CHAR_VERSION1_EFUSEVAL 1
+
+static const uint32_t adc1_D_mean_low[] = {2231, 1643, 1290, 701};
+static const uint32_t adc2_D_mean_low[] = {2305, 1693, 1343, 723};
+static const uint32_t adc1_D_mean_high[] = {5775, 5692, 5725, 6209};
+static const uint32_t adc2_D_mean_high[] = {5817, 5703, 5731, 6157};
+
+static const int Dlow_data_length = 6;
+static const int Dhigh_data_length = 8;
+
+static const int adc_efuse_block = 2;
+static const int adc_calib_ver_block = 2;
+static const int adc_calib_ver_word_loc = 4;
+static const int adc_calib_ver_offset = 4;
+static const int adc_calib_ver_len = 3;
+
+static const int adc1_atten0_Dlow_word_loc = 6;
+static const int adc2_atten0_Dlow_word_loc = 7;
+static const int adc1_atten0_Dhigh_word_loc = 4;
+static const int adc2_atten0_Dhigh_word_loc = 5;
+
+static const int adc1_atten0_Dlow_offset = 16;
+static const int adc2_atten0_Dlow_offset = 8;
+static const int adc1_atten0_Dhigh_offset = 16;
+static const int adc2_atten0_Dhigh_offset = 16;
+/* ----------------------- EFuse Access Functions --------------------------- */
+/**
+ *  Convenience function that reads a few bits from efuse and assembles them.
+ *  For example, if the contents of the EFuse are:
+ *   Word2: 0x1234 Word3:0x5678
+ *   Then, setting base=2, offset=24, len=24 will yield 0x456.
+ *  @note does not check for boundaries, make sure parameters are correct
+ *  @param blk EFuse Block
+ *  @param base the starting word
+ *  @param offset the bit offset in the starting word
+ *  @param bit how many consecutive bits to fetch
+ *  @return the assembled number
+ */
+static uint32_t get_consecutive_bits_from_blk(int blk, uint32_t base, int offset, int len)
+{
+
+    base += offset / 32;
+    offset %= 32;
+    if (offset + len <= 32 || base == 7) {
+        uint32_t result = esp_efuse_read_reg(blk, base);
+        result <<= (32 - offset - len);
+        result >>= (32 - len);
+        return result;
+    } else {
+        // need to fetch both bytes.
+        uint64_t result = ((uint64_t)esp_efuse_read_reg(blk, base + 1) << 32) + esp_efuse_read_reg(blk, base);
+        result &= ((uint64_t)1 << (offset + len)) - 1;
+        result >>= offset;
+        return result;
+    }
+}
+
+/**
+ *  To save space in EFuse, the calibration values for adc are compressed.
+ *  The compression scheme is: for X bits of ADC Efuse data,
+ *  The actual ADC reading is: BASE_VALUE + 4*ADC_OFFSET
+ *  where ADC_OFFSET = bits X-1:0 in Efuse, the highest bit is the sign bit (0:+, 1:-).
+ *
+ *  The following functions do this conversion.
+ *  @param efuse_val raw values read from efuse.
+ *  @param adc_num Specifies the channel number. The 2 adc channels each have different calibration values.
+ *  @param attem Specifies the attenuation. Different attenuation level have different calibration values.
+ */
+static uint32_t efuse_low_val_to_d(uint16_t efuse_val, adc_unit_t adc_num, adc_atten_t atten)
+{
+    // efuse_val is 5 bits + 6th sign bit.
+    int32_t rawoffsetval = efuse_val & ((1 << (Dlow_data_length - 1)) - 1);
+    // if the sign bit is 1, it means it is a negative sign.
+    int32_t offset = (efuse_val & (1 << (Dlow_data_length - 1))) ? (-rawoffsetval * 4) : (rawoffsetval * 4);
+    if (adc_num == ADC_UNIT_1) {
+        return offset + adc1_D_mean_low[atten - ADC_ATTEN_DB_0];
+    } else {
+        return offset + adc2_D_mean_low[atten - ADC_ATTEN_DB_0];
+    }
+}
+
+static uint32_t efuse_high_val_to_d (uint16_t efuse_val, adc_unit_t adc_num, adc_atten_t atten)
+{
+    // efuse_val is 7 bits + 8th sign bit.
+    int32_t rawoffsetval = efuse_val & ((1 << (Dhigh_data_length - 1)) - 1);
+    int32_t offset = (efuse_val & (1 << (Dhigh_data_length - 1))) ? (-rawoffsetval * 4) : (rawoffsetval * 4);
+    if (adc_num == ADC_UNIT_1) {
+        return offset + adc1_D_mean_high[atten - ADC_ATTEN_DB_0];
+    } else {
+        return offset + adc2_D_mean_high[atten - ADC_ATTEN_DB_0];
+    }
+
+}
+
+/**
+ *  To save space in EFuse, the calibration values for adc are compressed.
+ *  The compression scheme is: for X bits of ADC Efuse data,
+ *  The actual ADC reading is: BASE_VALUE + 4*ADC_OFFSET
+ *  where ADC_OFFSET = bits X-1:0 in Efuse, the highest bit is the sign bit (0:+, 1:-).
+ *
+ *  The following functions do the reading.
+ *  @param efuse_val raw values read from efuse.
+ *  @param adc_num Specifies the channel number. The 2 adc channels each have different calibration values.
+ *  @param attem Specifies the attenuation. Different attenuation level have different calibration values.
+ */
+static uint32_t read_efuse_tp_low(adc_unit_t adc_num, adc_atten_t atten)
+{
+    // this fcn retrieves and decodes the calibration value stored in efuse.
+    uint32_t base;
+    int offset;
+    // may need to move magic numbers out
+    if (adc_num == ADC_UNIT_1) {
+        // the first value is at the 16th bit of the 6th word of the efuse block 2, each value is 6 bits long.
+        base = adc1_atten0_Dlow_word_loc;
+        offset = adc1_atten0_Dlow_offset + Dlow_data_length * (atten - ADC_ATTEN_DB_0);
+
+    } else {
+        // the first value is at the 8th bit of the 7th word of the efuse block 2, each value is 6 bits long.
+        base = adc2_atten0_Dlow_word_loc;
+        offset = adc2_atten0_Dlow_offset + Dlow_data_length * (atten - ADC_ATTEN_DB_0);
+    }
+    uint32_t read_result = get_consecutive_bits_from_blk(adc_efuse_block, base, offset, Dlow_data_length);
+    return read_result;
+}
+
+static uint32_t read_efuse_tp_high(adc_unit_t adc_num, adc_atten_t atten)
+{
+    // this fcn retrieves and decodes the calibration value stored in efuse.
+    uint32_t base;
+    int offset;
+
+    if (adc_num == ADC_UNIT_1) {
+        // the first value is at the 16th bit of the 4th word of the efuse block 2, each value is 8 bits long.
+        base = adc1_atten0_Dhigh_word_loc;
+        offset = adc1_atten0_Dhigh_offset + Dhigh_data_length * (atten - ADC_ATTEN_DB_0);
+
+    } else {
+        // the first value is at the 16th bit of the 5th word of the efuse block 2, each value is 8 bits long.
+        base = adc2_atten0_Dhigh_word_loc;
+        offset = adc2_atten0_Dhigh_offset + Dhigh_data_length * (atten - ADC_ATTEN_DB_0);
+    }
+    uint32_t read_result = get_consecutive_bits_from_blk(adc_efuse_block, base, offset, Dhigh_data_length);
+    return read_result;
+}
+
+/* ----------------------- Characterization Functions ----------------------- */
+
+// coeff_a and coeff_b are actually floats
+// they are scaled to put them into uint32_t so that the headers do not have to be changed
+static const int coeff_a_scaling = 65536;
+static const int coeff_b_scaling = 1024;
+
+/**
+ *  The Two Point calibration measures the reading at two specific input voltages, and calculates the (assumed linear) relation
+ *  between input voltage and ADC response. (Response = A * Vinput + B)
+ *  A and B are scaled ints.
+ *  @param high The ADC response at the higher voltage of the corresponding attenuation (600mV, 800mV, 1000mV, 2000mV).
+ *  @param low The ADC response at the lower voltage of the corresponding attenuation (all 250mV).
+ *
+ */
+static void characterize_using_two_point(adc_unit_t adc_num,
+        adc_atten_t atten,
+        uint32_t high,
+        uint32_t low,
+        uint32_t *coeff_a,
+        uint32_t *coeff_b)
+{
+    // once we have recovered the reference high(Dhigh) and low(Dlow) readings, we can calculate a and b from
+    // the measured high and low readings
+    static const uint32_t v_high[] = {600, 800, 1000, 2000};
+    static const uint32_t v_low = 250;
+    *coeff_a = coeff_a_scaling * (v_high[atten] - v_low) / (high - low);
+    *coeff_b = coeff_b_scaling * (v_low * high - v_high[atten] * low) / (high - low);
+}
+
+
+/* ------------------------- Public API ------------------------------------- */
+esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t source)
+{
+    if (source != ESP_ADC_CAL_VAL_EFUSE_TP) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    uint8_t adc1_atten0_dh = get_consecutive_bits_from_blk(adc_efuse_block, adc1_atten0_Dhigh_word_loc, adc1_atten0_Dhigh_offset, Dhigh_data_length);
+    uint8_t adc2_atten0_dh = get_consecutive_bits_from_blk(adc_efuse_block, adc2_atten0_Dhigh_word_loc, adc2_atten0_Dhigh_offset, Dhigh_data_length);
+    if (!adc1_atten0_dh || !adc2_atten0_dh) {
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    uint8_t adc_encoding_version = get_consecutive_bits_from_blk(adc_calib_ver_block, adc_calib_ver_word_loc, adc_calib_ver_offset, adc_calib_ver_len);
+    if (adc_encoding_version != 1) {
+        // current version only accepts encoding ver 1.
+        return ESP_ERR_INVALID_VERSION;
+    }
+    return ESP_OK;
+}
+
+esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num,
+        adc_atten_t atten,
+        adc_bits_width_t bit_width,
+        uint32_t default_vref,
+        esp_adc_cal_characteristics_t *chars)
+{
+    // Check parameters
+    assert((adc_num == ADC_UNIT_1) || (adc_num == ADC_UNIT_2));
+    assert(chars != NULL);
+    assert(bit_width == ADC_WIDTH_BIT_13);
+
+    // Characterize based on efuse Two Point values. If these values are not present in efuse,
+    // or efuse values are of a version that we do not recognize, automatically assume default values.
+    uint32_t adc_calib_high, adc_calib_low;
+    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
+        adc_calib_high = read_efuse_tp_high(adc_num, atten);
+        adc_calib_low = read_efuse_tp_low(adc_num, atten);
+    } else {
+        adc_calib_high = 0;
+        adc_calib_low = 0;
+    }
+    uint32_t high = efuse_high_val_to_d(adc_calib_high, adc_num, atten);
+    uint32_t low = efuse_low_val_to_d(adc_calib_low, adc_num, atten);
+    characterize_using_two_point(adc_num, atten, high, low, &(chars->coeff_a), &(chars->coeff_b));
+    // Initialize remaining fields
+    chars->adc_num = adc_num;
+    chars->atten = atten;
+    chars->bit_width = bit_width;
+
+    // these values are not used as the corresponding calibration themes are deprecated.
+    chars->vref = 0;
+    chars->low_curve = NULL;
+    chars->high_curve = NULL;
+
+    // in esp32s2 we only use the two point method to calibrate the adc.
+    return ESP_ADC_CAL_VAL_EFUSE_TP;
+}
+
+uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars)
+{
+    ADC_CAL_CHECK(chars != NULL, ESP_ERR_INVALID_ARG);
+
+    return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling;
+}
+
+esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel,
+                                  const esp_adc_cal_characteristics_t *chars,
+                                  uint32_t *voltage)
+{
+    // Check parameters
+    ADC_CAL_CHECK(chars != NULL, ESP_ERR_INVALID_ARG);
+    ADC_CAL_CHECK(voltage != NULL, ESP_ERR_INVALID_ARG);
+
+    int adc_reading;
+    if (chars->adc_num == ADC_UNIT_1) {
+        //Check if channel is valid on ADC1
+        ADC_CAL_CHECK((adc1_channel_t)channel < ADC1_CHANNEL_MAX, ESP_ERR_INVALID_ARG);
+        adc_reading = adc1_get_raw(channel);
+    } else {
+        //Check if channel is valid on ADC2
+        ADC_CAL_CHECK((adc2_channel_t)channel < ADC2_CHANNEL_MAX, ESP_ERR_INVALID_ARG);
+        if (adc2_get_raw(channel, chars->bit_width, &adc_reading) != ESP_OK) {
+            return ESP_ERR_TIMEOUT;     //Timed out waiting for ADC2
+        }
+    }
+    *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars);
+    return ESP_OK;
+}
+

+ 6 - 2
components/esp_adc_cal/include/esp_adc_cal.h

@@ -30,6 +30,7 @@ typedef enum {
     ESP_ADC_CAL_VAL_EFUSE_VREF = 0,         /**< Characterization based on reference voltage stored in eFuse*/
     ESP_ADC_CAL_VAL_EFUSE_TP = 1,           /**< Characterization based on Two Point values stored in eFuse*/
     ESP_ADC_CAL_VAL_DEFAULT_VREF = 2,       /**< Characterization based on default reference voltage*/
+    ESP_ADC_CAL_VAL_MAX
 } esp_adc_cal_value_t;
 
 /**
@@ -71,12 +72,15 @@ esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t value_type);
  * Characterization can be based on Two Point values, eFuse Vref, or default Vref
  * and the calibration values will be prioritized in that order.
  *
- * @note Two Point values and eFuse Vref can be enabled/disabled using menuconfig.
+ * @note 
+ * For ESP32, Two Point values and eFuse Vref calibration can be enabled/disabled using menuconfig.
+ * For ESP32s2, only Two Point values calibration and only ADC_WIDTH_BIT_13 is supported. The parameter default_vref is unused.
+ * 
  *
  * @param[in]   adc_num         ADC to characterize (ADC_UNIT_1 or ADC_UNIT_2)
  * @param[in]   atten           Attenuation to characterize
  * @param[in]   bit_width       Bit width configuration of ADC
- * @param[in]   default_vref    Default ADC reference voltage in mV (used if eFuse values is not available)
+ * @param[in]   default_vref    Default ADC reference voltage in mV (Only in ESP32, used if eFuse values is not available)
  * @param[out]  chars           Pointer to empty structure used to store ADC characteristics
  *
  * @return

+ 15 - 15
examples/peripherals/adc/main/adc1_example_main.c

@@ -12,15 +12,13 @@
 #include "freertos/task.h"
 #include "driver/gpio.h"
 #include "driver/adc.h"
-#if CONFIG_IDF_TARGET_ESP32
 #include "esp_adc_cal.h"
-#endif
 
 #define DEFAULT_VREF    1100        //Use adc2_vref_to_gpio() to obtain a better estimate
 #define NO_OF_SAMPLES   64          //Multisampling
 
-#if CONFIG_IDF_TARGET_ESP32
 static esp_adc_cal_characteristics_t *adc_chars;
+#if CONFIG_IDF_TARGET_ESP32
 static const adc_channel_t channel = ADC_CHANNEL_6;     //GPIO34 if ADC1, GPIO14 if ADC2
 static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
 #elif CONFIG_IDF_TARGET_ESP32S2
@@ -30,24 +28,34 @@ static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
 static const adc_atten_t atten = ADC_ATTEN_DB_0;
 static const adc_unit_t unit = ADC_UNIT_1;
 
-#if CONFIG_IDF_TARGET_ESP32
+
 static void check_efuse(void)
 {
-    //Check TP is burned into eFuse
+#if CONFIG_IDF_TARGET_ESP32
+    //Check if TP is burned into eFuse
     if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
         printf("eFuse Two Point: Supported\n");
     } else {
         printf("eFuse Two Point: NOT supported\n");
     }
-
     //Check Vref is burned into eFuse
     if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
         printf("eFuse Vref: Supported\n");
     } else {
         printf("eFuse Vref: NOT supported\n");
     }
+#elif CONFIG_IDF_TARGET_ESP32S2
+    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
+        printf("eFuse Two Point: Supported\n");
+    } else {
+        printf("Cannot retrieve eFuse Two Point calibration values. Default calibration values will be used.\n");
+    }
+#else
+#error "This example is configured for ESP32/ESP32S2."
+#endif
 }
 
+
 static void print_char_val_type(esp_adc_cal_value_t val_type)
 {
     if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
@@ -58,14 +66,12 @@ static void print_char_val_type(esp_adc_cal_value_t val_type)
         printf("Characterized using Default Vref\n");
     }
 }
-#endif
+
 
 void app_main(void)
 {
-#if CONFIG_IDF_TARGET_ESP32
     //Check if Two Point or Vref are burned into eFuse
     check_efuse();
-#endif
 
     //Configure ADC
     if (unit == ADC_UNIT_1) {
@@ -75,12 +81,10 @@ void app_main(void)
         adc2_config_channel_atten((adc2_channel_t)channel, atten);
     }
 
-#if CONFIG_IDF_TARGET_ESP32
     //Characterize ADC
     adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
     esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
     print_char_val_type(val_type);
-#endif
 
     //Continuously sample ADC1
     while (1) {
@@ -96,13 +100,9 @@ void app_main(void)
             }
         }
         adc_reading /= NO_OF_SAMPLES;
-#if CONFIG_IDF_TARGET_ESP32
         //Convert adc_reading to voltage in mV
         uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
         printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage);
-#elif CONFIG_IDF_TARGET_ESP32S2
-        printf("ADC%d CH%d Raw: %d\t\n", unit, channel, adc_reading);
-#endif
         vTaskDelay(pdMS_TO_TICKS(1000));
     }
 }

+ 1 - 1
examples/peripherals/adc2/main/adc2_example_main.c

@@ -45,7 +45,7 @@ void app_main(void)
 
     //be sure to do the init before using adc2. 
     printf("adc2_init...\n");
-    adc2_config_channel_atten( ADC2_EXAMPLE_CHANNEL, ADC_ATTEN_0db );
+    adc2_config_channel_atten( ADC2_EXAMPLE_CHANNEL, ADC_ATTEN_11db );
 
     vTaskDelay(2 * portTICK_PERIOD_MS);