From d4efd46b0996ffcde129811f1dcf747084df2281 Mon Sep 17 00:00:00 2001 From: cepetr Date: Wed, 24 Apr 2024 08:53:17 +0200 Subject: [PATCH] fixup! feat(core): refactor display drivers --- .../stm32f4/display/st-7789/display_driver.c | 83 +------------- .../stm32f4/display/st-7789/display_fb.c | 54 ++++++++- .../stm32f4/display/st-7789/display_fb.h | 24 +--- .../stm32f4/display/st-7789/display_nofb.c | 107 ++++++++++++++++++ core/site_scons/boards/trezor_t.py | 1 + core/site_scons/boards/trezor_t3t1_revE.py | 1 + core/site_scons/boards/trezor_t3t1_v4.py | 1 + 7 files changed, 168 insertions(+), 103 deletions(-) create mode 100644 core/embed/trezorhal/stm32f4/display/st-7789/display_nofb.c diff --git a/core/embed/trezorhal/stm32f4/display/st-7789/display_driver.c b/core/embed/trezorhal/stm32f4/display/st-7789/display_driver.c index b8d81be4e..848843c2f 100644 --- a/core/embed/trezorhal/stm32f4/display/st-7789/display_driver.c +++ b/core/embed/trezorhal/stm32f4/display/st-7789/display_driver.c @@ -110,8 +110,7 @@ int display_set_orientation(int angle) { drv->orientation_angle = angle; #ifdef XFRAMEBUFFER - memset(physical_frame_buffer_0, 0, sizeof(physical_frame_buffer_0)); - memset(physical_frame_buffer_1, 0, sizeof(physical_frame_buffer_1)); + display_physical_fb_clear(); #endif display_panel_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); @@ -133,12 +132,6 @@ int display_get_orientation(void) { return drv->orientation_angle; } -#ifndef XFRAMEBUFFER -void display_refresh(void) { - // if the framebuffer is not used the implementation is empty -} -#endif - void display_wait_for_sync(void) { #ifdef DISPLAY_TE_PIN uint32_t id = display_panel_identify(); @@ -154,77 +147,3 @@ void display_wait_for_sync(void) { } void display_set_compatible_settings(void) { display_panel_set_big_endian(); } - -static inline void set_window(const gl_bitblt_t* bb) { - display_panel_set_window(bb->dst_x, bb->dst_y, bb->dst_x + bb->width - 1, - bb->dst_y + bb->height + 1); -} - - -// For future notice, if we ever want to do a new model using progressive rendering. -// -// Following functions can be optimized by using DMA (regular is likely enough) to -// copy the data, along with the fill function. If even more performance is needed, -// we could use double-slice similarly to double-framebuffer and render to one with DMA2D while -// copying the other to the display with DMA. - -void display_fill(const gl_bitblt_t* bb) { - set_window(bb); - - uint16_t height = bb->height; - - while (height-- > 0) { - for (int x = 0; x < bb->width; x++) { - ISSUE_PIXEL_DATA(bb->src_fg); - } - } -} - -void display_copy_rgb565(const gl_bitblt_t* bb) { - set_window(bb); - - uint16_t* src_ptr = (uint16_t*)bb->src_row + bb->src_x; - uint16_t height = bb->height; - - while (height-- > 0) { - for (int x = 0; x < bb->width; x++) { - ISSUE_PIXEL_DATA(src_ptr[x]); - } - src_ptr += bb->src_stride / sizeof(*src_ptr); - } -} - -void display_copy_mono1p(const gl_bitblt_t* bb) { - set_window(bb); - - uint8_t* src = (uint8_t*)bb->src_row; - uint16_t src_ofs = bb->src_stride * bb->src_y + bb->src_x; - uint16_t height = bb->height; - - while (height-- > 0) { - for (int x = 0; x < bb->width; x++) { - uint8_t mask = 1 << (7 - ((src_ofs + x) & 7)); - uint8_t data = src[(src_ofs + x) / 8]; - ISSUE_PIXEL_DATA((data & mask) ? bb->src_fg : bb->src_bg); - } - src_ofs += bb->src_stride; - } -} - -void display_copy_mono4(const gl_bitblt_t* bb) { - set_window(bb); - - const gl_color16_t* gradient = gl_color16_gradient_a4(bb->src_fg, bb->src_bg); - - uint8_t* src_row = (uint8_t*)bb->src_row; - uint16_t height = bb->height; - - while (height-- > 0) { - for (int x = 0; x < bb->width; x++) { - uint8_t fg_data = src_row[(x + bb->src_x) / 2]; - uint8_t fg_lum = (x + bb->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF; - ISSUE_PIXEL_DATA(gradient[fg_lum]); - } - src_row += bb->src_stride / sizeof(*src_row); - } -} diff --git a/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.c b/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.c index f4ac9f996..69151d7fe 100644 --- a/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.c +++ b/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.c @@ -29,6 +29,7 @@ #include "display_panel.h" #include "xdisplay.h" +#include "gl_bitblt.h" #include "irq.h" #include "supervise.h" @@ -42,10 +43,14 @@ #error Framebuffer only supported on STM32U5 for now #endif -// Physical frame buffers in internal SRAM memory +// Size of the physical frame buffer in bytes +#define PHYSICAL_FRAME_BUFFER_SIZE (DISPLAY_RESX * DISPLAY_RESY * 2) + +// Physical frame buffers in internal SRAM memory. +// Both frame buffers layes in the fixed addresses that +// are shared between bootloaders and the firmware. __attribute__((section(".fb1"))) ALIGN_32BYTES(uint8_t physical_frame_buffer_0[PHYSICAL_FRAME_BUFFER_SIZE]); - __attribute__((section(".fb2"))) ALIGN_32BYTES(uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE]); @@ -54,6 +59,11 @@ ALIGN_32BYTES(uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE]); __attribute__((section(".framebuffer_select"))) uint32_t current_frame_buffer = 0; +void display_physical_fb_clear(void) { + memset(physical_frame_buffer_0, 0, sizeof(physical_frame_buffer_0)); + memset(physical_frame_buffer_1, 0, sizeof(physical_frame_buffer_1)); +} + #ifndef BOARDLOADER static bool pending_fb_switch = false; #endif @@ -169,4 +179,44 @@ void display_refresh(void) { #endif } +void display_fill(const gl_bitblt_t *bb) { + display_fb_info_t fb = display_get_frame_buffer(); + + gl_bitblt_t bb_new = *bb; + bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); + bb_new.dst_stride = fb.stride; + + gl_rgb565_fill(&bb_new); +} + +void display_copy_rgb565(const gl_bitblt_t *bb) { + display_fb_info_t fb = display_get_frame_buffer(); + + gl_bitblt_t bb_new = *bb; + bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); + bb_new.dst_stride = fb.stride; + + gl_rgb565_copy_rgb565(&bb_new); +} + +void display_copy_mono1p(const gl_bitblt_t *bb) { + display_fb_info_t fb = display_get_frame_buffer(); + + gl_bitblt_t bb_new = *bb; + bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); + bb_new.dst_stride = fb.stride; + + gl_rgb565_copy_mono1p(&bb_new); +} + +void display_copy_mono4(const gl_bitblt_t *bb) { + display_fb_info_t fb = display_get_frame_buffer(); + + gl_bitblt_t bb_new = *bb; + bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); + bb_new.dst_stride = fb.stride; + + gl_rgb565_copy_mono4(&bb_new); +} + #endif // XFRAMEBUFFER diff --git a/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.h b/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.h index bad36e107..d216be9c4 100644 --- a/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.h +++ b/core/embed/trezorhal/stm32f4/display/st-7789/display_fb.h @@ -17,30 +17,16 @@ * along with this program. If not, see . */ -#ifndef TREZOR_HAL_DISPLAY_INTERNAL_H -#define TREZOR_HAL_DISPLAY_INTERNAL_H - -#include TREZOR_BOARD +#ifndef TREZORHAL_DISPLAY_FB_H +#define TREZORHAL_DISPLAY_FB_H #include #ifdef XFRAMEBUFFER -// Size of the physical frame buffer in bytes -#define PHYSICAL_FRAME_BUFFER_SIZE (DISPLAY_RESX * DISPLAY_RESY * 2) - -// Physical frame buffers in internal SRAM memory -// -// Both frame buffers layes in the fixed addresses that -// are shared between bootloaders and the firmware. -extern uint8_t physical_frame_buffer_0[PHYSICAL_FRAME_BUFFER_SIZE]; -extern uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE]; - -// The current frame buffer selector at fixed memory address -// -// The variable address is shared between bootloaders and the firmware -extern uint32_t current_frame_buffer; +// Clears both physical frame buffers +void display_physical_fb_clear(void); #endif // XFRAMEBUFFER -#endif // TREZOR_HAL_DISPLAY_INTERNAL_H +#endif // TREZORHAL_DISPLAY_FB_H diff --git a/core/embed/trezorhal/stm32f4/display/st-7789/display_nofb.c b/core/embed/trezorhal/stm32f4/display/st-7789/display_nofb.c new file mode 100644 index 000000000..79ba45819 --- /dev/null +++ b/core/embed/trezorhal/stm32f4/display/st-7789/display_nofb.c @@ -0,0 +1,107 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include TREZOR_BOARD + +#ifdef XFRAMEBUFFER + +#include + +#include "display_io.h" +#include "display_panel.h" + +void display_refresh(void) { + // if the framebuffer is not used the implementation is empty +} + +static inline void set_window(const gl_bitblt_t* bb) { + display_panel_set_window(bb->dst_x, bb->dst_y, bb->dst_x + bb->width - 1, + bb->dst_y + bb->height + 1); +} + +// For future notice, if we ever want to do a new model using progressive +// rendering. +// +// Following functions can be optimized by using DMA (regular is likely enough) +// to copy the data, along with the fill function. If even more performance is +// needed, we could use double-slice similarly to double-framebuffer and render +// to one with DMA2D while copying the other to the display with DMA. + +void display_fill(const gl_bitblt_t* bb) { + set_window(bb); + + uint16_t height = bb->height; + + while (height-- > 0) { + for (int x = 0; x < bb->width; x++) { + ISSUE_PIXEL_DATA(bb->src_fg); + } + } +} + +void display_copy_rgb565(const gl_bitblt_t* bb) { + set_window(bb); + + uint16_t* src_ptr = (uint16_t*)bb->src_row + bb->src_x; + uint16_t height = bb->height; + + while (height-- > 0) { + for (int x = 0; x < bb->width; x++) { + ISSUE_PIXEL_DATA(src_ptr[x]); + } + src_ptr += bb->src_stride / sizeof(*src_ptr); + } +} + +void display_copy_mono1p(const gl_bitblt_t* bb) { + set_window(bb); + + uint8_t* src = (uint8_t*)bb->src_row; + uint16_t src_ofs = bb->src_stride * bb->src_y + bb->src_x; + uint16_t height = bb->height; + + while (height-- > 0) { + for (int x = 0; x < bb->width; x++) { + uint8_t mask = 1 << (7 - ((src_ofs + x) & 7)); + uint8_t data = src[(src_ofs + x) / 8]; + ISSUE_PIXEL_DATA((data & mask) ? bb->src_fg : bb->src_bg); + } + src_ofs += bb->src_stride; + } +} + +void display_copy_mono4(const gl_bitblt_t* bb) { + set_window(bb); + + const gl_color16_t* gradient = gl_color16_gradient_a4(bb->src_fg, bb->src_bg); + + uint8_t* src_row = (uint8_t*)bb->src_row; + uint16_t height = bb->height; + + while (height-- > 0) { + for (int x = 0; x < bb->width; x++) { + uint8_t fg_data = src_row[(x + bb->src_x) / 2]; + uint8_t fg_lum = (x + bb->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF; + ISSUE_PIXEL_DATA(gradient[fg_lum]); + } + src_row += bb->src_stride / sizeof(*src_row); + } +} + +#endif // XFRAMEBUFFER diff --git a/core/site_scons/boards/trezor_t.py b/core/site_scons/boards/trezor_t.py index 038bb17cf..f70af5fd6 100644 --- a/core/site_scons/boards/trezor_t.py +++ b/core/site_scons/boards/trezor_t.py @@ -43,6 +43,7 @@ def configure( if "new_rendering" in features_wanted: sources += ["embed/trezorhal/xdisplay_legacy.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_fb.c"] + sources += ["embed/trezorhal/stm32f4/display/st-7789/display_nofb.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_driver.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_io.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_panel.c"] diff --git a/core/site_scons/boards/trezor_t3t1_revE.py b/core/site_scons/boards/trezor_t3t1_revE.py index f3a5f0555..f9f25cab5 100644 --- a/core/site_scons/boards/trezor_t3t1_revE.py +++ b/core/site_scons/boards/trezor_t3t1_revE.py @@ -49,6 +49,7 @@ def configure( if "new_rendering" in features_wanted: sources += ["embed/trezorhal/xdisplay_legacy.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_fb.c"] + sources += ["embed/trezorhal/stm32f4/display/st-7789/display_nofb.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_driver.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_io.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_panel.c"] diff --git a/core/site_scons/boards/trezor_t3t1_v4.py b/core/site_scons/boards/trezor_t3t1_v4.py index 1bca7620a..ca8e1aefb 100644 --- a/core/site_scons/boards/trezor_t3t1_v4.py +++ b/core/site_scons/boards/trezor_t3t1_v4.py @@ -50,6 +50,7 @@ def configure( if "new_rendering" in features_wanted: sources += ["embed/trezorhal/xdisplay_legacy.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_fb.c"] + sources += ["embed/trezorhal/stm32f4/display/st-7789/display_nofb.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_driver.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_io.c"] sources += ["embed/trezorhal/stm32f4/display/st-7789/display_panel.c"]