duhao

duhao

0个粉丝

8

问答

0

专栏

0

资料

duhao  发布于  2014-12-04 11:10:24
采纳率 0%
8个问答
4219

刷卡器wiegand格式数据输出问题 hi3521

 
刷卡器数据线接到3521的GPIO7_6(DATA0)和GPIO7_7(DATA1),先设置了这两个口为通用gpio口且设置为输入,看数据手册显示整个GPIO7的中断号为112,下面是wiegand驱动程序.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
//#include
//#include

#include
#include

#define WIEGAND_MAJOR 244        

//delay 33ms to convert data
#define TIMER_DELAY HZ/30

#define DEVICE_NAME  "wiegand"

bool TIMEER_FLAG = false;   
bool RF_OPEN_FLAG = false;

struct wiegand_irq_desc{
int irq;
int pin;
int number;
char *name;
  };

  static struct wiegand_irq_desc wiegand_irqs[]={

  {112,6,1,"wiegand_data0"},{112,7,2,"wiegand_data1"},
};







struct wiegand_dev
{

        char wiegand[26];    //Wiegand Data 26Bits
        int hid;
        int pid;
        //unsigned char state;
        int count;    //Global Counter
        struct cdev cdev;
        struct semaphore sem;
        struct completion receive_completion;
        struct timer_list wiegand_timer;
        struct  wiegand_irq_desc wiegand_irqs[2];
      
};

static struct wiegand_dev *rf_card;



  static volatile unsigned long *gpio7_6_dat = NULL;
  static volatile unsigned long *gpio7_6_reg = NULL;
  static volatile unsigned long *gpio7_7_dat = NULL;
  static volatile unsigned long *gpio7_7_reg = NULL;
  static struct class *wiegand_class = NULL;

  static volatile unsigned long *gpio7_dir = NULL;
  //static volatile unsigned long *gpio7_ie = NULL;




//应该除了初始化外,只能有这一个地方能够将rf_card->count置为0,其余地方置为0皆不合法
static char convert_data(void)
{
        int i;
        int even;
        int  odd;
            even = 0;
            for(i = 1; i < 13;i++)
            {
                 if(rf_card->wiegand == 1)       
                  even = (~even) & 0x01;
            }
             if(even != rf_card->wiegand[0])
              {
                rf_card->count = 0;
                goto error;
              }       
       
            odd = 1;
            for(i = 13; i< 25;i++)
            {
            if(rf_card->wiegand == 1)                         
                        odd = (~odd)& 0x01;             
             }
             if(odd != rf_card->wiegand[25])
              {
                rf_card->count = 0;
               goto error;
              }

        //奇偶校验通过
        rf_card->hid = 0;
        for(i = 1 ;i<=12;i++)//hid转换
                rf_card->hid =  rf_card->hid << 1 |rf_card->wiegand;       

        rf_card->pid = 0;
        for(i = 13 ;i<=25;i++)//pid转换
                rf_card->pid =  rf_card->pid << 1 |rf_card->wiegand;       
          
            rf_card->count = 0;
        return 0;
       
error:
        printk("Parity Efficacy Error!\n");
        return -1;
}

static void wiegand_do_timer(unsigned long arg)
{
        printk("%s:wait wieg_data completed\n",__func__);
        wait_for_completion(&(rf_card->receive_completion));//等待维根数据传送完毕才进行转换

        disable_irq(112);
        disable_irq(112);//防止wieg_data在转换期间发生变化

        convert_data();
        up(&rf_card->sem);

        printk("%s:complete convert wieg_data,hid = %d,pid = %d \n",__func__,rf_card->hid,rf_card->pid);

        TIMEER_FLAG = false;

        enable_irq(112);
        enable_irq(112);
}

static void enable_irqs(void)
{       
        enable_irq(112);
        enable_irq(112);

        printk("%s:the irq is setup!\n",__func__);
}

static irqreturn_t wiegand_irq0(int irq, void *dev_id)
{
        disable_irq_nosync(112);
        printk("%s:IN\n",__func__);  
        udelay(5);

        if(*gpio7_6_dat== 0)
        {
                   rf_card->wiegand[rf_card->count] = 0;
                   printk("%s:wiegand[%d] = %d\n",__func__,rf_card->count,rf_card->wiegand[rf_card->count]);
                rf_card->count ++;
                udelay(300);
        }
        else
                goto end;
        


       // (*gpio7_ie)|=(0x3<<6);
        enable_irq(112);

        if(rf_card->count == 1)
                init_completion(&(rf_card->receive_completion));
        else if(rf_card->count == 26)
                complete(&(rf_card->receive_completion));

           if(TIMEER_FLAG == false)
           {
                rf_card->wiegand_timer.expires = jiffies + TIMER_DELAY;
                add_timer(&rf_card->wiegand_timer);
                TIMEER_FLAG = true;
                printk("%s:add_timer\n",__func__);
        }

        printk("%s:OUT\n",__func__);  
        return IRQ_HANDLED;
end:
        printk("%s:error data\n",__func__);
        enable_irq(112);
        return IRQ_HANDLED;
}

static irqreturn_t wiegand_irq1(int irq, void *dev_id)
{
        disable_irq_nosync(112);//必须用这个函数              printk("%s:IN\n",__func__);
   
        udelay(5);

        if(*gpio7_7_dat == 1 && rf_card->count < 26)
        {
                   rf_card->wiegand[rf_card->count] = 1;
                printk("%s:wiegand[%d] = %d\n",__func__,rf_card->count,rf_card->wiegand[rf_card->count]);
                rf_card->count ++;
                udelay(300);
        }
        else
                goto end;
       
        enable_irq(112);

        //rf_card->count经过上面“++”之后都会大1
        if(rf_card->count == 1)
                init_completion(&(rf_card->receive_completion));
        else if(rf_card->count == 26)
                complete(&(rf_card->receive_completion));//只能在此处complete

           if(TIMEER_FLAG== false)
           {
                rf_card->wiegand_timer.expires = jiffies + TIMER_DELAY;
                add_timer(&rf_card->wiegand_timer);
                TIMEER_FLAG = true;
                printk("%s:add_timer\n",__func__);  
        }

        printk("%s:OUT\n",__func__);  

        return IRQ_HANDLED;
end:
        printk("%s:error data\n",__func__);
        enable_irq(112);
        return IRQ_HANDLED;
}

static ssize_t rfcd_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{      

        printk("in kernel 1 read\n");
        down_interruptible(&rf_card->sem);
         
        printk("in kernel 2 read\n");
        
        if(size <= rf_card->count)
        size = rf_card->count;
                       
        return copy_to_user(buf,rf_card->wiegand, size);
}

static ssize_t rfcd_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
        return 0;
}

static int request_irqs(void)       
      {
       int ret;

        printk("%s:start request irqs\n",__func__);

        if(ret = request_irq(112,wiegand_irq0,IRQF_SHARED,"wiegand_data0",rf_card))
        {
                printk("%s:request 112:%d,ret:%d failed!\n",__func__,112,ret);
                return -1;   
        }

        if(ret = request_irq(112,wiegand_irq1,IRQF_SHARED,"wiegand_data1",rf_card))
        {
                printk("%s:request 112:%d,ret:%d failed!\n",__func__,112,ret);
                return -1;   
        }

        printk("%s:request irqs success!\n",__func__);
        return 0;
}

static int rfcd_open(struct inode *inode, struct file *filp)
{
           if(RF_OPEN_FLAG)
        return -EBUSY;//Don't open again!

        RF_OPEN_FLAG = true;
        TIMEER_FLAG = false;
        
        *gpio7_6_reg &= ~0x1;   //通用GPIO
        *gpio7_7_reg &= ~0x1;
        *gpio7_dir &= 0x00<<6; //6.7为输入
  //      (*gpio7_ie)|=(0x3<<6);



        setup_timer(&rf_card->wiegand_timer,wiegand_do_timer,0);

        memset(rf_card->wiegand,0x00,26);
        rf_card->count = 0;

        enable_irqs();


        printk("%s: the device have been open\n",__func__);
        return 0;
}

static void free_irqs(void)
{
        free_irq(112,rf_card);
        free_irq(112,rf_card);
}

int rfcd_release(struct inode *inode, struct file *filp)
{
        disable_irq(112);
        disable_irq(112);

        RF_OPEN_FLAG = false;

        del_timer_sync(&rf_card->wiegand_timer);
        return 0;
}

static struct file_operations rfcd_fops =
{
        .owner = THIS_MODULE,
        .read = rfcd_read,
        .write = rfcd_write,
        .open = rfcd_open,
        .release = rfcd_release,
};

static int __init wiegand_init(void)
{
        int err,result;
        dev_t devno = MKDEV(WIEGAND_MAJOR, 0);

        if(WIEGAND_MAJOR)
                result = register_chrdev_region(devno,1,DEVICE_NAME);   
        else
                result = alloc_chrdev_region(&devno,0,1,DEVICE_NAME);
       
        if(result < 0)
        {
                printk("%s:register_chrdev_region error\n",__func__);
                return result;
        }


        rf_card = kmalloc(sizeof(struct wiegand_dev),GFP_KERNEL);
        if (!rf_card)
        {
                result = -ENOMEM;
                goto fail_malloc;
        }

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

        rf_card->count = 0;

        cdev_init(&(rf_card->cdev), &rfcd_fops);
     
        rf_card->cdev.owner = THIS_MODULE;

        err = cdev_add(&rf_card->cdev, devno, 1);
       
        if(err)
        {
                printk("adding err\r\n");
                unregister_chrdev_region(devno,1);
                kfree(rf_card);
                free_irqs();
                return err;
        }
        

      
         wiegand_class = class_create(THIS_MODULE,"wiegand_class");
         device_create(wiegand_class,NULL,MKDEV(WIEGAND_MAJOR,0),NULL,"wiegand");





        init_completion(&(rf_card->receive_completion));
        //init_MUTEX_LOCKED(&rf_card->sem);
        sema_init(&rf_card->sem,0);




        //s3c_gpio_setpull(S3C64XX_GPL(9), S3C_GPIO_PULL_UP);
        //s3c_gpio_setpull(S3C64XX_GPL(10), S3C_GPIO_PULL_UP);





        result = request_irqs();

        if(result < 0)
        {
                printk("%s:request_irqs error\n",__func__);
                return result;
        }

        disable_irq(112);
        disable_irq(112);
        
        


        gpio7_6_reg        = ioremap(0x200f0000+0x0120,4);
        gpio7_7_reg        = ioremap(0x200f0000+0x0124,4);
        gpio7_dir        = ioremap(0x201c0000+0x0400,4);
    //          gpio7_ie        = ioremap(0x201c0000+0x0410,4);
        gpio7_6_dat        = ioremap(0x201c0000+0x0100,4);
        gpio7_7_dat        = ioremap(0x201c0000+0x0200,4);


        printk ("\n@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        printk (DEVICE_NAME"\tinitialized\n");
        printk ("\n@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        return 0;

fail_malloc:
        unregister_chrdev_region(devno,1);
       
        return result;
}

static void __exit wiegand_exit(void)
{
        cdev_del(&rf_card->cdev);
        kfree(rf_card);
        free_irqs();
        unregister_chrdev_region(MKDEV(WIEGAND_MAJOR,0),1);
        printk ("\n@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        printk (DEVICE_NAME"\tremoved\n");
        printk ("\n@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
}

module_init(wiegand_init);
module_exit(wiegand_exit);

MODULE_AUTHOR("Changsheng.Guo,[email]gcshy@126.com[/email]");
MODULE_LICENSE("GPL");





但是最后在开发板上运行测试程序时,刷卡后,既未接收到0信号,也没收到1信号,不知道问题出在哪里,求大神指导

补充内容 (2014-12-8 16:12):
之后把GPIO7_7改成GPIO7_6,中断号为107,避开两个中断号都为一样,下面寄存器配置gpio7-6都改成gpio2-7,之前卸载驱动时忘了解除映射,都加上,最后测试时发现还是未能进入中断,也就是刷卡后,没有数据通过gpio7-6和gpio2-7,不知道为什么?
我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区