7
Reply

Xmodem CRC generation?

Dave

Dave

Feb 11 2009 9:28 AM
11.3k

Any bit-twiddling, CRC-generation experts out there?  I'm trying to implement an Xmodem CRC receive function.  I have code from here in C# but it doesn't implement CRC on receiving, only on sending.  I also have code from here in C that does implement CRC on receiving.  The C# code looks like it was based on the C code. 

I've got my code doing the CRC checking in what *I think* is the same way the C code is doing it, but when I connect to one of my company's remote devices and try to retrieve a file, the CRC values never match.  I can retrieve a file fine using Xmodem CRC in Tera Term Pro when connecting to the same device (I'm doing this over sockets, not serial, if that matters).

The CRC-16 lookup table used by both the C and C# code are the same.  Are these C/C# code blocks equivalent?  And if they *are* equivalent, can anyone tell what I'm doing wrong that makes the crc comparison fail?? ('buf' contains the block of data received that needs to be checked; 'sz' is either 1024 or 128)

C#:     private bool check(bool isCrc, byte[] buf, int index, int sz) { // 'index' has a value of '3' passed in
            if (isCrc) {
                ushort crc = CRC16.CRC16_ccitt(buf, index, sz);
                ushort tcrc = (ushort)((buf[sz + index] << 8) + buf[sz + index + 1]);
                if (crc == tcrc)
                    return true;
            }
            return false;
        }


C:      static int check(int crc, const unsigned char *buf, int sz) {
            if (crc) {
                unsigned short crc = crc16_ccitt(buf, sz);
                unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];
                if (crc == tcrc)
                    return 1;

            }
            return 0;
        }

------------------------------
And are these blocks equivalent?

C#:     static public ushort CRC16_ccitt(byte[] buf, int index, int len) {
            int counter;
            ushort crc = 0;
            for( counter = 0; counter < len; counter++)
                crc = (ushort)((crc << 8) ^ crc16tab[((crc >> 8) ^ buf[index + counter]) & 0x00FF]);
            return crc;
        }


C:      unsigned short crc16_ccitt(const void *buf, int len) {
            register int counter;
            register unsigned short crc = 0;
            for( counter = 0; counter < len; counter++)
                crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF];
            return crc;
       }


Answers (7)