1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-12 17:38:13 +00:00

fixup! feat(core): display driver for T3W1

This commit is contained in:
tychovrahe 2024-12-10 11:35:00 +01:00
parent f779a062b5
commit f7117a70f8
4 changed files with 197 additions and 67 deletions

View File

@ -21,7 +21,7 @@ display_driver_t g_display_driver = {
.initialized = false,
};
static void display_pll_init(void) {
static bool display_pll_init(void) {
RCC_PeriphCLKInitTypeDef PLL3InitPeriph = {0};
/* Start and configure PLL3 */
@ -46,10 +46,10 @@ static void display_pll_init(void) {
PLL3InitPeriph.PLL3.PLL3RGE = RCC_PLLVCIRANGE_0;
PLL3InitPeriph.PLL3.PLL3ClockOut = RCC_PLL3_DIVR | RCC_PLL3_DIVP;
PLL3InitPeriph.PLL3.PLL3Source = RCC_PLLSOURCE_HSE;
(void)HAL_RCCEx_PeriphCLKConfig(&PLL3InitPeriph);
return HAL_RCCEx_PeriphCLKConfig(&PLL3InitPeriph) == HAL_OK;
}
static void display_dsi_init(void) {
static bool display_dsi_init(void) {
display_driver_t *drv = &g_display_driver;
RCC_PeriphCLKInitTypeDef DSIPHYInitPeriph = {0};
@ -83,7 +83,9 @@ static void display_dsi_init(void) {
DSIPHYInitPeriph.PeriphClockSelection = RCC_PERIPHCLK_DSI;
DSIPHYInitPeriph.DsiClockSelection = RCC_DSICLKSOURCE_DSIPHY;
(void)HAL_RCCEx_PeriphCLKConfig(&DSIPHYInitPeriph);
if (HAL_RCCEx_PeriphCLKConfig(&DSIPHYInitPeriph) != HAL_OK) {
return false;
}
/* Reset the TX escape clock division factor */
drv->hlcd_dsi.Instance->CCR &= ~DSI_CCR_TXECKDIV;
@ -116,8 +118,12 @@ static void display_dsi_init(void) {
PLLInit.PLLChargePump = DSI_PLL_CHARGE_PUMP_2000HZ_4400HZ;
PLLInit.PLLTuning = DSI_PLL_LOOP_FILTER_2000HZ_4400HZ;
HAL_DSI_Init(&drv->hlcd_dsi, &PLLInit);
HAL_DSI_SetGenericVCID(&drv->hlcd_dsi, 0);
if (HAL_DSI_Init(&drv->hlcd_dsi, &PLLInit) != HAL_OK) {
return false;
}
if (HAL_DSI_SetGenericVCID(&drv->hlcd_dsi, 0) != HAL_OK) {
return false;
}
/* Configure the DSI for Video mode */
drv->DSIVidCfg.VirtualChannelID = 0;
@ -150,7 +156,9 @@ static void display_dsi_init(void) {
drv->DSIVidCfg.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
/* Drive the display */
HAL_DSI_ConfigVideoMode(&drv->hlcd_dsi, &drv->DSIVidCfg);
if (HAL_DSI_ConfigVideoMode(&drv->hlcd_dsi, &drv->DSIVidCfg) != HAL_OK) {
return false;
}
/*********************/
/* LCD configuration */
@ -162,7 +170,9 @@ static void display_dsi_init(void) {
PhyTimers.DataLaneMaxReadTime = 0;
PhyTimers.StopWaitTime = 7;
HAL_DSI_ConfigPhyTimer(&drv->hlcd_dsi, &PhyTimers);
if (HAL_DSI_ConfigPhyTimer(&drv->hlcd_dsi, &PhyTimers)) {
return false;
}
HostTimeouts.TimeoutCkdiv = 1;
HostTimeouts.HighSpeedTransmissionTimeout = 0;
@ -174,14 +184,22 @@ static void display_dsi_init(void) {
HostTimeouts.LowPowerWriteTimeout = 0;
HostTimeouts.BTATimeout = 0;
HAL_DSI_ConfigHostTimeouts(&drv->hlcd_dsi, &HostTimeouts);
HAL_DSI_ConfigFlowControl(&drv->hlcd_dsi, DSI_FLOW_CONTROL_BTA);
if (HAL_DSI_ConfigHostTimeouts(&drv->hlcd_dsi, &HostTimeouts) != HAL_OK) {
return false;
}
if (HAL_DSI_ConfigFlowControl(&drv->hlcd_dsi, DSI_FLOW_CONTROL_BTA) !=
HAL_OK) {
return false;
}
/* Enable the DSI host */
__HAL_DSI_ENABLE(&drv->hlcd_dsi);
return true;
}
static void display_ltdc_config_layer(LTDC_HandleTypeDef *hltdc,
static bool display_ltdc_config_layer(LTDC_HandleTypeDef *hltdc,
uint32_t fb_addr) {
LTDC_LayerCfgTypeDef LayerCfg = {0};
@ -206,10 +224,10 @@ static void display_ltdc_config_layer(LTDC_HandleTypeDef *hltdc,
LayerCfg.Backcolor.Green = 0; /* Not Used: default value */
LayerCfg.Backcolor.Blue = 0; /* Not Used: default value */
LayerCfg.Backcolor.Reserved = 0xFF;
HAL_LTDC_ConfigLayer(hltdc, &LayerCfg, LTDC_LAYER_1);
return HAL_LTDC_ConfigLayer(hltdc, &LayerCfg, LTDC_LAYER_1) == HAL_OK;
}
static void display_ltdc_init(void) {
static bool display_ltdc_init(void) {
display_driver_t *drv = &g_display_driver;
__HAL_RCC_LTDC_CLK_ENABLE();
@ -229,16 +247,22 @@ static void display_ltdc_init(void) {
drv->hlcd_ltdc.Init.Backcolor.Blue = 0; /* Not used default value */
drv->hlcd_ltdc.Init.Backcolor.Reserved = 0xFF;
HAL_LTDCEx_StructInitFromVideoConfig(&drv->hlcd_ltdc, &drv->DSIVidCfg);
if (HAL_LTDCEx_StructInitFromVideoConfig(&drv->hlcd_ltdc, &drv->DSIVidCfg) !=
HAL_OK) {
return false;
}
HAL_LTDC_Init(&drv->hlcd_ltdc);
if (HAL_LTDC_Init(&drv->hlcd_ltdc) != HAL_OK) {
return false;
}
display_ltdc_config_layer(&drv->hlcd_ltdc, display_fb_get_initial_addr());
return display_ltdc_config_layer(&drv->hlcd_ltdc,
display_fb_get_initial_addr());
}
void display_set_fb(uint32_t fb_addr) {
bool display_set_fb(uint32_t fb_addr) {
display_driver_t *drv = &g_display_driver;
display_ltdc_config_layer(&drv->hlcd_ltdc, fb_addr);
return display_ltdc_config_layer(&drv->hlcd_ltdc, fb_addr);
}
// Fully initializes the display controller.
@ -297,16 +321,28 @@ void display_init(display_content_mode_t mode) {
display_gfxmmu_init(drv);
#endif
display_pll_init();
display_dsi_init();
display_ltdc_init();
if (!display_pll_init()) {
goto cleanup;
}
if (!display_dsi_init()) {
goto cleanup;
}
if (!display_ltdc_init()) {
goto cleanup;
}
/* Start DSI */
HAL_DSI_Start(&drv->hlcd_dsi);
if (HAL_DSI_Start(&drv->hlcd_dsi) != HAL_OK) {
goto cleanup;
}
panel_init(drv);
if (!panel_init(drv)) {
goto cleanup;
}
HAL_LTDC_ProgramLineEvent(&drv->hlcd_ltdc, LCD_HEIGHT);
if (HAL_LTDC_ProgramLineEvent(&drv->hlcd_ltdc, LCD_HEIGHT) != HAL_OK) {
goto cleanup;
}
/* Enable LTDC interrupt */
NVIC_SetPriority(LTDC_IRQn, IRQ_PRI_NORMAL);
@ -318,6 +354,24 @@ void display_init(display_content_mode_t mode) {
__HAL_LTDC_ENABLE_IT(&drv->hlcd_ltdc, LTDC_IT_LI | LTDC_IT_FU | LTDC_IT_TE);
drv->initialized = true;
return;
cleanup:
NVIC_DisableIRQ(LTDC_IRQn);
NVIC_DisableIRQ(LTDC_ER_IRQn);
__HAL_RCC_DSI_FORCE_RESET();
__HAL_RCC_LTDC_FORCE_RESET();
__HAL_RCC_LTDC_RELEASE_RESET();
__HAL_RCC_DSI_RELEASE_RESET();
#ifdef DISPLAY_GFXMMU
__HAL_RCC_GFXMMU_FORCE_RESET();
__HAL_RCC_GFXMMU_RELEASE_RESET();
#endif
drv->initialized = false;
}
int display_set_backlight(int level) {

View File

@ -10,7 +10,7 @@ extern uint8_t physical_frame_buffer_1[PHYSICAL_FRAME_BUFFER_SIZE];
extern const uint32_t gfxmmu_lut_config[2 * GFXMMU_LUT_SIZE];
void display_gfxmmu_init(display_driver_t *drv) {
bool display_gfxmmu_init(display_driver_t *drv) {
__HAL_RCC_GFXMMU_FORCE_RESET();
__HAL_RCC_GFXMMU_RELEASE_RESET();
@ -50,12 +50,21 @@ void display_gfxmmu_init(display_driver_t *drv) {
drv->hlcd_gfxmmu.Init.Interrupts.Activation = DISABLE;
drv->hlcd_gfxmmu.Init.Interrupts.UsedInterrupts =
GFXMMU_AHB_MASTER_ERROR_IT; /* NU */
HAL_GFXMMU_Init(&drv->hlcd_gfxmmu);
if (HAL_GFXMMU_Init(&drv->hlcd_gfxmmu) != HAL_OK) {
return false;
}
/* Initialize LUT */
HAL_GFXMMU_ConfigLut(&drv->hlcd_gfxmmu, 0, LCD_HEIGHT,
(uint32_t)&gfxmmu_lut_config);
if (HAL_GFXMMU_ConfigLut(&drv->hlcd_gfxmmu, 0, LCD_HEIGHT,
(uint32_t)&gfxmmu_lut_config) != HAL_OK) {
return false;
}
HAL_GFXMMU_DisableLutLines(&drv->hlcd_gfxmmu, LCD_HEIGHT, 1024 - LCD_HEIGHT);
if (HAL_GFXMMU_DisableLutLines(&drv->hlcd_gfxmmu, LCD_HEIGHT,
1024 - LCD_HEIGHT) != HAL_OK) {
return false;
}
return true;
}
#endif

View File

@ -60,7 +60,7 @@ typedef struct {
extern display_driver_t g_display_driver;
void display_set_fb(uint32_t fb_addr);
bool display_set_fb(uint32_t fb_addr);
void display_fb_clear(void);
@ -74,10 +74,10 @@ static inline uint32_t is_mode_exception(void) {
void display_ensure_refreshed(void);
void panel_init(display_driver_t *drv);
bool panel_init(display_driver_t *drv);
#ifdef DISPLAY_GFXMMU
void display_gfxmmu_init(display_driver_t *drv);
bool display_gfxmmu_init(display_driver_t *drv);
#endif
#endif // TREZOR_HAL_DISPLAY_INTERNAL_H

View File

@ -10,16 +10,34 @@
// todo static assert resolution
void panel_init(display_driver_t *drv) {
HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x11, 0);
bool panel_init(display_driver_t *drv) {
HAL_StatusTypeDef ret;
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x11,
0);
if (ret != HAL_OK) {
return false;
}
systick_delay_ms(120);
HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x36, 0x00);
HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x3A, 0x06);
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x36,
0x00);
if (ret != HAL_OK) {
return false;
}
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x3A,
0x06);
if (ret != HAL_OK) {
return false;
}
// mipi video mode
HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xB0, 0x10);
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xB0,
0x10);
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xB2);
// Write(Parameter , 0x00);
@ -32,65 +50,95 @@ void panel_init(display_driver_t *drv) {
// Write(Parameter , 0x33);
// Write(Parameter , 0x00);
// Write(Parameter , 0x33);
HAL_DSI_LongWrite(
ret = HAL_DSI_LongWrite(
&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 10, 0xB2,
(uint8_t[]){0x00, 0x0c, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x33, 0x00, 0x33});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xB7);
// Write(Parameter , 0x00);
// Write(Parameter , 0x06);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xB7,
(uint8_t[]){0x00, 0x06});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xB7,
(uint8_t[]){0x00, 0x06});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xBB);
// Write(Parameter , 0x00);
// Write(Parameter , 0x1E);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xBB,
(uint8_t[]){0x00, 0x1E});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xBB,
(uint8_t[]){0x00, 0x1E});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xC0);
// Write(Parameter , 0x00);
// Write(Parameter , 0x2C);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC0,
(uint8_t[]){0x00, 0x2C});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC0,
(uint8_t[]){0x00, 0x2C});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xC2);
// Write(Parameter , 0x00);
// Write(Parameter , 0x01);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC2,
(uint8_t[]){0x00, 0x01});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC2,
(uint8_t[]){0x00, 0x01});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xC3);
// Write(Parameter , 0x00);
// Write(Parameter , 0x0F);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC3,
(uint8_t[]){0x00, 0x0F});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC3,
(uint8_t[]){0x00, 0x0F});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xC6);
// Write(Parameter , 0x00);
// Write(Parameter , 0x0F);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC6,
(uint8_t[]){0x00, 0x0F});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xC6,
(uint8_t[]){0x00, 0x0F});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xD0);
// Write(Parameter , 0x00);
// Write(Parameter , 0xA7);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xD0,
(uint8_t[]){0x00, 0xA7});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xD0,
(uint8_t[]){0x00, 0xA7});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xD0);
// Write(Parameter , 0x00);
// Write(Parameter , 0xA4);
// Write(Parameter , 0x00);
// Write(Parameter , 0xA1);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 4, 0xD0,
(uint8_t[]){0x00, 0xA4, 0x00, 0xA1});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 4, 0xD0,
(uint8_t[]){0x00, 0xA4, 0x00, 0xA1});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xD6);
// Write(Parameter , 0x00);
// Write(Parameter , 0xA1);
HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xD6,
(uint8_t[]){0x00, 0xA1});
ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 2, 0xD6,
(uint8_t[]){0x00, 0xA1});
if (ret != HAL_OK) {
return false;
}
// Write(Command , 0xE0);
// Write(Parameter , 0x00);
@ -121,10 +169,12 @@ void panel_init(display_driver_t *drv) {
// Write(Parameter , 0x34);
// Write(Parameter , 0x00);
// Write(Parameter , 0x3A);
// HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 28, 0xE0,
// (uint8_t[]){0x00, 0xF0, 0x00, 0x06, 0x00, 0x11, 0x00, 0x09, 0x00, 0x0A,
// 0x00, 0x28, 0x00, 0x37, 0x00, 0x44, 0x00, 0x4E, 0x00, 0x39, 0x00, 0x14,
// 0x00, 0x15, 0x00, 0x34, 0x00, 0x3A});
// ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 28,
// 0xE0, (uint8_t[]){0x00, 0xF0, 0x00, 0x06, 0x00, 0x11, 0x00, 0x09, 0x00,
// 0x0A, 0x00, 0x28, 0x00, 0x37, 0x00, 0x44, 0x00, 0x4E, 0x00, 0x39, 0x00,
// 0x14, 0x00, 0x15, 0x00, 0x34, 0x00, 0x3A}); if (ret != HAL_OK) {
// return false;
// }
// Write(Command , 0xE1);
// Write(Parameter , 0x00);
@ -155,12 +205,29 @@ void panel_init(display_driver_t *drv) {
// Write(Parameter , 0x32);
// Write(Parameter , 0x00);
// Write(Parameter , 0x39);
// HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 28, 0xE1,
// (uint8_t[]){0x00, 0xF0, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x0A, 0x00, 0x08,
// 0x00, 0x04, 0x00, 0x37, 0x00, 0x43, 0x00, 0x4D, 0x00, 0x35, 0x00, 0x12,
// 0x00, 0x13, 0x00, 0x32, 0x00, 0x39});
// ret = HAL_DSI_LongWrite(&drv->hlcd_dsi, 0, DSI_DCS_LONG_PKT_WRITE, 28,
// 0xE1, (uint8_t[]){0x00, 0xF0, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x0A, 0x00,
// 0x08, 0x00, 0x04, 0x00, 0x37, 0x00, 0x43, 0x00, 0x4D, 0x00, 0x35, 0x00,
// 0x12, 0x00, 0x13, 0x00, 0x32, 0x00, 0x39}); if (ret != HAL_OK) {
// return false;
// }
HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x21, 0);
HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x29, 0);
HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x2C, 0);
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x21,
0);
if (ret != HAL_OK) {
return false;
}
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x29,
0);
if (ret != HAL_OK) {
return false;
}
ret = HAL_DSI_ShortWrite(&drv->hlcd_dsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x2C,
0);
if (ret != HAL_OK) {
return false;
}
return true;
}