diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader index bb6f685a4c..6bf5fa128a 100644 --- a/core/SConscript.bootloader +++ b/core/SConscript.bootloader @@ -36,7 +36,7 @@ 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'): +elif TREZOR_MODEL in ('T', 'T3W1', 'DISC1'): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD=None FONT_BOLD='Font_TTHoves_Bold_17' diff --git a/core/SConscript.bootloader_ci b/core/SConscript.bootloader_ci index 181f914027..9bac6a7c2b 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', 'T3W1'): 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 025ea3f5a8..a0dbf53430 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', ): +elif TREZOR_MODEL in ('T', 'T3W1'): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD=None FONT_BOLD='Font_TTHoves_Bold_17' @@ -159,7 +159,7 @@ env.Replace( env.Replace( TREZOR_MODEL=TREZOR_MODEL, ) -if TREZOR_MODEL in ('T', 'R'): +if TREZOR_MODEL in ('T', 'R', 'T3W1'): CPU_MODEL = 'STM32F427xx' elif TREZOR_MODEL in ('DISC1', ): CPU_MODEL = 'STM32F429xx' @@ -249,7 +249,7 @@ def cargo_build(): else: features = ["model_tt"] - if TREZOR_MODEL in ('T',): + if TREZOR_MODEL in ('T', 'T3W1'): features.append('touch') features.append('backlight') if TREZOR_MODEL in ('R', '1'): diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 42f2725a7c..b0286bc437 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -38,7 +38,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'): +elif TREZOR_MODEL in ('T', 'T3W1', 'DISC1'): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD='Font_TTHoves_DemiBold_21' FONT_BOLD='Font_TTHoves_Bold_17' @@ -379,7 +379,7 @@ env = Environment(ENV=os.environ, CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODU FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL) -if TREZOR_MODEL in ('T', 'DISC1'): +if TREZOR_MODEL in ('T', 'T3W1', 'DISC1'): LAYOUT = 'LAYOUT_TTV2' elif TREZOR_MODEL in ('1', 'R'): LAYOUT = 'LAYOUT_TR' @@ -813,7 +813,7 @@ BINARY_NAME += "-dirty" if tools.get_git_modified() else "" BINARY_NAME += ".bin" -if TREZOR_MODEL in ('T', 'R', 'DISC1'): +if TREZOR_MODEL in ('T', 'R', 'T3W1', 'DISC1'): action_bin=[ '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data --pad-to 0x08100000 $SOURCE ${TARGET}.p1', '$OBJCOPY -O binary -j .flash2 $SOURCE ${TARGET}.p2', diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest index 927693ad3c..ca432e6c91 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', 'T3W1'): FONT_NORMAL=None FONT_DEMIBOLD=None FONT_BOLD='Font_Roboto_Bold_20' diff --git a/core/SConscript.reflash b/core/SConscript.reflash index ea2cb2a1f7..f6577682c5 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', 'T3W1'): FONT_NORMAL=None FONT_DEMIBOLD=None FONT_BOLD='Font_Roboto_Bold_20' diff --git a/core/SConscript.unix b/core/SConscript.unix index 1fe590556d..f386543f14 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -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', ): +elif TREZOR_MODEL in ('T', 'T3W1'): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD='Font_TTHoves_DemiBold_21' FONT_BOLD='Font_TTHoves_Bold_17' @@ -384,7 +384,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', 'T3W1'): SOURCE_UNIX += [ 'embed/trezorhal/unix/sbu.c', ] @@ -416,14 +416,14 @@ 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', 'T3W1'): LAYOUT = 'LAYOUT_TTV2' elif TREZOR_MODEL in ('1', 'R'): LAYOUT = 'LAYOUT_TR' else: raise ValueError('Unknown Trezor model') -if TREZOR_MODEL in ('T',): +if TREZOR_MODEL in ('T', 'T3W1'): SDCARD = True SOURCE_UNIX += [ 'embed/trezorhal/unix/sdcard.c', @@ -479,7 +479,7 @@ if ARGUMENTS.get('TREZOR_MEMPERF', '0') == '1': env.Replace( TREZOR_MODEL=TREZOR_MODEL, ) -if TREZOR_MODEL in ('T', 'R'): +if TREZOR_MODEL in ('T', 'R', 'T3W1'): CPU_MODEL = 'STM32F427xx' elif TREZOR_MODEL in ('DISC1', ): CPU_MODEL = 'STM32F429xx' @@ -768,7 +768,7 @@ RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a' def cargo_build(): # T1 does not have its own Rust feature, it shares it with TR - model_feature = 'model_tr' if TREZOR_MODEL == '1' else f'model_t{TREZOR_MODEL.lower()}' + model_feature = 'model_tr' if TREZOR_MODEL == '1' else 'model_tt' features = ['micropython', 'protobuf', model_feature] if BITCOIN_ONLY == '1': features.append('bitcoin_only') @@ -778,7 +778,7 @@ def cargo_build(): if DMA2D: features.append('dma2d') - if TREZOR_MODEL in ('T',): + if TREZOR_MODEL in ('T', 'T3W1'): features.append('touch') features.append('sd_card') if TREZOR_MODEL in ('R', '1'): diff --git a/core/embed/firmware/bootloaders/bootloader_T3W1.bin b/core/embed/firmware/bootloaders/bootloader_T3W1.bin new file mode 100644 index 0000000000..304db439e2 Binary files /dev/null and b/core/embed/firmware/bootloaders/bootloader_T3W1.bin differ diff --git a/core/embed/firmware/memory_T3W1.ld b/core/embed/firmware/memory_T3W1.ld new file mode 120000 index 0000000000..d7ddaf41ac --- /dev/null +++ b/core/embed/firmware/memory_T3W1.ld @@ -0,0 +1 @@ +./memory_T.ld \ No newline at end of file diff --git a/core/embed/models/model.h b/core/embed/models/model.h index 0739cdf02d..ef3337099c 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_T3W1 +#include "model_T3W1.h" #elif defined TREZOR_MODEL_DISC1 #include "model_D001.h" #else diff --git a/core/embed/models/model_T3W1.h b/core/embed/models/model_T3W1.h new file mode 100644 index 0000000000..3547df9a8b --- /dev/null +++ b/core/embed/models/model_T3W1.h @@ -0,0 +1,29 @@ +#ifndef MODELS_MODEL_T3W1_H_ +#define MODELS_MODEL_T3W1_H_ + +#define MODEL_NAME "T3W1" +#define MODEL_INTERNAL_NAME "T3W1" +#define MODEL_INTERNAL_NAME_TOKEN T3W1 +#define MODEL_NAME_QSTR MP_QSTR_T3W1 +#define MODEL_INTERNAL_NAME_QSTR MP_QSTR_T3W1 + +/*** Using DEV KEYS temorarily ***/ +#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 0x08000000 +#define BOOTLOADER_START 0x08020000 +#define FIRMWARE_START 0x08040000 + +#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_T3W1_layout.c b/core/embed/models/model_T3W1_layout.c new file mode 100644 index 0000000000..b845ffa56f --- /dev/null +++ b/core/embed/models/model_T3W1_layout.c @@ -0,0 +1,82 @@ +#include "flash.h" +#include "model.h" + +const flash_area_t STORAGE_AREAS[STORAGE_AREAS_COUNT] = { + { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 4, + .num_sectors = 1, + }, + }, + { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 16, + .num_sectors = 1, + }, + }, +}; + +const flash_area_t BOARDLOADER_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 0, + .num_sectors = 3, + }, +}; + +const flash_area_t BOOTLOADER_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 5, + .num_sectors = 1, + }, +}; + +const flash_area_t FIRMWARE_AREA = { + .num_subareas = 2, + .subarea[0] = + { + .first_sector = 6, + .num_sectors = 6, + }, + .subarea[1] = + { + .first_sector = 17, + .num_sectors = 7, + }, +}; + +const flash_area_t WIPE_AREA = { + .num_subareas = 3, + .subarea[0] = + { + .first_sector = 4, + .num_sectors = 1, + }, + .subarea[1] = + { + .first_sector = 6, + .num_sectors = + 9, // sector 15 skipped due to bootloader MPU settings + }, + .subarea[2] = + { + .first_sector = 16, + .num_sectors = 8, + }, +}; + +const flash_area_t ALL_WIPE_AREA = { + .num_subareas = 1, + .subarea[0] = + { + .first_sector = 3, + .num_sectors = 21, + }, +}; diff --git a/core/embed/rust/src/ui/event.rs b/core/embed/rust/src/ui/event.rs index 0bb6bc7b0f..8f07931350 100644 --- a/core/embed/rust/src/ui/event.rs +++ b/core/embed/rust/src/ui/event.rs @@ -5,6 +5,7 @@ use core::convert::TryInto; pub enum PhysicalButton { Left, Right, + Power, } #[derive(Copy, Clone, PartialEq, Eq)] @@ -24,6 +25,7 @@ impl ButtonEvent { let button = match button { 0 => PhysicalButton::Left, 1 => PhysicalButton::Right, + 2 => PhysicalButton::Power, _ => return Err(error::Error::OutOfRange), }; let result = match event & 0xFF { diff --git a/core/embed/trezorhal/boards/board-unix.h b/core/embed/trezorhal/boards/board-unix.h index bdcb7b5452..a964dd3843 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_T3W1 +#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_t.h b/core/embed/trezorhal/boards/trezor_t.h index 950df81579..873406ea9e 100644 --- a/core/embed/trezorhal/boards/trezor_t.h +++ b/core/embed/trezorhal/boards/trezor_t.h @@ -14,6 +14,13 @@ #define USE_BACKLIGHT 1 #define USE_DISP_I8080_8BIT_DW 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 TRANSFORM_TOUCH_COORDS lx154a2422_transform_touch_coords + #define BACKLIGHT_PWM_FREQ 50000 #define BACKLIGHT_PWM_TIM TIM1 #define BACKLIGHT_PWM_TIM_CLK_EN __HAL_RCC_TIM1_CLK_ENABLE @@ -39,7 +46,16 @@ #define I2C_INSTANCE_1_RESET_FLG RCC_APB1RSTR_I2C1RST #define TOUCH_I2C_NUM 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_10 -#include "displays/st7789v.h" +#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/boards/trezor_t3w1_d1.h b/core/embed/trezorhal/boards/trezor_t3w1_d1.h new file mode 100644 index 0000000000..7c5fbfc36e --- /dev/null +++ b/core/embed/trezorhal/boards/trezor_t3w1_d1.h @@ -0,0 +1,71 @@ +#ifndef _TREZOR_T3W1_H +#define _TREZOR_T3W1_H + +#define DISPLAY_RESX 240 +#define DISPLAY_RESY 320 + +#define USE_SD_CARD 1 +#define USE_I2C 1 +#define USE_TOUCH 1 +#define USE_BUTTON 1 +#define USE_SBU 1 +#define USE_RGB_COLORS 1 +#define USE_BACKLIGHT 1 +#define USE_DISP_I8080_16BIT_DW 1 + +#define DISPLAY_PANEL_INIT_SEQ lhs200kb_if21_init_seq +#define DISPLAY_PANEL_ROTATE lhs200kb_if21_rotate +#define TRANSFORM_TOUCH_COORDS lhs200kb_if21_transform_touch_coords + +#include "displays/panels/lhs200kb-if21.h" +#include "displays/st7789v.h" + +#define BACKLIGHT_PWM_FREQ 50000 +#define BACKLIGHT_PWM_TIM TIM1 +#define BACKLIGHT_PWM_TIM_CLK_EN __HAL_RCC_TIM1_CLK_ENABLE +#define BACKLIGHT_PWM_TIM_AF GPIO_AF1_TIM1 +#define BACKLIGHT_PWM_TIM_OCMODE TIM_OCMODE_PWM2 +#define BACKLIGHT_PWM_TIM_CHANNEL TIM_CHANNEL_1 +#define BACKLIGHT_PWM_TIM_CCR CCR1 +#define BACKLIGHT_PWM_PIN GPIO_PIN_7 +#define BACKLIGHT_PWM_PORT GPIOA +#define BACKLIGHT_PWM_PORT_CLK_EN __HAL_RCC_GPIOA_CLK_ENABLE + +#define I2C_COUNT 1 +#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_11 +#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_10 +#define I2C_INSTANCE_1_SCL_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE +#define I2C_INSTANCE_1_RESET_FLG RCC_APB1RSTR_I2C2RST + +#define TOUCH_I2C_NUM 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_8 + +#define SD_DETECT_PORT GPIOB +#define SD_DETECT_PIN GPIO_PIN_0 +#define SD_ENABLE_PORT GPIOE +#define SD_ENABLE_PIN GPIO_PIN_1 + +#define GPIO_1_PORT GPIOC +#define GPIO_1_PIN GPIO_PIN_1 +#define GPIO_2_PORT GPIOC +#define GPIO_2_PIN GPIO_PIN_6 +#define GPIO_3_PORT GPIOC +#define GPIO_3_PIN GPIO_PIN_7 + +#define BTN_POWER_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE +#define BTN_POWER_PORT GPIOE +#define BTN_POWER_PIN GPIO_PIN_0 + +#endif //_TREZOR_T3W1_H diff --git a/core/embed/trezorhal/button.h b/core/embed/trezorhal/button.h index f1389f7f4e..ee4953a5fe 100644 --- a/core/embed/trezorhal/button.h +++ b/core/embed/trezorhal/button.h @@ -20,6 +20,9 @@ #ifndef TREZORHAL_BUTTON_H #define TREZORHAL_BUTTON_H +#include TREZOR_BOARD + +#include #include #define BTN_EVT_DOWN (1U << 24) @@ -27,10 +30,19 @@ #define BTN_LEFT 0 #define BTN_RIGHT 1 +#define BTN_POWER 2 void button_init(void); uint32_t button_read(void); -char button_state_left(void); -char button_state_right(void); + +#ifdef BTN_LEFT_CLK_ENA +bool button_state_left(void); +#endif +#ifdef BTN_RIGHT_CLK_ENA +bool button_state_right(void); +#endif +#ifdef BTN_POWER_CLK_ENA +bool button_state_power(void); +#endif #endif diff --git a/core/embed/trezorhal/stm32f4/button.c b/core/embed/trezorhal/stm32f4/button.c index 7555781d4e..9221f60595 100644 --- a/core/embed/trezorhal/stm32f4/button.c +++ b/core/embed/trezorhal/stm32f4/button.c @@ -1,28 +1,54 @@ + +#include "stdbool.h" + #include STM32_HAL_H #include "button.h" -#include TREZOR_BOARD - -static char last_left = 0, last_right = 0; - -void button_init(void) { - BTN_LEFT_CLK_ENA(); - BTN_RIGHT_CLK_ENA(); +static void init_btn(GPIO_TypeDef *port, uint16_t pin) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = BTN_LEFT_PIN; - HAL_GPIO_Init(BTN_LEFT_PORT, &GPIO_InitStructure); - GPIO_InitStructure.Pin = BTN_RIGHT_PIN; - HAL_GPIO_Init(BTN_RIGHT_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = pin; + HAL_GPIO_Init(port, &GPIO_InitStructure); +} + +#ifdef BTN_LEFT_CLK_ENA +static bool last_left = 0; +bool button_state_left(void) { return last_left; } +#endif + +#ifdef BTN_RIGHT_CLK_ENA +static bool last_right = 0; +bool button_state_right(void) { return last_right; } +#endif + +#ifdef BTN_POWER_CLK_ENA +static bool last_power = 0; +bool button_state_power(void) { return last_power; } +#endif + +void button_init(void) { +#ifdef BTN_LEFT_CLK_ENA + BTN_LEFT_CLK_ENA(); + init_btn(BTN_LEFT_PORT, BTN_LEFT_PIN); +#endif + +#ifdef BTN_RIGHT_CLK_ENA + BTN_RIGHT_CLK_ENA(); + init_btn(BTN_RIGHT_PORT, BTN_RIGHT_PIN); +#endif + +#ifdef BTN_POWER_CLK_ENA + BTN_POWER_CLK_ENA(); + init_btn(BTN_POWER_PORT, BTN_POWER_PIN); +#endif } uint32_t button_read(void) { - char left = (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_LEFT_PORT, BTN_LEFT_PIN)); - char right = - (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_RIGHT_PORT, BTN_RIGHT_PIN)); +#ifdef BTN_LEFT_CLK_ENA + bool left = (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_LEFT_PORT, BTN_LEFT_PIN)); if (last_left != left) { last_left = left; if (left) { @@ -31,6 +57,10 @@ uint32_t button_read(void) { return BTN_EVT_UP | BTN_LEFT; } } +#endif +#ifdef BTN_RIGHT_CLK_ENA + bool right = + (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_RIGHT_PORT, BTN_RIGHT_PIN)); if (last_right != right) { last_right = right; if (right) { @@ -39,9 +69,19 @@ uint32_t button_read(void) { return BTN_EVT_UP | BTN_RIGHT; } } +#endif +#ifdef BTN_POWER_CLK_ENA + bool power = + (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_POWER_PORT, BTN_POWER_PIN)); + if (last_power != power) { + last_power = power; + if (power) { + return BTN_EVT_DOWN | BTN_POWER; + } else { + return BTN_EVT_UP | BTN_POWER; + } + } +#endif + return 0; } - -char button_state_left(void) { return last_left; } - -char button_state_right(void) { return last_right; } diff --git a/core/embed/trezorhal/stm32f4/displays/panels/154a.h b/core/embed/trezorhal/stm32f4/displays/panels/154a.h index 0fd36a96fb..e9e6d66819 100644 --- a/core/embed/trezorhal/stm32f4/displays/panels/154a.h +++ b/core/embed/trezorhal/stm32f4/displays/panels/154a.h @@ -1,5 +1,5 @@ -#ifndef TT_OLD2_H_ -#define TT_OLD2_H_ +#ifndef _154A_H_ +#define _154A_H_ // ILI9341 IC controller diff --git a/core/embed/trezorhal/stm32f4/displays/panels/lhs200kb-if21.c b/core/embed/trezorhal/stm32f4/displays/panels/lhs200kb-if21.c new file mode 100644 index 0000000000..f692011c20 --- /dev/null +++ b/core/embed/trezorhal/stm32f4/displays/panels/lhs200kb-if21.c @@ -0,0 +1,151 @@ + +#include TREZOR_BOARD +#include "display_interface.h" +#include "displays/st7789v.h" +#include "touch.h" + +void lhs200kb_if21_init_seq() { + CMD(0x36); + DATA(0x00); + + CMD(0x35); + DATA(0x00); + + CMD(0x3A); + DATA(0x05); + + CMD(0xB2); + DATA(0x0C); + DATA(0x0C); + DATA(0x00); + DATA(0x33); + DATA(0x33); + + CMD(0xB7); + DATA(0x78); + + CMD(0xBB); + DATA(0x2F); + + CMD(0xC0); + DATA(0x2C); + + CMD(0xC2); + DATA(0x01); + + CMD(0xC3); + DATA(0x19); + + CMD(0xC4); + DATA(0x20); + + CMD(0xC6); + DATA(0x0F); + + CMD(0xD0); + DATA(0xA4); + DATA(0xA1); + + CMD(0xD6); + DATA(0xA1); + + CMD(0xE0); + DATA(0xF0); + DATA(0x08); + DATA(0x0F); + DATA(0x0B); + DATA(0x0B); + DATA(0x07); + DATA(0x34); + DATA(0x43); + DATA(0x4B); + DATA(0x38); + DATA(0x14); + DATA(0x13); + DATA(0x2C); + DATA(0x31); + + CMD(0xE1); + DATA(0xF0); + DATA(0x0C); + DATA(0x11); + DATA(0x09); + DATA(0x08); + DATA(0x24); + DATA(0x34); + DATA(0x33); + DATA(0x4A); + DATA(0x3A); + DATA(0x16); + DATA(0x16); + DATA(0x2E); + DATA(0x32); + + CMD(0x21); + + CMD(0x29); +} + +void lhs200kb_if21_rotate(int degrees, buffer_offset_t* offset) { + uint16_t shift = 0; + char BX = 0, BY = 0; + +#define RGB (1 << 3) +#define ML (1 << 4) // vertical refresh order +#define MH (1 << 2) // horizontal refresh order +#define MV (1 << 5) +#define MX (1 << 6) +#define MY (1 << 7) + // MADCTL: Memory Data Access Control - reference: + // section 8.12 in the ST7789V manual + uint8_t display_command_parameter = 0; + switch (degrees) { + case 0: + display_command_parameter = 0; + BY = 0; + break; + case 90: + display_command_parameter = MV | MX | MH | ML; + BX = 1; + shift = 1; + break; + case 180: + display_command_parameter = MX | MY | MH | ML; + BY = 0; + shift = 1; + break; + case 270: + display_command_parameter = MV | MY; + BX = 1; + break; + } + + CMD(0x36); + DATA(display_command_parameter); + + if (shift) { + // GATECTRL: Gate Control; NL = 320 gate lines, first scan line is + // gate 0.; gate scan direction 319 -> 0 + CMD(0xE4); + DATA(0x27); + DATA(0x00); + DATA(0x10); + } else { + // GATECTRL: Gate Control; NL = 320 gate lines, first scan line is + // gate 0.; gate scan direction 319 -> 0 + CMD(0xE4); + DATA(0x27); + DATA(0x00); + DATA(0x10); + } + + // reset the column and page extents + display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); + + offset->x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; + offset->y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; +} + +uint32_t lhs200kb_if21_transform_touch_coords(uint16_t x, uint16_t y) { + return touch_pack_xy(y, MAX_DISPLAY_RESY - x); +} diff --git a/core/embed/trezorhal/stm32f4/displays/panels/lhs200kb-if21.h b/core/embed/trezorhal/stm32f4/displays/panels/lhs200kb-if21.h new file mode 100644 index 0000000000..3cddcba7e8 --- /dev/null +++ b/core/embed/trezorhal/stm32f4/displays/panels/lhs200kb-if21.h @@ -0,0 +1,12 @@ + +#ifndef CORE_LHS200KB_IF21_H +#define CORE_LHS200KB_IF21_H +// ST7789_V IC controller + +#include "displays/st7789v.h" + +void lhs200kb_if21_init_seq(void); +void lhs200kb_if21_rotate(int degrees, buffer_offset_t* offset); +uint32_t lhs200kb_if21_transform_touch_coords(uint16_t x, uint16_t y); + +#endif // CORE_LHS200KB_IF21_H diff --git a/core/embed/trezorhal/stm32f4/displays/panels/lx154a2411.h b/core/embed/trezorhal/stm32f4/displays/panels/lx154a2411.h index 83485b2800..a785ca6506 100644 --- a/core/embed/trezorhal/stm32f4/displays/panels/lx154a2411.h +++ b/core/embed/trezorhal/stm32f4/displays/panels/lx154a2411.h @@ -1,5 +1,5 @@ -#ifndef TT_OLD3_H_ -#define TT_OLD3_H_ +#ifndef LX154A2411_H_ +#define LX154A2411_H_ // ST7789_V IC controller void lx154a2411_gamma(void); diff --git a/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.c b/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.c index 9787d51a58..cc24ddcc73 100644 --- a/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.c +++ b/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.c @@ -1,5 +1,7 @@ +#include "display_interface.h" #include "displays/st7789v.h" +#include "touch.h" void lx154a2422_gamma(void) { // positive voltage correction @@ -80,3 +82,67 @@ void lx154a2422_init_seq(void) { lx154a2422_gamma(); } + +void lx154a2422_rotate(int degrees, buffer_offset_t* offset) { + uint16_t shift = 0; + char BX = 0, BY = 0; + +#define RGB (1 << 3) +#define ML (1 << 4) // vertical refresh order +#define MH (1 << 2) // horizontal refresh order +#define MV (1 << 5) +#define MX (1 << 6) +#define MY (1 << 7) + // MADCTL: Memory Data Access Control - reference: + // section 8.12 in the ST7789V manual + uint8_t display_command_parameter = 0; + switch (degrees) { + case 0: + display_command_parameter = 0; + BY = 0; + break; + case 90: + display_command_parameter = MV | MX | MH | ML; + BX = 1; + shift = 1; + break; + case 180: + display_command_parameter = MX | MY | MH | ML; + BY = 0; + shift = 1; + break; + case 270: + display_command_parameter = MV | MY; + BX = 1; + break; + } + + CMD(0x36); + DATA(display_command_parameter); + + if (shift) { + // GATECTRL: Gate Control; NL = 240 gate lines, first scan line is + // gate 80.; gate scan direction 319 -> 0 + CMD(0xE4); + DATA(0x1D); + DATA(0x00); + DATA(0x11); + } else { + // GATECTRL: Gate Control; NL = 240 gate lines, first scan line is + // gate 80.; gate scan direction 319 -> 0 + CMD(0xE4); + DATA(0x1D); + DATA(0x0A); + DATA(0x11); + } + + // reset the column and page extents + display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); + + offset->x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; + offset->y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; +} + +uint32_t lx154a2422_transform_touch_coords(uint16_t x, uint16_t y) { + return touch_pack_xy(x, y); +} diff --git a/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.h b/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.h index 6f8508e527..3232542c3e 100644 --- a/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.h +++ b/core/embed/trezorhal/stm32f4/displays/panels/lx154a2422.h @@ -1,7 +1,11 @@ #ifndef LX154A2422_H_ #define LX154A2422_H_ +#include "displays/st7789v.h" + void lx154a2422_init_seq(void); void lx154a2422_gamma(void); +void lx154a2422_rotate(int degrees, buffer_offset_t* offset); +uint32_t lx154a2422_transform_touch_coords(uint16_t x, uint16_t y); #endif diff --git a/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.c b/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.c index cbceaeee9a..073e9b179c 100644 --- a/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.c +++ b/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.c @@ -1,3 +1,4 @@ +#include "display_interface.h" #include "displays/st7789v.h" void tf15411a_init_seq(void) { @@ -91,3 +92,67 @@ void tf15411a_init_seq(void) { DATA(0x37); DATA(0x8F); } + +void tf15411a_rotate(int degrees, buffer_offset_t* offset) { + uint16_t shift = 0; + char BX = 0, BY = 0; + +#define RGB (1 << 3) +#define ML (1 << 4) // vertical refresh order +#define MH (1 << 2) // horizontal refresh order +#define MV (1 << 5) +#define MX (1 << 6) +#define MY (1 << 7) + // MADCTL: Memory Data Access Control - reference: + // section 9.3 in the ILI9341 manual + // section 6.2.18 in the GC9307 manual + // section 8.12 in the ST7789V manual + uint8_t display_command_parameter = 0; + switch (degrees) { + case 0: + display_command_parameter = 0; + BY = 1; + break; + case 90: + display_command_parameter = MV | MX | MH | ML; + BX = 0; + shift = 1; + break; + case 180: + display_command_parameter = MX | MY | MH | ML; + BY = 1; + shift = 1; + break; + case 270: + display_command_parameter = MV | MY; + BX = 0; + break; + } + + display_command_parameter ^= RGB | MY; // XOR RGB and MY settings + + CMD(0x36); + DATA(display_command_parameter); + + if (shift) { + // GATECTRL: Gate Control; NL = 240 gate lines, first scan line is + // gate 80.; gate scan direction 319 -> 0 + CMD(0xE4); + DATA(0x1D); + DATA(0x00); + DATA(0x11); + } else { + // GATECTRL: Gate Control; NL = 240 gate lines, first scan line is + // gate 80.; gate scan direction 319 -> 0 + CMD(0xE4); + DATA(0x1D); + DATA(0x0A); + DATA(0x11); + } + + // reset the column and page extents + display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); + + offset->x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; + offset->y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; +} diff --git a/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.h b/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.h index 2771e7e836..12abc40aed 100644 --- a/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.h +++ b/core/embed/trezorhal/stm32f4/displays/panels/tf15411a.h @@ -1,8 +1,9 @@ -#ifndef TT_OLD1_H_ -#define TT_OLD1_H_ +#ifndef TF15411A_H_ +#define TF15411A_H_ // GC9307 IC controller void tf15411a_init_seq(void); +void tf15411a_rotate(int degrees, buffer_offset_t* offset); #endif diff --git a/core/embed/trezorhal/stm32f4/displays/st7789v.c b/core/embed/trezorhal/stm32f4/displays/st7789v.c index 681531ab72..acf782fd7c 100644 --- a/core/embed/trezorhal/stm32f4/displays/st7789v.c +++ b/core/embed/trezorhal/stm32f4/displays/st7789v.c @@ -67,9 +67,12 @@ __IO DISP_MEM_TYPE *const DISPLAY_DATA_ADDRESS = #define DISPLAY_ID_ILI9341V 0x009341U static int DISPLAY_ORIENTATION = -1; +static buffer_offset_t BUFFER_OFFSET = {0}; void display_pixeldata(uint16_t c) { PIXELDATA(c); } +#ifdef DISPLAY_IDENTIFY + static uint32_t read_display_id(uint8_t command) { volatile uint8_t c = 0; uint32_t id = 0; @@ -105,6 +108,9 @@ static uint32_t display_identify(void) { id_set = 1; return id; } +#else +static uint32_t display_identify(void) { return DISPLAY_ID_ST7789V; } +#endif bool display_is_inverted() { bool inv_on = false; @@ -149,8 +155,6 @@ static void display_unsleep(void) { } } -static struct { uint16_t x, y; } BUFFER_OFFSET; - void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { x0 += BUFFER_OFFSET.x; x1 += BUFFER_OFFSET.x; @@ -183,70 +187,16 @@ int display_orientation(int degrees) { // 2 bytes per pixel because we're using RGB 5-6-5 format PIXELDATA(0x0000); } - - uint16_t shift = 0; - char BX = 0, BY = 0; +#ifdef TREZOR_MODEL_T uint32_t id = display_identify(); - if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) || - (id == DISPLAY_ID_ST7789V)) { -#define RGB (1 << 3) -#define ML (1 << 4) // vertical refresh order -#define MH (1 << 2) // horizontal refresh order -#define MV (1 << 5) -#define MX (1 << 6) -#define MY (1 << 7) - // MADCTL: Memory Data Access Control - reference: - // section 9.3 in the ILI9341 manual - // section 6.2.18 in the GC9307 manual - // section 8.12 in the ST7789V manual - uint8_t display_command_parameter = 0; - switch (degrees) { - case 0: - display_command_parameter = 0; - BY = (id == DISPLAY_ID_GC9307); - break; - case 90: - display_command_parameter = MV | MX | MH | ML; - BX = (id != DISPLAY_ID_GC9307); - shift = 1; - break; - case 180: - display_command_parameter = MX | MY | MH | ML; - BY = (id == DISPLAY_ID_GC9307); - shift = 1; - break; - case 270: - display_command_parameter = MV | MY; - BX = (id != DISPLAY_ID_GC9307); - break; - } - if (id == DISPLAY_ID_GC9307) { - display_command_parameter ^= RGB | MY; // XOR RGB and MY settings - } - CMD(0x36); - DATA(display_command_parameter); - - if (shift) { - // GATECTRL: Gate Control; NL = 240 gate lines, first scan line is - // gate 80.; gate scan direction 319 -> 0 - CMD(0xE4); - DATA(0x1D); - DATA(0x00); - DATA(0x11); - } else { - // GATECTRL: Gate Control; NL = 240 gate lines, first scan line is - // gate 80.; gate scan direction 319 -> 0 - CMD(0xE4); - DATA(0x1D); - DATA(0x0A); - DATA(0x11); - } - - // reset the column and page extents - display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); + if (id == DISPLAY_ID_GC9307) { + tf15411a_rotate(degrees, &BUFFER_OFFSET); + } else { + lx154a2422_rotate(degrees, &BUFFER_OFFSET); } - BUFFER_OFFSET.x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; - BUFFER_OFFSET.y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0; +#else + DISPLAY_PANEL_ROTATE(degrees, &BUFFER_OFFSET); +#endif } } return DISPLAY_ORIENTATION; @@ -355,13 +305,15 @@ void display_init(void) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); - // LCD_FMARK/PD12 (tearing effect) +#ifdef DISPLAY_TE_PIN + // LCD_FMARK (tearing effect) GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStructure.Alternate = 0; - GPIO_InitStructure.Pin = GPIO_PIN_12; - HAL_GPIO_Init(GPIOD, &GPIO_InitStructure); + GPIO_InitStructure.Pin = DISPLAY_TE_PIN; + HAL_GPIO_Init(DISPLAY_TE_PORT, &GPIO_InitStructure); +#endif GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; @@ -420,15 +372,18 @@ void display_reinit(void) { } void display_sync(void) { +#ifdef DISPLAY_TE_PIN uint32_t id = display_identify(); if (id && (id != DISPLAY_ID_GC9307)) { // synchronize with the panel synchronization signal // in order to avoid visual tearing effects - while (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) { + while (GPIO_PIN_SET == HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) { } - while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) { + while (GPIO_PIN_RESET == + HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) { } } +#endif } void display_refresh(void) {} diff --git a/core/embed/trezorhal/stm32f4/displays/st7789v.h b/core/embed/trezorhal/stm32f4/displays/st7789v.h index 70445ff1fb..2905585aa2 100644 --- a/core/embed/trezorhal/stm32f4/displays/st7789v.h +++ b/core/embed/trezorhal/stm32f4/displays/st7789v.h @@ -2,6 +2,12 @@ #define _ST7789V_H #include STM32_HAL_H + +typedef struct { + uint16_t x; + uint16_t y; +} buffer_offset_t; + #include TREZOR_BOARD // ILI9341V, GC9307 and ST7789V drivers support 240px x 320px display resolution diff --git a/core/embed/trezorhal/stm32f4/lowlevel.c b/core/embed/trezorhal/stm32f4/lowlevel.c index 6170e69fba..4e72208861 100644 --- a/core/embed/trezorhal/stm32f4/lowlevel.c +++ b/core/embed/trezorhal/stm32f4/lowlevel.c @@ -141,6 +141,7 @@ void periph_init(void) { __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); // enable the PVD (programmable voltage detector). // select the "2.7V" threshold (level 5). diff --git a/core/embed/trezorhal/stm32f4/sdcard.c b/core/embed/trezorhal/stm32f4/sdcard.c index a3a242b4d9..728c548064 100644 --- a/core/embed/trezorhal/stm32f4/sdcard.c +++ b/core/embed/trezorhal/stm32f4/sdcard.c @@ -44,6 +44,7 @@ */ #include STM32_HAL_H +#include TREZOR_BOARD #include @@ -68,7 +69,7 @@ void DMA2_Stream3_IRQHandler(void) { } static inline void sdcard_default_pin_state(void) { - HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // SD_ON/PC0 + HAL_GPIO_WritePin(SD_ENABLE_PORT, SD_ENABLE_PIN, GPIO_PIN_SET); // SD_ON HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET); // SD_DAT0/PC8 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET); // SD_DAT1/PC9 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_RESET); // SD_DAT2/PC10 @@ -82,8 +83,8 @@ static inline void sdcard_default_pin_state(void) { GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = GPIO_PIN_0; - HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_InitStructure.Pin = SD_ENABLE_PIN; + HAL_GPIO_Init(SD_ENABLE_PORT, &GPIO_InitStructure); // configure SD GPIO GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; @@ -99,12 +100,13 @@ static inline void sdcard_default_pin_state(void) { GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = GPIO_PIN_13; - HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_InitStructure.Pin = SD_DETECT_PIN; + HAL_GPIO_Init(SD_DETECT_PORT, &GPIO_InitStructure); } static inline void sdcard_active_pin_state(void) { - HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // SD_ON/PC0 + HAL_GPIO_WritePin(SD_ENABLE_PORT, SD_ENABLE_PIN, + GPIO_PIN_RESET); // SD_ON/PC0 HAL_Delay(10); // we need to wait until the circuit fully kicks-in GPIO_InitTypeDef GPIO_InitStructure; @@ -210,7 +212,8 @@ void sdcard_power_off(void) { } secbool sdcard_is_present(void) { - return sectrue * (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)); + return sectrue * + (GPIO_PIN_RESET == HAL_GPIO_ReadPin(SD_DETECT_PORT, SD_DETECT_PIN)); } uint64_t sdcard_get_capacity_in_bytes(void) { diff --git a/core/embed/trezorhal/stm32f4/touch/ft6x36.c b/core/embed/trezorhal/stm32f4/touch/ft6x36.c index ab53da47f3..3cdde5a70e 100644 --- a/core/embed/trezorhal/stm32f4/touch/ft6x36.c +++ b/core/embed/trezorhal/stm32f4/touch/ft6x36.c @@ -47,15 +47,14 @@ static void touch_default_pin_state(void) { // set power off and other pins as per section 3.5 of FT6236 datasheet - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, - GPIO_PIN_SET); // CTP_ON/PB10 (active low) i.e.- CTPM power + 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 - HAL_GPIO_WritePin( - GPIOC, GPIO_PIN_4, - GPIO_PIN_RESET); // CTP_INT/PC4 normally an input, but drive low as an - // output while powered off - HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, - GPIO_PIN_RESET); // CTP_REST/PC5 (active low) i.e.- CTPM + 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 + HAL_GPIO_WritePin(TOUCH_RST_PORT, TOUCH_RST_PIN, + GPIO_PIN_RESET); // CTP_REST (active low) i.e.- CTPM // held in reset until released // set above pins to OUTPUT / NOPULL @@ -64,10 +63,12 @@ static void touch_default_pin_state(void) { GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = GPIO_PIN_10; - HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); - GPIO_InitStructure.Pin = GPIO_PIN_4 | GPIO_PIN_5; - HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_InitStructure.Pin = TOUCH_INT_PIN; + HAL_GPIO_Init(TOUCH_INT_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = TOUCH_RST_PIN; + HAL_GPIO_Init(TOUCH_RST_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = TOUCH_ON_PIN; + HAL_GPIO_Init(TOUCH_ON_PORT, &GPIO_InitStructure); // in-case power was on, or CTPM was active make sure to wait long enough // for these changes to take effect. a reset needs to be low for @@ -77,20 +78,21 @@ static void touch_default_pin_state(void) { } static void touch_active_pin_state(void) { - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); // CTP_ON/PB10 + HAL_GPIO_WritePin(TOUCH_ON_PORT, TOUCH_ON_PIN, GPIO_PIN_RESET); // CTP_ON HAL_Delay(10); // we need to wait until the circuit fully kicks-in GPIO_InitTypeDef GPIO_InitStructure; - // PC4 capacitive touch panel module (CTPM) interrupt (INT) input + // capacitive touch panel module (CTPM) interrupt (INT) input GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = GPIO_PIN_4; - HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); - __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_4); + GPIO_InitStructure.Pin = TOUCH_INT_PIN; + HAL_GPIO_Init(TOUCH_INT_PORT, &GPIO_InitStructure); + __HAL_GPIO_EXTI_CLEAR_FLAG(TOUCH_INT_PIN); - HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET); // release CTPM reset + HAL_GPIO_WritePin(TOUCH_RST_PORT, TOUCH_RST_PIN, + GPIO_PIN_SET); // release CTPM reset HAL_Delay(310); // "Time of starting to report point after resetting" min is // 300ms, giving an extra 10ms } @@ -115,6 +117,7 @@ void touch_power_on(void) { // turn on CTP circuitry touch_active_pin_state(); + HAL_Delay(50); } @@ -131,9 +134,9 @@ void touch_init(void) { GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = GPIO_PIN_4; - HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); - __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_4); + GPIO_InitStructure.Pin = TOUCH_INT_PIN; + HAL_GPIO_Init(TOUCH_INT_PORT, &GPIO_InitStructure); + __HAL_GPIO_EXTI_CLEAR_FLAG(TOUCH_INT_PIN); touch_set_mode(); touch_sensitivity(0x06); @@ -161,9 +164,9 @@ uint32_t touch_is_detected(void) { // Reference section 1.2 of "Application Note for FT6x06 CTPM". we // configure the touch controller to use "interrupt trigger mode". - uint32_t event = __HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_4); + uint32_t event = __HAL_GPIO_EXTI_GET_FLAG(TOUCH_INT_PIN); if (event != 0) { - __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_4); + __HAL_GPIO_EXTI_CLEAR_FLAG(TOUCH_INT_PIN); } return event; @@ -239,8 +242,8 @@ uint32_t touch_read(void) { // first touch) (tested with FT6206) const uint32_t event_flag = touch_data[3] & 0xC0; if (touch_data[1] == GESTURE_NO_GESTURE) { - xy = touch_pack_xy((X_POS_MSB << 8) | X_POS_LSB, - (Y_POS_MSB << 8) | Y_POS_LSB); + xy = TRANSFORM_TOUCH_COORDS((X_POS_MSB << 8) | X_POS_LSB, + (Y_POS_MSB << 8) | Y_POS_LSB); if ((number_of_touch_points == 1) && (event_flag == EVENT_PRESS_DOWN)) { touching = 1; return TOUCH_START | xy; diff --git a/core/embed/vendorheader/T3W1/vendor_unsafe.json b/core/embed/vendorheader/T3W1/vendor_unsafe.json new file mode 100644 index 0000000000..ddc8741f1f --- /dev/null +++ b/core/embed/vendorheader/T3W1/vendor_unsafe.json @@ -0,0 +1,19 @@ +{ + "header_len": 4608, + "text": "UNSAFE, DO NOT USE!", + "hw_model": "T3W1", + "expiry": 0, + "version": [0, 1], + "sig_m": 2, + "trust": { + "show_vendor_string": true, + "require_user_click": true, + "red_background": true, + "delay": 1 + }, + "pubkeys": [ + "e28a8970753332bd72fef413e6b0b2ef1b4aadda7aa2c141f233712a6876b351", + "d4eec1869fb1b8a4e817516ad5a931557cb56805c3eb16e8f3a803d647df7869", + "772c8a442b7db06e166cfbc1ccbcbcde6f3eba76a4e98ef3ffc519502237d6ef" + ] +} diff --git a/core/embed/vendorheader/T3W1/vendor_unsafe.toif b/core/embed/vendorheader/T3W1/vendor_unsafe.toif new file mode 100644 index 0000000000..8c25f0ddd9 Binary files /dev/null and b/core/embed/vendorheader/T3W1/vendor_unsafe.toif differ diff --git a/core/embed/vendorheader/T3W1/vendorheader_unsafe_signed_dev.bin b/core/embed/vendorheader/T3W1/vendorheader_unsafe_signed_dev.bin new file mode 100644 index 0000000000..d18bca9311 Binary files /dev/null and b/core/embed/vendorheader/T3W1/vendorheader_unsafe_signed_dev.bin differ diff --git a/core/embed/vendorheader/T3W1/vendorheader_unsafe_signed_prod.bin b/core/embed/vendorheader/T3W1/vendorheader_unsafe_signed_prod.bin new file mode 100644 index 0000000000..d18bca9311 Binary files /dev/null and b/core/embed/vendorheader/T3W1/vendorheader_unsafe_signed_prod.bin differ diff --git a/core/embed/vendorheader/T3W1/vendorheader_unsafe_unsigned.bin b/core/embed/vendorheader/T3W1/vendorheader_unsafe_unsigned.bin new file mode 100644 index 0000000000..4027561550 Binary files /dev/null and b/core/embed/vendorheader/T3W1/vendorheader_unsafe_unsigned.bin differ diff --git a/core/embed/vendorheader/generate.sh b/core/embed/vendorheader/generate.sh index 7dc1a264fa..31888dbbca 100755 --- a/core/embed/vendorheader/generate.sh +++ b/core/embed/vendorheader/generate.sh @@ -16,7 +16,7 @@ for arg in "$@"; do fi done -MODELS=(T2T1 T2B1 D001) +MODELS=(T2T1 T2B1 T3W1 D001) for MODEL in ${MODELS[@]}; do cd $MODEL diff --git a/core/site_scons/boards/trezor_t3w1_d1.py b/core/site_scons/boards/trezor_t3w1_d1.py new file mode 100644 index 0000000000..79eff5a920 --- /dev/null +++ b/core/site_scons/boards/trezor_t3w1_d1.py @@ -0,0 +1,90 @@ +from __future__ import annotations + +from . import get_hw_model_as_number +from .stm32f4_common import stm32f4_common_files + + +def configure( + env: dict, + features_wanted: list[str], + defines: list[str | tuple[str, str]], + sources: list[str], + paths: list[str], +) -> list[str]: + features_available: list[str] = [] + board = "trezor_t3w1_d1.h" + display = "st7789v.c" + hw_model = get_hw_model_as_number("T3W1") + hw_revision = 0 + features_available.append("disp_i8080_16bit_dw") + + mcu = "STM32F427xx" + + stm32f4_common_files(env, defines, sources, paths) + + env.get("ENV")[ + "CPU_ASFLAGS" + ] = "-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16" + env.get("ENV")[ + "CPU_CCFLAGS" + ] = "-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 " + env.get("ENV")["RUST_TARGET"] = "thumbv7em-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_T3W1_layout.c", + ] + sources += [f"embed/trezorhal/stm32f4/displays/{display}"] + sources += ["embed/trezorhal/stm32f4/backlight_pwm.c"] + sources += ["embed/trezorhal/stm32f4/displays/panels/lhs200kb-if21.c"] + features_available.append("backlight") + + if "input" in features_wanted: + sources += ["embed/lib/touch.c"] + sources += ["embed/trezorhal/stm32f4/i2c.c"] + sources += ["embed/trezorhal/stm32f4/touch/ft6x36.c"] + features_available.append("touch") + sources += ["embed/trezorhal/stm32f4/button.c"] + features_available.append("button") + + if "sd_card" in features_wanted: + sources += ["embed/trezorhal/stm32f4/sdcard.c"] + sources += ["embed/extmod/modtrezorio/ff.c"] + sources += ["embed/extmod/modtrezorio/ffunicode.c"] + features_available.append("sd_card") + + if "sd_card" in features_wanted: + sources += [ + "vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c" + ] + + if "sbu" in features_wanted: + sources += ["embed/trezorhal/stm32f4/sbu.c"] + features_available.append("sbu") + + if "usb" in features_wanted: + sources += [ + "embed/trezorhal/stm32f4/usb.c", + "embed/trezorhal/stm32f4/usbd_conf.c", + "embed/trezorhal/stm32f4/usbd_core.c", + "embed/trezorhal/stm32f4/usbd_ctlreq.c", + "embed/trezorhal/stm32f4/usbd_ioreq.c", + "vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c", + ] + features_available.append("usb") + + if "dma2d" in features_wanted: + defines += ["USE_DMA2D"] + sources += ["embed/trezorhal/stm32f4/dma2d.c"] + sources += [ + "vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c", + ] + features_available.append("dma2d") + + env.get("ENV")["TREZOR_BOARD"] = board + env.get("ENV")["MCU_TYPE"] = mcu + + return features_available diff --git a/core/site_scons/tools.py b/core/site_scons/tools.py index dccbb9f1d4..7ad16f4d55 100644 --- a/core/site_scons/tools.py +++ b/core/site_scons/tools.py @@ -3,6 +3,8 @@ from __future__ import annotations import subprocess from pathlib import Path +import subprocess + from boards import ( discovery, trezor_1, @@ -11,6 +13,7 @@ from boards import ( trezor_r_v6, trezor_r_v10, trezor_t, + trezor_t3w1_d1, ) HERE = Path(__file__).parent.resolve() @@ -56,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 ('T3W1',): + return trezor_t3w1_d1.configure(env, features_wanted, defines, sources, paths) elif model in ("DISC1",): return discovery.configure(env, features_wanted, defines, sources, paths) raise Exception("Unknown model") @@ -68,6 +73,8 @@ def get_model_identifier(model: str) -> str: return "T2T1" elif model == "R": return "T2B1" + elif model == "T3W1": + return "T3W1" elif model == "DISC1": return "D001" else: diff --git a/python/src/trezorlib/firmware/models.py b/python/src/trezorlib/firmware/models.py index e6f917360e..c032e720a2 100644 --- a/python/src/trezorlib/firmware/models.py +++ b/python/src/trezorlib/firmware/models.py @@ -27,6 +27,7 @@ class Model(Enum): T = b"T2T1" R = b"T2B1" DISC1 = b"D001" + T3W1 = b"T3W1" @classmethod def from_hw_model(cls, hw_model: t.Union["Self", bytes]) -> "Self": @@ -201,15 +202,42 @@ TREZOR_R = ModelKeys( firmware_sigs_needed=-1, ) + +TREZOR_T3W1 = 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, +) + TREZOR_R_DEV = TREZOR_T_DEV DISC1 = TREZOR_T_DEV DISC1_DEV = TREZOR_T_DEV +TREZOR_T3W1_DEV = TREZOR_T_DEV MODEL_MAP = { Model.ONE: TREZOR_ONE_V3, Model.T: TREZOR_T, Model.R: TREZOR_R, Model.DISC1: DISC1, + Model.T3W1: TREZOR_T3W1, } MODEL_MAP_DEV = { @@ -217,4 +245,5 @@ MODEL_MAP_DEV = { Model.T: TREZOR_T_DEV, Model.R: TREZOR_R_DEV, Model.DISC1: DISC1_DEV, + Model.T3W1: TREZOR_T3W1_DEV, } diff --git a/python/src/trezorlib/models.py b/python/src/trezorlib/models.py index f10eaabf13..87dd8db937 100644 --- a/python/src/trezorlib/models.py +++ b/python/src/trezorlib/models.py @@ -70,7 +70,16 @@ TREZOR_DISC1 = TrezorModel( default_mapping=mapping.DEFAULT_MAPPING, ) -TREZORS = {TREZOR_ONE, TREZOR_T, TREZOR_R, TREZOR_DISC1} +TREZOR_T3W1 = TrezorModel( + name="T3W1", + internal_name="T3W1", + minimum_version=(2, 1, 0), + vendors=VENDORS, + usb_ids=((0x1209, 0x53C1), (0x1209, 0x53C0)), + default_mapping=mapping.DEFAULT_MAPPING, +) + +TREZORS = {TREZOR_ONE, TREZOR_T, TREZOR_R, TREZOR_T3W1, TREZOR_DISC1} def by_name(name: Optional[str]) -> Optional[TrezorModel]: