cancel
Showing results for 
Search instead for 
Did you mean: 

Shifted image in custom display using DSI Video mode with Double buffering

HareshPrajapati
Associate II

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:
simulator.jpg


Actual Hardware:
hardware.jpg


My configuration for clocks are as  given below
clocks.jpg



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.

1 ACCEPTED SOLUTION

Accepted Solutions
HareshPrajapati
Associate II

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();
  }

View solution in original post

5 REPLIES 5
amelia892
Associate

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.

HareshPrajapati
Associate II

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

CDecouen
Associate II

Hello, have you tried changing line 68 of ltdc file? This sets the start column.

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);

HareshPrajapati
Associate II

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();
  }