免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3129 | 回复: 3

今天小心奕奕的把代码拷出来,是个按键驱动,大家帮忙看一下 [复制链接]

论坛徽章:
0
发表于 2011-03-04 19:46 |显示全部楼层
本帖最后由 0vk0 于 2011-03-04 19:50 编辑

是个按键驱动,大家帮忙看一下,现在按键抬起可以检测到,但再按别的



我测试时老是出现:
     
      当换一个按键时,会出现前一个按键,比如我按1时,按下会打印1,抬起会打印1,当我换按2时,第一遍按下会打印1,抬起会打印2,再第二遍的时候就不会了


      当我换按5时,第一遍按下会打印2,抬起会打印5,再第二遍的时候也不会了,请帮帮忙看下程序,谢谢了,第二个是应该层的测试程序
  1. #include <asm/gpio.h>
  2. #include <asm/jzsoc.h>
  3. ……

  4. #define DEVICE_NAME "keypad"
  5. #define    MAX_KEY_COUNT  32                                    

  6. #define HC164_CP       89     //kb2
  7. #define HC164_DS       88     //kb1
  8. #define INT_KEY1       93     //kb3
  9. #define INT_KEY2       91     //kb4

  10. #define KEY1_IRQ       (IRQ_GPIO_0 + INT_KEY1)
  11. #define KEY2_IRQ       (IRQ_GPIO_0 + INT_KEY2)
  12. typedef struct
  13. {
  14.     unsigned long jiffy[MAX_KEY_COUNT];  
  15.     unsigned char buf[MAX_KEY_COUNT];   
  16.     unsigned int head,tail;                 
  17. }KEY_BUFFER;

  18. static KEY_BUFFER g_keyBuffer;   
  19. static spinlock_t buffer_lock;

  20. static int   Keypad_major = 255;

  21. int a=200,b=201;

  22. /*
  23. */
  24. static unsigned long GetTickCount(void)
  25. {
  26.     struct timeval currTick;
  27.     unsigned long ulRet;

  28.     do_gettimeofday(&currTick);
  29.     ulRet = currTick.tv_sec;
  30.     ulRet *= 1000;
  31.     ulRet += (currTick.tv_usec + 500) / 1000;
  32.     return ulRet;
  33. }

  34. /*
  35. */
  36. static void init_keybuffer(void)
  37. {
  38.     int i;
  39.     spin_lock_irq(&buffer_lock);
  40.     g_keyBuffer.head = 0;
  41.     g_keyBuffer.tail = 0;
  42.     for(i = 0; i < MAX_KEY_COUNT; i++)
  43.     {
  44.         g_keyBuffer.buf[i] = 0;
  45.         g_keyBuffer.jiffy[i] = 0;
  46.     }
  47.     spin_unlock_irq(&buffer_lock);
  48. }

  49. /*
  50. */
  51. static void remove_timeoutkey(void)
  52. {
  53.     unsigned long ulTick;

  54.     spin_lock_irq(&buffer_lock);
  55.     while(g_keyBuffer.head != g_keyBuffer.tail)
  56.     {
  57.         ulTick = GetTickCount() - g_keyBuffer.jiffy[g_keyBuffer.head];
  58.         if (ulTick  < 5000)   
  59.             break;
  60.         g_keyBuffer.buf[g_keyBuffer.head] = 0;
  61.         g_keyBuffer.jiffy[g_keyBuffer.head] = 0;
  62.         g_keyBuffer.head ++;
  63.         g_keyBuffer.head &= (MAX_KEY_COUNT -1);
  64.     }
  65.     spin_unlock_irq(&buffer_lock);
  66. }
  67. /*
  68. */
  69. void _74HC164Send(unsigned char d)
  70. {
  71.         int j;

  72.         for(j=0;j<8;j++)
  73.         {
  74.                 if (d&1)
  75.                         __gpio_set_pin(HC164_DS);
  76.                 else
  77.                         __gpio_clear_pin(HC164_DS);

  78.                 mdelay(1);
  79.                 __gpio_set_pin(HC164_CP);
  80.                 mdelay(1);
  81.                 __gpio_clear_pin(HC164_CP);

  82.                  d >>= 1;
  83.         }
  84. }

  85. /*
  86. */
  87. static void init_gpio(void)
  88. {
  89.           __gpio_as_input(INT_KEY1);
  90.         __gpio_as_input(INT_KEY2);
  91.   
  92.         __gpio_as_output(HC164_CP);
  93.         __gpio_as_output(HC164_DS);
  94.    
  95.         __gpio_clear_pin(HC164_CP);
  96.         __gpio_clear_pin(HC164_DS);

  97.          _74HC164Send(0);
  98. }

  99. /*
  100. */
  101. static __inline void enable_irqs(void)
  102. {
  103.         unsigned long flags;

  104.         spin_lock_irqsave(buffer_lock, flags);
  105.         __gpio_unmask_irq(INT_KEY1);
  106.         __gpio_unmask_irq(INT_KEY2);
  107.         spin_unlock_irqrestore(buffer_lock, flags);

  108. }

  109. /*
  110. */
  111. static __inline void disable_irqs(void)
  112. {
  113.         unsigned long flags;

  114.         spin_lock_irqsave(buffer_lock, flags);
  115.         __gpio_mask_irq(INT_KEY1);
  116.         __gpio_mask_irq(INT_KEY2);
  117.         spin_unlock_irqrestore(buffer_lock, flags);
  118. }

  119. /*
  120. */
  121. static unsigned char num = 0;
  122. static __inline unsigned char button_scan(int irq)
  123. {
  124.      unsigned char ret=0xff;
  125.      unsigned char i;

  126.     if(!(__gpio_get_pin(INT_KEY1)))
  127.     {
  128.      for(i=1;i<9;i++)
  129.      {
  130.          printk("i=%d\n",i);
  131.          __gpio_set_pin(HC164_DS);
  132.          mdelay(1);
  133.          __gpio_set_pin(HC164_CP);
  134.          mdelay(1);
  135.          __gpio_clear_pin(HC164_CP);
  136.          if(__gpio_get_pin(INT_KEY1))
  137.          {
  138.                         num=i;            //此处改动过
  139.                         return i;
  140.          }
  141.      }
  142.     }
  143.     else
  144.     {
  145.        if(!(__gpio_get_pin(INT_KEY2)))
  146.        {
  147.           for(i=1;i<9;i++)
  148.           {
  149.          printk("key2 i=%d\n",i);
  150.             __gpio_set_pin(HC164_DS);
  151.             mdelay(1);
  152.             __gpio_set_pin(HC164_CP);
  153.             mdelay(1);
  154.             __gpio_clear_pin(HC164_CP);
  155.             if(__gpio_get_pin(INT_KEY2))
  156.             {
  157.                num=i+8;             //此处改动
  158.                return i;            
  159.             }
  160.           }
  161.        }
  162.     }
  163.     return ret ;
  164. }

  165. /*
  166. *
  167. */
  168. static irqreturn_t button_down_irq(int irq, void *dev_id)
  169. {
  170.     unsigned char ucKey;
  171.   disable_irqs();
  172.   udelay(1000);
  173.     ucKey = button_scan(irq);      
  174.    
  175.     if ((ucKey >= 1) && (ucKey <= 16))
  176.     {
  177.         if (((g_keyBuffer.head + 1) & (MAX_KEY_COUNT - 1)) != g_keyBuffer.tail)
  178.         {
  179.             spin_lock_irq(&buffer_lock);
  180.             g_keyBuffer.buf[g_keyBuffer.tail] = ucKey;
  181.             g_keyBuffer.jiffy[g_keyBuffer.tail] = GetTickCount();
  182.             g_keyBuffer.tail ++;
  183.             g_keyBuffer.tail &= (MAX_KEY_COUNT - 1);
  184.             spin_unlock_irq(&buffer_lock);
  185.         }
  186.     }
  187.    
  188.     _74HC164Send(0);
  189.     __gpio_ack_irq(INT_KEY1); // clear status
  190.     __gpio_ack_irq(INT_KEY2); // clear status
  191.     enable_irqs();

  192.     return IRQ_HANDLED;
  193. }

  194. static irqreturn_t button_rise_irq(int irq, void *dev_id)
  195. {
  196.     unsigned char ucKey;
  197.     disable_irqs();
  198.     udelay(1000);
  199.     ucKey = num;
  200.     // *****************************
  201.     buttonup_scan();
  202.    
  203.     if ((ucKey >= 1) && (ucKey <= 16))
  204.     {
  205.         if (((g_keyBuffer.head + 1) & (MAX_KEY_COUNT - 1)) != g_keyBuffer.tail)
  206.         {
  207.             spin_lock_irq(&buffer_lock);
  208.             g_keyBuffer.buf[g_keyBuffer.tail] = ucKey;
  209.             g_keyBuffer.jiffy[g_keyBuffer.tail] = GetTickCount();
  210.             g_keyBuffer.tail ++;
  211.             g_keyBuffer.tail &= (MAX_KEY_COUNT - 1);
  212.             spin_unlock_irq(&buffer_lock);
  213.         }
  214.     }
  215.    
  216.     _74HC164Send(0);
  217.     __gpio_ack_irq(INT_KEY1); // clear status
  218.     __gpio_ack_irq(INT_KEY2); // clear status
  219.     enable_irqs();

  220.     return IRQ_HANDLED;
  221. }

  222. /*
  223. *
  224. */
  225. static int request_irqs(void)
  226. {
  227.    __gpio_as_irq_fall_edge(INT_KEY1);         //下降沿发生中断
  228.    __gpio_as_irq_fall_edge(INT_KEY2);
  229.   
  230.    __gpio_as_irq_rise_edge(INT_KEY1);           //上升沿发生中断
  231.    __gpio_as_irq_rise_edge(INT_KEY2);

  232.               if(request_irq(KEY1_IRQ, button_rise_irq, IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &a)){
  233.                 printk("Could not allocate key1 IRQ:%d\n",KEY1_IRQ);
  234.                 return -EINVAL;
  235.    }
  236.    if(request_irq(KEY2_IRQ, button_rise_irq,  IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &a)){
  237.                 free_irq(KEY1_IRQ, &a);
  238.                 printk("Could not allocate key2 IRQ:%d\n",KEY2_IRQ);
  239.                 return -EINVAL;
  240.                 }
  241.                
  242.                    if(request_irq(KEY1_IRQ, button_down_irq,  IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &b)){
  243.                 printk("Could not allocate key1 IRQ:%d\n",KEY1_IRQ);
  244.                 return -EINVAL;
  245.    }
  246.    if(request_irq(KEY2_IRQ, button_down_irq,  IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &b)){
  247.                 free_irq(KEY1_IRQ, &b);
  248.                 printk("Could not allocate key2 IRQ:%d\n",KEY2_IRQ);
  249.                 return -EINVAL;
  250.                 }
  251.                         
  252.    __gpio_ack_irq(INT_KEY1); // clear status
  253.    __gpio_ack_irq(INT_KEY2); // clear status
  254.     return 0;
  255. }

  256. /*
  257. *
  258. */
  259. static __inline void free_irqs(void)
  260. {
  261.     free_irq(KEY1_IRQ, &a);
  262.     free_irq(KEY1_IRQ, &b);
  263.     free_irq(KEY2_IRQ, &a);
  264.     free_irq(KEY2_IRQ, &b);
  265. }
  266. /*
  267. *
  268. */
  269. static int keypad_open(struct inode *inode,struct file *filp)
  270. {
  271.     int ret = nonseekable_open(inode, filp);
  272.     if (ret >= 0)
  273.     {
  274.     printk("keypad opened ret>0.\n");
  275.         init_keybuffer();
  276.         enable_irqs();
  277.     }
  278.     printk("keypad opened.\n");
  279.     return ret;
  280. }

  281. /*
  282. *
  283. */
  284. static int keypad_release(struct inode *inode,struct file *filp)
  285. {
  286.     disable_irqs();
  287.     printk("keypad release.\n");
  288.     return 0;
  289. }

  290. /*
  291. *
  292. */
  293. static ssize_t keypad_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
  294. {
  295.     ssize_t ret = 0;

  296.     remove_timeoutkey();
  297.     spin_lock_irq(&buffer_lock);
  298.     while((g_keyBuffer.head != g_keyBuffer.tail) && (((size_t)ret) < count) )
  299.     {
  300.         buffer[ret] = (char)(g_keyBuffer.buf[g_keyBuffer.head]);
  301.         g_keyBuffer.buf[g_keyBuffer.head] = 0;
  302.         g_keyBuffer.jiffy[g_keyBuffer.head] = 0;
  303.         g_keyBuffer.head ++;
  304.         g_keyBuffer.head &= (MAX_KEY_COUNT - 1);
  305.         ret ++;
  306.     }
  307.     spin_unlock_irq(&buffer_lock);
  308.     return ret;
  309. }

  310. /*
  311. *
  312. */
  313. static int keypad_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  314. {
  315.     init_keybuffer();
  316.     return 1;
  317. }

  318. /*
  319. */
  320. static void led_setup_cdev(struct cdev *dev,int minor,struct file_operations *fops)
  321. {
  322.     int err;
  323.     int devno=MKDEV(Keypad_major,minor);
  324.     cdev_init(dev,fops);
  325.     dev->owner=THIS_MODULE;
  326.     dev->ops=fops;
  327.     err=cdev_add(dev,devno,1);
  328.     if(err)
  329.     printk(KERN_INFO"Error %d adding button %d\n",err,minor);
  330. }
  331. /*
  332. */
  333. static struct file_operations keypad_fops =
  334. {
  335.     .owner = THIS_MODULE,
  336.     .ioctl = keypad_ioctl,
  337.     .open = keypad_open,
  338.     .read = keypad_read,
  339.     .release = keypad_release,
  340. };

  341. static struct cdev SimpleDevs;  

  342. /*
  343. *
  344. */

  345. static int  KeyPad_Init(void)
  346. {
  347.     int ret;
  348.     int result;
  349.     dev_t dev;

  350.     dev=MKDEV(Keypad_major,0);
  351.     if(Keypad_major)
  352.      result=register_chrdev_region(dev,1,DEVICE_NAME);
  353.     else
  354.      {
  355.         result=alloc_chrdev_region(&dev,0,1,DEVICE_NAME);
  356.         Keypad_major=MAJOR(dev);
  357.      }
  358.     if(result<0)
  359.      {
  360.       printk(KERN_WARNING"Keypad:unable to get major %d\n",Keypad_major);        
  361.       return result;
  362.      }
  363.     if(Keypad_major==0)
  364.     Keypad_major=result;
  365.     led_setup_cdev(&SimpleDevs,0,&keypad_fops);
  366.     init_gpio();
  367.     ret = request_irqs();
  368.     if (ret < 0)
  369.     {
  370.       cdev_del(&SimpleDevs);
  371.       unregister_chrdev_region(MKDEV(Keypad_major,0),1);
  372.       return ret;
  373.     }
  374.     printk(KERN_INFO"keypad register ok!!!!!!!!!!\n");
  375.     return 0;
  376. }

  377. /*
  378. *
  379. */
  380. static void __exit KeyPad_Exit(void)
  381. {
  382.     disable_irqs();
  383.     free_irqs();
  384.     cdev_del(&SimpleDevs);
  385.     unregister_chrdev_region(MKDEV(Keypad_major,0),1);
  386.     printk("button device uninstalled\n");

  387. }

  388. module_init(KeyPad_Init);
  389. module_exit(KeyPad_Exit);

  390. MODULE_AUTHOR("zhyh");
  391. MODULE_DESCRIPTION("keypad driver");
  392. MODULE_LICENSE("GPL");
复制代码

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
发表于 2011-03-05 11:35 |显示全部楼层
你这个很难说出什么问题,程序本身估计没什么问题,与处理逻辑可能关系很大

论坛徽章:
0
发表于 2011-03-07 19:49 |显示全部楼层
你这个很难说出什么问题,程序本身估计没什么问题,与处理逻辑可能关系很大
dreamice 发表于 2011-03-05 11:35
  1. if(request_irq(KEY1_IRQ, button_rise_irq, IRQF_DISABLED | IRQF_SHARED, DEVICE_NAME, &a)){

  2.                 printk("Could not allocate key1 IRQ:%d\n",KEY1_IRQ);

  3.                 return -EINVAL;

  4.    }

复制代码
这里是否正确 ,我这里IRQF_DISABLED | IRQF_SHARED换成IRQF_TRIGGER_FALLING | IRQF_DISABLED |和IRQF_TRIGGER_FALLING |IRQF_DISABLED ,就会出现insmod: cannot insert 'key.ko': invalid parameter ,我知道是dev_id这里错误,但是我应该怎么改,请大虾赐教

论坛徽章:
0
发表于 2011-03-09 16:35 |显示全部楼层
首先

struct button_irq_desc {
    int irq;
    int gpio;
};


static struct button_irq_desc button_irqs [] = {
    {IRQ_EINTx, GPx0(x)}, /* K1 */
    {xxxxxxxxxxxxxxxxx} , /*K2*/
    ...
};

然后把你的申请写成个循环

其次,参数写成  IRQF_SHARED | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,

处理所谓按下抬起,在一个中断处理里做就可以了。

最后,你去看看gpio_keys.c   

内核是最好的老师,抄吧。不是非得写的跟内核不一样才能彰显代码的个性……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP