Lover雪儿
想念时,就看看天空,无论距离有多远,我们总在同一片天空下!

20150303 IMX257 输入子系统(二)之键盘模拟

2015-03-03 李海沿

前面我们已经详细介绍了基本的知识:地址http://www.cnblogs.com/lihaiyan/p/4309329.html

接下来,我们使用IMX257的IO引脚中断+Linux输入子系统实现一个模拟键盘按键。实现的效果是,我们使用IO模拟按键L、按键S和Enter键 这三个按键。

 

这次我们就不再多废话了,直接上程序,大家看代码:

 实验效果图:

 如图所示: 我们依次按下三个按键

第一个按键 显示的键值为 38   ,也就是我们的L键

第二个按键  31   自然就是S 键

第三个按键  28  自然就是enter键

驱动代码:

  1 /******************************
  2     linux key_inputSystem
  3  *****************************/
  4 #include <linux/module.h>  
  5 #include <linux/init.h>  
  6 #include <linux/fs.h>  
  7 #include <linux/interrupt.h>  
  8 #include <linux/irq.h>  
  9 #include <linux/sched.h>  
 10 #include <linux/pm.h>  
 11 #include <linux/sysctl.h>  
 12 #include <linux/proc_fs.h>  
 13 #include <linux/delay.h>  
 14 #include <linux/input.h>  
 15   
 16 #include <mach/hardware.h>  
 17 
 18 
 19 #include "mx257_gpio.h"
 20 #include "mx25_pins.h"
 21 #include "iomux.h"
 22 
 23 #define Driver_NAME "key_input"
 24 
 25 #define GPIO2_9     MX25_PIN_A23
 26 #define GPIO2_10    MX25_PIN_A24
 27 #define GPIO2_11    MX25_PIN_A25
 28 
 29 //定义各个按键按下的键值
 30 struct pin_desc{
 31     unsigned int pin;
 32     char *name;
 33     unsigned int key_val;
 34 };
 35 //当按键按下时,键值分别为 以下值
 36 struct pin_desc pins_desc[3] = {
 37     {GPIO2_9,  "KEY_L_9",    KEY_L},
 38     {GPIO2_10,  "KEY_R_10",    KEY_S},
 39     {GPIO2_11, "KEY_Enter_11",    KEY_ENTER},
 40 };
 41 
 42 static struct input_dev *key_input_dev;//输入子系统设备结构体
 43 static struct timer_list key_timer;    //定时器结构体
 44 static struct pin_desc *pin_desc_irq; //保存发生中断的引脚信息
 45 
 46 //定时器到时函数
 47 static int key_timer_function(unsigned long data){    
 48     struct pin_desc *pin_desc_tmp = pin_desc_irq;    //发生中断的引脚信息
 49     unsigned int pinval_tmp;        //按键键值缓冲
 50     if(!pin_desc_tmp)
 51         return 0;
 52     pinval_tmp = gpio_get_value(IOMUX_TO_GPIO(pin_desc_tmp->pin));//获取键值
 53     if(pinval_tmp){
 54         //松开 :0   按下:1
 55         input_event(key_input_dev,EV_KEY,pin_desc_tmp->key_val ,0);
 56         input_sync(key_input_dev);                //报告完毕,通知接收者
 57     }else{
 58         input_event(key_input_dev,EV_KEY,pin_desc_tmp->key_val ,1);
 59         input_sync(key_input_dev);                //报告完毕,通知接收者
 60     }
 61     return 0;
 62 }
 63 /* 中断程序key_irq */
 64 static irqreturn_t key_irq_function(int irq, void *dev_id)
 65 {
 66     pin_desc_irq = (struct pin_desc *)dev_id; //获取中断引脚的信息
 67     mod_timer(&key_timer,jiffies+HZ/50);    //开启定时器,时间20ms
 68 
 69     return IRQ_RETVAL(IRQ_HANDLED);
 70 }
 71 //初始化函数
 72 static int __init  key_input_init(void)
 73  {
 74     printk("<0>\nHello,this is %s module!\n\n",Driver_NAME);
 75       
 76     mxc_request_iomux(GPIO2_9, MUX_CONFIG_ALT5);//设备引脚为GPIO模式
 77     mxc_request_iomux(GPIO2_10, MUX_CONFIG_ALT5);//设备引脚为GPIO模式
 78     mxc_request_iomux(GPIO2_11, MUX_CONFIG_ALT5);//设备引脚为GPIO模式
 79      gpio_request(IOMUX_TO_GPIO(GPIO2_9), "GPIO2_9");//申请IO端口使用
 80      gpio_request(IOMUX_TO_GPIO(GPIO2_10), "GPIO2_10");//申请IO端口使用
 81      gpio_request(IOMUX_TO_GPIO(GPIO2_11), "GPIO2_11");//申请IO端口使用
 82     gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));//设备引脚为输入
 83     gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));//设备引脚为输入
 84     gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));//设备引脚为输入
 85     //设备引脚为上拉输入
 86     mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU);
 87     mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU);
 88     mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU);
 89     //申请中断
 90     if(request_irq(IOMUX_TO_IRQ(GPIO2_9), key_irq_function, IRQF_TRIGGER_FALLING, "key_GPIO2_9", &pins_desc[0]))
 91         return -1;
 92     if(request_irq(IOMUX_TO_IRQ(GPIO2_10), key_irq_function, IRQF_TRIGGER_FALLING, "key_GPIO2_10", &pins_desc[1]))
 93         return -1;
 94     if(request_irq(IOMUX_TO_IRQ(GPIO2_11), key_irq_function, IRQF_TRIGGER_FALLING, "key_GPIO2_11", &pins_desc[2]))
 95         return -1;
 96     
 97     //input输入子系统设置
 98     key_input_dev = input_allocate_device();//分配一个input_dev结构体
 99     //设置能产生哪些事件
100     set_bit(EV_KEY, key_input_dev->evbit); //按键事件
101     set_bit(KEY_L, key_input_dev->keybit); // L键 按键
102     set_bit(KEY_S, key_input_dev->keybit); // S键 按键
103     set_bit(KEY_ENTER, key_input_dev->keybit); // ENTER键 按键
104     set_bit(KEY_LEFTSHIFT, key_input_dev->keybit); // LEFTSHIFT键 按键
105     //注册
106     input_register_device(key_input_dev);
107 
108     init_timer(&key_timer);    //初始化定时器
109     key_timer.function = &key_timer_function;    //设置定时器处理函数
110     add_timer(&key_timer);    //将该定时器加入内核
111     
112     printk("<0>have setting all pins to gpio interrupt mod by IRQF_TRIGGER_FALLING !\n");
113     printk("Input system initialize successfu!\n\n");
114     return 0;
115 }
116 //exit
117 static void __exit key_input_exit(void)
118 {
119     printk("<0>\nGoodbye,%s!\n\n",Driver_NAME);
120     /* free gpios */
121     free_irq(IOMUX_TO_IRQ(GPIO2_9),  &pins_desc[0]);
122     free_irq(IOMUX_TO_IRQ(GPIO2_10),  &pins_desc[1]);
123     free_irq(IOMUX_TO_IRQ(GPIO2_11),  &pins_desc[2]);
124     mxc_free_iomux(GPIO2_9, MUX_CONFIG_ALT5);
125     mxc_free_iomux(GPIO2_10, MUX_CONFIG_ALT5);
126     mxc_free_iomux(GPIO2_11, MUX_CONFIG_ALT5);
127     gpio_free(IOMUX_TO_GPIO(GPIO2_9));
128     gpio_free(IOMUX_TO_GPIO(GPIO2_10));
129     gpio_free(IOMUX_TO_GPIO(GPIO2_11));
130 
131     del_timer(&key_timer);        //删除定时器
132     input_unregister_device(key_input_dev);    //注销驱动
133     input_free_device(key_input_dev);        //释放结构体内存
134     printk("Input system unregister successfu!\n\n");
135 }
136 
137 /* 这两行指定驱动程序的初始化函数和卸载函数 */
138 module_init(key_input_init);
139 module_exit(key_input_exit);
140 
141 /* 描述驱动程序的一些信息,不是必须的 */
142 MODULE_AUTHOR("Lover雪");
143 MODULE_VERSION("0.1.0");
144 MODULE_DESCRIPTION("IMX257 key Driver");
145 MODULE_LICENSE("GPL");

 

 

应用程序代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 #include <sys/stat.h>
 6 #include <fcntl.h>
 7 #include <termios.h>
 8 #include <errno.h>
 9 #include <limits.h>
10 #include <time.h>
11 #include <linux/input.h>
12 #include "mx257_gpio.h"
13 
14 
15 int main(int argc, char **argv)
16 {
17     int fd;
18     int key_value,i=0,count;
19     struct input_event ev_key;
20     
21     fd = open("/dev/input/event1",O_RDWR);
22     if(fd < 0){
23         printf("can't open !!!\n");
24         exit(1);
25     }
26     printf("open successful!\n");
27     while(1){
28         count = read(fd,&ev_key,sizeof(struct input_event));
29         for(i = 0; i<(int)count/sizeof(struct input_event); i++){
30             if(EV_KEY == ev_key.type)
31                 printf("type: %d ,code: %d ,value: %d \n",ev_key.type, ev_key.code,ev_key.value);
32             if(EV_SYN == ev_key.type)
33                 printf("syn event\n\n");
34         }
35     }
36     close(fd);
37     return 0;
38 }

 

posted on 2015-03-03 22:36  Lover雪儿  阅读(267)  评论(0编辑  收藏  举报