栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

linux驱动开发 ST7789 LCD驱动移植(I.MX6ULL平台)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux驱动开发 ST7789 LCD驱动移植(I.MX6ULL平台)

前言

I.MX6ULL的板子未选配RGB的屏幕,无法在板子上进行GUI的开发调试,不过手头上有块控制器为ST7789V3的LCD屏幕(1.3inch),通过简易接线后可以很方便进行驱动的移植

如有异议,欢迎留言指正

ST7789 LCD控制器

ST7789是一款单芯片TFT-LCD控制器,支持并口与SPI通信方式

特性
  • 控制器支持显示区域340x320(LCD屏幕实际为240x240)
  • RGB565、16bit、65K真彩
  • 支持SPI通信
  • LCD控制引脚
NO.引脚描述
1BLK背光调节亮度
2CS片选
3RES复位
4SDA数据引脚
5SCL串行时钟
6DC数据命令选择
修改设备树 修改&ecspi1
  • 板子上通过SPI1接到LCD上,设备树路径 arch/arm/boot/dts/100ask_imx6ull-14x14.dts,修改&ecspi1,增加 cs-gpios、dc-gpios、rst-gpio引脚(dc与rst也可以单独放到root节点下)
&ecspi1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi1>;
    fsl,spi-num-chipselects = <1>;
    cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>;
    dc-gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>;
    rst-gpio = <&gpio4 23 GPIO_ACTIVE_HIGH>;
    status = "okay";
    spidev: st7789s@0{
        compatible = "100ask, st7789s";
        spi-max-frequency = <25000000>;
        reg = <0>;
    };
};
修改pinctrl
  • 修改设备树中pinctrl_ecspi1,增加dc、rst的IO配置(dc与rst的配置也可以单独放到root节点下,需要屏蔽掉其他地方复用防止引起的冲突)
pinctrl_ecspi1: spi_st7789s {
             fsl,pins = <
         MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK          0x000010B1
         MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI          0x000010B1
         MX6UL_PAD_CSI_DATA07__ECSPI1_MISO          0x000010B1
         MX6UL_PAD_CSI_DATA03__GPIO4_IO24           0x000010B0
         MX6UL_PAD_CSI_DATA00__GPIO4_IO21           0x000010B0
         MX6UL_PAD_CSI_DATA02__GPIO4_IO23           0x000010B0
     >;
 };
SPI驱动框架 注册spi
  • Linux内核使用spi_driver标识spi设备驱动(匹配方式、probe、remove函数),通过 spi_register_driver向内核进行注册
  
static struct spi_driver st7789s_driver = {
    .probe = st7789s_probe,
    .remove = st7789s_remove,
    .driver = {
            .owner = THIS_MODULE,
            .name = ST7789S_NAME,
            .of_match_table = st7789s_of_match,
           },
    .id_table = st7789s_id,
};

static int __init st7789s_init(void)
{
    return spi_register_driver(&st7789s_driver);
}
数据发送
  • 将待发送数据添加到spi_message队列中,并使用同步(堵塞方式)发送
static int st7789_write_regs(struct st7789_dev *dev,unsigned char *buf, int len)
{
    int ret;
    struct spi_message m;
    struct spi_transfer *t;
    struct spi_device *spi = (struct spi_device *)dev->private_data;
    
    t = kzalloc(sizeof(struct spi_transfer), GFP_KERNEL);   
    t->tx_buf = buf;            
    t->len = len;               
    spi_message_init(&m);       
    spi_message_add_tail(t, &m);
    ret = spi_sync(spi, &m);    
    kfree(t);                   
    return ret;
}
probe函数
  • 设备与驱动匹配成功后,在probe中注册设备并进行刷屏
static int st7789s_probe(struct spi_device *spi)
{
    int ret = 0;
    printk("st7789 probe n");
    
    if (st7789sdev.major) {
        st7789sdev.devid = MKDEV(st7789sdev.major, 0);
        register_chrdev_region(st7789sdev.devid, ST7789S_CNT, ST7789S_NAME);
    } else {
        alloc_chrdev_region(&st7789sdev.devid, 0, ST7789S_CNT, ST7789S_NAME);
        st7789sdev.major = MAJOR(st7789sdev.devid);
    }
    
    cdev_init(&st7789sdev.cdev, &st7789s_ops);
    cdev_add(&st7789sdev.cdev, st7789sdev.devid, ST7789S_CNT);
    
    st7789sdev.class = class_create(THIS_MODULE, ST7789S_NAME);
    if (IS_ERR(st7789sdev.class)) {
        return PTR_ERR(st7789sdev.class);
    }
    
    st7789sdev.device = device_create(st7789sdev.class, NULL, st7789sdev.devid, NULL, ST7789S_NAME);
    if (IS_ERR(st7789sdev.device)) {
        return PTR_ERR(st7789sdev.device);
    }
    
    st7789sdev.nd = of_find_node_by_path("/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02008000");
    if(st7789sdev.nd == NULL) {
        printk("ecspi1 node not find!rn");
        return -EINVAL;
    }
    
    st7789sdev.cs_gpio = of_get_named_gpio(st7789sdev.nd, "cs-gpios", 0);
    if(st7789sdev.cs_gpio < 0) {
        printk("can't get cs-gpio");
        return -EINVAL;
    }
   
    st7789sdev.res_gpio = of_get_named_gpio(st7789sdev.nd, "rst-gpios", 0);
    if(st7789sdev.res_gpio < 0) {
        printk("can't get res-gpio");
        return -EINVAL;
    }
    st7789sdev.dc_gpio = of_get_named_gpio(st7789sdev.nd, "dc-gpios", 0);
    if(st7789sdev.dc_gpio < 0) {
        printk("can't get dc-gpio");
        return -EINVAL;
    }
    
    ret = gpio_direction_output(st7789sdev.cs_gpio, 1);//
    if(ret < 0) {
        printk("can't set cs gpio!rn");
    }
    gpio_set_value(st7789sdev.cs_gpio,1);
    ret = gpio_direction_output(st7789sdev.res_gpio, 1);
    if(ret < 0) {
        printk("can't set res gpio!rn");
    }
    ret = gpio_direction_output(st7789sdev.dc_gpio, 1);
    if(ret < 0) {
        printk("can't set dc gpio!rn");
    }
    
    spi->mode = SPI_MODE_2; 
    spi_setup(spi);
    st7789sdev.private_data = spi; 
    
    st7789s_reginit(&st7789sdev);     
    return 0;
}
编译运行

模块拷贝到板子中,由于在加载内核驱动中增加了刷图代码,所以加载驱动后LCD会显示如下图

后续章节贴完整源码
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/881856.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号