diff --git a/core/embed/prodtest/README.md b/core/embed/prodtest/README.md index 686efa49a..b12c6a443 100644 --- a/core/embed/prodtest/README.md +++ b/core/embed/prodtest/README.md @@ -118,6 +118,16 @@ Example: SENS 12 ``` +### TOUCH VERSION +Allows you to read the version of the touch screen controller, if its supported by the device. +The command returns `OK` followed by the version number. + +Example: +``` +TOUCH VERSION +OK 167 +``` + ### PWM The `PWM` command sets the display backlight using PWM (Pulse Width Modulation). This command takes one input parameter, a decimal value between 0 to 255, and adjusts the PWM output to control the display LED backlight. @@ -205,6 +215,15 @@ Example (to write 8 bytes into OTP memory): VARIANT 128 64 100 1 2 3 0 0 ``` +### VARIANT READ +The `VARIANT READ` command allows you to read 32 bytes of stored variant data (representing device variant options), each ranging from 0 to 255, and delimited by spaces. + +Example: +``` +VARIANT READ +OK 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +``` + ### WIPE This command invalidates the current firmware in the flash memory by erasing its beginning, including metadata. After performing this operation, it displays the text "WIPED" on the screen and returns the response OK. diff --git a/core/embed/prodtest/main.c b/core/embed/prodtest/main.c index d042719b2..71a822c99 100644 --- a/core/embed/prodtest/main.c +++ b/core/embed/prodtest/main.c @@ -387,6 +387,11 @@ static void test_sensitivity(const char *args) { touch_power_off(); } + +static void touch_version(void) { + uint8_t version = touch_get_version(); + vcp_println("OK %d", version); +} #endif static void test_pwm(const char *args) { @@ -523,6 +528,21 @@ static void test_otp_write(const char *args) { vcp_println("OK"); } +static void test_otp_read_device_variant() { + uint8_t data[32] = {0}; + if (sectrue != + flash_otp_read(FLASH_OTP_BLOCK_DEVICE_VARIANT, 0, data, sizeof(data))) { + vcp_println("ERROR"); + return; + } + + vcp_print("OK "); + for (int i = 0; i < sizeof(data); i++) { + vcp_print("%d ", data[i]); + } + vcp_println(""); +} + static void test_otp_write_device_variant(const char *args) { #ifdef USE_OPTIGA optiga_locked_status status = get_optiga_locked_status(); @@ -663,11 +683,15 @@ int main(void) { test_button(line + 7); #endif #ifdef USE_TOUCH + } else if (startswith(line, "TOUCH VERSION")) { + touch_version(); + } else if (startswith(line, "TOUCH ")) { test_touch(line + 6); } else if (startswith(line, "SENS ")) { test_sensitivity(line + 5); + #endif } else if (startswith(line, "PWM ")) { test_pwm(line + 4); @@ -715,6 +739,9 @@ int main(void) { } else if (startswith(line, "OTP WRITE ")) { test_otp_write(line + 10); + } else if (startswith(line, "VARIANT READ")) { + test_otp_read_device_variant(); + } else if (startswith(line, "VARIANT ")) { test_otp_write_device_variant(line + 8); diff --git a/core/embed/trezorhal/stm32f4/touch/ft6x36.c b/core/embed/trezorhal/stm32f4/touch/ft6x36.c index e285d062a..439dd16aa 100644 --- a/core/embed/trezorhal/stm32f4/touch/ft6x36.c +++ b/core/embed/trezorhal/stm32f4/touch/ft6x36.c @@ -275,3 +275,21 @@ uint32_t touch_read(void) { return 0; } + +uint8_t touch_get_version(void) { + uint8_t version = 0; + uint8_t outgoing[] = {0xA6}; // start reading from address 0xA6 + int result = i2c_transmit(TOUCH_I2C_INSTANCE, TOUCH_ADDRESS, outgoing, + sizeof(outgoing), 1); + if (result != HAL_OK) { + if (result == HAL_BUSY) i2c_cycle(TOUCH_I2C_INSTANCE); + return 0; + } + + if (HAL_OK != i2c_receive(TOUCH_I2C_INSTANCE, TOUCH_ADDRESS, &version, + sizeof(version), 1)) { + return 0; // read failure + } + + return version; +} diff --git a/core/embed/trezorhal/stm32f4/touch/stmpe811.c b/core/embed/trezorhal/stm32f4/touch/stmpe811.c index 6a08cc490..4a503b1ec 100644 --- a/core/embed/trezorhal/stm32f4/touch/stmpe811.c +++ b/core/embed/trezorhal/stm32f4/touch/stmpe811.c @@ -704,3 +704,5 @@ uint32_t touch_read(void) { } void touch_wait_until_ready(void) {} + +uint8_t touch_get_version(void) { return 0; } diff --git a/core/embed/trezorhal/stm32u5/touch/sitronix.c b/core/embed/trezorhal/stm32u5/touch/sitronix.c index d63524f2d..d097cc9ca 100644 --- a/core/embed/trezorhal/stm32u5/touch/sitronix.c +++ b/core/embed/trezorhal/stm32u5/touch/sitronix.c @@ -1216,3 +1216,5 @@ uint32_t touch_read(void) { } void touch_wait_until_ready(void) {} + +uint8_t touch_get_version(void) { return 0; } diff --git a/core/embed/trezorhal/touch.h b/core/embed/trezorhal/touch.h index 2f37f442d..decfa212d 100644 --- a/core/embed/trezorhal/touch.h +++ b/core/embed/trezorhal/touch.h @@ -17,6 +17,7 @@ secbool touch_sensitivity(uint8_t value); uint32_t touch_read(void); uint32_t touch_click(void); uint32_t touch_is_detected(void); +uint8_t touch_get_version(void); static inline uint16_t touch_unpack_x(uint32_t evt) { return (evt >> 12) & 0xFFF; diff --git a/core/embed/trezorhal/unix/touch/touch.c b/core/embed/trezorhal/unix/touch/touch.c index a5d18132f..be60d8690 100644 --- a/core/embed/trezorhal/unix/touch/touch.c +++ b/core/embed/trezorhal/unix/touch/touch.c @@ -225,6 +225,8 @@ uint32_t touch_is_detected(void) { return input_state == MOUSE_DOWN_INSIDE || is_button_swipe_initiated(); } +uint8_t touch_get_version(void) { return 0; } + #endif #ifdef USE_BUTTON