| [1] | 1 | #include "crc.h"
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 | /*******************************************************************\
|
|---|
| 6 | * *
|
|---|
| 7 | * Library : lib_crc *
|
|---|
| 8 | * File : lib_crc.c *
|
|---|
| 9 | * Author : Lammert Bies 1999-2008 *
|
|---|
| 10 | * E-mail : info@lammertbies.nl *
|
|---|
| 11 | * Language : ANSI C *
|
|---|
| 12 | * *
|
|---|
| 13 | * *
|
|---|
| 14 | * Description *
|
|---|
| 15 | * =========== *
|
|---|
| 16 | * *
|
|---|
| 17 | * The file lib_crc.c contains the private and public func- *
|
|---|
| 18 | * tions used for the calculation of CRC-16, CRC-CCITT and *
|
|---|
| 19 | * CRC-32 cyclic redundancy values. *
|
|---|
| 20 | * *
|
|---|
| 21 | * *
|
|---|
| 22 | * Dependencies *
|
|---|
| 23 | * ============ *
|
|---|
| 24 | * *
|
|---|
| 25 | * lib_crc.h CRC definitions and prototypes *
|
|---|
| 26 | * *
|
|---|
| 27 | * *
|
|---|
| 28 | * Modification history *
|
|---|
| 29 | * ==================== *
|
|---|
| 30 | * *
|
|---|
| 31 | * Date Version Comment *
|
|---|
| 32 | * *
|
|---|
| 33 | * 2008-04-20 1.16 Added CRC-CCITT calculation for Kermit *
|
|---|
| 34 | * *
|
|---|
| 35 | * 2007-04-01 1.15 Added CRC16 calculation for Modbus *
|
|---|
| 36 | * *
|
|---|
| 37 | * 2007-03-28 1.14 Added CRC16 routine for Sick devices *
|
|---|
| 38 | * *
|
|---|
| 39 | * 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F *
|
|---|
| 40 | * *
|
|---|
| 41 | * 2005-05-14 1.12 Added CRC-CCITT with start value 0 *
|
|---|
| 42 | * *
|
|---|
| 43 | * 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
|
|---|
| 44 | * *
|
|---|
| 45 | * 2005-02-04 1.10 Added CRC-DNP routines *
|
|---|
| 46 | * *
|
|---|
| 47 | * 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
|
|---|
| 48 | * *
|
|---|
| 49 | * 1999-01-22 1.00 Initial source *
|
|---|
| 50 | * *
|
|---|
| 51 | \*******************************************************************/
|
|---|
| 52 |
|
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 | /*******************************************************************\
|
|---|
| 56 | * *
|
|---|
| 57 | * #define P_xxxx *
|
|---|
| 58 | * *
|
|---|
| 59 | * The CRC's are computed using polynomials. The coefficients *
|
|---|
| 60 | * for the algorithms are defined by the following constants. *
|
|---|
| 61 | * *
|
|---|
| 62 | \*******************************************************************/
|
|---|
| 63 |
|
|---|
| 64 | #define P_16 0xA001
|
|---|
| 65 | #define P_32 0xEDB88320L
|
|---|
| 66 | #define P_CCITT 0x1021
|
|---|
| 67 | #define P_DNP 0xA6BC
|
|---|
| 68 | #define P_KERMIT 0x8408
|
|---|
| 69 | #define P_SICK 0x8005
|
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 | /*******************************************************************\
|
|---|
| 74 | * *
|
|---|
| 75 | * static int crc_tab...init *
|
|---|
| 76 | * static unsigned ... crc_tab...[] *
|
|---|
| 77 | * *
|
|---|
| 78 | * The algorithms use tables with precalculated values. This *
|
|---|
| 79 | * speeds up the calculation dramaticaly. The first time the *
|
|---|
| 80 | * CRC function is called, the table for that specific calcu- *
|
|---|
| 81 | * lation is set up. The ...init variables are used to deter- *
|
|---|
| 82 | * mine if the initialization has taken place. The calculated *
|
|---|
| 83 | * values are stored in the crc_tab... arrays. *
|
|---|
| 84 | * *
|
|---|
| 85 | * The variables are declared static. This makes them invisi- *
|
|---|
| 86 | * ble for other modules of the program. *
|
|---|
| 87 | * *
|
|---|
| 88 | \*******************************************************************/
|
|---|
| 89 |
|
|---|
| 90 | static int crc_tab16_init = FALSE;
|
|---|
| 91 | static int crc_tab32_init = FALSE;
|
|---|
| 92 | static int crc_tabccitt_init = FALSE;
|
|---|
| 93 | static int crc_tabdnp_init = FALSE;
|
|---|
| 94 | static int crc_tabkermit_init = FALSE;
|
|---|
| 95 |
|
|---|
| 96 | static unsigned short crc_tab16[256];
|
|---|
| 97 | static unsigned long crc_tab32[256];
|
|---|
| 98 | static unsigned short crc_tabccitt[256];
|
|---|
| 99 | static unsigned short crc_tabdnp[256];
|
|---|
| 100 | static unsigned short crc_tabkermit[256];
|
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 |
|
|---|
| 104 | /*******************************************************************\
|
|---|
| 105 | * *
|
|---|
| 106 | * static void init_crc...tab(); *
|
|---|
| 107 | * *
|
|---|
| 108 | * Three local functions are used to initialize the tables *
|
|---|
| 109 | * with values for the algorithm. *
|
|---|
| 110 | * *
|
|---|
| 111 | \*******************************************************************/
|
|---|
| 112 |
|
|---|
| 113 | static void init_crc16_tab( void );
|
|---|
| 114 | static void init_crc32_tab( void );
|
|---|
| 115 | static void init_crcccitt_tab( void );
|
|---|
| 116 | static void init_crcdnp_tab( void );
|
|---|
| 117 | static void init_crckermit_tab( void );
|
|---|
| 118 |
|
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 | /*******************************************************************\
|
|---|
| 122 | * *
|
|---|
| 123 | * unsigned short update_crc_ccitt( unsigned long crc, char c ); *
|
|---|
| 124 | * *
|
|---|
| 125 | * The function update_crc_ccitt calculates a new CRC-CCITT *
|
|---|
| 126 | * value based on the previous value of the CRC and the next *
|
|---|
| 127 | * byte of the data to be checked. *
|
|---|
| 128 | * *
|
|---|
| 129 | \*******************************************************************/
|
|---|
| 130 |
|
|---|
| 131 | unsigned short update_crc_ccitt( unsigned short crc, char c ) {
|
|---|
| 132 |
|
|---|
| 133 | unsigned short tmp, short_c;
|
|---|
| 134 |
|
|---|
| 135 | short_c = 0x00ff & (unsigned short) c;
|
|---|
| 136 |
|
|---|
| 137 | if ( ! crc_tabccitt_init ) init_crcccitt_tab();
|
|---|
| 138 |
|
|---|
| 139 | tmp = (crc >> 8) ^ short_c;
|
|---|
| 140 | crc = (crc << 8) ^ crc_tabccitt[tmp];
|
|---|
| 141 |
|
|---|
| 142 | return crc;
|
|---|
| 143 |
|
|---|
| 144 | } /* update_crc_ccitt */
|
|---|
| 145 |
|
|---|
| 146 |
|
|---|
| 147 |
|
|---|
| 148 | /*******************************************************************\
|
|---|
| 149 | * *
|
|---|
| 150 | * unsigned short update_crc_sick( *
|
|---|
| 151 | * unsigned long crc, char c, char prev_byte ); *
|
|---|
| 152 | * *
|
|---|
| 153 | * The function update_crc_sick calculates a new CRC-SICK *
|
|---|
| 154 | * value based on the previous value of the CRC and the next *
|
|---|
| 155 | * byte of the data to be checked. *
|
|---|
| 156 | * *
|
|---|
| 157 | \*******************************************************************/
|
|---|
| 158 |
|
|---|
| 159 | unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte ) {
|
|---|
| 160 |
|
|---|
| 161 | unsigned short short_c, short_p;
|
|---|
| 162 |
|
|---|
| 163 | short_c = 0x00ff & (unsigned short) c;
|
|---|
| 164 | short_p = ( 0x00ff & (unsigned short) prev_byte ) << 8;
|
|---|
| 165 |
|
|---|
| 166 | if ( crc & 0x8000 ) crc = ( crc << 1 ) ^ P_SICK;
|
|---|
| 167 | else crc = crc << 1;
|
|---|
| 168 |
|
|---|
| 169 | crc &= 0xffff;
|
|---|
| 170 | crc ^= ( short_c | short_p );
|
|---|
| 171 |
|
|---|
| 172 | return crc;
|
|---|
| 173 |
|
|---|
| 174 | } /* update_crc_sick */
|
|---|
| 175 |
|
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 | /*******************************************************************\
|
|---|
| 179 | * *
|
|---|
| 180 | * unsigned short update_crc_16( unsigned short crc, char c ); *
|
|---|
| 181 | * *
|
|---|
| 182 | * The function update_crc_16 calculates a new CRC-16 value *
|
|---|
| 183 | * based on the previous value of the CRC and the next byte *
|
|---|
| 184 | * of the data to be checked. *
|
|---|
| 185 | * *
|
|---|
| 186 | \*******************************************************************/
|
|---|
| 187 |
|
|---|
| 188 | unsigned short update_crc_16( unsigned short crc, char c ) {
|
|---|
| 189 |
|
|---|
| 190 | unsigned short tmp, short_c;
|
|---|
| 191 |
|
|---|
| 192 | short_c = 0x00ff & (unsigned short) c;
|
|---|
| 193 |
|
|---|
| 194 | if ( ! crc_tab16_init ) init_crc16_tab();
|
|---|
| 195 |
|
|---|
| 196 | tmp = crc ^ short_c;
|
|---|
| 197 | crc = (crc >> 8) ^ crc_tab16[ tmp & 0xff ];
|
|---|
| 198 |
|
|---|
| 199 | return crc;
|
|---|
| 200 |
|
|---|
| 201 | } /* update_crc_16 */
|
|---|
| 202 |
|
|---|
| 203 |
|
|---|
| 204 |
|
|---|
| 205 | /*******************************************************************\
|
|---|
| 206 | * *
|
|---|
| 207 | * unsigned short update_crc_kermit( unsigned short crc, char c ); *
|
|---|
| 208 | * *
|
|---|
| 209 | * The function update_crc_kermit calculates a new CRC value *
|
|---|
| 210 | * based on the previous value of the CRC and the next byte *
|
|---|
| 211 | * of the data to be checked. *
|
|---|
| 212 | * *
|
|---|
| 213 | \*******************************************************************/
|
|---|
| 214 |
|
|---|
| 215 | unsigned short update_crc_kermit( unsigned short crc, char c ) {
|
|---|
| 216 |
|
|---|
| 217 | unsigned short tmp, short_c;
|
|---|
| 218 |
|
|---|
| 219 | short_c = 0x00ff & (unsigned short) c;
|
|---|
| 220 |
|
|---|
| 221 | if ( ! crc_tabkermit_init ) init_crckermit_tab();
|
|---|
| 222 |
|
|---|
| 223 | tmp = crc ^ short_c;
|
|---|
| 224 | crc = (crc >> 8) ^ crc_tabkermit[ tmp & 0xff ];
|
|---|
| 225 |
|
|---|
| 226 | return crc;
|
|---|
| 227 |
|
|---|
| 228 | } /* update_crc_kermit */
|
|---|
| 229 |
|
|---|
| 230 |
|
|---|
| 231 |
|
|---|
| 232 | /*******************************************************************\
|
|---|
| 233 | * *
|
|---|
| 234 | * unsigned short update_crc_dnp( unsigned short crc, char c ); *
|
|---|
| 235 | * *
|
|---|
| 236 | * The function update_crc_dnp calculates a new CRC-DNP value *
|
|---|
| 237 | * based on the previous value of the CRC and the next byte *
|
|---|
| 238 | * of the data to be checked. *
|
|---|
| 239 | * *
|
|---|
| 240 | \*******************************************************************/
|
|---|
| 241 |
|
|---|
| 242 | unsigned short update_crc_dnp( unsigned short crc, char c ) {
|
|---|
| 243 |
|
|---|
| 244 | unsigned short tmp, short_c;
|
|---|
| 245 |
|
|---|
| 246 | short_c = 0x00ff & (unsigned short) c;
|
|---|
| 247 |
|
|---|
| 248 | if ( ! crc_tabdnp_init ) init_crcdnp_tab();
|
|---|
| 249 |
|
|---|
| 250 | tmp = crc ^ short_c;
|
|---|
| 251 | crc = (crc >> 8) ^ crc_tabdnp[ tmp & 0xff ];
|
|---|
| 252 |
|
|---|
| 253 | return crc;
|
|---|
| 254 |
|
|---|
| 255 | } /* update_crc_dnp */
|
|---|
| 256 |
|
|---|
| 257 |
|
|---|
| 258 |
|
|---|
| 259 | /*******************************************************************\
|
|---|
| 260 | * *
|
|---|
| 261 | * unsigned long update_crc_32( unsigned long crc, char c ); *
|
|---|
| 262 | * *
|
|---|
| 263 | * The function update_crc_32 calculates a new CRC-32 value *
|
|---|
| 264 | * based on the previous value of the CRC and the next byte *
|
|---|
| 265 | * of the data to be checked. *
|
|---|
| 266 | * *
|
|---|
| 267 | \*******************************************************************/
|
|---|
| 268 |
|
|---|
| 269 | unsigned long update_crc_32( unsigned long crc, char c ) {
|
|---|
| 270 |
|
|---|
| 271 | unsigned long tmp, long_c;
|
|---|
| 272 |
|
|---|
| 273 | long_c = 0x000000ffL & (unsigned long) c;
|
|---|
| 274 |
|
|---|
| 275 | if ( ! crc_tab32_init ) init_crc32_tab();
|
|---|
| 276 |
|
|---|
| 277 | tmp = crc ^ long_c;
|
|---|
| 278 | crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
|
|---|
| 279 |
|
|---|
| 280 | return crc;
|
|---|
| 281 |
|
|---|
| 282 | } /* update_crc_32 */
|
|---|
| 283 |
|
|---|
| 284 |
|
|---|
| 285 |
|
|---|
| 286 | /*******************************************************************\
|
|---|
| 287 | * *
|
|---|
| 288 | * static void init_crc16_tab( void ); *
|
|---|
| 289 | * *
|
|---|
| 290 | * The function init_crc16_tab() is used to fill the array *
|
|---|
| 291 | * for calculation of the CRC-16 with values. *
|
|---|
| 292 | * *
|
|---|
| 293 | \*******************************************************************/
|
|---|
| 294 |
|
|---|
| 295 | static void init_crc16_tab( void ) {
|
|---|
| 296 |
|
|---|
| 297 | int i, j;
|
|---|
| 298 | unsigned short crc, c;
|
|---|
| 299 |
|
|---|
| 300 | for (i=0; i<256; i++) {
|
|---|
| 301 |
|
|---|
| 302 | crc = 0;
|
|---|
| 303 | c = (unsigned short) i;
|
|---|
| 304 |
|
|---|
| 305 | for (j=0; j<8; j++) {
|
|---|
| 306 |
|
|---|
| 307 | if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_16;
|
|---|
| 308 | else crc = crc >> 1;
|
|---|
| 309 |
|
|---|
| 310 | c = c >> 1;
|
|---|
| 311 | }
|
|---|
| 312 |
|
|---|
| 313 | crc_tab16[i] = crc;
|
|---|
| 314 | }
|
|---|
| 315 |
|
|---|
| 316 | crc_tab16_init = TRUE;
|
|---|
| 317 |
|
|---|
| 318 | } /* init_crc16_tab */
|
|---|
| 319 |
|
|---|
| 320 |
|
|---|
| 321 |
|
|---|
| 322 | /*******************************************************************\
|
|---|
| 323 | * *
|
|---|
| 324 | * static void init_crckermit_tab( void ); *
|
|---|
| 325 | * *
|
|---|
| 326 | * The function init_crckermit_tab() is used to fill the array *
|
|---|
| 327 | * for calculation of the CRC Kermit with values. *
|
|---|
| 328 | * *
|
|---|
| 329 | \*******************************************************************/
|
|---|
| 330 |
|
|---|
| 331 | static void init_crckermit_tab( void ) {
|
|---|
| 332 |
|
|---|
| 333 | int i, j;
|
|---|
| 334 | unsigned short crc, c;
|
|---|
| 335 |
|
|---|
| 336 | for (i=0; i<256; i++) {
|
|---|
| 337 |
|
|---|
| 338 | crc = 0;
|
|---|
| 339 | c = (unsigned short) i;
|
|---|
| 340 |
|
|---|
| 341 | for (j=0; j<8; j++) {
|
|---|
| 342 |
|
|---|
| 343 | if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_KERMIT;
|
|---|
| 344 | else crc = crc >> 1;
|
|---|
| 345 |
|
|---|
| 346 | c = c >> 1;
|
|---|
| 347 | }
|
|---|
| 348 |
|
|---|
| 349 | crc_tabkermit[i] = crc;
|
|---|
| 350 | }
|
|---|
| 351 |
|
|---|
| 352 | crc_tabkermit_init = TRUE;
|
|---|
| 353 |
|
|---|
| 354 | } /* init_crckermit_tab */
|
|---|
| 355 |
|
|---|
| 356 |
|
|---|
| 357 |
|
|---|
| 358 | /*******************************************************************\
|
|---|
| 359 | * *
|
|---|
| 360 | * static void init_crcdnp_tab( void ); *
|
|---|
| 361 | * *
|
|---|
| 362 | * The function init_crcdnp_tab() is used to fill the array *
|
|---|
| 363 | * for calculation of the CRC-DNP with values. *
|
|---|
| 364 | * *
|
|---|
| 365 | \*******************************************************************/
|
|---|
| 366 |
|
|---|
| 367 | static void init_crcdnp_tab( void ) {
|
|---|
| 368 |
|
|---|
| 369 | int i, j;
|
|---|
| 370 | unsigned short crc, c;
|
|---|
| 371 |
|
|---|
| 372 | for (i=0; i<256; i++) {
|
|---|
| 373 |
|
|---|
| 374 | crc = 0;
|
|---|
| 375 | c = (unsigned short) i;
|
|---|
| 376 |
|
|---|
| 377 | for (j=0; j<8; j++) {
|
|---|
| 378 |
|
|---|
| 379 | if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_DNP;
|
|---|
| 380 | else crc = crc >> 1;
|
|---|
| 381 |
|
|---|
| 382 | c = c >> 1;
|
|---|
| 383 | }
|
|---|
| 384 |
|
|---|
| 385 | crc_tabdnp[i] = crc;
|
|---|
| 386 | }
|
|---|
| 387 |
|
|---|
| 388 | crc_tabdnp_init = TRUE;
|
|---|
| 389 |
|
|---|
| 390 | } /* init_crcdnp_tab */
|
|---|
| 391 |
|
|---|
| 392 |
|
|---|
| 393 |
|
|---|
| 394 | /*******************************************************************\
|
|---|
| 395 | * *
|
|---|
| 396 | * static void init_crc32_tab( void ); *
|
|---|
| 397 | * *
|
|---|
| 398 | * The function init_crc32_tab() is used to fill the array *
|
|---|
| 399 | * for calculation of the CRC-32 with values. *
|
|---|
| 400 | * *
|
|---|
| 401 | \*******************************************************************/
|
|---|
| 402 |
|
|---|
| 403 | static void init_crc32_tab( void ) {
|
|---|
| 404 |
|
|---|
| 405 | int i, j;
|
|---|
| 406 | unsigned long crc;
|
|---|
| 407 |
|
|---|
| 408 | for (i=0; i<256; i++) {
|
|---|
| 409 |
|
|---|
| 410 | crc = (unsigned long) i;
|
|---|
| 411 |
|
|---|
| 412 | for (j=0; j<8; j++) {
|
|---|
| 413 |
|
|---|
| 414 | if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
|
|---|
| 415 | else crc = crc >> 1;
|
|---|
| 416 | }
|
|---|
| 417 |
|
|---|
| 418 | crc_tab32[i] = crc;
|
|---|
| 419 | }
|
|---|
| 420 |
|
|---|
| 421 | crc_tab32_init = TRUE;
|
|---|
| 422 |
|
|---|
| 423 | } /* init_crc32_tab */
|
|---|
| 424 |
|
|---|
| 425 |
|
|---|
| 426 |
|
|---|
| 427 | /*******************************************************************\
|
|---|
| 428 | * *
|
|---|
| 429 | * static void init_crcccitt_tab( void ); *
|
|---|
| 430 | * *
|
|---|
| 431 | * The function init_crcccitt_tab() is used to fill the array *
|
|---|
| 432 | * for calculation of the CRC-CCITT with values. *
|
|---|
| 433 | * *
|
|---|
| 434 | \*******************************************************************/
|
|---|
| 435 |
|
|---|
| 436 | static void init_crcccitt_tab( void ) {
|
|---|
| 437 |
|
|---|
| 438 | int i, j;
|
|---|
| 439 | unsigned short crc, c;
|
|---|
| 440 |
|
|---|
| 441 | for (i=0; i<256; i++) {
|
|---|
| 442 |
|
|---|
| 443 | crc = 0;
|
|---|
| 444 | c = ((unsigned short) i) << 8;
|
|---|
| 445 |
|
|---|
| 446 | for (j=0; j<8; j++) {
|
|---|
| 447 |
|
|---|
| 448 | if ( (crc ^ c) & 0x8000 ) crc = ( crc << 1 ) ^ P_CCITT;
|
|---|
| 449 | else crc = crc << 1;
|
|---|
| 450 |
|
|---|
| 451 | c = c << 1;
|
|---|
| 452 | }
|
|---|
| 453 |
|
|---|
| 454 | crc_tabccitt[i] = crc;
|
|---|
| 455 | }
|
|---|
| 456 |
|
|---|
| 457 | crc_tabccitt_init = TRUE;
|
|---|
| 458 |
|
|---|
| 459 | } /* init_crcccitt_tab */
|
|---|