From 2a3a8f8f530ac36009ecc95dd2ce229326a0a9b9 Mon Sep 17 00:00:00 2001 From: Andrea Milazzo Date: Tue, 12 Mar 2024 09:45:19 +0100 Subject: [PATCH] esp32/adc: Add support for v5.2.1 calibration api. This new calibration routine exists for S3 in v5.1.1. It works for all platforms in 5.2.1. Signed-off-by: Andrew Leech --- ports/esp32/adc.c | 36 +++++++++++++++++++++++++++++++++--- ports/esp32/adc.h | 5 +++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ports/esp32/adc.c b/ports/esp32/adc.c index c5886624ec..7c9e0cfad6 100644 --- a/ports/esp32/adc.c +++ b/ports/esp32/adc.c @@ -28,6 +28,7 @@ #include "py/mphal.h" #include "adc.h" #include "driver/adc.h" +#include "esp_adc/adc_cali_scheme.h" #define DEFAULT_VREF 1100 @@ -63,30 +64,59 @@ void madcblock_bits_helper(machine_adc_block_obj_t *self, mp_int_t bits) { adc1_config_width(self->width); } for (adc_atten_t atten = ADC_ATTEN_DB_0; atten < ADC_ATTEN_MAX; atten++) { + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 1) + if (self->handle[atten] != NULL) { + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = self->unit_id, + .atten = atten, + .bitwidth = self->width, + }; + check_esp_err(adc_cali_create_scheme_curve_fitting(&cali_config, self->handle[atten])); + } + #else if (self->characteristics[atten] != NULL) { esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, self->characteristics[atten]); } + #endif } } mp_int_t madcblock_read_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id) { - int raw; + int raw = 0; if (self->unit_id == ADC_UNIT_1) { raw = adc1_get_raw(channel_id); } else { + #if (SOC_ADC_PERIPH_NUM >= 2) check_esp_err(adc2_get_raw(channel_id, self->width, &raw)); + #endif } return raw; } mp_int_t madcblock_read_uv_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id, adc_atten_t atten) { int raw = madcblock_read_helper(self, channel_id); + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 1) + adc_cali_handle_t *adc_handle = self->handle[atten]; + if (adc_handle == NULL) { + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = self->unit_id, + .atten = atten, + .bitwidth = self->width, + }; + adc_handle = malloc(sizeof(adc_cali_handle_t)); + check_esp_err(adc_cali_create_scheme_curve_fitting(&cali_config, adc_handle)); + self->handle[atten] = adc_handle; + } + int uv; + check_esp_err(adc_cali_raw_to_voltage(*adc_handle, raw, &uv)); + #else esp_adc_cal_characteristics_t *adc_chars = self->characteristics[atten]; if (adc_chars == NULL) { adc_chars = malloc(sizeof(esp_adc_cal_characteristics_t)); esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, adc_chars); self->characteristics[atten] = adc_chars; } - mp_int_t uv = esp_adc_cal_raw_to_voltage(raw, adc_chars) * 1000; - return uv; + mp_int_t uv = esp_adc_cal_raw_to_voltage(raw, adc_chars); + #endif + return (mp_int_t)uv * 1000; } diff --git a/ports/esp32/adc.h b/ports/esp32/adc.h index ae5c0d3c37..61771255d3 100644 --- a/ports/esp32/adc.h +++ b/ports/esp32/adc.h @@ -30,6 +30,7 @@ #include "py/runtime.h" #include "esp_adc_cal.h" +#include "esp_adc/adc_cali_scheme.h" #define ADC_ATTEN_MAX SOC_ADC_ATTEN_NUM @@ -38,7 +39,11 @@ typedef struct _machine_adc_block_obj_t { adc_unit_t unit_id; mp_int_t bits; adc_bits_width_t width; + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 1) + adc_cali_handle_t *handle[ADC_ATTEN_MAX]; + #else esp_adc_cal_characteristics_t *characteristics[ADC_ATTEN_MAX]; + #endif } machine_adc_block_obj_t; typedef struct _machine_adc_obj_t {