diff --git a/docs/conf.py b/docs/conf.py index 952d54441..5df4e3cdf 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -41,6 +41,7 @@ extensions = [ 'breathe', 'sphinx_sitemap', 'lv_example', + 'sphinx_design', 'sphinx_rtd_dark_mode', 'link_roles', 'sphinxcontrib.mermaid' diff --git a/docs/integration/chip/renesas.rst b/docs/integration/chip/renesas.rst index fb15d3059..b1263671a 100644 --- a/docs/integration/chip/renesas.rst +++ b/docs/integration/chip/renesas.rst @@ -29,66 +29,160 @@ It is able to drive LCD panles via a higly configurable RGB interface. More info can be found at the :ref:`dirver's page`. -Certified boards +Supported boards ---------------- -LVGL has `certified `__ one Renesas board so far (more will come soon). +.. list-table:: + :widths: 10 30 30 30 -.. raw:: html + * - + - **EK-RA8D1** + - **EK-RA6M3G** + - **RX72N Envision Kit** + * - CPU + - 480MHz, Arm Cortex-M85 core + - 120MHz, Arm Cortex-M4 core + - 240MHz, Renesas RXv3 core + * - Memory + - + | 1MB internal, 64MB external SDRAM + | 2MB internal, 64MB External Octo-SPI Flash + - + | 640kB internal SRAM + | 2MB internal, 32MB external QSPI Flash + - + | 1MB internal SRAM + | 4MB internal, 32MB external QSPI Flash + * - Display + - + | 4.5” + | 480x854 + | 2-lane MIPI + - + | 4.3” + | 480x272 + | Parallel RGB565 + - + | 4.3” + | 480x272 + | Parallel RGB565 + * - `Certification `__ video + - .. raw:: html - + + + - Coming soon + - Coming soon + * - Links + - `Demo repository for EK-RA8D1 `__ + - `Demo repository for EK-RA6M3G `__ + - `Demo repository for RX72N Envision Kit `__ Get started with the Renesas ecosystem -------------------------------------- -The official IDE of Renesas is called `e² studio `__. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well. +.. |img_debug_btn| image:: /misc/renesas/debug_btn.png + :alt: Debug button -To get started, just download and install e² studio. +.. dropdown:: RA Family -JLink is used for debugging, it can be downloaded [here](https://www.segger.com/downloads/jlink/) + - The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well. The RA family requires the latest version with FSP 5.3. It can be downloaded `here `__. -Getting started with LVGL -------------------------- + - JLink is used for debugging, it can be downloaded `here `__. -LVGL provides a ready-to-use project for the `EK-RA8D1 `__ development board. Its main features from the HMI's point of view are: -- 480MHz, Arm Cortex®-M85 core -- 2MB Code Flash, 1MB SRAM -- MIPI DSI & Parallel Graphics Expansion Ports -- 4.5 Inch backlit TFT display, 16.7M display colors -- 480x854 pixels resolution + - Clone the ready-to-use repository for your selected board: -**Setting up the project** + .. code-block:: shell -- First, clone the ready-to-use `lv_port_renesas_ek-ra8d1 `__ repository: + git clone https://github.com/lvgl/lv_port_renesas_ek-ra8d1.git --recurse-submodules - .. code-block:: shell + Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules. - 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`` -- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Exsisting projects into workspace`` + - Browse the cloned folder and press ``Finish``. - .. 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`. -- 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"*. - 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. - Press ``Generate Project Content`` in the top right corner. + .. image:: /misc/renesas/generate.png + :alt: Code generation with FSP - .. image:: /misc/renesas/generate.png - :alt: Code generation with FSP + - Build the project by pressing ``Ctrl`` + ``Alt`` + ``B`` -- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B`` + - Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``J-Link ARM`` as `Debug hardware` and the proper IC as `Target Device`: -- Click the Debug button. When prompted select the `J-Link ARM` Debugger and the `R7FA8D1BH` MCU. + - ``R7FA8D1BH`` for EK-RA8D1 -Note that on the ``SW1`` DIP switch (middle of the board) 7 should be ON, all others are OFF. + .. image:: /misc/renesas/debug_ra8.png + :alt: Debugger parameters for RA8 + + - ``R7FA6M3AH`` for EK-RA6M3G + + .. image:: /misc/renesas/debug_ra6.png + :alt: Debugger parameters for RA6 + + .. note:: + On EK-RA8D1 boards, the ``SW1`` DIP switch (middle of the board) 7 should be ON, all others are OFF. + +.. dropdown:: RX Family + + - The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well. It can be downloaded `here `__. + + - Download and install the required driver for the debugger + + - for Windows: `64 bit here `__ and `32 bit here `__ + - for Linux: `here `__ + + - RX72 requires an external compiler for the RXv3 core. A free and open-source version is available `here `__ after a registration. + + The compiler must be activated in e² studio: + + - Go to go to ``Help`` -> ``Add Renesas Toolchains`` + - Presss the ``Add... `` button + - Browse the installation folder of the toolchain + + | + + .. image:: /misc/renesas/toolchains.png + :alt: Toolchains + + - Clone the ready-to-use `lv_port_renesas_rx72n-envision-kit `__ repository: + + .. code-block:: shell + + git clone https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit.git --recurse-submodules + + Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules. + + - Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Exsisting projects into workspace`` + + - Select the cloned folder and press ``Finish``. + + - Double click on ``RX72N_EnVision_LVGL.scfg``. This will activate the `Configuration Window`. + + Renesas' Smart Configurator (SMC) 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 the application. + + Press ``Generate Code`` in the top right corner. + + .. image:: /misc/renesas/generate_smc.png + :alt: Code generation with SMC + + - Build the project by pressing ``Ctrl`` + ``Alt`` + ``B`` + + - Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``E2 Lite`` as `Debug hardware` and ``R5F572NN`` as `Target Device`: + + .. image:: /misc/renesas/debug_rx72.png + :alt: Debugger parameters for RX72 + + .. note:: + Make sure that both channels of ``SW1`` DIP switch (next to ``ECN1``) are OFF. Modify the project ------------------ @@ -96,24 +190,24 @@ Modify the project Open a demo ~~~~~~~~~~~ -In `LVGL_thread_entry `__, the demos are automatically enabled based on the settings in `lv_conf.h `__. +The entry point of the main task is contained in ``src/LVGL_thread_entry.c`` in all 3 projects. -You can disable all demos (or just comment them out) and call some ``lv_example_...()`` functions, or add your custom code. +You can disable the LVGL demos (or just comment them out) and call some ``lv_example_...()`` functions, or add your custom code. Configuration ~~~~~~~~~~~~~ -``lv_conf.h`` contains the most important settings for LVGL. Namely: +``src/lv_conf.h`` contains the most important settings for LVGL. Namely: - ``LV_COLOR_DEPTH`` to set LVGL's default color depth - ``LV_MEM_SIZE to`` set the maximum RAM available for LVGL - ``LV_USE_DAVE2D`` to enable the GPU -``configuration.xml`` contains the settings for the board and the MCU. By opening this file, all the hardware and software components can be customized in a visual way. +Hardware and software components can be modified in a visual way using the `Configuration Window`. Support ------- -In case of an problems or questions open an issue in the `lv_port_renesas_ek-ra8d1 `__ repository. +In case of any problems or questions open an issue in the corresponding repository. diff --git a/docs/integration/driver/display/renesas_glcdc.rst b/docs/integration/driver/display/renesas_glcdc.rst index 6f082a1f4..b7340f1a0 100644 --- a/docs/integration/driver/display/renesas_glcdc.rst +++ b/docs/integration/driver/display/renesas_glcdc.rst @@ -25,14 +25,17 @@ It is designed to automatically generate timing and data signals for different L - 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 `. -| Check out the `EK-RA8D1 example repository `__ for a ready-to-use example. +| Setting up a project and further integration with Renesas' ecosystem is described in detail on :ref:`page Renesas `. +| Check out the following repositories for ready-to-use examples: +- `EK-RA8D1 `__ +- `EK-RA6M3G `__ +- `RX72N Envision Kit `__ 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"*. +- This diver relies on code generated by e² studio. Missing the step while setting up the project will cause a compilation error. +- Activate the diver by setting :c:macro:`LV_USE_RENESAS_GLCDC` to ``1`` in your *"lv_conf.h"*. Usage ----- diff --git a/docs/misc/renesas/debug_btn.png b/docs/misc/renesas/debug_btn.png new file mode 100644 index 000000000..951e16c54 Binary files /dev/null and b/docs/misc/renesas/debug_btn.png differ diff --git a/docs/misc/renesas/debug_ra6.png b/docs/misc/renesas/debug_ra6.png new file mode 100644 index 000000000..890d69ca5 Binary files /dev/null and b/docs/misc/renesas/debug_ra6.png differ diff --git a/docs/misc/renesas/debug_ra8.png b/docs/misc/renesas/debug_ra8.png new file mode 100644 index 000000000..e2a8a8e9b Binary files /dev/null and b/docs/misc/renesas/debug_ra8.png differ diff --git a/docs/misc/renesas/debug_rx72.png b/docs/misc/renesas/debug_rx72.png new file mode 100644 index 000000000..6a2f2b6b3 Binary files /dev/null and b/docs/misc/renesas/debug_rx72.png differ diff --git a/docs/misc/renesas/generate_smc.png b/docs/misc/renesas/generate_smc.png new file mode 100644 index 000000000..b69c20efe Binary files /dev/null and b/docs/misc/renesas/generate_smc.png differ diff --git a/docs/misc/renesas/import.png b/docs/misc/renesas/import.png deleted file mode 100644 index 5364b2eb0..000000000 Binary files a/docs/misc/renesas/import.png and /dev/null differ diff --git a/docs/misc/renesas/toolchains.png b/docs/misc/renesas/toolchains.png new file mode 100644 index 000000000..ffcc5cffe Binary files /dev/null and b/docs/misc/renesas/toolchains.png differ diff --git a/docs/requirements.txt b/docs/requirements.txt index 58d5d08c0..27054d90d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,5 +11,6 @@ sphinxcontrib-jsmath sphinxcontrib-qthelp sphinxcontrib-serializinghtml sphinxcontrib-mermaid +sphinx-design sphinx-rtd-dark-mode typing-extensions diff --git a/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c b/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c index 3874cfc7d..342286a1d 100644 --- a/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c +++ b/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c @@ -3,6 +3,21 @@ * */ +/********************* + *PLATFORM ABSTRACTION + *********************/ + +#ifdef _RENESAS_RA_ + #define USE_FREE_RTOS (BSP_CFG_RTOS == 2) +#else // RX with SMC code generation + #ifndef _RENESAS_RX_ + #define _RENESAS_RX_ 1 + #endif + #define USE_FREE_RTOS 1 + #define DISPLAY_HSIZE_INPUT0 LCD_CH0_IN_GR2_HSIZE + #define DISPLAY_VSIZE_INPUT0 LCD_CH0_IN_GR2_VSIZE +#endif /*_RENESAS_RA_*/ + /********************* * INCLUDES *********************/ @@ -10,13 +25,22 @@ #if LV_USE_RENESAS_GLCDC -#include "LVGL_thread.h" +#ifdef _RENESAS_RA_ + #include "LVGL_thread.h" +#else /* RX */ + #include "hal_data.h" + #include "platform.h" + #include "r_glcdc_rx_if.h" + #include "r_glcdc_rx_pinset.h" +#endif /*_RENESAS_RA_*/ + #include #include "../../../display/lv_display_private.h" /********************* * DEFINES *********************/ +#define BYTES_PER_PIXEL 2 /********************** * TYPEDEFS @@ -25,16 +49,33 @@ /********************** * STATIC PROTOTYPES **********************/ +static lv_display_t * glcdc_create(void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode); static void glcdc_init(void); +static void give_vsync_sem_and_yield(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); +#ifdef _RENESAS_RX_ + static void enable_dave2d_drw_interrupt(void); +#endif /*_RENESAS_RX_*/ + /********************** * STATIC VARIABLES **********************/ +#ifdef _RENESAS_RX_ +static uint8_t fb_background[2][LCD_CH0_IN_GR2_HSIZE * LCD_CH0_IN_GR2_VSIZE * BYTES_PER_PIXEL]__attribute__(( + section(".framebuffer"), aligned(64), used)); +static SemaphoreHandle_t _SemaphoreVsync = NULL; +static glcdc_cfg_t g_config; +static glcdc_runtime_cfg_t g_layer_change; + +/* A global variable that Dave 2D driver relies on. (Being auto generated on RA platforms)*/ +display_t g_display0_cfg; +#endif /*_RENESAS_RX_*/ + /********************** * MACROS **********************/ @@ -45,43 +86,21 @@ static void flush_wait_partial(lv_display_t * display); 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; + return glcdc_create(&fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0]), + LV_DISPLAY_RENDER_MODE_DIRECT); } 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; + return glcdc_create(buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL); } /*This function is declared in and being used by FSP generated code modules*/ +#ifdef _RENESAS_RA_ 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 + give_vsync_sem_and_yield(); } else if(DISPLAY_EVENT_GR1_UNDERFLOW == p_args->event) { __BKPT(0); /*Layer 1 Underrun*/ @@ -92,18 +111,80 @@ void glcdc_callback(display_callback_args_t * p_args) else { /*DISPLAY_EVENT_FRAME_END*/ __BKPT(0); } - } +#else /* RX */ +void glcdc_callback(glcdc_callback_args_t * p_args) +{ + if(GLCDC_EVENT_LINE_DETECTION == p_args->event) { + give_vsync_sem_and_yield(); + } + else if(GLCDC_EVENT_GR1_UNDERFLOW == p_args->event) { + while(1); /*Layer 1 Underrun*/ + } + else if(GLCDC_EVENT_GR2_UNDERFLOW == p_args->event) { + while(1); /*Layer 2 Underrun*/ + } + else {/*DISPLAY_EVENT_FRAME_END*/ + while(1); + } +} +#endif /*_RENESAS_RA_*/ /********************** * STATIC FUNCTIONS **********************/ +static lv_display_t * glcdc_create(void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode) +{ +#ifdef _RENESAS_RA_ + glcdc_init(); +#else + g_display0_cfg.input->format = LCD_CH0_IN_GR2_FORMAT; + _SemaphoreVsync = xSemaphoreCreateBinary(); + + glcdc_init(); + enable_dave2d_drw_interrupt(); +#endif /*_RENESAS_RA_*/ + + lv_display_t * display = lv_display_create(DISPLAY_HSIZE_INPUT0, DISPLAY_VSIZE_INPUT0); + + if(render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) { + lv_display_set_flush_cb(display, flush_direct); + lv_display_set_flush_wait_cb(display, flush_wait_direct); + } + else if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { + lv_display_set_flush_cb(display, flush_partial); + lv_display_set_flush_wait_cb(display, flush_wait_partial); + } + else { + LV_ASSERT(0); + } + + lv_display_set_buffers(display, buf1, buf2, buf_size, render_mode); + + return display; +} + +static void give_vsync_sem_and_yield(void) +{ +#if USE_FREE_RTOS + 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 /*USE_FREE_RTOS*/ +} + 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)); +#ifdef _RENESAS_RA_ /* Initalize GLCDC driver */ uint8_t * p_fb = &fb_background[1][0]; fsp_err_t err; @@ -124,6 +205,32 @@ static void glcdc_init(void) (uint8_t *) p_fb, (display_frame_layer_t) 0); } while(FSP_ERR_INVALID_UPDATE_TIMING == err); +#else /* RX */ + glcdc_err_t err; + glcdc_runtime_cfg_t layer_change; + + R_GLCDC_PinSet(); + + err = R_GLCDC_Open(&g_config); + if(GLCDC_SUCCESS != err) { + while(1); + } + + err = R_GLCDC_Control(GLCDC_CMD_START_DISPLAY, &g_config); + if(GLCDC_SUCCESS != err) { + while(1); + } + + g_layer_change.input = g_config.input[GLCDC_FRAME_LAYER_2]; + g_layer_change.chromakey = g_config.chromakey[GLCDC_FRAME_LAYER_2]; + g_layer_change.blend = g_config.blend[GLCDC_FRAME_LAYER_2]; + + layer_change.input.p_base = (uint32_t *)&fb_background[1][0]; + + do { + err = R_GLCDC_LayerChange(GLCDC_FRAME_LAYER_2, &g_layer_change); + } while(GLCDC_ERR_INVALID_UPDATE_TIMING == err); +#endif /*_RENESAS_RA_*/ } static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) @@ -138,23 +245,33 @@ static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t SCB_CleanInvalidateDCache_by_Addr(px_map, sizeof(fb_background[0])); #endif +#ifdef _RENESAS_RA_ R_GLCDC_BufferChange(&g_display0_ctrl, (uint8_t *) px_map, (display_frame_layer_t) 0); +#else /* RX */ + glcdc_err_t err; + + g_layer_change.input.p_base = (uint32_t *)px_map; + + do { + err = R_GLCDC_LayerChange(GLCDC_FRAME_LAYER_2, &g_layer_change); + } while(GLCDC_ERR_INVALID_UPDATE_TIMING == err); +#endif /*_RENESAS_RA_*/ } static void flush_wait_direct(lv_display_t * display) { if(!lv_display_flush_is_last(display)) return; -#if BSP_CFG_RTOS == 2 /*FreeRTOS*/ +#if USE_FREE_RTOS /*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 +#endif /*USE_FREE_RTOS*/ } @@ -173,9 +290,10 @@ static void flush_partial(lv_display_t * display, const lv_area_t * area, uint8_ int32_t i; for(i = 0; i < h; i++) { - lv_memcpy(fb, img, w * 2); + lv_memcpy(fb, img, w * BYTES_PER_PIXEL); + #if defined(RENESAS_CORTEX_M85) && (BSP_CFG_DCACHE_ENABLED) - SCB_CleanInvalidateDCache_by_Addr(fb, w * 2); + SCB_CleanInvalidateDCache_by_Addr(fb, w * BYTES_PER_PIXEL); #endif fb += DISPLAY_HSIZE_INPUT0; img += w; @@ -189,4 +307,22 @@ static void flush_wait_partial(lv_display_t * display) return; } +#ifdef _RENESAS_RX_ +extern void drw_int_isr(void); + +static void enable_dave2d_drw_interrupt(void) +{ + bsp_int_ctrl_t grpal1; + + /* Specify the priority of the group interrupt. */ + grpal1.ipl = 5; + + /* Use the BSP API to register the interrupt handler for DRW2D. */ + R_BSP_InterruptWrite(BSP_INT_SRC_AL1_DRW2D_DRW_IRQ, (bsp_int_cb_t)drw_int_isr); + + /* Use the BSP API to enable the group interrupt. */ + R_BSP_InterruptControl(BSP_INT_SRC_AL1_DRW2D_DRW_IRQ, BSP_INT_CMD_GROUP_INTERRUPT_ENABLE, (void *)&grpal1); +} +#endif /*_RENESAS_RX_*/ + #endif /*LV_USE_RENESAS_GLCDC*/