2012年12月31日月曜日

リモコンフォーマットの解析と展開(家製協)

国内のリモコンは大きく分けて3種類有ります。
まずは一般的な家製協(AEHA)フォーマットの解析部分と解析されたデータを展開して戻す部分のコードです。

-----

/*
 code[0],code[1]    = ID
 code[2],code[3]    = length
 code[4]            = FormatAEHA 0x01
 code[5]            = 1TCLK
 code[6] - code[31] = reserve
 code[32],code[33]  = CustomerCode
 code[34] -         = Parity/Data0, Data1, Data2, ... DataN
*/
int FormatAnalyzeAEHA(unsigned int *buf, int bufSize, unsigned char *code, int codeSize) {

  int last = -1;
  int n = 0;
  int c = 0;
  int on = 0;
  int off = 0;
  int t = 1000;
  memset(code, 0, codeSize);
  for(int i = 0; i < bufSize * 32; i++) {
    int d = (buf[i / 32] >> (31 - (i % 32))) & 1;
    if((last < 0) && (d == 1)) continue; // skip nosignal

    if(d != last) { // data edge
      if(c && (last == 0)) {
        on = c;
      } else if(c) {
        off = c;
        if(!n) { // leader
          if(((on + off / 2) / off) != 2) return -1;
          t = (on + off) / 12;
        } else { // customer/data code
          if(((on + t / 2) / t) != 1) return -1;
          if(((off + t / 2) / t) == 3) {
            code[32 + (n-1)/8] |= 1 << ((n-1)%8);
          } else if(((off + t / 2) / t) != 1) {
            return -1;
          }
        }
        n++;
      }
      c = 1;
    } else { // data continue
      c++;
      if(c > t * 20) { // trailer
        if(last == 0) return -1;
        if(((on + t / 2) / t) != 1) return -1;
        break;
      }
    }
    last = d;
  }
  n += 6;
  unsigned char p = code[32] ^ (code[32] >> 4) ^ code[33] ^ (code[33] >> 4) ^ code[34];
  if(p & 0x0f) return -1;
  code[2] = (32 + n / 8) / 256;
  code[3] = (32 + n / 8) % 256;
  code[4] = 1;
  code[5] = t;
  return 32 + n / 8;
}

int CodeExpandAEHA(unsigned char *code, int codeSize, unsigned int *buf, int bufSize) {

  memset(buf, 0, bufSize * 4);
  int len = ((code[2] << 8) | code[3]) - 32;
  int t = code[5];

  int p = 0;
  // leader
  for(int i = 0; i < 8 * t; i++) {
    if(!(p & 1)) buf[p / 32] |= (1 << (31 - (p % 32)));
    p++;
  }
  p += 4 * t;

  // customer code & data
  for(int i = 0; i < len; i++) {
    for(int j = 0; j < 8; j++) {
      int d = (code[32 + i] >> j) & 1;
      for(int k = 0; k < t; k++) {
        if(!(p & 1)) buf[p / 32] |= (1 << (31 - (p % 32)));
        p++;
      }
      p += (d?t*3:t);
    }
  }

  // trailer
  for(int i = 0; i < t; i++) {
    if(!(p & 1)) buf[p / 32] |= (1 << (31 - (p % 32)));
    p++;
  }
  p += 20 * t;
  p += 31;
  return p / 32;
}

0 件のコメント:

コメントを投稿