adc: refactor adc single read api on esp32c3

This commit is contained in:
Armando
2021-02-23 21:40:15 +08:00
parent 69a0f8b9bb
commit 00a3f48bd8
7 changed files with 232 additions and 451 deletions

View File

@@ -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