Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30995354
  • 博文数量: 230
  • 博客积分: 2868
  • 博客等级: 少校
  • 技术积分: 2223
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-08 21:48
个人简介

Live & Learn

文章分类

全部博文(230)

文章存档

2022年(2)

2019年(5)

2018年(15)

2017年(42)

2016年(24)

2015年(13)

2014年(1)

2012年(5)

2011年(58)

2010年(56)

2009年(9)

我的朋友

分类: LINUX

2017-05-22 10:47:53

//驱动代码

点击(此处)折叠或打开

  1. /*

  2. * This program is free software; you can redistribute it and/or modify

  3. * it under the terms of the GNU General Public License as published by

  4. * the Free Software Foundation; either version 2 of the License, or

  5. * (at your option) any later version.

  6. */



  7. #include <linux/module.h>

  8. #include <linux/kernel.h>

  9. #include <linux/fs.h>

  10. #include <linux/init.h>

  11. #include <linux/delay.h>

  12. #include <linux/poll.h>

  13. #include <linux/irq.h>

  14. #include <asm/irq.h>

  15. #include <linux/interrupt.h>

  16. #include <asm/uaccess.h>

  17. #include <linux/platform_device.h>

  18. #include <linux/cdev.h>

  19. #include <linux/miscdevice.h>

  20. #include <linux/sched.h>

  21. #include <linux/gpio.h>



  22. #include <linux/time.h>

  23. #include <linux/jiffies.h>

  24. #include <linux/slab.h> //klocall()

  25. #include <asm/param.h> //HZ



  26. #include <asm/uaccess.h>

  27. #include </home/fo/DevSetting/Linux/src/kernel/linux-3.14.38/arch/arm/mach-imx/hardware.h>

  28. #include </home/fo/DevSetting/Linux/src/kernel/linux-3.14.38/arch/arm/mach-imx/iomux-v3.h> //mxc_iomux_v3_setup_pad

  29.      

  30. #define DEVICE_NAME     "WiegandCH0"



  31. #define OK             0x05

  32. #define STATE         0x00

  33. #define KEY_TIMER_DELAY     (2*HZ/100)



  34. #define WD1_D0_INT_PIN         IMX_GPIO_NR(4, 22)

  35. #define WD1_D0_INT         gpio_to_irq(WD1_D0_INT_PIN)



  36. #define WD1_D1_INT_PIN         IMX_GPIO_NR(4, 21)

  37. #define WD1_D1_INT         gpio_to_irq(WD1_D1_INT_PIN)





  38. int TIMING1 = 0;

  39. int TIMING2 = 0;

  40. int rf_openflag = 0;





  41. struct wiegand_dev

  42. {

  43.     char wiegand[128]; //Wiegand Data 26Bits

  44.     int global_var; //Global Counter

  45.     struct timer_list RFCD_timer;

  46. };





  47. static struct wiegand_dev *rf_card;



  48. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);



  49. static volatile int ev_press = 0;

  50. static volatile int save_count=0;

  51. static volatile int Delay_count=0;



  52. static char convert_data(void)

  53. {

  54.     int i;

  55.     if(rf_card->wiegand[0] == '0' && rf_card->wiegand[25] == '1') //Parity Check OK

  56.     {

  57.      for(i = 1;i <= 8;i++);



  58.      for(i = 9;i<= 24;i++);

  59.     }

  60.     printk("Parity Efficacy Error!\n");

  61.     return -1;

  62. }









  63. static void RFCD_timer_handler(unsigned long arg)

  64. {

  65.    //printk("Debug #3\n");

  66.     //convert_data();



  67.    if(rf_card-> save_count)

  68.        {

  69.      //up(&rf_card->sem);

  70.     save_count = rf_card->global_var;

  71.     Delay_count = 0;

  72.      }

  73.   else

  74.     {

  75.     Delay_count++;

  76.     }



  77.  if(Delay_count==3 && rf_card->global_var>0)

  78.    {

  79.     ev_press = 1;

  80.     wake_up_interruptible(&button_waitq);

  81.     }



  82.   rf_card->RFCD_timer.expires = jiffies + KEY_TIMER_DELAY;

  83.   add_timer(&rf_card->RFCD_timer);

  84. }





  85. static irqreturn_t jonhu_rfcd_irqhandler0(int irq, void *dev_id)

  86. {



  87.     udelay(20);

  88.    

  89.     if(gpio_get_value_cansleep(WD1_D0_INT_PIN)==0)

  90.        {

  91.             rf_card->wiegand[rf_card->global_var] = '0';

  92.             rf_card->global_var = rf_card->global_var + 1;

  93.     }

  94.     udelay(500);

  95.     return IRQ_RETVAL(IRQ_HANDLED);

  96. }



  97. static irqreturn_t jonhu_rfcd_irqhandler1(int irq, void *dev_id)

  98. {

  99.     udelay(20);


  100.        if(gpio_get_value_cansleep(WD1_D1_INT_PIN)==0)

  101.        {

  102.     rf_card->wiegand[rf_card->global_var] = '1';

  103.     rf_card->global_var = rf_card->global_var + 1;

  104.     //printk("Debug #2\n");

  105.     }

  106.    udelay(500);

  107.    return IRQ_RETVAL(IRQ_HANDLED);



  108. }





  109. static ssize_t jonhu_rfcd_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)

  110. {

  111.   // printk("Debug #5\n");

  112.   if (!ev_press)

  113.     {

  114.     if (filp->f_flags & O_NONBLOCK)

  115.      return -EAGAIN;

  116.     else

  117.      wait_event_interruptible(button_waitq, ev_press);

  118.     }

  119.    ev_press = 0;



  120.    printk("Debug #6,Size:%d,global_var:%d\n",size,rf_card->global_var);

  121.   if (size >= rf_card->global_var)

  122.         size = rf_card->global_var;

  123.    rf_card->global_var = 0;

  124.    copy_to_user(buf, rf_card->wiegand, size);

  125.    return size;

  126.        

  127.     //return 0;

  128. }



  129. static ssize_t jonhu_rfcd_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)

  130. {

  131.     return 0;

  132. }



  133. static int jonhu_request_irqs(void)

  134. {

  135.     int iRet;

  136.     

  137.         printk("WD_D0 GPIO NUMBER = %d\n", WD1_D0_INT_PIN);

  138.     iRet = gpio_request(WD1_D0_INT_PIN, "WD1_D0_IN");

  139.     if(iRet)

  140.     {

  141.      printk("Get button Failed!\n");

  142.     

  143. }

  144.         printk("WD_D0 irq = %d\n", WD1_D0_INT);





  145.         int ret = request_irq(WD1_D0_INT, jonhu_rfcd_irqhandler0,IRQF_TRIGGER_FALLING, "WD1_D0_INT", NULL);



  146.     if (ret)

  147.     {

  148.           printk("request WD1_D0_INT failed!\n");    

  149.      return ret;

  150.     }



  151.         printk("WD_D1 GPIO NUMBER = %d\n", WD1_D1_INT_PIN);

  152.         //mxc_iomux_v3_setup_pad(MX6UL_PAD_CSI_DATA01__GPIO4_IO21); //configures a single pad in the iomuxer

  153.     gpio_request(WD1_D1_INT_PIN, "WD1_D1_IN");



  154.     printk("WD_D1 irq = %u\n", WD1_D1_INT);







  155.        ret = request_irq(WD1_D1_INT, jonhu_rfcd_irqhandler1,IRQF_TRIGGER_FALLING, "WD1_D1_INT", NULL);



  156.     if (ret)

  157.     {

  158.           //free_irq(WD1_D0_INT, NULL);

  159.           printk("request WD1_D1_INT failed!\n");

  160.      return ret;

  161.     }

  162.     printk("request succ!\n");

  163.     

  164.     return 0;    

  165. }





  166. static void jonhu_free_irqs(void)

  167. {

  168.     free_irq(WD1_D0_INT, NULL);

  169.     free_irq(WD1_D1_INT, NULL);

  170. }



  171. static int jonhu_rfcd_open(struct inode *inode, struct file *filp)

  172. {

  173.    if ( rf_openflag )

  174.       return -EBUSY;



  175.    rf_openflag = 1;

  176.    TIMING1 = 0;

  177.    TIMING2 = 0;



  178.     printk("request irq\n");

  179.    if(jonhu_request_irqs()<0)

  180.         {

  181.               printk("request irq failed!\n");

  182.         jonhu_free_irqs();

  183.         return -EBUSY;

  184.         }

  185.    //memset(&tmr,0,sizeof(struct timer_list));

  186.    setup_timer(&rf_card->RFCD_timer,RFCD_timer_handler,0);

  187.    rf_card->RFCD_timer.expires = jiffies + KEY_TIMER_DELAY;

  188.    add_timer(&rf_card->RFCD_timer);

  189.    rf_card->global_var = 0;

  190.    return 0;

  191. }







  192. int jonhu_rfcd_release(struct inode *inode, struct file *filp)

  193. {

  194.     sewo_free_irqs();

  195.     rf_openflag = 0;

  196.     del_timer_sync(&rf_card->RFCD_timer);

  197.     return 0;

  198. }



  199. static unsigned int jonhu_rfcd_poll( struct file *file, struct poll_table_struct *wait)

  200. {

  201.     unsigned int mask = 0;

  202.     poll_wait(file, &button_waitq, wait);

  203.     if (ev_press)

  204.         mask |= POLLIN | POLLRDNORM;

  205.     return mask;

  206. }



  207. static struct file_operations jonhu_rfcd_fops =

  208. {

  209.     .owner = THIS_MODULE,

  210.     .read = jonhu_rfcd_read,

  211.     .write = jonhu_rfcd_write,

  212.     .poll = jonhu_rfcd_poll,

  213.     .open = jonhu_rfcd_open,

  214.     .release = jonhu_rfcd_release,

  215. };



  216. static struct miscdevice misc = {

  217.     .minor = MISC_DYNAMIC_MINOR,

  218.     .name = DEVICE_NAME,

  219.     .fops = &jonhu_rfcd_fops,

  220. };

  221.  



  222. static int __init jonhu_wiegand_init(void)

  223. {

  224.     int result;

  225.         printk("ins mode start..\n");

  226.     result = misc_register(&misc);

  227.     if(result < 0)

  228.       return result;



  229.     rf_card = kmalloc(sizeof(struct wiegand_dev),GFP_KERNEL);

  230.     if (!rf_card)

  231.     {

  232.           result = -ENOMEM;

  233.            goto fail_malloc;

  234.     }



  235.     memset(rf_card,0,sizeof(struct wiegand_dev));

  236.     //init_MUTEX_LOCKED(&rf_card->sem);

  237.         printk("ins mode sucee..\n");

  238.     return 0;



  239.     fail_malloc:

  240.           misc_deregister(&misc);

  241.     return result;

  242. }



  243. static void __exit jonhu_wiegand_exit(void)

  244. {

  245.     printk("ext mode start..\n");

  246.     kfree(rf_card);

  247.     misc_deregister(&misc);

  248. }



  249. module_init(jonhu_wiegand_init);

  250. module_exit(jonhu_wiegand_exit);



  251. MODULE_AUTHOR("Jon.Hu");

  252. MODULE_DESCRIPTION("Weigand character driver");

  253. MODULE_LICENSE("GPL");
//makefile

点击(此处)折叠或打开

  1. CROSS_COMPILE=arm-linux-
  2. ARCH:=arm
  3. CC:=$(CROSS_COMPILE)gcc
  4. LD:=$(CROSS_COMPILE)ld
  5. obj-m = WiegandCH0.o
  6. module-objs = WiegandCH0.o
  7. KDIR = /home/fo/DevSetting/Linux/src/kernel/linux-3.14.38
  8. PWD = $(shell pwd)
  9. default:
  10. $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
  11. clean:
  12. rm -rf *.o *.ko

阅读(3064) | 评论(0) | 转发(0) |
0

上一篇:Gpio-int-test.c

下一篇:LCD驱动调试

给主人留下些什么吧!~~