2024-05-14 08:56 PM
Hi,
I'm using a custom H7 board, with QSPI + 16-bit SDRAM, and using RTOS.
However I run into an issue where there's glitching in my gauge in TouchGFX (see attached video...)
TouchGFX is using double buffer, also animationStorage:
setFrameBufferStartAddresses((void*)0xC0000000, (void*)0xC0177000, (void*)0xC0400000);
A few points:
- I'm able to read/write to QSPI & SDRAM correctly
- Static images appear correctly
- Glitch also appears on the whole screen during transition from one image to another
MPU:
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes for region 0 */
/* Configure the MPU attributes for SDRAM to normal memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes for region 1 */
/* Configure the MPU attributes for the frontbuffer to normal memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes for region 2 */
/* Configure the MPU attributes for the backbuffer to normal memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0xC0200000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes for region 3 */
/* Configure the MPU attributes for Quad-SPI area to strongly ordered memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_64MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes for region 4 */
/* Configure the MPU attributes for QSPI memory to normal memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RO;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
Clock Configurations:
- System: 480 MHz
- FMC : 150 MHz
- LTDC : 20.15 MHz
- QUADSPI : 150 MHz
My LTDC & TouchGFX Configurations:
Can anyone please tell me why this happens? Thanks..
Solved! Go to Solution.
2024-12-06 10:58 PM
Okay, I got it to work but without the DMA2D, and I switched to RGB565.
I also did these, which removed the glitches and artifacts:
- Initialized FMC_NBL0 and FMC_NBL1 pins (crucial, as it turns out...)
- Set MPU of the SDRAM to:
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
- Disabling the DCache also helped during troubleshooting.
Thanks to everyone who has helped answer.
2024-05-14 10:07 PM
Hello
Have you try to set framebuffers and animation storage to not-cacheable ? It might help.
Br JTP
2024-05-14 10:42 PM
Thanks for the reply. I did as you said
/* Configure the MPU attributes for region 1 */
/* Configure the MPU attributes for the frontbuffer to normal memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes for region 2 */
/* Configure the MPU attributes for the backbuffer to normal memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0xC0200000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes for region 3 */
/* Configure the MPU attributes for the animationStorage to normal memory*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0xC0400000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
But not much difference. The needle just becomes a lighter blue..
2024-05-14 11:30 PM - edited 2024-05-14 11:31 PM
Isn't 1 Mbyte too small block for your frame buffer (800*480*4=aprox 1.5 Megabyte) ? I would try to set mpu region size to 2 Mbyte.
2024-05-15 12:28 AM
Good catch! It didn't do a difference tho. I'm starting to think that maybe the problem lies outside the MPU...
2024-05-15 02:07 AM - edited 2024-05-15 02:08 AM
Ok. Have you remember to call setAnimationStrorage after setting the frame buffer addresses ?
Maybe disable D cache completely to make sure it isn't causing problems.
Br JTP
2024-05-15 02:51 AM
Hello @wlynn777 ,
Unfortunately, I'm not an expert in MPUs, however, we have seen a similar issue that we could fix by changing the
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
for the internal RAM; but of course, it was a different project.
What I am trying to say is, as our amazing friend @JTP1 pointed out, it would be reasonable to disable all the optimizations first, check the result and then enable them individually to get to the desired performance.
Looking forward to hearing from you
2024-05-17 06:52 AM
Yes, I called setAnimationStorage((void*)0xC0400000); just after TouchGFXGeneratedHAL::initialize();
and D cache is disabled
2024-05-17 06:54 AM
I tried this, and testing with other possible values, it's still not working.. It doesn't do much difference to the display, unfortunately sometimes the gauge needle stops moving completely. I'm no expert in MPU as well, so I don't know how much tweaking this will affect the outcome, also can you please elaborate what you mean by disabling all the optimizations first? BR
2024-05-18 11:33 AM
Okey, Have you verify the framebuffer swapping logic that it works properly ? What the screen transition glitch looks like ?
Br JTP