Generating a CRC

Post Reply
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Generating a CRC

Post by Jeff Barnes »

Hi Everyone,

I am trying to connect to a patient monitor to extract data.
The monitor has an ASCII protocol the requires a CRC as part of the command request.

For example, If I want to issue a "Connect" command I would need to do the following:

Format: Header <command> CRC

so the actual command to send is: DIAP000<connect>CRC

In the manual they have a small section on the CRC that I just do not understand.

From the manual:

CRC Algorithm

The algorithm used to create the CRC follows:

const unsigned short crcTable[256] = {

0x0000, 0x0108, 0x0210, 0x0318, 0x0420, 0x0528, 0x0630, 0x0738,

0x0840, 0x0948, 0x0A50, 0x0B58, 0x0C60, 0x0D68, 0x0E70, 0x0F78,

0x1081, 0x1189, 0x1291, 0x1399, 0x14A1, 0x15A9, 0x16B1, 0x17B9,

0x18C1, 0x19C9, 0x1AD1, 0x1BD9, 0x1CE1, 0x1DE9, 0x1EF1, 0x1FF9,

0x2102, 0x200A, 0x2312, 0x221A, 0x2522, 0x242A, 0x2732, 0x263A,

0x2942, 0x284A, 0x2B52, 0x2A5A, 0x2D62, 0x2C6A, 0x2F72, 0x2E7A,

0x3183, 0x308B, 0x3393, 0x329B, 0x35A3, 0x34AB, 0x37B3, 0x36BB,

0x39C3, 0x38CB, 0x3BD3, 0x3ADB, 0x3DE3, 0x3CEB, 0x3FF3, 0x3EFB,

0x4204, 0x430C, 0x4014, 0x411C, 0x4624, 0x472C, 0x4434, 0x453C,

0x4A44, 0x4B4C, 0x4854, 0x495C, 0x4E64, 0x4F6C, 0x4C74, 0x4D7C,

0x5285, 0x538D, 0x5095, 0x519D, 0x56A5, 0x57AD, 0x54B5, 0x55BD,

0x5AC5, 0x5BCD, 0x58D5, 0x59DD, 0x5EE5, 0x5FED, 0x5CF5, 0x5DFD,

0x6306, 0x620E, 0x6116, 0x601E, 0x6726, 0x662E, 0x6536, 0x643E,

0x6B46, 0x6A4E, 0x6956, 0x685E, 0x6F66, 0x6E6E, 0x6D76, 0x6C7E,

0x7387, 0x728F, 0x7197, 0x709F, 0x77A7, 0x76AF, 0x75B7, 0x74BF,

0x7BC7, 0x7ACF, 0x79D7, 0x78DF, 0x7FE7, 0x7EEF, 0x7DF7, 0x7CFF,

0x8408, 0x8500, 0x8618, 0x8710, 0x8028, 0x8120, 0x8238, 0x8330,

0x8C48, 0x8D40, 0x8E58, 0x8F50, 0x8868, 0x8960, 0x8A78, 0x8B70,

0x9489, 0x9581, 0x9699, 0x9791, 0x90A9, 0x91A1, 0x92B9, 0x93B1,

0x9CC9, 0x9DC1, 0x9ED9, 0x9FD1, 0x98E9, 0x99E1, 0x9AF9, 0x9BF1,

0xA50A, 0xA402, 0xA71A, 0xA612, 0xA12A, 0xA022, 0xA33A, 0xA232,

0xAD4A, 0xAC42, 0xAF5A, 0xAE52, 0xA96A, 0xA862, 0xAB7A, 0xAA72,

0xB58B, 0xB483, 0xB79B, 0xB693, 0xB1AB, 0xB0A3, 0xB3BB, 0xB2B3,

0xBDCB, 0xBCC3, 0xBFDB, 0xBED3, 0xB9EB, 0xB8E3, 0xBBFB, 0xBAF3,

0xC60C, 0xC704, 0xC41C, 0xC514, 0xC22C, 0xC324, 0xC03C, 0xC134,

0xCE4C, 0xCF44, 0xCC5C, 0xCD54, 0xCA6C, 0xCB64, 0xC87C, 0xC974,

0xD68D, 0xD785, 0xD49D, 0xD595, 0xD2AD, 0xD3A5, 0xD0BD, 0xD1B5,

0xDECD, 0xDFC5, 0xDCDD, 0xDDD5, 0xDAED, 0xDBE5, 0xD8FD, 0xD9F5,

0xE70E, 0xE606, 0xE51E, 0xE416, 0xE32E, 0xE226, 0xE13E, 0xE036,

0xEF4E, 0xEE46, 0xED5E, 0xEC56, 0xEB6E, 0xEA66, 0xE97E, 0xE876,

0xF78F, 0xF687, 0xF59F, 0xF497, 0xF3AF, 0xF2A7, 0xF1BF, 0xF0B7,

0xFFCF, 0xFEC7, 0xFDDF, 0xFCD7, 0xFBEF, 0xFAE7, 0xF9FF, 0xF8F7,

};

unsigned short Crc (unsigned short lastCrc, unsigned long sizeOfBuffer,

unsigned char *buffer) {

unsigned long i;

unsigned char index;

for (i = 0L; i < sizeOfBuffer; i++) {

index = buffer ^ ((unsigned char)(lastCrc & 0x00FF));

lastCrc = ((lastCrc >> 8) & 0x00FF) ^ (crcTable[index]);

}

return (lastCrc);

}



CRC Test Program

The following program can be used to test the above:

#include <stdio.h>

int main(void) {

unsigned char buffer [] = {0, 0, 0, 0, 0, 0x77, 0xCF};

printf(“CRC(Expected 0x73F3) = 0x%04X\n”, Crc(0x0, 7, buffer));

return(0);

}

NOTE: For the example above, the value for the last CRC

parameter should be initalized to zero (0).







Can anyone help me to understand this and point me in the right direction?



Thanks in advance,
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Jeff,

FWH provides:

nFileCRC( cFileName ) --> nCRC

nStrCRC( cString ) --> nCRC
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Post by Jeff Barnes »

Enrico/Antonio,

The problem is that the CRC can only be a 4 char hex string.

Here is an example of the error codes returned with their correct CRC values:

DIAP000<%REQUEST CORRUPT>734D

DIAP000<%INVALID CRC CHAR>A471


I am just so lost on this one. I have send an email to the manufacturer of the device but I have no idea when they will reply and I need to provide an answer to end user today.

Any help you can provide will be greatly appreciated.
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Jeff,

You can use FWH DecToHex():

DecToHex( nFileCRC( cFileName ) )

DecToHex( nStrCRC( cString ) )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Post by Jeff Barnes »

Hi Antonio,

I've tried with the DecToHex() but still end up with an 8 char Hex number instead of the needed 4 char hex number as in the example below:


Header <command> CRC

DIAP000<%REQUEST CORRUPT>734D

DIAP000<%INVALID CRC CHAR>A471


I still have not had a reply from the manufacturer :-(
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Jeff,

A hex number of four characters can hold a number <= 65535

So if the number is larger than 65535 (FFFF) then you can not use four characters only.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Post by Jeff Barnes »

I have written a small app that will send the command with 0000 to FFFF and see what CRC works. It is going to take a while but I can not figure out how they generate this 4 char hex either.

Thanks for the effort ... You know they will finally get back to me after it has been figured out :-)
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
User avatar
Jeff Barnes
Posts: 912
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada
Contact:

Post by Jeff Barnes »

Is there a CRC16 function?
Thanks,
Jeff Barnes

(FWH 12.01, xHarbour 1.2.1, Bcc582)
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Post by Enrico Maria Giordano »

This is a function I used with Clipper long time ago:

Code: Select all

#include "extend.h"


CLIPPER crc16()
{
    char *s = _parc( 1 );
    int crc = 0;
    int i, j;

    for ( i = 0; i < 128; i++ )
    {
        crc ^= *s++ << 8;

        for ( j = 0; j < 8; j++ )
            if ( crc & 0x8000 )
                crc = ( crc << 1 ) ^ 0x1021;
            else
                crc = crc << 1;
    }

    _retni( crc );
}
EMG
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Post by Enrico Maria Giordano »

The fixed value of 128 has to be calculated using strlen() instead.

EMG
Post Reply