On the ESP32S3, the ADC voltage reference Vref varies a lot from chip to chip and needs to be measured with a voltmeter. To do so, adc_line_vref_to_gpio() lets you route Vref to a GPIO pin.
The problem is that I can’t figure out what arguments I should pass to this function.
I defined 9 ADC channels:
#define ADC_GPIOS { GPIO1, GPIO2, GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO11 }
GPIO11 is a channel of ADC2.
One must pass an ADC2 channel to adc_line_vref_to_gpio(), it seems.
As its 1st or 2nd argument ?
I initialized all ADC lines, then all of them except GPIO11:
// ADC_NUM_CH = 9
for(unsigned int i=0 ; i<ADC_NUM_CH ; i++) {
if(adc_init(ADC_LINE(i))) {
printf("adc_init() >> ERROR: invalid ADC line i = %d, line = %d\n", i, ADC_LINE(i));
}
}
I tried this:
if(adc_line_vref_to_gpio(ADC_LINE(8), GPIO11))
printf("%s() >> Error: can't output Vref\n", __FUNCTION__);
// or:
if(adc_line_vref_to_gpio(ADC_LINE(8), GPIO12))
printf("%s() >> Error: can't output Vref\n", __FUNCTION__);
but the application dies with this message: “#! exit 1: powering off”.
After inspecting the code, I think that I kind of figured out what arguments the function expects, but I think that there is a bug in the ESP SDK.
It turns out that the 1st argument of adc_line_vref_to_gpio() is only useful for checks. It is an index in the ADC_GPIOS
array in the 1st post of this thread and should equal e.g. 8, the index of GPIO11
, which is a channel of ADC2. The 2nd argument is really the one that is passed to the ESP32 SDK, and should also be a channel of ADC2, so GPIO11
should do.
adc_line_vref_to_gpio() calls adc_vref_to_gpio()
in $RIOTBASE/build/pkg/esp32_sdk/components/driver/adc_common.c
.
It translates GPIO11
to channel number 0 into the ch
variable, because it is the 1st line of ADC2.
GPIO12
would translate to 1, etc.
Then, adc_vref_to_gpio()
calls adc_hal_vref_output(ADC_NUM_2, ch, true)
at line 670 of the same file. This is where the crash occurs. I couldn’t find the code of this last function.
In 2022, some guys said that adc_vref_to_gpio()
was not implemented. Not sure what they meant exactly. Anyway, it looks like a SDK bug to me. As it can be mitigated by a manual calibration, I’ll stop investigating this issue.