RK3288 韦根发送驱动

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


//#define Delay_50us(x) usleep(x*50)
#define Delay_1ms(x)  msleep(x)
#define Delay_50us(x) usleep_range(50*x,50*x+20)

#define  D0_GPIO_NO  32*8+7-8  //gpio2_a7
#define  D1_GPIO_NO  32*8+1-8  //gpio2_b0


static struct workqueue_struct *queue = NULL;
static struct work_struct work;

static int even =0;
static int odd =0;

struct Wiegand26{
    bool flag;
    char data[24];
};

struct Wiegand34{
    bool flag;
    char data[32];
};

struct Wiegand26 wiegand26;
struct Wiegand34 wiegand34;

static int major;
 
static struct class *cls;
static struct device *dev;
 

 
static int wiegandOut_open(struct inode *inode, struct file *file){
 
    return 0;
}
 
static ssize_t wiegandOut_write(struct file *file, const char __user *buf,
    size_t count, loff_t *ppos){
 
   return 0;
}
 
static struct file_operations wiegandOut_fops = {
 
    .owner = THIS_MODULE,
    .open  = wiegandOut_open,
    .write = wiegandOut_write,
};

int Wiegand26_IntToChar(int data)
{
    int i = 0;
     odd=0;
     even=0;
    for (i = 0; i < 24; i++)
    {
        if ((1 << i) & data)
        {
            wiegand26.data[23-i] = '1';
            if(i<12)
                odd++;
            else
                even++;
        }
        else
            wiegand26.data[23-i] = '0';
     }
    printk("in str %s \n", wiegand26.data);
    printk("check even=%d,odd=%d \n",even,odd);
    return 0;    
}

int Wiegand34_IntToChar(int data)
{
    int i =0;
    odd=0;
    even=0;
    for (i = 0; i < 32; i++)
    {
        if ((1 << i) & data)
        {
        wiegand34.data[31-i] = '1';
        if(i<16)
            odd++;
        else
            even++;
        }
        else
            wiegand34.data[31-i] = '0';
     }
    printk("in str %s \n", wiegand34.data);
    printk("check even=%d,odd=%d \n",even,odd);
    return 0;    
}

void gpio_reset(void)
{
    gpio_direction_output(D0_GPIO_NO,1);
    gpio_direction_output(D1_GPIO_NO,1);
}

void Output_DATA0(void)
{
    gpio_set_value(D0_GPIO_NO,0);
    Delay_50us(8);
    gpio_set_value(D0_GPIO_NO,1);
    
}

void Output_DATA1(void)
{
    gpio_set_value(D1_GPIO_NO,0);
    Delay_50us(8);
    gpio_set_value(D1_GPIO_NO,1);
    
}

void Send_Wiegand34(unsigned char *str)
{
       unsigned char one_num = 0;
       int i =0; 
      
      // WG_DATA0 = 1;
      // WG_DATA1 = 1;
     gpio_reset();
       Delay_1ms(2);
       if(even % 2)
       {
            
            //  WG_DATA1 = 0;                    /*偶校验位为1*/
            printk("1");
            //   Delay_50us(8);
            //  WG_DATA1 = 1;
    Output_DATA1();
       }
       else
       {           
         Output_DATA0();    
         // WG_DATA0 = 0;                   /*偶校验位为0*/
     printk("0");
              //Delay_50us(8);
             // WG_DATA0 = 1;
       }
      
       Delay_1ms(2);                        /*延时2ms*/
      
       for(i = 0;i < 32;i++)
       {
           //   WG_DATA0 = 1;
           //   WG_DATA1 = 1;
 
              if(str[i] & 0x01)
              {
                    // WG_DATA1 = 0;
                    // Delay_50us(8);
                    // WG_DATA1 = 1;
        printk("1");
        Output_DATA1();
              }
              else
              {
                    // WG_DATA0 = 0;
                    // Delay_50us(8);
                    // WG_DATA0 = 1;
        printk("0");
        Output_DATA0();
              }
              //(*(long*)&str[0]) <<= 1;
              Delay_1ms(2);               /*延时2ms*/
       }
     //  WG_DATA0 = 1;
     //  WG_DATA1 = 1;
       if(odd % 2)
       {
          //    WG_DATA0 = 0;
           //    Delay_50us(8);
           //   WG_DATA0 = 1;
       printk("0");
       Output_DATA0();
    
       }
       else
       {           
            //  WG_DATA1 = 0;
            //  Delay_50us(8);
            //  WG_DATA1 = 1;
        printk("1");
        Output_DATA1();
       }
       Delay_1ms(2);  
}
/*
韦根26发送函数
*/
void Send_Wiegand26(unsigned char *str)
{
       unsigned char one_num = 0;
       int i =0;
       printk("\nSend_Wiegand26 start \n");
     
     //  WG_DATA0 = 1;
     //  WG_DATA1 = 1;
     gpio_reset();
       Delay_1ms(2);
       if(even % 2)
       {
            //  WG_DATA1 = 0;                    /*偶校验位为1*/
            //  Delay_50us(8);
            //  WG_DATA1 = 1;
           printk("1");
        Output_DATA1();
       }
       else
       {           
            //  WG_DATA0 = 0;                   /*偶校验位为0*/
            //  Delay_50us(8);
            //  WG_DATA0 = 1;
        Output_DATA0();
        printk("0");
       }
      
       Delay_1ms(2);                        /*延时2ms*/
      
       for(i = 0;i < 24;i++)
       {
            //  WG_DATA0 = 1;
            //  WG_DATA1 = 1;
 
              if(str[i] & 0x01)
              {
                  //   WG_DATA1 = 0;
                  //   Delay_50us(8);
                  //   WG_DATA1 = 1;
           printk("1");
        Output_DATA1();
              }
              else
              {
                  //   WG_DATA0 = 0;
                  //   Delay_50us(8);
                  //   WG_DATA0 = 1;
                printk("0");
        Output_DATA0();
              }
            //  (*(long*)&str[0]) <<= 1;
              Delay_1ms(2);               /*延时2ms*/
       }
      // WG_DATA0 = 1;
      // WG_DATA1 = 1;
       if(odd % 2)
       {
            //  WG_DATA0 = 0;
            //  Delay_50us(8);
            //  WG_DATA0 = 1;
        printk("0");
        Output_DATA0();
       }
       else
       {           
            //  WG_DATA1 = 0;
            //  Delay_50us(8);
            //  WG_DATA1 = 1;
         printk("1");
        Output_DATA1();
       }
       Delay_1ms(2);  
       printk("\n Send_Weigand26 end \n");
}

static void work_handler(struct work_struct *data)
{
    printk(KERN_ALERT"work handler function.\n");
    if(wiegand26.flag)
    {
    Send_Wiegand26(wiegand26.data);
    wiegand26.flag =false;
    }
    else if(wiegand34.flag)
    {
    Send_Wiegand34(wiegand34.data);
    wiegand34.flag =false;
    }
    else
    {
    printk(KERN_ALERT"work handler function error.\n");
    }
    printk(KERN_ALERT"work handler end.\n");
}

static ssize_t Wiegand26_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{

    return sprintf(buf,"%s\n", wiegand26.data);
}

static ssize_t Wiegand26_store(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t count)
{
    int val;
    sscanf(buf, "%d", &val);
    Wiegand26_IntToChar(val);
   wiegand26.flag = true;
   INIT_WORK(&work,work_handler);
    schedule_work(&work);
    return count;
}

static ssize_t Wiegand34_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"%s\n", wiegand34.data);
}

static ssize_t Wiegand34_store(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t count)
{
    int val;
    sscanf(buf, "%d", &val);
    Wiegand34_IntToChar(val);
    wiegand34.flag = true;
    INIT_WORK(&work,work_handler);
    schedule_work(&work);
    return count;
}

static DEVICE_ATTR(wiegand26,0664,Wiegand26_show, Wiegand26_store);
static DEVICE_ATTR(wiegand34,0664,Wiegand34_show, Wiegand34_store);

static struct attribute *wiegandOut_attributes[] = {
        &dev_attr_wiegand26.attr,
        &dev_attr_wiegand34.attr,
        NULL
};

static struct attribute_group wiegandOut_attribute_group = {
        .attrs = wiegandOut_attributes
};


static void wiegandOut_release(struct device *dev){

}
static struct of_device_id wiegandOut_of_match[] = {
    { .compatible = "qianyi,wiegandout" },
    { }
};
MODULE_DEVICE_TABLE(of, wiegandOut_of_match);

static int wiegandOut_probe(struct platform_device *pdev){
        
        int ret =0;
    printk("wiegandOut_probe\n");
 
    // 注册设备驱动 创建设备节点
    major = register_chrdev(0, "wiegandOut", &wiegandOut_fops);
    // 创建类
    cls = class_create(THIS_MODULE, "wiegandOut");
    // 创建设备节点
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "wiegandOut");
        ret = sysfs_create_group(&pdev->dev.kobj, &wiegandOut_attribute_group);   
    wiegand26.flag=false;
    wiegand34.flag=false;
    printk("wiegandOut_probe, end ret=%d \n",ret);
        return ret;
}
 
static int wiegandOut_remove(struct platform_device *pdev){
 
    printk("wiegandOut_remove, \n");    
    // 删除设备节点
    device_unregister(dev);
    // 销毁类
    class_destroy(cls);
    // 取消注册设备驱动
    unregister_chrdev(major, "wiegandOut");
    // 取消内存映射
    gpio_reset();
 
    return 0;
}
 
struct platform_driver wiegandOut_drv = {
 
    .probe     = wiegandOut_probe,    //匹配到dev之后调用probe
    .remove = wiegandOut_remove,
    .driver = {
        .name = "wiegandOut",
        .owner        = THIS_MODULE,
        .of_match_table    = of_match_ptr(wiegandOut_of_match),
    },
};

static int __init wiegandOut_init(void)
{
    int ret =0;
    printk(KERN_ALERT"ace test_init function.\n");
    queue=create_singlethread_workqueue("weigandSend");/*创建一个单线程的工作队列*/
    if (!queue)
            goto err;
   // INIT_WORK(&work,work_handler);
   //  schedule_work(&work);
    
    ret=platform_driver_register(&wiegandOut_drv);
    printk(KERN_ALERT"ace test_init end.ret=%d \n",ret);
      return 0;
err:
      return -1;
}

static   void __exit wiegandOut_exit(void)
{
    platform_device_unregister(&wiegandOut_drv);
       destroy_workqueue(queue);
}
MODULE_LICENSE("GPL");
module_init(wiegandOut_init);
module_exit(wiegandOut_exit);
 

 

///////////////////////////////////////////////////////////////////////

这里需要几点注意的地方:

1、此处没有做HID、PID的转换,直接将收到的数据做二进制转换的。如果需要的话,将收到的十进制数据分成HID和PID,再做二进制转换并发送

2、如果接收端移植无法正确识别,请查看发送的数据是否对。如果波形的数据无误,则是发送的周期太长导致接收端没能完整的接收数据,调整delay的时间即可

你可能感兴趣的:(RK3288 韦根发送驱动)