我使用的是海思的Hi3520DV300,SDK包里是有携带红外的驱动以及红外的测试程序,但是该代码不能直接使用,有几个坑,修改后测试正常。从官方提供的资料来看,该驱动以及测试程序都是比较旧的,应该做一些修改可以适用于海思的其它系列芯片。
官方提供的代码在SDK中的hisi-irda目录,文件结构如下:
biao@ubuntu:~/Hi3520DV300_SDK/Hi3521A_SDK_V1.0.3.1/drv/hisi-irda$ tree
.
├── hiir.c
├── hiir_codedef.h
├── hiir.h
├── Makefile
└── test
├── hiir_codedef.h
├── hiir.h
├── hiir_test.c
└── Makefile
1 directory, 8 files
biao@ubuntu:~/Hi3520DV300_SDK/Hi3521A_SDK_V1.0.3.1/drv/hisi-irda$
SDK编译的时候并不会编译该文件夹,所以需要我们自己手动编译,修改Makefile:
obj-m := hiir.o
KDIR := /home/biao/NVR_Hi3520/linux-3.10.y_Wifi_NandFlash/
PWD ?= $(shell pwd)
#make -C $(KDIR) M=$(PWD) modules
#make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- -C $(KDIR) M=$(PWD) modules
all:
make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o
Makefile注意几点:
1.KDIR表示kernel 所在的路径,按自己的实际路径填写
2.需要指定arm的架构和交叉编译工具,官方给的make -C $(KDIR) M=$(PWD) modules 需要修改为make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- -C $(KDIR) M=$(PWD) modules 交叉编译工具按自己实际使用的来配置。
3.编译模块驱动,需要配置内核,使它支持模块驱动。配置后需要全编译内核。配置如下:选择Enable loadable module support 然后再选择里面的前4个选项。
驱动代码如下:
/* interface/hiir/hiir.c
*
* Copyright (c) 2006 Hisilicon Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* History:
* 16-12-2006 Start of Hi3560 CPU support
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/sched.h>
//#include <asm/hardware.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/version.h>
#include "hiir.h"
#include "hiir_codedef.h"
/* irq */
#define HIIR_DEVICE_IRQ_NO 41
/* define IR IO */
#define IR_REG_BASE (IO_ADDRESS(0x12140000))
#define IR_ENABLE (IR_REG_BASE + 0x00)
#define IR_CONFIG (IR_REG_BASE + 0x04)
#define CNT_LEADS (IR_REG_BASE + 0x08)
#define CNT_LEADE (IR_REG_BASE + 0x0c)
#define CNT_SLEADE (IR_REG_BASE + 0x10)
#define CNT0_B (IR_REG_BASE + 0x14)
#define CNT1_B (IR_REG_BASE + 0x18)
#define IR_BUSY (IR_REG_BASE + 0x1c)
#define IR_DATAH (IR_REG_BASE + 0x20)
#define IR_DATAL (IR_REG_BASE + 0x24)
#define IR_INTM (IR_REG_BASE + 0x28)
#define IR_INTS (IR_REG_BASE + 0x2c)
#define IR_INTC (IR_REG_BASE + 0x30)
#define IR_START (IR_REG_BASE + 0x34)
/**modify by licaibiao**/
//#define IOCONFIG (IO_ADDRESS(0x0x120F0098)) //TODO: ASIC config pin share
#define IOCONFIG (IO_ADDRESS(0x120F0154)) //TODO: ASIC config pin share
/* interrupt mask */
#define INTMS_RCV (1L << 16)
#define INTMS_FRAMERR (1L << 17)
#define INTMS_OVERFLOW (1L << 18)
#define INTMS_RELEASE (1L << 19)
/* define macro */
#define WRITE_REG(Addr, Value) ((*(volatile unsigned int *)(Addr)) = (Value))
#define READ_REG(Addr) (*(volatile unsigned int *)(Addr))
/* debug */
static int g_dbg_flag = 0;
#define HIIR_PFX "hiir: "
#define hiir_dbg(params...) \
do{ \
if(g_dbg_flag) \
{ \
printk(KERN_DEBUG HIIR_PFX params); \
} \
}while(0);
#define hiir_show_reg() \
do{ \
if(g_dbg_flag) \
{ \
printk(KERN_DEBUG "HIIR11 REG:###################################################\n"); \
printk(KERN_DEBUG "%.8x ", READ_REG(IR_ENABLE)); \
printk("%.8x ", READ_REG(IR_CONFIG)); \
printk("%.8x ", READ_REG(CNT_LEADS)); \
printk("%.8x ", READ_REG(CNT_LEADE)); \
printk("%.8x ", READ_REG(CNT_SLEADE)); \
printk("%.8x ", READ_REG(CNT0_B)); \
printk("%.8x ", READ_REG(CNT1_B)); \
printk("\n"); \
printk(KERN_DEBUG "%.8x ", READ_REG(IR_BUSY)); \
printk("%.8x ", READ_REG(IR_DATAH)); \
printk("%.8x ", READ_REG(IR_DATAL)); \
printk("%.8x ", READ_REG(IR_INTM)); \
printk("%.8x ", READ_REG(IR_INTS)); \
printk("%.8x ", READ_REG(IR_INTC)); \
printk("%.8x ", READ_REG(IR_START)); \
printk("\n"); \
} \
}while(0);
#define DEFAULT_DELAYTIME 200
#define HI_IR_MAX_BUF 100
#define DEFAULT_BUF_LEN 8
#define BUF_HEAD hiir_dev.buf[hiir_dev.head]
#define BUF_TAIL hiir_dev.buf[hiir_dev.tail]
#define BUF_LAST hiir_dev.buf[(hiir_dev.head == 0)? (hiir_dev.buf_len - 1): (hiir_dev.head - 1)]
#define INC_BUF(x,len) ((++(x))%(len))
typedef struct
{
hiir_dev_param dev_parm;
unsigned int head;
unsigned int tail;
irkey_info_s buf[HI_IR_MAX_BUF + 1];
unsigned int buf_len;
unsigned int enable_repkey;
unsigned int repkey_checkflag;
unsigned int repkey_delaytime;
unsigned int enable_keyup;
wait_queue_head_t irkey_wait;
}hiir_dev_struct;
static hiir_dev_struct hiir_dev;
static void repkey_timeout_handler(unsigned long data);
static DEFINE_TIMER(repkey_timeout_timer, repkey_timeout_handler, 0, 0);
static void hiir_config(void)
{
int value = 0;
/* TODO: ASIC config pin share */
#if 1
value = READ_REG(IOCONFIG);
value = 1;
WRITE_REG(IOCONFIG, value);
#endif
WRITE_REG(IR_ENABLE, 0x01);
while(READ_REG(IR_BUSY))
{
hiir_dbg("IR_BUSY. Wait...\n");
//udelay(1);
}
value = (hiir_dev.dev_parm.codetype << 14);
value |= (hiir_dev.dev_parm.code_len - 1) << 8;
value |= (hiir_dev.dev_parm.frequence - 1);
WRITE_REG(IR_CONFIG, value);
value = hiir_dev.dev_parm.leads_min << 16;
value |= hiir_dev.dev_parm.leads_max;
WRITE_REG(CNT_LEADS, value);
value = hiir_dev.dev_parm.leade_min << 16;
value |= hiir_dev.dev_parm.leade_max;
WRITE_REG(CNT_LEADE, value);
value = hiir_dev.dev_parm.sleade_min << 16;
value |= hiir_dev.dev_parm.sleade_max;
WRITE_REG(CNT_SLEADE, value);
value = hiir_dev.dev_parm.cnt0_b_min << 16;
value |= hiir_dev.dev_parm.cnt0_b_max;
WRITE_REG(CNT0_B, value);
value = hiir_dev.dev_parm.cnt1_b_min << 16;
value |= hiir_dev.dev_parm.cnt1_b_max;
WRITE_REG(CNT1_B, value);
WRITE_REG(IR_INTM, 0x00);
WRITE_REG(IR_START, 0x00);
//hiir_dbg("current config is...\n");
//hiir_show_reg();
}
static void repkey_timeout_handler(unsigned long data)
{
del_timer(&repkey_timeout_timer);
hiir_dev.repkey_checkflag = 0;
}
static irqreturn_t hiir_interrupt(int irq, void *dev_id)
{
hiir_dbg("Enter hiir_interrupt.\n");
hiir_show_reg();
if(READ_REG(IR_INTS) & INTMS_FRAMERR)
{
hiir_dbg("frame error.\n");
WRITE_REG(IR_INTC, 0x01<<1);
}
else if(READ_REG(IR_INTS) & INTMS_OVERFLOW)
{
hiir_dbg("hardware overflow.\n");
WRITE_REG(IR_INTC, 0x01<<2);
}
else if(READ_REG(IR_INTS) & INTMS_RELEASE)
{
hiir_dbg("release key interrupt.\n");
WRITE_REG(IR_INTC, 0x01<<3);
del_timer(&repkey_timeout_timer);
hiir_dev.repkey_checkflag = 0;
if( (hiir_dev.enable_keyup) && (HIIR_KEY_UP != BUF_LAST.irkey_state_code) )
{
BUF_HEAD = BUF_LAST;
BUF_HEAD.irkey_state_code = HIIR_KEY_UP;
hiir_dev.head = INC_BUF(hiir_dev.head, hiir_dev.buf_len);
wake_up_interruptible(&(hiir_dev.irkey_wait));
}
}
else if(READ_REG(IR_INTS) & INTMS_RCV)
{
hiir_dbg("receive data interrupt. 0x%.8x-0x%.8x\n", READ_REG(IR_DATAH), READ_REG(IR_DATAL));
WRITE_REG(IR_INTC, 0x01<<0);
if(hiir_dev.enable_repkey)
{
if( (hiir_dev.repkey_checkflag) &&
(BUF_LAST.irkey_datah == READ_REG(IR_DATAH)) &&
(BUF_LAST.irkey_datal == READ_REG(IR_DATAL)) )
{
hiir_dbg("repeart key [0x%.8x]-[0x%.8x] detective\n", READ_REG(IR_DATAH), READ_REG(IR_DATAL));
}
else
{
/* repeat key check */
del_timer(&repkey_timeout_timer);
repkey_timeout_timer.expires = jiffies + hiir_dev.repkey_delaytime * HZ / 1000;
add_timer(&repkey_timeout_timer);
hiir_dev.repkey_checkflag = 1;
BUF_HEAD.irkey_datah = READ_REG(IR_DATAH);
BUF_HEAD.irkey_datal = READ_REG(IR_DATAL);
BUF_HEAD.irkey_state_code = HIIR_KEY_DOWN;
hiir_dev.head = INC_BUF(hiir_dev.head, hiir_dev.buf_len);
wake_up_interruptible(&(hiir_dev.irkey_wait));
}
}
else if( !((BUF_LAST.irkey_datah == READ_REG(IR_DATAH))
&& (BUF_LAST.irkey_datal == READ_REG(IR_DATAL))
&& (BUF_LAST.irkey_state_code == HIIR_KEY_DOWN) ) ){
BUF_HEAD.irkey_datah = READ_REG(IR_DATAH);
BUF_HEAD.irkey_datal = READ_REG(IR_DATAL);
BUF_HEAD.irkey_state_code = HIIR_KEY_DOWN;
hiir_dev.head = INC_BUF(hiir_dev.head, hiir_dev.buf_len);
wake_up_interruptible(&(hiir_dev.irkey_wait));
}
}
else
{
printk(KERN_DEBUG HIIR_PFX "logic Error: int_mask=0x%.8x, int_state=0x%.8x.\n", READ_REG(IR_INTM), READ_REG(IR_INTS));
}
hiir_dbg("Exit hiir_interrupt.\n");
return IRQ_HANDLED;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
static int hiir_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
#else
static long hiir_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
#endif
{
int __user *p = (int __user *)arg;
unsigned int min_val, max_val;
switch(cmd)
{
case IR_IOC_SET_BUF:
if((0<arg) && (arg<=HI_IR_MAX_BUF))
{
hiir_dev.buf_len = arg + 1;
/* need reset buf pointrt */
hiir_dev.head = 0;
hiir_dev.tail = 0;
}
hiir_dbg("IR_IOC_SET_BUF -> buf_len=%d\n", hiir_dev.buf_len);
break;
case IR_IOC_SET_ENABLE_KEYUP:
hiir_dev.enable_keyup = arg;
hiir_dbg("IR_IOC_SET_ENABLE_KEYUP -> enable_keyup=%d\n", hiir_dev.enable_keyup);
break;
case IR_IOC_SET_ENABLE_REPKEY:
hiir_dev.enable_repkey = arg;
hiir_dbg("IR_IOC_SET_ENABLE_REPKEY -> enable_repkey=%d\n", hiir_dev.enable_repkey);
break;
case IR_IOC_SET_REPKEY_TIMEOUTVAL:
if(arg > 0)
{
hiir_dev.repkey_delaytime = arg;
}
hiir_dbg("IR_IOC_SET_REPKEY_TIMEOUTVAL -> repkey_delaytime=%d\n", hiir_dev.repkey_delaytime);
break;
case IR_IOC_SET_FORMAT:
if( (arg < 0) || (arg > 3) )
{
printk(KERN_DEBUG HIIR_PFX "Error: IR_IOC_SET_FORMAT -> invalid args=%lu\n", arg);
return -EFAULT;
}
hiir_dev.dev_parm.codetype = arg;
hiir_dbg("IR_IOC_SET_FORMAT -> codetype=%d\n", hiir_dev.dev_parm.codetype);
break;
case IR_IOC_SET_CODELEN:
hiir_dev.dev_parm.code_len = arg;
hiir_dbg("IR_IOC_SET_CODELEN -> code_len=%d\n", hiir_dev.dev_parm.code_len);
break;
case IR_IOC_SET_FREQ:
if( (arg <= 0) || (arg > 128) )
{
printk(KERN_DEBUG HIIR_PFX "Error: IR_IOC_SET_FREQ -> invalid args=%lu\n", arg);
return -EFAULT;
}
hiir_dev.dev_parm.frequence = arg;
hiir_dbg("IR_IOC_SET_FREQ -> frequence=%d\n", hiir_dev.dev_parm.frequence);
break;
case IR_IOC_SET_LEADS:
if( get_user(min_val, p) || get_user(max_val, p+1) )
{
return -EFAULT;
}
hiir_dev.dev_parm.leads_min = min_val;
hiir_dev.dev_parm.leads_max = max_val;
hiir_dbg("IR_IOC_SET_LEADS -> leads_min=%d, leads_max=%d\n", hiir_dev.dev_parm.leads_min, hiir_dev.dev_parm.leads_max);
break;
case IR_IOC_SET_LEADE:
if( get_user(min_val, p) || get_user(max_val, p+1) )
{
return -EFAULT;
}
hiir_dev.dev_parm.leade_min = min_val;
hiir_dev.dev_parm.leade_max = max_val;
hiir_dbg("IR_IOC_SET_LEADE -> leade_min=%d, leade_max=%d\n", hiir_dev.dev_parm.leade_min, hiir_dev.dev_parm.leade_max);
break;
case IR_IOC_SET_SLEADE:
if( get_user(min_val, p) || get_user(max_val, p+1) )
{
return -EFAULT;
}
hiir_dev.dev_parm.sleade_min = min_val;
hiir_dev.dev_parm.sleade_max = max_val;
hiir_dbg("IR_IOC_SET_SLEADE -> sleade_min=%d, sleade_max=%d\n", hiir_dev.dev_parm.sleade_min, hiir_dev.dev_parm.sleade_max);
break;
case IR_IOC_SET_CNT0_B:
if( get_user(min_val, p) || get_user(max_val, p+1) )
{
return -EFAULT;
}
hiir_dev.dev_parm.cnt0_b_min = min_val;
hiir_dev.dev_parm.cnt0_b_max = max_val;
hiir_dbg("IR_IOC_SET_CNT0_B -> cnt0_b_min=%d, cnt0_b_max=%d\n", hiir_dev.dev_parm.cnt0_b_min, hiir_dev.dev_parm.cnt0_b_max);
break;
case IR_IOC_SET_CNT1_B:
if( get_user(min_val, p) || get_user(max_val, p+1) )
{
return -EFAULT;
}
hiir_dev.dev_parm.cnt1_b_min = min_val;
hiir_dev.dev_parm.cnt1_b_max = max_val;
hiir_dbg("IR_IOC_SET_CNT1_B -> cnt1_b_min=%d, cnt1_b_max=%d\n", hiir_dev.dev_parm.cnt1_b_min, hiir_dev.dev_parm.cnt1_b_max);
break;
case IR_IOC_GET_CONFIG:
if(copy_to_user((void __user *)arg, &(hiir_dev.dev_parm), sizeof(hiir_dev_param)))
{
printk("%s: copy_to_user fail!\n",__func__);
}
hiir_dbg("IR_IOC_GET_CONFIG\n");
break;
case IR_IOC_ENDBG:
g_dbg_flag = 1;
hiir_dbg("IR_IOC_ENDBG\n");
break;
case IR_IOC_DISDBG:
g_dbg_flag = 0;
hiir_dbg("IR_IOC_DISDBG\n");
break;
default:
printk(KERN_DEBUG HIIR_PFX "Error: Inappropriate ioctl for device. cmd=%d\n", cmd);
return -ENOTTY;
}
hiir_config();
return 0;
}
static ssize_t hiir_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
irkey_info_s irkey_to_user;
int res = 0;
retry :
hiir_dbg("Enter hiir_read : head=%d, tail=%d, buf_len=%d\n", hiir_dev.head, hiir_dev.tail, hiir_dev.buf_len);
if((hiir_dev.head)==(hiir_dev.tail))
{
if((filp->f_flags & O_NONBLOCK) == O_NONBLOCK)
return -EAGAIN;
wait_event_interruptible(hiir_dev.irkey_wait,(hiir_dev.head != hiir_dev.tail));
if(signal_pending(current))
return -ERESTARTSYS;
goto retry;
}
else
{
while( ((hiir_dev.head)!=(hiir_dev.tail)) && ((res + sizeof(irkey_info_s)) <= count) )
{
irkey_to_user = BUF_TAIL;
hiir_dev.tail = INC_BUF(hiir_dev.tail, hiir_dev.buf_len);
if(copy_to_user((buf + res), &irkey_to_user, sizeof(irkey_info_s)))
{
printk("%s: copy_to_user fail!\n",__func__);
}
res += sizeof(irkey_info_s);
}
}
return res;
}
static unsigned int hiir_select(struct file *filp, struct poll_table_struct *wait)
{
hiir_dbg("Enter hiir_select.\n");
if((hiir_dev.head)!=(hiir_dev.tail))
{
return 1;
}
poll_wait(filp, &(hiir_dev.irkey_wait), wait);
return 0;
}
static atomic_t hiir_s_available = ATOMIC_INIT(1);
static int hiir_open(struct inode *inode, struct file *filp)
{
hiir_dbg("Enter hiir_open.\n");
if(! atomic_dec_and_test(&hiir_s_available) )
{
atomic_inc(&hiir_s_available);
printk(KERN_DEBUG HIIR_PFX "Error: device already open.\n");
return -EBUSY;
}
del_timer(&repkey_timeout_timer);
g_dbg_flag = 0;
/* init hiir_dev */
hiir_dev.dev_parm = static_dev_param[0];/*nec format*/
hiir_dev.head = 0;
hiir_dev.tail = 0;
hiir_dev.buf_len = DEFAULT_BUF_LEN;
hiir_dev.enable_repkey = 1;
hiir_dev.repkey_checkflag = 0;
hiir_dev.repkey_delaytime = DEFAULT_DELAYTIME;
hiir_dev.enable_keyup = 1;
init_waitqueue_head(&hiir_dev.irkey_wait);
hiir_config();
return 0;
}
static int hiir_release(struct inode *inode, struct file *filp)
{
hiir_dbg("Enter hiir_release.\n");
del_timer(&repkey_timeout_timer);
/* disable HIIR11 */
WRITE_REG(IR_ENABLE, 0x00);
atomic_inc(&hiir_s_available);
return 0;
}
static int hiir_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
return 0;
}
static struct file_operations hiir_fops =
{
owner : THIS_MODULE,
open : hiir_open,
unlocked_ioctl : hiir_ioctl,
poll : hiir_select,
read : hiir_read,
write : hiir_write,
release : hiir_release,
};
static struct miscdevice hiir_miscdev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = HIIR_DEVICE_NAME,
.fops = &hiir_fops,
};
static int __init hiir_init(void)
{
int res = 0;
printk(KERN_INFO OSDRV_MODULE_VERSION_STRING "\n");
/* disable HIIR */
WRITE_REG(IR_ENABLE, 0x00);
res = misc_register(&hiir_miscdev);
if (0 != res)
{
printk(KERN_DEBUG HIIR_PFX "Error: can't register\n");
return -EFAULT;
}
res = request_irq(HIIR_DEVICE_IRQ_NO, hiir_interrupt, 0, HIIR_DEVICE_NAME, &hiir_interrupt);
if(res)
{
printk(KERN_DEBUG HIIR_PFX "Error: request IRQ(%d) failed\n", HIIR_DEVICE_IRQ_NO);
misc_deregister(&hiir_miscdev);
goto hi_ir_init_failed;
}
printk(HIIR_PFX "init ok. ver=%s, %s.\n", __DATE__, __TIME__);
hi_ir_init_failed:
return res;
}
static void __exit hiir_exit(void)
{
free_irq(HIIR_DEVICE_IRQ_NO, &hiir_interrupt);
misc_deregister(&hiir_miscdev);
}
module_init(hiir_init);
module_exit(hiir_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Hisilicon Infrared remoter(HIIR11) Device Driver");
MODULE_VERSION("HI_VERSION=" OSDRV_MODULE_VERSION_STRING);
注意点:
(1)#define IOCONFIG (IO_ADDRESS(0x0x120F0098)) 这一句,需要按自己板子的实际IR引脚的地址填写,在hi3520dV300中它的地址是0x120F0154 所以我改成了#define IOCONFIG (IO_ADDRESS(0x120F0154))
(2)注意下面代码:这代码是我改的,官方默认是#if 0 将它关闭了,并且官方默认的value值为0,这里要改为1。因为0是配置普通GPIO,1才是将该IO配置为红外功能。
#if 1
value = READ_REG(IOCONFIG);
value = 1;
WRITE_REG(IOCONFIG, value);
#endif
应用程序按需求更改就可以了,正常运行的日志如下:
20190103_22:57:49 /hi3520/app # ./hiir_test
20190103_22:57:49 Hi_IR_FUNC_TEST_001 start...
20190103_22:57:49 REMOTE codetype ...NEC with simple repeat code - uPD6121G
20190103_22:57:49 REMOTE_POWER key to finish the test...
20190103_22:57:49 REMOTE_MUTE key to set repkey delay time...
20190103_22:57:55 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xff00ff00.
20190103_22:57:55 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xff00ff00.
20190103_22:57:59 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xfa05ff00.
20190103_22:57:59 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xfa05ff00.
20190103_22:58:07 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xf30cff00.
20190103_22:58:07 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xf30cff00.
20190103_22:58:12 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xf10eff00.
20190103_22:58:12 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xf10eff00.
20190103_22:58:49 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xfd02ff00.
20190103_22:58:50 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xfd02ff00.
20190103_22:58:51 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xfe01ff00.
20190103_22:58:51 Error. get a invalid code. irkey_datah=0x00000000,irkey_datal=0xfe01ff00.
irkey_datal 的值就是实际采集到的IR按键值。按照采集到的按键值修改相应的宏定义即可。
完整工程下载路径为:海思Hi3520红外驱动及测试程序