How to use DMA2D on STM32H7
Preface
Recently, due to a requirement, we need to assist the customer in displaying a thermal camera on the MCU STM32H7 display panel using the STM32H750-DK development board. However, the display panel used in this development board is not SPI-driven, so we have to start learning LTDC+DMA2D. This section will introduce the usage and overview of DMA2D.
Introduction to DMA2D
When using the LTDC controller to control the LCD screen, after ensuring that the LTDC is functioning properly, we can write the desired pixel data to the configured display memory address. The LTDC will then transfer this data from the display memory to the LCD panel for display. However, the amount of display data is usually large, so it is beneficial to use DMA for efficient operations.
To address this requirement, STM32 has specifically designed the DMA2D peripheral. It enables fast drawing of rectangles, lines, layered data blending, data copying, and image data format conversion. DMA2D can be understood as a DMA specifically designed for graphics-related tasks
DMA2D Mode
- Register to memory
- Memory to memory
- Memory to memory with pixel color format conversion
- Memory to memory with pixel color format conversion and transparency blending
DMA2D operation
Mastery of the commonly used APIs of DMA2D is essential as they are utilized in the underlying driver acceleration of GUI, JPEG hardware decoding, camera, and other functionalities. Here, we will introduce the following commonly used APIs:
- _DMA2D_Fill –> This function is primarily used for color filling the LCD.
- _DMA2D_Copy –> This function is used to copy the color data from the foreground layer to the target region.
- _DMA2D_MixColorsBulk –> This function is used for color blending between the foreground layer and the target region, and outputs the blended image to the target region.
- _DMA2D_AlphaBlendingBulk –> This function is used for color blending between the foreground layer and the background layer, and outputs the blended image to the target region.
- _DMA2D_DrawAlphaBitmap –> This function is used to display an ARGB8888 format bitmap at the specified position.”
The characteristics of the framebuffer prevent us from simply using efficient operations like memset
to achieve rectangular area filling. Here, we will demonstrate two alternative methods for comparison.
for(int y = ys; y < ys + height; y++){
for(int x = xs; x < xs + width; x++){
framebuffer[y][x] = color;
}
}
Typically, we use the following double-loop method to fill an arbitrary rectangle, where xs and ys are the coordinates of the top-left corner of the rectangle on the screen, width and height represent the width and height of the rectangle, and color indicates the color to be filled:
static inline void DMA2D_Fill( void * pDst, uint32_t width, uint32_t height, uint32_t lineOff, uint32_t pixelFormat, uint32_t color) {
/* DMA2D configuration */
DMA2D->CR = 0x00030000UL; // Configured for register to memory mode
DMA2D->OCOLR = color; // Set the color to be used for filling (should have the same format as the configured color format)
DMA2D->OMAR = (uint32_t)pDst; // Starting memory address of the fill area
DMA2D->OOR = lineOff; // Line offset, i.e., number of pixels to skip (in pixels)
DMA2D->OPFCCR = pixelFormat; // Set the color format
DMA2D->NLR = (uint32_t)(width << 16) | (uint16_t)height; // Set the width and height of the fill area in pixels
/* Start the transfer */
DMA2D->CR |= DMA2D_CR_START;
/* Wait for DMA2D transfer to complete */
while (DMA2D->CR & DMA2D_CR_START) {}
}