RT-Thread 中 LCD
设备被注册为图形设备,其驱动模板如下
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-22 tyustli first version
*/
#include "rtconfig.h"
#ifdef BSP_USING_LCD
#include "board.h"
rt_uint8_t lcd_framebuffer[LCD_FRAMEBUFFER_SIZE];
struct drv_lcd_device
{
struct rt_device parent;
struct rt_device_graphic_info lcd_info;
struct rt_semaphore lcd_lock;
};
static struct drv_lcd_device _lcd;
static rt_err_t drv_lcd_init(struct rt_device *device)
{
/* init your display */
return RT_EOK;
}
void lcd_update_isr(void)
{
rt_interrupt_enter();
rt_sem_release(&_lcd.lcd_lock);
rt_interrupt_leave();
}
static rt_err_t drv_lcd_control(struct rt_device *device, int cmd, void *args)
{
struct drv_lcd_device *lcd = rt_list_entry(device, struct drv_lcd_device, parent);
switch (cmd)
{
case RTGRAPHIC_CTRL_RECT_UPDATE:
{
/* 等待上一次 lcd 刷屏完成 一般刷屏完成会有一个中断或者回调函数 */
rt_sem_take(&_lcd.lcd_lock, RT_WAITING_FOREVER);
/* update your lcd */
lcd_framebuffer_update(lcd_framebuffer, LCD_FRAMEBUFFER_SIZE);
}
break;
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
RT_ASSERT(info != RT_NULL);
info->pixel_format = lcd->lcd_info.pixel_format;
info->bits_per_pixel = lcd->lcd_info.bits_per_pixel;
info->width = lcd->lcd_info.width;
info->height = lcd->lcd_info.height;
info->framebuffer = lcd_framebuffer;
}
break;
}
return RT_EOK;
}
static int rt_hw_lcd_init(void)
{
rt_err_t result = RT_EOK;
struct rt_device *device = &_lcd.parent;
/* 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;
_lcd.lcd_info.framebuffer = (void *)lcd_framebuffer; /* the frame buffer address */
result = rt_sem_init(&_lcd.lcd_lock, "led_lock", 1, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("init lcd lock failed\r\n");
}
device->type = RT_Device_Class_Graphic;
#ifdef RT_USING_DEVICE_OPS
device->ops = &lcd_ops;
#else
device->init = drv_lcd_init;
device->control = drv_lcd_control;
result = rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);
if (result != RT_EOK)
{
rt_kprintf("register lcd device failed\r\n");
}
#endif
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_lcd_init);
#endif /* BSP_USING_LCD */