Skip to content

ADC fixes and improvements #6799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 27, 2022
Merged
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
109 changes: 45 additions & 64 deletions cores/esp32/esp32-hal-adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,28 @@
// limitations under the License.

#include "esp32-hal-adc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_attr.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/adc.h"

#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp_adc_cal.h"
#include "soc/sens_reg.h"
#include "soc/rtc_io_reg.h"
#include "esp32/rom/ets_sys.h"
#include "esp_intr_alloc.h"
#include "soc/dac_channel.h"
#define DEFAULT_VREF 1100
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
static uint16_t __analogVRef = 0;
static uint8_t __analogVRefPin = 0;
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#include "soc/sens_reg.h"
#include "soc/rtc_io_reg.h"

#if SOC_DAC_SUPPORTED //ESP32, ESP32S2
#include "soc/dac_channel.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/ets_sys.h"
#include "soc/sens_reg.h"
#include "soc/rtc_io_reg.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/ets_sys.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#include "esp_intr.h"
#endif

#define DEFAULT_VREF 1100

static uint8_t __analogAttenuation = 3;//11db
static uint8_t __analogWidth = ADC_WIDTH_MAX - 1; //3 for ESP32/ESP32C3; 4 for ESP32S2
static uint8_t __analogReturnedWidth = SOC_ADC_MAX_BITWIDTH; //12 for ESP32/ESP32C3; 13 for ESP32S2
static uint8_t __analogClockDiv = 1;
static adc_attenuation_t __pin_attenuation[SOC_GPIO_PIN_COUNT];

static uint16_t __analogVRef = 0;
#if CONFIG_IDF_TARGET_ESP32
static uint8_t __analogVRefPin = 0;
#endif

static inline uint16_t mapResolution(uint16_t value)
{
uint8_t from = __analogWidth + 9;
Expand Down Expand Up @@ -117,8 +95,8 @@ void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
if(channel < 0 || attenuation > 3){
return ;
}
if(channel > 9){
adc2_config_channel_atten(channel - 10, attenuation);
if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){
adc2_config_channel_atten(channel - SOC_ADC_MAX_CHANNEL_NUM, attenuation);
} else {
adc1_config_channel_atten(channel, attenuation);
}
Expand Down Expand Up @@ -181,8 +159,8 @@ uint16_t __analogRead(uint8_t pin)
return value;
}
__adcAttachPin(pin);
if(channel > 9){
channel -= 10;
if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){
channel -= SOC_ADC_MAX_CHANNEL_NUM;
r = adc2_get_raw( channel, __analogWidth, &value);
if ( r == ESP_OK ) {
return mapResolution(value);
Expand All @@ -206,7 +184,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin){
log_e("Pin %u is not ADC pin!", pin);
return 0;
}
#if CONFIG_IDF_TARGET_ESP32

if(!__analogVRef){
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
log_d("eFuse Two Point: Supported");
Expand All @@ -218,6 +196,8 @@ uint32_t __analogReadMilliVolts(uint8_t pin){
}
if(!__analogVRef){
__analogVRef = DEFAULT_VREF;

#if CONFIG_IDF_TARGET_ESP32
if(__analogVRefPin){
esp_adc_cal_characteristics_t chars;
if(adc_vref_to_gpio(ADC_UNIT_2, __analogVRefPin) == ESP_OK){
Expand All @@ -227,42 +207,44 @@ uint32_t __analogReadMilliVolts(uint8_t pin){
log_d("Vref to GPIO%u: %u", __analogVRefPin, __analogVRef);
}
}
#endif
}
}
uint8_t unit = 1;
if(channel > 9){
if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){
unit = 2;
}

uint16_t adc_reading = __analogRead(pin);
if(__analogCharacteristics[unit - 1] == NULL){
__analogCharacteristics[unit - 1] = calloc(1, sizeof(esp_adc_cal_characteristics_t));
if(__analogCharacteristics[unit - 1] == NULL){
return 0;
}
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, __analogAttenuation, __analogWidth, __analogVRef, __analogCharacteristics[unit - 1]);

uint8_t atten = __analogAttenuation;
if (__pin_attenuation[pin] != ADC_ATTENDB_MAX){
atten = __pin_attenuation[pin];
}

esp_adc_cal_characteristics_t chars = {};
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, __analogWidth, __analogVRef, &chars);

static bool print_chars_info = true;
if(print_chars_info)
{
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
log_i("ADC%u: Characterized using Two Point Value: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
log_i("ADC%u: Characterized using eFuse Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
} else if(__analogVRef != DEFAULT_VREF){
log_i("ADC%u: Characterized using Vref to GPIO%u: %u\n", unit, __analogVRefPin, __analogCharacteristics[unit - 1]->vref);
} else {
log_i("ADC%u: Characterized using Default Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
log_i("ADC%u: Characterized using Two Point Value: %u\n", unit, chars.vref);
}
else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
log_i("ADC%u: Characterized using eFuse Vref: %u\n", unit, chars.vref);
}
#if CONFIG_IDF_TARGET_ESP32
else if(__analogVRef != DEFAULT_VREF){
log_i("ADC%u: Characterized using Vref to GPIO%u: %u\n", unit, __analogVRefPin, chars.vref);
}
#endif
else {
log_i("ADC%u: Characterized using Default Vref: %u\n", unit, chars.vref);
}
print_chars_info = false;
}
return esp_adc_cal_raw_to_voltage(adc_reading, __analogCharacteristics[unit - 1]);
#else
uint16_t adc_reading = __analogRead(pin);
uint16_t max_reading = 8191;
uint16_t max_mv = 1100;
switch(__analogAttenuation){
case 3: max_mv = 3900; break;
case 2: max_mv = 2200; break;
case 1: max_mv = 1500; break;
default: break;
}
return (adc_reading * max_mv) / max_reading;
#endif
return esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, &chars);
}

#if CONFIG_IDF_TARGET_ESP32
Expand Down Expand Up @@ -297,4 +279,3 @@ extern void analogSetVRefPin(uint8_t pin) __attribute__ ((weak, alias("__analogS
extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth")));
extern int hallRead() __attribute__ ((weak, alias("__hallRead")));
#endif