diff --git a/core/Makefile b/core/Makefile index ff81363581..02e22f4628 100644 --- a/core/Makefile +++ b/core/Makefile @@ -29,7 +29,7 @@ PRODUCTION ?= 0 PYOPT ?= 1 BITCOIN_ONLY ?= 0 BOOTLOADER_QA ?= 0 -BOOTLOADER_DEVEL ?= 0 +BOOTLOADER_DEVEL ?= 1 TREZOR_MODEL ?= T TREZOR_MEMPERF ?= 0 ADDRESS_SANITIZER ?= 0 diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index f9fed5cc0f..7a5c085507 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -441,9 +441,10 @@ int bootloader_main(void) { optiga_hal_init(); #endif + bool touch_available = false; #ifdef USE_TOUCH touch_power_on(); - touch_init(); + touch_available = touch_init(); #endif #ifdef USE_BUTTON @@ -486,7 +487,7 @@ int bootloader_main(void) { // anyway uint32_t touched = 0; #ifdef USE_TOUCH - if (firmware_present == sectrue && stay_in_bootloader != sectrue) { + if (touch_available && firmware_present == sectrue && stay_in_bootloader != sectrue) { for (int i = 0; i < 100; i++) { touched = touch_is_detected() | touch_read(); if (touched) { diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index f21fdeac8b..a32992a19e 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -48,6 +48,7 @@ #include "mpu.h" #include "random_delays.h" #include "rust_ui.h" +#include "sdcard.h" #include TREZOR_BOARD @@ -89,6 +90,71 @@ #include "zkp_context.h" #endif + +bool check_cnt(const flash_area_t * area, int * cnt){ + // assuming one subarea + + int size = flash_area_get_size(area); + const uint32_t * addr = flash_area_get_address(area, 0, 0); + + bool clean = true; + + int zero_cnt = 0; + int clean_words = 0; + + for (int i = 0; i < size / sizeof(uint32_t); i++ ){ + if (clean && addr[i] == 0){ + clean_words += 1; + continue; + } else if (clean) { + uint32_t val = addr[i]; + + bool one = false; + zero_cnt = 0; + + + for (int j = 0; j < 32; j++){ + if (val & (1 << j)){ + one = true; + } else { + if (one){ + return false; + } + zero_cnt++; + } + } + + clean = false; + } else if (addr[i] != 0xFFFFFFFF) { + return false; + } + } + + *cnt = 32 * clean_words + zero_cnt; + + return true; +} + +void cnt_inc(const flash_area_t * area, uint32_t new_val) { + + uint32_t offset = (new_val / 32) * 4; + + uint32_t w = 0; + if (new_val % 32 == 0){ + offset -= 4; + w = 0; + }else { + w = 0xFFFFFFFF << (new_val % 32); + + } + (void)!flash_unlock_write(); + + (void)!flash_area_write_word(area, offset, w); + + (void)!flash_lock_write(); +} + + // from util.s extern void shutdown_privileged(void); @@ -133,7 +199,7 @@ int main(void) { check_and_replace_bootloader(); #endif // Enable MPU - mpu_config_firmware(); + //mpu_config_firmware(); #endif // Init peripherals @@ -164,8 +230,9 @@ int main(void) { i2c_init(); #endif + #ifdef USE_TOUCH - touch_init(); + bool touch_available = touch_init(); #endif #ifdef USE_SD_CARD @@ -182,13 +249,112 @@ int main(void) { #endif #if !defined TREZOR_MODEL_1 - drop_privileges(); + //drop_privileges(); #endif #ifdef USE_SECP256K1_ZKP ensure(sectrue * (zkp_context_init() == 0), NULL); #endif + sdcard_init(); + + + int cnt_success; + int cnt_fail; + + if (!check_cnt(&STORAGE_AREAS[0], &cnt_success)) { + (void)!flash_area_erase(&STORAGE_AREAS[0], NULL); + } + + if (!check_cnt(&STORAGE_AREAS[1], &cnt_fail)) { + (void)!flash_area_erase(&STORAGE_AREAS[1], NULL); + } + + + if (touch_available) { + uint32_t r = sdtest_init(cnt_success, cnt_fail); + + if (r == 2) { + (void)!flash_area_erase(&STORAGE_AREAS[0], NULL); + (void)!flash_area_erase(&STORAGE_AREAS[1], NULL); + cnt_success = 0; + cnt_fail = 0; + } + } + + + display_bar(0, 0, 240, 240, 0xE061); + + uint32_t data_wr[SDCARD_BLOCK_SIZE / sizeof(uint32_t)]; + uint32_t data_rd[SDCARD_BLOCK_SIZE / sizeof(uint32_t)]; + + for(;;){ + + uint32_t ticks = hal_ticks_ms(); + bool success = true; + if (sdcard_is_present()) { + sdcard_power_off(); + if (sectrue == sdcard_power_on()) { + + uint64_t cap = sdcard_get_capacity_in_bytes(); + + if (cap == 0) { + success = false; + } + else { + uint32_t BLOCK_END = cap / SDCARD_BLOCK_SIZE - 1; + uint32_t SDBACKUP_BLOCK_START = 0; + uint32_t SDBACKUP_N_WRITINGS = 100; + + for (int i = 0; i < SDCARD_BLOCK_SIZE / sizeof(uint32_t); i++) { + data_wr[i] = rng_get(); + } + + for (int n = 0; n < SDBACKUP_N_WRITINGS; n++) { + uint32_t block = SDBACKUP_BLOCK_START + n * (BLOCK_END - SDBACKUP_BLOCK_START) / (SDBACKUP_N_WRITINGS - 1); + data_wr[0] = block; + success &= sectrue == sdcard_write_blocks(data_wr, block, 1); + } + + sdcard_power_off(); + success &= sectrue == sdcard_power_on(); + + for (int n = 0; n < SDBACKUP_N_WRITINGS; n++) { + uint32_t block = SDBACKUP_BLOCK_START + n * (BLOCK_END - SDBACKUP_BLOCK_START) / (SDBACKUP_N_WRITINGS - 1); + success &= sectrue == sdcard_read_blocks(data_rd, block, 1); + data_wr[0] = block; + success &= memcmp(data_wr, data_rd, SDCARD_BLOCK_SIZE) == 0; + } + } + } else { + success = false; + } + } else { + success = false; + } + + if (success) + { + cnt_success++; + cnt_inc(&STORAGE_AREAS[0], cnt_success); + } else { + cnt_fail++; + cnt_inc(&STORAGE_AREAS[1], cnt_fail); + } + + sdtest_update(cnt_success, cnt_fail); + + uint32_t ticks_diff = hal_ticks_ms() - ticks; + + int delay = 10000 - ticks_diff; + + if (delay > 0) { + hal_delay(delay); + } + } + + + printf("CORE: Preparing stack\n"); // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. diff --git a/core/embed/rust/rust_ui.h b/core/embed/rust/rust_ui.h index 5f2ff97e1c..c1ec86d4d8 100644 --- a/core/embed/rust/rust_ui.h +++ b/core/embed/rust/rust_ui.h @@ -32,3 +32,6 @@ void display_image(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen); void display_icon(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen, uint16_t fg_color, uint16_t bg_color); void bld_continue_label(uint16_t bg_color); + +uint32_t sdtest_init(int32_t success, int32_t failure); +void sdtest_update(int32_t success, int32_t failure); diff --git a/core/embed/rust/src/ui/model_tt/component/error.rs b/core/embed/rust/src/ui/model_tt/component/error.rs index 739770f4f4..c44d118f10 100644 --- a/core/embed/rust/src/ui/model_tt/component/error.rs +++ b/core/embed/rust/src/ui/model_tt/component/error.rs @@ -7,7 +7,7 @@ use crate::ui::{ use crate::ui::model_tt::{ component::{ResultFooter, ResultStyle}, constant::WIDTH, - theme::{FATAL_ERROR_COLOR, ICON_WARNING40, RESULT_FOOTER_START, RESULT_PADDING, WHITE}, + theme::{FATAL_ERROR_COLOR, ICON_WARNING40, RESULT_PADDING, WHITE}, }; const ICON_TOP: i16 = 23; @@ -48,7 +48,6 @@ impl> Component for ErrorScreen<'_, T> { type Msg = Never; fn place(&mut self, _bounds: Rect) -> Rect { - self.bg.place(screen()); let title_area = Rect::new( Point::new(RESULT_PADDING, TITLE_AREA_START), @@ -58,12 +57,13 @@ impl> Component for ErrorScreen<'_, T> { let message_area = Rect::new( Point::new(RESULT_PADDING, MESSAGE_AREA_START), - Point::new(WIDTH - RESULT_PADDING, RESULT_FOOTER_START), + Point::new(WIDTH - RESULT_PADDING, 240), ); self.message.place(message_area); + self.bg.place(message_area); - let (_, bottom_area) = ResultFooter::::split_bounds(); - self.footer.place(bottom_area); + // let (_, bottom_area) = ResultFooter::::split_bounds(); + // self.footer.place(bottom_area); screen() } @@ -84,6 +84,6 @@ impl> Component for ErrorScreen<'_, T> { ); self.title.paint(); self.message.paint(); - self.footer.paint(); + // self.footer.paint(); } } diff --git a/core/embed/rust/src/ui/screens.rs b/core/embed/rust/src/ui/screens.rs index fa3c2cf5d8..1c2b916536 100644 --- a/core/embed/rust/src/ui/screens.rs +++ b/core/embed/rust/src/ui/screens.rs @@ -1,6 +1,20 @@ //! Reexporting the `screens` module according to the //! current feature (Trezor model) +use cty::int32_t; +use heapless::String; +use num_traits::ToPrimitive; +use crate::trezorhal::io::io_touch_read; +use crate::ui::component::{Component, Event, EventCtx, Label, Never}; +use crate::ui::constant::screen; +use crate::ui::display; +use crate::ui::display::Icon; +use crate::ui::event::TouchEvent; +use crate::ui::model_tt::component::bl_confirm::{Confirm, ConfirmTitle}; +use crate::ui::model_tt::component::{Button, ErrorScreen}; +use crate::ui::model_tt::constant; +use crate::ui::model_tt::theme::{BACKLIGHT_DIM, BACKLIGHT_NORMAL}; +use crate::ui::model_tt::theme::bootloader::{BLD_WIPE_COLOR, button_wipe_cancel, button_wipe_confirm, FIRE40, TEXT_WIPE_NORMAL}; #[cfg(all(feature = "model_tr", not(feature = "model_tt")))] pub use super::model_tr::screens::*; #[cfg(feature = "model_tt")] @@ -19,3 +33,146 @@ extern "C" fn screen_fatal_error_rust( screen_fatal_error(title, msg, footer); } + +pub trait ReturnToC { + fn return_to_c(self) -> u32; +} + +impl ReturnToC for Never { + fn return_to_c(self) -> u32 { + unreachable!() + } +} + +impl ReturnToC for T + where + T: ToPrimitive, +{ + fn return_to_c(self) -> u32 { + self.to_u32().unwrap() + } +} + + +fn fadein() { + display::fade_backlight_duration(BACKLIGHT_NORMAL, 150); +} + +fn fadeout() { + display::fade_backlight_duration(BACKLIGHT_DIM, 150); +} + + +fn touch_eval() -> Option { + let event = io_touch_read(); + if event == 0 { + return None; + } + let event_type = event >> 24; + let ex = ((event >> 12) & 0xFFF) as i16; + let ey = (event & 0xFFF) as i16; + + TouchEvent::new(event_type, ex as _, ey as _).ok() +} + + +fn run(frame: &mut F) -> u32 + where + F: Component, + F::Msg: ReturnToC, +{ + frame.place(constant::screen()); + fadeout(); + display::sync(); + frame.paint(); + display::refresh(); + fadein(); + + loop { + let event = touch_eval(); + if let Some(e) = event { + let mut ctx = EventCtx::new(); + let msg = frame.event(&mut ctx, Event::Touch(e)); + + if let Some(message) = msg { + return message.return_to_c(); + } + display::sync(); + frame.paint(); + display::refresh(); + } + } +} + +fn show(frame: &mut F, fading: bool) + where + F: Component, +{ + frame.place(screen()); + if fading { + fadeout() + }; + display::sync(); + frame.paint(); + display::refresh(); + if fading { + fadein() + }; +} + +#[no_mangle] +extern "C" fn sdtest_init( + success: int32_t, + failure: int32_t, +) -> u32 { + + let icon = Icon::new(FIRE40); + + let mut s: String<50> = String::new(); + unwrap!(s.push_str("Success: ")); + unwrap!(s.push_str(inttostr!(success))); + unwrap!(s.push_str("\n")); + unwrap!(s.push_str("Fail: ")); + unwrap!(s.push_str(inttostr!(failure))); + unwrap!(s.push_str("\n")); + unwrap!(s.push_str("Total: ")); + unwrap!(s.push_str(inttostr!(failure+success))); + unwrap!(s.push_str("\n")); + + let msg = Label::centered( + s.as_str(), + TEXT_WIPE_NORMAL, + ); + // let alert = Label::centered("SEED AND FIRMWARE\nWILL BE ERASED!", TEXT_WIPE_BOLD); + + let right = Button::with_text("RESET+TEST").styled(button_wipe_confirm()); + let left = Button::with_text("TEST").styled(button_wipe_cancel()); + + let mut frame = + Confirm::new(BLD_WIPE_COLOR, left, right, ConfirmTitle::Icon(icon), msg); + + run(&mut frame) + +} + +#[no_mangle] +extern "C" fn sdtest_update( + success: int32_t, + failure: int32_t, +) { + + + let mut s: String<50> = String::new(); + unwrap!(s.push_str("Success: ")); + unwrap!(s.push_str(inttostr!(success))); + unwrap!(s.push_str("\n")); + unwrap!(s.push_str("Fail: ")); + unwrap!(s.push_str(inttostr!(failure))); + unwrap!(s.push_str("\n")); + unwrap!(s.push_str("Total: ")); + unwrap!(s.push_str(inttostr!(failure+success))); + unwrap!(s.push_str("\n")); + + let mut frame = ErrorScreen::new("SD TEST RUNNING", s.as_str(), "Please wait"); + show(&mut frame, false); +} diff --git a/core/embed/trezorhal/stm32f4/displays/st7789v.c b/core/embed/trezorhal/stm32f4/displays/st7789v.c index 801a081274..878afa1e35 100644 --- a/core/embed/trezorhal/stm32f4/displays/st7789v.c +++ b/core/embed/trezorhal/stm32f4/displays/st7789v.c @@ -379,11 +379,11 @@ void display_sync(void) { 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(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) { - } - while (GPIO_PIN_RESET == - HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) { - } +// while (GPIO_PIN_SET == HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) { +// } +// while (GPIO_PIN_RESET == +// HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) { +// } } #endif } diff --git a/core/embed/trezorhal/stm32f4/touch/ft6x36.c b/core/embed/trezorhal/stm32f4/touch/ft6x36.c index 38d338168e..3e3a076226 100644 --- a/core/embed/trezorhal/stm32f4/touch/ft6x36.c +++ b/core/embed/trezorhal/stm32f4/touch/ft6x36.c @@ -97,19 +97,20 @@ static void touch_active_pin_state(void) { // 300ms, giving an extra 10ms } -void touch_set_mode(void) { +bool touch_set_mode(void) { // set register 0xA4 G_MODE to interrupt trigger mode (0x01). basically, CTPM // generates a pulse when new data is available uint8_t touch_panel_config[] = {0xA4, 0x01}; for (int i = 0; i < 3; i++) { if (HAL_OK == i2c_transmit(TOUCH_I2C_NUM, TOUCH_ADDRESS, touch_panel_config, sizeof(touch_panel_config), 10)) { - return; + return true; } i2c_cycle(TOUCH_I2C_NUM); } - ensure(secfalse, "Touch screen panel was not loaded properly."); + return false; + } void touch_power_on(void) { @@ -127,7 +128,7 @@ void touch_power_off(void) { touch_default_pin_state(); } -void touch_init(void) { +bool touch_init(void) { GPIO_InitTypeDef GPIO_InitStructure; // PC4 capacitive touch panel module (CTPM) interrupt (INT) input @@ -138,23 +139,25 @@ void touch_init(void) { HAL_GPIO_Init(TOUCH_INT_PORT, &GPIO_InitStructure); __HAL_GPIO_EXTI_CLEAR_FLAG(TOUCH_INT_PIN); - touch_set_mode(); - touch_sensitivity(TOUCH_SENSITIVITY); + if (!touch_set_mode()){ + return false; + } + return touch_sensitivity(TOUCH_SENSITIVITY); } -void touch_sensitivity(uint8_t value) { +bool touch_sensitivity(uint8_t value) { // set panel threshold (TH_GROUP) - default value is 0x12 uint8_t touch_panel_threshold[] = {0x80, value}; for (int i = 0; i < 3; i++) { if (HAL_OK == i2c_transmit(TOUCH_I2C_NUM, TOUCH_ADDRESS, touch_panel_threshold, sizeof(touch_panel_threshold), 10)) { - return; + return true; } i2c_cycle(TOUCH_I2C_NUM); } - ensure(secfalse, "Touch screen panel was not loaded properly."); + return false; } uint32_t touch_is_detected(void) { diff --git a/core/embed/trezorhal/touch.h b/core/embed/trezorhal/touch.h index 389c8a03f0..65d71b67e9 100644 --- a/core/embed/trezorhal/touch.h +++ b/core/embed/trezorhal/touch.h @@ -2,15 +2,16 @@ #define _TOUCH_H #include +#include #define TOUCH_START (1U << 24) #define TOUCH_MOVE (1U << 25) #define TOUCH_END (1U << 26) -void touch_init(void); +bool touch_init(void); void touch_power_on(void); void touch_power_off(void); -void touch_sensitivity(uint8_t value); +bool touch_sensitivity(uint8_t value); uint32_t touch_read(void); uint32_t touch_click(void); uint32_t touch_is_detected(void);