1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-23 14:58:09 +00:00

fix(core): improve tearing effect prevention

[no changelog]
This commit is contained in:
tychovrahe 2022-12-13 12:40:02 +01:00 committed by TychoVrahe
parent 996fec5aae
commit 52cd43bf29
10 changed files with 59 additions and 7 deletions

View File

@ -43,6 +43,7 @@ int display_backlight(int val);
void display_init(void); void display_init(void);
void display_reinit(void); void display_reinit(void);
void display_sync(void);
void display_refresh(void); void display_refresh(void);
const char *display_save(const char *prefix); const char *display_save(const char *prefix);
void display_clear_save(void); void display_clear_save(void);

View File

@ -293,6 +293,7 @@ fn generate_trezorhal_bindings() {
.allowlist_function("display_pixeldata") .allowlist_function("display_pixeldata")
.allowlist_function("display_pixeldata_dirty") .allowlist_function("display_pixeldata_dirty")
.allowlist_function("display_set_window") .allowlist_function("display_set_window")
.allowlist_function("display_sync")
.allowlist_var("DISPLAY_CMD_ADDRESS") .allowlist_var("DISPLAY_CMD_ADDRESS")
.allowlist_var("DISPLAY_DATA_ADDRESS") .allowlist_var("DISPLAY_DATA_ADDRESS")
.allowlist_type("toif_format_t") .allowlist_type("toif_format_t")

View File

@ -169,3 +169,9 @@ pub fn get_offset() -> (i16, i16) {
(x as i16, y as i16) (x as i16, y as i16)
} }
} }
pub fn sync() {
unsafe {
ffi::display_sync();
}
}

View File

@ -826,6 +826,10 @@ pub fn set_window(window: Rect) {
); );
} }
pub fn sync() {
display::sync();
}
pub fn get_color_table(fg_color: Color, bg_color: Color) -> [Color; 16] { pub fn get_color_table(fg_color: Color, bg_color: Color) -> [Color; 16] {
let mut table: [Color; 16] = [Color::from_u16(0); 16]; let mut table: [Color; 16] = [Color::from_u16(0); 16];

View File

@ -18,6 +18,7 @@ use crate::{
ui::{ ui::{
component::{Child, Component, Event, EventCtx, Never, TimerToken}, component::{Child, Component, Event, EventCtx, Never, TimerToken},
constant, constant,
display::sync,
geometry::Rect, geometry::Rect,
}, },
}; };
@ -200,6 +201,8 @@ impl LayoutObj {
unsafe { Gc::as_mut(&mut inner.root) }.obj_place(constant::screen()); unsafe { Gc::as_mut(&mut inner.root) }.obj_place(constant::screen());
} }
sync();
// SAFETY: `inner.root` is unique because of the `inner.borrow_mut()`. // SAFETY: `inner.root` is unique because of the `inner.borrow_mut()`.
unsafe { Gc::as_mut(&mut inner.root) }.obj_paint() unsafe { Gc::as_mut(&mut inner.root) }.obj_paint()
} }

View File

@ -192,6 +192,7 @@ void collect_hw_entropy(void) {
void ensure_compatible_settings(void) { void ensure_compatible_settings(void) {
#ifdef TREZOR_MODEL_T #ifdef TREZOR_MODEL_T
display_set_big_endian(); display_set_big_endian();
display_orientation(0);
set_core_clock(CLOCK_168_MHZ); set_core_clock(CLOCK_168_MHZ);
display_set_slow_pwm(); display_set_slow_pwm();
#endif #endif

View File

@ -151,11 +151,20 @@ int display_orientation(int degrees) {
if (degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270) { if (degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270) {
DISPLAY_ORIENTATION = degrees; DISPLAY_ORIENTATION = degrees;
display_set_window(0, 0, MAX_DISPLAY_RESX - 1, MAX_DISPLAY_RESY - 1);
for (uint32_t i = 0; i < MAX_DISPLAY_RESX * MAX_DISPLAY_RESY; i++) {
// 2 bytes per pixel because we're using RGB 5-6-5 format
PIXELDATA(0x0000);
}
uint16_t shift = 0;
char BX = 0, BY = 0; char BX = 0, BY = 0;
uint32_t id = display_identify(); uint32_t id = display_identify();
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) || if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
(id == DISPLAY_ID_ST7789V)) { (id == DISPLAY_ID_ST7789V)) {
#define RGB (1 << 3) #define RGB (1 << 3)
#define ML (1 << 4) // vertical refresh order
#define MH (1 << 2) // horizontal refresh order
#define MV (1 << 5) #define MV (1 << 5)
#define MX (1 << 6) #define MX (1 << 6)
#define MY (1 << 7) #define MY (1 << 7)
@ -170,12 +179,14 @@ int display_orientation(int degrees) {
BY = (id == DISPLAY_ID_GC9307); BY = (id == DISPLAY_ID_GC9307);
break; break;
case 90: case 90:
display_command_parameter = MV | MX; display_command_parameter = MV | MX | MH | ML;
BX = (id == DISPLAY_ID_GC9307); BX = (id != DISPLAY_ID_GC9307);
shift = 1;
break; break;
case 180: case 180:
display_command_parameter = MX | MY; display_command_parameter = MX | MY | MH | ML;
BY = (id != DISPLAY_ID_GC9307); BY = (id == DISPLAY_ID_GC9307);
shift = 1;
break; break;
case 270: case 270:
display_command_parameter = MV | MY; display_command_parameter = MV | MY;
@ -187,6 +198,23 @@ int display_orientation(int degrees) {
} }
CMD(0x36); CMD(0x36);
DATA(display_command_parameter); 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 // reset the column and page extents
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
} }
@ -634,18 +662,20 @@ void display_reinit(void) {
display_backlight(DISPLAY_BACKLIGHT); display_backlight(DISPLAY_BACKLIGHT);
} }
void display_refresh(void) { void display_sync(void) {
uint32_t id = display_identify(); uint32_t id = display_identify();
if (id && (id != DISPLAY_ID_GC9307)) { if (id && (id != DISPLAY_ID_GC9307)) {
// synchronize with the panel synchronization signal // synchronize with the panel synchronization signal
// in order to avoid visual tearing effects // in order to avoid visual tearing effects
while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) {
}
while (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) { while (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) {
} }
while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) {
}
} }
} }
void display_refresh(void) {}
void display_set_slow_pwm(void) { void display_set_slow_pwm(void) {
// enable PWM timer // enable PWM timer
TIM_HandleTypeDef TIM1_Handle; TIM_HandleTypeDef TIM1_Handle;

View File

@ -347,6 +347,8 @@ void display_init(void) {
display_init_seq(); display_init_seq();
} }
void display_sync(void) {}
void display_refresh(void) { void display_refresh(void) {
for (int y = 0; y < (DISPLAY_RESY / 8); y++) { for (int y = 0; y < (DISPLAY_RESY / 8); y++) {
display_set_page_and_col(y, 0); display_set_page_and_col(y, 0);

View File

@ -247,6 +247,8 @@ static void rotate_oled_buffer(void) {
} }
} }
void display_sync(void) {}
void display_refresh(void) { void display_refresh(void) {
static const uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00, static const uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00,
OLED_SETHIGHCOLUMN | 0x00, OLED_SETHIGHCOLUMN | 0x00,

View File

@ -234,6 +234,8 @@ void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
PIXELWINDOW.pos.y = y0; PIXELWINDOW.pos.y = y0;
} }
void display_sync(void) {}
void display_refresh(void) { void display_refresh(void) {
if (!RENDERER) { if (!RENDERER) {
display_init(); display_init();