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

这篇具有很好参考价值的文章主要介绍了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. 引脚 描述
1 BLK 背光调节亮度
2 CS 片选
3 RES 复位
4 SDA 数据引脚
5 SCL 串行时钟
6 DC 数据命令选择
修改设备树
修改&ecspi1
  • 板子上通过SPI1接到LCD上,设备树路径 arch/arm/boot/dts/100ask_imx6ull-14x14.dts,修改&ecspi1,增加 cs-gpiosdc-gpiosrst-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,增加dcrst的IO配置(dc与rst的配置也可以单独放到root节点下,需要屏蔽掉其他地方复用防止引起的冲突)
pinctrl_ecspi1: spi_st7789s {
             fsl,pins = <
         MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK          0x000010B1/*sclk*/
         MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI          0x000010B1/*mosi*/
         MX6UL_PAD_CSI_DATA07__ECSPI1_MISO          0x000010B1/*miso*/
         MX6UL_PAD_CSI_DATA03__GPIO4_IO24           0x000010B0/*cs*/
         MX6UL_PAD_CSI_DATA00__GPIO4_IO21           0x000010B0/*dc*/
         MX6UL_PAD_CSI_DATA02__GPIO4_IO23           0x000010B0/*rst*/
     >;
 };
SPI驱动框架
注册spi
  • Linux内核使用spi_driver标识spi设备驱动(匹配方式、probe、remove函数),通过 spi_register_driver向内核进行注册
/* SPI驱动结构体 */  
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,
};
/*
 * @description : 驱动入口函数
 * @param       : 无
 * @return      : 无
 */
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 */
    spi_message_add_tail(t, &m);/* 将spi_transfer添加到spi_message队列 */
    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");
    /* 1、构建设备号 */
    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);
    }
    /* 2、注册设备 */
    cdev_init(&st7789sdev.cdev, &st7789s_ops);
    cdev_add(&st7789sdev.cdev, st7789sdev.devid, ST7789S_CNT);
    /* 3、创建类 */
    st7789sdev.class = class_create(THIS_MODULE, ST7789S_NAME);
    if (IS_ERR(st7789sdev.class)) {
        return PTR_ERR(st7789sdev.class);
    }
    /* 4、创建设备 */
    st7789sdev.device = device_create(st7789sdev.class, NULL, st7789sdev.devid, NULL, ST7789S_NAME);
    if (IS_ERR(st7789sdev.device)) {
        return PTR_ERR(st7789sdev.device);
    }
    /* 获取设备树中cs片选信号 */
    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!\r\n");
        return -EINVAL;
    }
    /* 2、 获取设备树中的gpio属性,得到BEEP所使用的BEEP编号 */
    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;
    }
    /* 3、设置GPIO为输出,并且输出高电平 */
    ret = gpio_direction_output(st7789sdev.cs_gpio, 1);//
    if(ret < 0) {
        printk("can't set cs gpio!\r\n");
    }
    gpio_set_value(st7789sdev.cs_gpio,1);
    ret = gpio_direction_output(st7789sdev.res_gpio, 1);
    if(ret < 0) {
        printk("can't set res gpio!\r\n");
    }
    ret = gpio_direction_output(st7789sdev.dc_gpio, 1);
    if(ret < 0) {
        printk("can't set dc gpio!\r\n");
    }
    /*初始化spi_device */
    spi->mode = SPI_MODE_2; /*MODE0,CPOL=0,CPHA=0 */
    spi_setup(spi);
    st7789sdev.private_data = spi; /* 设置私有数据 */
    /* 初始化st7789s内部寄存器 */
    st7789s_reginit(&st7789sdev);     
    return 0;
}
编译运行

模块拷贝到板子中,由于在加载内核驱动中增加了刷图代码,所以加载驱动后LCD会显示如下图
linux驱动开发 ST7789 LCD驱动移植(I.MX6ULL平台)文章来源地址https://www.toymoban.com/news/detail-405706.html

后续章节贴完整源码

到了这里,关于linux驱动开发 ST7789 LCD驱动移植(I.MX6ULL平台)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • i.MX6ULL驱动开发 | 27 - 使用WM8960 CODEC播放音频

    WM8960是欧胜公司(wolfson)的一款低功耗、高质量的立体声音频编解码芯片。 其内部集成D类喇叭功放,每个通道可以驱动一个1W喇叭(8Ω),内部集成3个立体声输入源,可以灵活配置,拥有一路完整的麦克风接口。 WM8960内部ADC和DAC都为24位,主要特性如下: DAC的SNR(信噪比)

    2024年02月02日
    浏览(39)
  • 017——DS18B20驱动开发(基于I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 主要特点 1.3 存储器介绍 1.4 时序 1.5 命令 1.5.1 命令大全    1.5.2 命令使用 1.5.3 使用示例 1.6 原理图 二、 驱动程序 三、 应用程序 四、 测试         DS18B20 温度传感器具有线路简单、体积小的特点,用来测量温度非常简单,在一根通信线上

    2024年04月12日
    浏览(41)
  • 018——红外遥控模块驱动开发(基于HS0038和I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 协议 二、 驱动代码 三、 应用代码 四、 实验 五、 程序优化         红外遥控被广泛应用于家用电器、工业控制和智能仪器系统中,像我们熟知的有电视机盒子遥控器、空调遥控器。红外遥控器系统分为发送端和接收端,如图下图所示。

    2024年04月16日
    浏览(36)
  • I.MX6ULL开发笔记(二)——硬件外设操作

    在文章http://t.csdnimg.cn/EGWt9中有介绍Linux下文件目录,那么在Linux系统下,RGB灯也是一个设备,所以我们需要到 /sys 目录下去操作这个设备。 之后,我们进入到 class 目录,这里挂载着开发板上的外设: 在这里就能看到熟悉的硬件接口了,那么我们进入到 leds 的目录下: 可以看

    2024年01月24日
    浏览(41)
  • linux(全志F1C100S/F1C200S)系列02:移植LCD st7789驱动,LVGL8.3移植

    st7789V中指定了rst与dc引脚,pio 4 3 对应PE3,pio 4 5对应PE5; 详细配置方式见链接:全志 :gpio使用 需要根据自身硬件配置。 Tips:更改 spi-max-frequency = 32000000 - spi-max-frequency = 100000000; 和 fps = 30; 改为 fps = 60; 感谢楼下老哥提示。 rotate = 90;根据屏幕方向更改。 只需要更改下面的三个地

    2024年01月18日
    浏览(53)
  • 使用一根网线,让Ubuntu和正点原子I.MX6ULL开发板互相ping通

    准备一根网线即可 2.1 找根网线将I.MX6ULL和电脑连起来 2.2 让I.MX6ULL通电运行起来,我这里使用的是正点原子版本的内核、 2.3 进入电脑的网络连接后,按照如下步骤操作 2.4 将ip地址、子网掩码、默认网关设置如下,= 注意,子网掩码一定要是255.255.255.0 IP地址推荐使用192.168.5.

    2024年02月19日
    浏览(38)
  • I.MX6ull UART

     一 简介 UART 全称叫做串行接口,通常也叫做 COM 接口,串行接口指的是数据一个一个的顺序传输,通信线路简单。使用两条线即可实现双向通信,一条用于发送,一条用于接收。串口通 信距离远 ,但是速 度相对会低 ,串口是一种很常用的工业接口。I.MX6U 自带的 UART 外设

    2024年02月09日
    浏览(32)
  • 【Linux 裸机篇(五)】I.MX6ULL BSP工程管理下的 Makefile编写、链接脚本

    文件夹 描述 bsp 存放驱动文件 imx6ul 存放跟芯片有关的文件,比如 NXP 官方的 SDK库文件 obj 存放编译生成的.o 文件 project 存放 start.S 和 main.c 文件,也就是应用文件 行 描述 1~7 定义了一些变量,除了第 2 行以外其它的都是跟编译器有关的,如果使用其它编译器的话只需要修改第

    2023年04月20日
    浏览(40)
  • I.MX6ull EPIT定时器

    一 简介 EPIT定时器是一种增强的周期中断定时器,完成周期性中断定时的功能。 具有以下特点  EPIT定时器是一个32位的定时器  时钟源可选的向下计数器  EPIT 共有 3 个时钟源可选择,ipg_clk、ipg_clk_32k 和 ipg_clk_highfreq  当计数值和比较值相等的时候产生中断  12 位分频器 对

    2024年02月08日
    浏览(42)
  • I.MX6ull GPT高精度定时器

    一 简介 GPT的全称是General Purpose Timer,它是一个32位的向上的定时器, GPT 定时器也可以跟一个值进行比较,当计数器值和这个值相等的话就发生比较事件,产生比较中断。GPT 定时器有一个 12 位的分频器,可以对 GPT 定时器的时钟源进行分频。 分析方式 同EPTI  它具有以下特点

    2024年02月08日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包