- 论坛徽章:
- 0
|
本帖最后由 0vk0 于 2011-03-04 19:50 编辑
是个按键驱动,大家帮忙看一下,现在按键抬起可以检测到,但再按别的
我测试时老是出现:
当换一个按键时,会出现前一个按键,比如我按1时,按下会打印1,抬起会打印1,当我换按2时,第一遍按下会打印1,抬起会打印2,再第二遍的时候就不会了
当我换按5时,第一遍按下会打印2,抬起会打印5,再第二遍的时候也不会了,请帮帮忙看下程序,谢谢了,第二个是应该层的测试程序- #include <asm/gpio.h>
- #include <asm/jzsoc.h>
- ……
- #define DEVICE_NAME "keypad"
- #define MAX_KEY_COUNT 32
- #define HC164_CP 89 //kb2
- #define HC164_DS 88 //kb1
- #define INT_KEY1 93 //kb3
- #define INT_KEY2 91 //kb4
- #define KEY1_IRQ (IRQ_GPIO_0 + INT_KEY1)
- #define KEY2_IRQ (IRQ_GPIO_0 + INT_KEY2)
- typedef struct
- {
- unsigned long jiffy[MAX_KEY_COUNT];
- unsigned char buf[MAX_KEY_COUNT];
- unsigned int head,tail;
- }KEY_BUFFER;
- static KEY_BUFFER g_keyBuffer;
- static spinlock_t buffer_lock;
- static int Keypad_major = 255;
- int a=200,b=201;
- /*
- */
- static unsigned long GetTickCount(void)
- {
- struct timeval currTick;
- unsigned long ulRet;
- do_gettimeofday(&currTick);
- ulRet = currTick.tv_sec;
- ulRet *= 1000;
- ulRet += (currTick.tv_usec + 500) / 1000;
- return ulRet;
- }
- /*
- */
- static void init_keybuffer(void)
- {
- int i;
- spin_lock_irq(&buffer_lock);
- g_keyBuffer.head = 0;
- g_keyBuffer.tail = 0;
- for(i = 0; i < MAX_KEY_COUNT; i++)
- {
- g_keyBuffer.buf[i] = 0;
- g_keyBuffer.jiffy[i] = 0;
- }
- spin_unlock_irq(&buffer_lock);
- }
- /*
- */
- static void remove_timeoutkey(void)
- {
- unsigned long ulTick;
- spin_lock_irq(&buffer_lock);
- while(g_keyBuffer.head != g_keyBuffer.tail)
- {
- ulTick = GetTickCount() - g_keyBuffer.jiffy[g_keyBuffer.head];
- if (ulTick < 5000)
- break;
- g_keyBuffer.buf[g_keyBuffer.head] = 0;
- g_keyBuffer.jiffy[g_keyBuffer.head] = 0;
- g_keyBuffer.head ++;
- g_keyBuffer.head &= (MAX_KEY_COUNT -1);
- }
- spin_unlock_irq(&buffer_lock);
- }
- /*
- */
- void _74HC164Send(unsigned char d)
- {
- int j;
- for(j=0;j<8;j++)
- {
- if (d&1)
- __gpio_set_pin(HC164_DS);
- else
- __gpio_clear_pin(HC164_DS);
- mdelay(1);
- __gpio_set_pin(HC164_CP);
- mdelay(1);
- __gpio_clear_pin(HC164_CP);
- d >>= 1;
- }
- }
- /*
- */
- static void init_gpio(void)
- {
- __gpio_as_input(INT_KEY1);
- __gpio_as_input(INT_KEY2);
-
- __gpio_as_output(HC164_CP);
- __gpio_as_output(HC164_DS);
-
- __gpio_clear_pin(HC164_CP);
- __gpio_clear_pin(HC164_DS);
- _74HC164Send(0);
- }
- /*
- */
- static __inline void enable_irqs(void)
- {
- unsigned long flags;
- spin_lock_irqsave(buffer_lock, flags);
- __gpio_unmask_irq(INT_KEY1);
- __gpio_unmask_irq(INT_KEY2);
- spin_unlock_irqrestore(buffer_lock, flags);
- }
- /*
- */
- static __inline void disable_irqs(void)
- {
- unsigned long flags;
- spin_lock_irqsave(buffer_lock, flags);
- __gpio_mask_irq(INT_KEY1);
- __gpio_mask_irq(INT_KEY2);
- spin_unlock_irqrestore(buffer_lock, flags);
- }
- /*
- */
- static unsigned char num = 0;
- static __inline unsigned char button_scan(int irq)
- {
- unsigned char ret=0xff;
- unsigned char i;
- if(!(__gpio_get_pin(INT_KEY1)))
- {
- for(i=1;i<9;i++)
- {
- printk("i=%d\n",i);
- __gpio_set_pin(HC164_DS);
- mdelay(1);
- __gpio_set_pin(HC164_CP);
- mdelay(1);
- __gpio_clear_pin(HC164_CP);
- if(__gpio_get_pin(INT_KEY1))
- {
- num=i; //此处改动过
- return i;
- }
- }
- }
- else
- {
- if(!(__gpio_get_pin(INT_KEY2)))
- {
- for(i=1;i<9;i++)
- {
- printk("key2 i=%d\n",i);
- __gpio_set_pin(HC164_DS);
- mdelay(1);
- __gpio_set_pin(HC164_CP);
- mdelay(1);
- __gpio_clear_pin(HC164_CP);
- if(__gpio_get_pin(INT_KEY2))
- {
- num=i+8; //此处改动
- return i;
- }
- }
- }
- }
- return ret ;
- }
- /*
- *
- */
- static irqreturn_t button_down_irq(int irq, void *dev_id)
- {
- unsigned char ucKey;
- disable_irqs();
- udelay(1000);
- ucKey = button_scan(irq);
-
- if ((ucKey >= 1) && (ucKey <= 16))
- {
- if (((g_keyBuffer.head + 1) & (MAX_KEY_COUNT - 1)) != g_keyBuffer.tail)
- {
- spin_lock_irq(&buffer_lock);
- g_keyBuffer.buf[g_keyBuffer.tail] = ucKey;
- g_keyBuffer.jiffy[g_keyBuffer.tail] = GetTickCount();
- g_keyBuffer.tail ++;
- g_keyBuffer.tail &= (MAX_KEY_COUNT - 1);
- spin_unlock_irq(&buffer_lock);
- }
- }
-
- _74HC164Send(0);
- __gpio_ack_irq(INT_KEY1); // clear status
- __gpio_ack_irq(INT_KEY2); // clear status
- enable_irqs();
- return IRQ_HANDLED;
- }
- static irqreturn_t button_rise_irq(int irq, void *dev_id)
- {
- unsigned char ucKey;
- disable_irqs();
- udelay(1000);
- ucKey = num;
- // *****************************
- buttonup_scan();
-
- if ((ucKey >= 1) && (ucKey <= 16))
- {
- if (((g_keyBuffer.head + 1) & (MAX_KEY_COUNT - 1)) != g_keyBuffer.tail)
- {
- spin_lock_irq(&buffer_lock);
- g_keyBuffer.buf[g_keyBuffer.tail] = ucKey;
- g_keyBuffer.jiffy[g_keyBuffer.tail] = GetTickCount();
- g_keyBuffer.tail ++;
- g_keyBuffer.tail &= (MAX_KEY_COUNT - 1);
- spin_unlock_irq(&buffer_lock);
- }
- }
-
- _74HC164Send(0);
- __gpio_ack_irq(INT_KEY1); // clear status
- __gpio_ack_irq(INT_KEY2); // clear status
- enable_irqs();
- return IRQ_HANDLED;
- }
- /*
- *
- */
- static int request_irqs(void)
- {
- __gpio_as_irq_fall_edge(INT_KEY1); //下降沿发生中断
- __gpio_as_irq_fall_edge(INT_KEY2);
-
- __gpio_as_irq_rise_edge(INT_KEY1); //上升沿发生中断
- __gpio_as_irq_rise_edge(INT_KEY2);
- if(request_irq(KEY1_IRQ, button_rise_irq, IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &a)){
- printk("Could not allocate key1 IRQ:%d\n",KEY1_IRQ);
- return -EINVAL;
- }
- if(request_irq(KEY2_IRQ, button_rise_irq, IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &a)){
- free_irq(KEY1_IRQ, &a);
- printk("Could not allocate key2 IRQ:%d\n",KEY2_IRQ);
- return -EINVAL;
- }
-
- if(request_irq(KEY1_IRQ, button_down_irq, IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &b)){
- printk("Could not allocate key1 IRQ:%d\n",KEY1_IRQ);
- return -EINVAL;
- }
- if(request_irq(KEY2_IRQ, button_down_irq, IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &b)){
- free_irq(KEY1_IRQ, &b);
- printk("Could not allocate key2 IRQ:%d\n",KEY2_IRQ);
- return -EINVAL;
- }
-
- __gpio_ack_irq(INT_KEY1); // clear status
- __gpio_ack_irq(INT_KEY2); // clear status
- return 0;
- }
- /*
- *
- */
- static __inline void free_irqs(void)
- {
- free_irq(KEY1_IRQ, &a);
- free_irq(KEY1_IRQ, &b);
- free_irq(KEY2_IRQ, &a);
- free_irq(KEY2_IRQ, &b);
- }
- /*
- *
- */
- static int keypad_open(struct inode *inode,struct file *filp)
- {
- int ret = nonseekable_open(inode, filp);
- if (ret >= 0)
- {
- printk("keypad opened ret>0.\n");
- init_keybuffer();
- enable_irqs();
- }
- printk("keypad opened.\n");
- return ret;
- }
- /*
- *
- */
- static int keypad_release(struct inode *inode,struct file *filp)
- {
- disable_irqs();
- printk("keypad release.\n");
- return 0;
- }
- /*
- *
- */
- static ssize_t keypad_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
- {
- ssize_t ret = 0;
- remove_timeoutkey();
- spin_lock_irq(&buffer_lock);
- while((g_keyBuffer.head != g_keyBuffer.tail) && (((size_t)ret) < count) )
- {
- buffer[ret] = (char)(g_keyBuffer.buf[g_keyBuffer.head]);
- g_keyBuffer.buf[g_keyBuffer.head] = 0;
- g_keyBuffer.jiffy[g_keyBuffer.head] = 0;
- g_keyBuffer.head ++;
- g_keyBuffer.head &= (MAX_KEY_COUNT - 1);
- ret ++;
- }
- spin_unlock_irq(&buffer_lock);
- return ret;
- }
- /*
- *
- */
- static int keypad_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- init_keybuffer();
- return 1;
- }
- /*
- */
- static void led_setup_cdev(struct cdev *dev,int minor,struct file_operations *fops)
- {
- int err;
- int devno=MKDEV(Keypad_major,minor);
- cdev_init(dev,fops);
- dev->owner=THIS_MODULE;
- dev->ops=fops;
- err=cdev_add(dev,devno,1);
- if(err)
- printk(KERN_INFO"Error %d adding button %d\n",err,minor);
- }
- /*
- */
- static struct file_operations keypad_fops =
- {
- .owner = THIS_MODULE,
- .ioctl = keypad_ioctl,
- .open = keypad_open,
- .read = keypad_read,
- .release = keypad_release,
- };
- static struct cdev SimpleDevs;
- /*
- *
- */
- static int KeyPad_Init(void)
- {
- int ret;
- int result;
- dev_t dev;
- dev=MKDEV(Keypad_major,0);
- if(Keypad_major)
- result=register_chrdev_region(dev,1,DEVICE_NAME);
- else
- {
- result=alloc_chrdev_region(&dev,0,1,DEVICE_NAME);
- Keypad_major=MAJOR(dev);
- }
- if(result<0)
- {
- printk(KERN_WARNING"Keypad:unable to get major %d\n",Keypad_major);
- return result;
- }
- if(Keypad_major==0)
- Keypad_major=result;
- led_setup_cdev(&SimpleDevs,0,&keypad_fops);
- init_gpio();
- ret = request_irqs();
- if (ret < 0)
- {
- cdev_del(&SimpleDevs);
- unregister_chrdev_region(MKDEV(Keypad_major,0),1);
- return ret;
- }
- printk(KERN_INFO"keypad register ok!!!!!!!!!!\n");
- return 0;
- }
- /*
- *
- */
- static void __exit KeyPad_Exit(void)
- {
- disable_irqs();
- free_irqs();
- cdev_del(&SimpleDevs);
- unregister_chrdev_region(MKDEV(Keypad_major,0),1);
- printk("button device uninstalled\n");
- }
- module_init(KeyPad_Init);
- module_exit(KeyPad_Exit);
- MODULE_AUTHOR("zhyh");
- MODULE_DESCRIPTION("keypad driver");
- MODULE_LICENSE("GPL");
复制代码 |
|