📄 receive.c
字号:
/* $Id: receive.c,v 5.15 2002/09/21 15:25:28 lirc Exp $ *//**************************************************************************** ** receive.c *************************************************************** **************************************************************************** * * functions that decode IR codes * * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de> * */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <limits.h>#include "hardware.h"#include "lircd.h"#include "receive.h"extern struct hardware hw;extern struct ir_remote *last_remote;struct rbuf rec_buffer;inline lirc_t lirc_t_max(lirc_t a,lirc_t b){ return(a>b ? a:b);}lirc_t get_next_rec_buffer(lirc_t maxusec){ if(rec_buffer.rptr<rec_buffer.wptr) { LOGPRINTF(3,"<%lu",(unsigned long) rec_buffer.data[rec_buffer.rptr]&(PULSE_MASK)); rec_buffer.sum+=rec_buffer.data[rec_buffer.rptr]&(PULSE_MASK); return(rec_buffer.data[rec_buffer.rptr++]); } else { if(rec_buffer.wptr<RBUF_SIZE) { lirc_t data; data=hw.readdata(2*maxusec<50000 ? 50000:2*maxusec); if(!data) { return 0; } rec_buffer.data[rec_buffer.wptr]=data; if(rec_buffer.data[rec_buffer.wptr]==0) return(0); rec_buffer.sum+=rec_buffer.data[rec_buffer.rptr] &(PULSE_MASK); rec_buffer.wptr++; rec_buffer.rptr++; LOGPRINTF(3,"+%lu",(unsigned long) rec_buffer.data[rec_buffer.rptr-1] &(PULSE_MASK)); return(rec_buffer.data[rec_buffer.rptr-1]); } else { rec_buffer.too_long=1; return(0); } } return(0);}void init_rec_buffer(void){ memset(&rec_buffer,0,sizeof(rec_buffer));}void rewind_rec_buffer(void){ rec_buffer.rptr=0; rec_buffer.too_long=0; rec_buffer.pendingp=0; rec_buffer.pendings=0; rec_buffer.sum=0;}int clear_rec_buffer(void){ int move,i; if(hw.rec_mode==LIRC_MODE_LIRCCODE) { unsigned char buffer[sizeof(ir_code)]; size_t count; count=hw.code_length/CHAR_BIT; if(hw.code_length%CHAR_BIT) count++; if(read(hw.fd,buffer,count)!=count) { logprintf(LOG_ERR,"reading in mode " "LIRC_MODE_LIRCCODE failed"); return(0); } for(i=0,rec_buffer.decoded=0;i<count;i++) { rec_buffer.decoded=(rec_buffer.decoded<<CHAR_BIT)+ ((ir_code) buffer[i]); } } else if(hw.rec_mode==LIRC_MODE_CODE) { unsigned char c; if(read(hw.fd,&c,1)!=1) { logprintf(LOG_ERR,"reading in mode LIRC_MODE_CODE " "failed"); return(0); } rec_buffer.decoded=(ir_code) c; } else { lirc_t data; move=rec_buffer.wptr-rec_buffer.rptr; if(move>0 && rec_buffer.rptr>0) { memmove(&rec_buffer.data[0], &rec_buffer.data[rec_buffer.rptr], sizeof(rec_buffer.data[0])*move); rec_buffer.wptr-=rec_buffer.rptr; } else { rec_buffer.wptr=0; } data=hw.readdata(0); LOGPRINTF(3,"c%lu",(unsigned long) data&(PULSE_MASK)); rec_buffer.data[rec_buffer.wptr]=data; rec_buffer.wptr++; } rewind_rec_buffer(); rec_buffer.is_biphase=0; return(1);}inline void unget_rec_buffer(int count){ if(count==1 || count==2) { rec_buffer.rptr-=count; rec_buffer.sum-=rec_buffer.data[rec_buffer.rptr]&(PULSE_MASK); if(count==2) { rec_buffer.sum-=rec_buffer.data[rec_buffer.rptr+1] &(PULSE_MASK); } }}inline lirc_t get_next_pulse(lirc_t maxusec){ lirc_t data; data=get_next_rec_buffer(maxusec); if(data==0) return(0); if(!is_pulse(data)) { LOGPRINTF(2,"pulse expected"); return(0); } return(data&(PULSE_MASK));}inline lirc_t get_next_space(lirc_t maxusec){ lirc_t data; data=get_next_rec_buffer(maxusec); if(data==0) return(0); if(!is_space(data)) { LOGPRINTF(2,"space expected"); return(0); } return(data);}int expectpulse(struct ir_remote *remote,int exdelta){ lirc_t deltas,deltap; int retval; if(rec_buffer.pendings>0) { deltas=get_next_space(rec_buffer.pendings); if(deltas==0) return(0); retval=expect(remote,deltas,rec_buffer.pendings); if(!retval) return(0); rec_buffer.pendings=0; } deltap=get_next_pulse(rec_buffer.pendingp+exdelta); if(deltap==0) return(0); if(rec_buffer.pendingp>0) { retval=expect(remote,deltap, rec_buffer.pendingp+exdelta); if(!retval) return(0); rec_buffer.pendingp=0; } else { retval=expect(remote,deltap,exdelta); } return(retval);}int expectspace(struct ir_remote *remote,int exdelta){ lirc_t deltas,deltap; int retval; if(rec_buffer.pendingp>0) { deltap=get_next_pulse(rec_buffer.pendingp); if(deltap==0) return(0); retval=expect(remote,deltap,rec_buffer.pendingp); if(!retval) return(0); rec_buffer.pendingp=0; } deltas=get_next_space(rec_buffer.pendings+exdelta); if(deltas==0) return(0); if(rec_buffer.pendings>0) { retval=expect(remote,deltas, rec_buffer.pendings+exdelta); if(!retval) return(0); rec_buffer.pendings=0; } else { retval=expect(remote,deltas,exdelta); } return(retval);}inline int expectone(struct ir_remote *remote,int bit){ if(is_biphase(remote)) { if(is_rc6(remote) && remote->toggle_bit>0 && bit==remote->toggle_bit-1) { if(remote->sone>0 && !expectspace(remote,2*remote->sone)) { unget_rec_buffer(1); return(0); } rec_buffer.pendingp=2*remote->pone; } else { if(remote->sone>0 && !expectspace(remote,remote->sone)) { unget_rec_buffer(1); return(0); } rec_buffer.pendingp=remote->pone; } } else { if(remote->pone>0 && !expectpulse(remote,remote->pone)) { unget_rec_buffer(1); return(0); } if(remote->ptrail>0) { if(remote->sone>0 && !expectspace(remote,remote->sone)) { unget_rec_buffer(2); return(0); } } else { rec_buffer.pendings=remote->sone; } } return(1);}inline int expectzero(struct ir_remote *remote,int bit){ if(is_biphase(remote)) { if(is_rc6(remote) && remote->toggle_bit>0 && bit==remote->toggle_bit-1) { if(!expectpulse(remote,2*remote->pzero)) { unget_rec_buffer(1); return(0); } rec_buffer.pendings=2*remote->szero; } else { if(!expectpulse(remote,remote->pzero)) { unget_rec_buffer(1); return(0); } rec_buffer.pendings=remote->szero; } } else { if(!expectpulse(remote,remote->pzero)) { unget_rec_buffer(1); return(0); } if(remote->ptrail>0) { if(!expectspace(remote,remote->szero)) { unget_rec_buffer(2); return(0); } } else { rec_buffer.pendings=remote->szero; } } return(1);}inline lirc_t sync_rec_buffer(struct ir_remote *remote){ int count; lirc_t deltas,deltap; count=0; deltas=get_next_space(1000000); if(deltas==0) return(0); if(last_remote!=NULL && !is_rcmm(remote)) { while(deltas<last_remote->remaining_gap* (100-last_remote->eps)/100 && deltas<last_remote->remaining_gap-last_remote->aeps) { deltap=get_next_pulse(1000000); if(deltap==0) return(0); deltas=get_next_space(1000000); if(deltas==0) return(0); count++; if(count>REC_SYNC) /* no sync found, let's try a diffrent remote */ { return(0); } } } rec_buffer.sum=0; return(deltas);}inline int get_header(struct ir_remote *remote){ if(is_rcmm(remote)) { lirc_t deltap,deltas,sum; deltap=get_next_pulse(remote->phead); if(deltap==0) { unget_rec_buffer(1); return(0); } deltas=get_next_space(remote->shead); if(deltas==0) { unget_rec_buffer(2); return(0); } sum=deltap+deltas; if(expect(remote,sum,remote->phead+remote->shead)) { return(1); } unget_rec_buffer(2); return(0); } if(!expectpulse(remote,remote->phead)) { unget_rec_buffer(1); return(0); } /* if this flag is set I need a decision now if this is really a header */ if(remote->flags&NO_HEAD_REP) { lirc_t deltas; deltas=get_next_space(remote->shead); if(deltas!=0) { if(expect(remote,remote->shead,deltas)) { return(1); } unget_rec_buffer(2); return(0); } } rec_buffer.pendings=remote->shead; return(1);}inline int get_foot(struct ir_remote *remote){ if(!expectspace(remote,remote->sfoot)) return(0); if(!expectpulse(remote,remote->pfoot)) return(0); return(1);}inline int get_lead(struct ir_remote *remote){ if(remote->plead==0) return(1); rec_buffer.pendingp=remote->plead; return(1); }inline int get_trail(struct ir_remote *remote){ if(remote->ptrail!=0) { if(!expectpulse(remote,remote->ptrail)) return(0); } if(rec_buffer.pendingp>0) { if(!expectpulse(remote,0)) return(0); } return(1);}inline int get_gap(struct ir_remote *remote,lirc_t gap){ lirc_t data; LOGPRINTF(2,"sum: %ld",rec_buffer.sum); data=get_next_rec_buffer(gap*(100-remote->eps)/100); if(data==0) return(1); if(!is_space(data)) { LOGPRINTF(2,"space expected"); return(0); } unget_rec_buffer(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -