Showing results for 
Search instead for 
Did you mean: 

REPOST: Use internal SRAM for frame buffer

QUESTIONS / TouchGFX Community repost - John Leung - March 03 2016


Have been successful to use a 8080 16-bit LCD with touchgfx.

Hardware: stm32f429-disco

LCD: 240x240 MIPI display with SSD2805 as the bridge chip to convert 16-bit 8080 to DSI interface.

Framebuffer declared at 0xd0000000 where SDRAM address starts onboard of stm32f429-disco, everything is okay.

Now it is required to simplify the system by removing SDRAM. STM32f429 has an internal SRAM of 256kB size. A LCD of 240x240 requires only 115kB ram. The idea is to use internal SRAM of stm32F429 as the framebuffer to simplify the system hardware.

From datasheet SRAM location starts from 0x20000000 to 0x2002FFFF. By using the top 115KB SRAM, I have changed framebuffer location in BoardConfiguration.cpp to 0x20013dff. This is equivalent to 0x2002FFFF-0x1C200.

LCD is working but there is a strange flickering from time to time. Movie in Dropbox:

Why is that? Any insight is welcome.

John Leung

ANSWER - TouchGFX Community repost - Soren Pingel Dalsgaard - March 03 2016

Hi John,

It looks like a TFT fifo underrun, but I suppose you are not using the LTDC peripheral at all, with it being a 8080-based solution. So it must be something else.

Off the top of my head I have two suggestions:

  1. Is your frame buffer actually allocated as an array of 115kb, or are you just using the "raw" address of 0x20013dff as your frame buffer? I am asking because you need to make sure the linker does not choose to place other things in the same region, which would corrupt the image
  2. I suggest choosing the address 0x20013dfc instead, to make it 32-bit aligned, for performance reasons. Not sure if this could cause the problem you're seeing

Let me know if this helps.

ANSWER - TouchGFX Community repost - John Leung - March 03 2016

No, I am not using LTDC peripheral. The interface I am using is just like the one you have described in the article "203642951-MCUs-without-TFT-controller" with stm32f429 wired up with an external LCD controller thru' 8080.

I tried choosing the address 0x20013dfc with artifact remains.

Frame buffer belongs to "raw" category. Actually it is the same as the original stm32-disco small demo with frameBuf0 declared at (uint32_t)(0xd0000000) where SDRAM is located. This parameter is fed to setFrameBufferStartAddress(void *adr, ...) to setup the first frame buffer at frameBuffer0 with some casting inside.

Everything is good until I changed the address from 0xd0000000 to 0x20013DFF in an attempt to use internal SRAM as the framebuffer.

The question is: Do we need to change setFrameBufferStartAddress() function in any way to let the linker not choosing 0x20013DFF for other things?

If not, how to let the framework choose the new address as framebuffer solely and get it protected?


ANSWER - TouchGFX Community repost - Soren Pingel Dalsgaard - March 03 2016

Hi John,

The linker script mentions the internal SRAM only, as a range from 20000000 to 2002FFFF. The linker is not even aware of the SDRAM, which is why it is safe to specify the raw address to setFrameBufferStartAddress() when the address is in SDRAM. If the address is internal SRAM you must either:

Declare the frame buffer as an array

uint32_t frameBuffer[width*height/2];

and use that as parameter to setFrameBufferStartAddress. Notice it is declared as a 32-bit array to ensure 32-bit alignment.

Alternatively, you can modify the linker script to have an end address of 20013DFB instead of 2002FFFF, so it does not place variables in the same region as the frame buffer. In this case it is safe to just specify the raw address as frame buffer.

But I am not sure if this solves your problem. I would suspect that if you had memory clashes, you would see hard faults or at least more pixel corruption than you do.

I am not sure I can think of anything else that would cause this. TouchGFX does not really care where your frame buffer is placed, so it should not make any difference moving it to SRAM. One thing is of course that the timing profile will change - it is must faster to use the SRAM, and your "flushFrameBuffer" function will probably also transmit faster to your SSD2805. Maybe this timing change causes problems for your bridge?

ANSWER - TouchGFX Community repost - John Leung - March 03 2016


Change in timing profile when it is switched from SDRAM to SRAM is the key. A subtle amend to the code for data setup time and address setup time has solved the problem:

hsram1_timing.FMC_DataSetupTime = 7;

hsram1_timing.FMC_AddressSetupTime = 6;

However, I found the frame buffer size declared in array frameBuf0 is not relevant. Declaration like this in Keil working perfectly even though it is only 1/4 of the actual full frame requirement.

static uint32_t frameBuf0[width*height/8] __attribute__((at(0x20013dfc)))

Stepping through the code to HAL.hpp setFrameBufferStartAddress(void* adr...) there is a private variable bufferSizeInBytes = (DISPLAY_WIDTH*DISPLAY_HEIGHT)*2. So I am wondering if there is any relevance to declare frameBuf0[] array in BoardConfiguration.cpp for whatever size?

Anyway, thanks a lot and the problem has been solved. This is very critical for single chip design without SDRAM expansion.

John Leung

ANSWER - TouchGFX Community repost - Soren Pingel Dalsgaard - March 03 2016

Hi John,

Glad you solved it.

The relevance of the size of the array is that it will keep the linker from placing other things in that memory area. TouchGFX will of course write RGB data in the entire width*height*2 area of SRAM, regardless of the actual size of the array you use to declare your frame buffer.

The fact that it works in your case with a smaller array is simply because you are not using all the available SRAM. If you some day add more variables you risk that the linker makes use of the space which it thinks is free (from the end of your array to the end of SRAM region), but the point is that this memory is not free to use. Therefore you should really declare your array to be the correct size.

Also note that there is no initialization overhead in declaring an array like this in C, so there is no benefit from using a smaller array