海思Hi3520D红外驱动及功能测试

Source
版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/li_wen01/article/details/85833380

    我使用的是海思的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红外驱动及测试程序