mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-03 15:49:51 +01:00
esp_adc_cal/Add eFuse functionality
This commit updates the esp_adc_cal ocmponent to support new calibration methods which utilize calibratoin values stored in eFuse. This commit includes LUT mode
This commit is contained in:
37
components/esp_adc_cal/Kconfig
Normal file
37
components/esp_adc_cal/Kconfig
Normal file
@@ -0,0 +1,37 @@
|
||||
menu "ADC-Calibration"
|
||||
|
||||
config ADC_CAL_EFUSE_TP_DISABLE
|
||||
bool "Disable Two Point values"
|
||||
default "n"
|
||||
help
|
||||
Some ESP32s have Two Point calibration values burned into eFuse. Enabling
|
||||
this option will prevent the ADC calibration component from using Two Point
|
||||
values if they are available.
|
||||
|
||||
config ADC_CAL_EFUSE_VREF_DISABLE
|
||||
bool "Disable eFuse Vref"
|
||||
default "n"
|
||||
help
|
||||
Some ESP32s have ADC Vref burned into eFuse. Enabling this option will
|
||||
prevent the ADC calibration component from using eFuse Vref if they are
|
||||
available.
|
||||
|
||||
config ADC_CAL_DEFAULT_VREF_DISABLE
|
||||
bool "Disable Default Vref"
|
||||
default "n"
|
||||
help
|
||||
The esp_adc_cal_characterize() function requires the user to provide a
|
||||
vref_default argument to be used if eFuse values are unavailable. Enabling
|
||||
this option will prevent the ADC calibration component from using the
|
||||
vref_default argument. Note that if eFuse values are also unavailabe,
|
||||
the esp_adc_cal_characterize will trigger an abort.
|
||||
|
||||
config ADC_CAL_NO_BLK3_RESERVE_FLAG
|
||||
bool "EFUSE_BLK3_PART_RESERVE not set"
|
||||
default "n"
|
||||
help
|
||||
By default, ESP32s will have the EFUSE_BLK3_PART_RESERVE flag set if it
|
||||
uses BLK3 of eFuse to store Two Point values. Some ESP32s do not set this
|
||||
flag. Enable this option if that is the case
|
||||
|
||||
endmenu # ADC-Calibration
|
||||
@@ -13,99 +13,444 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_types.h"
|
||||
#include "driver/adc.h"
|
||||
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "assert.h"
|
||||
#include "esp_adc_cal_constants.h"
|
||||
#include "esp_adc_cal.h"
|
||||
|
||||
static const esp_adc_cal_lookup_table_t *table_ptrs[4] = {&esp_adc_cal_table_atten_0,
|
||||
&esp_adc_cal_table_atten_1,
|
||||
&esp_adc_cal_table_atten_2,
|
||||
&esp_adc_cal_table_atten_3};
|
||||
#define CONFIG_ADC_CAL_EFUSE_TP_DISABLE
|
||||
/* ----------------------------- Configuration ------------------------------ */
|
||||
|
||||
uint32_t get_adc_vref_from_efuse()
|
||||
#ifdef CONFIG_ADC_CAL_EFUSE_TP_DISABLE
|
||||
#define EFUSE_TP_ENABLED 0
|
||||
#else
|
||||
#define EFUSE_TP_ENABLED 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ADC_CAL_EFUSE_VREF_DISABLE
|
||||
#define EFUSE_VREF_ENABLED 0
|
||||
#else
|
||||
#define EFUSE_VREF_ENABLED 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ADC_CAL_DEFAULT_VREF_DISABLE
|
||||
#define DEFAULT_VREF_ENABLED 0
|
||||
#else
|
||||
#define DEFAULT_VREF_ENABLED 1
|
||||
#endif
|
||||
|
||||
/* ------------------------------ eFuse Access ----------------------------- */
|
||||
|
||||
#define BLK3_RESERVED_REG EFUSE_BLK0_RDATA4_REG
|
||||
|
||||
#define VREF_REG EFUSE_BLK0_RDATA4_REG
|
||||
#define VREF_SIGN_BIT 0x10
|
||||
#define VREF_MAG_BITS 0x0F
|
||||
#define VREF_STEP_SIZE 7
|
||||
#define VREF_OFFSET 1100
|
||||
|
||||
#define TP_REG EFUSE_BLK3_RDATA3_REG
|
||||
#define TP_LOW1_OFFSET 278
|
||||
#define TP_LOW2_OFFSET 421
|
||||
#define TP_HIGH1_OFFSET 3265
|
||||
#define TP_HIGH2_OFFSET 3406
|
||||
#define TP_LOW_SIGN_BIT 0x40
|
||||
#define TP_LOW_MAG_BITS 0x3F
|
||||
#define TP_LOW_VOLTAGE 150
|
||||
#define TP_HIGH_SIGN_BIT 0x100
|
||||
#define TP_HIGH_MAG_BITS 0xFF
|
||||
#define TP_HIGH_VOLTAGE 850
|
||||
#define TP_STEP_SIZE 4
|
||||
|
||||
/* -------------------- Linear and LUT mode constants ----------------------- */
|
||||
|
||||
#define LIN_COEFF_A_SCALE 65536
|
||||
#define LIN_COEFF_A_ROUND (LIN_COEFF_A_SCALE/2)
|
||||
#define LUT_VREF_IDEAL 1100
|
||||
#define LUT_VREF_LOW 1000
|
||||
#define LUT_VREF_HIGH 1200
|
||||
#define LUT_ADC_STEP_SIZE 128
|
||||
#define ADC_12_BIT_MAX 4095
|
||||
|
||||
#define ADC_CAL_ASSERT(cond, ret) ({ \
|
||||
if(!(cond)){ \
|
||||
return ret; \
|
||||
} \
|
||||
})
|
||||
|
||||
#define ESP_ADC_CAL_ERR_STR "No characterization possible"
|
||||
static const char* ESP_ADC_CAL_TAG = "esp_adc_cal_log";
|
||||
|
||||
extern const uint32_t adc1_lin_tp_atten_scale[4];
|
||||
extern const uint32_t adc2_lin_tp_atten_scale[4];
|
||||
extern const uint32_t adc1_lin_tp_atten_offset[4];
|
||||
extern const uint32_t adc2_lin_tp_atten_offset[4];
|
||||
extern const uint32_t adc1_lin_vref_atten_scale[4];
|
||||
extern const uint32_t adc2_lin_vref_atten_scale[4];
|
||||
extern const uint32_t adc1_lin_vref_atten_offset[4];
|
||||
extern const uint32_t adc2_lin_vref_atten_offset[4];
|
||||
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten0_adc1;
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten0_adc2;
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten1_adc1;
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten1_adc2;
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten2_adc1;
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten2_adc2;
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten3_adc1;
|
||||
extern const esp_adc_cal_lookup_table_t lut_atten3_adc2;
|
||||
|
||||
/* ----------------------- EFuse Access Functions --------------------------- */
|
||||
|
||||
//Check if Vref is burned in eFuse
|
||||
static bool check_efuse_vref()
|
||||
{
|
||||
//TODO: Replaced with read to eFuse once ATE confirms location of 5 bits
|
||||
return 0;
|
||||
//Check eFuse for vref
|
||||
return (REG_GET_FIELD(VREF_REG, EFUSE_RD_ADC_VREF) != 0) ? true : false;
|
||||
}
|
||||
|
||||
void esp_adc_cal_get_characteristics(uint32_t v_ref,
|
||||
//Check if Two Point values are burned in eFuse
|
||||
static bool check_efuse_tp()
|
||||
{
|
||||
#ifndef CONFIG_ADC_CAL_NO_BLK3_RESERVE_FLAG
|
||||
//BLK3_PART_RESERVE flag must be set
|
||||
if(REG_GET_FIELD(BLK3_RESERVED_REG, EFUSE_RD_BLK3_PART_RESERVE) == 0){
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
//All TP cal values must be non zero
|
||||
if((REG_GET_FIELD(TP_REG, EFUSE_RD_ADC1_TP_LOW) != 0) &&
|
||||
(REG_GET_FIELD(TP_REG, EFUSE_RD_ADC2_TP_LOW) != 0) &&
|
||||
(REG_GET_FIELD(TP_REG, EFUSE_RD_ADC1_TP_HIGH) != 0) &&
|
||||
(REG_GET_FIELD(TP_REG, EFUSE_RD_ADC2_TP_HIGH) != 0)){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Read Vref from eFuse
|
||||
static uint32_t read_efuse_vref()
|
||||
{
|
||||
//eFuse stores deviation from ideal reference voltage
|
||||
uint32_t ret = VREF_OFFSET; //Ideal vref
|
||||
uint32_t bits = REG_GET_FIELD(VREF_REG, EFUSE_ADC_VREF);
|
||||
|
||||
if(bits & VREF_SIGN_BIT){ //Negative deviation from ideal Vref
|
||||
#ifndef CONFIG_ADC_CAL_NO_BLK3_RESERVE_FLAG
|
||||
//Deviation stored in sign-magnitude format
|
||||
ret -= (bits & VREF_MAG_BITS) * VREF_STEP_SIZE;
|
||||
#else
|
||||
//Deviation stored in two's complement
|
||||
ret -= (((~bits)+1) & VREF_MAG_BITS) * VREF_STEP_SIZE;
|
||||
#endif
|
||||
} else { //Positive deviation from ideal Vref
|
||||
ret += (bits & VREF_MAG_BITS) * VREF_STEP_SIZE;
|
||||
}
|
||||
return ret; //ADC Vref in mV
|
||||
}
|
||||
|
||||
//Read Two Point low reading from eFuse
|
||||
static uint32_t read_efuse_tp_low(adc_unit_t adc_num)
|
||||
{
|
||||
//ADC reading at 150mV stored in two's complement format
|
||||
uint32_t ret;
|
||||
uint32_t bits;
|
||||
|
||||
if(adc_num == ADC_UNIT_1){
|
||||
ret = TP_LOW1_OFFSET;
|
||||
bits = REG_GET_FIELD(TP_REG, EFUSE_RD_ADC1_TP_LOW);
|
||||
} else {
|
||||
ret = TP_LOW2_OFFSET;
|
||||
bits = REG_GET_FIELD(TP_REG, EFUSE_RD_ADC2_TP_LOW);
|
||||
}
|
||||
|
||||
//Represented in two's complement format
|
||||
if(bits & TP_LOW_SIGN_BIT){ //Negative
|
||||
ret -= (((~bits) + 1) & TP_LOW_MAG_BITS) * TP_STEP_SIZE;
|
||||
} else { //Positive
|
||||
ret += (bits & TP_LOW_MAG_BITS) * TP_STEP_SIZE;
|
||||
}
|
||||
return ret; //Reading of ADC at 150mV
|
||||
}
|
||||
|
||||
//Read Two Point high reading from eFuse
|
||||
static uint32_t read_efuse_tp_high(adc_unit_t adc_num)
|
||||
{
|
||||
//ADC reading at 850mV stored in two's complement format
|
||||
uint32_t ret;
|
||||
uint32_t bits;
|
||||
if(adc_num == ADC_UNIT_1){
|
||||
ret = TP_HIGH1_OFFSET;
|
||||
bits = REG_GET_FIELD(TP_REG, EFUSE_RD_ADC1_TP_HIGH);
|
||||
} else {
|
||||
ret = TP_HIGH2_OFFSET;
|
||||
bits = REG_GET_FIELD(TP_REG, EFUSE_RD_ADC2_TP_HIGH);
|
||||
}
|
||||
|
||||
//Represented in two's complement format
|
||||
if(bits & TP_HIGH_SIGN_BIT){ //Negative
|
||||
ret -= (((~bits) + 1) & TP_HIGH_MAG_BITS) * TP_STEP_SIZE;
|
||||
} else { //Positive
|
||||
ret += (bits & TP_HIGH_MAG_BITS) * TP_STEP_SIZE;
|
||||
}
|
||||
return ret; //Reading of ADC at 850mV
|
||||
}
|
||||
|
||||
/* ----------------------- Characterization Functions ----------------------- */
|
||||
|
||||
//Linear characterization using Two Point values
|
||||
static void characterize_lin_tp(adc_unit_t adc_num,
|
||||
adc_atten_t atten,
|
||||
uint32_t high,
|
||||
uint32_t low,
|
||||
uint32_t *coeff_a,
|
||||
uint32_t *coeff_b)
|
||||
{
|
||||
const uint32_t *atten_scales;
|
||||
const uint32_t *atten_offsets;
|
||||
|
||||
if(adc_num == ADC_UNIT_1){ //Using ADC 1
|
||||
atten_scales = adc1_lin_tp_atten_scale;
|
||||
atten_offsets = adc1_lin_tp_atten_offset;
|
||||
} else { //Using ADC 2
|
||||
atten_scales = adc2_lin_tp_atten_scale;
|
||||
atten_offsets = adc2_lin_tp_atten_offset;
|
||||
}
|
||||
//Characterize ADC-Voltage curve as y = (coeff_a * x) + coeff_b
|
||||
uint32_t delta_x = high - low;
|
||||
uint32_t delta_v = TP_HIGH_VOLTAGE - TP_LOW_VOLTAGE;
|
||||
//coeff_a = (delta_v/delta_x) * atten_scale
|
||||
*coeff_a = (delta_v * atten_scales[atten] + (delta_x/2)) / delta_x; //+(delta_x/2) for rounding
|
||||
//coeff_b = high_v - ((delta_v/delta_x) * high_x) + atten_offset
|
||||
*coeff_b = TP_HIGH_VOLTAGE - ((delta_v * high + (delta_x/2)) / delta_x) + atten_offsets[atten];
|
||||
}
|
||||
|
||||
//Linear characterization using Vref
|
||||
static void characterize_lin_vref(adc_unit_t adc_num,
|
||||
adc_atten_t atten,
|
||||
uint32_t vref,
|
||||
uint32_t *coeff_a,
|
||||
uint32_t *coeff_b)
|
||||
{
|
||||
const uint32_t *atten_scales;;
|
||||
const uint32_t *atten_offsets;
|
||||
|
||||
if(adc_num == ADC_UNIT_1){ //Using ADC 1
|
||||
atten_scales = adc1_lin_vref_atten_scale;
|
||||
atten_offsets = adc1_lin_vref_atten_offset;
|
||||
} else { //Using ADC 2
|
||||
atten_scales = adc2_lin_vref_atten_scale;
|
||||
atten_offsets = adc2_lin_vref_atten_offset;
|
||||
}
|
||||
//Characterize ADC-Voltage curve as y = (coeff_a * x) + coeff_b
|
||||
//coeff_a = (vref/4096) * atten_scale
|
||||
*coeff_a = (vref * atten_scales[atten]) / (ADC_12_BIT_MAX + 1);
|
||||
*coeff_b = atten_offsets[atten];
|
||||
}
|
||||
|
||||
//LUT characterization
|
||||
static void characterize_lut(adc_unit_t adc_num,
|
||||
adc_atten_t atten,
|
||||
uint32_t vref,
|
||||
const esp_adc_cal_lookup_table_t **table_ptr)
|
||||
{
|
||||
//Get pointer to the correct lookup table
|
||||
if(atten == ADC_ATTEN_DB_0){
|
||||
*table_ptr = (adc_num == ADC_UNIT_1) ? &lut_atten0_adc1 : &lut_atten0_adc2;
|
||||
} else if (atten == ADC_ATTEN_DB_2_5){
|
||||
*table_ptr = (adc_num == ADC_UNIT_1) ? &lut_atten1_adc1 : &lut_atten1_adc2;
|
||||
} else if (atten == ADC_ATTEN_DB_6){
|
||||
*table_ptr = (adc_num == ADC_UNIT_1) ? &lut_atten2_adc1 : &lut_atten2_adc2;
|
||||
} else {
|
||||
*table_ptr = (adc_num == ADC_UNIT_1) ? &lut_atten3_adc1 : &lut_atten3_adc2;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------ Conversion Functions --------------------------- */
|
||||
|
||||
//Calculate voltage using linear characterization of the ADC curve
|
||||
static uint32_t linear_raw_to_voltage(uint32_t adc,
|
||||
uint32_t gain,
|
||||
uint32_t offset)
|
||||
{
|
||||
//ADC Curve is characterized as y = coeff_a * adc + coeff_b
|
||||
//All gains scaled by 65536
|
||||
return (((gain * adc) + LIN_COEFF_A_ROUND) / LIN_COEFF_A_SCALE) + offset;
|
||||
}
|
||||
|
||||
//Calculate voltage using a lookup table
|
||||
static uint32_t lut_raw_to_voltage(uint32_t adc, uint32_t vref, const esp_adc_cal_lookup_table_t *table)
|
||||
{
|
||||
//Get index of lower bound points of LUT
|
||||
uint32_t i = (adc / LUT_ADC_STEP_SIZE);
|
||||
|
||||
//Let the X Axis be Vref, Y axis be ADC reading, and Z be voltage
|
||||
int x2dist = LUT_VREF_HIGH - vref; //(x2 - x)
|
||||
int x1dist = vref - LUT_VREF_LOW; //(x - x1)
|
||||
int y2dist = ((i+1) * LUT_ADC_STEP_SIZE) - adc; //(y2 - y)
|
||||
int y1dist = adc - (i * LUT_ADC_STEP_SIZE); //(y - y1)
|
||||
|
||||
//For points for bilinear interpolation
|
||||
int q11 = (int)table->low_vref_curve[i]; //Lower bound point of low_vref_curve
|
||||
int q12 = (int)table->low_vref_curve[i+1]; //Upper bound point of low_vref_curve
|
||||
int q21 = (int)table->high_vref_curve[i]; //Lower bound point of high_vref_curve
|
||||
int q22 = (int)table->high_vref_curve[i+1]; //Upper bound point of high_vref_curve
|
||||
|
||||
//Bilinear interpolation
|
||||
//z = 1/((x2-x1)*(y2-y1)) * ( (q11*x2dist*y2dist) + (q21*x1dist*y2dist) + (q12*x2dist*y1dist) + (q22*x1dist*y1dist) )
|
||||
int voltage = (q11*x2dist*y2dist) + (q21*x1dist*y2dist) + (q12*x2dist*y1dist) + (q22*x1dist*y1dist);
|
||||
voltage += ((LUT_VREF_HIGH - LUT_VREF_LOW) * LUT_ADC_STEP_SIZE)/2; //Integer division rounding
|
||||
voltage /= ((LUT_VREF_HIGH - LUT_VREF_LOW) * LUT_ADC_STEP_SIZE); //Divide by ((x2-x1)*(y2-y1))
|
||||
return (uint32_t)voltage;
|
||||
}
|
||||
|
||||
/* ------------------------- 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 (check_efuse_tp()) ? ESP_OK : ESP_ERR_NOT_SUPPORTED;
|
||||
} else if (source == ESP_ADC_CAL_VAL_EFUSE_VREF){
|
||||
return (check_efuse_vref()) ? ESP_OK : ESP_ERR_NOT_SUPPORTED;
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num,
|
||||
adc_atten_t atten,
|
||||
esp_adc_cal_mode_t mode,
|
||||
uint32_t vref_default,
|
||||
esp_adc_cal_characteristics_t *chars)
|
||||
{
|
||||
assert((adc_num == ADC_UNIT_1) || (adc_num == ADC_UNIT_2));
|
||||
assert(chars != NULL);
|
||||
|
||||
//Check eFuse if enabled to do so
|
||||
bool efuse_tp_present = check_efuse_tp();
|
||||
bool efuse_vref_present = check_efuse_vref();
|
||||
esp_adc_cal_value_t ret;
|
||||
|
||||
if(mode == ESP_ADC_CAL_MODE_LIN){
|
||||
if(efuse_tp_present && EFUSE_TP_ENABLED){
|
||||
uint32_t high = read_efuse_tp_high(adc_num);
|
||||
uint32_t low = read_efuse_tp_low(adc_num);
|
||||
characterize_lin_tp(adc_num, atten, high, low, &chars->linear_chars.coeff_a, &chars->linear_chars.coeff_b);
|
||||
ret = ESP_ADC_CAL_VAL_EFUSE_TP;
|
||||
} else if(efuse_vref_present && EFUSE_VREF_ENABLED){
|
||||
uint32_t vref = read_efuse_vref();
|
||||
characterize_lin_vref(adc_num, atten, vref, &chars->linear_chars.coeff_a, &chars->linear_chars.coeff_b);
|
||||
ret = ESP_ADC_CAL_VAL_EFUSE_VREF;
|
||||
} else if(DEFAULT_VREF_ENABLED){
|
||||
characterize_lin_vref(adc_num, atten, vref_default, &chars->linear_chars.coeff_a, &chars->linear_chars.coeff_b);
|
||||
ret = ESP_ADC_CAL_VAL_DEFAULT_VREF;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
} else if (mode == ESP_ADC_CAL_MODE_LUT){
|
||||
if(efuse_vref_present && EFUSE_VREF_ENABLED){
|
||||
uint32_t vref = read_efuse_vref();
|
||||
chars->lut_chars.vref = vref;
|
||||
characterize_lut(adc_num, atten, vref, &chars->lut_chars.table);
|
||||
ret = ESP_ADC_CAL_VAL_EFUSE_VREF;
|
||||
} else if(DEFAULT_VREF_ENABLED){
|
||||
chars->lut_chars.vref = vref_default;
|
||||
characterize_lut(adc_num, atten, vref_default, &chars->lut_chars.table);
|
||||
ret = ESP_ADC_CAL_VAL_DEFAULT_VREF;
|
||||
} else{
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
chars->mode = mode;
|
||||
chars->adc_num = adc_num;
|
||||
return ret;
|
||||
|
||||
err: //No possible characterization
|
||||
// usually only occurs if users manually disable calibration values and modes in menuconfig
|
||||
ESP_LOGE(ESP_ADC_CAL_TAG, ESP_ADC_CAL_ERR_STR);
|
||||
abort();
|
||||
return ESP_ADC_CAL_VAL_DEFAULT_VREF; //Should not reach this point, added to suppress Eclipse warnings
|
||||
}
|
||||
|
||||
uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading,
|
||||
adc_bits_width_t bit_width,
|
||||
const esp_adc_cal_characteristics_t *chars)
|
||||
{
|
||||
assert(chars != NULL);
|
||||
//Scale adc_rading if not 12 bits wide
|
||||
if(bit_width != ADC_WIDTH_BIT_12){
|
||||
adc_reading = (adc_reading << (ADC_WIDTH_BIT_12 - bit_width));
|
||||
//If adc_reading is out of 12bit range
|
||||
if(adc_reading > ADC_12_BIT_MAX){
|
||||
adc_reading = ADC_12_BIT_MAX; //Set to 12bit max
|
||||
}
|
||||
}
|
||||
|
||||
//Convert ADC reading to voltage in mV
|
||||
if(chars->mode == ESP_ADC_CAL_MODE_LUT){ //Lookup Table
|
||||
assert(chars->lut_chars.table != NULL);
|
||||
return lut_raw_to_voltage(adc_reading, chars->lut_chars.vref, chars->lut_chars.table);
|
||||
} else {
|
||||
return linear_raw_to_voltage(adc_reading, chars->linear_chars.coeff_a, chars->linear_chars.coeff_b);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t adc_to_voltage(adc_channel_t channel,
|
||||
adc_bits_width_t bit_width,
|
||||
const esp_adc_cal_characteristics_t *chars,
|
||||
uint32_t *voltage)
|
||||
{
|
||||
//Check parameters
|
||||
ADC_CAL_ASSERT(chars != NULL, ESP_ERR_INVALID_ARG);
|
||||
ADC_CAL_ASSERT(voltage != NULL, ESP_ERR_INVALID_ARG);
|
||||
|
||||
if(chars->adc_num == ADC_UNIT_1){
|
||||
//Check channel is valid on ADC1
|
||||
ADC_CAL_ASSERT((adc1_channel_t)channel < ADC1_CHANNEL_MAX, ESP_ERR_INVALID_ARG);
|
||||
uint32_t adc_reading = (uint32_t)adc1_get_raw(channel); //Todo: get_raw function to change
|
||||
*voltage = esp_adc_cal_raw_to_voltage(adc_reading, bit_width, chars);
|
||||
} else {
|
||||
//Check channel is valid on ADC2
|
||||
ADC_CAL_ASSERT((adc2_channel_t)channel < ADC2_CHANNEL_MAX, ESP_ERR_INVALID_ARG);
|
||||
int adc_reading;
|
||||
if(adc2_get_raw(channel, bit_width, &adc_reading) != ESP_OK){
|
||||
//Timed out waiting for ADC2
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
*voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, bit_width, chars);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* ------------------------ Deprecated API --------------------------------- */
|
||||
|
||||
void esp_adc_cal_get_characteristics(uint32_t vref,
|
||||
adc_atten_t atten,
|
||||
adc_bits_width_t bit_width,
|
||||
esp_adc_cal_characteristics_t *chars)
|
||||
{
|
||||
chars->v_ref = v_ref;
|
||||
chars->table = table_ptrs[atten];
|
||||
chars->bit_width = bit_width;
|
||||
if (v_ref >= ADC_CAL_LOW_V_REF) {
|
||||
chars->gain = ((chars->v_ref - ADC_CAL_LOW_V_REF)
|
||||
* chars->table->gain_m)
|
||||
+ chars->table->gain_c;
|
||||
chars->offset = (((chars->v_ref - ADC_CAL_LOW_V_REF)
|
||||
* chars->table->offset_m)
|
||||
+ chars->table->offset_c
|
||||
+ ((1 << ADC_CAL_OFFSET_SCALE) / 2))
|
||||
>> ADC_CAL_OFFSET_SCALE; //Bit shift to cancel 2^10 multiplier
|
||||
chars->ideal_offset = (((ADC_CAL_IDEAL_V_REF - ADC_CAL_LOW_V_REF)
|
||||
* chars->table->offset_m)
|
||||
+ chars->table->offset_c
|
||||
+ ((1 << ADC_CAL_OFFSET_SCALE) / 2)) //Rounding
|
||||
>> ADC_CAL_OFFSET_SCALE;
|
||||
} else { //For case where v_ref is smaller than low bound resulting in negative
|
||||
chars->gain = chars->table->gain_c
|
||||
- ((ADC_CAL_LOW_V_REF - chars->v_ref)
|
||||
* chars->table->gain_m);
|
||||
chars->offset = (chars->table->offset_c
|
||||
- ((chars->v_ref - ADC_CAL_LOW_V_REF)
|
||||
* chars->table->offset_m)
|
||||
+ ((1 << ADC_CAL_OFFSET_SCALE) / 2)) //Rounding
|
||||
>> ADC_CAL_OFFSET_SCALE; //Bit shift to cancel 2^10 multiplier
|
||||
chars->ideal_offset = (chars->table->offset_c
|
||||
- ((ADC_CAL_IDEAL_V_REF - ADC_CAL_LOW_V_REF)
|
||||
* chars->table->offset_m)
|
||||
+ ((1 << ADC_CAL_OFFSET_SCALE) / 2)) //Rounding
|
||||
>> ADC_CAL_OFFSET_SCALE;
|
||||
}
|
||||
}
|
||||
//Default to ADC1 and LUT mode
|
||||
assert(chars != NULL);
|
||||
|
||||
static uint32_t esp_adc_cal_interpolate_round(uint32_t lower, uint32_t upper,
|
||||
uint32_t step, uint32_t point)
|
||||
{
|
||||
//Interpolate 'point' between 'lower' and 'upper' seperated by 'step'
|
||||
return ((lower * step) - (lower * point) + (upper * point) + (step / 2)) / step;
|
||||
}
|
||||
|
||||
uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc,
|
||||
const esp_adc_cal_characteristics_t *chars)
|
||||
{
|
||||
//Scale ADC to 12 bit width (0 to 4095)
|
||||
adc <<= (ADC_WIDTH_BIT_12 - chars->bit_width);
|
||||
uint32_t i = (adc >> chars->table->bit_shift); //find index for lut voltages
|
||||
//Refernce LUT to obtain voltage using index
|
||||
uint32_t voltage = esp_adc_cal_interpolate_round(chars->table->voltage[i],
|
||||
chars->table->voltage[i + 1],
|
||||
(1 << chars->table->bit_shift),
|
||||
adc - (i << chars->table->bit_shift));
|
||||
/*
|
||||
* Apply Gain, scaling(bit shift) and offset to interpolated voltage
|
||||
* v_true = (((v_id - off_id)*gain)*scaling) + off_true
|
||||
*/
|
||||
if (voltage > chars->ideal_offset) {
|
||||
voltage = (voltage - chars->ideal_offset) * chars->gain;
|
||||
voltage += (1 << ADC_CAL_GAIN_SCALE) / 2; //For rounding when scaled
|
||||
voltage >>= ADC_CAL_GAIN_SCALE;
|
||||
voltage += chars->offset;
|
||||
} else { //For case where voltage is less than ideal offset leading to negative value
|
||||
voltage = ((chars->ideal_offset - voltage) * chars->gain);
|
||||
voltage += (1 << ADC_CAL_GAIN_SCALE) / 2; //For rounding when scaled
|
||||
voltage >>= ADC_CAL_GAIN_SCALE;
|
||||
voltage = chars->offset - voltage;
|
||||
}
|
||||
|
||||
return voltage;
|
||||
//bit_width parameter unused, kept due to legacy API
|
||||
chars->mode = ESP_ADC_CAL_MODE_LUT;
|
||||
chars->lut_chars.vref = vref;
|
||||
characterize_lut(ADC_UNIT_1, atten, vref, &chars->lut_chars.table);
|
||||
chars->adc_num = ADC_UNIT_1;
|
||||
}
|
||||
|
||||
uint32_t adc1_to_voltage(adc1_channel_t channel, const esp_adc_cal_characteristics_t *chars)
|
||||
{
|
||||
return esp_adc_cal_raw_to_voltage((uint32_t)adc1_get_raw(channel), chars);
|
||||
assert(chars != NULL);
|
||||
uint32_t voltage = 0;
|
||||
adc_to_voltage((adc_channel_t) channel, ADC_WIDTH_BIT_12, chars, &voltage);
|
||||
return voltage;
|
||||
}
|
||||
|
||||
|
||||
|
||||
222
components/esp_adc_cal/esp_adc_cal_constants.c
Normal file
222
components/esp_adc_cal/esp_adc_cal_constants.c
Normal file
@@ -0,0 +1,222 @@
|
||||
// Copyright 2015-2016 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 "esp_adc_cal.h"
|
||||
#include "esp_adc_cal_constants.h"
|
||||
|
||||
/* ------------------------- Lookup Tables ---------------------------------- */
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 2.674297mV
|
||||
* Max error of 70 modules: 12.176238mV
|
||||
* Mean of max errors of 70 modules: 7.079913mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten0_adc1 = {
|
||||
.low_vref_curve = {
|
||||
58, 84, 114, 142, 168, 196, 224, 252,
|
||||
281, 308, 335, 363, 390, 417, 445, 473,
|
||||
501, 528, 556, 583, 611, 637, 665, 692,
|
||||
720, 747, 775, 802, 830, 856, 883, 910,
|
||||
937
|
||||
},
|
||||
.high_vref_curve = {
|
||||
86, 106, 152, 184, 218, 251, 283, 316,
|
||||
348, 381, 415, 447, 480, 513, 546, 579,
|
||||
612, 644, 677, 710, 742, 775, 808, 841,
|
||||
874, 906, 938, 971, 1003, 1035, 1068, 1100,
|
||||
1133
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 3.950325mV
|
||||
* Max error of 70 modules: 20.975788mV
|
||||
* Mean of max errors of 70 modules: 6.629054mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten0_adc2 = {
|
||||
.low_vref_curve = {
|
||||
49, 75, 105, 132, 160, 187, 214, 241,
|
||||
268, 296, 324, 352, 380, 407, 434, 461,
|
||||
488, 516, 545, 572, 600, 627, 654, 681,
|
||||
708, 735, 763, 791, 818, 845, 872, 899,
|
||||
927
|
||||
},
|
||||
.high_vref_curve = {
|
||||
72, 103, 137, 170, 202, 235, 268, 302,
|
||||
335, 367, 399, 432, 464, 497, 530, 563,
|
||||
596, 628, 661, 693, 725, 758, 791, 824,
|
||||
857, 889, 921, 954, 986, 1018, 1051, 1084,
|
||||
1116
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 3.339671mV
|
||||
* Max error of 70 modules: 13.476428mV
|
||||
* Mean of max errors of 70 modules: 5.818235mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten1_adc1 = {
|
||||
.low_vref_curve = {
|
||||
57, 87, 130, 168, 204, 240, 277, 313,
|
||||
349, 387, 424, 461, 498, 534, 571, 607,
|
||||
644, 680, 717, 753, 789, 826, 862, 898,
|
||||
934, 970, 1007, 1043, 1078, 1115, 1151, 1187,
|
||||
1223
|
||||
},
|
||||
.high_vref_curve = {
|
||||
89, 128, 178, 221, 264, 309, 353, 397,
|
||||
442, 484, 528, 572, 616, 659, 703, 747,
|
||||
790, 833, 877, 921, 964, 1006, 1050, 1094,
|
||||
1137, 1179, 1222, 1266, 1309, 1351, 1394, 1437,
|
||||
1481
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 5.319836mV
|
||||
* Max error of 70 modules: 29.034477mV
|
||||
* Mean of max errors of 70 modules: 9.226072mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten1_adc2 = {
|
||||
.low_vref_curve = {
|
||||
47, 86, 122, 159, 196, 232, 268, 305,
|
||||
340, 377, 415, 452, 487, 525, 562, 598,
|
||||
635, 671, 708, 745, 782, 817, 853, 890,
|
||||
926, 962, 999, 1035, 1071, 1107, 1144, 1180,
|
||||
1215
|
||||
},
|
||||
.high_vref_curve = {
|
||||
78, 113, 165, 209, 251, 295, 339, 383,
|
||||
427, 470, 514, 558, 602, 644, 688, 732,
|
||||
775, 818, 862, 905, 948, 992, 1036, 1079,
|
||||
1122, 1164, 1208, 1252, 1295, 1338, 1381, 1424,
|
||||
1468
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 4.943406mV
|
||||
* Max error of 70 modules: 19.203104mV
|
||||
* Mean of max errors of 70 modules: 9.462435mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten2_adc1 = {
|
||||
.low_vref_curve = {
|
||||
72, 117, 177, 228, 281, 330, 382, 434,
|
||||
483, 536, 587, 639, 690, 740, 791, 842,
|
||||
892, 942, 992, 1042, 1092, 1141, 1191, 1241,
|
||||
1290, 1339, 1391, 1441, 1490, 1540, 1591, 1642,
|
||||
1692
|
||||
},
|
||||
.high_vref_curve = {
|
||||
120, 175, 243, 305, 364, 426, 488, 550,
|
||||
612, 671, 732, 793, 852, 912, 973, 1033,
|
||||
1092, 1151, 1211, 1272, 1331, 1390, 1450, 1511,
|
||||
1571, 1631, 1691, 1752, 1812, 1872, 1933, 1994,
|
||||
2056
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 7.782408mV
|
||||
* Max error of 70 modules: 45.327423mV
|
||||
* Mean of max errors of 70 modules: 13.569581mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten2_adc2 = {
|
||||
.low_vref_curve = {
|
||||
61, 119, 164, 216, 267, 317, 369, 420,
|
||||
471, 522, 574, 625, 676, 726, 777, 828,
|
||||
878, 928, 979, 1030, 1080, 1130, 1180, 1230,
|
||||
1280, 1330, 1381, 1432, 1483, 1532, 1583, 1634,
|
||||
1685
|
||||
},
|
||||
.high_vref_curve = {
|
||||
102, 152, 225, 286, 347, 407, 469, 530,
|
||||
590, 651, 712, 773, 832, 892, 953, 1013,
|
||||
1073, 1132, 1192, 1253, 1313, 1372, 1432, 1494,
|
||||
1554, 1613, 1675, 1735, 1795, 1856, 1917, 1978,
|
||||
2039
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 9.568297mV
|
||||
* Max error of 70 modules: 44.480817mV
|
||||
* Mean of max errors of 70 modules: 20.165069mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten3_adc1 = {
|
||||
.low_vref_curve = {
|
||||
88, 185, 285, 380, 473, 568, 664, 759,
|
||||
853, 945, 1039, 1133, 1224, 1316, 1410, 1505,
|
||||
1599, 1692, 1788, 1886, 1983, 2081, 2186, 2297,
|
||||
2405, 2511, 2615, 2710, 2793, 2868, 2937, 3000,
|
||||
3061
|
||||
},
|
||||
.high_vref_curve = {
|
||||
173, 271, 399, 515, 628, 740, 853, 965,
|
||||
1075, 1186, 1299, 1411, 1523, 1634, 1749, 1863,
|
||||
1975, 2087, 2201, 2314, 2422, 2525, 2622, 2707,
|
||||
2779, 2844, 2901, 2956, 3008, 3059, 3110, 3160,
|
||||
3210
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 70 modules: 12.799173mV
|
||||
* Max error of 70 modules: 60.129227mV
|
||||
* Mean of max errors of 70 modules: 23.334659mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t lut_atten3_adc2 = {
|
||||
.low_vref_curve = {
|
||||
83, 177, 274, 370, 465, 559, 655, 751,
|
||||
844, 937, 1031, 1126, 1218, 1312, 1407, 1502,
|
||||
1597, 1691, 1787, 1885, 1983, 2081, 2185, 2293,
|
||||
2400, 2506, 2612, 2709, 2793, 2868, 2937, 2999,
|
||||
3059
|
||||
},
|
||||
.high_vref_curve = {
|
||||
155, 257, 383, 498, 610, 722, 836, 947,
|
||||
1058, 1170, 1283, 1396, 1507, 1619, 1733, 1848,
|
||||
1960, 2073, 2188, 2300, 2408, 2513, 2611, 2698,
|
||||
2773, 2838, 2895, 2946, 2996, 3044, 3092, 3139,
|
||||
3186
|
||||
}
|
||||
};
|
||||
|
||||
/* ---------------- Constants for linear calibration using TP --------------- */
|
||||
|
||||
// (0.999518539509928, 1.32714033039721, 1.83698541693337, 3.42269475397192) * 65536
|
||||
const uint32_t adc1_lin_tp_atten_scale[4] = {65504, 86975, 120389, 224310};
|
||||
|
||||
// (0.99895306551877194, 1.3253993908658808, 1.8373986067502703, 3.4287787961634124) * 65536
|
||||
const uint32_t adc2_lin_tp_atten_scale[4] = {65467, 86861, 120416, 224708};
|
||||
|
||||
// (0.369882210218334, 1.33352056600476, 26.5266258898132, 54.2706443679156)
|
||||
const uint32_t adc1_lin_tp_atten_offset[4] = {0, 1, 27, 54};
|
||||
|
||||
// (0.0, 3.59737421, 26.3951927, 64.738429)
|
||||
const uint32_t adc2_lin_tp_atten_offset[4] = {0, 9, 26, 66};
|
||||
|
||||
/* ------------- Constants for linear calibration using Vref ---------------- */
|
||||
|
||||
// (0.87632707, 1.16327136, 1.60951523, 2.99991113) * 65536
|
||||
const uint32_t adc1_lin_vref_atten_scale[4] = {57431, 76236, 105481, 196602};
|
||||
|
||||
// (0.87335934, 1.16233322, 1.61251264, 3.00858015) * 65536
|
||||
const uint32_t adc2_lin_vref_atten_scale[4] = {57236, 76175, 105678, 197170};
|
||||
|
||||
// (74.97079, 77.67434785, 106.58843993, 142.18959459)
|
||||
const uint32_t adc1_lin_vref_atten_offset[4] = {75, 78, 107, 142};
|
||||
|
||||
// (62.73368574, 66.33498527, 89.23584218, 127.69820652)
|
||||
const uint32_t adc2_lin_vref_atten_offset[4] = {63, 66, 89, 128};
|
||||
@@ -1,96 +0,0 @@
|
||||
// Copyright 2015-2016 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 "esp_adc_cal.h"
|
||||
|
||||
/**
|
||||
* Mean error of 219 modules: 3.756418mV
|
||||
* Max error of 219 modules: 26.314087mV
|
||||
* Mean of max errors of 219 modules: 7.387282mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_0 = {
|
||||
.gain_m = 56,
|
||||
.gain_c = 59928,
|
||||
.offset_m = 91,
|
||||
.offset_c = 52798,
|
||||
.bit_shift = 7,
|
||||
.voltage = {
|
||||
54, 90, 120, 150, 180, 209, 241, 271,
|
||||
301, 330, 360, 391, 421, 450, 480, 511,
|
||||
541, 571, 601, 630, 660, 690, 720, 750,
|
||||
780, 809, 839, 870, 900, 929, 959, 988,
|
||||
1018
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 219 modules: 4.952441mV
|
||||
* Max error of 219 modules: 38.235321mV
|
||||
* Mean of max errors of 219 modules: 9.718749mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_1 = {
|
||||
.gain_m = 57,
|
||||
.gain_c = 59834,
|
||||
.offset_m = 108,
|
||||
.offset_c = 54733,
|
||||
.bit_shift = 7,
|
||||
.voltage = {
|
||||
60, 102, 143, 184, 223, 262, 303, 343,
|
||||
383, 423, 463, 503, 543, 583, 623, 663,
|
||||
703, 742, 782, 823, 862, 901, 942, 981,
|
||||
1022, 1060, 1101, 1141, 1180, 1219, 1259, 1298,
|
||||
1338
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 219 modules: 6.793558mV
|
||||
* Max error of 219 modules: 51.435440mV
|
||||
* Mean of max errors of 219 modules: 13.083121mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_2 = {
|
||||
.gain_m = 56,
|
||||
.gain_c = 59927,
|
||||
.offset_m = 154,
|
||||
.offset_c = 71995,
|
||||
.bit_shift = 7,
|
||||
.voltage = {
|
||||
82, 138, 194, 250, 305, 360, 417, 473,
|
||||
529, 584, 639, 696, 751, 806, 861, 917,
|
||||
971, 1026, 1081, 1136, 1192, 1246, 1301, 1356,
|
||||
1411, 1466, 1522, 1577, 1632, 1687, 1743, 1799,
|
||||
1855
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mean error of 219 modules: 13.149460mV
|
||||
* Max error of 219 modules: 97.102951mV
|
||||
* Mean of max errors of 219 modules: 35.538924mV
|
||||
*/
|
||||
const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_3 = {
|
||||
.gain_m = 33,
|
||||
.gain_c = 62214,
|
||||
.offset_m = 610,
|
||||
.offset_c = 108422,
|
||||
.bit_shift = 7,
|
||||
.voltage = {
|
||||
110, 221, 325, 430, 534, 637, 741, 845,
|
||||
947, 1049, 1153, 1256, 1358, 1461, 1565, 1670,
|
||||
1774, 1878, 1983, 2088, 2192, 2293, 2393, 2490,
|
||||
2580, 2665, 2746, 2820, 2885, 2947, 3007, 3060,
|
||||
3107
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,131 +20,171 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/adc.h"
|
||||
#include "esp_adc_cal_constants.h"
|
||||
|
||||
/** @cond */
|
||||
#define ADC_CAL_GAIN_SCALE 16
|
||||
#define ADC_CAL_OFFSET_SCALE 10
|
||||
/**
|
||||
* @brief ADC characterization mode
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_ADC_CAL_MODE_LIN = 0, /**< Characterize the ADC as a linear curve*/
|
||||
ESP_ADC_CAL_MODE_LUT= 1, /**< Characterize the ADC using a lookup table*/
|
||||
} esp_adc_cal_mode_t;
|
||||
|
||||
#define ADC_CAL_IDEAL_V_REF 1100 //In mV
|
||||
#define ADC_CAL_LOW_V_REF 1000
|
||||
#define ADC_CAL_HIGH_V_REF 1200
|
||||
#define ADC_CAL_MIN 0
|
||||
#define ADC_CAL_MAX 4095
|
||||
/** @endcond */
|
||||
/**
|
||||
* @brief Type of calibration value used in characterization
|
||||
*/
|
||||
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_value_t;
|
||||
|
||||
/**
|
||||
* @brief Structure storing Lookup Table
|
||||
*
|
||||
* The Lookup Tables (LUT) of a given attenuation contains 33 equally spaced
|
||||
* points. The Gain and Offset curves are used to find the appopriate gain and
|
||||
* offset factor given a reference voltage v_ref.
|
||||
* A Lookup Table (LUT) of a given ADC and attenuation contains two curves
|
||||
* mapping ADC readings to a voltage in mV. Each curve contains 33 equally spaced
|
||||
* points separated by a step size of 128. The low_vref_curve represents the ADC
|
||||
* voltage curve of a module with a reference voltage of 1000mV, whilst the
|
||||
* high_vref_curve represents a reference voltage of 1200mV.
|
||||
*
|
||||
* @note A seperate LUT is provided for each attenuation and are defined in
|
||||
* esp_adc_cal_lookup_tables.c
|
||||
* @note Separate LUTs are provided for each ADC at each attenuation
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t gain_m; /**<Gradient of Gain Curve */
|
||||
uint32_t gain_c; /**<Offset of Gain Curve */
|
||||
uint32_t offset_m; /**<Gradient of Offset Curve */
|
||||
uint32_t offset_c; /**<Offset of Offset Curve */
|
||||
uint32_t bit_shift; /**<Bit shift used find corresponding LUT points
|
||||
given an ADC reading*/
|
||||
uint32_t voltage[]; /**<Array of voltages in mV representing the
|
||||
ADC-Voltage curve */
|
||||
uint32_t low_vref_curve[33]; /**< Voltage curve at a reference voltage of 1000mV*/
|
||||
uint32_t high_vref_curve[33]; /**< Voltage curve at a reference voltage of 1200mV*/
|
||||
} esp_adc_cal_lookup_table_t;
|
||||
|
||||
/**
|
||||
* @brief Structure storing ADC characteristics of given v_ref
|
||||
*
|
||||
* The ADC Characteristics structure stores the gain and offset factors of an
|
||||
* ESP32 module's ADC. These factors are calculated using the reference voltage,
|
||||
* and the Gain and Offset curves provided in the lookup tables.
|
||||
* @brief Structure storing characteristics of an ADC
|
||||
*
|
||||
* @note Call esp_adc_cal_get_characteristics() to initialize the structure
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t v_ref; /**<Reference Voltage of current ESP32 Module in mV*/
|
||||
uint32_t gain; /**<Scaling factor used to correct LUT voltages to
|
||||
current v_ref. Bit shifted by << ADC_CAL_GAIN_SCALE
|
||||
for uint32 arithmetic */
|
||||
uint32_t offset; /**<Offset in mV used to correct LUT Voltages to current v_ref */
|
||||
uint32_t ideal_offset; /**<Offset in mV at the ideal reference voltage */
|
||||
adc_bits_width_t bit_width; /**<Bit width of ADC e.g. ADC_WIDTH_BIT_12 */
|
||||
const esp_adc_cal_lookup_table_t *table; /**<Pointer to LUT */
|
||||
esp_adc_cal_mode_t mode; /**< Characterization mode*/
|
||||
adc_unit_t adc_num; /**< ADC number*/
|
||||
union {
|
||||
struct {
|
||||
uint32_t coeff_a; /**< 1st order coefficient of linear characteristics curve*/
|
||||
uint32_t coeff_b; /**< 0th order coefficient of linear characteristics curve*/
|
||||
} linear_chars;
|
||||
struct {
|
||||
uint32_t vref; /**< Reference voltage*/
|
||||
const esp_adc_cal_lookup_table_t *table; /**< Pointer to lookup table*/
|
||||
} lut_chars;
|
||||
};
|
||||
} esp_adc_cal_characteristics_t;
|
||||
|
||||
extern const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_0; /**<LUT for atten0 */
|
||||
extern const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_1; /**<LUT for atten1 */
|
||||
extern const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_2; /**<LUT for atten2 */
|
||||
extern const esp_adc_cal_lookup_table_t esp_adc_cal_table_atten_3; /**<LUT for atten3 */
|
||||
|
||||
/**
|
||||
* @brief Calculate characteristics of ADC
|
||||
* @brief Checks if ADC calibration values are stored in eFuse
|
||||
*
|
||||
* This function will calculate the gain and offset factors based on the
|
||||
* reference voltage parameter and the Gain and Offset curve provided in the LUT.
|
||||
* This function checks if ADC reference voltage or Two Point calibration voltages
|
||||
* have been burned to the eFuse of the current ESP32
|
||||
*
|
||||
* @note reference voltage of the ADCs can be routed to GPIO using
|
||||
* adc2_vref_to_gpio() from the ADC driver
|
||||
* @param value_type Type of calibration value (ESP_ADC_CAL_VAL_EFUSE_VREF or ESP_ADC_CAL_VAL_EFUSE_TP)
|
||||
*
|
||||
* @note The LUT members have been bit shifted by ADC_CAL_GAIN_SCALE or
|
||||
* ADC_CAL_OFFSET_SCALE to make them uint32_t compatible. This bit shifting will
|
||||
* accounted for in this function
|
||||
*
|
||||
* @param[in] v_ref true reference voltage of the ADC in mV (1000 to 1200mV). Nominal
|
||||
* value for reference voltage is 1100mV.
|
||||
* @param[in] atten attenuation setting used to select the corresponding lookup table
|
||||
* @param[in] bit_width bit width of ADC
|
||||
* @param[out] chars pointer to structure used to store ADC characteristics of module
|
||||
* @return
|
||||
* - ESP_OK: The calibration mode is supported in eFuse
|
||||
* - ESP_ERR_NOT_SUPPORTED: Error, eFuse values are not burned
|
||||
* - ESP_ERR_INVALID_ARG: Error, invalid argument (ESP_ADC_CAL_VAL_DEFAULT_VREF)
|
||||
*/
|
||||
void esp_adc_cal_get_characteristics(uint32_t v_ref,
|
||||
adc_atten_t atten,
|
||||
adc_bits_width_t bit_width,
|
||||
esp_adc_cal_characteristics_t *chars);
|
||||
esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t value_type);
|
||||
|
||||
/**
|
||||
* @brief Convert raw ADC reading to voltage in mV
|
||||
* @brief Characterize an ADC at a particular attenuation under Linear or LUT Mode
|
||||
*
|
||||
* This function converts a raw ADC reading to a voltage in mV. This conversion
|
||||
* is based on the ADC's characteristics. The raw ADC reading is referenced
|
||||
* against the LUT (pointed to inside characteristics struct) to obtain a voltage.
|
||||
* Gain and offset factors are then applied to the voltage in order to obtain
|
||||
* the final result.
|
||||
* This function will generate the characteristics curve of one of the ADCs at a
|
||||
* particular attenuation. This characteristics curve will be stored in a
|
||||
* characteristics structure. Linear Mode will be characterize the ADC-Voltage
|
||||
* curve as a linear curve. LUT Mode will characterize the ADC-Voltage curve
|
||||
* using a lookup table. Calibration values in eFuse will be used to generate
|
||||
* the characteristics curve if available, and vref_default will be used if they
|
||||
* are not.
|
||||
*
|
||||
* @param[in] adc ADC reading (different bit widths will be handled)
|
||||
* @param[in] chars pointer to structure containing ADC characteristics of
|
||||
* the module. Structure also contains pointer to the
|
||||
* corresponding LUT
|
||||
* @note This function will abort if there are no available options for
|
||||
* characterization (characterization modes and calibration value types
|
||||
* can be enabled and disabled in menuconfig)
|
||||
*
|
||||
* @return Calculated voltage in mV
|
||||
* @param[in] adc_num ADC to characterize (ADC_UNIT_1 or ADC_UNIT_2)
|
||||
* @param[in] atten Attenuation to characterize
|
||||
* @param[in] mode Characterization mode (Linear or LUT)
|
||||
* @param[in] vref_default Default ADC reference voltage in mV (used if eFuse is not available)
|
||||
* @param[out] chars Pointer to empty structure used to store ADC characteristics
|
||||
*
|
||||
* @note characteristics structure must be initialized using
|
||||
* esp_adc_cal_get_characteristics() before this function is used
|
||||
* @return
|
||||
* - ESP_ADC_CAL_VAL_EFUSE_VREF: eFuse Vref used for characterization
|
||||
* - ESP_ADC_CAL_VAL_EFUSE_TP: Two Point value used for characterization (only in Linear Mode)
|
||||
* - ESP_ADC_CAL_VAL_DEFAULT_VREF: Default Vref used for characterization
|
||||
*/
|
||||
uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc,
|
||||
const esp_adc_cal_characteristics_t *chars);
|
||||
esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num,
|
||||
adc_atten_t atten,
|
||||
esp_adc_cal_mode_t mode,
|
||||
uint32_t vref_default,
|
||||
esp_adc_cal_characteristics_t *chars);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reads ADC1 and returns voltage in mV
|
||||
* @brief Convert an ADC reading to voltage in mV
|
||||
*
|
||||
* This function reads the ADC1 using adc1_get_raw() to obtain a raw ADC
|
||||
* reading. The reading is then converted into a voltage value using
|
||||
* esp_adc_cal_raw_to_voltage().
|
||||
* This function converts a an ADC reading to a voltage in mV based on the
|
||||
* ADC characteristics curve provided.
|
||||
*
|
||||
* @param[in] channel Channel of ADC1 to measure
|
||||
* @param[in] chars Pointer to ADC characteristics struct
|
||||
* @param[in] adc_reading ADC reading
|
||||
* @param[in] bit_width Bit width of the ADC reading
|
||||
* @param[in] chars Pointer to initialized structure containing ADC characteristics curve
|
||||
*
|
||||
* @return voltage Calculated voltage in mV
|
||||
* @return Voltage in mV
|
||||
*
|
||||
* @note ADC must be initialized using adc1_config_width() and
|
||||
* adc1_config_channel_atten() before this function is used
|
||||
*
|
||||
* @note characteristics structure must be initialized using
|
||||
* esp_adc_cal_get_characteristics() before this function is used
|
||||
* @note characteristics structure must be initialized first using esp_adc_cal_characterize()
|
||||
*/
|
||||
uint32_t adc1_to_voltage(adc1_channel_t channel, const esp_adc_cal_characteristics_t *chars);
|
||||
uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, adc_bits_width_t bit_width, const esp_adc_cal_characteristics_t *chars);
|
||||
|
||||
/**
|
||||
* @brief Reads an ADC and returns a voltage in mV
|
||||
*
|
||||
* This function reads an ADC then converts the raw reading to a voltage in mV
|
||||
* using the characteristics curve provided. The ADC that is read is also
|
||||
* determined by the characteristics.
|
||||
*
|
||||
* @param[in] channel ADC Channel to read
|
||||
* @param[in] bit_width Bit width of ADC reading (must be same as ADC configuration)
|
||||
* @param[in] chars Pointer to initialized ADC characteristics structure
|
||||
* @param[out] voltage Pointer to store converted voltage
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: ADC read and converted
|
||||
* - ESP_ERR_TIMEOUT: Error, could not read ADC
|
||||
* - ESP_ERR_INVALID_ARG: Error due to invalid arguments
|
||||
*
|
||||
* @note The ADC must be initialized before calling this function. The
|
||||
* bit_width parameter must be the same as the bit width used in
|
||||
* configuration
|
||||
*
|
||||
* @note Characteristics structure must be initialized using before calling
|
||||
* this function
|
||||
*/
|
||||
esp_err_t adc_to_voltage(adc_channel_t channel, adc_bits_width_t bit_width, const esp_adc_cal_characteristics_t *chars, uint32_t *voltage);
|
||||
|
||||
/* -------------------------- Deprecated API ------------------------------- */
|
||||
|
||||
/** @cond */ //Doxygen command to hide deprecated function from API Reference
|
||||
/**
|
||||
* @deprecated ADC1 characterization function. Deprecated in order to accommodate
|
||||
* new characterization functions. Use esp_adc_cal_characterize() instead
|
||||
*/
|
||||
void esp_adc_cal_get_characteristics(uint32_t vref, adc_atten_t atten, adc_bits_width_t bit_width, esp_adc_cal_characteristics_t *chars) __attribute__((deprecated));
|
||||
|
||||
/*
|
||||
* @deprecated This function reads ADC1 and returns the corrected voltage. This
|
||||
* has been deprecated in order to accommodate ADC2 support and new
|
||||
* ADC calibration methods. Use the new function adc_to_voltage() instead
|
||||
*/
|
||||
uint32_t adc1_to_voltage(adc1_channel_t channel, const esp_adc_cal_characteristics_t *chars) __attribute__((deprecated));
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -79,17 +79,23 @@
|
||||
#define EFUSE_RD_WIFI_MAC_CRC_HIGH_S 0
|
||||
|
||||
#define EFUSE_BLK0_RDATA3_REG (DR_REG_EFUSE_BASE + 0x00c)
|
||||
/* EFUSE_RD_CHIP_VER_REV1 : R/W ;bitpos:[16] ;default: 1'b0 ; */
|
||||
/* EFUSE_RD_CHIP_VER_REV1 : R/W ;bitpos:[15] ;default: 1'b0 ; */
|
||||
/*description: bit is set to 1 for rev1 silicon*/
|
||||
#define EFUSE_RD_CHIP_VER_REV1 (BIT(15))
|
||||
#define EFUSE_RD_CHIP_VER_REV1_M ((EFUSE_RD_CHIP_VER_REV1_V)<<(EFUSE_RD_CHIP_VER_REV1_S))
|
||||
#define EFUSE_RD_CHIP_VER_REV1_V 0x1
|
||||
#define EFUSE_RD_CHIP_VER_REV1_S 15
|
||||
/* EFUSE_RD_CHIP_VER_RESERVE : R/W ;bitpos:[15:12] ;default: 3'b0 ; */
|
||||
/* EFUSE_RD_BLK3_PART_RESERVE : R/W ; bitpos:[14] ; default: 1'b0; */
|
||||
/*description: If set, this bit indicates that BLOCK3[143:96] is reserved for calibration purposes and BLOCK1/2/3 uses 3/4 encoding*/
|
||||
#define EFUSE_RD_BLK3_PART_RESERVE (BIT(14))
|
||||
#define EFUSE_RD_BLK3_PART_RESERVE_M ((EFUSE_RD_BLK3_PART_RESERVE_V)<<(EFUSE_RD_BLK3_PART_RESERVE_S))
|
||||
#define EFUSE_RD_BLK3_PART_RESERVE_V 0x1
|
||||
#define EFUSE_RD_BLK3_PART_RESERVE_S 14
|
||||
/* EFUSE_RD_CHIP_VER_RESERVE : R/W ;bitpos:[13:12] ;default: 2'b0 ; */
|
||||
/*description: */
|
||||
#define EFUSE_RD_CHIP_VER_RESERVE 0x00000007
|
||||
#define EFUSE_RD_CHIP_VER_RESERVE 0x00000003
|
||||
#define EFUSE_RD_CHIP_VER_RESERVE_M ((EFUSE_RD_CHIP_VER_RESERVE_V)<<(EFUSE_RD_CHIP_VER_RESERVE_S))
|
||||
#define EFUSE_RD_CHIP_VER_RESERVE_V 0x7
|
||||
#define EFUSE_RD_CHIP_VER_RESERVE_V 0x3
|
||||
#define EFUSE_RD_CHIP_VER_RESERVE_S 12
|
||||
/* EFUSE_RD_CHIP_VER : R/W ;bitpos:[11:9] ;default: 3'b0 ; */
|
||||
/*description: chip package */
|
||||
@@ -152,6 +158,15 @@
|
||||
#define EFUSE_RD_XPD_SDIO_REG_M (BIT(14))
|
||||
#define EFUSE_RD_XPD_SDIO_REG_V 0x1
|
||||
#define EFUSE_RD_XPD_SDIO_REG_S 14
|
||||
/* EFUSE_RD_ADC_VREF : R/W ;bitpos:[12:8] ;default: 5'b0 ; */
|
||||
/*description: True ADC reference voltage */
|
||||
#define EFUSE_RD_ADC_VREF 0x0000001F
|
||||
#define EFUSE_RD_ADC_VREF_M ((EFUSE_RD_ADC_VREF_V)<<(EFUSE_RD_ADC_VREF_S))
|
||||
#define EFUSE_RD_ADC_VREF_V 0x1F
|
||||
#define EFUSE_RD_ADC_VREF_S 8
|
||||
/* Note: EFUSE_ADC_VREF and SDIO_DREFH/M/L share the same address space. Newer
|
||||
* versions of ESP32 come with EFUSE_ADC_VREF already burned, therefore
|
||||
* SDIO_DREFH/M/L is only available in older versions of ESP32 */
|
||||
/* EFUSE_RD_SDIO_DREFL : RO ;bitpos:[13:12] ;default: 2'b0 ; */
|
||||
/*description: */
|
||||
#define EFUSE_RD_SDIO_DREFL 0x00000003
|
||||
@@ -314,17 +329,23 @@
|
||||
#define EFUSE_WIFI_MAC_CRC_HIGH_S 0
|
||||
|
||||
#define EFUSE_BLK0_WDATA3_REG (DR_REG_EFUSE_BASE + 0x028)
|
||||
/* EFUSE_CHIP_VER_REV1 : R/W ;bitpos:[16] ;default: 1'b0 ; */
|
||||
/* EFUSE_CHIP_VER_REV1 : R/W ;bitpos:[15] ;default: 1'b0 ; */
|
||||
/*description: */
|
||||
#define EFUSE_CHIP_VER_REV1 (BIT(15))
|
||||
#define EFUSE_CHIP_VER_REV1_M ((EFUSE_CHIP_VER_REV1_V)<<(EFUSE_CHIP_VER_REV1_S))
|
||||
#define EFUSE_CHIP_VER_REV1_V 0x1
|
||||
#define EFUSE_CHIP_VER_REV1_S 15
|
||||
/* EFUSE_CHIP_VER_RESERVE : R/W ;bitpos:[15:12] ;default: 3'b0 ; */
|
||||
/* EFUSE_BLK3_PART_RESERVE : R/W ; bitpos:[14] ; default: 1'b0; */
|
||||
/*description: If set, this bit indicates that BLOCK3[143:96] is reserved for calibration purposes and BLOCK1/2/3 uses 3/4 encoding*/
|
||||
#define EFUSE_BLK3_PART_RESERVE (BIT(14))
|
||||
#define EFUSE_BLK3_PART_RESERVE_M ((EFUSE_BLK3_PART_RESERVE_V)<<(EFUSE_BLK3_PART_RESERVE_S))
|
||||
#define EFUSE_BLK3_PART_RESERVE_V 0x1
|
||||
#define EFUSE_BLK3_PART_RESERVE_S 14
|
||||
/* EFUSE_CHIP_VER_RESERVE : R/W ;bitpos:[13:12] ;default: 2'b0 ; */
|
||||
/*description: */
|
||||
#define EFUSE_CHIP_VER_RESERVE 0x00000007
|
||||
#define EFUSE_CHIP_VER_RESERVE 0x00000003
|
||||
#define EFUSE_CHIP_VER_RESERVE_M ((EFUSE_CHIP_VER_RESERVE_V)<<(EFUSE_CHIP_VER_RESERVE_S))
|
||||
#define EFUSE_CHIP_VER_RESERVE_V 0x7
|
||||
#define EFUSE_CHIP_VER_RESERVE_V 0x3
|
||||
#define EFUSE_CHIP_VER_RESERVE_S 12
|
||||
/* EFUSE_CHIP_VER : R/W ;bitpos:[11:9] ;default: 3'b0 ; */
|
||||
/*description: */
|
||||
@@ -382,6 +403,15 @@
|
||||
#define EFUSE_XPD_SDIO_REG_M (BIT(14))
|
||||
#define EFUSE_XPD_SDIO_REG_V 0x1
|
||||
#define EFUSE_XPD_SDIO_REG_S 14
|
||||
/* EFUSE_ADC_VREF : R/W ;bitpos:[12:8] ;default: 5'b0 ; */
|
||||
/*description: True ADC reference voltage */
|
||||
#define EFUSE_ADC_VREF 0x0000001F
|
||||
#define EFUSE_ADC_VREF_M ((EFUSE_ADC_VREF_V)<<(EFUSE_ADC_VREF_S))
|
||||
#define EFUSE_ADC_VREF_V 0x1F
|
||||
#define EFUSE_ADC_VREF_S 8
|
||||
/* Note: EFUSE_ADC_VREF and SDIO_DREFH/M/L share the same address space. Newer
|
||||
* versions of ESP32 come with EFUSE_ADC_VREF already burned, therefore
|
||||
* SDIO_DREFH/M/L is only available in older versions of ESP32 */
|
||||
/* EFUSE_SDIO_DREFL : R/W ;bitpos:[13:12] ;default: 2'b0 ; */
|
||||
/*description: */
|
||||
#define EFUSE_SDIO_DREFL 0x00000003
|
||||
@@ -659,6 +689,8 @@
|
||||
#define EFUSE_BLK3_DOUT2_V 0xFFFFFFFF
|
||||
#define EFUSE_BLK3_DOUT2_S 0
|
||||
|
||||
/* Note: Newer ESP32s utilize BLK3_DATA3 and parts of BLK3_DATA4 for calibration
|
||||
* purposes. This usage is indicated by the EFUSE_RD_BLK3_PART_RESERVE bit.*/
|
||||
#define EFUSE_BLK3_RDATA3_REG (DR_REG_EFUSE_BASE + 0x084)
|
||||
/* EFUSE_BLK3_DOUT3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
/*description: read for BLOCK3*/
|
||||
@@ -666,6 +698,30 @@
|
||||
#define EFUSE_BLK3_DOUT3_M ((EFUSE_BLK3_DOUT3_V)<<(EFUSE_BLK3_DOUT3_S))
|
||||
#define EFUSE_BLK3_DOUT3_V 0xFFFFFFFF
|
||||
#define EFUSE_BLK3_DOUT3_S 0
|
||||
/* EFUSE_RD_ADC2_TP_HIGH : R/W ;bitpos:[31:23] ;default: 9'b0 ; */
|
||||
/*description: ADC2 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_RD_ADC2_TP_HIGH 0x1FF
|
||||
#define EFUSE_RD_ADC2_TP_HIGH_M ((EFUSE_RD_ADC2_TP_HIGH_V)<<(EFUSE_RD_ADC2_TP_HIGH_S))
|
||||
#define EFUSE_RD_ADC2_TP_HIGH_V 0x1FF
|
||||
#define EFUSE_RD_ADC2_TP_HIGH_S 23
|
||||
/* EFUSE_RD_ADC2_TP_LOW : R/W ;bitpos:[22:16] ;default: 7'b0 ; */
|
||||
/*description: ADC2 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_RD_ADC2_TP_LOW 0x7F
|
||||
#define EFUSE_RD_ADC2_TP_LOW_M ((EFUSE_RD_ADC2_TP_LOW_V)<<(EFUSE_RD_ADC2_TP_LOW_S))
|
||||
#define EFUSE_RD_ADC2_TP_LOW_V 0x7F
|
||||
#define EFUSE_RD_ADC2_TP_LOW_S 16
|
||||
/* EFUSE_RD_ADC1_TP_HIGH : R/W ;bitpos:[15:7] ;default: 9'b0 ; */
|
||||
/*description: ADC1 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_RD_ADC1_TP_HIGH 0x1FF
|
||||
#define EFUSE_RD_ADC1_TP_HIGH_M ((EFUSE_RD_ADC1_TP_HIGH_V)<<(EFUSE_RD_ADC1_TP_HIGH_S))
|
||||
#define EFUSE_RD_ADC1_TP_HIGH_V 0x1FF
|
||||
#define EFUSE_RD_ADC1_TP_HIGH_S 7
|
||||
/* EFUSE_RD_ADC1_TP_LOW : R/W ;bitpos:[6:0] ;default: 7'b0 ; */
|
||||
/*description: ADC1 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_RD_ADC1_TP_LOW 0x7F
|
||||
#define EFUSE_RD_ADC1_TP_LOW_M ((EFUSE_RD_ADC1_TP_LOW_V)<<(EFUSE_RD_ADC1_TP_LOW_S))
|
||||
#define EFUSE_RD_ADC1_TP_LOW_V 0x7F
|
||||
#define EFUSE_RD_ADC1_TP_LOW_S 0
|
||||
|
||||
#define EFUSE_BLK3_RDATA4_REG (DR_REG_EFUSE_BASE + 0x088)
|
||||
/* EFUSE_BLK3_DOUT4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
@@ -674,6 +730,12 @@
|
||||
#define EFUSE_BLK3_DOUT4_M ((EFUSE_BLK3_DOUT4_V)<<(EFUSE_BLK3_DOUT4_S))
|
||||
#define EFUSE_BLK3_DOUT4_V 0xFFFFFFFF
|
||||
#define EFUSE_BLK3_DOUT4_S 0
|
||||
/* EFUSE_RD_CAL_RESERVED: R/W ; bitpos:[0:15] ; default : 16'h0 ; */
|
||||
/*description: Reserved for future calibration use. Indicated by EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_RD_CAL_RESERVED 0x0000FFFF
|
||||
#define EFUSE_RD_CAL_RESERVED_M ((EFUSE_RD_CAL_RESERVED_V)<<(EFUSE_RD_CAL_RESERVED_S))
|
||||
#define EFUSE_RD_CAL_RESERVED_V 0xFFFF
|
||||
#define EFUSE_RD_CAL_RESERVED_S 0
|
||||
|
||||
#define EFUSE_BLK3_RDATA5_REG (DR_REG_EFUSE_BASE + 0x08c)
|
||||
/* EFUSE_BLK3_DOUT5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
@@ -851,6 +913,8 @@
|
||||
#define EFUSE_BLK3_DIN2_V 0xFFFFFFFF
|
||||
#define EFUSE_BLK3_DIN2_S 0
|
||||
|
||||
/* Note: Newer ESP32s utilize BLK3_DATA3 and parts of BLK3_DATA4 for calibration
|
||||
* purposes. This usage is indicated by the EFUSE_RD_BLK3_PART_RESERVE bit.*/
|
||||
#define EFUSE_BLK3_WDATA3_REG (DR_REG_EFUSE_BASE + 0x0e4)
|
||||
/* EFUSE_BLK3_DIN3 : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
/*description: program for BLOCK3*/
|
||||
@@ -858,6 +922,30 @@
|
||||
#define EFUSE_BLK3_DIN3_M ((EFUSE_BLK3_DIN3_V)<<(EFUSE_BLK3_DIN3_S))
|
||||
#define EFUSE_BLK3_DIN3_V 0xFFFFFFFF
|
||||
#define EFUSE_BLK3_DIN3_S 0
|
||||
/* EFUSE_ADC2_TP_HIGH : R/W ;bitpos:[31:23] ;default: 9'b0 ; */
|
||||
/*description: ADC2 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_ADC2_TP_HIGH 0x1FF
|
||||
#define EFUSE_ADC2_TP_HIGH_M ((EFUSE_ADC2_TP_HIGH_V)<<(EFUSE_ADC2_TP_HIGH_S))
|
||||
#define EFUSE_ADC2_TP_HIGH_V 0x1FF
|
||||
#define EFUSE_ADC2_TP_HIGH_S 23
|
||||
/* EFUSE_ADC2_TP_LOW : R/W ;bitpos:[22:16] ;default: 7'b0 ; */
|
||||
/*description: ADC2 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_ADC2_TP_LOW 0x7F
|
||||
#define EFUSE_ADC2_TP_LOW_M ((EFUSE_ADC2_TP_LOW_V)<<(EFUSE_ADC2_TP_LOW_S))
|
||||
#define EFUSE_ADC2_TP_LOW_V 0x7F
|
||||
#define EFUSE_ADC2_TP_LOW_S 16
|
||||
/* EFUSE_ADC1_TP_HIGH : R/W ;bitpos:[15:7] ;default: 9'b0 ; */
|
||||
/*description: ADC1 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_ADC1_TP_HIGH 0x1FF
|
||||
#define EFUSE_ADC1_TP_HIGH_M ((EFUSE_ADC1_TP_HIGH_V)<<(EFUSE_ADC1_TP_HIGH_S))
|
||||
#define EFUSE_ADC1_TP_HIGH_V 0x1FF
|
||||
#define EFUSE_ADC1_TP_HIGH_S 7
|
||||
/* EFUSE_ADC1_TP_LOW : R/W ;bitpos:[6:0] ;default: 7'b0 ; */
|
||||
/*description: ADC1 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE */
|
||||
#define EFUSE_ADC1_TP_LOW 0x7F
|
||||
#define EFUSE_ADC1_TP_LOW_M ((EFUSE_ADC1_TP_LOW_V)<<(EFUSE_ADC1_TP_LOW_S))
|
||||
#define EFUSE_ADC1_TP_LOW_V 0x7F
|
||||
#define EFUSE_ADC1_TP_LOW_S 0
|
||||
|
||||
#define EFUSE_BLK3_WDATA4_REG (DR_REG_EFUSE_BASE + 0x0e8)
|
||||
/* EFUSE_BLK3_DIN4 : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
@@ -866,6 +954,12 @@
|
||||
#define EFUSE_BLK3_DIN4_M ((EFUSE_BLK3_DIN4_V)<<(EFUSE_BLK3_DIN4_S))
|
||||
#define EFUSE_BLK3_DIN4_V 0xFFFFFFFF
|
||||
#define EFUSE_BLK3_DIN4_S 0
|
||||
/* EFUSE_CAL_RESERVED: R/W ; bitpos:[0:15] ; default : 16'h0 ; */
|
||||
/*description: Reserved for future calibration use. Indicated by EFUSE_BLK3_PART_RESERVE */
|
||||
#define EFUSE_CAL_RESERVED 0x0000FFFF
|
||||
#define EFUSE_CAL_RESERVED_M ((EFUSE_CAL_RESERVED_V)<<(EFUSE_CAL_RESERVED_S))
|
||||
#define EFUSE_CAL_RESERVED_V 0xFFFF
|
||||
#define EFUSE_CAL_RESERVED_S 0
|
||||
|
||||
#define EFUSE_BLK3_WDATA5_REG (DR_REG_EFUSE_BASE + 0x0ec)
|
||||
/* EFUSE_BLK3_DIN5 : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
|
||||
@@ -117,10 +117,15 @@ rtc_vddsdio_config_t rtc_vddsdio_get_config()
|
||||
result.force = 0;
|
||||
result.enable = (efuse_reg & EFUSE_RD_XPD_SDIO_REG_M) >> EFUSE_RD_XPD_SDIO_REG_S;
|
||||
result.tieh = (efuse_reg & EFUSE_RD_SDIO_TIEH_M) >> EFUSE_RD_SDIO_TIEH_S;
|
||||
// in this case, DREFH/M/L are also set from EFUSE
|
||||
result.drefh = (efuse_reg & EFUSE_RD_SDIO_DREFH_M) >> EFUSE_RD_SDIO_DREFH_S;
|
||||
result.drefm = (efuse_reg & EFUSE_RD_SDIO_DREFM_M) >> EFUSE_RD_SDIO_DREFM_S;
|
||||
result.drefl = (efuse_reg & EFUSE_RD_SDIO_DREFL_M) >> EFUSE_RD_SDIO_DREFL_S;
|
||||
//DREFH/M/L eFuse are used for EFUSE_ADC_VREF instead. Therefore tuning
|
||||
//will only be available on older chips that don't have EFUSE_ADC_VREF
|
||||
if(REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG ,EFUSE_RD_BLK3_PART_RESERVE) == 0){
|
||||
//BLK3_PART_RESERVE indicates the presence of EFUSE_ADC_VREF
|
||||
// in this case, DREFH/M/L are also set from EFUSE
|
||||
result.drefh = (efuse_reg & EFUSE_RD_SDIO_DREFH_M) >> EFUSE_RD_SDIO_DREFH_S;
|
||||
result.drefm = (efuse_reg & EFUSE_RD_SDIO_DREFM_M) >> EFUSE_RD_SDIO_DREFM_S;
|
||||
result.drefl = (efuse_reg & EFUSE_RD_SDIO_DREFL_M) >> EFUSE_RD_SDIO_DREFL_S;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user