diff --git a/docs/_static/esp32s2_adc_range_to_3300.patch b/docs/_static/esp32s2_adc_range_to_3300.patch new file mode 100644 index 000000000..cad6a4fbb --- /dev/null +++ b/docs/_static/esp32s2_adc_range_to_3300.patch @@ -0,0 +1,169 @@ +From 9964b799053269c4f2106629d583e4e44d3cdb5e Mon Sep 17 00:00:00 2001 +From: yanke +Date: Thu, 12 Dec 2024 15:32:09 +0800 +Subject: [PATCH] feat(adc): support esp32s2 adc range above 2500mv + +--- + components/driver/Kconfig | 23 ++++++++++++ + components/driver/adc_common.c | 26 ++++++++++++++ + components/esp_adc_cal/esp32s2/esp_adc_cal.c | 5 +++ + components/esp_adc_cal/esp_adc_cal_common.c | 37 ++++++++++++++++++++ + 4 files changed, 91 insertions(+) + +diff --git a/components/driver/Kconfig b/components/driver/Kconfig +index 7b838784cb..cb24eccf8f 100644 +--- a/components/driver/Kconfig ++++ b/components/driver/Kconfig +@@ -41,6 +41,29 @@ menu "Driver configurations" + If you stick to this, you can enable this option to force use ADC2 under above conditions. + For more details, you can search for errata on espressif website. + ++ menu "ADC User Code Offset" ++ depends on IDF_TARGET_ESP32S2 ++ config ENABLE_ADC_USER_CODE_OFFSET ++ bool "Enable ADC user code offset" ++ default y ++ help ++ On ESP32S2, you can enable the USER_CODE_OFFSET setting to adjust the ADC range to 1000mV - 3300mV. ++ ++ choice ++ prompt "ADC calibration type" ++ depends on ENABLE_ADC_USER_CODE_OFFSET ++ default ADC_CAL_TYPE_FLOAT ++ config ADC_CAL_TYPE_FLOAT ++ bool "Float" ++ help ++ Use float type for ADC calibration calculations. ++ config ADC_CAL_TYPE_DOUBLE ++ bool "Double" ++ help ++ Use double type for ADC calibration calculations. ++ endchoice ++ ++ endmenu + endmenu # ADC Configuration + + menu "MCPWM configuration" +diff --git a/components/driver/adc_common.c b/components/driver/adc_common.c +index 93dbb2f4f6..dd162b0297 100644 +--- a/components/driver/adc_common.c ++++ b/components/driver/adc_common.c +@@ -390,6 +390,25 @@ esp_err_t adc1_lock_release(void) + return ESP_OK; + } + ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++static int16_t g_adc_cal_delta = 0; ++static int16_t g_adc_cal_delta_actual = 0; ++/** ++ * @brief Set adc1 calibration delta value ++ * ++ * @param delta_mv delta value in mv, This value will be added to the calibration value. ++ * ++ */ ++void adc1_set_cal_delta(int16_t delta_mv) ++{ ++ g_adc_cal_delta = delta_mv * 1.54f; ++} ++int16_t adc1_get_cal_delta() ++{ ++ return g_adc_cal_delta_actual; ++} ++#endif ++ + int adc1_get_raw(adc1_channel_t channel) + { + int adc_value; +@@ -399,7 +418,14 @@ int adc1_get_raw(adc1_channel_t channel) + #if SOC_ADC_CALIBRATION_V1_SUPPORTED + // Get calibration value before going into critical section + uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel); ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++ uint32_t cal_val_new = cal_val + g_adc_cal_delta; ++ cal_val_new = cal_val_new > 4095 ? 4095 : cal_val_new; ++ g_adc_cal_delta_actual = cal_val_new - cal_val; ++ adc_hal_set_calibration_param(ADC_NUM_1, cal_val_new); ++#else + adc_hal_set_calibration_param(ADC_NUM_1, cal_val); ++#endif + #endif //SOC_ADC_CALIBRATION_V1_SUPPORTED + + SARADC1_ENTER(); +diff --git a/components/esp_adc_cal/esp32s2/esp_adc_cal.c b/components/esp_adc_cal/esp32s2/esp_adc_cal.c +index 3da83880d3..bc2b6bec0c 100644 +--- a/components/esp_adc_cal/esp32s2/esp_adc_cal.c ++++ b/components/esp_adc_cal/esp32s2/esp_adc_cal.c +@@ -196,5 +196,10 @@ esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, + uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars) + { + assert(chars != NULL); ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++ extern int16_t adc1_get_cal_delta(); ++ return (adc_reading + adc1_get_cal_delta() * 2) * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling; ++#else + return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling; ++#endif + } +diff --git a/components/esp_adc_cal/esp_adc_cal_common.c b/components/esp_adc_cal/esp_adc_cal_common.c +index 09878cc015..3e60ce0e6b 100644 +--- a/components/esp_adc_cal/esp_adc_cal_common.c ++++ b/components/esp_adc_cal/esp_adc_cal_common.c +@@ -17,6 +17,10 @@ + + const static char *TAG = "ADC_CALI"; + ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++extern void adc1_set_cal_delta(int16_t delta_mv); ++#endif ++ + esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, + const esp_adc_cal_characteristics_t *chars, + uint32_t *voltage) +@@ -33,11 +37,44 @@ esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, + } else { + ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(1), ESP_ERR_INVALID_ARG, TAG, "Invalid channel"); + ret = adc2_get_raw(channel, chars->bit_width, &adc_reading); ++ if (ret != ESP_OK) { ++ ESP_LOGD(TAG, "adc2_get_raw error, please retry"); ++ return ret; ++ } + } + + if (ret == ESP_OK) { + *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); + } ++ ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++ ++#if CONFIG_ADC_CAL_TYPE_FLOAT ++ typedef const float ADC_CAL_TYPE; ++#else ++ typedef const double ADC_CAL_TYPE; ++#endif ++ if (chars->atten == ADC_ATTEN_DB_12) { ++ if (*voltage > 2600) { ++ ESP_LOGV(TAG, "first is %u", *voltage); ++ adc1_set_cal_delta(1000); ++ adc_reading = adc1_get_raw(channel); ++ adc1_set_cal_delta(0); ++ uint32_t voltage_b = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); ++ ++ ADC_CAL_TYPE a = -0.0000050800531; ++ ADC_CAL_TYPE b = 0.02334678273232382; ++ ADC_CAL_TYPE c = -26.699083271336267; ++ ADC_CAL_TYPE e = a * voltage_b * voltage_b + b * voltage_b + c; ++ ++ voltage_b = voltage_b * (1 + e / 100); ++ ++ ESP_LOGD(TAG, "after is %u", voltage_b); ++ *voltage = voltage_b; ++ } ++ } ++#endif ++ + return ret; + } + +-- +2.34.1 + diff --git a/docs/_static/esp32s2_adc_range_to_3300_v531.patch b/docs/_static/esp32s2_adc_range_to_3300_v531.patch new file mode 100644 index 000000000..5bc3c7383 --- /dev/null +++ b/docs/_static/esp32s2_adc_range_to_3300_v531.patch @@ -0,0 +1,173 @@ +From 43afc527438ea55086c35bb0db9f3938c660e8fc Mon Sep 17 00:00:00 2001 +From: yanke +Date: Thu, 12 Dec 2024 15:25:49 +0800 +Subject: [PATCH] feat(adc): support esp32s2 adc range above 2500mv + +--- + components/esp_adc/Kconfig | 23 +++++++ + components/esp_adc/adc_oneshot.c | 61 +++++++++++++++++++ + .../esp_adc/esp32s2/adc_cali_line_fitting.c | 7 ++- + components/esp_hw_support/adc_share_hw_ctrl.c | 7 +++ + 4 files changed, 97 insertions(+), 1 deletion(-) + +diff --git a/components/esp_adc/Kconfig b/components/esp_adc/Kconfig +index 0bdf4dd73e..f9fcb88822 100644 +--- a/components/esp_adc/Kconfig ++++ b/components/esp_adc/Kconfig +@@ -66,6 +66,29 @@ menu "ADC and ADC Calibration" + If you stick to this, you can enable this option to force use ADC2 under above conditions. + For more details, you can search for errata on espressif website. + ++ menu "ADC User Code Offset" ++ depends on IDF_TARGET_ESP32S2 ++ config ENABLE_ADC_USER_CODE_OFFSET ++ bool "Enable ADC user code offset" ++ default y ++ help ++ On ESP32S2, you can enable the USER_CODE_OFFSET setting to adjust the ADC range to 1000mV - 3300mV. ++ ++ choice ++ prompt "ADC calibration type" ++ depends on ENABLE_ADC_USER_CODE_OFFSET ++ default ADC_CAL_TYPE_FLOAT ++ config ADC_CAL_TYPE_FLOAT ++ bool "Float" ++ help ++ Use float type for ADC calibration calculations. ++ config ADC_CAL_TYPE_DOUBLE ++ bool "Double" ++ help ++ Use double type for ADC calibration calculations. ++ endchoice ++ endmenu ++ + config ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 + depends on IDF_TARGET_ESP32C3 + bool "Force use ADC2 oneshot mode on ESP32C3" +diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c +index 0691e22f1a..dceeea4735 100644 +--- a/components/esp_adc/adc_oneshot.c ++++ b/components/esp_adc/adc_oneshot.c +@@ -166,6 +166,29 @@ esp_err_t adc_oneshot_config_channel(adc_oneshot_unit_handle_t handle, adc_chann + return ESP_OK; + } + ++ ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++static int16_t g_adc_cal_delta = 0; ++static int16_t g_adc_cal_delta_actual = 0; ++/** ++ * @brief Set adc1 calibration delta value ++ * ++ * @param delta_mv delta value in mv, This value will be added to the calibration value. ++ * ++ */ ++void adc1_set_cal_delta(int16_t delta_mv) ++{ ++ g_adc_cal_delta = delta_mv * 1.54f; ++} ++int16_t adc1_get_cal_delta() ++{ ++ return g_adc_cal_delta_actual; ++} ++ ++extern uint32_t get_calibration_offset(adc_unit_t adc_n, adc_atten_t atten); ++#endif ++ ++ + esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, int *out_raw) + { + ESP_RETURN_ON_FALSE(handle && out_raw, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); +@@ -180,7 +203,16 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, + #if SOC_ADC_CALIBRATION_V1_SUPPORTED + adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); + adc_hal_calibration_init(handle->unit_id); ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++ adc_calc_hw_calibration_code(handle->unit_id, atten); ++ uint32_t cal_val = get_calibration_offset(handle->unit_id, atten); ++ uint32_t cal_val_new = cal_val + g_adc_cal_delta; ++ cal_val_new = cal_val_new > 4095 ? 4095 : cal_val_new; ++ g_adc_cal_delta_actual = cal_val_new - cal_val; ++ adc_hal_set_calibration_param(handle->unit_id, cal_val_new); ++#else + adc_set_hw_calibration_code(handle->unit_id, atten); ++#endif + #endif // SOC_ADC_CALIBRATION_V1_SUPPORTED + bool valid = false; + valid = adc_oneshot_hal_convert(&(handle->hal), out_raw); +@@ -255,6 +287,35 @@ esp_err_t adc_oneshot_get_calibrated_result(adc_oneshot_unit_handle_t handle, ad + ESP_LOGD(TAG, "raw: 0d%d", raw); + ESP_RETURN_ON_ERROR(adc_cali_raw_to_voltage(cali_handle, raw, cali_result), TAG, "adc calibration fail"); + ++#if (CONFIG_IDF_TARGET_ESP32S2 & CONFIG_ENABLE_ADC_USER_CODE_OFFSET) ++ int voltage_b = 0; ++#if CONFIG_ADC_CAL_TYPE_DOUBLE ++ typedef const double ADC_CAL_TYPE; ++#else ++ typedef const float ADC_CAL_TYPE; ++#endif ++ ++ adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); ++ if(atten == ADC_ATTEN_DB_12) { ++ if(*cali_result > 2600) { ++ ESP_LOGD(TAG, "first is %u", *cali_result); ++ adc1_set_cal_delta(1000); ++ ESP_RETURN_ON_ERROR(adc_oneshot_read(handle, chan, &raw), TAG, "adc oneshot read fail"); ++ adc1_set_cal_delta(0); ++ ESP_RETURN_ON_ERROR(adc_cali_raw_to_voltage(cali_handle, raw, &voltage_b), TAG, "adc calibration fail"); ++ ++ ESP_LOGD(TAG, "before is %u", voltage_b); ++ ADC_CAL_TYPE a = -0.0000050800531; ++ ADC_CAL_TYPE b = 0.02334678273232382; ++ ADC_CAL_TYPE c = -26.699083271336267; ++ ADC_CAL_TYPE e = a * voltage_b * voltage_b + b * voltage_b + c; ++ voltage_b = voltage_b * (1 + e / 100); ++ ESP_LOGD(TAG, "after is %u", voltage_b); ++ *cali_result = voltage_b; ++ } ++ } ++#endif ++ + return ESP_OK; + } + +diff --git a/components/esp_adc/esp32s2/adc_cali_line_fitting.c b/components/esp_adc/esp32s2/adc_cali_line_fitting.c +index 2e826e1f08..a43cdc5173 100644 +--- a/components/esp_adc/esp32s2/adc_cali_line_fitting.c ++++ b/components/esp_adc/esp32s2/adc_cali_line_fitting.c +@@ -143,8 +143,13 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) + //pointers are checked in the upper layer + + cali_chars_line_fitting_t *ctx = arg; +- *voltage = raw * ctx->coeff_a / coeff_a_scaling + ctx->coeff_b / coeff_b_scaling; + ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++ extern int16_t adc1_get_cal_delta(); ++ *voltage = (raw + adc1_get_cal_delta() * 2) * ctx->coeff_a / coeff_a_scaling + ctx->coeff_b / coeff_b_scaling; ++#else ++ *voltage = raw * ctx->coeff_a / coeff_a_scaling + ctx->coeff_b / coeff_b_scaling; ++#endif + return ESP_OK; + } + +diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c +index 32f3c67b79..74019195bc 100644 +--- a/components/esp_hw_support/adc_share_hw_ctrl.c ++++ b/components/esp_hw_support/adc_share_hw_ctrl.c +@@ -96,6 +96,13 @@ void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten) + ESP_EARLY_LOGV(TAG, "Calib(V%d) ADC%d atten=%d: %04" PRIX32, version, adc_n + 1, atten, init_code); + } + ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S2) ++uint32_t get_calibration_offset(adc_unit_t adc_n, adc_atten_t atten) ++{ ++ return s_adc_cali_param[adc_n][atten]; ++} ++#endif ++ + void IRAM_ATTR adc_set_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten) + { + adc_hal_set_calibration_param(adc_n, s_adc_cali_param[adc_n][atten]); +-- +2.34.1 + diff --git a/docs/_static/esp32s3_adc_range_to_3300.patch b/docs/_static/esp32s3_adc_range_to_3300.patch index ce956cc96..4a5ae983a 100644 --- a/docs/_static/esp32s3_adc_range_to_3300.patch +++ b/docs/_static/esp32s3_adc_range_to_3300.patch @@ -1,24 +1,58 @@ -From 9696f0479565203ec3638cff3f2f38e0dfbcba4b Mon Sep 17 00:00:00 2001 +From ea8f5411ab7bb0bc76c02a7c72e6c3e108375688 Mon Sep 17 00:00:00 2001 From: yanke -Date: Wed, 18 Sep 2024 16:36:27 +0800 -Subject: [PATCH] fix(adc): support esp32s3 adc range above 3100mv +Date: Thu, 12 Dec 2024 15:00:02 +0800 +Subject: [PATCH] feat(adc): support esp32s3 adc range above 3100mV --- + components/driver/Kconfig | 22 +++++++++ components/driver/adc.c | 9 ++++ .../efuse/esp32s3/esp_efuse_rtc_calib.c | 45 ++++++++++++++++++- - .../esp32s3/include/esp_efuse_rtc_calib.h | 9 ++++ - components/esp_adc_cal/esp_adc_cal_common.c | 44 ++++++++++++++++++ - 4 files changed, 106 insertions(+), 1 deletion(-) + .../esp32s3/include/esp_efuse_rtc_calib.h | 7 +++ + components/esp_adc_cal/esp_adc_cal_common.c | 45 +++++++++++++++++++ + 5 files changed, 127 insertions(+), 1 deletion(-) +diff --git a/components/driver/Kconfig b/components/driver/Kconfig +index 7b838784cb..5d23f5a8b0 100644 +--- a/components/driver/Kconfig ++++ b/components/driver/Kconfig +@@ -41,6 +41,28 @@ menu "Driver configurations" + If you stick to this, you can enable this option to force use ADC2 under above conditions. + For more details, you can search for errata on espressif website. + ++ menu "ADC User Code Offset" ++ depends on IDF_TARGET_ESP32S3 ++ config ENABLE_ADC_USER_CODE_OFFSET ++ bool "Enable ADC user code offset" ++ default y ++ help ++ On ESP32S3, you can enable the USER_CODE_OFFSET setting to adjust the ADC range to 1000mV - 3300mV. ++ ++ choice ++ prompt "ADC calibration type" ++ depends on ENABLE_ADC_USER_CODE_OFFSET ++ default ADC_CAL_TYPE_FLOAT ++ config ADC_CAL_TYPE_FLOAT ++ bool "Float" ++ help ++ Use float type for ADC calibration calculations. ++ config ADC_CAL_TYPE_DOUBLE ++ bool "Double" ++ help ++ Use double type for ADC calibration calculations. ++ endchoice ++ endmenu + endmenu # ADC Configuration + + menu "MCPWM configuration" diff --git a/components/driver/adc.c b/components/driver/adc.c -index 756ec9f26c..4743dae082 100644 +index 756ec9f26c..9fb2a5cb1a 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -866,11 +866,17 @@ static uint16_t s_adc_cali_param[SOC_ADC_PERIPH_NUM][ADC_ATTEN_MAX] = {}; //This function shoudn't be called inside critical section or ISR uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten) { -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + if (!esp_efuse_rtc_calib_query_init_code_offset_flag(adc_n, atten)) { +#endif if (s_adc_cali_param[adc_n][atten]) { @@ -26,7 +60,7 @@ index 756ec9f26c..4743dae082 100644 return (uint32_t)s_adc_cali_param[adc_n][atten]; } -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + } +#endif // check if we can fetch the values from eFuse. @@ -36,14 +70,14 @@ index 756ec9f26c..4743dae082 100644 sar_periph_ctrl_adc_oneshot_power_release(); } -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + esp_efuse_rtc_calib_clear_init_code_offset_flag(adc_n, atten); +#endif s_adc_cali_param[adc_n][atten] = init_code; ESP_LOGV(ADC_TAG, "Calib(V%d) ADC%d atten=%d: %04X", version, adc_n, atten, init_code); diff --git a/components/efuse/esp32s3/esp_efuse_rtc_calib.c b/components/efuse/esp32s3/esp_efuse_rtc_calib.c -index 7fdcdc46b9..8966976ff6 100644 +index 7fdcdc46b9..dfcc8f3f9f 100644 --- a/components/efuse/esp32s3/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32s3/esp_efuse_rtc_calib.c @@ -9,6 +9,7 @@ @@ -58,7 +92,7 @@ index 7fdcdc46b9..8966976ff6 100644 return cali_version_v1; } -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) +static uint32_t adc_icode_offset[ADC_NUM_MAX][4] = {0}; +static bool adc_icode_offset_flag[ADC_NUM_MAX][4] = {0}; + @@ -104,7 +138,7 @@ index 7fdcdc46b9..8966976ff6 100644 } - return adc_icode[atten]; -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + return adc_icode[atten] + adc_icode_offset[adc_unit][atten]; +#else + return adc_icode[atten]; @@ -113,16 +147,14 @@ index 7fdcdc46b9..8966976ff6 100644 esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t *out_digi, uint32_t *out_vol_mv) diff --git a/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h b/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h -index e2f5b54329..9d215ac057 100644 +index e2f5b54329..4d6110d865 100644 --- a/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h -@@ -54,6 +54,15 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in +@@ -54,6 +54,13 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in */ float esp_efuse_rtc_calib_get_cal_temp(int version); -+#define CONFIG_ENABLE_ADC_USER_CODE_OFFSET 1 -+ -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) +void esp_efuse_rtc_calib_set_init_code_offset(uint32_t adc_unit, int atten, uint32_t offset); +uint32_t esp_efuse_rtc_calib_get_init_code_offset(uint32_t adc_unit, int atten); +bool esp_efuse_rtc_calib_query_init_code_offset_flag(uint32_t adc_unit, int atten); @@ -133,7 +165,7 @@ index e2f5b54329..9d215ac057 100644 } #endif diff --git a/components/esp_adc_cal/esp_adc_cal_common.c b/components/esp_adc_cal/esp_adc_cal_common.c -index 09878cc015..7910359718 100644 +index 09878cc015..5c7f9bf456 100644 --- a/components/esp_adc_cal/esp_adc_cal_common.c +++ b/components/esp_adc_cal/esp_adc_cal_common.c @@ -12,6 +12,7 @@ @@ -144,7 +176,7 @@ index 09878cc015..7910359718 100644 #include "esp_adc_cal.h" #include "esp_adc_cal_internal.h" -@@ -33,11 +34,54 @@ esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, +@@ -33,11 +34,55 @@ esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel, } else { ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(1), ESP_ERR_INVALID_ARG, TAG, "Invalid channel"); ret = adc2_get_raw(channel, chars->bit_width, &adc_reading); @@ -158,10 +190,11 @@ index 09878cc015..7910359718 100644 *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars); } + -+#if (CONFIG_IDF_TARGET_ESP32S3 & CONFIG_ENABLE_ADC_USER_CODE_OFFSET) //1000mv ~ 3500mV -+#if 0 //using double type ++#if (CONFIG_IDF_TARGET_ESP32S3 & CONFIG_ENABLE_ADC_USER_CODE_OFFSET) ++ ++#if CONFIG_ADC_CAL_TYPE_DOUBLE + typedef const double ADC_CAL_TYPE; -+#else //using float type ++#else + typedef const float ADC_CAL_TYPE; +#endif + if(chars->atten == ADC_ATTEN_DB_12) { diff --git a/docs/_static/esp32s3_adc_range_to_3300_v531.patch b/docs/_static/esp32s3_adc_range_to_3300_v531.patch index de9f6f02f..d206d4f53 100644 --- a/docs/_static/esp32s3_adc_range_to_3300_v531.patch +++ b/docs/_static/esp32s3_adc_range_to_3300_v531.patch @@ -1,24 +1,25 @@ -From a5c02c9a4a0cb2f8215e7e1ed519402eb4447fc5 Mon Sep 17 00:00:00 2001 +From 83483f029f34b33cc94805c2d04f9d6218ce3eb0 Mon Sep 17 00:00:00 2001 From: yanke -Date: Thu, 19 Sep 2024 18:07:36 +0800 -Subject: [PATCH] fix(adc): support esp32s3 adc range above 3100mv +Date: Thu, 12 Dec 2024 15:16:33 +0800 +Subject: [PATCH] feat(adc): support esp32s3 adc range above 3100mV --- .../efuse/esp32s3/esp_efuse_rtc_calib.c | 45 +++++++++++++++++++ - .../esp32s3/include/esp_efuse_rtc_calib.h | 10 +++++ - components/esp_adc/adc_oneshot.c | 33 ++++++++++++++ + .../esp32s3/include/esp_efuse_rtc_calib.h | 8 ++++ + components/esp_adc/Kconfig | 23 ++++++++++ + components/esp_adc/adc_oneshot.c | 40 +++++++++++++++++ components/esp_hw_support/adc_share_hw_ctrl.c | 11 ++++- - 4 files changed, 98 insertions(+), 1 deletion(-) + 5 files changed, 126 insertions(+), 1 deletion(-) diff --git a/components/efuse/esp32s3/esp_efuse_rtc_calib.c b/components/efuse/esp32s3/esp_efuse_rtc_calib.c -index 2ede5610ba..752d072ecb 100644 +index 2ede5610ba..64019b3deb 100644 --- a/components/efuse/esp32s3/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32s3/esp_efuse_rtc_calib.c @@ -25,6 +25,47 @@ int esp_efuse_rtc_calib_get_ver(void) return cali_version; } -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + +#define ADC_NUM_MAX (ADC_UNIT_2 + 1) +static const char* TAG = "eFuse"; @@ -66,7 +67,7 @@ index 2ede5610ba..752d072ecb 100644 adc_icode[3] = adc_icode_diff[3] + adc_icode[2]; } -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + return adc_icode[atten] + adc_icode_offset[adc_unit][atten]; +#else return adc_icode[atten]; @@ -75,17 +76,15 @@ index 2ede5610ba..752d072ecb 100644 esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t *out_digi, uint32_t *out_vol_mv) diff --git a/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h b/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h -index 49712040a0..edbcc6d85f 100644 +index 49712040a0..d89617acc9 100644 --- a/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h -@@ -57,6 +57,16 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in +@@ -57,6 +57,14 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in */ esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal); + -+#define CONFIG_ENABLE_ADC_USER_CODE_OFFSET 1 -+ -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) +void esp_efuse_rtc_calib_set_init_code_offset(uint32_t adc_unit, int atten, uint32_t offset); +uint32_t esp_efuse_rtc_calib_get_init_code_offset(uint32_t adc_unit, int atten); +bool esp_efuse_rtc_calib_query_init_code_offset_flag(uint32_t adc_unit, int atten); @@ -95,8 +94,42 @@ index 49712040a0..edbcc6d85f 100644 #ifdef __cplusplus } #endif +diff --git a/components/esp_adc/Kconfig b/components/esp_adc/Kconfig +index 0bdf4dd73e..68404f7797 100644 +--- a/components/esp_adc/Kconfig ++++ b/components/esp_adc/Kconfig +@@ -66,6 +66,29 @@ menu "ADC and ADC Calibration" + If you stick to this, you can enable this option to force use ADC2 under above conditions. + For more details, you can search for errata on espressif website. + ++ menu "ADC User Code Offset" ++ depends on IDF_TARGET_ESP32S3 ++ config ENABLE_ADC_USER_CODE_OFFSET ++ bool "Enable ADC user code offset" ++ default y ++ help ++ On ESP32S3, you can enable the USER_CODE_OFFSET setting to adjust the ADC range to 1000mV - 3300mV. ++ ++ choice ++ prompt "ADC calibration type" ++ depends on ENABLE_ADC_USER_CODE_OFFSET ++ default ADC_CAL_TYPE_FLOAT ++ config ADC_CAL_TYPE_FLOAT ++ bool "Float" ++ help ++ Use float type for ADC calibration calculations. ++ config ADC_CAL_TYPE_DOUBLE ++ bool "Double" ++ help ++ Use double type for ADC calibration calculations. ++ endchoice ++ endmenu ++ + config ADC_ONESHOT_FORCE_USE_ADC2_ON_C3 + depends on IDF_TARGET_ESP32C3 + bool "Force use ADC2 oneshot mode on ESP32C3" diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c -index 0691e22f1a..cccb6ee02e 100644 +index 0691e22f1a..3f437d649a 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -29,6 +29,7 @@ @@ -116,16 +149,18 @@ index 0691e22f1a..cccb6ee02e 100644 esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, int *out_raw) { ESP_RETURN_ON_FALSE(handle && out_raw, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); -@@ -180,6 +183,8 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, +@@ -180,6 +183,10 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); adc_hal_calibration_init(handle->unit_id); ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + // Get the offset first, then set the offset. + adc_calc_hw_calibration_code(handle->unit_id, atten); ++#endif adc_set_hw_calibration_code(handle->unit_id, atten); #endif // SOC_ADC_CALIBRATION_V1_SUPPORTED bool valid = false; -@@ -251,10 +256,38 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) +@@ -251,10 +258,43 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) esp_err_t adc_oneshot_get_calibrated_result(adc_oneshot_unit_handle_t handle, adc_cali_handle_t cali_handle, adc_channel_t chan, int *cali_result) { int raw = 0; @@ -135,7 +170,12 @@ index 0691e22f1a..cccb6ee02e 100644 ESP_RETURN_ON_ERROR(adc_cali_raw_to_voltage(cali_handle, raw, cali_result), TAG, "adc calibration fail"); +#if (CONFIG_IDF_TARGET_ESP32S3 & CONFIG_ENABLE_ADC_USER_CODE_OFFSET) ++#if CONFIG_ADC_CAL_TYPE_DOUBLE ++ typedef const double ADC_CAL_TYPE; ++#else + typedef const float ADC_CAL_TYPE; ++#endif ++ + adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); + if(atten == ADC_ATTEN_DB_12) { + if(*cali_result > 2900) { @@ -165,14 +205,14 @@ index 0691e22f1a..cccb6ee02e 100644 } diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c -index 32f3c67b79..1e2431bacd 100644 +index 32f3c67b79..c2386d960d 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/components/esp_hw_support/adc_share_hw_ctrl.c @@ -60,11 +60,16 @@ static uint32_t s_adc_cali_param[SOC_ADC_PERIPH_NUM][SOC_ADC_ATTEN_NUM] = {}; void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten) { -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + if (!esp_efuse_rtc_calib_query_init_code_offset_flag(adc_n, atten)) { +#endif if (s_adc_cali_param[adc_n][atten]) { @@ -180,7 +220,7 @@ index 32f3c67b79..1e2431bacd 100644 return ; } - -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + } +#endif // check if we can fetch the values from eFuse. @@ -190,7 +230,7 @@ index 32f3c67b79..1e2431bacd 100644 } #endif //SOC_ADC_SELF_HW_CALI_SUPPORTED -+#ifdef CONFIG_ENABLE_ADC_USER_CODE_OFFSET ++#if (CONFIG_ENABLE_ADC_USER_CODE_OFFSET & CONFIG_IDF_TARGET_ESP32S3) + esp_efuse_rtc_calib_clear_init_code_offset_flag(adc_n, atten); +#endif + diff --git a/docs/_static/others/adc_range/esp32-s2-adc-extension.png b/docs/_static/others/adc_range/esp32-s2-adc-extension.png new file mode 100644 index 000000000..69008216a Binary files /dev/null and b/docs/_static/others/adc_range/esp32-s2-adc-extension.png differ diff --git a/docs/_static/others/adc_range/esp32-s3-adc-extension.png b/docs/_static/others/adc_range/esp32-s3-adc-extension.png new file mode 100644 index 000000000..8139d8425 Binary files /dev/null and b/docs/_static/others/adc_range/esp32-s3-adc-extension.png differ diff --git a/docs/en/others/adc_range.rst b/docs/en/others/adc_range.rst index 0e0e5027b..118509b93 100644 --- a/docs/en/others/adc_range.rst +++ b/docs/en/others/adc_range.rst @@ -2,37 +2,49 @@ ADC Range Extension Solution ================================ :link_to_translation:`zh_CN:[中文]` -ESP32-S3 ADC Range Extension ------------------------------------- +.. important:: The current ADC extended range solution is only applicable to ESP32-S2 and ESP32-S3 chips. -The maximum effective range of the ESP32-S3 ADC is 0 ~ 3100 mV. Through the external voltage divider circuit, it can meet most of the functions such as the ADC button or battery voltage detection. However, for applications such as NTC (Negative Temperature Coefficient) based temperature measurement, it may need to support full-scale (0 ~ 3300 mV) measurement. -ESP32-S3 can adjust the ADC offset through registers, and combined with the nonlinear compensation method of the high voltage area, the expansion of the ADC range can be implemented. +The ESP32-S2/S3 ADC, within its default range, can handle most ADC functionalities such as key input and battery voltage detection through an external voltage divider circuit. However, for applications like NTC measurements, full-scale measurement (0 ~ 3300 mV) may be required. By configuring the registers to adjust the ADC's offset voltage and applying a nonlinear compensation method for the high-voltage region, we can extend the range of the ESP32-S2/S3 ADC. The process is as follows: 1. Measure the first voltage value using the default offset -2. If the measured voltage is less than 2900 mV, the first voltage is directly output as the measurement result -3. Else if the measured voltage is greater than 2900 mV, increase the offset value to take the secondary measurement. Then carried out the nonlinear correction calculation on the secondary value, will be output as the final measurement result. +2. If the measured voltage is less than the ``set voltage``, directly output the measured voltage as the result +3. If the measured voltage is greater than the ``set voltage``, increase the offset voltage, perform a second measurement, apply nonlinear correction, and output the corrected value as the result 4. Restore the offset value once measurement is completed Overall, during each ADC measurement, there will be 1-2 times ADC reading. For most application scenarios, the measurement delay introduced by this scheme is negligible. +.. note:: For the ESP32-S2, the ``set voltage`` is 2600 mV; for the ESP32-S3, the ``set voltage`` is 2900 mV. + Patch Use Guide ------------------- +.. important:: This patch is developed based on ESP-IDF ``v4.4.8`` and ``v5.3.1``. If you need to use this solution with other versions of ESP-IDF, please refer to the patch content and modify ESP-IDF accordingly. + How to Apply a Patch Based on ESP-IDF ``v4.4.8`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* ESP32-S2 ADC Extension Patch Download::download:`esp32s2_adc_range_to_3300.patch <../../_static/esp32s2_adc_range_to_3300.patch>` +* ESP32-S3 ADC Extension Patch Download::download:`esp32s3_adc_range_to_3300.patch <../../_static/esp32s3_adc_range_to_3300.patch>` + +Using the ESP32-S3 as an example, please load the patch as follows: + 1. Please make sure ESP-IDF has been ``checked out`` to the ``v4.4.8`` -2. Please download file :download:`esp32s3_adc_range_to_3300.patch <../../_static/esp32s3_adc_range_to_3300.patch>` to anywhere you want -3. Using command ``git am --signoff < esp32s3_adc_range_to_3300.patch`` to apply the patch to ESP-IDF +2. Using command ``git am --signoff < esp32s3_adc_range_to_3300.patch`` to apply the patch to ESP-IDF +3. Please note that this solution is only effective for the ``esp_adc_cal_get_voltage`` interface. Users can directly call this interface to obtain the extended readings. How to Apply a Patch Based on ESP-IDF ``v5.3.1`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* ESP32-S2 ADC Extension Patch Download::download:`esp32s2_adc_range_to_3300_v531.patch <../../_static/esp32s2_adc_range_to_3300_v531.patch>` +* ESP32-S3 ADC Extension Patch Download::download:`esp32s3_adc_range_to_3300_v531.patch <../../_static/esp32s3_adc_range_to_3300_v531.patch>` + +Using the ESP32-S3 as an example, please load the patch as follows: + 1. Please make sure ESP-IDF has been ``checked out`` to the ``v5.3.1`` -2. Please download file :download:`esp32s3_adc_range_to_3300_v531.patch <../../_static/esp32s3_adc_range_to_3300_v531.patch>` to anywhere you want -3. Using command ``git am --signoff < esp32s3_adc_range_to_3300_v531.patch`` to apply the patch to ESP-IDF +2. Using command ``git am --signoff < esp32s3_adc_range_to_3300_v531.patch`` to apply the patch to ESP-IDF +3. Please note that this solution is only effective for the ``adc_oneshot_get_calibrated_result`` interface. Users can directly call this interface to obtain the extended readings. API Guide ------------- @@ -44,8 +56,30 @@ The method to obtain the voltage value after ADC range extension varies for diff 1. To get the range expansion result, users must directly use ``esp_adc_cal_get_voltage`` to get the voltage of ``ADC1`` or ``ADC2``. 2. Other APIs of ESP-IDF ``v4.4.8`` ADC are not affected, and the read results are consistent with the default results - - ESP-IDF ``v5.3.1`` 1. To get the range expansion result, users must directly use ``adc_oneshot_get_calibrated_result`` to get the voltage of ``ADC1`` or ``ADC2``. 2. Other APIs of ESP-IDF ``v5.3.1`` ADC are not affected, and the read results are consistent with the default results + + +The patch enables ADC range extension by default and uses the ``float`` data type for correction. If you need to disable ADC extension or change the data type used during the correction process, please refer to the following procedure: + +* For ESP-IDF ``v4.4.8``: Please use ``menuconfig`` to modify the settings under ``Component config → Driver configurations → ADC configuration → ADC User Code Offset`` +* For ESP-IDF ``v5.3.1``: Please use ``menuconfig`` to modify the settings under ``Component config → ADC and ADC Calibration → ADC User Code Offset`` + +Comparison of ADC Range Extension Effects +-------------------------------------------- + +ESP32-S2 ADC Range Extension Effects Comparison: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. figure:: ../../_static/others/adc_range/esp32-s2-adc-extension.png + :align: center + :width: 70% + +ESP32-S3 ADC Range Extension Effects Comparison: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. figure:: ../../_static/others/adc_range/esp32-s3-adc-extension.png + :align: center + :width: 70% diff --git a/docs/zh_CN/others/adc_range.rst b/docs/zh_CN/others/adc_range.rst index a81d96496..02b443d06 100644 --- a/docs/zh_CN/others/adc_range.rst +++ b/docs/zh_CN/others/adc_range.rst @@ -2,39 +2,49 @@ ADC 扩展量程方案 ==================== :link_to_translation:`en:[English]` -ESP32-S3 ADC 扩展量程方案 ----------------------------- +.. important:: 当前 ADC 扩展量程方案仅适用于 ESP32-S2 与 ESP32-S3 芯片。 -ESP32-S3 ADC 最大有效量程为 0 ~ 3100 mV,通过外部分压电路,能够满足大部分的 ADC 按键、电池电压检测等功能。但是对于 NTC 等应用场景,可能需要支持满量程(0 ~ 3300 mV)测量。 -ESP32-S3 可通过配置寄存器调整 ADC 的偏置电压,再结合高电压区域非线性补偿方法,我们可以实现对 ESP32-S3 量程的扩展。 +ESP32-S2/S3 ADC 在默认量程范围可以通过外部分压电路,实现大部分的 ADC 按键、电池电压检测等功能。但是对于 NTC 等应用场景,可能需要支持满量程(0 ~ 3300 mV)测量。ESP32-S2/S3 可通过配置寄存器调整 ADC 的偏置电压,再结合高电压区域非线性补偿方法,我们可以实现对 ESP32-S2/S3 量程的扩展。 实现量程扩展的过程为: 1. 使用默认偏置,测量一次电压值 -2. 当测量电压值小于 2900 mV,直接输出测量电压值作为测量结果 -3. 当测量电压值大于 2900 mV,提升偏置电压,进行二次测量,并进行非线性修正计算,输出修正值作为测量结果 +2. 当测量电压值小于 ``设定电压``,直接输出测量电压值作为测量结果 +3. 当测量电压值大于 ``设定电压``,提升偏置电压,进行二次测量,并进行非线性修正计算,输出修正值作为测量结果 4. 测量完成,恢复偏置电压 因此,每次 ADC 测量,期间可能读取 1~2 次实际电压值。对于大部分的应用场景,该方案引入的测量延迟可以忽略不计。 +.. note:: 对于 ESP32-S2 而言,``设定电压`` 为 2600 mV;对于 ESP32-S3 而言, ``设定电压`` 为 2900 mV。 + Patch 使用方法 ------------------- +.. important:: 当前补丁基于 ESP-IDF ``v4.4.8`` 与 ``v5.3.1`` 开发,如需在其他 ESP-IDF 版本上使用该方案,请参考补丁内容自行修改 ESP-IDF。 + 基于 ESP-IDF ``v4.4.8`` 的 Patch 使用方法 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* ESP32-S2 ADC 扩展补丁下载::download:`esp32s2_adc_range_to_3300.patch <../../_static/esp32s2_adc_range_to_3300.patch>` +* ESP32-S3 ADC 扩展补丁下载::download:`esp32s3_adc_range_to_3300.patch <../../_static/esp32s3_adc_range_to_3300.patch>` + +以 ESP32-S3 为例,请按照如下方式加载补丁: + 1. 确认 ESP-IDF 已经 ``checkout`` 到 ``v4.4.8`` -2. 下载 :download:`esp32s3_adc_range_to_3300.patch <../../_static/esp32s3_adc_range_to_3300.patch>` 文件 -3. 使用指令 ``git am --signoff < esp32s3_adc_range_to_3300.patch`` 将 Patch 应用到 IDF 中 -4. 请注意, 该方案仅对 ``esp_adc_cal_get_voltage`` 接口有效,用户可直接调用该接口获取扩展后的读数 +2. 使用指令 ``git am --signoff < esp32s3_adc_range_to_3300.patch`` 将 Patch 应用到 IDF 中 +3. 请注意, 该方案仅对 ``esp_adc_cal_get_voltage`` 接口有效,用户可直接调用该接口获取扩展后的读数 基于 ESP-IDF ``v5.3.1`` 的 Patch 使用方法 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* ESP32-S2 ADC 扩展补丁下载::download:`esp32s2_adc_range_to_3300_v531.patch <../../_static/esp32s2_adc_range_to_3300_v531.patch>` +* ESP32-S3 ADC 扩展补丁下载::download:`esp32s3_adc_range_to_3300_v531.patch <../../_static/esp32s3_adc_range_to_3300_v531.patch>` + +以 ESP32-S3 为例,请按照如下方式加载补丁: + 1. 确认 ESP-IDF 已经 ``checkout`` 到 ``v5.3.1`` -2. 下载 :download:`esp32s3_adc_range_to_3300_v531.patch <../../_static/esp32s3_adc_range_to_3300_v531.patch>` 文件 -3. 使用指令 ``git am --signoff < esp32s3_adc_range_to_3300_v531.patch`` 将 Patch 应用到 IDF 中 -4. 请注意, 该方案仅对 ``adc_oneshot_get_calibrated_result`` 接口有效,用户可直接调用该接口获取扩展后的读数 +2. 使用指令 ``git am --signoff < esp32s3_adc_range_to_3300_v531.patch`` 将 Patch 应用到 IDF 中 +3. 请注意, 该方案仅对 ``adc_oneshot_get_calibrated_result`` 接口有效,用户可直接调用该接口获取扩展后的读数 API 使用说明 -------------- @@ -50,3 +60,26 @@ API 使用说明 1. 如果想要读取量程扩展后的电压值,用户必须使用 ``adc_oneshot_get_calibrated_result`` 直接获取 ``ADC1`` 或 ``ADC2`` 的通道电压 2. ESP-IDF ``v5.3.1`` ADC 其它 API 不受影响,读取的结果和默认结果一致 + + +补丁默认开启 ADC 量程扩展,并默认使用 ``float`` 数据类型进行校正,若您需要关闭 ADC 扩展或更换校正过程中的数据类型,请参考如下过程: + +* 对于 ESP-IDF ``v4.4.8``:请使用 ``menuconfig`` 在 ``Component config → Driver configurations → ADC configuration → ADC User Code Offset`` 进行修改。 +* 对于 ESP-IDF ``v5.3.1``:请使用 ``menuconfig`` 在 ``Component config → ADC and ADC Calibration → ADC User Code Offset`` 进行修改。 + +ADC 量程扩展效果对比 +--------------------- + +ESP32-S2 ADC 量程扩展效果对比: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. figure:: ../../_static/others/adc_range/esp32-s2-adc-extension.png + :align: center + :width: 70% + +ESP32-S3 ADC 量程扩展效果对比: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. figure:: ../../_static/others/adc_range/esp32-s3-adc-extension.png + :align: center + :width: 70% diff --git a/tools/ci/astyle-rules.yml b/tools/ci/astyle-rules.yml index 379adc76e..491ce4fd5 100644 --- a/tools/ci/astyle-rules.yml +++ b/tools/ci/astyle-rules.yml @@ -37,8 +37,10 @@ not_formatted_permanent: - "components/gui/lvgl_gui/" - "components/usb/usb_stream/test_apps/main/wave_1ch_16bits.c" - "components/utilities/xz/" - - "docs/_static/esp32s3_adc_range_to_3300_v531.patch" + - "docs/_static/esp32s2_adc_range_to_3300.patch" + - "docs/_static/esp32s2_adc_range_to_3300_v531.patch" - "docs/_static/esp32s3_adc_range_to_3300.patch" + - "docs/_static/esp32s3_adc_range_to_3300_v531.patch" - "docs/doxygen-known-warnings.txt" - "docs/sphinx-known-warnings.txt" - "examples/hmi/lvgl_coffee/"