#include #include #include #include "k_debug.h" #include "msp_ir.h" typedef struct s_bitparse { /* init part */ unsigned char *cmd; int cmdlen; int mint; int (*nextbit)( struct s_bitparse *p ); void (*reset) ( struct s_bitparse *p ); /* reset part */ int pos; int hl; int bits; int dt; /* return */ int mode; int addr; int code; int repeat; } t_bitparse; static void RCParserReset( struct s_bitparse *p ) { p->pos = 0; p->dt = 0; p->hl = 1; /* start with signal high */ p->bits = 0; /* return */ p->addr = 0; p->code = 0; p->repeat = 0; } static int RCParserNextBit( struct s_bitparse *p ) { if( p->dt<=0 ) { int actcmd = p->mint; if( p->poscmdlen ) actcmd = p->cmd[p->pos++]; if( actcmd==0xff && !(p->bits) ) return -1; p->dt = (actcmd)/p->mint; _D("[%02x:%d]",actcmd,p->dt); p->hl = !(p->hl); } if( p->dt ) { p->dt--; p->bits++; _D("%d",p->hl); return p->hl; } return -2; } static int RCParserInit( struct s_bitparse *p, unsigned char *cmd, int len ) { int i; int val; int RC6 = 0; int mint = 0xff; memset( p, 0, sizeof(*p) ); p->nextbit = RCParserNextBit; p->reset = RCParserReset; p->cmd = cmd; p->cmdlen = len; for( i=0 ; imint = mint; p->reset(p); return 0; } static int ParseManchester( struct s_bitparse *p, int len, int *value ) { int i; int bit1 = 0; int code = *value; for( i=0 ; inextbit(p)<<1)|p->nextbit(p); if( bit1<0 ) return -1; _D("(m:%d)",bit1); code <<= 1; switch( bit1 ) { case 1: code|=bit1; case 2: break; default: return -1; } } *value = code; return 0; } #if 0 static int parseRC5( struct s_bitparse *p ) { int code=0; int bit1 = 0; p->reset(p); /* start */ bit1 = p->nextbit(p); if( bit1!=0 ) return -1; /* code */ if( ParseManchester(p,13,&code)<0 ) return -1; code = ~code & 0x1fff; p->code = (code >> 0) & 0x3f; p->addr = (code >> 6) & 0x1f; _I("->%04x bits=%d : toggle=%d addr=%02x code=%02x\n",code,p->bits,code>>11,p->addr,p->code); return 0; } #endif static int parseRC6( struct s_bitparse *p ) { int i; int bit1 = 0; int bit2 = 0; int mode = 0; int addr = 0; int code = 0; int byte[2] = { 0, 0 }; _D("RC6\n"); p->reset(p); /* check header 00000011(mb2,mb1,mb0)10(TTTT=0011 o. 1100) */ /* Leader: 00000011 */ _D("Header:"); for( i=0 ; i<6 ; i++ ) { bit1 = p->nextbit(p); if( bit1!=0 ) return -1; } for( i=0 ; i<2 ; i++ ) { bit1 = p->nextbit(p); if( bit1!=1 ) return -1; } /* Start Bit */ bit1 = (p->nextbit(p)<<1)|p->nextbit(p); if( bit1!=1 ) return -1; /* RC6 mode */ _D("\nMode:"); bit1 = ParseManchester( p, 3, &mode ); if( bit1 < 0 ) return -1; _D("->%d\n",mode); /* Toggle bits 0011 o. 1100 */ _D("T:"); bit1 = (p->nextbit(p)<<1)|p->nextbit(p); if( bit1<0 ) return -1; switch( bit1 ) { case 0: case 3: break; default: return -1; } bit2 = (p->nextbit(p)<<1)|p->nextbit(p); if( bit2<0 ) return -1; switch( bit2 ) { case 0: case 3: break; default: return -1; } if( bit1 && bit2 ) return -1; if( !bit1 && !bit2 ) return -1; _D("->%d%d\n",bit1,bit2); /* header ok */ /* control field */ /* 0 = short customer code */ /* 1 = long customer code */ _D("S"); bit1 = ParseManchester( p, 8, &code ); if( bit1 < 0 ) return -1; _D("->%02x\n",code); if( code & 0x0080 ) { _D("L"); bit1 = ParseManchester( p, 8, &code ); if( bit1 < 0 ) return -1; } _D("->%02x\n",code); /* info field */ _D("B"); bit1 = ParseManchester( p, 8, byte ); if( bit1 < 0 ) return -1; _D("->%d\n",byte[0]); _D("B"); bit1 = ParseManchester( p, 8, byte+1 ); if( bit1 < 0 ) return -1; _D("->%d\n",byte[1]); p->mode = mode; p->addr = code; p->code = (byte[0]<<8) | byte[1]; _D("->%04x bits=%d : mode=%d custcode=0x%02x toggle=%d addr=%d code=%d [0x%02x]\n",p->code,p->bits,mode,p->addr,p->code>>15,(p->code>>8) & 0x7F,p->code & 0xff,p->code & 0xff); return 0; } int parseIR( unsigned char *cmd, int len, unsigned int custcode, unsigned int mode, unsigned int *code ) { int rv; struct s_bitparse p; rv = RCParserInit( &p, cmd, len ); if( rv<0 ) { //_D("->ERROR unknown timing\n"); return -1; } if( parseRC6(&p)<0 ) { _D("->ERROR\n"); return -1; } if( mode!=(unsigned int)p.mode ) { _D("->wrong mode\n"); return -1; } if( custcode!=(unsigned int)p.addr ) { _D("->wrong customer codes\n"); return -1; } *code = (unsigned int)p.code; return 0; }