cancel
Showing results for 
Search instead for 
Did you mean: 

Other display with F469-Disco board. How to set up?

Exit0815
Senior

Hello,

I hope someone can help me. After days over days reading docs, other questions and so on i am still confused how all the LTDC and DSI stuff works.

OK, so what i have is a STM32F469 Disovery board which already has a display on it.

I create a project in touchgfx with just a blue screen and 4 white boxes in the corners.

Opened in the IDE i can upload it and it works. No wonder, it is all original.

Now i changed the display using the same FPC connector. I am using a small pcb for changing the wires to match the spec of the new display.

It is also 2 lane DSI.

As program "template" i still use one of the 469-disco

I removed all the otm8009a stuff, and used the power-on sequence of the new display with the HX8363 instead of the OTM8009a

HAL_DSI_ShortWrite(&hdsi, 0x00, DSI_DCS_SHORT_PKT_WRITE_P1, 0x11, 0x00);
HAL_Delay(201);
uint8_t enExtCmd[5] = {0xFF, 0x83, 0x63};
HAL_DSI_LongWrite(&hdsi, 0x00, DSI_DCS_LONG_PKT_WRITE, 4, 0xB9, enExtCmd);
uint8_t setLaneNumer[15] ={0x80, 0x00, 0x10, 0x08, 0x08, 0x10, 0x7E, 0x6E, 0x6D, 0x0A, 0x01, 0x80, 0x43};
HAL_DSI_LongWrite(&hdsi,  0x00, DSI_DCS_LONG_PKT_WRITE, 14, 0xBA, setLaneNumer);
HAL_DSI_ShortWrite(&hdsi, 0x00, DSI_DCS_SHORT_PKT_WRITE_P1, 0x36, 0x00);
HAL_Delay(7);
HAL_DSI_ShortWrite(&hdsi, 0x00, DSI_DCS_SHORT_PKT_WRITE_P1, 0xCC, 0x0B);
HAL_Delay(11);
HAL_DSI_ShortWrite(&hdsi,  0x00, DSI_DCS_SHORT_PKT_WRITE_P1, 0x29, 0x00);

0693W00000Ka58HQAR.jpg 

After countless attempts playing around without knowing what i am doing i got the display showing something. For me it was a big success. I opened the IOC to change the touchgfx interface to Parallel RGB (LTDC) and Driver to LTDC.

DSI Host to Video Mode.

Datasheet:

- 4.0 inch diagonal display, 480 x RGB [H] x 800 [V] dots.
- 24bitRGB ( 8-8-8 Format ) / 16.7 Million colors.
- MIPI DSI as high-speed interface. Video mode only.

So far so good. I thought it would be easy now to get the timing and all the other parameters. Just use the datasheet and put the values in the correct parameter using the IOC config.

And here i started to read many many docs about LTDC, DSI and so on. But still do not understand it.

So the display is 4.0" WVGA 480 x RGB x 800 Portrait

In the dimensions part of the datasheet there is "Number of dots" 1440[H] x 800[V]. Is that something important to adjust or does that be controlled by the IC driver HX8363 ?

What about the timings? In all the datasheets some other people posted in their questions, which did not help me, the "Item" and "Symbol" is different, so it seems that every manufacturer use different namings of functions.

In my case:

0693W00000Ka5AwQAJ.jpgAnd:

0693W00000Ka5C9QAJ.jpg 

This is what my display actually show:

0693W00000Ka5D2QAJ.jpg 

Using this settings:

static void MX_DMA2D_Init(void)
{
  hdma2d.Instance = DMA2D;
  hdma2d.Init.Mode = DMA2D_M2M;
  hdma2d.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
  hdma2d.Init.OutputOffset = 0;
  hdma2d.LayerCfg[1].InputOffset = 0;
  hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
  hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
  hdma2d.LayerCfg[1].InputAlpha = 0;
  if (HAL_DMA2D_Init(&hdma2d) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) != HAL_OK)
  {
    Error_Handler();
  }
}
static void MX_DSIHOST_DSI_Init(void)
{
  /* USER CODE BEGIN DSIHOST_Init 0 */
  /* Activate XRES active low */
  HAL_Delay(20); /* wait 20 ms */
  HAL_GPIO_WritePin(GPIOH, GPIO_PIN_7, GPIO_PIN_RESET);
  HAL_Delay(20); /* wait 20 ms */
  /* Desactivate XRES */
  HAL_GPIO_WritePin(GPIOH, GPIO_PIN_7, GPIO_PIN_SET);
  /* Wait for 11ms after releasing XRES before sending commands */
  HAL_Delay(11);
  /* USER CODE END DSIHOST_Init 0 */
 
  DSI_PLLInitTypeDef PLLInit = {0};
  DSI_HOST_TimeoutTypeDef HostTimeouts = {0};
  DSI_PHY_TimerTypeDef PhyTimings = {0};
  DSI_VidCfgTypeDef VidCfg = {0};
 
  hdsi.Instance = DSI;
  hdsi.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_DISABLE;
  hdsi.Init.TXEscapeCkdiv = 4;
  hdsi.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
  PLLInit.PLLNDIV = 125;
  PLLInit.PLLIDF = DSI_PLL_IN_DIV2;
  PLLInit.PLLODF = DSI_PLL_OUT_DIV1;
  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 = 28;
  PhyTimings.ClockLaneLP2HSTime = 33;
  PhyTimings.DataLaneHS2LPTime = 15;
  PhyTimings.DataLaneLP2HSTime = 25;
  PhyTimings.DataLaneMaxReadTime = 0;
  PhyTimings.StopWaitTime = 0;
  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_SetLowPowerRXFilter(&hdsi, 10000) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_DSI_ConfigErrorMonitor(&hdsi, HAL_DSI_ERROR_NONE) != HAL_OK)
  {
    Error_Handler();
  }
  VidCfg.VirtualChannelID = 0;
  VidCfg.ColorCoding = DSI_RGB888;
  VidCfg.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
  VidCfg.Mode = DSI_VID_MODE_NB_PULSES;
  VidCfg.PacketSize = 1;
  VidCfg.NumberOfChunks = 200;
  VidCfg.NullPacketSize = 0;
  VidCfg.HSPolarity = DSI_HSYNC_ACTIVE_LOW;
  VidCfg.VSPolarity = DSI_VSYNC_ACTIVE_LOW;
  VidCfg.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
  VidCfg.HorizontalSyncActive = 4;
  VidCfg.HorizontalBackPorch = 2;
  VidCfg.HorizontalLine = 425;
  VidCfg.VerticalSyncActive = 2;
  VidCfg.VerticalBackPorch = 1;
  VidCfg.VerticalFrontPorch = 1;
  VidCfg.VerticalActive = 480;
  VidCfg.LPCommandEnable = DSI_LP_COMMAND_DISABLE;
  VidCfg.LPLargestPacketSize = 0;
  VidCfg.LPVACTLargestPacketSize = 0;
  VidCfg.LPHorizontalFrontPorchEnable = DSI_LP_HFP_DISABLE;
  VidCfg.LPHorizontalBackPorchEnable = DSI_LP_HBP_DISABLE;
  VidCfg.LPVerticalActiveEnable = DSI_LP_VACT_DISABLE;
  VidCfg.LPVerticalFrontPorchEnable = DSI_LP_VFP_DISABLE;
  VidCfg.LPVerticalBackPorchEnable = DSI_LP_VBP_DISABLE;
  VidCfg.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_DISABLE;
  VidCfg.FrameBTAAcknowledgeEnable = DSI_FBTAA_DISABLE;
  if (HAL_DSI_ConfigVideoMode(&hdsi, &VidCfg) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_DSI_SetGenericVCID(&hdsi, 0) != HAL_OK)
  {
    Error_Handler();
  }
}

I have to split here because i can not send the question "Text too large".

1 ACCEPTED SOLUTION

Accepted Solutions

Now try decrement/increment by 1

VidCfg.HorizontalSyncActive = 31;
  VidCfg.HorizontalBackPorch = 31;
  VidCfg.HorizontalLine = 1015;

 and for rotate mirror use datasheet register command...

View solution in original post

13 REPLIES 13
Exit0815
Senior

static void MX_LTDC_Init(void)
{
  LTDC_LayerCfgTypeDef pLayerCfg = {0};
 
  hltdc.Instance = LTDC;
  hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
  hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
  hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
  hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
  hltdc.Init.HorizontalSync = 1;
  hltdc.Init.VerticalSync = 1;
  hltdc.Init.AccumulatedHBP = 2;
  hltdc.Init.AccumulatedVBP = 2;
  hltdc.Init.AccumulatedActiveW = 202;
  hltdc.Init.AccumulatedActiveH = 482;
  hltdc.Init.TotalWidth = 203;
  hltdc.Init.TotalHeigh = 483;
  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 = 480;
  pLayerCfg.WindowY0 = 0;
  pLayerCfg.WindowY1 = 800;
  pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
  pLayerCfg.Alpha = 255;
  pLayerCfg.Alpha0 = 0;
  pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
  pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
  pLayerCfg.FBStartAdress = 0xC0000000;
  pLayerCfg.ImageWidth = 480;
  pLayerCfg.ImageHeight = 800;
  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_LTDC_DISABLE(&hltdc);
  DSI_LPCmdTypeDef LPCmd;
 
  HAL_DSI_Start(&hdsi);
 
  HX8363_Init(); // Power on sequence 
 
  LPCmd.LPGenShortWriteNoP = DSI_LP_GSW0P_DISABLE;
  LPCmd.LPGenShortWriteOneP = DSI_LP_GSW1P_DISABLE;
  LPCmd.LPGenShortWriteTwoP = DSI_LP_GSW2P_DISABLE;
  LPCmd.LPGenShortReadNoP = DSI_LP_GSR0P_DISABLE;
  LPCmd.LPGenShortReadOneP = DSI_LP_GSR1P_DISABLE;
  LPCmd.LPGenShortReadTwoP = DSI_LP_GSR2P_DISABLE;
  LPCmd.LPGenLongWrite = DSI_LP_GLW_DISABLE;
  LPCmd.LPDcsShortWriteNoP = DSI_LP_DSW0P_DISABLE;
  LPCmd.LPDcsShortWriteOneP = DSI_LP_DSW1P_DISABLE;
  LPCmd.LPDcsShortReadNoP = DSI_LP_DSR0P_DISABLE;
  LPCmd.LPDcsLongWrite = DSI_LP_DLW_DISABLE;
  HAL_DSI_ConfigCommand(&hdsi, &LPCmd);
 
  HAL_LTDC_SetPitch(&hltdc, 800, 0);
  __HAL_LTDC_ENABLE(&hltdc);
  /* USER CODE END LTDC_Init 2 */
 
}

0693W00000Ka5JuQAJ.jpg 

There are so many questions.

The CLK Frequency in my Display-Datasheet. is is TYP 25.0 MHz. Is this the clock "To DSI lane byte clock which is now 62.5?

The VSYNC and HSYNC frequency, in the datasheet 57.46 Hz and 48.6 Hz, where do i use that ones?

Should i start with the "MX_DSIHOST_DSI_Init" because there is a lot wrong?

I realy want to understand all the stuff, it is very interesting but hard for me.

Please help with simple words 🙂

Best regars,

Alex

MM..1
Chief

Hi Alex, for learn this you need more time, maybe month. But simple steps:

  1. LTDC is one hw component that read memory and send it converted to LCD lines or next component DSI
  2. DSI is bridge hw component between LTDC and MIPI LCD serialize paralel RGB data to serial stream on DSI clock
  3. all timing need calculate for example in your table is VSYNC pulse width 6/8/50 lines and HSYNC 6/16/76 CLK pixel and CLK is TYP 25MHz this value you need set in MX as LTDC DCLK dot clock. DSI max speed is 400 then in MX you need set on DSI for example 50MHz instead 62,5
  4. From this setup you need set LTDC sync HSYNC to from table TYP 16 , but for same value in DSI need calc 16 x 50/25 = 32 (VidCfg.HorizontalSyncActive = 31)
  5. ...

Arguably needs a secondary school level understanding of raster displays, like the old PAL/NTSC methods, admittedly in the 1980's this was perhaps more relevant to MCU coderz

The DSI is a bitwise transfer of the pixel data as dumped into the interface by the LTDC, so DSI needs to be AT LEAST AS FAST, CAN BE FASTER. It's less fussy, as it's a transport layer, the LTDC needs to match the workable settings of the display itself.

16-bit colour depth at 62.5 MHz needs 1 Gbps bandwidth, ie 2-lanes at 500 Mbps (250 MHz DDR), the maximum of the STM32.

For 24-bit the maximum clock would be 41.67 MHz

This is further complicated by your display indicating the lane limits for it are 400 Mbps (200 MHz DDR), which would be 33.33 MHz at 24-bit, and a LTDC side perhaps at 25-32 MHz

Understand the amount of pixels displayed, and undisplayed, and the refresh rate.

The line totals include the sync, back porch, displayed pixels, and front porch. ie 528 = 16 + 16 + 480 + 16

The pixel clock = refresh rate * horizontal total * vertical total

That clock is bounded by the colour depth and DSI, and also needs to be withing min/max of actual displays capabilities.

This seems to have NO bearing on a 480(528) x 800(824) display

  1. hltdc.Init.HorizontalSync = 1;
  2. hltdc.Init.VerticalSync = 1;
  3. hltdc.Init.AccumulatedHBP = 2;
  4. hltdc.Init.AccumulatedVBP = 2;
  5. hltdc.Init.AccumulatedActiveW = 202;
  6. hltdc.Init.AccumulatedActiveH = 482;
  7. hltdc.Init.TotalWidth = 203;
  8. hltdc.Init.TotalHeigh = 483;

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Exit0815
Senior

Thank you @MM..1​  and @Community member​ for your answers,

after reading again the docs about LTDC and DSI from ST i thought i am a step further and did some calculations again.

In my case the LTDC Clock is:

LTDC_TWCR:

TOTALW: HSYNC Width + HBP + Active width HFP -1 = 527

TOTALH: VSYNC Height + VBP + Active hight + VFP -1 = 823

That results a clock of 26Mhz by: 527 x 823 x 60 Hz

This is 1) in my picture, correct?

0693W00000KaFhlQAF.png 

Then, 2) is the max DSI speed, which is in my LCD Datasheet 400 ?

What about 3) and 4) in the clock configuration? In which way does that needs to be configured to the display?

@Community member​  You write total width and accumulated width only around 200. Why not the 800?

To complete it, i will attach the datasheet of the display.

Datasheet

MM..1
Chief

1234 seems be ok and Tesla copies your code around 200 and meean you need correct this all values.. Logix LTDC cant have less width as Playercfg etc.

Thank you @MM..1​ 

I am a bit further.

How it should look:

0693W00000KaRLwQAN.jpgAnd how it actually looks:

0693W00000KaRM1QAN.jpg 

I know there are a lot settings what could be the reason that it does not show correctly. But do you have any advice on how best to proceed?

Actual settings are:

  hdsi.Instance = DSI;
  hdsi.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_DISABLE;
  hdsi.Init.TXEscapeCkdiv = 3;
  hdsi.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
  PLLInit.PLLNDIV = 100;
  PLLInit.PLLIDF = DSI_PLL_IN_DIV2;
  PLLInit.PLLODF = DSI_PLL_OUT_DIV1;
  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 = 25;
  PhyTimings.ClockLaneLP2HSTime = 27;
  PhyTimings.DataLaneHS2LPTime = 13;
  PhyTimings.DataLaneLP2HSTime = 20;
  PhyTimings.DataLaneMaxReadTime = 0;
  PhyTimings.StopWaitTime = 0;
  VidCfg.VirtualChannelID = 0;
  VidCfg.ColorCoding = DSI_RGB888;
  VidCfg.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
  VidCfg.Mode = DSI_VID_MODE_NB_PULSES;
  VidCfg.PacketSize = 480;
  VidCfg.NumberOfChunks = 1;
  VidCfg.NullPacketSize = 0;
  VidCfg.HSPolarity = DSI_HSYNC_ACTIVE_LOW;
  VidCfg.VSPolarity = DSI_VSYNC_ACTIVE_LOW;
  VidCfg.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
  VidCfg.HorizontalSyncActive = 31;
  VidCfg.HorizontalBackPorch = 31;
  VidCfg.HorizontalLine = 1015;
  VidCfg.VerticalSyncActive = 8;
  VidCfg.VerticalBackPorch = 8;
  VidCfg.VerticalFrontPorch = 8;
  VidCfg.VerticalActive = 800;
  VidCfg.LPCommandEnable = DSI_LP_COMMAND_DISABLE;
  VidCfg.LPLargestPacketSize = 0;
  VidCfg.LPVACTLargestPacketSize = 0;
  VidCfg.LPHorizontalFrontPorchEnable = DSI_LP_HFP_DISABLE;
  VidCfg.LPHorizontalBackPorchEnable = DSI_LP_HBP_DISABLE;
  VidCfg.LPVerticalActiveEnable = DSI_LP_VACT_DISABLE;
  VidCfg.LPVerticalFrontPorchEnable = DSI_LP_VFP_DISABLE;
  VidCfg.LPVerticalBackPorchEnable = DSI_LP_VBP_DISABLE;
  VidCfg.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_DISABLE;
  VidCfg.FrameBTAAcknowledgeEnable = DSI_FBTAA_DISABLE;
  hltdc.Instance = LTDC;
  hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
  hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
  hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
  hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
  hltdc.Init.HorizontalSync = 15;
  hltdc.Init.VerticalSync = 7;
  hltdc.Init.AccumulatedHBP = 31;
  hltdc.Init.AccumulatedVBP = 15;
  hltdc.Init.AccumulatedActiveW = 511;
  hltdc.Init.AccumulatedActiveH = 815;
  hltdc.Init.TotalWidth = 527;
  hltdc.Init.TotalHeigh = 823;
  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 = 480;
  pLayerCfg.WindowY0 = 0;
  pLayerCfg.WindowY1 = 800;
  pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
  pLayerCfg.Alpha = 255;
  pLayerCfg.Alpha0 = 0;
  pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
  pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
  pLayerCfg.FBStartAdress = 0xC0000000;
  pLayerCfg.ImageWidth = 480;
  pLayerCfg.ImageHeight = 800;
  pLayerCfg.Backcolor.Blue = 0;
  pLayerCfg.Backcolor.Green = 0;
  pLayerCfg.Backcolor.Red = 0;
  if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
  {
    Error_Handler();
  }

I am using the power-on-init of the manufacturer so i don't think that there is a mistake.

What about the PHY Timings in the DSI settings? Does the display look like a DSI problem or is it more LTDC (and/or Layer) setting issue?

Next one step in TouchGFX designer change orientation

If your player config is 480x800 same must be TGFX and only rientation landscape/portrait

Well, in TouchGFX designer it is allready landscape orientation.

When i change it to portrait it has the same problems.

The photo of the display is wrong, display should be 180 flipped.

But anyway, the text is mirrored "New Text".

And the boxes should be in each corner, the stripes "RGB" from top to bottom, so many problems.

I am happy that it does show anything, but everything i change makes it worse.