1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 12:00:59 +00:00

refactor(core/embed): add initialized flag to display drivers

[no changelog]
This commit is contained in:
cepetr 2024-06-25 10:07:52 +02:00 committed by cepetr
parent 3f0770b4e1
commit e106df766e
10 changed files with 413 additions and 50 deletions

View File

@ -41,10 +41,17 @@
#endif #endif
// Display driver instance // Display driver instance
display_driver_t g_display_driver; display_driver_t g_display_driver = {
.initialized = false,
};
void display_init(display_content_mode_t mode) { void display_init(display_content_mode_t mode) {
display_driver_t* drv = &g_display_driver; display_driver_t* drv = &g_display_driver;
if (drv->initialized) {
return;
}
memset(drv, 0, sizeof(display_driver_t)); memset(drv, 0, sizeof(display_driver_t));
if (mode == DISPLAY_RESET_CONTENT) { if (mode == DISPLAY_RESET_CONTENT) {
@ -67,9 +74,17 @@ void display_init(display_content_mode_t mode) {
#ifdef XFRAMEBUFFER #ifdef XFRAMEBUFFER
display_io_init_te_interrupt(); display_io_init_te_interrupt();
#endif #endif
drv->initialized = true;
} }
void display_deinit(display_content_mode_t mode) { void display_deinit(display_content_mode_t mode) {
display_driver_t* drv = &g_display_driver;
if (!drv->initialized) {
return;
}
#ifdef XFRAMEBUFFER #ifdef XFRAMEBUFFER
#ifndef BOARDLOADER #ifndef BOARDLOADER
// Ensure that the ready frame buffer is transfered to // Ensure that the ready frame buffer is transfered to
@ -80,7 +95,8 @@ void display_deinit(display_content_mode_t mode) {
#endif #endif
#endif #endif
backlight_pwm_deinit(mode == DISPLAY_RESET_CONTENT ? BACKLIGHT_RESET : BACKLIGHT_RETAIN); backlight_pwm_deinit(mode == DISPLAY_RESET_CONTENT ? BACKLIGHT_RESET
: BACKLIGHT_RETAIN);
#ifdef TREZOR_MODEL_T #ifdef TREZOR_MODEL_T
// This ensures backward compatibility with legacy bootloader/firmware // This ensures backward compatibility with legacy bootloader/firmware
@ -90,9 +106,17 @@ void display_deinit(display_content_mode_t mode) {
} }
display_panel_set_big_endian(); display_panel_set_big_endian();
#endif #endif
drv->initialized = false;
} }
int display_set_backlight(int level) { int display_set_backlight(int level) {
display_driver_t* drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
#ifdef XFRAMEBUFFER #ifdef XFRAMEBUFFER
#ifndef BOARDLOADER #ifndef BOARDLOADER
// if turning on the backlight, wait until the panel is refreshed // if turning on the backlight, wait until the panel is refreshed
@ -110,6 +134,10 @@ int display_get_backlight(void) { return backlight_pwm_get(); }
int display_set_orientation(int angle) { int display_set_orientation(int angle) {
display_driver_t* drv = &g_display_driver; display_driver_t* drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
if (angle != drv->orientation_angle) { if (angle != drv->orientation_angle) {
if (angle == 0 || angle == 90 || angle == 180 || angle == 270) { if (angle == 0 || angle == 90 || angle == 180 || angle == 270) {
drv->orientation_angle = angle; drv->orientation_angle = angle;
@ -135,5 +163,9 @@ int display_set_orientation(int angle) {
int display_get_orientation(void) { int display_get_orientation(void) {
display_driver_t* drv = &g_display_driver; display_driver_t* drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->orientation_angle; return drv->orientation_angle;
} }

View File

@ -139,6 +139,14 @@ void DISPLAY_TE_INTERRUPT_HANDLER(void) {
display_fb_info_t display_get_frame_buffer(void) { display_fb_info_t display_get_frame_buffer(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
display_fb_info_t fb = {
.ptr = NULL,
.stride = 0,
};
return fb;
}
frame_buffer_state_t state; frame_buffer_state_t state;
// We have to wait if the buffer was passed for copying // We have to wait if the buffer was passed for copying
@ -191,6 +199,10 @@ static void wait_for_te_signal(void) {
void display_refresh(void) { void display_refresh(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
if (drv->queue.entry[drv->queue.wix] != FB_STATE_PREPARING) { if (drv->queue.entry[drv->queue.wix] != FB_STATE_PREPARING) {
// No refresh needed as the frame buffer is not in // No refresh needed as the frame buffer is not in
// the state to be copied to the display // the state to be copied to the display
@ -234,6 +246,10 @@ void display_ensure_refreshed(void) {
#ifndef BOARDLOADER #ifndef BOARDLOADER
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
if (!is_mode_handler()) { if (!is_mode_handler()) {
bool copy_pending; bool copy_pending;
@ -265,6 +281,10 @@ void display_ensure_refreshed(void) {
void display_fill(const gfx_bitblt_t *bb) { void display_fill(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;
@ -275,6 +295,10 @@ void display_fill(const gfx_bitblt_t *bb) {
void display_copy_rgb565(const gfx_bitblt_t *bb) { void display_copy_rgb565(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;
@ -285,6 +309,10 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
void display_copy_mono1p(const gfx_bitblt_t *bb) { void display_copy_mono1p(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;
@ -295,6 +323,10 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
void display_copy_mono4(const gfx_bitblt_t *bb) { void display_copy_mono4(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y); bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;

View File

@ -41,6 +41,9 @@ typedef struct {
// Display driver state // Display driver state
typedef struct { typedef struct {
// Set if the driver is initialized
bool initialized;
#ifdef XFRAMEBUFFER #ifdef XFRAMEBUFFER
// Framebuffer queue // Framebuffer queue
// (accessed & updated in the context of the main thread // (accessed & updated in the context of the main thread

View File

@ -33,6 +33,8 @@
// Display driver context. // Display driver context.
typedef struct { typedef struct {
// Set if the driver is initialized
bool initialized;
// Pointer to the frame buffer // Pointer to the frame buffer
uint16_t *framebuf; uint16_t *framebuf;
// Current display orientation (0, 90, 180, 270) // Current display orientation (0, 90, 180, 270)
@ -42,10 +44,17 @@ typedef struct {
} display_driver_t; } display_driver_t;
// Display driver instance // Display driver instance
static display_driver_t g_display_driver; static display_driver_t g_display_driver = {
.initialized = false,
};
void display_init(display_content_mode_t mode) { void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (drv->initialized) {
return;
}
memset(drv, 0, sizeof(display_driver_t)); memset(drv, 0, sizeof(display_driver_t));
drv->framebuf = (uint16_t *)FRAME_BUFFER_ADDR; drv->framebuf = (uint16_t *)FRAME_BUFFER_ADDR;
@ -55,15 +64,23 @@ void display_init(display_content_mode_t mode) {
// Initialize external display controller // Initialize external display controller
ili9341_init(); ili9341_init();
} }
drv->initialized = true;
} }
void display_deinit(display_content_mode_t mode) { void display_deinit(display_content_mode_t mode) {
// Not used and intentionally left empty display_driver_t *drv = &g_display_driver;
drv->initialized = false;
} }
int display_set_backlight(int level) { int display_set_backlight(int level) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
// Just emulation, not doing anything // Just emulation, not doing anything
drv->backlight_level = level; drv->backlight_level = level;
return level; return level;
@ -72,12 +89,20 @@ int display_set_backlight(int level) {
int display_get_backlight(void) { int display_get_backlight(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->backlight_level; return drv->backlight_level;
} }
int display_set_orientation(int angle) { int display_set_orientation(int angle) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
if (angle == 0 || angle == 90 || angle == 180 || angle == 270) { if (angle == 0 || angle == 90 || angle == 180 || angle == 270) {
// Just emulation, not doing anything // Just emulation, not doing anything
drv->orientation_angle = angle; drv->orientation_angle = angle;
@ -89,18 +114,29 @@ int display_set_orientation(int angle) {
int display_get_orientation(void) { int display_get_orientation(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->orientation_angle; return drv->orientation_angle;
} }
display_fb_info_t display_get_frame_buffer(void) { display_fb_info_t display_get_frame_buffer(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
display_fb_info_t fb = { if (!drv->initialized) {
.ptr = (void *)drv->framebuf, display_fb_info_t fb = {
.stride = DISPLAY_RESX * sizeof(uint16_t), .ptr = NULL,
}; .stride = 0,
};
return fb; return fb;
} else {
display_fb_info_t fb = {
.ptr = (void *)drv->framebuf,
.stride = DISPLAY_RESX * sizeof(uint16_t),
};
return fb;
}
} }
void display_refresh(void) { void display_refresh(void) {
@ -110,6 +146,10 @@ void display_refresh(void) {
void display_fill(const gfx_bitblt_t *bb) { void display_fill(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y); bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t); bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
@ -120,6 +160,10 @@ void display_fill(const gfx_bitblt_t *bb) {
void display_copy_rgb565(const gfx_bitblt_t *bb) { void display_copy_rgb565(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y); bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t); bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
@ -130,6 +174,10 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
void display_copy_mono1p(const gfx_bitblt_t *bb) { void display_copy_mono1p(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y); bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t); bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
@ -140,6 +188,10 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
void display_copy_mono4(const gfx_bitblt_t *bb) { void display_copy_mono4(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y); bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t); bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);

View File

@ -37,6 +37,8 @@
// Display driver context. // Display driver context.
typedef struct { typedef struct {
// Set if the driver is initialized
bool initialized;
// Frame buffer (8-bit Mono) // Frame buffer (8-bit Mono)
uint8_t framebuf[DISPLAY_RESX * DISPLAY_RESY]; uint8_t framebuf[DISPLAY_RESX * DISPLAY_RESY];
// Current display orientation (0 or 180) // Current display orientation (0 or 180)
@ -46,7 +48,9 @@ typedef struct {
} display_driver_t; } display_driver_t;
// Display driver instance // Display driver instance
static display_driver_t g_display_driver; static display_driver_t g_display_driver = {
.initialized = false,
};
// Macros to access display parallel interface // Macros to access display parallel interface
@ -179,6 +183,10 @@ static void display_set_page_and_col(uint8_t page, uint8_t col) {
static void display_sync_with_fb(void) { static void display_sync_with_fb(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return NULL;
}
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);
uint8_t *src = &drv->framebuf[y * DISPLAY_RESX * 8]; uint8_t *src = &drv->framebuf[y * DISPLAY_RESX * 8];
@ -293,6 +301,11 @@ static void display_init_interface(void) {
void display_init(display_content_mode_t mode) { void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (drv->initialized) {
return;
}
memset(drv, 0, sizeof(display_driver_t)); memset(drv, 0, sizeof(display_driver_t));
if (mode == DISPLAY_RESET_CONTENT) { if (mode == DISPLAY_RESET_CONTENT) {
@ -301,15 +314,23 @@ void display_init(display_content_mode_t mode) {
// Initialize display controller // Initialize display controller
display_init_controller(); display_init_controller();
} }
drv->initialized = true;
} }
void display_deinit(display_content_mode_t mode) { void display_deinit(display_content_mode_t mode) {
// Not used and intentionally left empty display_driver_t *drv = &g_display_driver;
drv->initialized = false;
} }
int display_set_backlight(int level) { int display_set_backlight(int level) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
if (level != drv->backlight_level) { if (level != drv->backlight_level) {
if (level >= 0 && level <= 255) { if (level >= 0 && level <= 255) {
drv->backlight_level = level; drv->backlight_level = level;
@ -325,12 +346,20 @@ int display_set_backlight(int level) {
int display_get_backlight(void) { int display_get_backlight(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->backlight_level; return drv->backlight_level;
} }
int display_set_orientation(int angle) { int display_set_orientation(int angle) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
if (angle != drv->orientation_angle) { if (angle != drv->orientation_angle) {
if (angle == 0 || angle == 180) { if (angle == 0 || angle == 180) {
drv->orientation_angle = angle; drv->orientation_angle = angle;
@ -354,25 +383,48 @@ int display_set_orientation(int angle) {
int display_get_orientation(void) { int display_get_orientation(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->orientation_angle; return drv->orientation_angle;
} }
display_fb_info_t display_get_frame_buffer(void) { display_fb_info_t display_get_frame_buffer(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
display_fb_info_t fb = { if (!drv->initialized) {
.ptr = &drv->framebuf[0], const static display_fb_info_t fb = {
.stride = DISPLAY_RESX, .ptr = NULL,
}; .stride = 0,
};
return fb; return fb;
} else {
display_fb_info_t fb = {
.ptr = &drv->framebuf[0],
.stride = DISPLAY_RESX,
};
return fb;
}
} }
void display_refresh(void) { display_sync_with_fb(); } void display_refresh(void) {
display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return NULL;
}
display_sync_with_fb();
}
void display_fill(const gfx_bitblt_t *bb) { void display_fill(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return NULL;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y]; bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX; bb_new.dst_stride = DISPLAY_RESX;
@ -383,6 +435,10 @@ void display_fill(const gfx_bitblt_t *bb) {
void display_copy_mono1p(const gfx_bitblt_t *bb) { void display_copy_mono1p(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return NULL;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y]; bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX; bb_new.dst_stride = DISPLAY_RESX;

View File

@ -42,6 +42,8 @@
// Display driver context. // Display driver context.
typedef struct { typedef struct {
// Set if the driver is initialized
bool initialized;
// SPI driver instance // SPI driver instance
SPI_HandleTypeDef spi; SPI_HandleTypeDef spi;
// Frame buffer (8-bit Mono) // Frame buffer (8-bit Mono)
@ -53,7 +55,9 @@ typedef struct {
} display_driver_t; } display_driver_t;
// Display driver instance // Display driver instance
static display_driver_t g_display_driver; static display_driver_t g_display_driver = {
.initialized = false,
};
// Display controller registers // Display controller registers
#define OLED_SETCONTRAST 0x81 #define OLED_SETCONTRAST 0x81
@ -223,6 +227,10 @@ static void display_sync_with_fb(display_driver_t *drv) {
void display_init(display_content_mode_t mode) { void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (drv->initialized) {
return;
}
memset(drv, 0, sizeof(display_driver_t)); memset(drv, 0, sizeof(display_driver_t));
drv->backlight_level = 255; drv->backlight_level = 255;
@ -289,15 +297,23 @@ void display_init(display_content_mode_t mode) {
} else { } else {
display_init_spi(drv); display_init_spi(drv);
} }
drv->initialized = true;
} }
void display_deinit(display_content_mode_t mode) { void display_deinit(display_content_mode_t mode) {
// Not used and intentionally left empty display_driver_t *drv = &g_display_driver;
drv->initialized = false;
} }
int display_set_backlight(int level) { int display_set_backlight(int level) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
drv->backlight_level = 255; drv->backlight_level = 255;
return drv->backlight_level; return drv->backlight_level;
} }
@ -305,12 +321,20 @@ int display_set_backlight(int level) {
int display_get_backlight(void) { int display_get_backlight(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->backlight_level; return drv->backlight_level;
} }
int display_set_orientation(int angle) { int display_set_orientation(int angle) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
if (angle != drv->orientation_angle) { if (angle != drv->orientation_angle) {
if (angle == 0 || angle == 180) { if (angle == 0 || angle == 180) {
drv->orientation_angle = angle; drv->orientation_angle = angle;
@ -324,23 +348,38 @@ int display_set_orientation(int angle) {
int display_get_orientation(void) { int display_get_orientation(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->orientation_angle; return drv->orientation_angle;
} }
display_fb_info_t display_get_frame_buffer(void) { display_fb_info_t display_get_frame_buffer(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
display_fb_info_t fb = { if (!drv->initialized) {
.ptr = &drv->framebuf[0], static const display_fb_info_t fb = {
.stride = DISPLAY_RESX, .ptr = NULL,
}; .stride = 0,
};
return fb; return fb;
} else {
display_fb_info_t fb = {
.ptr = &drv->framebuf[0],
.stride = DISPLAY_RESX,
};
return fb;
}
} }
void display_refresh(void) { void display_refresh(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
#if defined USE_CONSUMPTION_MASK && !defined BOARDLOADER #if defined USE_CONSUMPTION_MASK && !defined BOARDLOADER
// This is an intentional randomization of the consumption masking algorithm // This is an intentional randomization of the consumption masking algorithm
// after every change on the display // after every change on the display
@ -354,6 +393,10 @@ void display_refresh(void) {
void display_fill(const gfx_bitblt_t *bb) { void display_fill(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y]; bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX; bb_new.dst_stride = DISPLAY_RESX;
@ -364,6 +407,10 @@ void display_fill(const gfx_bitblt_t *bb) {
void display_copy_mono1p(const gfx_bitblt_t *bb) { void display_copy_mono1p(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y]; bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX; bb_new.dst_stride = DISPLAY_RESX;

View File

@ -30,18 +30,18 @@
#error "Incompatible display resolution" #error "Incompatible display resolution"
#endif #endif
// Display driver context.
typedef struct {
// Current display orientation (0, 90, 180, 270)
int orientation_angle;
// Current backlight level ranging from 0 to 255
int backlight_level;
} display_driver_t;
// Display driver instance // Display driver instance
static display_driver_t g_display_driver; display_driver_t g_display_driver = {
.initialized = false,
};
void display_init(display_content_mode_t mode) { void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;
if (drv->initialized) {
return;
}
if (mode == DISPLAY_RESET_CONTENT) { if (mode == DISPLAY_RESET_CONTENT) {
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
@ -76,19 +76,33 @@ void display_init(display_content_mode_t mode) {
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S); BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
} }
} }
drv->initialized = true;
} }
void display_deinit(display_content_mode_t mode) { void display_deinit(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
if (mode == DISPLAY_RESET_CONTENT) { if (mode == DISPLAY_RESET_CONTENT) {
BSP_LCD_DisplayOff(0); BSP_LCD_DisplayOff(0);
BSP_LCD_SetBrightness(0, 0); BSP_LCD_SetBrightness(0, 0);
BSP_LCD_DeInit(0); BSP_LCD_DeInit(0);
} }
drv->initialized = false;
} }
int display_set_backlight(int level) { int display_set_backlight(int level) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
// Just emulation, not doing anything // Just emulation, not doing anything
drv->backlight_level = level; drv->backlight_level = level;
return level; return level;
@ -97,12 +111,20 @@ int display_set_backlight(int level) {
int display_get_backlight(void) { int display_get_backlight(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->orientation_angle; return drv->orientation_angle;
} }
int display_set_orientation(int angle) { int display_set_orientation(int angle) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
if (angle == 0 || angle == 90 || angle == 180 || angle == 270) { if (angle == 0 || angle == 90 || angle == 180 || angle == 270) {
// Just emulation, not doing anything // Just emulation, not doing anything
drv->orientation_angle = angle; drv->orientation_angle = angle;
@ -114,12 +136,20 @@ int display_set_orientation(int angle) {
int display_get_orientation(void) { int display_get_orientation(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->orientation_angle; return drv->orientation_angle;
} }
void display_fill(const gfx_bitblt_t *bb) { void display_fill(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y); bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;
@ -130,6 +160,10 @@ void display_fill(const gfx_bitblt_t *bb) {
void display_copy_rgb565(const gfx_bitblt_t *bb) { void display_copy_rgb565(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y); bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;
@ -140,6 +174,10 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
void display_copy_mono1p(const gfx_bitblt_t *bb) { void display_copy_mono1p(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y); bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;
@ -150,6 +188,10 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
void display_copy_mono4(const gfx_bitblt_t *bb) { void display_copy_mono4(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer(); display_fb_info_t fb = display_get_frame_buffer();
if (fb.ptr == NULL) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y); bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride; bb_new.dst_stride = fb.stride;

View File

@ -39,6 +39,16 @@ __attribute__((section(".framebuffer_select"))) uint32_t current_frame_buffer =
0; 0;
display_fb_info_t display_get_frame_buffer(void) { display_fb_info_t display_get_frame_buffer(void) {
display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
display_fb_info_t fb = {
.ptr = NULL,
.stride = 0,
};
return fb;
}
uintptr_t addr; uintptr_t addr;
if (current_frame_buffer == 0) { if (current_frame_buffer == 0) {
@ -63,6 +73,12 @@ display_fb_info_t display_get_frame_buffer(void) {
} }
void display_refresh(void) { void display_refresh(void) {
display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
if (current_frame_buffer == 0) { if (current_frame_buffer == 0) {
current_frame_buffer = 1; current_frame_buffer = 1;
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S); BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);

View File

@ -20,8 +20,22 @@
#ifndef TREZOR_HAL_DISPLAY_INTERNAL_H #ifndef TREZOR_HAL_DISPLAY_INTERNAL_H
#define TREZOR_HAL_DISPLAY_INTERNAL_H #define TREZOR_HAL_DISPLAY_INTERNAL_H
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
// Display driver context.
typedef struct {
// Set if the driver is initialized
bool initialized;
// Current display orientation (0, 90, 180, 270)
int orientation_angle;
// Current backlight level ranging from 0 to 255
int backlight_level;
} display_driver_t;
// Display driver instance
extern display_driver_t g_display_driver;
// Size of the physical frame buffer in bytes // Size of the physical frame buffer in bytes
// //
// It's smaller than size of the virtual frame buffer // It's smaller than size of the virtual frame buffer

View File

@ -32,6 +32,8 @@
#define EMULATOR_BORDER 16 #define EMULATOR_BORDER 16
typedef struct { typedef struct {
// Set if the driver is initialized
bool initialized;
// Current display orientation (0 or 180) // Current display orientation (0 or 180)
int orientation_angle; int orientation_angle;
// Current backlight level ranging from 0 to 255 // Current backlight level ranging from 0 to 255
@ -52,7 +54,9 @@ typedef struct {
} display_driver_t; } display_driver_t;
static display_driver_t g_display_driver; static display_driver_t g_display_driver = {
.initialized = false,
};
//!@# TODO get rid of this... //!@# TODO get rid of this...
int sdl_display_res_x = DISPLAY_RESX, sdl_display_res_y = DISPLAY_RESY; int sdl_display_res_x = DISPLAY_RESX, sdl_display_res_y = DISPLAY_RESY;
@ -65,6 +69,10 @@ static void display_exit_handler(void) {
void display_init(display_content_mode_t mode) { void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (drv->initialized) {
return;
}
if (SDL_Init(SDL_INIT_VIDEO) != 0) { if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("%s\n", SDL_GetError()); printf("%s\n", SDL_GetError());
error_shutdown("SDL_Init error"); error_shutdown("SDL_Init error");
@ -144,11 +152,16 @@ void display_init(display_content_mode_t mode) {
#else #else
drv->orientation_angle = 0; drv->orientation_angle = 0;
#endif #endif
drv->initialized = true;
} }
void display_deinit(display_content_mode_t mode) { void display_deinit(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
SDL_FreeSurface(drv->prev_saved); SDL_FreeSurface(drv->prev_saved);
SDL_FreeSurface(drv->buffer); SDL_FreeSurface(drv->buffer);
if (drv->background != NULL) { if (drv->background != NULL) {
@ -164,11 +177,17 @@ void display_deinit(display_content_mode_t mode) {
SDL_DestroyWindow(drv->window); SDL_DestroyWindow(drv->window);
} }
SDL_Quit(); SDL_Quit();
drv->initialized = false;
} }
int display_set_backlight(int level) { int display_set_backlight(int level) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
#if !USE_BACKLIGHT #if !USE_BACKLIGHT
level = 255; level = 255;
#endif #endif
@ -183,11 +202,21 @@ int display_set_backlight(int level) {
int display_get_backlight(void) { int display_get_backlight(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->backlight_level; return drv->backlight_level;
} }
int display_set_orientation(int angle) { int display_set_orientation(int angle) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
if (angle != drv->orientation_angle) { if (angle != drv->orientation_angle) {
#if defined ORIENTATION_NSEW #if defined ORIENTATION_NSEW
if (angle == 0 || angle == 90 || angle == 180 || angle == 270) { if (angle == 0 || angle == 90 || angle == 180 || angle == 270) {
@ -205,6 +234,11 @@ int display_set_orientation(int angle) {
int display_get_orientation(void) { int display_get_orientation(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return 0;
}
return drv->orientation_angle; return drv->orientation_angle;
} }
@ -212,25 +246,32 @@ int display_get_orientation(void) {
display_fb_info_t display_get_frame_buffer(void) { display_fb_info_t display_get_frame_buffer(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
display_fb_info_t fb = {
.ptr = NULL,
.stride = 0,
};
return fb;
} else {
#ifdef DISPLAY_MONO #ifdef DISPLAY_MONO
display_fb_info_t fb = { display_fb_info_t fb = {
.ptr = drv->mono_framebuf, .ptr = drv->mono_framebuf,
.stride = DISPLAY_RESX, .stride = DISPLAY_RESX,
}; };
#else #else
display_fb_info_t fb = { display_fb_info_t fb = {
.ptr = drv->buffer->pixels, .ptr = drv->buffer->pixels,
.stride = DISPLAY_RESX * sizeof(uint16_t), .stride = DISPLAY_RESX * sizeof(uint16_t),
}; };
#endif #endif
return fb;
return fb; }
} }
#else // XFRAMEBUFFER #else // XFRAMEBUFFER
void display_wait_for_sync(void) { void display_wait_for_sync(void) {
// not used // not implemented in the emulator
} }
#endif #endif
@ -253,7 +294,7 @@ static void copy_mono_framebuf(display_driver_t *drv) {
void display_refresh(void) { void display_refresh(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->renderer) { if (!drv->initialized) {
return; return;
} }
@ -292,6 +333,10 @@ void display_refresh(void) {
void display_fill(const gfx_bitblt_t *bb) { void display_fill(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = bb_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y); (uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y);
@ -303,6 +348,10 @@ void display_fill(const gfx_bitblt_t *bb) {
void display_copy_rgb565(const gfx_bitblt_t *bb) { void display_copy_rgb565(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = bb_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y); (uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y);
@ -314,6 +363,10 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
void display_copy_mono1p(const gfx_bitblt_t *bb) { void display_copy_mono1p(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = bb_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y); (uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y);
@ -325,6 +378,10 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
void display_copy_mono4(const gfx_bitblt_t *bb) { void display_copy_mono4(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = bb_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y); (uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y);
@ -338,6 +395,10 @@ void display_copy_mono4(const gfx_bitblt_t *bb) {
void display_fill(const gfx_bitblt_t *bb) { void display_fill(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * bb_new.dst_y); bb_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX; bb_new.dst_stride = DISPLAY_RESX;
@ -348,6 +409,10 @@ void display_fill(const gfx_bitblt_t *bb) {
void display_copy_mono1p(const gfx_bitblt_t *bb) { void display_copy_mono1p(const gfx_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
gfx_bitblt_t bb_new = *bb; gfx_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * bb_new.dst_y); bb_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX; bb_new.dst_stride = DISPLAY_RESX;
@ -360,7 +425,7 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
const char *display_save(const char *prefix) { const char *display_save(const char *prefix) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->renderer) { if (!drv->initialized) {
return NULL; return NULL;
} }
@ -396,6 +461,10 @@ const char *display_save(const char *prefix) {
void display_clear_save(void) { void display_clear_save(void) {
display_driver_t *drv = &g_display_driver; display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
return;
}
SDL_FreeSurface(drv->prev_saved); SDL_FreeSurface(drv->prev_saved);
drv->prev_saved = NULL; drv->prev_saved = NULL;
} }