V8 display driver rotation problem

Description

V8 display driver rotation problem

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

Renesas Synergy S7 (32 Bit Arm Core @ 240 MHz) / GNU Arm Cross Compiler
TFT LCD with 640 x 480 Pixel and 16 Bit color (RGB 565)
external SDRAM with 16 Bit Bus Interface @ 120 MHz speed

What do you want to achieve?

Display Rotation by 90 Degrees from Landscape (horizontal) to Portrait Mode (vertical)
because we want to create an handheld device.

What have you tried so far?

First i implemented a double buffer approach because the Synergy S7 microcontroller has
an built in LCD driver peripheral and can drive up to 1024 x 1024 pixels. In the Flush Callback
routine i only have to swap the pointers and do some synchronisation stuff with the vertical frame
of the display. I run the example program lv_example_get_started_1 wich just shows a button and increments a label when pressed and all worked pretty well.

But when i want to rotate to 90 degrees the problems arise:

First no change in display was shown, i realize after some search in the forum that i have to implement
the 1 buffer method with an internal small draw buffer. After i implemented this the following hapened:

  • no rotation (horizontal / landscpae mode):
    some strange permanent artefacts show up after pressing the button
    (it looks like a very thin rectangle around the button, remains of the button press animation ?)

  • 90 degree rotation (vertical / potrait mode):
    the label starts already corrupted + artefacts and no label after pressing the button

Any ideas on how to handle this? Thanks!

Code to reproduce

Initialisation

#define LCD_WIDTH       640
#define LCD_HEIGHT      480


#define DRAW_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT / 5)
static lv_color_t          draw_buf[DRAW_BUF_SIZE];

.
.
.
.

lv_init();                                                        		// Initialize LVGL Library

lv_disp_draw_buf_init(&disp_buf,
					  draw_buf,
					  NULL,
					  DRAW_BUF_SIZE);                                   // Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2

lv_disp_drv_init(&disp_driver);                                         // Basic initialization
disp_driver.draw_buf = &disp_buf;                                       // Set an initialized buffer
disp_driver.flush_cb = DisplayFlushCallback;                            // Set a flush callback to draw to the display
disp_driver.hor_res = (lv_coord_t) g_display.p_cfg->input[0].hsize;     // Set the horizontal resolution in pixels
disp_driver.ver_res = (lv_coord_t) g_display.p_cfg->input[0].vsize;     // Set the vertical resolution in pixels


//    disp_driver.sw_rotate = 1;											// testing the rotation	
//    disp_driver.rotated = LV_DISP_ROT_90;						

lv_disp_drv_register(&disp_driver);                                   	// Register the driver in LVGL and save the created display objects


lv_indev_drv_init(&indev_driver);                                       // Basic initialization
indev_driver.type = LV_INDEV_TYPE_POINTER;                              // Type pointer
indev_driver.read_cb = DisplayInputReadCallback;                        // Set a input read callback
lv_indev_drv_register(&indev_driver);                                   // Register the driver in LVGL and save the created input device object

lv_example_get_started_1();

while (1)
{
	lv_timer_handler();
 
	tx_thread_sleep (1);												// sleep for max. 1 tick (10 ms)
}

Flush Calback


static void DisplayFlushCallback(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    uint32_t w = lv_area_get_width(area);
    uint32_t y;
  
    for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++)
    {
        lv_memcpy(&g_display_fb_background[0][y * LCD_WIDTH * 2 + area->x1], color_p, w * sizeof(lv_color_t));
        color_p += w;
    }

    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

The frambuffer g_display_fb_background is defined as a 2 dimensional Array because its generated
by the Synergy configuration tool, but i only use the first buffer with index 0.

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

no rotation (button not pressed yet)

no rotation (after button press)

90 degree rotation (button not pressed yet)

90 degree rotation (after button press)