cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5G9 - TouchGFX tick stops after first frame

robintechnology4u
Associate

I am developing a TouchGFX user interface on a STM32U5G9 with a 24bit RGB LCD screen. I have developed the user interface on the STM32U5G9J-DK2 development board, where it works fine. I imported the TouchGFX project on my custom board the framework stops after the first full screen is displayed.

As a test I have added a start-up screen with two colored boxes and a image in internal flash. I have configured interactions to jump to the main screen after 3 seconds. When I set a breakpoint inside model.tick(), it triggers before 25 ~30 times before it stops triggering. The other threads of the application run as intended (ThreadX). If I look at the thread list in CubeIDE, the TouchGFX thread has state ready, and it's run count stops increasing after the first frame is displayed on the screen. 

I compared both projects of the devboard and my projects in cubeMX, and I can't find any differences. I compared both IDE projects with winmerge, but also nothing found which could cause this. 

My debugging so far gave me the following insights: 

  • The LTDC interrupt is triggering and calling HAL_LTDC_LineEventCallback. In the function below tx_queue_enqueued equals 1, so the vsync towards TouchGFX is blocked. I have set a breakpoint inside waitForVSync(), which empties the queue. This breakpoint stops triggering after the first frame
void OSWrappers::signalVSync()
{
    UINT ret;

    // Send the message only if the queue is empty.
    // This call is from ISR, so no need to re-send
    // the message if not yet consumed by threads
    if (vsync_q.tx_queue_enqueued == 0)
    {
        // This is supposed to be called from Vsync Interrupt Handler
        // So wait_option should be equal to TX_NO_WAIT
        ret = tx_queue_send(&vsync_q, &dummy_msg, TX_NO_WAIT);
        if (ret != TX_SUCCESS)
        {
            assert(0 && "Failed to Signal Vsync!");
        }
    }
}
  • My conclusion of the above is that something is blocking the touchGFX task, I tried to add giveFrameBufferSemaphoreFromISR() inside the HAL_LTDC_LineEventCallback function, but no success.
  • I tried to set breakpoints in GPU2D_IRQHandler GPU2D_ER_IRQHandler and DMA2D_IRQHandler, but none is triggered. My preliminary conclusion is that touchGFX is stuck inside nema_wait_irq() as the GPU2D interrupt doesnt fire. The question is why..? 
  • I disabled GPU2D to see if DMA2D has different result, but it gives the same result

My touchGFX configuration:

  • Double buffering in internal RAM (RGB565). framebuffer = 400 * 800 * 2 bytes:
/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 1104K
  FRAMEBUFFER_RAM (xrw) : ORIGIN = 0x20000000 + 1104K, LENGTH = 1904K
  FLASH    (rx)    : ORIGIN = 0x08000000,   LENGTH = 4096K - 32K
  EXT_FLASH (rx)		: ORIGIN = 0x90000000, LENGTH = 32M
  EEPROM (rx) 		: ORIGIN = 0x08000000 + 4096K - 32K, LENGTH = 32K
}

.........

FramebufferSection (NOLOAD) :
  {
    *(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x4);
    
    *(Nemagfx_Stencil_Buffer Nemagfx_Stencil_Buffer.*)
	*(.gnu.linkonce.r.*)
	. = ALIGN(0x4);
	
	*(Nemagfx_Memory_Pool_Buffer Nemagfx_Memory_Pool_Buffer.*)
	*(.gnu.linkonce.r.*)
	. = ALIGN(0x4); 
	
  } >FRAMEBUFFER_RAM
  
  VideobufferSection (NOLOAD) :
  {
    *(Video_RGB_Buffer Video_RGB_Buffer.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x4);
  } >RAM
  • Interrupts of DMA2D, GPU2D and LTDC on priority 7
  • DMA2D enabled, GPU2D enabled, vector rendering enabled
  • GPU2d command list size = 16384 bytes
  • GPU2D buffers: 
#define RING_SIZE                      1024 /* Ring Buffer Size in byte */
#define NEMAGFX_MEM_POOL_SIZE          24320 /* NemaGFX byte pool size in byte */
#define NEMAGFX_STENCIL_POOL_SIZE      389120 /* NemaGFX stencil buffer pool size in byte */

LOCATION_PRAGMA_NOLOAD("Nemagfx_Memory_Pool_Buffer")
static uint8_t nemagfx_pool_mem[NEMAGFX_MEM_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Memory_Pool_Buffer"); /* NemaGFX memory pool */

LOCATION_PRAGMA_NOLOAD("Nemagfx_Stencil_Buffer")
static uint8_t nemagfx_stencil_buffer_mem[NEMAGFX_STENCIL_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Stencil_Buffer"); /* NemaGFX stencil buffer memory */
​

I hope someone can point me in the right direction :) 

Kind regards,

Robin

0 REPLIES 0