IR遥控分析资料:

1、红外解码器对红外遥控输入信号进行解码。支持两种操作模式:
[1]、硬件解码IR传输协议兼容帧解码器模式(NEC 三菱 Thomson 东芝 Sony SIRC RC5 RC6 RCMM Duokan Comcast Sanyo模式)
[2]、通用可编程时间测量帧解码器模式(通用模式)。

2、红外解码说明
2.1在硬件解码模式下,解码器采用信号模式搜索机制对数据帧进行解码。它可以检测逻辑0、1、00、01、10和11,以及数据帧的开始和结束。每当解码器检测和解码数据帧时,数据都保存在数据寄存器中

2.2在一般模式下,解码器采用边缘检测机制对数据帧进行解码。它可以检测每个输入信号的边缘,并记录两个边缘之间的时间。时间测量结果保存在控制寄存器中

2.3用户应根据遥控器的选择,设置适当的操作模式【重点】。

2.4在信号输入和解码器之间有一个简单的基于时间的信号滤波器。该滤波器可编程,有助于提高信号的完整性

3、红外译码器功能块中的寄存器分为3组
3.1控制和时钟寄存器,用于配置红外解码器和获取解码器状态。它也用于配置时钟检测速率。
3.2调谐寄存器用于调整硬件解码器模式的检测参数。
3.3数据寄存器,用于保存硬件解码器模式下的解码数据。

红外解码器有13种工作模式:12种硬件解码模式和一般模式。
在硬件解码模式下,数据帧基于硬件解码红外传输协议。
在一般模式下,可以对软件进行编程以适应其他传输协议,这些协议应该是基于脉冲距离编码的;

嵌入式处理器与红外译码器之间的通信是基于中断的。启用IR解码器并检测到任何有效的远程控制器信号输入后,将产生一个中断。处理器通过读取IR译码寄存器来处理中断并获取详细信息;

红外解码器的信号检测和解码是基于时间的。在所有的检测和计算处理中,将元素时间间隔称为T率,作为基本的检测窗口时间单元。软件可以通过设置适当的值到寄存器 AO_MF_IR_DEC_REG0 来配置速率;

滤波器可用于过滤输入信号在任何一种工作模式。滤波器的工作逻辑是:在信号从低到高的上升沿后,信号保持在高的时间最少的滤波器T滤波器前被接受为有效的高信号。在信号从高到低的下降沿之后,
信号至少要保持在低的T滤波器上,才能被接受为有效的低信号。

4、驱动代码流程浅析:
4.1dts部分,文件:common/arch/arm64/boot/dts/amlogic/mesontxlx.dtsi

 306                 remote_pins:remote_pin{307                         amlogic,setmask = <AO 0x1>;308                         amlogic,clrmask = <AO 0x200000>;309                         amlogic,pins = "GPIOAO_6";310                 };
 759         remote:rc@0xff808040 {760                 compatible = "amlogic, aml_remote";761                 dev_name = "meson-remote";762                 reg = <0x0 0xff808040 0x00 0x44>,763                         <0x0 0xff808000 0x00 0x20>;764                 status = "okay";765                 protocol = <REMOTE_TYPE_NEC>; //配置IR 控制器的初始模式->支持的协议,这里默认配置NEC766                 interrupts = <0 196 1>;767                 pinctrl-names = "default";768                 pinctrl-0 = <&remote_pins>;769                 map = <&custom_maps>;770                 max_frame_time = <200>; /*set software decoder max frame time*/771         };
773         custom_maps:custom_maps {774                 mapnum = <3>;775                 map0 = <&map_0>;776                 map1 = <&map_1>;777                 map2 = <&map_2>;778                 map_0: map_0{779                         mapname = "amlogic-remote-1";780                         customcode = <0xfb04>;781                         release_delay = <80>;782                         size  = <44>;   //keymap size783                         keymap = <REMOTE_KEY(0x01, KEY_1)784                                 REMOTE_KEY(0x02, KEY_2)785                                 REMOTE_KEY(0x03, KEY_3)786                                 REMOTE_KEY(0x04, KEY_4)787                                 REMOTE_KEY(0x05, KEY_5)788                                 REMOTE_KEY(0x06, KEY_6)789                                 REMOTE_KEY(0x07, KEY_7)790                                 REMOTE_KEY(0x08, KEY_8)791                                 REMOTE_KEY(0x09, KEY_9)792                                 REMOTE_KEY(0x0a, KEY_0)793                                 REMOTE_KEY(0x1F, KEY_FN_F1)794                                 REMOTE_KEY(0x15, KEY_MENU)795                                 REMOTE_KEY(0x16, KEY_TAB)796                                 REMOTE_KEY(0x0c, KEY_CHANNELUP)797                                 REMOTE_KEY(0x0d, KEY_CHANNELDOWN)798                                 REMOTE_KEY(0x0e, KEY_VOLUMEUP)799                                 REMOTE_KEY(0x0f, KEY_VOLUMEDOWN)800                                 REMOTE_KEY(0x11, KEY_HOME)801                                 REMOTE_KEY(0x1c, KEY_RIGHT)802                                 REMOTE_KEY(0x1b, KEY_LEFT)803                                 REMOTE_KEY(0x19, KEY_UP)804                                 REMOTE_KEY(0x1a, KEY_DOWN)805                                 REMOTE_KEY(0x1d, KEY_ENTER)806                                 REMOTE_KEY(0x17, KEY_MUTE)807                                 REMOTE_KEY(0x49, KEY_FINANCE)};};

4.2部分代码构成,其他可到该目录查看:

drivers/amlogic/input/remote/remote_meson.c //中心代码
drivers/amlogic/input/remote/remote_cdev.c //字符设备相关代码
drivers/amlogic/input/remote/remote_regmap.c //寄存器操作相关代码
drivers/amlogic/input/remote/remote_core.c //框架相关代码
drivers/amlogic/input/remote/sysfs.c //文件系统相关代码
drivers/amlogic/input/remote/remote_raw.c //原始码值的接收和处理

我这里从remote_probe函数开始跟:

我这里从remote_probe函数开始跟:->remote_allocate_device;//->dev->input_device = input_allocate_device(); //分配并注册一个输入设备->ir_input_device_init(dev->input_device, &pdev->dev, "aml_keypad"); //初始化输入子设备->ir_hardware_init(struct platform_device *pdev) //初始化IR设备---------------------------------------------------------------->ret = ir_get_devtree_pdata(pdev); //这里去获取dts的配置参数->ret = of_property_read_u32(pdev->dev.of_node,"protocol", &chip->protocol); //这里解析dts配置的protocol参数,设置ir的协议支持,//如chip->protocol = 1(NEC协议),protocol的宏定义在./include/dt-bindings/input/meson_rc.h中//如果没有设置,则默认是支持进入NEC协议(chip->protocol = 1)模式->ret = get_custom_tables(pdev->dev.of_node, chip); //获取在dts的客制映射信息,红外码值和linux code映射以及其他参数->chip->set_register_config(chip, chip->protocol); //设置IR寄存器进入对应chip->protocol配置的协议模式->chip->set_register_config = ir_register_default_config; //配置IR寄存器,函数原型在remote_regmap.c中->ir_contr_init(struct remote_chip *chip, int type, unsigned char id); //配置ir寄存器初始化->remote_reg_write(chip, LEGACY_IR_ID, REG_REG1, 0x0); //禁用旧的红外控制器->ir_contr_init(chip, MULTI_IR_TYPE_MASK(type), MULTI_IR_ID); //初始化多格式红外控制器的寄存器,设置IR控制器进入对应的IR协议模式//MULTI_IR_ID = 0,在./drivers/amlogic/input/remote/remote_meson.h中定义->remote_reg_write(chip, id, REG_REG1, 0x01); //重设ir解码器并禁用ir解码器的状态机->for (  ; size > 0;  ) { remote_reg_write(chip, id, reg_map->reg, reg_map->val); //根据reg_map,依次设置当前IR控制器寄存器值}->ret = request_irq(chip->irqno, ir_interrupt, IRQF_SHARED, "keypad", (void *)chip); //这里申请中断,注册中断执行函数: ir_interrupt/* 有遥控按键的时候会触发中断,调用中断子程序 ir_interrupt */->在 ir_interrupt 中利用多格式红外控制器的时间测量实现多协议的软件解码(可到该函数去看看)->if (MULTI_IR_SOFTWARE_DECODE(rc->protocol)) { //识别软件是否解码-----------------ir_interrupt-----------------rc->ir_work = MULTI_IR_ID;duration = val*10*1000;type    = RAW_PULSE;sprintf(buf, "------\n");debug_log_printk(rc->r_dev, buf);->remote_raw_event_store_edge(rc->r_dev, type, duration); //存储原始码值->rc = remote_raw_event_store(dev, &ev);->kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev) //Kfifo是内核里面的一个first in first out数据结构,//它采用环形循环队列(ringbuffer)的数据结构来实现;它提供一个无边界的字节流服务->remote_raw_event_handle(rc->r_dev);->wake_up_process(dev->raw->thread);-----------------ir_interrupt----------------->else---------------------------------------------for (cnt = 0; cnt < (ENABLE_LEGACY_IR(rc->protocol)? 2:1); cnt++) {remote_reg_read(rc, cnt, REG_STATUS, &contr_status);if (IR_DATA_IS_VALID(contr_status)) {rc->ir_work = cnt;break;}}----------------------------------------------->tasklet_schedule(&tasklet); //在适当的时候调度tasklet任务机制->amlremote_tasklet //在tasklet中需要先获取扫描码,然后获取解码状态,状态可能是从获取扫描码功能设置的标志->scancode = chip->ir_contr[chip->ir_work].get_scancode(chip); //获取扫描码,即原始码值->.get_scancode      = ir_nec_get_scancode,->ir_nec_get_scancode(struct remote_chip *chip) //NEC获取扫描码的接口函数----------------- 读取解码器状态值和数据帧寄存器值 ------------------ |---------------------------------|->remote_reg_read(chip, MULTI_IR_ID, REG_STATUS, &decode_status); //  |###### 读取解码器的状态值 ###### |->chip->decode_status = status; /*set decode status*/ //设置解码器状态|---------------------------------||--------------------------|->remote_reg_read(chip, MULTI_IR_ID, REG_FRAME, &code); // |###读取数据帧寄存器数据###|寄存器定义在./drivers/amlogic/input/remote/remote_meson.h->chip->r_dev->cur_hardcode = code;                    |--------------------------|->code = (code >> 16) & 0xff;->return code; //经过一定处理[把数据帧寄存器数据左移16bit然后和0xff与运算后取值]后返回得到遥控码值code;//假如读到数据帧寄存器值为framecode=0x6699bd02的遥控码值是0x99----------------- 读取解码器状态值和数据帧寄存器值 ------------------->status = chip->ir_contr[chip->ir_work].get_decode_status(chip); //获取解码状态值->.get_decode_status = ir_nec_get_decode_status, //NEC获取解码器状态值->status = chip->decode_status; //解码器状态值为decode_status->if (status == REMOTE_NORMAL) { //REMOTE_NORMAL == 0,码器状态值为0,说明按键码是新按下的码值//remote_dbg(chip->dev, "receive scancode=0x%x\n", scancode);remote_keydown(chip->r_dev, scancode, status); //上报键值和状态} else if (status & REMOTE_REPEAT) { //REMOTE_REPEAT == 1, 解码器状态值为1,说明按键码重复之前的码值//status解码器状态值在./drivers/amlogic/input/remote/remote_core.h宏定义。remote_dbg(chip->dev, "receive repeat\n");->remote_keydown(chip->r_dev, scancode, status); //按键重复,上报键值和状态} else{dev_err(chip->dev, "receive error %d\n", status);}                         \-----------------------------------------------------------------/->remote_keydown(chip->r_dev, scancode, status); /*上报键值和状态 */||    ->ir_report_rel(dev, scancode, status)) { /*报告相对轴事件*/    ||  ->keycode = dev->getkeycode(dev, scancode);                    ||      ir_do_keydown(dev, scancode, keycode); /*上报按键事件 */      ||        ->if (KEY_RESERVED != keycode) {                           ||           dev->keypressed = true;                                ||           dev->last_scancode = scancode; /*红外遥控码值*/         ||            dev->last_keycode = keycode;   /*linux code值*/        ||            input_report_key(dev->input_device, keycode, 1); //input子系统上报linux键值码,keycode在include/dt-bindings/input/input.h宏定义,//这里在adb执行getevent,然后操作遥控可以get到上报的linux code值【16进制数据】|          input_sync(dev->input_device);                //这里转换成16进制report/-----------------------------------------------------------------\   ->.get_custom_code   = ir_nec_get_custom_code //NEC获取客户码->custom_code = chip->r_dev->cur_hardcode & 0xffff; //这里是取数据帧寄存器数据的低16位为custom_code//假如读到数据帧寄存器值为framecode=0x6699bd02, 则客户码是0xbd02->tasklet_enable(&tasklet); //使能tasklet任务机制---------------------------------------------------------->ret = ir_cdev_init(chip); //初始化字符设备[]->ret = alloc_chrdev_region(&chip->chr_devno, 0, 1, AML_REMOTE_NAME); //动态分配设备号->ret = ir_sys_device_attribute_init(chip); //初始化sys文件系统->class_register(&remote_class); //注册class->dev = device_create(&remote_class,  NULL, chip->chr_devno, chip, chip->dev_name); //基于设备类创建设备节点-------------------------->static ssize_t protocol_show; //cat节点protocol查看当前的IR协议模式->static ssize_t protocol_store; //echo > 节点protocol设置选择进入的IR协议模式->ret = kstrtoint(buf, 0, &protocol); //设置进入对应的红外协议模式->chip->protocol = protocol;->chip->set_register_config(chip, chip->protocol);-------------------------休眠:.suspend = remote_suspend,->remote_suspend(struct platform_device *pdev, pm_message_t state); //休眠调用->disable_irq(chip->irqno); //关闭中断唤醒:.resume = remote_resume,->remote_resume(struct platform_device *pdev); //唤醒调用->chip->set_register_config(chip, chip->protocol); //重新设置IR寄存器进入对应chip->protocol配置的协议模式

5、remote相关节点

gtt92x:/ # ls -l sys/devices/virtual/remote/amremote/
total 0
-rw-r--r-- 1 root root 4096 1970-02-24 15:27 debug_enable
-rw-r--r-- 1 root root 4096 1970-02-24 15:27 debug_log
-r--r--r-- 1 root root 4096 1970-02-24 15:27 dev
-rw-r--r-- 1 root root 4096 1970-02-24 15:27 keymap
-r--r--r-- 1 root root 4096 1970-02-24 15:27 map_tables
drwxr-xr-x 2 root root    0 1970-02-24 15:26 power
-rw-r--r-- 1 root root 4096 1970-02-24 15:29 protocol
-rw-r--r-- 1 root root 4096 1970-02-24 15:27 repeat_enable
lrwxrwxrwx 1 root root    0 1970-02-24 15:27 subsystem -> ../../../../class/remote
-rw-r--r-- 1 root root 4096 1970-02-24 15:26 uevent
gtt92x:/ #

节点sys/devices/virtual/remote/amremote/protocol可以设置当前的红外协议模式,当前配置为NEC模式,在dts配置protocol = <REMOTE_TYPE_NEC>;

echo 1 > sys/devices/virtual/remote/amremote/protocol //设置为NEC协议REMOTE_TYPE_NEC模式
echo 131 > sys/devices/virtual/remote/amremote/protocol //设置为RAW协议REMOTE_TYPE_RAW_XMP_1模式

相关的红外协议模式在./include/dt-bindings/input/meson_rc.h中有宏定义,可以根据meson_rc.h往节点protocol写入对应数值设置当前支持的红外协议模式。

 17 /*hardware decode one protocol by using multi-format IR controller*/18 #define     REMOTE_TYPE_UNKNOW      0x0019 #define     REMOTE_TYPE_NEC         0x0120 #define     REMOTE_TYPE_DUOKAN      0x0221 #define     REMOTE_TYPE_XMP_1       0x0322 #define     REMOTE_TYPE_RC5         0x0423 #define     REMOTE_TYPE_RC6         0x0524 #define     REMOTE_TYPE_TOSHIBA     0x062526 /*hardware decode one protocol by using legacy IR controller*/27 #define     REMOTE_TYPE_LEGACY_NEC  0xff2829 /**30   *software decode multiple protocols by using Time measurement31   *of multi-format IR controller32   *using bit[7] to identify the software decode33   */34 #define     REMOTE_TYPE_RAW_NEC     0x8135 #define     REMOTE_TYPE_RAW_XMP_1   0x83

Amlogic_t962x_android7.1红外遥控驱动浅析相关推荐

  1. 移动咪咕盒子红外遥控驱动

    最近入手了一块显示屏,又惊喜的发现移动咪咕盒子一直落灰,(反正盒子没破解也不能看电视),那给我的讯为4412开发板刷个安卓系统,写个红外遥控驱动烧进去,这样就能用咪咕盒子的遥控器看电视了.说干就干,开 ...

  2. android红外遥控驱动

    在 Linux 内核中,IR 驱动仅支持 NEC 编码格式. 设备树文件 pwm0: pwm@ff680000 {compatible = "rockchip,rk-pwm";re ...

  3. Linux红外遥控驱动HS0038

    测试平台imx6q linux5.4.215 华为电信高清IPTV遥控器 使用其它遥控器可以更改key_table和user_id #include <linux/module.h> #i ...

  4. 遥控窗帘c语言程序,使用AT89C2051的红外遥控窗帘

    本文介绍一款使用微电脑管理的.红外遥控器控制的多功能窗帘控制器.该窗帘控制器采用89C2051单片机的最小系统设计,控制一个220V的可逆.变速电动机控制窗帘的拉开和关闭.窗帘控制器可以使用红外遥控器 ...

  5. AutoLeaders控制组——51单片机学习笔记(AD/DA、红外遥控)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...

  6. 遥控汽车的编程c语言,智能小车循迹、避障、红外遥控C语言代码.docx

    //智能小车避障.循迹.红外遥控C语言代码 // 实现功能有超声波避障, 红外遥控智能小车, 红外传感器实现小车自动循迹, 1602 显示小 车的工作状态,另有三个独立按键分别控制三种状态的转换 // ...

  7. 搭建红外遥控arm-hadoop集群过程

    很多人玩开发板用树莓派,树莓派的确很好,但是对于hadoop来说,内存有点小,只有512MB.所以我找了一圈,最后用的是国内一个开源硬件团队的产品叫CubieTruck.内存有2G,板载存储有8G,千 ...

  8. 基于红外遥控的arduino遥控小车

    遥控小车是每个人童年的最爱,不仅好奇它的奇妙,更是喜欢它带来的刺激.小编为大家带来几篇博客,来给大家讲讲制作遥控小车的程序. 看大标题可知我们一共有五个方法去制作一款带有遥控功能的小车,小编分开来给大 ...

  9. 循迹智能小车c语言主程序,智能小车循迹、避障、红外遥控C语言代码

    <智能小车循迹.避障.红外遥控C语言代码>由会员分享,可在线阅读,更多相关<智能小车循迹.避障.红外遥控C语言代码(13页珍藏版)>请在人人文库网上搜索. 1.智能小车避障.循 ...

  10. 树莓派配置红外遥控及关联python程序

    前言 关于树莓派配置红外遥控的过程,我相信玩过的人知道这里的坑有多少,在这写一下我配置的过程,仅供参考 硬件 1.树莓派4B 2.红外遥控器及接收模块,我用的 这里不得不提一下有关红外接收模,之前我用 ...

最新文章

  1. 再见了,公司的“烂系统”
  2. 零起点学习WPF之《WPF揭秘》读书笔记(7)——第三章 变更通知
  3. opencv将整个图片BGR通道的某个通道进行修改
  4. cnpm install时提示resource busy or locked,syslink...
  5. [Python]从零开始学python——Day03 字典,元组
  6. mysql数据压缩存储_压缩文本,然后存储在mysql数据库中
  7. layui列表筛选列_Shopify搜索产品并筛选产品列表功能介绍
  8. webstorm环境安装配置(less+autoprefixer)
  9. datatable行内内容太长,有时不自动换行解决方法
  10. python控制视频_控制Python面向对象的访问
  11. mysql集群异地部署_linux 环境下 部署mysql 集群
  12. 数据仓库和数据集市详解:ODS、DW、DWD、DWM、DWS、ADS
  13. 怎样才能走进区块链行业?
  14. 【读书笔记】点亮心中的那盏灯
  15. python生产实战 python 闭包之庖丁解牛篇
  16. django后台搜索显示Related Field got invalid lookup: icontains
  17. 从自身做起 全面提高论坛UEO
  18. 武林外传电影版java,武林外传经典台词
  19. vue watch的用法及新旧值一样问题解决
  20. android malware

热门文章

  1. CSS hack:区分IE6,IE7,firefox
  2. Python如何提取docx中的超链接
  3. EMNLP'21中预训练模型最新研究进展
  4. 【过拟合】防止模型过拟合的必备方法!
  5. 【NLP】关系提取简述
  6. 学生时代,代码要从 0 写起,拒绝拷贝!
  7. PyTorch学习—4.计算图与动态图机制以及torch.autograd(自动求导系统)
  8. 深度学习TF—9.循环神经网络RNN及其变体GRU、LSTM
  9. python—contour绘制轮廓线(等高线)
  10. notepad++反向查找/向上查找