00001 /************************************************************************************************** 00002 Software License Agreement (BSD License) 00003 00004 Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt 00005 All rights reserved. 00006 00007 Redistribution and use in source and binary forms, with or without modification, are permitted 00008 provided that the following conditions are met: 00009 00010 *Redistributions of source code must retain the above copyright notice, this list of 00011 conditions and the following disclaimer. 00012 *Redistributions in binary form must reproduce the above copyright notice, this list of 00013 conditions and the following disclaimer in the documentation and/or other materials provided 00014 with the distribution. 00015 *Neither the name of the University of Aveiro nor the names of its contributors may be used to 00016 endorse or promote products derived from this software without specific prior written permission. 00017 00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 00019 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00020 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 00021 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00024 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00025 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 ***************************************************************************************************/ 00032 #include <crc.h> 00033 00034 00035 00036 /*******************************************************************\ 00037 * * 00038 * Library : lib_crc * 00039 * File : lib_crc.c * 00040 * Author : Lammert Bies 1999-2008 * 00041 * E-mail : info@lammertbies.nl * 00042 * Language : ANSI C * 00043 * * 00044 * * 00045 * Description * 00046 * =========== * 00047 * * 00048 * The file lib_crc.c contains the private and public func- * 00049 * tions used for the calculation of CRC-16, CRC-CCITT and * 00050 * CRC-32 cyclic redundancy values. * 00051 * * 00052 * * 00053 * Dependencies * 00054 * ============ * 00055 * * 00056 * lib_crc.h CRC definitions and prototypes * 00057 * * 00058 * * 00059 * Modification history * 00060 * ==================== * 00061 * * 00062 * Date Version Comment * 00063 * * 00064 * 2008-04-20 1.16 Added CRC-CCITT calculation for Kermit * 00065 * * 00066 * 2007-04-01 1.15 Added CRC16 calculation for Modbus * 00067 * * 00068 * 2007-03-28 1.14 Added CRC16 routine for Sick devices * 00069 * * 00070 * 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F * 00071 * * 00072 * 2005-05-14 1.12 Added CRC-CCITT with start value 0 * 00073 * * 00074 * 2005-02-05 1.11 Fixed bug in CRC-DNP routine * 00075 * * 00076 * 2005-02-04 1.10 Added CRC-DNP routines * 00077 * * 00078 * 1999-02-21 1.01 Added FALSE and TRUE mnemonics * 00079 * * 00080 * 1999-01-22 1.00 Initial source * 00081 * * 00082 \*******************************************************************/ 00083 00084 00085 00086 /*******************************************************************\ 00087 * * 00088 * #define P_xxxx * 00089 * * 00090 * The CRC's are computed using polynomials. The coefficients * 00091 * for the algorithms are defined by the following constants. * 00092 * * 00093 \*******************************************************************/ 00094 00095 #define P_16 0xA001 00096 #define P_32 0xEDB88320L 00097 #define P_CCITT 0x1021 00098 #define P_DNP 0xA6BC 00099 #define P_KERMIT 0x8408 00100 #define P_SICK 0x8005 00101 00102 00103 00104 /*******************************************************************\ 00105 * * 00106 * static int crc_tab...init * 00107 * static unsigned ... crc_tab...[] * 00108 * * 00109 * The algorithms use tables with precalculated values. This * 00110 * speeds up the calculation dramaticaly. The first time the * 00111 * CRC function is called, the table for that specific calcu- * 00112 * lation is set up. The ...init variables are used to deter- * 00113 * mine if the initialization has taken place. The calculated * 00114 * values are stored in the crc_tab... arrays. * 00115 * * 00116 * The variables are declared static. This makes them invisi- * 00117 * ble for other modules of the program. * 00118 * * 00119 \*******************************************************************/ 00120 00121 static int crc_tab16_init = FALSE; 00122 static int crc_tab32_init = FALSE; 00123 static int crc_tabccitt_init = FALSE; 00124 static int crc_tabdnp_init = FALSE; 00125 static int crc_tabkermit_init = FALSE; 00126 00127 static unsigned short crc_tab16[256]; 00128 static unsigned long crc_tab32[256]; 00129 static unsigned short crc_tabccitt[256]; 00130 static unsigned short crc_tabdnp[256]; 00131 static unsigned short crc_tabkermit[256]; 00132 00133 00134 00135 /*******************************************************************\ 00136 * * 00137 * static void init_crc...tab(); * 00138 * * 00139 * Three local functions are used to initialize the tables * 00140 * with values for the algorithm. * 00141 * * 00142 \*******************************************************************/ 00143 00144 static void init_crc16_tab( void ); 00145 static void init_crc32_tab( void ); 00146 static void init_crcccitt_tab( void ); 00147 static void init_crcdnp_tab( void ); 00148 static void init_crckermit_tab( void ); 00149 00150 00151 00152 /*******************************************************************\ 00153 * * 00154 * unsigned short update_crc_ccitt( unsigned long crc, char c ); * 00155 * * 00156 * The function update_crc_ccitt calculates a new CRC-CCITT * 00157 * value based on the previous value of the CRC and the next * 00158 * byte of the data to be checked. * 00159 * * 00160 \*******************************************************************/ 00161 00162 unsigned short update_crc_ccitt(unsigned short crc, unsigned char c) { 00163 00164 unsigned short tmp, short_c; 00165 00166 short_c = 0x00ff & (unsigned short) c; 00167 00168 if ( ! crc_tabccitt_init ) init_crcccitt_tab(); 00169 00170 tmp = (crc >> 8) ^ short_c; 00171 crc = (crc << 8) ^ crc_tabccitt[tmp]; 00172 00173 return crc; 00174 00175 } /* update_crc_ccitt */ 00176 00177 00178 00179 /*******************************************************************\ 00180 * * 00181 * unsigned short update_crc_sick( * 00182 * unsigned long crc, char c, char prev_byte ); * 00183 * * 00184 * The function update_crc_sick calculates a new CRC-SICK * 00185 * value based on the previous value of the CRC and the next * 00186 * byte of the data to be checked. * 00187 * * 00188 \*******************************************************************/ 00189 00190 unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte ) { 00191 00192 unsigned short short_c, short_p; 00193 00194 short_c = 0x00ff & (unsigned short) c; 00195 short_p = ( 0x00ff & (unsigned short) prev_byte ) << 8; 00196 00197 if ( crc & 0x8000 ) crc = ( crc << 1 ) ^ P_SICK; 00198 else crc = crc << 1; 00199 00200 crc &= 0xffff; 00201 crc ^= ( short_c | short_p ); 00202 00203 return crc; 00204 00205 } /* update_crc_sick */ 00206 00207 00208 00209 /*******************************************************************\ 00210 * * 00211 * unsigned short update_crc_16( unsigned short crc, char c ); * 00212 * * 00213 * The function update_crc_16 calculates a new CRC-16 value * 00214 * based on the previous value of the CRC and the next byte * 00215 * of the data to be checked. * 00216 * * 00217 \*******************************************************************/ 00218 00219 unsigned short update_crc_16( unsigned short crc, char c ) { 00220 00221 unsigned short tmp, short_c; 00222 00223 short_c = 0x00ff & (unsigned short) c; 00224 00225 if ( ! crc_tab16_init ) init_crc16_tab(); 00226 00227 tmp = crc ^ short_c; 00228 crc = (crc >> 8) ^ crc_tab16[ tmp & 0xff ]; 00229 00230 return crc; 00231 00232 } /* update_crc_16 */ 00233 00234 00235 00236 /*******************************************************************\ 00237 * * 00238 * unsigned short update_crc_kermit( unsigned short crc, char c ); * 00239 * * 00240 * The function update_crc_kermit calculates a new CRC value * 00241 * based on the previous value of the CRC and the next byte * 00242 * of the data to be checked. * 00243 * * 00244 \*******************************************************************/ 00245 00246 unsigned short update_crc_kermit( unsigned short crc, char c ) { 00247 00248 unsigned short tmp, short_c; 00249 00250 short_c = 0x00ff & (unsigned short) c; 00251 00252 if ( ! crc_tabkermit_init ) init_crckermit_tab(); 00253 00254 tmp = crc ^ short_c; 00255 crc = (crc >> 8) ^ crc_tabkermit[ tmp & 0xff ]; 00256 00257 return crc; 00258 00259 } /* update_crc_kermit */ 00260 00261 00262 00263 /*******************************************************************\ 00264 * * 00265 * unsigned short update_crc_dnp( unsigned short crc, char c ); * 00266 * * 00267 * The function update_crc_dnp calculates a new CRC-DNP value * 00268 * based on the previous value of the CRC and the next byte * 00269 * of the data to be checked. * 00270 * * 00271 \*******************************************************************/ 00272 00273 unsigned short update_crc_dnp( unsigned short crc, char c ) { 00274 00275 unsigned short tmp, short_c; 00276 00277 short_c = 0x00ff & (unsigned short) c; 00278 00279 if ( ! crc_tabdnp_init ) init_crcdnp_tab(); 00280 00281 tmp = crc ^ short_c; 00282 crc = (crc >> 8) ^ crc_tabdnp[ tmp & 0xff ]; 00283 00284 return crc; 00285 00286 } /* update_crc_dnp */ 00287 00288 00289 00290 /*******************************************************************\ 00291 * * 00292 * unsigned long update_crc_32( unsigned long crc, char c ); * 00293 * * 00294 * The function update_crc_32 calculates a new CRC-32 value * 00295 * based on the previous value of the CRC and the next byte * 00296 * of the data to be checked. * 00297 * * 00298 \*******************************************************************/ 00299 00300 unsigned long update_crc_32( unsigned long crc, char c ) { 00301 00302 unsigned long tmp, long_c; 00303 00304 long_c = 0x000000ffL & (unsigned long) c; 00305 00306 if ( ! crc_tab32_init ) init_crc32_tab(); 00307 00308 tmp = crc ^ long_c; 00309 crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ]; 00310 00311 return crc; 00312 00313 } /* update_crc_32 */ 00314 00315 00316 00317 /*******************************************************************\ 00318 * * 00319 * static void init_crc16_tab( void ); * 00320 * * 00321 * The function init_crc16_tab() is used to fill the array * 00322 * for calculation of the CRC-16 with values. * 00323 * * 00324 \*******************************************************************/ 00325 00326 static void init_crc16_tab( void ) { 00327 00328 int i, j; 00329 unsigned short crc, c; 00330 00331 for (i=0; i<256; i++) { 00332 00333 crc = 0; 00334 c = (unsigned short) i; 00335 00336 for (j=0; j<8; j++) { 00337 00338 if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_16; 00339 else crc = crc >> 1; 00340 00341 c = c >> 1; 00342 } 00343 00344 crc_tab16[i] = crc; 00345 } 00346 00347 crc_tab16_init = TRUE; 00348 00349 } /* init_crc16_tab */ 00350 00351 00352 00353 /*******************************************************************\ 00354 * * 00355 * static void init_crckermit_tab( void ); * 00356 * * 00357 * The function init_crckermit_tab() is used to fill the array * 00358 * for calculation of the CRC Kermit with values. * 00359 * * 00360 \*******************************************************************/ 00361 00362 static void init_crckermit_tab( void ) { 00363 00364 int i, j; 00365 unsigned short crc, c; 00366 00367 for (i=0; i<256; i++) { 00368 00369 crc = 0; 00370 c = (unsigned short) i; 00371 00372 for (j=0; j<8; j++) { 00373 00374 if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_KERMIT; 00375 else crc = crc >> 1; 00376 00377 c = c >> 1; 00378 } 00379 00380 crc_tabkermit[i] = crc; 00381 } 00382 00383 crc_tabkermit_init = TRUE; 00384 00385 } /* init_crckermit_tab */ 00386 00387 00388 00389 /*******************************************************************\ 00390 * * 00391 * static void init_crcdnp_tab( void ); * 00392 * * 00393 * The function init_crcdnp_tab() is used to fill the array * 00394 * for calculation of the CRC-DNP with values. * 00395 * * 00396 \*******************************************************************/ 00397 00398 static void init_crcdnp_tab( void ) { 00399 00400 int i, j; 00401 unsigned short crc, c; 00402 00403 for (i=0; i<256; i++) { 00404 00405 crc = 0; 00406 c = (unsigned short) i; 00407 00408 for (j=0; j<8; j++) { 00409 00410 if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_DNP; 00411 else crc = crc >> 1; 00412 00413 c = c >> 1; 00414 } 00415 00416 crc_tabdnp[i] = crc; 00417 } 00418 00419 crc_tabdnp_init = TRUE; 00420 00421 } /* init_crcdnp_tab */ 00422 00423 00424 00425 /*******************************************************************\ 00426 * * 00427 * static void init_crc32_tab( void ); * 00428 * * 00429 * The function init_crc32_tab() is used to fill the array * 00430 * for calculation of the CRC-32 with values. * 00431 * * 00432 \*******************************************************************/ 00433 00434 static void init_crc32_tab( void ) { 00435 00436 int i, j; 00437 unsigned long crc; 00438 00439 for (i=0; i<256; i++) { 00440 00441 crc = (unsigned long) i; 00442 00443 for (j=0; j<8; j++) { 00444 00445 if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32; 00446 else crc = crc >> 1; 00447 } 00448 00449 crc_tab32[i] = crc; 00450 } 00451 00452 crc_tab32_init = TRUE; 00453 00454 } /* init_crc32_tab */ 00455 00456 00457 00458 /*******************************************************************\ 00459 * * 00460 * static void init_crcccitt_tab( void ); * 00461 * * 00462 * The function init_crcccitt_tab() is used to fill the array * 00463 * for calculation of the CRC-CCITT with values. * 00464 * * 00465 \*******************************************************************/ 00466 00467 static void init_crcccitt_tab( void ) { 00468 00469 int i, j; 00470 unsigned short crc, c; 00471 00472 for (i=0; i<256; i++) { 00473 00474 crc = 0; 00475 c = ((unsigned short) i) << 8; 00476 00477 for (j=0; j<8; j++) { 00478 00479 if ( (crc ^ c) & 0x8000 ) crc = ( crc << 1 ) ^ P_CCITT; 00480 else crc = crc << 1; 00481 00482 c = c << 1; 00483 } 00484 00485 crc_tabccitt[i] = crc; 00486 } 00487 00488 crc_tabccitt_init = TRUE; 00489 00490 } /* init_crcccitt_tab */