mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 14:14:11 +00:00 
			
		
		
		
	Merge branch 'feature/sync_adc_changes_from_c3_to_master' into 'master'
adc: sync adc changes from c3 to master See merge request espressif/esp-idf!11989
This commit is contained in:
		@@ -66,7 +66,9 @@ endif()
 | 
			
		||||
if(IDF_TARGET STREQUAL "esp32c3")
 | 
			
		||||
    list(APPEND srcs "gdma.c"
 | 
			
		||||
                     "spi_slave_hd.c"
 | 
			
		||||
                     "esp32c3/adc.c")
 | 
			
		||||
                     "esp32c3/adc.c"
 | 
			
		||||
                     "esp32c3/adc2_init_cal.c"
 | 
			
		||||
                     "esp32c3/rtc_tempsensor.c")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
idf_component_register(SRCS "${srcs}"
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,6 @@
 | 
			
		||||
#include "hal/adc_types.h"
 | 
			
		||||
#include "hal/adc_hal.h"
 | 
			
		||||
 | 
			
		||||
#if !CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#include "hal/dac_hal.h"
 | 
			
		||||
#include "hal/adc_hal_conf.h"
 | 
			
		||||
 | 
			
		||||
@@ -121,7 +120,7 @@ static esp_pm_lock_handle_t s_adc2_arbiter_lock;
 | 
			
		||||
                    ADC Common
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
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);
 | 
			
		||||
@@ -372,7 +371,7 @@ int adc1_get_raw(adc1_channel_t channel)
 | 
			
		||||
    adc1_rtc_mode_acquire();
 | 
			
		||||
    adc_power_acquire();
 | 
			
		||||
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
    // Get calibration value before going into critical section
 | 
			
		||||
    uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -382,7 +381,7 @@ int adc1_get_raw(adc1_channel_t channel)
 | 
			
		||||
    adc_hal_hall_disable(); //Disable other peripherals.
 | 
			
		||||
    adc_hal_amp_disable();  //Currently the LNA is not open, close it by default.
 | 
			
		||||
#endif
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
    adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
 | 
			
		||||
#endif
 | 
			
		||||
    adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC);    //Set controller
 | 
			
		||||
@@ -528,7 +527,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
 | 
			
		||||
 | 
			
		||||
    adc_power_acquire();         //in critical section with whole rtc module
 | 
			
		||||
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
    // Get calibration value before going into critical section
 | 
			
		||||
    uint32_t cal_val = get_calibration_offset(ADC_NUM_2, channel);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -544,7 +543,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
 | 
			
		||||
    adc2_dac_disable(channel);      //disable other peripherals
 | 
			
		||||
#endif
 | 
			
		||||
    adc2_config_width(width_bit);   // in critical section with whole rtc module. because the PWDET use the same registers, place it here.
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
    adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
 | 
			
		||||
#endif
 | 
			
		||||
    adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller
 | 
			
		||||
@@ -629,5 +628,3 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
 | 
			
		||||
    adc_gpio_init(ADC_UNIT_2, ch);
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // !CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@
 | 
			
		||||
#include "hal/adc_types.h"
 | 
			
		||||
#include "hal/adc_hal.h"
 | 
			
		||||
#include "hal/dma_types.h"
 | 
			
		||||
#include "esp32c3/esp_efuse_rtc_calib.h"
 | 
			
		||||
 | 
			
		||||
#define ADC_CHECK_RET(fun_ret) ({                  \
 | 
			
		||||
    if (fun_ret != ESP_OK) {                                \
 | 
			
		||||
@@ -89,13 +90,16 @@ typedef struct adc_digi_context_t {
 | 
			
		||||
    RingbufHandle_t         ringbuf_hdl;                //RX ringbuffer handler
 | 
			
		||||
    bool                    ringbuf_overflow_flag;      //1: ringbuffer overflow
 | 
			
		||||
    bool                    driver_start_flag;          //1: driver is started; 0: driver is stoped
 | 
			
		||||
    bool                    use_adc1;                   //1: ADC unit1 will be used; 0: ADC unit1 won't be used.
 | 
			
		||||
    bool                    use_adc2;                   //1: ADC unit2 will be used; 0: ADC unit2 won't be used. This determines whether to acquire sar_adc2_mutex lock or not.
 | 
			
		||||
    adc_atten_t             adc1_atten;                 //Attenuation for ADC1. On this chip each ADC can only support one attenuation.
 | 
			
		||||
    adc_atten_t             adc2_atten;                 //Attenuation for ADC2. On this chip each ADC can only support one attenuation.
 | 
			
		||||
    adc_digi_config_t       digi_controller_config;     //Digital Controller Configuration
 | 
			
		||||
} adc_digi_context_t;
 | 
			
		||||
 | 
			
		||||
static const char* ADC_DMA_TAG = "ADC_DMA:";
 | 
			
		||||
static adc_digi_context_t *s_adc_digi_ctx = NULL;
 | 
			
		||||
 | 
			
		||||
static uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan, adc_atten_t atten);
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                   ADC Continuous Read Mode (via DMA)
 | 
			
		||||
@@ -238,6 +242,7 @@ static IRAM_ATTR void adc_dma_intr(void *arg)
 | 
			
		||||
        s_adc_digi_ctx->hal_dma_config.desc_cnt = 0;
 | 
			
		||||
 | 
			
		||||
        //start next turns of dma operation
 | 
			
		||||
        adc_hal_digi_dma_multi_descriptor(&s_adc_digi_ctx->hal_dma_config, s_adc_digi_ctx->rx_dma_buf, s_adc_digi_ctx->bytes_between_intr, s_adc_digi_ctx->hal_dma_config.desc_max_num);
 | 
			
		||||
        adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -264,6 +269,16 @@ esp_err_t adc_digi_start(void)
 | 
			
		||||
 | 
			
		||||
    adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
 | 
			
		||||
    adc_hal_init();
 | 
			
		||||
 | 
			
		||||
    if (s_adc_digi_ctx->use_adc1) {
 | 
			
		||||
        uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, ADC_CHANNEL_MAX, s_adc_digi_ctx->adc1_atten);
 | 
			
		||||
        adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
 | 
			
		||||
    }
 | 
			
		||||
    if (s_adc_digi_ctx->use_adc2) {
 | 
			
		||||
        uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, ADC_CHANNEL_MAX, s_adc_digi_ctx->adc2_atten);
 | 
			
		||||
        adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    adc_hal_arbiter_config(&config);
 | 
			
		||||
    adc_hal_digi_init(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
 | 
			
		||||
    adc_hal_digi_controller_config(&s_adc_digi_ctx->digi_controller_config);
 | 
			
		||||
@@ -277,11 +292,13 @@ esp_err_t adc_digi_start(void)
 | 
			
		||||
 | 
			
		||||
    //enable in suc eof intr
 | 
			
		||||
    adc_hal_digi_ena_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT);
 | 
			
		||||
    //start DMA
 | 
			
		||||
    adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
 | 
			
		||||
 | 
			
		||||
    //start ADC
 | 
			
		||||
    adc_hal_digi_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
 | 
			
		||||
 | 
			
		||||
    //start DMA
 | 
			
		||||
    adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config);
 | 
			
		||||
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -326,7 +343,7 @@ esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_l
 | 
			
		||||
 | 
			
		||||
    data = xRingbufferReceiveUpTo(s_adc_digi_ctx->ringbuf_hdl, &size, ticks_to_wait, length_max);
 | 
			
		||||
    if (!data) {
 | 
			
		||||
        ESP_LOGW(ADC_DMA_TAG, "No data, increase timeout or reduce conv_num_each_intr");
 | 
			
		||||
        ESP_LOGV(ADC_TAG, "No data, increase timeout or reduce conv_num_each_intr");
 | 
			
		||||
        ret = ESP_ERR_TIMEOUT;
 | 
			
		||||
        *out_length = 0;
 | 
			
		||||
        return ret;
 | 
			
		||||
@@ -340,6 +357,7 @@ esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_l
 | 
			
		||||
    if (s_adc_digi_ctx->ringbuf_overflow_flag) {
 | 
			
		||||
        ret = ESP_ERR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -363,6 +381,7 @@ esp_err_t adc_digi_deinitialize(void)
 | 
			
		||||
        s_adc_digi_ctx->ringbuf_hdl = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(s_adc_digi_ctx->rx_dma_buf);
 | 
			
		||||
    free(s_adc_digi_ctx->hal_dma_config.rx_desc);
 | 
			
		||||
    free(s_adc_digi_ctx->digi_controller_config.adc_pattern);
 | 
			
		||||
    free(s_adc_digi_ctx);
 | 
			
		||||
@@ -382,8 +401,8 @@ static adc_atten_t s_atten2_single[ADC2_CHANNEL_MAX];    //Array saving attenuat
 | 
			
		||||
 | 
			
		||||
esp_err_t adc1_config_width(adc_bits_width_t width_bit)
 | 
			
		||||
{
 | 
			
		||||
    //On ESP32C3, the data width is always 13-bits.
 | 
			
		||||
    if (width_bit != ADC_WIDTH_BIT_13) {
 | 
			
		||||
    //On ESP32C3, the data width is always 12-bits.
 | 
			
		||||
    if (width_bit != ADC_WIDTH_BIT_12) {
 | 
			
		||||
        return ESP_ERR_INVALID_ARG;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -404,40 +423,42 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
 | 
			
		||||
 | 
			
		||||
int adc1_get_raw(adc1_channel_t channel)
 | 
			
		||||
{
 | 
			
		||||
    int result = 0;
 | 
			
		||||
    int raw_out = 0;
 | 
			
		||||
    adc_digi_config_t dig_cfg = {
 | 
			
		||||
        .conv_limit_en = 0,
 | 
			
		||||
        .conv_limit_num = 250,
 | 
			
		||||
        .interval = 40,
 | 
			
		||||
        .dig_clk.use_apll = 0,
 | 
			
		||||
        .dig_clk.div_num = 1,
 | 
			
		||||
        .dig_clk.div_a = 0,
 | 
			
		||||
        .dig_clk.div_b = 1,
 | 
			
		||||
        .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ADC_DIGI_LOCK_ACQUIRE();
 | 
			
		||||
 | 
			
		||||
    periph_module_enable(PERIPH_SARADC_MODULE);
 | 
			
		||||
 | 
			
		||||
    adc_atten_t atten = s_atten1_single[channel];
 | 
			
		||||
    uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, channel, atten);
 | 
			
		||||
    adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
 | 
			
		||||
 | 
			
		||||
    adc_hal_digi_controller_config(&dig_cfg);
 | 
			
		||||
 | 
			
		||||
    adc_hal_intr_clear(ADC_EVENT_ADC1_DONE);
 | 
			
		||||
 | 
			
		||||
    adc_hal_onetime_channel(ADC_NUM_1, channel);
 | 
			
		||||
    adc_hal_set_onetime_atten(s_atten1_single[channel]);
 | 
			
		||||
    adc_hal_set_onetime_atten(atten);
 | 
			
		||||
 | 
			
		||||
    adc_hal_adc1_onetime_sample_enable(true);
 | 
			
		||||
    //Trigger single read.
 | 
			
		||||
    adc_hal_adc1_onetime_sample_enable(true);
 | 
			
		||||
    adc_hal_onetime_start(&dig_cfg);
 | 
			
		||||
 | 
			
		||||
    while (!adc_hal_intr_get_raw(ADC_EVENT_ADC1_DONE));
 | 
			
		||||
    adc_hal_intr_clear(ADC_EVENT_ADC1_DONE);
 | 
			
		||||
    adc_hal_adc1_onetime_sample_enable(false);
 | 
			
		||||
 | 
			
		||||
    result = adc_hal_adc1_read();
 | 
			
		||||
    adc_hal_single_read(ADC_NUM_1, &raw_out);
 | 
			
		||||
    adc_hal_digi_deinit();
 | 
			
		||||
    periph_module_disable(PERIPH_SARADC_MODULE);
 | 
			
		||||
 | 
			
		||||
    ADC_DIGI_LOCK_RELEASE();
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
    return raw_out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
 | 
			
		||||
@@ -454,41 +475,46 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
    //On ESP32C3, the data width is always 13-bits.
 | 
			
		||||
    if (width_bit != ADC_WIDTH_BIT_13) {
 | 
			
		||||
    //On ESP32C3, the data width is always 12-bits.
 | 
			
		||||
    if (width_bit != ADC_WIDTH_BIT_12) {
 | 
			
		||||
        return ESP_ERR_INVALID_ARG;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    esp_err_t ret = ESP_OK;
 | 
			
		||||
    adc_digi_config_t dig_cfg = {
 | 
			
		||||
        .conv_limit_en = 0,
 | 
			
		||||
        .conv_limit_num = 250,
 | 
			
		||||
        .interval = 40,
 | 
			
		||||
        .dig_clk.use_apll = 0,
 | 
			
		||||
        .dig_clk.div_num = 1,
 | 
			
		||||
        .dig_clk.div_a = 0,
 | 
			
		||||
        .dig_clk.div_b = 1,
 | 
			
		||||
        .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    SAC_ADC2_LOCK_ACQUIRE();
 | 
			
		||||
    ADC_DIGI_LOCK_ACQUIRE();
 | 
			
		||||
    periph_module_enable(PERIPH_SARADC_MODULE);
 | 
			
		||||
 | 
			
		||||
    adc_atten_t atten = s_atten2_single[channel];
 | 
			
		||||
    uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, channel, atten);
 | 
			
		||||
    adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
 | 
			
		||||
 | 
			
		||||
    adc_hal_digi_controller_config(&dig_cfg);
 | 
			
		||||
 | 
			
		||||
    adc_hal_intr_clear(ADC_EVENT_ADC2_DONE);
 | 
			
		||||
 | 
			
		||||
    adc_hal_onetime_channel(ADC_NUM_2, channel);
 | 
			
		||||
    adc_hal_set_onetime_atten(s_atten2_single[channel]);
 | 
			
		||||
    adc_hal_set_onetime_atten(atten);
 | 
			
		||||
 | 
			
		||||
    adc_hal_adc2_onetime_sample_enable(true);
 | 
			
		||||
    //Trigger single read.
 | 
			
		||||
    adc_hal_adc2_onetime_sample_enable(true);
 | 
			
		||||
    adc_hal_onetime_start(&dig_cfg);
 | 
			
		||||
 | 
			
		||||
    while (!adc_hal_intr_get_raw(ADC_EVENT_ADC2_DONE));
 | 
			
		||||
    adc_hal_intr_clear(ADC_EVENT_ADC2_DONE);
 | 
			
		||||
    adc_hal_adc2_onetime_sample_enable(false);
 | 
			
		||||
 | 
			
		||||
    *raw_out = adc_hal_adc2_read();
 | 
			
		||||
    ret = adc_hal_single_read(ADC_NUM_2, raw_out);
 | 
			
		||||
    if (ret != ESP_OK) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    adc_hal_digi_deinit();
 | 
			
		||||
    periph_module_disable(PERIPH_SARADC_MODULE);
 | 
			
		||||
 | 
			
		||||
    ADC_DIGI_LOCK_RELEASE();
 | 
			
		||||
    SAC_ADC2_LOCK_RELEASE();
 | 
			
		||||
@@ -505,20 +531,38 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
 | 
			
		||||
    if (!s_adc_digi_ctx) {
 | 
			
		||||
        return ESP_ERR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
    ADC_CHECK(config->sample_freq_hz <= SOC_ADC_SAMPLE_FREQ_THRES_HIGH && config->sample_freq_hz >= SOC_ADC_SAMPLE_FREQ_THRES_LOW, "ADC sampling frequency out of range", ESP_ERR_INVALID_ARG);
 | 
			
		||||
 | 
			
		||||
    s_adc_digi_ctx->digi_controller_config.conv_limit_en = config->conv_limit_en;
 | 
			
		||||
    s_adc_digi_ctx->digi_controller_config.conv_limit_num = config->conv_limit_num;
 | 
			
		||||
    s_adc_digi_ctx->digi_controller_config.adc_pattern_len = config->adc_pattern_len;
 | 
			
		||||
    s_adc_digi_ctx->digi_controller_config.interval =  config->interval;
 | 
			
		||||
    s_adc_digi_ctx->digi_controller_config.dig_clk = config-> dig_clk;
 | 
			
		||||
    s_adc_digi_ctx->digi_controller_config.dma_eof_num = config->dma_eof_num;
 | 
			
		||||
    s_adc_digi_ctx->digi_controller_config.sample_freq_hz = config->sample_freq_hz;
 | 
			
		||||
    memcpy(s_adc_digi_ctx->digi_controller_config.adc_pattern, config->adc_pattern, config->adc_pattern_len * sizeof(adc_digi_pattern_table_t));
 | 
			
		||||
 | 
			
		||||
    //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver
 | 
			
		||||
    const int atten_uninitialised = 999;
 | 
			
		||||
    s_adc_digi_ctx->adc1_atten = atten_uninitialised;
 | 
			
		||||
    s_adc_digi_ctx->adc2_atten = atten_uninitialised;
 | 
			
		||||
    s_adc_digi_ctx->use_adc1 = 0;
 | 
			
		||||
    s_adc_digi_ctx->use_adc2 = 0;
 | 
			
		||||
    for (int i = 0; i < config->adc_pattern_len; i++) {
 | 
			
		||||
        if (config->adc_pattern->unit == ADC_NUM_2) {
 | 
			
		||||
        const adc_digi_pattern_table_t* pat = &config->adc_pattern[i];
 | 
			
		||||
        if (pat->unit == ADC_NUM_1) {
 | 
			
		||||
            s_adc_digi_ctx->use_adc1 = 1;
 | 
			
		||||
 | 
			
		||||
            if (s_adc_digi_ctx->adc1_atten == atten_uninitialised) {
 | 
			
		||||
                s_adc_digi_ctx->adc1_atten = pat->atten;
 | 
			
		||||
            } else if (s_adc_digi_ctx->adc1_atten != pat->atten) {
 | 
			
		||||
                return ESP_ERR_INVALID_ARG;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (pat->unit == ADC_NUM_2) {
 | 
			
		||||
            //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver
 | 
			
		||||
            s_adc_digi_ctx->use_adc2 = 1;
 | 
			
		||||
 | 
			
		||||
            if (s_adc_digi_ctx->adc2_atten == atten_uninitialised) {
 | 
			
		||||
                s_adc_digi_ctx->adc2_atten = pat->atten;
 | 
			
		||||
            } else if (s_adc_digi_ctx->adc2_atten != pat->atten) {
 | 
			
		||||
                return ESP_ERR_INVALID_ARG;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -547,12 +591,12 @@ esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config)
 | 
			
		||||
 * @note  For ADC1, Controller access is mutually exclusive.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_unit ADC unit.
 | 
			
		||||
 * @param ctrl ADC controller, Refer to `adc_ll_controller_t`.
 | 
			
		||||
 * @param ctrl ADC controller, Refer to `adc_controller_t`.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 *      - ESP_OK Success
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_ll_controller_t ctrl)
 | 
			
		||||
esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl)
 | 
			
		||||
{
 | 
			
		||||
    adc_arbiter_t config = {0};
 | 
			
		||||
    adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT();
 | 
			
		||||
@@ -611,34 +655,34 @@ esp_err_t adc_digi_reset(void)
 | 
			
		||||
 | 
			
		||||
esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2528
 | 
			
		||||
    ADC_ENTER_CRITICAL();
 | 
			
		||||
    adc_hal_digi_filter_reset(idx);
 | 
			
		||||
    ADC_EXIT_CRITICAL();
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2528
 | 
			
		||||
    ADC_ENTER_CRITICAL();
 | 
			
		||||
    adc_hal_digi_filter_set_factor(idx, config);
 | 
			
		||||
    ADC_EXIT_CRITICAL();
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2528
 | 
			
		||||
    ADC_ENTER_CRITICAL();
 | 
			
		||||
    adc_hal_digi_filter_get_factor(idx, config);
 | 
			
		||||
    ADC_EXIT_CRITICAL();
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2528
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the filtered data of adc digital controller filter. For debug.
 | 
			
		||||
 *        The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
 | 
			
		||||
 *
 | 
			
		||||
 * @param idx Filter index.
 | 
			
		||||
 * @return Filtered data. if <0, the read data invalid.
 | 
			
		||||
 */
 | 
			
		||||
int adc_digi_filter_read_data(adc_digi_filter_idx_t idx)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2528
 | 
			
		||||
    ADC_ENTER_CRITICAL();
 | 
			
		||||
    adc_hal_digi_filter_enable(idx, enable);
 | 
			
		||||
    ADC_EXIT_CRITICAL();
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**************************************/
 | 
			
		||||
@@ -648,23 +692,16 @@ int adc_digi_filter_read_data(adc_digi_filter_idx_t idx)
 | 
			
		||||
esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config)
 | 
			
		||||
{
 | 
			
		||||
    ADC_ENTER_CRITICAL();
 | 
			
		||||
    if (idx == ADC_DIGI_MONITOR_IDX0) {
 | 
			
		||||
        adc_hal_digi_monitor_config(ADC_NUM_1, config);
 | 
			
		||||
    } else if (idx == ADC_DIGI_MONITOR_IDX1) {
 | 
			
		||||
        adc_hal_digi_monitor_config(ADC_NUM_2, config);
 | 
			
		||||
    }
 | 
			
		||||
    adc_hal_digi_monitor_config(idx, config);
 | 
			
		||||
    ADC_EXIT_CRITICAL();
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ADC_ENTER_CRITICAL();
 | 
			
		||||
    if (idx == ADC_DIGI_MONITOR_IDX0) {
 | 
			
		||||
        adc_hal_digi_monitor_enable(ADC_NUM_1, enable);
 | 
			
		||||
    } else if (idx == ADC_DIGI_MONITOR_IDX1) {
 | 
			
		||||
        adc_hal_digi_monitor_enable(ADC_NUM_2, enable);
 | 
			
		||||
    }
 | 
			
		||||
    adc_hal_digi_monitor_enable(idx, enable);
 | 
			
		||||
    ADC_EXIT_CRITICAL();
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -756,3 +793,40 @@ esp_err_t adc_digi_isr_deregister(void)
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    RTC controller setting
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static uint16_t s_adc_cali_param[ADC_ATTEN_MAX] = {};
 | 
			
		||||
 | 
			
		||||
//NOTE: according to calibration version, different types of lock may be taken during the process:
 | 
			
		||||
//  1. Semaphore when reading efuse
 | 
			
		||||
//  2. Lock (Spinlock, or Mutex) if we actually do ADC calibration in the future
 | 
			
		||||
//This function shoudn't be called inside critical section or ISR
 | 
			
		||||
static uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
 | 
			
		||||
{
 | 
			
		||||
    const bool no_cal = false;
 | 
			
		||||
    if (s_adc_cali_param[atten]) {
 | 
			
		||||
        return (uint32_t)s_adc_cali_param[atten];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (no_cal) {
 | 
			
		||||
        return 0;   //indicating failure
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // check if we can fetch the values from eFuse.
 | 
			
		||||
    int version = esp_efuse_rtc_calib_get_ver();
 | 
			
		||||
    assert(version == 1);
 | 
			
		||||
    uint32_t init_code = esp_efuse_rtc_calib_get_init_code(version, atten);
 | 
			
		||||
 | 
			
		||||
    ESP_LOGD(ADC_TAG, "Calib(V%d) ADC%d atten=%d: %04X", version, adc_n, atten, init_code);
 | 
			
		||||
    s_adc_cali_param[atten] = init_code;
 | 
			
		||||
    return init_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Internal function to calibrate PWDET for WiFi
 | 
			
		||||
esp_err_t adc_cal_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t cal_val = adc_get_calibration_offset(adc_n, channel, atten);
 | 
			
		||||
    ADC_ENTER_CRITICAL();
 | 
			
		||||
    adc_hal_set_calibration_param(adc_n, cal_val);
 | 
			
		||||
    ADC_EXIT_CRITICAL();
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								components/driver/esp32c3/adc2_init_cal.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								components/driver/esp32c3/adc2_init_cal.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
// Copyright 2016-2018 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/* This file is used to get `adc2_init_code_calibration` executed before the APP when the ADC2 is used by Wi-Fi or other drivers.
 | 
			
		||||
The linker will link constructor (adc2_init_code_calibration) only when any sections inside the same file (adc2_cal_include) is used.
 | 
			
		||||
Don't put any other code into this file. */
 | 
			
		||||
 | 
			
		||||
#include "adc2_wifi_private.h"
 | 
			
		||||
#include "hal/adc_hal.h"
 | 
			
		||||
#include "esp_private/adc_cali.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Set initial code to ADC2 after calibration. ADC2 RTC and ADC2 PWDET controller share the initial code.
 | 
			
		||||
 *        This API be called in before `app_main()`.
 | 
			
		||||
 */
 | 
			
		||||
static __attribute__((constructor)) void adc2_init_code_calibration(void)
 | 
			
		||||
{
 | 
			
		||||
    const adc_ll_num_t adc_n = ADC_NUM_2;
 | 
			
		||||
    const adc_atten_t atten = ADC_ATTEN_DB_11;
 | 
			
		||||
    const adc_channel_t channel = 0;
 | 
			
		||||
    adc_cal_offset(adc_n, channel, atten);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Don't call `adc2_cal_include` in user code. */
 | 
			
		||||
void adc2_cal_include(void)
 | 
			
		||||
{
 | 
			
		||||
    /* When this empty function is called, the `adc2_init_code_calibration` constructor will be linked and executed before the app.*/
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								components/driver/esp32c3/include/driver/temp_sensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								components/driver/esp32c3/include/driver/temp_sensor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
// Copyright 2010-2018 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "esp_err.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */
 | 
			
		||||
    TSENS_DAC_L1,     /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */
 | 
			
		||||
    TSENS_DAC_L2,     /*!< offset =  0, measure range:-10℃ ~  80℃, error < 1℃. */
 | 
			
		||||
    TSENS_DAC_L3,     /*!< offset =  1, measure range:-30℃ ~  50℃, error < 2℃. */
 | 
			
		||||
    TSENS_DAC_L4,     /*!< offset =  2, measure range:-40℃ ~  20℃, error < 3℃. */
 | 
			
		||||
    TSENS_DAC_MAX,
 | 
			
		||||
    TSENS_DAC_DEFAULT = TSENS_DAC_L2,
 | 
			
		||||
} temp_sensor_dac_offset_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Configuration for temperature sensor reading
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    temp_sensor_dac_offset_t dac_offset;    /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */
 | 
			
		||||
    uint8_t clk_div;                        /*!< Default: 6 */
 | 
			
		||||
} temp_sensor_config_t;
 | 
			
		||||
 | 
			
		||||
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
 | 
			
		||||
                                .clk_div = 6}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Set parameter of temperature sensor.
 | 
			
		||||
 * @param tsens
 | 
			
		||||
 * @return
 | 
			
		||||
 *     - ESP_OK Success
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get parameter of temperature sensor.
 | 
			
		||||
 * @param tsens
 | 
			
		||||
 * @return
 | 
			
		||||
 *     - ESP_OK Success
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Start temperature sensor measure.
 | 
			
		||||
 * @return
 | 
			
		||||
 *     - ESP_OK Success
 | 
			
		||||
 *     - ESP_ERR_INVALID_ARG
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t temp_sensor_start(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Stop temperature sensor measure.
 | 
			
		||||
 * @return
 | 
			
		||||
 *     - ESP_OK Success
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t temp_sensor_stop(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Read temperature sensor raw data.
 | 
			
		||||
 * @param tsens_out Pointer to raw data, Range: 0 ~ 255
 | 
			
		||||
 * @return
 | 
			
		||||
 *     - ESP_OK Success
 | 
			
		||||
 *     - ESP_ERR_INVALID_ARG `tsens_out` is NULL
 | 
			
		||||
 *     - ESP_ERR_INVALID_STATE temperature sensor dont start
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Read temperature sensor data that is converted to degrees Celsius.
 | 
			
		||||
 * @note  Should not be called from interrupt.
 | 
			
		||||
 * @param celsius The measure output value.
 | 
			
		||||
 * @return
 | 
			
		||||
 *     - ESP_OK Success
 | 
			
		||||
 *     - ESP_ERR_INVALID_ARG ARG is NULL.
 | 
			
		||||
 *     - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t temp_sensor_read_celsius(float *celsius);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										133
									
								
								components/driver/esp32c3/rtc_tempsensor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								components/driver/esp32c3/rtc_tempsensor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
// Copyright 2016-2018 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include <esp_types.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include "freertos/FreeRTOS.h"
 | 
			
		||||
#include "freertos/semphr.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
#include "hal/adc_ll.h"
 | 
			
		||||
#include "soc/rtc_cntl_reg.h"
 | 
			
		||||
#include "soc/apb_saradc_struct.h"
 | 
			
		||||
#include "soc/apb_saradc_reg.h"
 | 
			
		||||
#include "soc/system_reg.h"
 | 
			
		||||
#include "driver/temp_sensor.h"
 | 
			
		||||
#include "regi2c_ctrl.h"
 | 
			
		||||
#include "esp32c3/rom/ets_sys.h"
 | 
			
		||||
 | 
			
		||||
static const char *TAG = "tsens";
 | 
			
		||||
 | 
			
		||||
#define TSENS_CHECK(res, ret_val) ({                                    \
 | 
			
		||||
    if (!(res)) {                                                       \
 | 
			
		||||
        ESP_LOGE(TAG, "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__);  \
 | 
			
		||||
        return (ret_val);                                               \
 | 
			
		||||
    }                                                                   \
 | 
			
		||||
})
 | 
			
		||||
#define TSENS_XPD_WAIT_DEFAULT 0xFF   /* Set wait cycle time(8MHz) from power up to reset enable. */
 | 
			
		||||
#define TSENS_ADC_FACTOR  (0.4386)
 | 
			
		||||
#define TSENS_DAC_FACTOR  (27.88)
 | 
			
		||||
#define TSENS_SYS_OFFSET  (20.52)
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    int index;
 | 
			
		||||
    int offset;
 | 
			
		||||
    int set_val;
 | 
			
		||||
    int range_min;
 | 
			
		||||
    int range_max;
 | 
			
		||||
    int error_max;
 | 
			
		||||
} tsens_dac_offset_t;
 | 
			
		||||
 | 
			
		||||
static const tsens_dac_offset_t dac_offset[TSENS_DAC_MAX] = {
 | 
			
		||||
    /*     DAC     Offset reg_val  min  max  error */
 | 
			
		||||
    {TSENS_DAC_L0,   -2,     5,    50,  125,   3},
 | 
			
		||||
    {TSENS_DAC_L1,   -1,     7,    20,  100,   2},
 | 
			
		||||
    {TSENS_DAC_L2,    0,    15,   -10,   80,   1},
 | 
			
		||||
    {TSENS_DAC_L3,    1,    11,   -30,   50,   2},
 | 
			
		||||
    {TSENS_DAC_L4,    2,    10,   -40,   20,   3},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
 | 
			
		||||
{
 | 
			
		||||
    REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_TSENS_CLK_EN);
 | 
			
		||||
    CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
 | 
			
		||||
    SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, dac_offset[tsens.dac_offset].set_val);
 | 
			
		||||
    APB_SARADC.apb_tsens_ctrl.tsens_clk_div = tsens.clk_div;
 | 
			
		||||
    APB_SARADC.apb_tsens_ctrl2.tsens_xpd_wait = TSENS_XPD_WAIT_DEFAULT;
 | 
			
		||||
    APB_SARADC.apb_tsens_ctrl2.tsens_xpd_force = 1;
 | 
			
		||||
    ESP_LOGD(TAG, "Config temperature range [%d°C ~ %d°C], error < %d°C",
 | 
			
		||||
             dac_offset[tsens.dac_offset].range_min,
 | 
			
		||||
             dac_offset[tsens.dac_offset].range_max,
 | 
			
		||||
             dac_offset[tsens.dac_offset].error_max);
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens)
 | 
			
		||||
{
 | 
			
		||||
    TSENS_CHECK(tsens != NULL, ESP_ERR_INVALID_ARG);
 | 
			
		||||
    CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
 | 
			
		||||
    SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
 | 
			
		||||
    tsens->dac_offset = REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
 | 
			
		||||
    for (int i = TSENS_DAC_L0; i < TSENS_DAC_MAX; i++) {
 | 
			
		||||
        if (tsens->dac_offset == dac_offset[i].set_val) {
 | 
			
		||||
            tsens->dac_offset = dac_offset[i].index;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    tsens->clk_div = APB_SARADC.apb_tsens_ctrl.tsens_clk_div;
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t temp_sensor_start(void)
 | 
			
		||||
{
 | 
			
		||||
    REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_TSENS_CLK_EN);
 | 
			
		||||
    APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = 1;
 | 
			
		||||
    APB_SARADC.apb_tsens_ctrl.tsens_pu = 1;
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t temp_sensor_stop(void)
 | 
			
		||||
{
 | 
			
		||||
    APB_SARADC.apb_tsens_ctrl.tsens_pu = 0;
 | 
			
		||||
    APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = 0;
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
 | 
			
		||||
{
 | 
			
		||||
    TSENS_CHECK(tsens_out != NULL, ESP_ERR_INVALID_ARG);
 | 
			
		||||
    *tsens_out = APB_SARADC.apb_tsens_ctrl.tsens_out;
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t temp_sensor_read_celsius(float *celsius)
 | 
			
		||||
{
 | 
			
		||||
    TSENS_CHECK(celsius != NULL, ESP_ERR_INVALID_ARG);
 | 
			
		||||
    temp_sensor_config_t tsens;
 | 
			
		||||
    uint32_t tsens_out = 0;
 | 
			
		||||
    esp_err_t ret = temp_sensor_get_config(&tsens);
 | 
			
		||||
    if (ret == ESP_OK) {
 | 
			
		||||
        ret = temp_sensor_read_raw(&tsens_out);
 | 
			
		||||
        printf("tsens_out %d\r\n", tsens_out);
 | 
			
		||||
        TSENS_CHECK(ret == ESP_OK, ret);
 | 
			
		||||
        const tsens_dac_offset_t *dac = &dac_offset[tsens.dac_offset];
 | 
			
		||||
        *celsius = (TSENS_ADC_FACTOR * (float)tsens_out - TSENS_DAC_FACTOR * dac->offset - TSENS_SYS_OFFSET);
 | 
			
		||||
        if (*celsius < dac->range_min || *celsius > dac->range_max) {
 | 
			
		||||
            ESP_LOGW(TAG, "Exceeding the temperature range!");
 | 
			
		||||
            ret = ESP_ERR_INVALID_STATE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
@@ -18,6 +18,7 @@ Don't put any other code into this file. */
 | 
			
		||||
 | 
			
		||||
#include "adc2_wifi_private.h"
 | 
			
		||||
#include "hal/adc_hal.h"
 | 
			
		||||
#include "esp_private/adc_cali.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Set initial code to ADC2 after calibration. ADC2 RTC and ADC2 PWDET controller share the initial code.
 | 
			
		||||
@@ -28,7 +29,6 @@ static __attribute__((constructor)) void adc2_init_code_calibration(void)
 | 
			
		||||
    const adc_ll_num_t adc_n = ADC_NUM_2;
 | 
			
		||||
    const adc_atten_t atten = ADC_ATTEN_DB_11;
 | 
			
		||||
    const adc_channel_t channel = 0;
 | 
			
		||||
    extern esp_err_t adc_cal_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten);
 | 
			
		||||
    adc_cal_offset(adc_n, channel, atten);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include "esp_err.h"
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "driver/gpio.h"
 | 
			
		||||
#include "hal/adc_types.h"
 | 
			
		||||
 | 
			
		||||
@@ -97,6 +98,13 @@ typedef enum {
 | 
			
		||||
#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5
 | 
			
		||||
#define ADC_ATTEN_6db   ADC_ATTEN_DB_6
 | 
			
		||||
#define ADC_ATTEN_11db  ADC_ATTEN_DB_11
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The default (max) bit width of the ADC of current version. You can also get the maximum bitwidth
 | 
			
		||||
 * by `SOC_ADC_MAX_BITWIDTH` defined in soc_caps.h.
 | 
			
		||||
 */
 | 
			
		||||
#define ADC_WIDTH_BIT_DEFAULT   (ADC_WIDTH_MAX-1)
 | 
			
		||||
 | 
			
		||||
//this definitions are only for being back-compatible
 | 
			
		||||
#define ADC_WIDTH_9Bit  ADC_WIDTH_BIT_9
 | 
			
		||||
#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10
 | 
			
		||||
@@ -469,6 +477,7 @@ esp_err_t adc_digi_deinit(void);
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 *      - ESP_ERR_INVALID_STATE Driver state is invalid.
 | 
			
		||||
 *      - ESP_ERR_INVALID_ARG   If the combination of arguments is invalid.
 | 
			
		||||
 *      - ESP_OK                On success
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								components/driver/include/esp_private/adc_cali.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								components/driver/include/esp_private/adc_cali.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Internal header for calibration, don't use in app
 | 
			
		||||
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "esp_err.h"
 | 
			
		||||
#include "hal/adc_hal.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !CONFIG_IDF_TARGET_ESP32
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Calibrate the offset of ADC. (Based on the pre-stored efuse or actual calibration)
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit to calibrate
 | 
			
		||||
 * @param channel Target channel if really do calibration
 | 
			
		||||
 * @param atten Attenuation to use
 | 
			
		||||
 * @return Always ESP_OK
 | 
			
		||||
 */
 | 
			
		||||
extern esp_err_t adc_cal_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -18,7 +18,6 @@
 | 
			
		||||
#include "esp_types.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
#include "soc/rtc_periph.h"
 | 
			
		||||
#include "soc/sens_periph.h"
 | 
			
		||||
#include "soc/syscon_periph.h"
 | 
			
		||||
#include "soc/rtc.h"
 | 
			
		||||
#include "soc/periph_defs.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										272
									
								
								components/driver/test/test_adc_dma.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								components/driver/test/test_adc_dma.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,272 @@
 | 
			
		||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "test_utils.h"
 | 
			
		||||
 | 
			
		||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3)
 | 
			
		||||
//API only supported for C3 now.
 | 
			
		||||
 | 
			
		||||
#include "driver/adc.h"
 | 
			
		||||
#include "esp_adc_cal.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
 | 
			
		||||
#define TEST_COUNT      4096
 | 
			
		||||
#define MAX_ARRAY_SIZE  4096
 | 
			
		||||
#define TEST_ATTEN      ADC_ATTEN_MAX //Set to ADC_ATTEN_*db to test a single attenuation       only
 | 
			
		||||
 | 
			
		||||
static int s_adc_count[MAX_ARRAY_SIZE]={};
 | 
			
		||||
static int s_adc_offset = -1;
 | 
			
		||||
 | 
			
		||||
static int insert_point(uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    const bool fixed_size = true;
 | 
			
		||||
 | 
			
		||||
    if (s_adc_offset < 0) {
 | 
			
		||||
        if (fixed_size) {
 | 
			
		||||
            TEST_ASSERT_GREATER_OR_EQUAL(4096, MAX_ARRAY_SIZE);
 | 
			
		||||
            s_adc_offset = 0;   //Fixed to 0 because the array can hold all the data in 12 bits
 | 
			
		||||
        } else {
 | 
			
		||||
            s_adc_offset = MAX((int)value - MAX_ARRAY_SIZE/2, 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!fixed_size && (value < s_adc_offset || value >= s_adc_offset + MAX_ARRAY_SIZE)) {
 | 
			
		||||
        TEST_ASSERT_GREATER_OR_EQUAL(s_adc_offset, value);
 | 
			
		||||
        TEST_ASSERT_LESS_THAN(s_adc_offset + MAX_ARRAY_SIZE, value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s_adc_count[value - s_adc_offset] ++;
 | 
			
		||||
    return value - s_adc_offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void reset_array(void)
 | 
			
		||||
{
 | 
			
		||||
    memset(s_adc_count, 0, sizeof(s_adc_count));
 | 
			
		||||
    s_adc_offset = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t get_average(void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t sum = 0;
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    for (int i = 0; i < MAX_ARRAY_SIZE; i++) {
 | 
			
		||||
        sum += s_adc_count[i] * (s_adc_offset+i);
 | 
			
		||||
        count += s_adc_count[i];
 | 
			
		||||
    }
 | 
			
		||||
    return sum/count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void print_summary(bool figure)
 | 
			
		||||
{
 | 
			
		||||
    const int MAX_WIDTH=20;
 | 
			
		||||
    int max_count = 0;
 | 
			
		||||
    int start = -1;
 | 
			
		||||
    int end = -1;
 | 
			
		||||
    uint32_t sum = 0;
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    for (int i = 0; i < MAX_ARRAY_SIZE; i++) {
 | 
			
		||||
        if (s_adc_count[i] > max_count) {
 | 
			
		||||
            max_count = s_adc_count[i];
 | 
			
		||||
        }
 | 
			
		||||
        if (s_adc_count[i] > 0 && start < 0) {
 | 
			
		||||
            start = i;
 | 
			
		||||
        }
 | 
			
		||||
        if (s_adc_count[i] > 0) {
 | 
			
		||||
            end = i;
 | 
			
		||||
        }
 | 
			
		||||
        count += s_adc_count[i];
 | 
			
		||||
        sum += s_adc_count[i] * (s_adc_offset+i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (figure) {
 | 
			
		||||
        for (int i = start; i <= end; i++) {
 | 
			
		||||
            printf("%4d ", i+s_adc_offset);
 | 
			
		||||
            int count = s_adc_count[i] * MAX_WIDTH / max_count;
 | 
			
		||||
            for (int j = 0; j < count; j++) {
 | 
			
		||||
                putchar('|');
 | 
			
		||||
            }
 | 
			
		||||
            printf("    %d\n", s_adc_count[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    float average = (float)sum/count;
 | 
			
		||||
 | 
			
		||||
    float variation_square = 0;
 | 
			
		||||
    for (int i = start; i <= end; i ++) {
 | 
			
		||||
        if (s_adc_count[i] == 0) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        float delta = i + s_adc_offset - average;
 | 
			
		||||
        variation_square += (delta * delta) * s_adc_count[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("%d points.\n", count);
 | 
			
		||||
    printf("average: %.1f\n", (float)sum/count);
 | 
			
		||||
    printf("std: %.2f\n", sqrt(variation_square/count));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num, adc_atten_t atten)
 | 
			
		||||
{
 | 
			
		||||
    adc_digi_init_config_t adc_dma_config = {
 | 
			
		||||
        .max_store_buf_size = TEST_COUNT*2,
 | 
			
		||||
        .conv_num_each_intr = 128,
 | 
			
		||||
        .dma_chan = SOC_GDMA_ADC_DMA_CHANNEL,
 | 
			
		||||
        .adc1_chan_mask = adc1_chan_mask,
 | 
			
		||||
        .adc2_chan_mask = adc2_chan_mask,
 | 
			
		||||
    };
 | 
			
		||||
    TEST_ESP_OK(adc_digi_initialize(&adc_dma_config));
 | 
			
		||||
 | 
			
		||||
    adc_digi_pattern_table_t adc_pattern[10] = {0};
 | 
			
		||||
    adc_digi_config_t dig_cfg = {
 | 
			
		||||
        .conv_limit_en = 0,
 | 
			
		||||
        .conv_limit_num = 250,
 | 
			
		||||
        .sample_freq_hz = 83333,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    dig_cfg.adc_pattern_len = channel_num;
 | 
			
		||||
    for (int i = 0; i < channel_num; i++) {
 | 
			
		||||
        uint8_t unit = ((channel[i] >> 3) & 0x1);
 | 
			
		||||
        uint8_t ch = channel[i] & 0x7;
 | 
			
		||||
        adc_pattern[i].atten = atten;
 | 
			
		||||
        adc_pattern[i].channel = ch;
 | 
			
		||||
        adc_pattern[i].unit = unit;
 | 
			
		||||
    }
 | 
			
		||||
    dig_cfg.adc_pattern = adc_pattern;
 | 
			
		||||
    TEST_ESP_OK(adc_digi_controller_config(&dig_cfg));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE("test_adc_dma", "[adc][ignore][manual]")
 | 
			
		||||
{
 | 
			
		||||
    uint16_t adc1_chan_mask = BIT(2);
 | 
			
		||||
    uint16_t adc2_chan_mask = 0;
 | 
			
		||||
    adc_channel_t channel[1] = {ADC1_CHANNEL_2};
 | 
			
		||||
    adc_atten_t target_atten = TEST_ATTEN;
 | 
			
		||||
 | 
			
		||||
    const int output_data_size = sizeof(adc_digi_output_data_t);
 | 
			
		||||
 | 
			
		||||
    int buffer_size = TEST_COUNT*output_data_size;
 | 
			
		||||
    uint8_t* read_buf = malloc(buffer_size);
 | 
			
		||||
    TEST_ASSERT_NOT_NULL(read_buf);
 | 
			
		||||
 | 
			
		||||
    adc_atten_t atten;
 | 
			
		||||
    bool print_figure;
 | 
			
		||||
    if (target_atten == ADC_ATTEN_MAX) {
 | 
			
		||||
        atten = ADC_ATTEN_DB_0;
 | 
			
		||||
        target_atten = ADC_ATTEN_DB_11;
 | 
			
		||||
        print_figure = false;
 | 
			
		||||
    } else {
 | 
			
		||||
        atten = target_atten;
 | 
			
		||||
        print_figure = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (1) {
 | 
			
		||||
        ESP_LOGI("TEST_ADC", "Test with atten: %d", atten);
 | 
			
		||||
        memset(read_buf, 0xce, buffer_size);
 | 
			
		||||
 | 
			
		||||
        esp_adc_cal_characteristics_t chan1_char = {};
 | 
			
		||||
        esp_adc_cal_value_t cal_ret = esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_12Bit, 0, &chan1_char);
 | 
			
		||||
        TEST_ASSERT(cal_ret == ESP_ADC_CAL_VAL_EFUSE_TP);
 | 
			
		||||
 | 
			
		||||
        continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t), atten);
 | 
			
		||||
        adc_digi_start();
 | 
			
		||||
 | 
			
		||||
        int remain_count = TEST_COUNT;
 | 
			
		||||
        while (remain_count) {
 | 
			
		||||
            int already_got = TEST_COUNT - remain_count;
 | 
			
		||||
            uint32_t ret_num;
 | 
			
		||||
            TEST_ESP_OK(adc_digi_read_bytes(read_buf + already_got*output_data_size,
 | 
			
		||||
                                    remain_count*output_data_size, &ret_num, ADC_MAX_DELAY));
 | 
			
		||||
 | 
			
		||||
            TEST_ASSERT((ret_num % output_data_size) == 0);
 | 
			
		||||
            remain_count -= ret_num / output_data_size;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        adc_digi_output_data_t *p = (void*)read_buf;
 | 
			
		||||
        reset_array();
 | 
			
		||||
        for (int i = 0; i < TEST_COUNT; i++) {
 | 
			
		||||
            insert_point(p[i].type2.data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        print_summary(print_figure);
 | 
			
		||||
 | 
			
		||||
        uint32_t raw = get_average();
 | 
			
		||||
        uint32_t voltage_mv = esp_adc_cal_raw_to_voltage(raw, &chan1_char);
 | 
			
		||||
        printf("Voltage = %d mV\n", voltage_mv);
 | 
			
		||||
 | 
			
		||||
        adc_digi_stop();
 | 
			
		||||
        TEST_ESP_OK(adc_digi_deinitialize());
 | 
			
		||||
 | 
			
		||||
        if (atten == target_atten) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        atten++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(read_buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE("test_adc_single", "[adc][ignore][manual]")
 | 
			
		||||
{
 | 
			
		||||
    adc_atten_t target_atten = TEST_ATTEN;
 | 
			
		||||
    adc_atten_t atten;
 | 
			
		||||
    bool print_figure;
 | 
			
		||||
    if (target_atten == ADC_ATTEN_MAX) {
 | 
			
		||||
        atten = ADC_ATTEN_DB_0;
 | 
			
		||||
        target_atten = ADC_ATTEN_DB_11;
 | 
			
		||||
        print_figure = false;
 | 
			
		||||
    } else {
 | 
			
		||||
        atten = target_atten;
 | 
			
		||||
        print_figure = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    adc1_config_width(ADC_WIDTH_BIT_12);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    while (1) {
 | 
			
		||||
        ESP_LOGI("TEST_ADC", "Test with atten: %d", atten);
 | 
			
		||||
 | 
			
		||||
        adc1_config_channel_atten(ADC1_CHANNEL_2, atten);
 | 
			
		||||
 | 
			
		||||
        esp_adc_cal_characteristics_t chan1_char = {};
 | 
			
		||||
        esp_adc_cal_value_t cal_ret = esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_12Bit, 0, &chan1_char);
 | 
			
		||||
        TEST_ASSERT(cal_ret == ESP_ADC_CAL_VAL_EFUSE_TP);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        const int test_count = TEST_COUNT;
 | 
			
		||||
        adc1_channel_t channel = ADC1_CHANNEL_2;
 | 
			
		||||
        while (1) {
 | 
			
		||||
 | 
			
		||||
            reset_array();
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < test_count; i++) {
 | 
			
		||||
                uint32_t raw = adc1_get_raw(channel);
 | 
			
		||||
                insert_point(raw);
 | 
			
		||||
            }
 | 
			
		||||
            print_summary(print_figure);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        uint32_t raw = get_average();
 | 
			
		||||
        uint32_t voltage_mv = esp_adc_cal_raw_to_voltage(raw, &chan1_char);
 | 
			
		||||
        printf("Voltage = %d mV\n", voltage_mv);
 | 
			
		||||
 | 
			
		||||
        if (atten == target_atten) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        atten++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -11,6 +11,9 @@ if(EXISTS "${COMPONENT_DIR}/${target}")
 | 
			
		||||
    if("esp32s2" STREQUAL "${target}")
 | 
			
		||||
        list(APPEND srcs "src/${target}/esp_efuse_rtc_table.c")
 | 
			
		||||
    endif()
 | 
			
		||||
    if("esp32c3" STREQUAL "${target}")
 | 
			
		||||
        list(APPEND srcs "src/${target}/esp_efuse_rtc_calib.c")
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
list(APPEND srcs "src/esp_efuse_api.c"
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include "esp_efuse_table.h"
 | 
			
		||||
 | 
			
		||||
// md5_digest_table 2c7ba2aa68a2748d3de9a5d1fed59b9f
 | 
			
		||||
// md5_digest_table 96cd6235ddc0947b4a296add3f942acb
 | 
			
		||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
 | 
			
		||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
 | 
			
		||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
 | 
			
		||||
@@ -392,8 +392,48 @@ static const esp_efuse_desc_t SPI_PAD_CONFIG_D7[] = {
 | 
			
		||||
    {EFUSE_BLK1, 108, 6}, 	 // SPI_PAD_configure D7,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t SYS_DATA_PART1[] = {
 | 
			
		||||
    {EFUSE_BLK2, 0, 256}, 	 // System configuration,
 | 
			
		||||
static const esp_efuse_desc_t BLOCK2_VERSION[] = {
 | 
			
		||||
    {EFUSE_BLK2, 128, 3}, 	 // Version of Block2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t TEMP_CALIB[] = {
 | 
			
		||||
    {EFUSE_BLK2, 131, 9}, 	 // Temperature calibration data,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t OCODE[] = {
 | 
			
		||||
    {EFUSE_BLK2, 140, 8}, 	 // ADC OCode,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0[] = {
 | 
			
		||||
    {EFUSE_BLK2, 148, 10}, 	 // ADC1 init code at atten0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN1[] = {
 | 
			
		||||
    {EFUSE_BLK2, 158, 10}, 	 // ADC1 init code at atten1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN2[] = {
 | 
			
		||||
    {EFUSE_BLK2, 168, 10}, 	 // ADC1 init code at atten2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN3[] = {
 | 
			
		||||
    {EFUSE_BLK2, 178, 10}, 	 // ADC1 init code at atten3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN0[] = {
 | 
			
		||||
    {EFUSE_BLK2, 188, 10}, 	 // ADC1 calibration voltage at atten0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN1[] = {
 | 
			
		||||
    {EFUSE_BLK2, 198, 10}, 	 // ADC1 calibration voltage at atten1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN2[] = {
 | 
			
		||||
    {EFUSE_BLK2, 208, 10}, 	 // ADC1 calibration voltage at atten2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN3[] = {
 | 
			
		||||
    {EFUSE_BLK2, 218, 10}, 	 // ADC1 calibration voltage at atten3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const esp_efuse_desc_t USER_DATA[] = {
 | 
			
		||||
@@ -892,8 +932,58 @@ const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[] = {
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART1[] = {
 | 
			
		||||
    &SYS_DATA_PART1[0],    		// System configuration
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[] = {
 | 
			
		||||
    &BLOCK2_VERSION[0],    		// Version of Block2
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[] = {
 | 
			
		||||
    &TEMP_CALIB[0],    		// Temperature calibration data
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_OCODE[] = {
 | 
			
		||||
    &OCODE[0],    		// ADC OCode
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[] = {
 | 
			
		||||
    &ADC1_INIT_CODE_ATTEN0[0],    		// ADC1 init code at atten0
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN1[] = {
 | 
			
		||||
    &ADC1_INIT_CODE_ATTEN1[0],    		// ADC1 init code at atten1
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[] = {
 | 
			
		||||
    &ADC1_INIT_CODE_ATTEN2[0],    		// ADC1 init code at atten2
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[] = {
 | 
			
		||||
    &ADC1_INIT_CODE_ATTEN3[0],    		// ADC1 init code at atten3
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[] = {
 | 
			
		||||
    &ADC1_CAL_VOL_ATTEN0[0],    		// ADC1 calibration voltage at atten0
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN1[] = {
 | 
			
		||||
    &ADC1_CAL_VOL_ATTEN1[0],    		// ADC1 calibration voltage at atten1
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[] = {
 | 
			
		||||
    &ADC1_CAL_VOL_ATTEN2[0],    		// ADC1 calibration voltage at atten2
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[] = {
 | 
			
		||||
    &ADC1_CAL_VOL_ATTEN3[0],    		// ADC1 calibration voltage at atten3
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -126,8 +126,21 @@
 | 
			
		||||
    SPI_PAD_CONFIG_D6,                    EFUSE_BLK1,  102,    6,     SPI_PAD_configure D6
 | 
			
		||||
    SPI_PAD_CONFIG_D7,                    EFUSE_BLK1,  108,    6,     SPI_PAD_configure D7
 | 
			
		||||
 | 
			
		||||
# SYS_DATA_PART1 #
 | 
			
		||||
#######################
 | 
			
		||||
    BLOCK2_VERSION,                       EFUSE_BLK2,  128,    3,     Version of Block2
 | 
			
		||||
    TEMP_CALIB,                           EFUSE_BLK2,  131,    9,     Temperature calibration data
 | 
			
		||||
    OCODE,                                EFUSE_BLK2,  140,    8,     ADC OCode
 | 
			
		||||
    ADC1_INIT_CODE_ATTEN0,                EFUSE_BLK2,  148,   10,     ADC1 init code at atten0
 | 
			
		||||
    ADC1_INIT_CODE_ATTEN1,                EFUSE_BLK2,  158,   10,     ADC1 init code at atten1
 | 
			
		||||
    ADC1_INIT_CODE_ATTEN2,                EFUSE_BLK2,  168,   10,     ADC1 init code at atten2
 | 
			
		||||
    ADC1_INIT_CODE_ATTEN3,                EFUSE_BLK2,  178,   10,     ADC1 init code at atten3
 | 
			
		||||
    ADC1_CAL_VOL_ATTEN0,                  EFUSE_BLK2,  188,   10,     ADC1 calibration voltage at atten0
 | 
			
		||||
    ADC1_CAL_VOL_ATTEN1,                  EFUSE_BLK2,  198,   10,     ADC1 calibration voltage at atten1
 | 
			
		||||
    ADC1_CAL_VOL_ATTEN2,                  EFUSE_BLK2,  208,   10,     ADC1 calibration voltage at atten2
 | 
			
		||||
    ADC1_CAL_VOL_ATTEN3,                  EFUSE_BLK2,  218,   10,     ADC1 calibration voltage at atten3
 | 
			
		||||
 | 
			
		||||
################
 | 
			
		||||
SYS_DATA_PART1,                           EFUSE_BLK2,    0,  256,     System configuration
 | 
			
		||||
USER_DATA,                                EFUSE_BLK3,    0,  256,     User data
 | 
			
		||||
KEY0,                                     EFUSE_BLK4,    0,  256,     Key0 or user data
 | 
			
		||||
KEY1,                                     EFUSE_BLK5,    0,  256,     Key1 or user data
 | 
			
		||||
 
 | 
			
		||||
| 
		
		
			 Can't render this file because it contains an unexpected character in line 7 and column 87. 
		
	 | 
@@ -17,7 +17,7 @@ extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// md5_digest_table 2c7ba2aa68a2748d3de9a5d1fed59b9f
 | 
			
		||||
// md5_digest_table 96cd6235ddc0947b4a296add3f942acb
 | 
			
		||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
 | 
			
		||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
 | 
			
		||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
 | 
			
		||||
@@ -115,7 +115,17 @@ extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D4[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D5[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D6[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART1[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_OCODE[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN1[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN1[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
 | 
			
		||||
extern const esp_efuse_desc_t* ESP_EFUSE_KEY1[];
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								components/efuse/include/esp32c3/esp_efuse_rtc_calib.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								components/efuse/include/esp32c3/esp_efuse_rtc_calib.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at",
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License
 | 
			
		||||
 | 
			
		||||
#include <esp_types.h>
 | 
			
		||||
#include <esp_err.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the RTC calibration efuse version
 | 
			
		||||
 *
 | 
			
		||||
 * @return Version of the stored efuse
 | 
			
		||||
 */
 | 
			
		||||
int esp_efuse_rtc_calib_get_ver(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the init code in the efuse, for the corresponding attenuation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param version Version of the stored efuse
 | 
			
		||||
 * @param atten  Attenuation of the init code
 | 
			
		||||
 * @return The init code stored in efuse
 | 
			
		||||
 */
 | 
			
		||||
uint16_t esp_efuse_rtc_calib_get_init_code(int version, int atten);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the calibration digits stored in the efuse, and the corresponding voltage.
 | 
			
		||||
 *
 | 
			
		||||
 * @param version Version of the stored efuse
 | 
			
		||||
 * @param atten         Attenuation to use
 | 
			
		||||
 * @param out_digi      Output buffer of the digits
 | 
			
		||||
 * @param out_vol_mv    Output of the voltage, in mV
 | 
			
		||||
 * @return
 | 
			
		||||
 *      - ESP_ERR_INVALID_ARG: If efuse version or attenuation is invalid
 | 
			
		||||
 *      - ESP_OK: if success
 | 
			
		||||
 */
 | 
			
		||||
esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t* out_digi, uint32_t* out_vol_mv);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										84
									
								
								components/efuse/src/esp32c3/esp_efuse_rtc_calib.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								components/efuse/src/esp32c3/esp_efuse_rtc_calib.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include <esp_bit_defs.h>
 | 
			
		||||
#include "esp_efuse.h"
 | 
			
		||||
#include "esp_efuse_table.h"
 | 
			
		||||
 | 
			
		||||
int esp_efuse_rtc_calib_get_ver(void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t result = 0;
 | 
			
		||||
    esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &result, 3);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t esp_efuse_rtc_calib_get_init_code(int version, int atten)
 | 
			
		||||
{
 | 
			
		||||
    assert(version == 1);
 | 
			
		||||
    const esp_efuse_desc_t** init_code_efuse;
 | 
			
		||||
    assert(atten < 4);
 | 
			
		||||
    if (atten == 0) {
 | 
			
		||||
        init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0;
 | 
			
		||||
    } else if (atten == 1) {
 | 
			
		||||
        init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN1;
 | 
			
		||||
    } else if (atten == 2) {
 | 
			
		||||
        init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN2;
 | 
			
		||||
    } else {
 | 
			
		||||
        init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int init_code_size = esp_efuse_get_field_size(init_code_efuse);
 | 
			
		||||
    assert(init_code_size == 10);
 | 
			
		||||
 | 
			
		||||
    uint32_t init_code = 0;
 | 
			
		||||
    esp_err_t err = esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size);
 | 
			
		||||
    assert(err == ESP_OK);
 | 
			
		||||
    return init_code + 1000;    // version 1 logic
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t* out_digi, uint32_t* out_vol_mv)
 | 
			
		||||
{
 | 
			
		||||
    const esp_efuse_desc_t** cal_vol_efuse;
 | 
			
		||||
    uint32_t calib_vol_expected_mv;
 | 
			
		||||
    if (version != 1) {
 | 
			
		||||
        return ESP_ERR_INVALID_ARG;
 | 
			
		||||
    }
 | 
			
		||||
    if (atten >= 4) {
 | 
			
		||||
        return ESP_ERR_INVALID_ARG;
 | 
			
		||||
    }
 | 
			
		||||
    if (atten == 0) {
 | 
			
		||||
        cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN0;
 | 
			
		||||
        calib_vol_expected_mv = 400;
 | 
			
		||||
    } else if (atten == 1) {
 | 
			
		||||
        cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN1;
 | 
			
		||||
        calib_vol_expected_mv = 550;
 | 
			
		||||
    } else if (atten == 2) {
 | 
			
		||||
        cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN2;
 | 
			
		||||
        calib_vol_expected_mv = 750;
 | 
			
		||||
    } else {
 | 
			
		||||
        cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN3;
 | 
			
		||||
        calib_vol_expected_mv = 1370;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int cal_vol_size = esp_efuse_get_field_size(cal_vol_efuse);
 | 
			
		||||
    assert(cal_vol_size == 10);
 | 
			
		||||
 | 
			
		||||
    uint32_t cal_vol = 0;
 | 
			
		||||
    esp_err_t err = esp_efuse_read_field_blob(cal_vol_efuse, &cal_vol, cal_vol_size) & 0x3FF;
 | 
			
		||||
    assert(err == ESP_OK);
 | 
			
		||||
 | 
			
		||||
    *out_digi = 2000 + ((cal_vol & BIT(9))? -(cal_vol & ~BIT9): cal_vol);
 | 
			
		||||
    *out_vol_mv = calib_vol_expected_mv;
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -68,7 +68,7 @@ esp_err_t esp_efuse_utility_process(const esp_efuse_desc_t* field[], void* ptr,
 | 
			
		||||
            if ((bits_counter + num_bits) > req_size) { // Limits the length of the field.
 | 
			
		||||
                num_bits = req_size - bits_counter;
 | 
			
		||||
            }
 | 
			
		||||
            ESP_EARLY_LOGD(TAG, "In EFUSE_BLK%d__DATA%d_REG is used %d bits starting with %d bit",
 | 
			
		||||
            ESP_LOGD(TAG, "In EFUSE_BLK%d__DATA%d_REG is used %d bits starting with %d bit",
 | 
			
		||||
                    (int)field[i]->efuse_block, num_reg, num_bits, start_bit);
 | 
			
		||||
            err = func_proc(num_reg, field[i]->efuse_block, start_bit, num_bits, ptr, &bits_counter);
 | 
			
		||||
            ++i_reg;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ PROVIDE ( GPIO = 0x60004000 );
 | 
			
		||||
PROVIDE ( SIGMADELTA = 0x60004f00 );
 | 
			
		||||
PROVIDE ( RTCCNTL = 0x60008000 );
 | 
			
		||||
PROVIDE ( RTCIO = 0x60008400 );
 | 
			
		||||
PROVIDE ( SENS = 0x60008800 );
 | 
			
		||||
PROVIDE ( HINF = 0x6000B000 );
 | 
			
		||||
PROVIDE ( I2S1  = 0x6002d000 );
 | 
			
		||||
PROVIDE ( I2C0  = 0x60013000 );
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,10 @@ void IRAM_ATTR esp_restart_noos(void)
 | 
			
		||||
    SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
 | 
			
		||||
                      SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
 | 
			
		||||
    REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
 | 
			
		||||
    // Reset dma
 | 
			
		||||
    SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
 | 
			
		||||
    REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0);
 | 
			
		||||
 | 
			
		||||
    // Set CPU back to XTAL source, no PLL, same as hard reset
 | 
			
		||||
#if !CONFIG_IDF_ENV_FPGA
 | 
			
		||||
    rtc_clk_cpu_freq_set_xtal();
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,13 @@ void IRAM_ATTR esp_restart_noos(void)
 | 
			
		||||
                      SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
 | 
			
		||||
    REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
 | 
			
		||||
 | 
			
		||||
    // Reset dma
 | 
			
		||||
    SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
 | 
			
		||||
    REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0);
 | 
			
		||||
 | 
			
		||||
    SET_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET);
 | 
			
		||||
    CLEAR_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET);
 | 
			
		||||
 | 
			
		||||
    // Set CPU back to XTAL source, no PLL, same as hard reset
 | 
			
		||||
#if !CONFIG_IDF_ENV_FPGA
 | 
			
		||||
    rtc_clk_cpu_freq_set_xtal();
 | 
			
		||||
 
 | 
			
		||||
@@ -10,4 +10,8 @@ elseif(${target} STREQUAL "esp32s2")
 | 
			
		||||
                    INCLUDE_DIRS "include"
 | 
			
		||||
                    REQUIRES driver efuse)
 | 
			
		||||
 | 
			
		||||
elseif(${target} STREQUAL "esp32c3")
 | 
			
		||||
    idf_component_register(SRCS "esp_adc_cal_esp32c3.c"
 | 
			
		||||
                    INCLUDE_DIRS "include"
 | 
			
		||||
                    REQUIRES driver efuse)
 | 
			
		||||
endif()
 | 
			
		||||
 
 | 
			
		||||
@@ -3,4 +3,4 @@
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
COMPONENT_ADD_INCLUDEDIRS := include
 | 
			
		||||
COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o
 | 
			
		||||
COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o esp_adc_cal_esp32c3.o
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										170
									
								
								components/esp_adc_cal/esp_adc_cal_esp32c3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								components/esp_adc_cal/esp_adc_cal_esp32c3.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "esp_types.h"
 | 
			
		||||
#include "esp_err.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
#include "driver/adc.h"
 | 
			
		||||
#include "hal/adc_ll.h"
 | 
			
		||||
#include "esp32c3/esp_efuse_rtc_calib.h"
 | 
			
		||||
#include "esp_adc_cal.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ADC_CALIB_CHECK(cond, err_msg, ret) do {\
 | 
			
		||||
             if (!(cond)) { \
 | 
			
		||||
                ESP_LOGE(LOG_TAG, err_msg); \
 | 
			
		||||
                return (ret); \
 | 
			
		||||
            } \
 | 
			
		||||
        } while(0)
 | 
			
		||||
 | 
			
		||||
const static char LOG_TAG[] = "adc_calib";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ------------------------ Characterization Constants ---------------------- */
 | 
			
		||||
 | 
			
		||||
// coeff_a and coeff_b are actually floats
 | 
			
		||||
// they are scaled to put them into uint32_t so that the headers do not have to be changed
 | 
			
		||||
static const int coeff_a_scaling = 65536;
 | 
			
		||||
static const int coeff_b_scaling = 1024;
 | 
			
		||||
/* -------------------- Characterization Helper Data Types ------------------ */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint32_t voltage;
 | 
			
		||||
    uint32_t digi;
 | 
			
		||||
} adc_calib_data_ver1;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    char version_num;
 | 
			
		||||
    adc_unit_t adc_num;
 | 
			
		||||
    adc_atten_t atten_level;
 | 
			
		||||
    union {
 | 
			
		||||
        adc_calib_data_ver1 ver1;
 | 
			
		||||
    } efuse_data;
 | 
			
		||||
} adc_calib_parsed_info;
 | 
			
		||||
 | 
			
		||||
static esp_err_t prepare_calib_data_for(int version_num, adc_unit_t adc_num, adc_atten_t atten, adc_calib_parsed_info *parsed_data_storage)
 | 
			
		||||
{
 | 
			
		||||
    assert(version_num == 1);
 | 
			
		||||
    esp_err_t ret;
 | 
			
		||||
 | 
			
		||||
    parsed_data_storage->version_num = version_num;
 | 
			
		||||
    parsed_data_storage->adc_num = adc_num;
 | 
			
		||||
    parsed_data_storage->atten_level = atten;
 | 
			
		||||
    // V1 we don't have calibration data for ADC2, using the efuse data of ADC1
 | 
			
		||||
    uint32_t voltage, digi;
 | 
			
		||||
    ret = esp_efuse_rtc_calib_get_cal_voltage(version_num, atten, &digi, &voltage);
 | 
			
		||||
    if (ret != ESP_OK) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    parsed_data_storage->efuse_data.ver1.voltage = voltage;
 | 
			
		||||
    parsed_data_storage->efuse_data.ver1.digi = digi;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------- Characterization Functions ----------------------- */
 | 
			
		||||
/*
 | 
			
		||||
 * Estimate the (assumed) linear relationship btwn the measured raw value and the voltage
 | 
			
		||||
 * with the previously done measurement when the chip was manufactured.
 | 
			
		||||
 */
 | 
			
		||||
static void calculate_characterization_coefficients(const adc_calib_parsed_info *parsed_data, esp_adc_cal_characteristics_t *chars)
 | 
			
		||||
{
 | 
			
		||||
    ESP_LOGD(LOG_TAG, "Calib V1, Cal Voltage = %d, Digi out = %d\n", parsed_data->efuse_data.ver1.voltage, parsed_data->efuse_data.ver1.digi);
 | 
			
		||||
 | 
			
		||||
    chars->coeff_a = coeff_a_scaling * parsed_data->efuse_data.ver1.voltage / parsed_data->efuse_data.ver1.digi;
 | 
			
		||||
    chars->coeff_b = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------- Public API ------------------------------------- */
 | 
			
		||||
esp_err_t esp_adc_cal_check_efuse(esp_adc_cal_value_t source)
 | 
			
		||||
{
 | 
			
		||||
    if (source != ESP_ADC_CAL_VAL_EFUSE_TP) {
 | 
			
		||||
        return ESP_ERR_NOT_SUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
    uint8_t adc_encoding_version = esp_efuse_rtc_calib_get_ver();
 | 
			
		||||
    if (adc_encoding_version != 1) {
 | 
			
		||||
        // current version only accepts encoding ver 1.
 | 
			
		||||
        return ESP_ERR_INVALID_VERSION;
 | 
			
		||||
    }
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num,
 | 
			
		||||
        adc_atten_t atten,
 | 
			
		||||
        adc_bits_width_t bit_width,
 | 
			
		||||
        uint32_t default_vref,
 | 
			
		||||
        esp_adc_cal_characteristics_t *chars)
 | 
			
		||||
{
 | 
			
		||||
    esp_err_t ret;
 | 
			
		||||
    adc_calib_parsed_info efuse_parsed_data = {0};
 | 
			
		||||
    // Check parameters
 | 
			
		||||
    ADC_CALIB_CHECK(adc_num == ADC_UNIT_1 || adc_num == ADC_UNIT_2, "Invalid unit num", ESP_ADC_CAL_VAL_NOT_SUPPORTED);
 | 
			
		||||
    ADC_CALIB_CHECK(chars != NULL, "Invalid characteristic", ESP_ADC_CAL_VAL_NOT_SUPPORTED);
 | 
			
		||||
    ADC_CALIB_CHECK(bit_width == ADC_WIDTH_BIT_12, "Invalid bit_width", ESP_ADC_CAL_VAL_NOT_SUPPORTED);
 | 
			
		||||
    ADC_CALIB_CHECK(atten < 4, "Invalid attenuation", ESP_ADC_CAL_VAL_NOT_SUPPORTED);
 | 
			
		||||
 | 
			
		||||
    int version_num = esp_efuse_rtc_calib_get_ver();
 | 
			
		||||
    ADC_CALIB_CHECK(version_num == 1, "No calibration efuse burnt", ESP_ADC_CAL_VAL_NOT_SUPPORTED);
 | 
			
		||||
 | 
			
		||||
    memset(chars, 0, sizeof(esp_adc_cal_characteristics_t));
 | 
			
		||||
 | 
			
		||||
    // make sure adc is calibrated.
 | 
			
		||||
    ret = prepare_calib_data_for(version_num, adc_num, atten, &efuse_parsed_data);
 | 
			
		||||
    if (ret != ESP_OK) {
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    calculate_characterization_coefficients(&efuse_parsed_data, chars);
 | 
			
		||||
    ESP_LOGD(LOG_TAG, "adc%d (atten leven %d) calibration done: A:%d B:%d\n", adc_num, atten, chars->coeff_a, chars->coeff_b);
 | 
			
		||||
 | 
			
		||||
    // Initialize remaining fields
 | 
			
		||||
    chars->adc_num = adc_num;
 | 
			
		||||
    chars->atten = atten;
 | 
			
		||||
    chars->bit_width = bit_width;
 | 
			
		||||
 | 
			
		||||
    // in esp32c3 we only use the two point method to calibrate the adc.
 | 
			
		||||
    return ESP_ADC_CAL_VAL_EFUSE_TP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_characteristics_t *chars)
 | 
			
		||||
{
 | 
			
		||||
    ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG);
 | 
			
		||||
 | 
			
		||||
    return adc_reading * chars->coeff_a / coeff_a_scaling + chars->coeff_b / coeff_b_scaling;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t esp_adc_cal_get_voltage(adc_channel_t channel,
 | 
			
		||||
                                  const esp_adc_cal_characteristics_t *chars,
 | 
			
		||||
                                  uint32_t *voltage)
 | 
			
		||||
{
 | 
			
		||||
    // Check parameters
 | 
			
		||||
    ADC_CALIB_CHECK(chars != NULL, "No characteristic input.", ESP_ERR_INVALID_ARG);
 | 
			
		||||
    ADC_CALIB_CHECK(voltage != NULL, "No output buffer.", ESP_ERR_INVALID_ARG);
 | 
			
		||||
 | 
			
		||||
    int adc_reading;
 | 
			
		||||
    if (chars->adc_num == ADC_UNIT_1) {
 | 
			
		||||
        //Check if channel is valid on ADC1
 | 
			
		||||
        ADC_CALIB_CHECK((adc1_channel_t)channel < ADC1_CHANNEL_MAX, "Invalid channel", ESP_ERR_INVALID_ARG);
 | 
			
		||||
        adc_reading = adc1_get_raw(channel);
 | 
			
		||||
    } else {
 | 
			
		||||
        //Check if channel is valid on ADC2
 | 
			
		||||
        ADC_CALIB_CHECK((adc2_channel_t)channel < ADC2_CHANNEL_MAX, "Invalid channel", ESP_ERR_INVALID_ARG);
 | 
			
		||||
        if (adc2_get_raw(channel, chars->bit_width, &adc_reading) != ESP_OK) {
 | 
			
		||||
            return ESP_ERR_TIMEOUT;     //Timed out waiting for ADC2
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    *voltage = esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, chars);
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -30,7 +30,8 @@ typedef enum {
 | 
			
		||||
    ESP_ADC_CAL_VAL_EFUSE_VREF = 0,         /**< Characterization based on reference voltage stored in eFuse*/
 | 
			
		||||
    ESP_ADC_CAL_VAL_EFUSE_TP = 1,           /**< Characterization based on Two Point values stored in eFuse*/
 | 
			
		||||
    ESP_ADC_CAL_VAL_DEFAULT_VREF = 2,       /**< Characterization based on default reference voltage*/
 | 
			
		||||
    ESP_ADC_CAL_VAL_MAX
 | 
			
		||||
    ESP_ADC_CAL_VAL_MAX,
 | 
			
		||||
    ESP_ADC_CAL_VAL_NOT_SUPPORTED = ESP_ADC_CAL_VAL_MAX,
 | 
			
		||||
} esp_adc_cal_value_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,18 @@
 | 
			
		||||
#define I2C_ULP_IR_RESETB_MSB 0
 | 
			
		||||
#define I2C_ULP_IR_RESETB_LSB 0
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_CK 0
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_CK_MSB 2
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_CK_LSB 2
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_IPH 0
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_IPH_MSB 4
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_IPH_LSB 4
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK 0
 | 
			
		||||
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_MSB 6
 | 
			
		||||
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_LSB 6
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_O_DONE_FLAG 3
 | 
			
		||||
#define I2C_ULP_O_DONE_FLAG_MSB 0
 | 
			
		||||
#define I2C_ULP_O_DONE_FLAG_LSB 0
 | 
			
		||||
@@ -38,14 +50,10 @@
 | 
			
		||||
#define I2C_ULP_BG_O_DONE_FLAG_MSB 3
 | 
			
		||||
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_IPH 0
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_IPH_MSB 4
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_IPH_LSB 4
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE 5
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE_MSB 6
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE_LSB 6
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_CK 0
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_CK_MSB 2
 | 
			
		||||
#define I2C_ULP_IR_FORCE_XPD_CK_LSB 2
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK 0
 | 
			
		||||
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_MSB 6
 | 
			
		||||
#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_LSB 6
 | 
			
		||||
#define I2C_ULP_EXT_CODE 6
 | 
			
		||||
#define I2C_ULP_EXT_CODE_MSB 7
 | 
			
		||||
#define I2C_ULP_EXT_CODE_LSB 0
 | 
			
		||||
 
 | 
			
		||||
@@ -43,10 +43,16 @@ extern "C" {
 | 
			
		||||
#define ANA_CONFIG_REG  0x6000E044
 | 
			
		||||
#define ANA_CONFIG_S    (8)
 | 
			
		||||
#define ANA_CONFIG_M    (0x3FF)
 | 
			
		||||
/* Clear to enable APLL */
 | 
			
		||||
#define I2C_APLL_M      (BIT(14))
 | 
			
		||||
/* Clear to enable BBPLL */
 | 
			
		||||
#define I2C_BBPLL_M     (BIT(17))
 | 
			
		||||
 | 
			
		||||
#define ANA_I2C_SAR_FORCE_PD BIT(18)
 | 
			
		||||
#define ANA_I2C_BBPLL_M      BIT(17) /* Clear to enable BBPLL */
 | 
			
		||||
#define ANA_I2C_APLL_M       BIT(14) /* Clear to enable APLL */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ANA_CONFIG2_REG  0x6000E048
 | 
			
		||||
#define ANA_CONFIG2_M    BIT(18)
 | 
			
		||||
 | 
			
		||||
#define ANA_I2C_SAR_FORCE_PU BIT(16)
 | 
			
		||||
 | 
			
		||||
/* ROM functions which read/write internal control bus */
 | 
			
		||||
uint8_t rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@
 | 
			
		||||
#include "esp32c3/rom/gpio.h"
 | 
			
		||||
#include "soc/rtc.h"
 | 
			
		||||
#include "soc/rtc_cntl_reg.h"
 | 
			
		||||
#include "soc/sens_reg.h"
 | 
			
		||||
#include "soc/efuse_reg.h"
 | 
			
		||||
#include "soc/syscon_reg.h"
 | 
			
		||||
#include "soc/system_reg.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,6 @@
 | 
			
		||||
#include "esp32c3/rom/uart.h"
 | 
			
		||||
#include "soc/rtc.h"
 | 
			
		||||
#include "soc/rtc_periph.h"
 | 
			
		||||
#include "soc/sens_periph.h"
 | 
			
		||||
#include "soc/efuse_periph.h"
 | 
			
		||||
#include "soc/apb_ctrl_reg.h"
 | 
			
		||||
#include "hal/cpu_hal.h"
 | 
			
		||||
@@ -56,7 +55,7 @@ void rtc_clk_init(rtc_clk_config_t cfg)
 | 
			
		||||
 | 
			
		||||
    /* Enable the internal bus used to configure PLLs */
 | 
			
		||||
    SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
 | 
			
		||||
    CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M | I2C_BBPLL_M);
 | 
			
		||||
    CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_APLL_M | ANA_I2C_BBPLL_M);
 | 
			
		||||
 | 
			
		||||
    rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
 | 
			
		||||
    esp_rom_uart_tx_wait_idle(0);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,14 @@
 | 
			
		||||
#include "soc/system_reg.h"
 | 
			
		||||
#include "regi2c_ctrl.h"
 | 
			
		||||
#include "soc_log.h"
 | 
			
		||||
#include "esp_efuse.h"
 | 
			
		||||
#include "esp_efuse_table.h"
 | 
			
		||||
 | 
			
		||||
static const char *TAG = "rtc_init";
 | 
			
		||||
 | 
			
		||||
static void set_ocode_by_efuse(int calib_version);
 | 
			
		||||
static void calibrate_ocode(void);
 | 
			
		||||
 | 
			
		||||
void rtc_init(rtc_config_t cfg)
 | 
			
		||||
{
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
 | 
			
		||||
@@ -135,54 +140,13 @@ void rtc_init(rtc_config_t cfg)
 | 
			
		||||
        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
 | 
			
		||||
    }
 | 
			
		||||
    if (cfg.cali_ocode) {
 | 
			
		||||
        /*
 | 
			
		||||
        Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration(must close PLL).
 | 
			
		||||
        Method:
 | 
			
		||||
        1. read current cpu config, save in old_config;
 | 
			
		||||
        2. switch cpu to xtal because PLL will be closed when o-code calibration;
 | 
			
		||||
        3. begin o-code calibration;
 | 
			
		||||
        4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
 | 
			
		||||
        5. set cpu to old-config.
 | 
			
		||||
        */
 | 
			
		||||
        rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
 | 
			
		||||
        rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
 | 
			
		||||
        rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
 | 
			
		||||
        rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
 | 
			
		||||
        if (slow_clk_freq == (rtc_slow_freq_x32k)) {
 | 
			
		||||
            cal_clk = RTC_CAL_32K_XTAL;
 | 
			
		||||
        } else if (slow_clk_freq == rtc_slow_freq_8MD256) {
 | 
			
		||||
            cal_clk  = RTC_CAL_8MD256;
 | 
			
		||||
        uint32_t rtc_calib_version = 0;
 | 
			
		||||
        esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &rtc_calib_version, 3);
 | 
			
		||||
        if (rtc_calib_version == 1) {
 | 
			
		||||
            set_ocode_by_efuse(rtc_calib_version);
 | 
			
		||||
        } else {
 | 
			
		||||
            calibrate_ocode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uint64_t max_delay_time_us = 10000;
 | 
			
		||||
        uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
 | 
			
		||||
        uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
 | 
			
		||||
        uint64_t cycle0 = rtc_time_get();
 | 
			
		||||
        uint64_t timeout_cycle = cycle0 + max_delay_cycle;
 | 
			
		||||
        uint64_t cycle1 = 0;
 | 
			
		||||
 | 
			
		||||
        rtc_cpu_freq_config_t old_config;
 | 
			
		||||
        rtc_clk_cpu_freq_get_config(&old_config);
 | 
			
		||||
        rtc_clk_cpu_freq_set_xtal();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
 | 
			
		||||
        bool odone_flag = 0;
 | 
			
		||||
        bool bg_odone_flag = 0;
 | 
			
		||||
        while (1) {
 | 
			
		||||
            odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
 | 
			
		||||
            bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
 | 
			
		||||
            cycle1 = rtc_time_get();
 | 
			
		||||
            if (odone_flag && bg_odone_flag) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if (cycle1 >= timeout_cycle) {
 | 
			
		||||
                SOC_LOGW(TAG, "o_code calibration fail\n");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        rtc_clk_cpu_freq_set_config(&old_config);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -223,3 +187,65 @@ void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
 | 
			
		||||
    val |= RTC_CNTL_SDIO_PD_EN;
 | 
			
		||||
    REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_ocode_by_efuse(int calib_version)
 | 
			
		||||
{
 | 
			
		||||
    assert(calib_version == 1);
 | 
			
		||||
    // use efuse ocode.
 | 
			
		||||
    uint32_t ocode;
 | 
			
		||||
    esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_OCODE, &ocode, 8);
 | 
			
		||||
    assert(err == ESP_OK);
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode);
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void calibrate_ocode(void)
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
    Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL).
 | 
			
		||||
    Method:
 | 
			
		||||
    1. read current cpu config, save in old_config;
 | 
			
		||||
    2. switch cpu to xtal because PLL will be closed when o-code calibration;
 | 
			
		||||
    3. begin o-code calibration;
 | 
			
		||||
    4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
 | 
			
		||||
    5. set cpu to old-config.
 | 
			
		||||
    */
 | 
			
		||||
    rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
 | 
			
		||||
    rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
 | 
			
		||||
    rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
 | 
			
		||||
    rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
 | 
			
		||||
    if (slow_clk_freq == (rtc_slow_freq_x32k)) {
 | 
			
		||||
        cal_clk = RTC_CAL_32K_XTAL;
 | 
			
		||||
    } else if (slow_clk_freq == rtc_slow_freq_8MD256) {
 | 
			
		||||
        cal_clk  = RTC_CAL_8MD256;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint64_t max_delay_time_us = 10000;
 | 
			
		||||
    uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
 | 
			
		||||
    uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
 | 
			
		||||
    uint64_t cycle0 = rtc_time_get();
 | 
			
		||||
    uint64_t timeout_cycle = cycle0 + max_delay_cycle;
 | 
			
		||||
    uint64_t cycle1 = 0;
 | 
			
		||||
 | 
			
		||||
    rtc_cpu_freq_config_t old_config;
 | 
			
		||||
    rtc_clk_cpu_freq_get_config(&old_config);
 | 
			
		||||
    rtc_clk_cpu_freq_set_xtal();
 | 
			
		||||
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
 | 
			
		||||
    bool odone_flag = 0;
 | 
			
		||||
    bool bg_odone_flag = 0;
 | 
			
		||||
    while (1) {
 | 
			
		||||
        odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
 | 
			
		||||
        bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
 | 
			
		||||
        cycle1 = rtc_time_get();
 | 
			
		||||
        if (odone_flag && bg_odone_flag) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (cycle1 >= timeout_cycle) {
 | 
			
		||||
            SOC_LOGW(TAG, "o_code calibration fail\n");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    rtc_clk_cpu_freq_set_config(&old_config);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,9 +38,10 @@
 | 
			
		||||
#define I2C_ULP_BG_O_DONE_FLAG_MSB 3
 | 
			
		||||
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_OCODE_ADDR 6
 | 
			
		||||
#define I2C_ULP_OCODE_ADDR_MSB 7
 | 
			
		||||
#define I2C_ULP_OCODE_ADDR_LSB 0
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE_ADDR 5
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE_ADDR_MSB 6
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE_ADDR_LSB 6
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE 5
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE_MSB 6
 | 
			
		||||
#define I2C_ULP_IR_FORCE_CODE_LSB 6
 | 
			
		||||
 | 
			
		||||
#define I2C_ULP_EXT_CODE 6
 | 
			
		||||
#define I2C_ULP_EXT_CODE_MSB 7
 | 
			
		||||
#define I2C_ULP_EXT_CODE_LSB 0
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,9 @@
 | 
			
		||||
#include "esp_efuse_table.h"
 | 
			
		||||
static const char *TAG = "rtc_init";
 | 
			
		||||
 | 
			
		||||
static void set_ocode_by_efuse(int calib_version);
 | 
			
		||||
static void calibrate_ocode(void);
 | 
			
		||||
 | 
			
		||||
void rtc_init(rtc_config_t cfg)
 | 
			
		||||
{
 | 
			
		||||
    CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU);
 | 
			
		||||
@@ -152,68 +155,9 @@ void rtc_init(rtc_config_t cfg)
 | 
			
		||||
        uint32_t rtc_calib_version = 0;
 | 
			
		||||
        esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &rtc_calib_version, 32);
 | 
			
		||||
        if (rtc_calib_version == 2) {
 | 
			
		||||
            // use efuse ocode.
 | 
			
		||||
            uint32_t ocode1 = 0;
 | 
			
		||||
            uint32_t ocode2 = 0;
 | 
			
		||||
            uint32_t ocode;
 | 
			
		||||
            esp_efuse_read_block(2, &ocode1, 16*8, 4);
 | 
			
		||||
            esp_efuse_read_block(2, &ocode2, 18*8, 3);
 | 
			
		||||
            ocode = (ocode2 << 4) + ocode1;
 | 
			
		||||
            if (ocode >> 6) {
 | 
			
		||||
                ocode = 93 - (ocode ^ (1 << 6));
 | 
			
		||||
            } else {
 | 
			
		||||
                ocode = 93 + ocode;
 | 
			
		||||
            }
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_OCODE_ADDR, ocode);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE_ADDR, 1);
 | 
			
		||||
            set_ocode_by_efuse(rtc_calib_version);
 | 
			
		||||
        } else {
 | 
			
		||||
            /*
 | 
			
		||||
            Bangap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration(must close PLL).
 | 
			
		||||
            Method:
 | 
			
		||||
            1. read current cpu config, save in old_config;
 | 
			
		||||
            2. switch cpu to xtal because PLL will be closed when o-code calibration;
 | 
			
		||||
            3. begin o-code calibration;
 | 
			
		||||
            4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
 | 
			
		||||
            5. set cpu to old-config.
 | 
			
		||||
            */
 | 
			
		||||
            rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
 | 
			
		||||
            rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
 | 
			
		||||
            rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
 | 
			
		||||
            rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
 | 
			
		||||
            if (slow_clk_freq == (rtc_slow_freq_x32k)) {
 | 
			
		||||
                cal_clk = RTC_CAL_32K_XTAL;
 | 
			
		||||
            } else if (slow_clk_freq == rtc_slow_freq_8MD256) {
 | 
			
		||||
                cal_clk  = RTC_CAL_8MD256;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            uint64_t max_delay_time_us = 10000;
 | 
			
		||||
            uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
 | 
			
		||||
            uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
 | 
			
		||||
            uint64_t cycle0 = rtc_time_get();
 | 
			
		||||
            uint64_t timeout_cycle = cycle0 + max_delay_cycle;
 | 
			
		||||
            uint64_t cycle1 = 0;
 | 
			
		||||
 | 
			
		||||
            rtc_cpu_freq_config_t old_config;
 | 
			
		||||
            rtc_clk_cpu_freq_get_config(&old_config);
 | 
			
		||||
            rtc_clk_cpu_freq_set_xtal();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
 | 
			
		||||
            bool odone_flag = 0;
 | 
			
		||||
            bool bg_odone_flag = 0;
 | 
			
		||||
            while(1) {
 | 
			
		||||
                odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
 | 
			
		||||
                bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
 | 
			
		||||
                cycle1 = rtc_time_get();
 | 
			
		||||
                if (odone_flag && bg_odone_flag)
 | 
			
		||||
                    break;
 | 
			
		||||
                if (cycle1 >= timeout_cycle) {
 | 
			
		||||
                    SOC_LOGW(TAG, "o_code calibration fail");
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            rtc_clk_cpu_freq_set_config(&old_config);
 | 
			
		||||
            calibrate_ocode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -269,3 +213,72 @@ void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
 | 
			
		||||
    val |= RTC_CNTL_SDIO_PD_EN;
 | 
			
		||||
    REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_ocode_by_efuse(int calib_version)
 | 
			
		||||
{
 | 
			
		||||
    assert(calib_version == 2);
 | 
			
		||||
    // use efuse ocode.
 | 
			
		||||
    uint32_t ocode1 = 0;
 | 
			
		||||
    uint32_t ocode2 = 0;
 | 
			
		||||
    uint32_t ocode;
 | 
			
		||||
    esp_efuse_read_block(2, &ocode1, 16*8, 4);
 | 
			
		||||
    esp_efuse_read_block(2, &ocode2, 18*8, 3);
 | 
			
		||||
    ocode = (ocode2 << 4) + ocode1;
 | 
			
		||||
    if (ocode >> 6) {
 | 
			
		||||
        ocode = 93 - (ocode ^ (1 << 6));
 | 
			
		||||
    } else {
 | 
			
		||||
        ocode = 93 + ocode;
 | 
			
		||||
    }
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode);
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void calibrate_ocode(void)
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
    Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL).
 | 
			
		||||
    Method:
 | 
			
		||||
    1. read current cpu config, save in old_config;
 | 
			
		||||
    2. switch cpu to xtal because PLL will be closed when o-code calibration;
 | 
			
		||||
    3. begin o-code calibration;
 | 
			
		||||
    4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
 | 
			
		||||
    5. set cpu to old-config.
 | 
			
		||||
    */
 | 
			
		||||
    rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
 | 
			
		||||
    rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
 | 
			
		||||
    rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
 | 
			
		||||
    rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
 | 
			
		||||
    if (slow_clk_freq == (rtc_slow_freq_x32k)) {
 | 
			
		||||
        cal_clk = RTC_CAL_32K_XTAL;
 | 
			
		||||
    } else if (slow_clk_freq == rtc_slow_freq_8MD256) {
 | 
			
		||||
        cal_clk  = RTC_CAL_8MD256;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint64_t max_delay_time_us = 10000;
 | 
			
		||||
    uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
 | 
			
		||||
    uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
 | 
			
		||||
    uint64_t cycle0 = rtc_time_get();
 | 
			
		||||
    uint64_t timeout_cycle = cycle0 + max_delay_cycle;
 | 
			
		||||
    uint64_t cycle1 = 0;
 | 
			
		||||
 | 
			
		||||
    rtc_cpu_freq_config_t old_config;
 | 
			
		||||
    rtc_clk_cpu_freq_get_config(&old_config);
 | 
			
		||||
    rtc_clk_cpu_freq_set_xtal();
 | 
			
		||||
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
 | 
			
		||||
    bool odone_flag = 0;
 | 
			
		||||
    bool bg_odone_flag = 0;
 | 
			
		||||
    while(1) {
 | 
			
		||||
        odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
 | 
			
		||||
        bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
 | 
			
		||||
        cycle1 = rtc_time_get();
 | 
			
		||||
        if (odone_flag && bg_odone_flag)
 | 
			
		||||
            break;
 | 
			
		||||
        if (cycle1 >= timeout_cycle) {
 | 
			
		||||
            SOC_LOGW(TAG, "o_code calibration fail");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    rtc_clk_cpu_freq_set_config(&old_config);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,12 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "unity.h"
 | 
			
		||||
 | 
			
		||||
#include "soc/soc_caps.h"
 | 
			
		||||
#include "soc/rtc.h"
 | 
			
		||||
#include "soc/rtc_periph.h"
 | 
			
		||||
#if SOC_ADC_SUPPORT_RTC_CTRL
 | 
			
		||||
#include "soc/sens_periph.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "soc/gpio_periph.h"
 | 
			
		||||
#include "hal/gpio_ll.h"
 | 
			
		||||
#include "driver/rtc_io.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -75,6 +75,11 @@ static const char *TAG = "clk";
 | 
			
		||||
{
 | 
			
		||||
#if !CONFIG_IDF_ENV_FPGA
 | 
			
		||||
    rtc_config_t cfg = RTC_CONFIG_DEFAULT();
 | 
			
		||||
    RESET_REASON rst_reas;
 | 
			
		||||
    rst_reas = rtc_get_reset_reason(0);
 | 
			
		||||
    if (rst_reas == POWERON_RESET) {
 | 
			
		||||
        cfg.cali_ocode = 1;
 | 
			
		||||
    }
 | 
			
		||||
    rtc_init(cfg);
 | 
			
		||||
 | 
			
		||||
    assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
 | 
			
		||||
 
 | 
			
		||||
@@ -30,11 +30,11 @@ if(NOT BOOTLOADER_BUILD)
 | 
			
		||||
                "sha_hal.c"
 | 
			
		||||
                "aes_hal.c"
 | 
			
		||||
                "twai_hal.c"
 | 
			
		||||
                "twai_hal_iram.c")
 | 
			
		||||
                "twai_hal_iram.c"
 | 
			
		||||
                "adc_hal.c")
 | 
			
		||||
 | 
			
		||||
    if(${target} STREQUAL "esp32")
 | 
			
		||||
        list(APPEND srcs
 | 
			
		||||
                    "adc_hal.c"
 | 
			
		||||
                    "dac_hal.c"
 | 
			
		||||
                    "mcpwm_hal.c"
 | 
			
		||||
                    "pcnt_hal.c"
 | 
			
		||||
@@ -52,7 +52,6 @@ if(NOT BOOTLOADER_BUILD)
 | 
			
		||||
 | 
			
		||||
    if(${target} STREQUAL "esp32s2")
 | 
			
		||||
        list(APPEND srcs
 | 
			
		||||
                    "adc_hal.c"
 | 
			
		||||
                    "dac_hal.c"
 | 
			
		||||
                    "pcnt_hal.c"
 | 
			
		||||
                    "spi_flash_hal_gpspi.c"
 | 
			
		||||
@@ -70,7 +69,6 @@ if(NOT BOOTLOADER_BUILD)
 | 
			
		||||
 | 
			
		||||
    if(${target} STREQUAL "esp32s3")
 | 
			
		||||
        list(APPEND srcs
 | 
			
		||||
            "adc_hal.c"
 | 
			
		||||
            "dac_hal.c"
 | 
			
		||||
            "gdma_hal.c"
 | 
			
		||||
            "pcnt_hal.c"
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,9 @@
 | 
			
		||||
#include "hal/adc_hal.h"
 | 
			
		||||
#include "hal/adc_hal_conf.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
#include "soc/gdma_channel.h"
 | 
			
		||||
#include "soc/soc.h"
 | 
			
		||||
#include "esp_rom_sys.h"
 | 
			
		||||
#endif
 | 
			
		||||
@@ -37,6 +39,7 @@ void adc_hal_deinit(void)
 | 
			
		||||
    adc_ll_set_power_manage(ADC_POWER_SW_OFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value)
 | 
			
		||||
{
 | 
			
		||||
    adc_ll_rtc_enable_channel(adc_n, channel);
 | 
			
		||||
@@ -45,6 +48,7 @@ int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value)
 | 
			
		||||
    *value = adc_ll_rtc_get_convert_value(adc_n);
 | 
			
		||||
    return (int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*value));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
//This feature is currently supported on ESP32C3, will be supported on other chips soon
 | 
			
		||||
@@ -108,6 +112,8 @@ void adc_hal_digi_start(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t
 | 
			
		||||
    adc_ll_digi_dma_enable();
 | 
			
		||||
    //enable sar adc timer
 | 
			
		||||
    adc_ll_digi_trigger_enable();
 | 
			
		||||
    //reset the adc state
 | 
			
		||||
    adc_ll_digi_reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adc_hal_digi_stop(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config)
 | 
			
		||||
@@ -139,7 +145,7 @@ void adc_hal_onetime_start(adc_digi_config_t *adc_digi_config)
 | 
			
		||||
     * This limitation will be removed in hardware future versions.
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t digi_clk = APB_CLK_FREQ / (adc_digi_config->dig_clk.div_num + adc_digi_config->dig_clk.div_a / adc_digi_config->dig_clk.div_b + 1);
 | 
			
		||||
    uint32_t digi_clk = APB_CLK_FREQ / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1);
 | 
			
		||||
    //Convert frequency to time (us). Since decimals are removed by this division operation. Add 1 here in case of the fact that delay is not enough.
 | 
			
		||||
    uint32_t delay = (1000 * 1000) / digi_clk + 1;
 | 
			
		||||
    //3 ADC digital controller clock cycle
 | 
			
		||||
@@ -183,14 +189,17 @@ void adc_hal_set_onetime_atten(adc_atten_t atten)
 | 
			
		||||
    adc_ll_onetime_set_atten(atten);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t adc_hal_adc1_read(void)
 | 
			
		||||
esp_err_t adc_hal_single_read(adc_ll_num_t unit, int *out_raw)
 | 
			
		||||
{
 | 
			
		||||
    return adc_ll_adc1_read();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t adc_hal_adc2_read(void)
 | 
			
		||||
{
 | 
			
		||||
    return adc_ll_adc2_read();
 | 
			
		||||
    if (unit == ADC_NUM_1) {
 | 
			
		||||
        *out_raw = adc_ll_adc1_read();
 | 
			
		||||
    } else if (unit == ADC_NUM_2) {
 | 
			
		||||
        *out_raw = adc_ll_adc2_read();
 | 
			
		||||
        if (adc_ll_analysis_raw_data(unit, *out_raw)) {
 | 
			
		||||
            return ESP_ERR_INVALID_STATE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return ESP_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------INTR-------------------------------
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,20 @@
 | 
			
		||||
 | 
			
		||||
// The HAL layer for ADC (ESP32-C3 specific part)
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "soc/soc_caps.h"
 | 
			
		||||
#include "hal/adc_hal.h"
 | 
			
		||||
#include "hal/adc_types.h"
 | 
			
		||||
#include "soc/soc.h"
 | 
			
		||||
 | 
			
		||||
//Currently we don't have context for the ADC HAL. So HAL variables are temporarily put here. But
 | 
			
		||||
//please don't follow this code. Create a context for your own HAL!
 | 
			
		||||
 | 
			
		||||
static bool s_filter_enabled[SOC_ADC_DIGI_FILTER_NUM] = {};
 | 
			
		||||
static adc_digi_filter_t s_filter[SOC_ADC_DIGI_FILTER_NUM] = {};
 | 
			
		||||
 | 
			
		||||
static bool s_monitor_enabled[SOC_ADC_DIGI_MONITOR_NUM] = {};
 | 
			
		||||
static adc_digi_monitor_t s_monitor_config[SOC_ADC_DIGI_MONITOR_NUM] = {};
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    Digital controller setting
 | 
			
		||||
@@ -33,14 +45,6 @@ void adc_hal_digi_deinit(void)
 | 
			
		||||
    adc_hal_deinit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal);
 | 
			
		||||
 | 
			
		||||
static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false);
 | 
			
		||||
    adc_hal_set_calibration_param(adc_n, cal_val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
 | 
			
		||||
{
 | 
			
		||||
    //only one pattern table is supported on C3, but LL still needs one argument.
 | 
			
		||||
@@ -51,9 +55,8 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
 | 
			
		||||
    if (cfg->adc_pattern_len) {
 | 
			
		||||
        adc_ll_digi_clear_pattern_table(pattern_both);
 | 
			
		||||
        adc_ll_digi_set_pattern_table_len(pattern_both, cfg->adc_pattern_len);
 | 
			
		||||
        for (int i = 0; i < cfg->adc_pattern_len; i++) {
 | 
			
		||||
        for (uint32_t i = 0; i < cfg->adc_pattern_len; i++) {
 | 
			
		||||
            adc_ll_digi_set_pattern_table(pattern_both, i, cfg->adc_pattern[i]);
 | 
			
		||||
            adc_set_init_code(pattern_both, cfg->adc_pattern[i].channel, cfg->adc_pattern[i].atten);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -65,24 +68,17 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
 | 
			
		||||
        adc_ll_digi_convert_limit_disable();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    adc_ll_digi_set_trigger_interval(cfg->interval);
 | 
			
		||||
    adc_hal_digi_clk_config(&cfg->dig_clk);
 | 
			
		||||
    //clock
 | 
			
		||||
    uint32_t interval = APB_CLK_FREQ / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1) / 2 / cfg->sample_freq_hz;
 | 
			
		||||
    adc_ll_digi_set_trigger_interval(interval);
 | 
			
		||||
    adc_hal_digi_clk_config();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
 | 
			
		||||
 * Enable clock and select clock source for ADC digital controller.
 | 
			
		||||
 * Expression: controller_clk = APLL/APB * (div_num  + div_b / div_a).
 | 
			
		||||
 *
 | 
			
		||||
 * @note ADC and DAC digital controller share the same frequency divider.
 | 
			
		||||
 *       Please set a reasonable frequency division factor to meet the sampling frequency of the ADC and the output frequency of the DAC.
 | 
			
		||||
 *
 | 
			
		||||
 * @param clk Refer to ``adc_digi_clk_t``.
 | 
			
		||||
 */
 | 
			
		||||
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk)
 | 
			
		||||
void adc_hal_digi_clk_config(void)
 | 
			
		||||
{
 | 
			
		||||
    adc_ll_digi_controller_clk_div(clk->div_num, clk->div_b, clk->div_a);
 | 
			
		||||
    adc_ll_digi_controller_clk_enable(clk->use_apll);
 | 
			
		||||
    //Here we set the clock divider factor to make the digital clock to 5M Hz
 | 
			
		||||
    adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT);
 | 
			
		||||
    adc_ll_digi_controller_clk_enable(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -103,17 +99,65 @@ void adc_hal_digi_disable(void)
 | 
			
		||||
    adc_ll_digi_dma_disable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Config monitor of adc digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param config Refer to `adc_digi_monitor_t`.
 | 
			
		||||
 */
 | 
			
		||||
void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config)
 | 
			
		||||
static void filter_update(adc_digi_filter_idx_t idx)
 | 
			
		||||
{
 | 
			
		||||
    adc_ll_digi_monitor_set_mode(adc_n, config->mode);
 | 
			
		||||
    adc_ll_digi_monitor_set_thres(adc_n, config->threshold);
 | 
			
		||||
    //ESP32-C3 has no enable bit, the filter will be enabled when the filter channel is configured
 | 
			
		||||
    if (s_filter_enabled[idx]) {
 | 
			
		||||
        adc_ll_digi_filter_set_factor(idx, &s_filter[idx]);
 | 
			
		||||
    } else {
 | 
			
		||||
        adc_ll_digi_filter_disable(idx);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set adc digital controller filter factor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param idx ADC filter unit.
 | 
			
		||||
 * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 */
 | 
			
		||||
void adc_hal_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
 | 
			
		||||
{
 | 
			
		||||
    s_filter[idx] = *filter;
 | 
			
		||||
    filter_update(idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get adc digital controller filter factor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 */
 | 
			
		||||
void adc_hal_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
 | 
			
		||||
{
 | 
			
		||||
    *filter = s_filter[idx];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adc_hal_digi_filter_enable(adc_digi_filter_idx_t filter_idx, bool enable)
 | 
			
		||||
{
 | 
			
		||||
    s_filter_enabled[filter_idx] = enable;
 | 
			
		||||
    filter_update(filter_idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void update_monitor(adc_digi_monitor_idx_t idx)
 | 
			
		||||
{
 | 
			
		||||
    //ESP32-C3 has no enable bit, the monitor will be enabled when the monitor channel is configured
 | 
			
		||||
    if (s_monitor_enabled[idx]) {
 | 
			
		||||
        adc_ll_digi_monitor_set_mode(idx, &s_monitor_config[idx]);
 | 
			
		||||
    } else {
 | 
			
		||||
        adc_ll_digi_monitor_disable(idx);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adc_hal_digi_monitor_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config)
 | 
			
		||||
{
 | 
			
		||||
    s_monitor_config[idx] = *config;
 | 
			
		||||
    update_monitor(idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adc_hal_digi_monitor_enable(adc_digi_monitor_idx_t mon_idx, bool enable)
 | 
			
		||||
{
 | 
			
		||||
    s_monitor_enabled[mon_idx] = enable;
 | 
			
		||||
    update_monitor(mon_idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
@@ -136,98 +180,3 @@ void adc_hal_arbiter_config(adc_arbiter_t *config)
 | 
			
		||||
    adc_ll_set_arbiter_work_mode(config->mode);
 | 
			
		||||
    adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    ADC calibration setting
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#define ADC_HAL_CAL_OFFSET_RANGE (4096)
 | 
			
		||||
#define ADC_HAL_CAL_TIMES        (10)
 | 
			
		||||
 | 
			
		||||
static uint16_t s_adc_cali_param[ADC_NUM_MAX][ADC_ATTEN_MAX] = { {0}, {0} };
 | 
			
		||||
 | 
			
		||||
static uint32_t adc_hal_read_self_cal(adc_ll_num_t adc_n, int channel)
 | 
			
		||||
{
 | 
			
		||||
    adc_ll_rtc_start_convert(adc_n, channel);
 | 
			
		||||
    while (adc_ll_rtc_convert_is_done(adc_n) != true);
 | 
			
		||||
    return (uint32_t)adc_ll_rtc_get_convert_value(adc_n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal)
 | 
			
		||||
{
 | 
			
		||||
    if (!force_cal) {
 | 
			
		||||
        if (s_adc_cali_param[adc_n][atten]) {
 | 
			
		||||
            return (uint32_t)s_adc_cali_param[adc_n][atten];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
 | 
			
		||||
    uint32_t code_sum = 0;
 | 
			
		||||
    uint32_t code_h = 0;
 | 
			
		||||
    uint32_t code_l = 0;
 | 
			
		||||
    uint32_t chk_code = 0;
 | 
			
		||||
    uint32_t dout = 0;
 | 
			
		||||
 | 
			
		||||
    adc_hal_set_power_manage(ADC_POWER_SW_ON);
 | 
			
		||||
    if (adc_n == ADC_NUM_2) {
 | 
			
		||||
        adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
 | 
			
		||||
        adc_hal_arbiter_config(&config);
 | 
			
		||||
    }
 | 
			
		||||
    adc_hal_set_controller(adc_n, ADC_CTRL_RTC);    //Set controller
 | 
			
		||||
 | 
			
		||||
    // adc_hal_arbiter_config(adc_arbiter_t *config)
 | 
			
		||||
    adc_ll_calibration_prepare(adc_n, channel, internal_gnd);
 | 
			
		||||
 | 
			
		||||
    /* Enable/disable internal connect GND (for calibration). */
 | 
			
		||||
    if (internal_gnd) {
 | 
			
		||||
        adc_ll_rtc_disable_channel(adc_n, channel);
 | 
			
		||||
        adc_ll_set_atten(adc_n, 0, atten);  // Note: when disable all channel, HW auto select channel0 atten param.
 | 
			
		||||
    } else {
 | 
			
		||||
        adc_ll_rtc_enable_channel(adc_n, channel);
 | 
			
		||||
        adc_ll_set_atten(adc_n, channel, atten);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) {
 | 
			
		||||
        code_h = ADC_HAL_CAL_OFFSET_RANGE;
 | 
			
		||||
        code_l = 0;
 | 
			
		||||
        chk_code = (code_h + code_l) / 2;
 | 
			
		||||
        adc_ll_set_calibration_param(adc_n, chk_code);
 | 
			
		||||
        dout = adc_hal_read_self_cal(adc_n, channel);
 | 
			
		||||
        while (code_h - code_l > 1) {
 | 
			
		||||
            if (dout == 0) {
 | 
			
		||||
                code_h = chk_code;
 | 
			
		||||
            } else {
 | 
			
		||||
                code_l = chk_code;
 | 
			
		||||
            }
 | 
			
		||||
            chk_code = (code_h + code_l) / 2;
 | 
			
		||||
            adc_ll_set_calibration_param(adc_n, chk_code);
 | 
			
		||||
            dout = adc_hal_read_self_cal(adc_n, channel);
 | 
			
		||||
            if ((code_h - code_l == 1)) {
 | 
			
		||||
                chk_code += 1;
 | 
			
		||||
                adc_ll_set_calibration_param(adc_n, chk_code);
 | 
			
		||||
                dout = adc_hal_read_self_cal(adc_n, channel);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        code_list[rpt] = chk_code;
 | 
			
		||||
        code_sum += chk_code;
 | 
			
		||||
    }
 | 
			
		||||
    code_l = code_list[0];
 | 
			
		||||
    code_h = code_list[0];
 | 
			
		||||
    for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) {
 | 
			
		||||
        if (code_l > code_list[i]) {
 | 
			
		||||
            code_l = code_list[i];
 | 
			
		||||
        }
 | 
			
		||||
        if (code_h < code_list[i]) {
 | 
			
		||||
            code_h = code_list[i];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    chk_code = code_h + code_l;
 | 
			
		||||
    dout = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
 | 
			
		||||
           ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2)
 | 
			
		||||
           : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
 | 
			
		||||
 | 
			
		||||
    adc_ll_set_calibration_param(adc_n, dout);
 | 
			
		||||
    adc_ll_calibration_finish(adc_n);
 | 
			
		||||
    s_adc_cali_param[adc_n][atten] = (uint16_t)dout;
 | 
			
		||||
    return dout;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -75,70 +75,62 @@ void adc_hal_digi_disable(void);
 | 
			
		||||
/**
 | 
			
		||||
 * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
 | 
			
		||||
 * Enable clock and select clock source for ADC digital controller.
 | 
			
		||||
 * Expression: controller_clk = APLL/APB * (div_num  + div_b / div_a).
 | 
			
		||||
 * Expression: controller_clk = APLL/APB * (div_num  + div_a / div_b + 1).
 | 
			
		||||
 *
 | 
			
		||||
 * @param clk Refer to `adc_digi_clk_t`.
 | 
			
		||||
 */
 | 
			
		||||
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk);
 | 
			
		||||
void adc_hal_digi_clk_config(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reset adc digital controller filter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param filter_idx ADC filter unit.
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_digi_filter_reset(adc_n) adc_ll_digi_filter_reset(adc_n)
 | 
			
		||||
#define adc_hal_digi_filter_reset(filter_idx) adc_ll_digi_filter_reset(filter_idx)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set adc digital controller filter factor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 * @param filter_idx ADC filter unit.
 | 
			
		||||
 * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_digi_filter_set_factor(adc_n, factor) adc_ll_digi_filter_set_factor(adc_n, factor)
 | 
			
		||||
void adc_hal_digi_filter_set_factor(adc_digi_filter_idx_t filter_idx, adc_digi_filter_t *filter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get adc digital controller filter factor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param filter_idx ADC filter unit.
 | 
			
		||||
 * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_digi_filter_get_factor(adc_n, factor) adc_ll_digi_filter_get_factor(adc_n, factor)
 | 
			
		||||
void adc_hal_digi_filter_get_factor(adc_digi_filter_idx_t filter_idx, adc_digi_filter_t *filter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable/disable adc digital controller filter.
 | 
			
		||||
 * Filtering the ADC data to obtain smooth data at higher sampling rates.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param filter_idx ADC filter unit.
 | 
			
		||||
 * @param enable True to enable the filter, otherwise disable.
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_digi_filter_enable(adc_n, enable) adc_ll_digi_filter_enable(adc_n, enable)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the filtered data of adc digital controller filter.
 | 
			
		||||
 * The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @return Filtered data.
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_digi_filter_read_data(adc_n) adc_ll_digi_filter_read_data(adc_n)
 | 
			
		||||
void adc_hal_digi_filter_enable(adc_digi_filter_idx_t filter_idx, bool enable);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Config monitor of adc digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @note If the channel info is not supported, the monitor function will not be enabled.
 | 
			
		||||
 * @param mon_idx ADC monitor index.
 | 
			
		||||
 * @param config Refer to `adc_digi_monitor_t`.
 | 
			
		||||
 */
 | 
			
		||||
void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config);
 | 
			
		||||
void adc_hal_digi_monitor_config(adc_digi_monitor_idx_t mon_idx, adc_digi_monitor_t *config);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable/disable monitor of adc digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param mon_idx ADC monitor index.
 | 
			
		||||
 * @param enable True to enable the monitor, otherwise disable.
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_digi_monitor_enable(adc_n, enable) adc_ll_digi_monitor_enable(adc_n, enable)
 | 
			
		||||
void adc_hal_digi_monitor_enable(adc_digi_monitor_idx_t mon_idx, bool enable);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable interrupt of adc digital controller by bitmask.
 | 
			
		||||
@@ -197,14 +189,6 @@ void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config)
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_digi_reset() adc_ll_digi_reset()
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    RTC controller setting
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
/**
 | 
			
		||||
 * Reset RTC controller FSM.
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_rtc_reset() adc_ll_rtc_reset()
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    Common setting
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
@@ -226,21 +210,6 @@ void adc_hal_arbiter_config(adc_arbiter_t *config);
 | 
			
		||||
                    ADC calibration setting
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Calibrate the ADC using internal connections.
 | 
			
		||||
 *
 | 
			
		||||
 * @note  Different ADC units and different attenuation options use different calibration data (initial data).
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC index number.
 | 
			
		||||
 * @param channel adc channel number.
 | 
			
		||||
 * @param atten The attenuation for the channel
 | 
			
		||||
 * @param internal_gnd true:  Disconnect from the IO port and use the internal GND as the calibration voltage.
 | 
			
		||||
 *                     false: Use IO external voltage as calibration voltage.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 *      - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set the calibration result (initial data) to ADC.
 | 
			
		||||
 
 | 
			
		||||
@@ -15,20 +15,25 @@
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "regi2c_ctrl.h"
 | 
			
		||||
#include "esp_attr.h"
 | 
			
		||||
 | 
			
		||||
#include "soc/adc_periph.h"
 | 
			
		||||
#include "hal/adc_types.h"
 | 
			
		||||
#include "soc/apb_saradc_struct.h"
 | 
			
		||||
#include "soc/apb_saradc_reg.h"
 | 
			
		||||
#include "soc/rtc_cntl_struct.h"
 | 
			
		||||
#include "soc/rtc_cntl_reg.h"
 | 
			
		||||
#include "regi2c_ctrl.h"
 | 
			
		||||
#include "esp_attr.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define ADC_LL_ADC2_CHANNEL_MAX     1
 | 
			
		||||
#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15
 | 
			
		||||
#define ADC_LL_CLKM_DIV_B_DEFAULT   1
 | 
			
		||||
#define ADC_LL_CLKM_DIV_A_DEFAULT   0
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    ADC_NUM_1 = 0,          /*!< SAR ADC 1 */
 | 
			
		||||
    ADC_NUM_2 = 1,          /*!< SAR ADC 2 */
 | 
			
		||||
@@ -55,32 +60,6 @@ typedef enum {
 | 
			
		||||
} adc_ll_intr_t;
 | 
			
		||||
FLAG_ATTR(adc_ll_intr_t)
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
#endif /* _MSC_VER */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Analyze whether the obtained raw data is correct.
 | 
			
		||||
 *        ADC2 use arbiter by default. The arbitration result can be judged by the flag bit in the original data.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint16_t data:     13;  /*!<ADC real output data info. Resolution: 13 bit. */
 | 
			
		||||
            uint16_t reserved:  1;  /*!<reserved */
 | 
			
		||||
            uint16_t flag:      2;  /*!<ADC data flag info.
 | 
			
		||||
                                        If (flag == 0), The data is valid.
 | 
			
		||||
                                        If (flag > 0), The data is invalid. */
 | 
			
		||||
        };
 | 
			
		||||
        uint16_t val;
 | 
			
		||||
    };
 | 
			
		||||
} adc_ll_rtc_output_data_t;
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
#endif /* _MSC_VER */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief ADC controller type selection.
 | 
			
		||||
 *
 | 
			
		||||
@@ -95,7 +74,7 @@ typedef enum {
 | 
			
		||||
    ADC2_CTRL_FORCE_PWDET = 3,  /*!<For ADC2. Arbiter in shield mode. Force select Wi-Fi controller work. */
 | 
			
		||||
    ADC2_CTRL_FORCE_RTC = 4,    /*!<For ADC2. Arbiter in shield mode. Force select RTC controller work. */
 | 
			
		||||
    ADC2_CTRL_FORCE_DIG = 6,    /*!<For ADC2. Arbiter in shield mode. Force select digital controller work. */
 | 
			
		||||
} adc_ll_controller_t;
 | 
			
		||||
} adc_controller_t;
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    Digital controller setting
 | 
			
		||||
@@ -127,7 +106,9 @@ static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wa
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    /* Should be called before writing I2C registers. */
 | 
			
		||||
    SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU);
 | 
			
		||||
    REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -142,16 +123,6 @@ static inline void adc_ll_digi_set_clk_div(uint32_t div)
 | 
			
		||||
    APB_SARADC.ctrl.sar_clk_div = div;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set adc output data format for digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @param format Output data format.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_set_output_format(adc_digi_output_format_t format)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set adc max conversion number for digital controller.
 | 
			
		||||
 * If the number of ADC conversion is equal to the maximum, the conversion is stopped.
 | 
			
		||||
@@ -181,53 +152,40 @@ static inline void adc_ll_digi_convert_limit_disable(void)
 | 
			
		||||
    APB_SARADC.ctrl2.meas_num_limit = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set adc conversion mode for digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note ADC digital controller on C3 only has one pattern table list, and do conversions one by one
 | 
			
		||||
 *
 | 
			
		||||
 * @param mode Conversion mode select.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_set_convert_mode(adc_digi_convert_mode_t mode)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2528
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set pattern table length for digital controller.
 | 
			
		||||
 * The pattern table that defines the conversion rules for each SAR ADC. Each table has 8 items, in which channel selection,
 | 
			
		||||
 * and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
 | 
			
		||||
 * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param patt_len Items range: 1 ~ 8.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_set_pattern_table_len(adc_ll_num_t adc_n, uint32_t patt_len)
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     *  channel 可以配置为0~6, 其中 0~4 代表 ADC1 , 5 代表 ADC2 , 6 代表有 EN_TEST 的测试选项,可以采样内部的一些电压信号
 | 
			
		||||
     */
 | 
			
		||||
    APB_SARADC.ctrl.sar_patt_len = patt_len - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set pattern table for digital controller.
 | 
			
		||||
 * The pattern table that defines the conversion rules for each SAR ADC. Each table has 8 items, in which channel selection,
 | 
			
		||||
 * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
 | 
			
		||||
 * pattern table one by one. For each controller the scan sequence has at most 8 different rules before repeating itself.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param pattern_index Items index. Range: 0 ~ 15.
 | 
			
		||||
 * @param pattern_index Items index. Range: 0 ~ 7.
 | 
			
		||||
 * @param pattern Stored conversion rules.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_digi_pattern_table_t pattern)
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     *  channel 可以配置为0~6, 其中 0~4 代表 ADC1 , 5 代表 ADC2 , 6 代表有 EN_TEST 的测试选项,可以采样内部的一些电压信号
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t tab;
 | 
			
		||||
    uint8_t index = pattern_index / 4;
 | 
			
		||||
    uint8_t offset = (pattern_index % 4) * 6;
 | 
			
		||||
 | 
			
		||||
    tab = APB_SARADC.sar_patt_tab[index].sar_patt_tab1;  // Read old register value
 | 
			
		||||
    tab &= (~(0xFC0000 >> offset));       // clear old data
 | 
			
		||||
    tab |= ((uint32_t)pattern.val << 18) >> offset; // Fill in the new data
 | 
			
		||||
    tab &= (~(0xFC0000 >> offset));                      // Clear old data
 | 
			
		||||
    tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset;       // Fill in the new data
 | 
			
		||||
    APB_SARADC.sar_patt_tab[index].sar_patt_tab1 = tab;  // Write back
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -237,9 +195,6 @@ static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pa
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_clear_pattern_table(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     *  channel 可以配置为0~6, 其中 0~4 代表 ADC1 , 5 代表 ADC2 , 6 代表有 EN_TEST 的测试选项,可以采样内部的一些电压信号
 | 
			
		||||
     */
 | 
			
		||||
    APB_SARADC.ctrl.sar_patt_p_clear = 1;
 | 
			
		||||
    APB_SARADC.ctrl.sar_patt_p_clear = 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -271,10 +226,11 @@ static inline void adc_ll_digi_output_invert(adc_ll_num_t adc_n, bool inv_en)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sets the number of interval clock cycles for the digital controller to trigger the measurement.
 | 
			
		||||
 * Set the interval clock cycle for the digital controller to trigger the measurement.
 | 
			
		||||
 * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The trigger interval should not be less than the sampling time of the SAR ADC.
 | 
			
		||||
 * @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095.
 | 
			
		||||
 * @note The trigger interval should not be smaller than the sampling time of the SAR ADC.
 | 
			
		||||
 * @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle)
 | 
			
		||||
{
 | 
			
		||||
@@ -303,7 +259,7 @@ static inline void adc_ll_digi_trigger_disable(void)
 | 
			
		||||
 *
 | 
			
		||||
 * @param div_num Division factor. Range: 1 ~ 255.
 | 
			
		||||
 * @param div_b Division factor. Range: 1 ~ 63.
 | 
			
		||||
 * @param div_a Division factor. Range: 1 ~ 63.
 | 
			
		||||
 * @param div_a Division factor. Range: 0 ~ 63.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a)
 | 
			
		||||
{
 | 
			
		||||
@@ -349,18 +305,18 @@ static inline void adc_ll_digi_filter_reset(adc_ll_num_t adc_n)
 | 
			
		||||
/**
 | 
			
		||||
 * Set adc digital controller filter factor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 * @note If the channel info is not supported, the filter function will not be enabled.
 | 
			
		||||
 * @param idx ADC filter unit.
 | 
			
		||||
 * @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_filter_set_factor(adc_ll_num_t adc_n, adc_digi_filter_mode_t factor)
 | 
			
		||||
static inline void adc_ll_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
 | 
			
		||||
{
 | 
			
		||||
    adc_channel_t channel = 0;
 | 
			
		||||
    if (!APB_SARADC.filter_ctrl0.filter_channel0) {
 | 
			
		||||
        APB_SARADC.filter_ctrl0.filter_channel0 = (adc_n<<4) | channel;
 | 
			
		||||
        APB_SARADC.filter_ctrl1.filter_factor0 = factor;
 | 
			
		||||
    } else if (!APB_SARADC.filter_ctrl0.filter_channel1) {
 | 
			
		||||
        APB_SARADC.filter_ctrl0.filter_channel1 = (adc_n<<4) | channel;
 | 
			
		||||
        APB_SARADC.filter_ctrl1.filter_factor1 = factor;
 | 
			
		||||
    if (idx == ADC_DIGI_FILTER_IDX0) {
 | 
			
		||||
        APB_SARADC.filter_ctrl0.filter_channel0 = (filter->adc_unit << 3) | (filter->channel & 0x7);
 | 
			
		||||
        APB_SARADC.filter_ctrl1.filter_factor0 = filter->mode;
 | 
			
		||||
    } else if (idx == ADC_DIGI_FILTER_IDX1) {
 | 
			
		||||
        APB_SARADC.filter_ctrl0.filter_channel1 = (filter->adc_unit << 3) | (filter->channel & 0x7);
 | 
			
		||||
        APB_SARADC.filter_ctrl1.filter_factor1 = filter->mode;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -370,70 +326,71 @@ static inline void adc_ll_digi_filter_set_factor(adc_ll_num_t adc_n, adc_digi_fi
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_filter_get_factor(adc_ll_num_t adc_n, adc_digi_filter_mode_t *factor)
 | 
			
		||||
static inline void adc_ll_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2528
 | 
			
		||||
    if (idx == ADC_DIGI_FILTER_IDX0) {
 | 
			
		||||
        filter->adc_unit = (APB_SARADC.filter_ctrl0.filter_channel0 >> 3) & 0x1;
 | 
			
		||||
        filter->channel = APB_SARADC.filter_ctrl0.filter_channel0 & 0x7;
 | 
			
		||||
        filter->mode = APB_SARADC.filter_ctrl1.filter_factor0;
 | 
			
		||||
    } else if (idx == ADC_DIGI_FILTER_IDX1) {
 | 
			
		||||
        filter->adc_unit = (APB_SARADC.filter_ctrl0.filter_channel1 >> 3) & 0x1;
 | 
			
		||||
        filter->channel = APB_SARADC.filter_ctrl0.filter_channel1 & 0x7;
 | 
			
		||||
        filter->mode = APB_SARADC.filter_ctrl1.filter_factor1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable/disable adc digital controller filter.
 | 
			
		||||
 * Disable adc digital controller filter.
 | 
			
		||||
 * Filtering the ADC data to obtain smooth data at higher sampling rates.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @note If the channel info is not supported, the filter function will not be enabled.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_filter_enable(adc_ll_num_t adc_n, bool enable)
 | 
			
		||||
static inline void adc_ll_digi_filter_disable(adc_digi_filter_idx_t idx)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the filtered data of adc digital controller filter.
 | 
			
		||||
 * The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @return Filtered data.
 | 
			
		||||
 */
 | 
			
		||||
static inline uint32_t adc_ll_digi_filter_read_data(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    if (idx == ADC_DIGI_FILTER_IDX0) {
 | 
			
		||||
        APB_SARADC.filter_ctrl0.filter_channel0 = 0xF;
 | 
			
		||||
        APB_SARADC.filter_ctrl1.filter_factor0 = 0;
 | 
			
		||||
    } else if (idx == ADC_DIGI_FILTER_IDX1) {
 | 
			
		||||
        APB_SARADC.filter_ctrl0.filter_channel1 = 0xF;
 | 
			
		||||
        APB_SARADC.filter_ctrl1.filter_factor1 = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set monitor mode of adc digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @note If the channel info is not supported, the monitor function will not be enabled.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param is_larger true:  If ADC_OUT >  threshold, Generates monitor interrupt.
 | 
			
		||||
 *                  false: If ADC_OUT <  threshold, Generates monitor interrupt.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_monitor_set_mode(adc_ll_num_t adc_n, bool is_larger)
 | 
			
		||||
static inline void adc_ll_digi_monitor_set_mode(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *cfg)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set monitor threshold of adc digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param threshold Monitor threshold.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_monitor_set_thres(adc_ll_num_t adc_n, uint32_t threshold)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    if (idx == ADC_DIGI_MONITOR_IDX0) {
 | 
			
		||||
        APB_SARADC.thres0_ctrl.thres0_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7);
 | 
			
		||||
        APB_SARADC.thres0_ctrl.thres0_high = cfg->h_threshold;
 | 
			
		||||
        APB_SARADC.thres0_ctrl.thres0_low = cfg->l_threshold;
 | 
			
		||||
    } else { // ADC_DIGI_MONITOR_IDX1
 | 
			
		||||
        APB_SARADC.thres1_ctrl.thres1_channel = (cfg->adc_unit << 3) | (cfg->channel & 0x7);
 | 
			
		||||
        APB_SARADC.thres1_ctrl.thres1_high = cfg->h_threshold;
 | 
			
		||||
        APB_SARADC.thres1_ctrl.thres1_low = cfg->l_threshold;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable/disable monitor of adc digital controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
 | 
			
		||||
 * @note If the channel info is not supported, the monitor function will not be enabled.
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_monitor_enable(adc_ll_num_t adc_n, bool enable)
 | 
			
		||||
static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    if (idx == ADC_DIGI_MONITOR_IDX0) {
 | 
			
		||||
        APB_SARADC.thres0_ctrl.thres0_channel = 0xF;
 | 
			
		||||
    } else { // ADC_DIGI_MONITOR_IDX1
 | 
			
		||||
        APB_SARADC.thres1_ctrl.thres1_channel = 0xF;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -444,7 +401,27 @@ static inline void adc_ll_digi_monitor_enable(adc_ll_num_t adc_n, bool enable)
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_intr_enable(adc_ll_num_t adc_n, adc_digi_intr_t intr)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
 | 
			
		||||
            APB_SARADC.int_ena.adc1_done = 1;
 | 
			
		||||
        }
 | 
			
		||||
    } else { // adc_n == ADC_NUM_2
 | 
			
		||||
        if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
 | 
			
		||||
            APB_SARADC.int_ena.adc2_done = 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR0_HIGH) {
 | 
			
		||||
        APB_SARADC.int_ena.thres0_high = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR0_LOW) {
 | 
			
		||||
        APB_SARADC.int_ena.thres0_low = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR1_HIGH) {
 | 
			
		||||
        APB_SARADC.int_ena.thres1_high = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR1_LOW) {
 | 
			
		||||
        APB_SARADC.int_ena.thres1_low = 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -455,7 +432,27 @@ static inline void adc_ll_digi_intr_enable(adc_ll_num_t adc_n, adc_digi_intr_t i
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_intr_disable(adc_ll_num_t adc_n, adc_digi_intr_t intr)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
 | 
			
		||||
            APB_SARADC.int_ena.adc1_done = 0;
 | 
			
		||||
        }
 | 
			
		||||
    } else { // adc_n == ADC_NUM_2
 | 
			
		||||
        if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
 | 
			
		||||
            APB_SARADC.int_ena.adc2_done = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR0_HIGH) {
 | 
			
		||||
        APB_SARADC.int_ena.thres0_high = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR0_LOW) {
 | 
			
		||||
        APB_SARADC.int_ena.thres0_low = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR1_HIGH) {
 | 
			
		||||
        APB_SARADC.int_ena.thres1_high = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR1_LOW) {
 | 
			
		||||
        APB_SARADC.int_ena.thres1_low = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -466,7 +463,27 @@ static inline void adc_ll_digi_intr_disable(adc_ll_num_t adc_n, adc_digi_intr_t
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_intr_clear(adc_ll_num_t adc_n, adc_digi_intr_t intr)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
 | 
			
		||||
            APB_SARADC.int_clr.adc1_done = 1;
 | 
			
		||||
        }
 | 
			
		||||
    } else { // adc_n == ADC_NUM_2
 | 
			
		||||
        if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
 | 
			
		||||
            APB_SARADC.int_clr.adc2_done = 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR0_HIGH) {
 | 
			
		||||
        APB_SARADC.int_clr.thres0_high = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR0_LOW) {
 | 
			
		||||
        APB_SARADC.int_clr.thres0_low = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR1_HIGH) {
 | 
			
		||||
        APB_SARADC.int_clr.thres1_high = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (intr & ADC_DIGI_INTR_MASK_MONITOR1_LOW) {
 | 
			
		||||
        APB_SARADC.int_clr.thres1_low = 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -478,7 +495,32 @@ static inline void adc_ll_digi_intr_clear(adc_ll_num_t adc_n, adc_digi_intr_t in
 | 
			
		||||
 */
 | 
			
		||||
static inline uint32_t adc_ll_digi_get_intr_status(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    uint32_t int_st = APB_SARADC.int_st.val;
 | 
			
		||||
    uint32_t ret_msk = 0;
 | 
			
		||||
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        if (int_st & APB_SARADC_ADC1_DONE_INT_ST_M) {
 | 
			
		||||
            ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    } else { // adc_n == ADC_NUM_2
 | 
			
		||||
        if (int_st & APB_SARADC_ADC2_DONE_INT_ST_M) {
 | 
			
		||||
            ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (int_st & APB_SARADC_THRES0_HIGH_INT_ST) {
 | 
			
		||||
        ret_msk |= ADC_DIGI_INTR_MASK_MONITOR0_HIGH;
 | 
			
		||||
    }
 | 
			
		||||
    if (int_st & APB_SARADC_THRES0_LOW_INT_ST_M) {
 | 
			
		||||
        ret_msk |= ADC_DIGI_INTR_MASK_MONITOR0_LOW;
 | 
			
		||||
    }
 | 
			
		||||
    if (int_st & APB_SARADC_THRES1_HIGH_INT_ST_M) {
 | 
			
		||||
        ret_msk |= ADC_DIGI_INTR_MASK_MONITOR1_HIGH;
 | 
			
		||||
    }
 | 
			
		||||
    if (int_st & APB_SARADC_THRES1_LOW_INT_ST_M) {
 | 
			
		||||
        ret_msk |= ADC_DIGI_INTR_MASK_MONITOR1_LOW;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret_msk;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -528,7 +570,8 @@ static inline void adc_ll_digi_reset(void)
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_pwdet_set_cct(uint32_t cct)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    /* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
 | 
			
		||||
    RTCCNTL.sensor_ctrl.sar2_pwdet_cct = cct;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -539,153 +582,32 @@ static inline void adc_ll_pwdet_set_cct(uint32_t cct)
 | 
			
		||||
 */
 | 
			
		||||
static inline uint32_t adc_ll_pwdet_get_cct(void)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    RTC controller setting
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
/**
 | 
			
		||||
 * Set adc output data format for RTC controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note ESP32S2 RTC controller only support 13bit.
 | 
			
		||||
 * @prarm adc_n ADC unit.
 | 
			
		||||
 * @prarm bits Output data bits width option.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_width_t bits)
 | 
			
		||||
{
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable adc channel to start convert.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Only one channel can be selected for once measurement.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param channel ADC channel number for each ADCn.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Disable adc channel to start convert.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Only one channel can be selected in once measurement.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param channel ADC channel number for each ADCn.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n, int channel)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Start conversion once by software for RTC controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @note It may be block to wait conversion idle for ADC1.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param channel ADC channel number for each ADCn.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check the conversion done flag for each ADCn for RTC controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @return
 | 
			
		||||
 *      -true  : The conversion process is finish.
 | 
			
		||||
 *      -false : The conversion process is not finish.
 | 
			
		||||
 */
 | 
			
		||||
static inline bool adc_ll_rtc_convert_is_done(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the converted value for each ADCn for RTC controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @return
 | 
			
		||||
 *      - Converted value.
 | 
			
		||||
 */
 | 
			
		||||
static inline int adc_ll_rtc_get_convert_value(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ADC module RTC output data invert or not.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param inv_en data invert or not.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable ADCn conversion complete interrupt for RTC controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_intr_enable(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Disable ADCn conversion complete interrupt for RTC controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_intr_disable(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reset RTC controller FSM.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_reset(void)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Only ADC2 have arbiter function.
 | 
			
		||||
 * @param cycle range: [0,4].
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    /* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
 | 
			
		||||
    return RTCCNTL.sensor_ctrl.sar2_pwdet_cct;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Analyze whether the obtained raw data is correct.
 | 
			
		||||
 * ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data.
 | 
			
		||||
 * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param raw_data ADC raw data input (convert value).
 | 
			
		||||
 * @return
 | 
			
		||||
 *      - 0: The data is correct to use.
 | 
			
		||||
 *      - 1: The data is invalid. The current controller is not enabled by the arbiter.
 | 
			
		||||
 *      - 2: The data is invalid. The current controller process was interrupted by a higher priority controller.
 | 
			
		||||
 *      - -1: The data is error.
 | 
			
		||||
 *        -  0: The data is correct to use.
 | 
			
		||||
 *        - -1: The data is invalid.
 | 
			
		||||
 */
 | 
			
		||||
static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t adc_n, uint16_t raw_data)
 | 
			
		||||
static inline adc_ll_rtc_raw_data_t adc_ll_analysis_raw_data(adc_ll_num_t adc_n, int raw_data)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        return ADC_RTC_DATA_OK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //The raw data API returns value without channel information. Read value directly from the register
 | 
			
		||||
    if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 13) & 0xF) > 9) {
 | 
			
		||||
        return ADC_RTC_DATA_FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ADC_RTC_DATA_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
@@ -702,13 +624,13 @@ static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
 | 
			
		||||
    //    Bit0  0:SW mode power down  1: SW mode power on */
 | 
			
		||||
    if (manage == ADC_POWER_SW_ON) {
 | 
			
		||||
        APB_SARADC.ctrl.sar_clk_gated = 1;
 | 
			
		||||
        APB_SARADC.ctrl.xpd_sar_force = SENS_FORCE_XPD_SAR_PU;
 | 
			
		||||
        APB_SARADC.ctrl.xpd_sar_force = 3;
 | 
			
		||||
    } else if (manage == ADC_POWER_BY_FSM) {
 | 
			
		||||
        APB_SARADC.ctrl.sar_clk_gated = 1;
 | 
			
		||||
        APB_SARADC.ctrl.xpd_sar_force = SENS_FORCE_XPD_SAR_FSM;
 | 
			
		||||
        APB_SARADC.ctrl.xpd_sar_force = 0;
 | 
			
		||||
    } else if (manage == ADC_POWER_SW_OFF) {
 | 
			
		||||
        APB_SARADC.ctrl.xpd_sar_force = SENS_FORCE_XPD_SAR_PD;
 | 
			
		||||
        APB_SARADC.ctrl.sar_clk_gated = 1;
 | 
			
		||||
        APB_SARADC.ctrl.xpd_sar_force = 2;
 | 
			
		||||
        APB_SARADC.ctrl.sar_clk_gated = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -720,67 +642,17 @@ static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
 | 
			
		||||
 */
 | 
			
		||||
static inline adc_ll_power_t adc_ll_get_power_manage(void)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param div Division factor.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set the attenuation of a particular channel on ADCn.
 | 
			
		||||
 *
 | 
			
		||||
 * @note For any given channel, this function must be called before the first time conversion.
 | 
			
		||||
 *
 | 
			
		||||
 * The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage,
 | 
			
		||||
 * usually 3.3V) requires setting >0dB signal attenuation for that ADC channel.
 | 
			
		||||
 *
 | 
			
		||||
 * When VDD_A is 3.3V:
 | 
			
		||||
 *
 | 
			
		||||
 * - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
 | 
			
		||||
 * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
 | 
			
		||||
 * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
 | 
			
		||||
 * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
 | 
			
		||||
 *
 | 
			
		||||
 * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured
 | 
			
		||||
 * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
 | 
			
		||||
 *
 | 
			
		||||
 * @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
 | 
			
		||||
 *
 | 
			
		||||
 * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges:
 | 
			
		||||
 *
 | 
			
		||||
 * - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV
 | 
			
		||||
 * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV
 | 
			
		||||
 * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV
 | 
			
		||||
 * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV
 | 
			
		||||
 *
 | 
			
		||||
 * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param channel ADCn channel number.
 | 
			
		||||
 * @param atten The attenuation option.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the attenuation of a particular channel on ADCn.
 | 
			
		||||
 *
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param channel ADCn channel number.
 | 
			
		||||
 * @return atten The attenuation option.
 | 
			
		||||
 */
 | 
			
		||||
static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t channel)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    /* Bit1  0:Fsm  1: SW mode
 | 
			
		||||
       Bit0  0:SW mode power down  1: SW mode power on */
 | 
			
		||||
    adc_ll_power_t manage;
 | 
			
		||||
    if (APB_SARADC.ctrl.xpd_sar_force == 3) {
 | 
			
		||||
        manage = ADC_POWER_SW_ON;
 | 
			
		||||
    } else if (APB_SARADC.ctrl.xpd_sar_force == 2) {
 | 
			
		||||
        manage = ADC_POWER_SW_OFF;
 | 
			
		||||
    } else {
 | 
			
		||||
        manage = ADC_POWER_BY_FSM;
 | 
			
		||||
    }
 | 
			
		||||
    return manage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -793,9 +665,9 @@ static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t cha
 | 
			
		||||
 * @param adc_n ADC unit.
 | 
			
		||||
 * @param ctrl ADC controller.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl)
 | 
			
		||||
static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_controller_t ctrl)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
    //NOTE: ULP is removed on C3, please remove ULP related (if there still are any) code and this comment
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -810,7 +682,6 @@ static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode)
 | 
			
		||||
{
 | 
			
		||||
    SENS.sar_meas2_mux.sar2_rtc_force = 0;  // Enable arbiter in wakeup mode
 | 
			
		||||
    if (mode == ADC_ARB_MODE_FIX) {
 | 
			
		||||
        APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0;
 | 
			
		||||
        APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1;
 | 
			
		||||
@@ -866,37 +737,7 @@ static inline void adc_ll_set_arbiter_priority(uint8_t pri_rtc, uint8_t pri_dig,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Force switch ADC2 to RTC controller in sleep mode. Shield arbiter.
 | 
			
		||||
 * In sleep mode, the arbiter is in power-down mode.
 | 
			
		||||
 * Need to switch the controller to RTC to shield the control of the arbiter.
 | 
			
		||||
 * After waking up, it needs to switch to arbiter control.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller.
 | 
			
		||||
 * @note Only support ADC2.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_enable_sleep_controller(void)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Force switch ADC2 to arbiter in wakeup mode.
 | 
			
		||||
 * In sleep mode, the arbiter is in power-down mode.
 | 
			
		||||
 * Need to switch the controller to RTC to shield the control of the arbiter.
 | 
			
		||||
 * After waking up, it needs to switch to arbiter control.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller.
 | 
			
		||||
 * @note Only support ADC2.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_disable_sleep_controller(void)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2094
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ADC calibration code. */
 | 
			
		||||
#define ADC_HAL_CAL_OFFSET_RANGE (4096)
 | 
			
		||||
#define ADC_HAL_CAL_TIMES        (10)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration.
 | 
			
		||||
@@ -910,7 +751,25 @@ static inline void adc_ll_disable_sleep_controller(void)
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2526
 | 
			
		||||
    /* Should be called before writing I2C registers. */
 | 
			
		||||
    SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU);
 | 
			
		||||
 | 
			
		||||
    /* Enable/disable internal connect GND (for calibration). */
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 4);
 | 
			
		||||
        if (internal_gnd) {
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1);
 | 
			
		||||
        } else {
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_DREF_ADDR, 4);
 | 
			
		||||
        if (internal_gnd) {
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 1);
 | 
			
		||||
        } else {
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -920,7 +779,11 @@ static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2526
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -932,7 +795,70 @@ static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n)
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_set_calibration_param(adc_ll_num_t adc_n, uint32_t param)
 | 
			
		||||
{
 | 
			
		||||
    abort(); // TODO ESP32-C3 IDF-2526
 | 
			
		||||
    uint8_t msb = param >> 8;
 | 
			
		||||
    uint8_t lsb = param & 0xFF;
 | 
			
		||||
    if (adc_n == ADC_NUM_1) {
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb);
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb);
 | 
			
		||||
    } else {
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, msb);
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, lsb);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/* Temp code end. */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  Output ADCn inter reference voltage to ADC2 channels.
 | 
			
		||||
 *
 | 
			
		||||
 *  This function routes the internal reference voltage of ADCn to one of
 | 
			
		||||
 *  ADC1's channels. This reference voltage can then be manually measured
 | 
			
		||||
 *  for calibration purposes.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param[in]  adc ADC unit select
 | 
			
		||||
 *  @param[in]  channel ADC1 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)
 | 
			
		||||
{
 | 
			
		||||
    if (en) {
 | 
			
		||||
        REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 3);
 | 
			
		||||
        SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
 | 
			
		||||
 | 
			
		||||
        REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 2);
 | 
			
		||||
        SET_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN);
 | 
			
		||||
        SET_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_GRANT_FORCE);
 | 
			
		||||
        SET_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_APB_FORCE);
 | 
			
		||||
        APB_SARADC.sar_patt_tab[0].sar_patt_tab1 = 0xFFFFFF;
 | 
			
		||||
        APB_SARADC.sar_patt_tab[1].sar_patt_tab1 = 0xFFFFFF;
 | 
			
		||||
        APB_SARADC.onetime_sample.adc1_onetime_sample = 1;
 | 
			
		||||
        APB_SARADC.onetime_sample.onetime_channel = channel;
 | 
			
		||||
        SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU);
 | 
			
		||||
        if (adc == ADC_NUM_1) {
 | 
			
		||||
            /* Config test mux to route v_ref to ADC1 Channels */
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 1);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 1);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 1);
 | 
			
		||||
        } else {
 | 
			
		||||
            /* Config test mux to route v_ref to ADC2 Channels */
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0);
 | 
			
		||||
            REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0);
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 0);
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0);
 | 
			
		||||
        REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0);
 | 
			
		||||
        APB_SARADC.onetime_sample.adc1_onetime_sample = 0;
 | 
			
		||||
        APB_SARADC.onetime_sample.onetime_channel = 0xf;
 | 
			
		||||
        REG_SET_FIELD(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR, 0);
 | 
			
		||||
        REG_SET_FIELD(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_SEL, 0);
 | 
			
		||||
        CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN);
 | 
			
		||||
        CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_GRANT_FORCE);
 | 
			
		||||
        CLEAR_PERI_REG_MASK(APB_SARADC_APB_ADC_ARB_CTRL_REG, APB_SARADC_ADC_ARB_APB_FORCE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
@@ -998,7 +924,8 @@ static inline void adc_ll_adc1_onetime_sample_dis(void)
 | 
			
		||||
 | 
			
		||||
static inline uint32_t adc_ll_adc1_read(void)
 | 
			
		||||
{
 | 
			
		||||
    return APB_SARADC.apb_saradc1_data_status.adc1_data;
 | 
			
		||||
    //On ESP32C3, valid data width is 12-bit
 | 
			
		||||
    return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------adc2------------------------------//
 | 
			
		||||
@@ -1014,8 +941,10 @@ static inline void adc_ll_adc2_onetime_sample_dis(void)
 | 
			
		||||
 | 
			
		||||
static inline uint32_t adc_ll_adc2_read(void)
 | 
			
		||||
{
 | 
			
		||||
    return APB_SARADC.apb_saradc2_data_status.adc2_data;
 | 
			
		||||
    //On ESP32C3, valid data width is 12-bit
 | 
			
		||||
    return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -268,11 +268,11 @@ static inline void adc_ll_digi_output_invert(adc_ll_num_t adc_n, bool inv_en)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sets the number of interval clock cycles for the digital controller to trigger the measurement.
 | 
			
		||||
 * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. Refer to ``adc_digi_clk_t``.
 | 
			
		||||
 * Set the interval clock cycle for the digital controller to trigger the measurement.
 | 
			
		||||
 * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The trigger interval should not be less than the sampling time of the SAR ADC.
 | 
			
		||||
 * @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095.
 | 
			
		||||
 * @note The trigger interval should be larger than the sampling time of the SAR ADC.
 | 
			
		||||
 * @param cycle The clock cycle (trigger interval) of the measurement. Range: 40 ~ 4095.
 | 
			
		||||
 */
 | 
			
		||||
static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -134,6 +134,7 @@ void adc_hal_deinit(void);
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_pwdet_get_cct() adc_ll_pwdet_get_cct()
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
/*---------------------------------------------------------------
 | 
			
		||||
                    RTC controller setting
 | 
			
		||||
---------------------------------------------------------------*/
 | 
			
		||||
@@ -167,6 +168,7 @@ int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value);
 | 
			
		||||
 * @prarm adc_n ADC unit.
 | 
			
		||||
 */
 | 
			
		||||
#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels.
 | 
			
		||||
@@ -213,6 +215,7 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg);
 | 
			
		||||
#include "hal/dma_types.h"
 | 
			
		||||
#include "hal/adc_ll.h"
 | 
			
		||||
#include "hal/dma_types.h"
 | 
			
		||||
#include "esp_err.h"
 | 
			
		||||
 | 
			
		||||
typedef struct adc_dma_hal_context_t {
 | 
			
		||||
    gdma_dev_t          *dev;           //address of the general DMA
 | 
			
		||||
@@ -259,9 +262,7 @@ void adc_hal_onetime_channel(adc_ll_num_t unit, adc_channel_t channel);
 | 
			
		||||
 | 
			
		||||
void adc_hal_set_onetime_atten(adc_atten_t atten);
 | 
			
		||||
 | 
			
		||||
uint32_t adc_hal_adc1_read(void);
 | 
			
		||||
 | 
			
		||||
uint32_t adc_hal_adc2_read(void);
 | 
			
		||||
esp_err_t adc_hal_single_read(adc_ll_num_t unit, int *out_raw);
 | 
			
		||||
 | 
			
		||||
void adc_hal_intr_enable(adc_event_t event);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "soc/soc_caps.h"
 | 
			
		||||
#include "esp_attr.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief ADC unit enumeration.
 | 
			
		||||
@@ -88,7 +89,9 @@ typedef enum {
 | 
			
		||||
    ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit. */
 | 
			
		||||
    ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit. */
 | 
			
		||||
    ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit. */
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
#elif SOC_ADC_MAX_BITWIDTH == 12
 | 
			
		||||
    ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit. */
 | 
			
		||||
#elif SOC_ADC_MAX_BITWIDTH == 13
 | 
			
		||||
    ADC_WIDTH_BIT_13 = 4, /*!< ADC capture width is 13Bit. */
 | 
			
		||||
#endif
 | 
			
		||||
    ADC_WIDTH_MAX,
 | 
			
		||||
@@ -139,7 +142,7 @@ typedef struct {
 | 
			
		||||
            uint8_t reserved:  2;   /*!< reserved0 */
 | 
			
		||||
#endif
 | 
			
		||||
        };
 | 
			
		||||
        uint8_t val;                /*!<Raw data value */
 | 
			
		||||
        uint8_t val;
 | 
			
		||||
    };
 | 
			
		||||
} adc_digi_pattern_table_t;
 | 
			
		||||
 | 
			
		||||
@@ -189,12 +192,13 @@ typedef struct {
 | 
			
		||||
typedef struct {
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t data:     13;  /*!<ADC real output data info. Resolution: 13 bit. */
 | 
			
		||||
            uint32_t channel:   3;  /*!<ADC channel index info.
 | 
			
		||||
                                        If (channel < ADC_CHANNEL_MAX), The data is valid.
 | 
			
		||||
                                        If (channel > ADC_CHANNEL_MAX), The data is invalid. */
 | 
			
		||||
            uint32_t unit:      1;  /*!<ADC unit index info. 0: ADC1; 1: ADC2.  */
 | 
			
		||||
            uint32_t reserved: 15;
 | 
			
		||||
            uint32_t data:          12; /*!<ADC real output data info. Resolution: 12 bit. */
 | 
			
		||||
            uint32_t reserved12:    1;
 | 
			
		||||
            uint32_t channel:       3;  /*!<ADC channel index info.
 | 
			
		||||
                                            If (channel < ADC_CHANNEL_MAX), The data is valid.
 | 
			
		||||
                                            If (channel > ADC_CHANNEL_MAX), The data is invalid. */
 | 
			
		||||
            uint32_t unit:          1;  /*!<ADC unit index info. 0: ADC1; 1: ADC2.  */
 | 
			
		||||
            uint32_t reserved17_31: 15;
 | 
			
		||||
        } type2;
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    };
 | 
			
		||||
@@ -271,7 +275,7 @@ typedef struct {
 | 
			
		||||
                                                 pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. */
 | 
			
		||||
    adc_digi_pattern_table_t *adc_pattern;   /*!<Pointer to pattern table for digital controller. The table size defined by `adc_pattern_len`. */
 | 
			
		||||
#endif
 | 
			
		||||
#if !CONFIG_IDF_TARGET_ESP32
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32S2
 | 
			
		||||
    uint32_t interval;                       /*!<The number of interval clock cycles for the digital controller to trigger the measurement.
 | 
			
		||||
                                                 The unit is the divided clock. Range: 40 ~ 4095.
 | 
			
		||||
                                                 Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. Refer to ``adc_digi_clk_t``.
 | 
			
		||||
@@ -281,6 +285,12 @@ typedef struct {
 | 
			
		||||
    uint32_t dma_eof_num;                    /*!<DMA eof num of adc digital controller.
 | 
			
		||||
                                                 If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated in DMA.
 | 
			
		||||
                                                 Note: The converted data in the DMA in link buffer will be multiple of two bytes. */
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
    uint32_t sample_freq_hz;  /*!< The expected ADC sampling frequency in Hz. Range: 611Hz ~ 83333Hz
 | 
			
		||||
                                   Fs = Fd / interval / 2
 | 
			
		||||
                                   Fs: sampling frequency;
 | 
			
		||||
                                   Fd: digital controller frequency, no larger than 5M for better performance
 | 
			
		||||
                                   interval: interval between 2 measurement trigger signal, the smallest interval should not be smaller than the ADC measurement period, the largest interval should not be larger than 4095 */
 | 
			
		||||
#endif
 | 
			
		||||
} adc_digi_config_t;
 | 
			
		||||
 | 
			
		||||
@@ -326,10 +336,19 @@ typedef struct {
 | 
			
		||||
 * @brief ADC digital controller (DMA mode) interrupt type options.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
    ADC_DIGI_INTR_MASK_MONITOR0_HIGH = BIT(0),
 | 
			
		||||
    ADC_DIGI_INTR_MASK_MONITOR0_LOW  = BIT(1),
 | 
			
		||||
    ADC_DIGI_INTR_MASK_MONITOR1_HIGH = BIT(2),
 | 
			
		||||
    ADC_DIGI_INTR_MASK_MONITOR1_LOW  = BIT(3),
 | 
			
		||||
    ADC_DIGI_INTR_MASK_MEAS_DONE     = BIT(4),
 | 
			
		||||
#else
 | 
			
		||||
    ADC_DIGI_INTR_MASK_MONITOR = 0x1,
 | 
			
		||||
    ADC_DIGI_INTR_MASK_MEAS_DONE = 0x2,
 | 
			
		||||
    ADC_DIGI_INTR_MASK_ALL = 0x3,
 | 
			
		||||
#endif
 | 
			
		||||
} adc_digi_intr_t;
 | 
			
		||||
FLAG_ATTR(adc_digi_intr_t)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief ADC digital controller (DMA mode) filter index options.
 | 
			
		||||
@@ -349,6 +368,9 @@ typedef enum {
 | 
			
		||||
 *        Expression: filter_data = (k-1)/k * last_data + new_data / k.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
    ADC_DIGI_FILTER_DIS = -1,  /*!< Disable filter */
 | 
			
		||||
#endif
 | 
			
		||||
    ADC_DIGI_FILTER_IIR_2 = 0, /*!<The filter mode is first-order IIR filter. The coefficient is 2. */
 | 
			
		||||
    ADC_DIGI_FILTER_IIR_4,     /*!<The filter mode is first-order IIR filter. The coefficient is 4. */
 | 
			
		||||
    ADC_DIGI_FILTER_IIR_8,     /*!<The filter mode is first-order IIR filter. The coefficient is 8. */
 | 
			
		||||
@@ -390,8 +412,14 @@ typedef enum {
 | 
			
		||||
 *        MONITOR_LOW: If ADC_OUT <  threshold, Generates monitor interrupt.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
    ADC_DIGI_MONITOR_DIS = 0,  /*!<Disable monitor. */
 | 
			
		||||
    ADC_DIGI_MONITOR_EN,       /*!<If ADC_OUT <  threshold, Generates monitor interrupt. */
 | 
			
		||||
                               /*!<If ADC_OUT >  threshold, Generates monitor interrupt. */
 | 
			
		||||
#else
 | 
			
		||||
    ADC_DIGI_MONITOR_HIGH = 0,  /*!<If ADC_OUT >  threshold, Generates monitor interrupt. */
 | 
			
		||||
    ADC_DIGI_MONITOR_LOW,       /*!<If ADC_OUT <  threshold, Generates monitor interrupt. */
 | 
			
		||||
#endif
 | 
			
		||||
    ADC_DIGI_MONITOR_MAX
 | 
			
		||||
} adc_digi_monitor_mode_t;
 | 
			
		||||
 | 
			
		||||
@@ -407,7 +435,12 @@ typedef struct {
 | 
			
		||||
    adc_channel_t channel;          /*!<Set adc channel number for monitor.
 | 
			
		||||
                                        For ESP32-S2, it's always `ADC_CHANNEL_MAX` */
 | 
			
		||||
    adc_digi_monitor_mode_t mode;   /*!<Set adc monitor mode. See ``adc_digi_monitor_mode_t``. */
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32C3
 | 
			
		||||
    uint32_t h_threshold;             /*!<Set monitor threshold of adc digital controller. */
 | 
			
		||||
    uint32_t l_threshold;             /*!<Set monitor threshold of adc digital controller. */
 | 
			
		||||
#else
 | 
			
		||||
    uint32_t threshold;             /*!<Set monitor threshold of adc digital controller. */
 | 
			
		||||
#endif
 | 
			
		||||
} adc_digi_monitor_t;
 | 
			
		||||
 | 
			
		||||
#endif // CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,7 @@
 | 
			
		||||
#define SOC_ADC_PATT_LEN_MAX            (16)
 | 
			
		||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 8: 10)
 | 
			
		||||
#define SOC_ADC_MAX_CHANNEL_NUM         (10)
 | 
			
		||||
#define SOC_ADC_MAX_BITWIDTH            (12)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if adc support digital controller (DMA) mode.
 | 
			
		||||
@@ -87,6 +88,7 @@
 | 
			
		||||
 *      - 0 : not support;
 | 
			
		||||
 */
 | 
			
		||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 0)
 | 
			
		||||
#define SOC_ADC_SUPPORT_RTC_CTRL        1
 | 
			
		||||
 | 
			
		||||
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
 | 
			
		||||
#if SOC_CAPS_ECO_VER >= 1
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,504 +0,0 @@
 | 
			
		||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
#ifndef _SOC_SENS_STRUCT_H_
 | 
			
		||||
#define _SOC_SENS_STRUCT_H_
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef volatile struct {
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar1_clk_div:    8;                                   /*clock divider*/
 | 
			
		||||
            uint32_t reserved8:      10;
 | 
			
		||||
            uint32_t sar1_clk_gated:  1;
 | 
			
		||||
            uint32_t sar1_sample_num: 8;
 | 
			
		||||
            uint32_t reserved27:      1;
 | 
			
		||||
            uint32_t sar1_data_inv:   1;                                   /*Invert SAR ADC1 data*/
 | 
			
		||||
            uint32_t sar1_int_en:     1;                                   /*enable saradc1 to send out interrupt*/
 | 
			
		||||
            uint32_t reserved30:      2;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_reader1_ctrl;
 | 
			
		||||
    uint32_t sar_reader1_status;                                           /**/
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:              24;
 | 
			
		||||
            uint32_t force_xpd_amp:           2;
 | 
			
		||||
            uint32_t amp_rst_fb_force:        2;
 | 
			
		||||
            uint32_t amp_short_ref_force:     2;
 | 
			
		||||
            uint32_t amp_short_ref_gnd_force: 2;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_meas1_ctrl1;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t meas1_data_sar:   16;                                 /*SAR ADC1 data*/
 | 
			
		||||
            uint32_t meas1_done_sar:    1;                                 /*SAR ADC1 conversion done indication*/
 | 
			
		||||
            uint32_t meas1_start_sar:   1;                                 /*SAR ADC1 controller (in RTC) starts conversion*/
 | 
			
		||||
            uint32_t meas1_start_force: 1;                                 /*1: SAR ADC1 controller (in RTC) is started by SW*/
 | 
			
		||||
            uint32_t sar1_en_pad:      12;                                 /*SAR ADC1 pad enable bitmap*/
 | 
			
		||||
            uint32_t sar1_en_pad_force: 1;                                 /*1: SAR ADC1 pad enable bitmap is controlled by SW*/
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_meas1_ctrl2;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:     31;
 | 
			
		||||
            uint32_t sar1_dig_force: 1;                                    /*1: SAR ADC1 controlled by DIG ADC1 CTRL*/
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_meas1_mux;
 | 
			
		||||
    uint32_t sar_atten1;                                                   /*2-bit attenuation for each pad*/
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar_amp_wait1:16;
 | 
			
		||||
            uint32_t sar_amp_wait2:16;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_amp_ctrl1;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar1_dac_xpd_fsm_idle:      1;
 | 
			
		||||
            uint32_t xpd_sar_amp_fsm_idle:       1;
 | 
			
		||||
            uint32_t amp_rst_fb_fsm_idle:        1;
 | 
			
		||||
            uint32_t amp_short_ref_fsm_idle:     1;
 | 
			
		||||
            uint32_t amp_short_ref_gnd_fsm_idle: 1;
 | 
			
		||||
            uint32_t xpd_sar_fsm_idle:           1;
 | 
			
		||||
            uint32_t sar_rstb_fsm_idle:          1;
 | 
			
		||||
            uint32_t reserved7:                  9;
 | 
			
		||||
            uint32_t sar_amp_wait3:             16;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_amp_ctrl2;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar1_dac_xpd_fsm:      4;
 | 
			
		||||
            uint32_t xpd_sar_amp_fsm:       4;
 | 
			
		||||
            uint32_t amp_rst_fb_fsm:        4;
 | 
			
		||||
            uint32_t amp_short_ref_fsm:     4;
 | 
			
		||||
            uint32_t amp_short_ref_gnd_fsm: 4;
 | 
			
		||||
            uint32_t xpd_sar_fsm:           4;
 | 
			
		||||
            uint32_t sar_rstb_fsm:          4;
 | 
			
		||||
            uint32_t reserved28:            4;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_amp_ctrl3;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar2_clk_div:        8;                               /*clock divider*/
 | 
			
		||||
            uint32_t reserved8:           8;
 | 
			
		||||
            uint32_t sar2_wait_arb_cycle: 2;                               /*wait arbit stable after sar_done*/
 | 
			
		||||
            uint32_t sar2_clk_gated:      1;
 | 
			
		||||
            uint32_t sar2_sample_num:     8;
 | 
			
		||||
            uint32_t reserved27:          2;
 | 
			
		||||
            uint32_t sar2_data_inv:       1;                               /*Invert SAR ADC2 data*/
 | 
			
		||||
            uint32_t sar2_int_en:         1;                               /*enable saradc2 to send out interrupt*/
 | 
			
		||||
            uint32_t reserved31:          1;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_reader2_ctrl;
 | 
			
		||||
    uint32_t sar_reader2_status;                                           /**/
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar2_cntl_state:   3;                                 /*saradc2_cntl_fsm*/
 | 
			
		||||
            uint32_t sar2_pwdet_cal_en: 1;                                 /*rtc control pwdet enable*/
 | 
			
		||||
            uint32_t sar2_pkdet_cal_en: 1;                                 /*rtc control pkdet enable*/
 | 
			
		||||
            uint32_t sar2_en_test:      1;                                 /*SAR2_EN_TEST*/
 | 
			
		||||
            uint32_t sar2_rstb_force:   2;
 | 
			
		||||
            uint32_t sar2_standby_wait: 8;
 | 
			
		||||
            uint32_t sar2_rstb_wait:    8;
 | 
			
		||||
            uint32_t sar2_xpd_wait:     8;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_meas2_ctrl1;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t meas2_data_sar:   16;                                 /*SAR ADC2 data*/
 | 
			
		||||
            uint32_t meas2_done_sar:    1;                                 /*SAR ADC2 conversion done indication*/
 | 
			
		||||
            uint32_t meas2_start_sar:   1;                                 /*SAR ADC2 controller (in RTC) starts conversion*/
 | 
			
		||||
            uint32_t meas2_start_force: 1;                                 /*1: SAR ADC2 controller (in RTC) is started by SW*/
 | 
			
		||||
            uint32_t sar2_en_pad:      12;                                 /*SAR ADC2 pad enable bitmap*/
 | 
			
		||||
            uint32_t sar2_en_pad_force: 1;                                 /*1: SAR ADC2 pad enable bitmap is controlled by SW*/
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_meas2_ctrl2;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:     28;
 | 
			
		||||
            uint32_t sar2_pwdet_cct: 3;                                    /*SAR2_PWDET_CCT*/
 | 
			
		||||
            uint32_t sar2_rtc_force: 1;                                    /*in sleep  force to use rtc to control ADC*/
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_meas2_mux;
 | 
			
		||||
    uint32_t sar_atten2;                                                   /*2-bit attenuation for each pad*/
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:    29;
 | 
			
		||||
            uint32_t force_xpd_sar: 2;
 | 
			
		||||
            uint32_t sarclk_en:     1;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_power_xpd_sar;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t i2c_slave_addr1:   11;
 | 
			
		||||
            uint32_t i2c_slave_addr0:   11;
 | 
			
		||||
            uint32_t meas_status:        8;
 | 
			
		||||
            uint32_t reserved30:         2;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_slave_addr1;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t i2c_slave_addr3:11;
 | 
			
		||||
            uint32_t i2c_slave_addr2:11;
 | 
			
		||||
            uint32_t reserved22:     10;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_slave_addr2;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t i2c_slave_addr5:11;
 | 
			
		||||
            uint32_t i2c_slave_addr4:11;
 | 
			
		||||
            uint32_t reserved22:     10;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_slave_addr3;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t i2c_slave_addr7:11;
 | 
			
		||||
            uint32_t i2c_slave_addr6:11;
 | 
			
		||||
            uint32_t reserved22:     10;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_slave_addr4;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t tsens_out:            8;                              /*temperature sensor data out*/
 | 
			
		||||
            uint32_t tsens_ready:          1;                              /*indicate temperature sensor out ready*/
 | 
			
		||||
            uint32_t reserved9:            3;
 | 
			
		||||
            uint32_t tsens_int_en:         1;                              /*enable temperature sensor to send out interrupt*/
 | 
			
		||||
            uint32_t tsens_in_inv:         1;                              /*invert temperature sensor data*/
 | 
			
		||||
            uint32_t tsens_clk_div:        8;                              /*temperature sensor clock divider*/
 | 
			
		||||
            uint32_t tsens_power_up:       1;                              /*temperature sensor power up*/
 | 
			
		||||
            uint32_t tsens_power_up_force: 1;                              /*1: dump out & power up controlled by SW*/
 | 
			
		||||
            uint32_t tsens_dump_out:       1;                              /*temperature sensor dump out*/
 | 
			
		||||
            uint32_t reserved25:           7;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_tctrl;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t tsens_xpd_wait: 12;
 | 
			
		||||
            uint32_t tsens_xpd_force: 2;
 | 
			
		||||
            uint32_t tsens_clk_inv:   1;
 | 
			
		||||
            uint32_t reserved15:     17;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_tctrl2;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar_i2c_ctrl:       28;                               /*I2C control data*/
 | 
			
		||||
            uint32_t sar_i2c_start:       1;                               /*start I2C*/
 | 
			
		||||
            uint32_t sar_i2c_start_force: 1;                               /*1: I2C started by SW*/
 | 
			
		||||
            uint32_t reserved30:          2;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_i2c_ctrl;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_outen:        15;                               /*touch controller output enable*/
 | 
			
		||||
            uint32_t touch_status_clr:    1;                               /*clear all touch active status*/
 | 
			
		||||
            uint32_t touch_data_sel:      2;                               /*3: smooth data 2: baseline 1 0: raw_data*/
 | 
			
		||||
            uint32_t touch_denoise_end:   1;                               /*touch_denoise_done*/
 | 
			
		||||
            uint32_t touch_unit_end:      1;                               /*touch_unit_done*/
 | 
			
		||||
            uint32_t touch_approach_pad2: 4;                               /*indicate which pad is approach pad2*/
 | 
			
		||||
            uint32_t touch_approach_pad1: 4;                               /*indicate which pad is approach pad1*/
 | 
			
		||||
            uint32_t touch_approach_pad0: 4;                               /*indicate which pad is approach pad0*/
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_touch_conf;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t thresh:       22;                                     /*Finger threshold for touch pad 1*/
 | 
			
		||||
            uint32_t reserved22:   10;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } touch_thresh[14];
 | 
			
		||||
    uint32_t reserved_98;
 | 
			
		||||
    uint32_t reserved_9c;
 | 
			
		||||
    uint32_t reserved_a0;
 | 
			
		||||
    uint32_t reserved_a4;
 | 
			
		||||
    uint32_t reserved_a8;
 | 
			
		||||
    uint32_t reserved_ac;
 | 
			
		||||
    uint32_t reserved_b0;
 | 
			
		||||
    uint32_t reserved_b4;
 | 
			
		||||
    uint32_t reserved_b8;
 | 
			
		||||
    uint32_t reserved_bc;
 | 
			
		||||
    uint32_t reserved_c0;
 | 
			
		||||
    uint32_t reserved_c4;
 | 
			
		||||
    uint32_t reserved_c8;
 | 
			
		||||
    uint32_t reserved_cc;
 | 
			
		||||
    uint32_t reserved_d0;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_pad_active: 15;                                 /*touch active status*/
 | 
			
		||||
            uint32_t touch_channel_clr:15;                                 /*Clear touch channel*/
 | 
			
		||||
            uint32_t reserved30:        1;
 | 
			
		||||
            uint32_t touch_meas_done:   1;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_touch_chn_st;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_denoise_data:22;                                /*the counter for touch pad 0*/
 | 
			
		||||
            uint32_t touch_scan_curr:    4;
 | 
			
		||||
            uint32_t reserved26:         6;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_touch_status0;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_pad1_data:    22;
 | 
			
		||||
            uint32_t reserved22:          7;
 | 
			
		||||
            uint32_t touch_pad_debounce:  3;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_touch_status[14];
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_slp_data:    22;
 | 
			
		||||
            uint32_t reserved22:         7;
 | 
			
		||||
            uint32_t touch_slp_debounce: 3;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_touch_status15;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_approach_pad2_cnt: 8;
 | 
			
		||||
            uint32_t touch_approach_pad1_cnt: 8;
 | 
			
		||||
            uint32_t touch_approach_pad0_cnt: 8;
 | 
			
		||||
            uint32_t touch_slp_approach_cnt:  8;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_touch_status16;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sw_fstep:          16;                                /*frequency step for CW generator*/
 | 
			
		||||
            uint32_t sw_tone_en:         1;                                /*1: enable CW generator*/
 | 
			
		||||
            uint32_t debug_bit_sel:      5;
 | 
			
		||||
            uint32_t dac_dig_force:      1;                                /*1: DAC1 & DAC2 use DMA*/
 | 
			
		||||
            uint32_t dac_clk_force_low:  1;                                /*1: force PDAC_CLK to low*/
 | 
			
		||||
            uint32_t dac_clk_force_high: 1;                                /*1: force PDAC_CLK to high*/
 | 
			
		||||
            uint32_t dac_clk_inv:        1;                                /*1: invert PDAC_CLK*/
 | 
			
		||||
            uint32_t reserved26:         6;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_dac_ctrl1;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t dac_dc1:    8;                                        /*DC offset for DAC1 CW generator*/
 | 
			
		||||
            uint32_t dac_dc2:    8;                                        /*DC offset for DAC2 CW generator*/
 | 
			
		||||
            uint32_t dac_scale1: 2;                                        /*00: no scale*/
 | 
			
		||||
            uint32_t dac_scale2: 2;                                        /*00: no scale*/
 | 
			
		||||
            uint32_t dac_inv1:   2;                                        /*00: do not invert any bits*/
 | 
			
		||||
            uint32_t dac_inv2:   2;                                        /*00: do not invert any bits*/
 | 
			
		||||
            uint32_t dac_cw_en1: 1;                                        /*1: to select CW generator as source to PDAC1_DAC[7:0]*/
 | 
			
		||||
            uint32_t dac_cw_en2: 1;                                        /*1: to select CW generator as source to PDAC2_DAC[7:0]*/
 | 
			
		||||
            uint32_t reserved26: 6;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_dac_ctrl2;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:        25;
 | 
			
		||||
            uint32_t dbg_trigger:       1;                                 /*trigger cocpu debug registers*/
 | 
			
		||||
            uint32_t clk_en_st:         1;                                 /*check cocpu whether clk on*/
 | 
			
		||||
            uint32_t reset_n:           1;                                 /*check cocpu whether in reset state*/
 | 
			
		||||
            uint32_t eoi:               1;                                 /*check cocpu whether in interrupt state*/
 | 
			
		||||
            uint32_t trap:              1;                                 /*check cocpu whether in trap state*/
 | 
			
		||||
            uint32_t ebreak:            1;                                 /*check cocpu whether in ebreak*/
 | 
			
		||||
            uint32_t reserved31:        1;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_state;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_done:                             1;            /*int from touch done*/
 | 
			
		||||
            uint32_t touch_inactive:                         1;            /*int from touch inactive*/
 | 
			
		||||
            uint32_t touch_active:                           1;            /*int from touch active*/
 | 
			
		||||
            uint32_t saradc1:                                1;            /*int from saradc1*/
 | 
			
		||||
            uint32_t saradc2:                                1;            /*int from saradc2*/
 | 
			
		||||
            uint32_t tsens:                                  1;            /*int from tsens*/
 | 
			
		||||
            uint32_t start:                                  1;            /*int from start*/
 | 
			
		||||
            uint32_t sw:                                     1;            /*int from software*/
 | 
			
		||||
            uint32_t swd:                                    1;            /*int from super watch dog*/
 | 
			
		||||
            uint32_t touch_timeout:                          1;
 | 
			
		||||
            uint32_t touch_approach_loop_done:               1;
 | 
			
		||||
            uint32_t touch_scan_done:                        1;
 | 
			
		||||
            uint32_t reserved12:                            20;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_int_raw;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_done:                             1;
 | 
			
		||||
            uint32_t touch_inactive:                         1;
 | 
			
		||||
            uint32_t touch_active:                           1;
 | 
			
		||||
            uint32_t saradc1:                                1;
 | 
			
		||||
            uint32_t saradc2:                                1;
 | 
			
		||||
            uint32_t tsens:                                  1;
 | 
			
		||||
            uint32_t start:                                  1;
 | 
			
		||||
            uint32_t sw:                                     1;            /*cocpu int enable*/
 | 
			
		||||
            uint32_t swd:                                    1;
 | 
			
		||||
            uint32_t touch_timeout:                          1;
 | 
			
		||||
            uint32_t touch_approach_loop_done:               1;
 | 
			
		||||
            uint32_t touch_scan_done:                        1;
 | 
			
		||||
            uint32_t reserved12:                            20;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_int_ena;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_done:                            1;
 | 
			
		||||
            uint32_t touch_inactive:                        1;
 | 
			
		||||
            uint32_t touch_active:                          1;
 | 
			
		||||
            uint32_t saradc1:                               1;
 | 
			
		||||
            uint32_t saradc2:                               1;
 | 
			
		||||
            uint32_t tsens:                                 1;
 | 
			
		||||
            uint32_t start:                                 1;
 | 
			
		||||
            uint32_t sw:                                    1;             /*cocpu int status*/
 | 
			
		||||
            uint32_t swd:                                   1;
 | 
			
		||||
            uint32_t touch_timeout:                         1;
 | 
			
		||||
            uint32_t touch_approach_loop_done:              1;
 | 
			
		||||
            uint32_t touch_scan_done:                       1;
 | 
			
		||||
            uint32_t reserved12:                           20;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_int_st;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_done:                             1;
 | 
			
		||||
            uint32_t touch_inactive:                         1;
 | 
			
		||||
            uint32_t touch_active:                           1;
 | 
			
		||||
            uint32_t saradc1:                                1;
 | 
			
		||||
            uint32_t saradc2:                                1;
 | 
			
		||||
            uint32_t tsens:                                  1;
 | 
			
		||||
            uint32_t start:                                  1;
 | 
			
		||||
            uint32_t sw:                                     1;            /*cocpu int clear*/
 | 
			
		||||
            uint32_t swd:                                    1;
 | 
			
		||||
            uint32_t touch_timeout:                          1;
 | 
			
		||||
            uint32_t touch_approach_loop_done:               1;
 | 
			
		||||
            uint32_t touch_scan_done:                        1;
 | 
			
		||||
            uint32_t reserved12:                            20;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_int_clr;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t pc:            13;                                    /*cocpu Program counter*/
 | 
			
		||||
            uint32_t mem_vld:        1;                                    /*cocpu mem valid output*/
 | 
			
		||||
            uint32_t mem_rdy:        1;                                    /*cocpu mem ready input*/
 | 
			
		||||
            uint32_t mem_wen:        4;                                    /*cocpu mem write enable output*/
 | 
			
		||||
            uint32_t mem_addr:      13;                                    /*cocpu mem address output*/
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_debug;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:       28;
 | 
			
		||||
            uint32_t xpd_hall:         1;                                  /*Power on hall sensor and connect to VP and VN*/
 | 
			
		||||
            uint32_t xpd_hall_force:   1;                                  /*1: XPD HALL is controlled by SW. 0: XPD HALL is controlled by FSM in ULP-coprocessor*/
 | 
			
		||||
            uint32_t hall_phase:       1;                                  /*Reverse phase of hall sensor*/
 | 
			
		||||
            uint32_t hall_phase_force: 1;                                  /*1: HALL PHASE is controlled by SW  0: HALL PHASE is controlled by FSM in ULP-coprocessor*/
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_hall_ctrl;
 | 
			
		||||
    uint32_t sar_nouse;                                                    /**/
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:     26;
 | 
			
		||||
            uint32_t dac_clk_en:     1;
 | 
			
		||||
            uint32_t rtc_i2c_clk_en: 1;
 | 
			
		||||
            uint32_t reserved28:     1;
 | 
			
		||||
            uint32_t tsens_clk_en:   1;
 | 
			
		||||
            uint32_t saradc_clk_en:  1;
 | 
			
		||||
            uint32_t iomux_clk_en:   1;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_peri_clk_gate_conf;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t reserved0:    25;
 | 
			
		||||
            uint32_t reset:         1;
 | 
			
		||||
            uint32_t dac_reset:     1;
 | 
			
		||||
            uint32_t rtc_i2c_reset: 1;
 | 
			
		||||
            uint32_t reserved28:    1;
 | 
			
		||||
            uint32_t tsens_reset:   1;
 | 
			
		||||
            uint32_t saradc_reset:  1;
 | 
			
		||||
            uint32_t reserved31:    1;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_peri_reset_conf;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_done_w1ts:                             1;
 | 
			
		||||
            uint32_t touch_inactive_w1ts:                         1;
 | 
			
		||||
            uint32_t touch_active_w1ts:                           1;
 | 
			
		||||
            uint32_t saradc1_w1ts:                                1;
 | 
			
		||||
            uint32_t saradc2_w1ts:                                1;
 | 
			
		||||
            uint32_t tsens_w1ts:                                  1;
 | 
			
		||||
            uint32_t start_w1ts:                                  1;
 | 
			
		||||
            uint32_t sw_w1ts:                                     1;
 | 
			
		||||
            uint32_t swd_w1ts:                                    1;
 | 
			
		||||
            uint32_t touch_timeout_w1ts:                          1;
 | 
			
		||||
            uint32_t touch_approach_loop_done_w1ts:               1;
 | 
			
		||||
            uint32_t touch_scan_done_w1ts:                        1;
 | 
			
		||||
            uint32_t reserved12:                                 20;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_int_ena_w1ts;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t touch_done_w1tc:                             1;
 | 
			
		||||
            uint32_t touch_inactive_w1tc:                         1;
 | 
			
		||||
            uint32_t touch_active_w1tc:                           1;
 | 
			
		||||
            uint32_t saradc1_w1tc:                                1;
 | 
			
		||||
            uint32_t saradc2_w1tc:                                1;
 | 
			
		||||
            uint32_t tsens_w1tc:                                  1;
 | 
			
		||||
            uint32_t start_w1tc:                                  1;
 | 
			
		||||
            uint32_t sw_w1tc:                                     1;
 | 
			
		||||
            uint32_t swd_w1tc:                                    1;
 | 
			
		||||
            uint32_t touch_timeout_w1tc:                          1;
 | 
			
		||||
            uint32_t touch_approach_loop_done_w1tc:               1;
 | 
			
		||||
            uint32_t touch_scan_done_w1tc:                        1;
 | 
			
		||||
            uint32_t reserved12:                                 20;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sar_cocpu_int_ena_w1tc;
 | 
			
		||||
    union {
 | 
			
		||||
        struct {
 | 
			
		||||
            uint32_t sar_date:  28;
 | 
			
		||||
            uint32_t reserved28: 4;
 | 
			
		||||
        };
 | 
			
		||||
        uint32_t val;
 | 
			
		||||
    } sardate;
 | 
			
		||||
} sens_dev_t;
 | 
			
		||||
extern sens_dev_t SENS;
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  /* _SOC_SENS_STRUCT_H_ */
 | 
			
		||||
@@ -102,19 +102,17 @@
 | 
			
		||||
#define SOC_AES_SUPPORT_AES_256 (1)
 | 
			
		||||
 | 
			
		||||
/*-------------------------- ADC CAPS -------------------------------*/
 | 
			
		||||
#define SOC_ADC_PERIPH_NUM              (2)
 | 
			
		||||
#define SOC_ADC_PATT_LEN_MAX            (16)
 | 
			
		||||
 | 
			
		||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 5 : 1)
 | 
			
		||||
#define SOC_ADC_MAX_CHANNEL_NUM         (10)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if adc support digital controller (DMA) mode.
 | 
			
		||||
 * @value
 | 
			
		||||
 *      - 1 : support;
 | 
			
		||||
 *      - 0 : not support;
 | 
			
		||||
 */
 | 
			
		||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) 1
 | 
			
		||||
#define SOC_ADC_PERIPH_NUM                      (2)
 | 
			
		||||
#define SOC_ADC_PATT_LEN_MAX                    (16)
 | 
			
		||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM)         ((PERIPH_NUM==0)? 5 : 1)
 | 
			
		||||
#define SOC_ADC_MAX_CHANNEL_NUM                 (10)
 | 
			
		||||
#define SOC_ADC_MAX_BITWIDTH                    (12)
 | 
			
		||||
#define SOC_ADC_DIGI_FILTER_NUM                 (2)
 | 
			
		||||
#define SOC_ADC_DIGI_MONITOR_NUM                (2)
 | 
			
		||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM)    1
 | 
			
		||||
//F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095
 | 
			
		||||
#define SOC_ADC_SAMPLE_FREQ_THRES_HIGH          83333
 | 
			
		||||
#define SOC_ADC_SAMPLE_FREQ_THRES_LOW           611
 | 
			
		||||
 | 
			
		||||
/*-------------------------- APB BACKUP DMA CAPS -------------------------------*/
 | 
			
		||||
#define SOC_APB_BACKUP_DMA              (1)
 | 
			
		||||
 
 | 
			
		||||
@@ -55,9 +55,9 @@
 | 
			
		||||
/*-------------------------- ADC CAPS ----------------------------------------*/
 | 
			
		||||
#define SOC_ADC_PERIPH_NUM              (2)
 | 
			
		||||
#define SOC_ADC_PATT_LEN_MAX            (16)
 | 
			
		||||
 | 
			
		||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
 | 
			
		||||
#define SOC_ADC_MAX_CHANNEL_NUM         (10)
 | 
			
		||||
#define SOC_ADC_MAX_BITWIDTH            (13)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if adc support digital controller (DMA) mode.
 | 
			
		||||
@@ -66,6 +66,7 @@
 | 
			
		||||
 *      - 0 : not support;
 | 
			
		||||
 */
 | 
			
		||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 1)
 | 
			
		||||
#define SOC_ADC_SUPPORT_RTC_CTRL        1
 | 
			
		||||
 | 
			
		||||
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
 | 
			
		||||
#define SOC_BROWNOUT_RESET_SUPPORTED 1
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,10 @@
 | 
			
		||||
 | 
			
		||||
#define SOC_ADC_PERIPH_NUM              (2)
 | 
			
		||||
#define SOC_ADC_PATT_LEN_MAX            (16)
 | 
			
		||||
 | 
			
		||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
 | 
			
		||||
#define SOC_ADC_MAX_CHANNEL_NUM         (10)
 | 
			
		||||
#define SOC_ADC_MAX_BITWIDTH            (13)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if adc support digital controller (DMA) mode.
 | 
			
		||||
@@ -26,3 +27,4 @@
 | 
			
		||||
 *      - 0 : not support;
 | 
			
		||||
 */
 | 
			
		||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 1)
 | 
			
		||||
#define SOC_ADC_SUPPORT_RTC_CTRL        1
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,12 @@
 | 
			
		||||
#include "soc/soc.h"
 | 
			
		||||
#include "soc/soc_caps.h"
 | 
			
		||||
#include "soc/syscon_struct.h"
 | 
			
		||||
 | 
			
		||||
#if SOC_ADC_SUPPORT_RTC_CTRL
 | 
			
		||||
#include "soc/sens_reg.h"
 | 
			
		||||
#include "soc/sens_struct.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
 | 
			
		||||
#include "soc/rtc_io_struct.h"
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -19,16 +19,17 @@
 | 
			
		||||
#include "soc/soc_caps.h"
 | 
			
		||||
 | 
			
		||||
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
 | 
			
		||||
 | 
			
		||||
#include "soc/rtc_io_channel.h"
 | 
			
		||||
#include "soc/rtc_io_reg.h"
 | 
			
		||||
#include "soc/rtc_io_struct.h"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "soc/rtc_cntl_reg.h"
 | 
			
		||||
#include "soc/rtc_cntl_struct.h"
 | 
			
		||||
 | 
			
		||||
#if SOC_ADC_SUPPORT_RTC_CTRL
 | 
			
		||||
#include "soc/sens_struct.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ Reading voltage on ADC1 channel 0 ({IDF_TARGET_ADC1_CH0})::
 | 
			
		||||
        int val = adc1_get_raw(ADC1_CHANNEL_0);
 | 
			
		||||
 | 
			
		||||
The input voltage in the above example is from 0 to 1.1 V (0 dB attenuation). The input range can be extended by setting a higher attenuation, see :cpp:type:`adc_atten_t`.
 | 
			
		||||
An example of using the ADC driver including calibration (discussed below) is available at esp-idf: :example:`peripherals/adc`
 | 
			
		||||
An example of using the ADC driver including calibration (discussed below) is available at esp-idf: :example:`peripherals/adc/adc`
 | 
			
		||||
 | 
			
		||||
Reading voltage on ADC2 channel 7 ({IDF_TARGET_ADC2_CH7})::
 | 
			
		||||
 | 
			
		||||
@@ -95,7 +95,7 @@ Reading voltage on ADC2 channel 7 ({IDF_TARGET_ADC2_CH7})::
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
The reading may fail due to collision with Wi-Fi, should check it.
 | 
			
		||||
An example using the ADC2 driver to read the output of DAC is available in esp-idf: :example:`peripherals/adc2`
 | 
			
		||||
An example using the ADC2 driver to read the output of DAC is available in esp-idf: :example:`peripherals/adc/adc2`
 | 
			
		||||
 | 
			
		||||
.. only:: esp32
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								examples/peripherals/adc/adc_dma/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								examples/peripherals/adc/adc_dma/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
# The following lines of boilerplate have to be in your project's CMakeLists
 | 
			
		||||
# in this exact order for cmake to work correctly
 | 
			
		||||
cmake_minimum_required(VERSION 3.5)
 | 
			
		||||
 | 
			
		||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
			
		||||
project(adc)
 | 
			
		||||
							
								
								
									
										63
									
								
								examples/peripherals/adc/adc_dma/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								examples/peripherals/adc/adc_dma/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
| Supported Targets | ESP32-C3 |
 | 
			
		||||
| ----------------- | -------- |
 | 
			
		||||
 | 
			
		||||
# ADC DMA Example
 | 
			
		||||
 | 
			
		||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
 | 
			
		||||
 | 
			
		||||
This example shows how to use DMA-Read-APIs and Single-Read-APIs to read voltage from GPIO pins via ADC controller.
 | 
			
		||||
 | 
			
		||||
## How to use example
 | 
			
		||||
 | 
			
		||||
### Hardware Required
 | 
			
		||||
 | 
			
		||||
* A development board with ESP32C3 SoC
 | 
			
		||||
* A USB cable for power supply and programming
 | 
			
		||||
 | 
			
		||||
For `single_read` (Single-Read-APIs example), we use `ADC1_CHANNEL_2`, `ADC1_CHANNEL_3`, `ADC1_CHANNEL_4`, `ADC2_CHANNEL_0`. Hence we need to connect voltage sources (0 ~ 3.3V) to GPIO2, GPIO3, GPIO4, GPIO5 respectively.
 | 
			
		||||
 | 
			
		||||
For `continuous_read` (DMA-Read-APIs example), we use `ADC1_CHANNEL_0`, `ADC1_CHANNEL_1` and `ADC2_CHANNEL_0`. Therefore, GPIO0, GPIO1 and GPIO5 should be connected to voltage sources (0 ~ 3.3V).
 | 
			
		||||
 | 
			
		||||
If other ADC units/channels are selected in your application, you need to change the GPIO pin (please refer to the `ESP32C3 Technical Reference Manual`).
 | 
			
		||||
 | 
			
		||||
### Configure the project
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
idf.py menuconfig
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Build and Flash
 | 
			
		||||
 | 
			
		||||
Build the project and flash it to the board, then run monitor tool to view serial output:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
idf.py -p PORT flash monitor
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
(To exit the serial monitor, type ``Ctrl-]``.)
 | 
			
		||||
 | 
			
		||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
 | 
			
		||||
 | 
			
		||||
## Example Output
 | 
			
		||||
 | 
			
		||||
Running this example, you will see the following log output on the serial monitor:
 | 
			
		||||
```
 | 
			
		||||
I (322) ADC1_CH2: 7c8
 | 
			
		||||
I (322) ADC1_CH3: 278
 | 
			
		||||
I (322) ADC1_CH4: d4b
 | 
			
		||||
I (322) ADC2_CH0: 48
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
ADC1_CH0: 61b
 | 
			
		||||
ADC1_CH1: 39b
 | 
			
		||||
ADC2_CH0: 4b
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Troubleshooting
 | 
			
		||||
 | 
			
		||||
* program upload failure
 | 
			
		||||
 | 
			
		||||
    * Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs.
 | 
			
		||||
    * The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again.
 | 
			
		||||
 | 
			
		||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
 | 
			
		||||
							
								
								
									
										2
									
								
								examples/peripherals/adc/adc_dma/main/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								examples/peripherals/adc/adc_dma/main/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
idf_component_register(SRCS "adc_dma_example_main.c"
 | 
			
		||||
                    INCLUDE_DIRS ".")
 | 
			
		||||
							
								
								
									
										126
									
								
								examples/peripherals/adc/adc_dma/main/adc_dma_example_main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								examples/peripherals/adc/adc_dma/main/adc_dma_example_main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "freertos/FreeRTOS.h"
 | 
			
		||||
#include "freertos/task.h"
 | 
			
		||||
#include "freertos/semphr.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
#include "driver/adc.h"
 | 
			
		||||
 | 
			
		||||
#define TIMES 256
 | 
			
		||||
#define DMA_CHANNEL 0
 | 
			
		||||
 | 
			
		||||
static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    esp_err_t ret = ESP_OK;
 | 
			
		||||
    assert(ret == ESP_OK);
 | 
			
		||||
 | 
			
		||||
    adc_digi_init_config_t adc_dma_config = {
 | 
			
		||||
        .max_store_buf_size = 1024,
 | 
			
		||||
        .conv_num_each_intr = 256,
 | 
			
		||||
        .dma_chan = SOC_GDMA_ADC_DMA_CHANNEL,
 | 
			
		||||
        .adc1_chan_mask = adc1_chan_mask,
 | 
			
		||||
        .adc2_chan_mask = adc2_chan_mask,
 | 
			
		||||
    };
 | 
			
		||||
    ret = adc_digi_initialize(&adc_dma_config);
 | 
			
		||||
    assert(ret == ESP_OK);
 | 
			
		||||
 | 
			
		||||
    adc_digi_pattern_table_t adc_pattern[10] = {0};
 | 
			
		||||
 | 
			
		||||
    //Do not set the sampling frequency out of the range between `SOC_ADC_SAMPLE_FREQ_THRES_LOW` and `SOC_ADC_SAMPLE_FREQ_THRES_HIGH`
 | 
			
		||||
    adc_digi_config_t dig_cfg = {
 | 
			
		||||
        .conv_limit_en = 0,
 | 
			
		||||
        .conv_limit_num = 250,
 | 
			
		||||
        .sample_freq_hz = 620,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    dig_cfg.adc_pattern_len = channel_num;
 | 
			
		||||
    for (int i = 0; i < channel_num; i++) {
 | 
			
		||||
        uint8_t unit = ((channel[i] >> 3) & 0x1);
 | 
			
		||||
        uint8_t ch = channel[i] & 0x7;
 | 
			
		||||
        adc_pattern[i].atten = ADC_ATTEN_DB_0;
 | 
			
		||||
        adc_pattern[i].channel = ch;
 | 
			
		||||
        adc_pattern[i].unit = unit;
 | 
			
		||||
    }
 | 
			
		||||
    dig_cfg.adc_pattern = adc_pattern;
 | 
			
		||||
    ret = adc_digi_controller_config(&dig_cfg);
 | 
			
		||||
    assert(ret == ESP_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool check_valid_data(const adc_digi_output_data_t *data)
 | 
			
		||||
{
 | 
			
		||||
    const unsigned int unit = data->type2.unit;
 | 
			
		||||
    if (unit > 2) return false;
 | 
			
		||||
    if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) return false;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void continuous_read(void *arg)
 | 
			
		||||
{
 | 
			
		||||
    esp_err_t ret;
 | 
			
		||||
    uint32_t ret_num = 0;
 | 
			
		||||
    uint8_t result[TIMES] = {0};
 | 
			
		||||
    memset(result, 0xcc, TIMES);
 | 
			
		||||
 | 
			
		||||
    uint16_t adc1_chan_mask = BIT(0) | BIT(1);
 | 
			
		||||
    uint16_t adc2_chan_mask = BIT(0);
 | 
			
		||||
    adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1, (ADC2_CHANNEL_0 | 1 << 3)};
 | 
			
		||||
 | 
			
		||||
    continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t));
 | 
			
		||||
    adc_digi_start();
 | 
			
		||||
 | 
			
		||||
    int n = 20;
 | 
			
		||||
    while(n--) {
 | 
			
		||||
        ret = adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY);
 | 
			
		||||
        for (int i = 0; i < ret_num; i+=4) {
 | 
			
		||||
            adc_digi_output_data_t *p = (void*)&result[i];
 | 
			
		||||
            if (check_valid_data(p)) {
 | 
			
		||||
                printf("ADC%d_CH%d: %x\n", p->type2.unit+1, p->type2.channel, p->type2.data);
 | 
			
		||||
            } else {
 | 
			
		||||
                printf("Invalid data [%d_%d_%x]\n", p->type2.unit+1, p->type2.channel, p->type2.data);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // If you see task WDT in this task, it means the conversion is too fast for the task to handle
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    adc_digi_stop();
 | 
			
		||||
    ret = adc_digi_deinitialize();
 | 
			
		||||
    assert(ret == ESP_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void single_read(void *arg)
 | 
			
		||||
{
 | 
			
		||||
    esp_err_t ret;
 | 
			
		||||
    int adc1_reading[3] = {0xcc};
 | 
			
		||||
    int adc2_reading[1] = {0xcc};
 | 
			
		||||
 | 
			
		||||
    const char TAG_CH[][10] = {"ADC1_CH2", "ADC1_CH3","ADC1_CH4", "ADC2_CH0"};
 | 
			
		||||
 | 
			
		||||
    adc1_config_width(ADC_WIDTH_BIT_DEFAULT);
 | 
			
		||||
    adc1_config_channel_atten(ADC1_CHANNEL_2, ADC_ATTEN_DB_0);
 | 
			
		||||
    adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6);
 | 
			
		||||
    adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0);
 | 
			
		||||
    adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0);
 | 
			
		||||
 | 
			
		||||
    int n = 20;
 | 
			
		||||
    while (n--) {
 | 
			
		||||
 | 
			
		||||
        adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_2);
 | 
			
		||||
        adc1_reading[1] = adc1_get_raw(ADC1_CHANNEL_3);
 | 
			
		||||
        adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4);
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < 3; i++) {
 | 
			
		||||
            ESP_LOGI(TAG_CH[i], "%x", adc1_reading[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]);
 | 
			
		||||
        assert(ret == ESP_OK);
 | 
			
		||||
        ESP_LOGI(TAG_CH[3], "%x", adc2_reading[0]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_main(void)
 | 
			
		||||
{
 | 
			
		||||
    single_read(NULL);
 | 
			
		||||
    continuous_read(NULL);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user