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:
parent
5ed3a064c1
commit
4d12d64e4e
@ -886,6 +886,9 @@
|
||||
|
||||
#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 */
|
||||
#define LV_USE_WINDOWS 0
|
||||
|
||||
|
4
Kconfig
4
Kconfig
@ -1625,6 +1625,10 @@ menu "LVGL configuration"
|
||||
bool "Generic MIPI driver"
|
||||
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
|
||||
bool "Use LVGL Windows backend"
|
||||
default n
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _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.
|
||||
|
||||
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
|
||||
----------------
|
||||
|
||||
@ -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.
|
||||
|
||||
JLink is used for debugging, it can be downloaded [here](https://www.segger.com/downloads/jlink/)
|
||||
|
||||
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
|
||||
- 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
|
||||
git clone https://github.com/lvgl/lv_renesas.git --recurse-submodules
|
||||
- First, clone the ready-to-use `lv_port_renesas_ek-ra8d1 <https://github.com/lvgl/lv_port_renesas_ek-ra8d1.git>`__ repository:
|
||||
|
||||
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.
|
||||
|
||||
@ -61,7 +96,7 @@ Modify the project
|
||||
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.
|
||||
|
||||
@ -81,4 +116,4 @@ Configuration
|
||||
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.
|
||||
|
@ -12,3 +12,4 @@ Display
|
||||
st7735
|
||||
st7789
|
||||
st7796
|
||||
renesas_glcdc
|
||||
|
58
docs/integration/driver/display/renesas_glcdc.rst
Normal file
58
docs/integration/driver/display/renesas_glcdc.rst
Normal 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);
|
BIN
docs/misc/renesas/generate.png
Normal file
BIN
docs/misc/renesas/generate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
BIN
docs/misc/renesas/glcdc.png
Normal file
BIN
docs/misc/renesas/glcdc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
BIN
docs/misc/renesas/import.png
Normal file
BIN
docs/misc/renesas/import.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
@ -103,6 +103,7 @@ remove the misleading guide above this code segment.
|
||||
|
||||
- LV_USE_ILI9341
|
||||
|
||||
- LV_USE_RENESAS_GLCDC
|
||||
|
||||
|
||||
5. Update `LV_LOG_PRINTF` to `1` and `LV_LOG_LEVEL` to `LV_LOG_LEVEL_USER`
|
||||
|
@ -967,6 +967,9 @@
|
||||
|
||||
#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 */
|
||||
#define LV_USE_WINDOWS 0
|
||||
|
||||
|
192
src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c
Normal file
192
src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c
Normal 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*/
|
57
src/drivers/display/renesas_glcdc/lv_renesas_glcdc.h
Normal file
57
src/drivers/display/renesas_glcdc/lv_renesas_glcdc.h
Normal 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 */
|
@ -3156,6 +3156,15 @@
|
||||
#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 */
|
||||
#ifndef LV_USE_WINDOWS
|
||||
#ifdef CONFIG_LV_USE_WINDOWS
|
||||
|
Loading…
x
Reference in New Issue
Block a user