2025-08-26 5:52 AM
Hi, I'm using a custom board based on STM32U5G9J-DK1.I am using DSI Video mode with double buffering, but i had some issues in the DSI video mode.
I am using CO5300 driver-based 466 X 466 Display which supports DSI video mode
I successfully got a display displaying the actual GUI but it is slightly shifted from the left and from upper and bottom side as well
I am attaching images here; the first image is the simulator, and the second is the actual display.
Simulator Image:
Actual Hardware:
My configuration for clocks are as given below
My MX_DSIHOST_DSI_Init() function looks like below
static void MX_DSIHOST_DSI_Init(void)
{
/* USER CODE BEGIN DSIHOST_Init 0 */
// Power up sequence
HAL_GPIO_WritePin(PWR_EN_GPIO_Port, PWR_EN_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(BACKLIGHT_EN_GPIO_Port, BACKLIGHT_EN_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(PANEL_RESET_GPIO_Port, PANEL_RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(VCI_EN_GPIO_Port, VCI_EN_Pin, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(BACKLIGHT_EN_GPIO_Port, BACKLIGHT_EN_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(PWR_EN_GPIO_Port, PWR_EN_Pin, GPIO_PIN_SET);
/* USER CODE END DSIHOST_Init 0 */
DSI_PLLInitTypeDef PLLInit = {0};
DSI_HOST_TimeoutTypeDef HostTimeouts = {0};
DSI_PHY_TimerTypeDef PhyTimings = {0};
DSI_VidCfgTypeDef VidCfg = {0};
/* USER CODE BEGIN DSIHOST_Init 1 */
/* USER CODE END DSIHOST_Init 1 */
hdsi.Instance = DSI;
hdsi.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_ENABLE;
hdsi.Init.TXEscapeCkdiv = 4;
hdsi.Init.NumberOfLanes = DSI_ONE_DATA_LANE;
hdsi.Init.PHYFrequencyRange = DSI_DPHY_FRANGE_450MHZ_510MHZ;
hdsi.Init.PHYLowPowerOffset = PHY_LP_OFFSSET_0_CLKP;
PLLInit.PLLNDIV = 125;
PLLInit.PLLIDF = DSI_PLL_IN_DIV4;
PLLInit.PLLODF = DSI_PLL_OUT_DIV2;
PLLInit.PLLVCORange = DSI_DPHY_VCO_FRANGE_800MHZ_1GHZ;
PLLInit.PLLChargePump = DSI_PLL_CHARGE_PUMP_2000HZ_4400HZ;
PLLInit.PLLTuning = DSI_PLL_LOOP_FILTER_2000HZ_4400HZ;
if (HAL_DSI_Init(&hdsi, &PLLInit) != HAL_OK)
{
Error_Handler();
}
HostTimeouts.TimeoutCkdiv = 1;
HostTimeouts.HighSpeedTransmissionTimeout = 0;
HostTimeouts.LowPowerReceptionTimeout = 0;
HostTimeouts.HighSpeedReadTimeout = 0;
HostTimeouts.LowPowerReadTimeout = 0;
HostTimeouts.HighSpeedWriteTimeout = 0;
HostTimeouts.HighSpeedWritePrespMode = DSI_HS_PM_DISABLE;
HostTimeouts.LowPowerWriteTimeout = 0;
HostTimeouts.BTATimeout = 0;
if (HAL_DSI_ConfigHostTimeouts(&hdsi, &HostTimeouts) != HAL_OK)
{
Error_Handler();
}
PhyTimings.ClockLaneHS2LPTime = 40;
PhyTimings.ClockLaneLP2HSTime = 40;
PhyTimings.DataLaneHS2LPTime = 12;
PhyTimings.DataLaneLP2HSTime = 13;
PhyTimings.DataLaneMaxReadTime = 0;
PhyTimings.StopWaitTime = 7;
if (HAL_DSI_ConfigPhyTimer(&hdsi, &PhyTimings) != HAL_OK)
{
Error_Handler();
}
if (HAL_DSI_ConfigFlowControl(&hdsi, DSI_FLOW_CONTROL_BTA) != HAL_OK)
{
Error_Handler();
}
if (HAL_DSI_SetLanePinsConfiguration(&hdsi, DSI_SWAP_LANE_PINS, DSI_CLOCK_LANE, ENABLE) != HAL_OK)
{
Error_Handler();
}
if (HAL_DSI_ConfigErrorMonitor(&hdsi, HAL_DSI_ERROR_NONE) != HAL_OK)
{
Error_Handler();
}
VidCfg.ColorCoding = DSI_RGB888;
VidCfg.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
VidCfg.Mode = DSI_VID_MODE_BURST;
VidCfg.PacketSize = 466;
VidCfg.NumberOfChunks = 0;
VidCfg.NullPacketSize = 0;
VidCfg.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
VidCfg.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
VidCfg.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
VidCfg.HorizontalSyncActive = 1;
VidCfg.HorizontalBackPorch = 1;
VidCfg.HorizontalLine = 466;
VidCfg.VerticalSyncActive = 2;
VidCfg.VerticalBackPorch = 2;
VidCfg.VerticalFrontPorch = 2;
VidCfg.VerticalActive = 466;
VidCfg.LPCommandEnable = DSI_LP_COMMAND_DISABLE;
VidCfg.LPLargestPacketSize = 0;
VidCfg.LPVACTLargestPacketSize = 0;
VidCfg.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;
VidCfg.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE;
VidCfg.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;
VidCfg.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;
VidCfg.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;
VidCfg.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE;
VidCfg.FrameBTAAcknowledgeEnable = DSI_FBTAA_ENABLE;
if (HAL_DSI_ConfigVideoMode(&hdsi, &VidCfg) != HAL_OK)
{
Error_Handler();
}
if (HAL_DSI_SetGenericVCID(&hdsi, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN DSIHOST_Init 2 */
if (HAL_DSI_Start(&hdsi) != HAL_OK)
{
Error_Handler();
}
RCC_PeriphCLKInitTypeDef PeriphClkInit;
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_DSI;
PeriphClkInit.DsiClockSelection = RCC_DSICLKSOURCE_DSIPHY;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
// display reset
HAL_GPIO_WritePin(PANEL_RESET_GPIO_Port, PANEL_RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(20);
HAL_GPIO_WritePin(PANEL_RESET_GPIO_Port, PANEL_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(200);
/* USER CODE END DSIHOST_Init 2 */
}
My MX_LTDS_Init look like below
static void MX_LTDC_Init(void)
{
/* USER CODE BEGIN LTDC_Init 0 */
/* USER CODE END LTDC_Init 0 */
LTDC_LayerCfgTypeDef pLayerCfg = {0};
/* USER CODE BEGIN LTDC_Init 1 */
/* USER CODE END LTDC_Init 1 */
hltdc.Instance = LTDC;
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AH;
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AH;
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IIPC;
hltdc.Init.HorizontalSync = 1;
hltdc.Init.VerticalSync = 1;
hltdc.Init.AccumulatedHBP = 3;
hltdc.Init.AccumulatedVBP = 3;
hltdc.Init.AccumulatedActiveW = 469;
hltdc.Init.AccumulatedActiveH = 469;
hltdc.Init.TotalWidth = 471;
hltdc.Init.TotalHeigh = 471;
hltdc.Init.Backcolor.Blue = 0;
hltdc.Init.Backcolor.Green = 0;
hltdc.Init.Backcolor.Red = 0;
if (HAL_LTDC_Init(&hltdc) != HAL_OK)
{
Error_Handler();
}
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 466;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 466;
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
pLayerCfg.Alpha = 255;
pLayerCfg.Alpha0 = 0;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
pLayerCfg.FBStartAdress = 0x0;
pLayerCfg.ImageWidth = 466;
pLayerCfg.ImageHeight = 466;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN LTDC_Init 2 */
HAL_Delay(100);
// Page 0
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x00);
// TE ON
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x35, 0x00);
// Ctrl Display
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x53, 0x20);
// Brightness
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x51, 0xFF);
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x63, 0xFF);
// Set column/row (example payloads)
uint8_t col[] = {0x00,0x06,0x01,0xD7};
uint8_t row[] = {0x00,0x00,0x01,0xD1};
HAL_DSI_LongWrite(&hdsi, 0, DSI_GEN_LONG_PKT_WRITE, 5, 0x2A, col);
HAL_DSI_LongWrite(&hdsi, 0, DSI_GEN_LONG_PKT_WRITE, 5, 0x2B, row);
// Sleep Out, Display ON
HAL_Delay(100);
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x11, 0);
HAL_Delay(100);
HAL_DSI_ShortWrite(&hdsi, 0, DSI_DCS_SHORT_PKT_WRITE_P0, 0x29, 0);
HAL_Delay(120);
// pLayerCfg.FBStartAdress = (uint32_t)disp_buffer;
for (int var = 0; var < 478*478; var++) {
disp_buffer[var] = 0xFF00FF00;
}
// while(1);
/* USER CODE END LTDC_Init 2 */
}
I have been debugging for over five days, yet the problem still exists. I am new to touchGFX so i dont have expertise like you guys.
Help will be really appreciated.
Solved! Go to Solution.
2025-09-12 4:54 AM
I solved the issue by changing my LTDC clock to 21.33 MHz and DSI clock to 42.666 Mhz.
A suggestion from @MM..1 really helped me to get the display working.
below is my DSI_VidCfgTypeDef VidCfg
#define LCD_WIDTH 466
#define LCD_HLINE (LCD_WIDTH + LCD_HSA + LCD_HBP + LCD_HFP)
#define LCD_VFP 8
#define LCD_HFP 20
#define LTDC_CLK_KHZ 21333
#define DSILANE_CLK_KHZ 42667
#define LCD_HEIGHT 466
#define LCD_VSA 2
#define LCD_VBP 8
#define LCD_HSA 2
#define LCD_HBP 16
VidCfg.ColorCoding = DSI_RGB888;
VidCfg.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
VidCfg.Mode = DSI_VID_MODE_BURST;
VidCfg.PacketSize = 466;
VidCfg.NumberOfChunks = 0;
VidCfg.NullPacketSize = 0;
VidCfg.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
VidCfg.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
VidCfg.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
VidCfg.HorizontalSyncActive = (LCD_HSA * DSILANE_CLK_KHZ) / LTDC_CLK_KHZ;
VidCfg.HorizontalBackPorch = (LCD_HBP * DSILANE_CLK_KHZ) / LTDC_CLK_KHZ;
VidCfg.HorizontalLine = (LCD_HLINE * DSILANE_CLK_KHZ) / LTDC_CLK_KHZ;
VidCfg.VerticalSyncActive = LCD_VSA;
VidCfg.VerticalBackPorch = LCD_VBP;
VidCfg.VerticalFrontPorch = LCD_VFP;
VidCfg.VerticalActive = LCD_HEIGHT;
VidCfg.LPCommandEnable = DSI_LP_COMMAND_DISABLE;
VidCfg.LPLargestPacketSize = 0;
VidCfg.LPVACTLargestPacketSize = 0;
VidCfg.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;
VidCfg.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE;
VidCfg.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;
VidCfg.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;
VidCfg.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;
VidCfg.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE;
VidCfg.FrameBTAAcknowledgeEnable = DSI_FBTAA_ENABLE;
if (HAL_DSI_ConfigVideoMode(&hdsi, &VidCfg) != HAL_OK)
{
Error_Handler();
}
2025-08-26 3:33 PM
I’ve dealt with that before. A shifted image in DSI video mode usually points to timing or sync issues. Double buffering can help, but you might need to tweak the display driver settings or check the panel timing configs.
2025-08-26 11:56 PM
Thank you very much @amelia892 , since i am relatively new to the DSI, i didnt understand how timing or sync works.
can you please elaborate more on this?
I am using below driver
driver link
2025-09-06 12:58 AM
Hello, have you tried changing line 68 of ltdc file? This sets the start column.
2025-09-06 3:03 AM
Start basic frame without TGFX run. And correct DSI config
VidCfg.HorizontalSyncActive = 1;
VidCfg.HorizontalBackPorch = 1;
VidCfg.HorizontalLine = 466;
this numbers require be in DSI clock counting, no video clock as LTDC. For example if LTDC dotclock is 20MHZ and DSI data clock is 60M all this require multiply 60/20= x3 usw.
Too exist helping func for start pattern on DSI ... HAL_DSI_PatternGeneratorStart(&hdsi,0,1);
2025-09-12 4:54 AM
I solved the issue by changing my LTDC clock to 21.33 MHz and DSI clock to 42.666 Mhz.
A suggestion from @MM..1 really helped me to get the display working.
below is my DSI_VidCfgTypeDef VidCfg
#define LCD_WIDTH 466
#define LCD_HLINE (LCD_WIDTH + LCD_HSA + LCD_HBP + LCD_HFP)
#define LCD_VFP 8
#define LCD_HFP 20
#define LTDC_CLK_KHZ 21333
#define DSILANE_CLK_KHZ 42667
#define LCD_HEIGHT 466
#define LCD_VSA 2
#define LCD_VBP 8
#define LCD_HSA 2
#define LCD_HBP 16
VidCfg.ColorCoding = DSI_RGB888;
VidCfg.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
VidCfg.Mode = DSI_VID_MODE_BURST;
VidCfg.PacketSize = 466;
VidCfg.NumberOfChunks = 0;
VidCfg.NullPacketSize = 0;
VidCfg.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
VidCfg.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
VidCfg.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
VidCfg.HorizontalSyncActive = (LCD_HSA * DSILANE_CLK_KHZ) / LTDC_CLK_KHZ;
VidCfg.HorizontalBackPorch = (LCD_HBP * DSILANE_CLK_KHZ) / LTDC_CLK_KHZ;
VidCfg.HorizontalLine = (LCD_HLINE * DSILANE_CLK_KHZ) / LTDC_CLK_KHZ;
VidCfg.VerticalSyncActive = LCD_VSA;
VidCfg.VerticalBackPorch = LCD_VBP;
VidCfg.VerticalFrontPorch = LCD_VFP;
VidCfg.VerticalActive = LCD_HEIGHT;
VidCfg.LPCommandEnable = DSI_LP_COMMAND_DISABLE;
VidCfg.LPLargestPacketSize = 0;
VidCfg.LPVACTLargestPacketSize = 0;
VidCfg.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;
VidCfg.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE;
VidCfg.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;
VidCfg.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;
VidCfg.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;
VidCfg.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE;
VidCfg.FrameBTAAcknowledgeEnable = DSI_FBTAA_ENABLE;
if (HAL_DSI_ConfigVideoMode(&hdsi, &VidCfg) != HAL_OK)
{
Error_Handler();
}