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:
parent
1a9bb11806
commit
08efb32632
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user