/* START LIBRARY DESCRIPTION ********************************************* CRC16.LIB Copyright (c) 1996, Robust DataComm. DESCRIPTION: Calc CRC-16 per Modbus using XMODEM type table SUPPORT LIB'S: END DESCRIPTION **********************************************************/ // History: unsigned int crc16_uCalcBuf( unsigned char *ucpBuf, int nByteCount); unsigned int crc16_uCalcByte( unsigned char uc, unsigned int uCRC); void crc16_Init( void); // pre-seed Table[] (must call to init table!) ushort crc16_Table[256]; // table for partial CRC seeds /* START FUNCTION DESCRIPTION ******************************************** crc16_uCalcBuf SYNTAX: unsigned int crc16_uCalcBuf( uchar *ucpBuf, int nByteCount); DESCRIPTION: Given buffer ptr & byte count, calc new CRC-16 RETURN VALUE: return CRC-16 (swap bytes for Modbus) END DESCRIPTION **********************************************************/ unsigned int crc16_uCalcBuf( uchar *ucpBuf, int nByteCount) { ushort crc_data; // holder of byte during calc ushort crc_crc; // holder of CRC int crc_i; // loop counter crc_crc = 0xFFFF; // start with all 1's for reverse CRC // printf( " <*> crc%x\n", crc_crc); for( crc_i = 0; crc_i < nByteCount; ++crc_i) { // process each byte crc_data = crc_crc ^ ucpBuf[crc_i]; crc_crc = (crc_crc >> 8) ^ crc16_Table[crc_data & 0x00FF]; // printf( " crc%d:%x", crc_i, crc_crc); } return( crc_crc); } /* Modbus CRC are stored MSByte in lo byte - you must swap bytes */ /* START FUNCTION DESCRIPTION ******************************************** crc16_uCalcByte SYNTAX: unsigned int crc16_uCalcByte( uchar uc, ushort uCRC); DESCRIPTION: accumulate CRC 1 byte at a time (use 0xFFFF for first call) RETURN VALUE: none END DESCRIPTION **********************************************************/ unsigned int crc16_uCalcByte( uchar uc, ushort uCRC) { static ushort crc_data; // holder of byte during calc crc_data = uCRC ^ uc; uCRC = (uCRC >> 8) ^ crc16_Table[crc_data & 0x00FF]; return( uCRC); } /* crc16_Init() - Initialize the CRC-16 table (crc16_Table[]) */ void crc16_Init( void) { ushort crc_data; // holder of byte during calc ushort crc_crc; // holder of CRC int crc_i; // loop counter char j; // loop counters for( crc_i = 0; crc_i < 256; crc_i++) { crc_data = (crc_i << 1); crc_crc = 0; for( j = 8; j > 0; j--) { crc_data >>= 1; if( (crc_data ^ crc_crc) & 0x0001) crc_crc = (crc_crc >> 1) ^ 0xA001; else crc_crc >>= 1; } // endfor j crc16_Table[crc_i] = crc_crc; // printf( " %d:%x", crc_i, crc16_Table[crc_i]); } // endfor crc_i return; }