driver/adc: support adc single sample on s3

This commit is contained in:
laokaiyao
2021-06-08 17:38:46 +08:00
parent 6bb6f3ebc4
commit 27d9657b6c
9 changed files with 241 additions and 644 deletions

View File

@@ -57,22 +57,6 @@ typedef enum {
ADC_LL_CTRL_ARB = 4, ///< For ADC2. The controller is selected by the arbiter.
} adc_ll_controller_t;
/**
* @brief ADC digital controller (DMA mode) work mode.
*
* @note The conversion mode affects the sampling frequency:
* SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once.
* SINGLE_UNIT_2: When the measurement is triggered, only ADC2 is sampled once.
* BOTH_UNIT : When the measurement is triggered, ADC1 and ADC2 are sampled at the same time.
* ALTER_UNIT : When the measurement is triggered, ADC1 or ADC2 samples alternately.
*/
typedef enum {
ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion
ADC_LL_DIGI_CONV_ONLY_ADC2 = 1, // Only use ADC2 for conversion
ADC_LL_DIGI_CONV_BOTH_UNIT = 2, // Use Both ADC1 and ADC2 for conversion simultaneously
ADC_LL_DIGI_CONV_ALTER_UNIT = 3 // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 .....
} adc_ll_digi_convert_mode_t;
typedef struct {
union {
struct {
@@ -96,8 +80,8 @@ typedef struct {
typedef struct {
union {
struct {
uint16_t data: 13; /*!<ADC real output data info. Resolution: 13 bit. */
uint16_t reserved: 1; /*!<reserved */
uint16_t data: 12; /*!<ADC real output data info. Resolution: 13 bit. */
uint16_t reserved: 2; /*!<reserved */
uint16_t flag: 2; /*!<ADC data flag info.
If (flag == 0), The data is valid.
If (flag > 0), The data is invalid. */
@@ -142,6 +126,7 @@ static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wa
static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
{
//To be added including RTC_CNTR reg and functions
abort();
}
/**
@@ -192,17 +177,17 @@ static inline void adc_ll_digi_convert_limit_disable(void)
*
* @param mode Conversion mode select.
*/
static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode)
static inline void adc_ll_digi_set_convert_mode(adc_digi_convert_mode_t mode)
{
if (mode == ADC_LL_DIGI_CONV_ONLY_ADC1) {
if (mode == ADC_CONV_SINGLE_UNIT_1) {
APB_SARADC.ctrl.work_mode = 0;
APB_SARADC.ctrl.sar_sel = 0;
} else if (mode == ADC_LL_DIGI_CONV_ONLY_ADC2) {
} else if (mode == ADC_CONV_SINGLE_UNIT_2) {
APB_SARADC.ctrl.work_mode = 0;
APB_SARADC.ctrl.sar_sel = 1;
} else if (mode == ADC_LL_DIGI_CONV_BOTH_UNIT) {
} else if (mode == ADC_CONV_BOTH_UNIT) {
APB_SARADC.ctrl.work_mode = 1;
} else if (mode == ADC_LL_DIGI_CONV_ALTER_UNIT) {
} else if (mode == ADC_CONV_ALTER_UNIT) {
APB_SARADC.ctrl.work_mode = 2;
}
APB_SARADC.ctrl.data_sar_sel = 1;
@@ -238,23 +223,7 @@ static inline void adc_ll_digi_set_pattern_table_len(adc_ll_num_t adc_n, uint32_
*/
static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_digi_pattern_table_t table)
{
uint32_t tab;
uint8_t index = pattern_index / 4;
uint8_t offset = (pattern_index % 4) * 6;
adc_ll_digi_pattern_table_t pattern = {0};
pattern.val = (table.atten & 0x3) | ((table.channel & 0xF) << 2);
if (table.unit == ADC_NUM_1){
tab = APB_SARADC.sar1_patt_tab[index].sar1_patt_tab; //Read old register value
tab &= (~(0xFC0000 >> offset)); //Clear old data
tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; //Fill in the new data
APB_SARADC.sar1_patt_tab[index].sar1_patt_tab = tab; //Write back
} else {
tab = APB_SARADC.sar2_patt_tab[index].sar2_patt_tab; //Read old register value
tab &= (~(0xFC0000 >> offset)); //clear old data
tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; //Fill in the new data
APB_SARADC.sar2_patt_tab[index].sar2_patt_tab = tab; //Write back
}
abort();
}
/**
@@ -377,13 +346,26 @@ static inline void adc_ll_digi_filter_reset(adc_ll_num_t adc_n)
abort();
}
/**
* Disable adc digital controller filter.
* Filtering the ADC data to obtain smooth data at higher sampling rates.
*
* @note If the channel info is not supported, the filter function will not be enabled.
* @param adc_n ADC unit.
*/
static inline void adc_ll_digi_filter_disable(adc_digi_filter_idx_t idx)
{
abort();
}
/**
* Set adc digital controller filter factor.
*
* @param adc_n ADC unit.
* @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
* @note If the channel info is not supported, the filter function will not be enabled.
* @param idx ADC filter unit.
* @param filter Filter config. Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
*/
static inline void adc_ll_digi_filter_set_factor(adc_ll_num_t adc_n, adc_digi_filter_mode_t factor)
static inline void adc_ll_digi_filter_set_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
{
abort();
}
@@ -394,19 +376,7 @@ static inline void adc_ll_digi_filter_set_factor(adc_ll_num_t adc_n, adc_digi_fi
* @param adc_n ADC unit.
* @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
*/
static inline void adc_ll_digi_filter_get_factor(adc_ll_num_t adc_n, adc_digi_filter_mode_t *factor)
{
abort();
}
/**
* Enable/disable adc digital controller filter.
* Filtering the ADC data to obtain smooth data at higher sampling rates.
*
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
*/
static inline void adc_ll_digi_filter_enable(adc_ll_num_t adc_n, bool enable)
static inline void adc_ll_digi_filter_get_factor(adc_digi_filter_idx_t idx, adc_digi_filter_t *filter)
{
abort();
}
@@ -432,11 +402,23 @@ static inline uint32_t adc_ll_digi_filter_read_data(adc_ll_num_t adc_n)
* @param is_larger true: If ADC_OUT > threshold, Generates monitor interrupt.
* false: If ADC_OUT < threshold, Generates monitor interrupt.
*/
static inline void adc_ll_digi_monitor_set_mode(adc_ll_num_t adc_n, bool is_larger)
static inline void adc_ll_digi_monitor_set_mode(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *cfg)
{
abort();
}
/**
* Enable/disable monitor of adc digital controller.
*
* @note If the channel info is not supported, the monitor function will not be enabled.
* @param adc_n ADC unit.
*/
static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx)
{
abort();
}
/**
* Set monitor threshold of adc digital controller.
*
@@ -523,6 +505,30 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
return SENS.sar_meas2_mux.sar2_pwdet_cct;
}
/**
* Analyze whether the obtained raw data is correct.
* ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data.
*
* @param adc_n ADC unit.
* @param raw_data ADC raw data input (convert value).
* @return
* - 0: The data is correct to use.
* - -1: The data is invalid.
*/
static inline adc_ll_rtc_raw_data_t adc_ll_analysis_raw_data(adc_ll_num_t adc_n, int raw_data)
{
if (adc_n == ADC_NUM_1) {
return ADC_RTC_DATA_OK;
}
//The raw data API returns value without channel information. Read value directly from the register
if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 12) & 0xF) > 9) {
return ADC_RTC_DATA_FAIL;
}
return ADC_RTC_DATA_OK;
}
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
@@ -534,12 +540,18 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
{
if (manage == ADC_POWER_SW_ON) {
SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1;
SENS.sar_power_xpd_sar.force_xpd_sar = 3; //SENS_FORCE_XPD_SAR_PU;
APB_SARADC.ctrl.sar_clk_gated = 1;
APB_SARADC.ctrl.xpd_sar_force = 3;
} else if (manage == ADC_POWER_BY_FSM) {
SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1;
SENS.sar_power_xpd_sar.force_xpd_sar = 0; //SENS_FORCE_XPD_SAR_FSM;
APB_SARADC.ctrl.sar_clk_gated = 1;
APB_SARADC.ctrl.xpd_sar_force = 0;
} else if (manage == ADC_POWER_SW_OFF) {
SENS.sar_power_xpd_sar.force_xpd_sar = 2; //SENS_FORCE_XPD_SAR_PD;
SENS.sar_peri_clk_gate_conf.saradc_clk_en = 0;
APB_SARADC.ctrl.sar_clk_gated = 0;
APB_SARADC.ctrl.xpd_sar_force = 2;
}
@@ -559,37 +571,37 @@ static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t
{
if (adc_n == ADC_NUM_1) {
switch (ctrl) {
case ADC_LL_CTRL_RTC:
SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_ULP:
SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_DIG:
SENS.sar_meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
default:
break;
case ADC_LL_CTRL_RTC:
SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_ULP:
SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_DIG:
SENS.sar_meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
default:
break;
}
} else { // adc_n == ADC_NUM_2
//If ADC2 is not controlled by ULP, the arbiter will decide which controller to use ADC2.
switch (ctrl) {
case ADC_LL_CTRL_ARB:
SENS.sar_meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_ULP:
SENS.sar_meas2_ctrl2.meas2_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
default:
break;
case ADC_LL_CTRL_ARB:
SENS.sar_meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_ULP:
SENS.sar_meas2_ctrl2.meas2_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
default:
break;
}
}
}
@@ -752,19 +764,23 @@ static inline void adc_ll_vref_output(adc_ll_num_t adc, adc_channel_t channel, b
*/
static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div)
{
abort();
if (adc_n == ADC_NUM_1) {
SENS.sar_reader1_ctrl.sar1_clk_div = div;
} else { // adc_n == ADC_NUM_2
SENS.sar_reader2_ctrl.sar2_clk_div = div;
}
}
/**
* Set adc output data format for RTC controller.
*
* @note ESP32S2 RTC controller only support 13bit.
* @note ESP32S3 RTC controller only support 13bit.
* @prarm adc_n ADC unit.
* @prarm bits Output data bits width option.
*/
static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_width_t bits)
{
abort();
}
/**
@@ -777,7 +793,11 @@ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_wid
*/
static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
{
abort();
if (adc_n == ADC_NUM_1) {
SENS.sar_meas1_ctrl2.sar1_en_pad = (1 << channel); //only one channel is selected.
} else { // adc_n == ADC_NUM_2
SENS.sar_meas2_ctrl2.sar2_en_pad = (1 << channel); //only one channel is selected.
}
}
/**
@@ -790,7 +810,11 @@ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
*/
static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n)
{
abort();
if (adc_n == ADC_NUM_1) {
SENS.sar_meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected.
} else { // adc_n == ADC_NUM_2
SENS.sar_meas2_ctrl2.sar2_en_pad = 0; //only one channel is selected.
}
}
/**
@@ -803,7 +827,14 @@ static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n)
*/
static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel)
{
abort();
if (adc_n == ADC_NUM_1) {
while (SENS.sar_slave_addr1.meas_status != 0);
SENS.sar_meas1_ctrl2.meas1_start_sar = 0;
SENS.sar_meas1_ctrl2.meas1_start_sar = 1;
} else { // adc_n == ADC_NUM_2
SENS.sar_meas2_ctrl2.meas2_start_sar = 0; //start force 0
SENS.sar_meas2_ctrl2.meas2_start_sar = 1; //start force 1
}
}
/**
@@ -816,7 +847,13 @@ static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel)
*/
static inline bool adc_ll_rtc_convert_is_done(adc_ll_num_t adc_n)
{
abort();
bool ret = true;
if (adc_n == ADC_NUM_1) {
ret = (bool)SENS.sar_meas1_ctrl2.meas1_done_sar;
} else { // adc_n == ADC_NUM_2
ret = (bool)SENS.sar_meas2_ctrl2.meas2_done_sar;
}
return ret;
}
/**
@@ -828,7 +865,13 @@ static inline bool adc_ll_rtc_convert_is_done(adc_ll_num_t adc_n)
*/
static inline int adc_ll_rtc_get_convert_value(adc_ll_num_t adc_n)
{
abort();
int ret_val = 0;
if (adc_n == ADC_NUM_1) {
ret_val = SENS.sar_meas1_ctrl2.meas1_data_sar;
} else { // adc_n == ADC_NUM_2
ret_val = SENS.sar_meas2_ctrl2.meas2_data_sar;
}
return ret_val;
}
/**
@@ -839,7 +882,11 @@ static inline int adc_ll_rtc_get_convert_value(adc_ll_num_t adc_n)
*/
static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en)
{
abort();
if (adc_n == ADC_NUM_1) {
SENS.sar_reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert
} else { // adc_n == ADC_NUM_2
SENS.sar_reader2_ctrl.sar2_data_inv = inv_en; // Enable / Disable ADC data invert
}
}
/**
@@ -849,7 +896,13 @@ static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en)
*/
static inline void adc_ll_rtc_intr_enable(adc_ll_num_t adc_n)
{
abort();
if (adc_n == ADC_NUM_1) {
SENS.sar_reader1_ctrl.sar1_int_en = 1;
RTCCNTL.int_ena.rtc_saradc1 = 1;
} else { // adc_n == ADC_NUM_2
SENS.sar_reader2_ctrl.sar2_int_en = 1;
RTCCNTL.int_ena.rtc_saradc2 = 1;
}
}
/**
@@ -859,7 +912,13 @@ static inline void adc_ll_rtc_intr_enable(adc_ll_num_t adc_n)
*/
static inline void adc_ll_rtc_intr_disable(adc_ll_num_t adc_n)
{
abort();
if (adc_n == ADC_NUM_1) {
SENS.sar_reader1_ctrl.sar1_int_en = 0;
RTCCNTL.int_ena.rtc_saradc1 = 0;
} else { // adc_n == ADC_NUM_2
SENS.sar_reader2_ctrl.sar2_int_en = 0;
RTCCNTL.int_ena.rtc_saradc2 = 0;
}
}
/**
@@ -867,7 +926,8 @@ static inline void adc_ll_rtc_intr_disable(adc_ll_num_t adc_n)
*/
static inline void adc_ll_rtc_reset(void)
{
abort();
SENS.sar_peri_reset_conf.saradc_reset = 1;
SENS.sar_peri_reset_conf.saradc_reset = 0;
}
/**
@@ -878,7 +938,7 @@ static inline void adc_ll_rtc_reset(void)
*/
static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
{
abort();
SENS.sar_reader2_ctrl.sar2_wait_arb_cycle = cycle;
}
/**
@@ -895,7 +955,20 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
*/
static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t adc_n, uint16_t raw_data)
{
abort();
/* ADC1 don't need check data */
if (adc_n == ADC_NUM_1) {
return ADC_RTC_DATA_OK;
}
adc_ll_rtc_output_data_t *temp = (adc_ll_rtc_output_data_t *)&raw_data;
if (temp->flag == 0) {
return ADC_RTC_DATA_OK;
} else if (temp->flag == 1) {
return ADC_RTC_CTRL_UNSELECTED;
} else if (temp->flag == 2) {
return ADC_RTC_CTRL_BREAK;
} else {
return ADC_RTC_DATA_FAIL;
}
}
/**
@@ -933,9 +1006,24 @@ static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t ad
*/
static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
{
abort();
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));
}
}
static inline uint32_t adc_ll_adc1_read(void)
{
//On ESP32S3, valid data width is 12-bit
return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff);
}
static inline uint32_t adc_ll_adc2_read(void)
{
//On ESP32S3, valid data width is 12-bit
return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff);
}
#ifdef __cplusplus
}