Rotate the screen 90 degree

Description

What MCU/Processor/Board and compiler are you using?

STM32F7

What LVGL version are you using?

V7.7

What do you want to achieve?

Rotate the screen 90 degree

What have you tried so far?

Hi, Sir,
I remember the lvgl lib only support the RGB TFT with horizontal scan version.I am using the normal RGB type 4.3 inch TFT ,the 480*272 one ,also the same horizontal type and display normally in that dirrection. But I need switching to the vertical direction by the customer choice. I had find somebody do the right thing on the net,but don’t know how to realize. Could you kindly give some advice on it ?

Code to reproduce

Screenshot and/or video

Depending on the RGB-controller it may be possible to rotate the screen with build-in features of the controller. Only if the controller does not support it you should rotate in software because of the decrease in performance. To find out if your controller supports it directly you need to check it´s datasheet.
If you want to / need to rotate in software, you can use the flush callback of lvgl. In this function you switch the columns and rows. In the code example you can see how it is done.
One thing i forgot. In lv_conf.h you need to switch the horizontal and vertical resolution. So if the display has 480x272 you need to set it to 272x480. But do not change the LTDC resolution.

Important the following code example is not from me, but i dont know anymore from where i have copied it. So all credits go to the original author.

static void tft_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
  int32_t     y;
  int32_t     x;
  int32_t     ys;
  int32_t     xs;
  uint32_t    w;
  uint32_t    ulSource;
  uint32_t    ulDest;

  w = lv_area_get_width (area);

  for (x = area->x1, xs = 0; x <= area->x2; x++, xs++) {                  // Copy the area data rotated into frame buffer 1.
    for (y = area->y1, ys = 0; y <= area->y2; y++, ys++) {
      ulSource = (uint32_t) color_p    + ((xs + (ys                          * w))                 * sizeof (lv_color_t));
      ulDest   = (uint32_t) ltdc_fb + ((y  + ((drv->hor_res - 1 - x) * drv->ver_res)) * sizeof (lv_color_t));

      if (sizeof (lv_color_t) == 4)  {
        *((uint32_t*) ulDest) = *((uint32_t*) ulSource);
      }
      else if (sizeof (lv_color_t) == 2)  {
        *((uint16_t*) ulDest) = *((uint16_t*) ulSource);
      }
      else {
         *((uint8_t*) ulDest) = *((uint8_t*) ulSource);
      }
    }
  }
  lv_disp_flush_ready (drv); // IMPORTANT! It must be called to tell the system the flush is ready
}
1 Like

Hi,

As @InfotecDehmer mentioned, you should rotate the display in hardware if possible.

If you use the master branch of LVGL (7.11+), software rotation support is now built-in. See the docs for information on how to configure it.

1 Like

Oh i didnt know that it is now supported. Sorry for my misleading information. Does the direct implementation in lvgl increase the performance of the rotation vs implementing the rotation in the flush callback?

1 Like

It’s going to be about the same or slightly worse; the main advantage is that you don’t have to implement it yourself anymore.

Hardware rotation is still the better option if it’s available, so your post is quite accurate. :+1:

1 Like

Hi,InfotecDehmer,
Many Thanks!
The RGB-controller of stm32 does not support the ratation in hardware. We have to do it in software. Thanks for your example code!

Hi, embeddedt,
Many Thanks!
It’s great to support the rotation in the lib. I am using the V7.7 ,and trying to upgrade to the latest one.

Best Regards,
James

Hi @JamesJJ, i did not mean the LTDC controller in the STM32F7. The Display itself has a RGB-Controller / LCD-Driver embedded which manages the single pixels and related tasks. The controller is the interface between the microcontroller and the display panel.
Down below you see a part of a display datasheet. The used controller is normally mentioned in the datasheet. When you know the controller, you have to search for the datasheet of the controller itself. Most likely you will find it with a google search.

1 Like

Hi,InfotecDehmer,
Many Thanks for your detail!
Yes some TFT support config the scan dirrection. I am using the basic one which have not such setup.
I will try the software rotaiton.

Hi, embeddedt,
I have tried adding lv_disp_set_rotation(NULL, LV_DISP_ROT_90) for runtime rotation. But the display fail. Is there any further configuration? Or if there have some example code about the rotation?

Best Regards,
James

Do you know what controller is used in your TFT? Can you share?

1 Like

Please take a look at the documentation I referenced - in particular ensure that you have disp_drv.sw_rotate = 1 in your driver initialization, otherwise software rotation won’t be used.

1 Like

By the way, you don’t need to swap hor_res and ver_res when using the lv_disp_set_rotation API as this is done automatically.

1 Like

Hi, zapta,
I don’t know the controller of the TFT. Attached the datasheet,FYI.

Hi, embeddedt,
Many Thanks!
I found out I can not use the rotation as I am using the true_double_buf. Is any reason for that case? Can I work around?

I also got an idea that if we could replace the low level driver like gpu_fill_cb for the rotation in runtime instead of rotating in the final VDB? If can, we will save a lot of cpu copy.

Best Regards,
James
AT070TN92-800x480.zip (662.3 KB)

You can try removing the condition, but I am pretty sure 90 and 270 degree rotation will need changes to work with true double buffering, as they assume that the VDB is being flushed to a display, not being used as the final framebuffer.

Unfortunately it’s a lot more complicated to add rotation support to the LVGL core directly, so this was the best compromise I could think of.

2 Likes

Hi, embeddedt,
Many Thanks!
I am trying the software rotation.

For the replacing the low level driver, I remember all the drawing in VDB is through the gpu_fill_cb. So if we mirror the X and Y in that cb, it might do the job . If can not, could you give some example for that case?

Best Regards,
James

gpu_fill_cb is used to accelerate specific parts of drawing; I don’t think it’s used exclusively. I’m pretty sure changing that function alone is just a small piece of the puzzle. :slightly_smiling_face:

@kisvegabor can probably give you some more details on the specific changes that would be required.

1 Like

@JamesJJ, I look at the datasheet and it seems that it gets ‘live’ video stream (R,G,B, Sync, etc) rather than writes commands. So it’s different kind of controller than I thought and rotation at the TFT panel level may not be possible.

2 Likes

gpu_fill_cb is really used only to accelerate drawing when larger areas are filled.

1 Like

Hi,kisvegabor & embeddedt,
Many Thanks!

As the software mapping from horizontal to vertical scan is very MIPS cost , especially for the large size TFT, is there any posibility to open some low layer interface ,just like the set_px_cb but still combining with the GPU, for the mapping when drawing into the VDB in the coming version?

@kisvegabor @embeddedt

Best Reagrds,
James

I think it is unlikely that there will be further improvements made at the renderer level for rotation in the near future, due to the way LVGL handles splitting the rendering (it is assumed that a row of pixels in memory matches a visual row on the screen).

3 Likes

Hi, embeddedt,
Many Thanks!

Agree with you. But there have lots of TFT, like the 5.5", 7", 8" , which are original the vertical scan mode. I just want to support them with the acceptable refreshing speed. I wish your team could consider more about the requirement in the future.

Best Regards,
James