From a71a608ea7514ff3ca48a87f36d18806f0cda6f2 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Thu, 24 Aug 2023 11:33:50 +0200 Subject: [PATCH] feat(core): add basic support for T3T1 --- core/Makefile | 10 ++ core/SConscript.bootloader | 6 +- core/SConscript.bootloader_ci | 2 +- core/SConscript.bootloader_emu | 6 +- core/SConscript.firmware | 7 +- core/SConscript.prodtest | 2 +- core/SConscript.reflash | 2 +- core/SConscript.unix | 14 +- .../firmware/bootloaders/bootloader_T3T1.bin | Bin 0 -> 111104 bytes core/embed/firmware/memory_T3T1.ld | 122 ++++++++++++++++++ core/embed/models/model.h | 2 + core/embed/models/model_T3T1.h | 33 +++++ core/embed/models/model_T3T1_layout.c | 84 ++++++++++++ core/embed/prodtest/main.c | 4 +- core/embed/trezorhal/boards/board-unix.h | 7 + core/embed/trezorhal/boards/trezor_t3t1_v4.h | 83 ++++++++++++ core/embed/trezorhal/stm32u5/backlight_pwm.c | 1 + core/embed/trezorhal/stm32u5/backlight_pwm.h | 1 + .../stm32u5/displays/panels/lx154a2422.c | 1 + .../stm32u5/displays/panels/lx154a2422.h | 1 + .../trezorhal/stm32u5/displays/st7789v.c | 1 + .../trezorhal/stm32u5/displays/st7789v.h | 1 + .../trezorhal/stm32u5/stm32u5xx_hal_conf.h | 4 +- core/embed/trezorhal/stm32u5/touch/ft6x36.c | 1 + core/embed/trezorhal/stm32u5/touch/ft6x36.h | 1 + .../T3T1/vendor_dev_DO_NOT_SIGN.json | 20 +++ .../T3T1/vendor_dev_DO_NOT_SIGN.toif | Bin 0 -> 4222 bytes .../vendorheader/T3T1/vendor_unsafe.json | 20 +++ .../vendorheader/T3T1/vendor_unsafe.toif | Bin 0 -> 3942 bytes ...endorheader_dev_DO_NOT_SIGN_signed_dev.bin | Bin 0 -> 4608 bytes .../vendorheader_dev_DO_NOT_SIGN_unsigned.bin | Bin 0 -> 4608 bytes .../T3T1/vendorheader_unsafe_signed_dev.bin | Bin 0 -> 4608 bytes .../T3T1/vendorheader_unsafe_signed_prod.bin | Bin 0 -> 4608 bytes .../T3T1/vendorheader_unsafe_unsigned.bin | Bin 0 -> 4608 bytes core/embed/vendorheader/generate.sh | 2 +- core/site_scons/boards/trezor_t3t1_v4.py | 94 ++++++++++++++ core/site_scons/tools.py | 5 + python/.changelog.d/3422.added | 1 + python/src/trezorlib/firmware/models.py | 28 ++++ python/src/trezorlib/models.py | 12 +- 40 files changed, 554 insertions(+), 24 deletions(-) create mode 100644 core/embed/firmware/bootloaders/bootloader_T3T1.bin create mode 100644 core/embed/firmware/memory_T3T1.ld create mode 100644 core/embed/models/model_T3T1.h create mode 100644 core/embed/models/model_T3T1_layout.c create mode 120000 core/embed/trezorhal/stm32u5/backlight_pwm.c create mode 120000 core/embed/trezorhal/stm32u5/backlight_pwm.h create mode 120000 core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.c create mode 120000 core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.h create mode 120000 core/embed/trezorhal/stm32u5/displays/st7789v.c create mode 120000 core/embed/trezorhal/stm32u5/displays/st7789v.h create mode 120000 core/embed/trezorhal/stm32u5/touch/ft6x36.c create mode 120000 core/embed/trezorhal/stm32u5/touch/ft6x36.h create mode 100644 core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json create mode 100644 core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.toif create mode 100644 core/embed/vendorheader/T3T1/vendor_unsafe.json create mode 100644 core/embed/vendorheader/T3T1/vendor_unsafe.toif create mode 100644 core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin create mode 100644 core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_unsigned.bin create mode 100644 core/embed/vendorheader/T3T1/vendorheader_unsafe_signed_dev.bin create mode 100644 core/embed/vendorheader/T3T1/vendorheader_unsafe_signed_prod.bin create mode 100644 core/embed/vendorheader/T3T1/vendorheader_unsafe_unsigned.bin create mode 100644 core/site_scons/boards/trezor_t3t1_v4.py create mode 100644 python/.changelog.d/3422.added diff --git a/core/Makefile b/core/Makefile index 06b3d0e98..9c270b347 100644 --- a/core/Makefile +++ b/core/Makefile @@ -55,6 +55,16 @@ BOOTLOADER_MAXSIZE = 131072 FIRMWARE_P1_MAXSIZE = 786432 FIRMWARE_P2_MAXSIZE = 917504 FIRMWARE_MAXSIZE = 1703936 +else ifeq ($(TREZOR_MODEL),$(filter $(TREZOR_MODEL),T3T1)) +OPENOCD_TARGET = target/stm32u5x.cfg +BOARDLOADER_START = 0x0C004000 +BOARDLOADER_END = 0x0C010000 +BOOTLOADER_START = 0x0C010000 +FIRMWARE_START = 0x0C050000 +PRODTEST_START = 0x0C050000 +BOARDLOADER_MAXSIZE = 49152 +BOOTLOADER_MAXSIZE = 131072 +FIRMWARE_MAXSIZE = 1703936 else ifeq ($(TREZOR_MODEL),$(filter $(TREZOR_MODEL),DISC2)) OPENOCD_TARGET = target/stm32u5x.cfg BOARDLOADER_START = 0x0C004000 diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader index a20cc2ea0..d55a22c1a 100644 --- a/core/SConscript.bootloader +++ b/core/SConscript.bootloader @@ -36,11 +36,11 @@ if TREZOR_MODEL in ('R', ): FONT_BOLD='Font_PixelOperator_Bold_8' FONT_MONO='Font_PixelOperator_Regular_8' FONT_BIG=None -elif TREZOR_MODEL in ('T', 'DISC1', 'DISC2'): +elif TREZOR_MODEL in ('T', 'T3T1', 'DISC1', 'DISC2'): FONT_NORMAL='Font_TTHoves_Regular_21' - FONT_DEMIBOLD=None + FONT_DEMIBOLD='Font_TTHoves_Regular_21' FONT_BOLD='Font_TTHoves_Bold_17' - FONT_MONO=None + FONT_MONO='Font_TTHoves_Regular_21' FONT_BIG=None # modtrezorcrypto diff --git a/core/SConscript.bootloader_ci b/core/SConscript.bootloader_ci index a01d88300..277d9a09e 100644 --- a/core/SConscript.bootloader_ci +++ b/core/SConscript.bootloader_ci @@ -34,7 +34,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_BOLD=None FONT_MONO='Font_PixelOperatorMono_Regular_8' FONT_BIG=None -elif TREZOR_MODEL in ('T', ): +elif TREZOR_MODEL in ('T', 'T3T1'): FONT_NORMAL='Font_Roboto_Regular_20' FONT_DEMIBOLD=None FONT_BOLD=None diff --git a/core/SConscript.bootloader_emu b/core/SConscript.bootloader_emu index 7a9e6eb11..5ff96facd 100644 --- a/core/SConscript.bootloader_emu +++ b/core/SConscript.bootloader_emu @@ -33,7 +33,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_BOLD='Font_PixelOperator_Bold_8' FONT_MONO='Font_PixelOperator_Regular_8' FONT_BIG=None -elif TREZOR_MODEL in ('T', 'DISC2'): +elif TREZOR_MODEL in ('T', 'T3T1', 'DISC2'): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD=None FONT_BOLD='Font_TTHoves_Bold_17' @@ -173,6 +173,8 @@ env.Replace( if TREZOR_MODEL in ('T', 'R'): CPU_MODEL = 'STM32F427xx' +elif TREZOR_MODEL in ('T3T1', ): + CPU_MODEL = 'STM32U585xx' elif TREZOR_MODEL in ('DISC1', ): CPU_MODEL = 'STM32F429xx' elif TREZOR_MODEL in ('DISC2', ): @@ -265,7 +267,7 @@ def cargo_build(): else: features = ["model_tt"] - if TREZOR_MODEL in ('T',): + if TREZOR_MODEL in ('T', 'T3T1'): features.append('touch') features.append('backlight') if TREZOR_MODEL in ('R', '1'): diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 3fb23cb93..6c6612574 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -41,7 +41,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_BOLD='Font_PixelOperator_Bold_8' FONT_MONO='Font_PixelOperatorMono_Regular_8' FONT_BIG='Font_Unifont_Regular_16' -elif TREZOR_MODEL in ('T', 'DISC1', 'DISC2'): +elif TREZOR_MODEL in ('T', 'T3T1', 'DISC1', 'DISC2'): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD='Font_TTHoves_DemiBold_21' FONT_BOLD='Font_TTHoves_Bold_17' @@ -392,7 +392,7 @@ SOURCE_FIRMWARE = [ ] -if TREZOR_MODEL in ('T', 'DISC1', 'DISC2'): +if TREZOR_MODEL in ('T', 'T3T1', 'DISC1', 'DISC2'): UI_LAYOUT = 'UI_LAYOUT_TT' ui_layout_feature = 'model_tt' elif TREZOR_MODEL in ('1', 'R'): @@ -839,8 +839,7 @@ BINARY_NAME += "-dirty" if tools.get_git_modified() else "" BINARY_NAME += ".bin" - -if TREZOR_MODEL in ('1',): +if TREZOR_MODEL in ('1'): action_bin=[ '$OBJCOPY -O binary -j .header -j .flash -j .data -j .sensitive $SOURCE $TARGET', '../legacy/bootloader/firmware_sign.py -f $TARGET', diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest index 0cd576290..11ec63e5b 100644 --- a/core/SConscript.prodtest +++ b/core/SConscript.prodtest @@ -38,7 +38,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_BOLD='Font_PixelOperator_Bold_8' FONT_MONO=None FONT_BIG=None -elif TREZOR_MODEL in ('T', ): +elif TREZOR_MODEL in ('T', 'T3T1'): FONT_NORMAL=None FONT_DEMIBOLD=None FONT_BOLD='Font_Roboto_Bold_20' diff --git a/core/SConscript.reflash b/core/SConscript.reflash index 5fc8605fa..43aedb734 100644 --- a/core/SConscript.reflash +++ b/core/SConscript.reflash @@ -33,7 +33,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_BOLD='Font_PixelOperator_Bold_8' FONT_MONO=None FONT_BIG=None -elif TREZOR_MODEL in ('T', ): +elif TREZOR_MODEL in ('T', 'T3T1'): FONT_NORMAL=None FONT_DEMIBOLD=None FONT_BOLD='Font_Roboto_Bold_20' diff --git a/core/SConscript.unix b/core/SConscript.unix index 07ddb578e..3a93dbc74 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -7,7 +7,7 @@ import tools BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0') EVERYTHING = BITCOIN_ONLY != '1' TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') -DMA2D = TREZOR_MODEL in ('T', ) +DMA2D = TREZOR_MODEL in ('T', 'T3T1') CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) if TREZOR_MODEL in ('DISC1', 'DISC2'): @@ -42,7 +42,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_BOLD='Font_PixelOperator_Bold_8' FONT_MONO='Font_PixelOperatorMono_Regular_8' FONT_BIG='Font_Unifont_Regular_16' -elif TREZOR_MODEL in ('T', 'DISC2'): +elif TREZOR_MODEL in ('T', 'T3T1'): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD='Font_TTHoves_DemiBold_21' FONT_BOLD='Font_TTHoves_Bold_17' @@ -177,7 +177,7 @@ if FEATURE_FLAGS["SECP256K1_ZKP"]: SOURCE_MOD += [ 'embed/extmod/modtrezorio/modtrezorio.c', ] -if TREZOR_MODEL in ('T',): +if TREZOR_MODEL in ('T', 'T3T1'): SOURCE_MOD += [ 'embed/extmod/modtrezorio/ff.c', 'embed/extmod/modtrezorio/ffunicode.c', @@ -393,7 +393,7 @@ SOURCE_UNIX = [ 'vendor/micropython/ports/unix/input.c', 'vendor/micropython/ports/unix/unix_mphal.c', ] -if TREZOR_MODEL in ('T', 'R'): +if TREZOR_MODEL in ('T', 'R', 'T3T1'): SOURCE_UNIX += [ 'embed/trezorhal/unix/sbu.c', ] @@ -430,7 +430,7 @@ else: env = Environment(ENV=os.environ, CFLAGS='%s -DPYOPT=%s -DBITCOIN_ONLY=%s %s' % (ARGUMENTS.get('CFLAGS', ''), PYOPT, BITCOIN_ONLY, STATIC)) -if TREZOR_MODEL in ('T',): +if TREZOR_MODEL in ('T', 'T3T1'): UI_LAYOUT = 'UI_LAYOUT_TT' ui_layout_feature = 'model_tt' elif TREZOR_MODEL in ('1', 'R'): @@ -497,6 +497,8 @@ env.Replace( if TREZOR_MODEL in ('T', 'R'): CPU_MODEL = 'STM32F427xx' +elif TREZOR_MODEL in ('T3T1', ): + CPU_MODEL = 'STM32U585xx' elif TREZOR_MODEL in ('DISC1', ): CPU_MODEL = 'STM32F429xx' elif TREZOR_MODEL in ('DISC2', ): @@ -810,7 +812,7 @@ def cargo_build(): if DMA2D: features.append('dma2d') - if TREZOR_MODEL in ('T',): + if TREZOR_MODEL in ('T', 'T3T1'): features.append('touch') features.append('sd_card') if TREZOR_MODEL in ('R', '1'): diff --git a/core/embed/firmware/bootloaders/bootloader_T3T1.bin b/core/embed/firmware/bootloaders/bootloader_T3T1.bin new file mode 100644 index 0000000000000000000000000000000000000000..304db439e28d883dce88742835c57cbd9cff3ddb GIT binary patch literal 111104 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%0DrR{3 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 AT>FLASH + + .header : ALIGN(4) { + KEEP(*(.header)); + } >FLASH AT>FLASH + + .flash : ALIGN(512) { + KEEP(*(.vector_table)); + . = ALIGN(4); + *(.text*); + . = ALIGN(4); + *(.rodata*); + . = ALIGN(4); + KEEP(*(.bootloader)); + *(.bootloader*); + . = ALIGN(512); + } >FLASH AT>FLASH + + .data : ALIGN(4) { + *(.data*); + . = ALIGN(512); + } >SRAM1 AT>FLASH + + /DISCARD/ : { + *(.ARM.exidx*); + } + + .bss : ALIGN(4) { + *(.bss*); + . = ALIGN(4); + } >SRAM1 + + .buf : ALIGN(4) { + *(.buf*); + . = ALIGN(4); + } >SRAM1 + + .stack : ALIGN(8) { + . = 16K; /* Overflow causes UsageFault */ + } >SRAM2 + + .sensitive : ALIGN(512) { + *(.sensitive*); + . = ALIGN(512); + } >SRAM2 AT>FLASH + + .fb : ALIGN(4) { + __fb_start = .; + *(.fb1*); + *(.fb2*); + __fb_end = .; + . = ALIGN(4); + } >SRAM3 + + .heap : ALIGN(4) { + . = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */ + . = ABSOLUTE(sram3_end); /* this explicitly sets the end of the heap */ + } >SRAM3 + + .boot_args : ALIGN(8) { + *(.boot_command*); + . = ALIGN(8); + *(.boot_args*); + . = ALIGN(8); + } >BOOT_ARGS +} diff --git a/core/embed/models/model.h b/core/embed/models/model.h index 1d1bbb1bc..1b98b8a81 100644 --- a/core/embed/models/model.h +++ b/core/embed/models/model.h @@ -9,6 +9,8 @@ #include "model_T2T1.h" #elif defined TREZOR_MODEL_R #include "model_T2B1.h" +#elif defined TREZOR_MODEL_T3T1 +#include "model_T3T1.h" #elif defined TREZOR_MODEL_DISC1 #include "model_D001.h" #elif defined TREZOR_MODEL_DISC2 diff --git a/core/embed/models/model_T3T1.h b/core/embed/models/model_T3T1.h new file mode 100644 index 000000000..0091f3628 --- /dev/null +++ b/core/embed/models/model_T3T1.h @@ -0,0 +1,33 @@ +#ifndef MODELS_MODEL_T3T1_H_ +#define MODELS_MODEL_T3T1_H_ + +#include "sizedefs.h" + +#define MODEL_NAME "T3T1" +#define MODEL_FULL_NAME "Trezor T3T1" +#define MODEL_INTERNAL_NAME "T3T1" +#define MODEL_INTERNAL_NAME_TOKEN T3T1 +#define MODEL_INTERNAL_NAME_QSTR MP_QSTR_T3T1 + +/*** Using DEV KEYS temporarily ***/ +#define MODEL_BOARDLOADER_KEYS \ + (const uint8_t *)"\xdb\x99\x5f\xe2\x51\x69\xd1\x41\xca\xb9\xbb\xba\x92\xba\xa0\x1f\x9f\x2e\x1e\xce\x7d\xf4\xcb\x2a\xc0\x51\x90\xf3\x7f\xcc\x1f\x9d", \ + (const uint8_t *)"\x21\x52\xf8\xd1\x9b\x79\x1d\x24\x45\x32\x42\xe1\x5f\x2e\xab\x6c\xb7\xcf\xfa\x7b\x6a\x5e\xd3\x00\x97\x96\x0e\x06\x98\x81\xdb\x12", \ + (const uint8_t *)"\x22\xfc\x29\x77\x92\xf0\xb6\xff\xc0\xbf\xcf\xdb\x7e\xdb\x0c\x0a\xa1\x4e\x02\x5a\x36\x5e\xc0\xe3\x42\xe8\x6e\x38\x29\xcb\x74\xb6", + +#define MODEL_BOOTLOADER_KEYS \ + (const uint8_t *)"\xd7\x59\x79\x3b\xbc\x13\xa2\x81\x9a\x82\x7c\x76\xad\xb6\xfb\xa8\xa4\x9a\xee\x00\x7f\x49\xf2\xd0\x99\x2d\x99\xb8\x25\xad\x2c\x48", \ + (const uint8_t *)"\x63\x55\x69\x1c\x17\x8a\x8f\xf9\x10\x07\xa7\x47\x8a\xfb\x95\x5e\xf7\x35\x2c\x63\xe7\xb2\x57\x03\x98\x4c\xf7\x8b\x26\xe2\x1a\x56", \ + (const uint8_t *)"\xee\x93\xa4\xf6\x6f\x8d\x16\xb8\x19\xbb\x9b\xeb\x9f\xfc\xcd\xfc\xdc\x14\x12\xe8\x7f\xee\x6a\x32\x4c\x2a\x99\xa1\xe0\xe6\x71\x48", + +#define BOARDLOADER_START 0x0C004000 +#define BOARD_CAPABILITIES_ADDR 0x0C00FF00 +#define BOOTLOADER_START 0x0C010000 +#define FIRMWARE_START 0x0C050000 + +#define IMAGE_CHUNK_SIZE (128 * 1024) +#define BOOTLOADER_IMAGE_MAXSIZE (128 * 1024 * 1) // 128 KB +#define FIRMWARE_IMAGE_MAXSIZE (128 * 1024 * 13) // 1664 KB +#define NORCOW_SECTOR_SIZE (64 * 1024) + +#endif diff --git a/core/embed/models/model_T3T1_layout.c b/core/embed/models/model_T3T1_layout.c new file mode 100644 index 000000000..d3565576d --- /dev/null +++ b/core/embed/models/model_T3T1_layout.c @@ -0,0 +1,84 @@ +#include "flash.h" +#include "model.h" + +const flash_area_t STORAGE_AREAS[STORAGE_AREAS_COUNT] = { + { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0x18, + .num_sectors = 8, + }, + }, + { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0x20, + .num_sectors = 8, + }, + }, +}; + +const flash_area_t BOARDLOADER_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 2, + .num_sectors = 6, + }, +}; + +const flash_area_t BOOTLOADER_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0x08, + .num_sectors = 16, + }, +}; + +const flash_area_t FIRMWARE_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0x28, + .num_sectors = 208, + }, +}; + +const flash_area_t SECRET_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0, + .num_sectors = 2, + }, +}; + +const flash_area_t BHK_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 1, + .num_sectors = 1, + }, +}; + +const flash_area_t WIPE_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0x18, + .num_sectors = 232, + }, +}; + +const flash_area_t ALL_WIPE_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0x08, + .num_sectors = 248, + }, +}; diff --git a/core/embed/prodtest/main.c b/core/embed/prodtest/main.c index 25b68ac79..f4f00d385 100644 --- a/core/embed/prodtest/main.c +++ b/core/embed/prodtest/main.c @@ -53,8 +53,8 @@ #ifdef TREZOR_MODEL_T #define MODEL_IDENTIFIER "TREZOR2-" -#elif TREZOR_MODEL_R -#define MODEL_IDENTIFIER "T2B1-" +#else +#define MODEL_IDENTIFIER MODEL_INTERNAL_NAME "-" #endif static secbool startswith(const char *s, const char *prefix) { diff --git a/core/embed/trezorhal/boards/board-unix.h b/core/embed/trezorhal/boards/board-unix.h index ec16dd4ad..bdc7acf73 100644 --- a/core/embed/trezorhal/boards/board-unix.h +++ b/core/embed/trezorhal/boards/board-unix.h @@ -9,6 +9,13 @@ #define USE_BACKLIGHT 1 #endif +#ifdef TREZOR_MODEL_T3T1 +#define USE_TOUCH 1 +#define USE_SD_CARD 1 +#define USE_SBU 1 +#define USE_RGB_COLORS 1 +#endif + #ifdef TREZOR_MODEL_1 #define USE_BUTTON 1 #endif diff --git a/core/embed/trezorhal/boards/trezor_t3t1_v4.h b/core/embed/trezorhal/boards/trezor_t3t1_v4.h index e69de29bb..8cd2604d1 100644 --- a/core/embed/trezorhal/boards/trezor_t3t1_v4.h +++ b/core/embed/trezorhal/boards/trezor_t3t1_v4.h @@ -0,0 +1,83 @@ +#ifndef _TREZOR_T3T1_H +#define _TREZOR_T3T1_H + +#define DISPLAY_RESX 240 +#define DISPLAY_RESY 240 + +#define VDD_1V8 1 +#define HSE_16MHZ 1 + +//#define USE_SD_CARD 1 +#define USE_I2C 1 +#define USE_TOUCH 1 +#define USE_SBU 1 +#define USE_RGB_COLORS 1 +#define USE_DISP_I8080_8BIT_DW 1 +#define USE_HAPTIC 1 +#define USE_BACKLIGHT 1 + +#include "displays/panels/lx154a2422.h" +#include "displays/st7789v.h" +#define DISPLAY_IDENTIFY 1 +#define DISPLAY_TE_PORT GPIOD +#define DISPLAY_TE_PIN GPIO_PIN_12 + +#define DISPLAY_PANEL_INIT_SEQ lx154a2422_init_seq +#define DISPLAY_PANEL_ROTATE lx154a2422_rotate +#define TRANSFORM_TOUCH_COORDS lx154a2422_transform_touch_coords + +#define BACKLIGHT_PWM_FREQ 12500 +#define BACKLIGHT_PWM_TIM TIM8 +#define BACKLIGHT_PWM_TIM_CLK_EN __HAL_RCC_TIM8_CLK_ENABLE +#define BACKLIGHT_PWM_TIM_AF GPIO_AF3_TIM8 +#define BACKLIGHT_PWM_TIM_OCMODE TIM_OCMODE_PWM1 +#define BACKLIGHT_PWM_TIM_CHANNEL TIM_CHANNEL_1 +#define BACKLIGHT_PWM_TIM_CCR CCR1 +#define BACKLIGHT_PWM_PIN GPIO_PIN_6 +#define BACKLIGHT_PWM_PORT GPIOC +#define BACKLIGHT_PWM_PORT_CLK_EN __HAL_RCC_GPIOC_CLK_ENABLE + +#define I2C_COUNT 2 +#define I2C_INSTANCE_0 I2C1 +#define I2C_INSTANCE_0_CLK_EN __HAL_RCC_I2C1_CLK_ENABLE +#define I2C_INSTANCE_0_CLK_DIS __HAL_RCC_I2C1_CLK_DISABLE +#define I2C_INSTANCE_0_PIN_AF GPIO_AF4_I2C1 +#define I2C_INSTANCE_0_SDA_PORT GPIOB +#define I2C_INSTANCE_0_SDA_PIN GPIO_PIN_7 +#define I2C_INSTANCE_0_SDA_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE +#define I2C_INSTANCE_0_SCL_PORT GPIOB +#define I2C_INSTANCE_0_SCL_PIN GPIO_PIN_6 +#define I2C_INSTANCE_0_SCL_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE +#define I2C_INSTANCE_0_RESET_REG &RCC->APB1RSTR1 +#define I2C_INSTANCE_0_RESET_BIT RCC_APB1RSTR1_I2C1RST + +#define I2C_INSTANCE_1 I2C2 +#define I2C_INSTANCE_1_CLK_EN __HAL_RCC_I2C2_CLK_ENABLE +#define I2C_INSTANCE_1_CLK_DIS __HAL_RCC_I2C2_CLK_DISABLE +#define I2C_INSTANCE_1_PIN_AF GPIO_AF4_I2C2 +#define I2C_INSTANCE_1_SDA_PORT GPIOB +#define I2C_INSTANCE_1_SDA_PIN GPIO_PIN_14 +#define I2C_INSTANCE_1_SDA_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE +#define I2C_INSTANCE_1_SCL_PORT GPIOB +#define I2C_INSTANCE_1_SCL_PIN GPIO_PIN_13 +#define I2C_INSTANCE_1_SCL_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE +#define I2C_INSTANCE_1_RESET_REG &RCC->APB1RSTR1 +#define I2C_INSTANCE_1_RESET_BIT RCC_APB1RSTR1_I2C2RST + +#define TOUCH_SENSITIVITY 0x40 +#define TOUCH_I2C_INSTANCE 0 +#define TOUCH_RST_PORT GPIOC +#define TOUCH_RST_PIN GPIO_PIN_5 +#define TOUCH_INT_PORT GPIOC +#define TOUCH_INT_PIN GPIO_PIN_4 +#define TOUCH_ON_PORT GPIOB +#define TOUCH_ON_PIN GPIO_PIN_0 + +#define OPTIGA_I2C_INSTANCE 1 + +#define SD_DETECT_PORT GPIOC +#define SD_DETECT_PIN GPIO_PIN_13 +#define SD_ENABLE_PORT GPIOC +#define SD_ENABLE_PIN GPIO_PIN_0 + +#endif //_TREZOR_T_H diff --git a/core/embed/trezorhal/stm32u5/backlight_pwm.c b/core/embed/trezorhal/stm32u5/backlight_pwm.c new file mode 120000 index 000000000..ca21f1a60 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/backlight_pwm.c @@ -0,0 +1 @@ +../stm32f4/backlight_pwm.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/backlight_pwm.h b/core/embed/trezorhal/stm32u5/backlight_pwm.h new file mode 120000 index 000000000..37053b491 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/backlight_pwm.h @@ -0,0 +1 @@ +../stm32f4/backlight_pwm.h \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.c b/core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.c new file mode 120000 index 000000000..9a0679934 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.c @@ -0,0 +1 @@ +../../../stm32f4/displays/panels/lx154a2422.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.h b/core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.h new file mode 120000 index 000000000..3bff06848 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/displays/panels/lx154a2422.h @@ -0,0 +1 @@ +../../../stm32f4/displays/panels/lx154a2422.h \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/displays/st7789v.c b/core/embed/trezorhal/stm32u5/displays/st7789v.c new file mode 120000 index 000000000..5f8dcd4cb --- /dev/null +++ b/core/embed/trezorhal/stm32u5/displays/st7789v.c @@ -0,0 +1 @@ +../../stm32f4/displays/st7789v.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/displays/st7789v.h b/core/embed/trezorhal/stm32u5/displays/st7789v.h new file mode 120000 index 000000000..7974c7d91 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/displays/st7789v.h @@ -0,0 +1 @@ +../../stm32f4/displays/st7789v.h \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h b/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h index 1d452c9f5..9cbfb8ff4 100644 --- a/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h +++ b/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h @@ -81,8 +81,8 @@ extern "C" { /*#define HAL_SMARTCARD_MODULE_ENABLED */ /*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */ -/*#define HAL_SRAM_MODULE_ENABLED */ -/*#define HAL_TIM_MODULE_ENABLED */ +#define HAL_SRAM_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED /*#define HAL_TSC_MODULE_ENABLED */ /*#define HAL_RAMCFG_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED diff --git a/core/embed/trezorhal/stm32u5/touch/ft6x36.c b/core/embed/trezorhal/stm32u5/touch/ft6x36.c new file mode 120000 index 000000000..68b33fbb6 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/touch/ft6x36.c @@ -0,0 +1 @@ +../../stm32f4/touch/ft6x36.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/touch/ft6x36.h b/core/embed/trezorhal/stm32u5/touch/ft6x36.h new file mode 120000 index 000000000..2c609d19b --- /dev/null +++ b/core/embed/trezorhal/stm32u5/touch/ft6x36.h @@ -0,0 +1 @@ +../../stm32f4/touch/ft6x36.h \ No newline at end of file diff --git a/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json b/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json new file mode 100644 index 000000000..a5b5b3bb1 --- /dev/null +++ b/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json @@ -0,0 +1,20 @@ +{ + "header_len": 4608, + "text": "DEV ONLY, DO NOT USE!", + "hw_model": "T3T1", + "expiry": 0, + "version": [0, 0], + "sig_m": 2, + "trust": { + "allow_run_with_secret": false, + "show_vendor_string": false, + "require_user_click": false, + "red_background": false, + "delay": 0 + }, + "pubkeys": [ + "e28a8970753332bd72fef413e6b0b2ef1b4aadda7aa2c141f233712a6876b351", + "d4eec1869fb1b8a4e817516ad5a931557cb56805c3eb16e8f3a803d647df7869", + "772c8a442b7db06e166cfbc1ccbcbcde6f3eba76a4e98ef3ffc519502237d6ef" + ] +} diff --git a/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.toif b/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.toif new file mode 100644 index 0000000000000000000000000000000000000000..231990e5a2eebbbd752b62b3a91db6e981b835ad GIT binary patch literal 4222 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 U@-XiBXA}NhKiALob3NDkf0mleR{#J2 literal 0 HcmV?d00001 diff --git a/core/embed/vendorheader/T3T1/vendor_unsafe.json b/core/embed/vendorheader/T3T1/vendor_unsafe.json new file mode 100644 index 000000000..b9f1bda48 --- /dev/null +++ b/core/embed/vendorheader/T3T1/vendor_unsafe.json @@ -0,0 +1,20 @@ +{ + "header_len": 4608, + "text": "UNSAFE, DO NOT USE!", + "hw_model": "T3T1", + "expiry": 0, + "version": [0, 1], + "sig_m": 2, + "trust": { + "allow_run_with_secret": false, + "show_vendor_string": true, + "require_user_click": true, + "red_background": true, + "delay": 1 + }, + "pubkeys": [ + "e28a8970753332bd72fef413e6b0b2ef1b4aadda7aa2c141f233712a6876b351", + "d4eec1869fb1b8a4e817516ad5a931557cb56805c3eb16e8f3a803d647df7869", + "772c8a442b7db06e166cfbc1ccbcbcde6f3eba76a4e98ef3ffc519502237d6ef" + ] +} diff --git a/core/embed/vendorheader/T3T1/vendor_unsafe.toif b/core/embed/vendorheader/T3T1/vendor_unsafe.toif new file mode 100644 index 0000000000000000000000000000000000000000..3b187a7006fb93342ae4e8459e995f53f2c5423f GIT binary patch literal 3942 zcmZu!>2K6k6fM(2+o7p+heEgMMwt$!8q8e@zIqQcZ;f6<{W|D~kRaXIYF(}_A_AlGs;-)31N|`}ppdGns*5j&*n)Hz z@N;ra^16tK2!30SZ%h7iepvbl(qKQJnJ}umIzwfg1=S?x9;nE)F>r4JXg9hNSLvne6P&Nf#PPxTsu~L;F#*v z%U}6m^fz)z9;emf0RzqRqIXq74~ks|b>~wMzhy&KuLkMnlH&?WVf5xjZ-FX`1_AL9 zW^gkkXH(4jXQ6?oAsm0)$lGC~{>doKG&_Y?@Ih$JlcJ~w0s zgf$bW&@(piMgl$y$O=)}+B~!rs(y}PF$ADQ6!;m<8iiFqx-L^S1xDQU2^4gx3$FP+ zdhV4u4RW*1S|JA^)V?9bsRYoqGob4ynKX0Ua*&yO;LxzQP0XRc-#Q7auy3Ee zhTS0GwFD9m@bEqv3{62-9CW0#sh^5FpQ%|qwHD0dvX?Z}%{;ebyEf9RzK3H5!li*p zhj$XnWUkE!zr@tAm5YoZ0h_?jrvT7DwmKZ@A!Fuk>>Ixc1h4}En~{wM@Tmc=9NsC0 zuvrujFlgSfm$hXl0j@-^T_+}ZvJ&K89?#r7F>33DFAKt#%+sg#F`2o6nJ;1{gl}-M zD}i}k12MRGRRiPI(`t5N1h6skA$$)CyiFc;sF)(I<%VSNX8=!SR!w~E8}SJbL#YeL zB-e4NWQgjFvh|lw^>ng+lNnRB4_}C3QhC<|jK|20023Q#GJqtGTW|J>k!N%#wXw`V zhEKFLcC1h=rlEE_Q&}L6ecXQ~jC$1yjPT|W?Gx{58CU6o%tII)kFHFpYOcv-YEX;c z_!=I2n&x(>JJ^$}x!RYnPbGuw;ub(UWJFAGv1Y9_ZXUxZ2NKT5v@JMtm3PWNpsK+I z!V{QOfZYJ7NElsY6^L&lj|K2l%;dqvGvjF;;sgKsHgmRWCW*ZS%sN3STa2tpJ0$GV z2jKl&BotzUH07xmwRt8U!}bP{DF`IsW1@k1>@EVWf-KL$U@WwvP(RK!0Vame1B0Xh z%gdFZR6ox^00CxtTAztAQR>unIPTS*TQv|LFRnJ?R#l=^m)6voc zwS5o-wDPL(7SBPZ(m?qTAXUE`>|{LzS3ZMwFrR=SKkdP*d37CLeIrw?^XvzQ%Qq$! zXf0qJd%4Qp7eSlZ9sS%+5a)7s!kW%zxJ=G2rhs>aFJa9OM{MIPNf|^n8?1>D^-6Se zQf+}7%x#?&Ab`P_h{>}wLD&T*hOH~=-XWdEw4ESdMBCz>R)Cdo)Z&=}mnw{JcFHg4e>V_OGS$`YV}ps{6RUO(wOo**uV~ z<*W`6;=THXSZxee!()GhO1QUR-kErbQ87jha~m`hMtT(}#X12lgjl0NywoH7=LAz@ zWds0kR-HHMk3(uDOE(;hG>9_=^Z%ZI{{l>gd+Q}{RNvCS3*%UT(4?O}lu65ln-+&~ zDR&Km)Iqkg3o7i9500k~!{P#hQq6h}mW35|M~Sal`;@~Z0&~1h^AL|4bo&HIL%(K; zVeV!|_vg<>S$QJ_B~ZqZi?2f&j3BiWo3mm9G{nGE;dn)v**u>=X&{eN>h8bCh6F6U zvVO5wvVp+`@^3A0@2qGRv(L1yYw?)6q!`x+fW{_e0(c;vY5D#Q5KCaq1_8V6=FOEp zZpsI&I*Q8+cKV?6mzvDAVgBmp7|p8|GU|uRW-xBzZ+<*wic|ia+IAOvH2MBn-hem= z&z>% literal 0 HcmV?d00001 diff --git a/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin b/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin new file mode 100644 index 0000000000000000000000000000000000000000..1d71c401cb38d60ba64ea3f5c73ff62ac1fbaf4e GIT binary patch literal 4608 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 list[str]: + features_available: list[str] = [] + board = "trezor_t3t1_v4.h" + display = "st7789v.c" + hw_model = get_hw_model_as_number("T3T1") + hw_revision = 0 + features_available.append("disp_i8080_8bit_dw") + + mcu = "STM32U585xx" + linker_script = "stm32u58" + + stm32u5_common_files(env, defines, sources, paths) + + env.get("ENV")[ + "CPU_ASFLAGS" + ] = "-mthumb -mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16 " + env.get("ENV")[ + "CPU_CCFLAGS" + ] = "-mthumb -mcpu=cortex-m33 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -mtune=cortex-m33 -mcmse " + env.get("ENV")["RUST_TARGET"] = "thumbv8m.main-none-eabihf" + + defines += [mcu] + defines += [f'TREZOR_BOARD=\\"boards/{board}\\"'] + defines += [f"HW_MODEL={hw_model}"] + defines += [f"HW_REVISION={hw_revision}"] + sources += [ + "embed/models/model_T3T1_layout.c", + ] + sources += [f"embed/trezorhal/stm32u5/displays/{display}"] + sources += ["embed/trezorhal/stm32u5/backlight_pwm.c"] + sources += [ + "embed/trezorhal/stm32u5/displays/panels/lx154a2422.c", + ] + + features_available.append("backlight") + + if "input" in features_wanted: + sources += ["embed/trezorhal/stm32u5/i2c.c"] + sources += ["embed/trezorhal/stm32u5/touch/ft6x36.c"] + sources += ["embed/lib/touch.c"] + features_available.append("touch") + + if "haptic" in features_wanted: + sources += [ + "embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c", + ] + features_available.append("haptic") + + # if "sd_card" in features_wanted: + # sources += ["embed/trezorhal/stm32u5/sdcard.c"] + # sources += ["embed/extmod/modtrezorio/ff.c"] + # sources += ["embed/extmod/modtrezorio/ffunicode.c"] + # sources += [ + # "vendor/stm32cube-u5/Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_dma.c" + # ] + # features_available.append("sd_card") + + if "sbu" in features_wanted: + sources += ["embed/trezorhal/stm32u5/sbu.c"] + features_available.append("sbu") + + if "usb" in features_wanted: + sources += [ + "embed/trezorhal/stm32u5/usb.c", + "embed/trezorhal/stm32u5/usbd_conf.c", + "embed/trezorhal/stm32u5/usbd_core.c", + "embed/trezorhal/stm32u5/usbd_ctlreq.c", + "embed/trezorhal/stm32u5/usbd_ioreq.c", + "vendor/stm32cube-u5/Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_ll_usb.c", + ] + features_available.append("usb") + + if "dma2d" in features_wanted: + defines += ["USE_DMA2D"] + sources += ["embed/trezorhal/stm32u5/dma2d.c"] + features_available.append("dma2d") + + env.get("ENV")["TREZOR_BOARD"] = board + env.get("ENV")["MCU_TYPE"] = mcu + env.get("ENV")["LINKER_SCRIPT"] = linker_script + + return features_available diff --git a/core/site_scons/tools.py b/core/site_scons/tools.py index d84bcc8d6..daf324222 100644 --- a/core/site_scons/tools.py +++ b/core/site_scons/tools.py @@ -13,6 +13,7 @@ from boards import ( trezor_r_v6, trezor_r_v10, trezor_t, + trezor_t3t1_v4, ) HERE = Path(__file__).parent.resolve() @@ -58,6 +59,8 @@ def configure_board( elif model_r_version == 10: return trezor_r_v10.configure(env, features_wanted, defines, sources, paths) raise Exception("Unknown model_r_version") + elif model in ("T3T1",): + return trezor_t3t1_v4.configure(env, features_wanted, defines, sources, paths) elif model in ("DISC1",): return discovery.configure(env, features_wanted, defines, sources, paths) elif model in ("DISC2",): @@ -72,6 +75,8 @@ def get_model_identifier(model: str) -> str: return "T2T1" elif model == "R": return "T2B1" + elif model == "T3T1": + return "T3T1" elif model == "DISC1": return "D001" elif model == "DISC2": diff --git a/python/.changelog.d/3422.added b/python/.changelog.d/3422.added new file mode 100644 index 000000000..17fb87f43 --- /dev/null +++ b/python/.changelog.d/3422.added @@ -0,0 +1 @@ +Added support for T3T1 diff --git a/python/src/trezorlib/firmware/models.py b/python/src/trezorlib/firmware/models.py index 5fc203f46..2b39783da 100644 --- a/python/src/trezorlib/firmware/models.py +++ b/python/src/trezorlib/firmware/models.py @@ -30,6 +30,7 @@ if t.TYPE_CHECKING: class Model(Enum): T1B1 = b"T1B1" T2T1 = b"T2T1" + T3T1 = b"T3T1" T2B1 = b"T2B1" D001 = b"D001" D002 = b"D002" @@ -221,6 +222,29 @@ T2B1 = ModelKeys( firmware_sigs_needed=-1, ) +T3T1 = ModelKeys( + production=False, + boardloader_keys=[ + bytes.fromhex(key) + for key in ( + "db995fe25169d141cab9bbba92baa01f9f2e1ece7df4cb2ac05190f37fcc1f9d", + "2152f8d19b791d24453242e15f2eab6cb7cffa7b6a5ed30097960e069881db12", + "22fc297792f0b6ffc0bfcfdb7edb0c0aa14e025a365ec0e342e86e3829cb74b6", + ) + ], + boardloader_sigs_needed=2, + bootloader_keys=[ + bytes.fromhex(key) + for key in ( + "d759793bbc13a2819a827c76adb6fba8a49aee007f49f2d0992d99b825ad2c48", + "6355691c178a8ff91007a7478afb955ef7352c63e7b25703984cf78b26e21a56", + "ee93a4f66f8d16b819bb9beb9ffccdfcdc1412e87fee6a324c2a99a1e0e67148", + ) + ], + bootloader_sigs_needed=2, + firmware_keys=(), + firmware_sigs_needed=-1, +) LEGACY_HASH_PARAMS = FirmwareHashParameters( hash_function=hashlib.sha256, @@ -244,6 +268,7 @@ MODEL_MAP = { Model.T1B1: LEGACY_V3, Model.T2T1: T2T1, Model.T2B1: T2B1, + Model.T3T1: TREZOR_CORE_DEV, Model.D001: TREZOR_CORE_DEV, Model.D002: TREZOR_CORE_DEV, } @@ -252,6 +277,7 @@ MODEL_MAP_DEV = { Model.T1B1: LEGACY_V3_DEV, Model.T2T1: TREZOR_CORE_DEV, Model.T2B1: TREZOR_CORE_DEV, + Model.T3T1: TREZOR_CORE_DEV, Model.D001: TREZOR_CORE_DEV, Model.D002: TREZOR_CORE_DEV, } @@ -259,6 +285,7 @@ MODEL_MAP_DEV = { MODEL_HASH_PARAMS_MAP = { Model.T1B1: LEGACY_HASH_PARAMS, Model.T2T1: T2T1_HASH_PARAMS, + Model.T3T1: T2T1_HASH_PARAMS, Model.T2B1: T2T1_HASH_PARAMS, Model.D001: T2T1_HASH_PARAMS, Model.D002: D002_HASH_PARAMS, @@ -273,6 +300,7 @@ TREZOR_ONE_V3_DEV = LEGACY_V3_DEV TREZOR_T = T2T1 TREZOR_R = T2B1 +TREZOR_T3T1 = T3T1 TREZOR_T_DEV = TREZOR_CORE_DEV TREZOR_R_DEV = TREZOR_CORE_DEV diff --git a/python/src/trezorlib/models.py b/python/src/trezorlib/models.py index f80b504f9..74b34855d 100644 --- a/python/src/trezorlib/models.py +++ b/python/src/trezorlib/models.py @@ -63,6 +63,15 @@ T2B1 = TrezorModel( default_mapping=mapping.DEFAULT_MAPPING, ) +T3T1 = TrezorModel( + name="T3T1", + internal_name="T3T1", + minimum_version=(2, 1, 0), + vendors=VENDORS, + usb_ids=((0x1209, 0x53C1), (0x1209, 0x53C0)), + default_mapping=mapping.DEFAULT_MAPPING, +) + DISC1 = TrezorModel( name="DISC1", internal_name="D001", @@ -87,10 +96,11 @@ TREZOR_ONE = T1B1 TREZOR_T = T2T1 TREZOR_R = T2B1 TREZOR_SAFE3 = T2B1 +TREZOR_T3T1 = T2B1 TREZOR_DISC1 = DISC1 TREZOR_DISC2 = DISC2 -TREZORS = {T1B1, T2T1, T2B1, DISC1, DISC2} +TREZORS = {T1B1, T2T1, T2B1, T3T1, DISC1, DISC2} def by_name(name: Optional[str]) -> Optional[TrezorModel]: