常识

  1. 红外线的定义:红外线是人眼无法观察的一种光波,具有抗干扰能力强,传输信息可靠的特点。常用于家用电器的红外遥控。可以通过红外发射二极管来发射红外线。红外发射二极管与普通的发光二极管的区别是:红外发光二极管发射的光不可见,而普通的发光二极管发出的光是可见的。
  2. 红外遥控的原理:常用的方式是将bit 0与bit 1调制在38KHZ的载波上,在通过红外发射二极管转化为红外信号发射出去。

image.png

  1. 红外发光二极管的参考设计电路如下:

image.png

  1. 常用的红外通信协议NEC的介绍:NEC通讯协议包含有:引导码、8bit的用户码、8bit的用户码反码、8bit的命令码、8bit的命令码反码、结束码。8bit的用户码和8bit的用户码反码通常会组成一个16位的用户码(代码中通常使用usercode变量用户码;用scancode表示命令码)。用户码是用来区分不同的遥控器的。命令则对应遥控器下的不同的按键。一个遥控器有且仅有一个用户码,有一个或多个命令码。NEC需要使用38KHZ的脉冲方波表示不同的信号,我们来学习一下看一下下面这张图,从图中可以看到:①引导码需要用需要连续产生9毫秒的脉冲方波,以及4.5毫秒的低电平;②bit 0是用0.56毫秒的38KHZ的脉冲方波以及0.56毫秒的低电平组成;③bit 1是用0.56毫秒的38KHZ脉冲方波以及1.685毫秒的低电平组成;④结束码是用0.56毫秒的38KHZ脉冲方波来表示;

image.png

  1. input子系统与红外的关系:接收到往外遥控的命令码之后,会映射为input子系统所定义keycode,然后通过input子系统上报给用户空间。用户空间可以通过常规的对于input设备的方法,来获知红外按键事件。

    RK3399的IR驱动分析

    对于rk3399的驱动所涉及的文件有:

    1. rk3399/kernel/drivers/input/remotectl/rockchip_pwm_remotectl.c 作用:红外接收与解码
    2. rk3399/kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 作用:定义pwm3节点,用做接收NEC载波
    3. rk3399/kernel/arch/arm64/boot/dts/rockchip/rk3399-lonbon-core.dtsi 作用:引用pwm3节点,在pwm3节点下定义key_table,这个表格是用于定义红外扫描码(scancode)与input子系统的按键码(keycode)的映射,如下:
    4. &pwm3 {
    5. status = "okay";
    6. interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH 0>;
    7. compatible = "rockchip,remotectl-pwm";
    8. remote_pwm_id = <3>;
    9. handle_cpu_id = <0>;
    10. ir_key1{
    11. rockchip,usercode = <0xff00>;
    12. rockchip,key_table =
    13. {0xeb, KEY_POWER}, // Power
    14. //Control
    15. {0xa3, 250}, // Settings
    16. {0xec, KEY_MENU}, // Menu
    17. {0xfc, KEY_UP}, // Up
    18. {0xfd, KEY_DOWN}, // Down
    19. {0xf1, KEY_LEFT}, // Left
    20. {0xe5, KEY_RIGHT}, // Right
    21. {0xf8, KEY_REPLY}, // Ok
    22. {0xb7, KEY_HOME}, // Home
    23. {0xfe, KEY_BACK}, // Back
    24. // Vol
    25. {0xa7, KEY_VOLUMEDOWN}, // Vol-
    26. {0xf4, KEY_VOLUMEUP}, // Vol+
    27. };
    28. };
    29. 注:第一列为键值,第二列为要响应的按键码。

    核心数据结构: ```c struct rkxx_remote_key_table { int scancode; //翻译为“扫描码”,对应为红外遥控器的命令码 int keycode; //翻译为“按键码”,对应input子系统的按键码 };

struct rkxx_remotectl_button { int usercode; //用户码:不同的红外遥控码表示不同的红外遥控器 int nbuttons; //红外遥控器下多少个按键 struct rkxx_remote_key_table key_table[MAX_NUM_KEYS]; };

**接口说明:**
```c
static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id)   作用:红外接收管接收到红外载波后进入该中断,会调用rk_pwm_remotectl_do_something
static void rk_pwm_remotectl_do_something(unsigned long  data) 作用:rk_pwm_remotectl_do_something负责解码

动态调试参数:
使用下面命令可以使能 DBG_CODE 打印,打印用户码与命令码:

echo 1 > /sys/module/rockchip_pwm_remotectl/parameters/code_print

将 IR 驱动编译进内核:
将 IR 驱动编译进内核的步骤如下所示:
(1)、向配置文件 kernel/drivers/input/remotectl/Kconfig 中添加如下配置:

config ROCKCHIP_REMOTECTL_PWM
        bool "rockchip remoctrl pwm capture"
        default n

(2)、修改 kernel/drivers/input/remotectl/Makefile 文件,添加如下编译选项:

obj-$(CONFIG_ROCKCHIP_REMOTECTL_PWM)    += rockchip_pwm_remotectl.o

(3)、在 kernel 路径下使用 make menuconfig ,按照如下方法将 IR 驱动选中。

Device Drivers
  --->Input device support
  ----->  [*]   rockchip remotectl
  ------->[*]   rockchip remoctrl pwm capture

保存后,执行 make 命令即可将该驱动编进内核。

S905D3的分析