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 ?
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
}
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?
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.
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.
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?
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.
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.
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.
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?
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.
@kisvegabor can probably give you some more details on the specific changes that would be required.
@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.
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?
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).
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.