cancel
Showing results for 
Search instead for 
Did you mean: 

TouchGFX LTDC Framebuffer Address for 800x600 Display with External eMMC (IS21ES08GA-JQLI)

siddum
Associate II

Hello ST Community Team,

We are currently working on an STM32N6-based design using TouchGFX and would appreciate your guidance regarding the LTDC framebuffer address configuration.

Setup details:

  • Display resolution: 800 × 600

  • Graphics framework: TouchGFX

  • External memory device: eMMC – IS21ES08GA-JQLI

  • The eMMC is used as external memory in the system

While configuring TouchGFX and LTDC, we need to specify the framebuffer start address for the LTDC layer. Since the framebuffer is not located in internal SRAM, we would like to understand:

  1. What LTDC framebuffer address should be provided when using an external eMMC (IS21ES08GA-JQLI)?

  2. Is it recommended (or required) to first map the framebuffer into an external RAM (such as SDRAM/PSRAM) instead of directly using eMMC?

  3. Are there any reference examples or application notes showing TouchGFX with LTDC using external eMMC for framebuffers?

Any clarification on the correct memory mapping and recommended architecture for this use case would be very helpful.

Thank you in advance for your support.

Best regards,
Marka

9 REPLIES 9
tdecker2
Associate III

Framebuffer must be in RAM, either internal or external. eMMC is flash not RAM.The flash can be used to store graphics and fonts, TouchGFX renders them into the framebuffer and LTDC sends that data to the display.

Not familiar with the N6-Family, but some of them should have enough internal RAM for the framebuffer (with RGB565 you need 800 x 600 x 2bytes=960000 bytes).

Osman SOYKURT
ST Employee

Hello @siddum , 

I wonder why won't you use the internal SRAM. The STM32N6 has 4.2MB available that should be used for storing framebuffer(s). By the way, as said by @tdecker2 , I believe  IS21ES08GA-JQLI eMMC is NAND flash memory which is non volatile. Therefore it can't be used for framebuffer storage, but you can still use it to store your assets.

Osman SOYKURT
ST Software Developer | TouchGFX

Hello Osman SOYKURT,

Thank you for your clarification regarding the internal SRAM usage.

Based on your suggestion, we are now using the internal SRAM of the STM32N657x0H3Q to configure TouchGFX, since the device provides 4.2 MB of internal SRAM, which is suitable for storing the framebuffer(s).

To avoid the RAM overflow errors we were encountering earlier, we increased the RAM size by 1 MB for the TouchGFX configuration. For this purpose, we separately allocated the AXISRAM1 base address(0x34000000) for RAM usage and updated the configuration accordingly.

However, after completing the configuration, we are facing an issue during debugging:
when we start debugging, the program automatically exits or stops unexpectedly.

Could you please guide us on whether there are any additional linker script settings, memory region constraints, or TouchGFX-specific configurations required when allocating AXISRAM1 for framebuffer and increasing SRAM size on STM32N657x0H3Q?

MEMORY

{

ROM (xrw) : ORIGIN = 0x34180400, LENGTH = 255K

RAM (xrw) : ORIGIN = 0x34200000, LENGTH = 1024K

/*ROM (xrw) : ORIGIN = 0x34180400, LENGTH = 255K (by default)*/

/*RAM (xrw) : ORIGIN = 0x341C0000, LENGTH = 256K(by default) */

 

}

FontFlashSection :

{

*(FontFlashSection FontFlashSection.*)

*(.gnu.linkonce.r.*)

. = ALIGN(0x4);

} >ROM

 

BufferSection (NOLOAD) :

{

*(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)

*(.gnu.linkonce.r.*)

. = ALIGN(0x4);

 

} >RAM

These what we have configured in the linker script to increase the RAM size.

Your support would be greatly appreciated.

 

Best regards,
siddu marka.

Hello tdecker2,

I am working with TouchGFX on an STM32N657X0H3Q  device and I am facing an issue during initialization.

And we are uisng internal  sram  AXISRAM1 for frame buffer .  

And the ltdc configurtaion is

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 = 7;

hltdc.Init.VerticalSync = 7;

hltdc.Init.AccumulatedHBP = 57;

hltdc.Init.AccumulatedVBP = 27;

hltdc.Init.AccumulatedActiveW = 857;

hltdc.Init.AccumulatedActiveH = 627;

hltdc.Init.TotalWidth = 867;

hltdc.Init.TotalHeigh = 637;

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 = 800;

pLayerCfg.WindowY0 = 0;

pLayerCfg.WindowY1 = 600;

pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;

pLayerCfg.Alpha = 255;

pLayerCfg.Alpha0 = 0;

pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;

pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;

pLayerCfg.FBStartAdress = 0x34000000;

pLayerCfg.ImageWidth = 800;

pLayerCfg.ImageHeight = 600;

pLayerCfg.Backcolor.Blue = 0;

pLayerCfg.Backcolor.Green = 0;

pLayerCfg.Backcolor.Red = 0;

if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)

{

Error_Handler();

}

 

}

And this is linker script we have added .

BufferSection (NOLOAD) :

{

*(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)

*(.gnu.linkonce.r.*)

. = ALIGN(4);

 

} >AXISRAM1

 

FontFlashSection :

{

*(FontFlashSection FontFlashSection.*)

*(.gnu.linkonce.r.*)

. = ALIGN(4);

} >ROM

}

 

Below is the relevant part of my touchgfx_init() function:

void touchgfx_init()
{
    Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
    TypedText::registerTexts(&texts);
    Texts::setLanguage(0);

    FontManager::setFontProvider(&fontProvider);

    FrontendHeap& heap = FrontendHeap::getInstance();
    (void)heap;

    hal.initialize();
}

Issue observed:

  1. When running in debug mode, execution automatically jumps out immediately after the line
    FrontendHeap& heap = FrontendHeap::getInstance();

  2. The program does not reach hal.initialize() reliably.

  3. After LTDC initialization, the display turns green and starts flickering continuously.

Additional observations:

  • The LTDC clock and RGB pins are configured.

  • Frame buffer is placed in internal SRAM.

  • TouchGFX is generated with a single framebuffer.

  • No hard fault handler is triggered, but the debugger exits the function unexpectedly.

Questions:

  1. What could cause execution to exit automatically after FrontendHeap::getInstance()?

  2. Could this be related to heap size, heap memory placement, or linker script configuration?

  3. Is the green flickering display a symptom of:

    • Incorrect LTDC timing (HSYNC/VSYNC/porches)?

    • Framebuffer address or alignment issue?

    • Cache or MPU configuration problem?

Any guidance on debugging this behavior or recommended checks for TouchGFX + LTDC initialization would be greatly appreciated.

Thanks in advance for your support.

Best regards,
marka.

It's been a few years since I set up TouchGFX on an F7. I would suggest to start with a framebuffer to LTDC test first and then add TochGFX later:

Initialize the framebuffer in a non-cached (MPU-config or D-cache off) ram area and fill it with a simple test pattern (two nested for-loops and you've almost got the test pattern with color stripes in the framebuffer.). When you see that pattern on the screen you're ready for activating TouchGFX.

Can't really help you with your current issue. Most likely a memory configuration issue (D-cache, MPU-access types, memory alignment, section placement, stack size, ...).

Hello @siddum ,
What do you mean by "increase the RAM size"? RAM is physical component and has a defined size and therefore can't be increased in size. On the STM32N6, the secure SRAM bank for AXISRAM1 is placed at address 0x34064000 (refer to the Reference Manual RM0486 - Table 1) 

OsmanSOYKURT_0-1770898986171.png

I invite you to look at our STM32N6570-DK TBS in TouchGFX Designer and particularly the linker file to see how we split the RAM area into smaller areas and have one of them dedicated for the framebuffer. 

 

/* Memories definition */
MEMORY
{
  DTCM_RAM       (xrw)    : ORIGIN = 0x30000000,   LENGTH = 0x00020000
  LRUN_APPLI_RAM (xr)     : ORIGIN = 0x34000400,   LENGTH = 0x000FFC00
  RAM            (xrw)    : ORIGIN = 0x34100000,   LENGTH = 0x00040000
  CMDLIST_RAM    (xrw)    : ORIGIN = 0x34140000,   LENGTH = 0x00006000
  FB_RAM         (xrw)    : ORIGIN = 0x34146000,   LENGTH = 0x002DA000
  PSRAM          (rw)     : ORIGIN = 0x90000000,   LENGTH = 0x02000000
  ROM            (xr)     : ORIGIN = 0x70100400,   LENGTH = 0x000FFC00
  ASSETS_ROM     (r)      : ORIGIN = 0x70200000,   LENGTH = 0x07E00000
}
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_sstack = _estack - _Min_Stack_Size;

_Min_Heap_Size = 0x1000;      /* required amount of heap  */
_Min_Stack_Size = 0x1000; /* required amount of stack */

/* Link ISR vectors */
SECTIONS
{
  /* The startup code into "LRUN_APPLI_RAM" Ram type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >LRUN_APPLI_RAM
}

/* Define specific placement of memory areas */
SECTIONS
{
  BufferSection (NOLOAD) :
  {
    *(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x8);

    *(Nemagfx_Stencil_Buffer Nemagfx_Stencil_Buffer.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x8);
  } >FB_RAM
...
...

 

 

Osman SOYKURT
ST Software Developer | TouchGFX

Hello @Osman,

Thank you for the clarification.

Currently, we have configured the LTDC framebuffer address at 0x34000000 and also tested with 0x24000000, but in both cases the RGB signals are not becoming active.

Since the STM32N6 has 4.2 MB of internal RAM, could you please confirm which internal SRAM region is recommended for the LTDC framebuffer?

Specifically:

  • Should the framebuffer be placed inside AXISRAM1 secure SRAM .

  • Or is there a preferred non-secure SRAM region for LTDC?

  • Are there any MPU or cache configuration requirements that must be applied for LTDC to generate RGB signals?

Looking forward to your guidance.

Best regards,
Siddum

 
Osman SOYKURT
ST Employee

Hello @siddum ,

1. Do you run a secure or non secure project? (We do not provide any non secure project with N6, the TBS we have on TouchGFX are secure and using AXISRAM secure memory ranges).

2. Do you run "eXecute In Place" or "Load and Run" application?

3. Are you sure your screen is correctly configured and can show pixels? (without TouchGFX)

Osman SOYKURT
ST Software Developer | TouchGFX

Hello @Osman,

Thank you for the clarification.

  1. Project type:
    We are running a secure project. And we are using secure configuration with AXISRAM1 secure memory(0x34000000) as framebuffer address .

  2. Execution mode:
    Our application is running in Execute In Place  mode.

  3. Display verification:
    We are currently not using TouchGFX. We are trying to verify the display through LTDC configuration directly.

  4. LTDC pixel clock used: 32 MHz

The LTDC initialization code/configuration is attached below for reference.

We can see the framebuffer data correctly updating in the memory window, which indicates that pixel values are being written to memory. However, the RGB output signals from the LTDC are not active, so no data appears on the display.

Kindly let us know if there are additional configurations required to enable the RGB output or if any clock or LTDC settings need to be verified.

Thank you for your support.

Best regards,
Siddum.