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