Skip to main content
Anders Nedergaard PETERSEN
Senior II
November 27, 2018
Solved

REPOST: Change LCD orientation in 180 degree

  • November 27, 2018
  • 10 replies
  • 11634 views

QUESTION - TouchGFX Community repost - Eyal goltzman - July 2016

Hello,

Following Yossi question from today and Martin reference to Soren answer in https://touchgfx.zendesk.com/hc/en-us/community/posts/206708899--orientation-180-degree

We are using LCD without SPI interface, only parallel RGB interface through the LCD-TFT Controller peripheral, so controlling the LCD as describe in your answer to the above link is not an option.

Since our customers have a mechanical issue with the display orientation (the flat cable position) we are trying to address it with SW solution.

As I see it, there is an option to rotate the frame buffer just before calling swapFrameBuffers, what do you think? It could be done? performance issues? Can we do it ourselves? How?

Thanks,

Eyal

ANSWER - TouchGFX Community repost - Soren Pingel Dalsgaard - July 2016

Hi Eyal,

How unfortunate! You could do the rotation manually, but the performance penalty will be very significant, to the extent that only very simple UIs can be realized.

This is due to two things:

  1. If anything changes on screen then you must invalidate() the entire screen. Otherwise it will not have properly "undone" the rotation from last time, causing the widgets to appear in both normal and rotated positions.
  2. The rotation algorithm must invert both X and Y axis. This means that you must either read or write each and every pixel of the screen non-sequentially to SDRAM, which is very expensive.

I think the right place to do such a rotation would be by overriding HAL::endFrame. Something like this:

void MyHAL::endFrame()
{
 dma.flush(); //wait for all dma operations to have completed
 rotateFb(getClientFrameBuffer()); //apply rotation on the fb
 HAL::endFrame(); //call base impl when rotation is done.}

Apart from this you would need also to invert the coordinates in your touch controller driver.

You can give it a shot, but I am not too optimistic to be honest. Hopefully you could convince your customer to switch to another display that can either be mounted normally or supports scan direction swap.

This topic has been closed for replies.
Best answer by Martin KJELDSEN

Hi Daniel,

Okay, here it is. It only supports 180 rotation, but you could port it to do all rotations easily if you wanted - You should be able to tell from the code.

So just to summarize - This rotation is done at a significant performance cost. It is an expensive operation since pixels must be swapped on both X and Y axis. It leads to very inefficient RAM accesses. 

Mirror.hpp is a custom widget which will just reverse the pixels on both X and Y axis. To use it you must:

 - #include it in your view, and add a member of type Mirror to your View class.

 - Place it at (0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT) so it covers the full screen area

 - Make sure it is on top (make it the last widget you add() to your view)

In addition you need to add the following function to your FrontendApplication.hpp:

 // Force redrawing entire screen
 virtual void draw(Rect& rect)
 {
 if (drawCacheEnabled)
 {
 // Invalidate entire screen instead of requested rect.
 Rect r(0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT);
 Application::draw(r);
 }
 else
 {
 // Use original rect if we are *actually* drawing and not just invalidating.
 Application::draw(rect);
 }
 }

Lastly, you need to revert the X and Y coordinates in your touch controller sampleTouch() function. Something like this (Assuming a 480x272 display):

x = 479-x;
y = 271-y;

If you are on a different resolution you need to also change a constant at the bottom of the Mirror.hpp file!

The Mirror class is assuming 16bpp frame buffer. You can probably figure out how to modify it if you are using 24bpp frame buffer.

Hope this helps!

Best regards,

Martin

10 replies

DSchr
Explorer
December 27, 2018

Hello,

is there already some progress to this topic.

I'm just rewriting an application from emWin to TouchGFX which is using a Stm32f746 Discovery board in portrait orientation.

All mechanics are fixed and the units are already in use with current emWin implementation.

Unfortunately the picture is upside down now with "HAL::getInstance()->setDisplayOrientation(ORIENTATION_PORTRAIT);"

Why does this function not allow 180° and 270° as well, when 90° is already implemented.

Thanks,

Daniel Schramm

Martin KJELDSEN
Principal III
January 2, 2019

Hi Daniel,

Back when we designed rotation we did so knowing that for a lot of displays it was possible to configure, at the driver level, a 180 degree rotation. We will be looking into whether or not to support 180 degree rotation, especially since other offers like STEmWin do so and perhaps also 270.

The original post outlines how to perform the rotation in endFrame(). If it is of any interest, i have a Custom Widget (that you add() to your Screen as the last element) that will rotate the framebuffer for you. This is an expensive operation, but it will perform the rotation none the less.

Best regards,

Martin

DSchr
Explorer
January 2, 2019

Hello Martin,

I would be very pleased if you can provide the source.

Support for 90, 180 and 270 degree is really useful for the discovery boards since the rotation in the projects is mainly selected depending on the connectors.

I'm currently working on the successor of this project: http://pinguin.sauerland.de/mp3player.html#mp3

The current EmWin implementation is not satisfying but having the screen upside down is also not nice ;)

There is not much animation implemented so rotation in software will be fast enough.

Do you allow to publish your code snippet when I publish the project as open source later?

Thanks,

Daniel

Martin KJELDSEN
Martin KJELDSENBest answer
Principal III
January 2, 2019

Hi Daniel,

Okay, here it is. It only supports 180 rotation, but you could port it to do all rotations easily if you wanted - You should be able to tell from the code.

So just to summarize - This rotation is done at a significant performance cost. It is an expensive operation since pixels must be swapped on both X and Y axis. It leads to very inefficient RAM accesses. 

Mirror.hpp is a custom widget which will just reverse the pixels on both X and Y axis. To use it you must:

 - #include it in your view, and add a member of type Mirror to your View class.

 - Place it at (0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT) so it covers the full screen area

 - Make sure it is on top (make it the last widget you add() to your view)

In addition you need to add the following function to your FrontendApplication.hpp:

 // Force redrawing entire screen
 virtual void draw(Rect& rect)
 {
 if (drawCacheEnabled)
 {
 // Invalidate entire screen instead of requested rect.
 Rect r(0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT);
 Application::draw(r);
 }
 else
 {
 // Use original rect if we are *actually* drawing and not just invalidating.
 Application::draw(rect);
 }
 }

Lastly, you need to revert the X and Y coordinates in your touch controller sampleTouch() function. Something like this (Assuming a 480x272 display):

x = 479-x;
y = 271-y;

If you are on a different resolution you need to also change a constant at the bottom of the Mirror.hpp file!

The Mirror class is assuming 16bpp frame buffer. You can probably figure out how to modify it if you are using 24bpp frame buffer.

Hope this helps!

Best regards,

Martin

DRoma.6
Visitor II
November 16, 2021

Hi @Martin KJELDSEN​ ,

I have successfully added the 180 degree rotation to my screen. But what I really want to do is to rotate my screen over 90 degrees.

How would I do that?

Damiën

DSchr
Explorer
January 3, 2019

Hello Martin,

I did a quick change for 24Bit depth and it seems to work well.

Using the internal Portrait functionality together with this mirror provides the 270 degree that I need.

Please find the updated Code attached.

Daniel

Martin KJELDSEN
Principal III
January 3, 2019

Glad it worked for you, Daniel. And thanks!

Martin KJELDSEN
Principal III
January 3, 2019

Also, would you mind accepting the post you feel helped as the correct answer? It's a very helpful indicator to other readers. Thanks!

Plaramee
Associate II
February 18, 2019

Just wanted to chime in as we require this feature also. Any progress on this topic?

Martin KJELDSEN
Principal III
February 18, 2019

Hi @Philippe Laramée​,

Nothing has been done yet to fully support 180 degree rotation in software.

Just a note: If you're running the STM32L4R9 - The GFXMMU on the L4R9 can flip the display vertically (mirroring top/bottom) by changing the programming order of the LUT (Look up table)

yanqin gem
Associate II
November 25, 2019

Hi , Martin

Did you mean that now only some MCU which take GFXMMU module like STM32L4R9 can support 180 degree rotation display ?

Plaramee
Associate II
February 18, 2019

Thank you Martin. We are unfortunately using an STM32H743 which does not seem to have this option.

Will there be something done in a future version on Touch GFX to support this? I think it would be an awesome addition to the library.

We will need to work on the mechanical side to position our LCD at 0 degrees but this has a big impact on the esthetics of our product. It would save a lot of time, effort and money to at least know ahead if it is planned and if so, in what kind of timeframe.

Thank you,

JJ.Lin
Associate III
July 6, 2021

Hello, @Martin KJELDSEN​ ,I have no idea on how to rotation the screen 180 degree yet since there is no way to do it by operate the STM32 registers, and SPI interface is not available on the display. I want to know if will it support in the future version?

Romain DIELEMAN
ST Employee
July 6, 2021

Hi,

180degree rotation is handled by TouchGFX, but I guess you are looking for another rotation ? It is in our plan to support all possible rotation but not in the near future at all...

/Romain

mandrake
Associate III
November 30, 2021

Hi @Romain DIELEMAN​ Can you please elaborate where to find 180-degree rotation in TouchGFX?

Visitor II
June 28, 2023

In regards to display surface rotation, I have read an article using DMA2D to perform a positive 90 degree rotation.  Essentially this algorithm would perform a 2D Source to Destination Blit of a rectangle with a biased 'skip count' for each stride copy by the length of a line -1.   This would copy a "line of pixels" into a "column of pixels".  Which would be a 90 degree rotation.   To rotate a display 180 degrees you would need to perform this operation twice, and you may need a second buffer.   Unfortunately I can not recall the article I read, nor do I have the source code for this algorithm