Skip to main content

Framebuffer Strategies

This section shows how to configure the TouchGFX Generator to generate a TouchGFX HAL that uses one of the following Framebuffer strategies:

  • Single
  • Double
  • Partial

Read more about framebuffers here.

All framebuffer options

Single Framebuffer

Choosing Single Buffer as the buffering strategy developers are able to let the compiler allocate memory for the framebuffer in internal RAM but can also choose a specific location for the buffer.

By Allocation

When choosing By Allocation TouchGFX Generator will allocate an array based on the dimensions and bit depth of the application.

Single framebuffer, by allocation

Code is generated to configure the HAL to use this array as the framebuffer.

TouchGFXGeneratedHAL.cpp
namespace {
// Use the section "TouchGFX_Framebuffer" in the linker script
// to specify the placement of the buffer
LOCATION_PRAGMA("TouchGFX_Framebuffer")
uint32_t frameBuf[(480 * 272 * 2 + 3) / 4] LOCATION_ATTRIBUTE("TouchGFX_Framebuffer");
}

void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)frameBuf, (void*)0, (void*)0);
}

By Address

When choosing By Address for the location of the framebuffer TouchGFX Generator will use the specified Start Addresses during HAL initialization.

Single framebuffer, by address

TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)0xC0000000, (void*)0, (void*)0);
}

Double Framebuffer

In a double framebuffer configuration, code to swap framebuffers will be generated in the HAL by TouchGFX Generator depending on the selected Framebuffer strategy and display interface. This memory interface to framebuffer location is used by the TouchGFX Engine during the main event loop.

By Address

When choosing By Address TouchGFX Generator will use the two specified Start Addresses during HAL initialization.

Double framebuffer, by address

TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)0xC0000000, (void*)0xC003FC00, (void*)0);
}
Tip
When using Parallel RGB (LTDC) as display interface, the start address will be inherited from the LTDC Layer settings.
Tip
When using Parallel RGB (LTDC) as display interface in 'By Allocation' mode, the generated TouchGFX HAL will automatically configure the LTDC Layer Color Frame Buffer Start Address at runtime, so you should not set a value in LTDC configuration.

By Allocation

When choosing By Allocation TouchGFX Generator will allocate an array based on the dimensions and bit depth of the application, exactly as with a Single Framebuffer, only twice the size.

Single framebuffer, by allocation

TouchGFXGeneratedHAL.cpp
namespace {
// Use the section "TouchGFX_Framebuffer" in the linker to specify the placement of the buffer
LOCATION_PRAGMA("TouchGFX_Framebuffer")
uint32_t frameBuf[(480 * 272 * 2 + 3) / 4 * 2] LOCATION_ATTRIBUTE("TouchGFX_Framebuffer");
}

void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf)/(sizeof(uint32_t)*2)), (void*)0);
}

Partial Framebuffer

With the partial framebuffer strategy, TouchGFX does not use a framebuffer in the same size as the display. Instead the user is allowed to choose a number of blocks (of a given size) to be used as framebuffers. TouchGFX uses a Frame Buffer Allocator object to control the use of these block.

With this strategy you don't supply a pointer to external memory (where the framebuffer would be located), nor allocate a framebuffer array in internal memory.

See the article on Framebuffer for a general overview of the concept of framebuffers.

Tip
Usually, small microcontrollers like STM32G0 does not have enough internal RAM to fit framebuffer. "Partial Buffer" would be a perfect match for a low cost solution using this MCU.

Partial framebuffer

Since a partial buffering strategy is typically only used with low cost MCU with no TFT controller and little internal RAM the Partial Buffer Strategy expects the developer to implement the transfer of the contents of the framebuffer to the display. See FMC/SPI Scenario for how to transmit pixels to e.g. a serial display on MCUs with no TFT Controller.

In order to link the display with TouchGFX when using the Partial Framebuffer strategy, developers are required to provide implementations for the following two functions. The code displayed below is generated by CubeMX inside TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp and defines the interface between the TouchGFX Engine and the display driver.

TouchGFXGeneratedHAL.cpp
/* ******************************************************
* Functions required by Partial Frame Buffer Strategy
* ******************************************************
*
* int touchgfxDisplayDriverTransmitActive() must return whether or not data is currently being transmitted, over e.g. SPI.
* void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h) will be called
* when the framework wants to send a block. The user must then transfer the data represented by the arguments.
*/

extern "C" int touchgfxDisplayDriverTransmitActive();
extern "C" int touchgfxDisplayDriverShouldTransferBlock(uint16_t bottom);
extern "C" void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
extern "C" void touchgfxSignalVSync(void);

For the STM32G071 TouchGFX Board Setup available in the TouchGFX Designer these functions are implemented in Core/Src/MB1642BDisplayDriver.c (only showing one here):

Core/Src/MB1642BDisplayDriver.c
int touchgfxDisplayDriverTransmitActive(void)
{
return IsTransmittingBlock_;
}

With this strategy CubeMX also generates the TouchGFXGeneratedHAL::flushFrameBuffer(Rect&) inside the read-only TouchGFXGeneratedHAL class in TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp.

Note
The flushFrameBuffer(Rect&) function is generally used for MCUs with no TFT Controller. In the case of Partial Framebuffers the TouchGFX Generator can generate a definition for this method specifically for that framebuffer strategy.
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
HAL::flushFrameBuffer(rect);
// Try transmitting a block
PartialFrameBufferManager::tryTransmitBlock();
}