diff --git a/build/configs/rtl8730e/loadable_ext_ddr/defconfig b/build/configs/rtl8730e/loadable_ext_ddr/defconfig index 59ebbfb011..09c25e91e0 100644 --- a/build/configs/rtl8730e/loadable_ext_ddr/defconfig +++ b/build/configs/rtl8730e/loadable_ext_ddr/defconfig @@ -594,6 +594,7 @@ CONFIG_LCD_ST7701SN=y # CONFIG_LCD_ST7789 is not set CONFIG_LCD_XRES=480 CONFIG_LCD_YRES=800 +CONFIG_LCD_LOGO_52_340=y CONFIG_LCD_LANDSCAPE=y # CONFIG_LCD_PORTRAIT is not set # CONFIG_LCD_RPORTRAIT is not set diff --git a/os/drivers/lcd/Kconfig b/os/drivers/lcd/Kconfig index 1c74ddfdc1..95fd1e09a3 100644 --- a/os/drivers/lcd/Kconfig +++ b/os/drivers/lcd/Kconfig @@ -156,6 +156,20 @@ config LCD_YRES ---help--- Specifies the Y resolution of the LCD. +if LCD_ST7701SN +choice + prompt "LCD Bootup LOGO" + default LCD_LOGO_52_340 + ---help--- + Select the bootup logo to show on the LCD. + +config LCD_LOGO_52_340 + bool "Logo 52x340" + ---help--- + LCD logo with resolution 52x340. +endchoice +endif + if LCD_ST7789 config LCD_ST7789_BPP int "Bit Per Pixel (12 or 16)" diff --git a/os/drivers/lcd/Make.defs b/os/drivers/lcd/Make.defs index d10b0b5c2c..4fe988e0dd 100644 --- a/os/drivers/lcd/Make.defs +++ b/os/drivers/lcd/Make.defs @@ -115,6 +115,10 @@ ifeq ($(CONFIG_LCD_ST7701SN),y) CSRCS += mipi_lcd.c endif +ifeq ($(CONFIG_LCD_LOGO_52_340),y) +CSRCS += lcd_logo_52_340.c +endif + endif # CONFIG_LCD ifeq ($(CONFIG_LCD),y) diff --git a/os/drivers/lcd/lcd_dev.c b/os/drivers/lcd/lcd_dev.c index e87e60ca75..e2a7d90bb5 100644 --- a/os/drivers/lcd/lcd_dev.c +++ b/os/drivers/lcd/lcd_dev.c @@ -427,6 +427,8 @@ int lcddev_register(struct lcd_dev_s *dev) } lcdvdbg("lcd flushing thread %d created \n", pid); #endif + + lcd_put_logo(dev); sem_init(&lcd_info->sem, 0, 1); if (lcd_info->dev->getplaneinfo) { lcd_info->dev->getplaneinfo(lcd_info->dev, 0, &lcd_info->planeinfo); //plane no is taken 0 here diff --git a/os/drivers/lcd/lcd_logo.h b/os/drivers/lcd/lcd_logo.h new file mode 100644 index 0000000000..7c09d1f52b --- /dev/null +++ b/os/drivers/lcd/lcd_logo.h @@ -0,0 +1,31 @@ +/**************************************************************************** + * + * Copyright 2024 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#ifndef __DRIVER_LCD_LOGO_H +#define __DRIVER_LCD_LOGO_H + +#include + +#define LCD_BLACK_VAL 0 +#ifdef CONFIG_LCD_LOGO_52_340 +#define LOGO_XRES 52 +#define LOGO_YRES 340 +#endif /* CONFIG_LCD_LOGO_52_340 */ + +#endif /* __DRIVER_LCD_LOGO_H */ + diff --git a/os/drivers/lcd/lcd_logo_52_340.c b/os/drivers/lcd/lcd_logo_52_340.c new file mode 100644 index 0000000000..0b481bba80 --- /dev/null +++ b/os/drivers/lcd/lcd_logo_52_340.c @@ -0,0 +1,27 @@ +/**************************************************************************** + * + * Copyright 2024 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include "lcd_logo.h" + +// Contains desired LOGO pixels +const uint8_t lcd_logo_raw_data[LOGO_XRES * LOGO_YRES * 2] = {LCD_BLACK_VAL, }; + diff --git a/os/drivers/lcd/mipi_lcd.c b/os/drivers/lcd/mipi_lcd.c index 76887e9050..e156087b40 100644 --- a/os/drivers/lcd/mipi_lcd.c +++ b/os/drivers/lcd/mipi_lcd.c @@ -28,6 +28,7 @@ #endif #include #include +#include "lcd_logo.h" #include #include @@ -38,11 +39,13 @@ #define CONFIG_LCD_MAXPOWER 100 #endif +extern const uint8_t lcd_logo_raw_data[]; // Buffer containing only logo +static uint8_t *lcd_logo_fullscreen_data = NULL; // Buffer containing full screen data with logo on specific position + #if defined(CONFIG_LCD_SW_ROTATION) #define NUM_OF_LCD_BUFFER 2 static uint8_t *lcd_buffer[NUM_OF_LCD_BUFFER] = { NULL, NULL }; //Two lcd buffers to avoid screen tearing static int lcd_buffer_index = 0; - static void lcd_rotate_buffer(short int* src, short int* dst) { int row; @@ -236,6 +239,10 @@ static int lcd_putarea(FAR struct lcd_dev_s *dev, fb_coord_t row_start, fb_coord priv->config->lcd_put_area((u8 *)lcd_buffer[lcd_buffer_index], row_start, col_start, row_end, col_end); lcd_buffer_index = (1 - lcd_buffer_index); #else + if (lcd_logo_fullscreen_data != NULL) { + kmm_free(lcd_logo_fullscreen_data); + lcd_logo_fullscreen_data = NULL; + } priv->config->lcd_put_area((u8 *)buffer, row_start, col_start, row_end, col_end); #endif return OK; @@ -399,6 +406,50 @@ static int lcd_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast) return OK; } +FAR void lcd_put_logo(FAR struct lcd_dev_s *dev) +{ + int logo_arr_index = 0; + int lcd_data_index = CONFIG_LCD_XRES * (CONFIG_LCD_YRES - LOGO_YRES) + (CONFIG_LCD_XRES - LOGO_XRES); + int lcd_data_col_count = 0; + FAR struct mipi_lcd_dev_s *priv = (FAR struct mipi_lcd_dev_s *)dev; + + /* Memory optimization applied using Rotation buffer + * If rotation is enabled, then we have two buffers allocated for rotation. + * During bootup, rotation buffer will not be used (No putarea call from application) + * Therefore, the rotation buffer can be safely used for storing logo data. + * + * If rotation is disabled, then we need to allocate memory for full screen data + * and it will allocate memory to lcd_logo_fullscreen_data buffer. + * + * If rotation is enabled, then lcd_logo_fullscreen_data contains pointer of rotation buffer */ +#if defined(CONFIG_LCD_SW_ROTATION) + lcd_logo_fullscreen_data = lcd_buffer[lcd_buffer_index]; + lcd_buffer_index = (1 - lcd_buffer_index); +#else + lcd_logo_fullscreen_data = (uint8_t *)kmm_malloc(CONFIG_LCD_XRES * CONFIG_LCD_YRES * 2 + 1); + if (!lcd_logo_fullscreen_data) { + lcddbg("ERROR: LCD logo data memory allocation failed\n"); + return; + } +#endif + /* Filling buffer with black color using memset and + * then filling it with logo data on specific index in while loop */ + memset(lcd_logo_fullscreen_data, LCD_BLACK_VAL, CONFIG_LCD_XRES * CONFIG_LCD_YRES * 2); + + while (logo_arr_index < (LOGO_YRES * LOGO_XRES * 2)) { + lcd_logo_fullscreen_data[lcd_data_index] = lcd_logo_raw_data[logo_arr_index++]; + lcd_logo_fullscreen_data[lcd_data_index + 1] = lcd_logo_raw_data[logo_arr_index++]; + lcd_data_index += 2; + lcd_data_col_count += 1; + if (lcd_data_col_count == LOGO_XRES) { + lcd_data_index += ((CONFIG_LCD_XRES - LOGO_XRES) * 2); + lcd_data_col_count = 0; + } + } + + priv->config->lcd_put_area((u8 *)lcd_logo_fullscreen_data, 1, 1, CONFIG_LCD_XRES, CONFIG_LCD_YRES); // 1, 1 -> Start index of the frame buffer +} + FAR struct lcd_dev_s *mipi_lcdinitialize(FAR struct mipi_dsi_device *dsi, struct mipi_lcd_config_s *config) { FAR struct mipi_lcd_dev_s *priv = &g_lcdcdev;