From df71a43db5846fa9dac2079cace4b0fd952058a2 Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Tue, 16 Jun 2026 17:55:55 +0800 Subject: [PATCH] feat(rgb_lcd): support convert rgb2rgb --- .../esp_hal_lcd/esp32p4/include/hal/lcd_ll.h | 42 ++++++- .../esp_hal_lcd/esp32s3/include/hal/lcd_ll.h | 4 +- .../esp_hal_lcd/esp32s31/include/hal/lcd_ll.h | 33 +++++- components/esp_lcd/rgb/esp_lcd_panel_rgb.c | 25 ++++- .../test_apps/rgb_lcd/main/test_rgb_board.h | 52 +++++++++ .../test_apps/rgb_lcd/main/test_rgb_panel.c | 106 ++++++++++++++++-- 6 files changed, 234 insertions(+), 28 deletions(-) diff --git a/components/esp_hal_lcd/esp32p4/include/hal/lcd_ll.h b/components/esp_hal_lcd/esp32p4/include/hal/lcd_ll.h index 1da1188fda0..51a87fbc396 100644 --- a/components/esp_hal_lcd/esp32p4/include/hal/lcd_ll.h +++ b/components/esp_hal_lcd/esp32p4/include/hal/lcd_ll.h @@ -22,6 +22,9 @@ #define LCD_LL_RGB_PANEL_NUM 1 #define LCD_LL_I80_BUS_WIDTH 24 #define LCD_LL_I80_BUS_NUM 1 +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 +#define LCD_LL_SUPPORT_RGB2RGB_CONV 1 +#endif #ifdef __cplusplus extern "C" { @@ -295,14 +298,13 @@ static inline void lcd_ll_enable_color_convert(lcd_cam_dev_t *dev, bool en) } /** - * @brief Set convert data line width + * @brief Set convert input data line width for YUV<->RGB conversion * * @param dev LCD register base address * @param width data line width */ -static inline void lcd_ll_set_convert_data_width(lcd_cam_dev_t *dev, uint32_t width) +static inline void lcd_ll_set_yuv_convert_input_data_width(lcd_cam_dev_t *dev, uint32_t width) { - HAL_ASSERT(width == 8 || width == 16); dev->lcd_rgb_yuv.lcd_conv_mode_8bits_on = (width == 8) ? 1 : 0; } @@ -351,6 +353,28 @@ static inline void lcd_ll_set_yuv_convert_std(lcd_cam_dev_t *dev, lcd_yuv_conv_s } } +#if LCD_LL_SUPPORT(RGB2RGB_CONV) +/** + * @brief Set the converter mode: RGB to RGB + * + * @param dev LCD register base address + * @param in_color_format Input color format + * @param out_color_format Output color format + */ +static inline void lcd_ll_set_rgb2rgb_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) +{ + dev->lcd_rgb_yuv.lcd_conv_trans_mode = 0; + dev->lcd_rgb_yuv.lcd_conv_yuv2yuv_mode = 3; + if (in_color_format == LCD_COLOR_FMT_RGB888 && out_color_format == LCD_COLOR_FMT_RGB565) { + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 0; + } else if (in_color_format == LCD_COLOR_FMT_RGB565 && out_color_format == LCD_COLOR_FMT_RGB888) { + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 1; + } else { + abort(); + } +} +#endif // LCD_LL_SUPPORT(RGB2RGB_CONV) + /** * @brief Set the converter mode: RGB to YUV * @@ -360,6 +384,9 @@ static inline void lcd_ll_set_yuv_convert_std(lcd_cam_dev_t *dev, lcd_yuv_conv_s */ static inline void lcd_ll_set_rgb2yuv_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) { +#if LCD_LL_SUPPORT(RGB2RGB_CONV) + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 2; +#endif dev->lcd_rgb_yuv.lcd_conv_trans_mode = 1; dev->lcd_rgb_yuv.lcd_conv_yuv2yuv_mode = 3; switch (out_color_format) { @@ -383,6 +410,9 @@ static inline void lcd_ll_set_rgb2yuv_convert_mode(lcd_cam_dev_t *dev, lcd_color */ static inline void lcd_ll_set_yuv2rgb_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) { +#if LCD_LL_SUPPORT(RGB2RGB_CONV) + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 2; +#endif dev->lcd_rgb_yuv.lcd_conv_trans_mode = 0; dev->lcd_rgb_yuv.lcd_conv_yuv2yuv_mode = 3; switch (in_color_format) { @@ -406,6 +436,9 @@ static inline void lcd_ll_set_yuv2rgb_convert_mode(lcd_cam_dev_t *dev, lcd_color */ static inline void lcd_ll_set_yuv2yuv_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) { +#if LCD_LL_SUPPORT(RGB2RGB_CONV) + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 2; +#endif dev->lcd_rgb_yuv.lcd_conv_trans_mode = 1; switch (in_color_format) { case LCD_COLOR_FMT_YUV422_UYVY: @@ -489,9 +522,6 @@ static inline void lcd_ll_set_dma_read_stride(lcd_cam_dev_t *dev, uint32_t strid case 24: dev->lcd_user.lcd_byte_mode = 2; break; - case 32: - dev->lcd_user.lcd_byte_mode = 3; - break; default: abort(); } diff --git a/components/esp_hal_lcd/esp32s3/include/hal/lcd_ll.h b/components/esp_hal_lcd/esp32s3/include/hal/lcd_ll.h index ef467bf4076..ed2da85f28d 100644 --- a/components/esp_hal_lcd/esp32s3/include/hal/lcd_ll.h +++ b/components/esp_hal_lcd/esp32s3/include/hal/lcd_ll.h @@ -267,12 +267,12 @@ static inline void lcd_ll_enable_color_convert(lcd_cam_dev_t *dev, bool en) } /** - * @brief Set convert data line width + * @brief Set convert input data line width for YUV<->RGB conversion * * @param dev LCD register base address * @param width data line width (8 or 16) */ -static inline void lcd_ll_set_convert_data_width(lcd_cam_dev_t *dev, uint32_t width) +static inline void lcd_ll_set_yuv_convert_input_data_width(lcd_cam_dev_t *dev, uint32_t width) { HAL_ASSERT(width == 8 || width == 16); dev->lcd_rgb_yuv.lcd_conv_mode_8bits_on = (width == 8) ? 1 : 0; diff --git a/components/esp_hal_lcd/esp32s31/include/hal/lcd_ll.h b/components/esp_hal_lcd/esp32s31/include/hal/lcd_ll.h index 0e11836c3f0..df27fee2ce8 100644 --- a/components/esp_hal_lcd/esp32s31/include/hal/lcd_ll.h +++ b/components/esp_hal_lcd/esp32s31/include/hal/lcd_ll.h @@ -24,6 +24,7 @@ #define LCD_LL_I80_BUS_NUM 1 #define LCD_LL_SUPPORT_IOMUX 1 +#define LCD_LL_SUPPORT_RGB2RGB_CONV 1 #ifdef __cplusplus extern "C" { @@ -333,17 +334,17 @@ static inline void lcd_ll_set_pixel_clock_prescale(lcd_cam_dev_t *dev, uint32_t static inline void lcd_ll_enable_color_convert(lcd_cam_dev_t *dev, bool en) { dev->lcd_rgb_yuv.lcd_conv_enable = en; + dev->lcd_rgb_yuv.lcd_conv_mem_clk_en = !en; } /** - * @brief Set convert data line width + * @brief Set convert input data line width for YUV<->RGB conversion * * @param dev LCD register base address * @param width data line width */ -static inline void lcd_ll_set_convert_data_width(lcd_cam_dev_t *dev, uint32_t width) +static inline void lcd_ll_set_yuv_convert_input_data_width(lcd_cam_dev_t *dev, uint32_t width) { - HAL_ASSERT(width == 8 || width == 16); dev->lcd_rgb_yuv.lcd_conv_mode_8bits_on = (width == 8) ? 1 : 0; } @@ -392,6 +393,26 @@ static inline void lcd_ll_set_yuv_convert_std(lcd_cam_dev_t *dev, lcd_yuv_conv_s } } +/** + * @brief Set the converter mode: RGB to RGB + * + * @param dev LCD register base address + * @param in_color_format Input color format + * @param out_color_format Output color format + */ +static inline void lcd_ll_set_rgb2rgb_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) +{ + dev->lcd_rgb_yuv.lcd_conv_trans_mode = 0; + dev->lcd_rgb_yuv.lcd_conv_yuv2yuv_mode = 3; + if (in_color_format == LCD_COLOR_FMT_RGB888 && out_color_format == LCD_COLOR_FMT_RGB565) { + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 0; + } else if (in_color_format == LCD_COLOR_FMT_RGB565 && out_color_format == LCD_COLOR_FMT_RGB888) { + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 1; + } else { + abort(); + } +} + /** * @brief Set the converter mode: RGB to YUV * @@ -402,6 +423,7 @@ static inline void lcd_ll_set_yuv_convert_std(lcd_cam_dev_t *dev, lcd_yuv_conv_s static inline void lcd_ll_set_rgb2yuv_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) { (void)in_color_format; + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 2; dev->lcd_rgb_yuv.lcd_conv_trans_mode = 1; dev->lcd_rgb_yuv.lcd_conv_yuv2yuv_mode = 3; switch (out_color_format) { @@ -426,6 +448,7 @@ static inline void lcd_ll_set_rgb2yuv_convert_mode(lcd_cam_dev_t *dev, lcd_color static inline void lcd_ll_set_yuv2rgb_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) { (void)out_color_format; + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 2; dev->lcd_rgb_yuv.lcd_conv_trans_mode = 0; dev->lcd_rgb_yuv.lcd_conv_yuv2yuv_mode = 3; switch (in_color_format) { @@ -449,6 +472,7 @@ static inline void lcd_ll_set_yuv2rgb_convert_mode(lcd_cam_dev_t *dev, lcd_color */ static inline void lcd_ll_set_yuv2yuv_convert_mode(lcd_cam_dev_t *dev, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format) { + dev->lcd_rgb_yuv.lcd_conv_rgb2rgb_mode = 2; dev->lcd_rgb_yuv.lcd_conv_trans_mode = 1; switch (in_color_format) { case LCD_COLOR_FMT_YUV422_UYVY: @@ -532,9 +556,6 @@ static inline void lcd_ll_set_dma_read_stride(lcd_cam_dev_t *dev, uint32_t strid case 24: dev->lcd_user.lcd_byte_mode = 2; break; - case 32: - dev->lcd_user.lcd_byte_mode = 3; - break; default: abort(); } diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index ef68a71565a..921abaac074 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -365,6 +365,12 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf ESP_RETURN_ON_FALSE(in_color_format != 0, ESP_ERR_INVALID_ARG, TAG, "cannot determine input color format"); // if out_color_format is not specified, set it the same as in_color_format lcd_color_format_t out_color_format = rgb_panel_config->out_color_format ? rgb_panel_config->out_color_format : in_color_format; + if ((in_color_format == LCD_COLOR_FMT_RGB565 && out_color_format == LCD_COLOR_FMT_RGB888) || + (in_color_format == LCD_COLOR_FMT_RGB888 && out_color_format == LCD_COLOR_FMT_RGB565)) { +#if !LCD_LL_SUPPORT(RGB2RGB_CONV) + ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "RGB to RGB conversion is not supported"); +#endif + } // calculate buffer size size_t fb_bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(in_color_format); @@ -603,8 +609,8 @@ esp_err_t esp_lcd_rgb_panel_set_yuv_conversion(esp_lcd_panel_handle_t panel, con // set color range lcd_ll_set_input_color_range(hal->dev, config->in_color_range); lcd_ll_set_output_color_range(hal->dev, config->out_color_range); - // set conversion data width - lcd_ll_set_convert_data_width(hal->dev, rgb_panel->data_width); + // set conversion input data width + lcd_ll_set_yuv_convert_input_data_width(hal->dev, rgb_panel->data_width); return ESP_OK; } @@ -654,7 +660,22 @@ static esp_err_t rgb_panel_init(esp_lcd_panel_t *panel) lcd_ll_set_pixel_clock_edge(rgb_panel->hal.dev, rgb_panel->timings.flags.pclk_active_neg); // enable RGB mode and set data width lcd_ll_enable_rgb_mode(rgb_panel->hal.dev, true); +#if LCD_LL_SUPPORT(RGB2RGB_CONV) + if ((rgb_panel->in_color_format == LCD_COLOR_FMT_RGB888 && rgb_panel->out_color_format == LCD_COLOR_FMT_RGB565) || \ + (rgb_panel->in_color_format == LCD_COLOR_FMT_RGB565 && rgb_panel->out_color_format == LCD_COLOR_FMT_RGB888)) { + lcd_ll_set_rgb2rgb_convert_mode(rgb_panel->hal.dev, rgb_panel->in_color_format, rgb_panel->out_color_format); + // RGB2RGB converter always uses full color range + lcd_ll_set_input_color_range(rgb_panel->hal.dev, LCD_COLOR_RANGE_FULL); + lcd_ll_set_output_color_range(rgb_panel->hal.dev, LCD_COLOR_RANGE_FULL); + } +#endif + + // ESP32S3 dma stride is equal to the data width +#if CONFIG_IDF_TARGET_ESP32S3 lcd_ll_set_dma_read_stride(rgb_panel->hal.dev, rgb_panel->data_width); +#else + lcd_ll_set_dma_read_stride(rgb_panel->hal.dev, rgb_panel->fb_bits_per_pixel); +#endif // enable conversion if the input color format is different from the output color format lcd_ll_enable_color_convert(rgb_panel->hal.dev, rgb_panel->in_color_format != rgb_panel->out_color_format); // enable data phase only diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_board.h b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_board.h index 38f912895c8..379e6c220a4 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_board.h +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_board.h @@ -68,6 +68,32 @@ extern "C" { #define TEST_LCD_DATA15_GPIO 19 // R4 #define TEST_LCD_DISP_EN_GPIO -1 +// GPIO definitions for 24-bit RGB888 interface (used by RGB565 to RGB888 conversion test) +#define TEST_LCD_24BIT_DATA0_GPIO 34 +#define TEST_LCD_24BIT_DATA1_GPIO 12 +#define TEST_LCD_24BIT_DATA2_GPIO 10 +#define TEST_LCD_24BIT_DATA3_GPIO 40 +#define TEST_LCD_24BIT_DATA4_GPIO 42 +#define TEST_LCD_24BIT_DATA5_GPIO 27 +#define TEST_LCD_24BIT_DATA6_GPIO 29 +#define TEST_LCD_24BIT_DATA7_GPIO 31 +#define TEST_LCD_24BIT_DATA8_GPIO 16 +#define TEST_LCD_24BIT_DATA9_GPIO 14 +#define TEST_LCD_24BIT_DATA10_GPIO 21 +#define TEST_LCD_24BIT_DATA11_GPIO 23 +#define TEST_LCD_24BIT_DATA12_GPIO 26 +#define TEST_LCD_24BIT_DATA13_GPIO 28 +#define TEST_LCD_24BIT_DATA14_GPIO 30 +#define TEST_LCD_24BIT_DATA15_GPIO 32 +#define TEST_LCD_24BIT_DATA16_GPIO 22 +#define TEST_LCD_24BIT_DATA17_GPIO 20 +#define TEST_LCD_24BIT_DATA18_GPIO 18 +#define TEST_LCD_24BIT_DATA19_GPIO 6 +#define TEST_LCD_24BIT_DATA20_GPIO 0 +#define TEST_LCD_24BIT_DATA21_GPIO 15 +#define TEST_LCD_24BIT_DATA22_GPIO 17 +#define TEST_LCD_24BIT_DATA23_GPIO 19 + #elif CONFIG_IDF_TARGET_ESP32S31 #define TEST_LCD_VSYNC_GPIO 45 @@ -92,6 +118,32 @@ extern "C" { #define TEST_LCD_DATA15_GPIO 7 // R7 #define TEST_LCD_DISP_EN_GPIO -1 +// GPIO definitions for 24-bit RGB888 interface (used by RGB565 to RGB888 conversion test) +#define TEST_LCD_24BIT_DATA0_GPIO 8 +#define TEST_LCD_24BIT_DATA1_GPIO 9 +#define TEST_LCD_24BIT_DATA2_GPIO 10 +#define TEST_LCD_24BIT_DATA3_GPIO 11 +#define TEST_LCD_24BIT_DATA4_GPIO 12 +#define TEST_LCD_24BIT_DATA5_GPIO 13 +#define TEST_LCD_24BIT_DATA6_GPIO 14 +#define TEST_LCD_24BIT_DATA7_GPIO 15 +#define TEST_LCD_24BIT_DATA8_GPIO 16 +#define TEST_LCD_24BIT_DATA9_GPIO 17 +#define TEST_LCD_24BIT_DATA10_GPIO 18 +#define TEST_LCD_24BIT_DATA11_GPIO 19 +#define TEST_LCD_24BIT_DATA12_GPIO 33 +#define TEST_LCD_24BIT_DATA13_GPIO 34 +#define TEST_LCD_24BIT_DATA14_GPIO 35 +#define TEST_LCD_24BIT_DATA15_GPIO 36 +#define TEST_LCD_24BIT_DATA16_GPIO 37 +#define TEST_LCD_24BIT_DATA17_GPIO 38 +#define TEST_LCD_24BIT_DATA18_GPIO 39 +#define TEST_LCD_24BIT_DATA19_GPIO 2 +#define TEST_LCD_24BIT_DATA20_GPIO 3 +#define TEST_LCD_24BIT_DATA21_GPIO 4 +#define TEST_LCD_24BIT_DATA22_GPIO 5 +#define TEST_LCD_24BIT_DATA23_GPIO 7 + #else #error "Unsupported target" #endif diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c index 0816b07ee06..40cb6809f5e 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c @@ -13,6 +13,7 @@ #include "esp_lcd_panel_ops.h" #include "esp_timer.h" #include "esp_attr.h" +#include "hal/lcd_ll.h" #include "test_rgb_board.h" #include "esp_private/spi_flash_os.h" #include "esp_clk_tree.h" @@ -25,13 +26,15 @@ #define TEST_IMG_SIZE (100 * 100 * sizeof(uint16_t)) -static esp_lcd_panel_handle_t test_rgb_panel_initialization(size_t data_width, lcd_color_format_t in_color_format, size_t bb_pixels, lcd_clock_source_t clk_src, bool refresh_on_demand, bool user_fb, +static esp_lcd_panel_handle_t test_rgb_panel_initialization(size_t data_width, lcd_color_format_t in_color_format, lcd_color_format_t out_color_format, + size_t bb_pixels, lcd_clock_source_t clk_src, bool refresh_on_demand, bool user_fb, esp_lcd_rgb_panel_vsync_cb_t vsync_cb, void *user_data) { esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_rgb_panel_config_t panel_config = { .data_width = data_width, .in_color_format = in_color_format, + .out_color_format = out_color_format, .dma_burst_size = 64, .bounce_buffer_size_px = bb_pixels, .clk_src = clk_src, @@ -79,6 +82,38 @@ static esp_lcd_panel_handle_t test_rgb_panel_initialization(size_t data_width, l panel_config.user_fbs[0] = frame_buffer; } +#if LCD_LL_SUPPORT(RGB2RGB_CONV) + if (data_width == 24) { + const int data_gpios[24] = { + TEST_LCD_24BIT_DATA0_GPIO, + TEST_LCD_24BIT_DATA1_GPIO, + TEST_LCD_24BIT_DATA2_GPIO, + TEST_LCD_24BIT_DATA3_GPIO, + TEST_LCD_24BIT_DATA4_GPIO, + TEST_LCD_24BIT_DATA5_GPIO, + TEST_LCD_24BIT_DATA6_GPIO, + TEST_LCD_24BIT_DATA7_GPIO, + TEST_LCD_24BIT_DATA8_GPIO, + TEST_LCD_24BIT_DATA9_GPIO, + TEST_LCD_24BIT_DATA10_GPIO, + TEST_LCD_24BIT_DATA11_GPIO, + TEST_LCD_24BIT_DATA12_GPIO, + TEST_LCD_24BIT_DATA13_GPIO, + TEST_LCD_24BIT_DATA14_GPIO, + TEST_LCD_24BIT_DATA15_GPIO, + TEST_LCD_24BIT_DATA16_GPIO, + TEST_LCD_24BIT_DATA17_GPIO, + TEST_LCD_24BIT_DATA18_GPIO, + TEST_LCD_24BIT_DATA19_GPIO, + TEST_LCD_24BIT_DATA20_GPIO, + TEST_LCD_24BIT_DATA21_GPIO, + TEST_LCD_24BIT_DATA22_GPIO, + TEST_LCD_24BIT_DATA23_GPIO, + }; + memcpy(panel_config.data_gpio_nums, data_gpios, sizeof(data_gpios)); + } +#endif + TEST_ESP_OK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle)); esp_lcd_rgb_panel_event_callbacks_t cbs = { @@ -97,7 +132,7 @@ TEST_CASE("lcd_rgb_panel_stream_mode", "[lcd]") TEST_ASSERT_NOT_NULL(img); printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); printf("flush random color block\r\n"); for (int i = 0; i < 200; i++) { uint8_t color_byte = rand() & 0xFF; @@ -119,7 +154,7 @@ TEST_CASE("lcd_rgb_panel_8bit_interface", "[lcd]") printf("initialize RGB panel with stream mode\r\n"); // bpp for RGB888 is 24 - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(8, LCD_COLOR_FMT_RGB888, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(8, LCD_COLOR_FMT_RGB888, LCD_COLOR_FMT_RGB888, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); uint8_t color_byte = rand() & 0xFF; printf("flush random color block 0x%x\r\n", color_byte); int x_start = rand() % (TEST_LCD_H_RES - 100); @@ -132,6 +167,53 @@ TEST_CASE("lcd_rgb_panel_8bit_interface", "[lcd]") free(img); } +#if LCD_LL_SUPPORT(RGB2RGB_CONV) +TEST_CASE("lcd_rgb_panel_rgb2rgb_conversion", "[lcd]") +{ + uint8_t *img = malloc(100 * 100 * 3); + TEST_ASSERT_NOT_NULL(img); + + printf("initialize RGB panel with RGB888 frame buffer and RGB565 output\r\n"); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB888, LCD_COLOR_FMT_RGB565, + 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + printf("flush random color block\r\n"); + for (int i = 0; i < 200; i++) { + uint8_t red = rand() & 0xFF; + uint8_t green = rand() & 0xFF; + uint8_t blue = rand() & 0xFF; + int x_start = rand() % (TEST_LCD_H_RES - 100); + int y_start = rand() % (TEST_LCD_V_RES - 100); + for (int j = 0; j < 100 * 100; j++) { + img[j * 3 + 0] = blue; + img[j * 3 + 1] = green; + img[j * 3 + 2] = red; + } + esp_lcd_panel_draw_bitmap(panel_handle, x_start, y_start, x_start + 100, y_start + 100, img); + vTaskDelay(pdMS_TO_TICKS(10)); + } + printf("delete RGB panel\r\n"); + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + + vTaskDelay(pdMS_TO_TICKS(500)); + + printf("initialize RGB panel with RGB565 frame buffer and RGB888 output\r\n"); + panel_handle = test_rgb_panel_initialization(24, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB888, + 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + printf("flush random color block\r\n"); + for (int i = 0; i < 200; i++) { + uint8_t color_byte = rand() & 0xFF; + int x_start = rand() % (TEST_LCD_H_RES - 100); + int y_start = rand() % (TEST_LCD_V_RES - 100); + memset(img, color_byte, TEST_IMG_SIZE); + esp_lcd_panel_draw_bitmap(panel_handle, x_start, y_start, x_start + 100, y_start + 100, img); + vTaskDelay(pdMS_TO_TICKS(10)); + } + printf("delete RGB panel\r\n"); + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + free(img); +} +#endif + TEST_LCD_CALLBACK_ATTR static bool test_rgb_panel_trans_done(esp_lcd_panel_handle_t panel, const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx) { TaskHandle_t task_to_notify = (TaskHandle_t)user_ctx; @@ -147,7 +229,7 @@ TEST_CASE("lcd_rgb_panel_refresh_on_demand", "[lcd]") TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); printf("initialize RGB panel with non-stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, true, false, test_rgb_panel_trans_done, cur_task); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, true, false, test_rgb_panel_trans_done, cur_task); printf("flush random color block\r\n"); for (int i = 0; i < 200; i++) { uint8_t color_byte = rand() & 0xFF; @@ -172,7 +254,7 @@ TEST_CASE("lcd_rgb_panel_bounce_buffer", "[lcd]") TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); printf("initialize RGB panel with non-stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 20 * TEST_LCD_H_RES, LCD_CLK_SRC_DEFAULT, false, false, test_rgb_panel_trans_done, cur_task); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 20 * TEST_LCD_H_RES, LCD_CLK_SRC_DEFAULT, false, false, test_rgb_panel_trans_done, cur_task); printf("flush random color block\r\n"); for (int i = 0; i < 200; i++) { uint8_t color_byte = rand() & 0xFF; @@ -195,7 +277,7 @@ TEST_CASE("lcd_rgb_panel_update_pclk", "[lcd]") TEST_ASSERT_NOT_NULL(img); printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); printf("flush one clock block to the LCD\r\n"); uint8_t color_byte = rand() & 0xFF; int x_start = rand() % (TEST_LCD_H_RES - 100); @@ -224,7 +306,7 @@ TEST_CASE("lcd_rgb_panel_restart", "[lcd]") TEST_ASSERT_NOT_NULL(img); printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); printf("flush one clock block to the LCD\r\n"); uint8_t color_byte = rand() & 0xFF; int x_start = rand() % (TEST_LCD_H_RES - 100); @@ -243,7 +325,7 @@ TEST_CASE("lcd_rgb_panel_restart", "[lcd]") free(img); #else printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); TEST_ASSERT_EQUAL(ESP_ERR_NOT_SUPPORTED, esp_lcd_rgb_panel_restart(panel_handle)); TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); #endif @@ -260,7 +342,7 @@ TEST_CASE("lcd_rgb_panel_rotate", "[lcd]") memset(img, color_byte, w * h * sizeof(uint16_t)); printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL); printf("Update the rotation of panel\r\n"); for (size_t i = 0; i < 8; i++) { @@ -285,7 +367,7 @@ TEST_CASE("lcd_rgb_panel_user_frame_buffer", "[lcd]") TEST_ASSERT_NOT_NULL(img); printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, true, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, true, NULL, NULL); printf("flush one clock block to the LCD\r\n"); uint8_t color_byte = rand() & 0xFF; @@ -319,7 +401,7 @@ TEST_CASE("lcd_rgb_panel_use_apll", "[lcd]") printf("APLL frequency: %"PRIu32" Hz\r\n", real_freq); printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_APLL, false, false, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_APLL, false, false, NULL, NULL); printf("flush random color block\r\n"); for (int i = 0; i < 200; i++) { uint8_t color_byte = rand() & 0xFF; @@ -360,7 +442,7 @@ TEST_CASE("lcd_rgb_panel_iram_safe", "[lcd]") uint32_t callback_calls = 0; printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, test_rgb_panel_count_in_callback, &callback_calls); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, test_rgb_panel_count_in_callback, &callback_calls); printf("flush one clock block to the LCD\r\n"); uint8_t color_byte = rand() & 0xFF; int x_start = rand() % (TEST_LCD_H_RES - 100);