Skip to main content
AlexSmart
Associate III
November 2, 2021
Solved

STM32H743 LTDC with no framebuffer

  • November 2, 2021
  • 20 replies
  • 4288 views

Is it possible to use STM32H743's LTDC with no frambuffer and fill its FIFO "on the fly"?

This topic has been closed for replies.
Best answer by MM..1

set 72 to 104 and when you dont see your memory isnt ready and work, Mayby you choose memory not accesible on bus with LTDC or init is bad.

Too MPU have role...

20 replies

MM..1
Super User
November 2, 2021

Maybe yes with line interrupts, but you dont fill FIFO, you set one line buffer address

AlexSmart
AlexSmartAuthor
Associate III
November 3, 2021

Seemed doable until I find out that there could be only one line interrupt per frame

MM..1
Super User
November 3, 2021

Tgfx uses more as one line int on frame to past blanking area , then i mean you can refresh on interrupt next line interrupt , but for efective i recomm use more as one line buffer.

AlexSmart
AlexSmartAuthor
Associate III
November 30, 2021

Ok, I managed to do that, Im using 32 lines buffer. But I see no output from that buffer. I see background color, black rectangle where buffer output should be, but no data inside...

unsigned short framebuffer[32][1280] __attribute__((used,aligned(4),at(0x30000000))); 
int main(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 HAL_Init();
 SystemClock_Config();
 
 MX_GPIO_Init();
 MX_LTDC_Init();
	__HAL_RCC_D2SRAM1_CLK_ENABLE();
	__HAL_RCC_D2SRAM2_CLK_ENABLE();
	__HAL_RCC_D2SRAM3_CLK_ENABLE();
	for (int line=0;line<32;line++)
	{
		for (int i=0;i<1280;)
		{
			if (line & 0x01)
			{
				framebuffer[line][i++] = 0x5555;
				framebuffer[line][i++] = 0xAAAA;
			}
			else
			{
				framebuffer[line][i++] = 0xAAAA;
				framebuffer[line][i++] = 0x5555;
			}
		}
	}
	HAL_NVIC_SetPriority(LTDC_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(LTDC_IRQn);
	HAL_LTDC_ProgramLineEvent(&hltdc, 0);
 while (1)
 {
 }
}
static void MX_LTDC_Init(void)
{
 LTDC_LayerCfgTypeDef pLayerCfg = {0};
 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_IPC;
 hltdc.Init.HorizontalSync = 19;
 hltdc.Init.VerticalSync = 4;
 hltdc.Init.AccumulatedHBP = 29;
 hltdc.Init.AccumulatedVBP = 9;
 hltdc.Init.AccumulatedActiveW = 1309;
 hltdc.Init.AccumulatedActiveH = 729;
 hltdc.Init.TotalWidth = 1319;
 hltdc.Init.TotalHeigh = 749;
 hltdc.Init.Backcolor.Blue = 0;
 hltdc.Init.Backcolor.Green = 0xff;
 hltdc.Init.Backcolor.Red = 0;
 if (HAL_LTDC_Init(&hltdc) != HAL_OK)
 {
 Error_Handler();
 }
 pLayerCfg.WindowX0 = 0;
 pLayerCfg.WindowX1 = 1280;
 pLayerCfg.WindowY0 = 72;
 pLayerCfg.WindowY1 = 692;
 pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
 pLayerCfg.Alpha = 255;
 pLayerCfg.Alpha0 = 255;
 pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
 pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
 pLayerCfg.FBStartAdress = 0x30000000;
 pLayerCfg.ImageWidth = 1280;
 pLayerCfg.ImageHeight = 32;
 pLayerCfg.Backcolor.Blue = 0;
 pLayerCfg.Backcolor.Green = 0xff;
 pLayerCfg.Backcolor.Red = 0;
 if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
 {
 Error_Handler();
 }
}

MM..1
Super User
November 30, 2021

Show IRQ too and start with only 32 line test ...

 pLayerCfg.WindowY0 = 72;
 pLayerCfg.WindowY1 = 72+32;

AlexSmart
AlexSmartAuthor
Associate III
November 30, 2021

Here is code for interrupt - no buffer or window manipulation here, just test signal output.

void LTDC_IRQHandler(void)
{
 static unsigned int line_num = 10;
	__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
	__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
	LTDC->LIPCR = line_num;
	__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
 
	line_num +=5;
	if (line_num>=720)
		line_num = 10;
	LED1_GPIO_Port->ODR ^=LED1_Pin;
}

window size now is 0..1280 and 72..692. Buffer size - 32. Shouldnt I excpect buffer output at line 72 to 104?

MM..1
Super User
November 30, 2021

Hmm lines is numbered with porch and irq on 0 maybe isnt good choice.

Inspire from touchgfx code

 lcd_int_active_line = (LTDC->BPCR & 0x7FF) - 1;
 lcd_int_porch_line = (LTDC->AWCR & 0x7FF) - 1;

MM..1
Super User
November 30, 2021

Trry explain for what you plan this because i dont see real use.

AlexSmart
AlexSmartAuthor
Associate III
November 30, 2021

I disabled interrupt for now. My goal is to see the buffer on the screen...

MM..1
MM..1Best answer
Super User
November 30, 2021

set 72 to 104 and when you dont see your memory isnt ready and work, Mayby you choose memory not accesible on bus with LTDC or init is bad.

Too MPU have role...

AlexSmart
AlexSmartAuthor
Associate III
November 30, 2021

Yes, moving buffer from SRAM1 to AXI-SRAM helped, thank you!

AlexSmart
AlexSmartAuthor
Associate III
November 30, 2021

However, manipulating window position on-the-fly doesnt work

void LTDC_IRQHandler(void)
{
	static unsigned int line_num = 72;
		
	LED1_GPIO_Port->ODR |=LED1_Pin;
	
	line_num +=10;
	if (line_num>=672)
		line_num = 72;
 
	__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
	__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
	LTDC->LIPCR = line_num;
	__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
 
	HAL_LTDC_SetWindowPosition(&hltdc, 10, line_num, 0);
	LED1_GPIO_Port->ODR &=~LED1_Pin;
}

When I set a breakpoint in interrupt code works as designed - every interrupt moving window 10 lines down. But when no breakpoint is active - blank screen.

MM..1
Super User
November 30, 2021
HAL_LTDC_SetWindowPosition(&hltdc, 10, line_num, 0);

??? and as i write i dont understand your idea

AlexSmart
AlexSmartAuthor
Associate III
December 1, 2021

Ok mistake in code,

 HAL_LTDC_SetWindowPosition(&hltdc, 10, line_num-9, 0);

but idea is the same. Every 10th line I set window position (buffer output) to line position+1 (buffer size changed to 10 lines).

I wanted to see if window position will update immediately or on the next frame. There is a posibility Im not getting whole mechanism right