diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 4a8fddb1e6..f34581d506 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -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") diff --git a/components/driver/adc_common.c b/components/driver/adc_common.c index 8ebfd1d885..8a987d2b16 100644 --- a/components/driver/adc_common.c +++ b/components/driver/adc_common.c @@ -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 @@ -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); @@ -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) { @@ -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; } @@ -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(); @@ -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; @@ -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; @@ -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); @@ -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(); @@ -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 @@ -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); @@ -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 @@ -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) { diff --git a/components/driver/esp32s3/include/driver/adc.h b/components/driver/esp32s3/include/driver/adc.h index c5c81ccdf2..8bade108db 100644 --- a/components/driver/esp32s3/include/driver/adc.h +++ b/components/driver/esp32s3/include/driver/adc.h @@ -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 diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index c4b873f724..db93aa7f86 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -48,8 +48,6 @@ void adc_hal_init(void) ADC calibration setting ---------------------------------------------------------------*/ #if SOC_ADC_HW_CALIBRATION_V1 -// ESP32-S2 and C3 support HW offset calibration. - void adc_hal_calibration_init(adc_ll_num_t adc_n) { adc_ll_calibration_init(adc_n); @@ -94,7 +92,7 @@ static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t att adc_ll_onetime_sample_enable(ADC_NUM_2, false); /* Enable/disable internal connect GND (for calibration). */ if (internal_gnd) { - const int esp32c3_invalid_chan = (adc_n == ADC_NUM_1)? 0xF: 0x1; + const int esp32c3_invalid_chan = (adc_n == ADC_NUM_1) ? 0xF : 0x1; adc_ll_onetime_set_channel(adc_n, esp32c3_invalid_chan); } else { adc_ll_onetime_set_channel(adc_n, channel); @@ -110,7 +108,7 @@ static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel) esp_rom_delay_us(5); adc_ll_onetime_start(true); - while(!adc_ll_intr_get_raw(ADC_LL_INTR_ADC1_DONE | ADC_LL_INTR_ADC2_DONE)); + while (!adc_ll_intr_get_raw(ADC_LL_INTR_ADC1_DONE | ADC_LL_INTR_ADC2_DONE)); uint32_t read_val = -1; if (adc_n == ADC_NUM_1) { @@ -179,8 +177,8 @@ uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc chk_code = code_h + code_l; uint32_t ret = ((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; + ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1; adc_ll_calibration_finish(adc_n); return ret; @@ -227,11 +225,11 @@ static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *d desc[n].dw0.suc_eof = 0; desc[n].dw0.owner = 1; desc[n].buffer = data_buf; - desc[n].next = &desc[n+1]; + desc[n].next = &desc[n + 1]; data_buf += size; n++; } - desc[n-1].next = NULL; + desc[n - 1].next = NULL; } void adc_hal_digi_rxdma_start(adc_hal_context_t *hal, uint8_t *data_buf) @@ -334,7 +332,7 @@ static void adc_hal_onetime_start(void) //3 ADC digital controller clock cycle delay = delay * 3; //This coefficient (8) is got from test. When digi_clk is not smaller than ``APB_CLK_FREQ/8``, no delay is needed. - if (digi_clk >= APB_CLK_FREQ/8) { + if (digi_clk >= APB_CLK_FREQ / 8) { delay = 0; } @@ -352,7 +350,7 @@ static esp_err_t adc_hal_single_read(adc_ll_num_t adc_n, int *out_raw) *out_raw = adc_ll_adc2_read(); if (adc_ll_analysis_raw_data(adc_n, *out_raw)) { return ESP_ERR_INVALID_STATE; - } + } } return ESP_OK; } diff --git a/components/hal/esp32s3/include/hal/adc_hal.h b/components/hal/esp32s3/include/hal/adc_hal.h deleted file mode 100644 index 25b85eede8..0000000000 --- a/components/hal/esp32s3/include/hal/adc_hal.h +++ /dev/null @@ -1,256 +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 (esp32s3 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 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 using internal connections. - * - * @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 atten The attenuation for the channel - * @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. - * - * @return - * - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set. - */ -uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd); - -/** - * 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 diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index 276d587adf..58302045e5 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -13,17 +13,23 @@ // limitations under the License. #pragma once +#include +#include #include "soc/adc_periph.h" #include "hal/adc_types.h" #include "soc/apb_saradc_struct.h" #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" -#include +#include "soc/rtc_cntl_reg.h" #ifdef __cplusplus extern "C" { #endif +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 + typedef enum { ADC_NUM_1 = 0, /*!< SAR ADC 1 */ ADC_NUM_2 = 1, /*!< SAR ADC 2 */ @@ -44,6 +50,24 @@ 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 = 4, ///< For ADC2. The controller is selected by the arbiter. +} adc_ll_controller_t; + +typedef struct { + union { + struct { + uint8_t atten: 2; + uint8_t channel: 4; + uint8_t reserved: 2; + }; + uint8_t val; + }; +} __attribute__((packed)) adc_ll_digi_pattern_table_t; + #ifdef _MSC_VER #pragma pack(push, 1) #endif /* _MSC_VER */ @@ -56,8 +80,8 @@ typedef enum { typedef struct { union { struct { - uint16_t data: 13; /*! 0), The data is invalid. */ @@ -70,23 +94,6 @@ typedef struct { #pragma pack(pop) #endif /* _MSC_VER */ -/** - * @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, /*! threshold, Generates monitor interrupt. * false: If ADC_OUT < threshold, Generates monitor interrupt. */ -static inline void adc_ll_digi_monitor_set_mode(adc_ll_num_t adc_n, bool is_larger) +static inline void adc_ll_digi_monitor_set_mode(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *cfg) { + abort(); } +/** + * Enable/disable monitor of adc digital controller. + * + * @note If the channel info is not supported, the monitor function will not be enabled. + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx) +{ + abort(); +} + + /** * Set monitor threshold of adc digital controller. * @@ -409,6 +428,7 @@ static inline void adc_ll_digi_monitor_set_mode(adc_ll_num_t adc_n, bool is_larg */ static inline void adc_ll_digi_monitor_set_thres(adc_ll_num_t adc_n, uint32_t threshold) { + abort(); } /** @@ -419,88 +439,7 @@ static inline void adc_ll_digi_monitor_set_thres(adc_ll_num_t adc_n, uint32_t th */ 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_MEAS_DONE) { - APB_SARADC.int_ena.adc1_done = 1; - } - } else { // adc_n == ADC_NUM_2 - 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_MEAS_DONE) { - APB_SARADC.int_ena.adc1_done = 0; - } - } else { // adc_n == ADC_NUM_2 - 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_MEAS_DONE) { - APB_SARADC.int_clr.adc1_done = 1; - } - } else { // adc_n == ADC_NUM_2 - 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; - } - } else { // adc_n == ADC_NUM_2 - if (int_st & APB_SARADC_ADC2_DONE_INT_ST_M) { - ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE; - } - } - - return ret_msk; + abort(); } /** @@ -566,19 +505,282 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) return SENS.sar_meas2_mux.sar2_pwdet_cct; } +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 0: The data is correct to use. + * - -1: The data is invalid. + */ +static inline adc_ll_rtc_raw_data_t adc_ll_analysis_raw_data(adc_ll_num_t adc_n, int raw_data) +{ + if (adc_n == ADC_NUM_1) { + return ADC_RTC_DATA_OK; + } + + //The raw data API returns value without channel information. Read value directly from the register + if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 12) & 0xF) > 9) { + return ADC_RTC_DATA_FAIL; + } + + return ADC_RTC_DATA_OK; +} + +/*--------------------------------------------------------------- + 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) +{ + if (manage == ADC_POWER_SW_ON) { + SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1; + SENS.sar_power_xpd_sar.force_xpd_sar = 3; //SENS_FORCE_XPD_SAR_PU; + APB_SARADC.ctrl.sar_clk_gated = 1; + APB_SARADC.ctrl.xpd_sar_force = 3; + } else if (manage == ADC_POWER_BY_FSM) { + SENS.sar_peri_clk_gate_conf.saradc_clk_en = 1; + SENS.sar_power_xpd_sar.force_xpd_sar = 0; //SENS_FORCE_XPD_SAR_FSM; + APB_SARADC.ctrl.sar_clk_gated = 1; + APB_SARADC.ctrl.xpd_sar_force = 0; + } else if (manage == ADC_POWER_SW_OFF) { + SENS.sar_power_xpd_sar.force_xpd_sar = 2; //SENS_FORCE_XPD_SAR_PD; + SENS.sar_peri_clk_gate_conf.saradc_clk_en = 0; + APB_SARADC.ctrl.sar_clk_gated = 0; + APB_SARADC.ctrl.xpd_sar_force = 2; + } +} + +/** + * Set ADC module controller. + * There are five SAR ADC controllers: + * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes; + * 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. + * + * @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) +{ + if (adc_n == ADC_NUM_1) { + 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_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_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; + break; + default: + break; + } + } else { // adc_n == ADC_NUM_2 + //If ADC2 is not controlled by ULP, the arbiter will decide which controller to use ADC2. + switch (ctrl) { + 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_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; + default: + break; + } + } +} + +/** + * Set ADC2 module arbiter work mode. + * 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 ADC 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. + * + * @param mode Refer to `adc_arbiter_mode_t`. + */ +static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode) +{ + if (mode == ADC_ARB_MODE_FIX) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1; + } else if (mode == ADC_ARB_MODE_LOOP) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 0; + } else { // Shield arbiter. + APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 1; + } +} + +/** + * Set ADC2 module controller priority in 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 ADC 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(2) > RTC(1) > Digital(0); + * + * @param pri_rtc RTC controller priority. Range: 0 ~ 2. + * @param pri_dig Digital controller priority. Range: 0 ~ 2. + * @param pri_pwdet Wi-Fi controller priority. Range: 0 ~ 2. + */ +static inline void adc_ll_set_arbiter_priority(uint8_t pri_rtc, uint8_t pri_dig, uint8_t pri_pwdet) +{ + if (pri_rtc != pri_dig && pri_rtc != pri_pwdet && pri_dig != pri_pwdet) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_priority = pri_rtc; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_priority = pri_dig; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_priority = pri_pwdet; + } + /* Should select highest priority controller. */ + if (pri_rtc > pri_dig) { + if (pri_rtc > pri_pwdet) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 1; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0; + } else { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1; + } + } else { + if (pri_dig > pri_pwdet) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 1; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0; + } else { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1; + } + } +} + +/** + * Force switch ADC2 to RTC controller in sleep mode. Shield arbiter. + * In sleep mode, the arbiter is in power-down mode. + * Need to switch the controller to RTC to shield the control of the arbiter. + * After waking up, it needs to switch to arbiter control. + * + * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller. + * @note Only support ADC2. + */ +static inline void adc_ll_enable_sleep_controller(void) +{ + SENS.sar_meas2_mux.sar2_rtc_force = 1; +} + +/** + * Force switch ADC2 to arbiter in wakeup mode. + * In sleep mode, the arbiter is in power-down mode. + * Need to switch the controller to RTC to shield the control of the arbiter. + * After waking up, it needs to switch to arbiter control. + * + * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller. + * @note Only support ADC2. + */ +static inline void adc_ll_disable_sleep_controller(void) +{ + SENS.sar_meas2_mux.sar2_rtc_force = 0; +} + +/** + * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. + * + * @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. + */ +static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd) +{ + abort(); +} + +/** + * Resume register status after calibration. + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n) +{ + abort(); +} + +/** + * Set the calibration result to ADC. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_set_calibration_param(adc_ll_num_t adc_n, uint32_t param) +{ + abort(); +} + +/** + * Output ADC internal reference voltage to channels, only available for ADC2 on ESP32. + * + * This function routes the internal reference voltage of ADCn to one of + * ADC2's channels. This reference voltage can then be manually measured + * for calibration purposes. + * + * @param[in] adc ADC unit select + * @param[in] channel ADC2 channel number + * @param[in] en Enable/disable the reference voltage output + */ +static inline void adc_ll_vref_output(adc_ll_num_t adc, adc_channel_t channel, bool en) +{ + abort(); +} + /*--------------------------------------------------------------- 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) { + SENS.sar_reader1_ctrl.sar1_clk_div = div; + } else { // adc_n == ADC_NUM_2 + SENS.sar_reader2_ctrl.sar2_clk_div = div; + } +} + /** * Set adc output data format for RTC controller. * - * @note ESP32S2 RTC controller only support 13bit. + * @note ESP32S3 RTC controller only support 13bit. * @prarm adc_n ADC unit. * @prarm bits Output data bits width option. */ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_width_t bits) { - return; + } /** @@ -724,6 +926,8 @@ static inline void adc_ll_rtc_intr_disable(adc_ll_num_t adc_n) */ static inline void adc_ll_rtc_reset(void) { + SENS.sar_peri_reset_conf.saradc_reset = 1; + SENS.sar_peri_reset_conf.saradc_reset = 0; } /** @@ -767,43 +971,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) -{ -} - -/** - * Get ADC module power management. - * - * @return - * - ADC power status. - */ -static inline adc_ll_power_t adc_ll_get_power_manage(void) -{ - return ADC_POWER_SW_OFF; -} - -/** - * 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) { - SENS.sar_reader1_ctrl.sar1_clk_div = div; - } else { // adc_n == ADC_NUM_2 - SENS.sar_reader2_ctrl.sar2_clk_div = div; - } -} - /** * Set the attenuation of a particular channel on ADCn. * @@ -846,333 +1013,18 @@ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, a } } -/** - * Get the attenuation of a particular channel on ADCn. - * - * @param adc_n ADC unit. - * @param channel ADCn channel number. - * @return atten The attenuation option. - */ -static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t channel) +static inline uint32_t adc_ll_adc1_read(void) { - if (adc_n == ADC_NUM_1) { - return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3); - } else { - return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3); - } + //On ESP32S3, valid data width is 12-bit + return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff); } -/** - * Set ADC module controller. - * There are five SAR ADC controllers: - * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes; - * 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. - * - * @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 uint32_t adc_ll_adc2_read(void) { - if (adc_n == ADC_NUM_1) { - switch ( ctrl ) { - case ADC_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: - 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: - 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; - break; - default: - break; - } - } else { // adc_n == ADC_NUM_2 - switch ( ctrl ) { - case ADC_CTRL_RTC: - 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: - 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; - } - } + //On ESP32S3, valid data width is 12-bit + return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff); } -/** - * Set ADC2 module arbiter work mode. - * 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 ADC 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. - * - * @param mode Refer to `adc_arbiter_mode_t`. - */ -static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode) -{ - SENS.sar_meas2_mux.sar2_rtc_force = 0; // Enable arbiter in wakeup mode - if (mode == ADC_ARB_MODE_FIX) { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1; - } else if (mode == ADC_ARB_MODE_LOOP) { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 0; - } else { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 1; // Shield arbiter. - } -} - -/** - * Set ADC2 module controller priority in 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 ADC 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(2) > RTC(1) > Digital(0); - * - * @param pri_rtc RTC controller priority. Range: 0 ~ 2. - * @param pri_dig Digital controller priority. Range: 0 ~ 2. - * @param pri_pwdet Wi-Fi controller priority. Range: 0 ~ 2. - */ -static inline void adc_ll_set_arbiter_priority(uint8_t pri_rtc, uint8_t pri_dig, uint8_t pri_pwdet) -{ - if (pri_rtc != pri_dig && pri_rtc != pri_pwdet && pri_dig != pri_pwdet) { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_priority = pri_rtc; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_priority = pri_dig; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_priority = pri_pwdet; - } - /* Should select highest priority controller. */ - if (pri_rtc > pri_dig) { - if (pri_rtc > pri_pwdet) { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 1; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0; - } else { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1; - } - } else { - if (pri_dig > pri_pwdet) { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 1; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0; - } else { - APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; - APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1; - } - } -} - -/** - * Force switch ADC2 to RTC controller in sleep mode. Shield arbiter. - * In sleep mode, the arbiter is in power-down mode. - * Need to switch the controller to RTC to shield the control of the arbiter. - * After waking up, it needs to switch to arbiter control. - * - * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller. - * @note Only support ADC2. - */ -static inline void adc_ll_enable_sleep_controller(void) -{ - SENS.sar_meas2_mux.sar2_rtc_force = 1; -} - -/** - * Force switch ADC2 to arbiter in wakeup mode. - * In sleep mode, the arbiter is in power-down mode. - * Need to switch the controller to RTC to shield the control of the arbiter. - * After waking up, it needs to switch to arbiter control. - * - * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller. - * @note Only support ADC2. - */ -static inline void adc_ll_disable_sleep_controller(void) -{ - SENS.sar_meas2_mux.sar2_rtc_force = 0; -} - -/* ADC calibration code. */ -#include "soc/rtc_cntl_reg.h" -#include "regi2c_ctrl.h" - -#define I2C_ADC 0X69 -#define I2C_ADC_HOSTID 0 - -#define SAR1_ENCAL_GND_ADDR 0x7 -#define SAR1_ENCAL_GND_ADDR_MSB 5 -#define SAR1_ENCAL_GND_ADDR_LSB 5 - -#define SAR2_ENCAL_GND_ADDR 0x7 -#define SAR2_ENCAL_GND_ADDR_MSB 7 -#define SAR2_ENCAL_GND_ADDR_LSB 7 - -#define SAR1_INITIAL_CODE_HIGH_ADDR 0x1 -#define SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3 -#define SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0 - -#define SAR1_INITIAL_CODE_LOW_ADDR 0x0 -#define SAR1_INITIAL_CODE_LOW_ADDR_MSB 0x7 -#define SAR1_INITIAL_CODE_LOW_ADDR_LSB 0x0 - -#define SAR2_INITIAL_CODE_HIGH_ADDR 0x4 -#define SAR2_INITIAL_CODE_HIGH_ADDR_MSB 0x3 -#define SAR2_INITIAL_CODE_HIGH_ADDR_LSB 0x0 - -#define SAR2_INITIAL_CODE_LOW_ADDR 0x3 -#define SAR2_INITIAL_CODE_LOW_ADDR_MSB 0x7 -#define SAR2_INITIAL_CODE_LOW_ADDR_LSB 0x0 - -#define SAR1_DREF_ADDR 0x2 -#define SAR1_DREF_ADDR_MSB 0x6 -#define SAR1_DREF_ADDR_LSB 0x4 - -#define SAR2_DREF_ADDR 0x5 -#define SAR2_DREF_ADDR_MSB 0x6 -#define SAR2_DREF_ADDR_LSB 0x4 - - -/** - * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. - * - * @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. - */ -static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd) -{ - /* Enable i2s_write_reg function. */ - void phy_get_romfunc_addr(void); - phy_get_romfunc_addr(); - // CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);//TODO: finish it in MR-10423. - // SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);//TODO: finish it in MR-10423. - CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M); - SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M); - - /* Enable/disable internal connect GND (for calibration). */ - if (adc_n == ADC_NUM_1) { - REGI2C_WRITE_MASK(I2C_ADC, SAR1_DREF_ADDR, 4); - if (internal_gnd) { - REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 1); - } else { - REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0); - } - } else { - REGI2C_WRITE_MASK(I2C_ADC, SAR2_DREF_ADDR, 4); - if (internal_gnd) { - REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 1); - } else { - REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0); - } - } -} - -/** - * Resume register status after calibration. - * - * @param adc_n ADC index number. - */ -static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n) -{ - if (adc_n == ADC_NUM_1) { - REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0); - } else { - REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0); - } -} - -/** - * Set the calibration result to ADC. - * - * @note Different ADC units and different attenuation options use different calibration data (initial data). - * - * @param adc_n ADC index number. - */ -static inline void adc_ll_set_calibration_param(adc_ll_num_t adc_n, uint32_t param) -{ - uint8_t msb = param >> 8; - uint8_t lsb = param & 0xFF; - /* Enable i2s_write_reg function. */ - void phy_get_romfunc_addr(void); - phy_get_romfunc_addr(); - // SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); //TODO: finish it in MR-10423. - CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M); - SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M); - - if (adc_n == ADC_NUM_1) { - REGI2C_WRITE_MASK(I2C_ADC, SAR1_INITIAL_CODE_HIGH_ADDR, msb); - REGI2C_WRITE_MASK(I2C_ADC, SAR1_INITIAL_CODE_LOW_ADDR, lsb); - } else { - REGI2C_WRITE_MASK(I2C_ADC, SAR2_INITIAL_CODE_HIGH_ADDR, msb); - REGI2C_WRITE_MASK(I2C_ADC, SAR2_INITIAL_CODE_LOW_ADDR, lsb); - } -} -/* Temp code end. */ - -/** - * Output ADC internal reference voltage to channels, only available for ADC2 on ESP32. - * - * This function routes the internal reference voltage of ADCn to one of - * ADC2's channels. This reference voltage can then be manually measured - * for calibration purposes. - * - * @param[in] adc ADC unit select - * @param[in] channel ADC2 channel number - * @param[in] en Enable/disable the reference voltage output - */ -static inline void adc_ll_vref_output(adc_ll_num_t adc, adc_channel_t channel, bool en) -{ - // if (adc != ADC_NUM_2) return; - - // if (en) { - // RTCCNTL.bias_conf.dbg_atten_monitor = 0; //Check DBG effect outside sleep mode - // //set dtest (MUX_SEL : 0 -> RTC; 1-> vdd_sar2) - // RTCCNTL.test_mux.dtest_rtc = 1; //Config test mux to route v_ref to ADC2 Channels - // //set ent - // RTCCNTL.test_mux.ent_rtc = 1; - // //set sar2_en_test - // SENS.sar_start_force.sar2_en_test = 1; - // //set sar2 en force - // SENS.sar_meas_start2.sar2_en_pad_force = 1; //Pad bitmap controlled by SW - // //set en_pad for channels 7,8,9 (bits 0x380) - // SENS.sar_meas_start2.sar2_en_pad = 1 << channel; - // } else { - // RTCCNTL.test_mux.dtest_rtc = 0; //Config test mux to route v_ref to ADC2 Channels - // //set ent - // RTCCNTL.test_mux.ent_rtc = 0; - // //set sar2_en_test - // SENS.sar_start_force.sar2_en_test = 0; - // //set sar2 en force - // SENS.sar_meas_start2.sar2_en_pad_force = 0; //Pad bitmap controlled by SW - // //set en_pad for channels 7,8,9 (bits 0x380) - // SENS.sar_meas_start2.sar2_en_pad = 0; - // } -} #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index bf71cb43a8..c0f6661f14 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -133,7 +133,7 @@ typedef struct { - 2: 11 bit; - 3: 12 bit. */ int8_t channel: 4; /*!< ADC channel index. */ -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#elif CONFIG_IDF_TARGET_ESP32S2 uint8_t reserved: 2; /*!< reserved0 */ uint8_t channel: 4; /*!< ADC channel index. */ #elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 @@ -295,7 +295,7 @@ typedef struct { #endif } adc_digi_config_t; -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32S2 /** * @brief ADC digital controller (DMA mode) interrupt type options. */ diff --git a/components/soc/esp32s3/include/soc/adc_caps.h b/components/soc/esp32s3/include/soc/adc_caps.h deleted file mode 100644 index 1460198b12..0000000000 --- a/components/soc/esp32s3/include/soc/adc_caps.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2010-2020 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. -#pragma once - -#define SOC_ADC_PERIPH_NUM (2) -#define SOC_ADC_PATT_LEN_MAX (16) -#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10) -#define SOC_ADC_MAX_CHANNEL_NUM (10) -#define SOC_ADC_MAX_BITWIDTH (13) - - -/** - * Check if adc support digital controller (DMA) mode. - * @value - * - 1 : support; - * - 0 : not support; - */ -#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 1) -#define SOC_ADC_SUPPORT_RTC_CTRL 1 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 6c62dad022..8e39d4bc76 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -28,7 +28,12 @@ /*-------------------------- ADC CAPS ----------------------------------------*/ -#include "adc_caps.h" +#define SOC_ADC_PERIPH_NUM (2) +#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10) +#define SOC_ADC_MAX_CHANNEL_NUM (10) +#define SOC_ADC_MAX_BITWIDTH (12) +#define SOC_ADC_SUPPORT_RTC_CTRL (1) + /*-------------------------- BROWNOUT CAPS -----------------------------------*/ #include "brownout_caps.h"