refactor(core): touch drivers' FT6x36 and FT3168 source code split. Each of them shall be developed separately. FT3168 source files derived out of FT6x36 ones. FT3168 source files are referenced from the respective build scripts of T3W1 (TS7). Board revisions A, B, C are covered. Macro TOUCH_WAKEUP_
What changed, and why it matters
This commit is a code cleanup and hardware-support refactor. It splits the touch-screen driver for the FT3168 controller out of the older FT6x36 driver, updates the T3W1 device build files to use the new driver, and removes an unused wake-up workaround. There is no obvious security vulnerability introduced, but any driver refactor carries a small risk of functional regressions in touch handling on the T3W1 hardware.
Treat as a normal hardware-support refactor. Verify touch functionality and regression tests on T3W1 revA/B/C devices. No immediate security response is indicated by the diff alone.
Security signals we found
Driver refactor with new file additions and deletions
Removal of TOUCH_WAKEUP_WORKAROUND macro and ft6x36_wake_up() function
Build-system switch from ft6x36 to ft3168 for T3W1 revisions A/B/C
No changes to crypto, secure storage, USB, or authentication code
Evidence from the diff
The change creates a dedicated FT3168 touch driver under core/embed/io/touch/ft3168/, derived from the FT6x36 source. It moves the LX250A2410A panel correction files to the new FT3168 directory, removes the TOUCH_WAKEUP_WORKAROUND macro and ft6x36_wake_up() calls, and updates T3W1 revA/B/C board headers and SCons build scripts to compile the FT3168 driver instead of FT6x36. The FT6x36 driver is simplified by removing FT3168-specific panel support. No cryptographic, authentication, or memory-safety changes are visible in the diff.
Changed components
core/embed/io/touch/ft3168/ft3168.ccore/embed/io/touch/ft3168/ft3168.hcore/embed/io/touch/ft3168/panels/lx250a2410a.ccore/embed/io/touch/ft3168/panels/lx250a2410a.hcore/embed/io/touch/ft6x36/ft6x36.ccore/embed/models/T3W1/boards/trezor_t3w1_revA.hcore/embed/models/T3W1/boards/trezor_t3w1_revB.hcore/embed/models/T3W1/boards/trezor_t3w1_revC.hcore/site_scons/models/T3W1/trezor_t3w1_revA.pycore/site_scons/models/T3W1/trezor_t3w1_revB.pycore/site_scons/models/T3W1/trezor_t3w1_revC.pyInspect captured patch +662 / −97
diff --git a/core/embed/io/touch/ft3168/ft3168.c b/core/embed/io/touch/ft3168/ft3168.c
new file mode 100644
index 000000000..3129363a8
--- /dev/null
+++ b/core/embed/io/touch/ft3168/ft3168.c
@@ -0,0 +1,526 @@
+/*
+ * 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/>.
+ */
+
+#include <trezor_bsp.h>
+#include <trezor_rtl.h>
+
+#ifdef KERNEL_MODE
+
+#include <io/i2c_bus.h>
+#include <io/touch.h>
+#include <sys/systick.h>
+#include "ft3168.h"
+
+#ifdef TOUCH_PANEL_LX250A2410A
+#include "panels/lx250a2410a.h"
+#endif
+
+#include "../touch_poll.h"
+
+// #define TOUCH_TRACE_REGS
+
+typedef struct {
+ // Set if the driver is initialized
+ secbool initialized;
+ // I2c bus where the touch controller is connected
+ i2c_bus_t* i2c_bus;
+ // Set if the driver is ready to report touches.
+ // FT3168 needs about 300ms after power-up to stabilize.
+ secbool ready;
+ // Captured tick counter when `touch_init()` was called
+ uint32_t init_ticks;
+ // Time (in ticks) when the touch registers were read last time
+ uint32_t read_ticks;
+ // Last reported touch state
+ uint32_t state;
+
+} touch_driver_t;
+
+// Touch driver instance
+static touch_driver_t g_touch_driver = {
+ .initialized = secfalse,
+};
+
+// Reads a subsequent registers from the FT3168.
+//
+// Returns: `sectrue` if the register was read
+// successfully, `secfalse` otherwise.
+//
+// If the I2C bus is busy, the function will cycle the
+// bus and retry the operation.
+static secbool ft3168_read_regs(i2c_bus_t* bus, uint8_t reg, uint8_t* value,
+ size_t count) {
+ i2c_op_t ops[] = {
+ {
+ .flags = I2C_FLAG_TX | I2C_FLAG_EMBED,
+ .size = 1,
+ .data = {reg},
+ },
+ {
+ .flags = I2C_FLAG_RX,
+ .size = count,
+ .ptr = value,
+ },
+ };
+
+ i2c_packet_t pkt = {
+ .address = FT3168_I2C_ADDR,
+ .op_count = ARRAY_LENGTH(ops),
+ .ops = ops,
+ };
+
+ if (I2C_STATUS_OK != i2c_bus_submit_and_wait(bus, &pkt)) {
+ return secfalse;
+ }
+
+ return sectrue;
+}
+
+// Writes a register to the FT3168.
+//
+// Returns: `sectrue` if the register was written
+// successfully, `secfalse` otherwise.
+//
+// If the I2C bus is busy, the function will cycle the
+// bus and retry the operation.
+static secbool ft3168_write_reg(i2c_bus_t* bus, uint8_t reg, uint8_t value) {
+ i2c_op_t ops[] = {
+ {
+ .flags = I2C_FLAG_TX | I2C_FLAG_EMBED,
+ .size = 2,
+ .data = {reg, value},
+ },
+ };
+
+ i2c_packet_t pkt = {
+ .address = FT3168_I2C_ADDR,
+ .op_count = ARRAY_LENGTH(ops),
+ .ops = ops,
+ };
+
+ if (I2C_STATUS_OK != i2c_bus_submit_and_wait(bus, &pkt)) {
+ return secfalse;
+ }
+
+ return sectrue;
+}
+
+// Wake up the touch controller from monitor mode.
+//
+// The FT3168 touch controller switches from active mode to monitor mode
+// after a period of inactivity (the default setting is ~12s).
+// This feature cannot be disabled (at least in the current controller
+// firmware). When in this mode, it fails to respond to the first I2C command —
+// writes are not ACKed, and reads return 0x00 or garbage data.
+// To avoid this issue, we need to wake up the controller before
+// sending any commands to it.
+static void ft3168_wake_up(i2c_bus_t* bus) {
+ uint8_t temp;
+ // Wake up the touch controller by reading one of its registers
+ // (the specific register does not matter)
+ ft3168_read_regs(bus, 0x00, &temp, 1);
+ // Wait for the touch controller to wake up
+ // (not sure if this is necessary, but it's safer to include it)
+ systick_delay_ms(1);
+}
+
+// Powers down the touch controller and puts all
+// the pins in the proper state to save power.
+static void ft3168_power_down(void) {
+#ifdef TOUCH_ON_PIN
+ GPIO_PinState state = HAL_GPIO_ReadPin(TOUCH_ON_PORT, TOUCH_ON_PIN);
+
+ // set power off and other pins as per section 3.5 of FT6236 datasheet
+ HAL_GPIO_WritePin(TOUCH_ON_PORT, TOUCH_ON_PIN,
+ GPIO_PIN_SET); // CTP_ON (active low) i.e.- CTPM power
+ // off when set/high/log 1
+
+#endif
+ HAL_GPIO_WritePin(TOUCH_INT_PORT, TOUCH_INT_PIN,
+ GPIO_PIN_RESET); // CTP_INT normally an input, but drive
+ // low as an output while powered off
+
+#ifdef TOUCH_RST_PIN
+ HAL_GPIO_WritePin(TOUCH_RST_PORT, TOUCH_RST_PIN,
+ GPIO_PIN_RESET); // CTP_REST (active low) i.e.- CTPM
+ // held in reset until released
+#endif
+
+ HAL_GPIO_DeInit(TOUCH_INT_PORT, TOUCH_INT_PIN);
+
+#if defined(TOUCH_RST_PIN) || defined(TOUCH_ON_PIN)
+ GPIO_InitTypeDef GPIO_InitStructure = {0};
+ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
+
+#ifdef TOUCH_RST_PIN
+ GPIO_InitStructure.Pin = TOUCH_RST_PIN;
+ HAL_GPIO_Init(TOUCH_RST_PORT, &GPIO_InitStructure);
+#endif
+
+#ifdef TOUCH_ON_PIN
+ GPIO_InitStructure.Pin = TOUCH_ON_PIN;
+ HAL_GPIO_Init(TOUCH_ON_PORT, &GPIO_InitStructure);
+
+ if (state == GPIO_PIN_SET) {
+ // 90 ms for circuitry to stabilize (being conservative)
+ systick_delay_ms(90);
+ }
+#endif
+#endif
+}
+
+// Powers up the touch controller and do proper reset sequence
+//
+// `ft3168_power_down()` must be called before calling this first time function
+// to properly initialize the GPIO pins.
+static void ft3168_power_up(void) {
+#ifdef TOUCH_RST_PIN
+ // Ensure the touch controller is in reset state
+ HAL_GPIO_WritePin(TOUCH_RST_PORT, TOUCH_RST_PIN, GPIO_PIN_RESET);
+#endif
+
+#ifdef TOUCH_ON_PIN
+ // Power up the touch controller
+ HAL_GPIO_WritePin(TOUCH_ON_PORT, TOUCH_ON_PIN, GPIO_PIN_RESET);
+#endif
+
+ // Wait until the circuit fully kicks-in
+ // (5ms is the minimum time required for the reset signal to be effective)
+ systick_delay_ms(10);
+
+ // Enable intterrupt input
+ GPIO_InitTypeDef GPIO_InitStructure = {0};
+ GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
+ GPIO_InitStructure.Pull = GPIO_PULLUP;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStructure.Pin = TOUCH_INT_PIN;
+ HAL_GPIO_Init(TOUCH_INT_PORT, &GPIO_InitStructure);
+
+#ifdef TOUCH_RST_PIN
+ // Release touch controller from reset
+ HAL_GPIO_WritePin(TOUCH_RST_PORT, TOUCH_RST_PIN, GPIO_PIN_SET);
+#endif
+
+ // Wait for the touch controller to boot up
+ systick_delay_ms(5);
+
+ // Clear the flag indicating rising edge on INT_PIN
+ __HAL_GPIO_EXTI_CLEAR_FLAG(TOUCH_INT_PIN);
+}
+
+// Checks if the touch controller has an interrupt pending
+// which indicates that new data is available.
+//
+// The function clears the interrupt flag if it was set so the
+// next call returns `false` if no new impulses were detected.
+static bool ft3168_test_and_clear_interrupt(void) {
+ uint32_t event = __HAL_GPIO_EXTI_GET_FLAG(TOUCH_INT_PIN);
+ if (event != 0) {
+ __HAL_GPIO_EXTI_CLEAR_FLAG(TOUCH_INT_PIN);
+ }
+
+ return event != 0;
+}
+
+// Configures the touch controller to the functional state.
+static secbool ft3168_configure(i2c_bus_t* i2c_bus) {
+ const static uint8_t config[] = {
+ // Set touch controller to the interrupt trigger mode.
+ // Basically, CTPM generates a pulse when new data is available.
+ FT3168_REG_G_MODE,
+ 0x01,
+ FT3168_REG_TH_GROUP,
+ TOUCH_SENSITIVITY,
+ };
+
+ _Static_assert(sizeof(config) % 2 == 0);
+
+ for (int i = 0; i < sizeof(config); i += 2) {
+ uint8_t reg = config[i];
+ uint8_t value = config[i + 1];
+
+ if (sectrue != ft3168_write_reg(i2c_bus, reg, value)) {
+ return secfalse;
+ }
+ }
+
+ return sectrue;
+}
+
+static void ft3168_panel_correction(uint16_t x, uint16_t y, uint16_t* x_new,
+ uint16_t* y_new) {
+#ifdef TOUCH_PANEL_LX250A2410A
+ lx250a2410a_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;
+
+ if (sectrue == driver->initialized) {
+ // The driver is already initialized
+ return sectrue;
+ }
+
+ memset(driver, 0, sizeof(touch_driver_t));
+
+ // Initialize GPIO to the default configuration
+ // (touch controller is powered down)
+ ft3168_power_down();
+
+ // Power up the touch controller and perform the reset sequence
+ ft3168_power_up();
+
+ driver->i2c_bus = i2c_bus_open(TOUCH_I2C_INSTANCE);
+ if (driver->i2c_bus == NULL) {
+ goto cleanup;
+ }
+
+ ft3168_wake_up(driver->i2c_bus);
+
+ // Configure the touch controller
+ if (sectrue != ft3168_configure(driver->i2c_bus)) {
+ goto cleanup;
+ }
+
+ if (!touch_poll_init()) {
+ goto cleanup;
+ }
+
+ driver->init_ticks = systick_ms();
+ driver->read_ticks = driver->init_ticks;
+ driver->initialized = sectrue;
+
+ return sectrue;
+
+cleanup:
+ touch_deinit();
+ return secfalse;
+}
+
+void touch_deinit(void) {
+ touch_driver_t* driver = &g_touch_driver;
+ touch_poll_deinit();
+ i2c_bus_close(driver->i2c_bus);
+ if (sectrue == driver->initialized) {
+ ft3168_power_down();
+ }
+ memset(driver, 0, sizeof(touch_driver_t));
+}
+
+void touch_power_set(bool on) {
+ if (on) {
+ ft3168_power_up();
+ } else {
+ touch_deinit();
+ ft3168_power_down();
+ }
+}
+
+secbool touch_ready(void) {
+ touch_driver_t* driver = &g_touch_driver;
+
+ if (sectrue == driver->initialized && sectrue != driver->ready) {
+ // FT3168 does not report events for 300ms
+ // after it is released from the reset state
+ if ((int)(systick_ms() - driver->init_ticks) >= 310) {
+ driver->ready = sectrue;
+ }
+ }
+
+ return driver->ready;
+}
+
+secbool touch_set_sensitivity(uint8_t value) {
+ touch_driver_t* driver = &g_touch_driver;
+
+ if (sectrue == driver->initialized) {
+ ft3168_wake_up(driver->i2c_bus);
+ return ft3168_write_reg(driver->i2c_bus, FT3168_REG_TH_GROUP, value);
+ } else {
+ return secfalse;
+ }
+}
+
+uint8_t touch_get_version(void) {
+ touch_driver_t* driver = &g_touch_driver;
+
+ if (sectrue != driver->initialized) {
+ return 0;
+ }
+
+ // After powering up the touch controller, we need to wait
+ // for an unspecified amount of time (~100ms) before attempting
+ // to read the firmware version. If we try to read too soon, we get 0x00
+ // and the chip behaves unpredictably.
+ while (sectrue != touch_ready()) {
+ systick_delay_ms(1);
+ }
+
+ ft3168_wake_up(driver->i2c_bus);
+
+ uint8_t fw_version = 0;
+
+ if (sectrue !=
+ ft3168_read_regs(driver->i2c_bus, FT3168_REG_FIRMID, &fw_version, 1)) {
+ ft3168_power_down();
+ return secfalse;
+ }
+
+ return fw_version;
+}
+
+secbool touch_activity(void) {
+ touch_driver_t* driver = &g_touch_driver;
+
+ if (sectrue == driver->initialized) {
+ if (ft3168_test_and_clear_interrupt()) {
+ return sectrue;
+ }
+ }
+
+ return secfalse;
+}
+
+#ifdef TOUCH_TRACE_REGS
+void trace_regs(uint8_t* regs) {
+ // Extract gesture ID (FT3168_GESTURE_xxx)
+ uint8_t gesture = regs[FT3168_REG_GEST_ID];
+
+ // Extract number of touches (0, 1, 2) or 0x0F before
+ // the first touch (tested with FT6206)
+ uint8_t nb_touches = regs[FT3168_REG_TD_STATUS] & 0x0F;
+
+ // Extract event flags (one of press down, contact, lift up)
+ uint8_t flags = regs[FT3168_REG_P1_XH] & FT3168_EVENT_MASK;
+
+ // Extract touch coordinates
+ uint16_t x = ((regs[FT3168_REG_P1_XH] & 0x0F) << 8) | regs[FT3168_REG_P1_XL];
+ uint16_t y = ((regs[FT3168_REG_P1_YH] & 0x0F) << 8) | regs[FT3168_REG_P1_YL];
+
+ char event;
+
+ if (flags == FT3168_EVENT_PRESS_DOWN) {
+ event = 'D';
+ } else if (flags == FT3168_EVENT_CONTACT) {
+ event = 'C';
+ } else if (flags == FT3168_EVENT_LIFT_UP) {
+ event = 'U';
+ } else {
+ event = '-';
+ }
+
+ uint32_t time = systicks_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
+
+// Reads touch registers and returns the last touch event
+// (state of touch registers) the controller is reporting.
+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
+ uint8_t regs[7];
+
+ // Ensure the registers are within the bounds
+ _Static_assert(sizeof(regs) > FT3168_REG_GEST_ID);
+ _Static_assert(sizeof(regs) > FT3168_REG_TD_STATUS);
+ _Static_assert(sizeof(regs) > FT3168_REG_P1_XH);
+ _Static_assert(sizeof(regs) > FT3168_REG_P1_XL);
+ _Static_assert(sizeof(regs) > FT3168_REG_P1_YH);
+ _Static_assert(sizeof(regs) > FT3168_REG_P1_YL);
+
+ uint32_t ticks = hal_ticks_ms();
+
+ // 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
+ bool pressed = (driver->state & TOUCH_START) || (driver->state & TOUCH_MOVE);
+
+ if (!ft3168_test_and_clear_interrupt() && (!pressed || toofast)) {
+ return driver->state;
+ }
+
+ driver->read_ticks = ticks;
+
+ // Read the set of registers containing touch event and coordinates
+ if (sectrue != ft3168_read_regs(driver->i2c_bus, 0x00, regs, sizeof(regs))) {
+ // Failed to read the touch registers
+ return driver->state;
+ }
+
+#ifdef TOUCH_TRACE_REGS
+ trace_regs(regs);
+#endif
+
+ // Extract gesture ID (FT3168_GESTURE_xxx)
+ uint8_t gesture = regs[FT3168_REG_GEST_ID];
+
+ if (gesture != FT3168_GESTURE_NONE) {
+ // This is here for unknown historical reasons
+ // It seems we can't get here with FT3168
+ return driver->state;
+ }
+
+ // Extract number of touches (0, 1, 2) or 0x0F before
+ // the first touch (tested with FT6206)
+ uint8_t nb_touches = regs[FT3168_REG_TD_STATUS] & 0x0F;
+
+ // Extract event flags (one of press down, contact, lift up)
+ uint8_t flags = regs[FT3168_REG_P1_XH] & FT3168_EVENT_MASK;
+
+ // Extract touch coordinates
+ uint16_t x_raw =
+ ((regs[FT3168_REG_P1_XH] & 0x0F) << 8) | regs[FT3168_REG_P1_XL];
+ uint16_t y_raw =
+ ((regs[FT3168_REG_P1_YH] & 0x0F) << 8) | regs[FT3168_REG_P1_YL];
+
+ uint16_t x, y;
+
+ ft3168_panel_correction(x_raw, y_raw, &x, &y);
+
+ uint32_t xy = touch_pack_xy(x, y);
+
+ if ((nb_touches == 1) && (flags == FT3168_EVENT_PRESS_DOWN)) {
+ driver->state = TOUCH_START | xy;
+ } else if ((nb_touches == 1) && (flags == FT3168_EVENT_CONTACT)) {
+ driver->state = TOUCH_MOVE | xy;
+ } else if ((nb_touches == 0) && (flags == FT3168_EVENT_LIFT_UP)) {
+ driver->state = TOUCH_END | xy;
+ }
+
+ return driver->state;
+}
+
+#endif // KERNEL_MODE
diff --git a/core/embed/io/touch/ft3168/ft3168.h b/core/embed/io/touch/ft3168/ft3168.h
new file mode 100644
index 000000000..0d9c38ca4
--- /dev/null
+++ b/core/embed/io/touch/ft3168/ft3168.h
@@ -0,0 +1,72 @@
+/*
+ * 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
+
+// I2C address of the FT3168 on the I2C bus.
+#define FT3168_I2C_ADDR 0x38
+
+// ------------------------------------------------------------
+// FT3168 registers
+// ------------------------------------------------------------
+
+// Gesture ID (see `FT3168_GESTURE_xxx`)
+#define FT3168_REG_GEST_ID 0x01
+
+// TD_STATUS (number of touch points in lower 4 bits)
+#define FT3168_REG_TD_STATUS 0x02
+
+// Event flags in higher 2 bits (see `FT3168_EVENT_xxx`)
+// MSB of touch x-coordinate in lower 4 bits
+#define FT3168_REG_P1_XH 0x03
+
+// LSB of touch x-coordinate
+#define FT3168_REG_P1_XL 0x04
+
+// MSB of touch y-coordinate in lower 4 bits
+#define FT3168_REG_P1_YH 0x05
+
+// LSB of touch y-coordinate
+#define FT3168_REG_P1_YL 0x06
+
+// Threshold for touch detection
+#define FT3168_REG_TH_GROUP 0x80
+
+// Mode register
+// 0x00 - interrupt polling mode
+// 0x01 - interrupt trigger mode
+#define FT3168_REG_G_MODE 0xA4
+
+// Firmware version
+#define FT3168_REG_FIRMID 0xA6
+
+// ------------------------------------------------------------
+// Event bits (see FT3168_REG_P1_XH)
+// ------------------------------------------------------------
+
+#define FT3168_EVENT_PRESS_DOWN 0x00
+#define FT3168_EVENT_CONTACT 0x80
+#define FT3168_EVENT_LIFT_UP 0x40
+#define FT3168_EVENT_MASK 0xC0
+
+// ------------------------------------------------------------
+// Gesture types (see FT3168_REG_GEST_ID)
+// ------------------------------------------------------------
+
+#define FT3168_GESTURE_NONE 0x00
diff --git a/core/embed/io/touch/ft3168/panels/lx250a2410a.c b/core/embed/io/touch/ft3168/panels/lx250a2410a.c
new file mode 100644
index 000000000..4b77c7b0e
--- /dev/null
+++ b/core/embed/io/touch/ft3168/panels/lx250a2410a.c
@@ -0,0 +1,30 @@
+
+/*
+ * 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/>.
+ */
+
+#include <trezor_rtl.h>
+
+#include "lx250a2410a.h"
+
+void lx250a2410a_touch_correction(uint16_t x, uint16_t y, uint16_t *x_new,
+ uint16_t *y_new) {
+ // This panel may report coordinates outside the display area
+ *x_new = MIN(x, DISPLAY_RESX - 1);
+ *y_new = MIN(y, DISPLAY_RESY - 1);
+}
diff --git a/core/embed/io/touch/ft3168/panels/lx250a2410a.h b/core/embed/io/touch/ft3168/panels/lx250a2410a.h
new file mode 100644
index 000000000..e6ec2aa93
--- /dev/null
+++ b/core/embed/io/touch/ft3168/panels/lx250a2410a.h
@@ -0,0 +1,28 @@
+/*
+ * 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
+
+#include <trezor_types.h>
+
+// Performs touch coordinates correction needed for a specific panel.
+// Input parameters x, y represent the original touch coordinates.
+// Output parameters x_new, y_new represent the corrected touch coordinates.
+void lx250a2410a_touch_correction(uint16_t x, uint16_t y, uint16_t *x_new,
+ uint16_t *y_new);
diff --git a/core/embed/io/touch/ft6x36/ft6x36.c b/core/embed/io/touch/ft6x36/ft6x36.c
index 07b929d40..f7b86c92b 100644
--- a/core/embed/io/touch/ft6x36/ft6x36.c
+++ b/core/embed/io/touch/ft6x36/ft6x36.c
@@ -31,8 +31,6 @@
#include "panels/lx154a2422cpt23.h"
#elif defined TOUCH_PANEL_LHS200KB_IF21
#include "panels/lhs200kb-if21.h"
-#elif defined TOUCH_PANEL_LX250A2410A
-#include "panels/lx250a2410a.h"
#endif
#include "../touch_poll.h"
@@ -125,27 +123,6 @@ static secbool ft6x36_write_reg(i2c_bus_t* bus, uint8_t reg, uint8_t value) {
return sectrue;
}
-// Wake up the touch controller from monitor mode.
-//
-// The FT3168 touch controller switches from active mode to monitor mode
-// after a period of inactivity (the default setting is ~12s).
-// This feature cannot be disabled (at least in the current controller
-// firmware). When in this mode, it fails to respond to the first I2C command —
-// writes are not ACKed, and reads return 0x00 or garbage data.
-// To avoid this issue, we need to wake up the controller before
-// sending any commands to it.
-static void ft6x36_wake_up(i2c_bus_t* bus) {
-#ifdef TOUCH_WAKEUP_WORKAROUND
- uint8_t temp;
- // Wake up the touch controller by reading one of its registers
- // (the specific register does not matter)
- ft6x36_read_regs(bus, 0x00, &temp, 1);
- // Wait for the touch controller to wake up
- // (not sure if this is necessary, but it's safer to include it)
- systick_delay_ms(1);
-#endif
-}
-
// Powers down the touch controller and puts all
// the pins in the proper state to save power.
static void ft6x36_power_down(void) {
@@ -277,8 +254,6 @@ static void ft6x36_panel_correction(uint16_t x, uint16_t y, uint16_t* x_new,
lx154a2422cpt23_touch_correction(x, y, x_new, y_new);
#elif defined TOUCH_PANEL_LHS200KB_IF21
lhs200kb_if21_touch_correction(x, y, x_new, y_new);
-#elif defined TOUCH_PANEL_LX250A2410A
- lx250a2410a_touch_correction(x, y, x_new, y_new);
#else
*x_new = x;
*y_new = y;
@@ -307,8 +282,6 @@ secbool touch_init(void) {
goto cleanup;
}
- ft6x36_wake_up(driver->i2c_bus);
-
// Configure the touch controller
if (sectrue != ft6x36_configure(driver->i2c_bus)) {
goto cleanup;
@@ -366,7 +339,6 @@ secbool touch_set_sensitivity(uint8_t value) {
touch_driver_t* driver = &g_touch_driver;
if (sectrue == driver->initialized) {
- ft6x36_wake_up(driver->i2c_bus);
return ft6x36_write_reg(driver->i2c_bus, FT6X36_REG_TH_GROUP, value);
} else {
return secfalse;
@@ -388,8 +360,6 @@ uint8_t touch_get_version(void) {
systick_delay_ms(1);
}
- ft6x36_wake_up(driver->i2c_bus);
-
uint8_t fw_version = 0;
if (sectrue !=
diff --git a/core/embed/io/touch/ft6x36/panels/lx250a2410a.c b/core/embed/io/touch/ft6x36/panels/lx250a2410a.c
deleted file mode 100644
index 4b77c7b0e..000000000
--- a/core/embed/io/touch/ft6x36/panels/lx250a2410a.c
+++ /dev/null
@@ -1,30 +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/>.
- */
-
-#include <trezor_rtl.h>
-
-#include "lx250a2410a.h"
-
-void lx250a2410a_touch_correction(uint16_t x, uint16_t y, uint16_t *x_new,
- uint16_t *y_new) {
- // This panel may report coordinates outside the display area
- *x_new = MIN(x, DISPLAY_RESX - 1);
- *y_new = MIN(y, DISPLAY_RESY - 1);
-}
diff --git a/core/embed/io/touch/ft6x36/panels/lx250a2410a.h b/core/embed/io/touch/ft6x36/panels/lx250a2410a.h
deleted file mode 100644
index e6ec2aa93..000000000
--- a/core/embed/io/touch/ft6x36/panels/lx250a2410a.h
+++ /dev/null
@@ -1,28 +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
-
-#include <trezor_types.h>
-
-// Performs touch coordinates correction needed for a specific panel.
-// Input parameters x, y represent the original touch coordinates.
-// Output parameters x_new, y_new represent the corrected touch coordinates.
-void lx250a2410a_touch_correction(uint16_t x, uint16_t y, uint16_t *x_new,
- uint16_t *y_new);
diff --git a/core/embed/models/T3W1/boards/trezor_t3w1_revA.h b/core/embed/models/T3W1/boards/trezor_t3w1_revA.h
index 33b31b402..8d156c1cf 100644
--- a/core/embed/models/T3W1/boards/trezor_t3w1_revA.h
+++ b/core/embed/models/T3W1/boards/trezor_t3w1_revA.h
@@ -127,7 +127,6 @@
#define TOUCH_PANEL_LX250A2410A 1
#define TOUCH_SENSITIVITY 0x40
-#define TOUCH_WAKEUP_WORKAROUND 1
#define TOUCH_I2C_INSTANCE 2
#define TOUCH_INT_PORT GPIOC
#define TOUCH_INT_PIN GPIO_PIN_3
diff --git a/core/embed/models/T3W1/boards/trezor_t3w1_revB.h b/core/embed/models/T3W1/boards/trezor_t3w1_revB.h
index f4058bc46..f78d1f377 100644
--- a/core/embed/models/T3W1/boards/trezor_t3w1_revB.h
+++ b/core/embed/models/T3W1/boards/trezor_t3w1_revB.h
@@ -127,7 +127,6 @@
#define TOUCH_PANEL_LX250A2410A 1
#define TOUCH_SENSITIVITY 0x40
-#define TOUCH_WAKEUP_WORKAROUND 1
#define TOUCH_I2C_INSTANCE 2
#define TOUCH_INT_PORT GPIOC
#define TOUCH_INT_PIN GPIO_PIN_3
diff --git a/core/embed/models/T3W1/boards/trezor_t3w1_revC.h b/core/embed/models/T3W1/boards/trezor_t3w1_revC.h
index 6f903f161..854fd3f91 100644
--- a/core/embed/models/T3W1/boards/trezor_t3w1_revC.h
+++ b/core/embed/models/T3W1/boards/trezor_t3w1_revC.h
@@ -145,7 +145,6 @@
#define TOUCH_PANEL_LX250A2410A 1
#define TOUCH_SENSITIVITY 0x40
-#define TOUCH_WAKEUP_WORKAROUND 1
#define TOUCH_I2C_INSTANCE 4
#define TOUCH_INT_PORT GPIOC
#define TOUCH_INT_PIN GPIO_PIN_3
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revA.py b/core/site_scons/models/T3W1/trezor_t3w1_revA.py
index 8f62ad875..ccd1ce75d 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revA.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revA.py
@@ -84,8 +84,8 @@ def configure(
paths += ["embed/io/backlight/inc"]
if "input" in features_wanted:
- sources += ["embed/io/touch/ft6x36/ft6x36.c"]
- sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
+ sources += ["embed/io/touch/ft3168/ft3168.c"]
+ sources += ["embed/io/touch/ft3168/panels/lx250a2410a.c"]
sources += ["embed/io/touch/touch_poll.c"]
paths += ["embed/io/touch/inc"]
features_available.append("touch")
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revB.py b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
index 2f9c3f298..df61ce317 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revB.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
@@ -84,8 +84,8 @@ def configure(
paths += ["embed/io/backlight/inc"]
if "input" in features_wanted:
- sources += ["embed/io/touch/ft6x36/ft6x36.c"]
- sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
+ sources += ["embed/io/touch/ft3168/ft3168.c"]
+ sources += ["embed/io/touch/ft3168/panels/lx250a2410a.c"]
sources += ["embed/io/touch/touch_poll.c"]
paths += ["embed/io/touch/inc"]
features_available.append("touch")
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
index 4193e0336..958da9b10 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
@@ -84,8 +84,8 @@ def configure(
paths += ["embed/io/backlight/inc"]
if "input" in features_wanted:
- sources += ["embed/io/touch/ft6x36/ft6x36.c"]
- sources += ["embed/io/touch/ft6x36/panels/lx250a2410a.c"]
+ sources += ["embed/io/touch/ft3168/ft3168.c"]
+ sources += ["embed/io/touch/ft3168/panels/lx250a2410a.c"]
sources += ["embed/io/touch/touch_poll.c"]
paths += ["embed/io/touch/inc"]
features_available.append("touch")
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.