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);
}
Solved! Go to Solution.
2025-03-25 7:50 AM
It appears that this problem was closely related to my other issue Re: Weird horizontal artifacts in touchGFX buttons - Page 4 - STMicroelectronics Community
As best I can tell, fast reads (using DMA) from my external quadspi-connected flash memory (in this case an MT25QL128 flash memory) were occasionally returning the wrong byte due to some bad settings in quadspi configuration (again, see link above).
Specifically what seemed to fix it was changing my clock prescaler to 0 from 2 (running the quadspi flash at a full clock speed of 80MHz) and changing the sample shifting to half-cycle. I realize that this is not a fully satisfactory answer, as increasing clock speed should not make signal integrity issues improve generally, but it is best I have for the moment, and hopefully if someone comes across this later, it will at least point them towards where to take a closer look.
2025-01-10 6:20 AM
Two additional observations:
1. The character distortion appears to go away when I shrink the font down to about 60 (currently its at 80)
2. If I set the option 'Use DMA2D Accelerator (Chrom-Art)' within the touchGFX settings in MX to 'No' but leave everything else the same (including leaving DMA2D enabled), the problem also goes away, though I suppose this is not surprising.
2025-03-25 7:50 AM
It appears that this problem was closely related to my other issue Re: Weird horizontal artifacts in touchGFX buttons - Page 4 - STMicroelectronics Community
As best I can tell, fast reads (using DMA) from my external quadspi-connected flash memory (in this case an MT25QL128 flash memory) were occasionally returning the wrong byte due to some bad settings in quadspi configuration (again, see link above).
Specifically what seemed to fix it was changing my clock prescaler to 0 from 2 (running the quadspi flash at a full clock speed of 80MHz) and changing the sample shifting to half-cycle. I realize that this is not a fully satisfactory answer, as increasing clock speed should not make signal integrity issues improve generally, but it is best I have for the moment, and hopefully if someone comes across this later, it will at least point them towards where to take a closer look.