Stabilize non-Mixer click handling and page-change touch suppress.

Report clicks on release for navigation pages, suppress residual presses after UI switch, and log touch task edges.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-08-31 21:59:12 +08:00
parent 5a9f7c81ea
commit d48e3fa63a
3 changed files with 65 additions and 19 deletions

View File

@ -24,6 +24,7 @@ static uint8_t long_press_fired = 0;
static uint8_t click_sent = 0; static uint8_t click_sent = 0;
static uint16_t last_slide_x = 0; static uint16_t last_slide_x = 0;
static uint16_t last_slide_y = 0; static uint16_t last_slide_y = 0;
static uint32_t suppress_until = 0;
static inline uint16_t abs_diff(int16_t a, int16_t b) static inline uint16_t abs_diff(int16_t a, int16_t b)
{ {
@ -41,6 +42,14 @@ void app_touch_reset(void)
last_slide_x = last_slide_y = 0; last_slide_x = last_slide_y = 0;
} }
void app_touch_suppress(uint32_t ms)
{
uint32_t now = rt_tick_get();
uint32_t ticks = (ms * RT_TICK_PER_SECOND + 999U) / 1000U;
suppress_until = now + ticks;
app_touch_reset();
}
app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed)
{ {
app_touch_result_t r; app_touch_result_t r;
@ -50,17 +59,29 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed)
uint32_t now = rt_tick_get(); uint32_t now = rt_tick_get();
/* 切页抑制窗口内丢弃按下,避免误触底栏设置 */
if ((int32_t)(now - suppress_until) < 0) {
if (!pressed) {
app_touch_reset();
}
return r;
}
if (!pressed) { if (!pressed) {
if (!long_press_fired && !click_sent && if (!long_press_fired && !click_sent &&
(touch_state == TOUCH_PRESS_WAIT_STABLE || (touch_state == TOUCH_PRESS_WAIT_STABLE ||
touch_state == TOUCH_PRESS_STABLE)) touch_state == TOUCH_PRESS_STABLE ||
touch_state == TOUCH_SLIDING))
{ {
/* 导航页:抬起时发一次点击(坐标更稳,避免按下瞬间误触底栏) */
if (CurrUIProcress != UI_Mixer_Process) {
r.gesture = GESTURE_RELEASE; r.gesture = GESTURE_RELEASE;
r.x = down_x; r.x = down_x;
r.y = down_y; r.y = down_y;
LOG_D("TP", "release x=%u y=%u", (unsigned)down_x, (unsigned)down_y); LOG_TPI("release x=%u y=%u -> MSG", (unsigned)down_x, (unsigned)down_y);
MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y); MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y);
} }
}
touch_state = TOUCH_IDLE; touch_state = TOUCH_IDLE;
down_x = down_y = 0; down_x = down_y = 0;
last_slide_x = last_slide_y = 0; last_slide_x = last_slide_y = 0;
@ -80,17 +101,24 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed)
click_sent = 0; click_sent = 0;
repeat_tick = 0; repeat_tick = 0;
touch_state = TOUCH_PRESS_WAIT_STABLE; touch_state = TOUCH_PRESS_WAIT_STABLE;
/* ??????????????????????? */ /* Mixer 推子:按下即报;其它页等抬起再报,防止进页后残留按下误触设置 */
if (CurrUIProcress == UI_Mixer_Process) {
click_sent = 1; click_sent = 1;
LOG_D("TP", "press down x=%u y=%u", (unsigned)down_x, (unsigned)down_y); LOG_TPI("press x=%u y=%u -> MSG", (unsigned)down_x, (unsigned)down_y);
MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y); MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y);
} else {
LOG_TPI("press down x=%u y=%u (wait release)", (unsigned)down_x, (unsigned)down_y);
}
break; break;
case TOUCH_PRESS_WAIT_STABLE: case TOUCH_PRESS_WAIT_STABLE:
if ((now - touch_tick) >= TOUCH_STABLE_TIME) { if ((now - touch_tick) >= TOUCH_STABLE_TIME) {
if (abs_diff(x, down_x) < 24 && abs_diff(y, down_y) < 24) if (abs_diff(x, down_x) < 24 && abs_diff(y, down_y) < 24) {
/* 用稳定后的坐标替换首采样噪声 */
down_x = x;
down_y = y;
touch_state = TOUCH_PRESS_STABLE; touch_state = TOUCH_PRESS_STABLE;
else { } else {
down_x = x; down_x = x;
down_y = y; down_y = y;
touch_tick = now; touch_tick = now;
@ -103,7 +131,7 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed)
long_press_fired = 1; long_press_fired = 1;
repeat_tick = now; repeat_tick = now;
r.gesture = GESTURE_LONG_PRESS; r.gesture = GESTURE_LONG_PRESS;
LOG_D("TP", "long_press x=%u y=%u", (unsigned)down_x, (unsigned)down_y); LOG_TPI("long_press x=%u y=%u", (unsigned)down_x, (unsigned)down_y);
MainTask_Sendmsg(MSG_ID_TOUCH_LONG_REPEAT, 1, down_x, down_y); MainTask_Sendmsg(MSG_ID_TOUCH_LONG_REPEAT, 1, down_x, down_y);
return r; return r;
} }
@ -122,11 +150,14 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed)
break; break;
case TOUCH_SLIDING: case TOUCH_SLIDING:
if (abs_diff(x, last_slide_x) >= TOUCH_SLIDE_STEP || /* 仅 Mixer 需要拖动连续坐标;其它页拖动会误触底栏设置 Tab */
abs_diff(y, last_slide_y) >= TOUCH_SLIDE_STEP) { if (CurrUIProcress == UI_Mixer_Process &&
(abs_diff(x, last_slide_x) >= TOUCH_SLIDE_STEP ||
abs_diff(y, last_slide_y) >= TOUCH_SLIDE_STEP)) {
r.gesture = GESTURE_DRAG; r.gesture = GESTURE_DRAG;
r.down_x = last_slide_x; r.down_x = last_slide_x;
r.down_y = last_slide_y; r.down_y = last_slide_y;
LOG_TPI("drag x=%u y=%u", (unsigned)x, (unsigned)y);
MainTask_Sendmsg(MSG_ID_TOUCH, 1, x, y); MainTask_Sendmsg(MSG_ID_TOUCH, 1, x, y);
last_slide_x = x; last_slide_x = x;
last_slide_y = y; last_slide_y = y;

View File

@ -25,6 +25,9 @@ typedef struct {
/* 重置状态机(页面切换/开机时可选调用) */ /* 重置状态机(页面切换/开机时可选调用) */
void app_touch_reset(void); void app_touch_reset(void);
/* 切页后短暂忽略触摸,避免手指未抬起/ADC 抖动误触底栏设置 Tab */
void app_touch_suppress(uint32_t ms);
/* 核心:喂一个采样点,产出手势。 /* 核心:喂一个采样点,产出手势。
* touch_task 20ms * touch_task 20ms
* gesture GESTURE_NONE */ * gesture GESTURE_NONE */

View File

@ -45,15 +45,21 @@ void TaskUIThread_entry(void* parameter)
void TaskTouchThread_entry(void* parameter) void TaskTouchThread_entry(void* parameter)
{ {
static uint8_t s_last_pressed = 0; static uint8_t s_last_pressed = 0;
LOG_TPI("touch task running");
while(1) while(1)
{ {
TP_Point tp = TP_Read(); /* 已含轴交换/镜像,直接进手势 */ TP_Point tp = TP_Read(); /* 已含轴交换/镜像,直接进手势 */
if (tp.pressed && !s_last_pressed) if (tp.pressed) {
{ if (!s_last_pressed) {
LOG_TP("down cal x=%u y=%u", (unsigned)tp.x, (unsigned)tp.y); LOG_TPI("scan down x=%u y=%u", (unsigned)tp.x, (unsigned)tp.y);
}
} else if (s_last_pressed) {
LOG_TPI("scan up");
} }
s_last_pressed = tp.pressed; s_last_pressed = tp.pressed;
app_touch_process(tp.x, tp.y, tp.pressed); app_touch_process(tp.x, tp.y, tp.pressed);
TP_LivePoll();
app_log_poll();
Read_Cur_Measure(); Read_Cur_Measure();
rt_thread_mdelay(8); rt_thread_mdelay(8);
} }
@ -275,6 +281,10 @@ void StartTouchTask(void)
{ {
rt_uint8_t st = (rt_uint8_t)(TaskTouchThread.stat & RT_THREAD_STAT_MASK); rt_uint8_t st = (rt_uint8_t)(TaskTouchThread.stat & RT_THREAD_STAT_MASK);
XPT2046_Init();
app_touch_reset();
LOG_TPI("gpio reinit before touch task");
if (st == RT_THREAD_CLOSE) if (st == RT_THREAD_CLOSE)
{ {
rt_thread_init(&TaskTouchThread, rt_thread_init(&TaskTouchThread,
@ -287,8 +297,10 @@ void StartTouchTask(void)
20); 20);
st = RT_THREAD_INIT; st = RT_THREAD_INIT;
} }
if (st == RT_THREAD_INIT) if (st == RT_THREAD_INIT) {
rt_thread_startup(&TaskTouchThread); rt_thread_startup(&TaskTouchThread);
LOG_TPI("touch task started stat=%u", (unsigned)TaskTouchThread.stat);
}
} }
void StartScanTask(void) void StartScanTask(void)