RK3288 7.1韦根 26位发送

以下代码为韦根26位发送代码,实际项目已经验证过,发送部分没有经过验证,思路可参考,实际调试过程如果有问题,建议使用示波器抓波形,按26位韦根协议对比波形调试,按部就班即可完成。

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

//#define INVALID_GPIO -1
#define uchar   unsigned char   
#define USE_INT
struct proc_dir_entry *gpio_extend_dir;
static struct class *rk_gpio_class = NULL;
void Send_Wiegand26(unsigned char *str);
static int Wiegand26_IntToChar(int data);
extern void rk_send_power_key(int state);
extern void rk_send_wakeup_key(void);

static int gpio2_a0;
static int gpio2_a1;
static int gl_value   = 0;
static int irq_gpio2_a0;
static int irq_gpio2_a1;


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

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

struct Wiegand26 wiegand26;

static char tmp[28];
static char send_tmp[30];
static int irq_count = 0;
static struct of_device_id gpio_of_match[] = {
    { .compatible = "gpio_ctrl" },
    { }
};


static void WG_send_bit_0(void);
static void WG_send_bit_1(void);

MODULE_DEVICE_TABLE(of, gpio_of_match);


static ssize_t gpio_write_proc_string(struct file *file, const char __user *buffer,
                    size_t count, loff_t *pos)
{
    char *buf;
    char buf2[11] = {0};
    //int i = 0;
    int ret;
    if (count < 1)
        return -EINVAL;

    buf = kmalloc(count, GFP_KERNEL);
    if (!buf)
        return -ENOMEM;

    if (copy_from_user(buf, buffer, count)) {
        kfree(buf);
        return -EFAULT;
    }

    printk("gpio_write_proc_string gpio buf = %s\n", buf);
    strncpy(buf2, buf, ((count > sizeof(buf2)) ? sizeof(buf2) : count));
    buf2[10] = '\0';
    printk("buf2 = %s\n", buf2);    

    kfree(buf);
    return count;
}

static int gpio_str_proc_show(struct seq_file *m, void *v)
{
    
    printk("gpio_str_proc_show something\n");
    return 0;
}

static int gpio_str_proc_open(struct inode *inode, struct file *file)
{
    return single_open(file, gpio_str_proc_show, NULL);
}

static int gpio_str_proc_read(struct file *file, char *buffer,
                        size_t count, loff_t *pos)
{
    if (count < 1)
        return -EINVAL;
    
    printk("tmp = %s\n", tmp);
    if (copy_to_user(buffer, tmp, count)) {
        //gpio_unlock(&gpio_lock);         
        return -EFAULT;
    }    
    
    //gpio_unlock(&gpio_lock);    

    return 1;

}


static const struct file_operations gpio_extend_fops = {
    .owner        = THIS_MODULE,
    .open        = gpio_str_proc_open,
    .read        = gpio_str_proc_read,
    .llseek        = seq_lseek,
    .release    = single_release,
    .write        = gpio_write_proc_string,
};


static ssize_t switch_show(struct class *cls,struct class_attribute *attr, char *_buf)
{
       printk("%s>>>>>>>>\n",__func__);
       
           ssize_t len = 0;
           int value = 0;
           value = gl_value;
        
        len += snprintf(_buf + len, PAGE_SIZE - len, "%d \r\n", value);


           return len;
}

static ssize_t switch_store(struct class *cls,struct class_attribute *attr, const char *buf, size_t _count)
{
        gl_value = simple_strtol(buf,NULL,10);
        
        if(gl_value == 1)
        {
            printk(KERN_INFO "gl_value is %d\n",gl_value);
            gpio_direction_input(gpio2_a0);
            gpio_direction_input(gpio2_a1);

            enable_irq(irq_gpio2_a0);
            enable_irq(irq_gpio2_a1);                
        }
        else if( gl_value ==  0)
        {
            printk(KERN_INFO "gl_value is %d\n",gl_value);
            disable_irq(irq_gpio2_a0);
            disable_irq(irq_gpio2_a1);

            gpio_direction_output(gpio2_a0, 1);
            gpio_direction_output(gpio2_a1, 1);
        }

    return _count;
}

//0010 0100 0111 0011 0011 1100

static ssize_t send_show(struct class *cls,struct class_attribute *attr, char *_buf)
{
       printk("%s>>>>>>>>\n",__func__);
       
           ssize_t len = 0;
           int value = 0;
           value = gl_value;
        
        len += snprintf(_buf + len, PAGE_SIZE - len, "%d \r\n", value);


           return len;
}

static ssize_t send_store(struct class *cls,struct class_attribute *attr, const char *buf, size_t _count)
{
        int value;
        printk("hxl buf = %s\n", buf);
        if(gl_value)
            return _count;
        
        strcpy(send_tmp,buf);
        printk("hxl send_tmp = %s\n", send_tmp);
        value = simple_strtol(buf,NULL,10);
       // sscanf(buf, "%d", &value);
        
        printk("send_store ============= %x\n",value);
        Wiegand26_IntToChar(value);
        Send_Wiegand26(wiegand26.data);
           return _count;
}


static CLASS_ATTR(switch, 0664, switch_show, switch_store);
static CLASS_ATTR(send, 0664, send_show, send_store);

static int gpio_sys_init(void)
{
    int ret ;
    rk_gpio_class = class_create(THIS_MODULE, "wg_switch");
    ret =  class_create_file(rk_gpio_class, &class_attr_switch);
    if (ret)
    {
       printk("Fail to creat class gpio5c1.\n");
    }

    ret =  class_create_file(rk_gpio_class, &class_attr_send);
    if (ret)
    {
       printk("Fail to creat class gpio5c3.\n");
    }
    
   return 0;
}


static void WG_send_bit_1(void)
{
    //WG_DATA1 = 0;
    gpio_direction_output(gpio2_a1, 0);
    //----------------------延时100us
    //delay_100us();
    udelay(100);
    //WG_DATA1 = 1;
    gpio_direction_output(gpio2_a1, 1);
    //-------------------------------延时一个发送周期
    //delay_1500us();  
    udelay(1500);
}
static void WG_send_bit_0(void)
{
    //WG_DATA0 = 0;
    gpio_direction_output(gpio2_a0, 0);
    //----------------------延时100us
    udelay(100);
    //delay_100us();
    //WG_DATA0 = 1;
    gpio_direction_output(gpio2_a0, 1);
    //-------------------------------延时一个发送周期
    //delay_1500us(); 
    udelay(1500);
}
 
 
static int Wiegand26_IntToChar(int data)
{
    
    int i = 0;
    odd = 0;
    even = 0;
    
    for(i = 0; i < 24; i++)
    {
        if(send_tmp[i] =='1')
        {
            wiegand26.data[i] = '1';
            if(i < 12)
                even ++;
            else
                odd    ++;
        }
        else
            wiegand26.data[i] = '0';
    }
    printk("in str %s \n", wiegand26.data);
    printk("check even=%d,odd=%d \n",even,odd);
    return 0;
}

void gpio_reset(void)
{
    gpio_direction_output(gpio2_a0,1);
    gpio_direction_output(gpio2_a1,1);
}


void Output_DATA0(void)
{
    gpio_direction_output(gpio2_a0, 0);
    udelay(400);
    gpio_direction_output(gpio2_a0, 1);
}

void Output_DATA1(void)
{
    gpio_direction_output(gpio2_a1, 0);
    udelay(400);
    gpio_direction_output(gpio2_a1, 1);
}

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;
    printk("hxl ===even % 2 = %d\n",even % 2);
    gpio_reset();
    udelay(2000);
    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");
    }
    udelay(2000);/*延时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;
    udelay(2000);/*延时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();
    }
    udelay(2000);
    printk("\n Send_Weigand26 end \n");
}

static irqreturn_t weigen_read1(int irq, void *dev_id)
{
    //printk("0 \n");
    tmp[irq_count] = '0';
    irq_count++;
    if (irq_count > 25)
    {
        irq_count = 0;

        
    }
    return IRQ_HANDLED;
}

static irqreturn_t weigen_read2(int irq, void *dev_id)
{
    tmp[irq_count] = '1';
    irq_count++;
    if (irq_count > 25)
    {
        irq_count = 0;
    }
    return IRQ_HANDLED;
}


static int gpio_control_probe(struct platform_device *pdev)
{
        struct device_node *node = pdev->dev.of_node;
        struct device *dev = &pdev->dev;
        enum of_gpio_flags flags;
        int ret,error;
        int en_value;
        
        struct proc_dir_entry *ent;

        printk("hxl func: %s\n", __func__); 
        if (!node)
                return -ENODEV;

    printk("gpio_control_prob hxl #####\n");
    gpio2_a0 = of_get_named_gpio_flags(node, "gpio_control_1", 0, &flags);
    en_value = (flags == GPIO_ACTIVE_HIGH)? 1:0;
    //gpio =  of_get_named_gpio(node, "gpios", 0);
    if(!gpio_is_valid(gpio2_a0)){
        dev_err(&pdev->dev, "invalid gpio_control gpio%d\n", gpio2_a0);
    }

    printk("gpio_request hxl ####\n");
    ret = devm_gpio_request(&pdev->dev, gpio2_a0, "gpio1");
    if (ret) {
        dev_err(&pdev->dev,
            "failed to request GPIO%d for otg_drv\n",
            gpio2_a0);
        return -EINVAL;
    }
    printk("set gpio direction_output hxl ###");
    //gpio_direction_output(gpio2_a0, en_value);
    gpio_direction_input(gpio2_a0);

#ifdef USE_INT

    irq_gpio2_a0 = gpio_to_irq(gpio2_a0);
    if (irq_gpio2_a0 < 0) {
        printk("gpio-keys: Unable to get irq number for GPIO %d\n",
               gpio2_a0);
        gpio_free(gpio2_a0);
        //goto fail1;
    }


     error = devm_request_irq(dev, irq_gpio2_a0, weigen_read1,
                         IRQF_TRIGGER_FALLING,
                         "gpio2_a0",
                         NULL);             
    if (error) {
        pr_err("gpio-keys: Unable to irq_gpio2_a0 irq %d; error %d\n",
               irq_gpio2_a0, error);
        gpio_free(gpio2_a0);
    }
    disable_irq(irq_gpio2_a0);

#endif
        
    gpio2_a1 = of_get_named_gpio_flags(node, "gpio_control_2", 0, &flags);
    en_value = (flags == GPIO_ACTIVE_HIGH)? 1:0;
    //gpio =  of_get_named_gpio(node, "gpios", 0);
    if(!gpio_is_valid(gpio2_a1)){
        dev_err(&pdev->dev, "invalid gpio_control gpio%d\n", gpio2_a1);
    }
    
    ret = devm_gpio_request(&pdev->dev, gpio2_a1, "gpio2");
    if (ret) {
        dev_err(&pdev->dev,
            "failed to request GPIO%d for otg_drv\n",
            gpio2_a1);
        return -EINVAL;
    }
    printk("set gpio direction_output hxl ###");
    //gpio_direction_output(gpio2_a1, en_value);
    gpio_direction_input(gpio2_a1);


//#if 0
#ifdef USE_INT

    irq_gpio2_a1 = gpio_to_irq(gpio2_a1);
    if (irq_gpio2_a1 < 0) {
        printk("gpio-keys: Unable to get irq number for GPIO %d\n",
               gpio2_a1);
        gpio_free(gpio2_a1);
        //goto fail1;
    }
    #if 0
    error = devm_request_threaded_irq(dev, irq, NULL,weigen_read2,
                IRQF_TRIGGER_RISING | IRQF_ONESHOT, 
                  "gpio2_a1",
                 NULL);
    #else
    error = devm_request_irq(dev, irq_gpio2_a1, weigen_read2,
                         IRQF_TRIGGER_FALLING,
                         "gpio2_a1",
                         NULL);             
    #endif             
    if (error) {
        pr_err("gpio-keys: Unable to irq_gpio2_a1 irq %d; error %d\n",
               irq_gpio2_a1, error);
        gpio_free(gpio2_a1);
        //goto fail1;
    }

    disable_irq(irq_gpio2_a1);

    
#endif

    gpio_direction_output(gpio2_a0, 1);
    gpio_direction_output(gpio2_a1, 1);

        
    gpio_extend_dir = proc_mkdir("gpio_extend", NULL);
    if(gpio_extend_dir == NULL)
    {
        printk("unable to creat /proc/gpio_extend directory\n");
        return -ENOMEM;
    }
    
    ent = proc_create("gpio_str", 0666, gpio_extend_dir, &gpio_extend_fops);
    if(ent == NULL)
    {
        printk("unable to create /proc/gpio_extend/gpio_str entry");
        //goto fail;
    }
    gpio_sys_init();

    return 0;
file:
        printk("func: %s some error\n", __func__); 
        return 0;
}

static int gpio_control_remove(struct platform_device *pdev)
{
        //printk("func: %s\n", __func__); 
    return 0;
}

#ifdef CONFIG_PM_SLEEP
static int gpio_control_suspend(struct device *dev)
{
        //printk("func: %s\n", __func__); 
    return 0;
}

static int gpio_control_resume(struct device *dev)
{
        //printk("func: %s\n", __func__); 
    return 0;
}
#endif

static const struct dev_pm_ops gpio_control_ops = {
#ifdef CONFIG_PM_SLEEP
    .suspend = gpio_control_suspend,
    .resume = gpio_control_resume,
    .poweroff = gpio_control_suspend,
    .restore = gpio_control_resume,
#endif
};

static struct platform_driver gpio_driver = {
    .driver        = {
        .name        = "gpio_control",
        .owner        = THIS_MODULE,
        .pm        = &gpio_control_ops,
        .of_match_table    = of_match_ptr(gpio_of_match),
    },
    .probe        = gpio_control_probe,
    .remove        = gpio_control_remove,
};

module_platform_driver(gpio_driver);

MODULE_DESCRIPTION("gpio_control");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:gpio_control");
 

你可能感兴趣的:(RK3288 7.1韦根 26位发送)