1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-20 05:18:08 +00:00

fix(core/embed): fix too frequent reading of touch panel registers

[no changelog]
This commit is contained in:
cepetr 2024-07-19 13:28:36 +02:00 committed by cepetr
parent 33f5d47330
commit 470d6ec24e

View File

@ -21,6 +21,7 @@
#include TREZOR_BOARD
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
@ -33,6 +34,9 @@
#include "panels/lx154a2422cpt23.h"
#endif
// #define TOUCH_TRACE_REGS
// #define TOUCH_TRACE_EVENT
typedef struct {
// Set if the driver is initialized
secbool initialized;
@ -43,6 +47,8 @@ typedef struct {
uint32_t init_ticks;
// Time (in ticks) when touch_get_event() was called last time
uint32_t poll_ticks;
// Time (in ticks) when the touch registers were read last time
uint32_t read_ticks;
// Set if the touch controller is currently touched
// (respectively, the we detected a touch event)
bool pressed;
@ -259,6 +265,7 @@ secbool touch_init(void) {
driver->init_ticks = hal_ticks_ms();
driver->poll_ticks = driver->init_ticks;
driver->read_ticks = driver->init_ticks;
driver->initialized = sectrue;
return sectrue;
@ -337,6 +344,57 @@ secbool touch_activity(void) {
return secfalse;
}
#ifdef TOUCH_TRACE_REGS
void trace_regs(uint8_t* regs) {
// Extract gesture ID (FT6X63_GESTURE_xxx)
uint8_t gesture = regs[FT6X63_REG_GEST_ID];
// Extract number of touches (0, 1, 2) or 0x0F before
// the first touch (tested with FT6206)
uint8_t nb_touches = regs[FT6X63_REG_TD_STATUS] & 0x0F;
// Extract event flags (one of press down, contact, lift up)
uint8_t flags = regs[FT6X63_REG_P1_XH] & FT6X63_EVENT_MASK;
// Extract touch coordinates
uint16_t x = ((regs[FT6X63_REG_P1_XH] & 0x0F) << 8) | regs[FT6X63_REG_P1_XL];
uint16_t y = ((regs[FT6X63_REG_P1_YH] & 0x0F) << 8) | regs[FT6X63_REG_P1_YL];
char event;
if (flags == FT6X63_EVENT_PRESS_DOWN) {
event = 'D';
} else if (flags == FT6X63_EVENT_CONTACT) {
event = 'C';
} else if (flags == FT6X63_EVENT_LIFT_UP) {
event = 'U';
} else {
event = '-';
}
uint32_t time = hal_ticks_ms() % 10000;
printf("%04ld [gesture=%02X, nb_touches=%d, flags=%c, x=%3d, y=%3d]\r\n",
time, gesture, nb_touches, event, x, y);
}
#endif
#ifdef TOUCH_TRACE_EVENT
void trace_event(uint32_t event) {
char event_type = (event & TOUCH_START) ? 'D'
: (event & TOUCH_MOVE) ? 'M'
: (event & TOUCH_END) ? 'U'
: '-';
uint16_t x = touch_unpack_x(event);
uint16_t y = touch_unpack_y(event);
uint32_t time = hal_ticks_ms() % 10000;
printf("%04ld [event=%c, x=%3d, y=%3d]\r\n", time, event_type, x, y);
}
#endif
uint32_t touch_get_event(void) {
touch_driver_t* driver = &g_touch_driver;
@ -361,18 +419,28 @@ uint32_t touch_get_event(void) {
bool starving = (int32_t)(ticks - driver->poll_ticks) > 300 /* ms */;
driver->poll_ticks = ticks;
// Test if the touch controller is polled too frequently
// (less than 20ms since the last read)
bool toofast = (int32_t)(ticks - driver->read_ticks) < 20 /* ms */;
// Fast track: if there is no new event and the touch controller
// is not touched, we do not need to read the registers
if (!ft6x36_test_and_clear_interrupt() && !driver->pressed) {
if (!ft6x36_test_and_clear_interrupt() && (!driver->pressed || toofast)) {
return 0;
}
driver->read_ticks = ticks;
// Read the set of registers containing touch event and coordinates
if (sectrue != ft6x36_read_regs(0x00, regs, sizeof(regs))) {
// Failed to read the touch registers
return 0;
}
#ifdef TOUCH_TRACE_REGS
trace_regs(regs);
#endif
// Extract gesture ID (FT6X63_GESTURE_xxx)
uint8_t gesture = regs[FT6X63_REG_GEST_ID];
@ -465,5 +533,9 @@ uint32_t touch_get_event(void) {
driver->last_x = x;
driver->last_y = y;
#ifdef TOUCH_TRACE_EVENT
trace_event(event);
#endif
return event;
}