一、背景
工作需要解码美的的红外编码,芯片本身是有红外接收的,但是使用发现遇到特定波形会漏波,排除掉了,只能采用gpio中断解码了
二、实现
内核本身是有gpio接口代码的,但是不能直接用,需要修改一下,主要修改之处如下:
static int gpio_ir_recv_probe(struct platform_device *pdev)
{
PF_Inerrupt_Debo = (volatile unsigned long *)ioremap(0x01C20800+0x258,4); /*此处主要是提高中断采用的频率*/
write_bit(1,0,PF_Inerrupt_Debo);
// printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
platform_set_drvdata(pdev, gpio_dev);
// printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
gpio_ir_recv_irq,
IRQF_TRIGGER_FALLING , /*此处修改的中断触发的方式,改为下降沿触发*/
"gpio-ir-recv-irq", gpio_dev);
}
static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
{
struct gpio_rc_dev *gpio_dev = dev_id;
int gval;
int rc = 0;
int f;
enum raw_event_type type = IR_SPACE;
unsigned int offset;
long long now = ktime_to_us(ktime_get());/*获取系统时间*/
if(!flag){ // 数据开始
flag = 1;
prev = now;
num = 0;
return IRQ_HANDLED;
}
offset =(unsigned int)(now - prev);
prev = now;
times[num++] = offset;
rawir.duration = offset;
ir_raw_event_store(gpio_dev->rcdev, &rawir); /*存储数据*/
if(num >= 100)
{
// for(f = 0;f<100;f++)
// printk("times[%d] = %ld\n",f, times[f]);
flag = 0;
ir_raw_event_handle(gpio_dev->rcdev); /*调用对应协议进行解码*/
}
err_get_value:
return IRQ_HANDLED;
}
上面是主要的修改出,可以适应任何协议的接收,解码步骤可以放在中断处理中,也可以采用通用的红外框架去解码,通过输入设备上报,这取决于协议的位数,像美的的协议达到了64bit,没办法进行上报,系统是32bit的,所以后期只能通过read接口返回给应用层,这篇文章主要是留个记录。