这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【瑞萨RA8D1LVGL/LWIP评测】基于mdk移植LVGL

共1条 1/1 1 跳转至

【瑞萨RA8D1LVGL/LWIP评测】基于mdk移植LVGL

高工
2026-01-19 17:31:48     打赏

【目标】

瑞萨RA8D1 LVGL移植,基于mdk的环境搭建。

【开发环境】

win11

【硬件】

1、CPKCOR-RA8D1B核心板

2、拓展板(CPKEXP-EKRA8X1)

【开发工具】

1、keil+fsp

2、vscode+fsp

【移植LVGL】

1、首先准备一个基于ra8d1的led工程。

2、rasc提供了lvgl的组件,打开rasc后,在stack中添加lvgl

image.png

3、打开bsp,开启sdram,将堆栈空间加大:

image.png

4、开启LCD时钟,时钟为240MHz

image.png

【配置LVGL】

1、关闭RTOS

image.png

2、修改自定义参数:

image.png

image.png

image.png

3、新建MIPI Display

image.png

然后修改LIN为1

image.png

生成工程,使用mdk打开工程。

【自定义代码添加】

1、添加dsi_layer.c/h

#include "r_ioport.h"
#include "r_mipi_dsi_api.h"

#include "hal_data.h"
#include "dsi_layer.h"

void mipi_dsi0_callback(mipi_dsi_callback_args_t * p_args);
static fsp_err_t dsi_layer_set_peripheral_max_return_msg_size(void);

static volatile bool g_message_sent = false;
void mipi_dsi_push_table (const LCD_setting_table *table);

fsp_err_t dsi_layer_configure_peripheral()
{
    fsp_err_t err = FSP_SUCCESS;
    LCD_setting_table * init_table = lcd_init_focuslcd;

    err = dsi_layer_set_peripheral_max_return_msg_size(); // This must be performed prior to reading from display
    if (FSP_SUCCESS == err)
    {

        LCD_setting_table * p_entry = init_table;
        uint32_t counter = 0;
        while(p_entry->msg_id != MIPI_DSI_DISPLAY_CONFIG_DATA_END_OF_TABLE)
        {
            mipi_dsi_cmd_t msg = { .channel = 0,
                                   .cmd_id = p_entry->msg_id,
                                   .flags = p_entry->flags,
                                   .tx_len = p_entry->size,
                                   .p_tx_buffer = p_entry->buffer };


            if (p_entry->msg_id == MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG)
            {
                R_BSP_SoftwareDelay(p_entry->size, BSP_DELAY_UNITS_MILLISECONDS);
            }
            else
            {

                g_message_sent = false;
                err = R_MIPI_DSI_Command (&g_mipi_dsi0_ctrl, &msg);
                if (FSP_SUCCESS == err)
                {

                    while(!g_message_sent);

                    mipi_dsi_status_t status;
                    R_MIPI_DSI_StatusGet(&g_mipi_dsi0_ctrl, &status);
                    while (MIPI_DSI_LINK_STATUS_CH0_RUNNING & status.link_status)
                    {
                        R_MIPI_DSI_StatusGet(&g_mipi_dsi0_ctrl, &status);
                    }
                }
                else
                {
                    break;
                }

            }
            p_entry++;
            counter++;
        }
    }

    return err;
}


void mipi_dsi0_callback (mipi_dsi_callback_args_t * p_args)
{
    fsp_err_t err;
    switch (p_args->event)
    {
        case MIPI_DSI_EVENT_SEQUENCE_0:
        {
//            g_message_sent |= (p_args->tx_status == MIPI_DSI_SEQUENCE_STATUS_DESCRIPTORS_FINISHED);
            if (MIPI_DSI_SEQUENCE_STATUS_DESCRIPTORS_FINISHED == p_args->tx_status)
            {
                g_message_sent = 1U;
            }
            break;
        }
        case MIPI_DSI_EVENT_SEQUENCE_1:
        {
            __NOP();
            break;
        }
        case MIPI_DSI_EVENT_VIDEO:
        {
            __NOP();
            break;
        }
        case MIPI_DSI_EVENT_RECEIVE:
        {
            __NOP();
            break;
        }
        case MIPI_DSI_EVENT_FATAL:
        {
            __NOP();
            break;
        }
        case MIPI_DSI_EVENT_PHY:
        {
            __NOP();
            break;
        }
        case MIPI_DSI_EVENT_POST_OPEN:
        {
            /* This case is called from R_DSI_Open(), so not from an interrupt */

            err = dsi_layer_configure_peripheral();
              if (FSP_SUCCESS != err)
              {
                  __BKPT(0);
              }
            break;
        }
        default:
        {
            break;
        }
    }
}

/* See ILI9806E Datasheet, chapter  3.5.39
 *  1. Set max return packet size
 *  2. Read data be sending appropriate request */
static fsp_err_t  dsi_layer_set_peripheral_max_return_msg_size()
{
    fsp_err_t err;
    uint8_t msg_buffer[] = {0x02, 0x00};
    mipi_dsi_cmd_t return_size_msg = { .channel = 0,
                                       .cmd_id = MIPI_CMD_ID_SET_MAXIMUM_RETURN_PACKET_SIZE,
                                       .flags = MIPI_DSI_CMD_FLAG_LOW_POWER,
                                       .tx_len = 2,
                                       .p_tx_buffer = msg_buffer, };
    /* Set Return packet size */
    g_message_sent = false;
    err = R_MIPI_DSI_Command (&g_mipi_dsi0_ctrl, &return_size_msg);
    if (FSP_SUCCESS == err)
    {
    while(!g_message_sent);
    }

    return err;
}
#pragma once

#include "r_mipi_dsi.h"


typedef struct {
    unsigned char size;
    unsigned char buffer[15];
    mipi_dsi_cmd_id_t  msg_id;
    mipi_dsi_cmd_flag_t flags;
} LCD_setting_table;


extern const mipi_dsi_cfg_t g_mipi_dsi1_cfg;
extern mipi_dsi_instance_ctrl_t  g_mipi_dsi0_ctrl;
extern LCD_setting_table lcd_init_focuslcd[];

fsp_err_t dsi_layer_configure_peripheral(void);


#define MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG      ((mipi_dsi_cmd_id_t) 0xFE)
#define MIPI_DSI_DISPLAY_CONFIG_DATA_END_OF_TABLE    ((mipi_dsi_cmd_id_t) 0xFD)

2、添加board_init.h/c

#include "board_init.h"

#include "lvgl.h"
#include "common_data.h"



#if LV_USE_DRAW_DAVE2D
#define DIRECT_MODE 1
#else
#define DIRECT_MODE 0
#endif



void board_init(void)
{
    /* Need to initialise the Touch Controller before the LCD, as only a Single Reset line shared between them */
    //touch_init();

#if DIRECT_MODE
    fsp_err_t err;
    err = RM_LVGL_PORT_Open(&g_lvgl_port_ctrl, &g_lvgl_port_cfg);
    if (FSP_SUCCESS != err)
    {
        __BKPT(0);
    }
#else
    static uint8_t partial_draw_buf[64*1024] BSP_PLACE_IN_SECTION(".dtcm_bss") BSP_ALIGN_VARIABLE(1024);

    lv_display_t * disp = lv_renesas_glcdc_partial_create(partial_draw_buf, NULL, sizeof(partial_draw_buf));
#endif

#if DIRECT_MODE
    lv_display_set_default(g_lvgl_port_ctrl.p_lv_display);
#else
    lv_display_set_default(disp);
#endif


}

#pragma once

void board_init(void);

3、添加lcd配置文件dsi_configuration_data.c

#include "dsi_layer.h"

/* This table of commands was adapted from sample code provided by FocusLCD
 * Page Link: https://focuslcds.com/product/4-5-tft-display-capacitive-tp-e45ra-mw276-c/
 * File Link: https://focuslcds.com/content/E45RA-MW276-C_init_code.txt
 */
LCD_setting_table lcd_init_focuslcd[] =
{

         {2,     {0x11, 0x00},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},

         {2,     {0xF0, 0xC3},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xF0, 0x96},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0x36, 0x48},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0x3A, 0x55},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xB4, 0x01},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},

         //0xB5, VFP=2,VBP=6, HBP=48
//          {5,     {0xB5, 0x02,0x06,0x00,0x30},                           MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},

         {4,     {0xB6, 0x8A, 0x07, 0x3B},   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
//          {9,     {0xB6, 0x8A, 0x8A, 0x00,0x00,0x29,0x19,0xA5,0x33},   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xB7, 0xC6},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {3,     {0xB9, 0x02,0xE0},                           MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {3,     {0xC0, 0xC0,0x64},                           MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xC1, 0x1D},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xC2, 0xA7},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xC5, 0x18},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {9,     {0xE8, 0x40, 0x8A, 0x00,0x00,0x29,0x19,0xA5,0x33},/*0x25,0x0A,0x38,0x33},*//*0x29,0x19,0xA5,0x33},*/   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
         //0xE0, positive gamma 控制
         {15,    {0xE0, 0xF0, 0x0B, 0x12,0x09,0x0A,0x26,0x39,0x54,0x4E,0x38,0x13,0x13,0x2E,0x34},   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
         //0xE1, negative gamma 控制
         {15,    {0xE1, 0xF0, 0x10, 0x15,0x0D,0x0C,0x07,0x38,0x43,0x4D,0x3A,0x16,0x15,0x30,0x35},   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xF0, 0x3C},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0xF0, 0x69},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0x35, 0x00},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
//          {1,     {0x29},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
//          {1,     {0x21},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {2,     {0x29, 0x00},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},

         {2,     {0x21, 0x00},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},

         {5,     {0x2A, 0x00, 0x31, 0x01,0x0E},   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {5,     {0x2B, 0x00, 0x00, 0x01,0xDF},   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
//          {5,     {0x2B, 0x00, 0x02, 0x01,0xE1},   MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},

         {2,     {0x2C, 0x00},                           MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
         {0x00,  {0},                                    MIPI_DSI_DISPLAY_CONFIG_DATA_END_OF_TABLE, (mipi_dsi_cmd_flag_t)0},


};

4、修改hal_entry.c

#include "hal_data.h"
//#include "board_sdram.h"
#include "board_init.h"

//#include "lvgl/lvgl/lvgl.h"
#include "demos/lv_demos.h"

FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    /* TODO: add your own code here */

    lv_init();
    board_init();
    #if (1 == LV_USE_DEMO_BENCHMARK)
        lv_demo_benchmark();
    #endif

    #if (1 == LV_USE_DEMO_MUSIC)
        lv_demo_music();
    #endif

    #if (1 == LV_USE_DEMO_KEYPAD_AND_ENCODER)
        lv_demo_keypad_encoder();

    #endif

    #if (1 == LV_USE_DEMO_STRESS)
        lv_demo_stress();
    #endif

    #if (1 == LV_USE_DEMO_WIDGETS && 0 == LV_USE_DEMO_BENCHMARK)
//        lv_demo_widgets();
    #endif
        lv_demo_widgets();
    while (1)
    {
        lv_timer_handler();
        R_BSP_SoftwareDelay(3, BSP_DELAY_UNITS_MILLISECONDS);
    }
#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

/*******************************************************************************************************************//**
 * This function is called at various points during the startup process.  This implementation uses the event that is
 * called right before main() to set up the pins.
 *
 * @param[in]  event    Where at in the start up process the code is currently at
 **********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

        /* Enable reading from data flash. */
        R_FACI_LP->DFLCTL = 1U;

        /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
        /* C runtime environment and system clocks are setup. */

        /* Configure pins. */
        R_IOPORT_Open (&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);

#if BSP_CFG_SDRAM_ENABLED

        /* Setup SDRAM and initialize it. Must configure pins first. */
        R_BSP_SdramInit(true);
#endif
//        bsp_sdram_init();
    }
}

#if BSP_TZ_SECURE_BUILD

FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{

}
FSP_CPP_FOOTER

#endif

编译后下载到开发板。可以看到成功的运行了demo

dcddf8f18eda670b05659aaa46312d52.jpg

【添加自定义工程】

使用guiguider设计一个基于lvgl9的窗口:

image.png

生成工程后,拷贝generated到工程中,并添加工程文件/目录

image.png

【实验效果】

84c2b78fbe49d9e012d94ec76e886853.jpg

【总结】

对于其他的MCU系列来说,RA的生态现在非常好了,通过图形化的配置,可以快速的创建工程,并验证开发板的功能。





关键词: RA8D1LVGL     瑞萨    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]