TouchGFX with SPI TFT
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-17 12:44 PM
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.
- Labels:
-
SPI
-
STM32L4 series
-
TouchGFX
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-28 3:54 PM
Let's get to the bottom of this, @ebray​ ! :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 6:54 AM
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 7:10 AM
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 7:17 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 9:18 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 9:23 AM
Yes, HAL::lockFrameBuffer(); calls OSWrappers::takeFrameBufferSemaphore(); so you could break in there and see what happens.
/Martin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 9:26 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 9:41 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-04-29 9:56 AM
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-22 10:30 AM
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:
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
