diff --git a/core/embed/io/display/ltdc_dsi/display_driver.c b/core/embed/io/display/ltdc_dsi/display_driver.c index 219948d784..d939c42888 100644 --- a/core/embed/io/display/ltdc_dsi/display_driver.c +++ b/core/embed/io/display/ltdc_dsi/display_driver.c @@ -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) { diff --git a/core/embed/io/display/ltdc_dsi/display_gfxmmu.c b/core/embed/io/display/ltdc_dsi/display_gfxmmu.c index 926b9d57c5..7635a701f6 100644 --- a/core/embed/io/display/ltdc_dsi/display_gfxmmu.c +++ b/core/embed/io/display/ltdc_dsi/display_gfxmmu.c @@ -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 diff --git a/core/embed/io/display/ltdc_dsi/display_internal.h b/core/embed/io/display/ltdc_dsi/display_internal.h index bd48e14c25..c4a8cafba0 100644 --- a/core/embed/io/display/ltdc_dsi/display_internal.h +++ b/core/embed/io/display/ltdc_dsi/display_internal.h @@ -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 diff --git a/core/embed/io/display/ltdc_dsi/panels/lx200d2406a/lx200d2406a.c b/core/embed/io/display/ltdc_dsi/panels/lx200d2406a/lx200d2406a.c index fc81069a44..dfbe30ea7a 100644 --- a/core/embed/io/display/ltdc_dsi/panels/lx200d2406a/lx200d2406a.c +++ b/core/embed/io/display/ltdc_dsi/panels/lx200d2406a/lx200d2406a.c @@ -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; }