mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
driver(adc/dac): fix adc dac driver for esp32s2
1. update register file about adc; 2. fix adc driver; 3. add UT for adc/dac; See merge request espressif/esp-idf!7776
This commit is contained in:
parent
dfbb108ab4
commit
baa7898e35
@ -1,5 +1,5 @@
|
||||
set(srcs
|
||||
"adc.c"
|
||||
"adc_common.c"
|
||||
"can.c"
|
||||
"dac.c"
|
||||
"gpio.c"
|
||||
@ -31,13 +31,15 @@ if(IDF_TARGET STREQUAL "esp32")
|
||||
"sdio_slave.c"
|
||||
"sdmmc_host.c"
|
||||
"sdmmc_transaction.c"
|
||||
"esp32/touch_sensor.c")
|
||||
"esp32/touch_sensor.c"
|
||||
"esp32/adc.c")
|
||||
list(APPEND includes "esp32/include")
|
||||
endif()
|
||||
|
||||
if(IDF_TARGET STREQUAL "esp32s2")
|
||||
list(APPEND srcs "esp32s2/rtc_tempsensor.c"
|
||||
"esp32s2/touch_sensor.c")
|
||||
"esp32s2/touch_sensor.c"
|
||||
"esp32s2/adc.c")
|
||||
# currently only S2 beta has its own target-specific includes
|
||||
list(APPEND includes "esp32s2/include")
|
||||
endif()
|
||||
|
@ -12,8 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _DRIVER_ADC1_I2S_PRIVATE_H_
|
||||
#define _DRIVER_ADC1_I2S_PRIVATE_H_
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -34,26 +33,26 @@ void adc_power_always_on(void);
|
||||
/**
|
||||
* @brief For I2S dma to claim the usage of ADC1.
|
||||
*
|
||||
* Other tasks will be forbidden to use ADC1 between ``adc1_i2s_mode_acquire`` and ``adc1_i2s_release``.
|
||||
* Other tasks will be forbidden to use ADC1 between ``adc1_dma_mode_acquire`` and ``adc1_i2s_release``.
|
||||
* The I2S module may have to wait for a short time for the current conversion (if exist) to finish.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_TIMEOUT reserved for future use. Currently the function will wait until success.
|
||||
*/
|
||||
esp_err_t adc1_i2s_mode_acquire(void);
|
||||
esp_err_t adc1_dma_mode_acquire(void);
|
||||
|
||||
/**
|
||||
* @brief For ADC1 to claim the usage of ADC1.
|
||||
*
|
||||
* Other tasks will be forbidden to use ADC1 between ``adc1_adc_mode_acquire`` and ``adc1_i2s_release``.
|
||||
* Other tasks will be forbidden to use ADC1 between ``adc1_rtc_mode_acquire`` and ``adc1_i2s_release``.
|
||||
* The ADC1 may have to wait for some time for the I2S read operation to finish.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_TIMEOUT reserved for future use. Currently the function will wait until success.
|
||||
*/
|
||||
esp_err_t adc1_adc_mode_acquire(void);
|
||||
esp_err_t adc1_rtc_mode_acquire(void);
|
||||
|
||||
/**
|
||||
* @brief to let other tasks use the ADC1 when I2S is not work.
|
||||
@ -69,5 +68,3 @@ esp_err_t adc1_lock_release(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_DRIVER_ADC1_I2S_PRIVATE_H_*/
|
||||
|
@ -12,8 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _DRIVER_ADC2_INTERNAL_H_
|
||||
#define _DRIVER_ADC2_INTERNAL_H_
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -48,5 +47,3 @@ esp_err_t adc2_wifi_release(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_DRIVER_ADC2_INTERNAL_H_*/
|
||||
|
@ -20,25 +20,18 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_pm.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "rtc_io.h"
|
||||
#include "adc.h"
|
||||
#include "dac.h"
|
||||
#include "driver/dac.h"
|
||||
#include "sys/lock.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "adc1_i2s_private.h"
|
||||
#include "driver/adc.h"
|
||||
#include "adc1_private.h"
|
||||
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_hal.h"
|
||||
|
||||
#define ADC_MAX_MEAS_NUM_DEFAULT (255)
|
||||
#define ADC_MEAS_NUM_LIM_DEFAULT (1)
|
||||
#define SAR_ADC_CLK_DIV_DEFUALT (2)
|
||||
|
||||
#define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIG_FORMAT_12BIT)
|
||||
#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11)
|
||||
#define DIG_ADC_BIT_WIDTH_DEFUALT (ADC_WIDTH_BIT_12)
|
||||
|
||||
#define ADC_CHECK_RET(fun_ret) ({ \
|
||||
if (fun_ret != ESP_OK) { \
|
||||
ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \
|
||||
@ -65,9 +58,11 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi
|
||||
|
||||
/*
|
||||
In ADC2, there're two locks used for different cases:
|
||||
1. lock shared with app and WIFI:
|
||||
when wifi using the ADC2, we assume it will never stop,
|
||||
so app checks the lock and returns immediately if failed.
|
||||
1. lock shared with app and Wi-Fi:
|
||||
ESP32:
|
||||
When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed.
|
||||
ESP32S2:
|
||||
The controller's control over the ADC is determined by the arbiter. There is no need to control by lock.
|
||||
|
||||
2. lock shared between tasks:
|
||||
when several tasks sharing the ADC2, we want to guarantee
|
||||
@ -77,13 +72,40 @@ In ADC2, there're two locks used for different cases:
|
||||
|
||||
adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
|
||||
*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
//prevent ADC2 being used by wifi and other tasks at the same time.
|
||||
static _lock_t adc2_wifi_lock;
|
||||
/** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock. */
|
||||
#define ADC2_WIFI_LOCK_ACQUIRE() _lock_acquire( &adc2_wifi_lock )
|
||||
#define ADC2_WIFI_LOCK_RELEASE() _lock_release( &adc2_wifi_lock )
|
||||
#define ADC2_WIFI_LOCK_TRY_ACQUIRE() _lock_try_acquire( &adc2_wifi_lock )
|
||||
#define ADC2_WIFI_LOCK_CHECK() ((uint32_t *)adc2_wifi_lock != NULL)
|
||||
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#define ADC2_WIFI_LOCK_ACQUIRE()
|
||||
#define ADC2_WIFI_LOCK_RELEASE()
|
||||
#define ADC2_WIFI_LOCK_TRY_ACQUIRE() (0) //WIFI controller and rtc controller have independent parameter configuration.
|
||||
#define ADC2_WIFI_LOCK_CHECK() (true)
|
||||
|
||||
#endif
|
||||
|
||||
//prevent ADC2 being used by tasks (regardless of WIFI)
|
||||
static portMUX_TYPE adc2_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
#define ADC2_ENTER_CRITICAL() portENTER_CRITICAL( &adc2_spinlock )
|
||||
#define ADC2_EXIT_CRITICAL() portEXIT_CRITICAL( &adc2_spinlock )
|
||||
|
||||
//prevent ADC1 being used by I2S dma and other tasks at the same time.
|
||||
static _lock_t adc1_i2s_lock;
|
||||
static _lock_t adc1_dma_lock;
|
||||
#define ADC1_DMA_LOCK_ACQUIRE() _lock_acquire( &adc1_dma_lock )
|
||||
#define ADC1_DMA_LOCK_RELEASE() _lock_release( &adc1_dma_lock )
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
static esp_pm_lock_handle_t s_adc2_arbiter_lock;
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
#endif //CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
ADC Common
|
||||
---------------------------------------------------------------*/
|
||||
@ -121,16 +143,7 @@ void adc_power_off(void)
|
||||
esp_err_t adc_set_clk_div(uint8_t clk_div)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_set_clk_div(clk_div);
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src)
|
||||
{
|
||||
ADC_CHECK(src < ADC_I2S_DATA_SRC_MAX, "ADC i2s data source error", ESP_ERR_INVALID_ARG);
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_dig_set_data_source(src);
|
||||
adc_hal_digi_set_clk_div(clk_div);
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -141,18 +154,14 @@ esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel)
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
||||
gpio_num = ADC_GET_IO_NUM(ADC_NUM_1, channel);
|
||||
|
||||
ADC_CHECK_RET(rtc_gpio_init(gpio_num));
|
||||
ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
|
||||
ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING));
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
|
||||
gpio_num = ADC_GET_IO_NUM(ADC_NUM_2, channel);
|
||||
ADC_CHECK_RET(rtc_gpio_init(gpio_num));
|
||||
ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
|
||||
ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING));
|
||||
}
|
||||
ADC_CHECK_RET(rtc_gpio_init(gpio_num));
|
||||
ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
|
||||
ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -160,18 +169,24 @@ esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc_hal_output_invert(ADC_NUM_1, inv_en);
|
||||
adc_hal_rtc_output_invert(ADC_NUM_1, inv_en);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
adc_hal_output_invert(ADC_NUM_1, inv_en);
|
||||
adc_hal_rtc_output_invert(ADC_NUM_1, inv_en);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits)
|
||||
{
|
||||
ADC_CHECK(bits < ADC_WIDTH_MAX, "ADC bit width error", ESP_ERR_INVALID_ARG);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
ADC_CHECK(bits < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
ADC_CHECK(bits == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG);
|
||||
#endif
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc_hal_rtc_set_output_format(ADC_NUM_1, bits);
|
||||
@ -181,68 +196,41 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits)
|
||||
adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* this function should be called in the critical section. */
|
||||
static int adc_convert(adc_ll_num_t adc_n, int channel)
|
||||
/**
|
||||
* @brief Reset RTC controller FSM.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
esp_err_t adc_rtc_reset(void)
|
||||
{
|
||||
return adc_hal_convert(adc_n, channel);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------
|
||||
* ADC I2S
|
||||
*------------------------------------------------------------------------------------*/
|
||||
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel)
|
||||
{
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_1)), "ADC1 not support DMA for now.", ESP_ERR_INVALID_ARG);
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_2)), "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG);
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
|
||||
}
|
||||
|
||||
adc_ll_pattern_table_t adc1_pattern[1];
|
||||
adc_ll_pattern_table_t adc2_pattern[1];
|
||||
adc_hal_dig_config_t dig_cfg = {
|
||||
.conv_limit_en = ADC_MEAS_NUM_LIM_DEFAULT,
|
||||
.conv_limit_num = ADC_MAX_MEAS_NUM_DEFAULT,
|
||||
.clk_div = SAR_ADC_CLK_DIV_DEFUALT,
|
||||
.format = DIG_ADC_OUTPUT_FORMAT_DEFUALT,
|
||||
.conv_mode = (adc_ll_convert_mode_t)adc_unit,
|
||||
};
|
||||
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
|
||||
adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
|
||||
adc1_pattern[0].channel = channel;
|
||||
dig_cfg.adc1_pattern_len = 1;
|
||||
dig_cfg.adc1_pattern = adc1_pattern;
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
|
||||
adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
|
||||
adc2_pattern[0].channel = channel;
|
||||
dig_cfg.adc2_pattern_len = 1;
|
||||
dig_cfg.adc2_pattern = adc2_pattern;
|
||||
}
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_init();
|
||||
adc_hal_dig_controller_config(&dig_cfg);
|
||||
adc_hal_rtc_reset();
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel)
|
||||
{
|
||||
adc_atten_t atten = adc_hal_get_atten(adc_n, channel);
|
||||
uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false);
|
||||
adc_hal_set_calibration_param(adc_n, cal_val);
|
||||
ESP_LOGD(ADC_TAG, "Set cal adc %d\n", cal_val);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------------------
|
||||
* ADC1
|
||||
*------------------------------------------------------------------------------------*/
|
||||
esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num)
|
||||
{
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
||||
|
||||
int io = ADC_GET_IO_NUM(ADC_NUM_1, channel);
|
||||
if (io < 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -257,71 +245,91 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
|
||||
{
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
||||
ADC_CHECK(atten < ADC_ATTEN_MAX, "ADC Atten Err", ESP_ERR_INVALID_ARG);
|
||||
|
||||
adc_gpio_init(ADC_UNIT_1, channel);
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_set_atten(ADC_NUM_1, channel, atten);
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc1_config_width(adc_bits_width_t width_bit)
|
||||
{
|
||||
ADC_CHECK(width_bit < ADC_WIDTH_MAX, "ADC bit width error", ESP_ERR_INVALID_ARG);
|
||||
#ifdef 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_ESP32S2
|
||||
ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG);
|
||||
#endif
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_rtc_set_output_format(ADC_NUM_1, width_bit);
|
||||
adc_hal_output_invert(ADC_NUM_1, true);
|
||||
adc_hal_rtc_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT);
|
||||
adc_hal_set_sar_clk_div(ADC_NUM_1, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_1));
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc1_i2s_mode_acquire(void)
|
||||
esp_err_t adc1_dma_mode_acquire(void)
|
||||
{
|
||||
/* Use locks to avoid digtal and RTC controller conflicts.
|
||||
for adc1, block until acquire the lock. */
|
||||
_lock_acquire( &adc1_i2s_lock );
|
||||
ESP_LOGD( ADC_TAG, "i2s mode takes adc1 lock." );
|
||||
ADC1_DMA_LOCK_ACQUIRE();
|
||||
ESP_LOGD( ADC_TAG, "dma mode takes adc1 lock." );
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||
/* switch SARADC into DIG channel */
|
||||
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc1_adc_mode_acquire(void)
|
||||
esp_err_t adc1_rtc_mode_acquire(void)
|
||||
{
|
||||
/* Use locks to avoid digtal and RTC controller conflicts.
|
||||
for adc1, block until acquire the lock. */
|
||||
_lock_acquire( &adc1_i2s_lock );
|
||||
ADC1_DMA_LOCK_ACQUIRE();
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
/* switch SARADC into RTC channel. */
|
||||
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC);
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc1_lock_release(void)
|
||||
{
|
||||
ADC_CHECK((uint32_t *)adc1_i2s_lock != NULL, "adc1 lock release called before acquire", ESP_ERR_INVALID_STATE );
|
||||
/* Use locks to avoid digtal and RTC controller conflicts.
|
||||
for adc1, block until acquire the lock. */
|
||||
_lock_release( &adc1_i2s_lock );
|
||||
ADC_CHECK((uint32_t *)adc1_dma_lock != NULL, "adc1 lock release called before acquire", ESP_ERR_INVALID_STATE );
|
||||
/* Use locks to avoid digtal and RTC controller conflicts. for adc1, block until acquire the lock. */
|
||||
ADC1_DMA_LOCK_RELEASE();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int adc1_get_raw(adc1_channel_t channel)
|
||||
{
|
||||
uint16_t adc_value;
|
||||
int adc_value;
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
||||
adc1_adc_mode_acquire();
|
||||
|
||||
adc1_rtc_mode_acquire();
|
||||
adc_power_on();
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
/* disable other peripherals. */
|
||||
adc_hal_hall_disable();
|
||||
/* currently the LNA is not open, close it by default. */
|
||||
adc_hal_amp_disable();
|
||||
/* set controller */
|
||||
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC);
|
||||
/* start conversion */
|
||||
adc_value = adc_convert(ADC_NUM_1, channel);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
adc_hal_hall_disable(); //Disable other peripherals.
|
||||
adc_hal_amp_disable(); //Currently the LNA is not open, close it by default.
|
||||
#endif
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
adc_set_init_code(ADC_NUM_1, channel); // calibration for adc
|
||||
#endif
|
||||
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); //Set controller
|
||||
adc_hal_convert(ADC_NUM_1, channel, &adc_value); //Start conversion, For ADC1, the data always valid.
|
||||
ADC_EXIT_CRITICAL();
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
adc_hal_rtc_reset(); //Reset FSM of rtc controller
|
||||
#endif
|
||||
|
||||
adc1_lock_release();
|
||||
return adc_value;
|
||||
@ -340,9 +348,11 @@ void adc1_ulp_enable(void)
|
||||
adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_ULP);
|
||||
/* 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
|
||||
/* disable other peripherals. */
|
||||
adc_hal_hall_disable();
|
||||
adc_hal_amp_disable();
|
||||
#endif
|
||||
ADC_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
@ -352,6 +362,7 @@ void adc1_ulp_enable(void)
|
||||
esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num)
|
||||
{
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
|
||||
|
||||
int io = ADC_GET_IO_NUM(ADC_NUM_2, channel);
|
||||
if (io < 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -362,20 +373,21 @@ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock.*/
|
||||
esp_err_t adc2_wifi_acquire(void)
|
||||
{
|
||||
/* Wi-Fi module will use adc2. Use locks to avoid conflicts. */
|
||||
_lock_acquire( &adc2_wifi_lock );
|
||||
ADC2_WIFI_LOCK_ACQUIRE();
|
||||
ESP_LOGD( ADC_TAG, "Wi-Fi takes adc2 lock." );
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc2_wifi_release(void)
|
||||
{
|
||||
ADC_CHECK((uint32_t *)adc2_wifi_lock != NULL, "wifi release called before acquire", ESP_ERR_INVALID_STATE );
|
||||
|
||||
_lock_release( &adc2_wifi_lock );
|
||||
ADC_CHECK(ADC2_WIFI_LOCK_CHECK(), "wifi release called before acquire", ESP_ERR_INVALID_STATE );
|
||||
ADC2_WIFI_LOCK_RELEASE();
|
||||
ESP_LOGD( ADC_TAG, "Wi-Fi returns adc2 lock." );
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -395,119 +407,123 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
|
||||
ADC_CHECK(atten <= ADC_ATTEN_11db, "ADC2 Atten Err", ESP_ERR_INVALID_ARG);
|
||||
|
||||
adc2_pad_init(channel);
|
||||
portENTER_CRITICAL( &adc2_spinlock );
|
||||
|
||||
//lazy initialization
|
||||
ADC2_ENTER_CRITICAL();
|
||||
//avoid collision with other tasks
|
||||
if ( _lock_try_acquire( &adc2_wifi_lock ) == -1 ) {
|
||||
if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) {
|
||||
//try the lock, return if failed (wifi using).
|
||||
portEXIT_CRITICAL( &adc2_spinlock );
|
||||
ADC2_EXIT_CRITICAL();
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
adc_hal_set_atten(ADC_NUM_2, channel, atten);
|
||||
_lock_release( &adc2_wifi_lock );
|
||||
ADC2_WIFI_LOCK_RELEASE();
|
||||
ADC2_EXIT_CRITICAL();
|
||||
|
||||
portEXIT_CRITICAL( &adc2_spinlock );
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static inline void adc2_config_width(adc_bits_width_t width_bit)
|
||||
{
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
/* Lock APB clock. */
|
||||
if (s_adc2_arbiter_lock == NULL) {
|
||||
esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc2", &s_adc2_arbiter_lock);
|
||||
}
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
#endif //CONFIG_IDF_TARGET_ESP32S2
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_rtc_set_output_format(ADC_NUM_2, width_bit);
|
||||
adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
|
||||
adc_hal_output_invert(ADC_NUM_2, true);
|
||||
adc_hal_rtc_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT);
|
||||
adc_hal_set_sar_clk_div(ADC_NUM_2, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_2));
|
||||
ADC_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
static inline void adc2_dac_disable( adc2_channel_t channel)
|
||||
{
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
if ( channel == ADC2_CHANNEL_8 ) { // the same as DAC channel 1
|
||||
dac_output_disable(DAC_CHANNEL_1);
|
||||
} else if ( channel == ADC2_CHANNEL_9 ) {
|
||||
dac_output_disable(DAC_CHANNEL_2);
|
||||
}
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
if ( channel == ADC2_CHANNEL_6 ) { // the same as DAC channel 1
|
||||
dac_output_disable(DAC_CHANNEL_1);
|
||||
} else if ( channel == ADC2_CHANNEL_7 ) {
|
||||
dac_output_disable(DAC_CHANNEL_2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//registers in critical section with adc1:
|
||||
//SENS_SAR_START_FORCE_REG,
|
||||
/**
|
||||
* @note For ESP32S2:
|
||||
* The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
|
||||
* Or, the RTC controller will fail when get raw data.
|
||||
* This issue does not occur on digital controllers (DMA mode), and the hardware guarantees that there will be no errors.
|
||||
*/
|
||||
esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out)
|
||||
{
|
||||
uint16_t adc_value = 0;
|
||||
int adc_value = 0;
|
||||
|
||||
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
|
||||
ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG);
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG);
|
||||
#endif
|
||||
|
||||
//in critical section with whole rtc module
|
||||
adc_power_on();
|
||||
adc_power_on(); //in critical section with whole rtc module
|
||||
|
||||
//avoid collision with other tasks
|
||||
portENTER_CRITICAL(&adc2_spinlock);
|
||||
//lazy initialization
|
||||
//try the lock, return if failed (wifi using).
|
||||
if ( _lock_try_acquire( &adc2_wifi_lock ) == -1 ) {
|
||||
portEXIT_CRITICAL( &adc2_spinlock );
|
||||
ADC2_ENTER_CRITICAL(); //avoid collision with other tasks
|
||||
|
||||
if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) { //try the lock, return if failed (wifi using).
|
||||
ADC2_EXIT_CRITICAL();
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
//disable other peripherals
|
||||
#ifdef CONFIG_ADC_DISABLE_DAC
|
||||
adc2_dac_disable(channel);
|
||||
adc2_dac_disable(channel); //disable other peripherals
|
||||
#endif
|
||||
// set controller
|
||||
// in critical section with whole rtc module
|
||||
// because the PWDET use the same registers, place it here.
|
||||
adc2_config_width(width_bit);
|
||||
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);
|
||||
//start converting
|
||||
adc_value = adc_convert(ADC_NUM_2, channel);
|
||||
_lock_release( &adc2_wifi_lock );
|
||||
portEXIT_CRITICAL(&adc2_spinlock);
|
||||
adc2_config_width(width_bit); // in critical section with whole rtc module. because the PWDET use the same registers, place it here.
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
adc_set_init_code(ADC_NUM_2, channel); // calibration for adc
|
||||
#endif
|
||||
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller
|
||||
|
||||
*raw_out = (int)adc_value;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_adc2_arbiter_lock) {
|
||||
esp_pm_lock_acquire(s_adc2_arbiter_lock);
|
||||
}
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
if (adc_hal_convert(ADC_NUM_2, channel, &adc_value)) {
|
||||
adc_value = -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
/* Release APB clock. */
|
||||
if (s_adc2_arbiter_lock) {
|
||||
esp_pm_lock_release(s_adc2_arbiter_lock);
|
||||
}
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
ADC2_WIFI_LOCK_RELEASE();
|
||||
ADC2_EXIT_CRITICAL();
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
adc_rtc_reset();
|
||||
#endif
|
||||
|
||||
if (adc_value < 0) {
|
||||
ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." );
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
*raw_out = adc_value;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)
|
||||
{
|
||||
adc_power_always_on(); //Select power source of ADC
|
||||
if (adc_hal_vref_output(gpio) != true) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
} else {
|
||||
//Configure RTC gpio
|
||||
rtc_gpio_init(gpio);
|
||||
rtc_gpio_set_direction(gpio, RTC_GPIO_MODE_DISABLED);
|
||||
rtc_gpio_pullup_dis(gpio);
|
||||
rtc_gpio_pulldown_dis(gpio);
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
HALL SENSOR
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
static int hall_sensor_get_value(void) //hall sensor without LNA
|
||||
{
|
||||
int hall_value;
|
||||
|
||||
adc_power_on();
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
/* disable other peripherals. */
|
||||
adc_hal_amp_disable();
|
||||
adc_hal_hall_enable();
|
||||
// set controller
|
||||
adc_hal_set_controller( ADC_NUM_1, ADC_CTRL_RTC );
|
||||
hall_value = adc_hal_hall_convert();
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return hall_value;
|
||||
}
|
||||
|
||||
int hall_sensor_read(void)
|
||||
{
|
||||
adc_gpio_init(ADC_NUM_1, ADC1_CHANNEL_0);
|
||||
adc_gpio_init(ADC_NUM_1, ADC1_CHANNEL_3);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0);
|
||||
return hall_sensor_get_value();
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
COMPONENT_SRCDIRS := . $(IDF_TARGET)
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := include $(IDF_TARGET)/include
|
||||
COMPONENT_ADD_INCLUDEDIRS := include $(IDF_TARGET)/include $(IDF_TARGET)/include/driver
|
||||
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include/driver
|
||||
|
||||
|
181
components/driver/esp32/adc.c
Normal file
181
components/driver/esp32/adc.c
Normal file
@ -0,0 +1,181 @@
|
||||
// Copyright 2016-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.
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "esp_log.h"
|
||||
#include "sys/lock.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/rtc_cntl.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Enable built-in checks in queue.h in debug builds
|
||||
#define INVARIANTS
|
||||
#endif
|
||||
#include "sys/queue.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_hal.h"
|
||||
|
||||
#define ADC_MAX_MEAS_NUM_DEFAULT (255)
|
||||
#define ADC_MEAS_NUM_LIM_DEFAULT (1)
|
||||
#define SAR_ADC_CLK_DIV_DEFUALT (2)
|
||||
|
||||
#define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT)
|
||||
#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11)
|
||||
#define DIG_ADC_BIT_WIDTH_DEFUALT (ADC_WIDTH_BIT_12)
|
||||
|
||||
#define ADC_CHECK_RET(fun_ret) ({ \
|
||||
if (fun_ret != ESP_OK) { \
|
||||
ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \
|
||||
return ESP_FAIL; \
|
||||
} \
|
||||
})
|
||||
|
||||
static const char *ADC_TAG = "ADC";
|
||||
|
||||
#define ADC_CHECK(a, str, ret_val) ({ \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(ADC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
|
||||
return (ret_val); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
|
||||
|
||||
#define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG)
|
||||
|
||||
extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
|
||||
#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
|
||||
#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src)
|
||||
{
|
||||
ADC_CHECK(src < ADC_I2S_DATA_SRC_MAX, "ADC i2s data source error", ESP_ERR_INVALID_ARG);
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_set_data_source(src);
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel)
|
||||
{
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_1)), "ADC1 not support DMA for now.", ESP_ERR_INVALID_ARG);
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_2)), "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG);
|
||||
ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
|
||||
}
|
||||
|
||||
adc_hal_digi_pattern_table_t adc1_pattern[1];
|
||||
adc_hal_digi_pattern_table_t adc2_pattern[1];
|
||||
adc_hal_digi_config_t dig_cfg = {
|
||||
.conv_limit_en = ADC_MEAS_NUM_LIM_DEFAULT,
|
||||
.conv_limit_num = ADC_MAX_MEAS_NUM_DEFAULT,
|
||||
.clk_div = SAR_ADC_CLK_DIV_DEFUALT,
|
||||
.format = DIG_ADC_OUTPUT_FORMAT_DEFUALT,
|
||||
.conv_mode = (adc_hal_digi_convert_mode_t)adc_unit,
|
||||
};
|
||||
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
|
||||
adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
|
||||
adc1_pattern[0].channel = channel;
|
||||
dig_cfg.adc1_pattern_len = 1;
|
||||
dig_cfg.adc1_pattern = adc1_pattern;
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
|
||||
adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
|
||||
adc2_pattern[0].channel = channel;
|
||||
dig_cfg.adc2_pattern_len = 1;
|
||||
dig_cfg.adc2_pattern = adc2_pattern;
|
||||
}
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_init();
|
||||
adc_hal_digi_controller_config(&dig_cfg);
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||
ADC_EXIT_CRITICAL();
|
||||
if (adc_hal_vref_output(gpio) != true) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
//Configure RTC gpio
|
||||
rtc_gpio_init(gpio);
|
||||
rtc_gpio_set_direction(gpio, RTC_GPIO_MODE_DISABLED);
|
||||
rtc_gpio_pullup_dis(gpio);
|
||||
rtc_gpio_pulldown_dis(gpio);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
HALL SENSOR
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
static int hall_sensor_get_value(void) //hall sensor without LNA
|
||||
{
|
||||
int hall_value;
|
||||
|
||||
adc_power_on();
|
||||
|
||||
ADC_ENTER_CRITICAL();
|
||||
/* disable other peripherals. */
|
||||
adc_hal_amp_disable();
|
||||
adc_hal_hall_enable();
|
||||
// set controller
|
||||
adc_hal_set_controller( ADC_NUM_1, ADC_CTRL_RTC );
|
||||
hall_value = adc_hal_hall_convert();
|
||||
ADC_EXIT_CRITICAL();
|
||||
|
||||
return hall_value;
|
||||
}
|
||||
|
||||
int hall_sensor_read(void)
|
||||
{
|
||||
adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_0);
|
||||
adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_3);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0);
|
||||
return hall_sensor_get_value();
|
||||
}
|
88
components/driver/esp32/include/driver/adc.h
Normal file
88
components/driver/esp32/include/driver/adc.h
Normal file
@ -0,0 +1,88 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "driver/adc_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Set I2S data source
|
||||
* @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC.
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
*/
|
||||
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src);
|
||||
|
||||
/**
|
||||
* @brief Initialize I2S ADC mode
|
||||
* @param adc_unit ADC unit index
|
||||
* @param channel ADC channel index
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Output ADC2 reference voltage to GPIO 25 or 26 or 27
|
||||
*
|
||||
* This function utilizes the testing mux exclusive to ADC 2 to route the
|
||||
* reference voltage one of ADC2's channels. Supported GPIOs are GPIOs
|
||||
* 25, 26, and 27. This refernce voltage can be manually read from the pin
|
||||
* and used in the esp_adc_cal component.
|
||||
*
|
||||
* @param[in] gpio GPIO number (GPIOs 25, 26 and 27 are supported)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: v_ref successfully routed to selected GPIO
|
||||
* - ESP_ERR_INVALID_ARG: Unsupported GPIO
|
||||
*/
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio);
|
||||
|
||||
/**
|
||||
* @brief Read Hall Sensor
|
||||
*
|
||||
* @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on,
|
||||
* the input of GPIO36 and GPIO39 will be pulled down for about 80ns.
|
||||
* When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39.
|
||||
* Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue.
|
||||
*
|
||||
* @note The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure
|
||||
* these channels for use as ADC channels.
|
||||
*
|
||||
* @note The ADC1 module must be enabled by calling
|
||||
* adc1_config_width() before calling hall_sensor_read(). ADC1
|
||||
* should be configured for 12 bit readings, as the hall sensor
|
||||
* readings are low values and do not cover the full range of the
|
||||
* ADC.
|
||||
*
|
||||
* @return The hall sensor reading.
|
||||
*/
|
||||
int hall_sensor_read(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
380
components/driver/esp32s2/adc.c
Normal file
380
components/driver/esp32s2/adc.c
Normal file
@ -0,0 +1,380 @@
|
||||
// Copyright 2016-2018 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.
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "esp_log.h"
|
||||
#include "sys/lock.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/rtc_cntl.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_hal.h"
|
||||
|
||||
#define ADC_CHECK_RET(fun_ret) ({ \
|
||||
if (fun_ret != ESP_OK) { \
|
||||
ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \
|
||||
return ESP_FAIL; \
|
||||
} \
|
||||
})
|
||||
|
||||
static const char *ADC_TAG = "ADC";
|
||||
|
||||
#define ADC_CHECK(a, str, ret_val) ({ \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(ADC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
|
||||
return (ret_val); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
|
||||
|
||||
#define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG)
|
||||
|
||||
extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
|
||||
#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
|
||||
#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
esp_err_t adc_digi_init(void)
|
||||
{
|
||||
adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_init();
|
||||
adc_hal_arbiter_config(&config);
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_deinit(void)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_init();
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_controller_config(config);
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config)
|
||||
{
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_arbiter_config(config);
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 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.
|
||||
*
|
||||
* @note Only ADC2 support arbiter to switch controllers automatically. Access to the ADC is based on the priority of the controller.
|
||||
* @note For ADC1, Controller access is mutually exclusive.
|
||||
*
|
||||
* @param adc_unit ADC unit.
|
||||
* @param ctrl ADC controller, Refer to `adc_controller_t`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl)
|
||||
{
|
||||
adc_arbiter_t config = {0};
|
||||
adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT();
|
||||
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc_hal_set_controller(ADC_NUM_1, ctrl);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
adc_hal_set_controller(ADC_NUM_2, ctrl);
|
||||
switch (ctrl) {
|
||||
case ADC2_CTRL_FORCE_PWDET:
|
||||
config.pwdet_pri = 2;
|
||||
config.mode = ADC_ARB_MODE_SHIELD;
|
||||
adc_hal_arbiter_config(&config);
|
||||
adc_hal_set_controller(ADC_NUM_2, ADC2_CTRL_PWDET);
|
||||
break;
|
||||
case ADC2_CTRL_FORCE_RTC:
|
||||
config.rtc_pri = 2;
|
||||
config.mode = ADC_ARB_MODE_SHIELD;
|
||||
adc_hal_arbiter_config(&config);
|
||||
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);
|
||||
break;
|
||||
case ADC2_CTRL_FORCE_ULP:
|
||||
config.rtc_pri = 2;
|
||||
config.mode = ADC_ARB_MODE_SHIELD;
|
||||
adc_hal_arbiter_config(&config);
|
||||
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_ULP);
|
||||
break;
|
||||
case ADC2_CTRL_FORCE_DIG:
|
||||
config.dig_pri = 2;
|
||||
config.mode = ADC_ARB_MODE_SHIELD;
|
||||
adc_hal_arbiter_config(&config);
|
||||
adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
|
||||
break;
|
||||
default:
|
||||
adc_hal_arbiter_config(&cfg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_start(void)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_enable();
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_stop(void)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_disable();
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset FSM of adc digital controller.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t adc_digi_reset(void)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
adc_hal_digi_reset();
|
||||
adc_hal_digi_clear_pattern_table(ADC_NUM_1);
|
||||
adc_hal_digi_clear_pattern_table(ADC_NUM_2);
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
/* Digital controller filter setting */
|
||||
/*************************************/
|
||||
|
||||
esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (idx == ADC_DIGI_FILTER_IDX0) {
|
||||
adc_hal_digi_filter_reset(ADC_NUM_1);
|
||||
} else if (idx == ADC_DIGI_FILTER_IDX1) {
|
||||
adc_hal_digi_filter_reset(ADC_NUM_2);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (idx == ADC_DIGI_FILTER_IDX0) {
|
||||
adc_hal_digi_filter_set_factor(ADC_NUM_1, config->mode);
|
||||
} else if (idx == ADC_DIGI_FILTER_IDX1) {
|
||||
adc_hal_digi_filter_set_factor(ADC_NUM_2, config->mode);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (idx == ADC_DIGI_FILTER_IDX0) {
|
||||
config->adc_unit = ADC_UNIT_1;
|
||||
config->channel = ADC_CHANNEL_MAX;
|
||||
adc_hal_digi_filter_get_factor(ADC_NUM_1, &config->mode);
|
||||
} else if (idx == ADC_DIGI_FILTER_IDX1) {
|
||||
config->adc_unit = ADC_UNIT_2;
|
||||
config->channel = ADC_CHANNEL_MAX;
|
||||
adc_hal_digi_filter_get_factor(ADC_NUM_2, &config->mode);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (idx == ADC_DIGI_FILTER_IDX0) {
|
||||
adc_hal_digi_filter_enable(ADC_NUM_1, enable);
|
||||
} else if (idx == ADC_DIGI_FILTER_IDX1) {
|
||||
adc_hal_digi_filter_enable(ADC_NUM_2, enable);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the filtered data of adc digital controller filter. For debug.
|
||||
* 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 For ESP32S2, The filter will filter all the enabled channel data of the each ADC unit at the same time.
|
||||
* @param idx Filter index.
|
||||
* @return Filtered data. if <0, the read data invalid.
|
||||
*/
|
||||
int adc_digi_filter_read_data(adc_digi_filter_idx_t idx)
|
||||
{
|
||||
if (idx == ADC_DIGI_FILTER_IDX0) {
|
||||
return adc_hal_digi_filter_read_data(ADC_NUM_1);
|
||||
} else if (idx == ADC_DIGI_FILTER_IDX1) {
|
||||
return adc_hal_digi_filter_read_data(ADC_NUM_2);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
/* Digital controller monitor setting */
|
||||
/**************************************/
|
||||
|
||||
esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (idx == ADC_DIGI_MONITOR_IDX0) {
|
||||
adc_hal_digi_monitor_config(ADC_NUM_1, config);
|
||||
} else if (idx == ADC_DIGI_MONITOR_IDX1) {
|
||||
adc_hal_digi_monitor_config(ADC_NUM_2, config);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (idx == ADC_DIGI_MONITOR_IDX0) {
|
||||
adc_hal_digi_monitor_enable(ADC_NUM_1, enable);
|
||||
} else if (idx == ADC_DIGI_MONITOR_IDX1) {
|
||||
adc_hal_digi_monitor_enable(ADC_NUM_2, enable);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
/* Digital controller intr setting */
|
||||
/**************************************/
|
||||
|
||||
esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc_hal_digi_intr_enable(ADC_NUM_1, intr_mask);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
adc_hal_digi_intr_enable(ADC_NUM_2, intr_mask);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc_hal_digi_intr_disable(ADC_NUM_1, intr_mask);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
adc_hal_digi_intr_disable(ADC_NUM_2, intr_mask);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
|
||||
{
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
adc_hal_digi_intr_clear(ADC_NUM_1, intr_mask);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
adc_hal_digi_intr_clear(ADC_NUM_2, intr_mask);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
ADC_ENTER_CRITICAL();
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
ret = adc_hal_digi_get_intr_status(ADC_NUM_1);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
ret = adc_hal_digi_get_intr_status(ADC_NUM_2);
|
||||
}
|
||||
ADC_EXIT_CRITICAL();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t s_isr_registered = 0;
|
||||
static intr_handle_t s_adc_isr_handle = NULL;
|
||||
|
||||
esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags)
|
||||
{
|
||||
ADC_CHECK((fn != NULL), "Parameter error", ESP_ERR_INVALID_ARG);
|
||||
ADC_CHECK(s_isr_registered == 0, "ADC ISR have installed, can not install again", ESP_FAIL);
|
||||
|
||||
esp_err_t ret = esp_intr_alloc(ETS_APB_ADC_INTR_SOURCE, intr_alloc_flags, fn, arg, &s_adc_isr_handle);
|
||||
if (ret == ESP_OK) {
|
||||
s_isr_registered = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t adc_digi_isr_deregister(void)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
if (s_isr_registered) {
|
||||
ret = esp_intr_free(s_adc_isr_handle);
|
||||
if (ret == ESP_OK) {
|
||||
s_isr_registered = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
277
components/driver/esp32s2/include/driver/adc.h
Normal file
277
components/driver/esp32s2/include/driver/adc.h
Normal file
@ -0,0 +1,277 @@
|
||||
// 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.
|
||||
|
||||
#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);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Deprecated API
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Set I2S data source
|
||||
*
|
||||
* @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC.
|
||||
*
|
||||
* @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_controller_config`` instead.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
*/
|
||||
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief Initialize I2S ADC mode
|
||||
*
|
||||
* @param adc_unit ADC unit index
|
||||
* @param channel ADC channel index
|
||||
*
|
||||
* @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_controller_config`` instead.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel) __attribute__((deprecated));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -21,6 +21,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief temperature sensor range option.
|
||||
*/
|
||||
typedef enum {
|
||||
TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */
|
||||
TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */
|
||||
@ -39,6 +42,9 @@ typedef struct {
|
||||
uint8_t clk_div; /*!< Default: 6 */
|
||||
} temp_sensor_config_t;
|
||||
|
||||
/**
|
||||
* @brief temperature sensor default setting.
|
||||
*/
|
||||
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
|
||||
.clk_div = 6}
|
||||
|
||||
@ -74,7 +80,7 @@ esp_err_t temp_sensor_start(void);
|
||||
esp_err_t temp_sensor_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Read temperature sensor raw data.
|
||||
* @brief Read temperature sensor raw data.
|
||||
* @param tsens_out Pointer to raw data, Range: 0 ~ 255
|
||||
* @return
|
||||
* - ESP_OK Success
|
@ -233,7 +233,7 @@ esp_err_t touch_pad_isr_register(intr_handler_t fn, void *arg, touch_pad_intr_ma
|
||||
*
|
||||
* @param enable true(default): Enable the timeout check; false: Disable the timeout check.
|
||||
* @param threshold For all channels, the maximum value that will not be exceeded during normal operation.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
@ -244,7 +244,7 @@ esp_err_t touch_pad_timeout_set(bool enable, uint32_t threshold);
|
||||
* If this API is not called, the touch FSM will stop the measurement after timeout interrupt.
|
||||
*
|
||||
* @note Call this API after finishes the exception handling by user.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
@ -491,7 +491,7 @@ esp_err_t touch_pad_sleep_channel_get_info(touch_pad_sleep_channel_t *slp_config
|
||||
* e.g. The user should uses `touch_pad_sleep_channel_read_data` instead of `touch_pad_read_raw_data` to obtain the sleep channel reading.
|
||||
*
|
||||
* @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param enable true: enable sleep pad for touch sensor; false: disable sleep pad for touch sensor;
|
||||
* @param enable true: enable sleep pad for touch sensor; false: disable sleep pad for touch sensor;
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
@ -502,9 +502,9 @@ esp_err_t touch_pad_sleep_channel_enable(touch_pad_t pad_num, bool enable);
|
||||
* The touch sensor can works in sleep mode to wake up sleep.
|
||||
*
|
||||
* @note ESP32S2 only support one sleep channel.
|
||||
*
|
||||
*
|
||||
* @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param enable true: enable proximity for sleep channel; false: disable proximity for sleep channel;
|
||||
* @param enable true: enable proximity for sleep channel; false: disable proximity for sleep channel;
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
@ -515,7 +515,7 @@ esp_err_t touch_pad_sleep_channel_enable_proximity(touch_pad_t pad_num, bool ena
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
*
|
||||
* @note In general, the touch threshold during sleep can use the threshold parameter parameters before sleep.
|
||||
*
|
||||
*
|
||||
* @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param touch_thres touch sleep pad threshold
|
||||
* @return
|
||||
@ -528,7 +528,7 @@ esp_err_t touch_pad_sleep_set_threshold(touch_pad_t pad_num, uint32_t touch_thre
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
*
|
||||
* @note In general, the touch threshold during sleep can use the threshold parameter parameters before sleep.
|
||||
*
|
||||
*
|
||||
* @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param touch_thres touch sleep pad threshold
|
||||
* @return
|
@ -18,11 +18,12 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/rtc_io_struct.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "temp_sensor.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
|
||||
static const char *TAG = "tsens";
|
||||
@ -38,6 +39,18 @@ static const char *TAG = "tsens";
|
||||
#define TSENS_DAC_FACTOR (27.88)
|
||||
#define TSENS_SYS_OFFSET (20.52)
|
||||
|
||||
#include "i2c_rtc_clk.h"
|
||||
|
||||
#define ANA_CONFIG2_REG 0x6000E048
|
||||
#define ANA_CONFIG2_M (BIT(18))
|
||||
|
||||
#define I2C_ADC 0X69
|
||||
#define I2C_ADC_HOSTID 1
|
||||
|
||||
#define I2C_SARADC_TSENS_DAC 6
|
||||
#define I2C_SARADC_TSENS_DAC_MSB 3
|
||||
#define I2C_SARADC_TSENS_DAC_LSB 0
|
||||
|
||||
typedef struct {
|
||||
int index;
|
||||
int offset;
|
||||
@ -60,7 +73,11 @@ static SemaphoreHandle_t rtc_tsens_mux = NULL;
|
||||
|
||||
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
|
||||
{
|
||||
// SENS.sar_tctrl.tsens_dac = dac_offset[tsens.dac_offset].set_val; // TODO: others MR resolve it.
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
|
||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
|
||||
SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16));
|
||||
I2C_WRITEREG_MASK_RTC(I2C_ADC, I2C_SARADC_TSENS_DAC, dac_offset[tsens.dac_offset].set_val);
|
||||
SENS.sar_tctrl.tsens_clk_div = tsens.clk_div;
|
||||
SENS.sar_tctrl.tsens_power_up_force = 1;
|
||||
SENS.sar_tctrl2.tsens_xpd_wait = TSENS_XPD_WAIT_DEFAULT;
|
||||
@ -77,9 +94,13 @@ esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
|
||||
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens)
|
||||
{
|
||||
TSENS_CHECK(tsens != NULL, ESP_ERR_INVALID_ARG);
|
||||
// tsens->dac_offset = SENS.sar_tctrl.tsens_dac; // TODO: others MR resolve it.
|
||||
for(int i=TSENS_DAC_L0; i<TSENS_DAC_MAX; i++) {
|
||||
if(tsens->dac_offset == dac_offset[i].set_val) {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
|
||||
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18));
|
||||
SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16));
|
||||
tsens->dac_offset = I2C_READREG_MASK_RTC(I2C_ADC, I2C_SARADC_TSENS_DAC);
|
||||
for (int i = TSENS_DAC_L0; i < TSENS_DAC_MAX; i++) {
|
||||
if (tsens->dac_offset == dac_offset[i].set_val) {
|
||||
tsens->dac_offset = dac_offset[i].index;
|
||||
break;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
#if SOC_I2S_SUPPORTS_ADC_DAC
|
||||
#include "driver/dac.h"
|
||||
#include "hal/i2s_hal.h"
|
||||
#include "adc1_i2s_private.h"
|
||||
#include "adc1_private.h"
|
||||
#endif
|
||||
|
||||
#include "esp_intr_alloc.h"
|
||||
@ -1061,7 +1061,7 @@ esp_err_t i2s_adc_enable(i2s_port_t i2s_num)
|
||||
I2S_CHECK((p_i2s_obj[i2s_num] != NULL), "Not initialized yet", ESP_ERR_INVALID_STATE);
|
||||
I2S_CHECK((p_i2s_obj[i2s_num]->mode & I2S_MODE_ADC_BUILT_IN), "i2s built-in adc not enabled", ESP_ERR_INVALID_STATE);
|
||||
|
||||
adc1_i2s_mode_acquire();
|
||||
adc1_dma_mode_acquire();
|
||||
_i2s_adc_mode_recover();
|
||||
i2s_hal_start_rx(&(p_i2s_obj[i2s_num]->hal));
|
||||
i2s_hal_reset(&(p_i2s_obj[i2s_num]->hal));
|
||||
|
@ -12,30 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _DRIVER_ADC_H_
|
||||
#define _DRIVER_ADC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/adc_periph.h"
|
||||
#include "hal/adc_types.h"
|
||||
|
||||
//this definitions are only for being back-compatible
|
||||
#define ADC_ATTEN_0db ADC_ATTEN_DB_0
|
||||
#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5
|
||||
#define ADC_ATTEN_6db ADC_ATTEN_DB_6
|
||||
#define ADC_ATTEN_11db ADC_ATTEN_DB_11
|
||||
//this definitions are only for being back-compatible
|
||||
#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9
|
||||
#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10
|
||||
#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11
|
||||
#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**** `adc1_channel_t` will be deprecated functions, combine into `adc_channel_t` ********/
|
||||
typedef enum {
|
||||
@ -71,17 +58,29 @@ typedef enum {
|
||||
ADC2_CHANNEL_MAX,
|
||||
} adc2_channel_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_UNIT_1 = 1, /*!< SAR ADC 1*/
|
||||
ADC_UNIT_2 = 2, /*!< SAR ADC 2, not supported yet*/
|
||||
ADC_UNIT_BOTH = 3, /*!< SAR ADC 1 and 2, not supported yet */
|
||||
ADC_UNIT_ALTER = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */
|
||||
ADC_UNIT_MAX,
|
||||
} adc_unit_t;
|
||||
/**
|
||||
* @brief ADC rtc controller attenuation option.
|
||||
*
|
||||
* @note This definitions are only for being back-compatible
|
||||
*/
|
||||
#define ADC_ATTEN_0db ADC_ATTEN_DB_0
|
||||
#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5
|
||||
#define ADC_ATTEN_6db ADC_ATTEN_DB_6
|
||||
#define ADC_ATTEN_11db ADC_ATTEN_DB_11
|
||||
//this definitions are only for being back-compatible
|
||||
#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9
|
||||
#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10
|
||||
#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11
|
||||
#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller encode option.
|
||||
*
|
||||
* @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_output_format_t`` instead.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ENCODE_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data */
|
||||
ADC_ENCODE_11BIT, /*!< ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data */
|
||||
ADC_ENCODE_12BIT, /*!< ADC to DMA data format, , [15:12]-channel [11:0]-12 bits ADC data */
|
||||
ADC_ENCODE_11BIT, /*!< ADC to DMA data format, [15]-unit, [14:11]-channel [10:0]-11 bits ADC data */
|
||||
ADC_ENCODE_MAX,
|
||||
} adc_i2s_encode_t;
|
||||
|
||||
@ -89,7 +88,6 @@ typedef enum {
|
||||
* @brief Get the GPIO number of a specific ADC1 channel.
|
||||
*
|
||||
* @param channel Channel to get the GPIO number
|
||||
*
|
||||
* @param gpio_num output buffer to hold the GPIO number
|
||||
*
|
||||
* @return
|
||||
@ -99,60 +97,38 @@ typedef enum {
|
||||
esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Configure ADC1 capture width, meanwhile enable output invert for ADC1.
|
||||
* The configuration is for all channels of ADC1
|
||||
* @param width_bit Bit capture width for ADC1
|
||||
* @brief Set the attenuation of a particular channel on ADC1, and configure its associated GPIO pin mux.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
|
||||
|
||||
/**
|
||||
* @brief Configure ADC capture width.
|
||||
* @param adc_unit ADC unit index
|
||||
* @param width_bit Bit capture width for ADC unit.
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit);
|
||||
|
||||
/**
|
||||
* @brief Set the attenuation of a particular channel on ADC1, and configure its
|
||||
* associated GPIO pin mux.
|
||||
* The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage,
|
||||
* usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel.
|
||||
*
|
||||
* @note For any given channel, this function must be called before the first time
|
||||
* adc1_get_raw() is called for that channel.
|
||||
* When VDD_A is 3.3 V:
|
||||
*
|
||||
* @note This function can be called multiple times to configure multiple
|
||||
* ADC channels simultaneously. adc1_get_raw() can then be called for any configured
|
||||
* channel.
|
||||
* - 0 dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1 V
|
||||
* - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5 V
|
||||
* - 6 dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2 V
|
||||
* - 11 dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9 V (see note below)
|
||||
*
|
||||
* The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage,
|
||||
* usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel.
|
||||
*
|
||||
* When VDD_A is 3.3 V:
|
||||
*
|
||||
* - 0 dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1 V
|
||||
* - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5 V
|
||||
* - 6 dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2 V
|
||||
* - 11 dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9 V (see note below)
|
||||
*
|
||||
* @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured
|
||||
* bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
|
||||
* @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured bit width,
|
||||
* this value in ESP32 is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.
|
||||
* this value in ESP32S2 is: 8191 for 13-bits.)
|
||||
*
|
||||
* @note At 11 dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
|
||||
*
|
||||
* Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges:
|
||||
* @note For ESP32:
|
||||
* Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges:
|
||||
*
|
||||
* - 0 dB attenuation (ADC_ATTEN_DB_0) between 100 and 950 mV
|
||||
* - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250 mV
|
||||
* - 6 dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750 mV
|
||||
* - 11 dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450 mV
|
||||
* - 0 dB attenuation (ADC_ATTEN_DB_0) between 100 and 950 mV
|
||||
* - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250 mV
|
||||
* - 6 dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750 mV
|
||||
* - 11 dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450 mV
|
||||
*
|
||||
* For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges.
|
||||
* For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges.
|
||||
*
|
||||
* @note For any given channel, this function must be called before the first time ``adc1_get_raw()`` is called for that channel.
|
||||
*
|
||||
* @note This function can be called multiple times to configure multiple
|
||||
* ADC channels simultaneously. ``adc1_get_raw()`` can then be called for any configured channel.
|
||||
*
|
||||
* @param channel ADC1 channel to configure
|
||||
* @param atten Attenuation level
|
||||
@ -163,19 +139,31 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit);
|
||||
*/
|
||||
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten);
|
||||
|
||||
/**
|
||||
* @brief Configure ADC1 capture width, meanwhile enable output invert for ADC1.
|
||||
* The configuration is for all channels of ADC1
|
||||
* @param width_bit Bit capture width for ADC1
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
|
||||
|
||||
/**
|
||||
* @brief Take an ADC1 reading from a single channel.
|
||||
* @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on,
|
||||
* @note ESP32:
|
||||
* When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on,
|
||||
* the input of GPIO36 and GPIO39 will be pulled down for about 80ns.
|
||||
* When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39.
|
||||
* Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue.
|
||||
*
|
||||
* @note Call adc1_config_width() before the first time this
|
||||
* function is called.
|
||||
* function is called.
|
||||
*
|
||||
* @note For any given channel, adc1_config_channel_atten(channel)
|
||||
* must be called before the first time this function is called. Configuring
|
||||
* a new channel does not prevent a previously configured channel from being read.
|
||||
* must be called before the first time this function is called. Configuring
|
||||
* a new channel does not prevent a previously configured channel from being read.
|
||||
*
|
||||
* @param channel ADC1 channel to read
|
||||
*
|
||||
@ -225,22 +213,18 @@ esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en);
|
||||
esp_err_t adc_set_clk_div(uint8_t clk_div);
|
||||
|
||||
/**
|
||||
* @brief Set I2S data source
|
||||
* @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC.
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
*/
|
||||
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src);
|
||||
|
||||
/**
|
||||
* @brief Initialize I2S ADC mode
|
||||
* @brief Configure ADC capture width.
|
||||
*
|
||||
* @note For ESP32S2, only support ``ADC_WIDTH_BIT_13``.
|
||||
*
|
||||
* @param adc_unit ADC unit index
|
||||
* @param channel ADC channel index
|
||||
* @param width_bit Bit capture width for ADC unit. For ESP32S2, only support ``ADC_WIDTH_BIT_13``.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel);
|
||||
esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit);
|
||||
|
||||
/**
|
||||
* @brief Configure ADC1 to be usable by the ULP
|
||||
@ -253,27 +237,6 @@ esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel);
|
||||
*/
|
||||
void adc1_ulp_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Read Hall Sensor
|
||||
*
|
||||
* @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on,
|
||||
* the input of GPIO36 and GPIO39 will be pulled down for about 80ns.
|
||||
* When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39.
|
||||
* Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue.
|
||||
*
|
||||
* @note The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure
|
||||
* these channels for use as ADC channels.
|
||||
*
|
||||
* @note The ADC1 module must be enabled by calling
|
||||
* adc1_config_width() before calling hall_sensor_read(). ADC1
|
||||
* should be configured for 12 bit readings, as the hall sensor
|
||||
* readings are low values and do not cover the full range of the
|
||||
* ADC.
|
||||
*
|
||||
* @return The hall sensor reading.
|
||||
*/
|
||||
int hall_sensor_read(void);
|
||||
|
||||
/**
|
||||
* @brief Get the GPIO number of a specific ADC2 channel.
|
||||
*
|
||||
@ -290,23 +253,24 @@ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num);
|
||||
/**
|
||||
* @brief Configure the ADC2 channel, including setting attenuation.
|
||||
*
|
||||
* The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage,
|
||||
* usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel.
|
||||
*
|
||||
* When VDD_A is 3.3 V:
|
||||
*
|
||||
* - 0 dB attenuation (ADC_ATTEN_0db) gives full-scale voltage 1.1 V
|
||||
* - 2.5 dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5 V
|
||||
* - 6 dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2 V
|
||||
* - 11 dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9 V (see note below)
|
||||
*
|
||||
* @note This function also configures the input GPIO pin mux to
|
||||
* connect it to the ADC2 channel. It must be called before calling
|
||||
* ``adc2_get_raw()`` for this channel.
|
||||
*
|
||||
* The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage,
|
||||
* usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel.
|
||||
*
|
||||
* When VDD_A is 3.3 V:
|
||||
*
|
||||
* - 0 dB attenuation (ADC_ATTEN_0db) gives full-scale voltage 1.1 V
|
||||
* - 2.5 dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5 V
|
||||
* - 6 dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2 V
|
||||
* - 11 dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9 V (see note below)
|
||||
* connect it to the ADC2 channel. It must be called before calling
|
||||
* ``adc2_get_raw()`` for this channel.
|
||||
*
|
||||
* @note The full-scale voltage is the voltage corresponding to a maximum reading
|
||||
* (depending on ADC2 configured bit width, this value is: 4095 for 12-bits, 2047
|
||||
* for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
|
||||
* (depending on ADC2 configured bit width,
|
||||
* this value of ESP32 is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.
|
||||
* this value of ESP32S2 is: 8191 for 13-bits.)
|
||||
*
|
||||
* @note At 11 dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
|
||||
*
|
||||
@ -322,46 +286,32 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten);
|
||||
/**
|
||||
* @brief Take an ADC2 reading on a single channel
|
||||
*
|
||||
* @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on,
|
||||
* @note ESP32:
|
||||
* When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on,
|
||||
* the input of GPIO36 and GPIO39 will be pulled down for about 80ns.
|
||||
* When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39.
|
||||
* Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue.
|
||||
*
|
||||
* @note For a given channel, ``adc2_config_channel_atten()``
|
||||
* must be called before the first time this function is called. If Wi-Fi is started via ``esp_wifi_start()``, this
|
||||
* function will always fail with ``ESP_ERR_TIMEOUT``.
|
||||
* @note ESP32:
|
||||
* For a given channel, ``adc2_config_channel_atten()``
|
||||
* must be called before the first time this function is called. If Wi-Fi is started via ``esp_wifi_start()``, this
|
||||
* function will always fail with ``ESP_ERR_TIMEOUT``.
|
||||
*
|
||||
* @param channel ADC2 channel to read
|
||||
*
|
||||
* @param width_bit Bit capture width for ADC2
|
||||
* @note ESP32S2:
|
||||
* ADC2 support hardware 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. Default priority: Wi-Fi > RTC > Digital;
|
||||
*
|
||||
* @param channel ADC2 channel to read
|
||||
* @param width_bit Bit capture width for ADC2. For ESP32S2, only support ``ADC_WIDTH_BIT_13``.
|
||||
* @param raw_out the variable to hold the output data.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if success
|
||||
* - ESP_ERR_TIMEOUT the WIFI is started, using the ADC2
|
||||
* - ESP_ERR_TIMEOUT ADC2 is being used by other controller and the request timed out.
|
||||
* - ESP_ERR_INVALID_STATE The controller status is invalid. Please try again.
|
||||
*/
|
||||
esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out);
|
||||
|
||||
/**
|
||||
* @brief Output ADC2 reference voltage to GPIO 25 or 26 or 27
|
||||
*
|
||||
* This function utilizes the testing mux exclusive to ADC 2 to route the
|
||||
* reference voltage one of ADC2's channels. Supported GPIOs are GPIOs
|
||||
* 25, 26, and 27. This refernce voltage can be manually read from the pin
|
||||
* and used in the esp_adc_cal component.
|
||||
*
|
||||
* @param[in] gpio GPIO number (GPIOs 25, 26 and 27 are supported)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: v_ref successfully routed to selected GPIO
|
||||
* - ESP_ERR_INVALID_ARG: Unsupported GPIO
|
||||
*/
|
||||
esp_err_t adc2_vref_to_gpio(gpio_num_t gpio);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_DRIVER_ADC_H_*/
|
||||
|
@ -24,7 +24,7 @@ extern "C" {
|
||||
#include "hal/dac_types.h"
|
||||
|
||||
/**
|
||||
* @brief Get the gpio number of a specific DAC channel.
|
||||
* @brief Get the GPIO number of a specific DAC channel.
|
||||
*
|
||||
* @param channel Channel to get the gpio number
|
||||
* @param gpio_num output buffer to hold the gpio number
|
||||
|
@ -14,4 +14,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "touch_sensor.h"
|
||||
#include "driver/touch_sensor.h"
|
@ -1,3 +1,3 @@
|
||||
idf_component_register(SRC_DIRS . param_test touch_sensor_test
|
||||
idf_component_register(SRC_DIRS . param_test touch_sensor_test adc_dma_test dac_dma_test
|
||||
PRIV_INCLUDE_DIRS include param_test/include
|
||||
PRIV_REQUIRES unity test_utils driver nvs_flash esp_serial_slave_link infrared_tools)
|
||||
PRIV_REQUIRES unity test_utils driver nvs_flash esp_serial_slave_link infrared_tools)
|
142
components/driver/test/adc_dma_test/test_esp32.c
Normal file
142
components/driver/test/adc_dma_test/test_esp32.c
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright 2015-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.
|
||||
|
||||
/*
|
||||
Tests for the adc device driver
|
||||
*/
|
||||
#include "esp_system.h"
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP8266, ESP32S2) // This testcase for ESP32
|
||||
|
||||
/*
|
||||
* ADC DMA testcase
|
||||
*/
|
||||
#include "driver/i2s.h"
|
||||
|
||||
//i2s number
|
||||
#define EXAMPLE_I2S_NUM (0)
|
||||
//i2s sample rate
|
||||
#define EXAMPLE_I2S_SAMPLE_RATE (16000)
|
||||
//i2s data bits
|
||||
#define EXAMPLE_I2S_SAMPLE_BITS (16)
|
||||
//enable display buffer for debug
|
||||
#define EXAMPLE_I2S_BUF_DEBUG (0)
|
||||
//I2S read buffer length
|
||||
#define EXAMPLE_I2S_READ_LEN (16 * 1024)
|
||||
//I2S data format
|
||||
#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT)
|
||||
//I2S channel number
|
||||
#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1))
|
||||
//I2S built-in ADC unit
|
||||
#define I2S_ADC_UNIT ADC_UNIT_1
|
||||
//I2S built-in ADC channel
|
||||
//#define I2S_ADC_CHANNEL //adc1_ch[0]
|
||||
|
||||
//flash record size, for recording 5 seconds' data
|
||||
#define FLASH_RECORD_SIZE (EXAMPLE_I2S_CHANNEL_NUM * EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_SAMPLE_BITS / 8 * 5)
|
||||
#define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE)
|
||||
//sector size of flash
|
||||
#define FLASH_SECTOR_SIZE (0x1000)
|
||||
|
||||
#define ADC1_TEST_CHANNEL_NUM 3
|
||||
#define ADC2_TEST_CHANNEL_NUM 3
|
||||
|
||||
static const int adc1_ch[ADC1_TEST_CHANNEL_NUM] = {
|
||||
ADC1_CHANNEL_2,
|
||||
ADC1_CHANNEL_3,
|
||||
ADC1_CHANNEL_4,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief I2S ADC/DAC mode init.
|
||||
*/
|
||||
static void example_i2s_init(void)
|
||||
{
|
||||
int i2s_num = EXAMPLE_I2S_NUM;
|
||||
i2s_config_t i2s_config = {
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
|
||||
.sample_rate = EXAMPLE_I2S_SAMPLE_RATE,
|
||||
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
|
||||
.communication_format = I2S_COMM_FORMAT_PCM,
|
||||
.channel_format = EXAMPLE_I2S_FORMAT,
|
||||
.intr_alloc_flags = 0,
|
||||
.dma_buf_count = 2,
|
||||
.dma_buf_len = 1024,
|
||||
.use_apll = 1,
|
||||
};
|
||||
//install and start i2s driver
|
||||
TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) );
|
||||
//init ADC pad
|
||||
TEST_ESP_OK( i2s_set_adc_mode(I2S_ADC_UNIT, adc1_ch[0]) );
|
||||
}
|
||||
|
||||
static void example_i2s_deinit(void)
|
||||
{
|
||||
TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief debug buffer data
|
||||
*/
|
||||
static void example_disp_buf(uint8_t *buf, int length)
|
||||
{
|
||||
printf("======\n");
|
||||
for (int i = 0; i < length; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
if ((i + 1) % 8 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("======\n");
|
||||
}
|
||||
|
||||
TEST_CASE("ADC DMA read", "[adc dma]")
|
||||
{
|
||||
example_i2s_init();
|
||||
|
||||
int i2s_read_len = EXAMPLE_I2S_READ_LEN;
|
||||
int flash_wr_size = 0;
|
||||
size_t bytes_read;
|
||||
|
||||
char *i2s_read_buff = (char *) calloc(i2s_read_len, sizeof(char));
|
||||
TEST_ESP_OK( i2s_adc_enable(EXAMPLE_I2S_NUM) );
|
||||
while (flash_wr_size < FLASH_RECORD_SIZE) {
|
||||
//read data from I2S bus, in this case, from ADC.
|
||||
TEST_ESP_OK( i2s_read(EXAMPLE_I2S_NUM, (void *) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY) );
|
||||
example_disp_buf((uint8_t *) i2s_read_buff, 64);
|
||||
//save original data from I2S(ADC) into flash.
|
||||
flash_wr_size += i2s_read_len;
|
||||
ets_printf("Sound recording %u%%\n", flash_wr_size * 100 / FLASH_RECORD_SIZE);
|
||||
}
|
||||
TEST_ESP_OK( i2s_adc_disable(EXAMPLE_I2S_NUM) );
|
||||
if (i2s_read_buff) {
|
||||
free(i2s_read_buff);
|
||||
i2s_read_buff = NULL;
|
||||
}
|
||||
|
||||
example_i2s_deinit();
|
||||
}
|
||||
|
||||
#endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32S2)
|
494
components/driver/test/adc_dma_test/test_esp32s2.c
Normal file
494
components/driver/test/adc_dma_test/test_esp32s2.c
Normal file
@ -0,0 +1,494 @@
|
||||
// Copyright 2015-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.
|
||||
|
||||
/*
|
||||
Tests for the adc device driver
|
||||
*/
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/adc_periph.h"
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP8266, ESP32) // This testcase for ESP32S2
|
||||
|
||||
#include "soc/system_reg.h"
|
||||
|
||||
static const char *TAG = "test_adc";
|
||||
|
||||
#define PLATFORM_SELECT (1) //0: pxp; 1: chip
|
||||
#if (PLATFORM_SELECT == 0) //PXP platform
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#define SET_BREAK_POINT(flag) REG_WRITE(APB_CTRL_DATE_REG, flag)
|
||||
//PXP clk is slower.
|
||||
#define SYS_DELAY_TIME_MOM (1/40)
|
||||
#define RTC_SLOW_CLK_FLAG 1 // Slow clock is 32KHz.
|
||||
static void test_pxp_deinit_io(void)
|
||||
{
|
||||
for (int i = 0; i < 22; i++) {
|
||||
rtc_gpio_init(i);
|
||||
}
|
||||
}
|
||||
#else
|
||||
//PXP clk is slower.
|
||||
#define SET_BREAK_POINT(flag)
|
||||
#define SYS_DELAY_TIME_MOM (1)
|
||||
#define RTC_SLOW_CLK_FLAG 0 // Slow clock is 32KHz.
|
||||
#endif
|
||||
|
||||
#define ADC_REG_BASE_TEST() ({ \
|
||||
TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(APB_SARADC_APB_CTRL_DATE_REG, APB_SARADC_APB_CTRL_DATE), APB_SARADC.apb_ctrl_date); \
|
||||
TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \
|
||||
TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \
|
||||
})
|
||||
#define TEST_ADC_TRIGGER_INTERVAL_DEFAULT (40)
|
||||
#define TEST_ADC_COUNT_NUM (10)
|
||||
#define TEST_ADC_CHANNEL (10)
|
||||
static adc_channel_t adc_list[TEST_ADC_CHANNEL] = {
|
||||
ADC_CHANNEL_0,
|
||||
ADC_CHANNEL_1,
|
||||
ADC_CHANNEL_2,
|
||||
ADC_CHANNEL_3,
|
||||
ADC_CHANNEL_4,
|
||||
ADC_CHANNEL_5,
|
||||
ADC_CHANNEL_6,
|
||||
ADC_CHANNEL_7,
|
||||
ADC_CHANNEL_8,
|
||||
ADC_CHANNEL_9,
|
||||
};
|
||||
/* For ESP32S2, it should use same atten, or, it will have error. */
|
||||
// #define TEST_ADC_ATTEN_DEFAULT (ADC_ATTEN_11db)
|
||||
static adc_atten_t adc_atten[ADC_ATTEN_MAX] = {
|
||||
ADC_ATTEN_DB_0,
|
||||
ADC_ATTEN_DB_2_5,
|
||||
ADC_ATTEN_DB_6,
|
||||
ADC_ATTEN_DB_11
|
||||
};
|
||||
/*******************************************/
|
||||
/** SPI DMA INIT CODE */
|
||||
/*******************************************/
|
||||
extern esp_err_t adc_digi_reset(void);
|
||||
|
||||
typedef struct dma_link {
|
||||
struct {
|
||||
uint32_t size : 12; //the size of buf, must be able to be divisible by 4
|
||||
uint32_t length: 12; //in link,
|
||||
uint32_t reversed: 6; //reversed
|
||||
uint32_t eof: 1; //if this dma link is the last one, you shoule set this bit 1.
|
||||
uint32_t owner: 1; //the owner of buf, bit 1 : DMA, bit 0 : CPU.
|
||||
} des;
|
||||
uint8_t *buf; //the pointer of buf
|
||||
struct dma_link *pnext; //point to the next dma linker, if this link is the last one, set it NULL.
|
||||
} dma_link_t;
|
||||
/* Work mode.
|
||||
* sigle: eof_num;
|
||||
* double: SAR_EOF_NUMBER/2;
|
||||
* alter: eof_num;
|
||||
* */
|
||||
#define SAR_SIMPLE_NUM 64
|
||||
#define SAR_DMA_DATA_SIZE(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num) * 2) // 1 adc -> 2 byte
|
||||
#define SAR_EOF_NUMBER(unit, sample_num) ((sample_num) * (unit))
|
||||
#define SAR_MEAS_LIMIT_NUM(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num) / unit)
|
||||
|
||||
static uint8_t link_buf[2][SAR_DMA_DATA_SIZE(2, SAR_SIMPLE_NUM)] = {0};
|
||||
static dma_link_t dma1;
|
||||
static dma_link_t dma2;
|
||||
|
||||
static void dma_linker_init(adc_unit_t adc, bool is_loop)
|
||||
{
|
||||
dma1.des.eof = 0;
|
||||
dma1.des.owner = 1;
|
||||
dma1.pnext = &dma2;
|
||||
dma1.des.size = SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM);
|
||||
dma1.des.length = 0; //For input buffer, this field is no use.
|
||||
dma1.buf = &link_buf[0][0];
|
||||
|
||||
dma2.des.eof = 1;
|
||||
dma2.des.owner = 1;
|
||||
if (is_loop) {
|
||||
dma2.pnext = &dma1;
|
||||
} else {
|
||||
dma2.pnext = NULL;
|
||||
}
|
||||
dma2.des.size = SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM);
|
||||
dma2.des.length = 0; //For input buffer, this field is no use.
|
||||
dma2.buf = &link_buf[1][0];
|
||||
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_APB_SARADC_CLK_EN_M);
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_DMA_CLK_EN_M);
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
|
||||
REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_DMA_RST_M);
|
||||
REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST_M);
|
||||
uint32_t dma_pointer = (uint32_t)&dma1;
|
||||
SET_PERI_REG_BITS(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_ADDR, dma_pointer, 0);
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
REG_SET_BIT(SPI_DMA_INT_ENA_REG(3), SPI_IN_SUC_EOF_INT_ENA);
|
||||
printf("reg addr 0x%08x 0x%08x \n", SPI_DMA_IN_LINK_REG(3), dma_pointer);
|
||||
}
|
||||
|
||||
static void dma_linker_restart(void)
|
||||
{
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_RESTART_M);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_RESTART_M);
|
||||
REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START);
|
||||
REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP);
|
||||
adc_digi_reset();
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
/** SPI DMA INIT CODE END */
|
||||
/*******************************************/
|
||||
|
||||
/**
|
||||
* TEST TOOLS
|
||||
* Note: internal pullup/pulldown is weak energy. if enabled WiFi, it should be need outside pullup/pulldown.
|
||||
*/
|
||||
#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
|
||||
|
||||
static void adc_fake_tie_middle(adc_unit_t adc)
|
||||
{
|
||||
if (adc & ADC_UNIT_1) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_1, adc_list[i]);
|
||||
TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(0, adc_list[i])));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(0, adc_list[i])));
|
||||
}
|
||||
}
|
||||
if (adc & ADC_UNIT_2) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_2, adc_list[i]);
|
||||
TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(1, adc_list[i])));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(1, adc_list[i])));
|
||||
}
|
||||
}
|
||||
vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO.
|
||||
}
|
||||
|
||||
static void adc_fake_tie_high(adc_unit_t adc)
|
||||
{
|
||||
if (adc & ADC_UNIT_1) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_1, adc_list[i]);
|
||||
TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(0, adc_list[i])));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_dis(ADC_GET_IO_NUM(0, adc_list[i])));
|
||||
}
|
||||
}
|
||||
if (adc & ADC_UNIT_2) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_2, adc_list[i]);
|
||||
TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(1, adc_list[i])));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_dis(ADC_GET_IO_NUM(1, adc_list[i])));
|
||||
}
|
||||
}
|
||||
vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO.
|
||||
}
|
||||
|
||||
static void adc_fake_tie_low(adc_unit_t adc)
|
||||
{
|
||||
if (adc & ADC_UNIT_1) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_1, adc_list[i]);
|
||||
TEST_ESP_OK(rtc_gpio_pullup_dis(ADC_GET_IO_NUM(0, adc_list[i])));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(0, adc_list[i])));
|
||||
}
|
||||
}
|
||||
if (adc & ADC_UNIT_2) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_2, adc_list[i]);
|
||||
TEST_ESP_OK(rtc_gpio_pullup_dis(ADC_GET_IO_NUM(1, adc_list[i])));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(1, adc_list[i])));
|
||||
}
|
||||
}
|
||||
vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO.
|
||||
}
|
||||
|
||||
static void adc_io_normal(adc_unit_t adc)
|
||||
{
|
||||
if (adc & ADC_UNIT_1) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_1, adc_list[i]);
|
||||
}
|
||||
}
|
||||
if (adc & ADC_UNIT_2) {
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc_gpio_init(ADC_UNIT_2, adc_list[i]);
|
||||
}
|
||||
}
|
||||
vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO.
|
||||
}
|
||||
|
||||
#define DEBUG_CHECK_ENABLE 0
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
#define DEBUG_CHECK_ERROR 100
|
||||
|
||||
static esp_err_t adc_dma_data_check(adc_unit_t adc, int ideal_level)
|
||||
{
|
||||
#if DEBUG_CHECK_ENABLE
|
||||
int unit_old = 1;
|
||||
int ch_cnt = 0;
|
||||
#endif
|
||||
for (int cnt = 0; cnt < 2; cnt++) {
|
||||
ets_printf("\n[%s] link_buf[%d]: \n", __func__, cnt % 2);
|
||||
for (int i = 0; i < SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM); i++, i++) {
|
||||
uint16_t h = link_buf[cnt % 2][i + 1], l = link_buf[cnt % 2][i];
|
||||
uint16_t temp = (h << 8 | l);
|
||||
adc_digi_output_data_t *data = (adc_digi_output_data_t *)&temp;
|
||||
|
||||
if (adc > ADC_UNIT_2) { //ADC_ENCODE_11BIT
|
||||
#if DEBUG_PRINT_ENABLE
|
||||
if (i % 16 == 0) {
|
||||
ets_printf("\n");
|
||||
}
|
||||
ets_printf("[%d_%d_%04x] ", data->type2.unit, data->type2.channel, data->type2.data);
|
||||
#endif
|
||||
#if DEBUG_CHECK_ENABLE
|
||||
TEST_ASSERT_NOT_EQUAL(unit_old, data->type2.unit);
|
||||
unit_old = data->type2.unit;
|
||||
if (data->type2.channel > ADC_CHANNEL_MAX) {
|
||||
printf("Data invalid [%d]\n", data->type2.channel);
|
||||
continue;
|
||||
}
|
||||
int cur_ch = ((ch_cnt++ / 2) % TEST_ADC_CHANNEL);
|
||||
TEST_ASSERT_EQUAL( data->type2.channel, adc_list[cur_ch] );
|
||||
/*Check data channel unit*/
|
||||
if (ideal_level == 1) {
|
||||
TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0x7FF, data->type2.data );
|
||||
} else if (ideal_level == 0) {
|
||||
TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0, data->type2.data );
|
||||
} else {
|
||||
// middle vol
|
||||
}
|
||||
#endif
|
||||
} else { //ADC_ENCODE_12BIT
|
||||
#if DEBUG_PRINT_ENABLE
|
||||
if (i % 16 == 0) {
|
||||
ets_printf("\n");
|
||||
}
|
||||
ets_printf("[%d_%04x] ", data->type1.channel, data->type1.data);
|
||||
#endif
|
||||
#if DEBUG_CHECK_ENABLE
|
||||
/*Check data channel */
|
||||
if (ideal_level == 1) {
|
||||
if (data->type1.data != 0XFFF) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else if (ideal_level == 0) {
|
||||
if (data->type1.data != 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else {
|
||||
if (data->type1.data == 0 || data->type1.data == 0XFFF) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
int cur_ch = ((i / 2) % TEST_ADC_CHANNEL);
|
||||
if (data->type1.channel != adc_list[cur_ch] ) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
link_buf[cnt % 2][i] = 0;
|
||||
link_buf[cnt % 2][i + 1] = 0;
|
||||
}
|
||||
ets_printf("\n");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc)
|
||||
{
|
||||
ESP_LOGI(TAG, "adc IO fake tie low, test ...");
|
||||
adc_fake_tie_low(adc);
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR);
|
||||
TEST_ESP_OK( adc_digi_start() );
|
||||
while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {};
|
||||
REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR);
|
||||
if ( ESP_OK != adc_dma_data_check(adc, 0)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "adc IO fake tie high, test ...");
|
||||
adc_fake_tie_high(adc);
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR);
|
||||
TEST_ESP_OK( adc_digi_start() );
|
||||
while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {};
|
||||
REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR);
|
||||
if ( ESP_OK != adc_dma_data_check(adc, 1)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "adc IO fake tie middle, test ...");
|
||||
adc_fake_tie_middle(adc);
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
dma_linker_restart();
|
||||
REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR);
|
||||
TEST_ESP_OK( adc_digi_start() );
|
||||
while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {};
|
||||
REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR);
|
||||
if ( ESP_OK != adc_dma_data_check(adc, 2)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
TEST_ESP_OK( adc_digi_stop() );
|
||||
adc_io_normal(adc);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#include "soc/apb_saradc_struct.h"
|
||||
/**
|
||||
* @brief Test the partten table setting. It's easy wrong.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param in_partten_len The length of partten be set.
|
||||
* @param in_partten_len The channel number of the last message.
|
||||
*/
|
||||
static esp_err_t adc_check_patt_table(adc_unit_t adc, uint32_t in_partten_len, adc_channel_t in_last_ch)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
uint8_t index = (in_partten_len - 1) / 4;
|
||||
uint8_t offset = 24 - ((in_partten_len - 1) % 4) * 8;
|
||||
uint32_t temp = 0, len;
|
||||
|
||||
if (adc & ADC_UNIT_1) {
|
||||
len = APB_SARADC.ctrl.sar1_patt_len + 1;
|
||||
temp = APB_SARADC.sar1_patt_tab[index];
|
||||
printf("patt1 len %d\n", len);
|
||||
printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[0]);
|
||||
printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[1]);
|
||||
printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[2]);
|
||||
printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[3]);
|
||||
if (in_partten_len == len) {
|
||||
if (in_last_ch == (((temp >> (offset + 4))) & 0xf)) {
|
||||
ret = ESP_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adc & ADC_UNIT_2) {
|
||||
len = APB_SARADC.ctrl.sar2_patt_len + 1;
|
||||
temp = APB_SARADC.sar2_patt_tab[index];
|
||||
printf("patt2 len %d\n", len);
|
||||
printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[0]);
|
||||
printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[1]);
|
||||
printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[2]);
|
||||
printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[3]);
|
||||
if (in_partten_len == len) {
|
||||
if (in_last_ch == (((temp >> (offset + 4))) & 0xf)) {
|
||||
ret = ESP_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_adc_dig_dma_single_unit(adc_unit_t adc)
|
||||
{
|
||||
ESP_LOGI(TAG, " >> %s << ", __func__);
|
||||
ESP_LOGI(TAG, " >> adc unit: %x << ", adc);
|
||||
|
||||
TEST_ESP_OK( adc_digi_init() );
|
||||
/* arbiter config */
|
||||
adc_arbiter_t arb_cfg = {
|
||||
.mode = ADC_ARB_MODE_FIX,
|
||||
.dig_pri = 0,
|
||||
.pwdet_pri = 2,
|
||||
.rtc_pri = 1,
|
||||
};
|
||||
TEST_ESP_OK( adc_arbiter_config(ADC_UNIT_2, &arb_cfg) ); // If you want use force
|
||||
|
||||
adc_digi_config_t config = {
|
||||
.conv_limit_en = false,
|
||||
.conv_limit_num = 0,
|
||||
.interval = TEST_ADC_TRIGGER_INTERVAL_DEFAULT,
|
||||
.dig_clk.use_apll = 0, // APB clk
|
||||
.dig_clk.div_num = 2, // 80 MHz / 160 = 500 KHz
|
||||
.dig_clk.div_b = 1,
|
||||
.dig_clk.div_a = 1,
|
||||
.dma_eof_num = SAR_EOF_NUMBER((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM),
|
||||
};
|
||||
/* Config pattern table */
|
||||
adc_digi_pattern_table_t adc1_patt[TEST_ADC_CHANNEL] = {0};
|
||||
adc_digi_pattern_table_t adc2_patt[TEST_ADC_CHANNEL] = {0};
|
||||
if (adc & ADC_UNIT_1) {
|
||||
config.adc1_pattern_len = TEST_ADC_CHANNEL;
|
||||
config.adc1_pattern = adc1_patt;
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc1_patt[i].atten = adc_atten[i%ADC_ATTEN_MAX];
|
||||
adc1_patt[i].channel = adc_list[i];
|
||||
adc_gpio_init(ADC_UNIT_1, adc_list[i]);
|
||||
}
|
||||
}
|
||||
if (adc & ADC_UNIT_2) {
|
||||
config.adc2_pattern_len = TEST_ADC_CHANNEL;
|
||||
config.adc2_pattern = adc2_patt;
|
||||
for (int i = 0; i < TEST_ADC_CHANNEL; i++) {
|
||||
adc2_patt[i].atten = adc_atten[i%ADC_ATTEN_MAX];
|
||||
adc2_patt[i].channel = adc_list[i];
|
||||
adc_gpio_init(ADC_UNIT_2, adc_list[i]);
|
||||
}
|
||||
}
|
||||
if (adc == ADC_UNIT_1) {
|
||||
config.conv_mode = ADC_CONV_SINGLE_UNIT_1;
|
||||
config.format = ADC_DIGI_FORMAT_12BIT;
|
||||
} else if (adc == ADC_UNIT_2) {
|
||||
config.conv_mode = ADC_CONV_SINGLE_UNIT_2;
|
||||
config.format = ADC_DIGI_FORMAT_12BIT;
|
||||
} else if (adc == ADC_UNIT_BOTH) {
|
||||
config.conv_mode = ADC_CONV_BOTH_UNIT;
|
||||
config.format = ADC_DIGI_FORMAT_11BIT;
|
||||
} else if (adc == ADC_UNIT_ALTER) {
|
||||
config.conv_mode = ADC_CONV_ALTER_UNIT;
|
||||
config.format = ADC_DIGI_FORMAT_11BIT;
|
||||
}
|
||||
TEST_ESP_OK( adc_digi_controller_config(&config) );
|
||||
|
||||
dma_linker_init(adc, false);
|
||||
TEST_ESP_OK( adc_check_patt_table(adc, TEST_ADC_CHANNEL, adc_list[TEST_ADC_CHANNEL - 1]) );
|
||||
|
||||
TEST_ESP_OK( adc_digi_start() );
|
||||
|
||||
adc_dma_data_multi_st_check(adc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_CASE("ADC DMA single read", "[ADC]")
|
||||
{
|
||||
test_adc_dig_dma_single_unit(ADC_UNIT_BOTH);
|
||||
|
||||
test_adc_dig_dma_single_unit(ADC_UNIT_ALTER);
|
||||
|
||||
test_adc_dig_dma_single_unit(ADC_UNIT_1);
|
||||
|
||||
test_adc_dig_dma_single_unit(ADC_UNIT_2);
|
||||
}
|
||||
|
||||
#endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32)
|
@ -2,7 +2,7 @@
|
||||
#Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_SRCDIRS += param_test
|
||||
COMPONENT_SRCDIRS += param_test touch_sensor_test adc_test
|
||||
COMPONENT_PRIV_INCLUDEDIRS += param_test/include
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
||||
|
4989
components/driver/test/dac_dma_test/test_dac_audio_file.h
Normal file
4989
components/driver/test/dac_dma_test/test_dac_audio_file.h
Normal file
File diff suppressed because it is too large
Load Diff
176
components/driver/test/dac_dma_test/test_esp32.c
Normal file
176
components/driver/test/dac_dma_test/test_esp32.c
Normal file
@ -0,0 +1,176 @@
|
||||
// Copyright 2015-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.
|
||||
|
||||
/*
|
||||
Tests for the dac device driver
|
||||
Hardware connection:
|
||||
- ESP32: GPIO25 <---> GPIO26
|
||||
- ESP32S2: GPIO17 <---> GPIO18
|
||||
*/
|
||||
#include "esp_system.h"
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_dac_audio_file.h"
|
||||
#include "driver/i2s.h"
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP8266, ESP32S2) // This testcase for ESP32
|
||||
|
||||
/*
|
||||
* DAC DMA config.
|
||||
*/
|
||||
|
||||
//enable record sound and save in flash
|
||||
#define RECORD_IN_FLASH_EN (1)
|
||||
//enable replay recorded sound in flash
|
||||
#define REPLAY_FROM_FLASH_EN (1)
|
||||
|
||||
//i2s number
|
||||
#define EXAMPLE_I2S_NUM (0)
|
||||
//i2s sample rate
|
||||
#define EXAMPLE_I2S_SAMPLE_RATE (16000)
|
||||
//i2s data bits
|
||||
#define EXAMPLE_I2S_SAMPLE_BITS (16)
|
||||
//enable display buffer for debug
|
||||
#define EXAMPLE_I2S_BUF_DEBUG (0)
|
||||
//I2S read buffer length
|
||||
#define EXAMPLE_I2S_READ_LEN (16 * 1024)
|
||||
//I2S data format
|
||||
#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT)
|
||||
//I2S channel number
|
||||
#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1))
|
||||
|
||||
//flash record size, for recording 5 seconds' data
|
||||
#define FLASH_RECORD_SIZE (EXAMPLE_I2S_CHANNEL_NUM * EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_SAMPLE_BITS / 8 * 5)
|
||||
#define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE)
|
||||
//sector size of flash
|
||||
#define FLASH_SECTOR_SIZE (0x1000)
|
||||
//flash read / write address
|
||||
#define FLASH_ADDR (0x200000)
|
||||
|
||||
/**
|
||||
* @brief I2S ADC/DAC mode init.
|
||||
*/
|
||||
static void example_i2s_init(void)
|
||||
{
|
||||
int i2s_num = EXAMPLE_I2S_NUM;
|
||||
i2s_config_t i2s_config = {
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
|
||||
.sample_rate = EXAMPLE_I2S_SAMPLE_RATE,
|
||||
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
|
||||
.communication_format = I2S_COMM_FORMAT_PCM,
|
||||
.channel_format = EXAMPLE_I2S_FORMAT,
|
||||
.intr_alloc_flags = 0,
|
||||
.dma_buf_count = 2,
|
||||
.dma_buf_len = 1024,
|
||||
.use_apll = 1,
|
||||
};
|
||||
//install and start i2s driver
|
||||
TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) );
|
||||
//init DAC pad
|
||||
TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN) );
|
||||
}
|
||||
|
||||
static void example_i2s_deinit(void)
|
||||
{
|
||||
TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set i2s clock for example audio file
|
||||
*/
|
||||
static void example_set_file_play_mode(void)
|
||||
{
|
||||
TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, 16000, EXAMPLE_I2S_SAMPLE_BITS, 1) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scale data to 16bit/32bit for I2S DMA output.
|
||||
* DAC can only output 8bit data value.
|
||||
* I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data.
|
||||
*/
|
||||
static int example_i2s_dac_data_scale(uint8_t *d_buff, uint8_t *s_buff, uint32_t len)
|
||||
{
|
||||
uint32_t j = 0;
|
||||
#if (EXAMPLE_I2S_SAMPLE_BITS == 16)
|
||||
for (int i = 0; i < len; i++) {
|
||||
d_buff[j++] = 0;
|
||||
d_buff[j++] = s_buff[i];
|
||||
}
|
||||
return (len * 2);
|
||||
#else
|
||||
for (int i = 0; i < len; i++) {
|
||||
d_buff[j++] = 0;
|
||||
d_buff[j++] = 0;
|
||||
d_buff[j++] = 0;
|
||||
d_buff[j++] = s_buff[i];
|
||||
}
|
||||
return (len * 4);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @brief debug buffer data
|
||||
*/
|
||||
static void example_disp_buf(uint8_t *buf, int length)
|
||||
{
|
||||
printf("======\n");
|
||||
for (int i = 0; i < length; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
if ((i + 1) % 8 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("======\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset i2s clock and mode
|
||||
*/
|
||||
static void example_reset_play_mode(void)
|
||||
{
|
||||
TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_SAMPLE_BITS, EXAMPLE_I2S_CHANNEL_NUM) );
|
||||
}
|
||||
|
||||
TEST_CASE("DAC DMA output", "[dac]")
|
||||
{
|
||||
example_i2s_init();
|
||||
|
||||
size_t bytes_written;
|
||||
int i2s_read_len = EXAMPLE_I2S_READ_LEN;
|
||||
uint8_t *i2s_write_buff = (uint8_t *) calloc(i2s_read_len, sizeof(char));
|
||||
printf("Playing file example: \n");
|
||||
int offset = 0;
|
||||
int tot_size = sizeof(audio_table);
|
||||
example_set_file_play_mode();
|
||||
while (offset < tot_size) {
|
||||
int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset);
|
||||
int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t *)(audio_table + offset), play_len);
|
||||
i2s_write(EXAMPLE_I2S_NUM, i2s_write_buff, i2s_wr_len, &bytes_written, portMAX_DELAY);
|
||||
offset += play_len;
|
||||
example_disp_buf((uint8_t *) i2s_write_buff, 32);
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
example_reset_play_mode();
|
||||
free(i2s_write_buff);
|
||||
|
||||
example_i2s_deinit();
|
||||
}
|
||||
|
||||
#endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32S2)
|
@ -1,330 +0,0 @@
|
||||
/*
|
||||
Tests for the touch sensor device driver
|
||||
*/
|
||||
#include "esp_system.h"
|
||||
#include "driver/touch_pad.h"
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/rtc_io_struct.h"
|
||||
|
||||
static const char *TAG = "test_touch";
|
||||
|
||||
#define TOUCH_READ_INVALID_VAL (0)
|
||||
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
|
||||
|
||||
#define TOUCH_REG_BASE_TEST() ({ \
|
||||
TEST_ASSERT_EQUAL_UINT32(RTC_CNTL_BROWN_OUT_REG, &RTCCNTL.brown_out.val); \
|
||||
TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \
|
||||
TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \
|
||||
})
|
||||
|
||||
#define TOUCH_READ_ERROR (50)
|
||||
#define TEST_TOUCH_COUNT_NUM (10)
|
||||
#define TEST_TOUCH_CHANNEL (9)
|
||||
static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = {
|
||||
TOUCH_PAD_NUM0,
|
||||
// TOUCH_PAD_NUM1 is GPIO0, for download.
|
||||
TOUCH_PAD_NUM2,
|
||||
TOUCH_PAD_NUM3,
|
||||
TOUCH_PAD_NUM4,
|
||||
TOUCH_PAD_NUM5,
|
||||
TOUCH_PAD_NUM6,
|
||||
TOUCH_PAD_NUM7,
|
||||
TOUCH_PAD_NUM8,
|
||||
TOUCH_PAD_NUM9,
|
||||
};
|
||||
|
||||
static void printf_touch_hw_read(const char *str)
|
||||
{
|
||||
uint16_t touch_value;
|
||||
printf("[%s] ", str);
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
while (!touch_pad_meas_is_done()) ;
|
||||
touch_pad_read_raw_data(touch_list[i], &touch_value);
|
||||
printf("[%d]%d ", touch_list[i], touch_value);
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the slope to get larger value from touch sensor.
|
||||
*/
|
||||
static void test_push_fake(touch_pad_t pad_num)
|
||||
{
|
||||
touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_2, TOUCH_PAD_TIE_OPT_DEFAULT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the slope to get larger value from touch sensor.
|
||||
*/
|
||||
static void test_release_fake(touch_pad_t pad_num)
|
||||
{
|
||||
touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT);
|
||||
}
|
||||
|
||||
static esp_err_t test_touch_sw_read(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s", __func__);
|
||||
uint16_t touch_value;
|
||||
|
||||
TEST_ESP_OK( touch_pad_init() );
|
||||
TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) );
|
||||
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
|
||||
}
|
||||
|
||||
// Start task to read values sensed by pads
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) );
|
||||
printf("T%d:[%4d] ", touch_list[i], touch_value);
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
TEST_ESP_OK( touch_pad_deinit() );
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t test_touch_timer_read(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s", __func__);
|
||||
uint16_t touch_value[TEST_TOUCH_CHANNEL], touch_temp[TEST_TOUCH_CHANNEL];
|
||||
int t_cnt = TEST_TOUCH_COUNT_NUM;
|
||||
|
||||
TEST_ESP_OK( touch_pad_init() );
|
||||
TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
|
||||
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
|
||||
}
|
||||
// Start task to read values sensed by pads
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value[i]) );
|
||||
printf("T%d:[%4d] ", touch_list[i], touch_value[i]);
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]);
|
||||
}
|
||||
while (t_cnt--) {
|
||||
// Start task to read values sensed by pads
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_temp[i]) );
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]);
|
||||
TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]);
|
||||
}
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
TEST_ESP_OK( touch_pad_deinit() );
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t test_touch_filtered_read(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s", __func__);
|
||||
uint16_t touch_value, touch_temp;
|
||||
int t_cnt = TEST_TOUCH_COUNT_NUM;
|
||||
|
||||
TEST_ESP_OK( touch_pad_init() );
|
||||
TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
|
||||
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
|
||||
}
|
||||
// Initialize and start a software filter to detect slight change of capacitance.
|
||||
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
while (t_cnt--) {
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) );
|
||||
TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) );
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
|
||||
TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_temp) );
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp);
|
||||
TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value);
|
||||
printf("T%d:[%4d] ", touch_list[i], touch_value);
|
||||
}
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
TEST_ESP_OK( touch_pad_deinit() );
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// test the basic configuration function with right parameters and error parameters
|
||||
TEST_CASE("Touch Sensor all channel read test", "[touch]")
|
||||
{
|
||||
TOUCH_REG_BASE_TEST();
|
||||
TEST_ESP_OK( test_touch_sw_read() );
|
||||
TEST_ESP_OK( test_touch_timer_read() );
|
||||
TEST_ESP_OK( test_touch_filtered_read() );
|
||||
}
|
||||
|
||||
static int test_touch_parameter(touch_pad_t pad_num, int meas_time, int slp_time, int vol_h, int vol_l, int vol_a, int slope)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s", __func__);
|
||||
uint16_t touch_value;
|
||||
TEST_ESP_OK( touch_pad_init() );
|
||||
TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
|
||||
TEST_ESP_OK( touch_pad_config(pad_num, TOUCH_READ_INVALID_VAL) );
|
||||
|
||||
touch_pad_set_meas_time(slp_time, meas_time);
|
||||
touch_pad_set_voltage(vol_h, vol_l, vol_a);
|
||||
touch_pad_set_cnt_mode(pad_num, slope, TOUCH_PAD_TIE_OPT_DEFAULT);
|
||||
|
||||
// Initialize and start a software filter to detect slight change of capacitance.
|
||||
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
|
||||
// Start task to read values sensed by pads
|
||||
TEST_ESP_OK( touch_pad_read(pad_num, &touch_value) );
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
|
||||
printf("T%d:[%4d] ", pad_num, touch_value);
|
||||
TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) );
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
|
||||
printf("T%d:[%4d] ", pad_num, touch_value);
|
||||
TEST_ESP_OK( touch_pad_read_filtered(pad_num, &touch_value) );
|
||||
TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
|
||||
printf("T%d:[%4d] \n", pad_num, touch_value);
|
||||
|
||||
TEST_ESP_OK( touch_pad_deinit() );
|
||||
|
||||
return touch_value;
|
||||
}
|
||||
|
||||
TEST_CASE("Touch Sensor parameters test", "[touch]")
|
||||
{
|
||||
int touch_val[5] = {0};
|
||||
|
||||
ESP_LOGI(TAG, "Charge / incharge voltage level test");
|
||||
touch_val[0] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
|
||||
TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V,
|
||||
TOUCH_PAD_SLOPE_DEFAULT);
|
||||
touch_val[1] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
|
||||
TOUCH_HVOLT_2V5, TOUCH_LVOLT_0V6, TOUCH_HVOLT_ATTEN_1V,
|
||||
TOUCH_PAD_SLOPE_DEFAULT);
|
||||
touch_val[2] = test_touch_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
|
||||
TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5,
|
||||
TOUCH_PAD_SLOPE_DEFAULT);
|
||||
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]);
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]);
|
||||
|
||||
ESP_LOGI(TAG, "Measure time / sleep time test");
|
||||
touch_val[0] = test_touch_parameter(touch_list[0], 0xff, 0xa,
|
||||
TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT);
|
||||
touch_val[1] = test_touch_parameter(touch_list[0], 0x1ff, 0xf,
|
||||
TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT);
|
||||
touch_val[2] = test_touch_parameter(touch_list[0], 0x2fff, 0x1f,
|
||||
TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT);
|
||||
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]);
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]);
|
||||
|
||||
ESP_LOGI(TAG, "Charge / incharge slope level test");
|
||||
touch_val[0] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
|
||||
TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 1);
|
||||
touch_val[1] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
|
||||
TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 3);
|
||||
touch_val[2] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
|
||||
TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 7);
|
||||
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]);
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]);
|
||||
}
|
||||
|
||||
static bool s_pad_activated[TOUCH_PAD_MAX];
|
||||
|
||||
static void test_touch_intr_cb(void *arg)
|
||||
{
|
||||
uint32_t pad_intr = touch_pad_get_status();
|
||||
ets_printf("T%x ", pad_intr);
|
||||
//clear interrupt
|
||||
touch_pad_clear_status();
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
if ((pad_intr >> touch_list[i]) & 0x1) {
|
||||
s_pad_activated[touch_list[i]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t test_touch_interrupt(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s", __func__);
|
||||
uint16_t touch_value;
|
||||
|
||||
TEST_ESP_OK( touch_pad_init() );
|
||||
TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
|
||||
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
|
||||
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
|
||||
}
|
||||
// Initialize and start a software filter to detect slight change of capacitance.
|
||||
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
//read filtered value
|
||||
TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_value) );
|
||||
ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", touch_list[i], touch_value);
|
||||
//set interrupt threshold.
|
||||
TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * 2 / 3) );
|
||||
}
|
||||
|
||||
// Register touch interrupt ISR
|
||||
TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL) );
|
||||
TEST_ESP_OK( touch_pad_clear_status() );
|
||||
TEST_ESP_OK( touch_pad_intr_enable() );
|
||||
|
||||
int test_cnt = TEST_TOUCH_COUNT_NUM;
|
||||
while (test_cnt--) {
|
||||
ESP_LOGI(TAG, "touch push");
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
test_push_fake(touch_list[i]);
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
printf_touch_hw_read("push");
|
||||
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
if (s_pad_activated[touch_list[i]] == false) {
|
||||
ESP_LOGE(TAG, "touch%d not active", touch_list[i]);
|
||||
TEST_FAIL();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
s_pad_activated[touch_list[i]] = 0;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "touch release");
|
||||
for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
|
||||
test_release_fake(touch_list[i]);
|
||||
}
|
||||
printf_touch_hw_read("release");
|
||||
}
|
||||
|
||||
TEST_ESP_OK( touch_pad_deinit() );
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
TEST_CASE("Touch Sensor interrupt test", "[touch]")
|
||||
{
|
||||
TEST_ESP_OK( test_touch_interrupt() );
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,186 +0,0 @@
|
||||
#include "esp_err.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp32s2/rom/uart.h"
|
||||
|
||||
#define ROM_UART_DRIVER_ENABLE 0
|
||||
|
||||
#if ROM_UART_DRIVER_ENABLE
|
||||
static uint8_t scope_uart_num = 0;
|
||||
static int8_t uart_used = 0;
|
||||
#else
|
||||
static uint8_t scope_uart_num = 255;
|
||||
static int8_t uart_used = -1;
|
||||
#endif
|
||||
static int scope_tx_io_num = 0;
|
||||
static int scope_rx_io_num = 0;
|
||||
static int scope_debug_baud_rate = 256000;
|
||||
static unsigned char datascope_output_buffer[42] = {0}; // Data buff.
|
||||
|
||||
/**
|
||||
* @brief Translate a float data to four unsigned char data for uart TX.
|
||||
* @param target target float data address.
|
||||
* @param buf save translated data.
|
||||
* @param offset the start position in buf.
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
static void Float2Byte(float *target, unsigned char *buf, unsigned char offset)
|
||||
{
|
||||
unsigned char *point;
|
||||
point = (unsigned char*)target; //Get the address of float.
|
||||
buf[offset] = point[0];
|
||||
buf[offset+1] = point[1];
|
||||
buf[offset+2] = point[2];
|
||||
buf[offset+3] = point[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add data to channal buff.
|
||||
* @param Data target data.
|
||||
* @param Channel target channel (1 - 10).
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
static void datascope_get_channel_data(float data, unsigned char channel)
|
||||
{
|
||||
if ( (channel > 10) || (channel == 0) ) {
|
||||
return;
|
||||
} else {
|
||||
switch (channel) {
|
||||
case 1: Float2Byte(&data,datascope_output_buffer,1); break;
|
||||
case 2: Float2Byte(&data,datascope_output_buffer,5); break;
|
||||
case 3: Float2Byte(&data,datascope_output_buffer,9); break;
|
||||
case 4: Float2Byte(&data,datascope_output_buffer,13); break;
|
||||
case 5: Float2Byte(&data,datascope_output_buffer,17); break;
|
||||
case 6: Float2Byte(&data,datascope_output_buffer,21); break;
|
||||
case 7: Float2Byte(&data,datascope_output_buffer,25); break;
|
||||
case 8: Float2Byte(&data,datascope_output_buffer,29); break;
|
||||
case 9: Float2Byte(&data,datascope_output_buffer,33); break;
|
||||
case 10: Float2Byte(&data,datascope_output_buffer,37); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transform float data to DataScopeV1.0 data format.
|
||||
* @param channel_num the number of channel that wait to be translated.
|
||||
* @return
|
||||
* - The number of the UART TX data.
|
||||
*/
|
||||
static unsigned char datascope_data_generate(unsigned char channel_num)
|
||||
{
|
||||
if ( (channel_num > 10) || (channel_num == 0) ) {
|
||||
return 0;
|
||||
} else {
|
||||
datascope_output_buffer[0] = '$'; //frame header
|
||||
switch(channel_num) {
|
||||
case 1: datascope_output_buffer[5] = 5; return 6; break;
|
||||
case 2: datascope_output_buffer[9] = 9; return 10; break;
|
||||
case 3: datascope_output_buffer[13] = 13; return 14; break;
|
||||
case 4: datascope_output_buffer[17] = 17; return 18; break;
|
||||
case 5: datascope_output_buffer[21] = 21; return 22; break;
|
||||
case 6: datascope_output_buffer[25] = 25; return 26; break;
|
||||
case 7: datascope_output_buffer[29] = 29; return 30; break;
|
||||
case 8: datascope_output_buffer[33] = 33; return 34; break;
|
||||
case 9: datascope_output_buffer[37] = 37; return 38; break;
|
||||
case 10: datascope_output_buffer[41] = 41; return 42; break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send touch sensor data to HMI in PC via UART.
|
||||
* @param uart_num Choose uart port (0, 1, 2).
|
||||
* @param data The addr of the touch sensor data.
|
||||
* @param channel_num The number of channel that wait to be translated.
|
||||
* @return
|
||||
* - ESP_FAIL Error
|
||||
* - The number of the UART TX data.
|
||||
*/
|
||||
int test_tp_print_to_scope(float *data, unsigned char channel_num)
|
||||
{
|
||||
uint8_t uart_num = scope_uart_num;
|
||||
|
||||
if (uart_num >= UART_NUM_MAX) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if ( (channel_num > 10) || (channel_num == 0) || (NULL == data) ) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
for(uint8_t i = 0 ; i < channel_num; i++) {
|
||||
datascope_get_channel_data(data[i] , i+1); // write data x into channel 1~10.
|
||||
}
|
||||
unsigned char out_len = datascope_data_generate(channel_num); // Generate n number data.
|
||||
unsigned char *out_data = datascope_output_buffer;
|
||||
// Init uart.
|
||||
if(uart_num != uart_used) {
|
||||
return 0;
|
||||
} else {
|
||||
#if ROM_UART_DRIVER_ENABLE
|
||||
uart_tx_wait_idle(uart_num); // Default print uart mumber is 0.
|
||||
for(int i=0; i<out_len; i++) {
|
||||
uart_tx_one_char(out_data[i]);
|
||||
}
|
||||
return out_len;
|
||||
#else
|
||||
uart_wait_tx_done(uart_num, portMAX_DELAY);
|
||||
return uart_write_bytes(uart_num, (const char *)out_data, out_len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable scope debug function. Print the touch sensor raw data to "DataScope" tool via UART.
|
||||
* "DataScope" tool is touch sensor tune tool. User can monitor the data of each touch channel,
|
||||
* evaluate the touch system's touch performance (sensitivity, SNR, stability, channel coupling)
|
||||
* and determine the threshold for each channel.
|
||||
*
|
||||
* @attention 1. Choose a UART port that will only be used for scope debug.
|
||||
* @attention 2. Use this feature only during the testing phase.
|
||||
* @attention 3. "DataScope" tool can be downloaded from Espressif's official website.
|
||||
*
|
||||
* @param uart_num The uart port to send touch sensor raw data.
|
||||
* @param tx_io_num set UART TXD IO.
|
||||
* @param rx_io_num set UART RXD IO.
|
||||
* @param baud_rate set debug port baud rate.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - ESP_FAIL: the param uart_num is error
|
||||
*/
|
||||
esp_err_t test_tp_scope_debug_init(uint8_t uart_num, int tx_io_num, int rx_io_num, int baud_rate)
|
||||
{
|
||||
#if ROM_UART_DRIVER_ENABLE
|
||||
uart_tx_wait_idle(0); // Default print uart mumber is 0.
|
||||
if(uart_num != 0) {
|
||||
uart_tx_switch(uart_num);
|
||||
// uart_div_modify(uart_num, baud_rate); //DivLatchValue : (clock << 4)/baudrate.
|
||||
}
|
||||
#else
|
||||
if(uart_used == uart_num) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (uart_num >= UART_NUM_MAX) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
scope_uart_num = uart_num;
|
||||
scope_tx_io_num = tx_io_num;
|
||||
scope_rx_io_num = rx_io_num;
|
||||
scope_debug_baud_rate = baud_rate;
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = scope_debug_baud_rate,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
};
|
||||
uart_param_config(uart_num, &uart_config);
|
||||
// Set UART pins using UART0 default pins i.e. no changes
|
||||
uart_set_pin(uart_num, scope_tx_io_num, scope_rx_io_num,
|
||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
uart_driver_install(uart_num, 1024, 2048, 0, NULL, 0);
|
||||
uart_used = uart_num;
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
int test_tp_print_to_scope(float *data, unsigned char channel_num);
|
||||
esp_err_t test_tp_scope_debug_init(uint8_t uart_num, int tx_io_num, int rx_io_num, int baud_rate);
|
@ -12,10 +12,23 @@
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
|
||||
|
||||
static const char* TAG = "test_adc2";
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define ADC_TEST_WIDTH ADC_WIDTH_BIT_12
|
||||
#define ADC_TEST_RESOLUTION (4096)
|
||||
#define ADC_TEST_DAC_RANGE (256)
|
||||
#define ADC_TEST_CH1 ADC2_CHANNEL_8
|
||||
#define ADC_TEST_CH2 ADC2_CHANNEL_9
|
||||
#define ADC_TEST_ERROR (600)
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
#define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width
|
||||
#define ADC_TEST_RESOLUTION (8192)
|
||||
#define ADC_TEST_DAC_RANGE (210)
|
||||
#define ADC_TEST_CH1 ADC2_CHANNEL_6
|
||||
#define ADC_TEST_CH2 ADC2_CHANNEL_7
|
||||
#define ADC_TEST_ERROR (1500)
|
||||
#endif
|
||||
#define DEFAULT_SSID "TEST_SSID"
|
||||
#define DEFAULT_PWD "TEST_PASS"
|
||||
|
||||
@ -84,9 +97,8 @@ TEST_CASE("adc2 work with wifi","[adc]")
|
||||
TEST_ESP_OK( dac_output_enable( DAC_CHANNEL_2 ));
|
||||
TEST_ESP_OK( dac_output_voltage( DAC_CHANNEL_1, 30 ));
|
||||
TEST_ESP_OK( dac_output_voltage( DAC_CHANNEL_2, 60 ));
|
||||
TEST_ESP_OK( adc2_config_channel_atten( ADC2_CHANNEL_8, ADC_ATTEN_0db ));
|
||||
TEST_ESP_OK( adc2_config_channel_atten( ADC2_CHANNEL_9, ADC_ATTEN_0db ));
|
||||
|
||||
TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CH1, ADC_ATTEN_0db ));
|
||||
TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CH2, ADC_ATTEN_0db ));
|
||||
//init wifi
|
||||
printf("nvs init\n");
|
||||
esp_err_t r = nvs_flash_init();
|
||||
@ -112,23 +124,26 @@ TEST_CASE("adc2 work with wifi","[adc]")
|
||||
TEST_ESP_OK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
|
||||
|
||||
//test read value
|
||||
TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw ));
|
||||
target_value = 30*4096*3/256; //3 = 3.3/1.1
|
||||
TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw ));
|
||||
target_value = 30*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE; //3 = 3.3/1.1
|
||||
printf("dac set: %d, adc read: %d (target_value: %d)\n", 30, read_raw, target_value );
|
||||
TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw );
|
||||
TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw ));
|
||||
target_value = 60*4096*3/256;
|
||||
TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw );
|
||||
TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw ));
|
||||
target_value = 60*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE;
|
||||
printf("dac set: %d, adc read: %d (target_value: %d)\n", 60, read_raw, target_value );
|
||||
TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw );
|
||||
TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw );
|
||||
|
||||
//now start wifi
|
||||
printf("wifi start...\n");
|
||||
TEST_ESP_OK(esp_wifi_start());
|
||||
|
||||
//test reading during wifi on
|
||||
TEST_ASSERT_EQUAL( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw ), ESP_ERR_TIMEOUT );
|
||||
TEST_ASSERT_EQUAL( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw ), ESP_ERR_TIMEOUT );
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw ), ESP_ERR_TIMEOUT );
|
||||
TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw ), ESP_ERR_TIMEOUT );
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw ), ESP_OK );
|
||||
TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw ), ESP_OK );
|
||||
#endif
|
||||
//wifi stop again
|
||||
printf("wifi stop...\n");
|
||||
TEST_ESP_OK( esp_wifi_stop() );
|
||||
@ -137,18 +152,16 @@ TEST_CASE("adc2 work with wifi","[adc]")
|
||||
nvs_flash_deinit();
|
||||
|
||||
//test read value
|
||||
TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw ));
|
||||
target_value = 30*4096*3/256; //3 = 3.3/1.1
|
||||
TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw ));
|
||||
target_value = 30*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE; //3 = 3.3/1.1
|
||||
printf("dac set: %d, adc read: %d (target_value: %d)\n", 30, read_raw, target_value );
|
||||
TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw );
|
||||
TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw ));
|
||||
target_value = 60*4096*3/256;
|
||||
TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw );
|
||||
TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw ));
|
||||
target_value = 60*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE;
|
||||
printf("dac set: %d, adc read: %d (target_value: %d)\n", 60, read_raw, target_value );
|
||||
TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw );
|
||||
TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw );
|
||||
|
||||
printf("test passed...\n");
|
||||
|
||||
TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop.");
|
||||
}
|
||||
|
||||
#endif
|
266
components/driver/test/test_adc_common.c
Normal file
266
components/driver/test/test_adc_common.c
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
Tests for the adc device driver
|
||||
*/
|
||||
#include "esp_system.h"
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
#include "soc/adc_periph.h"
|
||||
|
||||
static const char *TAG = "test_adc";
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define ADC1_TEST_WIDTH ADC_WIDTH_BIT_12
|
||||
#define ADC2_TEST_WIDTH ADC_WIDTH_BIT_12
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
#define ADC1_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width
|
||||
#define ADC2_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width
|
||||
#endif
|
||||
|
||||
#define ADC1_TEST_ATTEN ADC_ATTEN_DB_11
|
||||
#define ADC2_TEST_ATTEN ADC_ATTEN_DB_11
|
||||
|
||||
#define ADC1_TEST_CHANNEL_NUM 8
|
||||
#define ADC2_TEST_CHANNEL_NUM 6
|
||||
|
||||
static const int adc1_ch[ADC1_TEST_CHANNEL_NUM] = {
|
||||
ADC1_CHANNEL_0,
|
||||
ADC1_CHANNEL_1,
|
||||
ADC1_CHANNEL_2,
|
||||
ADC1_CHANNEL_3,
|
||||
ADC1_CHANNEL_4,
|
||||
ADC1_CHANNEL_5,
|
||||
ADC1_CHANNEL_6,
|
||||
ADC1_CHANNEL_7,
|
||||
};
|
||||
|
||||
static const int adc2_ch[ADC2_TEST_CHANNEL_NUM] = {
|
||||
ADC2_CHANNEL_0,
|
||||
ADC2_CHANNEL_1,
|
||||
ADC2_CHANNEL_2,
|
||||
ADC2_CHANNEL_3,
|
||||
ADC2_CHANNEL_4,
|
||||
ADC2_CHANNEL_5,
|
||||
};
|
||||
|
||||
#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
|
||||
|
||||
static void adc_fake_tie_middle(adc_unit_t adc_unit, adc_channel_t channel)
|
||||
{
|
||||
gpio_num_t gpio_num = 0;
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
gpio_num = ADC_GET_IO_NUM(0, channel);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
gpio_num = ADC_GET_IO_NUM(1, channel);
|
||||
}
|
||||
TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num));
|
||||
TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_PULLDOWN));
|
||||
}
|
||||
|
||||
static void adc_fake_tie_high(adc_unit_t adc_unit, adc_channel_t channel)
|
||||
{
|
||||
gpio_num_t gpio_num = 0;
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
gpio_num = ADC_GET_IO_NUM(0, channel);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
gpio_num = ADC_GET_IO_NUM(1, channel);
|
||||
}
|
||||
TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num));
|
||||
TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_ONLY));
|
||||
}
|
||||
|
||||
static void adc_fake_tie_low(adc_unit_t adc_unit, adc_channel_t channel)
|
||||
{
|
||||
gpio_num_t gpio_num = 0;
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
gpio_num = ADC_GET_IO_NUM(0, channel);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
gpio_num = ADC_GET_IO_NUM(1, channel);
|
||||
}
|
||||
TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num));
|
||||
TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLDOWN_ONLY));
|
||||
}
|
||||
|
||||
static void adc_io_normal(adc_unit_t adc_unit, adc_channel_t channel)
|
||||
{
|
||||
gpio_num_t gpio_num = 0;
|
||||
if (adc_unit & ADC_UNIT_1) {
|
||||
gpio_num = ADC_GET_IO_NUM(0, channel);
|
||||
}
|
||||
if (adc_unit & ADC_UNIT_2) {
|
||||
gpio_num = ADC_GET_IO_NUM(1, channel);
|
||||
}
|
||||
TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num));
|
||||
TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num));
|
||||
TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_FLOATING));
|
||||
}
|
||||
|
||||
TEST_CASE("ADC1 rtc read", "[adc1]")
|
||||
{
|
||||
int adc1_val[ADC1_TEST_CHANNEL_NUM] = {0};
|
||||
|
||||
/* adc1 Configure */
|
||||
adc1_config_width(ADC1_TEST_WIDTH);
|
||||
ESP_LOGI(TAG, "ADC1 [CH - GPIO]:");
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
TEST_ESP_OK( adc1_config_channel_atten(adc1_ch[i], ADC1_TEST_ATTEN) );
|
||||
ESP_LOGI(TAG, "[CH%d - IO%d]:", adc1_ch[i], ADC_GET_IO_NUM(0, adc1_ch[i]));
|
||||
}
|
||||
printf("ADC tie normal read: ");
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
|
||||
/* adc Read */
|
||||
printf("ADC1: ");
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]);
|
||||
printf("CH%d-%d ", adc1_ch[i], adc1_val[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* tie high */
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc_fake_tie_high(ADC_UNIT_1, adc1_ch[i]);
|
||||
}
|
||||
printf("ADC tie high read: ");
|
||||
vTaskDelay(50 / portTICK_RATE_MS);
|
||||
/* adc Read */
|
||||
printf("ADC1: ");
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]);
|
||||
printf("CH%d-%d ", adc1_ch[i], adc1_val[i]);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
TEST_ASSERT_EQUAL( adc1_val[i], 0x1fff );
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* tie low */
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc_fake_tie_low(ADC_UNIT_1, adc1_ch[i]);
|
||||
}
|
||||
printf("ADC tie low read: ");
|
||||
vTaskDelay(50 / portTICK_RATE_MS);
|
||||
/* adc Read */
|
||||
printf("ADC1: ");
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]);
|
||||
printf("CH%d-%d ", adc1_ch[i], adc1_val[i]);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
TEST_ASSERT_INT_WITHIN( 100, 0, adc1_val[i] );
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* tie midedle */
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc_fake_tie_middle(ADC_UNIT_1, adc1_ch[i]);
|
||||
}
|
||||
printf("ADC tie mid read: ");
|
||||
vTaskDelay(50 / portTICK_RATE_MS);
|
||||
/* adc Read */
|
||||
printf("ADC1: ");
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]);
|
||||
printf("CH%d-%d ", adc1_ch[i], adc1_val[i]);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
TEST_ASSERT_NOT_EQUAL( adc1_val[i], 0 );
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc_io_normal(ADC_UNIT_1, adc1_ch[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ADC2 rtc read", "[adc2]")
|
||||
{
|
||||
int adc2_val[ADC2_TEST_CHANNEL_NUM] = {0};
|
||||
|
||||
/* adc2 Configure */
|
||||
ESP_LOGI(TAG, "ADC2 [CH - GPIO]:");
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
TEST_ESP_OK( adc2_config_channel_atten(adc2_ch[i], ADC2_TEST_ATTEN) );
|
||||
ESP_LOGI(TAG, "[CH%d - IO%d]:", adc2_ch[i], ADC_GET_IO_NUM(1, adc2_ch[i]));
|
||||
}
|
||||
printf("ADC float read: ");
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
|
||||
/* adc Read */
|
||||
printf("ADC2: ");
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) );
|
||||
printf("CH%d-%d ", adc2_ch[i], adc2_val[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* tie high */
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
adc_fake_tie_high(ADC_UNIT_2, adc2_ch[i]);
|
||||
}
|
||||
printf("ADC tie high read: ");
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
/* adc Read */
|
||||
printf("ADC2: ");
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) );
|
||||
printf("CH%d-%d ", adc2_ch[i], adc2_val[i]);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
TEST_ASSERT_EQUAL( adc2_val[i], 0x1fff );
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* tie low */
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
adc_fake_tie_low(ADC_UNIT_2, adc2_ch[i]);
|
||||
}
|
||||
printf("ADC tie low read: ");
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
/* adc Read */
|
||||
printf("ADC2: ");
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) );
|
||||
printf("CH%d-%d ", adc2_ch[i], adc2_val[i]);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
TEST_ASSERT_INT_WITHIN( 100, 0, adc2_val[i] );
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* tie midedle */
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
adc_fake_tie_middle(ADC_UNIT_2, adc2_ch[i]);
|
||||
}
|
||||
printf("ADC tie middle read: ");
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
/* adc Read */
|
||||
printf("ADC2: ");
|
||||
for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) {
|
||||
TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) );
|
||||
printf("CH%d-%d ", adc2_ch[i], adc2_val[i]);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
TEST_ASSERT_NOT_EQUAL( 0, adc2_val[i] );
|
||||
TEST_ASSERT_NOT_EQUAL( 0x1fff, adc2_val[i] );
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) {
|
||||
adc_io_normal(ADC_UNIT_1, adc1_ch[i]);
|
||||
}
|
||||
}
|
120
components/driver/test/test_dac.c
Normal file
120
components/driver/test/test_dac.c
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
Tests for the dac device driver
|
||||
*/
|
||||
#include "esp_system.h"
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "test_utils.h"
|
||||
#include "driver/i2s.h"
|
||||
|
||||
static const char *TAG = "test_dac";
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define ADC_TEST_WIDTH ADC_WIDTH_BIT_12
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
#define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width
|
||||
#endif
|
||||
#define ADC_TEST_ATTEN ADC_ATTEN_DB_11
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_8 // GPIO25
|
||||
#define DAC_TEST_CHANNEL_NUM DAC_CHANNEL_1 // GPIO25
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_6 // GPIO17
|
||||
#define DAC_TEST_CHANNEL_NUM DAC_CHANNEL_1 // GPIO17
|
||||
#endif
|
||||
|
||||
#define DAC_OUT_MAX (200)
|
||||
#define DAC_OUT_TIMES (10)
|
||||
#define DAC_OUT_STEP (DAC_OUT_MAX / DAC_OUT_TIMES)
|
||||
|
||||
#define DAC_TEST_TIMES (100)
|
||||
|
||||
TEST_CASE("DAC output (RTC) check by adc", "[dac]")
|
||||
{
|
||||
gpio_num_t adc_gpio_num, dac_gpio_num;
|
||||
|
||||
TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) );
|
||||
TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) );
|
||||
|
||||
printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
|
||||
DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num );
|
||||
|
||||
TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) );
|
||||
|
||||
//be sure to do the init before using adc2.
|
||||
printf("adc2_init...\n");
|
||||
TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN ) );
|
||||
|
||||
vTaskDelay(2 * portTICK_RATE_MS);
|
||||
|
||||
printf("start conversion.\n");
|
||||
int output_data = 0;
|
||||
int read_raw = 0, read_old = 0;
|
||||
for (int i = 0; i < DAC_OUT_TIMES; i++) {
|
||||
TEST_ESP_OK( dac_output_voltage( DAC_TEST_CHANNEL_NUM, output_data ) );
|
||||
output_data += DAC_OUT_STEP;
|
||||
vTaskDelay(2 * portTICK_RATE_MS);
|
||||
TEST_ESP_OK( adc2_get_raw( ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw) );
|
||||
ESP_LOGI(TAG, "DAC%d - ADC%d", output_data, read_raw);
|
||||
if (read_old != 0) {
|
||||
TEST_ASSERT_GREATER_THAN(read_old, read_raw);
|
||||
}
|
||||
read_old = read_raw;
|
||||
}
|
||||
TEST_ESP_OK( dac_output_disable( DAC_TEST_CHANNEL_NUM ) );
|
||||
}
|
||||
|
||||
TEST_CASE("DAC cw generator output (RTC) check by adc", "[dac]")
|
||||
{
|
||||
gpio_num_t adc_gpio_num, dac_gpio_num;
|
||||
|
||||
TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) );
|
||||
TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) );
|
||||
|
||||
printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
|
||||
DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num );
|
||||
|
||||
dac_cw_config_t cw = {
|
||||
.en_ch = DAC_TEST_CHANNEL_NUM,
|
||||
.scale = DAC_CW_SCALE_2,
|
||||
.phase = DAC_CW_PHASE_0,
|
||||
.freq = 1000,
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
.offset = 64,
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
.offset = 16,
|
||||
#endif
|
||||
};
|
||||
TEST_ESP_OK( dac_cw_generator_config(&cw) );
|
||||
TEST_ESP_OK( dac_cw_generator_enable() );
|
||||
TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) );
|
||||
|
||||
//be sure to do the init before using adc2.
|
||||
printf("adc2_init...\n");
|
||||
TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN ) );
|
||||
|
||||
vTaskDelay(2 * portTICK_RATE_MS);
|
||||
|
||||
printf("start conversion.\n");
|
||||
int read_raw[3] = {0};
|
||||
for (int i = 0; i < DAC_TEST_TIMES; i++) {
|
||||
vTaskDelay(10 * portTICK_RATE_MS);
|
||||
TEST_ESP_OK( adc2_get_raw( ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw[0]) );
|
||||
ESP_LOGI(TAG, "ADC: %d", read_raw[0]);
|
||||
if (read_raw[0] == read_raw[1]) {
|
||||
TEST_ASSERT_NOT_EQUAL(read_raw[1], read_raw[2]);
|
||||
}
|
||||
read_raw[2] = read_raw[1];
|
||||
read_raw[1] = read_raw[0];
|
||||
}
|
||||
|
||||
TEST_ESP_OK( dac_cw_generator_disable() );
|
||||
TEST_ESP_OK( dac_output_disable( DAC_TEST_CHANNEL_NUM ) );
|
||||
}
|
@ -205,7 +205,7 @@ TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s]")
|
||||
|
||||
#if !DISABLED_FOR_TARGETS(ESP32S2)
|
||||
/* ESP32S2 has only single I2S port and hence following test cases are not applicable */
|
||||
TEST_CASE("I2S adc test", "[i2s]")
|
||||
TEST_CASE("I2S adc test", "[i2s][ignore]")
|
||||
{
|
||||
// init I2S ADC
|
||||
i2s_config_t i2s_config = {
|
||||
|
@ -3,18 +3,6 @@
|
||||
#include "hal/adc_types.h"
|
||||
#include "hal/adc_ll.h"
|
||||
|
||||
typedef struct {
|
||||
bool conv_limit_en;
|
||||
uint32_t conv_limit_num;
|
||||
uint32_t clk_div;
|
||||
uint32_t adc1_pattern_len;
|
||||
uint32_t adc2_pattern_len;
|
||||
adc_ll_pattern_table_t *adc1_pattern;
|
||||
adc_ll_pattern_table_t *adc2_pattern;
|
||||
adc_ll_convert_mode_t conv_mode;
|
||||
adc_ll_dig_output_format_t format;
|
||||
} adc_hal_dig_config_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Common setting
|
||||
---------------------------------------------------------------*/
|
||||
@ -23,6 +11,11 @@ typedef struct {
|
||||
*/
|
||||
void adc_hal_init(void);
|
||||
|
||||
/**
|
||||
* ADC module deinitialization.
|
||||
*/
|
||||
void adc_hal_deinit(void);
|
||||
|
||||
/**
|
||||
* Set adc sample cycle for digital controller.
|
||||
*
|
||||
@ -30,7 +23,7 @@ void adc_hal_init(void);
|
||||
* @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor.
|
||||
* Range: 2 ~ 0xFF.
|
||||
*/
|
||||
#define adc_hal_dig_set_sample_cycle(sample_cycle) adc_ll_dig_set_sample_cycle(sample_cycle)
|
||||
#define adc_hal_digi_set_sample_cycle(sample_cycle) adc_ll_digi_set_sample_cycle(sample_cycle)
|
||||
|
||||
/**
|
||||
* Set ADC module power management.
|
||||
@ -52,14 +45,14 @@ void adc_hal_init(void);
|
||||
*
|
||||
* @prarm div Division factor.
|
||||
*/
|
||||
#define adc_hal_set_clk_div(div) adc_ll_set_clk_div(div)
|
||||
#define adc_hal_digi_set_clk_div(div) adc_ll_digi_set_clk_div(div)
|
||||
|
||||
/**
|
||||
* ADC module output data invert or not.
|
||||
* ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @prarm div Division factor.
|
||||
*/
|
||||
void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en);
|
||||
#define adc_hal_set_sar_clk_div(adc_n, div) adc_ll_set_sar_clk_div(adc_n, div)
|
||||
|
||||
/**
|
||||
* Set ADC module controller.
|
||||
@ -108,6 +101,15 @@ void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en);
|
||||
*/
|
||||
#define adc_hal_set_atten(adc_n, channel, atten) adc_ll_set_atten(adc_n, channel, atten)
|
||||
|
||||
/**
|
||||
* Get the attenuation of a particular channel on ADCn.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADCn channel number.
|
||||
* @return atten The attenuation option.
|
||||
*/
|
||||
#define adc_hal_get_atten(adc_n, channel) adc_ll_get_atten(adc_n, channel)
|
||||
|
||||
/**
|
||||
* Close ADC AMP module if don't use it for power save.
|
||||
*/
|
||||
@ -137,6 +139,21 @@ void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en);
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get the converted value for each ADCn for RTC controller.
|
||||
*
|
||||
* @note It may be block to wait conversion finish.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param channel adc channel number.
|
||||
* @param value Pointer for touch value.
|
||||
*
|
||||
* @return
|
||||
* - 0: The value is valid.
|
||||
* - ~0: The value is invalid.
|
||||
*/
|
||||
int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value);
|
||||
|
||||
/**
|
||||
* Set adc output data format for RTC controller.
|
||||
*
|
||||
@ -146,62 +163,19 @@ void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en);
|
||||
#define adc_hal_rtc_set_output_format(adc_n, bits) adc_ll_rtc_set_output_format(adc_n, bits)
|
||||
|
||||
/**
|
||||
* Get the converted value for each ADCn for RTC controller.
|
||||
* ADC module output data invert or not.
|
||||
*
|
||||
* @note It may be block to wait conversion finish.
|
||||
* @prarm adc_n ADC unit.
|
||||
* @return
|
||||
* - Converted value.
|
||||
*/
|
||||
int adc_hal_convert(adc_ll_num_t adc_n, int channel);
|
||||
#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Setting the digital controller.
|
||||
* Reset the pattern table pointer, then take the measurement rule from table header in next measurement.
|
||||
*
|
||||
* @prarm adc_hal_dig_config_t cfg Pointer to digital controller paramter.
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
void adc_hal_dig_controller_config(const adc_hal_dig_config_t *cfg);
|
||||
|
||||
/**
|
||||
* Set I2S DMA data source for digital controller.
|
||||
*
|
||||
* @param src i2s data source.
|
||||
*/
|
||||
#define adc_hal_dig_set_data_source(src) adc_ll_dig_set_data_source(src)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Hall sensor setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Enable hall sensor.
|
||||
*/
|
||||
#define adc_hal_hall_enable() adc_ll_hall_enable()
|
||||
|
||||
/**
|
||||
* Disable hall sensor.
|
||||
*/
|
||||
#define adc_hal_hall_disable() adc_ll_hall_disable()
|
||||
|
||||
/**
|
||||
* Start hall convert and return the hall value.
|
||||
*
|
||||
* @return Hall value.
|
||||
*/
|
||||
int adc_hal_hall_convert(void);
|
||||
|
||||
/**
|
||||
* @brief Output ADC2 reference voltage to gpio
|
||||
*
|
||||
* This function utilizes the testing mux exclusive to ADC2 to route the
|
||||
* reference voltage one of ADC2's channels.
|
||||
*
|
||||
* @param[in] io GPIO number
|
||||
* @return
|
||||
* - true: v_ref successfully routed to selected gpio
|
||||
* - false: Unsupported gpio
|
||||
*/
|
||||
#define adc_hal_vref_output(io) adc_ll_vref_output(io)
|
||||
#define adc_hal_digi_clear_pattern_table(adc_n) adc_ll_digi_clear_pattern_table(adc_n)
|
||||
|
@ -1,5 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "soc/adc_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @brief ADC units selected handle.
|
||||
*
|
||||
* @note For ADC digital controller(DMA mode), ESP32 don't support `ADC_UNIT_2`, `ADC_UNIT_BOTH`, `ADC_UNIT_ALTER`.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_UNIT_1 = 1, /*!< SAR ADC 1. */
|
||||
ADC_UNIT_2 = 2, /*!< SAR ADC 2. */
|
||||
ADC_UNIT_BOTH = 3, /*!< SAR ADC 1 and 2. */
|
||||
ADC_UNIT_ALTER = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */
|
||||
ADC_UNIT_MAX,
|
||||
} adc_unit_t;
|
||||
|
||||
/**
|
||||
* @brief ADC channels handle. See ``adc1_channel_t``, ``adc2_channel_t``.
|
||||
*
|
||||
* @note For ESP32 ADC1, don't support `ADC_CHANNEL_8`, `ADC_CHANNEL_9`. See ``adc1_channel_t``.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_CHANNEL_0 = 0, /*!< ADC channel */
|
||||
ADC_CHANNEL_1, /*!< ADC channel */
|
||||
@ -14,6 +36,9 @@ typedef enum {
|
||||
ADC_CHANNEL_MAX,
|
||||
} adc_channel_t;
|
||||
|
||||
/**
|
||||
* @brief ADC attenuation parameter. Different parameters determine the range of the ADC. See ``adc1_config_channel_atten``.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ATTEN_DB_0 = 0, /*!<The input voltage of ADC will be reduced to about 1/1 */
|
||||
ADC_ATTEN_DB_2_5 = 1, /*!<The input voltage of ADC will be reduced to about 1/1.34 */
|
||||
@ -22,16 +47,278 @@ typedef enum {
|
||||
ADC_ATTEN_MAX,
|
||||
} adc_atten_t;
|
||||
|
||||
/**
|
||||
* @brief ESP32 ADC DMA source selection.
|
||||
*
|
||||
* @note It's be deprecated in ESP32S2. Beacause ESP32S2 don't use I2S DMA.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_I2S_DATA_SRC_IO_SIG = 0, /*!< I2S data from GPIO matrix signal */
|
||||
ADC_I2S_DATA_SRC_ADC = 1, /*!< I2S data from ADC */
|
||||
ADC_I2S_DATA_SRC_MAX,
|
||||
} adc_i2s_source_t;
|
||||
|
||||
/**
|
||||
* @brief ADC resolution setting option.
|
||||
*
|
||||
* @note For ESP32S2. Only support 13 bit resolution.
|
||||
* For ESP32. Don't support 13 bit resolution.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_WIDTH_BIT_9 = 0, /*!< ADC capture width is 9Bit*/
|
||||
ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit*/
|
||||
ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit*/
|
||||
ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit*/
|
||||
ADC_WIDTH_BIT_9 = 0, /*!< ADC capture width is 9Bit. Only ESP32 is supported. */
|
||||
ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit. Only ESP32 is supported. */
|
||||
ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit. Only ESP32 is supported. */
|
||||
ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit. Only ESP32 is supported. */
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
ADC_WIDTH_BIT_13 = 4, /*!< ADC capture width is 13Bit. Only ESP32S2 is supported. */
|
||||
#endif
|
||||
ADC_WIDTH_MAX,
|
||||
} adc_bits_width_t;
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) clock system setting.
|
||||
* Expression: controller_clk = (`APLL` or `APB`) * (div_num + div_b / div_a).
|
||||
*/
|
||||
typedef struct {
|
||||
bool use_apll; /*!<true: use APLL clock; false: use APB clock. */
|
||||
uint32_t div_num; /*!<Division factor. Range: 1 ~ 255. */
|
||||
uint32_t div_b; /*!<Division factor. Range: 1 ~ 63. */
|
||||
uint32_t div_a; /*!<Division factor. Range: 1 ~ 63. */
|
||||
} adc_digi_clk_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) clock system default setting.
|
||||
*/
|
||||
#define ADC_DIGITAL_CLK_DEFAULT() { \
|
||||
.use_apll = 0, \
|
||||
.div_num = 40, \
|
||||
.div_b = 1, \
|
||||
.div_a = 1, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC arbiter work mode option.
|
||||
*
|
||||
* @note ESP32S2: Only ADC2 support arbiter.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ARB_MODE_SHIELD,/*!<Force shield arbiter, Select the highest priority controller to work. */
|
||||
ADC_ARB_MODE_FIX, /*!<Fixed priority switch controller mode. */
|
||||
ADC_ARB_MODE_LOOP, /*!<Loop priority switch controller mode. Each controller has the same priority,
|
||||
and the arbiter will switch to the next controller after the measurement is completed. */
|
||||
} adc_arbiter_mode_t;
|
||||
|
||||
/**
|
||||
* @brief ADC arbiter work mode and priority setting.
|
||||
*
|
||||
* @note ESP32S2: Only ADC2 support arbiter.
|
||||
*/
|
||||
typedef struct {
|
||||
adc_arbiter_mode_t mode; /*!<Refer to `adc_arbiter_mode_t`. Note: only support ADC2. */
|
||||
uint8_t rtc_pri; /*!<RTC controller priority. Range: 0 ~ 2. */
|
||||
uint8_t dig_pri; /*!<Digital controller priority. Range: 0 ~ 2. */
|
||||
uint8_t pwdet_pri; /*!<Wi-Fi controller priority. Range: 0 ~ 2. */
|
||||
} adc_arbiter_t;
|
||||
|
||||
/**
|
||||
* @brief ADC arbiter default configuration.
|
||||
*
|
||||
* @note ESP32S2: Only ADC2 support arbiter.
|
||||
*/
|
||||
#define ADC_ARBITER_CONFIG_DEFAULT() { \
|
||||
.mode = ADC_ARB_MODE_FIX, \
|
||||
.rtc_pri = 1, \
|
||||
.dig_pri = 0, \
|
||||
.pwdet_pri = 2, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) work mode.
|
||||
*
|
||||
* @note Member `channel` can be used to judge the validity of the ADC data, because the role of the arbiter may get invalid ADC data.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_CONV_SINGLE_UNIT_1 = 1, /*!< SAR ADC 1. */
|
||||
ADC_CONV_SINGLE_UNIT_2 = 2, /*!< SAR ADC 2. */
|
||||
ADC_CONV_BOTH_UNIT = 3, /*!< SAR ADC 1 and 2. */
|
||||
ADC_CONV_ALTER_UNIT = 7, /*!< SAR ADC 1 and 2 alternative mode. */
|
||||
ADC_CONV_UNIT_MAX,
|
||||
} adc_digi_convert_mode_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) output data format option.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DIGI_FORMAT_12BIT, /*!<ADC to DMA data format, [15:12]-channel, [11: 0]-12 bits ADC data (`adc_digi_output_data_t`).
|
||||
Note: In single convert mode. */
|
||||
ADC_DIGI_FORMAT_11BIT, /*!<ADC to DMA data format, [15]-adc unit, [14:11]-channel, [10: 0]-11 bits ADC data (`adc_digi_output_data_t`).
|
||||
Note: In multi or alter convert mode. */
|
||||
ADC_DIGI_FORMAT_MAX,
|
||||
} adc_digi_output_format_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) output data format.
|
||||
* Used to analyze the acquired ADC (DMA) data.
|
||||
*
|
||||
* @note Member `channel` can be used to judge the validity of the ADC data, because the role of the arbiter may get invalid ADC data.
|
||||
*/
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint16_t data: 12; /*!<ADC real output data info. Resolution: 12 bit. */
|
||||
uint16_t channel: 4; /*!<ADC channel index info.
|
||||
If (channel < ADC_CHANNEL_MAX), The data is valid.
|
||||
If (channel > ADC_CHANNEL_MAX), The data is invalid. */
|
||||
} type1; /*!<When the configured output format is 12bit. `ADC_DIGI_FORMAT_12BIT` */
|
||||
struct {
|
||||
uint16_t data: 11; /*!<ADC real output data info. Resolution: 11 bit. */
|
||||
uint16_t channel: 4; /*!<ADC channel index info.
|
||||
If (channel < ADC_CHANNEL_MAX), The data is valid.
|
||||
If (channel > ADC_CHANNEL_MAX), The data is invalid. */
|
||||
uint16_t unit: 1; /*!<ADC unit index info. 0: ADC1; 1: ADC2. */
|
||||
} type2; /*!<When the configured output format is 11bit. `ADC_DIGI_FORMAT_11BIT` */
|
||||
uint16_t val;
|
||||
};
|
||||
} adc_digi_output_data_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) conversion rules setting.
|
||||
*/
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint8_t atten: 2; /*!< ADC sampling voltage attenuation configuration.
|
||||
0: input voltage * 1;
|
||||
1: input voltage * 1/1.34;
|
||||
2: input voltage * 1/2;
|
||||
3: input voltage * 1/3.6. */
|
||||
uint8_t reserved: 2; /*!< reserved0 */
|
||||
uint8_t channel: 4; /*!< ADC channel index. */
|
||||
};
|
||||
uint8_t val;
|
||||
};
|
||||
} adc_digi_pattern_table_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) interrupt type options.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DIGI_INTR_MASK_MONITOR = 0x1,
|
||||
ADC_DIGI_INTR_MASK_MEAS_DONE = 0x2,
|
||||
ADC_DIGI_INTR_MASK_ALL = 0x3,
|
||||
} adc_digi_intr_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) configuration parameters.
|
||||
*/
|
||||
typedef struct {
|
||||
bool conv_limit_en; /*!<Enable max conversion number detection for digital controller.
|
||||
If the number of ADC conversion is equal to the `limit_num`, the conversion is stopped. */
|
||||
uint32_t conv_limit_num; /*!<ADC max conversion number for digital controller. */
|
||||
uint32_t adc1_pattern_len; /*!<Pattern table length for digital controller. Range: 0 ~ 16.
|
||||
The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
|
||||
resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
|
||||
pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. */
|
||||
uint32_t adc2_pattern_len; /*!<Refer to `adc1_pattern_len` */
|
||||
adc_digi_pattern_table_t *adc1_pattern; /*!<Pointer to pattern table for digital controller. The table size defined by `adc1_pattern_len`. */
|
||||
adc_digi_pattern_table_t *adc2_pattern; /*!<Refer to `adc1_pattern` */
|
||||
adc_digi_convert_mode_t conv_mode; /*!<ADC conversion mode for digital controller. */
|
||||
adc_digi_output_format_t format; /*!<ADC output data format for digital controller. */
|
||||
uint32_t interval; /*!<The number of interval clock cycles for the digital controller to trigger the measurement.
|
||||
The unit is the divided clock. Range: 40 ~ 4095. */
|
||||
adc_digi_clk_t dig_clk; /*!<Refer to `adc_digi_clk_t` */
|
||||
uint32_t dma_eof_num; /*!<DMA eof num of adc digital controller.
|
||||
If the number of measurements reaches `dma_eof_num`,
|
||||
then `dma_in_suc_eof` signal is generated. */
|
||||
} adc_digi_config_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) filter index options.
|
||||
*
|
||||
* @note For ESP32S2, The filter object of the ADC is fixed.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DIGI_FILTER_IDX0 = 0, /*!<The filter index 0.
|
||||
For ESP32S2, It can only be used to filter all enabled channels of ADC1 unit at the same time. */
|
||||
ADC_DIGI_FILTER_IDX1, /*!<The filter index 1.
|
||||
For ESP32S2, It can only be used to filter all enabled channels of ADC2 unit at the same time. */
|
||||
ADC_DIGI_FILTER_IDX_MAX
|
||||
} adc_digi_filter_idx_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) filter type options.
|
||||
* Expression: filter_data = (k-1)/k * last_data + new_data / k.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DIGI_FILTER_IIR_2 = 0, /*!<The filter mode is first-order IIR filter. The coefficient is 2. */
|
||||
ADC_DIGI_FILTER_IIR_4, /*!<The filter mode is first-order IIR filter. The coefficient is 4. */
|
||||
ADC_DIGI_FILTER_IIR_8, /*!<The filter mode is first-order IIR filter. The coefficient is 8. */
|
||||
ADC_DIGI_FILTER_IIR_16, /*!<The filter mode is first-order IIR filter. The coefficient is 16. */
|
||||
ADC_DIGI_FILTER_IIR_64, /*!<The filter mode is first-order IIR filter. The coefficient is 64. */
|
||||
ADC_DIGI_FILTER_IIR_MAX
|
||||
} adc_digi_filter_mode_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) filter configuration.
|
||||
*
|
||||
* @note For ESP32S2, The filter object of the ADC is fixed.
|
||||
* @note For ESP32S2, The filter object is always all enabled channels.
|
||||
*/
|
||||
typedef struct {
|
||||
adc_unit_t adc_unit; /*!<Set adc unit number for filter.
|
||||
For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. */
|
||||
adc_channel_t channel; /*!<Set adc channel number for filter.
|
||||
For ESP32S2, it's always `ADC_CHANNEL_MAX` */
|
||||
adc_digi_filter_mode_t mode;/*!<Set adc filter mode for filter. See ``adc_digi_filter_mode_t``. */
|
||||
} adc_digi_filter_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) monitor index options.
|
||||
*
|
||||
* @note For ESP32S2, The monitor object of the ADC is fixed.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DIGI_MONITOR_IDX0 = 0, /*!<The monitor index 0.
|
||||
For ESP32S2, It can only be used to monitor all enabled channels of ADC1 unit at the same time. */
|
||||
ADC_DIGI_MONITOR_IDX1, /*!<The monitor index 1.
|
||||
For ESP32S2, It can only be used to monitor all enabled channels of ADC2 unit at the same time. */
|
||||
ADC_DIGI_MONITOR_IDX_MAX
|
||||
} adc_digi_monitor_idx_t;
|
||||
|
||||
/**
|
||||
* @brief Set monitor mode of adc digital controller.
|
||||
* MONITOR_HIGH:If ADC_OUT > threshold, Generates monitor interrupt.
|
||||
* MONITOR_LOW: If ADC_OUT < threshold, Generates monitor interrupt.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DIGI_MONITOR_HIGH = 0, /*!<If ADC_OUT > threshold, Generates monitor interrupt. */
|
||||
ADC_DIGI_MONITOR_LOW, /*!<If ADC_OUT < threshold, Generates monitor interrupt. */
|
||||
ADC_DIGI_MONITOR_MAX
|
||||
} adc_digi_monitor_mode_t;
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller (DMA mode) monitor configuration.
|
||||
*
|
||||
* @note For ESP32S2, The monitor object of the ADC is fixed.
|
||||
* @note For ESP32S2, The monitor object is always all enabled channels.
|
||||
*/
|
||||
typedef struct {
|
||||
adc_unit_t adc_unit; /*!<Set adc unit number for monitor.
|
||||
For ESP32S2, monitor IDX0/IDX1 can only be used to monitor all enabled channels of ADC1/ADC2 unit at the same time. */
|
||||
adc_channel_t channel; /*!<Set adc channel number for monitor.
|
||||
For ESP32S2, it's always `ADC_CHANNEL_MAX` */
|
||||
adc_digi_monitor_mode_t mode; /*!<Set adc monitor mode. See ``adc_digi_monitor_mode_t``. */
|
||||
uint32_t threshold; /*!<Set monitor threshold of adc digital controller. */
|
||||
} adc_digi_monitor_t;
|
||||
|
||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
@ -10,7 +10,7 @@ typedef enum {
|
||||
} dac_channel_t;
|
||||
|
||||
/**
|
||||
* The multiple of the amplitude of the cosine wave generator. The max amplitude is VDD3P3_RTC.
|
||||
* @brief The multiple of the amplitude of the cosine wave generator. The max amplitude is VDD3P3_RTC.
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_CW_SCALE_1 = 0x0, /*!< 1/1. Default. */
|
||||
@ -20,7 +20,7 @@ typedef enum {
|
||||
} dac_cw_scale_t;
|
||||
|
||||
/**
|
||||
* Set the phase of the cosine wave generator output.
|
||||
* @brief Set the phase of the cosine wave generator output.
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_CW_PHASE_0 = 0x2, /*!< Phase shift +0° */
|
||||
@ -28,13 +28,13 @@ typedef enum {
|
||||
} dac_cw_phase_t;
|
||||
|
||||
/**
|
||||
* Config the cosine wave generator function in DAC module.
|
||||
* @brief Config the cosine wave generator function in DAC module.
|
||||
*/
|
||||
typedef struct {
|
||||
dac_channel_t en_ch; /*!< Enable the cosine wave generator of DAC channel. */
|
||||
dac_cw_scale_t scale; /*!< Set the amplitude of the cosine wave generator output. */
|
||||
dac_cw_phase_t phase; /*!< Set the phase of the cosine wave generator output. */
|
||||
uint32_t freq; /*!< Set frequency of cosine wave generator output. Range: 130(130Hz) ~ 55000(100KHz). */
|
||||
int8_t offset; /*!< Set the voltage value of the DC component of the cosine wave generator output.
|
||||
int8_t offset; /*!< Set the voltage value of the DC component of the cosine wave generator output.
|
||||
Note: Unreasonable settings can cause waveform to be oversaturated. Range: -128 ~ 127. */
|
||||
} dac_cw_config_t;
|
@ -290,7 +290,8 @@ typedef struct touch_filter_config {
|
||||
/** Touch sensor channel sleep configuration */
|
||||
typedef struct {
|
||||
touch_pad_t touch_num; /*!<Set touch channel number for sleep pad.
|
||||
Only one touch sensor channel is supported in deep sleep mode. */
|
||||
Only one touch sensor channel is supported in deep sleep mode.
|
||||
If clear the sleep channel, point this pad to `TOUCH_PAD_NUM0` */
|
||||
bool en_proximity; /*!<enable proximity function for sleep pad */
|
||||
} touch_pad_sleep_channel_t;
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||
|
||||
#define SOC_ADC1_DATA_INVERT_DEFAULT (1)
|
||||
#define SOC_ADC2_DATA_INVERT_DEFAULT (0)
|
||||
#define SOC_ADC2_DATA_INVERT_DEFAULT (1)
|
||||
|
||||
#define SOC_ADC_FSM_RSTB_WAIT_DEFAULT (8)
|
||||
#define SOC_ADC_FSM_START_WAIT_DEFAULT (5)
|
||||
@ -22,4 +22,6 @@
|
||||
*/
|
||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 0)
|
||||
|
||||
#define SOC_ADC_PWDET_CCT_DEFAULT (4)
|
||||
#define SOC_ADC_PWDET_CCT_DEFAULT (4)
|
||||
|
||||
#define SOC_ADC_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (2)
|
@ -6,8 +6,10 @@
|
||||
#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (10)
|
||||
#define SOC_ADC_MAX_CHANNEL_NUM (10)
|
||||
|
||||
#define SOC_ADC1_DATA_INVERT_DEFAULT (1)
|
||||
#define SOC_ADC2_DATA_INVERT_DEFAULT (1)
|
||||
#define SOC_ADC1_DATA_INVERT_DEFAULT (0)
|
||||
#define SOC_ADC2_DATA_INVERT_DEFAULT (0)
|
||||
|
||||
#define SOC_ADC_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (0)
|
||||
|
||||
#define SOC_ADC_FSM_RSTB_WAIT_DEFAULT (8)
|
||||
#define SOC_ADC_FSM_START_WAIT_DEFAULT (5)
|
||||
@ -20,6 +22,10 @@
|
||||
* - 1 : support;
|
||||
* - 0 : not support;
|
||||
*/
|
||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 0)
|
||||
#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 1)
|
||||
|
||||
#define SOC_ADC_PWDET_CCT_DEFAULT (4)
|
||||
#define SOC_ADC_PWDET_CCT_DEFAULT (4)
|
||||
|
||||
#define SOC_ADC_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) ((PERIPH_NUM==0)? 2 : 1)
|
||||
|
||||
#define SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT (1)
|
@ -39,81 +39,6 @@ typedef volatile struct {
|
||||
};
|
||||
uint32_t val;
|
||||
} tick_conf;
|
||||
union {
|
||||
struct {
|
||||
uint32_t start_force: 1;
|
||||
uint32_t start: 1;
|
||||
uint32_t reserved2: 1;
|
||||
uint32_t work_mode: 2; /*0: single mode 1: double mode 2: alternate mode*/
|
||||
uint32_t sar_sel: 1; /*0: SAR1 1: SAR2 only work for single SAR mode*/
|
||||
uint32_t sar_clk_gated: 1;
|
||||
uint32_t sar_clk_div: 8; /*SAR clock divider*/
|
||||
uint32_t sar1_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/
|
||||
uint32_t sar2_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/
|
||||
uint32_t sar1_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC1 CTRL*/
|
||||
uint32_t sar2_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC2 CTRL*/
|
||||
uint32_t data_sar_sel: 1; /*1: sar_sel will be coded by the MSB of the 16-bit output data in this case the resolution should not be larger than 11 bits.*/
|
||||
uint32_t data_to_i2s: 1; /*1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix*/
|
||||
uint32_t xpd_sar_force: 2; /*force option to xpd sar blocks*/
|
||||
uint32_t reserved29: 3;
|
||||
};
|
||||
uint32_t val;
|
||||
} saradc_ctrl;
|
||||
union {
|
||||
struct {
|
||||
uint32_t meas_num_limit: 1;
|
||||
uint32_t max_meas_num: 8; /*max conversion number*/
|
||||
uint32_t sar1_inv: 1; /*1: data to DIG ADC1 CTRL is inverted otherwise not*/
|
||||
uint32_t sar2_inv: 1; /*1: data to DIG ADC2 CTRL is inverted otherwise not*/
|
||||
uint32_t timer_sel: 1; /*1: select saradc timer 0: i2s_ws trigger*/
|
||||
uint32_t timer_target: 8; /*to set saradc timer target*/
|
||||
uint32_t timer_en: 1; /*to enable saradc timer trigger*/
|
||||
uint32_t reserved21: 11;
|
||||
};
|
||||
uint32_t val;
|
||||
} saradc_ctrl2;
|
||||
union {
|
||||
struct {
|
||||
uint32_t reserved0: 16;
|
||||
uint32_t sample_num: 8; /*sample number*/
|
||||
uint32_t sample_cycle: 8; /*sample cycles*/
|
||||
};
|
||||
uint32_t val;
|
||||
} saradc_fsm;
|
||||
union {
|
||||
struct {
|
||||
uint32_t xpd_wait: 8;
|
||||
uint32_t rstb_wait: 8;
|
||||
uint32_t standby_wait: 8;
|
||||
uint32_t reserved24: 8;
|
||||
};
|
||||
uint32_t val;
|
||||
} saradc_fsm_wait;
|
||||
uint32_t saradc_sar1_status; /**/
|
||||
uint32_t saradc_sar2_status; /**/
|
||||
uint32_t saradc_sar1_patt_tab1; /*item 0 ~ 3 for pattern table 1 (each item one byte)*/
|
||||
uint32_t saradc_sar1_patt_tab2; /*Item 4 ~ 7 for pattern table 1 (each item one byte)*/
|
||||
uint32_t saradc_sar1_patt_tab3; /*Item 8 ~ 11 for pattern table 1 (each item one byte)*/
|
||||
uint32_t saradc_sar1_patt_tab4; /*Item 12 ~ 15 for pattern table 1 (each item one byte)*/
|
||||
uint32_t saradc_sar2_patt_tab1; /*item 0 ~ 3 for pattern table 2 (each item one byte)*/
|
||||
uint32_t saradc_sar2_patt_tab2; /*Item 4 ~ 7 for pattern table 2 (each item one byte)*/
|
||||
uint32_t saradc_sar2_patt_tab3; /*Item 8 ~ 11 for pattern table 2 (each item one byte)*/
|
||||
uint32_t saradc_sar2_patt_tab4; /*Item 12 ~ 15 for pattern table 2 (each item one byte)*/
|
||||
union {
|
||||
struct {
|
||||
uint32_t reserved0: 2;
|
||||
uint32_t adc_arb_apb_force: 1; /*adc2 arbiter force to enableapb controller*/
|
||||
uint32_t adc_arb_rtc_force: 1; /*adc2 arbiter force to enable rtc controller*/
|
||||
uint32_t adc_arb_wifi_force: 1; /*adc2 arbiter force to enable wifi controller*/
|
||||
uint32_t adc_arb_grant_force: 1; /*adc2 arbiter force grant*/
|
||||
uint32_t adc_arb_apb_priority: 2; /*Set adc2 arbiterapb priority*/
|
||||
uint32_t adc_arb_rtc_priority: 2; /*Set adc2 arbiter rtc priority*/
|
||||
uint32_t adc_arb_wifi_priority: 2; /*Set adc2 arbiter wifi priority*/
|
||||
uint32_t adc_arb_fix_priority: 1; /*adc2 arbiter uses fixed priority*/
|
||||
uint32_t reserved13: 19;
|
||||
};
|
||||
uint32_t val;
|
||||
} adc_arb_ctrl;
|
||||
union {
|
||||
struct {
|
||||
uint32_t clk20_oen: 1;
|
||||
@ -134,11 +59,7 @@ typedef volatile struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t peri_io_swap: 8;
|
||||
uint32_t spi0_hold: 1;
|
||||
uint32_t spi1_hold: 1;
|
||||
uint32_t reserved10: 3;
|
||||
uint32_t spi_prior: 1;
|
||||
uint32_t reserved14: 18;
|
||||
uint32_t reserved8: 24;
|
||||
};
|
||||
uint32_t val;
|
||||
} host_inf_sel;
|
||||
@ -177,10 +98,10 @@ typedef volatile struct {
|
||||
};
|
||||
uint32_t val;
|
||||
} flash_ace3_attr;
|
||||
uint32_t flash_ace0_addr; /**/
|
||||
uint32_t flash_ace1_addr; /**/
|
||||
uint32_t flash_ace2_addr; /**/
|
||||
uint32_t flash_ace3_addr; /**/
|
||||
uint32_t flash_ace0_addr; /**/
|
||||
uint32_t flash_ace1_addr; /**/
|
||||
uint32_t flash_ace2_addr; /**/
|
||||
uint32_t flash_ace3_addr; /**/
|
||||
union {
|
||||
struct {
|
||||
uint32_t flash_ace0_size:16;
|
||||
@ -237,10 +158,10 @@ typedef volatile struct {
|
||||
};
|
||||
uint32_t val;
|
||||
} sram_ace3_attr;
|
||||
uint32_t sram_ace0_addr; /**/
|
||||
uint32_t sram_ace1_addr; /**/
|
||||
uint32_t sram_ace2_addr; /**/
|
||||
uint32_t sram_ace3_addr; /**/
|
||||
uint32_t sram_ace0_addr; /**/
|
||||
uint32_t sram_ace1_addr; /**/
|
||||
uint32_t sram_ace2_addr; /**/
|
||||
uint32_t sram_ace3_addr; /**/
|
||||
union {
|
||||
struct {
|
||||
uint32_t sram_ace0_size:16;
|
||||
@ -271,24 +192,14 @@ typedef volatile struct {
|
||||
} sram_ace3_size;
|
||||
union {
|
||||
struct {
|
||||
uint32_t spi0_reject_int: 1;
|
||||
uint32_t spi0_reject_clr: 1;
|
||||
uint32_t spi0_reject_cde: 5;
|
||||
uint32_t reserved7: 25;
|
||||
uint32_t spi_mem_reject_int: 1;
|
||||
uint32_t spi_mem_reject_clr: 1;
|
||||
uint32_t spi_mem_reject_cde: 5;
|
||||
uint32_t reserved7: 25;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi0_pms_ctrl;
|
||||
uint32_t spi0_reject_addr; /**/
|
||||
union {
|
||||
struct {
|
||||
uint32_t spi1_reject_int: 1;
|
||||
uint32_t spi1_reject_clr: 1;
|
||||
uint32_t spi1_reject_cde: 5;
|
||||
uint32_t reserved7: 25;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi1_pms_ctrl;
|
||||
uint32_t spi1_reject_addr; /**/
|
||||
} spi_mem_pms_ctrl;
|
||||
uint32_t spi_mem_reject_addr; /**/
|
||||
union {
|
||||
struct {
|
||||
uint32_t sdio_win_access_en: 1;
|
||||
@ -310,10 +221,10 @@ typedef volatile struct {
|
||||
};
|
||||
uint32_t val;
|
||||
} redcy_sig1;
|
||||
uint32_t wifi_bb_cfg; /**/
|
||||
uint32_t wifi_bb_cfg_2; /**/
|
||||
uint32_t wifi_clk_en; /**/
|
||||
uint32_t wifi_rst_en; /**/
|
||||
uint32_t wifi_bb_cfg; /**/
|
||||
uint32_t wifi_bb_cfg_2; /**/
|
||||
uint32_t wifi_clk_en; /**/
|
||||
uint32_t wifi_rst_en; /**/
|
||||
union {
|
||||
struct {
|
||||
uint32_t agc_mem_force_pu: 1;
|
||||
@ -326,6 +237,23 @@ typedef volatile struct {
|
||||
};
|
||||
uint32_t val;
|
||||
} front_end_mem_pd;
|
||||
uint32_t reserved_9c;
|
||||
uint32_t reserved_a0;
|
||||
uint32_t reserved_a4;
|
||||
uint32_t reserved_a8;
|
||||
uint32_t reserved_ac;
|
||||
uint32_t reserved_b0;
|
||||
uint32_t reserved_b4;
|
||||
uint32_t reserved_b8;
|
||||
uint32_t reserved_bc;
|
||||
uint32_t reserved_c0;
|
||||
uint32_t reserved_c4;
|
||||
uint32_t reserved_c8;
|
||||
uint32_t reserved_cc;
|
||||
uint32_t reserved_d0;
|
||||
uint32_t reserved_d4;
|
||||
uint32_t reserved_d8;
|
||||
uint32_t reserved_dc;
|
||||
uint32_t reserved_e0;
|
||||
uint32_t reserved_e4;
|
||||
uint32_t reserved_e8;
|
||||
@ -525,7 +453,7 @@ typedef volatile struct {
|
||||
uint32_t reserved_3f0;
|
||||
uint32_t reserved_3f4;
|
||||
uint32_t reserved_3f8;
|
||||
uint32_t date; /**/
|
||||
uint32_t date; /**/
|
||||
} apb_ctrl_dev_t;
|
||||
extern apb_ctrl_dev_t APB_CTRL;
|
||||
#ifdef __cplusplus
|
||||
|
@ -73,13 +73,6 @@ typedef volatile struct {
|
||||
uint32_t sar2_status; /**/
|
||||
uint32_t sar1_patt_tab[4]; /*item 0 ~ 3 for pattern table 1 (each item one byte)*/
|
||||
uint32_t sar2_patt_tab[4];
|
||||
// uint32_t sar1_patt_tab2; /*Item 4 ~ 7 for pattern table 1 (each item one byte)*/
|
||||
// uint32_t sar1_patt_tab3; /*Item 8 ~ 11 for pattern table 1 (each item one byte)*/
|
||||
// uint32_t sar1_patt_tab4; /*Item 12 ~ 15 for pattern table 1 (each item one byte)*/
|
||||
// uint32_t sar2_patt_tab1; /*item 0 ~ 3 for pattern table 2 (each item one byte)*/
|
||||
// uint32_t sar2_patt_tab2; /*Item 4 ~ 7 for pattern table 2 (each item one byte)*/
|
||||
// uint32_t sar2_patt_tab3; /*Item 8 ~ 11 for pattern table 2 (each item one byte)*/
|
||||
// uint32_t sar2_patt_tab4; /*Item 12 ~ 15 for pattern table 2 (each item one byte)*/
|
||||
union {
|
||||
struct {
|
||||
uint32_t reserved0: 2;
|
||||
|
@ -172,11 +172,7 @@ typedef volatile struct {
|
||||
} fifo_data;
|
||||
union {
|
||||
struct {
|
||||
uint32_t byte_num: 8; /*Byte_num represent the number of data need to be send or data need to be received.*/
|
||||
uint32_t ack_en: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/
|
||||
uint32_t ack_exp: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/
|
||||
uint32_t ack_val: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/
|
||||
uint32_t op_code: 3; /*op_code is the command 0:RSTART 1:WRITE 2:READ 3:STOP . 4:END.*/
|
||||
uint32_t command0: 14; /*command0*/
|
||||
uint32_t reserved14: 17;
|
||||
uint32_t done: 1; /*command0_done*/
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
set(srcs "brownout_hal.c"
|
||||
set(srcs "adc_hal.c"
|
||||
"brownout_hal.c"
|
||||
"rtc_clk.c"
|
||||
"rtc_clk_init.c"
|
||||
"rtc_init.c"
|
||||
|
87
components/soc/src/esp32/adc_hal.c
Normal file
87
components/soc/src/esp32/adc_hal.c
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The HAL layer for ADC (common part)
|
||||
|
||||
#include "hal/adc_hal.h"
|
||||
#include "hal/adc_types.h"
|
||||
|
||||
void adc_hal_digi_init(void)
|
||||
{
|
||||
adc_hal_init();
|
||||
adc_hal_set_sar_clk_div(ADC_NUM_1, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_1));
|
||||
adc_hal_set_sar_clk_div(ADC_NUM_2, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_2));
|
||||
}
|
||||
|
||||
void adc_hal_digi_deinit(void)
|
||||
{
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
||||
adc_hal_deinit();
|
||||
}
|
||||
|
||||
void adc_hal_digi_controller_config(const adc_hal_digi_config_t *cfg)
|
||||
{
|
||||
/* If enable digital controller, adc xpd should always on. */
|
||||
adc_ll_set_power_manage(ADC_POWER_SW_ON);
|
||||
adc_ll_digi_set_clk_div(cfg->clk_div);
|
||||
/* Single channel mode or multi channel mode. */
|
||||
adc_ll_digi_set_convert_mode(cfg->conv_mode);
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
||||
adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
|
||||
if (cfg->adc1_pattern_len) {
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
|
||||
for (int i = 0; i < cfg->adc1_pattern_len; i++) {
|
||||
adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
|
||||
adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
|
||||
if (cfg->adc2_pattern_len) {
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
|
||||
for (int i = 0; i < cfg->adc2_pattern_len; i++) {
|
||||
adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
adc_ll_digi_set_output_format(cfg->format);
|
||||
if (cfg->conv_limit_en) {
|
||||
adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num);
|
||||
adc_ll_digi_convert_limit_enable();
|
||||
} else {
|
||||
adc_ll_digi_convert_limit_disable();
|
||||
}
|
||||
adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_ADC);
|
||||
}
|
||||
|
||||
int adc_hal_hall_convert(void)
|
||||
{
|
||||
int Sens_Vp0;
|
||||
int Sens_Vn0;
|
||||
int Sens_Vp1;
|
||||
int Sens_Vn1;
|
||||
int hall_value;
|
||||
// convert for 4 times with different phase and outputs
|
||||
adc_ll_hall_phase_disable(); // hall phase
|
||||
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0, &Sens_Vp0 );
|
||||
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3, &Sens_Vn0 );
|
||||
adc_ll_hall_phase_enable();
|
||||
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0, &Sens_Vp1 );
|
||||
adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3, &Sens_Vn1 );
|
||||
hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0);
|
||||
return hall_value;
|
||||
}
|
118
components/soc/src/esp32/include/hal/adc_hal.h
Normal file
118
components/soc/src/esp32/include/hal/adc_hal.h
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The HAL layer for ADC (esp32 specific part)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/adc_ll.h"
|
||||
#include "hal/adc_types.h"
|
||||
|
||||
#include_next "hal/adc_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
bool conv_limit_en; /*!<Enable max conversion number detection for digital controller.
|
||||
If the number of ADC conversion is equal to the `limit_num`, the conversion is stopped. */
|
||||
uint32_t conv_limit_num; /*!<ADC max conversion number for digital controller. */
|
||||
uint32_t adc1_pattern_len; /*!<Pattern table length for digital controller. Range: 0 ~ 16.
|
||||
The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
|
||||
resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
|
||||
pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. */
|
||||
uint32_t adc2_pattern_len; /*!<Refer to `adc1_pattern_len` */
|
||||
adc_hal_digi_pattern_table_t *adc1_pattern; /*!<Pointer to pattern table for digital controller. The table size defined by `adc1_pattern_len`. */
|
||||
adc_hal_digi_pattern_table_t *adc2_pattern; /*!<Refer to `adc1_pattern` */
|
||||
adc_hal_digi_convert_mode_t conv_mode; /*!<ADC conversion mode for digital controller. ESP32 only support ADC1 single mode. */
|
||||
adc_hal_digi_output_format_t format; /*!<ADC output data format for digital controller. */
|
||||
uint32_t clk_div; /*!< ADC module clock division factor. ADC clock divided from APB clock.*/
|
||||
} adc_hal_digi_config_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Set I2S DMA data source for digital controller.
|
||||
*
|
||||
* @param src i2s data source.
|
||||
*/
|
||||
#define adc_hal_digi_set_data_source(src) adc_ll_digi_set_data_source(src)
|
||||
|
||||
/**
|
||||
* Setting the digital controller.
|
||||
*
|
||||
* @prarm adc_digi_config_t cfg Pointer to digital controller paramter.
|
||||
*/
|
||||
void adc_hal_digi_controller_config(const adc_hal_digi_config_t *cfg);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Common setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller initialization.
|
||||
*/
|
||||
void adc_hal_digi_init(void);
|
||||
|
||||
/**
|
||||
* @brief ADC digital controller deinitialization.
|
||||
*/
|
||||
void adc_hal_digi_deinit(void);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Hall sensor setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Enable hall sensor.
|
||||
*/
|
||||
#define adc_hal_hall_enable() adc_ll_hall_enable()
|
||||
|
||||
/**
|
||||
* Disable hall sensor.
|
||||
*/
|
||||
#define adc_hal_hall_disable() adc_ll_hall_disable()
|
||||
|
||||
/**
|
||||
* Start hall convert and return the hall value.
|
||||
*
|
||||
* @return Hall value.
|
||||
*/
|
||||
int adc_hal_hall_convert(void);
|
||||
|
||||
/**
|
||||
* @brief Output ADC2 reference voltage to gpio
|
||||
*
|
||||
* This function utilizes the testing mux exclusive to ADC2 to route the
|
||||
* reference voltage one of ADC2's channels.
|
||||
*
|
||||
* @param[in] io GPIO number
|
||||
* @return
|
||||
* - true: v_ref successfully routed to selected gpio
|
||||
* - false: Unsupported gpio
|
||||
*/
|
||||
#define adc_hal_vref_output(io) adc_ll_vref_output(io)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -9,12 +9,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ADC_DIG_FORMAT_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data.
|
||||
ADC_DIGI_FORMAT_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data.
|
||||
Note: In single convert mode. */
|
||||
ADC_DIG_FORMAT_11BIT, /*!< ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data.
|
||||
ADC_DIGI_FORMAT_11BIT, /*!< ADC to I2S data format, [15]-adc unit [14:11]-channel [10:0]-11 bits ADC data.
|
||||
Note: In multi convert mode. */
|
||||
ADC_DIG_FORMAT_MAX,
|
||||
} adc_ll_dig_output_format_t;
|
||||
ADC_DIGI_FORMAT_MAX,
|
||||
} adc_hal_digi_output_format_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_CONV_SINGLE_UNIT_1 = 1, /*!< SAR ADC 1*/
|
||||
@ -22,7 +22,7 @@ typedef enum {
|
||||
ADC_CONV_BOTH_UNIT = 3, /*!< SAR ADC 1 and 2, not supported yet */
|
||||
ADC_CONV_ALTER_UNIT = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */
|
||||
ADC_CONV_UNIT_MAX,
|
||||
} adc_ll_convert_mode_t;
|
||||
} adc_hal_digi_convert_mode_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_NUM_1 = 0, /*!< SAR ADC 1 */
|
||||
@ -47,18 +47,18 @@ typedef struct {
|
||||
};
|
||||
uint8_t val;
|
||||
};
|
||||
} adc_ll_pattern_table_t;
|
||||
} adc_hal_digi_pattern_table_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */
|
||||
ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */
|
||||
ADC_POWER_SW_OFF, /*!< ADC XPD controled by SW. power off. */
|
||||
ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */
|
||||
ADC_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
|
||||
ADC_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */
|
||||
ADC_POWER_MAX, /*!< For parameter check. */
|
||||
} adc_ll_power_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_HALL_CTRL_ULP = 0x0,/*!< Hall sensor controled by ULP */
|
||||
ADC_HALL_CTRL_RTC = 0x1 /*!< Hall sensor controled by RTC */
|
||||
ADC_HALL_CTRL_ULP = 0x0,/*!< Hall sensor controlled by ULP */
|
||||
ADC_HALL_CTRL_RTC = 0x1 /*!< Hall sensor controlled by RTC */
|
||||
} adc_ll_hall_controller_t ;
|
||||
|
||||
typedef enum {
|
||||
@ -66,7 +66,11 @@ typedef enum {
|
||||
ADC_CTRL_ULP = 1,
|
||||
ADC_CTRL_DIG = 2,
|
||||
ADC2_CTRL_PWDET = 3,
|
||||
} adc_ll_controller_t ;
|
||||
} adc_hal_controller_t ;
|
||||
|
||||
typedef enum {
|
||||
ADC_RTC_DATA_OK = 0,
|
||||
} adc_ll_rtc_raw_data_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
@ -79,7 +83,7 @@ typedef enum {
|
||||
* @param start_wait Delay time after open xpd.
|
||||
* @param standby_wait Delay time to close xpd.
|
||||
*/
|
||||
static inline void adc_ll_dig_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait)
|
||||
static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait)
|
||||
{
|
||||
// Internal FSM reset wait time
|
||||
SYSCON.saradc_fsm.rstb_wait = rst_wait;
|
||||
@ -96,17 +100,28 @@ static inline void adc_ll_dig_set_fsm_time(uint32_t rst_wait, uint32_t start_wai
|
||||
* @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor.
|
||||
* Range: 2 ~ 0xFF.
|
||||
*/
|
||||
static inline void adc_ll_dig_set_sample_cycle(uint32_t sample_cycle)
|
||||
static inline void adc_ll_digi_set_sample_cycle(uint32_t sample_cycle)
|
||||
{
|
||||
SYSCON.saradc_fsm.sample_cycle = sample_cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module clock division factor setting. ADC clock divided from APB clock.
|
||||
*
|
||||
* @param div Division factor.
|
||||
*/
|
||||
static inline void adc_ll_digi_set_clk_div(uint32_t div)
|
||||
{
|
||||
/* ADC clock divided from APB clk, e.g. 80 / 2 = 40Mhz, */
|
||||
SYSCON.saradc_ctrl.sar_clk_div = div;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set adc output data format for digital controller.
|
||||
*
|
||||
* @param format Output data format.
|
||||
* @param format Output data format, see ``adc_hal_digi_output_format_t``.
|
||||
*/
|
||||
static inline void adc_ll_dig_set_output_format(adc_ll_dig_output_format_t format)
|
||||
static inline void adc_ll_digi_set_output_format(adc_hal_digi_output_format_t format)
|
||||
{
|
||||
SYSCON.saradc_ctrl.data_sar_sel = format;
|
||||
}
|
||||
@ -117,7 +132,7 @@ static inline void adc_ll_dig_set_output_format(adc_ll_dig_output_format_t forma
|
||||
*
|
||||
* @param meas_num Max conversion number. Range: 0 ~ 255.
|
||||
*/
|
||||
static inline void adc_ll_dig_set_convert_limit_num(uint32_t meas_num)
|
||||
static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num)
|
||||
{
|
||||
SYSCON.saradc_ctrl2.max_meas_num = meas_num;
|
||||
}
|
||||
@ -126,7 +141,7 @@ static inline void adc_ll_dig_set_convert_limit_num(uint32_t meas_num)
|
||||
* Enable max conversion number detection for digital controller.
|
||||
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
|
||||
*/
|
||||
static inline void adc_ll_dig_convert_limit_enable(void)
|
||||
static inline void adc_ll_digi_convert_limit_enable(void)
|
||||
{
|
||||
SYSCON.saradc_ctrl2.meas_num_limit = 1;
|
||||
}
|
||||
@ -135,7 +150,7 @@ static inline void adc_ll_dig_convert_limit_enable(void)
|
||||
* Disable max conversion number detection for digital controller.
|
||||
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
|
||||
*/
|
||||
static inline void adc_ll_dig_convert_limit_disable(void)
|
||||
static inline void adc_ll_digi_convert_limit_disable(void)
|
||||
{
|
||||
SYSCON.saradc_ctrl2.meas_num_limit = 0;
|
||||
}
|
||||
@ -145,9 +160,9 @@ static inline void adc_ll_dig_convert_limit_disable(void)
|
||||
*
|
||||
* @note ESP32 only support ADC1 single mode.
|
||||
*
|
||||
* @param mode Conversion mode select.
|
||||
* @param mode Conversion mode select, see ``adc_hal_digi_convert_mode_t``.
|
||||
*/
|
||||
static inline void adc_ll_dig_set_convert_mode(adc_ll_convert_mode_t mode)
|
||||
static inline void adc_ll_digi_set_convert_mode(adc_hal_digi_convert_mode_t mode)
|
||||
{
|
||||
if (mode == ADC_CONV_SINGLE_UNIT_1) {
|
||||
SYSCON.saradc_ctrl.work_mode = 0;
|
||||
@ -162,27 +177,41 @@ static inline void adc_ll_dig_set_convert_mode(adc_ll_convert_mode_t mode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module Digital output data invert or not.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_ll_digi_output_invert(adc_ll_num_t adc_n, bool inv_en)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SYSCON.saradc_ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SYSCON.saradc_ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set I2S DMA data source for digital controller.
|
||||
*
|
||||
* @param src i2s data source.
|
||||
* @param src i2s data source, see ``adc_i2s_source_t``.
|
||||
*/
|
||||
static inline void adc_ll_dig_set_data_source(adc_i2s_source_t src)
|
||||
static inline void adc_ll_digi_set_data_source(adc_i2s_source_t src)
|
||||
{
|
||||
/* 1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix */
|
||||
SYSCON.saradc_ctrl.data_to_i2s = src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pattern table lenth for digital controller.
|
||||
* Set pattern table length for digital controller.
|
||||
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
|
||||
* resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
|
||||
* pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param adc_n ADC unit.
|
||||
* @param patt_len Items range: 1 ~ 16.
|
||||
*/
|
||||
static inline void adc_ll_set_pattern_table_len(adc_ll_num_t adc_n, uint32_t patt_len)
|
||||
static inline void adc_ll_digi_set_pattern_table_len(adc_ll_num_t adc_n, uint32_t patt_len)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SYSCON.saradc_ctrl.sar1_patt_len = patt_len - 1;
|
||||
@ -197,22 +226,41 @@ static inline void adc_ll_set_pattern_table_len(adc_ll_num_t adc_n, uint32_t pat
|
||||
* resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
|
||||
* pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param pattern_index Items index. Range: 1 ~ 16.
|
||||
* @param pattern Stored conversion rules.
|
||||
* @param adc_n ADC unit.
|
||||
* @param pattern_index Items index. Range: 0 ~ 15.
|
||||
* @param pattern Stored conversion rules, see ``adc_hal_digi_pattern_table_t``.
|
||||
*/
|
||||
static inline void adc_ll_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_ll_pattern_table_t pattern)
|
||||
static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern_index, adc_hal_digi_pattern_table_t pattern)
|
||||
{
|
||||
const uint32_t patt_tab_idx = pattern_index / 4;
|
||||
const uint32_t patt_shift = (3 - (pattern_index % 4)) * 8;
|
||||
const uint32_t patt_mask = 0xFF << patt_shift;
|
||||
|
||||
uint32_t tab;
|
||||
uint8_t index = pattern_index / 4;
|
||||
uint8_t offset = (pattern_index % 4) * 8;
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SYSCON.saradc_sar1_patt_tab[patt_tab_idx] &= ~patt_mask;
|
||||
SYSCON.saradc_sar1_patt_tab[patt_tab_idx] |= pattern.val << patt_shift;
|
||||
tab = SYSCON.saradc_sar1_patt_tab[index]; // Read old register value
|
||||
tab &= (~(0xFF000000 >> offset)); // clear old data
|
||||
tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
|
||||
SYSCON.saradc_sar1_patt_tab[index] = tab; // Write back
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SYSCON.saradc_sar2_patt_tab[patt_tab_idx] &= ~patt_mask;
|
||||
SYSCON.saradc_sar2_patt_tab[patt_tab_idx] |= pattern.val << patt_shift;
|
||||
tab = SYSCON.saradc_sar2_patt_tab[index]; // Read old register value
|
||||
tab &= (~(0xFF000000 >> offset)); // clear old data
|
||||
tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
|
||||
SYSCON.saradc_sar2_patt_tab[index] = tab; // Write back
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the pattern table pointer, then take the measurement rule from table header in next measurement.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_ll_digi_clear_pattern_table(adc_ll_num_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SYSCON.saradc_ctrl.sar1_patt_p_clear = 1;
|
||||
SYSCON.saradc_ctrl.sar1_patt_p_clear = 0;
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SYSCON.saradc_ctrl.sar2_patt_p_clear = 1;
|
||||
SYSCON.saradc_ctrl.sar2_patt_p_clear = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +271,7 @@ static inline void adc_ll_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern
|
||||
* Set adc cct for PWDET controller.
|
||||
*
|
||||
* @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
|
||||
* @prarm cct Range: 0 ~ 7.
|
||||
* @param cct Range: 0 ~ 7.
|
||||
*/
|
||||
static inline void adc_ll_pwdet_set_cct(uint32_t cct)
|
||||
{
|
||||
@ -249,8 +297,8 @@ static inline uint32_t adc_ll_pwdet_get_cct(void)
|
||||
/**
|
||||
* Set adc output data format for RTC controller.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @prarm bits Output data bits width option.
|
||||
* @param adc_n ADC unit.
|
||||
* @param bits Output data bits width option, see ``adc_bits_width_t``.
|
||||
*/
|
||||
static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_width_t bits)
|
||||
{
|
||||
@ -266,9 +314,9 @@ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_wid
|
||||
/**
|
||||
* Enable adc channel to start convert.
|
||||
*
|
||||
* @note Only one channel can be selected for once measurement.
|
||||
* @note Only one channel can be selected in once measurement.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
|
||||
@ -280,12 +328,29 @@ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable adc channel to start convert.
|
||||
*
|
||||
* @note Only one channel can be selected in once measurement.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n, int channel)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SENS.sar_meas_start1.sar1_en_pad = 0; //only one channel is selected.
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SENS.sar_meas_start2.sar2_en_pad = 0; //only one channel is selected.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start conversion once by software for RTC controller.
|
||||
*
|
||||
* @note It may be block to wait conversion idle for ADC1.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel)
|
||||
@ -303,7 +368,7 @@ static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel)
|
||||
/**
|
||||
* Check the conversion done flag for each ADCn for RTC controller.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param adc_n ADC unit.
|
||||
* @return
|
||||
* -true : The conversion process is finish.
|
||||
* -false : The conversion process is not finish.
|
||||
@ -322,7 +387,7 @@ static inline bool adc_ll_rtc_convert_is_done(adc_ll_num_t adc_n)
|
||||
/**
|
||||
* Get the converted value for each ADCn for RTC controller.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param adc_n ADC unit.
|
||||
* @return
|
||||
* - Converted value.
|
||||
*/
|
||||
@ -337,13 +402,41 @@ static inline int adc_ll_rtc_get_convert_value(adc_ll_num_t adc_n)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module RTC output data invert or not.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SENS.sar_read_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SENS.sar_read_ctrl2.sar2_data_inv = inv_en; // Enable / Disable ADC data invert
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze whether the obtained raw data is correct.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param raw_data ADC raw data input (convert value).
|
||||
* @return
|
||||
* - 0: The data is correct to use.
|
||||
*/
|
||||
static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t adc_n, uint16_t raw_data)
|
||||
{
|
||||
/* ADC1 don't need check data */
|
||||
return ADC_RTC_DATA_OK;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Common setting
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Set ADC module power management.
|
||||
*
|
||||
* @prarm manage Set ADC power status.
|
||||
* @param manage Set ADC power status.
|
||||
*/
|
||||
static inline void adc_ll_set_power_manage(adc_ll_power_t manage)
|
||||
{
|
||||
@ -380,14 +473,17 @@ static inline adc_ll_power_t adc_ll_get_power_manage(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module clock division factor setting. ADC clock devided from APB clock.
|
||||
* ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`.
|
||||
*
|
||||
* @prarm div Division factor.
|
||||
* @param div Division factor.
|
||||
*/
|
||||
static inline void adc_ll_set_clk_div(uint32_t div)
|
||||
static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div)
|
||||
{
|
||||
/* ADC clock devided from APB clk, e.g. 80 / 2 = 40Mhz, */
|
||||
SYSCON.saradc_ctrl.sar_clk_div = div;
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SENS.sar_read_ctrl.sar1_clk_div = div;
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SENS.sar_read_ctrl2.sar2_clk_div = div;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,7 +496,7 @@ static inline void adc_ll_set_clk_div(uint32_t div)
|
||||
*
|
||||
* When VDD_A is 3.3V:
|
||||
*
|
||||
* - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
|
||||
* - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
|
||||
* - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
|
||||
* - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
|
||||
* - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
|
||||
@ -412,16 +508,16 @@ static inline void adc_ll_set_clk_div(uint32_t div)
|
||||
*
|
||||
* Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges:
|
||||
*
|
||||
* - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV
|
||||
* - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV
|
||||
* - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV
|
||||
* - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV
|
||||
* - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV
|
||||
*
|
||||
* For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @prarm channel ADCn channel number.
|
||||
* @prarm atten The attenuation option.
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADCn channel number.
|
||||
* @param atten The attenuation option.
|
||||
*/
|
||||
static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
|
||||
{
|
||||
@ -433,30 +529,18 @@ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, a
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module RTC output data invert or not.
|
||||
* Get the attenuation of a particular channel on ADCn.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADCn channel number.
|
||||
* @return atten The attenuation option.
|
||||
*/
|
||||
static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en)
|
||||
static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t channel)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SENS.sar_read_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SENS.sar_read_ctrl2.sar2_data_inv = inv_en; // Enable / Disable ADC data invert
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ADC module Digital output data invert or not.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
*/
|
||||
static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SYSCON.saradc_ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert
|
||||
} else { // adc_n == ADC_NUM_2
|
||||
SYSCON.saradc_ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert
|
||||
return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3);
|
||||
} else {
|
||||
return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,10 +551,10 @@ static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en)
|
||||
* Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep;
|
||||
* the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2.
|
||||
*
|
||||
* @prarm adc_n ADC unit.
|
||||
* @prarm ctrl ADC controller.
|
||||
* @param adc_n ADC unit.
|
||||
* @param ctrl ADC controller.
|
||||
*/
|
||||
static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl)
|
||||
static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_hal_controller_t ctrl)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
switch ( ctrl ) {
|
||||
|
@ -178,6 +178,7 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
|
||||
static inline void dac_ll_dma_enable(void)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 1;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,6 +187,7 @@ static inline void dac_ll_dma_enable(void)
|
||||
static inline void dac_ll_dma_disable(void)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 0;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The HAL layer for SPI (common part)
|
||||
// The HAL layer for Touch sensor (common part)
|
||||
|
||||
#include "hal/touch_sensor_hal.h"
|
||||
#include "hal/touch_sensor_types.h"
|
||||
|
@ -1,4 +1,5 @@
|
||||
set(srcs "brownout_hal.c"
|
||||
set(srcs "adc_hal.c"
|
||||
"brownout_hal.c"
|
||||
"rtc_clk.c"
|
||||
"rtc_clk_init.c"
|
||||
"rtc_init.c"
|
||||
|
252
components/soc/src/esp32s2/adc_hal.c
Normal file
252
components/soc/src/esp32s2/adc_hal.c
Normal file
@ -0,0 +1,252 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The HAL layer for ADC (esp32s2 specific part)
|
||||
|
||||
#include "hal/adc_hal.h"
|
||||
#include "hal/adc_types.h"
|
||||
#include "esp_log.h"
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
void adc_hal_digi_init(void)
|
||||
{
|
||||
adc_hal_init();
|
||||
adc_ll_digi_set_clk_div(SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT);
|
||||
adc_ll_digi_output_invert(ADC_NUM_1, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_1));
|
||||
adc_ll_digi_output_invert(ADC_NUM_2, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_2));
|
||||
|
||||
}
|
||||
|
||||
void adc_hal_digi_deinit(void)
|
||||
{
|
||||
adc_ll_digi_trigger_disable(); // boss
|
||||
adc_ll_digi_dma_disable();
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
||||
adc_ll_digi_filter_reset(ADC_NUM_1);
|
||||
adc_ll_digi_filter_reset(ADC_NUM_2);
|
||||
adc_ll_digi_reset();
|
||||
adc_ll_digi_controller_clk_disable();
|
||||
adc_hal_deinit();
|
||||
}
|
||||
|
||||
static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
|
||||
{
|
||||
uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false);
|
||||
adc_hal_set_calibration_param(adc_n, cal_val);
|
||||
}
|
||||
|
||||
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
||||
{
|
||||
/* If enable digtal controller, adc xpd should always on. */
|
||||
adc_ll_set_power_manage(ADC_POWER_SW_ON);
|
||||
/* Single channel mode or multi channel mode. */
|
||||
adc_ll_digi_set_convert_mode(cfg->conv_mode);
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
||||
if (cfg->adc1_pattern_len) {
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
|
||||
for (int i = 0; i < cfg->adc1_pattern_len; i++) {
|
||||
adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
|
||||
adc_set_init_code(ADC_NUM_1, cfg->adc1_pattern[i].channel, cfg->adc1_pattern[i].atten);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
|
||||
if (cfg->adc2_pattern_len) {
|
||||
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
|
||||
for (int i = 0; i < cfg->adc2_pattern_len; i++) {
|
||||
adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
|
||||
adc_set_init_code(ADC_NUM_2, cfg->adc2_pattern[i].channel, cfg->adc2_pattern[i].atten);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
||||
adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
|
||||
}
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
|
||||
adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
|
||||
}
|
||||
adc_ll_digi_set_output_format(cfg->format);
|
||||
if (cfg->conv_limit_en) {
|
||||
adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num);
|
||||
adc_ll_digi_convert_limit_enable();
|
||||
} else {
|
||||
adc_ll_digi_convert_limit_disable();
|
||||
}
|
||||
|
||||
adc_ll_digi_set_trigger_interval(cfg->interval);
|
||||
adc_hal_digi_clk_config(&cfg->dig_clk);
|
||||
adc_ll_digi_dma_set_eof_num(cfg->dma_eof_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
|
||||
* Enable clock and select clock source for ADC digital controller.
|
||||
* Expression: controller_clk = APLL/APB * (div_num + div_b / div_a).
|
||||
*
|
||||
* @param clk Refer to `adc_digi_clk_t`.
|
||||
*/
|
||||
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk)
|
||||
{
|
||||
adc_ll_digi_controller_clk_div(clk->div_num, clk->div_b, clk->div_a);
|
||||
adc_ll_digi_controller_clk_enable(clk->use_apll);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable digital controller to trigger the measurement.
|
||||
*/
|
||||
void adc_hal_digi_enable(void)
|
||||
{
|
||||
adc_ll_digi_dma_enable();
|
||||
adc_ll_digi_trigger_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable digital controller to trigger the measurement.
|
||||
*/
|
||||
void adc_hal_digi_disable(void)
|
||||
{
|
||||
adc_ll_digi_trigger_disable();
|
||||
adc_ll_digi_dma_disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config monitor of adc digital controller.
|
||||
*
|
||||
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
|
||||
* @param adc_n ADC unit.
|
||||
* @param config Refer to `adc_digi_monitor_t`.
|
||||
*/
|
||||
void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config)
|
||||
{
|
||||
adc_ll_digi_monitor_set_mode(adc_n, config->mode);
|
||||
adc_ll_digi_monitor_set_thres(adc_n, config->threshold);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Common setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Config ADC2 module arbiter.
|
||||
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
|
||||
* the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data.
|
||||
*
|
||||
* @note Only ADC2 support arbiter.
|
||||
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
|
||||
* @note Default priority: Wi-Fi > RTC > Digital;
|
||||
*
|
||||
* @param config Refer to `adc_arbiter_t`.
|
||||
*/
|
||||
void adc_hal_arbiter_config(adc_arbiter_t *config)
|
||||
{
|
||||
adc_ll_set_arbiter_work_mode(config->mode);
|
||||
adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
ADC calibration setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
static uint16_t s_adc_cali_param[ADC_NUM_MAX][ADC_ATTEN_MAX] = { {0}, {0} };
|
||||
|
||||
static uint32_t adc_hal_read_self_cal(adc_ll_num_t adc_n, int channel)
|
||||
{
|
||||
adc_ll_rtc_start_convert(adc_n, channel);
|
||||
while (adc_ll_rtc_convert_is_done(adc_n) != true);
|
||||
return (uint32_t)adc_ll_rtc_get_convert_value(adc_n);
|
||||
}
|
||||
|
||||
uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal)
|
||||
{
|
||||
if (!force_cal) {
|
||||
if (s_adc_cali_param[adc_n][atten]) {
|
||||
return (uint32_t)s_adc_cali_param[adc_n][atten];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
|
||||
uint32_t code_sum = 0;
|
||||
uint32_t code_h = 0;
|
||||
uint32_t code_l = 0;
|
||||
uint32_t chk_code = 0;
|
||||
uint32_t dout = 0;
|
||||
|
||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||
if (adc_n == ADC_NUM_2) {
|
||||
adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
|
||||
adc_hal_arbiter_config(&config);
|
||||
}
|
||||
adc_hal_set_controller(adc_n, ADC_CTRL_RTC); //Set controller
|
||||
|
||||
// adc_hal_arbiter_config(adc_arbiter_t *config)
|
||||
adc_ll_calibration_prepare(adc_n, channel, internal_gnd);
|
||||
|
||||
/* Enable/disable internal connect GND (for calibration). */
|
||||
if (internal_gnd) {
|
||||
adc_ll_rtc_disable_channel(adc_n, channel);
|
||||
adc_ll_set_atten(adc_n, 0, atten); // Note: when disable all channel, HW auto select channel0 atten param.
|
||||
} else {
|
||||
adc_ll_rtc_enable_channel(adc_n, channel);
|
||||
adc_ll_set_atten(adc_n, channel, atten);
|
||||
}
|
||||
|
||||
for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) {
|
||||
code_h = ADC_HAL_CAL_OFFSET_RANGE;
|
||||
code_l = 0;
|
||||
chk_code = (code_h + code_l) / 2;
|
||||
adc_ll_set_calibration_param(adc_n, chk_code);
|
||||
dout = adc_hal_read_self_cal(adc_n, channel);
|
||||
while (code_h - code_l > 1) {
|
||||
if (dout == 0) {
|
||||
code_h = chk_code;
|
||||
} else {
|
||||
code_l = chk_code;
|
||||
}
|
||||
chk_code = (code_h + code_l) / 2;
|
||||
adc_ll_set_calibration_param(adc_n, chk_code);
|
||||
dout = adc_hal_read_self_cal(adc_n, channel);
|
||||
if ((code_h - code_l == 1)) {
|
||||
chk_code += 1;
|
||||
adc_ll_set_calibration_param(adc_n, chk_code);
|
||||
dout = adc_hal_read_self_cal(adc_n, channel);
|
||||
}
|
||||
}
|
||||
code_list[rpt] = chk_code;
|
||||
code_sum += chk_code;
|
||||
}
|
||||
code_l = code_list[0];
|
||||
code_h = code_list[0];
|
||||
for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) {
|
||||
if (code_l > code_list[i]) {
|
||||
code_l = code_list[i];
|
||||
}
|
||||
if (code_h < code_list[i]) {
|
||||
code_h = code_list[i];
|
||||
}
|
||||
}
|
||||
chk_code = code_h + code_l;
|
||||
dout = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
|
||||
? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2)
|
||||
: (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
|
||||
|
||||
adc_ll_set_calibration_param(adc_n, dout);
|
||||
adc_ll_calibration_finish(adc_n);
|
||||
s_adc_cali_param[adc_n][atten] = (uint16_t)dout;
|
||||
return dout;
|
||||
}
|
262
components/soc/src/esp32s2/include/hal/adc_hal.h
Normal file
262
components/soc/src/esp32s2/include/hal/adc_hal.h
Normal file
@ -0,0 +1,262 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The HAL layer for ADC (esp32s2 specific part)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/adc_ll.h"
|
||||
#include "hal/adc_types.h"
|
||||
|
||||
#include_next "hal/adc_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Digital controller initialization.
|
||||
*/
|
||||
void adc_hal_digi_init(void);
|
||||
|
||||
/**
|
||||
* Digital controller deinitialization.
|
||||
*/
|
||||
void adc_hal_digi_deinit(void);
|
||||
|
||||
/**
|
||||
* Setting the digital controller.
|
||||
*
|
||||
* @param cfg Pointer to digital controller paramter.
|
||||
*/
|
||||
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg);
|
||||
|
||||
/**
|
||||
* ADC Digital controller output data invert or not.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param inv_en data invert or not.
|
||||
*/
|
||||
#define adc_hal_digi_output_invert(adc_n, inv_en) adc_ll_digi_output_invert(adc_n, inv_en)
|
||||
|
||||
/**
|
||||
* Sets the number of interval clock cycles for the digital controller to trigger the measurement.
|
||||
*
|
||||
* @note The trigger interval should not be less than the sampling time of the SAR ADC.
|
||||
* @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095.
|
||||
*/
|
||||
#define adc_hal_digi_set_trigger_interval(cycle) adc_ll_digi_set_trigger_interval(cycle)
|
||||
|
||||
/**
|
||||
* Enable digital controller to trigger the measurement.
|
||||
*/
|
||||
void adc_hal_digi_enable(void);
|
||||
|
||||
/**
|
||||
* Disable digital controller to trigger the measurement.
|
||||
*/
|
||||
void adc_hal_digi_disable(void);
|
||||
|
||||
/**
|
||||
* Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
|
||||
* Enable clock and select clock source for ADC digital controller.
|
||||
* Expression: controller_clk = APLL/APB * (div_num + div_b / div_a).
|
||||
*
|
||||
* @param clk Refer to `adc_digi_clk_t`.
|
||||
*/
|
||||
void adc_hal_digi_clk_config(const adc_digi_clk_t *clk);
|
||||
|
||||
/**
|
||||
* Reset adc digital controller filter.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
#define adc_hal_digi_filter_reset(adc_n) adc_ll_digi_filter_reset(adc_n)
|
||||
|
||||
/**
|
||||
* Set adc digital controller filter factor.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
|
||||
*/
|
||||
#define adc_hal_digi_filter_set_factor(adc_n, factor) adc_ll_digi_filter_set_factor(adc_n, factor)
|
||||
|
||||
/**
|
||||
* Get adc digital controller filter factor.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64).
|
||||
*/
|
||||
#define adc_hal_digi_filter_get_factor(adc_n, factor) adc_ll_digi_filter_get_factor(adc_n, factor)
|
||||
|
||||
/**
|
||||
* Enable/disable adc digital controller filter.
|
||||
* Filtering the ADC data to obtain smooth data at higher sampling rates.
|
||||
*
|
||||
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
#define adc_hal_digi_filter_enable(adc_n, enable) adc_ll_digi_filter_enable(adc_n, enable)
|
||||
|
||||
/**
|
||||
* Get the filtered data of adc digital controller filter.
|
||||
* The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
|
||||
*
|
||||
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
|
||||
* @param adc_n ADC unit.
|
||||
* @return Filtered data.
|
||||
*/
|
||||
#define adc_hal_digi_filter_read_data(adc_n) adc_ll_digi_filter_read_data(adc_n)
|
||||
|
||||
/**
|
||||
* Config monitor of adc digital controller.
|
||||
*
|
||||
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
|
||||
* @param adc_n ADC unit.
|
||||
* @param config Refer to `adc_digi_monitor_t`.
|
||||
*/
|
||||
void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config);
|
||||
|
||||
/**
|
||||
* Enable/disable monitor of adc digital controller.
|
||||
*
|
||||
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
|
||||
* @param adc_n ADC unit.
|
||||
*/
|
||||
#define adc_hal_digi_monitor_enable(adc_n, enable) adc_ll_digi_monitor_enable(adc_n, enable)
|
||||
|
||||
/**
|
||||
* Enable interrupt of adc digital controller by bitmask.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param intr Interrupt bitmask.
|
||||
*/
|
||||
#define adc_hal_digi_intr_enable(adc_n, intr) adc_ll_digi_intr_enable(adc_n, intr)
|
||||
|
||||
/**
|
||||
* Disable interrupt of adc digital controller by bitmask.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param intr Interrupt bitmask.
|
||||
*/
|
||||
#define adc_hal_digi_intr_disable(adc_n, intr) adc_ll_digi_intr_disable(adc_n, intr)
|
||||
|
||||
/**
|
||||
* Clear interrupt of adc digital controller by bitmask.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @param intr Interrupt bitmask.
|
||||
*/
|
||||
#define adc_hal_digi_intr_clear(adc_n, intr) adc_ll_digi_intr_clear(adc_n, intr)
|
||||
|
||||
/**
|
||||
* Get interrupt status mask of adc digital controller.
|
||||
*
|
||||
* @param adc_n ADC unit.
|
||||
* @return
|
||||
* - intr Interrupt bitmask.
|
||||
*/
|
||||
#define adc_hal_digi_get_intr_status(adc_n) adc_ll_digi_get_intr_status(adc_n)
|
||||
|
||||
|
||||
/**
|
||||
* Set DMA eof num of adc digital controller.
|
||||
* If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated.
|
||||
*
|
||||
* @param num eof num of DMA.
|
||||
*/
|
||||
#define adc_hal_digi_dma_set_eof_num(num) adc_ll_digi_dma_set_eof_num(num)
|
||||
|
||||
/**
|
||||
* Enable output data to DMA from adc digital controller.
|
||||
*/
|
||||
#define adc_hal_digi_dma_enable() adc_ll_digi_dma_enable()
|
||||
|
||||
/**
|
||||
* Disable output data to DMA from adc digital controller.
|
||||
*/
|
||||
#define adc_hal_digi_dma_disable() adc_ll_digi_dma_disable()
|
||||
|
||||
/**
|
||||
* Reset adc digital controller.
|
||||
*/
|
||||
#define adc_hal_digi_reset() adc_ll_digi_reset()
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* Reset RTC controller FSM.
|
||||
*/
|
||||
#define adc_hal_rtc_reset() adc_ll_rtc_reset()
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Common setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Config ADC2 module arbiter.
|
||||
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
|
||||
* the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data.
|
||||
*
|
||||
* @note Only ADC2 support arbiter.
|
||||
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
|
||||
* @note Default priority: Wi-Fi > RTC > Digital;
|
||||
*
|
||||
* @param config Refer to `adc_arbiter_t`.
|
||||
*/
|
||||
void adc_hal_arbiter_config(adc_arbiter_t *config);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
ADC calibration setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Calibrate the ADC according to the parameters.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
* @param channel adc channel number.
|
||||
* @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage.
|
||||
* false: Use IO external voltage as calibration voltage.
|
||||
* @param force_cal true: Do not use the results that have already been verified, and perform the verification again. It will take a long time.
|
||||
* false: Use the result of the last calibration.
|
||||
*
|
||||
* @return
|
||||
* - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
|
||||
*/
|
||||
uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal);
|
||||
|
||||
/**
|
||||
* Set the calibration result (initial data) to ADC.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
*/
|
||||
#define adc_hal_set_calibration_param(adc_n, param) adc_ll_set_calibration_param(adc_n, param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
RTC controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Power on dac module and start output voltage.
|
||||
*
|
||||
@ -36,6 +40,7 @@ extern "C" {
|
||||
*/
|
||||
static inline void dac_ll_power_on(dac_channel_t channel)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_clkgate_en = 1;
|
||||
RTCIO.pad_dac[channel].dac_xpd_force = 1;
|
||||
RTCIO.pad_dac[channel].xpd_dac = 1;
|
||||
}
|
||||
@ -49,6 +54,9 @@ static inline void dac_ll_power_down(dac_channel_t channel)
|
||||
{
|
||||
RTCIO.pad_dac[channel].dac_xpd_force = 0;
|
||||
RTCIO.pad_dac[channel].xpd_dac = 0;
|
||||
if (RTCIO.pad_dac[0].xpd_dac == 0 && RTCIO.pad_dac[1].xpd_dac == 0) {
|
||||
SENS.sar_dac_ctrl1.dac_clkgate_en = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,6 +77,15 @@ static inline void dac_ll_update_output_value(dac_channel_t channel, uint8_t val
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset dac by software.
|
||||
*/
|
||||
static inline void dac_ll_rtc_reset(void)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_reset = 1;
|
||||
SENS.sar_dac_ctrl1.dac_reset = 0;
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/* DAC cosine wave generator API's */
|
||||
/************************************/
|
||||
@ -168,6 +185,10 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Digital controller setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/************************************/
|
||||
/* DAC DMA API's */
|
||||
/************************************/
|
||||
@ -178,6 +199,7 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset)
|
||||
static inline void dac_ll_dma_enable(void)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 1;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,6 +208,7 @@ static inline void dac_ll_dma_enable(void)
|
||||
static inline void dac_ll_dma_disable(void)
|
||||
{
|
||||
SENS.sar_dac_ctrl1.dac_dig_force = 0;
|
||||
SENS.sar_dac_ctrl1.dac_clk_inv = 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -623,12 +623,6 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable);
|
||||
*/
|
||||
#define touch_hal_sleep_read_baseline(baseline) touch_ll_sleep_read_baseline(baseline)
|
||||
|
||||
#define touch_hal_sleep_read_smooth(smooth_data) touch_ll_sleep_read_smooth(smooth_data)
|
||||
|
||||
#define touch_hal_sleep_read_data(raw_data) touch_ll_sleep_read_data(raw_data)
|
||||
|
||||
#define touch_hal_sleep_reset_baseline() touch_ll_sleep_reset_baseline()
|
||||
|
||||
/**
|
||||
* Read smooth data of touch sensor for sleep pad.
|
||||
*/
|
||||
|
@ -231,26 +231,6 @@ static inline void touch_ll_get_fsm_mode(touch_fsm_mode_t *mode)
|
||||
*mode = (touch_fsm_mode_t)RTCCNTL.touch_ctrl2.touch_start_force;
|
||||
}
|
||||
|
||||
static inline void touch_ll_clk_enable(void)
|
||||
{
|
||||
RTCCNTL.touch_ctrl2.touch_clkgate_en = 1; //enable touch clock for FSM. or force enable.
|
||||
}
|
||||
|
||||
static inline void touch_ll_clk_disable(void)
|
||||
{
|
||||
RTCCNTL.touch_ctrl2.touch_clkgate_en = 0; //enable touch clock for FSM. or force enable.
|
||||
}
|
||||
|
||||
/**
|
||||
* Touch timer trigger measurement and always wait measurement done.
|
||||
* Force done for touch timer ensures that the timer always can get the measurement done signal.
|
||||
*/
|
||||
static inline void touch_ll_timer_force_done(void)
|
||||
{
|
||||
RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_FORCE_DONE;
|
||||
RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_DONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable clock gate of touch sensor.
|
||||
*
|
||||
|
@ -17,72 +17,22 @@
|
||||
void adc_hal_init(void)
|
||||
{
|
||||
// Set internal FSM wait time, fixed value.
|
||||
adc_ll_dig_set_fsm_time(SOC_ADC_FSM_RSTB_WAIT_DEFAULT, SOC_ADC_FSM_START_WAIT_DEFAULT,
|
||||
SOC_ADC_FSM_STANDBY_WAIT_DEFAULT);
|
||||
adc_ll_dig_set_sample_cycle(ADC_FSM_SAMPLE_CYCLE_DEFAULT);
|
||||
adc_hal_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT);
|
||||
adc_hal_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT);
|
||||
adc_ll_digi_set_fsm_time(SOC_ADC_FSM_RSTB_WAIT_DEFAULT, SOC_ADC_FSM_START_WAIT_DEFAULT,
|
||||
SOC_ADC_FSM_STANDBY_WAIT_DEFAULT);
|
||||
adc_ll_digi_set_sample_cycle(ADC_FSM_SAMPLE_CYCLE_DEFAULT);
|
||||
adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
|
||||
}
|
||||
|
||||
void adc_hal_dig_controller_config(const adc_hal_dig_config_t *cfg)
|
||||
void adc_hal_deinit(void)
|
||||
{
|
||||
/* If enable digtal controller, adc xpd should always on. */
|
||||
adc_ll_set_power_manage(ADC_POWER_SW_ON);
|
||||
adc_ll_set_clk_div(cfg->clk_div);
|
||||
/* Single channel mode or multi channel mode. */
|
||||
adc_ll_dig_set_convert_mode(cfg->conv_mode);
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
||||
adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG);
|
||||
adc_ll_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
|
||||
for (int i = 0; i < cfg->adc1_pattern_len; i++) {
|
||||
adc_ll_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
|
||||
}
|
||||
}
|
||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
|
||||
adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
|
||||
adc_ll_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
|
||||
for (int i = 0; i < cfg->adc2_pattern_len; i++) {
|
||||
adc_ll_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
|
||||
}
|
||||
}
|
||||
adc_ll_dig_set_output_format(cfg->format);
|
||||
if (cfg->conv_limit_en) {
|
||||
adc_ll_dig_set_convert_limit_num(cfg->conv_limit_num);
|
||||
adc_ll_dig_convert_limit_enable();
|
||||
} else {
|
||||
adc_ll_dig_convert_limit_disable();
|
||||
}
|
||||
adc_ll_dig_set_data_source(ADC_I2S_DATA_SRC_ADC);
|
||||
adc_ll_set_power_manage(ADC_POWER_SW_OFF);
|
||||
}
|
||||
|
||||
int adc_hal_convert(adc_ll_num_t adc_n, int channel)
|
||||
int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value)
|
||||
{
|
||||
adc_ll_rtc_enable_channel(adc_n, channel);
|
||||
adc_ll_rtc_start_convert(adc_n, channel);
|
||||
while (adc_ll_rtc_convert_is_done(adc_n) != true);
|
||||
return adc_ll_rtc_get_convert_value(adc_n);
|
||||
*value = adc_ll_rtc_get_convert_value(adc_n);
|
||||
return (int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*value));
|
||||
}
|
||||
|
||||
int adc_hal_hall_convert(void)
|
||||
{
|
||||
int Sens_Vp0;
|
||||
int Sens_Vn0;
|
||||
int Sens_Vp1;
|
||||
int Sens_Vn1;
|
||||
int hall_value;
|
||||
// convert for 4 times with different phase and outputs
|
||||
adc_ll_hall_phase_disable(); // hall phase
|
||||
Sens_Vp0 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0 );
|
||||
Sens_Vn0 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3 );
|
||||
adc_ll_hall_phase_enable();
|
||||
Sens_Vp1 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0 );
|
||||
Sens_Vn1 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3 );
|
||||
hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0);
|
||||
return hall_value;
|
||||
}
|
||||
|
||||
void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en)
|
||||
{
|
||||
adc_ll_rtc_output_invert(adc_n, inv_en);
|
||||
adc_ll_dig_output_invert(adc_n, inv_en);
|
||||
}
|
@ -86,7 +86,6 @@ INPUT = \
|
||||
##
|
||||
## Peripherals - API Reference
|
||||
##
|
||||
$(IDF_PATH)/components/driver/include/driver/adc.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/can.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/can_types.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/dac.h \
|
||||
@ -103,10 +102,12 @@ INPUT = \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_master.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_slave.h \
|
||||
$(IDF_PATH)/components/driver/$(IDF_TARGET)/include/touch_sensor.h \
|
||||
$(IDF_PATH)/components/driver/esp32s2/include/temp_sensor.h \
|
||||
$(IDF_PATH)/components/driver/$(IDF_TARGET)/include/driver/adc.h \
|
||||
$(IDF_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
|
||||
$(IDF_PATH)/components/driver/esp32s2/include/driver/temp_sensor.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/timer.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/touch_sensor_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/adc_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/uart.h \
|
||||
$(IDF_PATH)/components/esp_adc_cal/include/esp_adc_cal.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/rmt_types.h \
|
||||
|
@ -22,8 +22,10 @@
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static esp_adc_cal_characteristics_t *adc_chars;
|
||||
static const adc_channel_t channel = ADC_CHANNEL_6; //GPIO34 if ADC1, GPIO14 if ADC2
|
||||
static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
static const adc_channel_t channel = ADC_CHANNEL_6; // GPIO7 if ADC1, GPIO17 if ADC2
|
||||
static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
|
||||
#endif
|
||||
static const adc_atten_t atten = ADC_ATTEN_DB_0;
|
||||
static const adc_unit_t unit = ADC_UNIT_1;
|
||||
@ -67,7 +69,7 @@ void app_main(void)
|
||||
|
||||
//Configure ADC
|
||||
if (unit == ADC_UNIT_1) {
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
adc1_config_width(width);
|
||||
adc1_config_channel_atten(channel, atten);
|
||||
} else {
|
||||
adc2_config_channel_atten((adc2_channel_t)channel, atten);
|
||||
@ -76,7 +78,7 @@ void app_main(void)
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//Characterize ADC
|
||||
adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
|
||||
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);
|
||||
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
|
||||
print_char_val_type(val_type);
|
||||
#endif
|
||||
|
||||
@ -89,7 +91,7 @@ void app_main(void)
|
||||
adc_reading += adc1_get_raw((adc1_channel_t)channel);
|
||||
} else {
|
||||
int raw;
|
||||
adc2_get_raw((adc2_channel_t)channel, ADC_WIDTH_BIT_12, &raw);
|
||||
adc2_get_raw((adc2_channel_t)channel, width, &raw);
|
||||
adc_reading += raw;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,12 @@
|
||||
#define DAC_EXAMPLE_CHANNEL CONFIG_EXAMPLE_DAC_CHANNEL
|
||||
#define ADC2_EXAMPLE_CHANNEL CONFIG_EXAMPLE_ADC2_CHANNEL
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
|
||||
#endif
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
uint8_t output_data=0;
|
||||
@ -46,7 +52,7 @@ void app_main(void)
|
||||
printf("start conversion.\n");
|
||||
while(1) {
|
||||
dac_output_voltage( DAC_EXAMPLE_CHANNEL, output_data++ );
|
||||
r = adc2_get_raw( ADC2_EXAMPLE_CHANNEL, ADC_WIDTH_12Bit, &read_raw);
|
||||
r = adc2_get_raw( ADC2_EXAMPLE_CHANNEL, width, &read_raw);
|
||||
if ( r == ESP_OK ) {
|
||||
printf("%d: %d\n", output_data, read_raw );
|
||||
} else if ( r == ESP_ERR_INVALID_STATE ) {
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "audio_example_file.h"
|
||||
#include "esp_adc_cal.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
static const char* TAG = "ad/da";
|
||||
#define V_REF 1100
|
||||
#define ADC1_TEST_CHANNEL (ADC1_CHANNEL_7)
|
||||
@ -288,5 +290,4 @@ esp_err_t app_main(void)
|
||||
xTaskCreate(adc_read_task, "ADC read task", 2048, NULL, 5, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
/* Note: ESP32 don't support temperature sensor */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "temp_sensor.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
|
||||
static const char *TAG = "TempSensor";
|
||||
|
||||
|
@ -88,7 +88,11 @@ static int adc1_sample_and_show(int sampling_period)
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Enabling ADC1 on channel 6 / GPIO34.");
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
adc1_config_width(ADC_WIDTH_BIT_13);
|
||||
#endif
|
||||
adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_DB_11);
|
||||
|
||||
ESP_LOGI(TAG, "Enabling CW generator on DAC channel 1 / GPIO25.");
|
||||
|
@ -64,7 +64,11 @@ static void init_ulp_program(void)
|
||||
/* Note: when changing channel here, also change 'adc_channel' constant
|
||||
in adc.S */
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
adc1_config_width(ADC_WIDTH_BIT_13);
|
||||
#endif
|
||||
adc1_ulp_enable();
|
||||
|
||||
/* Set low and high thresholds, approx. 1.35V - 1.75V*/
|
||||
|
@ -336,7 +336,7 @@ example_test_012:
|
||||
|
||||
UT_001:
|
||||
extends: .unit_test_template
|
||||
parallel: 36
|
||||
parallel: 37
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
Loading…
Reference in New Issue
Block a user