add skip calibration and wakeup channel, fix isr in sleep mode

This commit is contained in:
Kang Zuoling
2022-08-15 20:03:12 +08:00
committed by laokaiyao
parent 24e63fd2c0
commit 82bf6c0935
12 changed files with 612 additions and 12 deletions
+10
View File
@@ -0,0 +1,10 @@
menu "Touch Element"
config TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
bool "Enable skip deep sleep wakeup calibration"
default n
help
This option allows to store all Touch Sensor channels' threshold into RTC Fast Memory. So that Touch Sensor
threshold will only be configured once after Power-on Reset.
endmenu
@@ -256,6 +256,21 @@ 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);
typedef struct {
uint16_t scan_time;
uint16_t sleep_time;
} touch_elem_sleep_config_t;
esp_err_t touch_element_sleep_install(touch_elem_sleep_config_t *sleep_config);
void touch_element_sleep_uninstall(void);
esp_err_t touch_element_sleep_add_wakeup(touch_elem_handle_t element_handle);
esp_err_t touch_element_sleep_remove_wakeup(touch_elem_handle_t element_handle);
esp_err_t touch_element_sleep_add_wakeup_channel(touch_pad_t wakeup_channel);
esp_err_t touch_element_sleep_remove_wakeup_channel(touch_pad_t wakeup_channel);
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
esp_err_t touch_element_sleep_config_wakeup_calibration(touch_elem_handle_t element_handle, bool en);
#endif
#ifdef __cplusplus
}
#endif
@@ -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,9 @@ 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
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
bool is_use_last_threshold;
#endif
} te_dev_t;
typedef enum {
@@ -69,6 +74,7 @@ typedef struct {
esp_err_t (*set_threshold) (void);
void (*process_state) (void);
void (*update_state) (touch_pad_t, te_state_t);
touch_elem_handle_t (*search_channel_handle) (touch_pad_t);
} te_object_methods_t;
/* -------------------------------------------- Waterproof basic type --------------------------------------------- */
@@ -79,6 +85,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;
esp_pm_lock_handle_t pm_lock;
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
uint32_t *non_volatile_threshold;
#endif
};
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 +186,18 @@ 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);
inline touch_pad_t te_get_sleep_channel(void);
bool button_object_handle_check(touch_elem_handle_t element_handle);
bool slider_object_handle_check(touch_elem_handle_t element_handle);
bool matrix_object_handle_check(touch_elem_handle_t element_handle);
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
void button_config_wakeup_calibration(te_button_handle_t button_handle, bool en);
void slider_config_wakeup_calibration(te_slider_handle_t slider_handle, bool en);
void matrix_config_wakeup_calibration(te_matrix_handle_t matrix_handle, bool en);
#endif
/* ------------------------------------------------------------------------------------------------------------------ */
#ifdef __cplusplus
+37
View File
@@ -40,6 +40,7 @@ static bool button_object_check_channel(touch_pad_t channel_num);
static esp_err_t button_object_set_threshold(void);
static void button_object_process_state(void);
static void button_object_update_state(touch_pad_t channel_num, te_state_t channel_state);
static te_button_handle_t button_object_search_channel_handle(touch_pad_t channel_num);
/* ------------------------------------------------------------------------------------------------------------------ */
esp_err_t touch_button_install(const touch_button_global_config_t *global_config)
@@ -268,6 +269,21 @@ static void button_object_update_state(touch_pad_t channel_num, te_state_t chann
}
}
static te_button_handle_t button_object_search_channel_handle(touch_pad_t channel_num)
{
te_button_handle_list_t *item;
te_button_handle_t button_handle = NULL;
SLIST_FOREACH(item, &s_te_btn_obj->handle_list, next) {
touch_pad_t button_channel = item->button_handle->device->channel;
if (channel_num == button_channel) {
button_handle = item->button_handle;
break;
}
}
return button_handle;
}
static esp_err_t button_object_add_instance(te_button_handle_t button_handle)
{
te_button_handle_list_t *item = (te_button_handle_list_t *)calloc(1, sizeof(te_button_handle_list_t));
@@ -296,6 +312,20 @@ static esp_err_t button_object_remove_instance(te_button_handle_t button_handle)
return ret;
}
bool button_object_handle_check(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 +376,13 @@ static inline void button_dispatch(te_button_handle_t button_handle, touch_elem_
}
}
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
void button_config_wakeup_calibration(te_button_handle_t button_handle, bool en)
{
button_handle->device->is_use_last_threshold = en;
}
#endif
/**
* @brief Button process
*
+261 -12
View File
@@ -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 "hal/touch_sensor_hal.h" //TODO: remove hal
#include "touch_element/touch_element_private.h"
#include "esp32s2/rom/rtc.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,15 +91,21 @@ 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)
SemaphoreHandle_t mutex; //Global resource mutex
bool is_set_threshold; //Threshold configuration state bit
uint32_t denoise_channel_raw; //De-noise channel(TO) raw signal
// touch_elem_sleep_config_t *sleep_config;
// esp_pm_lock_handle_t pm_lock_handle;
} te_obj_t;
static te_obj_t *s_te_obj = NULL;
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
RTC_FAST_ATTR uint32_t threshold_shadow[TOUCH_PAD_MAX - 1] = {0};
#endif
/**
* Internal de-noise channel(Touch channel 0) equivalent capacitance table, depends on hardware design
@@ -313,6 +323,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)
{
RESET_REASON rtc_reset_reason = rtc_get_reset_reason(0);
if (rtc_reset_reason != DEEPSLEEP_RESET) {
return false;
}
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
return wakeup_reason == ESP_SLEEP_WAKEUP_TOUCHPAD;
}
inline 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 +363,39 @@ 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) {
esp_pm_lock_acquire(s_te_obj->sleep_handle->pm_lock);
}
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) {
@@ -355,7 +412,7 @@ 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
// 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 +442,19 @@ 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 (te_intr_msg.intr_type == TE_INTR_RELEASE) {
if (s_te_obj->sleep_handle != NULL) {
esp_pm_lock_release(s_te_obj->sleep_handle->pm_lock);
}
}
} 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) {
esp_pm_lock_release(s_te_obj->sleep_handle->pm_lock);
}
}
if (waterproof_check_state()) {
te_waterproof_handle_t waterproof_handle = s_te_obj->waterproof_handle;
@@ -500,6 +565,9 @@ 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;
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
device[idx]->is_use_last_threshold = false;
#endif
esp_err_t ret = touch_pad_config(device[idx]->channel);
TE_CHECK(ret == ESP_OK, ret);
}
@@ -513,10 +581,48 @@ void te_dev_deinit(te_dev_t **device, uint8_t device_num)
}
}
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;
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
if (s_te_obj->sleep_handle == NULL) {
ESP_LOGE(TE_TAG, "Touch Element sleep is not installed");
return ESP_ERR_INVALID_STATE;
}
if (device->is_use_last_threshold) {
if (te_is_touch_dsleep_wakeup()) { //Deep sleep wakeup reset
touch_pad_t sleep_channel = te_get_sleep_channel();
ets_printf("----config rtc %ld %ld\n", s_te_obj->sleep_handle->non_volatile_threshold[device->channel - 1], sleep_channel);
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);
}
#else
smo_val = te_read_smooth_signal(device->channel);
ret = te_config_thresh(device->channel, device->sens * smo_val);
#endif
ESP_LOGD(TE_DEBUG_TAG, "channel: %"PRIu8", smo_val: %"PRIu32, device->channel, smo_val);
return ret;
}
@@ -648,7 +754,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 +986,145 @@ 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_sleep_install(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(sleep_config != NULL, ESP_ERR_INVALID_ARG);
s_te_obj->sleep_handle = calloc(1, sizeof(struct te_sleep_s));
if (s_te_obj->sleep_handle == NULL) {
return ESP_ERR_NO_MEM;
}
esp_err_t ret;
touch_pad_sleep_channel_set_work_time(sleep_config->sleep_time, sleep_config->scan_time);
ret = esp_sleep_enable_touchpad_wakeup();
TE_CHECK_GOTO(ret == ESP_OK, cleanup);
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_ON);
TE_CHECK_GOTO(ret == ESP_OK, cleanup);
s_te_obj->sleep_handle->non_volatile_threshold = threshold_shadow;
#endif
ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "touch_element", &s_te_obj->sleep_handle->pm_lock);
TE_CHECK_GOTO(ret == ESP_OK, cleanup);
ret = esp_pm_lock_acquire(s_te_obj->sleep_handle->pm_lock);
TE_CHECK_GOTO(ret == ESP_OK, cleanup);
return ESP_OK;
cleanup:
if (s_te_obj->sleep_handle->pm_lock != NULL) {
esp_err_t del_ret = esp_pm_lock_delete(s_te_obj->sleep_handle->pm_lock);
if (del_ret != ESP_OK) {
abort();
}
}
TE_FREE_AND_NULL(s_te_obj->sleep_handle);
return ret;
}
void touch_element_sleep_uninstall(void)
{
esp_err_t ret;
if (s_te_obj->sleep_handle->pm_lock != NULL) {
ret = esp_pm_lock_delete(s_te_obj->sleep_handle->pm_lock);
if (ret != ESP_OK) {
abort();
}
}
if (s_te_obj->sleep_handle->wakeup_handle != NULL) {
te_button_handle_t button_handle = s_te_obj->sleep_handle->wakeup_handle;
ret = touch_pad_sleep_channel_enable(button_handle->device->channel, false);
if (ret != ESP_OK) {
abort();
}
}
s_te_obj->sleep_handle->pm_lock = NULL;
s_te_obj->sleep_handle->wakeup_handle = NULL;
TE_FREE_AND_NULL(s_te_obj->sleep_handle);
}
esp_err_t touch_element_sleep_add_wakeup(touch_elem_handle_t element_handle)
{
TE_CHECK(s_te_obj->sleep_handle != NULL, ESP_ERR_INVALID_STATE);
TE_CHECK(element_handle != NULL, ESP_ERR_INVALID_ARG);
if (s_te_obj->sleep_handle->wakeup_handle != NULL) {
ESP_LOGE(TE_TAG, "sleep not null");
return ESP_ERR_NOT_SUPPORTED; //Only support one channel/element as the deep sleep wakeup channel/element
}
if (!button_object_handle_check(element_handle)) {
ESP_LOGE(TE_TAG, "not button handle");
return ESP_ERR_NOT_SUPPORTED; //Only support button element as the deep sleep wakeup channel
}
s_te_obj->sleep_handle->wakeup_handle = element_handle;
te_button_handle_t button_handle = element_handle;
esp_err_t ret = touch_pad_sleep_channel_enable(button_handle->device->channel, true);
if (ret != ESP_OK) {
return ret;
}
return ESP_OK;
}
esp_err_t touch_element_sleep_remove_wakeup(touch_elem_handle_t element_handle)
{
TE_CHECK(s_te_obj->sleep_handle != NULL, ESP_ERR_INVALID_STATE);
TE_CHECK(element_handle != NULL, ESP_ERR_INVALID_ARG);
TE_CHECK(s_te_obj->sleep_handle->wakeup_handle != NULL &&
s_te_obj->sleep_handle->wakeup_handle == element_handle,
ESP_ERR_NOT_FOUND);
s_te_obj->sleep_handle->wakeup_handle = NULL;
te_button_handle_t button_handle = element_handle; //Now we are sure it's absolutely a button element
esp_err_t ret = touch_pad_sleep_channel_enable(button_handle->device->channel, false);
if (ret != ESP_OK) {
return ret;
}
return ESP_OK;
}
esp_err_t touch_element_sleep_add_wakeup_channel(touch_pad_t wakeup_channel)
{
TE_CHECK(s_te_obj->sleep_handle != NULL, ESP_ERR_INVALID_STATE);
TE_CHECK(wakeup_channel > TOUCH_PAD_NUM0 && wakeup_channel < TOUCH_PAD_MAX, ESP_ERR_INVALID_ARG);
touch_pad_sleep_channel_t sleep_channel_info;
touch_pad_sleep_channel_get_info(&sleep_channel_info);
if (sleep_channel_info.touch_num == wakeup_channel) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t ret = touch_pad_sleep_channel_enable(wakeup_channel, true);
if (ret != ESP_OK) {
return ret;
}
return ESP_OK;
}
esp_err_t touch_element_sleep_remove_wakeup_channel(touch_pad_t wakeup_channel)
{
TE_CHECK(s_te_obj->sleep_handle != NULL, ESP_ERR_INVALID_STATE);
TE_CHECK(wakeup_channel > TOUCH_PAD_NUM0 && wakeup_channel < TOUCH_PAD_MAX, ESP_ERR_INVALID_ARG);
esp_err_t ret = touch_pad_sleep_channel_enable(wakeup_channel, false);
if (ret != ESP_OK) {
return ret;
}
return ESP_OK;
}
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
esp_err_t touch_element_sleep_config_wakeup_calibration(touch_elem_handle_t element_handle, bool en)
{
TE_CHECK(element_handle != NULL, ESP_ERR_INVALID_ARG);
if (button_object_handle_check(element_handle)) {
button_config_wakeup_calibration(element_handle, en);
} else if (slider_object_handle_check(element_handle)) {
slider_config_wakeup_calibration(element_handle, en);
} else if (matrix_object_handle_check(element_handle)) {
matrix_config_wakeup_calibration(element_handle, en);
} else {
return ESP_ERR_NOT_FOUND;
}
return ESP_OK;
}
#endif
+42
View File
@@ -43,6 +43,7 @@ static bool matrix_object_check_channel(touch_pad_t channel_num);
static esp_err_t matrix_object_set_threshold(void);
static void matrix_object_process_state(void);
static void matrix_object_update_state(touch_pad_t channel_num, te_state_t channel_state);
static te_matrix_handle_t matrix_object_search_channel_handle(touch_pad_t channel_num);
/* ------------------------------------------------------------------------------------------------------------------ */
esp_err_t touch_matrix_install(const touch_matrix_global_config_t *global_config)
@@ -307,6 +308,24 @@ static void matrix_object_update_state(touch_pad_t channel_num, te_state_t chann
}
}
static te_matrix_handle_t matrix_object_search_channel_handle(touch_pad_t channel_num)
{
te_matrix_handle_list_t *item;
te_matrix_handle_t matrix_handle = NULL;
SLIST_FOREACH(item, &s_te_mat_obj->handle_list, next) {
for (int idx = 0; idx < item->matrix_handle->x_channel_num + item->matrix_handle->y_channel_num; idx++) {
touch_pad_t matrix_channel = item->matrix_handle->device[idx]->channel;
if (channel_num == matrix_channel) {
matrix_handle = item->matrix_handle;
goto found;
}
}
}
found:
return matrix_handle;
}
static esp_err_t matrix_object_add_instance(te_matrix_handle_t matrix_handle)
{
te_matrix_handle_list_t *item = (te_matrix_handle_list_t *)calloc(1, sizeof(te_matrix_handle_list_t));
@@ -335,6 +354,20 @@ static esp_err_t matrix_object_remove_instance(te_matrix_handle_t matrix_handle)
return ret;
}
bool matrix_object_handle_check(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 +436,15 @@ static inline void matrix_dispatch(te_matrix_handle_t matrix_handle, touch_elem_
}
}
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
void matrix_config_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;
}
}
#endif
/**
* @brief Scan the matrix channel
*
+42
View File
@@ -49,6 +49,7 @@ static bool slider_object_check_channel(touch_pad_t channel_num);
static esp_err_t slider_object_set_threshold(void);
static void slider_object_process_state(void);
static void slider_object_update_state(touch_pad_t channel_num, te_state_t channel_state);
static te_slider_handle_t slider_object_search_channel_handle(touch_pad_t channel_num);
/* ------------------------------------------------------------------------------------------------------------------ */
esp_err_t touch_slider_install(const touch_slider_global_config_t *global_config)
@@ -300,6 +301,24 @@ static void slider_object_update_state(touch_pad_t channel_num, te_state_t chann
}
}
static te_slider_handle_t slider_object_search_channel_handle(touch_pad_t channel_num)
{
te_slider_handle_list_t *item;
te_slider_handle_t slider_handle = NULL;
SLIST_FOREACH(item, &s_te_sld_obj->handle_list, next) {
for (int idx = 0; idx < item->slider_handle->channel_sum; idx++) {
touch_pad_t slider_channel = item->slider_handle->device[idx]->channel;
if (channel_num == slider_channel) {
slider_handle = item->slider_handle;
goto found;
}
}
}
found:
return slider_handle;
}
static esp_err_t slider_object_add_instance(te_slider_handle_t slider_handle)
{
te_slider_handle_list_t *item = (te_slider_handle_list_t *)calloc(1, sizeof(te_slider_handle_list_t));
@@ -328,6 +347,20 @@ static esp_err_t slider_object_remove_instance(te_slider_handle_t slider_handle)
return ret;
}
bool slider_object_handle_check(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 +439,15 @@ static inline void slider_dispatch(te_slider_handle_t slider_handle, touch_elem_
}
}
#ifdef CONFIG_TE_SKIP_DSLEEP_WAKEUP_CALIBRATION
void slider_config_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;
}
}
#endif
/**
* @brief Slider process
*