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