add Comment for touchpad

This commit is contained in:
fuzhibo 2019-06-20 16:13:47 +08:00
parent fbb0687b97
commit 572084821b
43 changed files with 2780 additions and 1952 deletions

View file

@ -20,7 +20,6 @@
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/i2s_periph.h" #include "soc/i2s_periph.h"
#include "esp_log.h" #include "esp_log.h"
#include "soc/io_mux_reg.h"
#ifndef BOOTLOADER_BUILD #ifndef BOOTLOADER_BUILD
#include "esp_system.h" #include "esp_system.h"
@ -89,12 +88,6 @@ void bootloader_random_enable(void)
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP); CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP);
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP); CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP);
#elif CONFIG_IDF_TARGET_ESP32S2BETA #elif CONFIG_IDF_TARGET_ESP32S2BETA
/* Disable IO1 digital function for random function. */
PIN_INPUT_DISABLE(PERIPHS_IO_MUX_GPIO1_U);
PIN_PULLDWN_DIS(PERIPHS_IO_MUX_GPIO1_U);
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO1_U);
WRITE_PERI_REG(SYSCON_SARADC_SAR1_PATT_TAB1_REG, 0xFFFFFFFF);
SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL1_REG, SENS_SAR2_EN_TEST); SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL1_REG, SENS_SAR2_EN_TEST);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_CTRL_REG, RTC_CNTL_ULP_CP_FORCE_START_TOP); CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_CTRL_REG, RTC_CNTL_ULP_CP_FORCE_START_TOP);

View file

@ -6,8 +6,6 @@ set(COMPONENT_SRCS "can.c"
"periph_ctrl.c" "periph_ctrl.c"
"rmt.c" "rmt.c"
"rtc_module.c" "rtc_module.c"
"rtc_tempsensor.c"
"rtc_touchpad.c"
"sdspi_crc.c" "sdspi_crc.c"
"sdspi_host.c" "sdspi_host.c"
"sdspi_transaction.c" "sdspi_transaction.c"
@ -31,6 +29,13 @@ set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_PRIV_INCLUDEDIRS "include/driver") set(COMPONENT_PRIV_INCLUDEDIRS "include/driver")
set(COMPONENT_REQUIRES esp_ringbuf soc) #cannot totally hide soc headers, since there are a lot arguments in the driver are chip-dependent set(COMPONENT_REQUIRES esp_ringbuf soc) #cannot totally hide soc headers, since there are a lot arguments in the driver are chip-dependent
if(CONFIG_IDF_TARGET_ESP32S2BETA)
list(APPEND COMPONENT_SRCS "${CONFIG_IDF_TARGET}/rtc_tempsensor.c"
"${CONFIG_IDF_TARGET}/rtc_touchpad.c")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "${CONFIG_IDF_TARGET}/include")
endif()
register_component() register_component()

View file

@ -1,8 +1,9 @@
# #
# Component Makefile # Component Makefile
# #
COMPONENT_SRCDIRS := . $(IDF_TARGET)
COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_ADD_INCLUDEDIRS := include $(IDF_TARGET)/include
COMPONENT_PRIV_INCLUDEDIRS := include/driver COMPONENT_PRIV_INCLUDEDIRS := include/driver

View file

@ -0,0 +1,96 @@
// Copyright 2010-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.
#pragma once
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
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℃. */
TSENS_DAC_L2, /*!< offset = 0, measure range:-10℃ ~ 80℃, error < 1℃. */
TSENS_DAC_L3, /*!< offset = 1, measure range:-30℃ ~ 50℃, error < 2℃. */
TSENS_DAC_L4, /*!< offset = 2, measure range:-40℃ ~ 20℃, error < 3℃. */
TSENS_DAC_MAX,
TSENS_DAC_DEFAULT = TSENS_DAC_L2,
} temp_sensor_dac_offset_t;
typedef struct {
temp_sensor_dac_offset_t dac_offset; /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */
uint8_t clk_div; /*!< Default: 6 */
} temp_sensor_config_t;
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
.clk_div = 6}
/**
* @brief Set parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens);
/**
* @brief Get parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens);
/**
* @brief Start temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG
*/
esp_err_t temp_sensor_start(void);
/**
* @brief Stop temperature sensor measure.
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_stop(void);
/**
* @brief Read temperature sensor raw data.
* @param tsens_out Pointer to raw data, Range: 0 ~ 255
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG `tsens_out` is NULL
* - ESP_ERR_INVALID_STATE temperature sensor dont start
*/
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out);
/**
* @brief Read temperature sensor data that is converted to degrees Celsius.
* @note Should not be called from interrupt.
* @param celsius The measure output value.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG ARG is NULL.
* - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
*/
esp_err_t temp_sensor_read_celsius(float *celsius);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,144 @@
// 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 "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.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 "esp32s2beta/rom/ets_sys.h"
static const char *TAG = "tsens";
#define TSENS_CHECK(res, ret_val) ({ \
if (!(res)) { \
ESP_LOGE(TAG, "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__); \
return (ret_val); \
} \
})
#define TSENS_XPD_WAIT_DEFAULT 0xFF /* Set wait cycle time(8MHz) from power up to reset enable. */
#define TSENS_ADC_FACTOR (0.4386)
#define TSENS_DAC_FACTOR (27.88)
#define TSENS_SYS_OFFSET (20.52)
typedef struct {
int index;
int offset;
int set_val;
int range_min;
int range_max;
int error_max;
} tsens_dac_offset_t;
static const tsens_dac_offset_t dac_offset[TSENS_DAC_MAX] = {
/* DAC Offset reg_val min max error */
{TSENS_DAC_L0, -2, 5, 50, 125, 3},
{TSENS_DAC_L1, -1, 7, 20, 100, 2},
{TSENS_DAC_L2, 0, 15, -10, 80, 1},
{TSENS_DAC_L3, 1, 11, -30, 50, 2},
{TSENS_DAC_L4, 2, 10, -40, 20, 3},
};
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;
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;
SENS.sar_tctrl2.tsens_xpd_force = 1;
SENS.sar_tctrl2.tsens_reset = 1;// Reset the temp sensor.
SENS.sar_tctrl2.tsens_reset = 0;// Clear the reset status.
ESP_LOGI(TAG, "Config temperature range [%d°C ~ %d°C], error < %d°C",
dac_offset[tsens.dac_offset].range_min,
dac_offset[tsens.dac_offset].range_max,
dac_offset[tsens.dac_offset].error_max);
return ESP_OK;
}
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;
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;
}
}
tsens->clk_div = SENS.sar_tctrl.tsens_clk_div;
return ESP_OK;
}
esp_err_t temp_sensor_start(void)
{
if (rtc_tsens_mux == NULL) {
rtc_tsens_mux = xSemaphoreCreateMutex();
}
TSENS_CHECK(rtc_tsens_mux != NULL, ESP_ERR_NO_MEM);
SENS.sar_tctrl.tsens_dump_out = 0;
SENS.sar_tctrl2.tsens_clkgate_en = 1;
SENS.sar_tctrl.tsens_power_up = 1;
return ESP_OK;
}
esp_err_t temp_sensor_stop(void)
{
SENS.sar_tctrl.tsens_power_up = 0;
SENS.sar_tctrl2.tsens_clkgate_en = 0;
if (rtc_tsens_mux != NULL) {
vSemaphoreDelete(rtc_tsens_mux);
rtc_tsens_mux = NULL;
}
return ESP_OK;
}
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
{
TSENS_CHECK(tsens_out != NULL, ESP_ERR_INVALID_ARG);
TSENS_CHECK(rtc_tsens_mux != NULL, ESP_ERR_INVALID_STATE);
xSemaphoreTake(rtc_tsens_mux, portMAX_DELAY);
SENS.sar_tctrl.tsens_dump_out = 1;
while (!SENS.sar_tctrl.tsens_ready);
*tsens_out = SENS.sar_tctrl.tsens_out;
SENS.sar_tctrl.tsens_dump_out = 0;
xSemaphoreGive(rtc_tsens_mux);
return ESP_OK;
}
esp_err_t temp_sensor_read_celsius(float *celsius)
{
TSENS_CHECK(celsius != NULL, ESP_ERR_INVALID_ARG);
temp_sensor_config_t tsens;
uint32_t tsens_out = 0;
esp_err_t ret = temp_sensor_get_config(&tsens);
if (ret == ESP_OK) {
ret = temp_sensor_read_raw(&tsens_out);
TSENS_CHECK(ret == ESP_OK, ret);
const tsens_dac_offset_t *dac = &dac_offset[tsens.dac_offset];
*celsius = (TSENS_ADC_FACTOR * (float)tsens_out - TSENS_DAC_FACTOR * dac->offset - TSENS_SYS_OFFSET);
if (*celsius < dac->range_min || *celsius > dac->range_max) {
ESP_LOGW(TAG, "Exceeding the temperature range!");
ret = ESP_ERR_INVALID_STATE;
}
}
return ret;
}

View file

@ -0,0 +1,674 @@
// 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 "soc/rtc_periph.h"
#include "soc/sens_periph.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_io_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.h"
#include "soc/periph_defs.h"
#include "rtc_io.h"
#include "touch_pad.h"
#include "freertos/FreeRTOS.h"
#include "freertos/xtensa_api.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "esp_intr_alloc.h"
#include "sys/lock.h"
#include "driver/rtc_cntl.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp32s2beta/rom/ets_sys.h"
#ifndef NDEBUG
// Enable built-in checks in queue.h in debug builds
#define INVARIANTS
#endif
#include "sys/queue.h"
#define TOUCH_PAD_FILTER_FACTOR_DEFAULT (4) // IIR filter coefficient.
#define TOUCH_PAD_SHIFT_DEFAULT (4) // Increase computing accuracy.
#define TOUCH_PAD_SHIFT_ROUND_DEFAULT (8) // ROUND = 2^(n-1); rounding off for fractional.
#define TOUCH_PAD_MEASURE_WAIT_DEFAULT (0xFF) // The timer frequency is 8Mhz, the max value is 0xff
#define DAC_ERR_STR_CHANNEL_ERROR "DAC channel error"
#define RTC_MODULE_CHECK(a, str, ret_val) ({ \
if (!(a)) { \
ESP_LOGE(RTC_MODULE_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret_val); \
} \
})
#define RTC_RES_CHECK(res, ret_val) ({ \
if ( (res) != ESP_OK) { \
ESP_LOGE(RTC_MODULE_TAG,"%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__);\
return (ret_val); \
} \
})
static portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
#define RTC_TOUCH_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
#define RTC_TOUCH_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
static SemaphoreHandle_t rtc_touch_mux = NULL;
static const char *RTC_MODULE_TAG = "RTC_MODULE";
/*---------------------------------------------------------------
Touch Pad
---------------------------------------------------------------*/
esp_err_t touch_pad_isr_register(intr_handler_t fn, void *arg, touch_pad_intr_mask_t intr_mask)
{
assert(fn != NULL);
return rtc_isr_register(fn, arg, TOUCH_PAD_INTR_MASK_ALL & (intr_mask << RTC_CNTL_TOUCH_DONE_INT_ENA_S));
}
esp_err_t touch_pad_isr_deregister(intr_handler_t fn, void *arg)
{
return rtc_isr_deregister(fn, arg);
}
esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_times)
{
RTC_TOUCH_ENTER_CRITICAL();
// touch sensor sleep cycle Time = sleep_cycle / RTC_SLOW_CLK( can be 150k or 32k depending on the options)
RTCCNTL.touch_ctrl1.touch_sleep_cycles = sleep_cycle;
//The times of charge and discharge in each measure process of touch channels.
RTCCNTL.touch_ctrl1.touch_meas_num = meas_times;
//the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD
RTCCNTL.touch_ctrl2.touch_xpd_wait = TOUCH_PAD_MEASURE_WAIT_DEFAULT; //wait volt stable
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_times)
{
if (sleep_cycle) {
*sleep_cycle = RTCCNTL.touch_ctrl1.touch_sleep_cycles;
}
if (meas_times) {
*meas_times = RTCCNTL.touch_ctrl1.touch_meas_num;
}
return ESP_OK;
}
esp_err_t touch_pad_set_inactive_connect(touch_pad_conn_type_t type)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_scan_ctrl.touch_inactive_connection = type;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_get_inactive_connect(touch_pad_conn_type_t *type)
{
RTC_MODULE_CHECK(type != NULL, "parameter is NULL", ESP_ERR_INVALID_ARG);
*type = RTCCNTL.touch_scan_ctrl.touch_inactive_connection;
return ESP_OK;
}
esp_err_t touch_pad_set_voltage(touch_high_volt_t refh, touch_low_volt_t refl, touch_volt_atten_t atten)
{
RTC_TOUCH_ENTER_CRITICAL();
if (refh > TOUCH_HVOLT_KEEP) {
RTCCNTL.touch_ctrl2.touch_drefh = refh;
}
if (refl > TOUCH_LVOLT_KEEP) {
RTCCNTL.touch_ctrl2.touch_drefl = refl;
}
if (atten > TOUCH_HVOLT_ATTEN_KEEP) {
RTCCNTL.touch_ctrl2.touch_drange = atten;
}
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_get_voltage(touch_high_volt_t *refh, touch_low_volt_t *refl, touch_volt_atten_t *atten)
{
if (refh) {
*refh = RTCCNTL.touch_ctrl2.touch_drefh;
}
if (refl) {
*refl = RTCCNTL.touch_ctrl2.touch_drefl;
}
if (atten) {
*atten = RTCCNTL.touch_ctrl2.touch_drange;
}
return ESP_OK;
}
esp_err_t touch_pad_set_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t slope, touch_tie_opt_t opt)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCIO.touch_pad[touch_num].tie_opt = opt;
RTCIO.touch_pad[touch_num].dac = slope;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_get_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t *slope, touch_tie_opt_t *opt)
{
if (slope) {
*slope = RTCIO.touch_pad[touch_num].dac;
}
if (opt) {
*opt = RTCIO.touch_pad[touch_num].tie_opt;
}
return ESP_OK;
}
esp_err_t touch_pad_io_init(touch_pad_t touch_num)
{
RTC_MODULE_CHECK(touch_num != TOUCH_DENOISE_CHANNEL,
"please use `touch_pad_denoise_enable` to set denoise channel", ESP_ERR_INVALID_ARG);
rtc_gpio_init(touch_num);
rtc_gpio_set_direction(touch_num, RTC_GPIO_MODE_DISABLED);
rtc_gpio_pulldown_dis(touch_num);
rtc_gpio_pullup_dis(touch_num);
return ESP_OK;
}
esp_err_t touch_pad_wait_init_done()
{
// TODO
return ESP_FAIL;
}
esp_err_t touch_pad_fsm_start()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_ctrl2.touch_clkgate_en = 1; //enable touch clock for FSM. or force enable.
SENS.sar_touch_chn_st.touch_channel_clr = TOUCH_PAD_BIT_MASK_MAX; // clear SENS_TOUCH_SLP_BASELINE
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_fsm_stop()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_ctrl2.touch_start_en = 0; //stop touch fsm
RTCCNTL.touch_ctrl2.touch_slp_timer_en = 0;
RTCCNTL.touch_ctrl2.touch_clkgate_en = 0; //enable touch clock for FSM. or force enable.
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_set_fsm_mode(touch_fsm_mode_t mode)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_ctrl2.touch_start_en = 0; //stop touch fsm
RTCCNTL.touch_ctrl2.touch_start_force = mode;
RTCCNTL.touch_ctrl2.touch_slp_timer_en = (mode == TOUCH_FSM_MODE_TIMER ? 1 : 0);
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_get_fsm_mode(touch_fsm_mode_t *mode)
{
assert(mode != NULL);
*mode = RTCCNTL.touch_ctrl2.touch_start_force;
return ESP_OK;
}
bool touch_pad_meas_is_done(void)
{
return SENS.sar_touch_chn_st.touch_meas_done;
}
esp_err_t touch_pad_sw_start(void)
{
RTC_MODULE_CHECK((RTCCNTL.touch_ctrl2.touch_start_force == TOUCH_FSM_MODE_SW),
"touch fsm mode error", ESP_ERR_INVALID_STATE);
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_ctrl2.touch_start_en = 0;
RTCCNTL.touch_ctrl2.touch_start_en = 1;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint32_t threshold)
{
RTC_MODULE_CHECK((touch_num < TOUCH_PAD_MAX) && (touch_num != TOUCH_DENOISE_CHANNEL), "touch num error", ESP_ERR_INVALID_ARG);
RTC_TOUCH_ENTER_CRITICAL();
SENS.touch_thresh[touch_num - 1].thresh = threshold;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint32_t *threshold)
{
if (threshold) {
*threshold = SENS.touch_thresh[touch_num - 1].thresh;
}
return ESP_OK;
}
esp_err_t touch_pad_set_group_mask(uint16_t enable_mask)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_scan_ctrl.touch_scan_pad_map |= (enable_mask & TOUCH_PAD_BIT_MASK_MAX);
SENS.sar_touch_conf.touch_outen |= (enable_mask & TOUCH_PAD_BIT_MASK_MAX);
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_get_group_mask(uint16_t *enable_mask)
{
RTC_TOUCH_ENTER_CRITICAL();
*enable_mask = SENS.sar_touch_conf.touch_outen \
& RTCCNTL.touch_scan_ctrl.touch_scan_pad_map \
& TOUCH_PAD_BIT_MASK_MAX;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_clear_group_mask(uint16_t enable_mask)
{
RTC_TOUCH_ENTER_CRITICAL();
SENS.sar_touch_conf.touch_outen &= ~(enable_mask & TOUCH_PAD_BIT_MASK_MAX);
RTCCNTL.touch_scan_ctrl.touch_scan_pad_map &= ~(enable_mask & TOUCH_PAD_BIT_MASK_MAX);
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
uint32_t IRAM_ATTR touch_pad_get_status(void)
{
return (SENS.sar_touch_chn_st.touch_pad_active & TOUCH_PAD_BIT_MASK_MAX);
}
static esp_err_t touch_pad_clear_status(void)
{
SENS.sar_touch_conf.touch_status_clr = 1;
return ESP_OK;
}
touch_pad_t IRAM_ATTR touch_pad_get_scan_curr(void)
{
return (touch_pad_t)(SENS.sar_touch_status0.touch_scan_curr);
}
esp_err_t touch_pad_intr_enable(touch_pad_intr_mask_t int_mask)
{
RTC_TOUCH_ENTER_CRITICAL();
if (int_mask & TOUCH_PAD_INTR_MASK_DONE) {
RTCCNTL.int_ena.rtc_touch_done = 1;
}
if (int_mask & TOUCH_PAD_INTR_MASK_ACTIVE) {
RTCCNTL.int_ena.rtc_touch_active = 1;
}
if (int_mask & TOUCH_PAD_INTR_MASK_INACTIVE) {
RTCCNTL.int_ena.rtc_touch_inactive = 1;
}
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_intr_disable(touch_pad_intr_mask_t int_mask)
{
RTC_TOUCH_ENTER_CRITICAL();
if (int_mask & TOUCH_PAD_INTR_MASK_DONE) {
RTCCNTL.int_ena.rtc_touch_done = 0;
}
if (int_mask & TOUCH_PAD_INTR_MASK_ACTIVE) {
RTCCNTL.int_ena.rtc_touch_active = 0;
}
if (int_mask & TOUCH_PAD_INTR_MASK_INACTIVE) {
RTCCNTL.int_ena.rtc_touch_inactive = 0;
}
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
uint32_t touch_pad_intr_status_get_mask()
{
return ((REG_READ(RTC_CNTL_INT_ST_REG) >> (RTC_CNTL_TOUCH_DONE_INT_ST_S)) & TOUCH_PAD_INTR_MASK_ALL);
}
esp_err_t touch_pad_config(touch_pad_t touch_num)
{
RTC_MODULE_CHECK(touch_num != TOUCH_DENOISE_CHANNEL, \
"please use `touch_pad_denoise_enable` to set denoise channel", ESP_ERR_INVALID_ARG);
touch_pad_io_init(touch_num);
touch_pad_set_cnt_mode(touch_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_LOW);
touch_pad_set_thresh(touch_num, TOUCH_PAD_THRESHOLD_MAX);
touch_pad_set_group_mask(BIT(touch_num));
return ESP_OK;
}
esp_err_t touch_pad_init()
{
if (rtc_touch_mux == NULL) {
rtc_touch_mux = xSemaphoreCreateMutex();
}
if (rtc_touch_mux == NULL) {
return ESP_ERR_NO_MEM;
}
touch_pad_intr_disable(TOUCH_PAD_INTR_ALL);
touch_pad_clear_group_mask(TOUCH_PAD_BIT_MASK_MAX);
touch_pad_clear_status();
touch_pad_set_meas_time(TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_MEASURE_CYCLE_DEFAULT);
// Set reference voltage for charging/discharging
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V5);
touch_pad_set_inactive_connect(TOUCH_PAD_CONN_GND);
return ESP_OK;
}
esp_err_t touch_pad_deinit()
{
RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL);
xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
touch_pad_fsm_stop();
touch_pad_clear_status();
touch_pad_intr_disable(TOUCH_PAD_INTR_ALL);
xSemaphoreGive(rtc_touch_mux);
vSemaphoreDelete(rtc_touch_mux);
rtc_touch_mux = NULL;
return ESP_OK;
}
esp_err_t IRAM_ATTR touch_pad_read_raw_data(touch_pad_t touch_num, uint32_t *raw_data)
{
if (raw_data) {
*raw_data = SENS.touch_meas[touch_num].meas_out;
}
return ESP_OK;
}
esp_err_t IRAM_ATTR touch_pad_filter_baseline_read(touch_pad_t touch_num, uint32_t *basedata)
{
RTC_MODULE_CHECK(touch_num != TOUCH_DENOISE_CHANNEL, "denoise channel don't support", ESP_ERR_INVALID_ARG);
if (basedata) {
*basedata = SENS.sar_touch_status[touch_num - 1].touch_pad_baseline;
}
return ESP_OK;
}
esp_err_t touch_pad_filter_debounce_read(touch_pad_t touch_num, uint32_t *debounce)
{
RTC_MODULE_CHECK(touch_num != TOUCH_DENOISE_CHANNEL, "denoise channel don't support", ESP_ERR_INVALID_ARG);
if (debounce) {
*debounce = SENS.sar_touch_status[touch_num - 1].touch_pad_debounce;
}
return ESP_OK;
}
/* Should be call after clk enable and filter enable. */
esp_err_t touch_pad_filter_baseline_reset(touch_pad_t touch_num)
{
RTC_TOUCH_ENTER_CRITICAL();
if (touch_num == TOUCH_PAD_MAX) {
SENS.sar_touch_chn_st.touch_channel_clr = TOUCH_PAD_BIT_MASK_MAX;
} else {
SENS.sar_touch_chn_st.touch_channel_clr = BIT(touch_num);
}
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_filter_set_config(touch_filter_config_t *filter_info)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_filter_ctrl.touch_filter_mode = filter_info->mode;
RTCCNTL.touch_filter_ctrl.touch_debounce = filter_info->debounce_cnt;
RTCCNTL.touch_filter_ctrl.touch_hysteresis = filter_info->hysteresis_thr;
RTCCNTL.touch_filter_ctrl.touch_noise_thres = filter_info->noise_thr;
RTCCNTL.touch_filter_ctrl.touch_neg_noise_thres = filter_info->noise_neg_thr;
RTCCNTL.touch_filter_ctrl.touch_neg_noise_limit = filter_info->neg_noise_limit;
RTCCNTL.touch_filter_ctrl.touch_jitter_step = filter_info->jitter_step;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_filter_get_config(touch_filter_config_t *filter_info)
{
RTC_TOUCH_ENTER_CRITICAL();
filter_info->mode = RTCCNTL.touch_filter_ctrl.touch_filter_mode;
filter_info->debounce_cnt = RTCCNTL.touch_filter_ctrl.touch_debounce;
filter_info->hysteresis_thr = RTCCNTL.touch_filter_ctrl.touch_hysteresis;
filter_info->noise_thr = RTCCNTL.touch_filter_ctrl.touch_noise_thres;
filter_info->noise_neg_thr = RTCCNTL.touch_filter_ctrl.touch_neg_noise_thres;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_filter_enable()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_filter_ctrl.touch_filter_en = 1;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_filter_disable()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_filter_ctrl.touch_filter_en = 0;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_denoise_enable()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_scan_ctrl.touch_scan_pad_map &= ~(BIT(TOUCH_DENOISE_CHANNEL));
RTCCNTL.touch_scan_ctrl.touch_denoise_en = 1;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_denoise_disable()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_scan_ctrl.touch_denoise_en = 0;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_denoise_set_config(touch_pad_denoise_t denoise)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCIO.touch_pad[TOUCH_DENOISE_CHANNEL].tie_opt = TOUCH_PAD_TIE_OPT_LOW;
RTCIO.touch_pad[TOUCH_DENOISE_CHANNEL].dac = TOUCH_PAD_SLOPE_7;
RTCCNTL.touch_ctrl2.touch_refc = denoise.cap_level;
RTCCNTL.touch_scan_ctrl.touch_denoise_res = denoise.grade;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_denoise_get_config(touch_pad_denoise_t *denoise)
{
RTC_TOUCH_ENTER_CRITICAL();
denoise->grade = RTCCNTL.touch_scan_ctrl.touch_denoise_res;
denoise->cap_level = RTCCNTL.touch_ctrl2.touch_refc;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_denoise_data_get(uint32_t *data)
{
if (data) {
*data = SENS.sar_touch_status0.touch_denoise_data;
}
return ESP_OK;
}
esp_err_t touch_pad_waterproof_set_config(touch_pad_waterproof_t waterproof)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_scan_ctrl.touch_out_ring = waterproof.guard_ring_pad;
RTCCNTL.touch_scan_ctrl.touch_bufdrv = waterproof.shield_driver;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_waterproof_get_config(touch_pad_waterproof_t *waterproof)
{
if (waterproof) {
RTC_TOUCH_ENTER_CRITICAL();
waterproof->guard_ring_pad = RTCCNTL.touch_scan_ctrl.touch_out_ring;
waterproof->shield_driver = RTCCNTL.touch_scan_ctrl.touch_bufdrv;
RTC_TOUCH_EXIT_CRITICAL();
}
return ESP_OK;
}
esp_err_t touch_pad_waterproof_enable()
{
touch_pad_io_init(TOUCH_SHIELD_CHANNEL);
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_scan_ctrl.touch_scan_pad_map &= ~(BIT(TOUCH_SHIELD_CHANNEL));
RTCCNTL.touch_scan_ctrl.touch_shield_pad_en = 1;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_waterproof_disable()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_scan_ctrl.touch_shield_pad_en = 0;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_proximity_set_config(touch_pad_proximity_t proximity)
{
RTC_TOUCH_ENTER_CRITICAL();
if (proximity.select_pad0) {
SENS.sar_touch_conf.touch_approach_pad0 = proximity.select_pad0;
}
if (proximity.select_pad1) {
SENS.sar_touch_conf.touch_approach_pad1 = proximity.select_pad1;
}
if (proximity.select_pad2) {
SENS.sar_touch_conf.touch_approach_pad2 = proximity.select_pad2;
}
RTCCNTL.touch_approach.touch_approach_meas_time = proximity.meas_num;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_proximity_get_config(touch_pad_proximity_t *proximity)
{
if (proximity) {
RTC_TOUCH_ENTER_CRITICAL();
proximity->select_pad0 = SENS.sar_touch_conf.touch_approach_pad0;
proximity->select_pad1 = SENS.sar_touch_conf.touch_approach_pad1;
proximity->select_pad2 = SENS.sar_touch_conf.touch_approach_pad2;
proximity->meas_num = RTCCNTL.touch_approach.touch_approach_meas_time;
RTC_TOUCH_EXIT_CRITICAL();
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t touch_pad_proximity_get_meas_cnt(touch_pad_t touch_num, uint32_t *cnt)
{
if (cnt == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (SENS.sar_touch_conf.touch_approach_pad0 == touch_num) {
*cnt = SENS.sar_touch_status16.touch_approach_pad0_cnt;
} else if (SENS.sar_touch_conf.touch_approach_pad1 == touch_num) {
*cnt = SENS.sar_touch_status16.touch_approach_pad1_cnt;
} else if (SENS.sar_touch_conf.touch_approach_pad2 == touch_num) {
*cnt = SENS.sar_touch_status16.touch_approach_pad2_cnt;
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t touch_pad_proximity_data_get(touch_pad_t touch_num, uint32_t *measure_out)
{
if ((SENS.sar_touch_conf.touch_approach_pad0 != touch_num)
&& (SENS.sar_touch_conf.touch_approach_pad1 != touch_num)
&& (SENS.sar_touch_conf.touch_approach_pad2 != touch_num)) {
return ESP_ERR_INVALID_ARG;
}
if (ESP_OK != touch_pad_filter_baseline_read(touch_num, measure_out)) {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t touch_pad_reset()
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_ctrl2.touch_reset = 0;
RTCCNTL.touch_ctrl2.touch_reset = 1;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
/************** sleep pad setting ***********************/
esp_err_t touch_pad_sleep_channel_config(touch_pad_sleep_channel_t slp_config)
{
RTC_TOUCH_ENTER_CRITICAL();
RTCCNTL.touch_slp_thres.touch_slp_pad = slp_config.touch_num;
RTCCNTL.touch_slp_thres.touch_slp_th = slp_config.sleep_pad_threshold;
RTCCNTL.touch_slp_thres.touch_slp_approach_en = slp_config.en_proximity;
RTC_TOUCH_EXIT_CRITICAL();
return ESP_OK;
}
esp_err_t touch_pad_sleep_channel_baseline_get(uint32_t *baseline)
{
if (baseline) {
*baseline = REG_GET_FIELD(SENS_SAR_TOUCH_STATUS15_REG, SENS_TOUCH_SLP_BASELINE);
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t touch_pad_sleep_channel_debounce_get(uint32_t *debounce)
{
if (debounce) {
*debounce = REG_GET_FIELD(SENS_SAR_TOUCH_STATUS15_REG, SENS_TOUCH_SLP_DEBOUNCE);
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t touch_pad_sleep_channel_proximity_cnt_get(uint32_t *approach_cnt)
{
if (approach_cnt) {
*approach_cnt = REG_GET_FIELD(SENS_SAR_TOUCH_STATUS16_REG, SENS_TOUCH_SLP_APPROACH_CNT);
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t touch_pad_get_wakeup_status(touch_pad_t *pad_num)
{
if (pad_num) {
*pad_num = (touch_pad_t)RTCCNTL.touch_slp_thres.touch_slp_pad;
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}

View file

@ -52,61 +52,37 @@ typedef enum {
#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11 #define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11
#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12 #define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12
typedef enum {
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 (ESP32), GPIO1 (ESP32-S2) */
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO37 (ESP32), GPIO2 (ESP32-S2) */
ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO38 (ESP32), GPIO3 (ESP32-S2) */
ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO39 (ESP32), GPIO4 (ESP32-S2) */
ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO32 (ESP32), GPIO5 (ESP32-S2) */
ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO33 (ESP32), GPIO6 (ESP32-S2) */
ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO34 (ESP32), GPIO7 (ESP32-S2) */
ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO35 (ESP32), GPIO8 (ESP32-S2) */
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
typedef enum {
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO37 */
ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO38 */
ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO39 */
ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO32 */
ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO33 */
ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO34 */
ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO35 */
ADC1_CHANNEL_MAX, ADC1_CHANNEL_MAX,
} adc1_channel_t;
typedef enum {
ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO4 */
ADC2_CHANNEL_1, /*!< ADC2 channel 1 is GPIO0 */
ADC2_CHANNEL_2, /*!< ADC2 channel 2 is GPIO2 */
ADC2_CHANNEL_3, /*!< ADC2 channel 3 is GPIO15 */
ADC2_CHANNEL_4, /*!< ADC2 channel 4 is GPIO13 */
ADC2_CHANNEL_5, /*!< ADC2 channel 5 is GPIO12 */
ADC2_CHANNEL_6, /*!< ADC2 channel 6 is GPIO14 */
ADC2_CHANNEL_7, /*!< ADC2 channel 7 is GPIO27 */
ADC2_CHANNEL_8, /*!< ADC2 channel 8 is GPIO25 */
ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO26 */
ADC2_CHANNEL_MAX,
} adc2_channel_t;
#elif CONFIG_IDF_TARGET_ESP32S2BETA #elif CONFIG_IDF_TARGET_ESP32S2BETA
typedef enum { ADC1_CHANNEL_8, /*!< ADC1 channel 6 is GPIO9 (ESP32-S2)*/
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO1 */ ADC1_CHANNEL_9, /*!< ADC1 channel 7 is GPIO10 (ESP32-S2) */
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO2 */
ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO3 */
ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO4 */
ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO5 */
ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO6 */
ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO7 */
ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO8 */
ADC1_CHANNEL_8, /*!< ADC1 channel 6 is GPIO9 */
ADC1_CHANNEL_9, /*!< ADC1 channel 7 is GPIO10 */
ADC1_CHANNEL_MAX, ADC1_CHANNEL_MAX,
#endif
} adc1_channel_t; } adc1_channel_t;
typedef enum { typedef enum {
ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO11 */ ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO4 (ESP32), GPIO11 (ESP32-S2) */
ADC2_CHANNEL_1, /*!< ADC2 channel 1 is GPIO12 */ ADC2_CHANNEL_1, /*!< ADC2 channel 1 is GPIO0 (ESP32), GPIO12 (ESP32-S2) */
ADC2_CHANNEL_2, /*!< ADC2 channel 2 is GPIO13 */ ADC2_CHANNEL_2, /*!< ADC2 channel 2 is GPIO2 (ESP32), GPIO13 (ESP32-S2) */
ADC2_CHANNEL_3, /*!< ADC2 channel 3 is GPIO14 */ ADC2_CHANNEL_3, /*!< ADC2 channel 3 is GPIO15 (ESP32), GPIO14 (ESP32-S2) */
ADC2_CHANNEL_4, /*!< ADC2 channel 4 is GPIO15 */ ADC2_CHANNEL_4, /*!< ADC2 channel 4 is GPIO13 (ESP32), GPIO15 (ESP32-S2) */
ADC2_CHANNEL_5, /*!< ADC2 channel 5 is GPIO16 */ ADC2_CHANNEL_5, /*!< ADC2 channel 5 is GPIO12 (ESP32), GPIO16 (ESP32-S2) */
ADC2_CHANNEL_6, /*!< ADC2 channel 6 is GPIO17 */ ADC2_CHANNEL_6, /*!< ADC2 channel 6 is GPIO14 (ESP32), GPIO17 (ESP32-S2) */
ADC2_CHANNEL_7, /*!< ADC2 channel 7 is GPIO18 */ ADC2_CHANNEL_7, /*!< ADC2 channel 7 is GPIO27 (ESP32), GPIO18 (ESP32-S2) */
ADC2_CHANNEL_8, /*!< ADC2 channel 8 is GPIO19 */ ADC2_CHANNEL_8, /*!< ADC2 channel 8 is GPIO25 (ESP32), GPIO19 (ESP32-S2) */
ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO20 */ ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO26 (ESP32), GPIO20 (ESP32-S2) */
ADC2_CHANNEL_MAX, ADC2_CHANNEL_MAX,
} adc2_channel_t; } adc2_channel_t;
#endif
typedef enum { typedef enum {
ADC_CHANNEL_0 = 0, /*!< ADC channel */ ADC_CHANNEL_0 = 0, /*!< ADC channel */

View file

@ -23,19 +23,11 @@ extern "C" {
#include "esp_err.h" #include "esp_err.h"
#include "soc/dac_periph.h" #include "soc/dac_periph.h"
#if CONFIG_IDF_TARGET_ESP32
typedef enum { typedef enum {
DAC_CHANNEL_1 = 1, /*!< DAC channel 1 is GPIO25 */ DAC_CHANNEL_1 = 1, /*!< DAC channel 1 is GPIO25 (ESP32), GPIO17 (ESP32-S2) */
DAC_CHANNEL_2, /*!< DAC channel 2 is GPIO26 */ DAC_CHANNEL_2, /*!< DAC channel 2 is GPIO26 (ESP32), GPIO18 (ESP32-S2) */
DAC_CHANNEL_MAX, DAC_CHANNEL_MAX,
} dac_channel_t; } dac_channel_t;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
typedef enum {
DAC_CHANNEL_1 = 1, /*!< DAC channel 1 is GPIO17 */
DAC_CHANNEL_2, /*!< DAC channel 2 is GPIO18 */
DAC_CHANNEL_MAX,
} dac_channel_t;
#endif
/** /**
* @brief Get the gpio number of a specific DAC channel. * @brief Get the gpio number of a specific DAC channel.

View file

@ -316,7 +316,18 @@ typedef enum {
GPIO_NUM_26 = 26, /*!< GPIO26, input and output */ GPIO_NUM_26 = 26, /*!< GPIO26, input and output */
GPIO_NUM_27 = 27, /*!< GPIO27, input and output */ GPIO_NUM_27 = 27, /*!< GPIO27, input and output */
GPIO_NUM_28 = 28, /*!< GPIO28, input and output */ GPIO_NUM_28 = 28, /*!< GPIO28, input and output */
GPIO_NUM_29 = 29, /*!< GPIO29, input and output */
GPIO_NUM_30 = 30, /*!< GPIO30, input and output */
GPIO_NUM_31 = 31, /*!< GPIO31, input and output */
GPIO_NUM_32 = 32, /*!< GPIO32, input and output */ GPIO_NUM_32 = 32, /*!< GPIO32, input and output */
GPIO_NUM_33 = 33, /*!< GPIO33, input and output */
GPIO_NUM_34 = 34, /*!< GPIO34, input and output */
GPIO_NUM_35 = 35, /*!< GPIO35, input and output */
GPIO_NUM_36 = 36, /*!< GPIO36, input and output */
GPIO_NUM_37 = 37, /*!< GPIO37, input and output */
GPIO_NUM_38 = 38, /*!< GPIO38, input and output */
GPIO_NUM_39 = 39, /*!< GPIO39, input and output */
GPIO_NUM_40 = 40, /*!< GPIO40, input and output */
GPIO_NUM_41 = 41, /*!< GPIO41, input and output */ GPIO_NUM_41 = 41, /*!< GPIO41, input and output */
GPIO_NUM_42 = 42, /*!< GPIO42, input and output */ GPIO_NUM_42 = 42, /*!< GPIO42, input and output */
GPIO_NUM_43 = 43, /*!< GPIO43, input and output */ GPIO_NUM_43 = 43, /*!< GPIO43, input and output */

View file

@ -1,36 +0,0 @@
#ifndef _TEMP_SENSOR_H_
#define _TEMP_SENSOR_H_
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_IDF_TARGET_ESP32S2BETA
typedef enum {
TEMP_SENSOR_DAC_L0 = 5, // offset = -2, range: 50℃ ~ 125℃, error < 3℃.
TEMP_SENSOR_DAC_L1 = 7, // offset = -1, range: 20℃ ~ 100℃, error < 2℃.
TEMP_SENSOR_DAC_L2 = 15, // offset = 0, range:-10℃ ~ 80℃, error < 1℃.
TEMP_SENSOR_DAC_L3 = 11, // offset = 1, range:-30℃ ~ 50℃, error < 2℃.
TEMP_SENSOR_DAC_L4 = 10, // offset = 2, range:-40℃ ~ 20℃, error < 3℃.
TEMP_SENSOR_DAC_DEFAULT = TEMP_SENSOR_DAC_L2,
} temp_sensor_dac_offset_t;;
typedef struct temp_sensor {
temp_sensor_dac_offset_t dac_offset;
uint8_t clk_div;
} temp_sensor_t;
esp_err_t temp_sensor_set_config(temp_sensor_t temps);
esp_err_t temp_sensor_get_config(temp_sensor_t *temps);
esp_err_t temp_sensor_start(void);
esp_err_t temp_sensor_stop(void);
esp_err_t temp_sensor_read(uint8_t *temp_out);
#endif
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -86,7 +86,9 @@ static const char *RTC_MODULE_TAG = "RTC_MODULE";
} }while (0) } }while (0)
portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED; portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
#if CONFIG_IDF_TARGET_ESP32
static SemaphoreHandle_t rtc_touch_mux = NULL; static SemaphoreHandle_t rtc_touch_mux = NULL;
#endif
/* /*
In ADC2, there're two locks used for different cases: In ADC2, there're two locks used for different cases:
1. lock shared with app and WIFI: 1. lock shared with app and WIFI:
@ -124,48 +126,6 @@ static uint16_t s_touch_pad_init_bit = 0x0000;
static filter_cb_t s_filter_cb = NULL; static filter_cb_t s_filter_cb = NULL;
#endif #endif
#if CONFIG_IDF_TARGET_ESP32S2BETA
typedef volatile struct {
uint32_t reserved0: 13;
uint32_t fun_ie: 1; /*input enable in work mode*/
uint32_t slp_oe: 1; /*output enable in sleep mode*/
uint32_t slp_ie: 1; /*input enable in sleep mode*/
uint32_t slp_sel: 1; /*1: enable sleep mode during sleep 0: no sleep mode*/
uint32_t fun_sel: 2; /*function sel*/
uint32_t mux_sel: 1; /*1: use RTC GPIO 0: use digital GPIO*/
uint32_t reserved20: 7;
uint32_t rue: 1; /*RUE*/
uint32_t rde: 1; /*RDE*/
uint32_t drv: 2; /*DRV*/
uint32_t reserved31: 1;
} rtc_gpio_info_t;
static rtc_gpio_info_t* rtc_gpio[RTC_GPIO_NUMBER] = {
&RTCIO.touch_pad[0].val,
&RTCIO.touch_pad[1].val,
&RTCIO.touch_pad[2].val,
&RTCIO.touch_pad[3].val,
&RTCIO.touch_pad[4].val,
&RTCIO.touch_pad[5].val,
&RTCIO.touch_pad[6].val,
&RTCIO.touch_pad[7].val,
&RTCIO.touch_pad[8].val,
&RTCIO.touch_pad[9].val,
&RTCIO.touch_pad[10].val,
&RTCIO.touch_pad[11].val,
&RTCIO.touch_pad[12].val,
&RTCIO.touch_pad[13].val,
&RTCIO.touch_pad[14].val,
&RTCIO.xtal_32p_pad.val,
&RTCIO.xtal_32n_pad.val,
&RTCIO.pad_dac[0].val,
&RTCIO.pad_dac[1].val,
&RTCIO.rtc_pad19.val,
&RTCIO.rtc_pad20.val,
&RTCIO.rtc_pad21.val
};
#endif
typedef enum { typedef enum {
ADC_CTRL_RTC = 0, ADC_CTRL_RTC = 0,
ADC_CTRL_ULP = 1, ADC_CTRL_ULP = 1,
@ -529,10 +489,13 @@ esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num)
esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num) esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num)
{ {
#if CONFIG_IDF_TARGET_ESP32
if (rtc_gpio_desc[gpio_num].reg == 0) { if (rtc_gpio_desc[gpio_num].reg == 0) {
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
#elif CONFIG_IDF_TARGET_ESP32S2BETA
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
#endif
rtc_gpio_pullup_dis(gpio_num); rtc_gpio_pullup_dis(gpio_num);
rtc_gpio_pulldown_dis(gpio_num); rtc_gpio_pulldown_dis(gpio_num);
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED); rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
@ -994,11 +957,9 @@ uint32_t IRAM_ATTR touch_pad_get_status()
return TOUCH_BITS_SWAP(status); return TOUCH_BITS_SWAP(status);
} }
esp_err_t IRAM_ATTR touch_pad_clear_status() esp_err_t touch_pad_clear_status()
{ {
portENTER_CRITICAL(&rtc_spinlock);
SENS.sar_touch_ctrl2.touch_meas_en_clr = 1; SENS.sar_touch_ctrl2.touch_meas_en_clr = 1;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK; return ESP_OK;
} }
@ -1281,6 +1242,7 @@ esp_err_t touch_pad_get_wakeup_status(touch_pad_t *pad_num)
static esp_err_t adc_set_fsm_time(int rst_wait, int start_wait, int standby_wait, int sample_cycle) static esp_err_t adc_set_fsm_time(int rst_wait, int start_wait, int standby_wait, int sample_cycle)
{ {
portENTER_CRITICAL(&rtc_spinlock); portENTER_CRITICAL(&rtc_spinlock);
#if CONFIG_IDF_TARGET_ESP32
// Internal FSM reset wait time // Internal FSM reset wait time
if (rst_wait >= 0) { if (rst_wait >= 0) {
SYSCON.saradc_fsm.rstb_wait = rst_wait; SYSCON.saradc_fsm.rstb_wait = rst_wait;
@ -1293,6 +1255,20 @@ static esp_err_t adc_set_fsm_time(int rst_wait, int start_wait, int standby_wait
if (standby_wait >= 0) { if (standby_wait >= 0) {
SYSCON.saradc_fsm.standby_wait = standby_wait; SYSCON.saradc_fsm.standby_wait = standby_wait;
} }
#elif CONFIG_IDF_TARGET_ESP32S2BETA
// Internal FSM reset wait time
if (rst_wait >= 0) {
SYSCON.saradc_fsm_wait.rstb_wait = rst_wait;
}
// Internal FSM start wait time
if (start_wait >= 0) {
SYSCON.saradc_fsm_wait.xpd_wait = start_wait;
}
// Internal FSM standby wait time
if (standby_wait >= 0) {
SYSCON.saradc_fsm_wait.standby_wait = standby_wait;
}
#endif
// Internal FSM standby sample cycle // Internal FSM standby sample cycle
if (sample_cycle >= 0) { if (sample_cycle >= 0) {
SYSCON.saradc_fsm.sample_cycle = sample_cycle; SYSCON.saradc_fsm.sample_cycle = sample_cycle;
@ -1617,31 +1593,19 @@ static void adc_set_controller(adc_unit_t unit, adc_controller_t ctrl )
case ADC_CTRL_RTC: case ADC_CTRL_RTC:
SENS.sar_meas2_ctrl2.meas2_start_force = true; //RTC controller controls the ADC,not ulp coprocessor SENS.sar_meas2_ctrl2.meas2_start_force = true; //RTC controller controls the ADC,not ulp coprocessor
SENS.sar_meas2_ctrl2.sar2_en_pad_force = true; //RTC controller controls the data port, not ulp coprocessor SENS.sar_meas2_ctrl2.sar2_en_pad_force = true; //RTC controller controls the data port, not ulp coprocessor
// SENS.sar_read_ctrl2.sar2_dig_force = false; //RTC controller controls the ADC, not digital controller
// SENS.sar_read_ctrl2.sar2_pwdet_force = false; //RTC controller controls the ADC, not PWDET
SYSCON.saradc_ctrl.sar2_mux = true; //RTC controller controls the ADC, not PWDET
break; break;
case ADC_CTRL_ULP: case ADC_CTRL_ULP:
SENS.sar_meas2_ctrl2.meas2_start_force = false; SENS.sar_meas2_ctrl2.meas2_start_force = false;
SENS.sar_meas2_ctrl2.sar2_en_pad_force = false; SENS.sar_meas2_ctrl2.sar2_en_pad_force = false;
// SENS.sar_read_ctrl2.sar2_dig_force = false;
// SENS.sar_read_ctrl2.sar2_pwdet_force = false;
SYSCON.saradc_ctrl.sar2_mux = true;
break; break;
case ADC_CTRL_DIG: case ADC_CTRL_DIG:
SENS.sar_meas2_ctrl2.meas2_start_force = true; SENS.sar_meas2_ctrl2.meas2_start_force = true;
SENS.sar_meas2_ctrl2.sar2_en_pad_force = true; SENS.sar_meas2_ctrl2.sar2_en_pad_force = true;
// SENS.sar_read_ctrl2.sar2_dig_force = true;
// SENS.sar_read_ctrl2.sar2_pwdet_force = false;
SYSCON.saradc_ctrl.sar2_mux = true;
break; break;
case ADC2_CTRL_PWDET: case ADC2_CTRL_PWDET:
//currently only used by Wi-Fi //currently only used by Wi-Fi
SENS.sar_meas2_ctrl2.meas2_start_force = true; SENS.sar_meas2_ctrl2.meas2_start_force = true;
SENS.sar_meas2_ctrl2.sar2_en_pad_force = true; SENS.sar_meas2_ctrl2.sar2_en_pad_force = true;
// SENS.sar_read_ctrl2.sar2_dig_force = false;
// SENS.sar_read_ctrl2.sar2_pwdet_force = true;
SYSCON.saradc_ctrl.sar2_mux = false;
break; break;
default: default:
ESP_LOGE(TAG, "adc2 selects invalid controller"); ESP_LOGE(TAG, "adc2 selects invalid controller");

View file

@ -1,99 +0,0 @@
// 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 "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.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"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/ets_sys.h"
#endif
#if CONFIG_IDF_TARGET_ESP32S2BETA
#define TEMP_SENSOR_XPD_WAIT_DEFAULT 0xFF /* Set wait cycle time(8MHz) from power up to reset enable. */
portMUX_TYPE rtc_temp_spinlock = portMUX_INITIALIZER_UNLOCKED;
static SemaphoreHandle_t rtc_touch_mux = NULL;
esp_err_t temp_sensor_set_config(temp_sensor_t temps)
{
portENTER_CRITICAL(&rtc_temp_spinlock);
SENS.sar_tctrl.tsens_dac = temps.dac_offset;
SENS.sar_tctrl.tsens_clk_div = temps.clk_div;
SENS.sar_tctrl.tsens_power_up_force = 1;
SENS.sar_tctrl2.tsens_xpd_wait = TEMP_SENSOR_XPD_WAIT_DEFAULT;
SENS.sar_tctrl2.tsens_xpd_force = 1;
SENS.sar_tctrl2.tsens_reset = 1;// Reset the temp sensor.
SENS.sar_tctrl2.tsens_reset = 0;// Clear the reset status.
portEXIT_CRITICAL(&rtc_temp_spinlock);
return ESP_OK;
}
esp_err_t temp_sensor_get_config(temp_sensor_t *temps)
{
if(temps) {
portENTER_CRITICAL(&rtc_temp_spinlock);
temps->dac_offset = SENS.sar_tctrl.tsens_dac;
temps->clk_div = SENS.sar_tctrl.tsens_clk_div;
portEXIT_CRITICAL(&rtc_temp_spinlock);
return ESP_OK;
} else {
return ESP_FAIL;
}
}
esp_err_t temp_sensor_start(void)
{
portENTER_CRITICAL(&rtc_temp_spinlock);
SENS.sar_tctrl.tsens_dump_out = 0;
SENS.sar_tctrl2.tsens_clkgate_en = 1;
SENS.sar_tctrl.tsens_power_up = 1;
portEXIT_CRITICAL(&rtc_temp_spinlock);
return ESP_OK;
}
esp_err_t temp_sensor_stop(void)
{
portENTER_CRITICAL(&rtc_temp_spinlock);
SENS.sar_tctrl.tsens_power_up = 0;
SENS.sar_tctrl2.tsens_clkgate_en = 0;
portEXIT_CRITICAL(&rtc_temp_spinlock);
return ESP_OK;
}
esp_err_t temp_sensor_read(uint8_t *temp_out)
{
if(temp_out) {
portENTER_CRITICAL(&rtc_temp_spinlock);
SENS.sar_tctrl.tsens_dump_out = 1;
while(!SENS.sar_tctrl.tsens_ready);
*temp_out = SENS.sar_tctrl.tsens_out;
SENS.sar_tctrl.tsens_dump_out = 0;
portEXIT_CRITICAL(&rtc_temp_spinlock);
return ESP_OK;
} else {
return ESP_FAIL;
}
}
#endif

View file

@ -1,738 +0,0 @@
// 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 "soc/rtc_periph.h"
#include "soc/sens_periph.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_io_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.h"
#include "soc/periph_defs.h"
#include "rtc_io.h"
#include "touch_pad.h"
#include "freertos/FreeRTOS.h"
#include "freertos/xtensa_api.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "esp_intr_alloc.h"
#include "sys/lock.h"
#include "driver/rtc_cntl.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/ets_sys.h"
#endif
#ifndef NDEBUG
// Enable built-in checks in queue.h in debug builds
#define INVARIANTS
#endif
#include "sys/queue.h"
#if CONFIG_IDF_TARGET_ESP32S2BETA
#define TOUCH_PAD_FILTER_FACTOR_DEFAULT (4) // IIR filter coefficient.
#define TOUCH_PAD_SHIFT_DEFAULT (4) // Increase computing accuracy.
#define TOUCH_PAD_SHIFT_ROUND_DEFAULT (8) // ROUND = 2^(n-1); rounding off for fractional.
#define DAC_ERR_STR_CHANNEL_ERROR "DAC channel error"
static portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
static const char *RTC_MODULE_TAG = "RTC_MODULE";
#define RTC_MODULE_CHECK(a, str, ret_val) if (!(a)) { \
ESP_LOGE(RTC_MODULE_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret_val); \
}
#define RTC_RES_CHECK(res, ret_val) if ( (a) != ESP_OK) { \
ESP_LOGE(RTC_MODULE_TAG,"%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__); \
return (ret_val); \
}
static SemaphoreHandle_t rtc_touch_mux = NULL;
// check if touch pad be inited.
static uint16_t s_touch_pad_init_bit = 0x0000;
/*---------------------------------------------------------------
Touch Pad
---------------------------------------------------------------*/
esp_err_t touch_pad_isr_register(intr_handler_t fn, void* arg, touch_pad_intr_mask_t intr_mask)
{
RTC_MODULE_CHECK(intr_mask < TOUCH_PAD_INTR_MASK_MAX, "intr mask err", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(fn, "Touch_Pad ISR null", ESP_ERR_INVALID_ARG);
return rtc_isr_register(fn, arg, intr_mask << RTC_CNTL_TOUCH_DONE_INT_ENA_S);
}
esp_err_t touch_pad_isr_deregister(intr_handler_t fn, void *arg)
{
return rtc_isr_deregister(fn, arg);
}
esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_cycle)
{
xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
portENTER_CRITICAL(&rtc_spinlock);
// touch sensor sleep cycle Time = sleep_cycle / RTC_SLOW_CLK( can be 150k or 32k depending on the options)
RTCCNTL.touch_ctrl1.touch_sleep_cycles = sleep_cycle;
//touch sensor measure time= meas_cycle / 8Mhz
RTCCNTL.touch_ctrl1.touch_meas_num = meas_cycle;
//the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD
RTCCNTL.touch_ctrl2.touch_xpd_wait = 255; //wait volt stable
portEXIT_CRITICAL(&rtc_spinlock);
xSemaphoreGive(rtc_touch_mux);
return ESP_OK;
}
esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_cycle)
{
RTC_MODULE_CHECK(sleep_cycle != NULL, "parameter is NULL", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(meas_cycle != NULL, "parameter is NULL", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
*sleep_cycle = RTCCNTL.touch_ctrl1.touch_sleep_cycles;
*meas_cycle = RTCCNTL.touch_ctrl1.touch_meas_num;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_set_inactive_connect(touch_pad_conn_type_t type)
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_scan_ctrl.touch_inactive_connection = type;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_get_inactive_connect(touch_pad_conn_type_t *type)
{
if(type) {
*type = RTCCNTL.touch_scan_ctrl.touch_inactive_connection;
return ESP_FAIL;
} else {
return ESP_OK;
}
}
esp_err_t touch_pad_set_voltage(touch_high_volt_t refh, touch_low_volt_t refl, touch_volt_atten_t atten)
{
portENTER_CRITICAL(&rtc_spinlock);
if (refh > TOUCH_HVOLT_KEEP) {
RTCCNTL.touch_ctrl2.touch_drefh = refh;
}
if (refl > TOUCH_LVOLT_KEEP) {
RTCCNTL.touch_ctrl2.touch_drefl = refl;
}
if (atten > TOUCH_HVOLT_ATTEN_KEEP) {
RTCCNTL.touch_ctrl2.touch_drange = atten;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_get_voltage(touch_high_volt_t *refh, touch_low_volt_t *refl, touch_volt_atten_t *atten)
{
portENTER_CRITICAL(&rtc_spinlock);
if (refh) {
*refh = RTCCNTL.touch_ctrl2.touch_drefh;
}
if (refl) {
*refl = RTCCNTL.touch_ctrl2.touch_drefl;
}
if (atten) {
*atten = RTCCNTL.touch_ctrl2.touch_drange;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_set_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t slope)
{
portENTER_CRITICAL(&rtc_spinlock);
RTCIO.touch_pad[touch_num].tie_opt = TOUCH_PAD_TIE_OPT_LOW;
RTCIO.touch_pad[touch_num].dac = slope;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_get_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t *slope)
{
portENTER_CRITICAL(&rtc_spinlock);
if(slope) {
*slope = RTCIO.touch_pad[touch_num].dac;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_io_init(touch_pad_t touch_num)
{
RTC_MODULE_CHECK((touch_num < TOUCH_PAD_MAX), "touch IO error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK((touch_num > TOUCH_PAD_NUM0), "touch IO error", ESP_ERR_INVALID_ARG);
gpio_num_t gpio_num = GPIO_NUM_1;
gpio_num = touch_num;
rtc_gpio_init(gpio_num);
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
rtc_gpio_pulldown_dis(gpio_num);
rtc_gpio_pullup_dis(gpio_num);
return ESP_OK;
}
esp_err_t touch_pad_wait_init_done()
{
// TODO
return ESP_FAIL;
}
/*touch_pad_fsm_start_vf, after set mask*/
esp_err_t touch_pad_fsm_start(touch_fsm_mode_t mode)
{
RTC_MODULE_CHECK((mode < TOUCH_FSM_MODE_MAX), "touch fsm mode error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_ctrl2.touch_start_en = 0; //stop touch fsm
RTCCNTL.touch_ctrl2.touch_start_force = mode;
RTCCNTL.touch_ctrl2.touch_slp_timer_en = (mode == TOUCH_FSM_MODE_TIMER ? 1 : 0);
RTCCNTL.touch_ctrl2.touch_clkgate_en = 1; //enable touch clock for FSM. or force enable.
SENS.sar_touch_chn_st.touch_channel_clr = TOUCH_PAD_BIT_MASK_MAX; // clear baseline
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_fsm_stop()
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_ctrl2.touch_start_en = 0; //stop touch fsm
RTCCNTL.touch_ctrl2.touch_slp_timer_en = 0;
RTCCNTL.touch_ctrl2.touch_clkgate_en = 0; //enable touch clock for FSM. or force enable.
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_get_fsm_mode(touch_fsm_mode_t *mode)
{
if (mode) {
*mode = RTCCNTL.touch_ctrl2.touch_start_force;
}
return ESP_OK;
}
/*
* If doing measure, the flag will be self-clear.
* After measure, the flag will be set.
*/
uint8_t touch_pad_means_is_done()
{
return SENS.sar_touch_chn_st.touch_meas_done;
}
/* return the current scan channel. */
esp_err_t touch_pad_sw_start(touch_pad_t *current_scan)
{
RTC_MODULE_CHECK((RTCCNTL.touch_ctrl2.touch_start_force == TOUCH_FSM_MODE_SW),
"touch IO error", ESP_FAIL);
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_ctrl2.touch_start_en = 0;
RTCCNTL.touch_ctrl2.touch_start_en = 1;
portEXIT_CRITICAL(&rtc_spinlock);
if(current_scan) {
*current_scan = SENS.sar_touch_status0.touch_scan_curr;
}
return ESP_OK;
}
/* If set "TOUCH_PAD_THRESHOLD_MAX", the filter is not triger. */
esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint32_t threshold)
{
RTC_MODULE_CHECK((threshold != 0), "threshold error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK((touch_num < TOUCH_PAD_MAX), "touch IO error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK((touch_num > TOUCH_PAD_NUM0), "touch0 no thresh", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
SENS.touch_thresh[touch_num-1].thresh = threshold;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint32_t *threshold)
{
RTC_MODULE_CHECK((touch_num < TOUCH_PAD_MAX), "touch IO error", ESP_ERR_INVALID_ARG);
if (threshold) {
*threshold = SENS.touch_thresh[touch_num-1].thresh;
}
return ESP_OK;
}
/* If set mask, the FSM timer should be stop firsty.
* Noitce: The touchpad that in scan map ,should be deinit digital function firstly.
* */
esp_err_t touch_pad_set_group_mask(uint16_t enable_mask)
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_scan_ctrl.touch_scan_pad_map |= (enable_mask&TOUCH_PAD_BIT_MASK_MAX);
SENS.sar_touch_conf.touch_outen |= (enable_mask&TOUCH_PAD_BIT_MASK_MAX);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_get_group_mask(uint16_t *enable_mask)
{
portENTER_CRITICAL(&rtc_spinlock);
*enable_mask = SENS.sar_touch_conf.touch_outen \
& RTCCNTL.touch_scan_ctrl.touch_scan_pad_map \
& TOUCH_PAD_BIT_MASK_MAX;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
/* If clear all mask, the FSM timer should be stop firsty. */
esp_err_t touch_pad_clear_group_mask(uint16_t enable_mask)
{
portENTER_CRITICAL(&rtc_spinlock);
SENS.sar_touch_conf.touch_outen &= ~(enable_mask&TOUCH_PAD_BIT_MASK_MAX);
RTCCNTL.touch_scan_ctrl.touch_scan_pad_map &= ~(enable_mask&TOUCH_PAD_BIT_MASK_MAX);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
uint32_t IRAM_ATTR touch_pad_get_int_status()
{
return REG_READ(RTC_CNTL_INT_ST_REG) >> (RTC_CNTL_TOUCH_DONE_INT_ST_S) & (TOUCH_PAD_INTR_MASK_ALL);
}
/*
* The "touch_pad_active" will be change auto.
* If status bit is 1, this pad is be active, else, this pad is inactive.
*/
uint32_t IRAM_ATTR touch_pad_get_status()
{
return (SENS.sar_touch_chn_st.touch_pad_active & TOUCH_PAD_BIT_MASK_MAX);
}
// get current scan channel. note: in interrupt and set a litter sleep time.
uint32_t IRAM_ATTR touch_pad_get_scan_curr()
{
return (SENS.sar_touch_status0.touch_scan_curr);
}
/*
* Normaly, Should't call this function manual. .
*/
esp_err_t IRAM_ATTR touch_pad_clear_status()
{
portENTER_CRITICAL(&rtc_spinlock);
SENS.sar_touch_conf.touch_status_clr = 1;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_intr_enable(touch_pad_intr_type_t type)
{
portENTER_CRITICAL(&rtc_spinlock);
if(type == TOUCH_PAD_INTR_DONE) {
RTCCNTL.int_ena.rtc_touch_done = 1;
} else if(type == TOUCH_PAD_INTR_ACTIVE) {
RTCCNTL.int_ena.rtc_touch_active = 1;
} else if(type == TOUCH_PAD_INTR_INACTIVE) {
RTCCNTL.int_ena.rtc_touch_inactive = 1;
} else if(type == TOUCH_PAD_INTR_ALL){
RTCCNTL.int_ena.rtc_touch_done = 1;
RTCCNTL.int_ena.rtc_touch_active = 1;
RTCCNTL.int_ena.rtc_touch_inactive = 1;
} else {
ESP_LOGE(RTC_MODULE_TAG, "no this intr type");
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_intr_disable(touch_pad_intr_type_t type)
{
portENTER_CRITICAL(&rtc_spinlock);
if(type == TOUCH_PAD_INTR_DONE) {
RTCCNTL.int_ena.rtc_touch_done = 0;
} else if(type == TOUCH_PAD_INTR_ACTIVE) {
RTCCNTL.int_ena.rtc_touch_active = 0;
} else if(type == TOUCH_PAD_INTR_INACTIVE) {
RTCCNTL.int_ena.rtc_touch_inactive = 0;
} else if(type == TOUCH_PAD_INTR_ALL){
RTCCNTL.int_ena.rtc_touch_done = 0;
RTCCNTL.int_ena.rtc_touch_active = 0;
RTCCNTL.int_ena.rtc_touch_inactive = 0;
} else {
ESP_LOGE(RTC_MODULE_TAG, "no this intr type");
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
uint32_t IRAM_ATTR touch_pad_intr_get_mask()
{
return REG_READ(RTC_CNTL_INT_ENA_REG) >> (RTC_CNTL_TOUCH_DONE_INT_ENA_S) & (TOUCH_PAD_INTR_MASK_ALL);
}
esp_err_t touch_pad_config(touch_pad_t touch_num)
{
RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL);
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
touch_pad_io_init(touch_num);
touch_pad_set_cnt_mode(touch_num, TOUCH_PAD_SLOPE_7);
touch_pad_set_thresh(touch_num, TOUCH_PAD_THRESHOLD_MAX);
touch_pad_set_group_mask(BIT(touch_num));
return ESP_OK;
}
esp_err_t touch_pad_init()
{
if (rtc_touch_mux == NULL) {
rtc_touch_mux = xSemaphoreCreateMutex();
}
if (rtc_touch_mux == NULL) {
return ESP_FAIL;
}
touch_pad_intr_disable(TOUCH_PAD_INTR_ALL);
touch_pad_clear_group_mask(TOUCH_PAD_BIT_MASK_MAX);
touch_pad_clear_status();
touch_pad_set_meas_time(TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_MEASURE_CYCLE_DEFAULT);
// Set reference voltage for charging/discharging
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V5);
touch_pad_set_inactive_connect(TOUCH_PAD_CONN_GND);
return ESP_OK;
}
esp_err_t touch_pad_deinit()
{
RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL);
xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
s_touch_pad_init_bit = 0x0000;
touch_pad_fsm_stop();
touch_pad_clear_status();
touch_pad_intr_disable(TOUCH_PAD_INTR_ALL);
xSemaphoreGive(rtc_touch_mux);
vSemaphoreDelete(rtc_touch_mux);
rtc_touch_mux = NULL;
return ESP_OK;
}
/*raw data 的单位是时间,单位是 1/8MHz */
IRAM_ATTR esp_err_t touch_pad_read_raw(touch_pad_t touch_num, uint32_t *raw_data)
{
RTC_MODULE_CHECK(touch_num > TOUCH_PAD_NUM0, "Touch pad0 is forbidden", ESP_FAIL);
if (raw_data) {
*raw_data = SENS.touch_meas[touch_num].meas_out;
}
return ESP_OK;
}
IRAM_ATTR esp_err_t touch_pad_filter_baseline_read(touch_pad_t touch_num, uint32_t *basedata)
{
RTC_MODULE_CHECK(touch_num > TOUCH_PAD_NUM0, "Touch pad0 is forbidden", ESP_FAIL);
if (basedata) {
*basedata = SENS.sar_touch_status[touch_num-1].touch_pad_baseline;
}
return ESP_OK;
}
IRAM_ATTR esp_err_t touch_pad_read_debounce(touch_pad_t touch_num, uint32_t *debounce)
{
RTC_MODULE_CHECK(touch_num > TOUCH_PAD_NUM0, "Touch pad0 is forbidden", ESP_FAIL);
if (debounce) {
*debounce = SENS.sar_touch_status[touch_num-1].touch_pad_debounce;
}
return ESP_OK;
}
IRAM_ATTR esp_err_t touch_pad_read_thresh(touch_pad_t touch_num, uint32_t *thresh_out)
{
RTC_MODULE_CHECK(touch_num > TOUCH_PAD_NUM0, "Touch pad0 is forbidden", ESP_FAIL);
if (thresh_out) {
*thresh_out = SENS.touch_thresh[touch_num-1].thresh;
}
return ESP_OK;
}
/* Should be call after clk enable and filter enable. */
esp_err_t touch_pad_filter_baseline_reset(touch_pad_t touch_num)
{
RTC_MODULE_CHECK(touch_num <= TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
if(touch_num == TOUCH_PAD_MAX) {
SENS.sar_touch_chn_st.touch_channel_clr = TOUCH_PAD_BIT_MASK_MAX;
} else {
SENS.sar_touch_chn_st.touch_channel_clr = BIT(touch_num);
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_filter_set_config(touch_filter_config_t filter_info)
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_filter_ctrl.touch_filter_mode = filter_info.mode;
RTCCNTL.touch_filter_ctrl.touch_debounce = filter_info.debounce_cnt;
RTCCNTL.touch_filter_ctrl.touch_hysteresis = filter_info.hysteresis_thr;
RTCCNTL.touch_filter_ctrl.touch_noise_thres = filter_info.noise_thr;
RTCCNTL.touch_filter_ctrl.touch_neg_noise_thres = filter_info.noise_neg_thr;
RTCCNTL.touch_filter_ctrl.touch_neg_noise_limit = filter_info.neg_noise_limit;
RTCCNTL.touch_filter_ctrl.touch_jitter_step = filter_info.jitter_step;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_filter_get_config(touch_filter_config_t *filter_info)
{
portENTER_CRITICAL(&rtc_spinlock);
filter_info->mode = RTCCNTL.touch_filter_ctrl.touch_filter_mode;
filter_info->debounce_cnt = RTCCNTL.touch_filter_ctrl.touch_debounce;
filter_info->hysteresis_thr = RTCCNTL.touch_filter_ctrl.touch_hysteresis;
filter_info->noise_thr = RTCCNTL.touch_filter_ctrl.touch_noise_thres;
filter_info->noise_neg_thr = RTCCNTL.touch_filter_ctrl.touch_neg_noise_thres;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_filter_start()
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_filter_ctrl.touch_filter_en = 1;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_filter_stop()
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_filter_ctrl.touch_filter_en = 0;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_denoise_enable()
{
touch_pad_clear_group_mask(BIT(TOUCH_PAD_NUM0));
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_scan_ctrl.touch_denoise_en = 1;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_denoise_disable()
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_scan_ctrl.touch_denoise_en = 0;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_denoise_set_config(touch_pad_denoise_t denoise)
{
touch_pad_set_cnt_mode(TOUCH_PAD_NUM0, TOUCH_PAD_SLOPE_7);
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_ctrl2.touch_refc = denoise.cap_level;
RTCCNTL.touch_scan_ctrl.touch_denoise_res = denoise.grade;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_denoise_get_config(touch_pad_denoise_t *denoise)
{
if(denoise) {
denoise->grade = RTCCNTL.touch_scan_ctrl.touch_denoise_res;
denoise->cap_level = RTCCNTL.touch_ctrl2.touch_refc;
return ESP_OK;
} else {
return ESP_FAIL;
}
}
esp_err_t touch_pad_denoise_data_get(uint32_t *data)
{
*data = SENS.sar_touch_status0.touch_denoise_data;
return ESP_OK;
}
/*
* waterproof function include two setting part: 'shield pad driver' and 'guard ring pad num'
* @note waterproof and touch function are mutually exclusive. if config touch14, dont use shield.
* @note self-calibration is implemented in hardware.
* @note touch_out_ring point to touch0, can disable the guatd ring function ?
* @note "touch_bufdrv" should user config ?
*/
esp_err_t touch_pad_waterproof_set_config(touch_pad_waterproof_t waterproof)
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_scan_ctrl.touch_out_ring = waterproof.guard_ring_pad;
RTCCNTL.touch_scan_ctrl.touch_bufdrv = waterproof.shield_driver;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_waterproof_get_config(touch_pad_waterproof_t *waterproof)
{
if(waterproof) {
waterproof->guard_ring_pad = RTCCNTL.touch_scan_ctrl.touch_out_ring;
waterproof->shield_driver = RTCCNTL.touch_scan_ctrl.touch_bufdrv;
return ESP_OK;
} else {
return ESP_FAIL;
}
}
esp_err_t touch_pad_waterproof_enable()
{
touch_pad_clear_group_mask(BIT(TOUCH_PAD_NUM14));
touch_pad_io_init(TOUCH_PAD_NUM14);
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_scan_ctrl.touch_shield_pad_en = 1;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_waterproof_disable()
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_scan_ctrl.touch_shield_pad_en = 0;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
/*
* @note approach pad can set three pin.
* @note if clear the approach pad, point this pad to touch0 and then reset this channel baseline.
* @note the approach thresh is abs value.
* @note TODO: add channel reset reg.
*/
esp_err_t touch_pad_approach_set_config(touch_pad_approach_t approach)
{
portENTER_CRITICAL(&rtc_spinlock);
if(approach.select_pad0) {
SENS.sar_touch_conf.touch_approach_pad0 = approach.select_pad0;
}
if(approach.select_pad1) {
SENS.sar_touch_conf.touch_approach_pad1 = approach.select_pad1;
}
if(approach.select_pad2) {
SENS.sar_touch_conf.touch_approach_pad2 = approach.select_pad2;
}
RTCCNTL.touch_approach.touch_approach_meas_time = approach.means_num;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_approach_get_config(touch_pad_approach_t *approach)
{
if(approach) {
approach->select_pad0 = SENS.sar_touch_conf.touch_approach_pad0;
approach->select_pad1 = SENS.sar_touch_conf.touch_approach_pad1;
approach->select_pad2 = SENS.sar_touch_conf.touch_approach_pad2;
approach->means_num = RTCCNTL.touch_approach.touch_approach_meas_time;
return ESP_OK;
} else {
return ESP_FAIL;
}
}
uint32_t touch_pad_approach_get_cnt(uint8_t pad)
{
uint32_t cnt = 0;
if(pad == 0){
cnt = SENS.sar_touch_status16.touch_approach_pad0_cnt;
} else if(pad == 1) {
cnt = SENS.sar_touch_status16.touch_approach_pad1_cnt;
} else if(pad == 2) {
cnt = SENS.sar_touch_status16.touch_approach_pad2_cnt;
} else if(pad == 3) {
cnt = SENS.sar_touch_status16.touch_slp_approach_cnt;
}
return cnt;
}
/* TODO */
esp_err_t touch_pad_approach_disable()
{
portENTER_CRITICAL(&rtc_spinlock);
SENS.sar_touch_conf.touch_approach_pad0 = 0;
SENS.sar_touch_conf.touch_approach_pad1 = 0;
SENS.sar_touch_conf.touch_approach_pad2 = 0;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
/* After touch_clkgate_en = 0, reset the whole of touch module. */
esp_err_t touch_pad_reset()
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_ctrl2.touch_reset = 0;
RTCCNTL.touch_ctrl2.touch_reset = 1;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
/************** sleep pad setting ***********************/
esp_err_t touch_pad_sleep_pad_config(touch_pad_t pad, uint32_t sleep_thr, uint8_t is_approach)
{
portENTER_CRITICAL(&rtc_spinlock);
RTCCNTL.touch_slp_thres.touch_slp_pad = pad;
RTCCNTL.touch_slp_thres.touch_slp_th = sleep_thr;
RTCCNTL.touch_slp_thres.touch_slp_approach_en = is_approach?1:0;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
/**
* Get sleep touch pad baseline data.
*
* @param baseline
*/
void touch_sleep_baseline_get(uint32_t *baseline)
{
*baseline = REG_GET_FIELD(SENS_SAR_TOUCH_STATUS15_REG, SENS_TOUCH_SLP_BASELINE);
}
/**
* Get sleep touch pad debounce data.
*
* @param debounce
*/
void touch_sleep_debounce_get(uint32_t *debounce)
{
*debounce = REG_GET_FIELD(SENS_SAR_TOUCH_STATUS15_REG, SENS_TOUCH_SLP_DEBOUNCE);
}
/**
* Get sleep touch pad approach cnt data.
*
* @param approach_cnt
*/
void touch_sleep_approach_cnt_get(uint32_t *approach_cnt)
{
*approach_cnt = REG_GET_FIELD(SENS_SAR_TOUCH_STATUS16_REG, SENS_TOUCH_SLP_APPROACH_CNT);
}
esp_err_t touch_pad_get_wakeup_status(touch_pad_t *pad_num)
{
uint32_t touch_mask = SENS.sar_touch_chn_st.touch_pad_active;
*pad_num = __builtin_ffs(touch_mask) - 1;
return ESP_OK;
}
#endif

View file

@ -406,9 +406,10 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status()
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) { if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) {
return TOUCH_PAD_MAX; return TOUCH_PAD_MAX;
} }
uint32_t touch_mask = REG_GET_FIELD(RTC_CNTL_TOUCH_CTRL1_REG, RTC_CNTL_TOUCH_MEAS_NUM); touch_pad_t pad_num;
assert(touch_mask != 0 && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero"); esp_err_t ret = touch_pad_get_wakeup_status(&pad_num);
return (touch_pad_t) (__builtin_ffs(touch_mask) - 1); assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero");
return pad_num;
} }
esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
@ -423,7 +424,7 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP"); ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
} }
s_config.ext0_rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num; s_config.ext0_rtc_gpio_num = gpio_num;
s_config.ext0_trigger_level = level; s_config.ext0_trigger_level = level;
s_config.wakeup_triggers |= RTC_EXT0_TRIG_EN; s_config.wakeup_triggers |= RTC_EXT0_TRIG_EN;
return ESP_OK; return ESP_OK;
@ -437,13 +438,12 @@ static void ext0_wakeup_prepare()
// Set level which will trigger wakeup // Set level which will trigger wakeup
SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
s_config.ext0_trigger_level, RTC_CNTL_EXT_WAKEUP0_LV_S); s_config.ext0_trigger_level, RTC_CNTL_EXT_WAKEUP0_LV_S);
// Find GPIO descriptor in the rtc_gpio_desc table and configure the pad // Find GPIO descriptor in the rtc_gpio_reg table and configure the pad
for (size_t gpio_num = 0; gpio_num < GPIO_PIN_COUNT; ++gpio_num) { for (size_t gpio_num = 0; gpio_num < GPIO_PIN_COUNT; ++gpio_num) {
const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio_num]; if (gpio_num == rtc_gpio_num && RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
if (desc->rtc_num == rtc_gpio_num) { rtc_gpio_reg[gpio_num]->mux_sel = 1;
REG_SET_BIT(desc->reg, desc->mux); rtc_gpio_reg[gpio_num]->fun_sel = 0;
SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); rtc_gpio_reg[gpio_num]->fun_ie = 1;
REG_SET_BIT(desc->reg, desc->ie);
break; break;
} }
} }
@ -464,7 +464,7 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode
ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio); ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio);
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;
} }
rtc_gpio_mask |= BIT(rtc_gpio_desc[gpio].rtc_num); rtc_gpio_mask |= BIT(gpio);
} }
s_config.ext1_rtc_gpio_mask = rtc_gpio_mask; s_config.ext1_rtc_gpio_mask = rtc_gpio_mask;
s_config.ext1_trigger_mode = mode; s_config.ext1_trigger_mode = mode;
@ -477,26 +477,27 @@ static void ext1_wakeup_prepare()
// Configure all RTC IOs selected as ext1 wakeup inputs // Configure all RTC IOs selected as ext1 wakeup inputs
uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask; uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask;
for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) { for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) {
int rtc_pin = rtc_gpio_desc[gpio].rtc_num; if(!RTC_GPIO_IS_VALID_GPIO(gpio)) {
if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) { continue;
}
if ((rtc_gpio_mask & BIT(gpio)) == 0) {
continue; continue;
} }
const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio];
// Route pad to RTC // Route pad to RTC
REG_SET_BIT(desc->reg, desc->mux); rtc_gpio_reg[gpio]->mux_sel = 1;
SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); rtc_gpio_reg[gpio]->fun_sel = 0;
// set input enable in sleep mode // set input enable in sleep mode
REG_SET_BIT(desc->reg, desc->ie); rtc_gpio_reg[gpio]->fun_ie = 1;
// Pad configuration depends on RTC_PERIPH state in sleep mode // Pad configuration depends on RTC_PERIPH state in sleep mode
if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) {
// RTC_PERIPH will be powered down, so RTC_IO_ registers will // RTC_PERIPH will be powered down, so RTC_IO_ registers will
// loose their state. Lock pad configuration. // loose their state. Lock pad configuration.
// Pullups/pulldowns also need to be disabled. // Pullups/pulldowns also need to be disabled.
REG_CLR_BIT(desc->reg, desc->pulldown); rtc_gpio_reg[gpio]->rue = 0;
REG_CLR_BIT(desc->reg, desc->pullup); rtc_gpio_reg[gpio]->rde = 0;
} }
// Keep track of pins which are processed to bail out early // Keep track of pins which are processed to bail out early
rtc_gpio_mask &= ~BIT(rtc_pin); rtc_gpio_mask &= ~BIT(gpio);
} }
// Clear state from previous wakeup // Clear state from previous wakeup
REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
@ -519,7 +520,7 @@ uint64_t esp_sleep_get_ext1_wakeup_status()
if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { if (!RTC_GPIO_IS_VALID_GPIO(gpio)) {
continue; continue;
} }
int rtc_pin = rtc_gpio_desc[gpio].rtc_num; int rtc_pin = gpio;
if ((status & BIT(rtc_pin)) == 0) { if ((status & BIT(rtc_pin)) == 0) {
continue; continue;
} }

View file

@ -91,14 +91,8 @@ typedef volatile struct {
} saradc_fsm_wait; } saradc_fsm_wait;
uint32_t saradc_sar1_status; /**/ uint32_t saradc_sar1_status; /**/
uint32_t saradc_sar2_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_tab[4]; /*item 0 ~ 15 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_sar2_patt_tab[4]; /*item 0 ~ 15 for pattern table 2 (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 { union {
struct { struct {
uint32_t reserved0: 2; uint32_t reserved0: 2;
@ -310,11 +304,22 @@ typedef volatile struct {
}; };
uint32_t val; uint32_t val;
} redcy_sig1; } redcy_sig1;
uint32_t reserved_cc; uint32_t wifi_bb_cfg; /**/
uint32_t reserved_d0; uint32_t wifi_bb_cfg_2; /**/
uint32_t reserved_d4; uint32_t wifi_clk_en; /**/
uint32_t reserved_d8; uint32_t wifi_rst_en; /**/
uint32_t reserved_dc; union {
struct {
uint32_t agc_mem_force_pu: 1;
uint32_t agc_mem_force_pd: 1;
uint32_t pbus_mem_force_pu: 1;
uint32_t pbus_mem_force_pd: 1;
uint32_t dc_mem_force_pu: 1;
uint32_t dc_mem_force_pd: 1;
uint32_t reserved6: 26;
};
uint32_t val;
} front_end_mem_pd;
uint32_t reserved_e0; uint32_t reserved_e0;
uint32_t reserved_e4; uint32_t reserved_e4;
uint32_t reserved_e8; uint32_t reserved_e8;

View file

@ -171,13 +171,9 @@ typedef volatile struct {
} fifo_data; } fifo_data;
union { union {
struct { 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 command: 14; /*command*/
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 0RSTART 1WRITE 2READ 3STOP . 4:END.*/
uint32_t reserved14: 17; uint32_t reserved14: 17;
uint32_t done: 1; /*command0_done*/ uint32_t done: 1; /*command_done*/
}; };
uint32_t val; uint32_t val;
} command[16]; } command[16];

View file

@ -277,118 +277,6 @@ typedef volatile struct {
}; };
uint32_t val; uint32_t val;
} sar_touch_status[14]; } sar_touch_status[14];
// union {
// struct {
// uint32_t touch_pad2_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad2_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status2;
// union {
// struct {
// uint32_t touch_pad3_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad3_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status3;
// union {
// struct {
// uint32_t touch_pad4_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad4_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status4;
// union {
// struct {
// uint32_t touch_pad5_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad5_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status5;
// union {
// struct {
// uint32_t touch_pad6_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad6_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status6;
// union {
// struct {
// uint32_t touch_pad7_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad7_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status7;
// union {
// struct {
// uint32_t touch_pad8_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad8_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status8;
// union {
// struct {
// uint32_t touch_pad9_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad9_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status9;
// union {
// struct {
// uint32_t touch_pad10_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad10_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status10;
// union {
// struct {
// uint32_t touch_pad11_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad11_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status11;
// union {
// struct {
// uint32_t touch_pad12_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad12_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status12;
// union {
// struct {
// uint32_t touch_pad13_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad13_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status13;
// union {
// struct {
// uint32_t touch_pad14_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_pad14_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status14;
// union {
// struct {
// uint32_t touch_slp_baseline:22;
// uint32_t reserved22: 7;
// uint32_t touch_slp_debounce: 3;
// };
// uint32_t val;
// } sar_touch_status15;
union { union {
struct { struct {
uint32_t touch_approach_pad2_cnt: 8; uint32_t touch_approach_pad2_cnt: 8;

View file

@ -25,37 +25,26 @@ typedef volatile struct {
uint32_t clk_320m_en: 1; uint32_t clk_320m_en: 1;
uint32_t clk_en: 1; uint32_t clk_en: 1;
uint32_t rst_tick: 1; uint32_t rst_tick: 1;
uint32_t quick_clk_chng: 1; uint32_t reserved13: 1;
uint32_t reserved14: 18; uint32_t soc_clk_sel: 2;
uint32_t reserved16: 16;
}; };
uint32_t val; uint32_t val;
}clk_conf; } clk_conf;
union { union {
struct { struct {
uint32_t xtal_tick: 8; uint32_t xtal_tick: 8;
uint32_t reserved8: 24;
};
uint32_t val;
}xtal_tick_conf;
union {
struct {
uint32_t pll_tick: 8;
uint32_t reserved8: 24;
};
uint32_t val;
}pll_tick_conf;
union {
struct {
uint32_t ck8m_tick: 8; uint32_t ck8m_tick: 8;
uint32_t reserved8: 24; uint32_t tick_enable: 1;
uint32_t reserved17: 15;
}; };
uint32_t val; uint32_t val;
}ck8m_tick_conf; } tick_conf;
union { union {
struct { struct {
uint32_t start_force: 1; uint32_t start_force: 1;
uint32_t start: 1; uint32_t start: 1;
uint32_t sar2_mux: 1; /*1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled by PWDET CTRL*/ uint32_t reserved2: 1;
uint32_t work_mode: 2; /*0: single mode 1: double mode 2: alternate mode*/ 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_sel: 1; /*0: SAR1 1: SAR2 only work for single SAR mode*/
uint32_t sar_clk_gated: 1; uint32_t sar_clk_gated: 1;
@ -66,53 +55,471 @@ typedef volatile struct {
uint32_t sar2_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC2 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_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 data_to_i2s: 1; /*1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix*/
uint32_t reserved27: 5; uint32_t xpd_sar_force: 2; /*force option to xpd sar blocks*/
uint32_t reserved29: 3;
}; };
uint32_t val; uint32_t val;
}saradc_ctrl; } saradc_ctrl;
union { union {
struct { struct {
uint32_t meas_num_limit: 1; uint32_t meas_num_limit: 1;
uint32_t max_meas_num: 8; /*max conversion number*/ 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 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 sar2_inv: 1; /*1: data to DIG ADC2 CTRL is inverted otherwise not*/
uint32_t reserved11: 21; 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; uint32_t val;
}saradc_ctrl2; } saradc_ctrl2;
union { union {
struct { struct {
uint32_t rstb_wait: 8; uint32_t reserved0: 16;
uint32_t standby_wait: 8; uint32_t sample_num: 8; /*sample number*/
uint32_t start_wait: 8;
uint32_t sample_cycle: 8; /*sample cycles*/ uint32_t sample_cycle: 8; /*sample cycles*/
}; };
uint32_t val; uint32_t val;
}saradc_fsm; } saradc_fsm;
uint32_t saradc_sar1_patt_tab[4]; /*item 0 ~ 3 for ADC1 pattern table*/
uint32_t saradc_sar2_patt_tab[4]; /*item 0 ~ 3 for ADC2 pattern table*/
union { union {
struct { struct {
uint32_t apll_tick: 8; uint32_t xpd_wait: 8;
uint32_t reserved8: 24; uint32_t rstb_wait: 8;
uint32_t standby_wait: 8;
uint32_t reserved24: 8;
}; };
uint32_t val; uint32_t val;
}apll_tick_conf; } saradc_fsm_wait;
uint32_t reserved_40; uint32_t saradc_sar1_status; /**/
uint32_t reserved_44; uint32_t saradc_sar2_status; /**/
uint32_t reserved_48; uint32_t saradc_sar1_patt_tab[4]; /*item 0 ~ 15 for pattern table 1 (each item one byte)*/
uint32_t reserved_4c; uint32_t saradc_sar2_patt_tab[4]; /*item 0 ~ 15 for pattern table 2 (each item one byte)*/
uint32_t reserved_50; union {
uint32_t reserved_54; struct {
uint32_t reserved_58; uint32_t reserved0: 2;
uint32_t reserved_5c; uint32_t adc_arb_apb_force: 1; /*adc2 arbiter force to enableapb controller*/
uint32_t reserved_60; uint32_t adc_arb_rtc_force: 1; /*adc2 arbiter force to enable rtc controller*/
uint32_t reserved_64; uint32_t adc_arb_wifi_force: 1; /*adc2 arbiter force to enable wifi controller*/
uint32_t reserved_68; uint32_t adc_arb_grant_force: 1; /*adc2 arbiter force grant*/
uint32_t reserved_6c; uint32_t adc_arb_apb_priority: 2; /*Set adc2 arbiterapb priority*/
uint32_t reserved_70; uint32_t adc_arb_rtc_priority: 2; /*Set adc2 arbiter rtc priority*/
uint32_t reserved_74; uint32_t adc_arb_wifi_priority: 2; /*Set adc2 arbiter wifi priority*/
uint32_t reserved_78; 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;
uint32_t clk22_oen: 1;
uint32_t clk44_oen: 1;
uint32_t clk_bb_oen: 1;
uint32_t clk80_oen: 1;
uint32_t clk160_oen: 1;
uint32_t clk_320m_oen: 1;
uint32_t clk_adc_inf_oen: 1;
uint32_t clk_dac_cpu_oen: 1;
uint32_t clk40x_bb_oen: 1;
uint32_t clk_xtal_oen: 1;
uint32_t reserved11: 21;
};
uint32_t val;
} clk_out_en;
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 val;
} host_inf_sel;
union {
struct {
uint32_t ext_mem_pms_lock: 1;
uint32_t reserved1: 31;
};
uint32_t val;
} ext_mem_pms_lock;
union {
struct {
uint32_t flash_ace0_attr: 3;
uint32_t reserved3: 29;
};
uint32_t val;
} flash_ace0_attr;
union {
struct {
uint32_t flash_ace1_attr: 3;
uint32_t reserved3: 29;
};
uint32_t val;
} flash_ace1_attr;
union {
struct {
uint32_t flash_ace2_attr: 3;
uint32_t reserved3: 29;
};
uint32_t val;
} flash_ace2_attr;
union {
struct {
uint32_t flash_ace3_attr: 3;
uint32_t reserved3: 29;
};
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; /**/
union {
struct {
uint32_t flash_ace0_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} flash_ace0_size;
union {
struct {
uint32_t flash_ace1_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} flash_ace1_size;
union {
struct {
uint32_t flash_ace2_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} flash_ace2_size;
union {
struct {
uint32_t flash_ace3_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} flash_ace3_size;
union {
struct {
uint32_t sram_ace0_attr: 3;
uint32_t reserved3: 29;
};
uint32_t val;
} sram_ace0_attr;
union {
struct {
uint32_t sram_ace1_attr: 3;
uint32_t reserved3: 29;
};
uint32_t val;
} sram_ace1_attr;
union {
struct {
uint32_t sram_ace2_attr: 3;
uint32_t reserved3: 29;
};
uint32_t val;
} sram_ace2_attr;
union {
struct {
uint32_t sram_ace3_attr: 3;
uint32_t reserved3: 29;
};
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; /**/
union {
struct {
uint32_t sram_ace0_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} sram_ace0_size;
union {
struct {
uint32_t sram_ace1_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} sram_ace1_size;
union {
struct {
uint32_t sram_ace2_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} sram_ace2_size;
union {
struct {
uint32_t sram_ace3_size:16;
uint32_t reserved16: 16;
};
uint32_t val;
} 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 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; /**/
union {
struct {
uint32_t sdio_win_access_en: 1;
uint32_t reserved1: 31;
};
uint32_t val;
} sdio_ctrl;
union {
struct {
uint32_t redcy_sig0: 31;
uint32_t redcy_andor: 1;
};
uint32_t val;
} redcy_sig0;
union {
struct {
uint32_t redcy_sig1: 31;
uint32_t redcy_nandor: 1;
};
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; /**/
union {
struct {
uint32_t agc_mem_force_pu: 1;
uint32_t agc_mem_force_pd: 1;
uint32_t pbus_mem_force_pu: 1;
uint32_t pbus_mem_force_pd: 1;
uint32_t dc_mem_force_pu: 1;
uint32_t dc_mem_force_pd: 1;
uint32_t reserved6: 26;
};
uint32_t val;
} front_end_mem_pd;
uint32_t reserved_e0;
uint32_t reserved_e4;
uint32_t reserved_e8;
uint32_t reserved_ec;
uint32_t reserved_f0;
uint32_t reserved_f4;
uint32_t reserved_f8;
uint32_t reserved_fc;
uint32_t reserved_100;
uint32_t reserved_104;
uint32_t reserved_108;
uint32_t reserved_10c;
uint32_t reserved_110;
uint32_t reserved_114;
uint32_t reserved_118;
uint32_t reserved_11c;
uint32_t reserved_120;
uint32_t reserved_124;
uint32_t reserved_128;
uint32_t reserved_12c;
uint32_t reserved_130;
uint32_t reserved_134;
uint32_t reserved_138;
uint32_t reserved_13c;
uint32_t reserved_140;
uint32_t reserved_144;
uint32_t reserved_148;
uint32_t reserved_14c;
uint32_t reserved_150;
uint32_t reserved_154;
uint32_t reserved_158;
uint32_t reserved_15c;
uint32_t reserved_160;
uint32_t reserved_164;
uint32_t reserved_168;
uint32_t reserved_16c;
uint32_t reserved_170;
uint32_t reserved_174;
uint32_t reserved_178;
uint32_t reserved_17c;
uint32_t reserved_180;
uint32_t reserved_184;
uint32_t reserved_188;
uint32_t reserved_18c;
uint32_t reserved_190;
uint32_t reserved_194;
uint32_t reserved_198;
uint32_t reserved_19c;
uint32_t reserved_1a0;
uint32_t reserved_1a4;
uint32_t reserved_1a8;
uint32_t reserved_1ac;
uint32_t reserved_1b0;
uint32_t reserved_1b4;
uint32_t reserved_1b8;
uint32_t reserved_1bc;
uint32_t reserved_1c0;
uint32_t reserved_1c4;
uint32_t reserved_1c8;
uint32_t reserved_1cc;
uint32_t reserved_1d0;
uint32_t reserved_1d4;
uint32_t reserved_1d8;
uint32_t reserved_1dc;
uint32_t reserved_1e0;
uint32_t reserved_1e4;
uint32_t reserved_1e8;
uint32_t reserved_1ec;
uint32_t reserved_1f0;
uint32_t reserved_1f4;
uint32_t reserved_1f8;
uint32_t reserved_1fc;
uint32_t reserved_200;
uint32_t reserved_204;
uint32_t reserved_208;
uint32_t reserved_20c;
uint32_t reserved_210;
uint32_t reserved_214;
uint32_t reserved_218;
uint32_t reserved_21c;
uint32_t reserved_220;
uint32_t reserved_224;
uint32_t reserved_228;
uint32_t reserved_22c;
uint32_t reserved_230;
uint32_t reserved_234;
uint32_t reserved_238;
uint32_t reserved_23c;
uint32_t reserved_240;
uint32_t reserved_244;
uint32_t reserved_248;
uint32_t reserved_24c;
uint32_t reserved_250;
uint32_t reserved_254;
uint32_t reserved_258;
uint32_t reserved_25c;
uint32_t reserved_260;
uint32_t reserved_264;
uint32_t reserved_268;
uint32_t reserved_26c;
uint32_t reserved_270;
uint32_t reserved_274;
uint32_t reserved_278;
uint32_t reserved_27c;
uint32_t reserved_280;
uint32_t reserved_284;
uint32_t reserved_288;
uint32_t reserved_28c;
uint32_t reserved_290;
uint32_t reserved_294;
uint32_t reserved_298;
uint32_t reserved_29c;
uint32_t reserved_2a0;
uint32_t reserved_2a4;
uint32_t reserved_2a8;
uint32_t reserved_2ac;
uint32_t reserved_2b0;
uint32_t reserved_2b4;
uint32_t reserved_2b8;
uint32_t reserved_2bc;
uint32_t reserved_2c0;
uint32_t reserved_2c4;
uint32_t reserved_2c8;
uint32_t reserved_2cc;
uint32_t reserved_2d0;
uint32_t reserved_2d4;
uint32_t reserved_2d8;
uint32_t reserved_2dc;
uint32_t reserved_2e0;
uint32_t reserved_2e4;
uint32_t reserved_2e8;
uint32_t reserved_2ec;
uint32_t reserved_2f0;
uint32_t reserved_2f4;
uint32_t reserved_2f8;
uint32_t reserved_2fc;
uint32_t reserved_300;
uint32_t reserved_304;
uint32_t reserved_308;
uint32_t reserved_30c;
uint32_t reserved_310;
uint32_t reserved_314;
uint32_t reserved_318;
uint32_t reserved_31c;
uint32_t reserved_320;
uint32_t reserved_324;
uint32_t reserved_328;
uint32_t reserved_32c;
uint32_t reserved_330;
uint32_t reserved_334;
uint32_t reserved_338;
uint32_t reserved_33c;
uint32_t reserved_340;
uint32_t reserved_344;
uint32_t reserved_348;
uint32_t reserved_34c;
uint32_t reserved_350;
uint32_t reserved_354;
uint32_t reserved_358;
uint32_t reserved_35c;
uint32_t reserved_360;
uint32_t reserved_364;
uint32_t reserved_368;
uint32_t reserved_36c;
uint32_t reserved_370;
uint32_t reserved_374;
uint32_t reserved_378;
uint32_t reserved_37c;
uint32_t reserved_380;
uint32_t reserved_384;
uint32_t reserved_388;
uint32_t reserved_38c;
uint32_t reserved_390;
uint32_t reserved_394;
uint32_t reserved_398;
uint32_t reserved_39c;
uint32_t reserved_3a0;
uint32_t reserved_3a4;
uint32_t reserved_3a8;
uint32_t reserved_3ac;
uint32_t reserved_3b0;
uint32_t reserved_3b4;
uint32_t reserved_3b8;
uint32_t reserved_3bc;
uint32_t reserved_3c0;
uint32_t reserved_3c4;
uint32_t reserved_3c8;
uint32_t reserved_3cc;
uint32_t reserved_3d0;
uint32_t reserved_3d4;
uint32_t reserved_3d8;
uint32_t reserved_3dc;
uint32_t reserved_3e0;
uint32_t reserved_3e4;
uint32_t reserved_3e8;
uint32_t reserved_3ec;
uint32_t reserved_3f0;
uint32_t reserved_3f4;
uint32_t reserved_3f8;
uint32_t date; /**/ uint32_t date; /**/
} syscon_dev_t; } syscon_dev_t;

View file

@ -83,6 +83,7 @@ INPUT = \
../../components/driver/include/driver/spi_common.h \ ../../components/driver/include/driver/spi_common.h \
../../components/driver/include/driver/spi_master.h \ ../../components/driver/include/driver/spi_master.h \
../../components/driver/include/driver/spi_slave.h \ ../../components/driver/include/driver/spi_slave.h \
../../components/driver/esp32s2beta/include/temp_sensor.h \
../../components/driver/include/driver/timer.h \ ../../components/driver/include/driver/timer.h \
../../components/driver/include/driver/touch_pad.h \ ../../components/driver/include/driver/touch_pad.h \
../../components/driver/include/driver/uart.h \ ../../components/driver/include/driver/uart.h \

View file

@ -22,6 +22,7 @@ Peripherals API
Sigma-delta Modulation <sigmadelta> Sigma-delta Modulation <sigmadelta>
SPI Master <spi_master> SPI Master <spi_master>
SPI Slave <spi_slave> SPI Slave <spi_slave>
Temp sensor <temp_sensor>
Timer <timer> Timer <timer>
Touch Sensor <touch_pad> Touch Sensor <touch_pad>
UART <uart> UART <uart>

View file

@ -0,0 +1,32 @@
ESP32-S2 Temperature Sensor
==================
Overview
--------
The ESP32-S2 has a built-in temperature sensor. The temperature sensor module contains an 8-bit Sigma-Delta ADC and a temperature offset DAC.
The conversion relationship is the first columns of the table below. Among them, offset = 0 is the main measurement option, and other values are extended measurement options.
+--------+------------------------+------------------------+
| offset | measure range(Celsius) | measure error(Celsius) |
+========+========================+========================+
| -2 | 50 ~ 125 | < 3 |
+--------+------------------------+------------------------+
| -1 | 20 ~ 100 | < 2 |
+--------+------------------------+------------------------+
| 0 | -10 ~ 80 | < 1 |
+--------+------------------------+------------------------+
| 1 | -30 ~ 50 | < 2 |
+--------+------------------------+------------------------+
| 2 | -40 ~ 20 | < 3 |
+--------+------------------------+------------------------+
Application Example
-------------------
Temperature sensor reading example: :example:`peripherals/temp_sensor`.
API Reference - Normal Temp Sensor
----------------------------------
.. include:: /_build/inc/temp_sensor.inc

View file

@ -22,6 +22,7 @@
Sigma-delta Modulation <sigmadelta> Sigma-delta Modulation <sigmadelta>
SPI Master <spi_master> SPI Master <spi_master>
SPI Slave <spi_slave> SPI Slave <spi_slave>
Temp sensor <temp_sensor>
Timer <timer> Timer <timer>
Touch Sensor <touch_pad> Touch Sensor <touch_pad>
UART <uart> UART <uart>

View file

@ -0,0 +1 @@
.. include:: ../../../en/api-reference/peripherals/temp_sensor.rst

View file

@ -12,17 +12,23 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/adc.h" #include "driver/adc.h"
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
#include "esp_adc_cal.h" #include "esp_adc_cal.h"
#endif
#define DEFAULT_VREF 1100 //Use adc2_vref_to_gpio() to obtain a better estimate #define DEFAULT_VREF 1100 //Use adc2_vref_to_gpio() to obtain a better estimate
#define NO_OF_SAMPLES 64 //Multisampling #define NO_OF_SAMPLES 64 //Multisampling
#if CONFIG_IDF_TARGET_ESP32
static esp_adc_cal_characteristics_t *adc_chars; 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_channel_t channel = ADC_CHANNEL_6; //GPIO34 if ADC1, GPIO14 if ADC2
#elif CONFIG_IDF_TARGET_ESP32S2BETA
static const adc_channel_t channel = ADC_CHANNEL_6; // GPIO7 if ADC1, GPIO17 if ADC2
#endif
static const adc_atten_t atten = ADC_ATTEN_DB_0; static const adc_atten_t atten = ADC_ATTEN_DB_0;
static const adc_unit_t unit = ADC_UNIT_1; static const adc_unit_t unit = ADC_UNIT_1;
#if CONFIG_IDF_TARGET_ESP32
static void check_efuse() static void check_efuse()
{ {
//Check TP is burned into eFuse //Check TP is burned into eFuse
@ -50,11 +56,14 @@ static void print_char_val_type(esp_adc_cal_value_t val_type)
printf("Characterized using Default Vref\n"); printf("Characterized using Default Vref\n");
} }
} }
#endif
void app_main() void app_main()
{ {
#if CONFIG_IDF_TARGET_ESP32
//Check if Two Point or Vref are burned into eFuse //Check if Two Point or Vref are burned into eFuse
check_efuse(); check_efuse();
#endif
//Configure ADC //Configure ADC
if (unit == ADC_UNIT_1) { if (unit == ADC_UNIT_1) {
@ -64,10 +73,12 @@ void app_main()
adc2_config_channel_atten((adc2_channel_t)channel, atten); adc2_config_channel_atten((adc2_channel_t)channel, atten);
} }
#if CONFIG_IDF_TARGET_ESP32
//Characterize ADC //Characterize ADC
adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); 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, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);
print_char_val_type(val_type); print_char_val_type(val_type);
#endif
//Continuously sample ADC1 //Continuously sample ADC1
while (1) { while (1) {
@ -83,49 +94,13 @@ void app_main()
} }
} }
adc_reading /= NO_OF_SAMPLES; adc_reading /= NO_OF_SAMPLES;
#if CONFIG_IDF_TARGET_ESP32
//Convert adc_reading to voltage in mV //Convert adc_reading to voltage in mV
uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage); printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
#elif CONFIG_IDF_TARGET_ESP32S2BETA #elif CONFIG_IDF_TARGET_ESP32S2BETA
#define NO_OF_SAMPLES 64 //Multisampling
static const adc_channel_t channel = ADC_CHANNEL_6; // GPIO7 if ADC1, GPIO17 if ADC2
static const adc_atten_t atten = ADC_ATTEN_DB_11; // Detect 0 ~ 3.6v
static const adc_unit_t unit = ADC_UNIT_2;
static const adc_unit_t width = ADC_WIDTH_BIT_12;
void app_main()
{
//Configure ADC
if (unit == ADC_UNIT_1) {
adc1_config_width(width);
adc1_config_channel_atten(channel, atten);
} else {
adc2_config_channel_atten((adc2_channel_t)channel, atten);
}
//Continuously sample ADC1
while (1) {
uint32_t adc_reading = 0;
// Multisampling
for (int i = 0; i < NO_OF_SAMPLES; i++) {
if (unit == ADC_UNIT_1) {
adc_reading += adc1_get_raw((adc1_channel_t)channel);
} else {
int raw;
adc2_get_raw((adc2_channel_t)channel, width, &raw);
adc_reading += raw;
}
}
adc_reading /= NO_OF_SAMPLES;
printf("ADC%d CH%d Raw: %d\t\n", unit, channel, adc_reading); printf("ADC%d CH%d Raw: %d\t\n", unit, channel, adc_reading);
#endif
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
} }
} }
#endif

View file

@ -1,3 +0,0 @@
#
# Main Makefile. This is basically the same as a component makefile.
#

View file

@ -3,4 +3,4 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(temp_sensor) project(temp_sensor_esp32s2)

View file

@ -3,7 +3,7 @@
# project subdirectory. # project subdirectory.
# #
PROJECT_NAME := temp_sensor PROJECT_NAME := temp_sensor_esp32s2
include $(IDF_PATH)/make/project.mk include $(IDF_PATH)/make/project.mk

View file

@ -0,0 +1,27 @@
# ESP32-S2 Temperature Sensor Example
The ESP32-S2 has a built-in temperature sensor. The temperature sensor module contains an 8-bit Sigma-Delta ADC and a temperature offset DAC.
The conversion relationship is the first two columns of the table below. Among them, `offset = 0`(default) is the main measurement option, and other values are extended measurement options.
DAC level | offset | measure range(℃) | measure error(℃)
:-: | :-: | :-: | :-:
0 | -2 | 50 ~ 125 | < 3
1 | -1 | 20 ~ 100 | < 2
2 | 0 | -10 ~ 80 | < 1
3 | 1 | -30 ~ 50 | < 2
4 | 2 | -40 ~ 20 | < 3
* Log output :
```
I (243) TempSensor: Initializing Temperature sensor
I (243) TempSensor: default dac 2, clk_div 6
I (243) TempSensor: Config temperature range [-10°C ~ 80°C], error < 1°C
I (253) TempSensor: Temperature sensor started
I (1253) TempSensor: Temperature out celsius 27.287399°C
I (2253) TempSensor: Temperature out celsius 26.848801°C
I (3253) TempSensor: Temperature out celsius 26.848801°C
I (4253) TempSensor: Temperature out celsius 27.287399°C
I (5253) TempSensor: Temperature out celsius 27.287399°C
```

View file

@ -0,0 +1,5 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View file

@ -1,4 +1,4 @@
/* ADC1 Example /* Temperature Sensor Example
This example code is in the Public Domain (or CC0 licensed, at your option.) This example code is in the Public Domain (or CC0 licensed, at your option.)
@ -11,30 +11,31 @@
#include "esp_log.h" #include "esp_log.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "driver/temp_sensor.h"
/* Note: ESP32 don't support temperature sensor */
#if CONFIG_IDF_TARGET_ESP32S2BETA #if CONFIG_IDF_TARGET_ESP32S2BETA
#include "temp_sensor.h"
static const char* TAG = "TempSensor"; static const char *TAG = "TempSensor";
void tempsensor_example(void *arg) void tempsensor_example(void *arg)
{ {
// Initialize touch pad peripheral, it will start a timer to run a filter // Initialize touch pad peripheral, it will start a timer to run a filter
ESP_LOGI(TAG, "Initializing temp sensor"); ESP_LOGI(TAG, "Initializing Temperature sensor");
uint8_t temp_out; float tsens_out;
temp_sensor_t temp_sensor; temp_sensor_config_t temp_sensor = TSENS_CONFIG_DEFAULT();
temp_sensor_get_config(&temp_sensor); temp_sensor_get_config(&temp_sensor);
ESP_LOGI(TAG, "default dac %d, clk_div %d", temp_sensor.dac_offset, temp_sensor.clk_div); ESP_LOGI(TAG, "default dac %d, clk_div %d", temp_sensor.dac_offset, temp_sensor.clk_div);
temp_sensor.dac_offset = TEMP_SENSOR_DAC_DEFAULT; // DEFAULT: range:-10℃ ~ 80℃, error < 1℃. temp_sensor.dac_offset = TSENS_DAC_DEFAULT; // DEFAULT: range:-10℃ ~ 80℃, error < 1℃.
temp_sensor_set_config(temp_sensor); temp_sensor_set_config(temp_sensor);
temp_sensor_start(); temp_sensor_start();
ESP_LOGI(TAG, "temp sensor started"); ESP_LOGI(TAG, "Temperature sensor started");
while(1) { while (1) {
vTaskDelay(1000 / portTICK_RATE_MS); vTaskDelay(1000 / portTICK_RATE_MS);
temp_sensor_read(&temp_out); temp_sensor_read_celsius(&tsens_out);
ESP_LOGI(TAG, "temp out %d", temp_out); ESP_LOGI(TAG, "Temperature out celsius %f°C", tsens_out);
} }
ESP_LOGI(TAG, "test over");
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@ -42,5 +43,12 @@ void app_main()
{ {
xTaskCreate(tempsensor_example, "temp", 2048, NULL, 5, NULL); xTaskCreate(tempsensor_example, "temp", 2048, NULL, 5, NULL);
} }
#endif
#elif CONFIG_IDF_TARGET_ESP32
void app_main()
{
printf("ESP32 don't support temperature sensor\n");
}
#endif

View file

@ -1,4 +1,3 @@
set(COMPONENT_SRCS "tp_interrupt_main.c") set(COMPONENT_SRCS "${CONFIG_IDF_TARGET}/tp_interrupt_main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component() register_component()

View file

@ -3,3 +3,4 @@
# #
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
COMPONENT_SRCDIRS := $(IDF_TARGET)

View file

@ -0,0 +1,171 @@
/* Touch Pad Interrupt Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "soc/rtc_periph.h"
#include "soc/sens_periph.h"
static const char *TAG = "Touch pad";
#define TOUCH_THRESH_NO_USE (0)
#define TOUCH_THRESH_PERCENT (80)
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
static bool s_pad_activated[TOUCH_PAD_MAX];
static uint32_t s_pad_init_val[TOUCH_PAD_MAX];
/*
Read values sensed at all available touch pads.
Use 2 / 3 of read value as the threshold
to trigger interrupt when the pad is touched.
Note: this routine demonstrates a simple way
to configure activation threshold for the touch pads.
Do not touch any pads when this routine
is running (on application start).
*/
static void tp_example_set_thresholds(void)
{
uint16_t touch_value;
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
//read filtered value
touch_pad_read_filtered(i, &touch_value);
s_pad_init_val[i] = touch_value;
ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", i, touch_value);
//set interrupt threshold.
ESP_ERROR_CHECK(touch_pad_set_thresh(i, touch_value * 2 / 3));
}
}
/*
Check if any of touch pads has been activated
by reading a table updated by rtc_intr()
If so, then print it out on a serial monitor.
Clear related entry in the table afterwards
In interrupt mode, the table is updated in touch ISR.
In filter mode, we will compare the current filtered value with the initial one.
If the current filtered value is less than 80% of the initial value, we can
regard it as a 'touched' event.
When calling touch_pad_init, a timer will be started to run the filter.
This mode is designed for the situation that the pad is covered
by a 2-or-3-mm-thick medium, usually glass or plastic.
The difference caused by a 'touch' action could be very small, but we can still use
filter mode to detect a 'touch' event.
*/
static void tp_example_read_task(void *pvParameter)
{
static int show_message;
int change_mode = 0;
int filter_mode = 0;
while (1) {
if (filter_mode == 0) {
//interrupt mode, enable touch interrupt
touch_pad_intr_enable();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
if (s_pad_activated[i] == true) {
ESP_LOGI(TAG, "T%d activated!", i);
// Wait a while for the pad being released
vTaskDelay(200 / portTICK_PERIOD_MS);
// Clear information on pad activation
s_pad_activated[i] = false;
// Reset the counter triggering a message
// that application is running
show_message = 1;
}
}
} else {
//filter mode, disable touch interrupt
touch_pad_intr_disable();
touch_pad_clear_status();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
uint16_t value = 0;
touch_pad_read_filtered(i, &value);
if (value < s_pad_init_val[i] * TOUCH_THRESH_PERCENT / 100) {
ESP_LOGI(TAG, "T%d activated!", i);
ESP_LOGI(TAG, "value: %d; init val: %d", value, s_pad_init_val[i]);
vTaskDelay(200 / portTICK_PERIOD_MS);
// Reset the counter to stop changing mode.
change_mode = 1;
show_message = 1;
}
}
}
vTaskDelay(10 / portTICK_PERIOD_MS);
// If no pad is touched, every couple of seconds, show a message
// that application is running
if (show_message++ % 500 == 0) {
ESP_LOGI(TAG, "Waiting for any pad being touched...");
}
// Change mode if no pad is touched for a long time.
// We can compare the two different mode.
if (change_mode++ % 2000 == 0) {
filter_mode = !filter_mode;
ESP_LOGW(TAG, "Change mode...%s", filter_mode == 0 ? "interrupt mode" : "filter mode");
}
}
}
/*
Handle an interrupt triggered when a pad is touched.
Recognize what pad has been touched and save it in a table.
*/
static void tp_example_rtc_intr(void *arg)
{
uint32_t pad_intr = touch_pad_get_status();
//clear interrupt
touch_pad_clear_status();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
if ((pad_intr >> i) & 0x01) {
s_pad_activated[i] = true;
}
}
}
/*
* Before reading touch pad, we need to initialize the RTC IO.
*/
static void tp_example_touch_pad_init()
{
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
//init RTC IO and mode for touch pad.
touch_pad_config(i, TOUCH_THRESH_NO_USE);
}
}
void app_main()
{
// Initialize touch pad peripheral, it will start a timer to run a filter
ESP_LOGI(TAG, "Initializing touch pad");
touch_pad_init();
// If use interrupt trigger mode, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'.
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
// Set reference voltage for charging/discharging
// For most usage scenarios, we recommend using the following combination:
// the high reference valtage will be 2.7V - 1V = 1.7V, The low reference voltage will be 0.5V.
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
// Init touch pad IO
tp_example_touch_pad_init();
// Initialize and start a software filter to detect slight change of capacitance.
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
// Set thresh hold
tp_example_set_thresholds();
// Register touch interrupt ISR
touch_pad_isr_register(tp_example_rtc_intr, NULL);
// Start a task to show what pads have been touched
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
}

View file

@ -0,0 +1,201 @@
/* Touch Pad Interrupt Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "soc/rtc_periph.h"
#include "soc/sens_periph.h"
static const char *TAG = "Touch pad";
static QueueHandle_t que_touch = NULL;
typedef struct touch_msg {
touch_pad_intr_mask_t intr_mask;
uint32_t pad_num;
uint32_t pad_status;
uint32_t pad_val;
} touch_event_t;
#define TOUCH_BUTTON_NUM 4
#define TOUCH_BUTTON_WATERPROOF_ENABLE 1
#define TOUCH_BUTTON_DENOISE_ENABLE 1
static const touch_pad_t button[TOUCH_BUTTON_NUM] = {
TOUCH_PAD_NUM7, // 'SELECT' button.
TOUCH_PAD_NUM9, // 'MENU' button.
TOUCH_PAD_NUM11, // 'BACK' button.
TOUCH_PAD_NUM13, // Guard ring for waterproof design.
// if this pad be touched, other pads no response.
};
/*
* Touch threshold. The threshold determines the sensitivity of the touch.
* This threshold is derived by testing changes in readings from different touch channels.
* If (raw_data - baseline) > baseline * threshold, the pad be actived.
* If (raw_data - baseline) < baseline * threshold, the pad be inactived.
*/
static const float button_threshold[TOUCH_BUTTON_NUM] = {
0.2, // 20%.
0.2, // 20%.
0.2, // 20%.
0.1, // 10%.
};
/*
Handle an interrupt triggered when a pad is touched.
Recognize what pad has been touched and save it in a table.
*/
static void touchsensor_interrupt_cb(void *arg)
{
int task_awoken = pdFALSE;
touch_event_t evt;
evt.intr_mask = touch_pad_intr_status_get_mask();
evt.pad_status = touch_pad_get_status();
evt.pad_num = touch_pad_get_scan_curr();
if (evt.intr_mask & TOUCH_PAD_INTR_MASK_DONE) {
touch_pad_filter_baseline_read(evt.pad_num, &evt.pad_val);
}
xQueueSendFromISR(que_touch, &evt, &task_awoken);
if (task_awoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
static void tp_example_set_thresholds(void)
{
uint32_t touch_value;
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
//read baseline value
touch_pad_read_raw_data(button[i], &touch_value);
//set interrupt threshold.
touch_pad_set_thresh(button[i], touch_value * button_threshold[i]);
ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \
button[i], touch_value, (uint32_t)(touch_value * button_threshold[i]));
}
}
static void touchsensor_filter_set(touch_filter_mode_t mode)
{
/* Filter function */
touch_filter_config_t filter_info = {
.mode = mode, // Test jitter and filter 1/4.
.debounce_cnt = 1, // 1 time count.
.hysteresis_thr = 1, // 9.4%
.noise_thr = 1, // 37.5%
.noise_neg_thr = 1, // 37.5%
.neg_noise_limit = 10, // 10 time count.
.jitter_step = 4, // use for jitter mode.
};
touch_pad_filter_set_config(&filter_info);
touch_pad_filter_enable();
touch_pad_filter_baseline_reset(TOUCH_PAD_MAX);
ESP_LOGI(TAG, "touch pad filter init %d", mode);
}
static void tp_example_read_task(void *pvParameter)
{
touch_event_t evt = {0};
static uint8_t guard_mode_flag = 0;
/* Wait touch sensor init done */
vTaskDelay(100 / portTICK_RATE_MS);
tp_example_set_thresholds();
while (1) {
int ret = xQueueReceive(que_touch, &evt, (portTickType)portMAX_DELAY);
if (ret != pdTRUE) {
continue;
}
if (evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) {
/* if guard pad be touched, other pads no response. */
if (evt.pad_num == button[3]) {
guard_mode_flag = 1;
ESP_LOGW(TAG, "TouchSensor [%d] be actived, enter guard mode", evt.pad_num);
} else {
if (guard_mode_flag == 0) {
ESP_LOGI(TAG, "TouchSensor [%d] be actived, status mask 0x%x", evt.pad_num, evt.pad_status);
} else {
ESP_LOGW(TAG, "In guard mode. No response");
}
}
}
if (evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) {
/* if guard pad be touched, other pads no response. */
if (evt.pad_num == button[3]) {
guard_mode_flag = 0;
ESP_LOGW(TAG, "TouchSensor [%d] be actived, exit guard mode", evt.pad_num);
} else {
if (guard_mode_flag == 0) {
ESP_LOGI(TAG, "TouchSensor [%d] be inactived, status mask 0x%x", evt.pad_num, evt.pad_status);
}
}
}
if (evt.intr_mask & TOUCH_PAD_INTR_MASK_DONE) {
ESP_LOGI(TAG, "TouchSensor [%d] measure done, raw data %d", evt.pad_num, evt.pad_val);
}
}
}
void app_main()
{
if (que_touch == NULL) {
que_touch = xQueueCreate(TOUCH_BUTTON_NUM, sizeof(touch_event_t));
}
// Initialize touch pad peripheral, it will start a timer to run a filter
ESP_LOGI(TAG, "Initializing touch pad");
/* Initialize touch pad peripheral. */
touch_pad_init();
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
touch_pad_config(button[i]);
touch_pad_set_thresh(button[i], TOUCH_PAD_THRESHOLD_MAX);
}
#if TOUCH_BUTTON_DENOISE_ENABLE
/* Denoise setting at TouchSensor 0. */
touch_pad_denoise_t denoise = {
/* The bits to be cancelled are determined according to the noise level. */
.grade = TOUCH_PAD_DENOISE_BIT4,
.cap_level = TOUCH_PAD_DENOISE_CAP_L7,
};
touch_pad_denoise_set_config(denoise);
touch_pad_denoise_enable();
ESP_LOGI(TAG, "Denoise function init");
#endif
#if TOUCH_BUTTON_WATERPROOF_ENABLE
/* Waterproof function */
touch_pad_waterproof_t waterproof = {
.guard_ring_pad = button[3], // If no ring pad, set 0;
/* It depends on the number of the parasitic capacitance of the shield pad. */
.shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf
};
touch_pad_waterproof_set_config(waterproof);
touch_pad_waterproof_enable();
ESP_LOGI(TAG, "touch pad waterproof init");
#endif
/* Filter setting */
touchsensor_filter_set(TOUCH_PAD_FILTER_IIR_8);
/* Register touch interrupt ISR, enable intr type. */
touch_pad_isr_register(touchsensor_interrupt_cb, NULL, TOUCH_PAD_INTR_MASK_ALL);
touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE);
// touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_DONE); // Use for debug
/* Enable touch sensor clock. Work mode is "timer trigger". */
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
touch_pad_fsm_start();
// Start a task to show what pads have been touched
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
}

View file

@ -1,356 +0,0 @@
/* Touch Pad Interrupt Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "soc/rtc_periph.h"
#include "soc/sens_periph.h"
static const char* TAG = "Touch pad";
#if CONFIG_IDF_TARGET_ESP32
#define TOUCH_THRESH_NO_USE (0)
#define TOUCH_THRESH_PERCENT (80)
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
static bool s_pad_activated[TOUCH_PAD_MAX];
static uint32_t s_pad_init_val[TOUCH_PAD_MAX];
/*
Read values sensed at all available touch pads.
Use 2 / 3 of read value as the threshold
to trigger interrupt when the pad is touched.
Note: this routine demonstrates a simple way
to configure activation threshold for the touch pads.
Do not touch any pads when this routine
is running (on application start).
*/
static void tp_example_set_thresholds(void)
{
uint16_t touch_value;
for (int i = 0; i<TOUCH_PAD_MAX; i++) {
//read filtered value
touch_pad_read_filtered(i, &touch_value);
s_pad_init_val[i] = touch_value;
ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", i, touch_value);
//set interrupt threshold.
ESP_ERROR_CHECK(touch_pad_set_thresh(i, touch_value * 2 / 3));
}
}
/*
Check if any of touch pads has been activated
by reading a table updated by rtc_intr()
If so, then print it out on a serial monitor.
Clear related entry in the table afterwards
In interrupt mode, the table is updated in touch ISR.
In filter mode, we will compare the current filtered value with the initial one.
If the current filtered value is less than 80% of the initial value, we can
regard it as a 'touched' event.
When calling touch_pad_init, a timer will be started to run the filter.
This mode is designed for the situation that the pad is covered
by a 2-or-3-mm-thick medium, usually glass or plastic.
The difference caused by a 'touch' action could be very small, but we can still use
filter mode to detect a 'touch' event.
*/
static void tp_example_read_task(void *pvParameter)
{
static int show_message;
int change_mode = 0;
int filter_mode = 0;
while (1) {
if (filter_mode == 0) {
//interrupt mode, enable touch interrupt
touch_pad_intr_enable();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
if (s_pad_activated[i] == true) {
ESP_LOGI(TAG, "T%d activated!", i);
// Wait a while for the pad being released
vTaskDelay(200 / portTICK_PERIOD_MS);
// Clear information on pad activation
s_pad_activated[i] = false;
// Reset the counter triggering a message
// that application is running
show_message = 1;
}
}
} else {
//filter mode, disable touch interrupt
touch_pad_intr_disable();
touch_pad_clear_status();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
uint16_t value = 0;
touch_pad_read_filtered(i, &value);
if (value < s_pad_init_val[i] * TOUCH_THRESH_PERCENT / 100) {
ESP_LOGI(TAG, "T%d activated!", i);
ESP_LOGI(TAG, "value: %d; init val: %d", value, s_pad_init_val[i]);
vTaskDelay(200 / portTICK_PERIOD_MS);
// Reset the counter to stop changing mode.
change_mode = 1;
show_message = 1;
}
}
}
vTaskDelay(10 / portTICK_PERIOD_MS);
// If no pad is touched, every couple of seconds, show a message
// that application is running
if (show_message++ % 500 == 0) {
ESP_LOGI(TAG, "Waiting for any pad being touched...");
}
// Change mode if no pad is touched for a long time.
// We can compare the two different mode.
if (change_mode++ % 2000 == 0) {
filter_mode = !filter_mode;
ESP_LOGW(TAG, "Change mode...%s", filter_mode == 0? "interrupt mode": "filter mode");
}
}
}
/*
Handle an interrupt triggered when a pad is touched.
Recognize what pad has been touched and save it in a table.
*/
static void tp_example_rtc_intr(void * arg)
{
uint32_t pad_intr = touch_pad_get_status();
//clear interrupt
touch_pad_clear_status();
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
if ((pad_intr >> i) & 0x01) {
s_pad_activated[i] = true;
}
}
}
/*
* Before reading touch pad, we need to initialize the RTC IO.
*/
static void tp_example_touch_pad_init()
{
for (int i = 0;i< TOUCH_PAD_MAX;i++) {
//init RTC IO and mode for touch pad.
touch_pad_config(i, TOUCH_THRESH_NO_USE);
}
}
void app_main()
{
// Initialize touch pad peripheral, it will start a timer to run a filter
ESP_LOGI(TAG, "Initializing touch pad");
touch_pad_init();
// If use interrupt trigger mode, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'.
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
// Set reference voltage for charging/discharging
// For most usage scenarios, we recommend using the following combination:
// the high reference valtage will be 2.7V - 1V = 1.7V, The low reference voltage will be 0.5V.
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
// Init touch pad IO
tp_example_touch_pad_init();
// Initialize and start a software filter to detect slight change of capacitance.
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
// Set thresh hold
tp_example_set_thresholds();
// Register touch interrupt ISR
touch_pad_isr_register(tp_example_rtc_intr, NULL);
// Start a task to show what pads have been touched
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
}
#elif CONFIG_IDF_TARGET_ESP32S2BETA
static QueueHandle_t que_touch = NULL;
typedef struct touch_msg {
touch_pad_intr_mask_t intr_mask;
uint32_t pad_num;
uint32_t pad_status;
uint32_t pad_val;
}touch_event_t;
#define TOUCH_BUTTON_NUM 4
#define TOUCH_BUTTON_WATERPROOF_ENABLE 1
#define TOUCH_BUTTON_DENOISE_ENABLE 1
static const touch_pad_t button[TOUCH_BUTTON_NUM] = {
TOUCH_PAD_NUM7, // 'SELECT' button.
TOUCH_PAD_NUM9, // 'MENU' button.
TOUCH_PAD_NUM11, // 'BACK' button.
TOUCH_PAD_NUM13, // Guard ring for waterproof design.
// if this pad be touched, other pads no response.
};
/*
* Touch threshold. The threshold determines the sensitivity of the touch.
* This threshold is derived by testing changes in readings from different touch channels.
* If (raw_data - baseline) > baseline * threshold, the pad be actived.
* If (raw_data - baseline) < baseline * threshold, the pad be inactived.
*/
static const float button_threshold[TOUCH_BUTTON_NUM] = {
0.2, // 20%.
0.2, // 20%.
0.2, // 20%.
0.1, // 10%.
};
/*
Handle an interrupt triggered when a pad is touched.
Recognize what pad has been touched and save it in a table.
*/
static void touchsensor_interrupt_cb(void * arg)
{
int task_awoken = pdFALSE;
touch_event_t evt;
evt.intr_mask = touch_pad_get_int_status();
evt.pad_status = touch_pad_get_status();
evt.pad_num = touch_pad_get_scan_curr();
if(evt.intr_mask & TOUCH_PAD_INTR_MASK_DONE) {
touch_pad_filter_baseline_read(evt.pad_num, &evt.pad_val);
}
xQueueSendFromISR(que_touch, &evt, &task_awoken);
if (task_awoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
static void tp_example_set_thresholds(void)
{
uint32_t touch_value;
for (int i = 0; i<TOUCH_BUTTON_NUM; i++) {
//read baseline value
touch_pad_read_raw(button[i], &touch_value);
//set interrupt threshold.
touch_pad_set_thresh(button[i], touch_value * button_threshold[i]);
ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \
button[i], touch_value, (uint32_t)(touch_value * button_threshold[i]));
}
}
static void touchsensor_filter_set(touch_filter_mode_t mode)
{
/* Filter function */
touch_filter_config_t filter_info = {
.mode = mode, // Test jitter and filter 1/4.
.debounce_cnt = 1, // 1 time count.
.hysteresis_thr = 1, // 9.4%
.noise_thr = 1, // 37.5%
.noise_neg_thr = 1, // 37.5%
.neg_noise_limit = 10, // 10 time count.
.jitter_step = 4, // use for jitter mode.
};
touch_pad_filter_set_config(filter_info);
touch_pad_filter_start();
touch_pad_filter_baseline_reset(TOUCH_PAD_MAX);
ESP_LOGI(TAG, "touch pad filter init %d", mode);
}
static void tp_example_read_task(void *pvParameter)
{
touch_event_t evt = {0};
static uint8_t guard_mode_flag = 0;
/* Wait touch sensor init done */
vTaskDelay(100 / portTICK_RATE_MS);
tp_example_set_thresholds();
while (1) {
int ret = xQueueReceive(que_touch, &evt, (portTickType)portMAX_DELAY);
if(ret != pdTRUE) {
continue;
}
if(evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) {
/* if guard pad be touched, other pads no response. */
if(evt.pad_num == button[3]) {
guard_mode_flag = 1;
ESP_LOGW(TAG, "TouchSensor [%d] be actived, enter guard mode", evt.pad_num);
} else {
if(guard_mode_flag == 0) {
ESP_LOGI(TAG, "TouchSensor [%d] be actived, status mask 0x%x", evt.pad_num, evt.pad_status);
} else {
ESP_LOGW(TAG, "In guard mode. No response");
}
}
}
if(evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) {
/* if guard pad be touched, other pads no response. */
if(evt.pad_num == button[3]) {
guard_mode_flag = 0;
ESP_LOGW(TAG, "TouchSensor [%d] be actived, exit guard mode", evt.pad_num);
} else {
if(guard_mode_flag == 0) {
ESP_LOGI(TAG, "TouchSensor [%d] be inactived, status mask 0x%x", evt.pad_num, evt.pad_status);
}
}
}
if(evt.intr_mask & TOUCH_PAD_INTR_MASK_DONE) {
ESP_LOGI(TAG, "TouchSensor [%d] measure done, raw data %d", evt.pad_num, evt.pad_val);
}
}
}
void app_main()
{
touch_event_t evt = {0};
if(que_touch == NULL) {
que_touch = xQueueCreate(TOUCH_BUTTON_NUM, sizeof(touch_event_t));
}
// Initialize touch pad peripheral, it will start a timer to run a filter
ESP_LOGI(TAG, "Initializing touch pad");
/* Initialize touch pad peripheral. */
touch_pad_init();
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
touch_pad_config(button[i]);
touch_pad_set_thresh(button[i], TOUCH_PAD_THRESHOLD_MAX);
}
#if TOUCH_BUTTON_DENOISE_ENABLE
/* Denoise setting at TouchSensor 0. */
touch_pad_denoise_t denoise = {
/* The bits to be cancelled are determined according to the noise level. */
.grade = TOUCH_PAD_DENOISE_BIT4,
.cap_level = TOUCH_PAD_DENOISE_CAP_L7,
};
touch_pad_denoise_set_config(denoise);
touch_pad_denoise_enable();
ESP_LOGI(TAG, "Denoise function init");
#endif
#if TOUCH_BUTTON_WATERPROOF_ENABLE
/* Waterproof function */
touch_pad_waterproof_t waterproof = {
.guard_ring_pad = button[3], // If no ring pad, set 0;
/* It depends on the number of the parasitic capacitance of the shield pad. */
.shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf
};
touch_pad_waterproof_set_config(waterproof);
touch_pad_waterproof_enable();
ESP_LOGI(TAG, "touch pad waterproof init");
#endif
/* Filter setting */
touchsensor_filter_set(TOUCH_PAD_FILTER_IIR_8);
/* Register touch interrupt ISR, enable intr type. */
touch_pad_isr_register(touchsensor_interrupt_cb, NULL, TOUCH_PAD_INTR_MASK_ALL);
touch_pad_intr_enable(TOUCH_PAD_INTR_INACTIVE);
touch_pad_intr_enable(TOUCH_PAD_INTR_ACTIVE);
/* Enable touch sensor clock. Work mode is "timer trigger". */
touch_pad_fsm_start(TOUCH_FSM_MODE_TIMER);
// Start a task to show what pads have been touched
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
}
#endif

View file

@ -1,4 +1,3 @@
set(COMPONENT_SRCS "tp_read_main.c") set(COMPONENT_SRCS "${CONFIG_IDF_TARGET}/tp_read_main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component() register_component()

View file

@ -3,3 +3,4 @@
# #
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
COMPONENT_SRCDIRS := $(IDF_TARGET)

View file

@ -12,7 +12,6 @@
#include "driver/touch_pad.h" #include "driver/touch_pad.h"
#include "esp_log.h" #include "esp_log.h"
#if CONFIG_IDF_TARGET_ESP32
#define TOUCH_PAD_NO_CHANGE (-1) #define TOUCH_PAD_NO_CHANGE (-1)
#define TOUCH_THRESH_NO_USE (0) #define TOUCH_THRESH_NO_USE (0)
#define TOUCH_FILTER_MODE_EN (1) #define TOUCH_FILTER_MODE_EN (1)
@ -71,74 +70,3 @@ void app_main()
// Start task to read values sensed by pads // Start task to read values sensed by pads
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL); xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
} }
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#define TOUCH_BUTTON_NUM 14
static const char * TAG = "touch read";
static const touch_pad_t button[TOUCH_BUTTON_NUM] = {
TOUCH_PAD_NUM1,
TOUCH_PAD_NUM2,
TOUCH_PAD_NUM3,
TOUCH_PAD_NUM4,
TOUCH_PAD_NUM5,
TOUCH_PAD_NUM6,
TOUCH_PAD_NUM7,
TOUCH_PAD_NUM8,
TOUCH_PAD_NUM9,
TOUCH_PAD_NUM10,
TOUCH_PAD_NUM11,
TOUCH_PAD_NUM12,
TOUCH_PAD_NUM13,
TOUCH_PAD_NUM14
};
/*
Read values sensed at all available touch pads.
Print out values in a loop on a serial monitor.
*/
static void tp_example_read_task(void *pvParameter)
{
uint16_t touch_value;
uint16_t touch_filter_value;
/* Wait touch sensor init done */
vTaskDelay(100 / portTICK_RATE_MS);
printf("Touch Sensor read, the output format is: \nTouchpad num:[raw data]\n\n");
while (1) {
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
touch_pad_read_raw(button[i], &touch_value); // read raw data.
printf("T%d: [%4d] ", button[i], touch_value);
}
printf("\n");
vTaskDelay(200 / portTICK_PERIOD_MS);
}
}
void app_main()
{
/* Initialize touch pad peripheral. */
touch_pad_init();
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
touch_pad_config(button[i]);
touch_pad_set_thresh(button[i], TOUCH_PAD_THRESHOLD_MAX);
}
/* Denoise setting at TouchSensor 0. */
touch_pad_denoise_t denoise = {
/* The bits to be cancelled are determined according to the noise level. */
.grade = TOUCH_PAD_DENOISE_BIT4,
.cap_level = TOUCH_PAD_DENOISE_CAP_L7,
};
touch_pad_denoise_set_config(denoise);
touch_pad_denoise_enable();
ESP_LOGI(TAG, "Denoise function init");
/* Enable touch sensor clock. Work mode is "timer trigger". */
touch_pad_fsm_start(TOUCH_FSM_MODE_TIMER);
/* Start task to read values by pads. */
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
}
#endif

View file

@ -0,0 +1,82 @@
/* Touch Pad Read Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/touch_pad.h"
#include "esp_log.h"
#define TOUCH_BUTTON_NUM 14
static const char * TAG = "touch read";
static const touch_pad_t button[TOUCH_BUTTON_NUM] = {
TOUCH_PAD_NUM1,
TOUCH_PAD_NUM2,
TOUCH_PAD_NUM3,
TOUCH_PAD_NUM4,
TOUCH_PAD_NUM5,
TOUCH_PAD_NUM6,
TOUCH_PAD_NUM7,
TOUCH_PAD_NUM8,
TOUCH_PAD_NUM9,
TOUCH_PAD_NUM10,
TOUCH_PAD_NUM11,
TOUCH_PAD_NUM12,
TOUCH_PAD_NUM13,
TOUCH_PAD_NUM14
};
/*
Read values sensed at all available touch pads.
Print out values in a loop on a serial monitor.
*/
static void tp_example_read_task(void *pvParameter)
{
uint32_t touch_value;
/* Wait touch sensor init done */
vTaskDelay(100 / portTICK_RATE_MS);
printf("Touch Sensor read, the output format is: \nTouchpad num:[raw data]\n\n");
while (1) {
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
touch_pad_read_raw_data(button[i], &touch_value); // read raw data.
printf("T%d: [%4d] ", button[i], touch_value);
}
printf("\n");
vTaskDelay(200 / portTICK_PERIOD_MS);
}
}
void app_main()
{
/* Initialize touch pad peripheral. */
touch_pad_init();
for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
touch_pad_config(button[i]);
touch_pad_set_thresh(button[i], TOUCH_PAD_THRESHOLD_MAX);
}
/* Denoise setting at TouchSensor 0. */
touch_pad_denoise_t denoise = {
/* The bits to be cancelled are determined according to the noise level. */
.grade = TOUCH_PAD_DENOISE_BIT4,
.cap_level = TOUCH_PAD_DENOISE_CAP_L7,
};
touch_pad_denoise_set_config(denoise);
touch_pad_denoise_enable();
ESP_LOGI(TAG, "Denoise function init");
/* Enable touch sensor clock. Work mode is "timer trigger". */
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
touch_pad_fsm_start();
/* Start task to read values by pads. */
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
}

View file

@ -145,6 +145,7 @@ void app_main()
esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH); esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH);
#ifdef CONFIG_ENABLE_TOUCH_WAKEUP #ifdef CONFIG_ENABLE_TOUCH_WAKEUP
#if CONFIG_IDF_TARGET_ESP32
// Initialize touch pad peripheral. // Initialize touch pad peripheral.
// The default fsm mode is software trigger mode. // The default fsm mode is software trigger mode.
touch_pad_init(); touch_pad_init();
@ -160,9 +161,50 @@ void app_main()
touch_pad_config(TOUCH_PAD_NUM9, TOUCH_THRESH_NO_USE); touch_pad_config(TOUCH_PAD_NUM9, TOUCH_THRESH_NO_USE);
calibrate_touch_pad(TOUCH_PAD_NUM8); calibrate_touch_pad(TOUCH_PAD_NUM8);
calibrate_touch_pad(TOUCH_PAD_NUM9); calibrate_touch_pad(TOUCH_PAD_NUM9);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
/* Initialize touch pad peripheral. */
touch_pad_init();
/* Only support one touch channel in sleep mode. */
touch_pad_set_thresh(TOUCH_PAD_NUM8, TOUCH_PAD_THRESHOLD_MAX);
touch_pad_sleep_channel_t slp_config = {
.touch_num = TOUCH_PAD_NUM8,
.sleep_pad_threshold = TOUCH_PAD_THRESHOLD_MAX,
.en_proximity = false,
};
touch_pad_sleep_channel_config(slp_config);
/* Filter setting */
touch_filter_config_t filter_info = {
.mode = TOUCH_PAD_FILTER_IIR_8,
.debounce_cnt = 1, // 1 time count.
.hysteresis_thr = 1, // 9.4%
.noise_thr = 1, // 37.5%
.noise_neg_thr = 1, // 37.5%
.neg_noise_limit = 10, // 10 time count.
.jitter_step = 4, // use for jitter mode.
};
touch_pad_filter_set_config(&filter_info);
touch_pad_filter_enable();
touch_pad_filter_baseline_reset(TOUCH_PAD_MAX);
printf("touch pad filter init %d", TOUCH_PAD_FILTER_IIR_8);
/* Enable touch sensor clock. Work mode is "timer trigger". */
touch_pad_fsm_start(TOUCH_FSM_MODE_TIMER);
uint32_t touch_value;
//read baseline value
touch_pad_read_raw(TOUCH_PAD_NUM8, &touch_value);
//set interrupt threshold.
touch_pad_sleep_channel_t slp_config = {
.touch_num = TOUCH_PAD_NUM8,
.sleep_pad_threshold = touch_value * 0.2,
.en_proximity = false,
};
touch_pad_sleep_channel_config(slp_config); //20%
printf("test init: touch pad [%d] base %d, thresh %d", \
TOUCH_PAD_NUM8, touch_value, (uint32_t)(touch_value * 0.2));
#endif
printf("Enabling touch pad wakeup\n"); printf("Enabling touch pad wakeup\n");
esp_sleep_enable_touchpad_wakeup(); esp_sleep_enable_touchpad_wakeup();
#endif // CONFIG_ENABLE_TOUCH_WAKEUP #endif // CONFIG_ENABLE_TOUCH_WAKEUP
#ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP #ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP
@ -186,6 +228,7 @@ void app_main()
} }
#ifdef CONFIG_ENABLE_TOUCH_WAKEUP #ifdef CONFIG_ENABLE_TOUCH_WAKEUP
#if CONFIG_IDF_TARGET_ESP32
static void calibrate_touch_pad(touch_pad_t pad) static void calibrate_touch_pad(touch_pad_t pad)
{ {
int avg = 0; int avg = 0;
@ -207,6 +250,7 @@ static void calibrate_touch_pad(touch_pad_t pad)
touch_pad_config(pad, threshold); touch_pad_config(pad, threshold);
} }
} }
#endif
#endif // CONFIG_ENABLE_TOUCH_WAKEUP #endif // CONFIG_ENABLE_TOUCH_WAKEUP
#ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP #ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP