/******************************************************************************
*                                                                             *
*               Cyclic Redundancy Check (CRC) functions                       *
*                                                                             *
******************************************************************************/

/*
*   crc_clear:
*	This function clears the CRC to zero. It should be called prior to
*	the start of the processing of a block for both received messages,
*	and messages to be transmitted.
*
*	Calling sequence:
*
*	short crc;
*	crc = crc_clear();
*/
short crc_clear()
{
	return(0);
}
/*
*   crc_update:
*	this function must be called once for each character which is
*	to be included in the CRC for messages to be transmitted.
*	This function is called once for each character which is included
*	in the CRC of a received message, AND once for each of the two CRC
*	characters at the end of the received message. If the resulting
*	CRC is zero, then the message has been correctly received.
*
*   Calling sequence:
*
*	crc = crc_update(crc,next_char);
*/
short crc_update(crc,crc_char)
short crc;
char crc_char;
{
	long x;
	short i;

/* "x" will contain the character to be processed in bits 0-7 and the CRC    */
/* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared  */
/* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not    */
/* used. ("x" is treated as though it is a 32 bit register).                 */
	x = ((long)crc << 8) + crc_char;    /* Get the CRC and the character */

/* Repeat the following loop 8 times (for the 8 bits of the character).      */
	for(i = 0;i < 8;i++)
	{

/* Shift the high-order bit of the character into the low-order bit of the   */
/* CRC, and shift the high-order bit of the CRC into bit 24.                 */
		x = x << 1;                        /* Shift "x" left one bit */

/* Test to see if the old high-order bit of the CRC was a 1.                 */
		if(x & 0x01000000)                     /* Test bit 24 of "x" */

/* If the old high-order bit of the CRC was a 1, exclusive-or it with a one  */
/* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the     */
/* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce  */
/* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from  */
/* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005    */
/* and produce the same CRC that IBM uses for their synchronous transmission */
/* protocols.                                                                */
			x = x ^ 0x01102100;     /* Exclusive-or "x" with a...*/
                                              /* ...constant of hex 01102100 */
/* And repeat 8 times.                                                       */
	}                                               /* End of "for" loop */

/* Return the CRC as the 16 low-order bits of this function's value.         */
	return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */
                                  /* ...shift the result 8 bits to the right */

}
/*
*   crc_finish:
*	This function must be called once after all the characters in a block
*	have been processed for a message which is to be TRANSMITTED. It
*	returns the calculated CRC bytes, which should be transmitted as the
*	two characters following the block. The first of these 2 bytes
*	must be taken from the high-order byte of the CRC, and the second
*	must be taken from the low-order byte of the CRC. This routine is NOT
*	called for a message which has been RECEIVED.
*
*   Calling sequence:
*
*	crc = crc_finish(crc);
*/
short crc_finish(crc)
short crc;
{
/* Call crc_update twice, passing it a character of hex 00 each time, to     */
/* flush out the last 16 bits from the CRC calculation, and return the       */
/* result as the value of this function.                                     */
	return(crc_update(crc_update(crc,'\0'),'\0'));

}

/*
* This is a sample of the use of the CRC functions, which calculates the
* CRC for a 1-character message block, and then passes the resulting CRC back
* into the CRC functions to see if the "received" 1-character message and CRC
* are correct.
*/
main()
{

	short crc;                                     /* The calculated CRC */
	char crc_char;                            /* The 1-character message */
	char x, y;            /* 2 places to hold the 2 "received" CRC bytes */

	crc_char = 'A';                    /* Define the 1-character message */
	crc = crc_clear();      /* Reset the CRC to "transmit" a new message */
	crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
                                   /* ...(and only) character of the message */
	crc = crc_finish(crc);        /* Finish the transmission calculation */
	x = (char)((crc & 0xff00) >> 8);  /* Extract the high-order CRC byte */
	y = (char)(crc & 0x00ff);          /* And extract the low-order byte */
	printf("%04x\n",crc);                           /* Print the results */

	crc = crc_clear();                 /* Prepare to "receive" a message */
	crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
                                   /* ...(and only) character of the message */
	crc = crc_update(crc,x);     /* Pass both bytes of the "received"... */
	crc = crc_update(crc,y);           /* ...CRC through crc_update, too */
	printf("%04x\n",crc);    /* If the result was 0, then the message... */
                                            /* ...was received without error */

}
eceived without error */

}
                                                                                                                                