Computer Interfacing
Discussions about interfacing and electronics
 

problem with CRC Xmodem calculation ! help !


 

       Computer Interfacing Forum Index -> Error detection and correction
Author Message
emeceuy
Junior Member



Joined: 31 Dec 2007
Posts: 11


Oct 08, 2008 7:51 pm

Hi all ! well, i can calculate with the following delphi procedure the CRC 16 of an array of integers, but when I tried to calculate CRC 16 XMODEM (so I change the generator polynom), the result defeers from the number calculted in your web.
For example, the CRC XMODEM of: 0x02 0xA5 is 0x83 0x2D, and in my procedure is 0x17 0xC1.

I insist, the standard CRC16 result is OK, but not XMODEM when I change the polynom.

thank you all in advance ! Marcelo

Code:

procedure fsCalculaCRC;
 
  function DATparaXOR(Datos1,Datos2: string):string;
  var vloop:integer;
      vbol1,vbol2:boolean;
  begin
    if length(Datos1)<>length(Datos2) then showmessage('Error');
    for vloop:=1 to length(Datos2) do
      begin
        if Datos1[vloop]='1' then vbol1:=true else vbol1:=false;
        if Datos2[vloop]='1' then vbol2:=true else vbol2:=false;
        if vbol1 xor vbol2 then result[vloop]:='1' else result[vloop]:='0';
      end;
    result:=trim(result);
  end;

  function EliminaMSB(Datos:string):string;
  begin
    EliminaMSB:=trim(copy(Datos,2,999));
  end;

  function ProximoDato:string;
    begin
      if length(vBinario)>0 then ProximoDato:=vBinario[1]
       else
         begin
           ProximoDato:='0';
           showmessage('Error');
         end;
       vBinario:=trim(copy(vBinario,2,999));
    end;

  function Invierte(Datos: string):string;
  var vloop:integer;
  begin
    for vloop:=1 to length(Datos) do result[vloop]:=Datos[length(Datos)+1-vloop];
    result:=trim(result);
  end;

// HERE STARTS THE FUNCTION

   begin
      vBinario:='';
      for vloop:=0 to length(pDatos)-1 do vBinario:=vBinario+Invierte(inttobin(pDatos[vloop]));

      // CRC 16
      vGenerador:='10001000000100001';
      vCeros:='00000000000000000';

      vBinario:=vBinario+copy(vCeros,1,length(vCeros)-1);        // 16 bits por el CRC-16

      vLargoDAT:=length(vBinario);
      vLargoGEN:=length(vGenerador);
      setlength(mCRC,0,0);
      setlength(mCRC,vLargoDAT-vLargoGEN+10,17);

      vResultado:='X'+copy(vBinario,1,vLargoGEN-1);
      vBinario:=trim(copy(vBinario,vLargoGEN,999));

      repeat
         begin
            vDividendo:=EliminaMSB(vResultado)+ProximoDato;
            if vDividendo[1]='1' then vDivisor:=vGenerador else vDivisor:=vCeros;

            vResultado:=DATparaXOR(vDividendo,vDivisor);

            if vResultado[1]='1' then showmessage('Error, MSB del resultado es "1"');
         end
      until length(vBinario)=0;

      vResultado:=Invierte(EliminaMSB(vResultado));

      vCRCH:=bintoint(copy(vresultado,9,8));
      vCRCL:=bintoint(copy(vresultado,1,8));

      vCaracteres:=vCaracteres+char(vCRCH)+char(vCRCL);
      vDecimales:=vDecimales+'-'+formatfloat('000',vCRCH)+'-'+formatfloat('000',vCRCL);
end;
lammert
Site Admin



Joined: 13 Mar 2007
Posts: 145
Location: Netherlands and Kazakhstan

Oct 10, 2008 2:59 am

Your Delphi code is bulky and unreadable at least, and I expect it to be about 100 times slower than the C implementations you can download here. This is because of all the conversions between different datatypes and the implementation of the XOR in a separate function with a loop running on chars, where the binary XOR of data is a single one clock-tick CPU instruction on even the simplest processors.

This forum is not intended to debug code written by others. Instead I would advice you to try to understand the code (which I assume you haven't written yourself) and change it accordingly, or use the C examples here and implement a fast version of the algorithm in Delphi instead.

       Computer Interfacing Forum Index -> Error detection and correction
Page 1 of 1



Running on php BB © 2001, 2009 php BB Group
   Lammert Bies     Interfacing     Sitemap     Forum