Skip to main content
Associate II
May 15, 2024
Solved

TouchGFX gauge glitch

  • May 15, 2024
  • 4 replies
  • 11231 views

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:

LTDCParams.png

LTDC.png

TGFXGenerator.png

Can anyone please tell me why this happens? Thanks..

Best answer by wlynn777

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.

4 replies

Graduate II
May 15, 2024

Hello

Have you try to set framebuffers and animation storage to not-cacheable ? It might help. 

Br JTP

wlynn777Author
Associate II
May 15, 2024

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..

Graduate II
May 15, 2024

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. 

ST Employee
May 15, 2024

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

wlynn777Author
Associate II
May 17, 2024

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

urbito
Senior II
May 20, 2024

if you are being able to see proper GUI without animations, but when changing from one to another screen and getting a glitch, i have solved it from different sources:

 

it happened to me once with wrong MPU and Cache configurations.

Then, it happened to me also with a wrong SDRAM configuration, in this case i did not have glitch at all, but something like "lossing frames"

And the last time i had it, i have provided more memory to heap/stack(talking about the RTOS task memory, the touchGFX task). I am not the best coder, so i made some kind of spagetti and was destroying the memory, i noted and provided more memory, it wasnt the cleanest, but worked.

 

Greetings

wlynn777Author
Associate II
May 30, 2024

Thanks for the reply.

I think the SDRAM is already functioning properly, as data is written without corruption, and static image is not corrupt as well..

For RTOS, we are using TOTAL_HEAP_SIZE = 40000 Bytes and touchGFX task has a stack size of 8192 Words.

Could you please tell us where the MPU and Cache configurations might be wrong? We've tried so many combinations for the MPU and it's still not working..

And is it possible to set an MPU config for DMA2D? 

BR

urbito
Senior II
June 3, 2024

It is not an exact way to try, but may you try to put for example 16Kb of total Heap and use like, 12Kb of those? Give it a shoot. 

ST Employee
June 21, 2024

Hello @wlynn777 ,

Have you made any progress on this topic? 

wlynn777Author
Associate II
June 24, 2024

Not yet, unfortunately. We suspect there's a problem with the LCD framebuffer as the LCD we're using is not branded, so we're looking for a different one. We'll keep this thread updated.