RK3288_Android7.1調試紅外遙控IR

紅外遙控的發射電路是採用紅外發光二極管來發出經過調製的紅外光波;紅外接收電路由紅外接收二極管、三極管或硅光電池組成,它們將紅外發射器發射的紅外光轉換爲相應的電信號,再送後置放大器。鑑於家用電器的品種多樣化和用戶的使用特點,生產廠家對紅外遙控編碼進行了嚴格的規範編碼,這些編碼各不相同,從而形成不同的編碼方式,統一稱爲紅外遙控器編碼傳輸協議。到目前爲止,紅外遙控協議已多達十種, 如: 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層的鍵值映射就完成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章