adc: support adc efuse-based calibration on esp32s3

This commit is contained in:
Armando
2021-09-07 11:21:35 +08:00
committed by Armando (Dou Yiwen)
parent c54caa457e
commit c45c6f52f1
32 changed files with 1017 additions and 190 deletions

View File

@@ -18,16 +18,18 @@
#include "driver/gpio.h"
#include "driver/adc.h"
#include "adc1_private.h"
#include "hal/adc_types.h"
#include "hal/adc_hal.h"
#include "hal/adc_hal_conf.h"
#if SOC_DAC_SUPPORTED
#include "driver/dac.h"
#include "hal/dac_hal.h"
#endif
#include "hal/adc_hal_conf.h"
#if CONFIG_IDF_TARGET_ESP32S3
#include "esp_efuse_rtc_calib.h"
#endif
#define ADC_CHECK_RET(fun_ret) ({ \
if (fun_ret != ESP_OK) { \
@@ -123,20 +125,10 @@ static esp_pm_lock_handle_t s_adc2_arbiter_lock;
#endif //CONFIG_PM_ENABLE
#endif // !CONFIG_IDF_TARGET_ESP32
/*---------------------------------------------------------------
ADC Common
---------------------------------------------------------------*/
#if CONFIG_IDF_TARGET_ESP32S2
static uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
{
adc_atten_t atten = adc_hal_get_atten(adc_n, chan);
extern uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool no_cal);
return adc_get_calibration_offset(adc_n, chan, atten, false);
}
#endif
// ADC Power
// This gets incremented when adc_power_acquire() is called, and decremented when
@@ -226,7 +218,56 @@ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num)
return ESP_OK;
}
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
//------------------------------------------------------------RTC Single Read----------------------------------------------//
#if SOC_ADC_RTC_CTRL_SUPPORTED
/*---------------------------------------------------------------
ADC Calibration
---------------------------------------------------------------*/
#if CONFIG_IDF_TARGET_ESP32S3
/**
* Temporarily put this function here. These are about ADC calibration and will be moved driver/adc.c in !14278.
* Reason for putting calibration functions in driver/adc.c:
* adc_common.c is far too confusing. Before a refactor is applied to adc_common.c, will put definite code in driver/adc.c
*/
static uint16_t s_adc_cali_param[ADC_UNIT_MAX][ADC_ATTEN_MAX] = {};
uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
{
if (s_adc_cali_param[adc_n][atten]) {
//These value won't exceed UINT16_MAX
return s_adc_cali_param[adc_n][atten];
}
//Get the calibration version
int version = esp_efuse_rtc_calib_get_ver();
uint32_t init_code = 0;
if (version == 1) {
init_code = esp_efuse_rtc_calib_get_init_code(version, adc_n, atten);
s_adc_cali_param[adc_n][atten] = init_code;
} else {
ESP_LOGW(ADC_TAG, "Calibration eFuse is not configured, skip calibration");
}
return s_adc_cali_param[adc_n][atten];
}
#elif CONFIG_IDF_TARGET_ESP32S2
//Temporarily extern this from s2/adc.c. Will be modified in !14278.
extern uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten);
#endif //CONFIG_IDF_TARGET_ESP32S3
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
static uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
{
adc_atten_t atten = adc_hal_get_atten(adc_n, chan);
return adc_get_calibration_offset(adc_n, chan, atten);
}
#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
esp_err_t adc_set_clk_div(uint8_t clk_div)
{
DIGI_CONTROLLER_ENTER();
@@ -349,7 +390,7 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
adc_hal_set_atten(ADC_NUM_1, channel, atten);
SARADC1_EXIT();
#if SOC_ADC_HW_CALIBRATION_V1
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
adc_hal_calibration_init(ADC_NUM_1);
#endif
@@ -427,11 +468,11 @@ int adc1_get_raw(adc1_channel_t channel)
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
adc1_rtc_mode_acquire();
#if CONFIG_IDF_TARGET_ESP32S2
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
// Get calibration value before going into critical section
uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel);
adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
#endif
#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED
SARADC1_ENTER();
#ifdef CONFIG_IDF_TARGET_ESP32
@@ -521,7 +562,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
SARADC2_RELEASE();
#if SOC_ADC_HW_CALIBRATION_V1
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
adc_hal_calibration_init(ADC_NUM_2);
#endif
@@ -578,11 +619,11 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG);
#endif
#if CONFIG_IDF_TARGET_ESP32S2
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
// Get calibration value before going into critical section
uint32_t cal_val = get_calibration_offset(ADC_NUM_2, channel);
adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
#endif
#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED
if ( SARADC2_TRY_ACQUIRE() == -1 ) {
//try the lock, return if failed (wifi using).
@@ -679,4 +720,4 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
return ESP_OK;
}
#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#endif //SOC_ADC_RTC_CTRL_SUPPORTED