TA的每日心情 | 奋斗 昨天 11:11 |
|---|
签到天数: 2771 天 连续签到: 1 天 [LV.Master]伴坛终老
状元
- 积分
- 3532
|
一、前言
我们知道瑞萨 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[0];
- #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[0].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 lcd backlight */
- 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[2 * i] = 0x00;
- lcd->lcd_info.framebuffer[2 * i + 1] = 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[2 * i] = 0xE0;
- lcd->lcd_info.framebuffer[2 * i + 1] = 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[2 * i] = 0x1F;
- lcd->lcd_info.framebuffer[2 * i + 1] = 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[0]);
- 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[0][0], &fb_background[1][0], sizeof(fb_background[0]), LV_DISPLAY_RENDER_MODE_FULL);
- lvgl_init_flag = 1;
- }
复制代码 编译完成后,再将程序下载到开发板中,待开发板重启后,显示的效果见bilibili视频,如下图所示。如此验证了正常驱动MIPI屏,并体现了板卡刷图的高效流畅性。后续可将人脸识别的实时检测效果显示在MIPI屏上。
|
|