2021-04-19 09:44 AM
Hey!
I've been struggling to understand TouchGFX engine. I tried Discovery board and examples provided by TouchGFX Designer - everything works out of the box.
However playing with high level app software on discovery boards won't help me on the product boards, so I tried build project from scratch and failed. After that I reduced my task to pick small I2C B/W display, working LCD driver and draw a square on it with TouchGFX framework. Just to see that engine "ticks" as expected. Still no luck.
Things I tried so far:
Maybe anyone saw EXACT steps on how connect TouchGFX framework to hardware. Like what signals/interrupts framework needs, which file to put it (ex. step 1: you should provide this instruction here for this and this flag there for that). I guess I'm talking about "Touch AL" layer which seems to be the hardest part. Theoretically I kinda understand what is rendering, when flushing buffer takes place and such things, yet no able to run it.
For now I always stuck at
virtual void backPorchExited()
{
swapFrameBuffers();
tick(); // <- here
}
Worth mention that tried I provide Vsync flag with Timer interrupt. I tried different timer rates and different places to start it, also tried to emulate Vsync flag.
extern "C" void touchgfx_signalVSyncTimer(void)
{
HAL::getInstance()->vSync();
touchgfx::OSWrappers::signalVSync();
}
Any suggestions appreciated! Thanks
Solved! Go to Solution.
2021-05-05 08:43 AM
Hi,
Thanks for sharing indeed !
If I can give my 2 cents on the single frame buffer issue : I got a similar issue recently (double frame buffer strategy is fine while single frame buffer is not), the root was the DMA2D synchronization that can be enabled by default when selecting double frame buffer and remains there when switching to single frame buffer.
You could try to disable it by adding the following line to void TouchGFXHAL::initialize() method after mother class initialize() call) : lockDMAToFrontPorch(false);
Best regards,
Nicolas
2021-04-20 06:29 AM
Hi,
It is a bit complicated to know what exactly you are struggling with and guide you accordingly without more details, especially since I guess you have already looked a bit everywhere from what you wrote :grinning_face_with_sweat: But maybe this video from another user (HP) can help you for some of the steps. For the blog I guess you are referring to that one ?
/Romain
2021-04-20 09:59 AM
Thanks for response!
Yeah I was refering to that link and example with NUCLEO-G071 & X-NUCLEO-GFX01M1. Both used partial buffer strategy.
Found somewhat similar problem in this thread https://community.st.com/s/question/0D53W000004nFAu/touchgfx-with-spi-tft.
I was using single buffering also. Changed it to double buffering in CubeMX and now I was able to run engine freely without stuck at backPorchExited(), my display finally draw me something. Not sure if it was a bug or did I missed something during setting project up.
For now I want to keep this thread for a while since I would likely need help with double buffering strategy. My display showed only half of the image, with other half filled with random pixels.
2021-04-27 01:44 AM
Hi,
For your information a new video has just been released from our TouchGFX Development team, focused on board bring-up.
I think it should be of great help in your case,
Board Bring-up
TouchGFX Board bring up introduction
Abstraction Layer:
TouchGFX Abstration layer development introduction
Best regards,
Nicolas
2021-05-05 02:01 AM
Thanks for the videos!
After days and days I finally had some success. I bought DISCOVERY-F429 board with ili93141-based display which supports RGB interface.
Now I have 4 working projects made from scratch: with/without SDRAM, with/without RTOS.
If someone needs help here's what I did:
void touchgfx_taskEntry()
{
/*
* Main event loop will check for VSYNC signal, and then process next frame.
*
* Note This function returns immediately if there is no VSYNC signal.
*/
if (OSWrappers::isVSyncAvailable())
{
OSWrappers::signalRenderingDone(); //// <- ADD THIS TO RESET VSYNC FLAG
hal.backPorchExited();
}
}
However my SPI-display based approach does not work as expected. Single buffer strategy doesn't work at all. With double buffer strategy I can see my UI screens, but waveforms acquried with logic analyzer are complete mess. I definately missed some flags somewhere.
2021-05-05 02:07 AM
Thanks for sharing :thumbs_up:
Just out of curiosity did you also try the partial framebuffer strategy with the SPI display approach ? What is the issue with the single framebuffer ? Nothing is displayed or a hardfault in the initialization ?
/Romain
2021-05-05 03:08 AM
No didn't try.
With single framebuffer I can't even make it to flushFrameBuffer() part, engine dies at backPorchExited() in HAL.hpp file.
With double buffer strategy engine "ticks" and my UI screens are displayed, yet something is wrong too. I attached waveforms just in case (VSYNCS are set by 60 Hz timer, MOSI & SCK - actual "flushing" framebuffer to display).
extern "C" void touchgfx_signalVSyncTimer(void)
{
GPIO::set(GPIO::VSYNC_FREQ);
/* VSync has occurred, increment TouchGFX engine vsync counter */
touchgfx::HAL::getInstance()->vSync();
/* VSync has occurred, signal TouchGFX engine */
touchgfx::OSWrappers::signalVSync();
GPIO::clear(GPIO::VSYNC_FREQ);
}
void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect &rect)
{
// Calling parent implementation of flushFrameBuffer(const touchgfx::Rect& rect).
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
// Please note, HAL::flushFrameBuffer(const touchgfx::Rect& rect) must
// be called to notify the touchgfx framework that flush has been performed.
ssd1306_FlushFrameBuffer(getClientFrameBuffer());
//TouchGFXGeneratedHAL::flushFrameBuffer(rect);
}
As I understand flushFrameBuffer() should be called after RENDER_TIME is done, since it makes sense. In my case it is called twice and during RENDER_TIME. So something else I should provide.
2021-05-05 08:43 AM
Hi,
Thanks for sharing indeed !
If I can give my 2 cents on the single frame buffer issue : I got a similar issue recently (double frame buffer strategy is fine while single frame buffer is not), the root was the DMA2D synchronization that can be enabled by default when selecting double frame buffer and remains there when switching to single frame buffer.
You could try to disable it by adding the following line to void TouchGFXHAL::initialize() method after mother class initialize() call) : lockDMAToFrontPorch(false);
Best regards,
Nicolas
2021-05-05 09:43 AM
Ok, thanks!
Now it works with single buffer too.
But flushFrameBuffer is called twice in one vsync period, so SPI actually sends same data twice to display.
Another question, do I have to implement anything else except actual sending pixel data into TouchGFXHAL::flushFrameBuffer() ?
void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect &rect)
{
// Calling parent implementation of flushFrameBuffer(const touchgfx::Rect& rect).
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
// Please note, HAL::flushFrameBuffer(const touchgfx::Rect& rect) must
// be called to notify the touchgfx framework that flush has been performed.
mydriver_FlushFrameBuffer(getClientFrameBuffer());
HAL::flushFrameBuffer(rect); // <- does this line needed? seems no influence at all
}
2021-05-06 08:37 AM
Hi,
This may not have a direct influence in your case but I think the "HAL::flushFrameBuffer(rect);" call is preferable as it updates some internal states of the TouchGFX library.
Best regards,
Nicolas