F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
lib_crc.c
Go to the documentation of this file.
1 #include "lib_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 dramatically. 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 
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 
138 
139  tmp = (crc >> 8) ^ short_c;
140  crc = (unsigned short)((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 = (unsigned short)(( 0x00ff & (unsigned short) prev_byte ) << 8);
165 
166  if ( crc & 0x8000 ) crc = (unsigned short)(( crc << 1 ) ^ P_SICK);
167  else crc = (unsigned short)(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  // Note: when masking by 0xff, range is limited to unsigned char
198  // which fits within unsigned int.
199  crc = (crc >> 8) ^ crc_tab16[ (unsigned int)(tmp & 0xff) ];
200 
201  return crc;
202 
203 } /* update_crc_16 */
204 
205 
206 
207  /*******************************************************************\
208  * *
209  * unsigned short update_crc_kermit( unsigned short crc, char c ); *
210  * *
211  * The function update_crc_kermit calculates a new CRC value *
212  * based on the previous value of the CRC and the next byte *
213  * of the data to be checked. *
214  * *
215  \*******************************************************************/
216 
217 unsigned short update_crc_kermit( unsigned short crc, char c ) {
218 
219  unsigned short tmp, short_c;
220 
221  short_c = 0x00ff & (unsigned short) c;
222 
224 
225  tmp = crc ^ short_c;
226  crc = (crc >> 8) ^ crc_tabkermit[ tmp & 0xff ];
227 
228  return crc;
229 
230 } /* update_crc_kermit */
231 
232 
233 
234  /*******************************************************************\
235  * *
236  * unsigned short update_crc_dnp( unsigned short crc, char c ); *
237  * *
238  * The function update_crc_dnp calculates a new CRC-DNP value *
239  * based on the previous value of the CRC and the next byte *
240  * of the data to be checked. *
241  * *
242  \*******************************************************************/
243 
244 unsigned short update_crc_dnp( unsigned short crc, char c ) {
245 
246  unsigned short tmp, short_c;
247 
248  short_c = 0x00ff & (unsigned short) c;
249 
250  if ( ! crc_tabdnp_init ) init_crcdnp_tab();
251 
252  tmp = crc ^ short_c;
253  crc = (crc >> 8) ^ crc_tabdnp[ tmp & 0xff ];
254 
255  return crc;
256 
257 } /* update_crc_dnp */
258 
259 
260 
261  /*******************************************************************\
262  * *
263  * unsigned long update_crc_32( unsigned long crc, char c ); *
264  * *
265  * The function update_crc_32 calculates a new CRC-32 value *
266  * based on the previous value of the CRC and the next byte *
267  * of the data to be checked. *
268  * *
269  \*******************************************************************/
270 
271 unsigned long update_crc_32( unsigned long crc, char c ) {
272 
273  unsigned long tmp, long_c;
274 
275  long_c = 0x000000ffL & (unsigned long) c;
276 
277  if ( ! crc_tab32_init ) init_crc32_tab();
278 
279  tmp = crc ^ long_c;
280  crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
281 
282  return crc;
283 
284 } /* update_crc_32 */
285 
286 
287 
288  /*******************************************************************\
289  * *
290  * static void init_crc16_tab( void ); *
291  * *
292  * The function init_crc16_tab() is used to fill the array *
293  * for calculation of the CRC-16 with values. *
294  * *
295  \*******************************************************************/
296 
297 static void init_crc16_tab( void ) {
298 
299  int i, j;
300  unsigned short crc, c;
301 
302  for (i=0; i<256; i++) {
303 
304  crc = 0;
305  c = (unsigned short) i;
306 
307  for (j=0; j<8; j++) {
308 
309  if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_16;
310  else crc = crc >> 1;
311 
312  c = c >> 1;
313  }
314 
315  crc_tab16[i] = crc;
316  }
317 
319 
320 } /* init_crc16_tab */
321 
322 
323 
324  /*******************************************************************\
325  * *
326  * static void init_crckermit_tab( void ); *
327  * *
328  * The function init_crckermit_tab() is used to fill the array *
329  * for calculation of the CRC Kermit with values. *
330  * *
331  \*******************************************************************/
332 
333 static void init_crckermit_tab( void ) {
334 
335  int i, j;
336  unsigned short crc, c;
337 
338  for (i=0; i<256; i++) {
339 
340  crc = 0;
341  c = (unsigned short) i;
342 
343  for (j=0; j<8; j++) {
344 
345  if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_KERMIT;
346  else crc = crc >> 1;
347 
348  c = c >> 1;
349  }
350 
351  crc_tabkermit[i] = crc;
352  }
353 
355 
356 } /* init_crckermit_tab */
357 
358 
359 
360  /*******************************************************************\
361  * *
362  * static void init_crcdnp_tab( void ); *
363  * *
364  * The function init_crcdnp_tab() is used to fill the array *
365  * for calculation of the CRC-DNP with values. *
366  * *
367  \*******************************************************************/
368 
369 static void init_crcdnp_tab( void ) {
370 
371  int i, j;
372  unsigned short crc, c;
373 
374  for (i=0; i<256; i++) {
375 
376  crc = 0;
377  c = (unsigned short) i;
378 
379  for (j=0; j<8; j++) {
380 
381  if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_DNP;
382  else crc = crc >> 1;
383 
384  c = c >> 1;
385  }
386 
387  crc_tabdnp[i] = crc;
388  }
389 
391 
392 } /* init_crcdnp_tab */
393 
394 
395 
396  /*******************************************************************\
397  * *
398  * static void init_crc32_tab( void ); *
399  * *
400  * The function init_crc32_tab() is used to fill the array *
401  * for calculation of the CRC-32 with values. *
402  * *
403  \*******************************************************************/
404 
405 static void init_crc32_tab( void ) {
406 
407  int i, j;
408  unsigned long crc;
409 
410  for (i=0; i<256; i++) {
411 
412  crc = (unsigned long) i;
413 
414  for (j=0; j<8; j++) {
415 
416  if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
417  else crc = crc >> 1;
418  }
419 
420  crc_tab32[i] = crc;
421  }
422 
424 
425 } /* init_crc32_tab */
426 
427 
428 
429  /*******************************************************************\
430  * *
431  * static void init_crcccitt_tab( void ); *
432  * *
433  * The function init_crcccitt_tab() is used to fill the array *
434  * for calculation of the CRC-CCITT with values. *
435  * *
436  \*******************************************************************/
437 
438 static void init_crcccitt_tab( void ) {
439 
440  int i, j;
441  unsigned short crc, c;
442 
443  for (i=0; i<256; i++) {
444 
445  crc = 0;
446  c = (unsigned short)(((unsigned short) i) << 8);
447 
448  for (j=0; j<8; j++) {
449 
450  if ( (crc ^ c) & 0x8000 ) crc = (unsigned short)(( crc << 1 ) ^ P_CCITT);
451  else crc = (unsigned short)(crc << 1);
452 
453  c = (unsigned short)(c << 1);
454  }
455 
456  crc_tabccitt[i] = crc;
457  }
458 
460 
461 } /* init_crcccitt_tab */
unsigned short update_crc_ccitt(unsigned short crc, char c)
Definition: lib_crc.c:131
unsigned short update_crc_kermit(unsigned short crc, char c)
Definition: lib_crc.c:217
static void init_crcdnp_tab(void)
Definition: lib_crc.c:369
static void init_crc32_tab(void)
Definition: lib_crc.c:405
unsigned short update_crc_sick(unsigned short crc, char c, char prev_byte)
Definition: lib_crc.c:159
unsigned long update_crc_32(unsigned long crc, char c)
Definition: lib_crc.c:271
static void init_crcccitt_tab(void)
Definition: lib_crc.c:438
unsigned short update_crc_dnp(unsigned short crc, char c)
Definition: lib_crc.c:244
#define P_16
Definition: lib_crc.c:64
#define P_KERMIT
Definition: lib_crc.c:68
unsigned short update_crc_16(unsigned short crc, char c)
Definition: lib_crc.c:188
static unsigned short crc_tabdnp[256]
Definition: lib_crc.c:99
static void init_crc16_tab(void)
Definition: lib_crc.c:297
static int crc_tab16_init
Definition: lib_crc.c:90
static void init_crckermit_tab(void)
Definition: lib_crc.c:333
static int crc_tab32_init
Definition: lib_crc.c:91
static unsigned short crc_tab16[256]
Definition: lib_crc.c:96
static int crc_tabccitt_init
Definition: lib_crc.c:92
static unsigned long crc_tab32[256]
Definition: lib_crc.c:97
#define P_CCITT
Definition: lib_crc.c:66
#define P_32
Definition: lib_crc.c:65
#define P_DNP
Definition: lib_crc.c:67
#define P_SICK
Definition: lib_crc.c:69
static int crc_tabdnp_init
Definition: lib_crc.c:93
static int crc_tabkermit_init
Definition: lib_crc.c:94
static unsigned short crc_tabkermit[256]
Definition: lib_crc.c:100
static unsigned short crc_tabccitt[256]
Definition: lib_crc.c:98
#define CRC_FALSE
Definition: lib_crc.h:61
#define CRC_TRUE
Definition: lib_crc.h:62