开发多按键输入驱动,不妨采用这种方式
多按键输入驱动
荔枝派的全志V3s开发板上面,有4个按键本身不是通过gpio连接到soc上面的。它是通过ad的方法,连接到主芯片的。这个时候,不同的按键被按下的时候,就会生成不同的电压或者电流,那么完全可以根据对应的电信号,推算出当前是哪一个按键被按下去了。
1、查找电路图
简单看一下电路之后,下面就是去找设备树,对应的信号是什么、在哪里。
2、查找设备树
在sun8i-v3s-licheepi-zero-dock.dts文件当中,我们发现了这样的内容,
&lradc { vref-supply = <®_vcc3v0>; status = "okay"; button@200 { label = "Volume Up"; linux,code = <KEY_VOLUMEUP>; channel = <0>; voltage = <200000>; }; button@400 { label = "Volume Down"; linux,code = <KEY_VOLUMEDOWN>; channel = <0>; voltage = <400000>; }; button@600 { label = "Select"; linux,code = <KEY_SELECT>; channel = <0>; voltage = <600000>; }; button@800 { label = "Start"; linux,code = <KEY_OK>; channel = <0>; voltage = <800000>; }; };
很明显,每一个button都是和电路中的按键是一一对应的,这个没有问题。那么,我们不禁还有一个疑问,既然是ad转换得到的结果,那么肯定要知道ad相关的设备配置是恶还那么。仔细找了一下,可以在sun8i-v3s.dtsi文件发现这样的内容,
lradc: lradc@01c22800 { compatible = "allwinner,sun4i-a10-lradc-keys"; reg = <0x01c22800 0x400>; interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; };
看到这里,大家应该放心了,确实是有这么一个ad的驱动。兼容的设备是sun4i-a10-lradc-keys,寄存器地址空间是0x01c22800,长度是0x400,中断是GIC_SPI类型,状态关闭。有了设备树,还有了兼容设备号,接下来的一步就是根据设备号sun4i-a10-lradc-keys找到对应的驱动文件。
3、查找驱动代码,准备测试程序
通过工具查找一下,不难发现,文件在这,即sun4i-lradc-keys.c,
static const struct of_device_id sun4i_lradc_of_match[] = { { .compatible = "allwinner,sun4i-a10-lradc-keys", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match); static struct platform_driver sun4i_lradc_driver = { .driver = { .name = "sun4i-a10-lradc-keys", .of_match_table = of_match_ptr(sun4i_lradc_of_match), }, .probe = sun4i_lradc_probe, }; module_platform_driver(sun4i_lradc_driver); MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver"); MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); MODULE_LICENSE("GPL");
大致看一下最后一段的代码,内容方面应该错不了。一般来说,如果按键ok的话,会在设备启动的时候生成个/dev/input/event0节点,此时,如果编写一个应用程序,读写这些节点,就完全可以获取相关的按键信息。所以,我们还得准备一个input.c的读写程序,
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <linux/input.h> #include <linux/input-event-codes.h> const char * path = "/dev/input/event0"; int main(char argc,char *argv[]) { int ret; int fd; struct input_event event; fd = open(path,O_RDONLY); if(fd < 0) { perror(path); exit(-1); } while(1) { ret = read(fd,&event,sizeof(struct input_event)); if(ret == sizeof(struct input_event)) { if(event.type != EV_SYN) { printf("Event: time %ld.%ld,",event.time.tv_sec,event.time.tv_usec); printf("type:%d,code:%d,value:%d\n", event.type,event.code,event.value); } } } close(fd); return 0; }
上面这段代码是从其他地方copy而来,谢谢了。准备好了程序之后,下面就是交叉编译,下载到开发板上面。但是实际运行的时候,发现按键被按下的时候,有三个按键的数值居然是一样的,都是352,另外一个是114。这就非常蹊跷了。
4、发现问题、解决问题
一般情况下,遇到这种情况,第一个怀疑的就是电阻坏了,R24、R25、R26、R27当中肯定有三个被击穿了,不然这种情况是说不过去的。于是,我们拿掉sd卡,让v3s继续跑之前norflash里面的嵌入式系统,输入key程序,也就是按键测试程序,没想到结果居然是正常的。这说明,硬件,没问题。问题出在上层应用或者驱动程序。
回过头查看sun4i-lradc-keys.c,惊讶地发现电压判断标准是根据sun8i-v3s-licheepi-zero-dock.dts中的voltage来验证的,这并不符合实际的情况。我们通过printk&dmesg打印,也验证了这一想法,所以如果需要得到正确的按键数值,只需要修正一下sun4i-lradc-keys.c中的判断逻辑就可以了,修改方法如下,具体的标定数值可以做实验来解决,
#if 0 // by feixiaoxing voltage = val * lradc->vref / 63; for (i = 0; i < lradc->chan0_map_count; i++) { diff = abs(lradc->chan0_map[i].voltage - voltage); if (diff < closest) { closest = diff; keycode = lradc->chan0_map[i].keycode; } } #else printk("val = %d\n", val); if(val >=9 && val <= 13) keycode = lradc->chan0_map[0].keycode; else if(val >=24 && val <= 29) keycode = lradc->chan0_map[1].keycode; else if(val >= 35 && val <= 40) keycode = lradc->chan0_map[2].keycode; else keycode = lradc->chan0_map[3].keycode; #endif

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
一种实现Spring动态数据源切换的方法 | 京东云技术团队
1 目标 不在现有查询代码逻辑上做任何改动,实现dao维度的数据源切换(即表维度) 2 使用场景 节约bdp的集群资源。接入新的宽表时,通常uat验证后就会停止集群释放资源,在对应的查询服务器uat环境时需要查询的是生产库的表数据(uat库表因为bdp实时任务停止,没有数据落入),只进行服务器配置文件的改动而无需进行代码的修改变更,即可按需切换查询的数据源。 2.1 实时任务对应的集群资源 2.2 实时任务产生的数据进行存储的两套环境 2.3 数据使用系统的两套环境(查询展示数据) 即需要在zhongyouex-bigdata-uat中查询生产库的数据。 3 实现过程 3.1 实现重点 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource spring提供的这个类是本次实现的核心,能够让我们实现运行时多数据源的动态切换,但是数据源是需要事先配置好的,无法动态的增加数据源。 Spring提供的Aop拦截执行的mapper,进行切换判断并进行切换。 注:另外还有一个就是ThreadLocal类,用于保存每个...
- 下一篇
IoTOS v1.0.0 开源,高效 实用 | 免费商用
IoTOS v1.0.0 一款高效实用 IoTCard 管理 & 运营系统。 IoTOS 目前取名范围过大,其主要用于IoTCard 管理业务以高效、健壮、灵活设计 SaaS、多语言、机器人推送、自动化管理、数据同步多类型算法为主要业务。 一、 关于 IoTOS 1.1 介绍 IoTOS 是基于 SpringBoot、Vue、Mybatis、RabbitMq、Mysql、Redis 的开源 IoTCard(物联卡管理) 系统,是企业私域管理与运营的综合解决方案。 IoTOS 基于多个物联网管理系统API(如:中国移动 oneLink 等 后续接入API) 开放能力,不仅集成了上游强大的API管理及基础的 数据同步算法 功能,而且提供了多语言国际化方案。并通过 高效灵活的同步算法、系统构架业务分离 等灵活高效的数据运营模块,让企业与上游之间建立强链接,从而进一步通过多元化的管理运营方案,帮助企业提高物联网卡运营效率,强化运营能力,拓展科盈利空间。 目前主要运用于 物联网卡 服务行业领域。 1.2 能力 IoTOS-IoTCard 基于物联网多上游API接口综合业务管理,...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Hadoop3单机部署,实现最简伪集群
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8编译安装MySQL8.0.19
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)