Skip to main content
Nicholas Yunker_2
Senior
May 24, 2025
Solved

Unable to get LTDC to output contents of Frame Buffer

  • May 24, 2025
  • 1 reply
  • 976 views

Hello,

I am attempting to use an STM32H735G-DK development kit to drive an LCD and eventually use TouchGFX to build a menu for a proof of concept I'm working on.  I was able to very quickly get a working screen using TouchGFX example board setup for this development kit but I want to use a larger LCD in the future with a custom PCB and I've never brought up an LCD panel before so I am following the bring up guide at https://support.touchgfx.com/docs/development/board-bring-up/board-introduction to make sure I understand all the settings and the process for bringing up the board.  Steps 1 and 2 in the guide go well but step 3 is where it stops working properly where it wants you to set up a frame buffer in internal memory and point the LTDC at this location for what you put there to be displayed.  I am able to get the background color of the entire screen to change and I can see a black box in the upper left corner where I create a small window the size of my framebuffer.  I can even go to the framebuffer's location in internal memory and see the information I told it to put there (an entirely red window).  I also opened the LTDC peripheral registers in my IDE (Keil) and I can see the L1CFBAR register is pointing to the framebuffer's location.  However, the window is not displaying the information that is in that memory location, just all black.

I have seen multiple posts on this forum where people have this problem but then the solution is never given, the post is just abandoned.  Here is an example: https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/unable-to-get-ltdc-working-on-stm32h735g-dk/m-p/641145

I am attaching my CubeMX file as well as my main.c and stm32h7xx_it.c files to show my setup and modifications that section 3 of the guide tell you to make.  Is there a step I'm missing?  Is there a command that needs to be run to make the LTDC refresh the screen so it displays information that has changed in the framebuffer?

Best answer by LouisB

Hello @Nicholas Yunker_2 ,

Your issue is due to H7 ram being map to the DTCM memory by default, the LTDC cant access to the DTCM, check image h735-memory-adresses.png attached to this post


You need to modify your linker script, and use an internal ram that LTDC as access to , like AXI SRAM addresses instead, check h735-accessible-memory.png attached to this post

 

Here's the full datasheet where these tables came from Datasheet - STM32H735xG - Arm<Sup>®</Sup> Cortex<Sup>®</Sup>-M7 32-bit 550 MHz MCU, 1 MB flash, 564 KB RAM, Ethernet, USB, 3x FD-CAN, Graphics, 2x 16-bit ADCs, crypto/hash

BR,

1 reply

GGODA
Associate II
May 26, 2025

Hello @Nicholas Yunker_2 ,

 

WHere did you place your framebuffer?
It need to be accessible by SRAM (SRAM1, SRAM2 ro SDRAM).
You can try to define your framebuffer like so :

__attribute__((aligned(4))) uint8_t framebuffer[25 * 25 * 3];

to be sure that it is aligned 4 which is required for LTDC.

 

LTDC will update the display only if the framebuffer is the same size as the window's layer, however, you set the framebuffer to be 25x25 but in your STM32CubeMX setup I think you set the layer to be 100x100.
Either you :

  1. change your layer dimension
  2. change your framebuffer dimension
  3. force a redraw with something like (I am not sure) HAL_LTDC_Reload

 

Regards,

Nicholas Yunker_2
Senior
May 26, 2025

Hello, thank you for your reply.  the frame buffer is just a variable, so the compiler chooses the exact address itself, in this case it was choosing 0x200000A8.  I went to that memory address and I could see my framebuffer is loaded correctly starting at that location.  I also checked the LTDC register and it was looking at the correct memory location.  I have tried to use SRAM1 (0x30000000) and I was able to get the pointer to point there but as it steps through the code to load values into memory nothing is being written...it just fills with 0x00.  Is there something special I need to do to load code into this region?  Here is the code I have now:

	__attribute__((aligned(4))) uint8_t framebuffer[25*25*3] __attribute__((section (".ARM.__at_0x30000000"))); //24 bit framebuffer
.
.
.
	uint8_t *fb = framebuffer;
	while(fb < (uint8_t*)(framebuffer + (25*25*3)))		//fill framebuffer with data
	{
		*fb++ = 0x00; // Write blue color and increment pointer by one byte
		*fb++ = 0x00; // Write green color
		*fb++ = 0xFF; // Write red color
	}

 As I step through the code line by line I can see that *fb is referencing the correct memory location, but for instance when it's 0x300000002 it does not actually place 0xFF in that location like it should and like it does just fine when I let the compiler chose the memory location instead of forcing it into SRAM1.  Do I need to enable the SRAM region or is that automatically unlocked and fully read/write?  I can clearly read it in my memory watch widow in Keil, but for some reason I can't seem to write to it (though no errors are thrown or anything like that).

All that said, is there any reason the LTDC can't pull the frame  buffer from 0x2000000A8 (DTCM RAM region)?  Does it have to be in SRAM1, SRAM2 or SRAM4 if I'm using internal RAM?

As for your other points about the window size I have changed the window position as well as the frame buffer size to 25 x 25 and that didn't have an effect.

LouisBBest answer
ST Employee
May 28, 2025

Hello @Nicholas Yunker_2 ,

Your issue is due to H7 ram being map to the DTCM memory by default, the LTDC cant access to the DTCM, check image h735-memory-adresses.png attached to this post


You need to modify your linker script, and use an internal ram that LTDC as access to , like AXI SRAM addresses instead, check h735-accessible-memory.png attached to this post

 

Here's the full datasheet where these tables came from Datasheet - STM32H735xG - Arm<Sup>®</Sup> Cortex<Sup>®</Sup>-M7 32-bit 550 MHz MCU, 1 MB flash, 564 KB RAM, Ethernet, USB, 3x FD-CAN, Graphics, 2x 16-bit ADCs, crypto/hash

BR,