mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-23 23:18:16 +00:00
refactor(core): unify touch polling functionality
[no changelog]
This commit is contained in:
parent
5306421964
commit
6860c4be0a
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include <io/i2c_bus.h>
|
#include <io/i2c_bus.h>
|
||||||
#include <io/touch.h>
|
#include <io/touch.h>
|
||||||
#include <sys/sysevent_source.h>
|
|
||||||
#include <sys/systick.h>
|
#include <sys/systick.h>
|
||||||
#include "ft6x36.h"
|
#include "ft6x36.h"
|
||||||
|
|
||||||
@ -36,10 +35,9 @@
|
|||||||
#include "panels/lx250a2410a.h"
|
#include "panels/lx250a2410a.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../touch_fsm.h"
|
#include "../touch_poll.h"
|
||||||
|
|
||||||
// #define TOUCH_TRACE_REGS
|
// #define TOUCH_TRACE_REGS
|
||||||
// #define TOUCH_TRACE_EVENT
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Set if the driver is initialized
|
// Set if the driver is initialized
|
||||||
@ -55,8 +53,6 @@ typedef struct {
|
|||||||
uint32_t read_ticks;
|
uint32_t read_ticks;
|
||||||
// Last reported touch state
|
// Last reported touch state
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
// Touch state machine for each task
|
|
||||||
touch_fsm_t tls[SYSTASK_MAX_TASKS];
|
|
||||||
|
|
||||||
} touch_driver_t;
|
} touch_driver_t;
|
||||||
|
|
||||||
@ -65,9 +61,6 @@ static touch_driver_t g_touch_driver = {
|
|||||||
.initialized = secfalse,
|
.initialized = secfalse,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt;
|
|
||||||
|
|
||||||
// Reads a subsequent registers from the FT6X36.
|
// Reads a subsequent registers from the FT6X36.
|
||||||
//
|
//
|
||||||
// Returns: `sectrue` if the register was read
|
// Returns: `sectrue` if the register was read
|
||||||
@ -321,7 +314,7 @@ secbool touch_init(void) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!syshandle_register(SYSHANDLE_TOUCH, &g_touch_handle_vmt, driver)) {
|
if (!touch_poll_init()) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +331,7 @@ cleanup:
|
|||||||
|
|
||||||
void touch_deinit(void) {
|
void touch_deinit(void) {
|
||||||
touch_driver_t* driver = &g_touch_driver;
|
touch_driver_t* driver = &g_touch_driver;
|
||||||
syshandle_unregister(SYSHANDLE_TOUCH);
|
touch_poll_deinit();
|
||||||
i2c_bus_close(driver->i2c_bus);
|
i2c_bus_close(driver->i2c_bus);
|
||||||
if (sectrue == driver->initialized) {
|
if (sectrue == driver->initialized) {
|
||||||
ft6x36_power_down();
|
ft6x36_power_down();
|
||||||
@ -455,28 +448,15 @@ void trace_regs(uint8_t* regs) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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;
|
|
||||||
|
|
||||||
systask_id_t task_id = systask_id(systask_active());
|
|
||||||
|
|
||||||
printf("%04ld [task=%d, event=%c, x=%3d, y=%3d]\r\n", time, task_id,
|
|
||||||
event_type, x, y);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Reads touch registers and returns the last touch event
|
// Reads touch registers and returns the last touch event
|
||||||
// (state of touch registers) the controller is reporting.
|
// (state of touch registers) the controller is reporting.
|
||||||
static uint32_t touch_get_state(touch_driver_t* driver) {
|
uint32_t touch_get_state(void) {
|
||||||
|
touch_driver_t* driver = &g_touch_driver;
|
||||||
|
|
||||||
|
if (sectrue != driver->initialized) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Content of registers 0x00 - 0x06 read from the touch controller
|
// Content of registers 0x00 - 0x06 read from the touch controller
|
||||||
uint8_t regs[7];
|
uint8_t regs[7];
|
||||||
|
|
||||||
@ -553,59 +533,4 @@ static uint32_t touch_get_state(touch_driver_t* driver) {
|
|||||||
return driver->state;
|
return driver->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t touch_get_event(void) {
|
|
||||||
touch_driver_t* driver = &g_touch_driver;
|
|
||||||
|
|
||||||
if (sectrue != driver->initialized) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
touch_fsm_t* fsm = &driver->tls[systask_id(systask_active())];
|
|
||||||
|
|
||||||
uint32_t touch_state = touch_get_state(driver);
|
|
||||||
|
|
||||||
uint32_t event = touch_fsm_get_event(fsm, touch_state);
|
|
||||||
|
|
||||||
#ifdef TOUCH_TRACE_EVENT
|
|
||||||
trace_event(event);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_task_created(void* context, systask_id_t task_id) {
|
|
||||||
touch_driver_t* driver = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &driver->tls[task_id];
|
|
||||||
touch_fsm_init(fsm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_event_poll(void* context, bool read_awaited,
|
|
||||||
bool write_awaited) {
|
|
||||||
touch_driver_t* driver = (touch_driver_t*)context;
|
|
||||||
UNUSED(write_awaited);
|
|
||||||
|
|
||||||
if (read_awaited) {
|
|
||||||
uint32_t touch_state = touch_get_state(driver);
|
|
||||||
syshandle_signal_read_ready(SYSHANDLE_TOUCH, &touch_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
|
||||||
void* param) {
|
|
||||||
touch_driver_t* driver = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &driver->tls[task_id];
|
|
||||||
|
|
||||||
uint32_t touch_state = *(uint32_t*)param;
|
|
||||||
|
|
||||||
return touch_fsm_event_ready(fsm, touch_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt = {
|
|
||||||
.task_created = on_task_created,
|
|
||||||
.task_killed = NULL,
|
|
||||||
.check_read_ready = on_check_read_ready,
|
|
||||||
.check_write_ready = NULL,
|
|
||||||
.poll = on_event_poll,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
||||||
|
@ -73,6 +73,8 @@ secbool touch_set_sensitivity(uint8_t value);
|
|||||||
// The function should not be used together with `touch_get_event()`.
|
// The function should not be used together with `touch_get_event()`.
|
||||||
secbool touch_activity(void);
|
secbool touch_activity(void);
|
||||||
|
|
||||||
|
uint32_t touch_get_state(void);
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
||||||
|
|
||||||
// Returns the last event in packed 32-bit format
|
// Returns the last event in packed 32-bit format
|
||||||
|
@ -22,9 +22,8 @@
|
|||||||
#include <trezor_rtl.h>
|
#include <trezor_rtl.h>
|
||||||
|
|
||||||
#include <io/touch.h>
|
#include <io/touch.h>
|
||||||
#include <sys/sysevent_source.h>
|
|
||||||
|
|
||||||
#include "../touch_fsm.h"
|
#include "../touch_poll.h"
|
||||||
#include "sitronix.h"
|
#include "sitronix.h"
|
||||||
|
|
||||||
// Touch driver
|
// Touch driver
|
||||||
@ -33,8 +32,6 @@ typedef struct {
|
|||||||
secbool initialized;
|
secbool initialized;
|
||||||
// Last reported touch state
|
// Last reported touch state
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
// Touch state machine for each task
|
|
||||||
touch_fsm_t tls[SYSTASK_MAX_TASKS];
|
|
||||||
|
|
||||||
} touch_driver_t;
|
} touch_driver_t;
|
||||||
|
|
||||||
@ -43,9 +40,6 @@ static touch_driver_t g_touch_driver = {
|
|||||||
.initialized = secfalse,
|
.initialized = secfalse,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt;
|
|
||||||
|
|
||||||
secbool touch_init(void) {
|
secbool touch_init(void) {
|
||||||
touch_driver_t* drv = &g_touch_driver;
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
@ -66,7 +60,7 @@ secbool touch_init(void) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!syshandle_register(SYSHANDLE_TOUCH, &g_touch_handle_vmt, drv)) {
|
if (!touch_poll_init()) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +76,7 @@ void touch_deinit(void) {
|
|||||||
touch_driver_t* drv = &g_touch_driver;
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
BSP_TS_DeInit(0);
|
BSP_TS_DeInit(0);
|
||||||
syshandle_unregister(SYSHANDLE_TOUCH);
|
touch_poll_deinit();
|
||||||
|
|
||||||
memset(drv, 0, sizeof(touch_driver_t));
|
memset(drv, 0, sizeof(touch_driver_t));
|
||||||
}
|
}
|
||||||
@ -119,7 +113,13 @@ secbool touch_activity(void) {
|
|||||||
return sitronix_touching ? sectrue : secfalse;
|
return sitronix_touching ? sectrue : secfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t touch_get_state(touch_driver_t* drv) {
|
uint32_t touch_get_state(void) {
|
||||||
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
|
if (sectrue != drv->initialized) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
TS_State_t ts = {0};
|
TS_State_t ts = {0};
|
||||||
BSP_TS_GetState(0, &ts);
|
BSP_TS_GetState(0, &ts);
|
||||||
|
|
||||||
@ -153,58 +153,4 @@ static uint32_t touch_get_state(touch_driver_t* drv) {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t touch_get_event(void) {
|
|
||||||
touch_driver_t* drv = &g_touch_driver;
|
|
||||||
|
|
||||||
if (sectrue != drv->initialized) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
touch_fsm_t* fsm = &drv->tls[systask_id(systask_active())];
|
|
||||||
|
|
||||||
uint32_t touch_state = touch_get_state(drv);
|
|
||||||
|
|
||||||
uint32_t event = touch_fsm_get_event(fsm, touch_state);
|
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_task_created(void* context, systask_id_t task_id) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &drv->tls[task_id];
|
|
||||||
touch_fsm_init(fsm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_event_poll(void* context, bool read_awaited,
|
|
||||||
bool write_awaited) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
|
|
||||||
UNUSED(write_awaited);
|
|
||||||
|
|
||||||
if (read_awaited) {
|
|
||||||
uint32_t touch_state = touch_get_state(drv);
|
|
||||||
if (touch_state != 0) {
|
|
||||||
syshandle_signal_read_ready(SYSHANDLE_TOUCH, &touch_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
|
||||||
void* param) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &drv->tls[task_id];
|
|
||||||
|
|
||||||
uint32_t touch_state = *(uint32_t*)param;
|
|
||||||
|
|
||||||
return touch_fsm_event_ready(fsm, touch_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt = {
|
|
||||||
.task_created = on_task_created,
|
|
||||||
.task_killed = NULL,
|
|
||||||
.check_read_ready = on_check_read_ready,
|
|
||||||
.check_write_ready = NULL,
|
|
||||||
.poll = on_event_poll,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
||||||
|
@ -23,9 +23,8 @@
|
|||||||
#ifdef KERNEL_MODE
|
#ifdef KERNEL_MODE
|
||||||
|
|
||||||
#include <io/touch.h>
|
#include <io/touch.h>
|
||||||
#include <sys/sysevent_source.h>
|
|
||||||
|
|
||||||
#include "../touch_fsm.h"
|
#include "../touch_poll.h"
|
||||||
#include "stmpe811.h"
|
#include "stmpe811.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -35,8 +34,6 @@ typedef struct {
|
|||||||
i2c_bus_t* i2c_bus;
|
i2c_bus_t* i2c_bus;
|
||||||
// Last reported touch state
|
// Last reported touch state
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
// Touch state machine for each task
|
|
||||||
touch_fsm_t tls[SYSTASK_MAX_TASKS];
|
|
||||||
|
|
||||||
} touch_driver_t;
|
} touch_driver_t;
|
||||||
|
|
||||||
@ -45,9 +42,6 @@ static touch_driver_t g_touch_driver = {
|
|||||||
.initialized = secfalse,
|
.initialized = secfalse,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt;
|
|
||||||
|
|
||||||
secbool touch_init(void) {
|
secbool touch_init(void) {
|
||||||
touch_driver_t* drv = &g_touch_driver;
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
@ -63,7 +57,7 @@ secbool touch_init(void) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!syshandle_register(SYSHANDLE_TOUCH, &g_touch_handle_vmt, drv)) {
|
if (!touch_poll_init()) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +75,7 @@ cleanup:
|
|||||||
void touch_deinit(void) {
|
void touch_deinit(void) {
|
||||||
touch_driver_t* drv = &g_touch_driver;
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
syshandle_unregister(SYSHANDLE_TOUCH);
|
touch_poll_deinit();
|
||||||
i2c_bus_close(drv->i2c_bus);
|
i2c_bus_close(drv->i2c_bus);
|
||||||
memset(drv, 0, sizeof(touch_driver_t));
|
memset(drv, 0, sizeof(touch_driver_t));
|
||||||
}
|
}
|
||||||
@ -112,7 +106,13 @@ secbool touch_activity(void) {
|
|||||||
return state > 0 ? sectrue : secfalse;*/
|
return state > 0 ? sectrue : secfalse;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t touch_get_state(touch_driver_t* drv) {
|
uint32_t touch_get_state(void) {
|
||||||
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
|
if (sectrue != drv->initialized) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
TS_StateTypeDef ts = {0};
|
TS_StateTypeDef ts = {0};
|
||||||
BSP_TS_GetState(&ts);
|
BSP_TS_GetState(&ts);
|
||||||
|
|
||||||
@ -142,58 +142,4 @@ static uint32_t touch_get_state(touch_driver_t* drv) {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t touch_get_event(void) {
|
|
||||||
touch_driver_t* drv = &g_touch_driver;
|
|
||||||
|
|
||||||
if (sectrue != drv->initialized) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
touch_fsm_t* fsm = &drv->tls[systask_id(systask_active())];
|
|
||||||
|
|
||||||
uint32_t touch_state = touch_get_state(drv);
|
|
||||||
|
|
||||||
uint32_t event = touch_fsm_get_event(fsm, touch_state);
|
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_task_created(void* context, systask_id_t task_id) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &drv->tls[task_id];
|
|
||||||
touch_fsm_init(fsm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_event_poll(void* context, bool read_awaited,
|
|
||||||
bool write_awaited) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
|
|
||||||
UNUSED(write_awaited);
|
|
||||||
|
|
||||||
if (read_awaited) {
|
|
||||||
uint32_t touch_state = touch_get_state(drv);
|
|
||||||
if (touch_state != 0) {
|
|
||||||
syshandle_signal_read_ready(SYSHANDLE_TOUCH, &touch_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
|
||||||
void* param) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &drv->tls[task_id];
|
|
||||||
|
|
||||||
uint32_t touch_state = *(uint32_t*)param;
|
|
||||||
|
|
||||||
return touch_fsm_event_ready(fsm, touch_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt = {
|
|
||||||
.task_created = on_task_created,
|
|
||||||
.task_killed = NULL,
|
|
||||||
.check_read_ready = on_check_read_ready,
|
|
||||||
.check_write_ready = NULL,
|
|
||||||
.poll = on_event_poll,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Trezor project, https://trezor.io/
|
|
||||||
*
|
|
||||||
* Copyright (c) SatoshiLabs
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// This module is a simple finite state machine for touch events.
|
|
||||||
//
|
|
||||||
// It is designed to be used in a polling loop, where the state of the touch
|
|
||||||
// is read periodically. The module keeps track of the state changes and
|
|
||||||
// provides a simple interface to get the events that happened since the last
|
|
||||||
// call to touch_fsm_get_event().
|
|
||||||
//
|
|
||||||
// The benefit of using this module is that it can properly handle situations
|
|
||||||
// when the touch panel is not read frequently enough or when some
|
|
||||||
// touch events are missed.
|
|
||||||
//
|
|
||||||
// The structure is designed to be used in a multi-threaded environment, where
|
|
||||||
// each thread has its own state machine. The state machines are stored in an
|
|
||||||
// array indexed by the task ID.
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
// Time (in ticks) when the tls was last updated
|
|
||||||
uint32_t update_ticks;
|
|
||||||
// Last reported touch state
|
|
||||||
uint32_t state;
|
|
||||||
// Set if the touch controller is currently touched
|
|
||||||
// (respectively, that we detected a touch event)
|
|
||||||
bool pressed;
|
|
||||||
// Previously reported x-coordinate
|
|
||||||
uint16_t last_x;
|
|
||||||
// Previously reported y-coordinate
|
|
||||||
uint16_t last_y;
|
|
||||||
} touch_fsm_t;
|
|
||||||
|
|
||||||
// Initializes button finite state machine
|
|
||||||
void touch_fsm_init(touch_fsm_t* fsm);
|
|
||||||
|
|
||||||
// Checks if touch_fsm_get_event() would return `true` on the next call
|
|
||||||
bool touch_fsm_event_ready(touch_fsm_t* fsm, uint32_t touch_state);
|
|
||||||
|
|
||||||
// Processes the new state of thetouch panel and fills the event structure.
|
|
||||||
//
|
|
||||||
// `touch_state` is the current state of the touch panel. The state has
|
|
||||||
// the same format as the return value of `touch_get_state()`.
|
|
||||||
//
|
|
||||||
// Returns `true` if the event structure was filled.
|
|
||||||
uint32_t touch_fsm_get_event(touch_fsm_t* fsm, uint32_t touch_state);
|
|
@ -22,11 +22,41 @@
|
|||||||
#include <trezor_rtl.h>
|
#include <trezor_rtl.h>
|
||||||
|
|
||||||
#include <io/touch.h>
|
#include <io/touch.h>
|
||||||
|
#include <sys/sysevent_source.h>
|
||||||
|
#include <sys/systask.h>
|
||||||
#include <sys/systick.h>
|
#include <sys/systick.h>
|
||||||
|
|
||||||
#include "touch_fsm.h"
|
#include "touch_poll.h"
|
||||||
|
|
||||||
void touch_fsm_init(touch_fsm_t* fsm) {
|
// #define TOUCH_TRACE_EVENT
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Time (in ticks) when the tls was last updated
|
||||||
|
uint32_t update_ticks;
|
||||||
|
// Last reported touch state
|
||||||
|
uint32_t state;
|
||||||
|
// Set if the touch controller is currently touched
|
||||||
|
// (respectively, that we detected a touch event)
|
||||||
|
bool pressed;
|
||||||
|
// Previously reported x-coordinate
|
||||||
|
uint16_t last_x;
|
||||||
|
// Previously reported y-coordinate
|
||||||
|
uint16_t last_y;
|
||||||
|
} touch_fsm_t;
|
||||||
|
|
||||||
|
// Touch state machine for each task
|
||||||
|
static touch_fsm_t g_touch_tls[SYSTASK_MAX_TASKS];
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
static const syshandle_vmt_t g_touch_handle_vmt;
|
||||||
|
|
||||||
|
bool touch_poll_init(void) {
|
||||||
|
return syshandle_register(SYSHANDLE_TOUCH, &g_touch_handle_vmt, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void touch_poll_deinit(void) { syshandle_unregister(SYSHANDLE_TOUCH); }
|
||||||
|
|
||||||
|
static void touch_fsm_clear(touch_fsm_t* fsm) {
|
||||||
memset(fsm, 0, sizeof(touch_fsm_t));
|
memset(fsm, 0, sizeof(touch_fsm_t));
|
||||||
fsm->update_ticks = systick_ms();
|
fsm->update_ticks = systick_ms();
|
||||||
}
|
}
|
||||||
@ -35,6 +65,25 @@ bool touch_fsm_event_ready(touch_fsm_t* fsm, uint32_t touch_state) {
|
|||||||
return fsm->state != touch_state;
|
return fsm->state != touch_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
systask_id_t task_id = systask_id(systask_active());
|
||||||
|
|
||||||
|
printf("%04ld [task=%d, event=%c, x=%3d, y=%3d]\r\n", time, task_id,
|
||||||
|
event_type, x, y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t touch_fsm_get_event(touch_fsm_t* fsm, uint32_t touch_state) {
|
uint32_t touch_fsm_get_event(touch_fsm_t* fsm, uint32_t touch_state) {
|
||||||
uint32_t ticks = hal_ticks_ms();
|
uint32_t ticks = hal_ticks_ms();
|
||||||
|
|
||||||
@ -111,4 +160,52 @@ uint32_t touch_fsm_get_event(touch_fsm_t* fsm, uint32_t touch_state) {
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t touch_get_event(void) {
|
||||||
|
touch_fsm_t* fsm = &g_touch_tls[systask_id(systask_active())];
|
||||||
|
|
||||||
|
uint32_t touch_state = touch_get_state();
|
||||||
|
|
||||||
|
uint32_t event = touch_fsm_get_event(fsm, touch_state);
|
||||||
|
|
||||||
|
#ifdef TOUCH_TRACE_EVENT
|
||||||
|
if (event != 0) {
|
||||||
|
trace_event(event);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_task_created(void* context, systask_id_t task_id) {
|
||||||
|
touch_fsm_t* fsm = &g_touch_tls[task_id];
|
||||||
|
touch_fsm_clear(fsm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_event_poll(void* context, bool read_awaited,
|
||||||
|
bool write_awaited) {
|
||||||
|
UNUSED(write_awaited);
|
||||||
|
|
||||||
|
if (read_awaited) {
|
||||||
|
uint32_t touch_state = touch_get_state();
|
||||||
|
syshandle_signal_read_ready(SYSHANDLE_TOUCH, &touch_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
||||||
|
void* param) {
|
||||||
|
touch_fsm_t* fsm = &g_touch_tls[task_id];
|
||||||
|
|
||||||
|
uint32_t touch_state = *(uint32_t*)param;
|
||||||
|
|
||||||
|
return touch_fsm_event_ready(fsm, touch_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const syshandle_vmt_t g_touch_handle_vmt = {
|
||||||
|
.task_created = on_task_created,
|
||||||
|
.task_killed = NULL,
|
||||||
|
.check_read_ready = on_check_read_ready,
|
||||||
|
.check_write_ready = NULL,
|
||||||
|
.poll = on_event_poll,
|
||||||
|
};
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
24
core/embed/io/touch/touch_poll.h
Normal file
24
core/embed/io/touch/touch_poll.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Trezor project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (c) SatoshiLabs
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
bool touch_poll_init(void);
|
||||||
|
|
||||||
|
void touch_poll_deinit(void);
|
@ -21,11 +21,10 @@
|
|||||||
#include <trezor_rtl.h>
|
#include <trezor_rtl.h>
|
||||||
|
|
||||||
#include <io/touch.h>
|
#include <io/touch.h>
|
||||||
#include <sys/sysevent_source.h>
|
|
||||||
#include <sys/systick.h>
|
#include <sys/systick.h>
|
||||||
#include <sys/unix/sdl_event.h>
|
#include <sys/unix/sdl_event.h>
|
||||||
|
|
||||||
#include "../touch_fsm.h"
|
#include "../touch_poll.h"
|
||||||
|
|
||||||
extern int sdl_display_res_x, sdl_display_res_y;
|
extern int sdl_display_res_x, sdl_display_res_y;
|
||||||
extern int sdl_touch_offset_x, sdl_touch_offset_y;
|
extern int sdl_touch_offset_x, sdl_touch_offset_y;
|
||||||
@ -62,8 +61,6 @@ typedef struct {
|
|||||||
|
|
||||||
// Last event not yet read
|
// Last event not yet read
|
||||||
uint32_t last_event;
|
uint32_t last_event;
|
||||||
// Touch state machine for each task
|
|
||||||
touch_fsm_t tls[SYSTASK_MAX_TASKS];
|
|
||||||
|
|
||||||
} touch_driver_t;
|
} touch_driver_t;
|
||||||
|
|
||||||
@ -72,9 +69,6 @@ static touch_driver_t g_touch_driver = {
|
|||||||
.initialized = secfalse,
|
.initialized = secfalse,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt;
|
|
||||||
|
|
||||||
static bool is_inside_display(int x, int y) {
|
static bool is_inside_display(int x, int y) {
|
||||||
return x >= sdl_touch_offset_x && y >= sdl_touch_offset_y &&
|
return x >= sdl_touch_offset_x && y >= sdl_touch_offset_y &&
|
||||||
x - sdl_touch_offset_x < sdl_display_res_x &&
|
x - sdl_touch_offset_x < sdl_display_res_x &&
|
||||||
@ -209,7 +203,7 @@ secbool touch_init(void) {
|
|||||||
memset(drv, 0, sizeof(touch_driver_t));
|
memset(drv, 0, sizeof(touch_driver_t));
|
||||||
drv->state = IDLE;
|
drv->state = IDLE;
|
||||||
|
|
||||||
if (!syshandle_register(SYSHANDLE_TOUCH, &g_touch_handle_vmt, drv)) {
|
if (!touch_poll_init()) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +222,7 @@ void touch_deinit(void) {
|
|||||||
touch_driver_t* drv = &g_touch_driver;
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
if (drv->initialized == sectrue) {
|
if (drv->initialized == sectrue) {
|
||||||
syshandle_unregister(SYSHANDLE_TOUCH);
|
touch_poll_deinit();
|
||||||
memset(drv, 0, sizeof(touch_driver_t));
|
memset(drv, 0, sizeof(touch_driver_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,7 +254,13 @@ secbool touch_activity(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t touch_get_state(touch_driver_t* drv) {
|
uint32_t touch_get_state(void) {
|
||||||
|
touch_driver_t* drv = &g_touch_driver;
|
||||||
|
|
||||||
|
if (sectrue != drv->initialized) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sdl_events_poll();
|
sdl_events_poll();
|
||||||
|
|
||||||
if (drv->state == BUTTON_SWIPE_INITIATED) {
|
if (drv->state == BUTTON_SWIPE_INITIATED) {
|
||||||
@ -277,57 +277,3 @@ uint32_t touch_get_state(touch_driver_t* drv) {
|
|||||||
|
|
||||||
return drv->last_event;
|
return drv->last_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t touch_get_event(void) {
|
|
||||||
touch_driver_t* driver = &g_touch_driver;
|
|
||||||
|
|
||||||
if (sectrue != driver->initialized) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
touch_fsm_t* fsm = &driver->tls[systask_id(systask_active())];
|
|
||||||
|
|
||||||
uint32_t touch_state = touch_get_state(driver);
|
|
||||||
|
|
||||||
uint32_t event = touch_fsm_get_event(fsm, touch_state);
|
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_task_created(void* context, systask_id_t task_id) {
|
|
||||||
touch_driver_t* dr = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &dr->tls[task_id];
|
|
||||||
touch_fsm_init(fsm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_event_poll(void* context, bool read_awaited,
|
|
||||||
bool write_awaited) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
|
|
||||||
UNUSED(write_awaited);
|
|
||||||
|
|
||||||
if (read_awaited) {
|
|
||||||
uint32_t touch_state = touch_get_state(drv);
|
|
||||||
if (touch_state != 0) {
|
|
||||||
syshandle_signal_read_ready(SYSHANDLE_TOUCH, &touch_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
|
||||||
void* param) {
|
|
||||||
touch_driver_t* drv = (touch_driver_t*)context;
|
|
||||||
touch_fsm_t* fsm = &drv->tls[task_id];
|
|
||||||
|
|
||||||
uint32_t touch_state = *(uint32_t*)param;
|
|
||||||
|
|
||||||
return touch_fsm_event_ready(fsm, touch_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const syshandle_vmt_t g_touch_handle_vmt = {
|
|
||||||
.task_created = on_task_created,
|
|
||||||
.task_killed = NULL,
|
|
||||||
.check_read_ready = on_check_read_ready,
|
|
||||||
.check_write_ready = NULL,
|
|
||||||
.poll = on_event_poll,
|
|
||||||
};
|
|
||||||
|
@ -73,7 +73,7 @@ def configure(
|
|||||||
sources += ["embed/io/i2c_bus/stm32f4/i2c_bus.c"]
|
sources += ["embed/io/i2c_bus/stm32f4/i2c_bus.c"]
|
||||||
sources += ["embed/io/touch/stmpe811/stmpe811.c"]
|
sources += ["embed/io/touch/stmpe811/stmpe811.c"]
|
||||||
sources += ["embed/io/touch/stmpe811/touch.c"]
|
sources += ["embed/io/touch/stmpe811/touch.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/i2c_bus/inc"]
|
paths += ["embed/io/i2c_bus/inc"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
|
@ -57,7 +57,7 @@ def configure(
|
|||||||
sources += ["embed/io/i2c_bus/stm32u5/i2c_bus.c"]
|
sources += ["embed/io/i2c_bus/stm32u5/i2c_bus.c"]
|
||||||
sources += ["embed/io/touch/sitronix/touch.c"]
|
sources += ["embed/io/touch/sitronix/touch.c"]
|
||||||
sources += ["embed/io/touch/sitronix/sitronix.c"]
|
sources += ["embed/io/touch/sitronix/sitronix.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/i2c_bus/inc"]
|
paths += ["embed/io/i2c_bus/inc"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
|
@ -52,7 +52,7 @@ def configure(
|
|||||||
|
|
||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/touch/unix/touch.c"]
|
sources += ["embed/io/touch/unix/touch.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
defines += [("USE_TOUCH", "1")]
|
defines += [("USE_TOUCH", "1")]
|
||||||
|
@ -63,7 +63,7 @@ def configure(
|
|||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/i2c_bus/stm32f4/i2c_bus.c"]
|
sources += ["embed/io/i2c_bus/stm32f4/i2c_bus.c"]
|
||||||
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/i2c_bus/inc"]
|
paths += ["embed/io/i2c_bus/inc"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
|
@ -62,7 +62,7 @@ def configure(
|
|||||||
|
|
||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/touch/unix/touch.c"]
|
sources += ["embed/io/touch/unix/touch.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
defines += [("USE_TOUCH", "1")]
|
defines += [("USE_TOUCH", "1")]
|
||||||
|
@ -66,7 +66,7 @@ def configure(
|
|||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/i2c_bus/stm32u5/i2c_bus.c"]
|
sources += ["embed/io/i2c_bus/stm32u5/i2c_bus.c"]
|
||||||
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
sources += ["embed/io/touch/ft6x36/panels/lx154a2422cpt23.c"]
|
sources += ["embed/io/touch/ft6x36/panels/lx154a2422cpt23.c"]
|
||||||
paths += ["embed/io/i2c_bus/inc"]
|
paths += ["embed/io/i2c_bus/inc"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
|
@ -82,7 +82,7 @@ def configure(
|
|||||||
|
|
||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/touch/unix/touch.c"]
|
sources += ["embed/io/touch/unix/touch.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
defines += [("USE_TOUCH", "1")]
|
defines += [("USE_TOUCH", "1")]
|
||||||
|
@ -61,7 +61,7 @@ def configure(
|
|||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
||||||
sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
|
sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
sources += ["embed/io/button/stm32/button.c"]
|
sources += ["embed/io/button/stm32/button.c"]
|
||||||
|
@ -61,7 +61,7 @@ def configure(
|
|||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
||||||
sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
|
sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
sources += ["embed/io/button/stm32/button.c"]
|
sources += ["embed/io/button/stm32/button.c"]
|
||||||
|
@ -61,7 +61,7 @@ def configure(
|
|||||||
if "input" in features_wanted:
|
if "input" in features_wanted:
|
||||||
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
|
||||||
sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
|
sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
|
||||||
sources += ["embed/io/touch/touch_fsm.c"]
|
sources += ["embed/io/touch/touch_poll.c"]
|
||||||
paths += ["embed/io/touch/inc"]
|
paths += ["embed/io/touch/inc"]
|
||||||
features_available.append("touch")
|
features_available.append("touch")
|
||||||
sources += ["embed/io/button/stm32/button.c"]
|
sources += ["embed/io/button/stm32/button.c"]
|
||||||
|
Loading…
Reference in New Issue
Block a user