mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 20:41:14 +00:00
adc: refactor adc single read api on esp32c3
This commit is contained in:
@@ -23,6 +23,12 @@
|
||||
#include "soc/gdma_channel.h"
|
||||
#include "soc/soc.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
typedef enum {
|
||||
ADC_EVENT_ADC1_DONE = BIT(0),
|
||||
ADC_EVENT_ADC2_DONE = BIT(1),
|
||||
} adc_hal_event_t;
|
||||
|
||||
#endif
|
||||
|
||||
void adc_hal_init(void)
|
||||
@@ -41,18 +47,6 @@ void adc_hal_deinit(void)
|
||||
{
|
||||
adc_ll_set_power_manage(ADC_POWER_SW_OFF);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value)
|
||||
{
|
||||
adc_ll_rtc_enable_channel(adc_n, channel);
|
||||
adc_ll_rtc_start_convert(adc_n, channel);
|
||||
while (adc_ll_rtc_convert_is_done(adc_n) != true);
|
||||
*value = adc_ll_rtc_get_convert_value(adc_n);
|
||||
return (int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*value));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
ADC calibration setting
|
||||
---------------------------------------------------------------*/
|
||||
@@ -99,15 +93,9 @@ static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
|
||||
{
|
||||
adc_hal_set_controller(adc_n, ADC_CTRL_DIG); //Set controller
|
||||
|
||||
adc_digi_config_t dig_cfg = {
|
||||
.conv_limit_en = 0,
|
||||
.conv_limit_num = 250,
|
||||
.sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH,
|
||||
};
|
||||
adc_hal_digi_controller_config(&dig_cfg);
|
||||
|
||||
adc_ll_onetime_sample_enable(ADC_NUM_1, false);
|
||||
adc_ll_onetime_sample_enable(ADC_NUM_2, false);
|
||||
adc_ll_set_power_manage(ADC_POWER_SW_ON);
|
||||
/* Enable/disable internal connect GND (for calibration). */
|
||||
if (internal_gnd) {
|
||||
const int esp32c3_invalid_chan = (adc_n == ADC_NUM_1)? 0xF: 0x1;
|
||||
@@ -116,8 +104,7 @@ static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t att
|
||||
adc_ll_onetime_set_channel(adc_n, channel);
|
||||
}
|
||||
adc_ll_onetime_set_atten(atten);
|
||||
adc_hal_adc1_onetime_sample_enable((adc_n == ADC_NUM_1));
|
||||
adc_hal_adc2_onetime_sample_enable((adc_n == ADC_NUM_2));
|
||||
adc_ll_onetime_sample_enable(adc_n, true);
|
||||
}
|
||||
|
||||
static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
|
||||
@@ -223,8 +210,8 @@ void adc_hal_digi_init(adc_hal_context_t *hal)
|
||||
gdma_ll_clear_interrupt_status(hal->dev, hal->dma_chan, UINT32_MAX);
|
||||
gdma_ll_enable_interrupt(hal->dev, hal->dma_chan, GDMA_LL_EVENT_RX_SUC_EOF, true);
|
||||
adc_ll_digi_dma_set_eof_num(hal->eof_num);
|
||||
adc_ll_adc1_onetime_sample_enable(false);
|
||||
adc_ll_adc2_onetime_sample_enable(false);
|
||||
adc_ll_onetime_sample_enable(ADC_NUM_1, false);
|
||||
adc_ll_onetime_sample_enable(ADC_NUM_2, false);
|
||||
}
|
||||
|
||||
void adc_hal_fifo_reset(adc_hal_context_t *hal)
|
||||
@@ -309,7 +296,32 @@ void adc_hal_digi_stop(adc_hal_context_t *hal)
|
||||
/*---------------------------------------------------------------
|
||||
Single Read
|
||||
---------------------------------------------------------------*/
|
||||
void adc_hal_onetime_start(adc_digi_config_t *adc_digi_config)
|
||||
|
||||
//--------------------INTR-------------------------------//
|
||||
static adc_ll_intr_t get_event_intr(adc_hal_event_t event)
|
||||
{
|
||||
adc_ll_intr_t intr_mask = 0;
|
||||
if (event & ADC_EVENT_ADC1_DONE) {
|
||||
intr_mask |= ADC_LL_INTR_ADC1_DONE;
|
||||
}
|
||||
if (event & ADC_EVENT_ADC2_DONE) {
|
||||
intr_mask |= ADC_LL_INTR_ADC2_DONE;
|
||||
}
|
||||
return intr_mask;
|
||||
}
|
||||
|
||||
static void adc_hal_intr_clear(adc_hal_event_t event)
|
||||
{
|
||||
adc_ll_intr_clear(get_event_intr(event));
|
||||
}
|
||||
|
||||
static bool adc_hal_intr_get_raw(adc_hal_event_t event)
|
||||
{
|
||||
return adc_ll_intr_get_raw(get_event_intr(event));
|
||||
}
|
||||
|
||||
//--------------------Single Read-------------------------------//
|
||||
static void adc_hal_onetime_start(void)
|
||||
{
|
||||
/**
|
||||
* There is a hardware limitation. If the APB clock frequency is high, the step of this reg signal: ``onetime_start`` may not be captured by the
|
||||
@@ -335,74 +347,54 @@ void adc_hal_onetime_start(adc_digi_config_t *adc_digi_config)
|
||||
//No need to delay here. Becuase if the start signal is not seen, there won't be a done intr.
|
||||
}
|
||||
|
||||
void adc_hal_adc1_onetime_sample_enable(bool enable)
|
||||
static esp_err_t adc_hal_single_read(adc_ll_num_t adc_n, int *out_raw)
|
||||
{
|
||||
adc_ll_adc1_onetime_sample_enable(enable);
|
||||
}
|
||||
|
||||
void adc_hal_adc2_onetime_sample_enable(bool enable)
|
||||
{
|
||||
adc_ll_adc2_onetime_sample_enable(enable);
|
||||
}
|
||||
|
||||
void adc_hal_onetime_channel(adc_ll_num_t unit, adc_channel_t channel)
|
||||
{
|
||||
adc_ll_onetime_set_channel(unit, channel);
|
||||
}
|
||||
|
||||
void adc_hal_set_onetime_atten(adc_atten_t atten)
|
||||
{
|
||||
adc_ll_onetime_set_atten(atten);
|
||||
}
|
||||
|
||||
esp_err_t adc_hal_single_read(adc_ll_num_t unit, int *out_raw)
|
||||
{
|
||||
if (unit == ADC_NUM_1) {
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
*out_raw = adc_ll_adc1_read();
|
||||
} else if (unit == ADC_NUM_2) {
|
||||
} else if (adc_n == ADC_NUM_2) {
|
||||
*out_raw = adc_ll_adc2_read();
|
||||
if (adc_ll_analysis_raw_data(unit, *out_raw)) {
|
||||
if (adc_ll_analysis_raw_data(adc_n, *out_raw)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
//--------------------INTR-------------------------------
|
||||
static adc_ll_intr_t get_event_intr(adc_event_t event)
|
||||
esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw)
|
||||
{
|
||||
adc_ll_intr_t intr_mask = 0;
|
||||
if (event & ADC_EVENT_ADC1_DONE) {
|
||||
intr_mask |= ADC_LL_INTR_ADC1_DONE;
|
||||
esp_err_t ret;
|
||||
adc_hal_event_t event;
|
||||
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
event = ADC_EVENT_ADC1_DONE;
|
||||
} else {
|
||||
event = ADC_EVENT_ADC2_DONE;
|
||||
}
|
||||
if (event & ADC_EVENT_ADC2_DONE) {
|
||||
intr_mask |= ADC_LL_INTR_ADC2_DONE;
|
||||
|
||||
adc_hal_intr_clear(event);
|
||||
adc_ll_onetime_sample_enable(adc_n, true);
|
||||
adc_ll_onetime_set_channel(adc_n, channel);
|
||||
|
||||
//Trigger single read.
|
||||
adc_hal_onetime_start();
|
||||
while (!adc_hal_intr_get_raw(event));
|
||||
ret = adc_hal_single_read(adc_n, out_raw);
|
||||
adc_ll_onetime_sample_enable(adc_n, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else // !CONFIG_IDF_TARGET_ESP32C3
|
||||
esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw)
|
||||
{
|
||||
adc_ll_rtc_enable_channel(adc_n, channel);
|
||||
adc_ll_rtc_start_convert(adc_n, channel);
|
||||
while (adc_ll_rtc_convert_is_done(adc_n) != true);
|
||||
*out_raw = adc_ll_rtc_get_convert_value(adc_n);
|
||||
|
||||
if ((int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*out_raw))) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
} else {
|
||||
return ESP_OK;
|
||||
}
|
||||
return intr_mask;
|
||||
}
|
||||
|
||||
void adc_hal_intr_enable(adc_event_t event)
|
||||
{
|
||||
adc_ll_intr_enable(get_event_intr(event));
|
||||
}
|
||||
|
||||
void adc_hal_intr_disable(adc_event_t event)
|
||||
{
|
||||
adc_ll_intr_disable(get_event_intr(event));
|
||||
}
|
||||
|
||||
void adc_hal_intr_clear(adc_event_t event)
|
||||
{
|
||||
adc_ll_intr_clear(get_event_intr(event));
|
||||
}
|
||||
|
||||
bool adc_hal_intr_get_raw(adc_event_t event)
|
||||
{
|
||||
return adc_ll_intr_get_raw(get_event_intr(event));
|
||||
}
|
||||
|
||||
bool adc_hal_intr_get_status(adc_event_t event)
|
||||
{
|
||||
return adc_ll_intr_get_status(get_event_intr(event));
|
||||
}
|
||||
#endif
|
||||
#endif //#if !CONFIG_IDF_TARGET_ESP32C3
|
||||
|
Reference in New Issue
Block a user