SPI Display Interface
This scenario describes how to configure SPI and TouchGFX Generator when using a display with a SPI serial interface and GRAM.
Note
Configuration
SPI configuration
Compared to other display interfaces (e.g., FMC), SPI has a lower bandwidth. It is therefore important to optimize the SPI configuration to highest Baud rate to maximize bandwidth. Enable the SPI from the Connectivity group in the STM32CubeMX category list. It is recommended to configure a DMA channel to the SPI to minimize CPU load. An example below is for a 64MHz MCU, which caps the SPI Baud at 32MBit/s.
Be sure to configure the Clock Parameters to align with the display.
TouchGFX Generator
When using a SPI display interface, the Custom Display Interface must be selected in the TouchGFX Generator. This means a full HAL cannot be automatically generated, so the developer must implement functionality to configure and transfer pixels from the framebuffer memory to the display manually. All necessary handles to accomplish this are generated by the TouchGFX Generator:
DMA configuration
To minimize CPU load, a DMA channel can be configured to transfer pixel data from the framebuffer to the SPI TX address.
User Code
Generally, for displays with embedded GRAM, the implementation of the generated TouchGFX HAL handles in TouchGFXHAL.cpp
should perform the following steps to transfer pixels to the display and synchronize the display with the TouchGFX Engine:
- Wait for "VSYNC" (sometimes called Tearing Effect (TE) signal) to signal the TouchGFX Engine.
- Based on the area of the framebuffer to be redrawn, move the "display cursor" and "active window" (the region of the display being updated) to a place in GRAM that matches this area.
- GRAM에 입력되는 픽셀 데이터를 기록할 준비를 합니다. Depending on the framebuffer strategy and display interface used, this could be swapping framebuffer pointers, signaling TouchGFX Engine, or waiting for previous transfers to complete.
- 픽셀 데이터를 전송합니다.
Depending on the display used and the framebuffer strategy, the implementation of the above steps will vary.
Supported Framebuffer Strategies
- Single
- Double
- Partial - GRAM display (Recommended)
Further reading
Because of the limited bandwidth achieved with SPI compared to other display interfaces, it is recommended to use the Partial - GRAM display strategy. This strategy has the advantage of using very little RAM (SPI is commonly used on simple systems with limited RAM) and optimizes the use of the available bandwidth by only initiating transfers to the display containing updated pixels. However, there is a risk of tearing.
Using Single buffering with SPI will avoid tearing caused by long rendering. However, the low bandwidth of SPI means that it is generally slower to transfer pixels to the display than the display scanline read the GRAM buffer. Because of this it is important to start transfers on the Falling edge of the TE signal (when the display enters the active area) to avoid tearing. This could look something like this:
TouchGFXHAL.cpp
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == LCD_TE_Pin)
{
// VSync has occurred, increment TouchGFX engine vsync counter
HAL::getInstance()->vSync();
// VSync has occurred, signal TouchGFX engine
OSWrappers::signalVSync();
GPIO::clear(GPIO::VSYNC_FREQ);
if (refreshRequested)
{
refreshRequested = false;
nextSendToDisplayLine = refreshMinLine;
maxSendToDisplayLine = refreshMaxLine;
sendNextFrameBufferBlockToDisplay();
}
}
}
Note
Using Double buffering with SPI will avoid tearing caused by long rendering. However, if too many pixels are transferred to the display at each frame, the scanline that read the GRAM buffer may collide with the region being transferred, causing tearing due to slow transfer bandwidth. This can be mitigated by only transferring pixels areas that have been updated and not the whole framebuffer. The function TouchGFXHAL::flushFrameBuffer
can be used to calculate the updated area in each frame to define that minimum area to transfer.
Single
Currently, no TouchGFX Board Support have a reference implementation for Single buffering with SPI. The setup would be similar to FMC Single buffer setup, but using SPI driver functions instead of FMC.
Double
Currently, no TouchGFX Board Support have a reference implementation for Double buffering with SPI. The setup would be similar to FMC Double buffer setup, but using SPI driver functions instead of FMC.
Partial - GRAM display
The TouchGFX Board Setup NUCLEO-G071RB + GFX01M2 includes a reference implementation of Partial - GRAM display with SPI. The setup is similar to FMC Partial buffer setup, but using SPI driver functions instead of FMC: