遥控码值总结
需要调试IR 想必须搞清楚遥控码值 / 底层 / 上层 的key值是多少。
遥控码值
底层
0a ,40
----------
5E / A2
20 / B3
21 / 13
22 / 01
23 / 5D
-------
94 / 162
32 / 179
33 / 19
34 / 1
35 / 93
上层
--------
0 / 3
0 / 126
88 / 166
87 / 167
127 / 0
配置客户IR新增遥控器头码
文件路径:kernel/fusion/mstar2/drv/ir_mirc/ir_common.h
@@ -105,7 +105,7 @@ #define NAME_KEYMAP_GOME_TV "ir-gome-tv" #define NAME_KEYMAP_BEKO_RC5_TV "ir-beko-rc5-tv" -#define NUM_KEYMAP_MSTAR_TV 0x807F +#define NUM_KEYMAP_MSTAR_TV 0x00ff// 0x807F #define NUM_KEYMAP_TCL_TV 0x00F0 #define NUM_KEYMAP_GOME_TV0 0x6D92 #define NUM_KEYMAP_CHANGHONG_TV 0x40BF
IR Driver配置遥控码和KEY的对应关系
文件路径:kernel/fusion/mstar2/drv/ir_mirc/keymaps/keymap-mstar-tv.c
@@ -76,6 +76,7 @@ */ static struct key_map_table mstar_tv[] = { + #if 0 { 0x46, KEY_POWER }, { 0x50, KEY_0 }, { 0x49, KEY_1 }, @@ -142,7 +143,41 @@ static struct key_map_table mstar_tv[] = { { 0x5F, KEY_F8 }, // MSTAR_CLOCK { 0xFE, KEY_POWER2 }, // FAKE_POWER { 0xFF, KEY_OK }, // KEY_OK - +#else + { 0x14, KEY_MUTE }, + { 0x1c, KEY_POWER }, + { 0x09, KEY_1 }, + { 0x1d, KEY_2 }, + { 0x1f, KEY_3 }, + { 0x0D, KEY_4 }, + { 0x19, KEY_5 }, + { 0x1b, KEY_6 }, + { 0x11, KEY_7 }, + { 0x15, KEY_8 }, + { 0x17, KEY_9 }, + { 0x12, KEY_0 }, + { 0x03, KEY_UP }, + { 0x02, KEY_DOWN }, + { 0x0e, KEY_LEFT }, + { 0x1A, KEY_RIGHT }, + { 0x07, KEY_ENTER }, + { 0x24, KEY_MENU }, + { 0x54, KEY_VOLUMEUP }, + { 0x55, KEY_VOLUMEDOWN }, + { 0x0A, KEY_BACKSPACE }, + { 0x5C, KEY_BACK }, + { 0x40, KEY_KP1 }, // TV_INPUT + { 0x5E, KEY_BRIGHTNESSDOWN }, + { 0x20, KEY_BRIGHTNESSUP }, + { 0xA2, KEY_HOME }, + { 0xB3, KEY_PLAY }, + { 0x21, KEY_PREVIOUSSONG }, + { 0x22, KEY_NEXTSONG }, + { 0x23, KEY_PAUSE }, + { 0x13, KEY_CHANNELUP }, + { 0x01, KEY_CHANNELDOWN }, + { 0x5D, KEY_OK }, + #endif // 2nd IR controller. };
Kernel新增自定义KEY
3.1 IR Driver新增KEY_XX定义
文件路径:kernel/fusion/4.9/include/uapi/linux/input-event-codes.h
@@ -808,8 +808,25 @@ public class KeyEvent extends InputEvent implements Parcelable { public static final int KEYCODE_ALL_APPS = 284; /** Key code constant: Refresh key. */ public static final int KEYCODE_REFRESH = 285; + + + public static final int KEYCODE_NUMERIC_1 = 4317; + public static final int KEYCODE_NUMERIC_2 = 4309; + public static final int KEYCODE_NUMERIC_3 = 4302; + public static final int KEYCODE_NUMERIC_4 = 4303; + public static final int KEYCODE_NUMERIC_5 = 4305; + public static final int KEYCODE_NUMERIC_6 = 4304; + public static final int KEYCODE_NUMERIC_7 = 4318; + public static final int KEYCODE_NUMERIC_8 = 4312; + public static final int KEYCODE_NUMERIC_9 = 4319; + public static final int KEYCODE_NUMERIC_A = 4313; + public static final int KEYCODE_NUMERIC_B = 4320; + public static final int KEYCODE_NUMERIC_C = 4314; + private static final int LAST_KEYCODE = KEYCODE_NUMERIC_C;
4. Framework层新增自定义KEY
4.1 新增KeyEvent.java KEY_XX
文件路径:frameworks/base/core/java/android/view/KeyEvent.java
@@ -808,8 +808,25 @@ public class KeyEvent extends InputEvent implements Parcelable { public static final int KEYCODE_ALL_APPS = 284; /** Key code constant: Refresh key. */ public static final int KEYCODE_REFRESH = 285; + + + public static final int KEYCODE_NUMERIC_1 = 4317; + public static final int KEYCODE_NUMERIC_2 = 4309; + public static final int KEYCODE_NUMERIC_3 = 4302; + public static final int KEYCODE_NUMERIC_4 = 4303; + public static final int KEYCODE_NUMERIC_5 = 4305; + public static final int KEYCODE_NUMERIC_6 = 4304; + public static final int KEYCODE_NUMERIC_7 = 4318; + public static final int KEYCODE_NUMERIC_8 = 4312; + public static final int KEYCODE_NUMERIC_9 = 4319; + public static final int KEYCODE_NUMERIC_A = 4313; + public static final int KEYCODE_NUMERIC_B = 4320; + public static final int KEYCODE_NUMERIC_C = 4314; + private static final int LAST_KEYCODE = KEYCODE_NUMERIC_C;
4.2 新增attrs.xml KEY_XX
文件路径:frameworks/base/core/res/res/values/attrs.xml
@@ -1904,6 +1904,19 @@ <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" /> <enum name="KEYCODE_ALL_APPS" value="284" /> <enum name="KEYCODE_REFRESH" value="285" /> + + <enum name="KEYCODE_NUMERIC_1" value="4317" /> + <enum name="KEYCODE_NUMERIC_2" value="4309" /> + <enum name="KEYCODE_NUMERIC_3" value="4302" /> + <enum name="KEYCODE_NUMERIC_4" value="4303" /> + <enum name="KEYCODE_NUMERIC_5" value="4305" /> + <enum name="KEYCODE_NUMERIC_6" value="4304" /> + <enum name="KEYCODE_NUMERIC_7" value="4318" /> + <enum name="KEYCODE_NUMERIC_8" value="4312" /> + <enum name="KEYCODE_NUMERIC_9" value="4319" /> + <enum name="KEYCODE_NUMERIC_A" value="4313" /> + <enum name="KEYCODE_NUMERIC_B" value="4320" /> + <enum name="KEYCODE_NUMERIC_C" value="4314" /> </attr>
4.3 新增keycodes.h KEY_XX
文件路径:frameworks/native/include/android/keycodes.h
@@ -769,7 +769,20 @@ enum { /** all apps */ AKEYCODE_ALL_APPS = 284, /** refresh key */ - AKEYCODE_REFRESH = 285 + AKEYCODE_REFRESH = 285, + AKEYCODE_NUMERIC_1 = 4317, + AKEYCODE_NUMERIC_2 = 4309, + AKEYCODE_NUMERIC_3 = 4302, + AKEYCODE_NUMERIC_4 = 4303, + AKEYCODE_NUMERIC_5 = 4305, + AKEYCODE_NUMERIC_6 = 4304, + AKEYCODE_NUMERIC_7 = 4318, + AKEYCODE_NUMERIC_8 = 4312, + AKEYCODE_NUMERIC_9 = 4319, + AKEYCODE_NUMERIC_A = 4313, + AKEYCODE_NUMERIC_B = 4320, + AKEYCODE_NUMERIC_C = 4314
4.4 新增InputEventLabels.h
文件路径:frameworks/native/include/input/InputEventLabels.h
@@ -325,6 +325,18 @@ static const InputEventLabel KEYCODES[] = { DEFINE_KEYCODE(SYSTEM_NAVIGATION_RIGHT), DEFINE_KEYCODE(ALL_APPS), DEFINE_KEYCODE(REFRESH), + DEFINE_KEYCODE(NUMERIC_1), + DEFINE_KEYCODE(NUMERIC_2), + DEFINE_KEYCODE(NUMERIC_3), + DEFINE_KEYCODE(NUMERIC_4), + DEFINE_KEYCODE(NUMERIC_5), + DEFINE_KEYCODE(NUMERIC_6), + DEFINE_KEYCODE(NUMERIC_7), + DEFINE_KEYCODE(NUMERIC_8), + DEFINE_KEYCODE(NUMERIC_9), + DEFINE_KEYCODE(NUMERIC_A), + DEFINE_KEYCODE(NUMERIC_B), + DEFINE_KEYCODE(NUMERIC_C),
4.5 客制化kl新增映射码
文件路径:vendor/mediatek/proprietary_tv/open/product/m7332/preinstall/keylayout/Vendor_3697_Product_0001.kl
@@ -73,3 +73,15 @@ key 469 CAPTIONS key 64 EISU key 60 TV_DATA_SERVICE key 471 SYSRQ +key 513 NUMERIC_1 +key 514 NUMERIC_2 +key 515 NUMERIC_3 +key 516 NUMERIC_4 +key 517 NUMERIC_5 +key 518 NUMERIC_6 +key 519 NUMERIC_7 +key 520 NUMERIC_8 +key 521 NUMERIC_9 +key 524 NUMERIC_A +key 525 NUMERIC_B +key 526 NUMERIC_C
调试IR KeyCode
5.1 确认系统用的哪个客制化KL文件
- 使用命令
dumpsys input
或者cat /proc/bus/input/devices
确认当前系统使用的是/vendor/usr/keylayout/Vendor_3697_Product_0001.kl
5.2 调试内核层按键码值是否正确
- 使用
getevent
命令,在按下遥控键时会打印出遥控按键的原始码值。
5.3 调试系统层映射是否正确
- 在framework层的PhoneWindowManager.java#interceptKeyBeforeDispatching函数中添加日志打印,以打印系统所有的KeyCode键值。
- 文件路径:frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@Override public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) { final boolean keyguardOn = keyguardOn(); final int keyCode = event.getKeyCode(); final int repeatCount = event.getRepeatCount(); final int metaState = event.getMetaState(); final int flags = event.getFlags(); final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; final boolean canceled = event.isCanceled(); if (true) { Log.d(TAG, "Leon interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount=" + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed + " canceled=" + canceled); } }
5.3 拦截系统按键和发送特定按键广播
- 在framework层的PhoneWindowManager.java#interceptKeyBeforeDispatching函数中添加了在拦截按键代码时发送广播的功能。
- 文件路径:frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
///---------修改开始 2021/05/28 Intent send_intent = new Intent(); send_intent = new Intent("com.android.action.keydown.KEYCODE_SHORT_CUT"); send_intent.putExtra("keyCode",keyCode); send_intent.putExtra("KeyDown",0); send_intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); //mContext.sendBroadcastAsUser(send_intent, UserHandle.ALL,android.Manifest.permission.USER_ACTIVITY); mContext.sendStickyBroadcastAsUser(send_intent, UserHandle.ALL); if(keyCode == 24||keyCode == 25||keyCode == 164){ return -1; } ///--------- 修改结束 2021/05/28
5.4 app增加注册广播接收framework发送的按键值
private String KEYEVENT = "com.android.action.keydown.KEYCODE_SHORT_CUT"; private KeyBroadcastReceiver kbr = new KeyBroadcastReceiver(); 注册按键监听广播 IntentFilter ifilter = new IntentFilter(); ifilter.addAction(KEYEVENT); registerReceiver(kbr, ifilter); private class KeyBroadcastReceiver extends BroadcastReceiver { StringBuffer sb = new StringBuffer(); boolean isFlag = false; @RequiresApi(api = Build.VERSION_CODES. O) @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); int keyCode = intent.getIntExtra("keyCode", 1); int keyDown = intent.getIntExtra("KeyDown", 1); } }
6.1 遥控器学习功能原理:
将被学习的遥控器发射头对准学习型遥控器的接收头,按被学习遥控器上的功能
键,然后按学习型遥控器上的按键进行记忆。使原来的遥控器功能“复制”到学习
型遥控器上来。
该过程是对原发射信号波形采集到主控芯片的ram中,进行信号分析,压缩信号,
存储信号:
1.发射信号波形测量:
由高速芯片对原始信号采样,同时把采集到的信号存储到
RAM中。
2.分析信号:
对采集到的信号进行分析(周期,高低电平时间)。
3.压缩编码:
根据常用的高低电平的时间,特殊的高低电平时间,发送周期,对
原始信号进行压缩编码。
4.存储信号:
把压缩编码后的数据存储到rom中。
学习型红外遥控分类:
以固定码格式学习的遥控器和波形拷贝方式学习的遥控器。前者,需要收集各种不
同种类的遥控器信号,然后进行识别比较,最后再记录。但是,要实现几乎所有的
红外遥控器的成功复制就太难了。因为,红外遥控器的红外编码格式变化太多。不
过这种学习型遥控器对硬件要求相对简单,处理器的工作频率可以不高,存储容量
也较小,其缺点是对未知编码的遥控器无效。后者主要是把原始遥控器所发出的信
号进行完全拷贝,而不管遥控器是什么格式,存储在EEPROM等存储器中。当发射时,
只需将储存器中记录的波形长度还原成原始信号即可。这种学习型遥控器对MCU的主
频要求高,RAM要求较大,其优点是对任何一种红外遥控器都可以进行学习。