电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
《rt-thread驱动框架分析》-touch驱动
分 享
扫描二维码分享
《rt-thread驱动框架分析》-touch驱动
rtthrea
touch驱动
Rice嵌入式开发
关注
发布时间: 2021-01-26
丨
阅读: 442
## 简介 - rt-smart相关文章 - [《rt-smart的第一个应用程序,imx6ull用户态点灯》](https://mp.weixin.qq.com/s/vFvxlkPuEa2xQhaho-kKoQ) - [《rt-smart用户态通过IPC通信玩转传感器数据》](https://mp.weixin.qq.com/s/nmO_0LH2pztHW4MK3ZLK6A) - rt-thread驱动相关文章 - [《rt-thread驱动框架分析》-pin驱动](https://mp.weixin.qq.com/s/vFvxlkPuEa2xQhaho-kKoQ) - [《rt-thread驱动框架分析》-i2c驱动](https://mp.weixin.qq.com/s/nmO_0LH2pztHW4MK3ZLK6A) - 有了LCD之后,那必然要有触摸,没触摸的屏幕感觉少了灵魂。 - TouchIC没有对应软件包(重新造了一个软件包GT911,目前已经PR到RTT的软件包仓库了,欢迎使用),下面讲解的是我个人的做法,不对的地方,请指出。。。。 ### Touch IC驱动 - 对于Touch,RT-Thread有专门的设备驱动框架,官网文档有对相关API使用的说明,可以查看下面链接。这篇文章主要描述底层的touch驱动对接。应用相关的直接看文档中心。 - 文档中心:https://www.rt-thread.org/document/site/programming-manual/device/touch/touch/ - Touch 驱动对接,其实就是对接一个ops,然后通过API: rt_hw_touch_register(),就可以完事了: ```C struct rt_touch_ops { rt_size_t (*touch_readpoint)(struct rt_touch_device *touch, void *buf, rt_size_t touch_num); rt_err_t (*touch_control)(struct rt_touch_device *touch, int cmd, void *arg); }; ``` - 其实这两个api就是根据手册操作寄存器。 ###### API: touch_control: - 主要操作0x8047 ~ 0x8100这186个寄存器。而作者比较懒,如果一个一个寄存器去配置,会花很长时间,其实我用的就是100ask_imx6ull,在韦老师的提供的linux代码中就有相对应的驱动,而且而且这些控制寄存器的相关配置是在设备树中,所以直接把设备树的这些寄存器拷贝过来就完事了,在韦老师的代码中,他的设备树支持不同尺寸的屏幕,所以不要搬错砖。 ![](https://RiceChen0.gitee.io/picture/rt-thread专辑/touch框架/1.png) - 其中在conctrol里面,主要就是对接下面这个cmd type。将下面cmd与相关寄存器一一对应。最后在一次性把相关寄存器配置写入。 ``` C /@@* Touch control cmd types */ #define RT_TOUCH_CTRL_GET_ID (0) /@@* Get device id */ #define RT_TOUCH_CTRL_GET_INFO (1) /@@* Get touch info */ #define RT_TOUCH_CTRL_SET_MODE (2) /@@* Set touch's work mode. ex. RT_TOUCH_MODE_POLLING,RT_TOUCH_MODE_INT */ #define RT_TOUCH_CTRL_SET_X_RANGE (3) /@@* Set x coordinate range */ #define RT_TOUCH_CTRL_SET_Y_RANGE (4) /@@* Set y coordinate range */ #define RT_TOUCH_CTRL_SET_X_TO_Y (5) /@@* Set X Y coordinate exchange */ #define RT_TOUCH_CTRL_DISABLE_INT (6) /@@* Disable interrupt */ #define RT_TOUCH_CTRL_ENABLE_INT (7) /@@* Enable interrupt */ ``` ###### API:touch_readpoint - 主要操作0x8140 ~ 0x8177这56个寄存器。先读取状态寄存器,根据状态寄存器去读取触摸点的信息。其实这一块的操作可以直接根据其他的软件,我编写的这个驱动就是参考gt9147软件包的。 ##### 注册 ``` C int rt_hw_gt911_init(const char *name, struct rt_touch_config *cfg) { struct rt_touch_device *touch_device = RT_NULL; touch_device = (struct rt_touch_device *)rt_malloc(sizeof(struct rt_touch_device)); if(touch_device == RT_NULL) { LOG_E("touch device malloc fail"); return -RT_ERROR; } rt_memset((void *)touch_device, 0, sizeof(struct rt_touch_device)); /@@* hw init*/ rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT); rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_OUTPUT); rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_LOW); rt_thread_delay(10); rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_HIGH); rt_thread_delay(10); rt_pin_write(cfg->irq_pin.pin, PIN_MODE_INPUT); rt_thread_delay(100); gt911_client.bus = (struct rt_i2c_bus_device *)rt_device_find(cfg->dev_name); if(gt911_client.bus == RT_NULL) { LOG_E("Can't find %s device", cfg->dev_name); return -RT_ERROR; } if(rt_device_open((rt_device_t)gt911_client.bus, RT_DEVICE_FLAG_RDWR) != RT_EOK) { LOG_E("open %s device failed", cfg->dev_name); return -RT_ERROR; } gt911_client.client_addr = GT911_ADDRESS_HIGH; gt911_soft_reset(>911_client); /@@* register touch device */ touch_device->info.type = RT_TOUCH_TYPE_CAPACITANCE; touch_device->info.vendor = RT_TOUCH_VENDOR_GT; rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config)); touch_device->ops = >911_touch_ops; rt_hw_touch_register(touch_device, name, RT_DEVICE_FLAG_INT_RX, RT_NULL); LOG_I("touch device gt911 init success"); return RT_EOK; } ``` - 上面的代码,主要经过几个步骤,通过GPIO的初始化时序确定从机地址,时序图如下: ![](https://RiceChen0.gitee.io/picture/rt-thread专辑/touch框架/2.png) - 然后关联对应的I2C总线 - 复位触摸芯片 - 配置触摸芯片的相关信息,其实就是填写下面结构体。 ``` C struct rt_touch_info { rt_uint8_t type; /@@* The touch type */ rt_uint8_t vendor; /@@* Vendor of touchs */ rt_uint8_t point_num; /@@* Support point num */ rt_int32_t range_x; /@@* X coordinate range */ rt_int32_t range_y; /@@* Y coordinate range */ }; ``` - 其中touch_config提供用户配置的。根据硬件实际情况进行配置。 ```C struct rt_touch_config { struct rt_device_pin_mode irq_pin; /@@* Interrupt pin, The purpose of this pin is to notification read data */ char *dev_name; /@@* The name of the communication device */ void *user_data; }; ``` - 然后通过rt_hw_touch_register()进行配置。这样就可以完成了驱动。 ###### 效果(通过打印演示) ![](https://RiceChen0.gitee.io/picture/rt-thread专辑/touch框架/3.png)
关注微信公众号『Rice嵌入式开发技术分享』,后台回复“微信”添加作者微信,备注”入群“,便可邀请进入技术交流群。 ![](https://RiceChen0.gitee.io/picture/logo/logo_.jpg)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
Rice嵌入式开发
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交