2025-01-08 10:08 AM - edited 2025-01-08 10:11 AM
Hi Everyone,
It was recently recommended to me that I enable DMA2D on my project to possibly alleviate another problem that I'm having detailed here (Weird horizontal artifacts in touchGFX buttons - STMicroelectronics Community). My question is, how do I properly set it up? I've read several documents on the DMA2D including How to use Chrom-ART Accelerator to refresh an LCD-TFT display on STM32 MCUs - Application note and 8. Hardware acceleration | TouchGFX Documentation but I'm left scratching my head.
If I simple enable DMA2D in MX with my current project without making any code changes like this :
Then I get weird distortions on some of my text:
I'm also confused as to how I should be changing my code to take full advantage of the DMA2D. In My Mind, my flushFrameBuffer function which looks like this right now
void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
uint16_t* frameBuffer = getTFTFrameBuffer();
setLCDwindow(rect.x, rect.y, rect.width, rect.height);
LCD_IO_WriteReg(RAMWR);
int32_t YxWIDTH;
for (int32_t y = rect.y; y < rect.bottom(); y++) {
YxWIDTH = y * TFT_WIDTH;
for (int32_t x = rect.x; x < rect.right(); x++) {
LCD_IO_WriteData(frameBuffer[YxWIDTH + x]);
}
}
TouchGFXGeneratedHAL::flushFrameBuffer(rect);
}
Should be re-written to be something more like
void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
uint16_t* frameBuffer = getTFTFrameBuffer();
setLCDwindow(rect.x, rect.y, rect.width, rect.height);
LCD_IO_WriteReg(RAMWR);
uint16_t* frameBuffer = getTFTFrameBuffer();
uint16_t* destAddress = (uint16_t*)(LCD_BASE_ADDRESS + (rect.y * TFT_WIDTH + rect.x) * 2);
// Calculate the output offset
uint32_t OutputOffset = TFT_WIDTH - rect.width;
// Configure DMA2D transfer
hdma2d.Init.Mode = DMA2D_M2M;
hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565;
hdma2d.Init.OutputOffset = OutputOffset;
if (HAL_DMA2D_Init(&hdma2d) != HAL_OK) {
// Handle error
return;
}
// Start DMA2D transfer
if (HAL_DMA2D_Start(&hdma2d,
(uint32_t)(frameBuffer + rect.y * TFT_WIDTH + rect.x), // Source
(uint32_t)destAddress, // Destination
rect.width, // Width
rect.height) // Height
!= HAL_OK) {
// Handle error
return;
}
// Wait for transfer to complete
HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY);
TouchGFXGeneratedHAL::flushFrameBuffer(rect);
}