diff --git a/core/assets/device_name_T.png b/core/assets/device_name_T.png new file mode 100644 index 000000000..93f17c7bc Binary files /dev/null and b/core/assets/device_name_T.png differ diff --git a/core/assets/lock_empty.png b/core/assets/lock_empty.png new file mode 100644 index 000000000..e7145516a Binary files /dev/null and b/core/assets/lock_empty.png differ diff --git a/core/assets/lock_full.png b/core/assets/lock_full.png new file mode 100644 index 000000000..7bbf058ef Binary files /dev/null and b/core/assets/lock_full.png differ diff --git a/core/assets/logo.jpg b/core/assets/logo.jpg deleted file mode 100644 index a3b4eecc9..000000000 Binary files a/core/assets/logo.jpg and /dev/null differ diff --git a/core/assets/start.png b/core/assets/start.png new file mode 100644 index 000000000..adeed3046 Binary files /dev/null and b/core/assets/start.png differ diff --git a/core/embed/bootloader/bootui.c b/core/embed/bootloader/bootui.c index 141b60d96..85c45196b 100644 --- a/core/embed/bootloader/bootui.c +++ b/core/embed/bootloader/bootui.c @@ -117,6 +117,7 @@ void ui_screen_boot_click(void) { // welcome UI +void ui_screen_welcome_model(void) { screen_welcome_model(); } void ui_screen_welcome(void) { screen_welcome(); } uint32_t ui_screen_intro(const vendor_header *const vhdr, diff --git a/core/embed/bootloader/bootui.h b/core/embed/bootloader/bootui.h index 5159d7a7a..6b6dc5e4e 100644 --- a/core/embed/bootloader/bootui.h +++ b/core/embed/bootloader/bootui.h @@ -37,6 +37,7 @@ void ui_screen_boot(const vendor_header* const vhdr, void ui_screen_boot_wait(int wait_seconds); void ui_screen_boot_click(void); +void ui_screen_welcome_model(void); void ui_screen_welcome(void); uint32_t ui_screen_intro(const vendor_header* const vhdr, diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index a00567ac3..10875fccc 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -359,6 +359,8 @@ int main(void) { ui_set_initial_setup(true); + ui_screen_welcome_model(); + hal_delay(1000); ui_screen_welcome(); // erase storage diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 6f157a691..d4c5fc6ec 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -135,8 +135,6 @@ int main(void) { sdcard_init(); #endif - display_clear(); - #if !defined TREZOR_MODEL_1 // jump to unprivileged mode // http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html diff --git a/core/embed/rust/rust_ui.h b/core/embed/rust/rust_ui.h index 1cd3b6bba..b27e0cc45 100644 --- a/core/embed/rust/rust_ui.h +++ b/core/embed/rust/rust_ui.h @@ -24,5 +24,6 @@ void screen_wipe_fail(void); uint32_t screen_install_success(const char* reboot_msg, bool initial_setup, bool complete_draw); uint32_t screen_install_fail(void); +void screen_welcome_model(void); void screen_welcome(void); void screen_boot_empty(bool firmware_present, bool fading); diff --git a/core/embed/rust/src/ui/geometry.rs b/core/embed/rust/src/ui/geometry.rs index 077ee9aa8..bab90e4f7 100644 --- a/core/embed/rust/src/ui/geometry.rs +++ b/core/embed/rust/src/ui/geometry.rs @@ -474,6 +474,7 @@ pub const TOP_CENTER: Alignment2D = (Alignment::Center, Alignment::Start); pub const CENTER: Alignment2D = (Alignment::Center, Alignment::Center); pub const BOTTOM_LEFT: Alignment2D = (Alignment::Start, Alignment::End); pub const BOTTOM_RIGHT: Alignment2D = (Alignment::End, Alignment::End); +pub const BOTTOM_CENTER: Alignment2D = (Alignment::Center, Alignment::End); #[derive(Copy, Clone, PartialEq, Eq)] pub enum Axis { diff --git a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs index 3f9b8c77a..c6b66a983 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs @@ -5,7 +5,7 @@ use crate::{ display::{self, Font}, event::TouchEvent, geometry::Point, - model_tt::constant, + model_tt::{component::WelcomeScreen, constant}, }, }; use heapless::String; @@ -16,6 +16,7 @@ mod connect; pub mod intro; pub mod menu; pub mod theme; +pub mod welcome; use crate::{ strutil::hexlify, @@ -23,7 +24,7 @@ use crate::{ component::text::paragraphs::{Paragraph, ParagraphVecShort, Paragraphs, VecExt}, constant::screen, display::{Color, Icon}, - geometry::{Alignment, LinearPlacement, CENTER}, + geometry::{Alignment, LinearPlacement, TOP_CENTER}, model_tt::{ bootloader::{ connect::Connect, @@ -33,6 +34,7 @@ use crate::{ CHECK40, DOWNLOAD32, FIRE32, FIRE40, LOGO_EMPTY, TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, WELCOME_HIGHLIGHT_COLOR, X24, }, + welcome::Welcome, }, component::{Button, ResultScreen}, theme::{ @@ -401,7 +403,7 @@ extern "C" fn screen_boot_empty(firmware_present: bool, fading: bool) { }; display::rect_fill(constant::screen(), bg); let icon = Icon::new(LOGO_EMPTY); - icon.draw(screen().center(), CENTER, fg, bg); + icon.draw(Point::new(screen().center().x, 48), TOP_CENTER, fg, bg); if fading { fadein(); @@ -502,16 +504,13 @@ extern "C" fn screen_install_success( } #[no_mangle] -extern "C" fn screen_welcome() { - fadeout(); - display::rect_fill(screen(), WELCOME_COLOR); - - let mut messages = ParagraphVecShort::new(); - messages.add(Paragraph::new(&theme::TEXT_WELCOME, "Get started with").centered()); - messages.add(Paragraph::new(&theme::TEXT_WELCOME, "your trezor at").centered()); - messages.add(Paragraph::new(&theme::TEXT_WELCOME_URL, "trezor.io/start").centered()); - let mut frame = - Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center()); - show(&mut frame, false); - fadein(); +extern "C" fn screen_welcome_model() { + let mut frame = WelcomeScreen::new(); + show(&mut frame, true); +} + +#[no_mangle] +extern "C" fn screen_welcome() { + let mut frame = Welcome::new(); + show(&mut frame, true); } diff --git a/core/embed/rust/src/ui/model_tt/bootloader/theme.rs b/core/embed/rust/src/ui/model_tt/bootloader/theme.rs index 090df5b13..c462d1320 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/theme.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/theme.rs @@ -69,7 +69,9 @@ pub const WARNING40: &[u8] = include_res!("model_tt/res/warning40.toif"); pub const CHECK24: &[u8] = include_res!("model_tt/res/check24.toif"); pub const CHECK40: &[u8] = include_res!("model_tt/res/check40.toif"); -pub const LOGO_EMPTY: &[u8] = include_res!("model_tt/res/trezor_empty.toif"); +pub const LOGO_EMPTY: &[u8] = include_res!("model_tt/res/lock_empty.toif"); +pub const DEVICE_NAME: &[u8] = include_res!("model_tt/res/device_name_T.toif"); +pub const START_URL: &[u8] = include_res!("model_tt/res/start.toif"); pub fn button_confirm() -> ButtonStyleSheet { ButtonStyleSheet { diff --git a/core/embed/rust/src/ui/model_tt/bootloader/welcome.rs b/core/embed/rust/src/ui/model_tt/bootloader/welcome.rs new file mode 100644 index 000000000..3ec205019 --- /dev/null +++ b/core/embed/rust/src/ui/model_tt/bootloader/welcome.rs @@ -0,0 +1,59 @@ +use crate::ui::{ + component::{Component, Event, EventCtx, Never, Pad}, + constant::screen, + display::{self, Font, Icon}, + geometry::{Offset, Rect, TOP_CENTER}, + model_tt::{ + bootloader::theme::{START_URL, WELCOME_COLOR}, + theme::{BLACK, GREY_MEDIUM, WHITE}, + }, +}; + +pub struct Welcome { + bg: Pad, +} + +impl Welcome { + pub fn new() -> Self { + Self { + bg: Pad::with_background(WELCOME_COLOR).with_clear(), + } + } +} + +impl Component for Welcome { + type Msg = Never; + + fn place(&mut self, bounds: Rect) -> Rect { + self.bg.place(screen()); + bounds + } + + fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option { + None + } + + fn paint(&mut self) { + self.bg.paint(); + display::text_center( + screen().top_center() + Offset::y(102), + "Get started with", + Font::NORMAL, + GREY_MEDIUM, + BLACK, + ); + display::text_center( + screen().top_center() + Offset::y(126), + "your Trezor at", + Font::NORMAL, + GREY_MEDIUM, + BLACK, + ); + Icon::new(START_URL).draw( + screen().top_center() + Offset::y(135), + TOP_CENTER, + WHITE, + BLACK, + ); + } +} diff --git a/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs b/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs index 1db1b35ae..7db76a14b 100644 --- a/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs +++ b/core/embed/rust/src/ui/model_tt/component/welcome_screen.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "bootloader")] +use crate::ui::model_tt::bootloader::theme::DEVICE_NAME; use crate::ui::{ component::{Component, Event, EventCtx, Never}, display::{self, Icon}, @@ -33,6 +35,13 @@ impl Component for WelcomeScreen { } fn paint(&mut self) { + Icon::new(theme::ICON_LOGO).draw( + self.area.top_center() + Offset::y(ICON_TOP_MARGIN), + geometry::TOP_CENTER, + theme::FG, + theme::BG, + ); + #[cfg(not(feature = "bootloader"))] display::text_center( self.area.bottom_center() - Offset::y(TEXT_BOTTOM_MARGIN), MODEL_NAME, @@ -40,9 +49,10 @@ impl Component for WelcomeScreen { theme::FG, theme::BG, ); - Icon::new(theme::ICON_LOGO).draw( - self.area.top_center() + Offset::y(ICON_TOP_MARGIN), - geometry::TOP_CENTER, + #[cfg(feature = "bootloader")] + Icon::new(DEVICE_NAME).draw( + self.area.bottom_center() - Offset::y(TEXT_BOTTOM_MARGIN) + Offset::y(1), + geometry::BOTTOM_CENTER, theme::FG, theme::BG, ); diff --git a/core/embed/rust/src/ui/model_tt/res/device_name_T.toif b/core/embed/rust/src/ui/model_tt/res/device_name_T.toif new file mode 100644 index 000000000..397bffd9d Binary files /dev/null and b/core/embed/rust/src/ui/model_tt/res/device_name_T.toif differ diff --git a/core/embed/rust/src/ui/model_tt/res/lock_empty.toif b/core/embed/rust/src/ui/model_tt/res/lock_empty.toif new file mode 100644 index 000000000..96836d2d2 Binary files /dev/null and b/core/embed/rust/src/ui/model_tt/res/lock_empty.toif differ diff --git a/core/embed/rust/src/ui/model_tt/res/lock_full.toif b/core/embed/rust/src/ui/model_tt/res/lock_full.toif new file mode 100644 index 000000000..5e1a79583 Binary files /dev/null and b/core/embed/rust/src/ui/model_tt/res/lock_full.toif differ diff --git a/core/embed/rust/src/ui/model_tt/res/logo.toif b/core/embed/rust/src/ui/model_tt/res/logo.toif deleted file mode 100644 index fa80ed960..000000000 Binary files a/core/embed/rust/src/ui/model_tt/res/logo.toif and /dev/null differ diff --git a/core/embed/rust/src/ui/model_tt/res/start.toif b/core/embed/rust/src/ui/model_tt/res/start.toif new file mode 100644 index 000000000..cd4331163 Binary files /dev/null and b/core/embed/rust/src/ui/model_tt/res/start.toif differ diff --git a/core/embed/rust/src/ui/model_tt/theme.rs b/core/embed/rust/src/ui/model_tt/theme.rs index d0cfb3e7c..82a9cba84 100644 --- a/core/embed/rust/src/ui/model_tt/theme.rs +++ b/core/embed/rust/src/ui/model_tt/theme.rs @@ -98,7 +98,7 @@ pub const IMAGE_BG_BACK_BTN: &[u8] = include_res!("model_tt/res/bg-back40.toif") pub const IMAGE_BG_BACK_BTN_TALL: &[u8] = include_res!("model_tt/res/bg-back52.toif"); // Welcome screen. -pub const ICON_LOGO: &[u8] = include_res!("model_tt/res/logo.toif"); +pub const ICON_LOGO: &[u8] = include_res!("model_tt/res/lock_full.toif"); // Default homescreen pub const IMAGE_HOMESCREEN: &[u8] = include_res!("model_tt/res/bg.jpg"); diff --git a/core/embed/trezorhal/displays/st7789v.c b/core/embed/trezorhal/displays/st7789v.c index 59629dd07..ae6f54000 100644 --- a/core/embed/trezorhal/displays/st7789v.c +++ b/core/embed/trezorhal/displays/st7789v.c @@ -647,20 +647,18 @@ void display_reinit(void) { // important for model T as this is not set in boardloader display_set_little_endian(); - // enable PWM timer - TIM_HandleTypeDef TIM1_Handle; - TIM1_Handle.Instance = TIM1; - TIM1_Handle.Init.Period = LED_PWM_TIM_PERIOD - 1; - // TIM1/APB2 source frequency equals to SystemCoreClock in our configuration, - // we want 1 MHz - TIM1_Handle.Init.Prescaler = SystemCoreClock / 1000000 - 1; - TIM1_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TIM1_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; - TIM1_Handle.Init.RepetitionCounter = 0; - HAL_TIM_PWM_Init(&TIM1_Handle); + uint32_t prev_arr = TIM1->ARR; + uint32_t prev_ccr1 = TIM1->CCR1; + + uint8_t prev_val = (prev_ccr1 * 255) / prev_arr; + DISPLAY_BACKLIGHT = prev_val; + DISPLAY_ORIENTATION = 0; pwm_period = LED_PWM_TIM_PERIOD; - display_backlight(DISPLAY_BACKLIGHT); + TIM1->CR1 |= TIM_CR1_ARPE; + TIM1->CR2 |= TIM_CR2_CCPC; + TIM1->CCR1 = pwm_period * prev_val / 255; + TIM1->ARR = LED_PWM_TIM_PERIOD - 1; } void display_sync(void) { @@ -678,20 +676,16 @@ void display_sync(void) { void display_refresh(void) {} void display_set_slow_pwm(void) { - // enable PWM timer - TIM_HandleTypeDef TIM1_Handle; - TIM1_Handle.Instance = TIM1; - TIM1_Handle.Init.Period = LED_PWM_SLOW_TIM_PERIOD - 1; - // TIM1/APB2 source frequency equals to SystemCoreClock in our configuration, - // we want 1 MHz - TIM1_Handle.Init.Prescaler = SystemCoreClock / 1000000 - 1; - TIM1_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TIM1_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; - TIM1_Handle.Init.RepetitionCounter = 0; - HAL_TIM_PWM_Init(&TIM1_Handle); + uint32_t prev_arr = TIM1->ARR; + uint32_t prev_ccr1 = TIM1->CCR1; + + uint8_t prev_val = (prev_ccr1 * 255) / prev_arr; pwm_period = LED_PWM_SLOW_TIM_PERIOD; - display_backlight(DISPLAY_BACKLIGHT); + TIM1->CR1 |= TIM_CR1_ARPE; + TIM1->CR2 |= TIM_CR2_CCPC; + TIM1->ARR = LED_PWM_SLOW_TIM_PERIOD - 1; + TIM1->CCR1 = pwm_period * prev_val / 255; } void display_set_little_endian(void) { diff --git a/core/src/boot.py b/core/src/boot.py index 4a88da4d5..e9a668939 100644 --- a/core/src/boot.py +++ b/core/src/boot.py @@ -21,7 +21,7 @@ from trezor.ui.layouts.homescreen import Lockscreen from apps.common.request_pin import can_lock_device, verify_user_pin -_WELCOME_SCREEN_MS = 1500 # how long do we want to show welcome screen (minimum) +_WELCOME_SCREEN_MS = 1200 # how long do we want to show welcome screen (minimum) def enforce_welcome_screen_duration() -> None: