Saturday, July 28, 2012

8 bit dallas/ maxim CRC

It is the division between the data, multipled by 2^n (otherwise 1 byte data is always 0) with the polynomial

x^8+x^5+x^4+1

The bits are considered with the LSByte as first byte (byte 0), MSB as Byte 7,
and bits are reversed as well:imagine to push the bits from the left)

example:
the polynomial itself is 8C80


see info here

1 THEORY )Reversing CRC -- Theory and Practice (2006) by Martin Stigge , Henryk Plötz , Wolf Müller , Jens-Peter Redlich)

2 DATA SHEET) http://www.maxim-ic.com/app-notes/index.mvp/id/27

3 CALCULATOR)http://www.maxim-ic.com/design/tools/appnotes/4600/AN4600-calculator.xls

4 FORUM DISCUSSION with multiple solutions) http://www.ccsinfo.com/forum/viewtopic.php?t=37015

5 SOLUTION crc2) http://www.dattalo.com/technical/software/pic/crc_8bit.c



============ 2 TABLE VERSION===========

static const unsigned char L[16]={0x00,0x5e,0xbc,0xe2,
 0x61,0x3f,0xdd,0x83,
 0xc2,0x9c,0x7e,0x20,
 0xa3,0xfd,0x1f,0x41};
static const unsigned char H[16]={0x00,0x9d,0x23,0xbe,
 0x46,0xdb,0x65,0xf8,
 0x8c,0x11,0xaf,0x32,
 0xca,0x57,0xe9,0x74};


int8 crcf(int8 crc, int8 crc_data)
{
  int8 i;
  i = (crc_data ^ crc) ;
  crc = L[i&0x0F]^H[i>>4];
  return crc;
}


=========CRC2  SOLUTION========

int8 crc2(int8 crc, int8 crc_data) 
  int8 i; 
  i = (crc_data ^ crc) ;//& 0xff; 
  crc = 0; 
  if(i & 1) 
    crc ^= 0x5e; 
  if(i & 2) 
    crc ^= 0xbc; 
  if(i & 4) 
    crc ^= 0x61; 
  if(i & 8) 
    crc ^= 0xc2; 
  if(i & 0x10) 
    crc ^= 0x9d; 
  if(i & 0x20) 
    crc ^= 0x23; 
  if(i & 0x40) 
    crc ^= 0x46; 
  if(i & 0x80) 
    crc ^= 0x8c; 
  return(crc); 
}



=============TABLE DERIVATION=============


void printtableL(){
  std::cout<<"L=";
  for (int i=0;i<16;i++){
    unsigned char crc=0;
    if (i & 1)
      crc ^= 0x5e;
    if(i & 2)
      crc ^= 0xbc;
    if(i & 4)
      crc ^= 0x61;
    if(i & 8)
      crc ^= 0xc2;  
    std::cout<<std::hex<<(int)crc<<",";
  }
  std::cout<<std::endl;
}

void printtableH(){
  std::cout<<"H=";
  for (int i=0;i<16;i++){
     unsigned char crc=0;
     if(i & 0x10>>4)
       crc ^= 0x9d;
     if(i & 0x20>>4)
       crc ^= 0x23;
     if(i & 0x40>>4)
       crc ^= 0x46;
     if(i & 0x80>>4)
       crc ^= 0x8c;
     std::cout<<std::hex<<(int)crc<<",";
  }
  std::cout<<std::endl;
}


=============TESTING ====================




void print(unsigned char* c,int l,int ident){
  for (int i=0;i<ident;i++){
    cout<<" ";
  }
  for (int i=0;i<l;i++){
    cout<<(int)c[i];
  }
  cout<<endl;
}



unsigned char dataReverse(unsigned char c){
  unsigned char r=0;
  for (int i=0;i<8;i++){
    if (c&(1<<i)){
      r=r|(1<<(7-i));
    }
  }
  return r;
}

unsigned char trivcrc(const unsigned char* d,int n){
  unsigned char buffer[1024];
  int c=0;

  unsigned char cs=0x31;
  unsigned char csbuf[9];

  csbuf[0]=1;
  for (int b=7;b>=0;b--){
    if (cs&(1<<b)){
      csbuf[7-b+1]=1;
    }else{
      csbuf[7-b+1]=0;
    }
  }


  for (int i=0;i<n;i++){
    for (int b=7;b>=0;b--){
      if (d[i]&(1<<b)){
buffer[c++]=1;
      }else{
buffer[c++]=0;
      }
    }  
  }
  for (int i=0;i<8;i++){
    buffer[c++]=0;
  }

  for (int i=0;i<c-8;i++){
    print(buffer,c,0);
    print(csbuf,9,i);
    if (buffer[i]==1){
      for (int j=0;j<9;j++){
buffer[i+j]=buffer[i+j]^csbuf[j];
      }
    }
  }
  print(buffer,c,0);

  unsigned char r=0;
  for (int b=7;b>=0;b--){
    if (buffer[c-1-b]){
      r=r|(1<<b);
    }
  }
  std::cout<<"r is"<<std::hex<<(int)r<<std::endl;
  return r;
}


void bufferReverse(unsigned char* dst,unsigned char* src,int n){
  for (int i=0;i<n;i++){
    dst[i]=0;
  }
  for (int b=0;b<n*8;b++){
    int it=(b%8);
    int ite=b/8;
    if (src[ite]&(1<<it))
      dst[n-1-ite]|=(1<<(7-it));


}

}










int main(){




unsigned char buff[3];

buff[0]=0x00;

buff[1]=0xF5;

buff[2]=0xF4;

unsigned char revbuff[3];

bufferReverse(revbuff,buff,3);

cout<<hex<<(int)dataReverse(trivcrc(revbuff,3))<<endl;




int8 crc=0;

for (int i=0;i<3;i++){

crc=crc2(crc,buff[2-i]);

}




int8 fcrc=0;

for (int i=0;i<3;i++){

fcrc=crcf(fcrc,buff[2-i]);

}







std::cout<<"fast="<<(int)crc<<endl;

std::cout<<"ffast="<<(int)fcrc<<endl;




}

No comments:

Post a Comment