diff --git a/core/.changelog.d/3972.fixed b/core/.changelog.d/3972.fixed
new file mode 100644
index 0000000000..f2cfd86999
--- /dev/null
+++ b/core/.changelog.d/3972.fixed
@@ -0,0 +1 @@
+[T3T1] Improve touch layer precision
diff --git a/core/embed/models/T3T1/boards/trezor_t3t1_revE.h b/core/embed/models/T3T1/boards/trezor_t3t1_revE.h
index 4fd2f7b48b..591ff37b52 100644
--- a/core/embed/models/T3T1/boards/trezor_t3t1_revE.h
+++ b/core/embed/models/T3T1/boards/trezor_t3t1_revE.h
@@ -77,6 +77,7 @@
#define I2C_INSTANCE_2_RESET_REG &RCC->APB3RSTR
#define I2C_INSTANCE_2_RESET_BIT RCC_APB3RSTR_I2C3RST
+#define TOUCH_PANEL_LX154A2422CPT23 1
#define TOUCH_SENSITIVITY 0x40
#define TOUCH_I2C_INSTANCE 0
#define TOUCH_RST_PORT GPIOC
diff --git a/core/embed/trezorhal/stm32f4/touch/ft6x36.c b/core/embed/trezorhal/stm32f4/touch/ft6x36.c
index 7d9f3d1ab0..bd22aad8cb 100644
--- a/core/embed/trezorhal/stm32f4/touch/ft6x36.c
+++ b/core/embed/trezorhal/stm32f4/touch/ft6x36.c
@@ -29,6 +29,10 @@
#include "i2c.h"
#include "touch.h"
+#ifdef TOUCH_PANEL_LX154A2422CPT23
+#include "panels/lx154a2422cpt23.h"
+#endif
+
typedef struct {
// Set if the driver is initialized
secbool initialized;
@@ -222,6 +226,16 @@ static secbool ft6x36_configure(void) {
return sectrue;
}
+static void ft6x36_panel_correction(uint16_t x, uint16_t y, uint16_t* x_new,
+ uint16_t* y_new) {
+#ifdef TOUCH_PANEL_LX154A2422CPT23
+ lx154a2422cpt23_touch_correction(x, y, x_new, y_new);
+#else
+ *x_new = x;
+ *y_new = y;
+#endif
+}
+
secbool touch_init(void) {
touch_driver_t* driver = &g_touch_driver;
@@ -376,8 +390,14 @@ uint32_t touch_get_event(void) {
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];
+ uint16_t x_raw =
+ ((regs[FT6X63_REG_P1_XH] & 0x0F) << 8) | regs[FT6X63_REG_P1_XL];
+ uint16_t y_raw =
+ ((regs[FT6X63_REG_P1_YH] & 0x0F) << 8) | regs[FT6X63_REG_P1_YL];
+
+ uint16_t x, y;
+
+ ft6x36_panel_correction(x_raw, y_raw, &x, &y);
uint32_t event = 0;
diff --git a/core/embed/trezorhal/stm32f4/touch/panels/lx154a2422cpt23.c b/core/embed/trezorhal/stm32f4/touch/panels/lx154a2422cpt23.c
new file mode 100644
index 0000000000..1da0f19161
--- /dev/null
+++ b/core/embed/trezorhal/stm32f4/touch/panels/lx154a2422cpt23.c
@@ -0,0 +1,42 @@
+/*
+ * 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 .
+ */
+
+#include TREZOR_BOARD
+
+#include "lx154a2422cpt23.h"
+
+#include "touch.h"
+
+void lx154a2422cpt23_touch_correction(uint16_t x, uint16_t y, uint16_t *x_new,
+ uint16_t *y_new) {
+#define CENTER (DISPLAY_RESX / 2)
+#define CORRECTION 30
+
+ int x_corrected = CENTER + ((x - CENTER) * (CORRECTION + CENTER) / CENTER);
+
+ if (x_corrected < 0) {
+ *x_new = 0;
+ } else if (x_corrected >= DISPLAY_RESX) {
+ *x_new = DISPLAY_RESX - 1;
+ } else {
+ *x_new = (uint16_t)x_corrected;
+ }
+
+ *y_new = y;
+}
diff --git a/core/embed/trezorhal/stm32f4/touch/panels/lx154a2422cpt23.h b/core/embed/trezorhal/stm32f4/touch/panels/lx154a2422cpt23.h
new file mode 100644
index 0000000000..bb17bf5d2a
--- /dev/null
+++ b/core/embed/trezorhal/stm32f4/touch/panels/lx154a2422cpt23.h
@@ -0,0 +1,35 @@
+/*
+ * 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 .
+ */
+
+#ifndef TREZORHAL_TOUCH_LX154A2422CPT23_H
+#define TREZORHAL_TOUCH_LX154A2422CPT23_H
+
+#include
+
+// Performs touch coordinates correction needed for a specific panel
+// Input parameteres x, y represent original touch coordinates.
+// Output parameters x_new, y_new represent corrected touch coordinates.
+//
+// In case of LX154A2422CPT23, this correction means to shift X coordinate
+// towards the edge of the screen, proportionally to the distance from the
+// center of the screen.
+void lx154a2422cpt23_touch_correction(uint16_t x, uint16_t y, uint16_t *x_new,
+ uint16_t *y_new);
+
+#endif
diff --git a/core/embed/trezorhal/stm32u5/touch/panels b/core/embed/trezorhal/stm32u5/touch/panels
new file mode 120000
index 0000000000..1923ae8946
--- /dev/null
+++ b/core/embed/trezorhal/stm32u5/touch/panels
@@ -0,0 +1 @@
+../../stm32f4/touch/panels/
\ No newline at end of file
diff --git a/core/embed/trezorhal/touch.h b/core/embed/trezorhal/touch.h
index d0fe29a561..2120bde4bf 100644
--- a/core/embed/trezorhal/touch.h
+++ b/core/embed/trezorhal/touch.h
@@ -66,6 +66,7 @@ uint32_t touch_get_event(void);
#define TOUCH_START (1U << 24)
#define TOUCH_MOVE (1U << 25)
#define TOUCH_END (1U << 26)
+#define TOUCH_EVENT_MASK (0xFF << 24)
// Returns x-coordinates from a packed touch event
static inline uint16_t touch_unpack_x(uint32_t evt) {
diff --git a/core/site_scons/models/T3T1/trezor_t3t1_revE.py b/core/site_scons/models/T3T1/trezor_t3t1_revE.py
index 64c5baab77..644efac595 100644
--- a/core/site_scons/models/T3T1/trezor_t3t1_revE.py
+++ b/core/site_scons/models/T3T1/trezor_t3t1_revE.py
@@ -73,6 +73,7 @@ def configure(
if "input" in features_wanted:
sources += ["embed/trezorhal/stm32u5/i2c.c"]
sources += ["embed/trezorhal/stm32u5/touch/ft6x36.c"]
+ sources += ["embed/trezorhal/stm32u5/touch/panels/lx154a2422cpt23.c"]
features_available.append("touch")
if "haptic" in features_wanted: