mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-15 02:48:11 +00:00
refactor(core): switch DISC2 display driver to universal LTDC DSI implementation
[no changelog]
This commit is contained in:
parent
03a296f815
commit
3bc13b5707
@ -1,35 +1,9 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : gfxmmu_lut.h
|
||||
* Description : header file for GFX MMU Configuration Table
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __gfxmmu_lut_H
|
||||
#define __gfxmmu_lut_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// GFX MMU Configuration Table
|
||||
#ifdef KERNEL_MODE
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#define GFXMMU_FB_SIZE 733936
|
||||
#define GFXMMU_LUT_FIRST 0
|
||||
#define GFXMMU_LUT_LAST 479
|
||||
#define GFXMMU_LUT_SIZE 480
|
||||
#include "../../display_internal.h"
|
||||
|
||||
static const uint32_t gfxmmu_lut_config[2 * GFXMMU_LUT_SIZE] = {
|
||||
const uint32_t gfxmmu_lut_config[2 * GFXMMU_LUT_SIZE] = {
|
||||
0x00413601, // GFXMMU_LUT0L
|
||||
0x003FFCA0, // GFXMMU_LUT0H
|
||||
0x00433401, // GFXMMU_LUT1L
|
||||
@ -992,15 +966,188 @@ static const uint32_t gfxmmu_lut_config[2 * GFXMMU_LUT_SIZE] = {
|
||||
0x000B2ED0 // GFXMMU_LUT479H
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
bool panel_init(display_driver_t* drv) {
|
||||
HAL_StatusTypeDef ret;
|
||||
/* CMD Mode */
|
||||
uint8_t InitParam1[3] = {0xFF, 0x83, 0x79};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 3, 0xB9,
|
||||
InitParam1);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* SETPOWER */
|
||||
uint8_t InitParam2[16] = {0x44, 0x1C, 0x1C, 0x37, 0x57, 0x90, 0xD0, 0xE2,
|
||||
0x58, 0x80, 0x38, 0x38, 0xF8, 0x33, 0x34, 0x42};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 16, 0xB1,
|
||||
InitParam2);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* SETDISP */
|
||||
uint8_t InitParam3[9] = {0x80, 0x14, 0x0C, 0x30, 0x20,
|
||||
0x50, 0x11, 0x42, 0x1D};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 9, 0xB2,
|
||||
InitParam3);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set display cycle timing */
|
||||
uint8_t InitParam4[10] = {0x01, 0xAA, 0x01, 0xAF, 0x01,
|
||||
0xAF, 0x10, 0xEA, 0x1C, 0xEA};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 10, 0xB4,
|
||||
InitParam4);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* SETVCOM */
|
||||
uint8_t InitParam5[4] = {00, 00, 00, 0xC0};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 4, 0xC7,
|
||||
InitParam5);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set Panel Related Registers */
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xCC,
|
||||
0x02);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xD2,
|
||||
0x77);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t InitParam6[37] = {0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x32,
|
||||
0x10, 0x01, 0x00, 0x01, 0x03, 0x72, 0x03, 0x72,
|
||||
0x00, 0x08, 0x00, 0x08, 0x33, 0x33, 0x05, 0x05,
|
||||
0x37, 0x05, 0x05, 0x37, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x01, 0x00, 0x0E};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 37, 0xD3,
|
||||
InitParam6);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t InitParam7[34] = {
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x18, 0x18,
|
||||
0x18, 0x18, 0x19, 0x19, 0x01, 0x00, 0x03, 0x02, 0x05, 0x04, 0x07, 0x06,
|
||||
0x23, 0x22, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 34, 0xD5,
|
||||
InitParam7);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t InitParam8[32] = {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x19, 0x19, 0x18, 0x18, 0x19, 0x19, 0x18, 0x18,
|
||||
0x06, 0x07, 0x04, 0x05, 0x02, 0x03, 0x00, 0x01,
|
||||
0x20, 0x21, 0x22, 0x23, 0x18, 0x18, 0x18, 0x18};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 35, 0xD6,
|
||||
InitParam8);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* SET GAMMA */
|
||||
uint8_t InitParam9[42] = {
|
||||
0x00, 0x16, 0x1B, 0x30, 0x36, 0x3F, 0x24, 0x40, 0x09, 0x0D, 0x0F,
|
||||
0x18, 0x0E, 0x11, 0x12, 0x11, 0x14, 0x07, 0x12, 0x13, 0x18, 0x00,
|
||||
0x17, 0x1C, 0x30, 0x36, 0x3F, 0x24, 0x40, 0x09, 0x0C, 0x0F, 0x18,
|
||||
0x0E, 0x11, 0x14, 0x11, 0x12, 0x07, 0x12, 0x14, 0x18};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 42, 0xE0,
|
||||
InitParam9);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t InitParam10[3] = {0x2C, 0x2C, 00};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 3, 0xB6,
|
||||
InitParam10);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xBD,
|
||||
0x00);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
uint8_t InitParam11[] = {0x01, 0x00, 0x07, 0x0F, 0x16, 0x1F, 0x27, 0x30, 0x38,
|
||||
0x40, 0x47, 0x4E, 0x56, 0x5D, 0x65, 0x6D, 0x74, 0x7D,
|
||||
0x84, 0x8A, 0x90, 0x99, 0xA1, 0xA9, 0xB0, 0xB6, 0xBD,
|
||||
0xC4, 0xCD, 0xD4, 0xDD, 0xE5, 0xEC, 0xF3, 0x36, 0x07,
|
||||
0x1C, 0xC0, 0x1B, 0x01, 0xF1, 0x34, 0x00};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 42, 0xC1,
|
||||
InitParam11);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xBD,
|
||||
0x01);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t InitParam12[] = {0x00, 0x08, 0x0F, 0x16, 0x1F, 0x28, 0x31, 0x39, 0x41,
|
||||
0x48, 0x51, 0x59, 0x60, 0x68, 0x70, 0x78, 0x7F, 0x87,
|
||||
0x8D, 0x94, 0x9C, 0xA3, 0xAB, 0xB3, 0xB9, 0xC1, 0xC8,
|
||||
0xD0, 0xD8, 0xE0, 0xE8, 0xEE, 0xF5, 0x3B, 0x1A, 0xB6,
|
||||
0xA0, 0x07, 0x45, 0xC5, 0x37, 0x00};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 42, 0xC1,
|
||||
InitParam12);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xBD,
|
||||
0x02);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t InitParam13[42] = {
|
||||
0x00, 0x09, 0x0F, 0x18, 0x21, 0x2A, 0x34, 0x3C, 0x45, 0x4C, 0x56,
|
||||
0x5E, 0x66, 0x6E, 0x76, 0x7E, 0x87, 0x8E, 0x95, 0x9D, 0xA6, 0xAF,
|
||||
0xB7, 0xBD, 0xC5, 0xCE, 0xD5, 0xDF, 0xE7, 0xEE, 0xF4, 0xFA, 0xFF,
|
||||
0x0C, 0x31, 0x83, 0x3C, 0x5B, 0x56, 0x1E, 0x5A, 0xFF};
|
||||
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 42, 0xC1,
|
||||
InitParam13);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xBD,
|
||||
0x00);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Exit Sleep Mode*/
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x11,
|
||||
0x00);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HAL_Delay(120);
|
||||
|
||||
/* Display On */
|
||||
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1,
|
||||
DSI_SET_DISPLAY_ON, 0x00);
|
||||
if (ret != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HAL_Delay(120);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif /*__ gfxmmu_lut_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define VSYNC 1
|
||||
#define VBP 12
|
||||
#define VFP 50
|
||||
#define VACT 481
|
||||
#define HSYNC 2
|
||||
#define HBP 1
|
||||
#define HFP 1
|
||||
#define HACT 480
|
||||
#define LCD_WIDTH 480
|
||||
#define LCD_HEIGHT 480
|
||||
|
||||
#define LCD_Y_OFFSET 1
|
||||
|
||||
#define GFXMMU_FB_SIZE 733936
|
||||
#define GFXMMU_LUT_FIRST 0
|
||||
#define GFXMMU_LUT_LAST 479
|
||||
#define GFXMMU_LUT_SIZE 480
|
||||
|
||||
#define PANEL_DSI_MODE DSI_VID_MODE_BURST
|
||||
#define PANEL_DSI_LANES DSI_TWO_DATA_LANES
|
||||
#define PANEL_LTDC_PIXEL_FORMAT LTDC_PIXEL_FORMAT_ARGB8888
|
||||
|
||||
// Size of the physical frame buffer in bytes
|
||||
//
|
||||
// It's smaller than size of the virtual frame buffer
|
||||
// due to used GFXMMU settings
|
||||
#define PHYSICAL_FRAME_BUFFER_SIZE (184320 * 4)
|
||||
|
||||
// Pitch (in pixels) of the virtual frame buffer
|
||||
#define FRAME_BUFFER_PIXELS_PER_LINE 768
|
||||
|
||||
// Size of the virtual frame buffer in bytes
|
||||
#define VIRTUAL_FRAME_BUFFER_SIZE \
|
||||
(FRAME_BUFFER_PIXELS_PER_LINE * LCD_HEIGHT * 4)
|
@ -1,226 +0,0 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <io/display.h>
|
||||
#include <sys/mpu.h>
|
||||
|
||||
#include "display_internal.h"
|
||||
|
||||
#if (DISPLAY_RESX != 240) || (DISPLAY_RESY != 240)
|
||||
#error "Incompatible display resolution"
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
// Display driver instance
|
||||
display_driver_t g_display_driver = {
|
||||
.initialized = false,
|
||||
};
|
||||
|
||||
void display_init(display_content_mode_t mode) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == DISPLAY_RESET_CONTENT) {
|
||||
__HAL_RCC_DSI_FORCE_RESET();
|
||||
__HAL_RCC_LTDC_FORCE_RESET();
|
||||
__HAL_RCC_GFXMMU_FORCE_RESET();
|
||||
__HAL_RCC_DSI_RELEASE_RESET();
|
||||
__HAL_RCC_LTDC_RELEASE_RESET();
|
||||
__HAL_RCC_GFXMMU_RELEASE_RESET();
|
||||
|
||||
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
|
||||
mpu_set_active_fb(physical_frame_buffer_0, PHYSICAL_FRAME_BUFFER_SIZE);
|
||||
memset(physical_frame_buffer_0, 0x00, PHYSICAL_FRAME_BUFFER_SIZE);
|
||||
|
||||
mpu_set_active_fb(physical_frame_buffer_1, PHYSICAL_FRAME_BUFFER_SIZE);
|
||||
memset(physical_frame_buffer_1, 0x00, PHYSICAL_FRAME_BUFFER_SIZE);
|
||||
|
||||
mpu_set_active_fb(NULL, 0);
|
||||
|
||||
BSP_LCD_Init(0, LCD_ORIENTATION_PORTRAIT);
|
||||
BSP_LCD_SetBrightness(0, 100);
|
||||
BSP_LCD_DisplayOn(0);
|
||||
} else {
|
||||
// Retain display content
|
||||
BSP_LCD_Reinit(0);
|
||||
if (drv->current_frame_buffer == 0) {
|
||||
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
|
||||
} else {
|
||||
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
|
||||
}
|
||||
}
|
||||
|
||||
drv->initialized = true;
|
||||
}
|
||||
|
||||
void display_deinit(display_content_mode_t mode) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
if (mode == DISPLAY_RESET_CONTENT) {
|
||||
__HAL_RCC_DSI_FORCE_RESET();
|
||||
__HAL_RCC_LTDC_FORCE_RESET();
|
||||
__HAL_RCC_GFXMMU_FORCE_RESET();
|
||||
__HAL_RCC_DSI_RELEASE_RESET();
|
||||
__HAL_RCC_LTDC_RELEASE_RESET();
|
||||
__HAL_RCC_GFXMMU_RELEASE_RESET();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == DISPLAY_RESET_CONTENT) {
|
||||
BSP_LCD_DisplayOff(0);
|
||||
BSP_LCD_SetBrightness(0, 0);
|
||||
BSP_LCD_DeInit(0);
|
||||
}
|
||||
|
||||
mpu_set_active_fb(NULL, 0);
|
||||
|
||||
drv->initialized = false;
|
||||
}
|
||||
|
||||
int display_set_backlight(int level) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Just emulation, not doing anything
|
||||
drv->backlight_level = level;
|
||||
return level;
|
||||
}
|
||||
|
||||
int display_get_backlight(void) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return drv->orientation_angle;
|
||||
}
|
||||
|
||||
int display_set_orientation(int angle) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (angle == 0 || angle == 90 || angle == 180 || angle == 270) {
|
||||
// Just emulation, not doing anything
|
||||
drv->orientation_angle = angle;
|
||||
}
|
||||
|
||||
return drv->orientation_angle;
|
||||
}
|
||||
|
||||
int display_get_orientation(void) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return drv->orientation_angle;
|
||||
}
|
||||
|
||||
void display_fill(const gfx_bitblt_t *bb) {
|
||||
display_fb_info_t fb;
|
||||
|
||||
if (!display_get_frame_buffer(&fb)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx_bitblt_t bb_new = *bb;
|
||||
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
|
||||
bb_new.dst_stride = fb.stride;
|
||||
|
||||
gfx_rgba8888_fill(&bb_new);
|
||||
}
|
||||
|
||||
void display_copy_rgb565(const gfx_bitblt_t *bb) {
|
||||
display_fb_info_t fb;
|
||||
|
||||
if (!display_get_frame_buffer(&fb)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx_bitblt_t bb_new = *bb;
|
||||
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
|
||||
bb_new.dst_stride = fb.stride;
|
||||
|
||||
gfx_rgba8888_copy_rgb565(&bb_new);
|
||||
}
|
||||
|
||||
void display_copy_mono1p(const gfx_bitblt_t *bb) {
|
||||
display_fb_info_t fb;
|
||||
|
||||
if (!display_get_frame_buffer(&fb)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx_bitblt_t bb_new = *bb;
|
||||
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
|
||||
bb_new.dst_stride = fb.stride;
|
||||
|
||||
gfx_rgba8888_copy_mono1p(&bb_new);
|
||||
}
|
||||
|
||||
void display_copy_mono4(const gfx_bitblt_t *bb) {
|
||||
display_fb_info_t fb;
|
||||
|
||||
if (!display_get_frame_buffer(&fb)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx_bitblt_t bb_new = *bb;
|
||||
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
|
||||
bb_new.dst_stride = fb.stride;
|
||||
|
||||
gfx_rgba8888_copy_mono4(&bb_new);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <io/display.h>
|
||||
#include <sys/mpu.h>
|
||||
|
||||
#include "display_internal.h"
|
||||
|
||||
#ifdef USE_TRUSTZONE
|
||||
#include <sys/trustzone.h>
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
// Physical frame buffers in internal SRAM memory
|
||||
__attribute__((section(".fb1"), aligned(PHYSICAL_FRAME_BUFFER_ALIGNMENT)))
|
||||
uint8_t physical_frame_buffer_0[PHYSICAL_FRAME_BUFFER_SIZE];
|
||||
|
||||
__attribute__((section(".fb2"), aligned(PHYSICAL_FRAME_BUFFER_ALIGNMENT)))
|
||||
uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE];
|
||||
|
||||
#ifdef USE_TRUSTZONE
|
||||
void display_set_unpriv_access(bool unpriv) {
|
||||
// To allow unprivileged access both GFXMMU virtual buffers area and
|
||||
// underlying SRAM region must be configured as unprivileged.
|
||||
|
||||
// Order of GFXMMU and SRAM unprivileged access configuration is important
|
||||
// to avoid the situation the virtual frame buffer has lower privileges
|
||||
// than underlying frame buffer in physical memory so LTDC could not
|
||||
// refresh the display properly.
|
||||
|
||||
if (!unpriv) {
|
||||
tz_set_gfxmmu_unpriv(unpriv);
|
||||
}
|
||||
|
||||
tz_set_sram_unpriv((uint32_t)physical_frame_buffer_0,
|
||||
PHYSICAL_FRAME_BUFFER_SIZE, unpriv);
|
||||
|
||||
tz_set_sram_unpriv((uint32_t)physical_frame_buffer_1,
|
||||
PHYSICAL_FRAME_BUFFER_SIZE, unpriv);
|
||||
|
||||
if (unpriv) {
|
||||
tz_set_gfxmmu_unpriv(unpriv);
|
||||
}
|
||||
|
||||
#ifdef USE_DMA2D
|
||||
tz_set_dma2d_unpriv(unpriv);
|
||||
#endif
|
||||
}
|
||||
#endif // USE_TRUSTZONE
|
||||
|
||||
bool display_get_frame_buffer(display_fb_info_t *fb) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
fb->ptr = NULL;
|
||||
fb->stride = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uintptr_t addr;
|
||||
|
||||
if (drv->current_frame_buffer == 0) {
|
||||
addr = GFXMMU_VIRTUAL_BUFFER1_BASE_S;
|
||||
} else {
|
||||
addr = GFXMMU_VIRTUAL_BUFFER0_BASE_S;
|
||||
}
|
||||
|
||||
uint32_t fb_stride = FRAME_BUFFER_PIXELS_PER_LINE * sizeof(uint32_t);
|
||||
|
||||
// We do not utilize whole area of the display
|
||||
// (discovery kit display is 480x480 and we need just 240x240)
|
||||
addr += (480 - DISPLAY_RESY) / 2 * sizeof(uint32_t);
|
||||
addr += (480 - DISPLAY_RESX) / 2 * fb_stride;
|
||||
|
||||
fb->ptr = (void *)addr;
|
||||
fb->stride = fb_stride;
|
||||
|
||||
// Enable access to the frame buffer from the unprivileged code
|
||||
mpu_set_active_fb(fb->ptr, VIRTUAL_FRAME_BUFFER_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void display_refresh(void) {
|
||||
display_driver_t *drv = &g_display_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable access to the frame buffer from the unprivileged code
|
||||
mpu_set_active_fb(NULL, 0);
|
||||
|
||||
if (drv->current_frame_buffer == 0) {
|
||||
drv->current_frame_buffer = 1;
|
||||
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
|
||||
} else {
|
||||
drv->current_frame_buffer = 0;
|
||||
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZOR_HAL_DISPLAY_INTERNAL_H
|
||||
#define TREZOR_HAL_DISPLAY_INTERNAL_H
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include <rtl/sizedefs.h>
|
||||
|
||||
#ifdef USE_TRUSTZONE
|
||||
#include <sys/trustzone.h>
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
// The current frame buffer selector
|
||||
uint32_t current_frame_buffer;
|
||||
} display_driver_t;
|
||||
|
||||
// Display driver instance
|
||||
extern display_driver_t g_display_driver;
|
||||
|
||||
// Hardware requires physical frame buffer alignment
|
||||
#ifdef USE_TRUSTZONE
|
||||
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT TZ_SRAM_ALIGNMENT
|
||||
#else
|
||||
#define PHYSICAL_FRAME_BUFFER_ALIGNMENT 32
|
||||
#endif
|
||||
|
||||
// Size of the physical frame buffer in bytes
|
||||
//
|
||||
// It's smaller than size of the virtual frame buffer
|
||||
// due to used GFXMMU settings
|
||||
#define PHYSICAL_FRAME_BUFFER_SIZE \
|
||||
ALIGN_UP_CONST(184320 * 4, PHYSICAL_FRAME_BUFFER_ALIGNMENT)
|
||||
|
||||
// Pitch (in pixels) of the virtual frame buffer
|
||||
#define FRAME_BUFFER_PIXELS_PER_LINE 768
|
||||
|
||||
// Size of the virtual frame buffer in bytes
|
||||
#define VIRTUAL_FRAME_BUFFER_SIZE \
|
||||
(FRAME_BUFFER_PIXELS_PER_LINE * DISPLAY_RESY * 4)
|
||||
|
||||
// Physical frame buffers in internal SRAM memory
|
||||
//
|
||||
// Both frame buffers layers 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];
|
||||
|
||||
// LCD orientations
|
||||
#define LCD_ORIENTATION_PORTRAIT 0U
|
||||
#define LCD_ORIENTATION_LANDSCAPE 1U
|
||||
#define LCD_ORIENTATION_PORTRAIT_ROT180 2U
|
||||
#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
|
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,14 @@
|
||||
#define VDD_1V8 1
|
||||
|
||||
#define DISPLAY_COLOR_MODE DMA2D_OUTPUT_ARGB8888
|
||||
#define DISPLAY_PANEL_STM32U5A9J_DK
|
||||
#define DISPLAY_GFXMMU 1
|
||||
#define DISPLAY_RESET_PIN GPIO_PIN_5
|
||||
#define DISPLAY_RESET_PORT GPIOD
|
||||
#define DISPLAY_RESET_CLK_ENA __HAL_RCC_GPIOD_CLK_ENABLE
|
||||
#define DISPLAY_BACKLIGHT_PIN GPIO_PIN_6
|
||||
#define DISPLAY_BACKLIGHT_PORT GPIOI
|
||||
#define DISPLAY_BACKLIGHT_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
|
||||
|
||||
#define I2C_COUNT 1
|
||||
#define I2C_INSTANCE_0 I2C5
|
||||
|
@ -39,9 +39,12 @@ def configure(
|
||||
]
|
||||
|
||||
sources += [
|
||||
"embed/io/display/stm32u5a9j-dk/display_driver.c",
|
||||
"embed/io/display/stm32u5a9j-dk/display_fb.c",
|
||||
"embed/io/display/stm32u5a9j-dk/display_ltdc_dsi.c",
|
||||
"embed/io/display/ltdc_dsi/display_driver.c",
|
||||
"embed/io/display/ltdc_dsi/panels/stm32u5a9j-dk/stm32u5a9j-dk.c",
|
||||
"embed/io/display/ltdc_dsi/display_fb.c",
|
||||
"embed/io/display/ltdc_dsi/display_fb_rgb888.c",
|
||||
"embed/io/display/ltdc_dsi/display_gfxmmu.c",
|
||||
"embed/io/display/fb_queue/fb_queue.c",
|
||||
]
|
||||
paths += ["embed/io/display/inc"]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user