How to run ADC two point calibration?

vonnieda
Posts: 90
Joined: Tue Nov 07, 2017 3:42 pm

How to run ADC two point calibration?

Postby vonnieda » Wed Jan 09, 2019 2:30 am

Hi all,

The docs at https://docs.espressif.com/projects/esp ... ion-values say "Two Point values represent each of the ADCs’ readings at 150mV and 850mV. To obtain more accurate calibration results these values should be measured by user and burned into eFuse BLOCK3" but there doesn't seem to be further information on how this is done. Is this documented somewhere, and if not, can someone explain the process?

In particular:
* How do I go about reading the value? Is it simply adc1_get_raw()? Should I do any averaging?
* How should I configure the ADC? Attenuation / bit width?
* How do I burn the values once I know them?

Thanks,
Jason

ESP_Dazz
Posts: 60
Joined: Fri Jun 02, 2017 6:50 am

Re: How to run ADC two point calibration?

Postby ESP_Dazz » Wed Jan 09, 2019 3:55 am


vonnieda
Posts: 90
Joined: Tue Nov 07, 2017 3:42 pm

Re: How to run ADC two point calibration?

Postby vonnieda » Wed Jan 09, 2019 3:59 am

ESP_Dazz wrote:
Wed Jan 09, 2019 3:55 am
See the ADC1 example and esp_adc_cal_get_voltage().
Hi ESP_Dazz,

Thanks for the response, but I wasn't asking how to use the calibration. I'm asking how to perform it. I have chips that do not have the two point EFUSE calibration burned in, and I'd like to burn it in. The docs say this can be done by the user, but do not explain how.

Again, I am looking for information on this part from the docs: To obtain more accurate calibration results these values should be measured by user and burned into eFuse BLOCK3

Thanks,
Jason

ESP_Dazz
Posts: 60
Joined: Fri Jun 02, 2017 6:50 am

Re: How to run ADC two point calibration?

Postby ESP_Dazz » Thu Jan 10, 2019 4:01 pm

Currently, the support for burning Two Point Calibration is minimal as it'll require manually calculating the encoded values, and burning block 3 using esptool. I would recommend you open an issue on the esptool Github.

However, if you would prefer to do it manually, the Two Point Calibration process is outlined below:

Writing Two Point Calibration values into EFuse Block 3 can be split into the following stages

Measurement
The first step is the measure the readings of ADC1 and ADC2 when given two voltages (150mV and 850mV) at 12-bit preceision and 0db attenuation. adcx_get_raw() can be used to obtain the readings.
  • Sample multiple times (e.g. 128 times) and then average to get a more stable reading
Scaling and Encoding
Two Point calibrations values are allocated 32bits of EFUSE_BLK3_RDATA3_REG. 7 bits are used for the 150mV readings and 9 bits are used for the 850mV readings:

EFUSE_BLK3_RDATA3[6:0] - ADC1 150mV Calibration Value
EFUSE_BLK3_RDATA3[15:7] - ADC1 850mV Calibration Value
EFUSE_BLK3_RDATA3[22:16] - ADC2 150mV Calibration Value
EFUSE_BLK3_RDATA3[32:23] - ADC2 850mV Calibration Value

However, in order to fit a 12 bit ADC reading (i.e. a reading of 0 to 4095) into 7 or 9 bits, the ADC readings must first be scaled and shifted as follows.

A1 = (ADC1 150mV Reading - 279)/4
B1 = (ADC1 850mV Reading - 3265)/4
A2 = (ADC2 150mV Reading - 421)/4
B2 = (ADC2 850mV Reading - 3406)/4

After scaling and shifting, A1 and A2 should be able to fit into 7 bits. Likewise, B1 and B2 should be able to fit into 9 bits. However, the scaled and shifted values could be negative, therefore A1, B1, A2, B2 must all be encoded into 2's complement format.

The 2's complement format must be slightly modified to account by using an all 0 binary to represent uncalibrated efuses, and the most negative value (or -0 in sign magnitude) to represent a calibrated 0 value. Using 7 bits as an example, 7'b0000000 would represent an uncalibrated value, whilst 7'b1000000 would represent a calibrated 0 value.

After encoding into two's complement format, the calibration values should be written to their respective fields within EFUSE_BLK3_RDATA3.

Example
Given the following ADC readings:
ADC1 150mV Reading: 306
ADC1 850mV Reading: 3153
ADC2 150mV Reading: 389
ADC2 850mV Reading: 3206

The scaling and shifting will result in the following:
A1 = (306 - 278)/4 = 7
B1 = (3153 - 3265)/4 = -28
A2 = (389 - 421)/4 = -8
B2 = (3206 - 3406)/4 = -50

Two's complement encoding will result in the following:
EFUSE_BLK3_RDATA3[6:0] = 7'b 0000111
EFUSE_BLK3_RDATA3[15:7] = 9'b 111100100
EFUSE_BLK3_RDATA3[22:16] = 7'b 1111000
EFUSE_BLK3_RDATA3[32:23] = 9'b 111001110

Therefore, EFUSE_BLK3_RDATA3 = 0xE778F207

Verifying Calibration Value Correctness

To verify correctness before burning, I recommend you test your final calculated value of EFUSE_BLK3_RDATA3 on a few chips by running adc1 example with a modified esp_adc_cal.c (see attached). The modified esp_adc_cal.c will read the two point calibration value from a global uint32_t, so define your calculated the following somewhere in example main:

Code: Select all

uint32_t const test_two_point_value = ...;
Burning

See the espefuse wiki regarding burning non-key data. Don't forgot to set also burn the BLK3_PART_RESERVE flag to indicate that Block 3 has been used for two point calibration
Attachments
esp_adc_cal_mod.c
(17.95 KiB) Downloaded 9 times

vonnieda
Posts: 90
Joined: Tue Nov 07, 2017 3:42 pm

Re: How to run ADC two point calibration?

Postby vonnieda » Thu Jan 10, 2019 4:43 pm

Thank you ESP_Dazz, this is exactly what I was looking for!

Thanks,
Jason

Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 19 guests