Infrared Receiver

来自Firefly wiki
跳转至: 导航搜索

IR Configuration

The Firefly-RK3288 development board comes with IR sensor (between the USB OTG and headset jack) . This article describes how to use and configure the IR to work properly.

You can do this in two parts:

  1. Modify the IR kernel driver. Works on both Linux and Android, which is low level hacking.
  2. Modify the key mapping if you are using Android, which is user space hacking.

Kernel Driver

The IR driver only supports NEC encode format. Below is the instructions of how to add your IR remote to send the right key code in Linux kernel.

There is just one file related:

kernel/drivers/input/remotectl/rk_pwm_remotectl.c 

Define Data Structure

Do as follows:

  • Add a array as follow:
static struct rkxx_remote_key_table remote_key_table_r66[12] = { 
    {0xeb, KEY_POWER},        // Power
    // Control
    {0xa3, 250},              // Settings
    {0xec, KEY_MENU},         // Menu
    {0xfc, KEY_UP},           // Up
    {0xfd, KEY_DOWN},         // Down
    {0xf1, KEY_LEFT},         // Left
    {0xe5, KEY_RIGHT},        // Right
    {0xf8, KEY_REPLY},        // Ok
    {0xb7, KEY_HOME},         // Home
    {0xfe, KEY_BACK},         // Back
    // Vol
    {0xa7, KEY_VOLUMEDOWN},   // Vol-
    {0xf4, KEY_VOLUMEUP},     // Vol+
};

Note: the first column is the IR key value, and the second column is the corresponding key code.

  • Add the item in
static struct rkxx_remotectl_button remotectl_button[] =
{
    //...
    {
       .usercode = 0xff00,/* need to get the usercode in next step */
       .nbuttons =  12,/* number of buttons */
       .key_table = &remote_key_table_r66[0],/* key table */
    },
    // ...
};
  1. usercode is the user code. Every IR has a user code.
  2. nbuttons is the number of buttons.
  3. key_table is the address of the array you added in the first step.

Get User Code and Key Value

You can get the answer in the remotectl_do_something func:

  case RMC_USERCODE:
        {
            //ddata->scanData <<= 1;
            //ddata->count ++;
            if ((RK_PWM_TIME_BIT1_MIN < ddata->period) && (ddata->period < RK_PWM_TIME_BIT1_MAX)){
                ddata->scanData |= (0x01<<ddata->count);;
            }
            ddata->count ++;
            if (ddata->count == 0x10){//16 bit user code
                DBG_CODE("GET USERCODE=0x%x\n",((ddata->scanData) & 0xffff));
                if (remotectl_keybdNum_lookup(ddata)){
                    ddata->state = RMC_GETDATA;
                    ddata->scanData = 0;
                    ddata->count = 0;
                }else{                //user code error
                    ddata->state = RMC_PRELOAD;
                }
            }
        }

You can get the user code through DBG_CODE function.

Add them to the remotectl_button array.

 case RMC_GETDATA:
        {
            //ddata->count ++;
            //ddata->scanData <<= 1;
            #ifdef CONFIG_FIREFLY_POWER_LED
            mod_timer(&timer_led,jiffies + msecs_to_jiffies(50));
            remotectl_led_ctrl(0);
            #endif
            if ((RK_PWM_TIME_BIT1_MIN < ddata->period) && (ddata->period < RK_PWM_TIME_BIT1_MAX)){
                ddata->scanData |= (0x01<<ddata->count);
            }
            ddata->count ++;
            if (ddata->count == 0x10){
                DBG_CODE("RMC_GETDATA=%x\n",(ddata->scanData>>8));
                if ((ddata->scanData&0x0ff) == ((~ddata->scanData >> 8)&0x0ff)){
                    if (remotectl_keycode_lookup(ddata)){
                        ddata->press = 1;
                        ...
                     }
                     ...
                  }
                  ...
              }
         }

You can get the IR key value through DBG_CODE.

Add the Driver to Kernel

Add the driver to kernel as the following steps:

(1) Make sure the config option is written in the file drivers/input/remotectl/Kconfig, as following:

config RK_REMOTECTL_PWM
    bool "rkxx remoctrl pwm0 capture"
default n

(2) Edit drivers/input/remotectl/Makefile. Add object file as following:

obj-$(CONFIG_RK_REMOTECTL_PWM)      += rk_pwm_remotectl.o

(3) Use make menuconfig, and select in the IR support:

Device Drivers
  --->Input device support
  ----->  [*]   rkxx remotectl
  ------->[*]   rkxx remoctrl pwm0 capture.

Then you can make the kernel.

Android Key Remapping

/system/usr/keylayout/ff680000_pwm.kl is a file mapping scancodes in kernel to keycodes in Android. You can add or modify it to match your IR remote's keys.

The content of the file is:

key 28    ENTER
key 116   POWER             WAKE
key 158   BACK
key 139   MENU
key 217   SEARCH
key 232   DPAD_CENTER
key 108   DPAD_DOWN
key 103   DPAD_UP
key 102   HOME
key 105   DPAD_LEFT
key 106   DPAD_RIGHT
key 115   VOLUME_UP
key 114   VOLUME_DOWN
key 143   NOTIFICATION      WAKE
key 113   VOLUME_MUTE
key 388   TV_KEYMOUSE_MODE_SWITCH
key 400   TV_MEDIA_MULT_BACKWARD
key 401   TV_MEDIA_MULT_FORWARD
key 402   TV_MEDIA_PLAY_PAUSE
key 64    TV_MEDIA_PLAY
key 65    TV_MEDIA_PAUSE
key 66    TV_MEDIA_STOP

You can modify this file via adb and reboot to take effect.