1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-24 07:28:34 +00:00

sd card test

This commit is contained in:
tychovrahe 2024-02-07 15:56:56 +01:00
parent 1a9bb11806
commit 08efb32632
9 changed files with 359 additions and 28 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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.

View File

@ -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);

View File

@ -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<T: AsRef<str>> 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<T: AsRef<str>> 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::<T>::split_bounds();
self.footer.place(bottom_area);
// let (_, bottom_area) = ResultFooter::<T>::split_bounds();
// self.footer.place(bottom_area);
screen()
}
@ -84,6 +84,6 @@ impl<T: AsRef<str>> Component for ErrorScreen<'_, T> {
);
self.title.paint();
self.message.paint();
self.footer.paint();
// self.footer.paint();
}
}

View File

@ -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<T> 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<TouchEvent> {
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<F>(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<F>(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);
}

View File

@ -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
}

View File

@ -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) {

View File

@ -2,15 +2,16 @@
#define _TOUCH_H
#include <stdint.h>
#include <stdbool.h>
#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);