2024-10-27 07:27 PM
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 */
}
}
2024-10-28 04:46 AM
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
2024-10-28 05:11 AM
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.
2024-10-28 05:50 AM
Try LTDC Start command ...
2024-10-28 05:50 AM
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?
2024-10-28 06:05 AM
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.
2024-10-28 06:57 AM - edited 2024-10-28 06:59 AM
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;