Skip to content

Commit

Permalink
driver/adc: support adc single sample on s3
Browse files Browse the repository at this point in the history
  • Loading branch information
L-KAYA committed Jul 15, 2021
1 parent 6bb6f3e commit 27d9657
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 639 deletions.
3 changes: 1 addition & 2 deletions components/driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ if(${target} STREQUAL "esp32s3")
"sdmmc_transaction.c"
"mcpwm.c"
"spi_slave_hd.c"
"touch_sensor_common.c"
)
"touch_sensor_common.c")
endif()

if(IDF_TARGET STREQUAL "esp32c3")
Expand Down
52 changes: 36 additions & 16 deletions components/driver/adc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static _lock_t adc2_wifi_lock;

#endif // CONFIG_IDF_TARGET_*

#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
#ifdef CONFIG_PM_ENABLE
static esp_pm_lock_handle_t s_adc2_arbiter_lock;
#endif //CONFIG_PM_ENABLE
Expand All @@ -127,7 +127,7 @@ static esp_pm_lock_handle_t s_adc2_arbiter_lock;
ADC Common
---------------------------------------------------------------*/

#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
static uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
{
adc_atten_t atten = adc_hal_get_atten(adc_n, chan);
Expand Down Expand Up @@ -299,10 +299,10 @@ esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en)

esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits)
{
#ifdef CONFIG_IDF_TARGET_ESP32
#if CONFIG_IDF_TARGET_ESP32
ADC_CHECK(bits < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
#else
ADC_CHECK(bits == ADC_WIDTH_BIT_13, "WIDTH ERR: " CONFIG_IDF_TARGET " support 13 bit width", ESP_ERR_INVALID_ARG);
ADC_CHECK(bits == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG);
#endif

if (adc_unit & ADC_UNIT_1) {
Expand All @@ -329,7 +329,7 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits)
esp_err_t adc_rtc_reset(void)
{
FSM_ENTER();
adc_hal_rtc_reset();
adc_ll_rtc_reset();
FSM_EXIT();
return ESP_OK;
}
Expand Down Expand Up @@ -358,10 +358,10 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)

esp_err_t adc1_config_width(adc_bits_width_t width_bit)
{
#ifdef CONFIG_IDF_TARGET_ESP32
#if CONFIG_IDF_TARGET_ESP32
ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
#elif !defined(CONFIG_IDF_TARGET_ESP32)
ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: " CONFIG_IDF_TARGET " support 13 bit width", ESP_ERR_INVALID_ARG);
#else
ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG);
#endif

SARADC1_ENTER();
Expand All @@ -382,7 +382,11 @@ esp_err_t adc1_dma_mode_acquire(void)

SARADC1_ENTER();
/* switch SARADC into DIG channel */
#if CONFIG_IDF_TARGET_ESP32S3 // remove this macro. TODO: IDF-1776
adc_hal_set_controller(ADC_NUM_1, ADC_LL_CTRL_DIG);
#else
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
#endif
SARADC1_EXIT();

return ESP_OK;
Expand All @@ -397,7 +401,11 @@ esp_err_t adc1_rtc_mode_acquire(void)

SARADC1_ENTER();
/* switch SARADC into RTC channel. */
#if CONFIG_IDF_TARGET_ESP32S3 // remove this macro. TODO: IDF-1776
adc_hal_set_controller(ADC_NUM_1, ADC_LL_CTRL_RTC);
#else
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC);
#endif
SARADC1_EXIT();

return ESP_OK;
Expand All @@ -419,7 +427,7 @@ int adc1_get_raw(adc1_channel_t channel)
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
adc1_rtc_mode_acquire();

#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
// Get calibration value before going into critical section
uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel);
adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
Expand All @@ -430,10 +438,14 @@ int adc1_get_raw(adc1_channel_t channel)
adc_hal_hall_disable(); //Disable other peripherals.
adc_hal_amp_disable(); //Currently the LNA is not open, close it by default.
#endif
#if CONFIG_IDF_TARGET_ESP32S3 // remove this macro. TODO: IDF-1776
adc_hal_set_controller(ADC_NUM_1, ADC_LL_CTRL_RTC); //Set controller
#else
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); //Set controller
#endif
adc_hal_convert(ADC_NUM_1, channel, &adc_value); //Start conversion, For ADC1, the data always valid.
#if !CONFIG_IDF_TARGET_ESP32
adc_hal_rtc_reset(); //Reset FSM of rtc controller
adc_ll_rtc_reset(); //Reset FSM of rtc controller
#endif
SARADC1_EXIT();

Expand All @@ -452,7 +464,11 @@ void adc1_ulp_enable(void)
adc_power_acquire();

SARADC1_ENTER();
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_ULP);
#if CONFIG_IDF_TARGET_ESP32S3 // remove this macro. TODO: IDF-1776
adc_hal_set_controller(ADC_NUM_1, ADC_LL_CTRL_ULP);
#else
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_ULP); //Set controller
#endif
/* since most users do not need LNA and HALL with uLP, we disable them here
open them in the uLP if needed. */
#ifdef CONFIG_IDF_TARGET_ESP32
Expand Down Expand Up @@ -556,13 +572,13 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *

ADC_CHECK(raw_out != NULL, "ADC out value err", ESP_ERR_INVALID_ARG);
ADC_CHECK(channel < ADC2_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
#ifdef CONFIG_IDF_TARGET_ESP32
#if CONFIG_IDF_TARGET_ESP32
ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
#else
ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG);
ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG);
#endif

#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
// Get calibration value before going into critical section
uint32_t cal_val = get_calibration_offset(ADC_NUM_2, channel);
adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
Expand All @@ -581,7 +597,11 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
adc2_dac_disable(channel); //disable other peripherals
#endif
adc_hal_rtc_set_output_format(ADC_NUM_2, width_bit);
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller
#if CONFIG_IDF_TARGET_ESP32S3 // remove this macro. TODO: IDF-1776
adc_hal_set_controller(ADC_NUM_2, ADC_LL_CTRL_ARB);// set controller
#else
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);
#endif

#if !CONFIG_IDF_TARGET_ESP32
#ifdef CONFIG_PM_ENABLE
Expand All @@ -596,7 +616,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
adc_value = -1;
}

#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#if CONFIG_IDF_TARGET_ESP32S2
#ifdef CONFIG_PM_ENABLE
/* Release APB clock. */
if (s_adc2_arbiter_lock) {
Expand Down
229 changes: 1 addition & 228 deletions components/driver/esp32s3/include/driver/adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,231 +7,4 @@
#pragma once

#include "driver/adc_common.h"

#ifdef __cplusplus
extern "C" {
#endif

/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/

/**
* @brief Config ADC 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 Default priority: Wi-Fi > RTC > Digital;
* @note In normal use, there is no need to call this interface to config arbiter.
*
* @param adc_unit ADC unit.
* @param config Refer to `adc_arbiter_t`.
*
* @return
* - ESP_OK Success
* - ESP_ERR_NOT_SUPPORTED ADC unit not support arbiter.
*/
esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config);

/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
/**
* @brief ADC digital controller initialization.
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_init(void);

/**
* @brief ADC digital controller deinitialization.
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_deinit(void);

/**
* @brief Setting the digital controller.
*
* @param config Pointer to digital controller paramter. Refer to `adc_digi_config_t`.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config);

/**
* @brief Enable digital controller to trigger the measurement.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_start(void);

/**
* @brief Disable digital controller to trigger the measurement.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_stop(void);

/*************************************/
/* Digital controller filter setting */
/*************************************/
/**
* @brief Reset adc digital controller filter.
*
* @param idx Filter index.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx);

/**
* @brief Set adc digital controller filter configuration.
*
* @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time.
*
* @param idx Filter index.
* @param config See ``adc_digi_filter_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config);

/**
* @brief Get adc digital controller filter configuration.
*
* @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time.
*
* @param idx Filter index.
* @param config See ``adc_digi_filter_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config);

/**
* @brief Enable/disable adc digital controller filter.
* Filtering the ADC data to obtain smooth data at higher sampling rates.
*
* @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time.
*
* @param idx Filter index.
* @param enable Enable/Disable filter.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable);

/**************************************/
/* Digital controller monitor setting */
/**************************************/

/**
* @brief Config monitor of adc digital controller.
*
* @note For ESP32S2, The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
*
* @param idx Monitor index.
* @param config See ``adc_digi_monitor_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config);

/**
* @brief Enable/disable monitor of adc digital controller.
*
* @note For ESP32S2, The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
*
* @param idx Monitor index.
* @param enable True or false enable monitor.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable);

/**************************************/
/* Digital controller intr setting */
/**************************************/

/**
* @brief Enable interrupt of adc digital controller by bitmask.
*
* @param adc_unit ADC unit.
* @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask);

/**
* @brief Disable interrupt of adc digital controller by bitmask.
*
* @param adc_unit ADC unit.
* @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask);

/**
* @brief Clear interrupt of adc digital controller by bitmask.
*
* @param adc_unit ADC unit.
* @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``.
*
* @return
* - ESP_OK Success
*/
esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask);

/**
* @brief Get interrupt status mask of adc digital controller.
*
* @param adc_unit ADC unit.
* @return
* - intr Interrupt bitmask, See ``adc_digi_intr_t``.
*/
uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit);

/**
* @brief Register ADC interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
*
* @param fn Interrupt handler function.
* @param arg Parameter for handler function
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
*
* @return
* - ESP_OK Success
* - ESP_ERR_NOT_FOUND Can not find the interrupt that matches the flags.
* - ESP_ERR_INVALID_ARG Function pointer error.
*/
esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags);

/**
* @brief Deregister ADC interrupt handler, the handler is an ISR.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG hander error.
* - ESP_FAIL ISR not be registered.
*/
esp_err_t adc_digi_isr_deregister(void);

#ifdef __cplusplus
}
#endif
// This file will be removed. TODO: IDF-1776
Loading

0 comments on commit 27d9657

Please sign in to comment.