From 751390ec084dd60f84367ece055ce7977a608f08 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Mon, 6 May 2024 11:35:16 +0200 Subject: [PATCH] fix(core): fix old frame flicker when backlight is risen too soon [no changelog] --- .../stm32f4/xdisplay/st-7789/display_driver.c | 7 +++--- .../stm32f4/xdisplay/st-7789/display_fb.c | 24 +++++++++++++++---- .../stm32f4/xdisplay/st-7789/display_fb.h | 2 ++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c index 848843c2f..83df221c2 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c @@ -89,10 +89,9 @@ void display_finish_actions(void) { int display_set_backlight(int level) { #ifdef XFRAMEBUFFER #ifndef BOARDLOADER - // wait for DMA transfer to finish before changing backlight - // so that we know that panel has current data - if (backlight_pwm_get() != level && !is_mode_handler()) { - bg_copy_wait(); + // if turning on the backlight, wait until the panel is refreshed + if (backlight_pwm_get() < level && !is_mode_handler()) { + display_ensure_refreshed(); } #endif #endif diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c index d9aab839c..8c4400b0d 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c @@ -63,7 +63,8 @@ void display_physical_fb_clear(void) { } #ifndef BOARDLOADER -static bool pending_fb_switch = false; +static volatile bool pending_fb_switch = false; +static volatile uint32_t last_fb_update_time = 0; #endif #ifndef BOARDLOADER @@ -82,6 +83,7 @@ void DISPLAY_TE_INTERRUPT_HANDLER(void) { } pending_fb_switch = false; + last_fb_update_time = HAL_GetTick(); __HAL_GPIO_EXTI_CLEAR_FLAG(DISPLAY_TE_PIN); } @@ -93,7 +95,7 @@ static void wait_for_fb_switch(void) { } #endif -static void copy_fb_to_display(uint16_t *fb) { +static void copy_fb_to_display(const uint16_t *fb) { for (int i = 0; i < DISPLAY_RESX * DISPLAY_RESY; i++) { // 2 bytes per pixel because we're using RGB 5-6-5 format ISSUE_PIXEL_DATA(fb[i]); @@ -122,7 +124,7 @@ static void switch_fb_manually(void) { } #ifndef BOARDLOADER -static void switch_fb_in_backround(void) { +static void switch_fb_in_background(void) { if (current_frame_buffer == 0) { current_frame_buffer = 1; @@ -169,7 +171,7 @@ void display_refresh(void) { if (is_mode_handler()) { switch_fb_manually(); } else { - switch_fb_in_backround(); + switch_fb_in_background(); } #else display_panel_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); @@ -177,6 +179,20 @@ void display_refresh(void) { #endif } +void display_ensure_refreshed(void) { +#ifndef BOARDLOADER + if (!is_mode_handler()) { + wait_for_fb_switch(); + // the update time is collected after starting the BG copy, then we need to + // wait: for the bg copy to finish and for at least one full refresh cycle + // before we can consider the display fully redrawn + while (HAL_GetTick() - last_fb_update_time < 40) { + __WFI(); + } + } +#endif +} + void display_fill(const gfx_bitblt_t *bb) { display_fb_info_t fb = display_get_frame_buffer(); diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.h b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.h index d216be9c4..0afa1de2d 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.h +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.h @@ -27,6 +27,8 @@ // Clears both physical frame buffers void display_physical_fb_clear(void); +void display_ensure_refreshed(void); + #endif // XFRAMEBUFFER #endif // TREZORHAL_DISPLAY_FB_H