• IRM3800 红外遥控器解码 linux驱动


    这一次还是接在 Cemera 上。用 中断引脚 EINT20 也就是 GPG12.

    之前焊的 51 板子上有一个红外接收器。

    请注意了,是

    标准的 NEC 码规范:
    首次发送的是9ms的高电平脉冲,其后是4.5ms的低电平,接下来就是8bit的地址码(从低有效位开始发),
    而后是8bit的地址码的反码(主要是用于校验是否出错)。然后是8bit 的命令码(也是从低有效位开始发),
    而后也是8bit 的命令码的反码。其“0”为载波发射0.56ms,不发射0.565ms,其“1”为载波发射0.56ms,
    不发射1.69ms。

    这是一种不太好的实现方式,以后会更新其它更好的算法。

    原理比较简单,当有中断发生中,将GPG12设为输入功能,通过读引脚的电平,配合时间,就能得到 红外遥控器发出的代码。

    代码共4个,厂家ID 高, 厂家ID 低, 命令 , 命令反码

    经过试验,发现,命令只有低6个bit 是正常的,

    驱动源码

     1 #include <linux/consolemap.h>
     2 #include <linux/module.h>
     3 #include <linux/sched.h>
     4 #include <linux/tty.h>
     5 #include <linux/tty_flip.h>
     6 #include <linux/mm.h>
     7 #include <linux/string.h>
     8 #include <linux/init.h>
     9 #include <linux/slab.h>
    10 
    11 #include <linux/kbd_kern.h>
    12 #include <linux/kbd_diacr.h>
    13 #include <linux/vt_kern.h>
    14 #include <linux/input.h>
    15 #include <linux/reboot.h>
    16 #include <linux/notifier.h>
    17 #include <linux/jiffies.h>
    18 #include <linux/uaccess.h>
    19 
    20 #include <asm/irq_regs.h>
    21 #include <linux/interrupt.h>
    22 #include <linux/irq.h>
    23 #include <linux/delay.h>
    24 
    25 #include <linux/gpio.h>
    26 #include <mach/regs-gpio.h>
    27 #include <mach/gpio-samsung.h>
    28 #include <mach/hardware.h>
    29 #include <plat/gpio-cfg.h>
    30 
    31 /*
    32 标准的 NEC 码规范:
    33 首次发送的是9ms的高电平脉冲,其后是4.5ms的低电平,接下来就是8bit的地址码(从低有效位开始发),
    34 而后是8bit的地址码的反码(主要是用于校验是否出错)。然后是8bit 的命令码(也是从低有效位开始发),
    35 而后也是8bit 的命令码的反码。其“0”为载波发射0.56ms,不发射0.565ms,其“1”为载波发射0.56ms,
    36 不发射1.69ms。
    37 */
    38 
    39 #define IR gpio_get_value(S3C2410_GPG(12))
    40 
    41 static irqreturn_t irm_irq(int irq, void *dev_id)
    42 {
    43     int k,i;
    44     unsigned char irm_code[4] = {0, 0, 0, 0};
    45     
    46     /* 操作原理 当有中断发生中 配置引脚功能为 GPIO 输入型 直接读IRM信号电平高低 */
    47     s3c_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPIO_INPUT);
    48     mdelay(5); //9ms 内必须是低电平否则就不是头信息
    49     if(0 == IR)
    50      {
    51          while(! IR);//等待4.5ms的高电平
    52          
    53          //检测是否是 2.5ms 重码 
    54          mdelay(3);
    55          if(1 == IR)
    56          {
    57              //k 4位编码
    58              for(k=0; k<4; k++)
    59              {
    60                  //i 每一个编码的 8bit
    61                  for(i=0;i<8;i++)
    62                  {
    63                      while(IR);     //等待变为低电平时
    64                      while(! IR);   //等待变为高电平后
    65                      udelay(700);  //休眠700us 后读值
    66                      irm_code[k] |= (IR & 1)<<i;//先存低位
    67                  }
    68              }
    69              
    70              //计算反码 code码是否正确
    71              if((irm_code[2]&0x3f) == (~(irm_code[3]) & 0x3f))
    72              {
    73                  printk("FID:0x%x 0x%x CID: 0x%x 0x%x
    ", irm_code[0], irm_code[1], irm_code[2], irm_code[3]);
    74              }
    75          }
    76      }
    77     s3c_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPIO_IRQ);
    78     return IRQ_HANDLED;
    79 }
    80 
    81 static int irm_init(void)
    82 {
    83     int ret;
    84     //注册中断 上升沿触发
    85     ret = request_irq(IRQ_EINT20, irm_irq, IRQF_TRIGGER_RISING, "irm_irq", NULL);
    86     return 0;
    87 }
    88 
    89 static void irm_exit(void)
    90 {
    91     free_irq(IRQ_EINT20, NULL);
    92 }
    93 
    94 module_init(irm_init);
    95 module_exit(irm_exit);
    96 MODULE_LICENSE("GPL");
  • 相关阅读:
    HDU 2444 The Accomodation of Students (判断是否是二分图,然后求最大匹配)
    HDU 1045 Fire Net (二分匹配)
    Leangoo如何颠覆传统项目管理软件?
    团队协作神器:Leangoo
    Leangoo-让工作更简单
    leangoo 轻量级项目协作和列表管理平台
    团队协作中的“贵族”leangoo
    使用leangoo实现多泳道任务看板
    项目管理工具到底应该为谁服务?
    《精益创业实战》读书笔记
  • 原文地址:https://www.cnblogs.com/ningci/p/6663750.html
Copyright © 2020-2023  润新知