mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
adc: support adc dma driver on all chips
This commit is contained in:

committed by
Armando (Dou Yiwen)

parent
5ddce053ea
commit
4dc0d6b2fe
@@ -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);
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
@@ -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;
|
||||
}
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user