ADC Direct register programming...
Posted: Wed Nov 20, 2024 7:20 pm
I am trying to better understand the basics of the ESP32-S3 registers.
I wish to run a simple test ADC conversion on GPIO pin 2. But am unable to get the ADC running.
I can use the APIs:
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_1,ADC_ATTEN_DB_0);
val = adc1_get_raw(ADC1_CHANNEL_1);
Which works OK (I seem unable to actually trace what registers adc1_get_raw(ADC1_CHANNEL_1) actually manipulates.)
My own code is:
SET_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_PWM0_CLK_EN );
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL); // Contrary to table 6-5 Analog Select should =1;
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_RDE | RTC_IO_TOUCH_PAD2_RUE | RTC_IO_TOUCH_PAD2_FUN_IE);
WRITE_PERI_REG(SENS_SAR_ATTEN1_REG,0xFFFFFFF3);
SET_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN | SENS_SARADC_CLK_EN);
WRITE_PERI_REG(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_INT_EN | 1 << SENS_SAR1_CLK_DIV_S);
WRITE_PERI_REG(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD_FORCE | 0b10<<SENS_SAR1_EN_PAD_S | SENS_MEAS1_START_FORCE);
SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR);
while (!(READ_PERI_REG(SENS_SAR_MEAS1_CTRL2_REG) & SENS_MEAS2_DONE_SAR)) {
}
val =READ_PERI_REG(SENS_SAR_MEAS1_CTRL2_REG);
The code runs but strangely give ADC values that are much too high. (Checked with a controlled test voltage <1V)
I have compared all the registers I can think of, and they are all the same, although I am mystified why the "analog function =1" is not used. I have also double checked the attenuation registers. So what am I missing?!
I would also like to understand what the Calibration API actually does.. like where and what are the calibration settings that are programmed into the ESP32 memory.
I wish to run a simple test ADC conversion on GPIO pin 2. But am unable to get the ADC running.
I can use the APIs:
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_1,ADC_ATTEN_DB_0);
val = adc1_get_raw(ADC1_CHANNEL_1);
Which works OK (I seem unable to actually trace what registers adc1_get_raw(ADC1_CHANNEL_1) actually manipulates.)
My own code is:
SET_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_PWM0_CLK_EN );
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL); // Contrary to table 6-5 Analog Select should =1;
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_RDE | RTC_IO_TOUCH_PAD2_RUE | RTC_IO_TOUCH_PAD2_FUN_IE);
WRITE_PERI_REG(SENS_SAR_ATTEN1_REG,0xFFFFFFF3);
SET_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN | SENS_SARADC_CLK_EN);
WRITE_PERI_REG(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_INT_EN | 1 << SENS_SAR1_CLK_DIV_S);
WRITE_PERI_REG(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD_FORCE | 0b10<<SENS_SAR1_EN_PAD_S | SENS_MEAS1_START_FORCE);
SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR);
while (!(READ_PERI_REG(SENS_SAR_MEAS1_CTRL2_REG) & SENS_MEAS2_DONE_SAR)) {
}
val =READ_PERI_REG(SENS_SAR_MEAS1_CTRL2_REG);
The code runs but strangely give ADC values that are much too high. (Checked with a controlled test voltage <1V)
I have compared all the registers I can think of, and they are all the same, although I am mystified why the "analog function =1" is not used. I have also double checked the attenuation registers. So what am I missing?!
I would also like to understand what the Calibration API actually does.. like where and what are the calibration settings that are programmed into the ESP32 memory.