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-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/*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平台)相关推荐
- 【Linux驱动开发】LCD 驱动实验
一.简介 Framebuffer 设备,Framebuffer(帧缓冲),简称 fb. LCD 对应的设备文件是 /dev/fbX(X=0~n). 在 Linux 中应用程序也是通过操作 RGB LC ...
- 【i.MX6ULL】驱动开发11——LCD驱动实践
之前在Linux系统移植时提到过LCD驱动,本篇来看下Linux设备树如何配置LCD驱动. 1 知识点 首先需要了解一个新的概念:Framebuffer 1.1 Framebuffer Framebu ...
- <Linux开发>驱动开发 -之-platform 驱动
<Linux开发>驱动开发 -之-platform 驱动 交叉编译环境搭建: <Linux开发> linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下: < ...
- <Linux开发>--驱动开发-- 字符设备驱动(3) 过程详细记录
<Linux开发>–驱动开发-- 字符设备驱动(3) 过程详细记录 驱动开发是建立再系统之上的,前面作者也记录了系统移植的过程记录,如果有兴趣,可进入博主的主页查看相关文章,这里就不添加链 ...
- Linux 设备驱动开发 —— platform设备驱动应用实例解析
前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 -- platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...
- Linux驱动开发1:驱动开发与裸机开发的区别
Linux驱动开发1:驱动开发与裸机开发的区别 1.裸机驱动开发回顾: 裸机驱动开发是非常底层的,跟寄存器打交道,有些MCU为了方便我们开发,提供了一些库,让我们通过调用API函数来间接的实现利用寄存 ...
- Linux驱动开发—内核I2C驱动详解
Linux驱动开发--内核I2C驱动 I2C驱动文件结构 I2C数据传输过程 i2c_transfer i2c_msg I2C通讯常用的接口函数(老版本) 快速读写接口函数:(连续读写) 常用的读操作 ...
- Linux嵌入式驱动开发07——GPIO驱动过程记录(飞凌开发板)
文章目录 全系列传送门 1. 在/arch/arm/boot/dts/imx6q-pinfunc.h查找 2. 在设备树配置文件中添加设备节点定义以及其引脚定义 3. 修改设备树文件添加配置 4. d ...
- STM32MP157驱动开发——USB设备驱动
STM32MP157驱动开发--USB设备驱动 一.简介 1.电气属性 2.USB OTG 3.STM32MP1 USB 接口简介 4.Type-C 电气属性 二.USB HOST 驱动开发 1.US ...
- STM32MP157驱动开发——4G通信模块驱动
STM32MP157驱动开发--4G通信模块驱动 一.简介 二.驱动开发 1.高新兴 ME3630 驱动开发 驱动修改 添加 ECM 支持程序 配置 Linux 内核 ppp拨号功能测试 ECM 联网 ...
最新文章
- 即学即用的30段Python实用代码
- 1357篇ECCV 2020论文打包下载!奖项公布:李飞飞高徒获最佳论文奖
- WordPress更新时提示无法连接到FTP服务器的解决方案
- VisualStudio2017中新建项目没有Asp.Net项目
- 王爽 16 位汇编语言学习记录
- 快搜浏览器_opera、Google、firefox三个浏览器的选择
- 防止Ddos攻击脚本
- Jmeter远程启动负载机
- DataFrame基础操作
- 对象 复制构造函数
- 如何使用代码获取电脑内存_代码实战 | 如何在 Android 开发中使用协程
- caffe安装系列——综述
- 编写SQL语句,从Orders表中检索顾客ID(cust_id)和订单号(order_num),并先按顾客ID对结果进行排序,再按订单日期倒序排列
- Ubuntu 16 NFS的安装与使用
- 区块链项目ICO注意事项
- 【网络编程】一、如何记住OSI七层协议模型,看完还记不住的来打我。
- java山地车火山_2019“JAVA(佳沃)杯”第十届凤凰山山地自行车挑战赛
- 转载: windows硬盘默认是NTFS文件格式
- everything增强神器,文档搜索效率何止翻倍!
- 深海迷航创造模式火箭怎么飞_深海迷航火箭怎么发射说什么没关 | 手游网游页游攻略大全...
热门文章
- Adam:大规模分布式机器学习框架
- 使用ViewPage + Fragment,ViewPage所在的activity重建时的问题
- python与数据思维基础网课答案_智慧树知到_Python数据分析与数据可视化_答案免费查询...
- 离散数学7__第2章命题逻辑的推理理论__主析取范式和主合取范式
- python隐藏窗口_python中隐藏Console窗口
- 电子技术基础(三)_第3章集成运算放大器及其应用__基本运算电路
- 关于交换机端口的Trunk和Access模式的分析与验证
- ☆☆☆Windows服务器部署及原理☆☆☆
- 联想l430主板图纸_【有图】Thinkpad L430升级内存,点亮,成功实现双通道!附详细教程及评测!!!...
- 常见电容器图片_最强汇总:燃油锅炉常见故障分析与解决方法简单粗暴!编辑不易!...