【瑞萨AI挑战赛】MIPI LCD屏测
一、前言我们知道瑞萨 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接口。
int rt_hw_lcd_init(void)
{
struct rt_device *device = &_lcd.parent;
/* memset _lcd to zero */
memset(&_lcd, 0x00, sizeof(_lcd));
/* config LCD dev info */
_lcd.lcd_info.height = LCD_HEIGHT;
_lcd.lcd_info.width = LCD_WIDTH;
_lcd.lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
_lcd.lcd_info.pixel_format = LCD_PIXEL_FORMAT;
#if defined(SOC_SERIES_R7FA8M85)
_lcd.lcd_info.framebuffer = (uint8_t *)lcd_framebuffer;
#elif defined(SOC_SERIES_R7KA8P1)
_lcd.lcd_info.framebuffer = (uint8_t *)&fb_background;
#endif
LOG_D("\nlcd framebuffer address:%#x", _lcd.lcd_info.framebuffer);
memset(_lcd.lcd_info.framebuffer, 0x0, LCD_BUF_SIZE);
device->type = RT_Device_Class_Graphic;
#ifdef RT_USING_DEVICE_OPS
device->ops = &lcd_ops;
#else
device->init = drv_lcd_init;
device->control = ra_lcd_control;
#endif
/* register lcd device */
rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);
#ifdef SOC_SERIES_R7FA8M85
rt_completion_init(&sync_completion);
#endif
/* Initialize buffer pointers */
gp_single_buffer = (uint16_t *) G_LCD_CFG.input.p_base;
/* Double buffer for drawing color bands with good quality */
gp_double_buffer = gp_single_buffer + LCD_BUF_SIZE;
reset_lcd_panel();
ra_bsp_lcd_init();
/* turn on lcdbacklight */
turn_on_lcd_backlight();
screen_rotation = ROTATION_ZERO;
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_lcd_init);
#if defined(SOC_SERIES_R7FA8M85) || defined(SOC_SERIES_R7KA8P1)
rt_weak void ra8_mipi_lcd_init(void)
{
LOG_E("please Implementation function %s", __func__);
}
#endif
int lcd_test(void)
{
struct drv_lcd_device *lcd;
struct rt_device_rect_info rect_info;
rect_info.x = 0;
rect_info.y = 0;
rect_info.width = LCD_WIDTH;
rect_info.height = LCD_HEIGHT;
lcd = (struct drv_lcd_device *)rt_device_find("lcd");
for (int i = 0; i < 2; i++)
{
/* red */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
lcd->lcd_info.framebuffer = 0x00;
lcd->lcd_info.framebuffer = 0xF8;
}
LOG_D("red buffer...");
lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
rt_thread_mdelay(1000);
/* green */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
lcd->lcd_info.framebuffer = 0xE0;
lcd->lcd_info.framebuffer = 0x07;
}
LOG_D("green buffer...");
lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
rt_thread_mdelay(1000);
/* blue */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
lcd->lcd_info.framebuffer = 0x1F;
lcd->lcd_info.framebuffer = 0x00;
}
LOG_D("blue buffer...");
lcd->parent.control(&lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
rt_thread_mdelay(1000);
}
return RT_EOK;
}
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项,显示更直观。
static lv_demo_benchmark_scene_dsc_t scenes[] = {
{.name = "Multiple ARGB images", .scene_time = 3000, .create_cb = multiple_argb_images_cb},
{.name = "Multiple labels", .scene_time = 6000, .create_cb = multiple_labels_cb},
{.name = "Screen sized text", .scene_time = 8000, .create_cb = screen_sized_text_cb},
{.name = "Multiple arcs", .scene_time = 3000, .create_cb = multiple_arcs_cb},
{.name = "Containers with scrolling",.scene_time = 5000, .create_cb = containers_with_scrolling_cb},
{.name = "Widgets demo", .scene_time = 6000, .create_cb = widgets_demo_cb},
{.name = "", .create_cb = NULL}
};lv_port_disp.c
#include <lvgl.h>
#include <rtthread.h>
#include "ra8/lcd_config.h"
#include "hal_data.h"
static rt_sem_t _SemaphoreVsync = RT_NULL;
static uint8_t lvgl_init_flag = 0;
void DisplayVsyncCallback(display_callback_args_t *p_args)
{
rt_interrupt_enter();
if (DISPLAY_EVENT_LINE_DETECTION == p_args->event)
{
if (lvgl_init_flag != 0)
rt_sem_release(_SemaphoreVsync);
}
rt_interrupt_leave();
}
static void vsync_wait_cb(lv_display_t *display)
{
if (!lv_display_flush_is_last(display)) return;
//
// If Vsync semaphore has already been set, clear it then wait to avoid tearing
//
rt_sem_take(_SemaphoreVsync, RT_WAITING_FOREVER);
}
static void disp_flush(lv_display_t *display, const lv_area_t *area, uint8_t *px_map)
{
if (!lv_display_flush_is_last(display)) return;
#if (BSP_CFG_DCACHE_ENABLED)
int32_t size;
/* Invalidate cache - so the HW can access any data written by the CPU */
size = sizeof(fb_background);
SCB_CleanInvalidateDCache_by_Addr(px_map, size);
#endif
R_GLCDC_BufferChange(&g_display0_ctrl,
(uint8_t *) px_map,
(display_frame_layer_t) DISPLAY_FRAME_LAYER_1);
}
void lv_port_disp_init(void)
{
static rt_device_t device;
/* LCD Device Init */
device = rt_device_find("lcd");
RT_ASSERT(device != RT_NULL);
_SemaphoreVsync = rt_sem_create("lvgl_sem", 1, RT_IPC_FLAG_PRIO);
if (RT_NULL == _SemaphoreVsync)
{
rt_kprintf("lvgl semaphore create failed\r\n");
RT_ASSERT(0);
}
/*------------------------------------
* Create a display and set a flush_cb
* -----------------------------------*/
lv_display_t *disp = lv_display_create(LV_HOR_RES_MAX, LV_VER_RES_MAX);
lv_display_set_flush_cb(disp, disp_flush);
lv_display_set_flush_wait_cb(disp, vsync_wait_cb);
lv_display_set_buffers(disp, &fb_background, &fb_background, sizeof(fb_background), LV_DISPLAY_RENDER_MODE_FULL);
lvgl_init_flag = 1;
} 编译完成后,再将程序下载到开发板中,待开发板重启后,显示的效果见bilibili视频,如下图所示。如此验证了正常驱动MIPI屏,并体现了板卡刷图的高效流畅性。后续可将人脸识别的实时检测效果显示在MIPI屏上。
https://www.bilibili.com/video/BV1SdcCzoE5f/
页:
[1]