Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

st7701 RGB+SPI display rotation support (AEGHB-721) #380

Closed
3 tasks done
raoulh opened this issue Jul 3, 2024 · 1 comment
Closed
3 tasks done

st7701 RGB+SPI display rotation support (AEGHB-721) #380

raoulh opened this issue Jul 3, 2024 · 1 comment

Comments

@raoulh
Copy link

raoulh commented Jul 3, 2024

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

General issue report

Hi,

I have a project using an esp32-s3 and a connected display that uses RGB+3 wire SPI. The LCD is a quad 480x480 pixels screen. I'm configuring the display using esp_lcd_st7701, esp_lcd and lvgl_port. It works good and I have a nice LVGL9 UI that runs at 60FPS using direct mode and no tearing.

I configured the display as such:

esp_lcd_rgb_panel_config_t rgb_panel_config =
    {
        .data_width = 16, // RGB565 in parallel mode, thus 16bit in width
        .bits_per_pixel = 16,
        .psram_trans_align = 64,
        .clk_src = LCD_CLK_SRC_PLL160M,
        .disp_gpio_num = GPIO_NUM_NC,
        .pclk_gpio_num = GPIO_LCD_PCLK,
        .vsync_gpio_num = GPIO_LCD_VSYNC,
        .hsync_gpio_num = GPIO_LCD_HSYNC,
        .de_gpio_num = GPIO_LCD_DE,
        .data_gpio_nums =
        {
            GPIO_LCD_B0, GPIO_LCD_B1, GPIO_LCD_B2, GPIO_LCD_B3, GPIO_LCD_B4,         
            GPIO_LCD_G0, GPIO_LCD_G1, GPIO_LCD_G2, GPIO_LCD_G3, GPIO_LCD_G4, GPIO_LCD_G5,
            GPIO_LCD_R0, GPIO_LCD_R1, GPIO_LCD_R2, GPIO_LCD_R3, GPIO_LCD_R4,
        },
        .timings =
        {
            .pclk_hz = 10 * 1000 * 1000,
            .h_res = LCD_WIDTH,
            .v_res = LCD_HEIGHT,
            // The following parameters should refer to LCD spec
            .hsync_back_porch = 44,
            .hsync_front_porch = 50,
            .hsync_pulse_width = 2,
            .vsync_back_porch = 18,
            .vsync_front_porch = 16,
            .vsync_pulse_width = 2,
            .flags.pclk_active_neg = 0, // RGB data is clocked out on falling edge
        },
        .num_fbs = 2,
        .flags.fb_in_psram = 1, // allocate frame buffer in PSRAM
        .bounce_buffer_size_px = LCD_WIDTH * 10,
    };

    st7701_vendor_config_t vendor_config =
    {
        .rgb_config = &rgb_panel_config,
        .init_cmds = square480_lcd, // LCD custom initialization commands
        .init_cmds_size = sizeof(square480_lcd) / sizeof(st7701_lcd_init_cmd_t),
        .flags =
        {
            .auto_del_panel_io = 0,         /**
                                             * Set to 1 if panel IO is no longer needed after LCD initialization.
                                             * If the panel IO pins are sharing other pins of the RGB interface to save GPIOs,
                                             * Please set it to 1 to release the pins.
                                             */
            .mirror_by_cmd = 1,             // Set to 1 if mirror is implemented by LCD command
        },
    };

    const esp_lcd_panel_dev_config_t panel_config =
    {
        .reset_gpio_num = -1,                           // Set to -1 if not use
        .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,     // Implemented by LCD command `36h`
        .bits_per_pixel = 16,                           // Implemented by LCD command `3Ah` (16/18/24)
        .vendor_config = &vendor_config,
    };

    ESP_ERROR_CHECK(esp_lcd_new_panel_st7701(io_handle, &panel_config, &panel_handle));

    ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
    ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));

    // Init LVGL after display initialization

    lvgl_port_display_cfg_t disp_cfg =
    {
        .io_handle = io_handle,
        .panel_handle = panel_handle,
        .double_buffer = true,
        .hres = LCD_WIDTH,
        .vres = LCD_HEIGHT,
        .monochrome = false,
        .color_format = LV_COLOR_FORMAT_RGB565,
        /* Rotation values must be same as used in esp_lcd for initial settings of the screen */
        .rotation =
        {
            .swap_xy = false,
            .mirror_x = false,
            .mirror_y = false,
        },
        .flags =
        {
            .buff_dma = true,
            .buff_spiram = false,
            .full_refresh = false,
            .direct_mode = true,
            .swap_bytes = false,
        }
    };

    const lvgl_port_display_rgb_cfg_t rgb_cfg =
    {
        .flags =
        {
            .bb_mode = true,
            .avoid_tearing = true,
        }
    };

    const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
    ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "Failed to initialize LVGL port");

I want now to be able to rotate the screen dynamically using:

lv_display_set_rotation(display, rotation);

From my understanding esp_lvgl_port will handle the screen rotation here:
https://github.com/espressif/esp-bsp/blob/master/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c#L442

by calling esp_lcd_panel_swap_xy and esp_lcd_panel_mirror accordingly to the requested rotation.
I have set .mirror_by_cmd = 1 in st7701_vendor_config_t so it means mirroring is handled by the ST7701 chip directly using SPI commands. This works.

The issue I have is that only mirroring is happening but swapping x/y is not done using my actual configuration and thus rotation 90 and 270 are not working as expected. Only rotation to 180 is Ok because there is no swapping involved.

How to make rotation work correctly (and fast). I also tried to use esp_lcd_rgb software rotation by disabling direct_mode and avoid_tearing but it's slow and contains tearing effects. When I rotate to 90 I get 2-3 FPS only. This is not a solution.

Could you tell me what are ma solution to have a good and working rotation solution for the ST7701 with esp_lcd APIs?

@github-actions github-actions bot changed the title st7701 RGB+SPI display rotation support st7701 RGB+SPI display rotation support (AEGHB-721) Jul 3, 2024
@Lzw655
Copy link
Contributor

Lzw655 commented Jul 4, 2024

Hi @raoulh,

Most RGB LCDs can't rotate the screen by sending a command like SPI or I80 LCDs. The ESP32-S3 can rotate the screen only through software, but this will lower the FPS. Unfortunately, there's no good solution yet for the screen rotation on ESP32-S3.

@raoulh raoulh closed this as completed Jul 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants