How to run ADC two point calibration?

vonnieda
Posts: 134
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: 193
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: 134
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: 193
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 494 times

vonnieda
Posts: 134
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

tommag
Posts: 1
Joined: Tue Jun 25, 2019 2:14 pm

Re: How to run ADC two point calibration?

Postby tommag » Tue Jun 25, 2019 2:25 pm

Hi all,

I just wanted to let you know that I have written a small program to assist in measuring and converting the ADC calibration values.
You can find it here : https://github.com/tommag/ESP32_ADC_Calibration_tool

Thanks for the useful and detailed info !
Tom

pgmcbt
Posts: 1
Joined: Mon Sep 14, 2020 6:25 pm

Re: How to run ADC two point calibration?

Postby pgmcbt » Mon Sep 14, 2020 6:37 pm

Hello Tom ,

Please have a look at efuse_blk3.bin file ... ( 29 bytes )
Following steps done :
echo -n -e \\x3b\\xf3\\xa5\\xed > efuse_blk3.bin
espefuse.py burn_block_data --offset 12 BLK3 efuse_blk3.bin , after this I've got the following errors ..

C:\Users\Embed>espefuse.py --port COM4 --baud 115200 burn_block_data --offset 12 BLK3 efuse_blk3.bin
espefuse.py v2.8
Connecting........_____....._____....._____..
Traceback (most recent call last):
File "C:\Users\Embed\.platformio\python37\Scripts\espefuse.py-script.py", line 11, in <module>
load_entry_point('esptool==2.8', 'console_scripts', 'espefuse.py')()
File "c:\users\embed\.platformio\python37\lib\site-packages\espefuse.py", line 967, in _main
main()
File "c:\users\embed\.platformio\python37\lib\site-packages\espefuse.py", line 962, in main
operation_func(esp, efuses, args)
File "c:\users\embed\.platformio\python37\lib\site-packages\espefuse.py", line 656, in burn_block_data
raise RuntimeError("Data will not fit: Key block size %d bytes, data file is %d bytes" % (num_bytes, len(data)))
RuntimeError: Data will not fit: Key block size 32 bytes, data file is 29 bytes

C:\Users\Embed>

Any idea what I'm doing wrong ?
Thank you for your support .
Greetings
Chris
Attachments
efuse_blk3.bin.txt
bin file
(29 Bytes) Downloaded 7 times
calibration 1135.txt
Calibration data esp32
(1.1 KiB) Downloaded 11 times

Who is online

Users browsing this forum: No registered users and 40 guests