概述

架构

Realtek 的红外 (IR) 驱动遵循 Linux 框架:RC 核心、IR 核心和 LIRC 系统。LIRC 为用户空间提供红外接口。以下是红外软件架构示意图。

../../rst_linux/8_ir/figures/ir_software_arch.svg

有关 Linux 遥控系统的更多细节,请参考 Remote Controller v5.4Remote Controller v6.6

IR 被包含在 Linux 遥控部分。

实现

IR 驱动程序实现为以下文件:

驱动位置

介绍

<linux>/drivers/rtkdrivers/ir/Kconfig

IR 驱动程序 Kconfig

<linux>/drivers/rtkdrivers/ir/Makefile

IR 驱动程序 Makefile

<linux>/drivers/rtkdrivers/ir/ir-realtek.c

IR 函数

<linux>/drivers/rtkdrivers/ir/ir-realtek.h

IR 相关函数声明、宏定义、结构定义以及引用的其他头文件

配置

设备树配置

IR 设备树的摘录如下:

ir: ir@0x400EE000 {
   compatible = "realtek,ameba-ir";
   reg = <0x400EE000 0x30>;
   interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
   clocks = <&rcc RTK_CKE_IRDA>;
   rtk,ir-receiver = <0>;
   rtk,ir-tx-encode = <1>;
   rtk,ir-rx-auto = <1>;
   rtk,ir-cnt-thred-type = <1>;
   rtk,ir-cnt-threshold = <30000>;
   rtk,ir-rx-trigger-mode = <0>;
   rtk,ir-idle-level = <0>;
   rtk,ir_rx_inverse = <0>;
   status = "disabled";
};

IR 的设备树配置列在下表中。

属性

描述

可配置?

compatible

IR驱动的描述: realtek,ameba-ir

reg

IR 设备的硬件地址和大小: <0x400EE000 0x30>

interrupts

IR 设备的 GIC 号: <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>

clocks

IR 设备的时钟: <&rcc RTK_CKE_IRDA>

rtk,ir-receiver

  • 设置 1 以将 IR 配置为接收器

  • 设置 0 以将 IR 配置为发射器

0/1

rtk,ir-tx-encode

设置 1 以发送扫描码

设置为0时,编码和解码应由用户空间完成,IR驱动程序仅传输用户空间提供的原始数据

0/1

rtk,ir-rx-auto

  • 设置为1时,设备开启后会自动接收所有IR信号

  • 设置为0时,仅在某些时间段内接收IR信号

0/1

rtk,ir-cnt-threshold

用于判断结束的时间。这里设置为30000表示如果硬件在30毫秒内未收到数据,则表示传输结束

rtk,ir-cnt-thred-type

  • 设置为0表示如果低电平持续时间超过计数阈值,则信号终止

  • 设置为1表示如果高电平持续时间超过计数阈值,则信号终止

0/1

rtk,ir-rx-trigger-mode

边缘接收过程开始于:

  • 0: 下降沿

  • 1: 上升沿

  • 2: 两者皆有

0/1/2

rtk,ir-idle-level

  • 0: 低电平表示空闲

  • 1: 高电平表示空闲

0/1

rtk,ir_rx_inverse

  • 0: 不需要软件反相

  • 1: 需要软件反相

0/1

status

是否启用设备

  • disabled

  • okay

IR 引脚分配列在下表中。

引脚名字

引脚功能

pinctrl 描述

PB10

IR_RX

<&ir_pins>

PB11

IR_TX

PA25

IR_TX

需手动添加

PB22

IR_RX

PB25

IR_TX

需手动添加

PB26

IR_RX

PA3

IR_TX

需手动添加

PA4

IR_RX

PA17

IR_TX

需手动添加

可以根据具体情况选择引脚复用。更多详情请参考 pinctrl 文档说明。

编译配置

为遥控功能选择 Device Drivers > Drivers for Realtek > IR

../../rst_linux/8_ir/figures/ir_driver.png

API

用户空间 API

用户空间的 IR 接口由 LIRC header v5.4LIRC header v6.6 提供。

以下是一些常用的用于控制 IR 设备的 API。 参考 LIRC FUNC v5.4LIRC FUNC v6.6 获取更多细节。

接口

介绍

ir_lirc_open

打开IR设备

ir_lirc_close

关闭IR设备

ir_lirc_ioctl

配置IR参数

ir_lirc_transmit_ir

调用IR驱动程序发送消息

ir_lirc_read

读取接收到的扫描码

IR 发送示例

  1. 打开 IR 设备

    fd = open("/dev/lirc0", O_RDWR);
    
  2. 将 IR 模式更改为扫描码传输

    #include <linux/lirc.h>
    int to_set = LIRC_MODE_SCANCODE;
    ret = ioctl(fd, LIRC_SET_SEND_MODE, &to_set);
    
  3. 配置用于发送的 IR 扫描码

    • timestamp 并不重要。

    • keycodeflags 需设为 0。

    • rc_proto 需设为 RC_PROTO_NEC

    • 要发送的 scancode 应按照 NEC 规则组织,否则传输将返回错误。

    #include <linux/lirc.h>
    struct lirc_scancode {
       __u64  timestamp;
       __u16  flags;
       __u16  rc_proto;
       __u32  keycode;
       __u64  scancode;
    };
    struct lirc_scancode scan;
    scan.rc_proto = RC_PROTO_NEC;
    scan.scancode = 0xEA158A75;
    scan.keycode = 0;
    scan.timestamp = 0;
    scan.flags = 0;
    
  4. 发送 IR 扫描码:返回 0 表示成功;否则表示失败。

    ret = write(fd, &scan, sizeof(scan));
    

IR 接收示例

  1. 打开 IR 设备

    fd = open("/dev/lirc0", O_RDWR);
    

    当 IR 驱动器被配置为接收模式时,打开 IR 意味着开始 IR 接收。

    此过程可以忽略,因为 IR 设备将在下一个过程中自动打开。

  2. 打开事件处理程序

    getevent -l &
    

    符号 & 用于使事件通知与 IR 接收过程并行进行。

  3. 等待 IR 信号。对面的发射器也应是 IR 发光半导体。

    当接收到信号时,波形将通过 NEC 协议解码,然后转换为扫描码。扫描码将提交给事件处理程序,并作为事件通知用户空间。

    参考 <test>/ir 获取更多细节。

内核空间 API

无。