最近,产品基本定型了,所以开始着手升级版。说是升级版,只是在操作上面有所修改。产品需要使用旋钮进行人机交互。对linux驱动十窍通了九窍,一窍不通,所以从最低级的开始看起,然后把gpio_key.c这个东西,看了一遍又一遍。都快看吐了

首先修改设备树文件,这个东西是linux3.0的新东西,弄的我无限糊涂,到现在依然糊涂。我只能稍微修改一点需要的东西,让我写肯定写不出来。以后再慢慢研究。在这个文件的KEY_X0里面,把对应的,改成。因为是使用设备树这种方式,所以需要修改对应的gpio_keys_get_devtree_pdata这个函数,

修改以上两处,这个函数的改动就结束了。这样改完编译会发现有错误,因为button里面没有ckgpio这些东西。所以修改对应linux目录中include/linux/gpio_key.h

struct gpio_keys_button {/* Configuration parameters */unsigned int code;    /* input event code (KEY_*, SW_*) */int gpio;       /* -1 if this key does not support gpio */int active_low;const char *desc;unsigned int type;    /* input event type (EV_KEY, EV_SW, EV_ABS) */int wakeup;       /* configure the button as a wake-up source */int debounce_interval;    /* debounce ticks interval in msecs */bool can_disable;int value;       /* axis value for EV_ABS */unsigned int irq;    /* Irq number in case of interrupt keys */
};

改成:

struct gpio_keys_button {/* Configuration parameters */unsigned int code;    /* input event code (KEY_*, SW_*) */int gpio;       /* -1 if this key does not support gpio */int active_low;const char *desc;unsigned int type;    /* input event type (EV_KEY, EV_SW, EV_ABS) */int wakeup;       /* configure the button as a wake-up source */int debounce_interval;    /* debounce ticks interval in msecs */bool can_disable;int value;       /* axis value for EV_ABS */unsigned int irq;    /* Irq number in case of interrupt keys */<span style="color:#ff0000;">int ckgpio; /*zxf*/     保存旋转编码器的另外一个引脚</span>
<span style="color:#33ff33;">  unsigned int oldcode;   记录原始键值</span><span style="color:#000099;">unsigned int ckcode; /*zxf*/ 记录新键值</span>
};

这样设备树就修改完了。

接下来修改中断触发方式,我只需下降沿,就可以判断是正转还是反转了,所以:

<span style="white-space:pre">  </span>if (button->ckgpio != button->gpio)irqflags = IRQF_TRIGGER_FALLING;对应旋钮部分elseirqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;对应按键部分

因为ec11这种东西有旋钮部分,也有按钮部分,所以把对应的中断响应函数进行了区分,按钮部分不动,旋钮部分改成:

static irqreturn_t gpio_knob_gpio_isr(int irq, void *dev_id)
{struct gpio_button_data *bdata = dev_id;BUG_ON(irq != bdata->irq);if(gpio_get_value(bdata->button->ckgpio) )<span style="color:#ff0000;">判断对应的另外一个引脚电平状态。</span>bdata->button->code = bdata->button->oldcode;elsebdata->button->code = bdata->button->ckcode;//printk(KERN_ALERT"gpio:%d, ckgpio:%d, check=%d", bdata->button->gpio, bdata->button->ckgpio,bdata->button->check);if (bdata->timer_debounce)mod_timer(&bdata->timer,jiffies + msecs_to_jiffies(bdata->timer_debounce));elseschedule_work(&bdata->work);return IRQ_HANDLED;
}

中断分为上半部分,和下半部分,上述代码是中断的上半部分。功能就是检测另外一个引脚的点评状态,并给code赋不同的键值。

中断的下半部分,事件上报函数改成:

static void gpio_knob_gpio_report_event(struct gpio_button_data *bdata)
{struct gpio_keys_button *button = bdata->button;struct input_dev *input = bdata->input;unsigned int type = button->type ?: EV_KEY;<span style="background-color: rgb(51, 51, 255);">input_event(input, type, button->code, 1);</span>
<span style="background-color: rgb(51, 51, 255);">  //printk(KERN_ALERT"type:%d,code:%d\n", type,button->code);input_sync(input);</span><span style="background-color: rgb(255, 0, 0);">input_event(input, type, button->code, 0);//printk(KERN_ALERT"type:%d,code:%d\n", type,button->code);
<span style="white-space:pre"> </span>input_sync(input);</span>
}

可以看到这里面有两条重复的语句,原因是按键有按下和放开两个状态,而我的旋钮,我值捕捉到了下降沿,所以上升沿部分我自己编造一个,反正内核不知道我是认为编造的。红色部分很重要,如果只有蓝色部分,那就相当于按键一直按下,而没有弹起。cat event*会发现一直不停的输出。我在这就卡了两天,因为没有好好理解什么是key。

中断部分修改完了以后,修改gpio_keys_setup_key()函数。

if (gpio_is_valid(button->gpio)) {error = gpio_request(button->gpio, desc);if (error < 0) {dev_err(dev, "Failed to request GPIO %d, error %d\n",button->gpio, error);return error;}if (button->ckgpio != button->gpio){error = gpio_request(button->ckgpio, desc);if (error < 0) {dev_err(dev, "Failed to request GPIO %d, error %d\n",button->ckgpio, error);return error;}}error = gpio_direction_input(button->gpio);if (error < 0) {dev_err(dev,"Failed to configure direction for GPIO %d, error %d\n",button->gpio, error);goto fail;}if (button->ckgpio != button->gpio){error = gpio_direction_input(button->ckgpio);if (error < 0) {dev_err(dev,"Failed to configure direction for GPIO %d, error %d\n",button->ckgpio, error);goto fail;}}

就是增加了对旋钮部分按键的配置操作。

现在编译应该可以通过,使用hexdump测试event会发现,只有一个方向的旋转才有输出。另一个方向是没有反映的,通过跟踪代码发现,是在input_handle_event()函数出现的问题:

case EV_KEY:       if (<span style="color:#ff0000;">is_event_supported(code, dev->keybit, KEY_MAX)</span> &&!!test_bit(code, dev->key) != value) {if (value != 2) {__change_bit(code, dev->key);if (value)input_start_autorepeat(dev, code);elseinput_stop_autorepeat(dev);}disposition = INPUT_PASS_TO_HANDLERS;}break;

红色部分就是跟踪后发现问题的地方,另一个方向旋转并不能进入到这个if语句中,再继续跟踪发现:

static inline int is_event_supported(unsigned int code, unsigned long *bm, unsigned int max)
{return code <= max && <span style="color:#ff0000;">test_bit(code, bm)</span>;
}

这个函数的test_bit函数出的问题,它会测试input_dev是否支持这个键值。这个地方卡了我两周的时间,因为不了解linux的输入子系统。我现在还不知道,可以上报的那个键值是在哪设置的,有知道的前辈请不吝告诉我。为了让input_dev支持另外一个键值,在gpio_keys_setup_key()函数增加如下代码:

set_bit(button->ckcode, input->keybit);

这样就可以了。
这个事情进行到一半的时候,想过自己重新写。可是真的没有信心能写出来,这个事情我还欠缺很多。把原文件也是弄得面目全非。以后再继续学习把。

让linux支持EC11等旋转编码器相关推荐

  1. EC11代码 旋转编码器

    一.硬件部分 1.EC11硬件和时序 硬件不详细叙述,RC滤波一定要加,不然检测不准. A为上升沿时,B为高电平.顺时针 A为下升沿时,B为低电平.顺时针 A为上升沿时,B为低电平.逆时针 A为下升沿 ...

  2. 认识EC11旋转编码器编写驱动程序

    前言 抛开工作,以电子爱好者的身份,单片机玩多了都会想着在单片机的外围设备玩出一些花样来. 这其中首先想到的就是"升级"输入输出设备. 这里先说一说我们常给单片机使用的输入设备. ...

  3. linux4.6 EC11旋转编码器的驱动

    最近项目使用了旋转编码器EC11,遍查内核,发现并没有它的驱动,查了查CSDN,终于找到一篇有用的.根据自己的需要和对最基础的gpio_key.c的理解,我改写出了一份EC11的专用驱动. 感谢下面博 ...

  4. 【STM32F4系列】【HAL库】旋转编码器(EC11)

    目录 概述 电气连接 波形分析 思路 HAL初始化 代码 成品 概述 EC11是一种增量型AB相旋转编码器 旋转编码器是一种可以无限旋转的旋钮,常被作为各种需要大量数据范围的情况(如收音机选台,音量选 ...

  5. linux 旋转编码器,基于ARM_Linux的旋转编码器接口与驱动程序的设计

    旋转编码器作为速度和位移反馈的传感器,广泛应用于 角位移或角速率的测量,通常有A,B,Z 三相输出.目前,在 实际的应用中,旋转编码器多与PLC.单片机.PC 联合组成控 制采集系统,如文献[1 - ...

  6. 旋钮编码器c代码_旋转编码器EC11驱动

    旋转编码器EC11驱动 /*-------->>>>>>>>--------注意事项:EC11旋转编码器的扫描时间间隔控制在1~4ms之间, 否则5ms ...

  7. 旋转编码器EC11调试心得

    手头的旋转编码器为20格一定位一脉冲,在静止的时候AB两线输出都是高电平.转动一格,AB两线各自输出一个低电平脉冲,然后又回到高电平状态.对应于EC11内部AB两个触点开关的动作为断开–>闭合– ...

  8. EC11旋转编码器驱动程序

    EC11驱动程序 不多做介绍,百度上很多相关的介绍 首先,放上参考文档 代码有正转.反转.按下正转.按下反转.单机.双击.长按和长安松手检测,有什么问题可以在下方留言 我是对该文档代码进行一些修改,偏 ...

  9. 使用Arduino开发板连接ec11旋转编码器

    使用Arduino开发板连接ec11旋转编码器 因为最近要用到旋转编码器,从网上花了好长时间找了好多关于arduino使用旋转编码器的资料,总是找不到合适的,最后总结了一下(部分内容有借鉴,仅作分享, ...

最新文章

  1. 蜻蜓大脑算法速度超快,AI科学家:拿来吧你
  2. 下属能否提拔,关键就看这10条!庸才是毒瘤,宁可错杀不可错用
  3. Clipboard.js:不用Flash实现剪贴板功能的轻量级JavaScript库
  4. ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)G GCD Guessing Game
  5. 【Android 修炼手册】常用技术篇 -- Android 自定义 View
  6. linux增加调整虚拟内存
  7. 1477: 青蛙的约会
  8. Python 3 学习——函数扩展and迭代器生成器装饰器
  9. java steam filter 动态条件_Filter解决全站编码问题
  10. STM32学习:串口通讯(proteus仿真)
  11. matlab 线性规划求最大值,MATLAB求解线性规划(含整数规划和01规划)问题.pdf
  12. Nagios 3 Centreon 2 RC5 安装与配置(1)
  13. 模拟游戏--鸭子的种类
  14. 【NUAAOS实验job3】
  15. 【翻译】MED 3D: TRANSFER LEARNING FOR 3D MEDICAL I MAGE ANALYSIS
  16. Android Things:让你陌生的面包板
  17. ENSP实验六——三层交换机+路由器
  18. 为什么上传速度比下载速度慢
  19. RK3568平台开发系列讲解(USB篇)libusb流程简介
  20. http://www.cnblogs.com/wayfarer/archive/2004/09/29/47896.html

热门文章

  1. 基于高云FPGA的FM调制与解调
  2. pt 2021创意 3D贴图绘画和投影工具Substance 3D Painter
  3. 视频教程-HTML5和CSS3移动端开发全套教程-HTML5/CSS
  4. matlab降压启动,基于Matlab的笼形异步电动机降压启动分析
  5. 使用Appuim+Python脚本实现Android应用自动登录
  6. 曾鸣《智能商业》- 读书笔记
  7. 5G的到来,真正受益的应该是数据中心
  8. [附源码]JAVA+ssm计算机毕业设计电影院订票管理系统(程序+Lw)
  9. SAP-S4HANA中新增的委外销售订单库存怎么玩
  10. 多线程CountDownLatch