cancel
Showing results for 
Search instead for 
Did you mean: 

TouchGFX gauge glitch

wlynn777
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

25 REPLIES 25
JTP1
Lead

Hello

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

Br JTP

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

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. 

Good catch! It didn't do a difference tho. I'm starting to think that maybe the problem lies outside the MPU... 

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

 

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

Mohammad MORADI
ST Software Developer | TouchGFX

Yes, I called setAnimationStorage((void*)0xC0400000); just after TouchGFXGeneratedHAL::initialize();
and D cache is disabled

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

Okey, Have you verify the framebuffer swapping logic that it works properly ? What the screen transition glitch looks like ?

Br JTP