1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(drivers): Renesas GLCDC display dirver

This commit is contained in:
Akos Becsey 2024-05-13 22:05:01 +02:00 committed by Gabor Kiss-Vamosi
parent 5ed3a064c1
commit 4d12d64e4e
13 changed files with 369 additions and 6 deletions

View File

@ -886,6 +886,9 @@
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) #define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
/*Driver for Renesas GLCD*/
#define LV_USE_RENESAS_GLCDC 0
/* LVGL Windows backend */ /* LVGL Windows backend */
#define LV_USE_WINDOWS 0 #define LV_USE_WINDOWS 0

View File

@ -1625,6 +1625,10 @@ menu "LVGL configuration"
bool "Generic MIPI driver" bool "Generic MIPI driver"
default y if LV_USE_ST7735 || LV_USE_ST7789 || LV_USE_ST7796 || LV_USE_ILI9341 default y if LV_USE_ST7735 || LV_USE_ST7789 || LV_USE_ST7796 || LV_USE_ILI9341
config LV_USE_RENESAS_GLCDC
bool "Use Renesas GLCDC driver"
default n
config LV_USE_WINDOWS config LV_USE_WINDOWS
bool "Use LVGL Windows backend" bool "Use LVGL Windows backend"
default n default n

View File

@ -1,3 +1,5 @@
.. _renesas:
======= =======
Renesas Renesas
======= =======
@ -19,6 +21,14 @@ Dave2D is capable of accelerating most of the drawing operations of LVGL:
As Dave2D works in the background, the CPU is free for other tasks. In practice, during rendering, Dave2D can reduce the CPU usage by half or to one-third, depending on the application. As Dave2D works in the background, the CPU is free for other tasks. In practice, during rendering, Dave2D can reduce the CPU usage by half or to one-third, depending on the application.
GLCDC
-----
GLCDC is a multi-stage graphics output peripheral available in several Renesas MCUs.
It is able to drive LCD panles via a higly configurable RGB interface.
More info can be found at the :ref:`dirver's page<renesas_glcdc>`.
Certified boards Certified boards
---------------- ----------------
@ -35,6 +45,8 @@ The official IDE of Renesas is called `e² studio <https://www.renesas.com/us/en
To get started, just download and install e² studio. To get started, just download and install e² studio.
JLink is used for debugging, it can be downloaded [here](https://www.segger.com/downloads/jlink/)
Getting started with LVGL Getting started with LVGL
------------------------- -------------------------
@ -46,12 +58,35 @@ LVGL provides a ready-to-use project for the `EK-RA8D1 <https://www.renesas.com/
- 4.5 Inch backlit TFT display, 16.7M display colors - 4.5 Inch backlit TFT display, 16.7M display colors
- 480x854 pixels resolution - 480x854 pixels resolution
To get a ready-to-use project, clone the `lv_renesas <https://github.com/lvgl/lv_renesas.git>`__ repository: **Setting up the project**
.. code:: shell - First, clone the ready-to-use `lv_port_renesas_ek-ra8d1 <https://github.com/lvgl/lv_port_renesas_ek-ra8d1.git>`__ repository:
git clone https://github.com/lvgl/lv_renesas.git --recurse-submodules
After that, *Import* ``lv_ek_ra8d1`` into e² studio, build the project, and flash it. .. code-block:: shell
git clone https://github.com/lvgl/lv_port_renesas_ek-ra8d1.git --recurse-submodules
- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Exsisting projects into workspace``
.. image:: /misc/renesas/import.png
:alt: Importing the project
- Browse the cloned folder and press ``Finish``
- Double click on ``configuration.xml``. This will activate the configuration window.
Renesas' Flexible Software Package (FSP) incudes BSP and HAL layer support extended with multiple RTOS variants and other middleware stacks.
The components will be available via code generation, incuding the entry point of *"main.c"*.
Press ``Generate Project Content`` in the top right corner.
.. image:: /misc/renesas/generate.png
:alt: Code generation with FSP
- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B``
- Click the Debug button. When prompted select the `J-Link ARM` Debugger and the `R7FA8D1BH` MCU.
Note that on the ``SW1`` DIP switch (middle of the board) 7 should be ON, all others are OFF. Note that on the ``SW1`` DIP switch (middle of the board) 7 should be ON, all others are OFF.
@ -61,7 +96,7 @@ Modify the project
Open a demo Open a demo
~~~~~~~~~~~ ~~~~~~~~~~~
In `LVGL_thread_entry <https://github.com/lvgl/lv_renesas/blob/master/lv_ek_ra8d1/src/LVGL_thread_entry.c>`__, the demos are automatically enabled based on the settings in `lv_conf.h <https://github.com/lvgl/lv_renesas/blob/master/lv_ek_ra8d1/src/lv_conf.h>`__. In `LVGL_thread_entry <https://github.com/lvgl/lv_port_renesas_ek-ra8d1/blob/master/src/LVGL_thread_entry.c>`__, the demos are automatically enabled based on the settings in `lv_conf.h <https://github.com/lvgl/lv_port_renesas_ek-ra8d1/blob/master/src/lv_conf.h>`__.
You can disable all demos (or just comment them out) and call some ``lv_example_...()`` functions, or add your custom code. You can disable all demos (or just comment them out) and call some ``lv_example_...()`` functions, or add your custom code.
@ -81,4 +116,4 @@ Configuration
Support Support
------- -------
In case of an problems or questions open an issue in the `lv_renesas <https://github.com/lvgl/lv_renesas/issues>`__ repository. In case of an problems or questions open an issue in the `lv_port_renesas_ek-ra8d1 <https://github.com/lvgl/lv_port_renesas_ek-ra8d1/issues>`__ repository.

View File

@ -12,3 +12,4 @@ Display
st7735 st7735
st7789 st7789
st7796 st7796
renesas_glcdc

View File

@ -0,0 +1,58 @@
.. _renesas_glcdc:
=============
Renesas GLCDC
=============
Overview
--------
.. image:: /misc/renesas/glcdc.png
:alt: Architectural overview of Renesas GLCDC
:align: center
|
GLCDC is a multi-stage graphics output peripheral used in Renesas MCUs.
It is designed to automatically generate timing and data signals for different LCD panels.
- Supports LCD panels with RGB interface (up to 24 bits) and sync signals (HSYNC, VSYNC and Data Enable optional)
- Supports various color formats for input graphics planes (RGB888, ARGB8888, RGB565, ARGB1555, ARGB4444, CLUT8, CLUT4, CLUT1)
- Supports the Color Look-Up Table (CLUT) usage for input graphics planes (ARGB8888) with 512 words (32 bits/word)
- Supports various color formats for output (RGB888, RGB666, RGB565, Serial RGB888)
- Can input two graphics planes on top of the background plane and blend them on the screen
- Generates a dot clock to the panel. The clock source is selectable from internal or external (LCD_EXTCLK)
- Supports brightness adjustment, contrast adjustment, and gamma correction
- Supports GLCDC interrupts to handle frame-buffer switching or underflow detection
| Setting up a project and further integration with Renesas' ecosystem is described in detail on :ref:`page Renesas <renesas>`.
| Check out the `EK-RA8D1 example repository <https://github.com/lvgl/lv_port_renesas_ek-ra8d1>`__ for a ready-to-use example.
Prerequisites
-------------
- This diver relies on FSP generated code. Missing the step while setting up the project will cause a compilation error.
- Activate the diver by setting :c:macro:`LV_USE_DRAW_PXP` to ``1`` in your *"lv_conf.h"*.
Usage
-----
There is no need to implement any platform-specific functions.
The following code demonstrates using the diver in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` mode.
.. code:: c
lv_display_t * disp = lv_renesas_glcdc_direct_create();
lv_display_set_default(disp);
To use the driver in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` mode, an extra buffer must be allocated,
desireably in the fastest available memory region.
Buffer swapping can be activated by passing a second buffer of same size insted of the :cpp:expr:`NULL` argument.
.. code:: c
static lv_color_t partial_draw_buf[DISPLAY_HSIZE_INPUT0 * DISPLAY_VSIZE_INPUT0 / 10] BSP_PLACE_IN_SECTION(".sdram") BSP_ALIGN_VARIABLE(1024);
lv_display_t * disp = lv_renesas_glcdc_partial_create(partial_draw_buf, NULL, sizeof(partial_draw_buf));
lv_display_set_default(disp);

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
docs/misc/renesas/glcdc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -103,6 +103,7 @@ remove the misleading guide above this code segment.
- LV_USE_ILI9341 - LV_USE_ILI9341
- LV_USE_RENESAS_GLCDC
5. Update `LV_LOG_PRINTF` to `1` and `LV_LOG_LEVEL` to `LV_LOG_LEVEL_USER` 5. Update `LV_LOG_PRINTF` to `1` and `LV_LOG_LEVEL` to `LV_LOG_LEVEL_USER`

View File

@ -967,6 +967,9 @@
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) #define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
/*Driver for Renesas GLCD*/
#define LV_USE_RENESAS_GLCDC 0
/* LVGL Windows backend */ /* LVGL Windows backend */
#define LV_USE_WINDOWS 0 #define LV_USE_WINDOWS 0

View File

@ -0,0 +1,192 @@
/**
* @file lv_renesas_glcdc.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_renesas_glcdc.h"
#if LV_USE_RENESAS_GLCDC
#include "LVGL_thread.h"
#include <stdbool.h>
#include "../../../display/lv_display_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void glcdc_init(void);
static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
static void flush_partial(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
static void flush_wait_direct(lv_display_t * display);
static void flush_wait_partial(lv_display_t * display);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_display_t * lv_renesas_glcdc_direct_create(void)
{
glcdc_init();
lv_display_t * display = lv_display_create(DISPLAY_HSIZE_INPUT0, DISPLAY_VSIZE_INPUT0);
lv_display_set_flush_cb(display, flush_direct);
lv_display_set_flush_wait_cb(display, flush_wait_direct);
lv_display_set_buffers(display, &fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0]),
LV_DISPLAY_RENDER_MODE_DIRECT);
return display;
}
lv_display_t * lv_renesas_glcdc_partial_create(void * buf1, void * buf2, size_t buf_size)
{
glcdc_init();
lv_display_t * display = lv_display_create(DISPLAY_HSIZE_INPUT0, DISPLAY_VSIZE_INPUT0);
lv_display_set_flush_cb(display, flush_partial);
lv_display_set_flush_wait_cb(display, flush_wait_partial);
lv_display_set_buffers(display, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
return display;
}
/*This function is declared in and being used by FSP generated code modules*/
void glcdc_callback(display_callback_args_t * p_args)
{
if(DISPLAY_EVENT_LINE_DETECTION == p_args->event) {
#if BSP_CFG_RTOS == 2 /*FreeRTOS*/
BaseType_t context_switch;
/*Set Vsync semaphore*/
xSemaphoreGiveFromISR(_SemaphoreVsync, &context_switch);
/*Return to the highest priority available task*/
portYIELD_FROM_ISR(context_switch);
#else
#endif
}
else if(DISPLAY_EVENT_GR1_UNDERFLOW == p_args->event) {
__BKPT(0); /*Layer 1 Underrun*/
}
else if(DISPLAY_EVENT_GR2_UNDERFLOW == p_args->event) {
__BKPT(0); /*Layer 2 Underrun*/
}
else { /*DISPLAY_EVENT_FRAME_END*/
__BKPT(0);
}
}
/**********************
* STATIC FUNCTIONS
**********************/
static void glcdc_init(void)
{
/* Fill the Frame buffer with black colour (0x0000 in RGB565), for a clean start after previous runs */
lv_memzero(fb_background, sizeof(fb_background));
/* Initalize GLCDC driver */
uint8_t * p_fb = &fb_background[1][0];
fsp_err_t err;
err = R_GLCDC_Open(&g_display0_ctrl, &g_display0_cfg);
if(FSP_SUCCESS != err) {
__BKPT(0);
}
err = R_GLCDC_Start(&g_display0_ctrl);
if(FSP_SUCCESS != err) {
__BKPT(0);
}
do {
err =
R_GLCDC_BufferChange(&g_display0_ctrl,
(uint8_t *) p_fb,
(display_frame_layer_t) 0);
} while(FSP_ERR_INVALID_UPDATE_TIMING == err);
}
static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t * px_map)
{
FSP_PARAMETER_NOT_USED(area);
/*Display the frame buffer pointed by px_map*/
if(!lv_display_flush_is_last(display)) return;
#if defined(RENESAS_CORTEX_M85) && (BSP_CFG_DCACHE_ENABLED)
/* Invalidate cache - so the HW can access any data written by the CPU */
SCB_CleanInvalidateDCache_by_Addr(px_map, sizeof(fb_background[0]));
#endif
R_GLCDC_BufferChange(&g_display0_ctrl,
(uint8_t *) px_map,
(display_frame_layer_t) 0);
}
static void flush_wait_direct(lv_display_t * display)
{
if(!lv_display_flush_is_last(display)) return;
#if BSP_CFG_RTOS == 2 /*FreeRTOS*/
/*If Vsync semaphore has already been set, clear it then wait to avoid tearing*/
if(uxSemaphoreGetCount(_SemaphoreVsync)) {
xSemaphoreTake(_SemaphoreVsync, 10);
}
xSemaphoreTake(_SemaphoreVsync, portMAX_DELAY);
#endif
}
static void flush_partial(lv_display_t * display, const lv_area_t * area, uint8_t * px_map)
{
LV_UNUSED(display);
int32_t w = lv_area_get_width(area);
int32_t h = lv_area_get_height(area);
uint16_t * fb = (uint16_t *)fb_background[1];
uint16_t * img = (uint16_t *)px_map;
fb = fb + area->y1 * DISPLAY_HSIZE_INPUT0;
fb = fb + area->x1;
int32_t i;
for(i = 0; i < h; i++) {
lv_memcpy(fb, img, w * 2);
#if defined(RENESAS_CORTEX_M85) && (BSP_CFG_DCACHE_ENABLED)
SCB_CleanInvalidateDCache_by_Addr(fb, w * 2);
#endif
fb += DISPLAY_HSIZE_INPUT0;
img += w;
}
}
static void flush_wait_partial(lv_display_t * display)
{
LV_UNUSED(display);
return;
}
#endif /*LV_USE_RENESAS_GLCDC*/

View File

@ -0,0 +1,57 @@
/**
* @file lv_renesas_glcdc.h
*
*/
#ifndef LV_RENESAS_GLCDC_H
#define LV_RENESAS_GLCDC_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../../display/lv_display.h"
#if LV_USE_RENESAS_GLCDC
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a display using Renesas' GLCDC peripherial in DIRECT render mode
* @return pointer to the created display
*/
lv_display_t * lv_renesas_glcdc_direct_create(void);
/**
* Create a display using Renesas' GLCDC peripherial in PARTIAL render mode
* @param buf1 first buffer
* @param buf2 second buffer (can be `NULL`)
* @param buf_size buffer size in byte
* @return pointer to the created display
*/
lv_display_t * lv_renesas_glcdc_partial_create(void * buf1, void * buf2, size_t buf_size);
/**********************
* MACROS
**********************/
#endif /* LV_USE_RENESAS_GLCDC */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV_RENESAS_GLCDC_H */

View File

@ -3156,6 +3156,15 @@
#endif #endif
#endif #endif
/*Driver for Renesas GLCD*/
#ifndef LV_USE_RENESAS_GLCDC
#ifdef CONFIG_LV_USE_RENESAS_GLCDC
#define LV_USE_RENESAS_GLCDC CONFIG_LV_USE_RENESAS_GLCDC
#else
#define LV_USE_RENESAS_GLCDC 0
#endif
#endif
/* LVGL Windows backend */ /* LVGL Windows backend */
#ifndef LV_USE_WINDOWS #ifndef LV_USE_WINDOWS
#ifdef CONFIG_LV_USE_WINDOWS #ifdef CONFIG_LV_USE_WINDOWS