driver(adc/dac): fix adc dac driver for esp32s2

1. update register file about adc; 2. fix adc driver; 3. add UT for adc/dac;

See merge request espressif/esp-idf!7776
This commit is contained in:
fuzhibo
2020-02-25 22:19:48 +08:00
parent dfbb108ab4
commit baa7898e35
62 changed files with 9686 additions and 3691 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
set(srcs "brownout_hal.c"
set(srcs "adc_hal.c"
"brownout_hal.c"
"rtc_clk.c"
"rtc_clk_init.c"
"rtc_init.c"
+87
View File
@@ -0,0 +1,87 @@
// Copyright 2015-2019 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.
// The HAL layer for ADC (common part)
#include "hal/adc_hal.h"
#include "hal/adc_types.h"
void adc_hal_digi_init(void)
{
adc_hal_init();
adc_hal_set_sar_clk_div(ADC_NUM_1, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_1));
adc_hal_set_sar_clk_div(ADC_NUM_2, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_2));
}
void adc_hal_digi_deinit(void)
{
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
adc_hal_deinit();
}
void adc_hal_digi_controller_config(const adc_hal_digi_config_t *cfg)
{
/* If enable digital controller, adc xpd should always on. */
adc_ll_set_power_manage(ADC_POWER_SW_ON);
adc_ll_digi_set_clk_div(cfg->clk_div);
/* Single channel mode or multi channel mode. */
adc_ll_digi_set_convert_mode(cfg->conv_mode);
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
if (cfg->adc1_pattern_len) {
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
for (int i = 0; i < cfg->adc1_pattern_len; i++) {
adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
}
}
}
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
if (cfg->adc2_pattern_len) {
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
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_output_format(cfg->format);
if (cfg->conv_limit_en) {
adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num);
adc_ll_digi_convert_limit_enable();
} else {
adc_ll_digi_convert_limit_disable();
}
adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_ADC);
}
int adc_hal_hall_convert(void)
{
int Sens_Vp0;
int Sens_Vn0;
int Sens_Vp1;
int Sens_Vn1;
int hall_value;
// convert for 4 times with different phase and outputs
adc_ll_hall_phase_disable(); // hall phase
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0, &Sens_Vp0 );
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3, &Sens_Vn0 );
adc_ll_hall_phase_enable();
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0, &Sens_Vp1 );
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3, &Sens_Vn1 );
hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0);
return hall_value;
}
@@ -0,0 +1,118 @@
// Copyright 2019 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.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The HAL layer for ADC (esp32 specific part)
#pragma once
#include "hal/adc_ll.h"
#include "hal/adc_types.h"
#include_next "hal/adc_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
bool conv_limit_en; /*!<Enable max conversion number detection for digital controller.
If the number of ADC conversion is equal to the `limit_num`, the conversion is stopped. */
uint32_t conv_limit_num; /*!<ADC max conversion number for digital controller. */
uint32_t adc1_pattern_len; /*!<Pattern table length for digital controller. Range: 0 ~ 16.
The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. */
uint32_t adc2_pattern_len; /*!<Refer to `adc1_pattern_len` */
adc_hal_digi_pattern_table_t *adc1_pattern; /*!<Pointer to pattern table for digital controller. The table size defined by `adc1_pattern_len`. */
adc_hal_digi_pattern_table_t *adc2_pattern; /*!<Refer to `adc1_pattern` */
adc_hal_digi_convert_mode_t conv_mode; /*!<ADC conversion mode for digital controller. ESP32 only support ADC1 single mode. */
adc_hal_digi_output_format_t format; /*!<ADC output data format for digital controller. */
uint32_t clk_div; /*!< ADC module clock division factor. ADC clock divided from APB clock.*/
} adc_hal_digi_config_t;
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
/**
* Set I2S DMA data source for digital controller.
*
* @param src i2s data source.
*/
#define adc_hal_digi_set_data_source(src) adc_ll_digi_set_data_source(src)
/**
* Setting the digital controller.
*
* @prarm adc_digi_config_t cfg Pointer to digital controller paramter.
*/
void adc_hal_digi_controller_config(const adc_hal_digi_config_t *cfg);
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* @brief ADC digital controller initialization.
*/
void adc_hal_digi_init(void);
/**
* @brief ADC digital controller deinitialization.
*/
void adc_hal_digi_deinit(void);
/*---------------------------------------------------------------
Hall sensor setting
---------------------------------------------------------------*/
/**
* Enable hall sensor.
*/
#define adc_hal_hall_enable() adc_ll_hall_enable()
/**
* Disable hall sensor.
*/
#define adc_hal_hall_disable() adc_ll_hall_disable()
/**
* Start hall convert and return the hall value.
*
* @return Hall value.
*/
int adc_hal_hall_convert(void);
/**
* @brief Output ADC2 reference voltage to gpio
*
* This function utilizes the testing mux exclusive to ADC2 to route the
* reference voltage one of ADC2's channels.
*
* @param[in] io GPIO number
* @return
* - true: v_ref successfully routed to selected gpio
* - false: Unsupported gpio
*/
#define adc_hal_vref_output(io) adc_ll_vref_output(io)
#ifdef __cplusplus
}
#endif
+164 -80
View File
@@ -9,12 +9,12 @@ extern "C" {
#endif
typedef enum {
ADC_DIG_FORMAT_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data.
ADC_DIGI_FORMAT_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data.
Note: In single convert mode. */
ADC_DIG_FORMAT_11BIT, /*!< ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data.
ADC_DIGI_FORMAT_11BIT, /*!< ADC to I2S data format, [15]-adc unit [14:11]-channel [10:0]-11 bits ADC data.
Note: In multi convert mode. */
ADC_DIG_FORMAT_MAX,
} adc_ll_dig_output_format_t;
ADC_DIGI_FORMAT_MAX,
} adc_hal_digi_output_format_t;
typedef enum {
ADC_CONV_SINGLE_UNIT_1 = 1, /*!< SAR ADC 1*/
@@ -22,7 +22,7 @@ typedef enum {
ADC_CONV_BOTH_UNIT = 3, /*!< SAR ADC 1 and 2, not supported yet */
ADC_CONV_ALTER_UNIT = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */
ADC_CONV_UNIT_MAX,
} adc_ll_convert_mode_t;
} adc_hal_digi_convert_mode_t;
typedef enum {
ADC_NUM_1 = 0, /*!< SAR ADC 1 */
@@ -47,18 +47,18 @@ typedef struct {
};
uint8_t val;
};
} adc_ll_pattern_table_t;
} adc_hal_digi_pattern_table_t;
typedef enum {
ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */
ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */
ADC_POWER_SW_OFF, /*!< ADC XPD controled by SW. power off. */
ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */
ADC_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
ADC_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */
ADC_POWER_MAX, /*!< For parameter check. */
} adc_ll_power_t;
typedef enum {
ADC_HALL_CTRL_ULP = 0x0,/*!< Hall sensor controled by ULP */
ADC_HALL_CTRL_RTC = 0x1 /*!< Hall sensor controled by RTC */
ADC_HALL_CTRL_ULP = 0x0,/*!< Hall sensor controlled by ULP */
ADC_HALL_CTRL_RTC = 0x1 /*!< Hall sensor controlled by RTC */
} adc_ll_hall_controller_t ;
typedef enum {
@@ -66,7 +66,11 @@ typedef enum {
ADC_CTRL_ULP = 1,
ADC_CTRL_DIG = 2,
ADC2_CTRL_PWDET = 3,
} adc_ll_controller_t ;
} adc_hal_controller_t ;
typedef enum {
ADC_RTC_DATA_OK = 0,
} adc_ll_rtc_raw_data_t;
/*---------------------------------------------------------------
Digital controller setting
@@ -79,7 +83,7 @@ typedef enum {
* @param start_wait Delay time after open xpd.
* @param standby_wait Delay time to close xpd.
*/
static inline void adc_ll_dig_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait)
static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait)
{
// Internal FSM reset wait time
SYSCON.saradc_fsm.rstb_wait = rst_wait;
@@ -96,17 +100,28 @@ static inline void adc_ll_dig_set_fsm_time(uint32_t rst_wait, uint32_t start_wai
* @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor.
* Range: 2 ~ 0xFF.
*/
static inline void adc_ll_dig_set_sample_cycle(uint32_t sample_cycle)
static inline void adc_ll_digi_set_sample_cycle(uint32_t sample_cycle)
{
SYSCON.saradc_fsm.sample_cycle = sample_cycle;
}
/**
* ADC module clock division factor setting. ADC clock divided from APB clock.
*
* @param div Division factor.
*/
static inline void adc_ll_digi_set_clk_div(uint32_t div)
{
/* ADC clock divided from APB clk, e.g. 80 / 2 = 40Mhz, */
SYSCON.saradc_ctrl.sar_clk_div = div;
}
/**
* Set adc output data format for digital controller.
*
* @param format Output data format.
* @param format Output data format, see ``adc_hal_digi_output_format_t``.
*/
static inline void adc_ll_dig_set_output_format(adc_ll_dig_output_format_t format)
static inline void adc_ll_digi_set_output_format(adc_hal_digi_output_format_t format)
{
SYSCON.saradc_ctrl.data_sar_sel = format;
}
@@ -117,7 +132,7 @@ static inline void adc_ll_dig_set_output_format(adc_ll_dig_output_format_t forma
*
* @param meas_num Max conversion number. Range: 0 ~ 255.
*/
static inline void adc_ll_dig_set_convert_limit_num(uint32_t meas_num)
static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num)
{
SYSCON.saradc_ctrl2.max_meas_num = meas_num;
}
@@ -126,7 +141,7 @@ static inline void adc_ll_dig_set_convert_limit_num(uint32_t meas_num)
* Enable max conversion number detection for digital controller.
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
*/
static inline void adc_ll_dig_convert_limit_enable(void)
static inline void adc_ll_digi_convert_limit_enable(void)
{
SYSCON.saradc_ctrl2.meas_num_limit = 1;
}
@@ -135,7 +150,7 @@ static inline void adc_ll_dig_convert_limit_enable(void)
* Disable max conversion number detection for digital controller.
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
*/
static inline void adc_ll_dig_convert_limit_disable(void)
static inline void adc_ll_digi_convert_limit_disable(void)
{
SYSCON.saradc_ctrl2.meas_num_limit = 0;
}
@@ -145,9 +160,9 @@ static inline void adc_ll_dig_convert_limit_disable(void)
*
* @note ESP32 only support ADC1 single mode.
*
* @param mode Conversion mode select.
* @param mode Conversion mode select, see ``adc_hal_digi_convert_mode_t``.
*/
static inline void adc_ll_dig_set_convert_mode(adc_ll_convert_mode_t mode)
static inline void adc_ll_digi_set_convert_mode(adc_hal_digi_convert_mode_t mode)
{
if (mode == ADC_CONV_SINGLE_UNIT_1) {
SYSCON.saradc_ctrl.work_mode = 0;
@@ -162,27 +177,41 @@ static inline void adc_ll_dig_set_convert_mode(adc_ll_convert_mode_t mode)
}
}
/**
* ADC module Digital output data invert or not.
*
* @prarm adc_n ADC unit.
*/
static inline void adc_ll_digi_output_invert(adc_ll_num_t adc_n, bool inv_en)
{
if (adc_n == ADC_NUM_1) {
SYSCON.saradc_ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert
} else { // adc_n == ADC_NUM_2
SYSCON.saradc_ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert
}
}
/**
* Set I2S DMA data source for digital controller.
*
* @param src i2s data source.
* @param src i2s data source, see ``adc_i2s_source_t``.
*/
static inline void adc_ll_dig_set_data_source(adc_i2s_source_t src)
static inline void adc_ll_digi_set_data_source(adc_i2s_source_t src)
{
/* 1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix */
SYSCON.saradc_ctrl.data_to_i2s = src;
}
/**
* Set pattern table lenth for digital controller.
* Set pattern table length for digital controller.
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
* resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
* pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself.
*
* @prarm adc_n ADC unit.
* @param adc_n ADC unit.
* @param patt_len Items range: 1 ~ 16.
*/
static inline void adc_ll_set_pattern_table_len(adc_ll_num_t adc_n, uint32_t patt_len)
static inline void adc_ll_digi_set_pattern_table_len(adc_ll_num_t adc_n, uint32_t patt_len)
{
if (adc_n == ADC_NUM_1) {
SYSCON.saradc_ctrl.sar1_patt_len = patt_len - 1;
@@ -197,22 +226,41 @@ static inline void adc_ll_set_pattern_table_len(adc_ll_num_t adc_n, uint32_t pat
* resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
* pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself.
*
* @prarm adc_n ADC unit.
* @param pattern_index Items index. Range: 1 ~ 16.
* @param pattern Stored conversion rules.
* @param adc_n ADC unit.
* @param pattern_index Items index. Range: 0 ~ 15.
* @param pattern Stored conversion rules, see ``adc_hal_digi_pattern_table_t``.
*/
static inline void adc_ll_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_ll_pattern_table_t pattern)
static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_hal_digi_pattern_table_t pattern)
{
const uint32_t patt_tab_idx = pattern_index / 4;
const uint32_t patt_shift = (3 - (pattern_index % 4)) * 8;
const uint32_t patt_mask = 0xFF << patt_shift;
uint32_t tab;
uint8_t index = pattern_index / 4;
uint8_t offset = (pattern_index % 4) * 8;
if (adc_n == ADC_NUM_1) {
SYSCON.saradc_sar1_patt_tab[patt_tab_idx] &= ~patt_mask;
SYSCON.saradc_sar1_patt_tab[patt_tab_idx] |= pattern.val << patt_shift;
tab = SYSCON.saradc_sar1_patt_tab[index]; // Read old register value
tab &= (~(0xFF000000 >> offset)); // clear old data
tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
SYSCON.saradc_sar1_patt_tab[index] = tab; // Write back
} else { // adc_n == ADC_NUM_2
SYSCON.saradc_sar2_patt_tab[patt_tab_idx] &= ~patt_mask;
SYSCON.saradc_sar2_patt_tab[patt_tab_idx] |= pattern.val << patt_shift;
tab = SYSCON.saradc_sar2_patt_tab[index]; // Read old register value
tab &= (~(0xFF000000 >> offset)); // clear old data
tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
SYSCON.saradc_sar2_patt_tab[index] = tab; // Write back
}
}
/**
* Reset the pattern table pointer, then take the measurement rule from table header in next measurement.
*
* @param adc_n ADC unit.
*/
static inline void adc_ll_digi_clear_pattern_table(adc_ll_num_t adc_n)
{
if (adc_n == ADC_NUM_1) {
SYSCON.saradc_ctrl.sar1_patt_p_clear = 1;
SYSCON.saradc_ctrl.sar1_patt_p_clear = 0;
} else { // adc_n == ADC_NUM_2
SYSCON.saradc_ctrl.sar2_patt_p_clear = 1;
SYSCON.saradc_ctrl.sar2_patt_p_clear = 0;
}
}
@@ -223,7 +271,7 @@ static inline void adc_ll_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern
* Set adc cct for PWDET controller.
*
* @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
* @prarm cct Range: 0 ~ 7.
* @param cct Range: 0 ~ 7.
*/
static inline void adc_ll_pwdet_set_cct(uint32_t cct)
{
@@ -249,8 +297,8 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
/**
* Set adc output data format for RTC controller.
*
* @prarm adc_n ADC unit.
* @prarm bits Output data bits width option.
* @param adc_n ADC unit.
* @param bits Output data bits width option, see ``adc_bits_width_t``.
*/
static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_width_t bits)
{
@@ -266,9 +314,9 @@ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_wid
/**
* Enable adc channel to start convert.
*
* @note Only one channel can be selected for once measurement.
* @note Only one channel can be selected in once measurement.
*
* @prarm adc_n ADC unit.
* @param adc_n ADC unit.
* @param channel ADC channel number for each ADCn.
*/
static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
@@ -280,12 +328,29 @@ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
}
}
/**
* Disable adc channel to start convert.
*
* @note Only one channel can be selected in once measurement.
*
* @param adc_n ADC unit.
* @param channel ADC channel number for each ADCn.
*/
static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n, int channel)
{
if (adc_n == ADC_NUM_1) {
SENS.sar_meas_start1.sar1_en_pad = 0; //only one channel is selected.
} else { // adc_n == ADC_NUM_2
SENS.sar_meas_start2.sar2_en_pad = 0; //only one channel is selected.
}
}
/**
* Start conversion once by software for RTC controller.
*
* @note It may be block to wait conversion idle for ADC1.
*
* @prarm adc_n ADC unit.
* @param adc_n ADC unit.
* @param channel ADC channel number for each ADCn.
*/
static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel)
@@ -303,7 +368,7 @@ static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel)
/**
* Check the conversion done flag for each ADCn for RTC controller.
*
* @prarm adc_n ADC unit.
* @param adc_n ADC unit.
* @return
* -true : The conversion process is finish.
* -false : The conversion process is not finish.
@@ -322,7 +387,7 @@ static inline bool adc_ll_rtc_convert_is_done(adc_ll_num_t adc_n)
/**
* Get the converted value for each ADCn for RTC controller.
*
* @prarm adc_n ADC unit.
* @param adc_n ADC unit.
* @return
* - Converted value.
*/
@@ -337,13 +402,41 @@ static inline int adc_ll_rtc_get_convert_value(adc_ll_num_t adc_n)
return ret_val;
}
/**
* ADC module RTC output data invert or not.
*
* @param adc_n ADC unit.
*/
static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en)
{
if (adc_n == ADC_NUM_1) {
SENS.sar_read_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert
} else { // adc_n == ADC_NUM_2
SENS.sar_read_ctrl2.sar2_data_inv = inv_en; // Enable / Disable ADC data invert
}
}
/**
* Analyze whether the obtained raw data is correct.
*
* @param adc_n ADC unit.
* @param raw_data ADC raw data input (convert value).
* @return
* - 0: The data is correct to use.
*/
static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t adc_n, uint16_t raw_data)
{
/* ADC1 don't need check data */
return ADC_RTC_DATA_OK;
}
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* Set ADC module power management.
*
* @prarm manage Set ADC power status.
* @param manage Set ADC power status.
*/
static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
{
@@ -380,14 +473,17 @@ static inline adc_ll_power_t adc_ll_get_power_manage(void)
}
/**
* ADC module clock division factor setting. ADC clock devided from APB clock.
* ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`.
*
* @prarm div Division factor.
* @param div Division factor.
*/
static inline void adc_ll_set_clk_div(uint32_t div)
static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div)
{
/* ADC clock devided from APB clk, e.g. 80 / 2 = 40Mhz, */
SYSCON.saradc_ctrl.sar_clk_div = div;
if (adc_n == ADC_NUM_1) {
SENS.sar_read_ctrl.sar1_clk_div = div;
} else { // adc_n == ADC_NUM_2
SENS.sar_read_ctrl2.sar2_clk_div = div;
}
}
/**
@@ -400,7 +496,7 @@ static inline void adc_ll_set_clk_div(uint32_t div)
*
* When VDD_A is 3.3V:
*
* - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
* - 0dB attenuation (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)
@@ -412,16 +508,16 @@ static inline void adc_ll_set_clk_div(uint32_t div)
*
* 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
* - 0dB attenuation (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.
*
* @prarm adc_n ADC unit.
* @prarm channel ADCn channel number.
* @prarm atten The attenuation option.
* @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)
{
@@ -433,30 +529,18 @@ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, a
}
/**
* ADC module RTC output data invert or not.
* Get the attenuation of a particular channel on ADCn.
*
* @prarm adc_n ADC unit.
* @param adc_n ADC unit.
* @param channel ADCn channel number.
* @return atten The attenuation option.
*/
static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en)
static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t channel)
{
if (adc_n == ADC_NUM_1) {
SENS.sar_read_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert
} else { // adc_n == ADC_NUM_2
SENS.sar_read_ctrl2.sar2_data_inv = inv_en; // Enable / Disable ADC data invert
}
}
/**
* ADC module Digital output data invert or not.
*
* @prarm adc_n ADC unit.
*/
static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en)
{
if (adc_n == ADC_NUM_1) {
SYSCON.saradc_ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert
} else { // adc_n == ADC_NUM_2
SYSCON.saradc_ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert
return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3);
} else {
return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3);
}
}
@@ -467,10 +551,10 @@ static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en)
* Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep;
* the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2.
*
* @prarm adc_n ADC unit.
* @prarm ctrl ADC controller.
* @param adc_n ADC unit.
* @param ctrl ADC controller.
*/
static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl)
static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_hal_controller_t ctrl)
{
if (adc_n == ADC_NUM_1) {
switch ( ctrl ) {
@@ -178,6 +178,7 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
static inline void dac_ll_dma_enable(void)
{
SENS.sar_dac_ctrl1.dac_dig_force = 1;
SENS.sar_dac_ctrl1.dac_clk_inv = 1;
}
/**
@@ -186,6 +187,7 @@ static inline void dac_ll_dma_enable(void)
static inline void dac_ll_dma_disable(void)
{
SENS.sar_dac_ctrl1.dac_dig_force = 0;
SENS.sar_dac_ctrl1.dac_clk_inv = 0;
}
+1 -1
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// The HAL layer for SPI (common part)
// The HAL layer for Touch sensor (common part)
#include "hal/touch_sensor_hal.h"
#include "hal/touch_sensor_types.h"
+2 -1
View File
@@ -1,4 +1,5 @@
set(srcs "brownout_hal.c"
set(srcs "adc_hal.c"
"brownout_hal.c"
"rtc_clk.c"
"rtc_clk_init.c"
"rtc_init.c"
+252
View File
@@ -0,0 +1,252 @@
// Copyright 2015-2019 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.
// The HAL layer for ADC (esp32s2 specific part)
#include "hal/adc_hal.h"
#include "hal/adc_types.h"
#include "esp_log.h"
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
void adc_hal_digi_init(void)
{
adc_hal_init();
adc_ll_digi_set_clk_div(SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT);
adc_ll_digi_output_invert(ADC_NUM_1, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_1));
adc_ll_digi_output_invert(ADC_NUM_2, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_2));
}
void adc_hal_digi_deinit(void)
{
adc_ll_digi_trigger_disable(); // boss
adc_ll_digi_dma_disable();
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
adc_ll_digi_filter_reset(ADC_NUM_1);
adc_ll_digi_filter_reset(ADC_NUM_2);
adc_ll_digi_reset();
adc_ll_digi_controller_clk_disable();
adc_hal_deinit();
}
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)
{
/* If enable digtal controller, adc xpd should always on. */
adc_ll_set_power_manage(ADC_POWER_SW_ON);
/* Single channel mode or multi channel mode. */
adc_ll_digi_set_convert_mode(cfg->conv_mode);
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
if (cfg->adc1_pattern_len) {
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
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_set_init_code(ADC_NUM_1, cfg->adc1_pattern[i].channel, cfg->adc1_pattern[i].atten);
}
}
}
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
if (cfg->adc2_pattern_len) {
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
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_set_init_code(ADC_NUM_2, cfg->adc2_pattern[i].channel, cfg->adc2_pattern[i].atten);
}
}
}
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
}
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
}
adc_ll_digi_set_output_format(cfg->format);
if (cfg->conv_limit_en) {
adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num);
adc_ll_digi_convert_limit_enable();
} else {
adc_ll_digi_convert_limit_disable();
}
adc_ll_digi_set_trigger_interval(cfg->interval);
adc_hal_digi_clk_config(&cfg->dig_clk);
adc_ll_digi_dma_set_eof_num(cfg->dma_eof_num);
}
/**
* Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
* Enable clock and select clock source for ADC digital controller.
* Expression: controller_clk = APLL/APB * (div_num + div_b / div_a).
*
* @param clk Refer to `adc_digi_clk_t`.
*/
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk)
{
adc_ll_digi_controller_clk_div(clk->div_num, clk->div_b, clk->div_a);
adc_ll_digi_controller_clk_enable(clk->use_apll);
}
/**
* Enable digital controller to trigger the measurement.
*/
void adc_hal_digi_enable(void)
{
adc_ll_digi_dma_enable();
adc_ll_digi_trigger_enable();
}
/**
* Disable digital controller to trigger the measurement.
*/
void adc_hal_digi_disable(void)
{
adc_ll_digi_trigger_disable();
adc_ll_digi_dma_disable();
}
/**
* Config monitor of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @param config Refer to `adc_digi_monitor_t`.
*/
void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config)
{
adc_ll_digi_monitor_set_mode(adc_n, config->mode);
adc_ll_digi_monitor_set_thres(adc_n, config->threshold);
}
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* Config ADC2 module arbiter.
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
* the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data.
*
* @note Only ADC2 support arbiter.
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
* @note Default priority: Wi-Fi > RTC > Digital;
*
* @param config Refer to `adc_arbiter_t`.
*/
void adc_hal_arbiter_config(adc_arbiter_t *config)
{
adc_ll_set_arbiter_work_mode(config->mode);
adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri);
}
/*---------------------------------------------------------------
ADC calibration setting
---------------------------------------------------------------*/
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;
}
@@ -0,0 +1,262 @@
// Copyright 2019 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.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The HAL layer for ADC (esp32s2 specific part)
#pragma once
#include "hal/adc_ll.h"
#include "hal/adc_types.h"
#include_next "hal/adc_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
/**
* Digital controller initialization.
*/
void adc_hal_digi_init(void);
/**
* Digital controller deinitialization.
*/
void adc_hal_digi_deinit(void);
/**
* Setting the digital controller.
*
* @param cfg Pointer to digital controller paramter.
*/
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg);
/**
* ADC Digital controller output data invert or not.
*
* @param adc_n ADC unit.
* @param inv_en data invert or not.
*/
#define adc_hal_digi_output_invert(adc_n, inv_en) adc_ll_digi_output_invert(adc_n, inv_en)
/**
* Sets the number of interval clock cycles for the digital controller to trigger the measurement.
*
* @note The trigger interval should not be less than the sampling time of the SAR ADC.
* @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095.
*/
#define adc_hal_digi_set_trigger_interval(cycle) adc_ll_digi_set_trigger_interval(cycle)
/**
* Enable digital controller to trigger the measurement.
*/
void adc_hal_digi_enable(void);
/**
* Disable digital controller to trigger the measurement.
*/
void adc_hal_digi_disable(void);
/**
* Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
* Enable clock and select clock source for ADC digital controller.
* Expression: controller_clk = APLL/APB * (div_num + div_b / div_a).
*
* @param clk Refer to `adc_digi_clk_t`.
*/
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk);
/**
* Reset adc digital controller filter.
*
* @param adc_n ADC unit.
*/
#define adc_hal_digi_filter_reset(adc_n) adc_ll_digi_filter_reset(adc_n)
/**
* 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).
*/
#define adc_hal_digi_filter_set_factor(adc_n, factor) adc_ll_digi_filter_set_factor(adc_n, factor)
/**
* Get 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).
*/
#define adc_hal_digi_filter_get_factor(adc_n, factor) adc_ll_digi_filter_get_factor(adc_n, factor)
/**
* 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.
*/
#define adc_hal_digi_filter_enable(adc_n, enable) adc_ll_digi_filter_enable(adc_n, enable)
/**
* Get the filtered data of adc digital controller filter.
* The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
*
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @return Filtered data.
*/
#define adc_hal_digi_filter_read_data(adc_n) adc_ll_digi_filter_read_data(adc_n)
/**
* Config monitor of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @param config Refer to `adc_digi_monitor_t`.
*/
void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config);
/**
* Enable/disable monitor of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
*/
#define adc_hal_digi_monitor_enable(adc_n, enable) adc_ll_digi_monitor_enable(adc_n, enable)
/**
* Enable interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
#define adc_hal_digi_intr_enable(adc_n, intr) adc_ll_digi_intr_enable(adc_n, intr)
/**
* Disable interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
#define adc_hal_digi_intr_disable(adc_n, intr) adc_ll_digi_intr_disable(adc_n, intr)
/**
* Clear interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
#define adc_hal_digi_intr_clear(adc_n, intr) adc_ll_digi_intr_clear(adc_n, intr)
/**
* Get interrupt status mask of adc digital controller.
*
* @param adc_n ADC unit.
* @return
* - intr Interrupt bitmask.
*/
#define adc_hal_digi_get_intr_status(adc_n) adc_ll_digi_get_intr_status(adc_n)
/**
* Set DMA eof num of adc digital controller.
* If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated.
*
* @param num eof num of DMA.
*/
#define adc_hal_digi_dma_set_eof_num(num) adc_ll_digi_dma_set_eof_num(num)
/**
* Enable output data to DMA from adc digital controller.
*/
#define adc_hal_digi_dma_enable() adc_ll_digi_dma_enable()
/**
* Disable output data to DMA from adc digital controller.
*/
#define adc_hal_digi_dma_disable() adc_ll_digi_dma_disable()
/**
* Reset adc digital controller.
*/
#define adc_hal_digi_reset() adc_ll_digi_reset()
/*---------------------------------------------------------------
RTC controller setting
---------------------------------------------------------------*/
/**
* Reset RTC controller FSM.
*/
#define adc_hal_rtc_reset() adc_ll_rtc_reset()
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* Config ADC2 module arbiter.
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
* the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data.
*
* @note Only ADC2 support arbiter.
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
* @note Default priority: Wi-Fi > RTC > Digital;
*
* @param config Refer to `adc_arbiter_t`.
*/
void adc_hal_arbiter_config(adc_arbiter_t *config);
/*---------------------------------------------------------------
ADC calibration setting
---------------------------------------------------------------*/
/**
* Calibrate the ADC according to the parameters.
*
* @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.
* @param force_cal true: Do not use the results that have already been verified, and perform the verification again. It will take a long time.
* false: Use the result of the last calibration.
*
* @return
* - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
*/
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);
/**
* Set the calibration result (initial data) to ADC.
*
* @note Different ADC units and different attenuation options use different calibration data (initial data).
*
* @param adc_n ADC index number.
*/
#define adc_hal_set_calibration_param(adc_n, param) adc_ll_set_calibration_param(adc_n, param);
#ifdef __cplusplus
}
#endif
File diff suppressed because it is too large Load Diff
@@ -28,6 +28,10 @@
extern "C" {
#endif
/*---------------------------------------------------------------
RTC controller setting
---------------------------------------------------------------*/
/**
* Power on dac module and start output voltage.
*
@@ -36,6 +40,7 @@ extern "C" {
*/
static inline void dac_ll_power_on(dac_channel_t channel)
{
SENS.sar_dac_ctrl1.dac_clkgate_en = 1;
RTCIO.pad_dac[channel].dac_xpd_force = 1;
RTCIO.pad_dac[channel].xpd_dac = 1;
}
@@ -49,6 +54,9 @@ static inline void dac_ll_power_down(dac_channel_t channel)
{
RTCIO.pad_dac[channel].dac_xpd_force = 0;
RTCIO.pad_dac[channel].xpd_dac = 0;
if (RTCIO.pad_dac[0].xpd_dac == 0 && RTCIO.pad_dac[1].xpd_dac == 0) {
SENS.sar_dac_ctrl1.dac_clkgate_en = 0;
}
}
/**
@@ -69,6 +77,15 @@ static inline void dac_ll_update_output_value(dac_channel_t channel, uint8_t val
}
}
/**
* Reset dac by software.
*/
static inline void dac_ll_rtc_reset(void)
{
SENS.sar_dac_ctrl1.dac_reset = 1;
SENS.sar_dac_ctrl1.dac_reset = 0;
}
/************************************/
/* DAC cosine wave generator API's */
/************************************/
@@ -168,6 +185,10 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
}
}
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
/************************************/
/* DAC DMA API's */
/************************************/
@@ -178,6 +199,7 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
static inline void dac_ll_dma_enable(void)
{
SENS.sar_dac_ctrl1.dac_dig_force = 1;
SENS.sar_dac_ctrl1.dac_clk_inv = 1;
}
/**
@@ -186,6 +208,7 @@ static inline void dac_ll_dma_enable(void)
static inline void dac_ll_dma_disable(void)
{
SENS.sar_dac_ctrl1.dac_dig_force = 0;
SENS.sar_dac_ctrl1.dac_clk_inv = 0;
}
#ifdef __cplusplus
@@ -623,12 +623,6 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable);
*/
#define touch_hal_sleep_read_baseline(baseline) touch_ll_sleep_read_baseline(baseline)
#define touch_hal_sleep_read_smooth(smooth_data) touch_ll_sleep_read_smooth(smooth_data)
#define touch_hal_sleep_read_data(raw_data) touch_ll_sleep_read_data(raw_data)
#define touch_hal_sleep_reset_baseline() touch_ll_sleep_reset_baseline()
/**
* Read smooth data of touch sensor for sleep pad.
*/
@@ -231,26 +231,6 @@ static inline void touch_ll_get_fsm_mode(touch_fsm_mode_t *mode)
*mode = (touch_fsm_mode_t)RTCCNTL.touch_ctrl2.touch_start_force;
}
static inline void touch_ll_clk_enable(void)
{
RTCCNTL.touch_ctrl2.touch_clkgate_en = 1; //enable touch clock for FSM. or force enable.
}
static inline void touch_ll_clk_disable(void)
{
RTCCNTL.touch_ctrl2.touch_clkgate_en = 0; //enable touch clock for FSM. or force enable.
}
/**
* Touch timer trigger measurement and always wait measurement done.
* Force done for touch timer ensures that the timer always can get the measurement done signal.
*/
static inline void touch_ll_timer_force_done(void)
{
RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_FORCE_DONE;
RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_DONE;
}
/**
* Enable/disable clock gate of touch sensor.
*
+9 -59
View File
@@ -17,72 +17,22 @@
void adc_hal_init(void)
{
// Set internal FSM wait time, fixed value.
adc_ll_dig_set_fsm_time(SOC_ADC_FSM_RSTB_WAIT_DEFAULT, SOC_ADC_FSM_START_WAIT_DEFAULT,
SOC_ADC_FSM_STANDBY_WAIT_DEFAULT);
adc_ll_dig_set_sample_cycle(ADC_FSM_SAMPLE_CYCLE_DEFAULT);
adc_hal_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT);
adc_hal_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT);
adc_ll_digi_set_fsm_time(SOC_ADC_FSM_RSTB_WAIT_DEFAULT, SOC_ADC_FSM_START_WAIT_DEFAULT,
SOC_ADC_FSM_STANDBY_WAIT_DEFAULT);
adc_ll_digi_set_sample_cycle(ADC_FSM_SAMPLE_CYCLE_DEFAULT);
adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
}
void adc_hal_dig_controller_config(const adc_hal_dig_config_t *cfg)
void adc_hal_deinit(void)
{
/* If enable digtal controller, adc xpd should always on. */
adc_ll_set_power_manage(ADC_POWER_SW_ON);
adc_ll_set_clk_div(cfg->clk_div);
/* Single channel mode or multi channel mode. */
adc_ll_dig_set_convert_mode(cfg->conv_mode);
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
adc_ll_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
for (int i = 0; i < cfg->adc1_pattern_len; i++) {
adc_ll_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
}
}
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
adc_ll_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
for (int i = 0; i < cfg->adc2_pattern_len; i++) {
adc_ll_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
}
}
adc_ll_dig_set_output_format(cfg->format);
if (cfg->conv_limit_en) {
adc_ll_dig_set_convert_limit_num(cfg->conv_limit_num);
adc_ll_dig_convert_limit_enable();
} else {
adc_ll_dig_convert_limit_disable();
}
adc_ll_dig_set_data_source(ADC_I2S_DATA_SRC_ADC);
adc_ll_set_power_manage(ADC_POWER_SW_OFF);
}
int adc_hal_convert(adc_ll_num_t adc_n, int channel)
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);
return adc_ll_rtc_get_convert_value(adc_n);
*value = adc_ll_rtc_get_convert_value(adc_n);
return (int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*value));
}
int adc_hal_hall_convert(void)
{
int Sens_Vp0;
int Sens_Vn0;
int Sens_Vp1;
int Sens_Vn1;
int hall_value;
// convert for 4 times with different phase and outputs
adc_ll_hall_phase_disable(); // hall phase
Sens_Vp0 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0 );
Sens_Vn0 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3 );
adc_ll_hall_phase_enable();
Sens_Vp1 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0 );
Sens_Vn1 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3 );
hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0);
return hall_value;
}
void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en)
{
adc_ll_rtc_output_invert(adc_n, inv_en);
adc_ll_dig_output_invert(adc_n, inv_en);
}