adc: support adc dma driver on all chips

This commit is contained in:
Armando
2021-12-15 14:15:32 +08:00
committed by Armando (Dou Yiwen)
parent 5ddce053ea
commit 4dc0d6b2fe
81 changed files with 4156 additions and 5420 deletions

View File

@@ -1,123 +0,0 @@
// 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 (ESP32-S2 specific part)
#include "sdkconfig.h"
#include "hal/adc_hal.h"
#include "hal/adc_types.h"
#include "hal/adc_hal_conf.h"
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
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();
}
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
{
/* 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 (uint32_t 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) {
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 (uint32_t i = 0; i < cfg->adc2_pattern_len; i++) {
adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
}
}
}
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` or `APB`) / (div_num + div_a / div_b + 1).
*
* @note ADC and DAC digital controller share the same frequency divider.
* Please set a reasonable frequency division factor to meet the sampling frequency of the ADC and the output frequency of the DAC.
*
* @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);
}

View File

@@ -1,21 +1,13 @@
// 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.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The HAL layer for ADC (esp32s2 specific part)
#include "hal/dac_hal.h"
#include "hal/adc_hal.h"
#include "hal/adc_ll.h"
#include "hal/dac_types.h"
/*---------------------------------------------------------------
@@ -39,7 +31,8 @@ void dac_hal_digi_controller_config(const dac_digi_config_t *cfg)
{
dac_ll_digi_set_convert_mode(cfg->mode);
dac_ll_digi_set_trigger_interval(cfg->interval);
adc_hal_digi_clk_config(&cfg->dig_clk);
adc_ll_digi_controller_clk_div(cfg->dig_clk.div_num, cfg->dig_clk.div_b, cfg->dig_clk.div_a);
adc_ll_digi_clk_sel(cfg->dig_clk.use_apll);
}
void dac_hal_digi_start(void)

View File

@@ -1,202 +0,0 @@
// 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 hal/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
---------------------------------------------------------------*/
/**
* 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.
* Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. Refer to ``adc_digi_clk_t``.
*
* @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` or `APB`) / (div_num + div_a / div_b + 1).
*
* @note ADC and DAC digital controller share the same frequency divider.
* Please set a reasonable frequency division factor to meet the sampling frequency of the ADC and the output frequency of the DAC.
*
* @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()
#ifdef __cplusplus
}
#endif

View File

@@ -1,3 +1,9 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
@@ -15,6 +21,11 @@
extern "C" {
#endif
//To be checked if ESP32S2 has the 5M freq limit
#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15
#define ADC_LL_CLKM_DIV_B_DEFAULT 1
#define ADC_LL_CLKM_DIV_A_DEFAULT 0
typedef enum {
ADC_NUM_1 = 0, /*!< SAR ADC 1 */
ADC_NUM_2 = 1, /*!< SAR ADC 2 */
@@ -35,6 +46,40 @@ typedef enum {
ADC_RTC_DATA_FAIL = -1,
} adc_ll_rtc_raw_data_t;
typedef enum {
ADC_LL_CTRL_RTC = 0, ///< For ADC1. Select RTC controller.
ADC_LL_CTRL_ULP = 1, ///< For ADC1 and ADC2. Select ULP controller.
ADC_LL_CTRL_DIG = 2, ///< For ADC1. Select DIG controller.
ADC_LL_CTRL_ARB = 3, ///< 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 {
uint8_t atten: 2;
uint8_t reserved: 2;
uint8_t channel: 4;
};
uint8_t val;
};
} __attribute__((packed)) adc_ll_digi_pattern_table_t;
/**
* @brief Analyze whether the obtained raw data is correct.
* ADC2 use arbiter by default. The arbitration result can be judged by the flag bit in the original data.
@@ -53,24 +98,6 @@ typedef struct {
};
} adc_ll_rtc_output_data_t;
/**
* @brief ADC controller type selection.
*
* @note For ADC2, use the force option with care. The system power consumption detection will use ADC2.
* If it is forced to switch to another controller, it may cause the system to obtain incorrect values.
* @note Normally, there is no need to switch the controller manually.
*/
typedef enum {
ADC_CTRL_RTC = 0, /*!<For ADC1. Select RTC controller. For ADC2. The controller is selected by the arbiter. Arbiter in default mode. */
ADC_CTRL_ULP = 1, /*!<For ADC1. Select ULP controller. For ADC2. The controller is selected by the arbiter. Arbiter in default mode. */
ADC_CTRL_DIG = 2, /*!<For ADC1. Select DIG controller. For ADC2. The controller is selected by the arbiter. Arbiter in default mode. */
ADC2_CTRL_PWDET = 3,/*!<For ADC2. The controller is selected by the arbiter. Arbiter in default mode. */
ADC2_CTRL_FORCE_PWDET = 3, /*!<For ADC2. Arbiter in shield mode. Force select Wi-Fi controller work. */
ADC2_CTRL_FORCE_RTC = 4, /*!<For ADC2. Arbiter in shield mode. Force select RTC controller work. */
ADC2_CTRL_FORCE_ULP = 5, /*!<For ADC2. Arbiter in shield mode. Force select RTC controller work. */
ADC2_CTRL_FORCE_DIG = 6, /*!<For ADC2. Arbiter in shield mode. Force select digital controller work. */
} adc_ll_controller_t;
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
@@ -120,16 +147,6 @@ static inline void adc_ll_digi_set_clk_div(uint32_t div)
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div);
}
/**
* Set adc output data format for digital controller.
*
* @param format Output data format.
*/
static inline void adc_ll_digi_set_output_format(adc_digi_output_format_t format)
{
APB_SARADC.ctrl.data_sar_sel = format;
}
/**
* Set adc max conversion number for digital controller.
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
@@ -162,22 +179,25 @@ static inline void adc_ll_digi_convert_limit_disable(void)
/**
* Set adc conversion mode for digital controller.
*
* @note ESP32 only support ADC1 single mode.
*
* @param mode Conversion mode select.
* TODO IDF-3610
*/
static inline void adc_ll_digi_set_convert_mode(adc_digi_convert_mode_t mode)
static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode)
{
if (mode == ADC_CONV_SINGLE_UNIT_1) {
if (mode == ADC_LL_DIGI_CONV_ONLY_ADC1) {
APB_SARADC.ctrl.work_mode = 0;
APB_SARADC.ctrl.sar_sel = 0;
} else if (mode == ADC_CONV_SINGLE_UNIT_2) {
APB_SARADC.ctrl.data_sar_sel = 0;
} else if (mode == ADC_LL_DIGI_CONV_ONLY_ADC2) {
APB_SARADC.ctrl.work_mode = 0;
APB_SARADC.ctrl.sar_sel = 1;
} else if (mode == ADC_CONV_BOTH_UNIT) {
APB_SARADC.ctrl.data_sar_sel = 0;
} else if (mode == ADC_LL_DIGI_CONV_BOTH_UNIT) {
APB_SARADC.ctrl.work_mode = 1;
} else if (mode == ADC_CONV_ALTER_UNIT) {
APB_SARADC.ctrl.data_sar_sel = 1;
} else if (mode == ADC_LL_DIGI_CONV_ALTER_UNIT) {
APB_SARADC.ctrl.work_mode = 2;
APB_SARADC.ctrl.data_sar_sel = 1;
}
}
@@ -209,12 +229,15 @@ static inline void adc_ll_digi_set_pattern_table_len(adc_ll_num_t adc_n, uint32_
* @param pattern_index Items index. Range: 0 ~ 15.
* @param pattern Stored conversion rules.
*/
static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_digi_pattern_table_t pattern)
static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table)
{
uint32_t tab;
uint8_t index = pattern_index / 4;
uint8_t offset = (pattern_index % 4) * 8;
if (adc_n == ADC_NUM_1) {
adc_ll_digi_pattern_table_t pattern = {0};
pattern.val = (table.atten & 0x3) | ((table.channel & 0xF) << 4);
if (table.unit == ADC_NUM_1) {
tab = APB_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
@@ -319,7 +342,7 @@ static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div
*
* @param use_apll true: use APLL clock; false: use APB clock.
*/
static inline void adc_ll_digi_controller_clk_enable(bool use_apll)
static inline void adc_ll_digi_clk_sel(bool use_apll)
{
if (use_apll) {
APB_SARADC.apb_adc_clkm_conf.clk_sel = 1; // APLL clock
@@ -483,112 +506,6 @@ static inline void adc_ll_digi_monitor_enable(adc_ll_num_t adc_n, bool enable)
}
}
/**
* Enable interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
static inline void adc_ll_digi_intr_enable(adc_ll_num_t adc_n, adc_digi_intr_t intr)
{
if (adc_n == ADC_NUM_1) {
if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
APB_SARADC.int_ena.adc1_thres = 1;
}
if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
APB_SARADC.int_ena.adc1_done = 1;
}
} else { // adc_n == ADC_NUM_2
if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
APB_SARADC.int_ena.adc2_thres = 1;
}
if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
APB_SARADC.int_ena.adc2_done = 1;
}
}
}
/**
* Disable interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
static inline void adc_ll_digi_intr_disable(adc_ll_num_t adc_n, adc_digi_intr_t intr)
{
if (adc_n == ADC_NUM_1) {
if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
APB_SARADC.int_ena.adc1_thres = 0;
}
if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
APB_SARADC.int_ena.adc1_done = 0;
}
} else { // adc_n == ADC_NUM_2
if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
APB_SARADC.int_ena.adc2_thres = 0;
}
if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
APB_SARADC.int_ena.adc2_done = 0;
}
}
}
/**
* Clear interrupt of adc digital controller by bitmask.
*
* @param adc_n ADC unit.
* @param intr Interrupt bitmask.
*/
static inline void adc_ll_digi_intr_clear(adc_ll_num_t adc_n, adc_digi_intr_t intr)
{
if (adc_n == ADC_NUM_1) {
if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
APB_SARADC.int_clr.adc1_thres = 1;
}
if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
APB_SARADC.int_clr.adc1_done = 1;
}
} else { // adc_n == ADC_NUM_2
if (intr & ADC_DIGI_INTR_MASK_MONITOR) {
APB_SARADC.int_clr.adc2_thres = 1;
}
if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) {
APB_SARADC.int_clr.adc2_done = 1;
}
}
}
/**
* Get interrupt status mask of adc digital controller.
*
* @param adc_n ADC unit.
* @return
* - intr Interrupt bitmask.
*/
static inline uint32_t adc_ll_digi_get_intr_status(adc_ll_num_t adc_n)
{
uint32_t int_st = APB_SARADC.int_st.val;
uint32_t ret_msk = 0;
if (adc_n == ADC_NUM_1) {
if (int_st & APB_SARADC_ADC1_DONE_INT_ST_M) {
ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE;
}
if (int_st & APB_SARADC_ADC1_THRES_INT_ST) {
ret_msk |= ADC_DIGI_INTR_MASK_MONITOR;
}
} else { // adc_n == ADC_NUM_2
if (int_st & APB_SARADC_ADC2_DONE_INT_ST_M) {
ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE;
}
if (int_st & APB_SARADC_ADC2_THRES_INT_ST_M) {
ret_msk |= ADC_DIGI_INTR_MASK_MONITOR;
}
}
return ret_msk;
}
/**
* 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.
@@ -655,6 +572,20 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
/*---------------------------------------------------------------
RTC controller setting
---------------------------------------------------------------*/
/**
* ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`.
*
* @param div Division factor.
*/
static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div)
{
if (adc_n == ADC_NUM_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_reader1_ctrl, sar1_clk_div, div);
} else { // adc_n == ADC_NUM_2
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_reader2_ctrl, sar2_clk_div, div);
}
}
/**
* Set adc output data format for RTC controller.
*
@@ -855,65 +786,6 @@ static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t ad
}
}
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* Set ADC module power management.
*
* @param manage Set ADC power status.
*/
static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
{
/* Bit1 0:Fsm 1: SW mode
Bit0 0:SW mode power down 1: SW mode power on */
if (manage == ADC_POWER_SW_ON) {
SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
} else if (manage == ADC_POWER_BY_FSM) {
SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_FSM;
} else if (manage == ADC_POWER_SW_OFF) {
SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PD;
SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 0;
}
}
/**
* Get ADC module power management.
*
* @return
* - ADC power status.
*/
static inline adc_ll_power_t adc_ll_get_power_manage(void)
{
/* Bit1 0:Fsm 1: SW mode
Bit0 0:SW mode power down 1: SW mode power on */
adc_ll_power_t manage;
if (SENS.sar_power_xpd_sar.force_xpd_sar == SENS_FORCE_XPD_SAR_PU) {
manage = ADC_POWER_SW_ON;
} else if (SENS.sar_power_xpd_sar.force_xpd_sar == SENS_FORCE_XPD_SAR_PD) {
manage = ADC_POWER_SW_OFF;
} else {
manage = ADC_POWER_BY_FSM;
}
return manage;
}
/**
* ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`.
*
* @param div Division factor.
*/
static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div)
{
if (adc_n == ADC_NUM_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_reader1_ctrl, sar1_clk_div, div);
} else { // adc_n == ADC_NUM_2
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_reader2_ctrl, sar2_clk_div, div);
}
}
/**
* Set the attenuation of a particular channel on ADCn.
*
@@ -972,6 +844,30 @@ static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t cha
}
}
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* Set ADC module power management.
*
* @param manage Set ADC power status.
*/
static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
{
/* Bit1 0:Fsm 1: SW mode
Bit0 0:SW mode power down 1: SW mode power on */
if (manage == ADC_POWER_SW_ON) {
SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
} else if (manage == ADC_POWER_BY_FSM) {
SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1;
SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_FSM;
} else if (manage == ADC_POWER_SW_OFF) {
SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PD;
SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 0;
}
}
/**
* Set ADC module controller.
* There are five SAR ADC controllers:
@@ -985,18 +881,18 @@ static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t cha
static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl)
{
if (adc_n == ADC_NUM_1) {
switch ( ctrl ) {
case ADC_CTRL_RTC:
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_CTRL_ULP:
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_CTRL_DIG:
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;
@@ -1005,23 +901,16 @@ static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t
break;
}
} else { // adc_n == ADC_NUM_2
switch ( ctrl ) {
case ADC_CTRL_RTC:
switch (ctrl) {
//If ADC2 is not controlled by ULP, the arbiter will decide which controller to use ADC2.
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_CTRL_ULP:
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;
case ADC_CTRL_DIG:
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 ADC2_CTRL_PWDET: // currently only used by Wi-Fi
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;
default:
break;
}

View File

@@ -1,16 +1,8 @@
// 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.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*******************************************************************************
* NOTICE
@@ -1089,10 +1081,6 @@ static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
*/
static inline void spi_dma_ll_rx_reset(spi_dma_dev_t *dma_in, uint32_t channel)
{
//Reset RX DMA peripheral
dma_in->dma_in_link.dma_rx_ena = 0;
HAL_ASSERT(dma_in->dma_in_link.dma_rx_ena == 0);
dma_in->dma_conf.in_rst = 1;
dma_in->dma_conf.in_rst = 0;
}
@@ -1110,6 +1098,17 @@ static inline void spi_dma_ll_rx_start(spi_dma_dev_t *dma_in, uint32_t channel,
dma_in->dma_in_link.start = 1;
}
/**
* Stop RX DMA.
*
* @param dma_in Beginning address of the DMA peripheral registers which stores the data received from a peripheral into RAM.
* @param channel DMA channel, for chip version compatibility, not used.
*/
static inline void spi_dma_ll_rx_stop(spi_dma_dev_t *dma_in, uint32_t channel)
{
dma_in->dma_in_link.stop = 1;
}
/**
* Enable DMA RX channel burst for data
*
@@ -1173,6 +1172,17 @@ static inline void spi_dma_ll_tx_start(spi_dma_dev_t *dma_out, uint32_t channel,
dma_out->dma_out_link.start = 1;
}
/**
* Stop TX DMA.
*
* @param dma_out Beginning address of the DMA peripheral registers which transmits the data from RAM to a peripheral.
* @param channel DMA channel, for chip version compatibility, not used.
*/
static inline void spi_dma_ll_tx_stop(spi_dma_dev_t *dma_out, uint32_t channel)
{
dma_out->dma_out_link.stop = 1;
}
/**
* Enable DMA TX channel burst for data
*
@@ -1251,7 +1261,6 @@ static inline void spi_dma_ll_rx_disable(spi_dma_dev_t *dma_in)
static inline void spi_dma_ll_tx_disable(spi_dma_dev_t *dma_out)
{
dma_out->dma_out_link.dma_tx_ena = 0;
dma_out->dma_out_link.stop = 1;
}
static inline bool spi_ll_tx_get_empty_err(spi_dev_t *hw)