回答

收藏

[评测分享] 【瑞萨AI挑战赛】MIPI LCD屏测

#板卡评测 #板卡评测 42 人阅读 | 0 人回复 | 2026-03-13

一、前言

     我们知道瑞萨 RT-Thread RA8P1 Titan Board开发板支持22pin的MIPI DSI屏幕接口与40pin的RGB565屏幕接口,由于实现人或物体的实时检测需要将效果显示到屏幕上才比较直观,因此需要自备一块符合硬件接口的显示屏,手中虽有一块40pin的RGB屏,但引脚定义与Titan Board原理图上的RGB屏接口不相符,所以,笔者索性在官方“睿赛德科技”某宝店铺上购买了配套的MIPI DSI屏,该屏4.3寸800X480分辨率,不支持触摸功能。

二、硬件实物
      物流很快,收到的MIPI屏实物图如下,正如图中所示,连接MIPI DSI屏幕需要再连接一块转接板。


三、屏接口原理图


四、工程示例
1、mipi_lcd示例
        与上期的开箱及环境搭建与点灯帖中一样,使用RT-Thread Studio导入“sdk-bsp-ra8p1-titan-board-1.0.2”中的“Titan_driver_mipi_lcd”例程,导入后直接编译就行。这里暂且不针对使用FSP配置HyperRAM、MIPI DSI等参数配置,当然例程也已经包含了RT-Thread Settings的配置,使能了MIPI LCD接口。
  1. int rt_hw_lcd_init(void)
  2. {
  3.     struct rt_device *device = &_lcd.parent;

  4.     /* memset _lcd to zero */
  5.     memset(&_lcd, 0x00, sizeof(_lcd));

  6.     /* config LCD dev info */
  7.     _lcd.lcd_info.height = LCD_HEIGHT;
  8.     _lcd.lcd_info.width = LCD_WIDTH;
  9.     _lcd.lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
  10.     _lcd.lcd_info.pixel_format = LCD_PIXEL_FORMAT;
  11. #if defined(SOC_SERIES_R7FA8M85)
  12.     _lcd.lcd_info.framebuffer = (uint8_t *)lcd_framebuffer;
  13. #elif defined(SOC_SERIES_R7KA8P1)
  14.     _lcd.lcd_info.framebuffer = (uint8_t *)&fb_background[0];
  15. #endif
  16.     LOG_D("\nlcd framebuffer address:%#x", _lcd.lcd_info.framebuffer);
  17.     memset(_lcd.lcd_info.framebuffer, 0x0, LCD_BUF_SIZE);

  18.     device->type    = RT_Device_Class_Graphic;
  19. #ifdef RT_USING_DEVICE_OPS
  20.     device->ops     = &lcd_ops;
  21. #else
  22.     device->init    = drv_lcd_init;
  23.     device->control = ra_lcd_control;
  24. #endif

  25.     /* register lcd device */
  26.     rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);
  27. #ifdef SOC_SERIES_R7FA8M85
  28.     rt_completion_init(&sync_completion);
  29. #endif

  30.     /* Initialize buffer pointers */
  31.     gp_single_buffer = (uint16_t *) G_LCD_CFG.input[0].p_base;

  32.     /* Double buffer for drawing color bands with good quality */
  33.     gp_double_buffer = gp_single_buffer + LCD_BUF_SIZE;

  34.     reset_lcd_panel();

  35.     ra_bsp_lcd_init();

  36.     /* turn on lcd  backlight */
  37.     turn_on_lcd_backlight();

  38.     screen_rotation = ROTATION_ZERO;

  39.     return RT_EOK;
  40. }
  41. INIT_DEVICE_EXPORT(rt_hw_lcd_init);

  42. #if defined(SOC_SERIES_R7FA8M85) || defined(SOC_SERIES_R7KA8P1)
  43. rt_weak void ra8_mipi_lcd_init(void)
  44. {
  45.     LOG_E("please Implementation function %s", __func__);
  46. }
  47. #endif

  48. int lcd_test(void)
  49. {
  50.     struct drv_lcd_device *lcd;
  51.     struct rt_device_rect_info rect_info;
  52.     rect_info.x = 0;
  53.     rect_info.y = 0;
  54.     rect_info.width = LCD_WIDTH;
  55.     rect_info.height = LCD_HEIGHT;

  56.     lcd = (struct drv_lcd_device *)rt_device_find("lcd");

  57.     for (int i = 0; i < 2; i++)
  58.     {
  59.         /* red */
  60.         for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
  61.         {
  62.             lcd->lcd_info.framebuffer[2 * i] = 0x00;
  63.             lcd->lcd_info.framebuffer[2 * i + 1] = 0xF8;
  64.         }
  65.         LOG_D("red buffer...");
  66.         lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
  67.         rt_thread_mdelay(1000);
  68.         /* green */
  69.         for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
  70.         {
  71.             lcd->lcd_info.framebuffer[2 * i] = 0xE0;
  72.             lcd->lcd_info.framebuffer[2 * i + 1] = 0x07;
  73.         }
  74.         LOG_D("green buffer...");
  75.         lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
  76.         rt_thread_mdelay(1000);
  77.         /* blue */
  78.         for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
  79.         {
  80.             lcd->lcd_info.framebuffer[2 * i] = 0x1F;
  81.             lcd->lcd_info.framebuffer[2 * i + 1] = 0x00;
  82.         }
  83.         LOG_D("blue buffer...");
  84.         lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
  85.         rt_thread_mdelay(1000);
  86.     }
  87.     return RT_EOK;
  88. }
  89. MSH_CMD_EXPORT(lcd_test, lcd test cmd);
复制代码
       编译ok后,将固件下载到开发板中,复位后在终端输入“lcd_test”命令即可运行刷屏测试程序。


2、mipi_lvgl示例
       同样的方式,将“sdk-bsp-ra8p1-titan-board-1.0.2”中的“Titan_display_mipi_lvgl”导入到RT-Thread Studio中,由于该工程集成LVGL图形库,而且图形设计支持SquareLine Studio工具,例程中测试了多种图形、字符的显示方式,并得出每个测试项的速率。笔者将原来的16项减少到6项,显示更直观。
  1. static lv_demo_benchmark_scene_dsc_t scenes[] = {
  2.     {.name = "Multiple ARGB images",       .scene_time = 3000, .create_cb = multiple_argb_images_cb},
  3.     {.name = "Multiple labels",            .scene_time = 6000, .create_cb = multiple_labels_cb},
  4.     {.name = "Screen sized text",          .scene_time = 8000, .create_cb = screen_sized_text_cb},
  5.     {.name = "Multiple arcs",              .scene_time = 3000, .create_cb = multiple_arcs_cb},
  6. {.name = "Containers with scrolling",  .scene_time = 5000, .create_cb = containers_with_scrolling_cb},
  7. {.name = "Widgets demo",               .scene_time = 6000,           .create_cb = widgets_demo_cb},
  8. {.name = "", .create_cb = NULL}
  9. };
复制代码
lv_port_disp.c

  1. #include <lvgl.h>
  2. #include <rtthread.h>
  3. #include "ra8/lcd_config.h"
  4. #include "hal_data.h"

  5. static rt_sem_t _SemaphoreVsync = RT_NULL;
  6. static uint8_t lvgl_init_flag = 0;

  7. void DisplayVsyncCallback(display_callback_args_t *p_args)
  8. {
  9.     rt_interrupt_enter();
  10.     if (DISPLAY_EVENT_LINE_DETECTION == p_args->event)
  11.     {
  12.         if (lvgl_init_flag != 0)
  13.             rt_sem_release(_SemaphoreVsync);
  14.     }
  15.     rt_interrupt_leave();
  16. }

  17. static void vsync_wait_cb(lv_display_t *display)
  18. {
  19.     if (!lv_display_flush_is_last(display)) return;

  20.     //
  21.     // If Vsync semaphore has already been set, clear it then wait to avoid tearing
  22.     //
  23.     rt_sem_take(_SemaphoreVsync, RT_WAITING_FOREVER);
  24. }

  25. static void disp_flush(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
  26. {
  27.     if (!lv_display_flush_is_last(display)) return;

  28. #if (BSP_CFG_DCACHE_ENABLED)
  29.     int32_t size;
  30.     /* Invalidate cache - so the HW can access any data written by the CPU */
  31.     size = sizeof(fb_background[0]);

  32.     SCB_CleanInvalidateDCache_by_Addr(px_map, size);
  33. #endif

  34.     R_GLCDC_BufferChange(&g_display0_ctrl,
  35.                          (uint8_t *) px_map,
  36.                          (display_frame_layer_t) DISPLAY_FRAME_LAYER_1);
  37. }

  38. void lv_port_disp_init(void)
  39. {
  40.     static rt_device_t device;
  41.     /* LCD Device Init */
  42.     device = rt_device_find("lcd");
  43.     RT_ASSERT(device != RT_NULL);

  44.     _SemaphoreVsync = rt_sem_create("lvgl_sem", 1, RT_IPC_FLAG_PRIO);

  45.     if (RT_NULL == _SemaphoreVsync)
  46.     {
  47.         rt_kprintf("lvgl semaphore create failed\r\n");
  48.         RT_ASSERT(0);
  49.     }

  50.     /*------------------------------------
  51.      * Create a display and set a flush_cb
  52.      * -----------------------------------*/
  53.     lv_display_t *disp = lv_display_create(LV_HOR_RES_MAX, LV_VER_RES_MAX);
  54.     lv_display_set_flush_cb(disp, disp_flush);
  55.     lv_display_set_flush_wait_cb(disp, vsync_wait_cb);
  56.     lv_display_set_buffers(disp, &fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0]), LV_DISPLAY_RENDER_MODE_FULL);

  57.     lvgl_init_flag = 1;
  58. }
复制代码
    编译完成后,再将程序下载到开发板中,待开发板重启后,显示的效果见bilibili视频,如下图所示。如此验证了正常驱动MIPI屏,并体现了板卡刷图的高效流畅性。后续可将人脸识别的实时检测效果显示在MIPI屏上。




分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

软件工程师
3532 积分
37 主题
+ 关注
关闭

站长推荐上一条 /3 下一条