mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
Merge branch 'feature/touch_element_sleep' into 'master'
touch_element: add low-power support and example into touch element Closes IDF-3027 and IDF-4353 See merge request espressif/esp-idf!13001
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "hal/rtc_io_hal.h"
|
||||
#include "hal/rtc_cntl_ll.h"
|
||||
|
||||
#include "driver/uart.h"
|
||||
|
||||
|
||||
@@ -47,6 +47,11 @@ static inline void rtc_cntl_ll_ulp_int_clear(void)
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_SAR_INT_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, wait_cycle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,6 +47,11 @@ static inline void rtc_cntl_ll_ulp_int_clear(void)
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, wait_cycle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -127,6 +127,11 @@ static inline void rtc_cntl_ll_ulp_int_clear(void)
|
||||
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR);
|
||||
}
|
||||
|
||||
static inline void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
|
||||
{
|
||||
REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, wait_cycle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -292,7 +292,7 @@
|
||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||
#define SOC_TOUCH_VERSION_2 (1) /*!<Hardware version of touch sensor */
|
||||
#define SOC_TOUCH_SENSOR_NUM (15) /*!<15 Touch channels */
|
||||
#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3) /* Sopport touch proximity channel number. */
|
||||
#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3) /*!<Support touch proximity channel number. */
|
||||
|
||||
#define SOC_TOUCH_PAD_THRESHOLD_MAX (0x1FFFFF) /*!<If set touch threshold max value, The touch sensor can't be in touched status */
|
||||
#define SOC_TOUCH_PAD_MEASURE_WAIT_MAX (0xFF) /*!<The timer frequency is 8Mhz, the max value is 0xff */
|
||||
|
||||
@@ -94,6 +94,14 @@ typedef struct {
|
||||
touch_pad_t guard_channel; //!< Waterproof Guard-Sensor channel number (index)
|
||||
float guard_sensitivity; //!< Waterproof Guard-Sensor sensitivity
|
||||
} touch_elem_waterproof_config_t;
|
||||
|
||||
/**
|
||||
* @brief Touch element sleep configuration passed to touch_element_enable_light_sleep or touch_element_enable_deep_sleep
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t sample_count; //!< scan times in every measurement, normally equal to the 'sample_count' field in 'touch_elem_hw_config_t'.
|
||||
uint16_t sleep_cycle; //!< sleep_cycle decide the interval between two measurements, t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency), normally equal to the 'sleep_cycle' field in 'touch_elem_hw_config_t'.
|
||||
} touch_elem_sleep_config_t;
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
typedef void *touch_elem_handle_t; //!< Touch element handle type
|
||||
typedef uint32_t touch_elem_event_t; //!< Touch element event type
|
||||
@@ -256,6 +264,75 @@ esp_err_t touch_element_waterproof_add(touch_elem_handle_t element_handle);
|
||||
*/
|
||||
esp_err_t touch_element_waterproof_remove(touch_elem_handle_t element_handle);
|
||||
|
||||
/**
|
||||
* @brief Touch element light sleep initialization
|
||||
*
|
||||
* @note It should be called after touch button element installed.
|
||||
* Any of installed touch element can wake up from the light sleep
|
||||
*
|
||||
* @param[in] sleep_config Sleep configurations, set NULL to use default config
|
||||
* @return
|
||||
* - ESP_OK: Successfully initialized touch sleep
|
||||
* - ESP_ERR_INVALID_STATE: Touch element is not installed or touch sleep has been installed
|
||||
* - ESP_ERR_INVALID_ARG: inputed argument is NULL
|
||||
* - ESP_ERR_NO_MEM: no memory for touch sleep struct
|
||||
* - ESP_ERR_NOT_SUPPORTED: inputed wakeup_elem_handle is not touch_button_handle_t type, currently only touch_button_handle_t supported
|
||||
*/
|
||||
esp_err_t touch_element_enable_light_sleep(const touch_elem_sleep_config_t *sleep_config);
|
||||
|
||||
/**
|
||||
* @brief Release the resources that allocated by touch_element_enable_deep_sleep()
|
||||
*
|
||||
* This function will also disable the touch sensor to wake up the device
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: uninstall success
|
||||
* - ESP_ERR_INVALID_STATE: touch sleep has not been installed
|
||||
*/
|
||||
esp_err_t touch_element_disable_light_sleep(void);
|
||||
|
||||
/**
|
||||
* @brief Touch element deep sleep initialization
|
||||
*
|
||||
* This function will enable the device wake-up from deep sleep or light sleep by touch sensor
|
||||
*
|
||||
* @note It should be called after touch button element installed.
|
||||
* Only one touch button can be registered as the deep sleep wake-up button
|
||||
*
|
||||
* @param[in] wakeup_elem_handle Touch element instance handle for waking up the device, only support button element
|
||||
* @param[in] sleep_config Sleep configurations, set NULL to use default config
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Successfully initialized touch sleep
|
||||
* - ESP_ERR_INVALID_STATE: Touch element is not installed or touch sleep has been installed
|
||||
* - ESP_ERR_INVALID_ARG: inputed argument is NULL
|
||||
* - ESP_ERR_NO_MEM: no memory for touch sleep struct
|
||||
* - ESP_ERR_NOT_SUPPORTED: inputed wakeup_elem_handle is not touch_button_handle_t type, currently only touch_button_handle_t supported
|
||||
*/
|
||||
esp_err_t touch_element_enable_deep_sleep(touch_elem_handle_t wakeup_elem_handle, const touch_elem_sleep_config_t *sleep_config);
|
||||
|
||||
/**
|
||||
* @brief Release the resources that allocated by touch_element_enable_deep_sleep()
|
||||
*
|
||||
* This function will also disable the touch sensor to wake up the device
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: uninstall success
|
||||
* - ESP_ERR_INVALID_STATE: touch sleep has not been installed
|
||||
*/
|
||||
esp_err_t touch_element_disable_deep_sleep(void);
|
||||
|
||||
/**
|
||||
* @brief Touch element wake up calibrations
|
||||
*
|
||||
* This function will also disable the touch sensor to wake up the device
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: uninstall success
|
||||
* - ESP_ERR_INVALID_STATE: touch sleep has not been installed
|
||||
*/
|
||||
esp_err_t touch_element_sleep_enable_wakeup_calibration(touch_elem_handle_t element_handle, bool en);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "touch_element/touch_button.h"
|
||||
#include "touch_element/touch_slider.h"
|
||||
#include "touch_element/touch_matrix.h"
|
||||
#include "esp_pm.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -54,6 +56,7 @@ typedef struct {
|
||||
touch_pad_t channel; //!< Touch channel number(index)
|
||||
te_dev_type_t type; //!< Touch channel type TODO: need to refactor as te_class_type_t
|
||||
te_dev_state_t state; //!< Touch channel current state
|
||||
bool is_use_last_threshold;
|
||||
} te_dev_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -79,6 +82,16 @@ struct te_waterproof_s {
|
||||
bool is_shield_level_set; //Waterproof shield level setting bit
|
||||
};
|
||||
typedef struct te_waterproof_s* te_waterproof_handle_t;
|
||||
/* -------------------------------------------- Sleep basic type --------------------------------------------- */
|
||||
struct te_sleep_s {
|
||||
touch_elem_handle_t wakeup_handle;
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_handle_t pm_lock;
|
||||
#endif
|
||||
uint32_t *non_volatile_threshold;
|
||||
};
|
||||
|
||||
typedef struct te_sleep_s* te_sleep_handle_t;
|
||||
/* -------------------------------------------- Button basic type --------------------------------------------- */
|
||||
typedef struct {
|
||||
touch_elem_dispatch_t dispatch_method; //Button dispatch method
|
||||
@@ -170,6 +183,16 @@ void te_object_method_register(te_object_methods_t *object_methods, te_class_typ
|
||||
void te_object_method_unregister(te_class_type_t object_type);
|
||||
bool te_object_check_channel(const touch_pad_t *channel_array, uint8_t channel_sum);
|
||||
bool waterproof_check_mask_handle(touch_elem_handle_t te_handle);
|
||||
bool te_is_touch_dsleep_wakeup(void);
|
||||
touch_pad_t te_get_sleep_channel(void);
|
||||
|
||||
bool is_button_object_handle(touch_elem_handle_t element_handle);
|
||||
bool is_slider_object_handle(touch_elem_handle_t element_handle);
|
||||
bool is_matrix_object_handle(touch_elem_handle_t element_handle);
|
||||
|
||||
void button_enable_wakeup_calibration(te_button_handle_t button_handle, bool en);
|
||||
void slider_enable_wakeup_calibration(te_slider_handle_t slider_handle, bool en);
|
||||
void matrix_enable_wakeup_calibration(te_matrix_handle_t matrix_handle, bool en);
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -296,6 +296,20 @@ static esp_err_t button_object_remove_instance(te_button_handle_t button_handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool is_button_object_handle(touch_elem_handle_t element_handle)
|
||||
{
|
||||
te_button_handle_list_t *item;
|
||||
xSemaphoreTake(s_te_btn_obj->mutex, portMAX_DELAY);
|
||||
SLIST_FOREACH(item, &s_te_btn_obj->handle_list, next) {
|
||||
if (element_handle == item->button_handle) {
|
||||
xSemaphoreGive(s_te_btn_obj->mutex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(s_te_btn_obj->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool button_channel_check(te_button_handle_t button_handle, touch_pad_t channel_num)
|
||||
{
|
||||
return (channel_num == button_handle->device->channel);
|
||||
@@ -346,6 +360,11 @@ static inline void button_dispatch(te_button_handle_t button_handle, touch_elem_
|
||||
}
|
||||
}
|
||||
|
||||
void button_enable_wakeup_calibration(te_button_handle_t button_handle, bool en)
|
||||
{
|
||||
button_handle->device->is_use_last_threshold = !en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Button process
|
||||
*
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "hal/touch_sensor_hal.h" //TODO: remove hal
|
||||
#include "touch_element/touch_element_private.h"
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
|
||||
#define TE_CLASS_ITEM(cls, cls_type, cls_item) ((&((cls)[cls_type]))->cls_item)
|
||||
|
||||
#define TE_CLASS_FOREACH(cls_var, cls_start, cls_end) \
|
||||
@@ -87,6 +91,7 @@ typedef struct {
|
||||
te_object_methods_t object_methods[TE_CLS_TYPE_MAX]; //Class(object) methods
|
||||
touch_elem_global_config_t *global_config; //Global initialization
|
||||
te_waterproof_handle_t waterproof_handle; //Waterproof configuration
|
||||
te_sleep_handle_t sleep_handle;
|
||||
esp_timer_handle_t proc_timer; //Processing timer handle
|
||||
QueueHandle_t event_msg_queue; //Application event message queue (for user)
|
||||
QueueHandle_t intr_msg_queue; //Interrupt message (for internal)
|
||||
@@ -96,6 +101,7 @@ typedef struct {
|
||||
} te_obj_t;
|
||||
|
||||
static te_obj_t *s_te_obj = NULL;
|
||||
RTC_FAST_ATTR uint32_t threshold_shadow[TOUCH_PAD_MAX - 1] = {0};
|
||||
|
||||
/**
|
||||
* Internal de-noise channel(Touch channel 0) equivalent capacitance table, depends on hardware design
|
||||
@@ -313,6 +319,36 @@ esp_err_t te_event_give(touch_elem_message_t te_message)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t te_get_threshold(touch_pad_t channel_num)
|
||||
{
|
||||
uint32_t threshold = 0;
|
||||
touch_pad_sleep_channel_t sleep_channel_info;
|
||||
touch_pad_sleep_channel_get_info(&sleep_channel_info);
|
||||
if (channel_num != sleep_channel_info.touch_num) {
|
||||
touch_pad_get_thresh(channel_num, &threshold);
|
||||
} else {
|
||||
touch_pad_sleep_get_threshold(channel_num, &threshold);
|
||||
}
|
||||
return threshold;
|
||||
}
|
||||
|
||||
bool te_is_touch_dsleep_wakeup(void)
|
||||
{
|
||||
soc_reset_reason_t reset_reason = esp_rom_get_reset_reason(0);
|
||||
if (reset_reason != RESET_REASON_CORE_DEEP_SLEEP) {
|
||||
return false;
|
||||
}
|
||||
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
|
||||
return wakeup_reason == ESP_SLEEP_WAKEUP_TOUCHPAD;
|
||||
}
|
||||
|
||||
touch_pad_t te_get_sleep_channel(void)
|
||||
{
|
||||
touch_pad_sleep_channel_t sleep_channel_info;
|
||||
touch_pad_sleep_channel_get_info(&sleep_channel_info);
|
||||
return sleep_channel_info.touch_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Touch sensor interrupt service routine
|
||||
*
|
||||
@@ -323,22 +359,41 @@ static void te_intr_cb(void *arg)
|
||||
{
|
||||
TE_UNUSED(arg);
|
||||
static int scan_done_cnt = 0;
|
||||
static uint32_t touch_pre_trig_status = 0;
|
||||
int task_awoken = pdFALSE;
|
||||
te_intr_msg_t te_intr_msg;
|
||||
/*< Figure out which touch sensor channel is triggered and the trigger type */
|
||||
uint32_t intr_mask = touch_pad_read_intr_status_mask();
|
||||
te_intr_msg.channel_num = touch_pad_get_current_meas_channel();
|
||||
if (intr_mask == 0x0) { //For dummy interrupt
|
||||
return;
|
||||
}
|
||||
|
||||
bool need_send_queue = true;
|
||||
if (intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) {
|
||||
te_intr_msg.channel_state = TE_STATE_PRESS;
|
||||
te_intr_msg.intr_type = TE_INTR_PRESS;
|
||||
} else if (intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) {
|
||||
te_intr_msg.channel_state = TE_STATE_RELEASE;
|
||||
te_intr_msg.intr_type = TE_INTR_RELEASE;
|
||||
} else if (intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) {
|
||||
uint8_t pad_num = 0;
|
||||
uint32_t touch_trig_status = touch_pad_get_status();
|
||||
uint32_t touch_trig_diff = touch_trig_status ^ touch_pre_trig_status;
|
||||
while (touch_trig_diff) {
|
||||
if (touch_trig_diff & 0x1) {
|
||||
if (touch_trig_status & BIT(pad_num)) {
|
||||
if (s_te_obj->sleep_handle != NULL) {
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_acquire(s_te_obj->sleep_handle->pm_lock);
|
||||
#endif
|
||||
}
|
||||
te_intr_msg.channel_state = TE_STATE_PRESS;
|
||||
te_intr_msg.intr_type = TE_INTR_PRESS;
|
||||
} else {
|
||||
te_intr_msg.channel_state = TE_STATE_RELEASE;
|
||||
te_intr_msg.intr_type = TE_INTR_RELEASE;
|
||||
}
|
||||
touch_pre_trig_status = touch_trig_status;
|
||||
te_intr_msg.channel_num = pad_num;
|
||||
}
|
||||
pad_num++;
|
||||
touch_trig_diff >>= 1;
|
||||
}
|
||||
|
||||
if (intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) {
|
||||
te_intr_msg.channel_state = TE_STATE_IDLE;
|
||||
te_intr_msg.intr_type = TE_INTR_TIMEOUT;
|
||||
} else if (intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) {
|
||||
@@ -354,8 +409,6 @@ static void te_intr_cb(void *arg)
|
||||
}
|
||||
/*< De-noise channel signal must be read at the time between SCAN_DONE and next measurement beginning(sleep)!!! */
|
||||
touch_pad_denoise_read_data(&s_te_obj->denoise_channel_raw); //Update de-noise signal
|
||||
} else {
|
||||
te_intr_msg.intr_type = TE_INTR_MAX; // Unknown Exception
|
||||
}
|
||||
if (need_send_queue) {
|
||||
xQueueSendFromISR(s_te_obj->intr_msg_queue, &te_intr_msg, &task_awoken);
|
||||
@@ -385,11 +438,21 @@ static void te_proc_timer_cb(void *arg)
|
||||
if (ret == pdPASS) {
|
||||
if (te_intr_msg.intr_type == TE_INTR_PRESS || te_intr_msg.intr_type == TE_INTR_RELEASE) {
|
||||
te_object_update_state(te_intr_msg);
|
||||
if ((s_te_obj->sleep_handle != NULL) && (te_intr_msg.intr_type == TE_INTR_RELEASE)) {
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_release(s_te_obj->sleep_handle->pm_lock);
|
||||
#endif
|
||||
}
|
||||
} else if (te_intr_msg.intr_type == TE_INTR_SCAN_DONE) {
|
||||
if (s_te_obj->is_set_threshold != true) {
|
||||
s_te_obj->is_set_threshold = true;
|
||||
te_object_set_threshold(); //TODO: add set threshold error processing
|
||||
ESP_LOGD(TE_DEBUG_TAG, "Set threshold");
|
||||
if (s_te_obj->sleep_handle != NULL) {
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_release(s_te_obj->sleep_handle->pm_lock);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (waterproof_check_state()) {
|
||||
te_waterproof_handle_t waterproof_handle = s_te_obj->waterproof_handle;
|
||||
@@ -500,6 +563,7 @@ esp_err_t te_dev_init(te_dev_t **device, uint8_t device_num, te_dev_type_t type,
|
||||
device[idx]->sens = sens[idx] * divider;
|
||||
device[idx]->type = type;
|
||||
device[idx]->state = TE_STATE_IDLE;
|
||||
device[idx]->is_use_last_threshold = false;
|
||||
esp_err_t ret = touch_pad_config(device[idx]->channel);
|
||||
TE_CHECK(ret == ESP_OK, ret);
|
||||
}
|
||||
@@ -513,10 +577,37 @@ void te_dev_deinit(te_dev_t **device, uint8_t device_num)
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t te_config_thresh(touch_pad_t channel_num, uint32_t threshold)
|
||||
{
|
||||
esp_err_t ret;
|
||||
touch_pad_sleep_channel_t sleep_channel_info;
|
||||
touch_pad_sleep_channel_get_info(&sleep_channel_info);
|
||||
if (channel_num != sleep_channel_info.touch_num) {
|
||||
ret = touch_pad_set_thresh(channel_num, threshold);
|
||||
} else {
|
||||
ret = touch_pad_sleep_set_threshold(channel_num, threshold);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t te_dev_set_threshold(te_dev_t *device)
|
||||
{
|
||||
uint32_t smo_val = te_read_smooth_signal(device->channel);
|
||||
esp_err_t ret = touch_pad_set_thresh(device->channel, device->sens * smo_val);
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint32_t smo_val = 0;
|
||||
|
||||
if (s_te_obj->sleep_handle && device->is_use_last_threshold) {
|
||||
if (te_is_touch_dsleep_wakeup()) { //Deep sleep wakeup reset
|
||||
ret = te_config_thresh(device->channel, s_te_obj->sleep_handle->non_volatile_threshold[device->channel - 1]);
|
||||
} else { //Other reset
|
||||
smo_val = te_read_smooth_signal(device->channel);
|
||||
ret = te_config_thresh(device->channel, device->sens * smo_val);
|
||||
uint32_t threshold = te_get_threshold(device->channel);
|
||||
s_te_obj->sleep_handle->non_volatile_threshold[device->channel - 1] = threshold; //Write threshold into RTC Fast Memory
|
||||
}
|
||||
} else {
|
||||
smo_val = te_read_smooth_signal(device->channel);
|
||||
ret = te_config_thresh(device->channel, device->sens * smo_val);
|
||||
}
|
||||
ESP_LOGD(TE_DEBUG_TAG, "channel: %"PRIu8", smo_val: %"PRIu32, device->channel, smo_val);
|
||||
return ret;
|
||||
}
|
||||
@@ -648,7 +739,8 @@ static esp_err_t te_sw_init(const touch_elem_sw_config_t *software_init)
|
||||
const esp_timer_create_args_t te_proc_timer_args = {
|
||||
.name = "te_proc_timer_cb",
|
||||
.arg = NULL,
|
||||
.callback = &te_proc_timer_cb
|
||||
.callback = &te_proc_timer_cb,
|
||||
.skip_unhandled_events = true,
|
||||
};
|
||||
ret = esp_timer_create(&te_proc_timer_args, &s_te_obj->proc_timer);
|
||||
TE_CHECK_GOTO(ret == ESP_OK, cleanup);
|
||||
@@ -879,3 +971,147 @@ static void waterproof_guard_update_state(touch_pad_t current_channel, te_state_
|
||||
}
|
||||
ESP_LOGD(TE_DEBUG_TAG, "waterproof guard state update %d", guard_device->state);
|
||||
}
|
||||
|
||||
esp_err_t touch_element_enable_light_sleep(const touch_elem_sleep_config_t *sleep_config)
|
||||
{
|
||||
TE_CHECK(s_te_obj != NULL, ESP_ERR_INVALID_STATE);
|
||||
TE_CHECK(s_te_obj->sleep_handle == NULL, ESP_ERR_INVALID_STATE);
|
||||
uint16_t sample_count = 500;
|
||||
uint16_t sleep_cycle = 0x0f;
|
||||
if (sleep_config) {
|
||||
sample_count = sleep_config->sample_count;
|
||||
sleep_cycle = sleep_config->sleep_cycle;
|
||||
}
|
||||
|
||||
s_te_obj->sleep_handle = calloc(1, sizeof(struct te_sleep_s));
|
||||
TE_CHECK(s_te_obj->sleep_handle, ESP_ERR_NO_MEM);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
touch_pad_sleep_channel_set_work_time(sleep_cycle, sample_count);
|
||||
TE_CHECK_GOTO(esp_sleep_enable_touchpad_wakeup() == ESP_OK, cleanup);
|
||||
|
||||
TE_CHECK_GOTO(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON) == ESP_OK, cleanup);
|
||||
s_te_obj->sleep_handle->non_volatile_threshold = threshold_shadow;
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
TE_CHECK_GOTO(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "touch_element", &s_te_obj->sleep_handle->pm_lock) == ESP_OK, cleanup);
|
||||
TE_CHECK_GOTO(esp_pm_lock_acquire(s_te_obj->sleep_handle->pm_lock) == ESP_OK, cleanup);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
cleanup:
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_te_obj->sleep_handle->pm_lock != NULL) {
|
||||
if (esp_pm_lock_delete(s_te_obj->sleep_handle->pm_lock) != ESP_OK) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
TE_FREE_AND_NULL(s_te_obj->sleep_handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t touch_element_disable_light_sleep(void)
|
||||
{
|
||||
TE_CHECK(s_te_obj->sleep_handle, ESP_ERR_INVALID_STATE);
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_te_obj->sleep_handle->pm_lock != NULL) {
|
||||
/* Sleep channel is going to uninstall, pm lock is not needed anymore,
|
||||
but we need to make sure that pm lock has been released before delete it. */
|
||||
while(esp_pm_lock_release(s_te_obj->sleep_handle->pm_lock) == ESP_OK);
|
||||
esp_err_t ret = esp_pm_lock_delete(s_te_obj->sleep_handle->pm_lock);
|
||||
TE_CHECK(ret == ESP_OK, ret);
|
||||
s_te_obj->sleep_handle->pm_lock = NULL;
|
||||
}
|
||||
#endif
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TOUCHPAD);
|
||||
TE_FREE_AND_NULL(s_te_obj->sleep_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t touch_element_enable_deep_sleep(touch_elem_handle_t wakeup_elem_handle, const touch_elem_sleep_config_t *sleep_config)
|
||||
{
|
||||
TE_CHECK(s_te_obj != NULL, ESP_ERR_INVALID_STATE);
|
||||
TE_CHECK(s_te_obj->sleep_handle == NULL, ESP_ERR_INVALID_STATE);
|
||||
TE_CHECK(wakeup_elem_handle != NULL, ESP_ERR_INVALID_ARG);
|
||||
TE_CHECK(sleep_config != NULL, ESP_ERR_INVALID_ARG);
|
||||
uint16_t sample_count = 500;
|
||||
uint16_t sleep_cycle = 0x0f;
|
||||
if (sleep_config) {
|
||||
sample_count = sleep_config->sample_count;
|
||||
sleep_cycle = sleep_config->sleep_cycle;
|
||||
}
|
||||
|
||||
s_te_obj->sleep_handle = calloc(1, sizeof(struct te_sleep_s));
|
||||
TE_CHECK(s_te_obj->sleep_handle, ESP_ERR_NO_MEM);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
touch_pad_sleep_channel_set_work_time(sleep_cycle, sample_count);
|
||||
TE_CHECK_GOTO(esp_sleep_enable_touchpad_wakeup() == ESP_OK, cleanup);
|
||||
|
||||
TE_CHECK_GOTO(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON) == ESP_OK, cleanup);
|
||||
s_te_obj->sleep_handle->non_volatile_threshold = threshold_shadow;
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
TE_CHECK_GOTO(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "touch_element", &s_te_obj->sleep_handle->pm_lock) == ESP_OK, cleanup);
|
||||
TE_CHECK_GOTO(esp_pm_lock_acquire(s_te_obj->sleep_handle->pm_lock) == ESP_OK, cleanup);
|
||||
#endif
|
||||
//Only support one channel/element as the deep sleep wakeup channel/element
|
||||
TE_CHECK(is_button_object_handle(wakeup_elem_handle), ESP_ERR_NOT_SUPPORTED);
|
||||
s_te_obj->sleep_handle->wakeup_handle = wakeup_elem_handle;
|
||||
te_button_handle_t button_handle = wakeup_elem_handle;
|
||||
ret = touch_pad_sleep_channel_enable(button_handle->device->channel, true);
|
||||
TE_CHECK(ret == ESP_OK, ret);
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
cleanup:
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_te_obj->sleep_handle->pm_lock != NULL) {
|
||||
if (esp_pm_lock_delete(s_te_obj->sleep_handle->pm_lock) != ESP_OK) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
TE_FREE_AND_NULL(s_te_obj->sleep_handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t touch_element_disable_deep_sleep(void)
|
||||
{
|
||||
TE_CHECK(s_te_obj->sleep_handle, ESP_ERR_INVALID_STATE);
|
||||
esp_err_t ret;
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (s_te_obj->sleep_handle->pm_lock != NULL) {
|
||||
/* Sleep channel is going to uninstall, pm lock is not needed anymore,
|
||||
but we need to make sure that pm lock has been released before delete it. */
|
||||
while(esp_pm_lock_release(s_te_obj->sleep_handle->pm_lock) == ESP_OK);
|
||||
ret = esp_pm_lock_delete(s_te_obj->sleep_handle->pm_lock);
|
||||
TE_CHECK(ret == ESP_OK, ret);
|
||||
s_te_obj->sleep_handle->pm_lock = NULL;
|
||||
}
|
||||
#endif
|
||||
te_button_handle_t button_handle = s_te_obj->sleep_handle->wakeup_handle;
|
||||
ret = touch_pad_sleep_channel_enable(button_handle->device->channel, false);
|
||||
TE_CHECK(ret == ESP_OK, ret);
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TOUCHPAD);
|
||||
s_te_obj->sleep_handle->wakeup_handle = NULL;
|
||||
TE_FREE_AND_NULL(s_te_obj->sleep_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t touch_element_sleep_enable_wakeup_calibration(touch_elem_handle_t element_handle, bool en)
|
||||
{
|
||||
TE_CHECK(element_handle != NULL, ESP_ERR_INVALID_ARG);
|
||||
if (is_button_object_handle(element_handle)) {
|
||||
button_enable_wakeup_calibration(element_handle, en);
|
||||
} else if (is_slider_object_handle(element_handle)) {
|
||||
slider_enable_wakeup_calibration(element_handle, en);
|
||||
} else if (is_matrix_object_handle(element_handle)) {
|
||||
matrix_enable_wakeup_calibration(element_handle, en);
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -335,6 +335,20 @@ static esp_err_t matrix_object_remove_instance(te_matrix_handle_t matrix_handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool is_matrix_object_handle(touch_elem_handle_t element_handle)
|
||||
{
|
||||
te_matrix_handle_list_t *item;
|
||||
xSemaphoreTake(s_te_mat_obj->mutex, portMAX_DELAY);
|
||||
SLIST_FOREACH(item, &s_te_mat_obj->handle_list, next) {
|
||||
if (element_handle == item->matrix_handle) {
|
||||
xSemaphoreGive(s_te_mat_obj->mutex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(s_te_mat_obj->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool matrix_channel_check(te_matrix_handle_t matrix_handle, touch_pad_t channel_num)
|
||||
{
|
||||
te_dev_t *device;
|
||||
@@ -403,6 +417,13 @@ static inline void matrix_dispatch(te_matrix_handle_t matrix_handle, touch_elem_
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_enable_wakeup_calibration(te_matrix_handle_t matrix_handle, bool en)
|
||||
{
|
||||
for (int idx = 0; idx < matrix_handle->x_channel_num + matrix_handle->y_channel_num; ++idx) {
|
||||
matrix_handle->device[idx]->is_use_last_threshold = !en;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scan the matrix channel
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -328,6 +328,20 @@ static esp_err_t slider_object_remove_instance(te_slider_handle_t slider_handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool is_slider_object_handle(touch_elem_handle_t element_handle)
|
||||
{
|
||||
te_slider_handle_list_t *item;
|
||||
xSemaphoreTake(s_te_sld_obj->mutex, portMAX_DELAY);
|
||||
SLIST_FOREACH(item, &s_te_sld_obj->handle_list, next) {
|
||||
if (element_handle == item->slider_handle) {
|
||||
xSemaphoreGive(s_te_sld_obj->mutex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(s_te_sld_obj->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool slider_channel_check(te_slider_handle_t slider_handle, touch_pad_t channel_num)
|
||||
{
|
||||
te_dev_t *device;
|
||||
@@ -406,6 +420,13 @@ static inline void slider_dispatch(te_slider_handle_t slider_handle, touch_elem_
|
||||
}
|
||||
}
|
||||
|
||||
void slider_enable_wakeup_calibration(te_slider_handle_t slider_handle, bool en)
|
||||
{
|
||||
for (int idx = 0; idx < slider_handle->channel_sum; ++idx) {
|
||||
slider_handle->device[idx]->is_use_last_threshold = !en;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Slider process
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user