RK3288_Android7.1调试红外遥控IR

本文详细解析了红外遥控器的工作原理,包括发射电路和接收电路的组成,以及红外遥控编码传输协议的多样性。重点介绍了RK平台上的红外遥控实现机制,包括PWM工作模式、用户码与键值的获取及调试方法,以及从红外层到Android层的键值映射过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

红外遥控的发射电路是采用红外发光二极管来发出经过调制的红外光波;红外接收电路由红外接收二极管、三极管或硅光电池组成,它们将红外发射器发射的红外光转换为相应的电信号,再送后置放大器。鉴于家用电器的品种多样化和用户的使用特点,生产厂家对红外遥控编码进行了严格的规范编码,这些编码各不相同,从而形成不同的编码方式,统一称为红外遥控器编码传输协议。到目前为止,红外遥控协议已多达十种, 如: RC5、 SIRCS、 Sy、 RECS80、Denon、NEC、Motorola、Japanese、SAMSWNG 和 Daewoo 等。我国家用电器的红外遥控器的生产厂家,其编码方式多数是按上述的各种协议进行编码的,而用得较多的有 NEC 协议。目前 RK 平台也只支持 NEC 编码的红外协议。
RK 平台上红外实现原理简介
PWM 有三种工作模式, reference mode, one-shot mode 和 continuousmode. 红外遥控器就采用 reference mode,这种模式下 PWM 可以捕获输入高低电平的宽度,并产生中断,CPU接收到中断后去相应的寄存器读取。
按下遥控的时候,红外接收头会产生一系列的高低电平,PWM 就会产生相应的中断,CPU 读取相应的寄存器就知道这些高低电平的时间,根据协议就可以解码出红外的用户码和键值码出来。

1、查看遥控器的用户码和键值,供应商给的可能是反码,也有可能不正确,最好是自己打印出来看看是啥。
打开红外打印功能有以下两种方式,内核打印可以用串口,也可以在adb中使用指令 # cat proc/kmsg

(1)通过指令打开红外接收的打印功能,然后按遥控器按键,就可以在内核打印中看到用户码和键值。

root@rk3288:/ # cat sys/module/rockchip_pwm_remotectl/parameters/code_print     
0
root@rk3288:/ # echo 1 > sys/module/rockchip_pwm_remotectl/parameters/code_print

(2)在红外接收的源码中,给下面变量赋值,也可以打印用户码和键值,但需要重新编译烧录内核

path:kernel/drivers/input/remotectl/rockchip_pwm_remotectl.c

static int rk_remote_print_code = 1;

Kernel修改:

	--- a/arch/arm/boot/dts/rk3288-evb-android-rk808-hdmi.dts
	+++ b/arch/arm/boot/dts/rk3288-evb-android-rk808-hdmi.dts
	@@ -43,6 +43,7 @@
	 /dts-v1/;
	 #include "rk3288-evb.dtsi"
	 #include "rk3288-android.dtsi"
	+#include <dt-bindings/input/input.h>  //czd: support IR-Remote.

	 / {
        compatible = "rockchip,rk3288-evb-android-rk808-hdmi", "rockchip,rk3288";
	@@ -397,3 +398,71 @@
        pinctrl-0 = <&pwm1_pin_pull_down>;
	 };

	+//add by czd for support IR-Remote on start
	+&pwm2 {
	+       status = "okay";
	+       compatible = "rockchip,remotectl-pwm";
	+       pinctrl-names = "default";
	+       pinctrl-0 = <&pwm2_pin>;
	+       remote_pwm_id = <2>;
	+       handle_cpu_id = <1>;
	+       interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
	+       remote_support_psci = <1>;
	+
	+    ir_key1{
	+        rockchip,usercode = <0xbd02>;
	+        rockchip,key_table =
	+            <0x2f   KEY_BACK>,
	+             <0x35   KEY_UP>,
	......
	}

Android层修改:

	zwei@ubt144c:/work/zwei/czd/rk3288_7.1_mid/device/rockchip/common$ git diff
		diff --git a/device.mk b/device.mk
	index 37e73d5..fc82c24 100755
	--- a/device.mk
	+++ b/device.mk
	@@ -101,7 +101,7 @@ PRODUCT_COPY_FILES += \
     device/rockchip/common/ueventd.rockchip.rc:root/ueventd.$(TARGET_BOARD_HARDWARE).rc \
     device/rockchip/common/media_profiles_default.xml:system/etc/media_profiles_default.xml \
     device/rockchip/common/rk29-keypad.kl:system/usr/keylayout/rk29-keypad.kl \
    -    device/rockchip/common/ff680030_pwm.kl:system/usr/keylayout/ff680030_pwm.kl \
    +    device/rockchip/common/ff680030_pwm.kl:system/usr/keylayout/ff680020_pwm.kl \
         device/rockchip/common/alarm_filter.xml:system/etc/alarm_filter.xml \

并且需要添加对应按键的linux code和android code到ff680020_pwm.kl文件。

a)打开打印键值的调试开关:

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

b) 按遥控器的按键,记录下对应的键值

     [19634.735833] GET USERCODE=0xbd02
     [19634.762463] RMC_GETDATA=e9

说明:该遥控器的 usercode 是 0xbd02,向下键的键值就是 0xe9

有时候无法确定是内核按键判断出错,还是 android 层没有响应某个按键,可以在串口下输入getevent 调试命令,该命令会打印出驱动上报的所有 input 事件,如果按遥控器有打印,并且键值正确,那说明是 android 响应的问题。

    rk3288:/ # getevent                                                            
    add device 1: /dev/input/event1
	  name:     "rk29-keypad"
	add device 2: /dev/input/event0
	  name:     "ff680020.pwm"
	/dev/input/event0: 0001 006c 00000001
	/dev/input/event0: 0000 0000 00000000
	/dev/input/event0: 0001 006c 00000000
	/dev/input/event0: 0000 0000 00000000
	/dev/input/event0: 0001 009e 00000001

cmd输入 getevent,最前面会列出所有的 input 设备,按的时候会上报
事件,其中 0x6c 是上报的 linux 键值,后面的 1 代表按下,如果是 0 则代表弹起。

如果没有getevent到事件,无键值上报,adb执行cat proc/interrupts可以查看中断interrupt的注册使用情况:(第一列的数字对应注册的中断号,第二第三第四第五列数字分别表示中断在哪一个cpu上处理,有中断过来的话,对应的cpu下的数字相应自加1)

rk3288:/ # cat proc/interrupts
           CPU0       CPU1       CPU2       CPU3       
 16:          0          0          0          0       GIC  29 Edge      arch_timer
 17:     118303      97092      81417     115531       GIC  30 Edge      arch_timer
 20:          0          0          0          0       GIC  98 Level     rk_timer
 25:          0          0          0          0       GIC  34 Level     ff250000.dma-controller
 26:          0          0          0          0       GIC  35 Level     ff250000.dma-controller
 27:        367          0          0          0       GIC  32 Level     ff600000.dma-controller
 28:          0          0          0          0       GIC  33 Level     ff600000.dma-controller
 29:          0          0          0          0       GIC  64 Level     dw-mci
 30:      14838          0          0          0       GIC  65 Level     dw-mci
 31:      34851          0          0          0       GIC  67 Level     dw-mci
 32:       4565          0          0          0       GIC  68 Level     ff100000.saradc
 33:        747          0          0          0       GIC  92 Level     ff650000.i2c
 34:          0          0          0          0       GIC  94 Level     ff140000.i2c
 35:        153          0          0          0       GIC  95 Level     ff150000.i2c
 37:          0          0          0          0       GIC  69 Level     rockchip_thermal
 38:       4352          0          0          0       GIC  59 Level     eth0
 39:          0          0          0          0       GIC  60 Level     eth0
 40:          0          0          0          0       GIC  56 Level     ehci_hcd:usb2
 41:          0          0          0          0       GIC  73 Level     ohci_hcd:usb3
 42:        151          0          0          0       GIC  57 Level     ff540000.usb, dwc2_hsotg:usb1
 43:        489          0          0          0       GIC  55 Level     dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb4
 44:         24          0          0          0       GIC  93 Level     ff660000.i2c
 45:          0          1          0          0       GIC 110 Level     rk_pwm_irq

关于键值转换说明:键值经过两次转换到达安卓上层:
在Dts配置:(16进制寄存器值转换成linux code的宏,

0x35   KEY_UP

其中0x35为遥控键值码;
KEY_UP宏定义在include/dt-bindings/input/linux-event-codes.h文件)
这样遥控器红外层到linux层的键值映射就完成了。
input输入子系统上报键值(adb shell && getevent查看):

	/dev/input/event0: 0001 0067 00000001
	/dev/input/event0: 0000 0000 00000000
	/dev/input/event0: 0001 0067 00000000
	/dev/input/event0: 0000 0000 00000000

其中 0x67 是上报的 linux 键值(include/dt-bindings/input/linux-event-codes.h文件的10进制转成的16进制数,如0067是由103转换而来),后面的 1 代表按下,如果是 0 则代表弹起。

.kl文件键值转换:android kl(key layout)文件是一个映射文件,是标准linux与anroid的键值映射文件。adb使用dumpsys input命令可以查看当前设备对应使用的是哪个kl文件,(RK平台的 kl 文件一般是放在\device\rockchip\common(如rk3288) 目录下,与getevent获取的name属性名字一样的文件(只不过name中的“.”要换成 kl 中的“_”)。每个芯片的 kl 文件名字不一样,需要注意,一般在\device\rockchip\common\device.mk文件配置。),如果没有配置对应设备的.kl文件,则会默认使用Generic.kl这个kl
==>

	rk3288:/ # getevent                                                            
	add device 1: /dev/input/event1
	name:     "rk29-keypad"
	add device 2: /dev/input/event0
	  name:     "ff680020.pwm"

则对应需要kl文件为:ff680020_pwm.kl,目录在/system/usr/keylayout/,可以push进去验证

	130|rk3288:/ $ dumpsys input
    2: ff680020.pwm
      Classes: 0x00000401
      Path: /dev/input/event0
      Descriptor: d2c52ff0f656fac4cd7b7a118d575e0109a9fe1c
      Location: gpio-keys/remotectl
      ControllerNumber: 0
      UniqueId: 
      Identifier: bus=0x0019, vendor=0x0001, product=0x0001, version=0x0100
      KeyLayoutFile: /system/usr/keylayout/ff680020_pwm.kl
      KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
      ConfigurationFile: 
      HaveKeyboardLayoutOverlay: false

kl文件内容:

	key 28    ENTER
	key 116   POWER
	key 158   BACK、

说明:
key是固定的
28是linux code值
ENTER是Android code值
这样kernel层到Android层的键值映射就完成了。

<think>我们正在RK3128 Android 7.1平台上适配红外遥控器(IR模块),目标是获取遥控器键值。根据参考信息,我们可以采用以下步骤: ### 一、内核层配置 1. **启用红外接收驱动**: - RK3128通常使用`rockchip_pwm_remotectl`驱动,需在内核中启用: ```bash Device Drivers ---> Input device support ---> [*] Keyboards ---> <*> Rockchip PWM remote controller ``` 2. **设备树配置**: - 在`dts`文件中添加红外节点(通常在`i2c0`或`pwm`节点附近): ```dts &pwm0 { status = "okay"; }; &remotectl { status = "okay"; handle_cpu_id = <1>; ir_key1 { rockchip,usercode = <0xff00>; // 用户码(需替换为实际值) rockchip,key_table = <0xeb KEY_POWER>, // 键值映射 <0xec KEY_MENU>, <0xfe KEY_BACK>; }; }; ``` - **关键参数**: - `rockchip,usercode`:遥控器的用户码(通过`ir-keytable`工具读取原始值) - `rockchip,key_table`:将原始键值映射到Linux键值(如`KEY_POWER`) ### 二、驱动调试与键值获取 1. **查看原始红外数据**: ```bash adb shell cat /sys/devices/platform/ff680030.pwm/remotectl/decoder # 路径可能不同 ``` 按下遥控器按键,观察输出的用户码和键值。 2. **动态调试键值映射**(临时修改): ```bash echo "0xff00 0xeb 116" > /sys/class/remotectl/remotectl/keymap # 116=KEY_POWER ``` ### 三、Android键值映射 1. **创建按键布局文件**: - 在`/system/usr/keylayout/`下创建`Vendor_0001_Product_0001.kl`(文件名根据实际设备ID): ``` key 116 POWER WAKE key 139 MENU key 158 BACK ``` - **注意**:键值(如116)需与驱动上报的Linux键值一致。 2. **验证键值上报**: ```bash getevent -l # 查看原始事件 dumpsys input # 查看Android输入系统状态 ``` ### 四、优化建议(避免冗余设计) - **直接内核上报**:参考引用[2]的吐槽,应避免在用户态做中转,直接在内核驱动中完成键值映射并上报到`input`子系统。 ### 常见问题解决 1. **遥控无响应**: - 检查硬件连接(红外接收器是否接到正确的GPIO) - 确认设备树中`remotectl`的`pinctrl`配置正确: ```dts pinctrl-names = "default"; pinctrl-0 = <&ir_int>; ``` 2. **键值错误或重复**: - 调整驱动去抖参数(设备树中添加): ```dts rockchip,no_delay = <1>; // 禁用去抖(根据实际情况调整) ``` ### 相关问题 1. 如何获取遥控器的用户码和原始键值? 2. RK3128的红外接收GPIO应该如何配置? 3. Android 7.1的按键事件处理流程是怎样的? 4. 如何为不同的遥控器动态加载键值映射? 5. 红外遥控响应延迟大如何优化? [^1]: RK3128红外驱动配置与键值映射方法 [^2]: Android输入子系统处理流程</think>### RK3128 Android 7.1 红外遥控器适配指南 #### 一、内核层配置 1. **启用红外驱动**: ```bash make menuconfig # 路径: Device Drivers ---> Input device support ---> [*] Keyboards ---> <*> Rockchip PWM remote controller # RK3128专用驱动 ``` 2. **设备树配置**(修改 `rk3128.dtsi`): ```dts &pwm0 { compatible = "rockchip,remotectl-pwm"; status = "okay"; interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pwm0_pin>; }; &remotectl { status = "okay"; handle_cpu_id = <1>; // CPU核心ID ir_key1 { rockchip,usercode = <0x7f80>; // 遥控器用户码(需实测) rockchip,key_table = <0xeb KEY_POWER>, // 键值映射表 <0xa3 KEY_MENU>, <0xec KEY_HOME>; }; }; ``` **关键参数**: - `usercode`:通过示波器或调试工具获取的遥控器标识码 - `key_table`:原始键值到Linux键值的映射表(如 `KEY_POWER=116`) #### 二、驱动调试与键值获取 1. **查看原始红外数据**: ```bash adb shell cat /sys/devices/platform/ff680030.pwm/remotectl/decoder # 查看原始键值 ``` 按下遥控器按键后,输出格式:`USERCODE=0x7f80, KEY=0xeb` 2. **动态调试键值映射**(临时修改): ```bash echo "0x7f80 0xeb 116" > /sys/class/remotectl/remotectl/keymap # 116=KEY_POWER ``` #### 三、Android键值映射 1. **创建按键布局文件**: - 在 `/system/usr/keylayout/` 下创建 `Vendor_ff00_Product_ff00.kl`: ``` key 116 POWER WAKE key 139 MENU key 102 HOME ``` **说明**:数字键值需与 `rockchip,key_table` 中定义的Linux键值一致 2. **键值转换原理**: ```mermaid graph LR 遥控器按键 --> 红外接收器 --> 内核驱动(rockchip_pwm_remotectl) 内核驱动 --> |原始键值| Linux输入子系统 输入子系统 --> |KEY_POWER| Android框架 Android框架 --> 应用层 ``` #### 四、固件烧写与验证 1. **编译内核**: ```bash ./build.sh -d rockchip/rk3128 -j8 -k ``` 2. **测试流程**: ```bash adb root && adb remount adb push Vendor_ff00_Product_ff00.kl /system/usr/keylayout/ adb reboot # 验证键值上报 adb shell getevent -l # 查看原始输入事件 adb shell dumpsys input # 查看Android输入系统状态 ``` #### 常见问题解决 1. **遥控无响应**: - 检查硬件连接:确认红外接收器连接到正确的PWM引脚(通常PWM0) - 验证时钟配置: ```dts &pwm0 { clocks = <&cru PLL_GPLL>, <&cru PCLK_PWM>; clock-names = "pwm", "pclk"; }; ``` 2. **键值错误**: - 重新校准用户码:使用逻辑分析仪捕获红外波形 - 调整去抖参数(设备树中添加): ```dts rockchip,no_delay = <1>; // 禁用去抖 ``` 3. **长按失效**: - 修改Android策略文件 `/frameworks/base/core/res/res/values/config.xml`: ```xml <integer name="config_longPressOnPowerBehavior">1</integer> ``` ### 相关问题 1. 如何获取遥控器的原始用户码和键值? 2. RK3128的PWM接口与红外接收器如何硬件连接? 3. Android 7.1的按键事件处理流程是怎样的? 4. 如何为不同的遥控器动态加载键值映射表? 5. 红外遥控响应延迟大如何优化? [^1]: RK3128红外驱动配置与键值映射方法 [^2]: Android输入子系统事件处理流程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

常怀安

您的打赏将是我继续创作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值