概述
架构
Realtek 的红外 (IR) 驱动遵循 Linux 框架:RC 核心、IR 核心和 LIRC 系统。LIRC 为用户空间提供红外接口。以下是红外软件架构示意图。
有关 Linux 遥控系统的更多细节,请参考 Remote Controller v5.4 或 Remote 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驱动的描述: |
否 |
reg |
IR 设备的硬件地址和大小: <0x400EE000 0x30> |
否 |
interrupts |
IR 设备的 GIC 号: <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH> |
否 |
clocks |
IR 设备的时钟: <&rcc RTK_CKE_IRDA> |
否 |
rtk,ir-receiver |
|
0/1 |
rtk,ir-tx-encode |
设置 1 以发送扫描码 设置为0时,编码和解码应由用户空间完成,IR驱动程序仅传输用户空间提供的原始数据 |
0/1 |
rtk,ir-rx-auto |
|
0/1 |
rtk,ir-cnt-threshold |
用于判断结束的时间。这里设置为30000表示如果硬件在30毫秒内未收到数据,则表示传输结束 |
否 |
rtk,ir-cnt-thred-type |
|
0/1 |
rtk,ir-rx-trigger-mode |
边缘接收过程开始于:
|
0/1/2 |
rtk,ir-idle-level |
|
0/1 |
rtk,ir_rx_inverse |
|
0/1 |
status |
是否启用设备
|
是 |
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 文档说明。
编译配置
为遥控功能选择
:
API
用户空间 API
用户空间的 IR 接口由 LIRC header v5.4 或 LIRC header v6.6 提供。
以下是一些常用的用于控制 IR 设备的 API。 参考 LIRC FUNC v5.4 或 LIRC FUNC v6.6 获取更多细节。
接口 |
介绍 |
---|---|
ir_lirc_open |
打开IR设备 |
ir_lirc_close |
关闭IR设备 |
ir_lirc_ioctl |
配置IR参数 |
ir_lirc_transmit_ir |
调用IR驱动程序发送消息 |
ir_lirc_read |
读取接收到的扫描码 |
IR 发送示例
打开 IR 设备
fd = open("/dev/lirc0", O_RDWR);
将 IR 模式更改为扫描码传输
#include <linux/lirc.h> int to_set = LIRC_MODE_SCANCODE; ret = ioctl(fd, LIRC_SET_SEND_MODE, &to_set);
配置用于发送的 IR 扫描码
timestamp 并不重要。
keycode 和 flags 需设为 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;
发送 IR 扫描码:返回
0
表示成功;否则表示失败。ret = write(fd, &scan, sizeof(scan));
IR 接收示例
打开 IR 设备
fd = open("/dev/lirc0", O_RDWR);
当 IR 驱动器被配置为接收模式时,打开 IR 意味着开始 IR 接收。
此过程可以忽略,因为 IR 设备将在下一个过程中自动打开。
打开事件处理程序
getevent -l &
符号
&
用于使事件通知与 IR 接收过程并行进行。等待 IR 信号。对面的发射器也应是 IR 发光半导体。
当接收到信号时,波形将通过 NEC 协议解码,然后转换为扫描码。扫描码将提交给事件处理程序,并作为事件通知用户空间。
参考
<test>/ir
获取更多细节。
内核空间 API
无。