mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
system: reset dma when soft reset
This commit is contained in:
committed by
bot
parent
d35173c147
commit
d7d1dee208
@@ -22,7 +22,7 @@ set(srcs
|
|||||||
"twai.c"
|
"twai.c"
|
||||||
"uart.c")
|
"uart.c")
|
||||||
|
|
||||||
set(includes "include" "${target}/include")
|
set(includes "include" "${target}/include" "esp_private")
|
||||||
|
|
||||||
if(${target} STREQUAL "esp32")
|
if(${target} STREQUAL "esp32")
|
||||||
# SDMMC and MCPWM are in ESP32 only.
|
# SDMMC and MCPWM are in ESP32 only.
|
||||||
@@ -66,7 +66,8 @@ endif()
|
|||||||
if(IDF_TARGET STREQUAL "esp32c3")
|
if(IDF_TARGET STREQUAL "esp32c3")
|
||||||
list(APPEND srcs "gdma.c"
|
list(APPEND srcs "gdma.c"
|
||||||
"spi_slave_hd.c"
|
"spi_slave_hd.c"
|
||||||
"esp32c3/adc.c")
|
"esp32c3/adc.c"
|
||||||
|
"esp32c3/adc2_init_cal.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS "${srcs}"
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
@@ -31,7 +31,6 @@
|
|||||||
#include "hal/adc_types.h"
|
#include "hal/adc_types.h"
|
||||||
#include "hal/adc_hal.h"
|
#include "hal/adc_hal.h"
|
||||||
|
|
||||||
#if !CONFIG_IDF_TARGET_ESP32C3
|
|
||||||
#include "hal/dac_hal.h"
|
#include "hal/dac_hal.h"
|
||||||
#include "hal/adc_hal_conf.h"
|
#include "hal/adc_hal_conf.h"
|
||||||
|
|
||||||
@@ -75,14 +74,6 @@ In ADC2, there're two locks used for different cases:
|
|||||||
|
|
||||||
adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
|
adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
|
||||||
*/
|
*/
|
||||||
// This gets incremented when adc_power_acquire() is called, and decremented when
|
|
||||||
// adc_power_release() is called. ADC is powered down when the value reaches zero.
|
|
||||||
// Should be modified within critical section (ADC_ENTER/EXIT_CRITICAL).
|
|
||||||
static int s_adc_power_on_cnt;
|
|
||||||
|
|
||||||
static void adc_power_on_internal(void);
|
|
||||||
static void adc_power_off_internal(void);
|
|
||||||
|
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
//prevent ADC2 being used by wifi and other tasks at the same time.
|
//prevent ADC2 being used by wifi and other tasks at the same time.
|
||||||
static _lock_t adc2_wifi_lock;
|
static _lock_t adc2_wifi_lock;
|
||||||
@@ -121,7 +112,7 @@ static esp_pm_lock_handle_t s_adc2_arbiter_lock;
|
|||||||
ADC Common
|
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)
|
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);
|
adc_atten_t atten = adc_hal_get_atten(adc_n, chan);
|
||||||
@@ -131,60 +122,36 @@ static uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void adc_power_acquire(void)
|
void adc_power_always_on(void)
|
||||||
{
|
|
||||||
bool powered_on = false;
|
|
||||||
ADC_ENTER_CRITICAL();
|
|
||||||
s_adc_power_on_cnt++;
|
|
||||||
if (s_adc_power_on_cnt == 1) {
|
|
||||||
adc_power_on_internal();
|
|
||||||
powered_on = true;
|
|
||||||
}
|
|
||||||
ADC_EXIT_CRITICAL();
|
|
||||||
if (powered_on) {
|
|
||||||
ESP_LOGV(ADC_TAG, "%s: ADC powered on", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void adc_power_release(void)
|
|
||||||
{
|
|
||||||
bool powered_off = false;
|
|
||||||
ADC_ENTER_CRITICAL();
|
|
||||||
s_adc_power_on_cnt--;
|
|
||||||
/* Sanity check */
|
|
||||||
if (s_adc_power_on_cnt < 0) {
|
|
||||||
ADC_EXIT_CRITICAL();
|
|
||||||
ESP_LOGE(ADC_TAG, "%s called, but s_adc_power_on_cnt == 0", __func__);
|
|
||||||
abort();
|
|
||||||
} else if (s_adc_power_on_cnt == 0) {
|
|
||||||
adc_power_off_internal();
|
|
||||||
powered_off = true;
|
|
||||||
}
|
|
||||||
ADC_EXIT_CRITICAL();
|
|
||||||
if (powered_off) {
|
|
||||||
ESP_LOGV(ADC_TAG, "%s: ADC powered off", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void adc_power_on_internal(void)
|
|
||||||
{
|
{
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
/* Set the power always on to increase precision. */
|
|
||||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||||
ADC_EXIT_CRITICAL();
|
ADC_EXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_power_on(void) __attribute__((alias("adc_power_on_internal")));
|
void adc_power_on(void)
|
||||||
|
{
|
||||||
|
ADC_ENTER_CRITICAL();
|
||||||
|
/* The power FSM controlled mode saves more power, while the ADC noise may get increased. */
|
||||||
|
#ifndef CONFIG_ADC_FORCE_XPD_FSM
|
||||||
|
/* Set the power always on to increase precision. */
|
||||||
|
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||||
|
#else
|
||||||
|
/* Use the FSM to turn off the power while not used to save power. */
|
||||||
|
if (adc_hal_get_power_manage() != ADC_POWER_BY_FSM) {
|
||||||
|
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ADC_EXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
static void adc_power_off_internal(void)
|
void adc_power_off(void)
|
||||||
{
|
{
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
adc_hal_set_power_manage(ADC_POWER_SW_OFF);
|
adc_hal_set_power_manage(ADC_POWER_SW_OFF);
|
||||||
ADC_EXIT_CRITICAL();
|
ADC_EXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_power_off(void) __attribute__((alias("adc_power_off_internal")));
|
|
||||||
|
|
||||||
esp_err_t adc_set_clk_div(uint8_t clk_div)
|
esp_err_t adc_set_clk_div(uint8_t clk_div)
|
||||||
{
|
{
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
@@ -370,9 +337,9 @@ int adc1_get_raw(adc1_channel_t channel)
|
|||||||
int adc_value;
|
int adc_value;
|
||||||
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
||||||
adc1_rtc_mode_acquire();
|
adc1_rtc_mode_acquire();
|
||||||
adc_power_acquire();
|
adc_power_on();
|
||||||
|
|
||||||
#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
|
// Get calibration value before going into critical section
|
||||||
uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel);
|
uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel);
|
||||||
#endif
|
#endif
|
||||||
@@ -382,7 +349,7 @@ int adc1_get_raw(adc1_channel_t channel)
|
|||||||
adc_hal_hall_disable(); //Disable other peripherals.
|
adc_hal_hall_disable(); //Disable other peripherals.
|
||||||
adc_hal_amp_disable(); //Currently the LNA is not open, close it by default.
|
adc_hal_amp_disable(); //Currently the LNA is not open, close it by default.
|
||||||
#endif
|
#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);
|
adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
|
||||||
#endif
|
#endif
|
||||||
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); //Set controller
|
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); //Set controller
|
||||||
@@ -392,7 +359,6 @@ int adc1_get_raw(adc1_channel_t channel)
|
|||||||
#endif
|
#endif
|
||||||
ADC_EXIT_CRITICAL();
|
ADC_EXIT_CRITICAL();
|
||||||
|
|
||||||
adc_power_release();
|
|
||||||
adc1_lock_release();
|
adc1_lock_release();
|
||||||
return adc_value;
|
return adc_value;
|
||||||
}
|
}
|
||||||
@@ -405,7 +371,7 @@ int adc1_get_voltage(adc1_channel_t channel) //Deprecated. Use adc1_get_raw()
|
|||||||
#if SOC_ULP_SUPPORTED
|
#if SOC_ULP_SUPPORTED
|
||||||
void adc1_ulp_enable(void)
|
void adc1_ulp_enable(void)
|
||||||
{
|
{
|
||||||
adc_power_acquire();
|
adc_power_on();
|
||||||
|
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_ULP);
|
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_ULP);
|
||||||
@@ -526,9 +492,9 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
|||||||
ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG);
|
ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
adc_power_acquire(); //in critical section with whole rtc module
|
adc_power_on(); //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
|
// Get calibration value before going into critical section
|
||||||
uint32_t cal_val = get_calibration_offset(ADC_NUM_2, channel);
|
uint32_t cal_val = get_calibration_offset(ADC_NUM_2, channel);
|
||||||
#endif
|
#endif
|
||||||
@@ -537,14 +503,13 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
|||||||
|
|
||||||
if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) { //try the lock, return if failed (wifi using).
|
if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) { //try the lock, return if failed (wifi using).
|
||||||
ADC2_EXIT_CRITICAL();
|
ADC2_EXIT_CRITICAL();
|
||||||
adc_power_release();
|
|
||||||
return ESP_ERR_TIMEOUT;
|
return ESP_ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_ADC_DISABLE_DAC
|
#ifdef CONFIG_ADC_DISABLE_DAC
|
||||||
adc2_dac_disable(channel); //disable other peripherals
|
adc2_dac_disable(channel); //disable other peripherals
|
||||||
#endif
|
#endif
|
||||||
adc2_config_width(width_bit); // in critical section with whole rtc module. because the PWDET use the same registers, place it here.
|
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);
|
adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
|
||||||
#endif
|
#endif
|
||||||
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller
|
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller
|
||||||
@@ -579,12 +544,8 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
|||||||
|
|
||||||
if (adc_value < 0) {
|
if (adc_value < 0) {
|
||||||
ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." );
|
ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." );
|
||||||
adc_power_release();
|
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//in critical section with whole rtc module
|
|
||||||
adc_power_release();
|
|
||||||
*raw_out = adc_value;
|
*raw_out = adc_value;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -597,9 +558,7 @@ esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)
|
|||||||
esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
|
esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
adc_power_acquire();
|
|
||||||
if (adc_unit & ADC_UNIT_1) {
|
if (adc_unit & ADC_UNIT_1) {
|
||||||
adc_power_release();
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -612,7 +571,6 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ch == ADC2_CHANNEL_MAX) {
|
if (ch == ADC2_CHANNEL_MAX) {
|
||||||
adc_power_release();
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,5 +587,3 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
|
|||||||
adc_gpio_init(ADC_UNIT_2, ch);
|
adc_gpio_init(ADC_UNIT_2, ch);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !CONFIG_IDF_TARGET_ESP32C3
|
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include "hal/adc_types.h"
|
#include "hal/adc_types.h"
|
||||||
#include "hal/adc_hal.h"
|
#include "hal/adc_hal.h"
|
||||||
#include "hal/dma_types.h"
|
#include "hal/dma_types.h"
|
||||||
|
#include "esp32c3/esp_efuse_rtc_calib.h"
|
||||||
|
|
||||||
#define ADC_CHECK_RET(fun_ret) ({ \
|
#define ADC_CHECK_RET(fun_ret) ({ \
|
||||||
if (fun_ret != ESP_OK) { \
|
if (fun_ret != ESP_OK) { \
|
||||||
@@ -89,13 +90,17 @@ typedef struct adc_digi_context_t {
|
|||||||
RingbufHandle_t ringbuf_hdl; //RX ringbuffer handler
|
RingbufHandle_t ringbuf_hdl; //RX ringbuffer handler
|
||||||
bool ringbuf_overflow_flag; //1: ringbuffer overflow
|
bool ringbuf_overflow_flag; //1: ringbuffer overflow
|
||||||
bool driver_start_flag; //1: driver is started; 0: driver is stoped
|
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.
|
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_config_t digi_controller_config; //Digital Controller Configuration
|
||||||
} adc_digi_context_t;
|
} adc_digi_context_t;
|
||||||
|
|
||||||
static const char* ADC_DMA_TAG = "ADC_DMA:";
|
static const char* ADC_DMA_TAG = "ADC_DMA:";
|
||||||
static adc_digi_context_t *s_adc_digi_ctx = NULL;
|
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)
|
ADC Continuous Read Mode (via DMA)
|
||||||
@@ -265,6 +270,16 @@ esp_err_t adc_digi_start(void)
|
|||||||
|
|
||||||
adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
|
adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
|
||||||
adc_hal_init();
|
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_arbiter_config(&config);
|
||||||
adc_hal_digi_init(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_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);
|
adc_hal_digi_controller_config(&s_adc_digi_ctx->digi_controller_config);
|
||||||
@@ -365,6 +380,7 @@ esp_err_t adc_digi_deinitialize(void)
|
|||||||
s_adc_digi_ctx->ringbuf_hdl = NULL;
|
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->hal_dma_config.rx_desc);
|
||||||
free(s_adc_digi_ctx->digi_controller_config.adc_pattern);
|
free(s_adc_digi_ctx->digi_controller_config.adc_pattern);
|
||||||
free(s_adc_digi_ctx);
|
free(s_adc_digi_ctx);
|
||||||
@@ -420,11 +436,16 @@ int adc1_get_raw(adc1_channel_t channel)
|
|||||||
ADC_DIGI_LOCK_ACQUIRE();
|
ADC_DIGI_LOCK_ACQUIRE();
|
||||||
|
|
||||||
periph_module_enable(PERIPH_SARADC_MODULE);
|
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_digi_controller_config(&dig_cfg);
|
||||||
|
|
||||||
adc_hal_intr_clear(ADC_EVENT_ADC1_DONE);
|
adc_hal_intr_clear(ADC_EVENT_ADC1_DONE);
|
||||||
adc_hal_onetime_channel(ADC_NUM_1, channel);
|
adc_hal_onetime_channel(ADC_NUM_1, channel);
|
||||||
adc_hal_set_onetime_atten(s_atten1_single[channel]);
|
adc_hal_set_onetime_atten(atten);
|
||||||
|
|
||||||
//Trigger single read.
|
//Trigger single read.
|
||||||
adc_hal_adc1_onetime_sample_enable(true);
|
adc_hal_adc1_onetime_sample_enable(true);
|
||||||
@@ -475,13 +496,17 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
|||||||
|
|
||||||
SAC_ADC2_LOCK_ACQUIRE();
|
SAC_ADC2_LOCK_ACQUIRE();
|
||||||
ADC_DIGI_LOCK_ACQUIRE();
|
ADC_DIGI_LOCK_ACQUIRE();
|
||||||
|
|
||||||
periph_module_enable(PERIPH_SARADC_MODULE);
|
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_digi_controller_config(&dig_cfg);
|
||||||
|
|
||||||
adc_hal_intr_clear(ADC_EVENT_ADC2_DONE);
|
adc_hal_intr_clear(ADC_EVENT_ADC2_DONE);
|
||||||
adc_hal_onetime_channel(ADC_NUM_2, channel);
|
adc_hal_onetime_channel(ADC_NUM_2, channel);
|
||||||
adc_hal_set_onetime_atten(s_atten2_single[channel]);
|
adc_hal_set_onetime_atten(atten);
|
||||||
|
|
||||||
//Trigger single read.
|
//Trigger single read.
|
||||||
adc_hal_adc2_onetime_sample_enable(true);
|
adc_hal_adc2_onetime_sample_enable(true);
|
||||||
@@ -523,10 +548,26 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
|
|||||||
memcpy(s_adc_digi_ctx->digi_controller_config.adc_pattern, config->adc_pattern, config->adc_pattern_len * sizeof(adc_digi_pattern_table_t));
|
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
|
//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->adc1_atten = ADC_ATTEN_MAX;
|
||||||
|
s_adc_digi_ctx->adc2_atten = ADC_ATTEN_MAX;
|
||||||
|
s_adc_digi_ctx->use_adc1 = 0;
|
||||||
s_adc_digi_ctx->use_adc2 = 0;
|
s_adc_digi_ctx->use_adc2 = 0;
|
||||||
for (int i = 0; i < config->adc_pattern_len; i++) {
|
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 == ADC_ATTEN_MAX) {
|
||||||
|
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) {
|
||||||
s_adc_digi_ctx->use_adc2 = 1;
|
s_adc_digi_ctx->use_adc2 = 1;
|
||||||
|
if (s_adc_digi_ctx->adc2_atten == ADC_ATTEN_MAX) {
|
||||||
|
s_adc_digi_ctx->adc2_atten = pat->atten;
|
||||||
|
} else if (s_adc_digi_ctx->adc2_atten != pat->atten) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,3 +843,40 @@ esp_err_t adc_digi_isr_deregister(void)
|
|||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
RTC controller setting
|
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 "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.*/
|
||||||
|
}
|
157
components/driver/esp32c3/rtc_tempsensor.c
Normal file
157
components/driver/esp32c3/rtc_tempsensor.c
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
// 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 "soc/rtc_cntl_reg.h"
|
||||||
|
#include "driver/temp_sensor.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)
|
||||||
|
|
||||||
|
#include "regi2c_ctrl.h"
|
||||||
|
|
||||||
|
#define ANA_CONFIG2_REG 0x6000E048
|
||||||
|
#define ANA_CONFIG2_M (BIT(18))
|
||||||
|
|
||||||
|
#define I2C_ADC 0X69
|
||||||
|
#define I2C_ADC_HOSTID 1
|
||||||
|
|
||||||
|
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},
|
||||||
|
};
|
||||||
|
|
||||||
|
static SemaphoreHandle_t rtc_tsens_mux = NULL;
|
||||||
|
|
||||||
|
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
|
||||||
|
{
|
||||||
|
//CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
|
||||||
|
//SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
|
||||||
|
SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16));
|
||||||
|
REGI2C_WRITE_MASK(I2C_ADC, I2C_SARADC_TSENS_DAC, dac_offset[tsens.dac_offset].set_val);
|
||||||
|
SENS.sar_tctrl.tsens_clk_div = tsens.clk_div;
|
||||||
|
SENS.sar_tctrl.tsens_power_up_force = 1;
|
||||||
|
SENS.sar_tctrl2.tsens_xpd_wait = TSENS_XPD_WAIT_DEFAULT;
|
||||||
|
SENS.sar_tctrl2.tsens_xpd_force = 1;
|
||||||
|
// SENS.sar_tctrl2.tsens_reset = 1;// Reset the temp sensor.
|
||||||
|
// SENS.sar_tctrl2.tsens_reset = 0;// Clear the reset status.
|
||||||
|
ESP_LOGI(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(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
|
||||||
|
//SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
|
||||||
|
SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16));
|
||||||
|
tsens->dac_offset = REGI2C_READ_MASK(I2C_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 = SENS.sar_tctrl.tsens_clk_div;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t temp_sensor_start(void)
|
||||||
|
{
|
||||||
|
if (rtc_tsens_mux == NULL) {
|
||||||
|
rtc_tsens_mux = xSemaphoreCreateMutex();
|
||||||
|
}
|
||||||
|
TSENS_CHECK(rtc_tsens_mux != NULL, ESP_ERR_NO_MEM);
|
||||||
|
// SENS.sar_tctrl.tsens_dump_out = 0;
|
||||||
|
// SENS.sar_tctrl2.tsens_clkgate_en = 1;
|
||||||
|
// SENS.sar_tctrl.tsens_power_up = 1;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t temp_sensor_stop(void)
|
||||||
|
{
|
||||||
|
SENS.sar_tctrl.tsens_power_up = 0;
|
||||||
|
// SENS.sar_tctrl2.tsens_clkgate_en = 0;
|
||||||
|
if (rtc_tsens_mux != NULL) {
|
||||||
|
vSemaphoreDelete(rtc_tsens_mux);
|
||||||
|
rtc_tsens_mux = NULL;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
|
||||||
|
{
|
||||||
|
TSENS_CHECK(tsens_out != NULL, ESP_ERR_INVALID_ARG);
|
||||||
|
TSENS_CHECK(rtc_tsens_mux != NULL, ESP_ERR_INVALID_STATE);
|
||||||
|
xSemaphoreTake(rtc_tsens_mux, portMAX_DELAY);
|
||||||
|
SENS.sar_tctrl.tsens_dump_out = 1;
|
||||||
|
while (!SENS.sar_tctrl.tsens_ready);
|
||||||
|
*tsens_out = SENS.sar_tctrl.tsens_out;
|
||||||
|
SENS.sar_tctrl.tsens_dump_out = 0;
|
||||||
|
xSemaphoreGive(rtc_tsens_mux);
|
||||||
|
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);
|
||||||
|
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 "adc2_wifi_private.h"
|
||||||
#include "hal/adc_hal.h"
|
#include "hal/adc_hal.h"
|
||||||
|
#include "adc_cali.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set initial code to ADC2 after calibration. ADC2 RTC and ADC2 PWDET controller share the initial code.
|
* @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_ll_num_t adc_n = ADC_NUM_2;
|
||||||
const adc_atten_t atten = ADC_ATTEN_DB_11;
|
const adc_atten_t atten = ADC_ATTEN_DB_11;
|
||||||
const adc_channel_t channel = 0;
|
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);
|
adc_cal_offset(adc_n, channel, atten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
components/driver/esp_private/adc_cali.h
Normal file
41
components/driver/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
|
@@ -17,6 +17,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "hal/adc_types.h"
|
#include "hal/adc_types.h"
|
||||||
|
|
||||||
@@ -99,6 +100,13 @@ typedef enum {
|
|||||||
#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5
|
#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5
|
||||||
#define ADC_ATTEN_6db ADC_ATTEN_DB_6
|
#define ADC_ATTEN_6db ADC_ATTEN_DB_6
|
||||||
#define ADC_ATTEN_11db ADC_ATTEN_DB_11
|
#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
|
//this definitions are only for being back-compatible
|
||||||
#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9
|
#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9
|
||||||
#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10
|
#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
#include "esp_types.h"
|
#include "esp_types.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/sens_periph.h"
|
|
||||||
#include "soc/syscon_periph.h"
|
#include "soc/syscon_periph.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/periph_defs.h"
|
#include "soc/periph_defs.h"
|
||||||
|
284
components/driver/test/test_adc_dma.c
Normal file
284
components/driver/test/test_adc_dma.c
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
// 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) {
|
||||||
|
assert(MAX_ARRAY_SIZE >= 4096);
|
||||||
|
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)) {
|
||||||
|
assert(value >= s_adc_offset);
|
||||||
|
assert(value < s_adc_offset + MAX_ARRAY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
ret = adc_digi_initialize(&adc_dma_config);
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
|
||||||
|
adc_digi_pattern_table_t adc_pattern[10];
|
||||||
|
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 = 15,
|
||||||
|
.dig_clk.div_a = 0,
|
||||||
|
.dig_clk.div_b = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
ret = adc_digi_controller_config(&dig_cfg);
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("test_adc_dma", "[adc][ignore][manual]")
|
||||||
|
{
|
||||||
|
esp_err_t ret;
|
||||||
|
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);
|
||||||
|
assert(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);
|
||||||
|
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;
|
||||||
|
ret = adc_digi_read_bytes(read_buf + already_got*output_data_size,
|
||||||
|
remain_count*output_data_size, &ret_num, ADC_MAX_DELAY);
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
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();
|
||||||
|
ret = adc_digi_deinitialize();
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
|
||||||
|
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);
|
||||||
|
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}")
|
if("esp32s2" STREQUAL "${target}")
|
||||||
list(APPEND srcs "src/${target}/esp_efuse_rtc_table.c")
|
list(APPEND srcs "src/${target}/esp_efuse_rtc_table.c")
|
||||||
endif()
|
endif()
|
||||||
|
if("esp32c3" STREQUAL "${target}")
|
||||||
|
list(APPEND srcs "src/${target}/esp_efuse_rtc_calib.c")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND srcs "src/esp_efuse_api.c"
|
list(APPEND srcs "src/esp_efuse_api.c"
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "esp_efuse_table.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.
|
// 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
|
// 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.
|
// 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,
|
{EFUSE_BLK1, 108, 6}, // SPI_PAD_configure D7,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const esp_efuse_desc_t SYS_DATA_PART1[] = {
|
static const esp_efuse_desc_t BLOCK2_VERSION[] = {
|
||||||
{EFUSE_BLK2, 0, 256}, // System configuration,
|
{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[] = {
|
static const esp_efuse_desc_t USER_DATA[] = {
|
||||||
@@ -892,8 +932,58 @@ const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART1[] = {
|
const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[] = {
|
||||||
&SYS_DATA_PART1[0], // System configuration
|
&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
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -126,8 +126,21 @@
|
|||||||
SPI_PAD_CONFIG_D6, EFUSE_BLK1, 102, 6, SPI_PAD_configure D6
|
SPI_PAD_CONFIG_D6, EFUSE_BLK1, 102, 6, SPI_PAD_configure D6
|
||||||
SPI_PAD_CONFIG_D7, EFUSE_BLK1, 108, 6, SPI_PAD_configure D7
|
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
|
USER_DATA, EFUSE_BLK3, 0, 256, User data
|
||||||
KEY0, EFUSE_BLK4, 0, 256, Key0 or user data
|
KEY0, EFUSE_BLK4, 0, 256, Key0 or user data
|
||||||
KEY1, EFUSE_BLK5, 0, 256, Key1 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
|
#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.
|
// 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
|
// 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.
|
// 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_D5[];
|
||||||
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D6[];
|
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_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_USER_DATA[];
|
||||||
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
|
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
|
||||||
extern const esp_efuse_desc_t* ESP_EFUSE_KEY1[];
|
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;
|
||||||
|
}
|
@@ -7,7 +7,6 @@ PROVIDE ( GPIO = 0x60004000 );
|
|||||||
PROVIDE ( SIGMADELTA = 0x60004f00 );
|
PROVIDE ( SIGMADELTA = 0x60004f00 );
|
||||||
PROVIDE ( RTCCNTL = 0x60008000 );
|
PROVIDE ( RTCCNTL = 0x60008000 );
|
||||||
PROVIDE ( RTCIO = 0x60008400 );
|
PROVIDE ( RTCIO = 0x60008400 );
|
||||||
PROVIDE ( SENS = 0x60008800 );
|
|
||||||
PROVIDE ( HINF = 0x6000B000 );
|
PROVIDE ( HINF = 0x6000B000 );
|
||||||
PROVIDE ( I2S1 = 0x6002d000 );
|
PROVIDE ( I2S1 = 0x6002d000 );
|
||||||
PROVIDE ( I2C0 = 0x60013000 );
|
PROVIDE ( I2C0 = 0x60013000 );
|
||||||
|
@@ -100,9 +100,16 @@ void IRAM_ATTR esp_restart_noos(void)
|
|||||||
|
|
||||||
// Reset timer/spi/uart
|
// Reset timer/spi/uart
|
||||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
||||||
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
|
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SPI3_DMA_RST | SYSTEM_SPI2_DMA_RST);
|
||||||
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
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);
|
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
|
// Set CPU back to XTAL source, no PLL, same as hard reset
|
||||||
#if !CONFIG_IDF_ENV_FPGA
|
#if !CONFIG_IDF_ENV_FPGA
|
||||||
rtc_clk_cpu_freq_set_xtal();
|
rtc_clk_cpu_freq_set_xtal();
|
||||||
|
@@ -98,9 +98,13 @@ void IRAM_ATTR esp_restart_noos(void)
|
|||||||
|
|
||||||
// Reset timer/spi/uart
|
// Reset timer/spi/uart
|
||||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
|
||||||
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
|
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SPI3_DMA_RST | SYSTEM_SPI2_DMA_RST);
|
||||||
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
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
|
// Set CPU back to XTAL source, no PLL, same as hard reset
|
||||||
#if !CONFIG_IDF_ENV_FPGA
|
#if !CONFIG_IDF_ENV_FPGA
|
||||||
rtc_clk_cpu_freq_set_xtal();
|
rtc_clk_cpu_freq_set_xtal();
|
||||||
|
@@ -10,4 +10,8 @@ elseif(${target} STREQUAL "esp32s2")
|
|||||||
INCLUDE_DIRS "include"
|
INCLUDE_DIRS "include"
|
||||||
REQUIRES driver efuse)
|
REQUIRES driver efuse)
|
||||||
|
|
||||||
|
elseif(${target} STREQUAL "esp32c3")
|
||||||
|
idf_component_register(SRCS "esp_adc_cal_esp32c3.c"
|
||||||
|
INCLUDE_DIRS "include"
|
||||||
|
REQUIRES driver efuse)
|
||||||
endif()
|
endif()
|
||||||
|
@@ -3,4 +3,4 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
COMPONENT_ADD_INCLUDEDIRS := include
|
COMPONENT_ADD_INCLUDEDIRS := include
|
||||||
COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o
|
COMPONENT_OBJEXCLUDE += esp_adc_cal_esp32s2.o esp_adc_cal_esp32c3.o
|
||||||
|
164
components/esp_adc_cal/esp_adc_cal_esp32c3.c
Normal file
164
components/esp_adc_cal/esp_adc_cal_esp32c3.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
// 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 bool 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);
|
||||||
|
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;
|
||||||
|
esp_err_t ret = esp_efuse_rtc_calib_get_cal_voltage(version_num, atten, &digi, &voltage);
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
parsed_data_storage->efuse_data.ver1.voltage = voltage;
|
||||||
|
parsed_data_storage->efuse_data.ver1.digi = digi;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------- 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 bool 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;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------- 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)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
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);
|
||||||
|
|
||||||
|
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.
|
||||||
|
res = prepare_calib_data_for(version_num, adc_num, atten, &efuse_parsed_data);
|
||||||
|
assert(res);
|
||||||
|
res = calculate_characterization_coefficients(&efuse_parsed_data, chars);
|
||||||
|
assert(res);
|
||||||
|
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_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_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_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;
|
} esp_adc_cal_value_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -30,6 +30,18 @@
|
|||||||
#define I2C_ULP_IR_RESETB_MSB 0
|
#define I2C_ULP_IR_RESETB_MSB 0
|
||||||
#define I2C_ULP_IR_RESETB_LSB 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 3
|
||||||
#define I2C_ULP_O_DONE_FLAG_MSB 0
|
#define I2C_ULP_O_DONE_FLAG_MSB 0
|
||||||
#define I2C_ULP_O_DONE_FLAG_LSB 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_MSB 3
|
||||||
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
|
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
|
||||||
|
|
||||||
#define I2C_ULP_IR_FORCE_XPD_IPH 0
|
#define I2C_ULP_IR_FORCE_CODE 5
|
||||||
#define I2C_ULP_IR_FORCE_XPD_IPH_MSB 4
|
#define I2C_ULP_IR_FORCE_CODE_MSB 6
|
||||||
#define I2C_ULP_IR_FORCE_XPD_IPH_LSB 4
|
#define I2C_ULP_IR_FORCE_CODE_LSB 6
|
||||||
|
|
||||||
#define I2C_ULP_IR_FORCE_XPD_CK 0
|
#define I2C_ULP_EXT_CODE 6
|
||||||
#define I2C_ULP_IR_FORCE_XPD_CK_MSB 2
|
#define I2C_ULP_EXT_CODE_MSB 7
|
||||||
#define I2C_ULP_IR_FORCE_XPD_CK_LSB 2
|
#define I2C_ULP_EXT_CODE_LSB 0
|
||||||
|
|
||||||
#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
|
|
||||||
|
@@ -24,7 +24,6 @@
|
|||||||
#include "esp32c3/rom/gpio.h"
|
#include "esp32c3/rom/gpio.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/sens_reg.h"
|
|
||||||
#include "soc/efuse_reg.h"
|
#include "soc/efuse_reg.h"
|
||||||
#include "soc/syscon_reg.h"
|
#include "soc/syscon_reg.h"
|
||||||
#include "soc/system_reg.h"
|
#include "soc/system_reg.h"
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
#include "esp32c3/rom/uart.h"
|
#include "esp32c3/rom/uart.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/sens_periph.h"
|
|
||||||
#include "soc/efuse_periph.h"
|
#include "soc/efuse_periph.h"
|
||||||
#include "soc/apb_ctrl_reg.h"
|
#include "soc/apb_ctrl_reg.h"
|
||||||
#include "hal/cpu_hal.h"
|
#include "hal/cpu_hal.h"
|
||||||
|
@@ -24,9 +24,14 @@
|
|||||||
#include "soc/system_reg.h"
|
#include "soc/system_reg.h"
|
||||||
#include "regi2c_ctrl.h"
|
#include "regi2c_ctrl.h"
|
||||||
#include "soc_log.h"
|
#include "soc_log.h"
|
||||||
|
#include "esp_efuse.h"
|
||||||
|
#include "esp_efuse_table.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_init";
|
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)
|
void rtc_init(rtc_config_t cfg)
|
||||||
{
|
{
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
|
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);
|
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
|
||||||
}
|
}
|
||||||
if (cfg.cali_ocode) {
|
if (cfg.cali_ocode) {
|
||||||
/*
|
uint32_t rtc_calib_version = 0;
|
||||||
Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration(must close PLL).
|
esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &rtc_calib_version, 3);
|
||||||
Method:
|
if (rtc_calib_version == 1) {
|
||||||
1. read current cpu config, save in old_config;
|
set_ocode_by_efuse(rtc_calib_version);
|
||||||
2. switch cpu to xtal because PLL will be closed when o-code calibration;
|
} else {
|
||||||
3. begin o-code calibration;
|
calibrate_ocode();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,3 +187,65 @@ void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
|
|||||||
val |= RTC_CNTL_SDIO_PD_EN;
|
val |= RTC_CNTL_SDIO_PD_EN;
|
||||||
REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
|
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_MSB 3
|
||||||
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
|
#define I2C_ULP_BG_O_DONE_FLAG_LSB 3
|
||||||
|
|
||||||
#define I2C_ULP_OCODE_ADDR 6
|
#define I2C_ULP_IR_FORCE_CODE 5
|
||||||
#define I2C_ULP_OCODE_ADDR_MSB 7
|
#define I2C_ULP_IR_FORCE_CODE_MSB 6
|
||||||
#define I2C_ULP_OCODE_ADDR_LSB 0
|
#define I2C_ULP_IR_FORCE_CODE_LSB 6
|
||||||
#define I2C_ULP_IR_FORCE_CODE_ADDR 5
|
|
||||||
#define I2C_ULP_IR_FORCE_CODE_ADDR_MSB 6
|
#define I2C_ULP_EXT_CODE 6
|
||||||
#define I2C_ULP_IR_FORCE_CODE_ADDR_LSB 6
|
#define I2C_ULP_EXT_CODE_MSB 7
|
||||||
|
#define I2C_ULP_EXT_CODE_LSB 0
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
#include "esp_efuse_table.h"
|
#include "esp_efuse_table.h"
|
||||||
static const char *TAG = "rtc_init";
|
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)
|
void rtc_init(rtc_config_t cfg)
|
||||||
{
|
{
|
||||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU);
|
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;
|
uint32_t rtc_calib_version = 0;
|
||||||
esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &rtc_calib_version, 32);
|
esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &rtc_calib_version, 32);
|
||||||
if (rtc_calib_version == 2) {
|
if (rtc_calib_version == 2) {
|
||||||
// use efuse ocode.
|
set_ocode_by_efuse(rtc_calib_version);
|
||||||
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 {
|
} else {
|
||||||
ocode = 93 + ocode;
|
calibrate_ocode();
|
||||||
}
|
|
||||||
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_OCODE_ADDR, ocode);
|
|
||||||
REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE_ADDR, 1);
|
|
||||||
} 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,3 +213,72 @@ void rtc_vddsdio_set_config(rtc_vddsdio_config_t config)
|
|||||||
val |= RTC_CNTL_SDIO_PD_EN;
|
val |= RTC_CNTL_SDIO_PD_EN;
|
||||||
REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val);
|
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 <stdio.h>
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
|
#if SOC_ADC_SUPPORT_RTC_CTRL
|
||||||
#include "soc/sens_periph.h"
|
#include "soc/sens_periph.h"
|
||||||
|
#endif
|
||||||
#include "soc/gpio_periph.h"
|
#include "soc/gpio_periph.h"
|
||||||
#include "hal/gpio_ll.h"
|
#include "hal/gpio_ll.h"
|
||||||
#include "driver/rtc_io.h"
|
#include "driver/rtc_io.h"
|
||||||
|
@@ -75,6 +75,11 @@ static const char *TAG = "clk";
|
|||||||
{
|
{
|
||||||
#if !CONFIG_IDF_ENV_FPGA
|
#if !CONFIG_IDF_ENV_FPGA
|
||||||
rtc_config_t cfg = RTC_CONFIG_DEFAULT();
|
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);
|
rtc_init(cfg);
|
||||||
|
|
||||||
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
|
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
|
||||||
|
@@ -33,14 +33,6 @@ void adc_hal_digi_deinit(void)
|
|||||||
adc_hal_deinit();
|
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)
|
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.
|
//only one pattern table is supported on C3, but LL still needs one argument.
|
||||||
@@ -53,7 +45,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
|||||||
adc_ll_digi_set_pattern_table_len(pattern_both, cfg->adc_pattern_len);
|
adc_ll_digi_set_pattern_table_len(pattern_both, cfg->adc_pattern_len);
|
||||||
for (int i = 0; i < cfg->adc_pattern_len; i++) {
|
for (int i = 0; i < cfg->adc_pattern_len; i++) {
|
||||||
adc_ll_digi_set_pattern_table(pattern_both, i, cfg->adc_pattern[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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,98 +127,3 @@ void adc_hal_arbiter_config(adc_arbiter_t *config)
|
|||||||
adc_ll_set_arbiter_work_mode(config->mode);
|
adc_ll_set_arbiter_work_mode(config->mode);
|
||||||
adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri);
|
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;
|
|
||||||
}
|
|
||||||
|
@@ -226,21 +226,6 @@ void adc_hal_arbiter_config(adc_arbiter_t *config);
|
|||||||
ADC calibration setting
|
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.
|
* Set the calibration result (initial data) to ADC.
|
||||||
|
@@ -15,12 +15,13 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "regi2c_ctrl.h"
|
||||||
|
#include "esp_attr.h"
|
||||||
|
|
||||||
#include "soc/adc_periph.h"
|
#include "soc/adc_periph.h"
|
||||||
#include "hal/adc_types.h"
|
#include "hal/adc_types.h"
|
||||||
#include "soc/apb_saradc_struct.h"
|
#include "soc/apb_saradc_struct.h"
|
||||||
#include "soc/apb_saradc_reg.h"
|
#include "soc/apb_saradc_reg.h"
|
||||||
#include "soc/rtc_cntl_struct.h"
|
|
||||||
#include "esp_attr.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -845,13 +846,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 */
|
// Bit0 0:SW mode power down 1: SW mode power on */
|
||||||
if (manage == ADC_POWER_SW_ON) {
|
if (manage == ADC_POWER_SW_ON) {
|
||||||
APB_SARADC.ctrl.sar_clk_gated = 1;
|
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) {
|
} else if (manage == ADC_POWER_BY_FSM) {
|
||||||
APB_SARADC.ctrl.sar_clk_gated = 1;
|
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) {
|
} 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.sar_clk_gated = 1;
|
||||||
|
APB_SARADC.ctrl.xpd_sar_force = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -891,64 +892,6 @@ static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div)
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
// if (adc_n == ADC_NUM_1) {
|
|
||||||
// SENS.sar_atten1 = ( SENS.sar_atten1 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2));
|
|
||||||
// } else { // adc_n == ADC_NUM_2
|
|
||||||
// SENS.sar_atten2 = ( SENS.sar_atten2 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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(); // FIXME
|
|
||||||
// if (adc_n == ADC_NUM_1) {
|
|
||||||
// return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3);
|
|
||||||
// } else {
|
|
||||||
// return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set ADC module controller.
|
* Set ADC module controller.
|
||||||
@@ -1011,7 +954,6 @@ static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_controller_t ct
|
|||||||
*/
|
*/
|
||||||
static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode)
|
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) {
|
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_grant_force = 0;
|
||||||
APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1;
|
APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1;
|
||||||
@@ -1096,102 +1038,6 @@ static inline void adc_ll_disable_sleep_controller(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ADC calibration code. */
|
/* ADC calibration code. */
|
||||||
#include "soc/rtc_cntl_reg.h"
|
|
||||||
#include "regi2c_ctrl.h"
|
|
||||||
|
|
||||||
#define I2C_ADC 0X69
|
|
||||||
#define I2C_ADC_HOSTID 0
|
|
||||||
|
|
||||||
#define ANA_CONFIG2_REG 0x6000E048
|
|
||||||
#define ANA_CONFIG2_M (BIT(18))
|
|
||||||
|
|
||||||
#define SAR1_ENCAL_GND_ADDR 0x7
|
|
||||||
#define SAR1_ENCAL_GND_ADDR_MSB 5
|
|
||||||
#define SAR1_ENCAL_GND_ADDR_LSB 5
|
|
||||||
|
|
||||||
#define SAR2_ENCAL_GND_ADDR 0x7
|
|
||||||
#define SAR2_ENCAL_GND_ADDR_MSB 7
|
|
||||||
#define SAR2_ENCAL_GND_ADDR_LSB 7
|
|
||||||
|
|
||||||
#define SAR1_INITIAL_CODE_HIGH_ADDR 0x1
|
|
||||||
#define SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3
|
|
||||||
#define SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0
|
|
||||||
|
|
||||||
#define SAR1_INITIAL_CODE_LOW_ADDR 0x0
|
|
||||||
#define SAR1_INITIAL_CODE_LOW_ADDR_MSB 0x7
|
|
||||||
#define SAR1_INITIAL_CODE_LOW_ADDR_LSB 0x0
|
|
||||||
|
|
||||||
#define SAR2_INITIAL_CODE_HIGH_ADDR 0x4
|
|
||||||
#define SAR2_INITIAL_CODE_HIGH_ADDR_MSB 0x3
|
|
||||||
#define SAR2_INITIAL_CODE_HIGH_ADDR_LSB 0x0
|
|
||||||
|
|
||||||
#define SAR2_INITIAL_CODE_LOW_ADDR 0x3
|
|
||||||
#define SAR2_INITIAL_CODE_LOW_ADDR_MSB 0x7
|
|
||||||
#define SAR2_INITIAL_CODE_LOW_ADDR_LSB 0x0
|
|
||||||
|
|
||||||
#define SAR1_DREF_ADDR 0x2
|
|
||||||
#define SAR1_DREF_ADDR_MSB 0x6
|
|
||||||
#define SAR1_DREF_ADDR_LSB 0x4
|
|
||||||
|
|
||||||
#define SAR2_DREF_ADDR 0x5
|
|
||||||
#define SAR2_DREF_ADDR_MSB 0x6
|
|
||||||
#define SAR2_DREF_ADDR_LSB 0x4
|
|
||||||
|
|
||||||
#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.
|
|
||||||
*
|
|
||||||
* @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 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.
|
|
||||||
*/
|
|
||||||
static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd)
|
|
||||||
{
|
|
||||||
// /* Enable i2s_write_reg function. */
|
|
||||||
// void phy_get_romfunc_addr(void);
|
|
||||||
// phy_get_romfunc_addr();
|
|
||||||
// //CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
|
|
||||||
// //SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
|
|
||||||
// CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
|
|
||||||
// SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16));
|
|
||||||
|
|
||||||
// /* Enable/disable internal connect GND (for calibration). */
|
|
||||||
// if (adc_n == ADC_NUM_1) {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR1_DREF_ADDR, 4);
|
|
||||||
// if (internal_gnd) {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 1);
|
|
||||||
// } else {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR2_DREF_ADDR, 4);
|
|
||||||
// if (internal_gnd) {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 1);
|
|
||||||
// } else {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resume register status after calibration.
|
|
||||||
*
|
|
||||||
* @param adc_n ADC index number.
|
|
||||||
*/
|
|
||||||
static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n)
|
|
||||||
{
|
|
||||||
// if (adc_n == ADC_NUM_1) {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0);
|
|
||||||
// } else {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the calibration result to ADC.
|
* Set the calibration result to ADC.
|
||||||
*
|
*
|
||||||
@@ -1201,22 +1047,15 @@ 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)
|
static inline void adc_ll_set_calibration_param(adc_ll_num_t adc_n, uint32_t param)
|
||||||
{
|
{
|
||||||
// uint8_t msb = param >> 8;
|
uint8_t msb = param >> 8;
|
||||||
// uint8_t lsb = param & 0xFF;
|
uint8_t lsb = param & 0xFF;
|
||||||
// /* Enable i2s_write_reg function. */
|
if (adc_n == ADC_NUM_1) {
|
||||||
// void phy_get_romfunc_addr(void);
|
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb);
|
||||||
// phy_get_romfunc_addr();
|
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb);
|
||||||
// //SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
|
} else {
|
||||||
// CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
|
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, msb);
|
||||||
// SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16));
|
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, lsb);
|
||||||
|
}
|
||||||
// if (adc_n == ADC_NUM_1) {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR1_INITIAL_CODE_HIGH_ADDR, msb);
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR1_INITIAL_CODE_LOW_ADDR, lsb);
|
|
||||||
// } else {
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR2_INITIAL_CODE_HIGH_ADDR, msb);
|
|
||||||
// REGI2C_WRITE_MASK(I2C_ADC, SAR2_INITIAL_CODE_LOW_ADDR, lsb);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
/* Temp code end. */
|
/* Temp code end. */
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
|||||||
if (cfg->adc1_pattern_len) {
|
if (cfg->adc1_pattern_len) {
|
||||||
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
||||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
|
adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
|
||||||
for (uint32_t i = 0; i < cfg->adc1_pattern_len; i++) {
|
for (int i = 0; i < cfg->adc1_pattern_len; i++) {
|
||||||
adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
|
adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
|||||||
if (cfg->adc2_pattern_len) {
|
if (cfg->adc2_pattern_len) {
|
||||||
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
||||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
|
adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
|
||||||
for (uint32_t i = 0; i < cfg->adc2_pattern_len; i++) {
|
for (int i = 0; i < cfg->adc2_pattern_len; i++) {
|
||||||
adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
|
adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -79,6 +79,7 @@
|
|||||||
#define SOC_ADC_PATT_LEN_MAX (16)
|
#define SOC_ADC_PATT_LEN_MAX (16)
|
||||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 8: 10)
|
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 8: 10)
|
||||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||||
|
#define SOC_ADC_MAX_BITWIDTH (12)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if adc support digital controller (DMA) mode.
|
* Check if adc support digital controller (DMA) mode.
|
||||||
@@ -87,6 +88,7 @@
|
|||||||
* - 0 : not support;
|
* - 0 : not support;
|
||||||
*/
|
*/
|
||||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 0)
|
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 0)
|
||||||
|
#define SOC_ADC_SUPPORT_RTC_CTRL 1
|
||||||
|
|
||||||
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
|
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
|
||||||
#if SOC_CAPS_ECO_VER >= 1
|
#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_ */
|
|
@@ -104,9 +104,9 @@
|
|||||||
/*-------------------------- ADC CAPS -------------------------------*/
|
/*-------------------------- ADC CAPS -------------------------------*/
|
||||||
#define SOC_ADC_PERIPH_NUM (2)
|
#define SOC_ADC_PERIPH_NUM (2)
|
||||||
#define SOC_ADC_PATT_LEN_MAX (16)
|
#define SOC_ADC_PATT_LEN_MAX (16)
|
||||||
|
|
||||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 5 : 1)
|
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 5 : 1)
|
||||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||||
|
#define SOC_ADC_MAX_BITWIDTH (12)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if adc support digital controller (DMA) mode.
|
* Check if adc support digital controller (DMA) mode.
|
||||||
|
@@ -55,9 +55,9 @@
|
|||||||
/*-------------------------- ADC CAPS ----------------------------------------*/
|
/*-------------------------- ADC CAPS ----------------------------------------*/
|
||||||
#define SOC_ADC_PERIPH_NUM (2)
|
#define SOC_ADC_PERIPH_NUM (2)
|
||||||
#define SOC_ADC_PATT_LEN_MAX (16)
|
#define SOC_ADC_PATT_LEN_MAX (16)
|
||||||
|
|
||||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
|
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
|
||||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||||
|
#define SOC_ADC_MAX_BITWIDTH (13)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if adc support digital controller (DMA) mode.
|
* Check if adc support digital controller (DMA) mode.
|
||||||
@@ -66,6 +66,7 @@
|
|||||||
* - 0 : not support;
|
* - 0 : not support;
|
||||||
*/
|
*/
|
||||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 1)
|
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 1)
|
||||||
|
#define SOC_ADC_SUPPORT_RTC_CTRL 1
|
||||||
|
|
||||||
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
|
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
|
||||||
#define SOC_BROWNOUT_RESET_SUPPORTED 1
|
#define SOC_BROWNOUT_RESET_SUPPORTED 1
|
||||||
|
@@ -15,9 +15,10 @@
|
|||||||
|
|
||||||
#define SOC_ADC_PERIPH_NUM (2)
|
#define SOC_ADC_PERIPH_NUM (2)
|
||||||
#define SOC_ADC_PATT_LEN_MAX (16)
|
#define SOC_ADC_PATT_LEN_MAX (16)
|
||||||
|
|
||||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
|
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
|
||||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||||
|
#define SOC_ADC_MAX_BITWIDTH (13)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if adc support digital controller (DMA) mode.
|
* Check if adc support digital controller (DMA) mode.
|
||||||
@@ -26,3 +27,4 @@
|
|||||||
* - 0 : not support;
|
* - 0 : not support;
|
||||||
*/
|
*/
|
||||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 1)
|
#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.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/syscon_struct.h"
|
#include "soc/syscon_struct.h"
|
||||||
|
|
||||||
|
#if SOC_ADC_SUPPORT_RTC_CTRL
|
||||||
#include "soc/sens_reg.h"
|
#include "soc/sens_reg.h"
|
||||||
#include "soc/sens_struct.h"
|
#include "soc/sens_struct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
|
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
|
||||||
#include "soc/rtc_io_struct.h"
|
#include "soc/rtc_io_struct.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -19,16 +19,17 @@
|
|||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
|
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
|
||||||
|
|
||||||
#include "soc/rtc_io_channel.h"
|
#include "soc/rtc_io_channel.h"
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
#include "soc/rtc_io_struct.h"
|
#include "soc/rtc_io_struct.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/rtc_cntl_struct.h"
|
#include "soc/rtc_cntl_struct.h"
|
||||||
|
|
||||||
|
#if SOC_ADC_SUPPORT_RTC_CTRL
|
||||||
#include "soc/sens_struct.h"
|
#include "soc/sens_struct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
#include "esp_log.h"
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
|
|
||||||
#define TIMES 256
|
#define TIMES 256
|
||||||
@@ -47,6 +48,15 @@ static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask
|
|||||||
assert(ret == ESP_OK);
|
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_demo(void *arg)
|
static void continuous_read_demo(void *arg)
|
||||||
{
|
{
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
@@ -54,8 +64,8 @@ static void continuous_read_demo(void *arg)
|
|||||||
uint8_t result[TIMES] = {0};
|
uint8_t result[TIMES] = {0};
|
||||||
memset(result, 0xcc, TIMES);
|
memset(result, 0xcc, TIMES);
|
||||||
|
|
||||||
uint16_t adc1_chan_mask = BIT(ADC1_CHANNEL_0) | BIT(ADC1_CHANNEL_1);
|
uint16_t adc1_chan_mask = BIT(0) | BIT(1);
|
||||||
uint16_t adc2_chan_mask = BIT(ADC2_CHANNEL_0);
|
uint16_t adc2_chan_mask = BIT(0);
|
||||||
adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1, (ADC2_CHANNEL_0 | 1 << 3)};
|
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));
|
continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t));
|
||||||
@@ -65,13 +75,12 @@ static void continuous_read_demo(void *arg)
|
|||||||
while(n--) {
|
while(n--) {
|
||||||
ret = adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY);
|
ret = adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY);
|
||||||
for (int i = 0; i < ret_num; i+=4) {
|
for (int i = 0; i < ret_num; i+=4) {
|
||||||
uint32_t temp = (result[i+3] << 24) | (result[i+2] << 16) | (result[i+1] << 8) | (result[i+0]);
|
adc_digi_output_data_t *p = (void*)&result[i];
|
||||||
adc_digi_output_data_t *p = (void*)&temp;
|
if (check_valid_data(p)) {
|
||||||
printf("[%d_%d_%x](%02x %02x %02x %02x) \n", p->type2.unit, p->type2.channel, p->type2.data,
|
printf("ADC%d_CH%d: %x\n", p->type2.unit+1, p->type2.channel, p->type2.data);
|
||||||
result[i],
|
} else {
|
||||||
result[i + 1],
|
printf("Invalid data [%d_%d_%x]\n", p->type2.unit+1, p->type2.channel, p->type2.data);
|
||||||
result[i + 2],
|
}
|
||||||
result[i + 3]);
|
|
||||||
}
|
}
|
||||||
// If you see task WDT in this task, it means the conversion is too fast for the task to handle
|
// If you see task WDT in this task, it means the conversion is too fast for the task to handle
|
||||||
}
|
}
|
||||||
@@ -87,7 +96,9 @@ static void single_read_demo(void *arg)
|
|||||||
int adc1_reading[3] = {0xcc};
|
int adc1_reading[3] = {0xcc};
|
||||||
int adc2_reading[1] = {0xcc};
|
int adc2_reading[1] = {0xcc};
|
||||||
|
|
||||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
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_2, ADC_ATTEN_DB_0);
|
||||||
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6);
|
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6);
|
||||||
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0);
|
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0);
|
||||||
@@ -101,12 +112,12 @@ static void single_read_demo(void *arg)
|
|||||||
adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4);
|
adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4);
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
printf("[%x]\n", adc1_reading[i]);
|
ESP_LOGI(TAG_CH[i], "%x", adc1_reading[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]);
|
ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]);
|
||||||
assert(ret == ESP_OK);
|
assert(ret == ESP_OK);
|
||||||
printf("[%x]\n", adc2_reading[0]);
|
ESP_LOGI(TAG_CH[3], "%x", adc2_reading[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user