From 8e43402e5857e3c0aad34bece3c480898ff2a8d8 Mon Sep 17 00:00:00 2001 From: cepetr Date: Fri, 31 May 2024 15:16:35 +0200 Subject: [PATCH] refactor(core/embed): improve display driver init/deinit [no changelog] --- core/embed/boardloader/main.c | 4 +- core/embed/bootloader/emulator.c | 2 +- core/embed/bootloader/main.c | 5 +- core/embed/firmware/main.c | 2 +- core/embed/prodtest/main.c | 3 +- core/embed/trezorhal/display.h | 21 ++- core/embed/trezorhal/stm32f4/common.c | 2 +- core/embed/trezorhal/stm32f4/displays/ltdc.c | 2 +- .../trezorhal/stm32f4/displays/st7789v.c | 2 +- .../stm32f4/displays/ug-2828tswig01.c | 2 +- .../stm32f4/displays/vg-2864ksweg01.c | 2 +- core/embed/trezorhal/stm32f4/supervise.c | 5 +- .../stm32f4/xdisplay/st-7789/display_driver.c | 43 +++--- .../stm32f429i-disc1/display_driver.c | 20 +-- .../stm32f4/xdisplay/ug-2828/display_driver.c | 23 ++- .../stm32f4/xdisplay/vg-2864/display_driver.c | 137 +++++++++--------- core/embed/trezorhal/stm32u5/common.c | 2 +- core/embed/trezorhal/stm32u5/displays/dsi.c | 2 +- .../xdisplay/stm32u5a9j-dk/display_driver.c | 75 +++++----- .../xdisplay/stm32u5a9j-dk/display_internal.h | 2 + .../xdisplay/stm32u5a9j-dk/display_ltdc_dsi.c | 7 +- core/embed/trezorhal/unix/display_driver.c | 46 +++--- core/embed/trezorhal/xdisplay.h | 29 ++-- core/embed/trezorhal/xdisplay_legacy.h | 10 +- core/embed/unix/main.c | 2 +- 25 files changed, 231 insertions(+), 219 deletions(-) diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index 6444fff90..9c07c2c2f 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -274,7 +274,8 @@ int main(void) { dma2d_init(); #endif - display_init(); + display_init(DISPLAY_RESET_CONTENT); + display_clear(); display_refresh(); @@ -324,6 +325,7 @@ int main(void) { // This includes the version of bootloader potentially updated from SD card. write_bootloader_min_version(hdr->monotonic); + display_deinit(DISPLAY_RETAIN_CONTENT); ensure_compatible_settings(); mpu_config_off(); diff --git a/core/embed/bootloader/emulator.c b/core/embed/bootloader/emulator.c index fb570b0c9..473357a22 100644 --- a/core/embed/bootloader/emulator.c +++ b/core/embed/bootloader/emulator.c @@ -92,7 +92,7 @@ bool load_firmware(const char *filename, uint8_t *hash) { } __attribute__((noreturn)) int main(int argc, char **argv) { - display_init(); + display_init(DISPLAY_RESET_CONTENT); flash_init(); flash_otp_init(); diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index 95603eca2..e3e286e2a 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -330,7 +330,7 @@ void real_jump_to_firmware(void) { ui_screen_boot_stage_1(false); } - display_finish_actions(); + display_deinit(DISPLAY_RETAIN_CONTENT); ensure_compatible_settings(); mpu_config_off(); @@ -339,7 +339,6 @@ void real_jump_to_firmware(void) { #ifdef STM32U5 __attribute__((noreturn)) void jump_to_fw_through_reset(void) { - display_finish_actions(); display_fade(display_backlight(-1), 0, 200); disable_irq(); @@ -371,7 +370,7 @@ int bootloader_main(void) { i2c_init(); #endif - display_reinit(); + display_init(DISPLAY_RETAIN_CONTENT); #ifdef USE_DMA2D dma2d_init(); diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 8c1c55525..357dcd5e1 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -155,7 +155,7 @@ int main(void) { dma2d_init(); #endif - display_reinit(); + display_init(DISPLAY_RETAIN_CONTENT); #ifdef STM32U5 check_oem_keys(); diff --git a/core/embed/prodtest/main.c b/core/embed/prodtest/main.c index 433c591a3..973e3e76c 100644 --- a/core/embed/prodtest/main.c +++ b/core/embed/prodtest/main.c @@ -777,8 +777,7 @@ void cpuid_read(void) { int main(void) { svc_init(); - display_reinit(); - display_orientation(0); + display_init(DISPLAY_RETAIN_CONTENT); random_delays_init(); #ifdef STM32U5 secure_aes_init(); diff --git a/core/embed/trezorhal/display.h b/core/embed/trezorhal/display.h index 5e296a8f7..38091eec6 100644 --- a/core/embed/trezorhal/display.h +++ b/core/embed/trezorhal/display.h @@ -63,7 +63,7 @@ int display_orientation(int degrees); int display_get_orientation(void); int display_backlight(int val); -void display_init(void); +void display_init_all(void); void display_reinit(void); void display_sync(void); void display_refresh(void); @@ -77,5 +77,24 @@ uint8_t *display_get_wr_addr(void); void display_shift_window(uint16_t pixels); uint16_t display_get_window_offset(void); +typedef enum { + // Clear the display content + DISPLAY_RESET_CONTENT, + // Keeps the display without any changes + DISPLAY_RETAIN_CONTENT +} display_content_mode_t; + +static inline void display_init(display_content_mode_t mode) { + if (mode == DISPLAY_RESET_CONTENT) { + display_init_all(); + } else { + display_reinit(); + } +} + +static inline void display_deinit(display_content_mode_t mode) { + display_finish_actions(); +} + #endif // NEW_RENDERING #endif // TREZORHAL_DISPLAY_H diff --git a/core/embed/trezorhal/stm32f4/common.c b/core/embed/trezorhal/stm32f4/common.c index 88c397c27..dafde04c1 100644 --- a/core/embed/trezorhal/stm32f4/common.c +++ b/core/embed/trezorhal/stm32f4/common.c @@ -42,7 +42,7 @@ uint32_t systick_val_copy = 0; extern void shutdown_privileged(void); void __attribute__((noreturn)) trezor_shutdown(void) { - display_finish_actions(); + display_deinit(DISPLAY_RETAIN_CONTENT); #ifdef USE_SVC_SHUTDOWN svc_shutdown(); #else diff --git a/core/embed/trezorhal/stm32f4/displays/ltdc.c b/core/embed/trezorhal/stm32f4/displays/ltdc.c index 93ee9659e..515106e74 100644 --- a/core/embed/trezorhal/stm32f4/displays/ltdc.c +++ b/core/embed/trezorhal/stm32f4/displays/ltdc.c @@ -221,7 +221,7 @@ int display_backlight(int val) { void display_init_seq(void) { display_unsleep(); } -void display_init(void) { +void display_init_all(void) { GPIO_InitTypeDef GPIO_InitStructure = {0}; /* Enable the LTDC and DMA2D Clock */ diff --git a/core/embed/trezorhal/stm32f4/displays/st7789v.c b/core/embed/trezorhal/stm32f4/displays/st7789v.c index 5ab1adb0f..0ece17280 100644 --- a/core/embed/trezorhal/stm32f4/displays/st7789v.c +++ b/core/embed/trezorhal/stm32f4/displays/st7789v.c @@ -389,7 +389,7 @@ void display_setup_te_interrupt(void) { } #endif -void display_init(void) { +void display_init_all(void) { // init peripherals __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); diff --git a/core/embed/trezorhal/stm32f4/displays/ug-2828tswig01.c b/core/embed/trezorhal/stm32f4/displays/ug-2828tswig01.c index 4e09309a6..54c602e80 100644 --- a/core/embed/trezorhal/stm32f4/displays/ug-2828tswig01.c +++ b/core/embed/trezorhal/stm32f4/displays/ug-2828tswig01.c @@ -270,7 +270,7 @@ void display_init_seq(void) { display_unsleep(); } -void display_init(void) { +void display_init_all(void) { // init peripherals __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); diff --git a/core/embed/trezorhal/stm32f4/displays/vg-2864ksweg01.c b/core/embed/trezorhal/stm32f4/displays/vg-2864ksweg01.c index e841854e7..a7166a070 100644 --- a/core/embed/trezorhal/stm32f4/displays/vg-2864ksweg01.c +++ b/core/embed/trezorhal/stm32f4/displays/vg-2864ksweg01.c @@ -153,7 +153,7 @@ void display_handle_init(void) { spi_handle.Init.Mode = SPI_MODE_MASTER; } -void display_init(void) { +void display_init_all(void) { OLED_DC_CLK_ENA(); OLED_CS_CLK_ENA(); OLED_RST_CLK_ENA(); diff --git a/core/embed/trezorhal/stm32f4/supervise.c b/core/embed/trezorhal/stm32f4/supervise.c index d34806d08..83191ed08 100644 --- a/core/embed/trezorhal/stm32f4/supervise.c +++ b/core/embed/trezorhal/stm32f4/supervise.c @@ -31,6 +31,8 @@ __attribute__((noreturn)) static void _reboot_to_bootloader( #else __attribute__((noreturn)) static void _reboot_to_bootloader( boot_command_t boot_command) { + display_deinit(DISPLAY_RETAIN_CONTENT); + ensure_compatible_settings(); mpu_config_bootloader(); jump_to_with_flag(IMAGE_CODE_ALIGN(BOOTLOADER_START + IMAGE_HEADER_SIZE), boot_command); @@ -40,14 +42,12 @@ __attribute__((noreturn)) static void _reboot_to_bootloader( #endif void svc_reboot_to_bootloader(void) { - display_finish_actions(); boot_command_t boot_command = bootargs_get_command(); if (is_mode_unprivileged() && !is_mode_handler()) { register uint32_t r0 __asm__("r0") = boot_command; __asm__ __volatile__("svc %0" ::"i"(SVC_REBOOT_TO_BOOTLOADER), "r"(r0) : "memory"); } else { - ensure_compatible_settings(); _reboot_to_bootloader(boot_command); } } @@ -83,7 +83,6 @@ void SVC_C_Handler(uint32_t *stack) { ; break; case SVC_REBOOT_TO_BOOTLOADER: - ensure_compatible_settings(); __asm__ volatile("msr control, %0" ::"r"(0x0)); __asm__ volatile("isb"); 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 e486ebfaf..b49fcc0be 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c @@ -43,40 +43,33 @@ // Display driver instance display_driver_t g_display_driver; -void display_init(void) { +void display_init(display_content_mode_t mode) { display_driver_t* drv = &g_display_driver; memset(drv, 0, sizeof(display_driver_t)); - display_io_init_gpio(); - display_io_init_fmc(); - display_panel_init(); - display_panel_set_little_endian(); - backlight_pwm_init(BACKLIGHT_RESET); - -#ifdef XFRAMEBUFFER - display_io_init_te_interrupt(); -#endif -} - -void display_reinit(void) { - display_driver_t* drv = &g_display_driver; - memset(drv, 0, sizeof(display_driver_t)); - - // Reinitialize FMC to set correct timing - // We have to do this in reinit because boardloader is fixed. - display_io_init_fmc(); - - // Important for model T as this is not set in boardloader - display_panel_set_little_endian(); - display_panel_reinit(); - backlight_pwm_init(BACKLIGHT_RETAIN); + if (mode == DISPLAY_RESET_CONTENT) { + display_io_init_gpio(); + display_io_init_fmc(); + display_panel_init(); + display_panel_set_little_endian(); + backlight_pwm_init(BACKLIGHT_RESET); + } else { + // Reinitialize FMC to set correct timing + // We have to do this in reinit because boardloader is fixed. + display_io_init_fmc(); + + // Important for model T as this is not set in boardloader + display_panel_set_little_endian(); + display_panel_reinit(); + backlight_pwm_init(BACKLIGHT_RETAIN); + } #ifdef XFRAMEBUFFER display_io_init_te_interrupt(); #endif } -void display_finish_actions(void) { +void display_deinit(display_content_mode_t mode) { #ifdef XFRAMEBUFFER #ifndef BOARDLOADER display_ensure_refreshed(); diff --git a/core/embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_driver.c b/core/embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_driver.c index 378e63f70..27fa3c130 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_driver.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_driver.c @@ -44,24 +44,20 @@ typedef struct { // Display driver instance static display_driver_t g_display_driver; -void display_init(void) { +void display_init(display_content_mode_t mode) { display_driver_t *drv = &g_display_driver; memset(drv, 0, sizeof(display_driver_t)); drv->framebuf = (uint16_t *)FRAME_BUFFER_ADDR; - // Initialize LTDC controller - BSP_LCD_Init(); - // Initialize external display controller - ili9341_init(); -} - -void display_reinit(void) { - display_driver_t *drv = &g_display_driver; - memset(drv, 0, sizeof(display_driver_t)); - drv->framebuf = (uint16_t *)FRAME_BUFFER_ADDR; + if (mode == DISPLAY_RESET_CONTENT) { + // Initialize LTDC controller + BSP_LCD_Init(); + // Initialize external display controller + ili9341_init(); + } } -void display_finish_actions(void) { +void display_deinit(display_content_mode_t mode) { // Not used and intentionally left empty } diff --git a/core/embed/trezorhal/stm32f4/xdisplay/ug-2828/display_driver.c b/core/embed/trezorhal/stm32f4/xdisplay/ug-2828/display_driver.c index 7c2363713..9de46d12c 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/ug-2828/display_driver.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/ug-2828/display_driver.c @@ -291,25 +291,20 @@ static void display_init_interface(void) { HAL_SRAM_Init(&display_sram, &normal_mode_timing, NULL); } -void display_init(void) { +void display_init(display_content_mode_t mode) { display_driver_t *drv = &g_display_driver; memset(drv, 0, sizeof(display_driver_t)); - // Initialize GPIO & FSMC controller - display_init_interface(); - // Initialize display controller - display_init_controller(); -} - -void display_reinit(void) { - display_driver_t *drv = &g_display_driver; - memset(drv, 0, sizeof(display_driver_t)); - - // !@# TODO backlight level?? + if (mode == DISPLAY_RESET_CONTENT) { + // Initialize GPIO & FSMC controller + display_init_interface(); + // Initialize display controller + display_init_controller(); + } } -void display_finish_actions(void) { - /// Not used and intentionally left empty +void display_deinit(display_content_mode_t mode) { + // Not used and intentionally left empty } int display_set_backlight(int level) { diff --git a/core/embed/trezorhal/stm32f4/xdisplay/vg-2864/display_driver.c b/core/embed/trezorhal/stm32f4/xdisplay/vg-2864/display_driver.c index c0860a2c3..a3c4a8196 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/vg-2864/display_driver.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/vg-2864/display_driver.c @@ -220,84 +220,79 @@ static void display_sync_with_fb(display_driver_t *drv) { HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); } -void display_init(void) { +void display_init(display_content_mode_t mode) { display_driver_t *drv = &g_display_driver; memset(drv, 0, sizeof(display_driver_t)); drv->backlight_level = 255; - OLED_DC_CLK_ENA(); - OLED_CS_CLK_ENA(); - OLED_RST_CLK_ENA(); - OLED_SPI_SCK_CLK_ENA(); - OLED_SPI_MOSI_CLK_ENA(); - OLED_SPI_CLK_ENA(); - - GPIO_InitTypeDef GPIO_InitStructure; - - // Set GPIO for OLED display - GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStructure.Pull = GPIO_NOPULL; - GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStructure.Alternate = 0; - GPIO_InitStructure.Pin = OLED_CS_PIN; - HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); - HAL_GPIO_Init(OLED_CS_PORT, &GPIO_InitStructure); - GPIO_InitStructure.Pin = OLED_DC_PIN; - HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); - HAL_GPIO_Init(OLED_DC_PORT, &GPIO_InitStructure); - GPIO_InitStructure.Pin = OLED_RST_PIN; - HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_RESET); - HAL_GPIO_Init(OLED_RST_PORT, &GPIO_InitStructure); - - // Enable SPI 1 for OLED display - GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; - GPIO_InitStructure.Pull = GPIO_NOPULL; - GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStructure.Alternate = OLED_SPI_AF; - GPIO_InitStructure.Pin = OLED_SPI_SCK_PIN; - HAL_GPIO_Init(OLED_SPI_SCK_PORT, &GPIO_InitStructure); - GPIO_InitStructure.Pin = OLED_SPI_MOSI_PIN; - HAL_GPIO_Init(OLED_SPI_MOSI_PORT, &GPIO_InitStructure); - - // Initialize SPI controller - display_init_spi(drv); - - // Set to CMD - HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); - // SPI deselect - HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); - - // Reset the LCD - HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_SET); - HAL_Delay(1); - HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_RESET); - HAL_Delay(1); - HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_SET); - - // SPI select - HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); - // Send initialization command sequence - display_send_bytes(drv, &vg_2864ksweg01_init_seq[0], - sizeof(vg_2864ksweg01_init_seq)); - // SPI deselect - HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); - - // Clear display internal framebuffer - display_sync_with_fb(drv); -} - -void display_reinit(void) { - display_driver_t *drv = &g_display_driver; - - memset(drv, 0, sizeof(display_driver_t)); - drv->backlight_level = 255; - - display_init_spi(drv); + if (mode == DISPLAY_RESET_CONTENT) { + OLED_DC_CLK_ENA(); + OLED_CS_CLK_ENA(); + OLED_RST_CLK_ENA(); + OLED_SPI_SCK_CLK_ENA(); + OLED_SPI_MOSI_CLK_ENA(); + OLED_SPI_CLK_ENA(); + + GPIO_InitTypeDef GPIO_InitStructure; + + // Set GPIO for OLED display + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Alternate = 0; + GPIO_InitStructure.Pin = OLED_CS_PIN; + HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); + HAL_GPIO_Init(OLED_CS_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = OLED_DC_PIN; + HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); + HAL_GPIO_Init(OLED_DC_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = OLED_RST_PIN; + HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_RESET); + HAL_GPIO_Init(OLED_RST_PORT, &GPIO_InitStructure); + + // Enable SPI 1 for OLED display + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Alternate = OLED_SPI_AF; + GPIO_InitStructure.Pin = OLED_SPI_SCK_PIN; + HAL_GPIO_Init(OLED_SPI_SCK_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = OLED_SPI_MOSI_PIN; + HAL_GPIO_Init(OLED_SPI_MOSI_PORT, &GPIO_InitStructure); + + // Initialize SPI controller + display_init_spi(drv); + + // Set to CMD + HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); + // SPI deselect + HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); + + // Reset the LCD + HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_SET); + HAL_Delay(1); + HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_RESET); + HAL_Delay(1); + HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_SET); + + // SPI select + HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); + // Send initialization command sequence + display_send_bytes(drv, &vg_2864ksweg01_init_seq[0], + sizeof(vg_2864ksweg01_init_seq)); + // SPI deselect + HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); + + // Clear display internal framebuffer + display_sync_with_fb(drv); + } else { + display_init_spi(drv); + } } -void display_finish_actions(void) { - /// Not used and intentionally left empty +void display_deinit(display_content_mode_t mode) { + // Not used and intentionally left empty } int display_set_backlight(int level) { diff --git a/core/embed/trezorhal/stm32u5/common.c b/core/embed/trezorhal/stm32u5/common.c index 0541aabbc..677678780 100644 --- a/core/embed/trezorhal/stm32u5/common.c +++ b/core/embed/trezorhal/stm32u5/common.c @@ -38,7 +38,7 @@ uint32_t systick_val_copy = 0; extern void shutdown_privileged(void); void __attribute__((noreturn)) trezor_shutdown(void) { - display_finish_actions(); + display_deinit(DISPLAY_RETAIN_CONTENT); __HAL_RCC_SAES_CLK_DISABLE(); // Erase all secrets diff --git a/core/embed/trezorhal/stm32u5/displays/dsi.c b/core/embed/trezorhal/stm32u5/displays/dsi.c index 785f05671..775a451a7 100644 --- a/core/embed/trezorhal/stm32u5/displays/dsi.c +++ b/core/embed/trezorhal/stm32u5/displays/dsi.c @@ -1654,7 +1654,7 @@ int display_orientation(int degrees) { return degrees; } int display_get_orientation(void) { return 0; } int display_backlight(int val) { return val; } -void display_init(void) { +void display_init_all(void) { RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the common periph clock diff --git a/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_driver.c b/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_driver.c index daa321df2..d60c4fd0b 100644 --- a/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_driver.c +++ b/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_driver.c @@ -41,44 +41,49 @@ typedef struct { // Display driver instance static display_driver_t g_display_driver; -void display_init(void) { - RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; - - // Initializes the common periph clock - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_DSI; - PeriphClkInit.DsiClockSelection = RCC_DSICLKSOURCE_PLL3; - PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3; - PeriphClkInit.PLL3.PLL3Source = RCC_PLLSOURCE_HSE; - PeriphClkInit.PLL3.PLL3M = 4; - PeriphClkInit.PLL3.PLL3N = 125; - PeriphClkInit.PLL3.PLL3P = 8; - PeriphClkInit.PLL3.PLL3Q = 2; - PeriphClkInit.PLL3.PLL3R = 24; - PeriphClkInit.PLL3.PLL3RGE = RCC_PLLVCIRANGE_0; - PeriphClkInit.PLL3.PLL3FRACN = 0; - PeriphClkInit.PLL3.PLL3ClockOut = RCC_PLL3_DIVP | RCC_PLL3_DIVR; - HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); - - // Clear framebuffers - memset(physical_frame_buffer_0, 0x00, PHYSICAL_FRAME_BUFFER_SIZE); - memset(physical_frame_buffer_1, 0x00, PHYSICAL_FRAME_BUFFER_SIZE); - - BSP_LCD_Init(0, LCD_ORIENTATION_PORTRAIT); - BSP_LCD_SetBrightness(0, 100); - BSP_LCD_DisplayOn(0); -} - -void display_reinit(void) { - BSP_LCD_Reinit(0); - if (current_frame_buffer == 0) { - BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S); +void display_init(display_content_mode_t mode) { + if (mode == DISPLAY_RESET_CONTENT) { + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + // Initializes the common periph clock + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_DSI; + PeriphClkInit.DsiClockSelection = RCC_DSICLKSOURCE_PLL3; + PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3; + PeriphClkInit.PLL3.PLL3Source = RCC_PLLSOURCE_HSE; + PeriphClkInit.PLL3.PLL3M = 4; + PeriphClkInit.PLL3.PLL3N = 125; + PeriphClkInit.PLL3.PLL3P = 8; + PeriphClkInit.PLL3.PLL3Q = 2; + PeriphClkInit.PLL3.PLL3R = 24; + PeriphClkInit.PLL3.PLL3RGE = RCC_PLLVCIRANGE_0; + PeriphClkInit.PLL3.PLL3FRACN = 0; + PeriphClkInit.PLL3.PLL3ClockOut = RCC_PLL3_DIVP | RCC_PLL3_DIVR; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + // Clear framebuffers + memset(physical_frame_buffer_0, 0x00, PHYSICAL_FRAME_BUFFER_SIZE); + memset(physical_frame_buffer_1, 0x00, PHYSICAL_FRAME_BUFFER_SIZE); + + BSP_LCD_Init(0, LCD_ORIENTATION_PORTRAIT); + BSP_LCD_SetBrightness(0, 100); + BSP_LCD_DisplayOn(0); } else { - BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S); + // Retain display content + BSP_LCD_Reinit(0); + if (current_frame_buffer == 0) { + BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S); + } else { + BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S); + } } } -void display_finish_actions(void) { - // Not used and intentionally left empty +void display_deinit(display_content_mode_t mode) { + if (mode == DISPLAY_RESET_CONTENT) { + BSP_LCD_DisplayOff(0); + BSP_LCD_SetBrightness(0, 0); + BSP_LCD_DeInit(0); + } } int display_set_backlight(int level) { @@ -112,8 +117,6 @@ int display_get_orientation(void) { return drv->orientation_angle; } -void display_set_compatible_settings() {} - void display_fill(const gfx_bitblt_t *bb) { display_fb_info_t fb = display_get_frame_buffer(); diff --git a/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_internal.h b/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_internal.h index cf3a1e8b6..4ebe2cea2 100644 --- a/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_internal.h +++ b/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_internal.h @@ -50,9 +50,11 @@ extern uint32_t current_frame_buffer; #define LCD_ORIENTATION_LANDSCAPE_ROT180 3U int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation); +int32_t BSP_LCD_DeInit(uint32_t Instance); int32_t BSP_LCD_Reinit(uint32_t Instance); int32_t BSP_LCD_SetBrightness(uint32_t Instance, uint32_t Brightness); int32_t BSP_LCD_DisplayOn(uint32_t Instance); +int32_t BSP_LCD_DisplayOff(uint32_t Instance); int32_t BSP_LCD_SetFrameBuffer(uint32_t Instance, uint32_t fb_addr); #endif // TREZOR_HAL_DISPLAY_INTERNAL_H diff --git a/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_ltdc_dsi.c b/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_ltdc_dsi.c index 4f7dc55c9..fcd1975b8 100644 --- a/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_ltdc_dsi.c +++ b/core/embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_ltdc_dsi.c @@ -202,6 +202,11 @@ static void DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi); * @retval BSP status. */ int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation) { + memset(&hlcd_gfxmmu, 0, sizeof(hlcd_gfxmmu)); + memset(&hlcd_ltdc, 0, sizeof(hlcd_ltdc)); + memset(&hlcd_dsi, 0, sizeof(hlcd_dsi)); + memset(&DSIVidCfg, 0, sizeof(DSIVidCfg)); + int32_t status = BSP_ERROR_NONE; if ((Instance >= LCD_INSTANCES_NBR) || @@ -1274,7 +1279,7 @@ static int32_t LCD_DeInit(void) { } /* Wait before entering in sleep mode */ - HAL_Delay(2000); + // HAL_Delay(2000); /* Put LCD in sleep mode */ if (HAL_DSI_ShortWrite(&hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, diff --git a/core/embed/trezorhal/unix/display_driver.c b/core/embed/trezorhal/unix/display_driver.c index ac4d23f2f..6a433c2e3 100644 --- a/core/embed/trezorhal/unix/display_driver.c +++ b/core/embed/trezorhal/unix/display_driver.c @@ -58,34 +58,18 @@ static display_driver_t g_display_driver; int sdl_display_res_x = DISPLAY_RESX, sdl_display_res_y = DISPLAY_RESY; int sdl_touch_offset_x, sdl_touch_offset_y; -void display_deinit(void) { - display_driver_t *drv = &g_display_driver; - - SDL_FreeSurface(drv->prev_saved); - SDL_FreeSurface(drv->buffer); - if (drv->background != NULL) { - SDL_DestroyTexture(drv->background); - } - if (drv->texture != NULL) { - SDL_DestroyTexture(drv->texture); - } - if (drv->renderer != NULL) { - SDL_DestroyRenderer(drv->renderer); - } - if (drv->window != NULL) { - SDL_DestroyWindow(drv->window); - } - SDL_Quit(); +static void display_exit_handler(void) { + display_deinit(DISPLAY_RESET_CONTENT); } -void display_init(void) { +void display_init(display_content_mode_t mode) { display_driver_t *drv = &g_display_driver; if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("%s\n", SDL_GetError()); error_shutdown("SDL_Init error"); } - atexit(display_deinit); + atexit(display_exit_handler); char *window_title = NULL; char *window_title_alloc = NULL; @@ -162,12 +146,24 @@ void display_init(void) { #endif } -void display_reinit(void) { - // not used -} +void display_deinit(display_content_mode_t mode) { + display_driver_t *drv = &g_display_driver; -void display_finish_actions(void) { - // not used + SDL_FreeSurface(drv->prev_saved); + SDL_FreeSurface(drv->buffer); + if (drv->background != NULL) { + SDL_DestroyTexture(drv->background); + } + if (drv->texture != NULL) { + SDL_DestroyTexture(drv->texture); + } + if (drv->renderer != NULL) { + SDL_DestroyRenderer(drv->renderer); + } + if (drv->window != NULL) { + SDL_DestroyWindow(drv->window); + } + SDL_Quit(); } int display_set_backlight(int level) { diff --git a/core/embed/trezorhal/xdisplay.h b/core/embed/trezorhal/xdisplay.h index 0fc3a1420..5dc6e9326 100644 --- a/core/embed/trezorhal/xdisplay.h +++ b/core/embed/trezorhal/xdisplay.h @@ -46,18 +46,27 @@ // MIPI - // - STM32U5A9J-DK Discovery Board -// Fully initializes the display controller. -void display_init(void); +// Specifies how display content should be handled during +// initialization or deinitialization. +typedef enum { + // Clear the display content + DISPLAY_RESET_CONTENT, + // Retain the display content + DISPLAY_RETAIN_CONTENT +} display_content_mode_t; -// Called in application or bootloader to reinitialize an already initialized -// display controller without any distrubing visible effect (blinking, etc.). -void display_reinit(void); +// Initializes the display controller. +// +// If `mode` is `DISPLAY_RETAIN_CONTENT`, ensure the driver was previously +// initialized and `display_deinit(DISPLAY_RETAIN_CONTENT)` was called. +void display_init(display_content_mode_t mode); -// Waits for any backround operations (such as DMA copying) and returns. +// Deinitializes the display controller. // -// The function provides a barrier when jumping between -// boardloader/bootloader and firmware. -void display_finish_actions(void); +// If `mode` is `DISPLAY_RETAIN_CONTENT`, wait for background operations to +// complete and disable interrupts, so the application can safely proceed to +// the next boot stage and call `display_init(DISPLAY_RETAIN_CONTENT)`. +void display_deinit(display_content_mode_t mode); // Sets display backlight level ranging from 0 (off)..255 (maximum). // @@ -122,7 +131,7 @@ void display_refresh(void); // This is used when switching between the firmware and the bootloader. void display_set_compatible_settings(void); -// Following function define display's bitblt interface. +// Following functions define display's bitblt interface. // // These functions draw directly to to display or to the // currently inactive framebuffer. diff --git a/core/embed/trezorhal/xdisplay_legacy.h b/core/embed/trezorhal/xdisplay_legacy.h index 0fc4d75cc..fddec1e7e 100644 --- a/core/embed/trezorhal/xdisplay_legacy.h +++ b/core/embed/trezorhal/xdisplay_legacy.h @@ -23,12 +23,12 @@ #include #include -// These declarationscode emulates will be removed after the -// final cleanup of display drivers. They are here just to simplify -// integration with the legacy code. +// These declarations will be removed after the final cleanup +// of display drivers. They are here just to simplify integration +// with the legacy code. // -// Most of these function are not called when NEW_RENDERING=1 -// and they are only needed to for succesfully code compilation +// Most of these functions are not called when NEW_RENDERING=1, +// and they are only needed for successful code compilation. #define DISPLAY_FRAMEBUFFER_WIDTH 768 #define DISPLAY_FRAMEBUFFER_HEIGHT 480 diff --git a/core/embed/unix/main.c b/core/embed/unix/main.c index cf8d5a8a0..ebabd7c3a 100644 --- a/core/embed/unix/main.c +++ b/core/embed/unix/main.c @@ -486,7 +486,7 @@ MP_NOINLINE int main_(int argc, char **argv) { pre_process_options(argc, argv); - display_init(); + display_init(DISPLAY_RESET_CONTENT); #if USE_TOUCH touch_init();