cancel
Showing results for 
Search instead for 
Did you mean: 

Calling OSWrappers::signalVSync() in No-OS Application

PKriv.1
Associate III

Hello,

I understand that the TouchGFX Engine needs OSWrappers::signalVSync() to be called when the LCD transfer is done. Before that, the Engine was halted to make sure that framebuffer doesn't get overwritten during the data transfer to LCD. You mentioned in the tutorial, that we can use TE-signal from the LCD when the transfer is done to invoke the function. However, some LCDs, like very popular and cheap ILI9341 do not have such a signal.

In my application, I used a timer to periodically invoke OSWrappers::signalVSync(), every 5000 clock cycles (in its interrupt routine). Is there a better way to do that, and did you imagine it some other way?

Best regards,

6 REPLIES 6
Alexandre RENOUX
Principal

Hello PKriv.1,

As you mentioned, signalVSync is the heartbeat of your application. If no TE signal comes out of your display, you indeed have to use a timer to simulate the refresh period of the display. It's the only solution.

/Alexandre

PKriv.1
Associate III

Great, thanks for confirming it. Is there a way to know how long the timer should be running? I feel that if I choose just any value, it may be out of sync with the actual data transfer.

Alexandre RENOUX
Principal

In case you don't have the TE signal, you have no way of knowing the display refresh rate except if it is written in the datasheet. So first try with a 16.6 ms timer (60 Hz).

Could you enclosed your display datasheet ?

/Alexandre

PKriv.1
Associate III

Sure, here it is: https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf

But even if I do know the refresh rate, it still doesn't mean I can un-halt the engine at the right time. If I would call signalVSync  every 16.6ms, I still have no way of knowing if that happens during the data transfer.

Alexandre RENOUX
Principal

What Framebuffer strategy are you using ?

TouchGFX makes sure that if you receive a tearing effect (or simulated by a timer) while the transfer is being done, this does not render in the same block (for the case of Partial Framebuffer).

Have a look at the G0-Nucleo Application Template available in TouchGFX Designer. And look at the TouchGFXGeneratedHAL. You have transmitActive() that should tell you if you are transmitting or not. Of course the rest has to be implemented by you since it's your own custom driver that is involved, but the structure is automatically generated.

/Alexandre

PKriv.1
Associate III

I'm playing with the partial fb strategy, atm.

I just checked the code for G0-Nucleo. Well there is the signalVsync() clearly called in GPIO interrupt routine, just like you suggested originally. And transmitActive() is nothing more than the call for touchgfxDisplayDriverTransmitActive(), which according to partial fb strategy just raises the flag when the blocks are being transferred.

So, all in all, if LCD has no means of reporting when the transfer is completed, we can not know for sure if we should start rendering new fb or not. Timer shall call signalVsync() periodically, and if we set the period to be long enough (16.6ms in.e.) we might be on the safe side of nice graphics experience :) But it might eventually happen that Timer interrupt happens at one point during our data transfer, and we'll have a broken frame ;)