8. Hardware acceleration
Motivation
The Chrom-ART (DMA2D) graphics accelerator is capable of transferring parts of image data from memory and drawing it into or composing it onto the framebuffer. Chrom-ART can read data from internal or external memory. Similarly it writes to internal or external memory. This can be utilized when doing graphics, and has the possibility of drastically improving the graphical performance and at the same time significantly lowering the MCU usage of your application.
Many STM32 controllers contains the Chrom-ART accelerator, but not all. Check your datasheet. DMA2D is the code name for Chrom-ART and is used in the code and documentation.
Note
Goal
The goal of this step is to enable Chrom-ART and read and write data using it. The goal is not to examine the functionality of the Chrom-ART chip, but to verify that memory interfaces are functional from a Chrom-ART perspective.
Verification
Here are the verification points for this section:
Verification Point | Rationale |
---|---|
Chrom-ART is configured | Chrom-ART can be used for drawing the desired graphics |
Chrom-ART can read memory | Chrom-ART can be used for drawing graphics (M2M) |
Chrom-ART can write memory | Chrom-ART can be used for drawing graphics (M2M and R2M) |
Chrom-ART performance | Chrom-ART yields the desired performance for graphics |
Prerequisites
The following are the prerequisites for this step:
- MCU with Chrom-ART.
Do
The Chrom-ART is configured in CubeMX under the Multimedia -> DMA2D category. Activate DMA2D and configure Transfer mode and Color mode according to your display.
In the figure below DMA2D is activated and configured for Memory to Memory transfer mode and RGB565 Color Mode. Select the color mode that matches your display.
The DMA2D global interrupt is important for the syncronization of framebuffer access in a TouchGFX application. Ensure that the global interupt is enabled (NVIC tab) and that code generation for interrupt handlers is enabled (Code Generation tab) in the CubeMX NVIC settings as shown below. The priority is not important at this stage.
Write to Framebuffer Memory
Here is an overview of code that fills a specific color in a rectangle in target memory (register to memory). Check Cube Firmware packs for a concrete project for your MCU.
main.c
#include "stm32f7xx_hal.h"
#include "stm32f7xx_hal_dma2d.h"
...
uint32_t color = 0xF800; //Red in RGB565
hdma2d.Init.Mode = DMA2D_R2M;
hdma2d.Init.ColorMode = DMA2D_RGB565;
MODIFY_REG(hdma2d.Instance->CR, DMA2D_CR_MODE, DMA2D_R2M);
MODIFY_REG(hdma2d.Instance->OPFCCR, DMA2D_OPFCCR_CM, DMA2D_RGB565);
MODIFY_REG(hdma2d.Instance->OOR, DMA2D_OOR_LO, displayWidth - rectangleWidth);
hdma2d.LayerCfg[1].InputColorMode = CM_RGB565;
hdma2d.LayerCfg[1].InputOffset = 0;
HAL_DMA2D_ConfigLayer(&hdma2d, 1);
HAL_DMA2D_Start_IT(&hdma2d, color, (unsigned int)dstPtr, rectangleWidth, rectangleHeight);
If the Transfer Completed setup is configured correctly in CubeMX, a custom handler can be assigned to handle this event:
hdma2d.XferCpltCallback = DMA2D_XferCpltCallback;
And the handler can be defined as follows to verify the Transfer Completed interrupt configuration:
extern "C" {
static void DMA2D_XferCpltCallback(DMA2D_HandleTypeDef* handle)
{
//Ensure that you this callback is called
}
}
Memory-to-Memory can be tested by supplying a pointer to memory with pixel data.
HAL_DMA2D_Start_IT(&hdma2d,
(unsigned int)srcPtr,
(unsigned int)dstPtr,
displayWidth - nrOfPixels);
Performance is as expected
Compare the performance of the Chrom-ART with the performance results from previous steps of reading and writing memory. It is expected that the code utilizing Chrom-ART will be more performant than the previous CPU read/write operations.