Android GPIO方式解码红外数据

Android GPIO方式解码红外数据

1 红外遥控协议
1.1 基本概念
1)NEC协议,采用PWM方式调制。38KHz载波,一般是由引导码+地址码+地址反码+数据+数据反码构成。
遥控接收头端收到的信号为:逻辑1是560us低+1680us高,逻辑0是560us低+560us高。

地址:u32 >> 24
地址反码:u32 >> 16
数据:u32 >> 8
数据反码:u32 & 0xff

2)Philips RC-5协议,采用PPM方式调制

1.2 STM32 TIM解码红外信号
输入捕获模式下:当捕获单元捕获到外来有效信号边沿事件(通过TIM1 CH1 Capture Compare Enable Register = 0xB设置上升沿和下降沿捕获,STM32库使用宏TIM_ICPolarity_BothEdge = 0x000A配置双边沿触发捕获),将此刻计数器的值锁存到CCR(Capture Compare Register,16bit)影子寄存器并自动将CCR影子寄存器的值拷贝进CCR预装寄存器,以供用户读取。DMA传输方式就是将CCR预装寄存器中的计数值传输到内存中。CCR寄存器中的计数值与上一次的计数值相减 x 计数频率的倒数 = 高电平或者低电平信号宽度。
输入捕获采样的频率就是定时器经过预分配器(PSC)之后的频率,譬如STM32F1 TIM1 CH1的计数器频率等于4 x 1.786KHz (560us) = 72MHz/(Prescaler + 1),那么计数器计数每增加4个就表示一个bit。解码时,连续2次计数间隔相等时表示0,连续2次计数间隔不等时表示1。

另外一种方式是将TIM的计数频率配置成1MHz,则每1us计数值加1。

2 Android GPIO IR配置
2.1 Linux设备树配置
Add gpio-ir-recv platform device dts and pinctrl as shown below:
ir: ir-receiver {
        compatible = "gpio-ir-receiver";
        gpios = <&msmgpio 52 1>;
        linux,rc-map-name = "rc-YOUR_DEVICE-nec";
        pinctrl-names = "default";
        pinctrl-0 = <&oem_gpio_ir_pu>;
        oem,disable_ipc;
};

oem_gpio_ir {
       qcom,pins = <&gp 52>;
       qcom,num-grp-pins = <1>;
       qcom,pin-func = <1>;
       label = "oem_gpio_ir";
       oem_gpio_ir_pu: default {
               drive-strength = <16>;
               bias-pull-up;
       };
};

2.2 Kernel Config
CONFIG_RC_CORE=y
CONFIG_IR_NEC_DECODER=y
CONFIG_MEDIA_RC_SUPPORT=y
CONFIG_IR_GPIO_CIR=y

2.3 Keys Timeout
2.3.1 Kernel Hardcode
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index 5c42750..1be6592 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -116,7 +116,8 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_eve

        now = ktime_get();
        delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
-       delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]);
+       //delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]);
+       delay = MS_TO_NS(250); // 500

2.3.2 Disable Framework Reset Timeout
diff --git
services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index dfe5d3d..c40bd8f 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -1050,6 +1050,7 @@ static const int32_t GAMEPAD_KEYCODES[] = {

status_t EventHub::openDeviceLocked(const char *devicePath) {
     char buffer[80];
+     char oem_cache_devname[80];
 
     ALOGV("Opening device: %s", devicePath);
 
@@ -1067,6 +1068,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
     } else {
         buffer[sizeof(buffer) - 1] = '\0';
         identifier.name.setTo(buffer);
+         strcpy(oem_cache_devname, buffer);
     }
 
     // Check to see if the device is on our excluded list
@@ -1270,9 +1272,11 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
 
         // Disable kernel key repeat since we handle it ourselves
         unsigned int repeatRate[] = {0,0};
-        if (ioctl(fd, EVIOCSREP, repeatRate)) {
-            ALOGW("Unable to disable kernel key repeat for %s: %s",
-                devicePath, strerror(errno));
-        }
+        if (0 != strcmp(oem_cache_devname, "gpio_ir_recv")) {
+                if (ioctl(fd, EVIOCSREP, repeatRate)) {
+            ALOGW("Unable to disable kernel key repeat for %s: %s",
+                        devicePath, strerror(errno));
+                }
+        }
     }

版权声明:如无特殊标注,文章均来自网络,本站编辑整理,转载时请以链接形式注明文章出处,请自行分辨。

本文链接:https://www.shbk5.com/dnsj/72432.html