cancel
Showing results for 
Search instead for 
Did you mean: 

TouchGFX with SPI TFT

ebray
Associate II

I've created a simple project to interface a STM32L4R91-DISCO with a TFT using a SPI interface. I've attempted to follow the TouchGFX tutorial but thus far have been unsuccessful in getting the TouchGFX library to render anything.

I have a task that sits in a loop, periodically calling OSWrappers::signalVSync(). This appears to work as the vsync_queue fills up. However, in my separate task which is running the ToughGFX loop, the call to OSWrappers::waitForVsync never returns. This mean the frames don't get rendered and flushed to the display.

Any suggestions for getting this running would be greatly appreciated!

I'm using STM32CubeIDE 1.3.1 with TouchGFX 4.13.0.

31 REPLIES 31
Martin KJELDSEN
Chief III

Let's get to the bottom of this, @ebray​ ! :)

ebray
Associate II

I removed the acquire call in initialize:

void OSWrappers::initialize()
{
    // Create a queue of length 1
    frame_buffer_sem = osSemaphoreNew(1, 1, NULL); // Binary semaphore
    //osSemaphoreAcquire(frame_buffer_sem, osWaitForever); // take the lock
 
    // Create a queue of length 1
    vsync_queue = osMessageQueueNew(1, 4, NULL);
}

Unfortunately, it did not resolve the issue. I'm going to try the hardware timer next and get back to you. Out of curiosity though, is there any advantage to a hardware timer other than being more precise with the timing? It doesn't seem like it should have any impact on the issue I'm encountering.

Thanks!

ebray
Associate II

Using a hardware timer also makes no difference. I verified the timer is functioning correctly by toggling an LED in the interrupt handler.

Would it be helpful if I shared my project?

Thanks!

Martin KJELDSEN
Chief III

The comment about the VSYNC was unrelated, yeah.

What is the state of the application? Stil doesn't return from waitForVSync()? Can you check the state of the semaphore somehow? To see if your wrapper has properly put something in the queue

/Martin

ebray
Associate II

I've verified that the vsync signal is definitely being added to the queue. It also appears that both osMessageQueueGet() calls in waitForVSync() are succeeding. I've confirmed this by adding LED toggles surrounding them. However, after that GUI appears to get stuck at lockFrameBuffer(). I assume this function is implemented in libtouchgfx.a because there is no source available for it.

0693W000000WgQeQAK.jpg

Yes, HAL::lockFrameBuffer(); calls OSWrappers::takeFrameBufferSemaphore(); so you could break in there and see what happens.

/Martin

ebray
Associate II

I added breakpoints in OSWrappers::takeFrameBufferSemaphore() (as well as OSWrappers::tryTakeFrameBufferSemaphore() for good measure) but neither of them is reached. It appears that lockFrameBuffer gets hung up before calling them.

The only thing two functions that are called inside `HAL::lockFrameBuffer();` are the following - BUT only if you're NOT using Double Buffering. So if you're not - try enabling double buffering to see if you can skip these functions and see if somehow they cause a crash for you.

dma.isDmaQueueEmpty();
dma.getAllowed();

/Martin

I was using single buffering. I changed it to double buffering and now it does indeed make it into OSWrappers::takeFrameBufferSemaphore(). The subsequent call to osSemaphoreAcquire() never returns though.

Since single buffering isn't working, and those two functions you mentioned appear related to DMA, perhaps there's something misconfigured there?

ebray
Associate II

Martin,

I've got some more time to spend on this now and wanted to circle back with you. To recap:

Double Buffering: This now seems to work, but only after commenting out the osSemaphoreAcquire() call in OSWrappers::initialize(). Unfortunately, this modification gets reverted every time CubeMX code is generated. It seems like this is bug that needs to be resolved.

Single Buffering: This still does not work. The fix for Double Buffering does not seem to have any impact. The program continues to execute but the GUI task is stuck in HAL::lockFrameBuffer() and never returns. There is no source available for this function but this is what the disassembly shows:

0693W000001pKFRQA2.jpg

Execution stays inside the 3 highlighted lines.

Could you please help me sort out what is going wrong here? Using double buffering isn't really a viable option as it consumes all of the available RAM.

Thanks!

Eric