driver(adc): esp32s2 support API adc2_vref_to_gpio
This commit is contained in:
parent
6078fcebff
commit
8d922847af
9 changed files with 180 additions and 78 deletions
|
@ -535,3 +535,36 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)
|
||||
{
|
||||
return adc_vref_to_gpio(ADC_UNIT_2, gpio);
|
||||
}
|
||||
|
||||
esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
|
||||
{
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
if (adc_unit & ADC_UNIT_1) return ESP_ERR_INVALID_ARG;
|
||||
#endif
|
||||
adc2_channel_t ch = ADC2_CHANNEL_MAX;
|
||||
/* Check if the GPIO supported. */
|
||||
for (int i = 0; i < ADC2_CHANNEL_MAX; i++) {
|
||||
if (gpio == ADC_GET_IO_NUM(ADC_NUM_2, i)) {
|
||||
ch = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ch == ADC2_CHANNEL_MAX) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc_hal_vref_output(ADC_NUM_1, ch, true);
|
||||
} else if (adc_unit & ADC_UNIT_2) {
|
||||
adc_hal_vref_output(ADC_NUM_2, ch, true);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
//Configure RTC gpio, Only ADC2's channels IO are supported to output reference voltage.
|
||||
adc_gpio_init(ADC_UNIT_2, ch);
|
||||
return ESP_OK;
|
||||
}
|
|
@ -133,22 +133,6 @@ esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel)
|
|||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||
ADC_EXIT_CRITICAL();
|
||||
if (adc_hal_vref_output(gpio) != true) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
//Configure RTC gpio
|
||||
rtc_gpio_init(gpio);
|
||||
rtc_gpio_set_direction(gpio, RTC_GPIO_MODE_DISABLED);
|
||||
rtc_gpio_pullup_dis(gpio);
|
||||
rtc_gpio_pulldown_dis(gpio);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
HALL SENSOR
|
||||
---------------------------------------------------------------*/
|
||||
|
|
|
@ -46,22 +46,6 @@ esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel);
|
|||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Output ADC2 reference voltage to GPIO 25 or 26 or 27
|
||||
*
|
||||
* This function utilizes the testing mux exclusive to ADC 2 to route the
|
||||
* reference voltage one of ADC2's channels. Supported GPIOs are GPIOs
|
||||
* 25, 26, and 27. This refernce voltage can be manually read from the pin
|
||||
* and used in the esp_adc_cal component.
|
||||
*
|
||||
* @param[in] gpio GPIO number (GPIOs 25, 26 and 27 are supported)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: v_ref successfully routed to selected GPIO
|
||||
* - ESP_ERR_INVALID_ARG: Unsupported GPIO
|
||||
*/
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio);
|
||||
|
||||
/**
|
||||
* @brief Read Hall Sensor
|
||||
*
|
||||
|
|
|
@ -312,6 +312,40 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten);
|
|||
*/
|
||||
esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out);
|
||||
|
||||
/**
|
||||
* @brief Output ADC1 or ADC2's reference voltage to ``adc2_channe_t``'s IO.
|
||||
*
|
||||
* This function routes the internal reference voltage of ADCn to one of
|
||||
* ADC2's channels. This reference voltage can then be manually measured
|
||||
* for calibration purposes.
|
||||
*
|
||||
* @note ESP32 only supports output of ADC2's internal reference voltage.
|
||||
* @param[in] adc_unit ADC unit index
|
||||
* @param[in] gpio GPIO number (Only ADC2's channels IO are supported)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: v_ref successfully routed to selected GPIO
|
||||
* - ESP_ERR_INVALID_ARG: Unsupported GPIO
|
||||
*/
|
||||
esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio);
|
||||
|
||||
/**
|
||||
* @brief Output ADC2 reference voltage to ``adc2_channe_t``'s IO.
|
||||
*
|
||||
* This function routes the internal reference voltage of ADCn to one of
|
||||
* ADC2's channels. This reference voltage can then be manually measured
|
||||
* for calibration purposes.
|
||||
*
|
||||
* @deprecated Use ``adc_vref_to_gpio`` instead.
|
||||
*
|
||||
* @param[in] gpio GPIO number (ADC2's channels are supported)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: v_ref successfully routed to selected GPIO
|
||||
* - ESP_ERR_INVALID_ARG: Unsupported GPIO
|
||||
*/
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio) __attribute__((deprecated));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -168,6 +168,20 @@ int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value);
|
|||
*/
|
||||
#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en)
|
||||
|
||||
/**
|
||||
* Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels.
|
||||
*
|
||||
* This function routes the internal reference voltage of ADCn to one of
|
||||
* ADC2's channels. This reference voltage can then be manually measured
|
||||
* for calibration purposes.
|
||||
*
|
||||
* @note ESP32 only supports output of ADC2's internal reference voltage.
|
||||
* @param[in] adc ADC unit select
|
||||
* @param[in] channel ADC2 channel number
|
||||
* @param[in] en Enable/disable the reference voltage output
|
||||
*/
|
||||
#define adc_hal_vref_output(adc, channel, en) adc_ll_vref_output(adc, channel, en)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
|
|
@ -100,19 +100,6 @@ void adc_hal_digi_deinit(void);
|
|||
*/
|
||||
int adc_hal_hall_convert(void);
|
||||
|
||||
/**
|
||||
* @brief Output ADC2 reference voltage to gpio
|
||||
*
|
||||
* This function utilizes the testing mux exclusive to ADC2 to route the
|
||||
* reference voltage one of ADC2's channels.
|
||||
*
|
||||
* @param[in] io GPIO number
|
||||
* @return
|
||||
* - true: v_ref successfully routed to selected gpio
|
||||
* - false: Unsupported gpio
|
||||
*/
|
||||
#define adc_hal_vref_output(io) adc_ll_vref_output(io)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -673,43 +673,43 @@ static inline void adc_ll_set_hall_controller(adc_ll_hall_controller_t hall_ctrl
|
|||
}
|
||||
|
||||
/**
|
||||
* Output ADC2 reference voltage to gpio 25 or 26 or 27
|
||||
* Output ADC internal reference voltage to channels, only available for ADC2 on ESP32.
|
||||
*
|
||||
* This function utilizes the testing mux exclusive to ADC 2 to route the
|
||||
* reference voltage one of ADC2's channels. Supported gpios are gpios
|
||||
* 25, 26, and 27. This refernce voltage can be manually read from the pin
|
||||
* and used in the esp_adc_cal component.
|
||||
* This function routes the internal reference voltage of ADCn to one of
|
||||
* ADC2's channels. This reference voltage can then be manually measured
|
||||
* for calibration purposes.
|
||||
*
|
||||
* @param[in] io GPIO number (gpios 25,26,27 supported)
|
||||
*
|
||||
* @return
|
||||
* - true: v_ref successfully routed to selected gpio
|
||||
* - false: Unsupported gpio
|
||||
* @param[in] adc ADC unit select
|
||||
* @param[in] channel ADC2 channel number
|
||||
* @param[in] en Enable/disable the reference voltage output
|
||||
*/
|
||||
static inline bool adc_ll_vref_output(int io)
|
||||
static inline void adc_ll_vref_output(adc_ll_num_t adc, adc_channel_t channel, bool en)
|
||||
{
|
||||
int channel;
|
||||
if (io == 25) {
|
||||
channel = 8; //Channel 8 bit
|
||||
} else if (io == 26) {
|
||||
channel = 9; //Channel 9 bit
|
||||
} else if (io == 27) {
|
||||
channel = 7; //Channel 7 bit
|
||||
if (adc != ADC_NUM_2) return;
|
||||
|
||||
if (en) {
|
||||
RTCCNTL.bias_conf.dbg_atten = 0; //Check DBG effect outside sleep mode
|
||||
//set dtest (MUX_SEL : 0 -> RTC; 1-> vdd_sar2)
|
||||
RTCCNTL.test_mux.dtest_rtc = 1; //Config test mux to route v_ref to ADC2 Channels
|
||||
//set ent
|
||||
RTCCNTL.test_mux.ent_rtc = 1;
|
||||
//set sar2_en_test
|
||||
SENS.sar_start_force.sar2_en_test = 1;
|
||||
//set sar2 en force
|
||||
SENS.sar_meas_start2.sar2_en_pad_force = 1; //Pad bitmap controlled by SW
|
||||
//set en_pad for channels 7,8,9 (bits 0x380)
|
||||
SENS.sar_meas_start2.sar2_en_pad = 1 << channel;
|
||||
} else {
|
||||
return false;
|
||||
RTCCNTL.test_mux.dtest_rtc = 0; //Config test mux to route v_ref to ADC2 Channels
|
||||
//set ent
|
||||
RTCCNTL.test_mux.ent_rtc = 0;
|
||||
//set sar2_en_test
|
||||
SENS.sar_start_force.sar2_en_test = 0;
|
||||
//set sar2 en force
|
||||
SENS.sar_meas_start2.sar2_en_pad_force = 0; //Pad bitmap controlled by SW
|
||||
//set en_pad for channels 7,8,9 (bits 0x380)
|
||||
SENS.sar_meas_start2.sar2_en_pad = 0;
|
||||
}
|
||||
RTCCNTL.bias_conf.dbg_atten = 0; //Check DBG effect outside sleep mode
|
||||
//set dtest (MUX_SEL : 0 -> RTC; 1-> vdd_sar2)
|
||||
RTCCNTL.test_mux.dtest_rtc = 1; //Config test mux to route v_ref to ADC2 Channels
|
||||
//set ent
|
||||
RTCCNTL.test_mux.ent_rtc = 1;
|
||||
//set sar2_en_test
|
||||
SENS.sar_start_force.sar2_en_test = 1;
|
||||
//set sar2 en force
|
||||
SENS.sar_meas_start2.sar2_en_pad_force = 1; //Pad bitmap controlled by SW
|
||||
//set en_pad for channels 7,8,9 (bits 0x380)
|
||||
SENS.sar_meas_start2.sar2_en_pad = 1 << channel;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -110,6 +110,19 @@ typedef enum {
|
|||
#define ADC_LL_SAR1_SAMPLE_CYCLE_ADDR 0x2
|
||||
#define ADC_LL_SAR1_SAMPLE_CYCLE_ADDR_MSB 0x2
|
||||
#define ADC_LL_SAR1_SAMPLE_CYCLE_ADDR_LSB 0x0
|
||||
|
||||
#define ADC_LL_SARADC_DTEST_RTC_ADDR 0x7
|
||||
#define ADC_LL_SARADC_DTEST_RTC_ADDR_MSB 1
|
||||
#define ADC_LL_SARADC_DTEST_RTC_ADDR_LSB 0
|
||||
|
||||
#define ADC_LL_SARADC_ENT_TSENS_ADDR 0x7
|
||||
#define ADC_LL_SARADC_ENT_TSENS_ADDR_MSB 2
|
||||
#define ADC_LL_SARADC_ENT_TSENS_ADDR_LSB 2
|
||||
|
||||
#define ADC_LL_SARADC_ENT_RTC_ADDR 0x7
|
||||
#define ADC_LL_SARADC_ENT_RTC_ADDR_MSB 3
|
||||
#define ADC_LL_SARADC_ENT_RTC_ADDR_LSB 3
|
||||
|
||||
/* ADC calibration defines end. */
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
|
@ -1248,6 +1261,59 @@ static inline void adc_ll_set_calibration_param(adc_ll_num_t adc_n, uint32_t par
|
|||
}
|
||||
/* Temp code end. */
|
||||
|
||||
/**
|
||||
* Output ADCn inter reference voltage to ADC2 channels.
|
||||
*
|
||||
* This function routes the internal reference voltage of ADCn to one of
|
||||
* ADC2's channels. This reference voltage can then be manually measured
|
||||
* for calibration purposes.
|
||||
*
|
||||
* @param[in] adc ADC unit select
|
||||
* @param[in] channel ADC2 channel number
|
||||
* @param[in] en Enable/disable the reference voltage output
|
||||
*/
|
||||
static inline void adc_ll_vref_output(adc_ll_num_t adc, adc_channel_t channel, bool en)
|
||||
{
|
||||
/* Should be called before writing I2C registers. */
|
||||
void phy_get_romfunc_addr(void);
|
||||
phy_get_romfunc_addr();
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
|
||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
|
||||
SET_PERI_REG_MASK(ADC_LL_ANA_CONFIG2_REG, BIT(16));
|
||||
|
||||
if (en) {
|
||||
if (adc == ADC_NUM_1) {
|
||||
/* Config test mux to route v_ref to ADC1 Channels */
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_DTEST_RTC_ADDR, 1);
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_ENT_TSENS_ADDR, 0);
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_ENT_RTC_ADDR, 1);
|
||||
} else {
|
||||
/* Config test mux to route v_ref to ADC2 Channels */
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_DTEST_RTC_ADDR, 0);
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_ENT_TSENS_ADDR, 1);
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_ENT_RTC_ADDR, 0);
|
||||
}
|
||||
//in sleep force to use rtc to control ADC
|
||||
SENS.sar_meas2_mux.sar2_rtc_force = 1;
|
||||
//set sar2_en_test
|
||||
SENS.sar_meas2_ctrl1.sar2_en_test = 1;
|
||||
//set sar2 en force
|
||||
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; //Pad bitmap controlled by SW
|
||||
//set en_pad for ADC2 channels (bits 0x380)
|
||||
SENS.sar_meas2_ctrl2.sar2_en_pad = 1 << channel;
|
||||
} else {
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_ENT_TSENS_ADDR, 0);
|
||||
I2C_WRITEREG_MASK_RTC(ADC_LL_I2C_ADC, ADC_LL_SARADC_ENT_RTC_ADDR, 0);
|
||||
SENS.sar_meas2_mux.sar2_rtc_force = 0;
|
||||
//set sar2_en_test
|
||||
SENS.sar_meas2_ctrl1.sar2_en_test = 0;
|
||||
//set sar2 en force
|
||||
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 0; //Pad bitmap controlled by SW
|
||||
//set en_pad for ADC2 channels (bits 0x380)
|
||||
SENS.sar_meas2_ctrl2.sar2_en_pad = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -53,7 +53,7 @@ Then it is possible to read ADC conversion result with :cpp:func:`adc1_get_raw`
|
|||
|
||||
This API provides convenient way to configure ADC1 for reading from :doc:`ULP <../../api-guides/ulp>`. To do so, call function :cpp:func:`adc1_ulp_enable` and then set precision and attenuation as discussed above.
|
||||
|
||||
There is another specific function :cpp:func:`adc2_vref_to_gpio` used to route internal reference voltage to a GPIO pin. It comes handy to calibrate ADC reading and this is discussed in section :ref:`adc-api-adc-calibration`.
|
||||
There is another specific function :cpp:func:`adc_vref_to_gpio` used to route internal reference voltage to a GPIO pin. It comes handy to calibrate ADC reading and this is discussed in section :ref:`adc-api-adc-calibration`.
|
||||
|
||||
.. todo::
|
||||
|
||||
|
@ -228,7 +228,7 @@ Routing ADC reference voltage to GPIO, so it can be manually measured (for **Def
|
|||
|
||||
...
|
||||
|
||||
esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25);
|
||||
esp_err_t status = adc_vref_to_gpio(ADC_UNIT_1, GPIO_NUM_25);
|
||||
if (status == ESP_OK) {
|
||||
printf("v_ref routed to GPIO\n");
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue