mirror of
https://github.com/espressif/esp-idf.git
synced 2025-11-08 07:26:22 +00:00
adc: create common adc hal layer
This commit is contained in:
@@ -10,12 +10,14 @@
|
||||
|
||||
#include "soc/adc_periph.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_types_private.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/misc.h"
|
||||
#include "soc/apb_saradc_struct.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "soc/apb_saradc_reg.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "hal/misc.h"
|
||||
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
#include "regi2c_saradc.h"
|
||||
@@ -24,9 +26,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15
|
||||
#define ADC_LL_CLKM_DIV_B_DEFAULT 1
|
||||
#define ADC_LL_CLKM_DIV_A_DEFAULT 0
|
||||
#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15
|
||||
#define ADC_LL_CLKM_DIV_B_DEFAULT 1
|
||||
#define ADC_LL_CLKM_DIV_A_DEFAULT 0
|
||||
|
||||
#define ADC_LL_EVENT_ADC1_ONESHOT_DONE (1 << 0)
|
||||
#define ADC_LL_EVENT_ADC2_ONESHOT_DONE (1 << 1)
|
||||
|
||||
typedef enum {
|
||||
ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */
|
||||
@@ -36,10 +41,10 @@ typedef enum {
|
||||
} adc_ll_power_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_RTC_DATA_OK = 0,
|
||||
ADC_RTC_CTRL_UNSELECTED = 1,
|
||||
ADC_RTC_CTRL_BREAK = 2,
|
||||
ADC_RTC_DATA_FAIL = -1,
|
||||
ADC_LL_RTC_DATA_OK = 0,
|
||||
ADC_LL_RTC_CTRL_UNSELECTED = 1, ///< The current controller is not enabled by the arbiter.
|
||||
ADC_LL_RTC_CTRL_BREAK = 2, ///< The current controller process was interrupted by a higher priority controller.
|
||||
ADC_LL_RTC_DATA_FAIL = -1, ///< The data is wrong
|
||||
} adc_ll_rtc_raw_data_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -702,11 +707,10 @@ static inline void adc_ll_calibration_init(adc_unit_t adc_n)
|
||||
* Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration.
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
* @param channel Not used.
|
||||
* @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_unit_t adc_n, adc_channel_t channel, bool internal_gnd)
|
||||
static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd)
|
||||
{
|
||||
/* Should be called before writing I2C registers. */
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M);
|
||||
@@ -800,12 +804,13 @@ static inline void adc_ll_set_sar_clk_div(adc_unit_t adc_n, uint32_t div)
|
||||
* Set adc output data format for RTC controller.
|
||||
*
|
||||
* @note ESP32S3 RTC controller only support 12bit.
|
||||
* @prarm adc_n ADC unit.
|
||||
* @prarm bits Output data bits width option.
|
||||
* @param adc_n ADC unit.
|
||||
* @param bits Output data bits width option.
|
||||
*/
|
||||
static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width_t bits)
|
||||
static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits)
|
||||
{
|
||||
//ESP32S3 only supports 12bit, leave here for compatibility
|
||||
HAL_ASSERT(bits == ADC_BITWIDTH_12);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -816,7 +821,7 @@ static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel)
|
||||
static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
SENS.sar_meas1_ctrl2.sar1_en_pad = (1 << channel); //only one channel is selected.
|
||||
@@ -833,7 +838,7 @@ static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel)
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n)
|
||||
static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
SENS.sar_meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected.
|
||||
@@ -848,9 +853,8 @@ static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n)
|
||||
* @note It may be block to wait conversion idle for ADC1.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel)
|
||||
static inline void adc_oneshot_ll_start(adc_unit_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
while (HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_slave_addr1, meas_status) != 0) {}
|
||||
@@ -863,20 +867,33 @@ static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the conversion done flag for each ADCn for RTC controller.
|
||||
* Clear the event for each ADCn for Oneshot mode
|
||||
*
|
||||
* @param event ADC event
|
||||
*/
|
||||
static inline void adc_oneshot_ll_clear_event(uint32_t event)
|
||||
{
|
||||
//For compatibility
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the event for each ADCn for Oneshot mode
|
||||
*
|
||||
* @param event ADC event
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @return
|
||||
* -true : The conversion process is finish.
|
||||
* -false : The conversion process is not finish.
|
||||
*/
|
||||
static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n)
|
||||
static inline bool adc_oneshot_ll_get_event(uint32_t event)
|
||||
{
|
||||
bool ret = true;
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
if (event == ADC_LL_EVENT_ADC1_ONESHOT_DONE) {
|
||||
ret = (bool)SENS.sar_meas1_ctrl2.meas1_done_sar;
|
||||
} else { // adc_n == ADC_UNIT_2
|
||||
} else if (event == ADC_LL_EVENT_ADC2_ONESHOT_DONE) {
|
||||
ret = (bool)SENS.sar_meas2_ctrl2.meas2_done_sar;
|
||||
} else {
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -888,9 +905,9 @@ static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n)
|
||||
* @return
|
||||
* - Converted value.
|
||||
*/
|
||||
static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n)
|
||||
static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n)
|
||||
{
|
||||
int ret_val = 0;
|
||||
uint32_t ret_val = 0;
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
ret_val = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_meas1_ctrl2, meas1_data_sar);
|
||||
} else { // adc_n == ADC_UNIT_2
|
||||
@@ -899,13 +916,37 @@ static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze whether the obtained raw data is correct.
|
||||
* ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param raw ADC raw data input (convert value).
|
||||
* @return
|
||||
* - true: raw data is valid
|
||||
* - false: raw data is invalid
|
||||
*/
|
||||
static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
return true;
|
||||
}
|
||||
adc_ll_rtc_output_data_t *temp = (adc_ll_rtc_output_data_t *)&raw;
|
||||
if (temp->flag == 0) {
|
||||
return true;
|
||||
} else {
|
||||
//Could be ADC_LL_RTC_CTRL_UNSELECTED, ADC_LL_RTC_CTRL_BREAK or ADC_LL_RTC_DATA_FAIL
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module RTC output data invert or not.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param inv_en data invert or not.
|
||||
*/
|
||||
static inline void adc_ll_rtc_output_invert(adc_unit_t adc_n, bool inv_en)
|
||||
static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
SENS.sar_reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert
|
||||
@@ -966,36 +1007,6 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
|
||||
SENS.sar_reader2_ctrl.sar2_wait_arb_cycle = cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze whether the obtained raw data is correct.
|
||||
* ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param raw_data ADC raw data input (convert value).
|
||||
* @return
|
||||
* - 0: The data is correct to use.
|
||||
* - 1: The data is invalid. The current controller is not enabled by the arbiter.
|
||||
* - 2: The data is invalid. The current controller process was interrupted by a higher priority controller.
|
||||
* - -1: The data is error.
|
||||
*/
|
||||
static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_unit_t adc_n, uint16_t raw_data)
|
||||
{
|
||||
/* ADC1 don't need check data */
|
||||
if (adc_n == ADC_UNIT_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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attenuation of a particular channel on ADCn.
|
||||
*
|
||||
@@ -1029,7 +1040,7 @@ static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_unit_t adc_
|
||||
* @param channel ADCn channel number.
|
||||
* @param atten The attenuation option.
|
||||
*/
|
||||
static inline void adc_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten)
|
||||
static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
SENS.sar_atten1 = ( SENS.sar_atten1 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2));
|
||||
@@ -1066,6 +1077,25 @@ static inline uint32_t adc_ll_adc2_read(void)
|
||||
return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable oneshot conversion trigger
|
||||
*
|
||||
* @param adc_n Not used, for compatibility
|
||||
*/
|
||||
static inline void adc_oneshot_ll_enable(adc_unit_t adc_n)
|
||||
{
|
||||
(void)adc_n;
|
||||
//For compatibility
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable oneshot conversion trigger for all the ADC units
|
||||
*/
|
||||
static inline void adc_oneshot_ll_disable_all_unit(void)
|
||||
{
|
||||
//For compatibility
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user