Rice我叫加饭? · 2021年01月26日

《rt-thread驱动框架分析》-lcd驱动

首发:Rice 嵌入式开发技术分享
作者:RiceDIY

简介

LCD驱动:

  • imx6ull这款芯片自带LCD控制器,所以比较方便。
  • 关于LCD驱动,从RTT的代码是没有对应的驱动框架的,所以直接对接设备驱动框架中。而且只需要实现通用设备接口的init和control接口。
   /* common device interface */  
    rt_err_t  (*init)   (rt_device_t dev);  
    rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);  
    rt_err_t  (*close)  (rt_device_t dev);  
    rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);  
    rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);  
    rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);  

init接口:

我主要做了以下四个步骤(详情实现请clone代码):

  1. framebuffer清0,
  2. LCD控制器的相关GPIO初始化
  3. LCD控制器的相关时钟初始化
  4. LCD控制器的相关配置初始化(这里要结合屏幕手册进行配置)
  • 时钟配置,控制配置需要参考LCD的手册。

image.png

control接口:

  • rtt提供了如下6条命令:
/**  
 * graphic device control command  
 */  
#define RTGRAPHIC_CTRL_RECT_UPDATE      0  
#define RTGRAPHIC_CTRL_POWERON          1  
#define RTGRAPHIC_CTRL_POWEROFF         2  
#define RTGRAPHIC_CTRL_GET_INFO         3  
#define RTGRAPHIC_CTRL_SET_MODE         4  
#define RTGRAPHIC_CTRL_GET_EXT          5  
  • 因为我使用的是单个FB,所以实际只实现了3条命令:RTGRAPHIC\_CTRL\_POWERON、RTGRAPHIC\_CTRL\_POWEROFF、RTGRAPHIC\_CTRL\_GET\_INFO
static rt_err_t imx6ull_lcd_control(rt_device_t dev, int cmd, void *args)  
{  
    struct imx6ull_lcd *lcd_dev = (struct imx6ull_lcd *)dev;  
  
    switch(cmd)  
    {  
        case RTGRAPHIC_CTRL_RECT_UPDATE:  
        {  
            break;  
        }  
        case RTGRAPHIC_CTRL_POWERON:  
        {  
            rt_pin_write(IMX6ULL_LCD_BL_PIN, PIN_HIGH);  
            break;  
        }  
        case RTGRAPHIC_CTRL_POWEROFF:  
        {  
            rt_pin_write(IMX6ULL_LCD_BL_PIN, PIN_LOW);  
            break;  
        }  
        case RTGRAPHIC_CTRL_GET_INFO:  
        {  
            struct rt_device_graphic_info *info = (struct rt_device_graphic_info*)args;  
            RT_ASSERT(info != RT_NULL);  
            rt_memcpy(info, &lcd_dev->info, sizeof(lcd.info));  
            break;  
        }  
    }  
    return RT_EOK;  
}  

注册设备

  • 前面也说道LCD没有独立的驱动框架,所以以一个通用设备驱动框架来实现:
int rt_hw_lcd_init(void)  
{  
    rt_err_t ret;  
  
    lcd.device.type    = RT_Device_Class_Graphic;  
#ifdef RT_USING_DEVICE_OPS  
    lcd.device.ops         = &lcd_ops;  
#else  
    lcd.device.init    = imx6ull_lcd_init;  
    lcd.device.open    = RT_NULL;  
    lcd.device.close   = RT_NULL;  
    lcd.device.read    = RT_NULL;  
    lcd.device.write   = RT_NULL;  
    lcd.device.control = imx6ull_lcd_control;  
#endif  
    lcd.device.user_data = (void *)&lcd.info;  
  
    ret = rt_device_register(&lcd.device, "lcd", RT_DEVICE_FLAG_RDWR);  
    return ret;  
}  
INIT_BOARD_EXPORT(rt_hw_lcd_init);  

效果(通过刷屏演示)

  • 在代码中,我提供了测试样例,命令:lcd\_test

image.png

关注微信公众号『Rice嵌入式开发技术分享』,后台回复“微信”添加作者微信,备注”入群“,便可邀请进入技术交流群。

image.png
推荐阅读

更多嵌入式技术干货请关注Rice 嵌入式开发技术分享
推荐阅读
关注数
1761
内容数
51
一个周末很无聊的嵌入式软件工程师,写写经验,写写总结。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息