cancel
Showing results for 
Search instead for 
Did you mean: 

First time using the LTDC peripheral on anything - STM32U599VJT - no activity on RGB lines/interupt?

LoyalServant
Associate II

Hi all,

At a loss.

I'm working with a display on a custom board. There isn't much info on the display itself aside from the driver being an ST7701 so I can only assume that it's been initialised correctly. It's an RGB565 display.

That said, I get absolutely nothing on the display - save the backlight works but that's it. Probing around I see pixel clock, hsync, vsync, etc.

But I see -no- activity on any of the gpios configured for RGB. absolutely no activity. All of the code save the framebuffere address is configured with cubeide. Generated code and me trying to draw a white screen below.
I also noticed that LTDC_IRQHandler or LTDC_ER_IRQHandler don't fire either?
main() has MX_LTDC_Init() called in it - part of the generated code. The only things I call in main() are a function to send the display init code via SPI and I confirmed that with a logic probe and another to set the framebuffer. Whether or not theinit code is right is another thing altogether but I expect to at least see some activity on the RGB lines and the interrupt to fire.
As to the framebuffer - I have NO IDEA how to set that in stm32cubeide It wants an address and I have an array...
Maybe that's my issue? Other than that 
I am stumped. Is there some function I have to 'start' the peripheral that I am missing?



framebuffer:

#define DISPLAY_WIDTH  320
#define DISPLAY_HEIGHT 820
uint16_t framebuffer[DISPLAY_WIDTH * DISPLAY_HEIGHT];

 

trying to make the screen all white:

void LTDC_DisplayWhiteScreen(void) {
    for (int i = 0; i < DISPLAY_WIDTH * DISPLAY_HEIGHT; i++) {
    	framebuffer[i] = 0xFFFF;
    }
}

init, etc:

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_AL;
  hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
  hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
  hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
  hltdc.Init.HorizontalSync = 7;
  hltdc.Init.VerticalSync = 3;
  hltdc.Init.AccumulatedHBP = 14;
  hltdc.Init.AccumulatedVBP = 5;
  hltdc.Init.AccumulatedActiveW = 834;
  hltdc.Init.AccumulatedActiveH = 325;
  hltdc.Init.TotalWidth = 840;
  hltdc.Init.TotalHeigh = 327;
  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 = 320;
  pLayerCfg.WindowY0 = 0;
  pLayerCfg.WindowY1 = 820;
  pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
  pLayerCfg.Alpha = 0;
  pLayerCfg.Alpha0 = 0;
  pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
  pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
  pLayerCfg.FBStartAdress = (uint32_t)framebuffer;
  pLayerCfg.ImageWidth = 320;
  pLayerCfg.ImageHeight = 820;
  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 */

  /* USER CODE END LTDC_Init 2 */

}

void HAL_LTDC_MspInit(LTDC_HandleTypeDef* ltdcHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(ltdcHandle->Instance==LTDC)
  {
  /* USER CODE BEGIN LTDC_MspInit 0 */

  /* USER CODE END LTDC_MspInit 0 */

  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
    PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL2;
    PeriphClkInit.PLL2.PLL2Source = RCC_PLLSOURCE_HSI;
    PeriphClkInit.PLL2.PLL2M = 3;
    PeriphClkInit.PLL2.PLL2N = 24;
    PeriphClkInit.PLL2.PLL2P = 2;
    PeriphClkInit.PLL2.PLL2Q = 2;
    PeriphClkInit.PLL2.PLL2R = 7;
    PeriphClkInit.PLL2.PLL2RGE = RCC_PLLVCIRANGE_0;
    PeriphClkInit.PLL2.PLL2FRACN = 0;
    PeriphClkInit.PLL2.PLL2ClockOut = RCC_PLL2_DIVR;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }

    /* LTDC clock enable */
    __HAL_RCC_LTDC_CLK_ENABLE();

    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    /**LTDC GPIO Configuration
    PE7     ------> LTDC_B6
    PE8     ------> LTDC_B7
    PE9     ------> LTDC_G2
    PE10     ------> LTDC_G3
    PE11     ------> LTDC_G4
    PE12     ------> LTDC_G5
    PE13     ------> LTDC_G6
    PE14     ------> LTDC_G7
    PD8     ------> LTDC_R3
    PD9     ------> LTDC_R4
    PD10     ------> LTDC_R5
    PD11     ------> LTDC_R6
    PD12     ------> LTDC_R7
    PD13     ------> LTDC_VSYNC
    PD15     ------> LTDC_B3
    PD0     ------> LTDC_B4
    PD1     ------> LTDC_B5
    PD3     ------> LTDC_CLK
    PD6     ------> LTDC_DE
    PE0     ------> LTDC_HSYNC
    */
    GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
                          |GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF8_LTDC;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_15|GPIO_PIN_0
                          |GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF8_LTDC;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    /* LTDC interrupt Init */
    HAL_NVIC_SetPriority(LTDC_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(LTDC_IRQn);
    HAL_NVIC_SetPriority(LTDC_ER_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(LTDC_ER_IRQn);
  /* USER CODE BEGIN LTDC_MspInit 1 */

  /* USER CODE END LTDC_MspInit 1 */
  }
}

 

6 REPLIES 6
SofLit
ST Employee

Hello,

AN4861 "Introduction to LCD-TFT display controller (LTDC) on STM32 MCUs" may help

+ You can inspire from any LTDC examples of STM32 products. Example: https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM32F429I-Discovery/Examples/LTDC/LTDC_Display_2Layers

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
LoyalServant
Associate II

Appreciate the answer. I already reviewed that document - I used it to understand how to connect the display.

I ddi take another look; But it does not help me understand why I have the clocks, but no pixel data.

I grabbed another board and put a second mcu on it and gave that one a shot; with the same result. I was not a believer that this would change anything but worth a try. This time I did not connect the display in case there is some issue with it, but with the same result. I have no pixel data. I am obviously doing something very wrong to get the pixel clock and sync signals but no image data.

 

Try LTDC Start command ...

LoyalServant
Associate II

So after reviewing the example above I noticed this bit:

ReloadFlag = 0;
HAL_LTDC_Reload(&hltdc,LTDC_SRCR_VBR);
while(ReloadFlag == 0)
{
    // wait...
}

.....

void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc)
{
  ReloadFlag = 1;
}

 

Which sort of goes counter to my understanding that you point the LTDC at a framebuffer; and you simply updated that framebuffer and it would draw whatever you threw in there without having to tell it and tie up the processor waiting for it to draw the screen.

But I have pixel data so it's progress which means my still blank display likely lies in the initialisation/timings.

Can anyone clarify how NOT to tie up the processor waiting for it to draw a frame in the main superloop or task?

 

Sure. can you elaborate on this start command some more?

I don't see one in stm32u5xx_hal_ltdc.c and doing a quick search for one didn't come up with anything.

 

Sorry i mix with DSI, but your code error is in ALPHA value = all pix is black now (or transparent = background collor result). Try change to 

 

	pLayerCfg.Alpha = 255;
	pLayerCfg.Alpha0 = 0;
	pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
	pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;