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 
96 
97 static unsigned short crc_tab16[256];
98 static unsigned long crc_tab32[256];
99 static unsigned short crc_tabccitt[256];
100 static unsigned short crc_tabdnp[256];
101 static unsigned short crc_tabkermit[256];
102 
103 
104 
105  /*******************************************************************\
106  * *
107  * static void init_crc...tab(); *
108  * *
109  * Three local functions are used to initialize the tables *
110  * with values for the algorithm. *
111  * *
112  \*******************************************************************/
113 
114 static void init_crc16_tab( void );
115 static void init_crc32_tab( void );
116 static void init_crcccitt_tab( void );
117 static void init_crcdnp_tab( void );
118 static void init_crckermit_tab( void );
119 
120 
121 
122  /*******************************************************************\
123  * *
124  * unsigned short update_crc_ccitt( unsigned long crc, char c ); *
125  * *
126  * The function update_crc_ccitt calculates a new CRC-CCITT *
127  * value based on the previous value of the CRC and the next *
128  * byte of the data to be checked. *
129  * *
130  \*******************************************************************/
131 
132 unsigned short update_crc_ccitt( unsigned short crc, char c ) {
133 
134  unsigned short tmp, short_c;
135 
136  short_c = 0x00ff & (unsigned short) c;
137 
139 
140  tmp = (crc >> 8) ^ short_c;
141  crc = (unsigned short)((crc << 8) ^ crc_tabccitt[tmp]);
142 
143  return crc;
144 
145 } /* update_crc_ccitt */
146 
147 
148 
149  /*******************************************************************\
150  * *
151  * unsigned short update_crc_sick( *
152  * unsigned long crc, char c, char prev_byte ); *
153  * *
154  * The function update_crc_sick calculates a new CRC-SICK *
155  * value based on the previous value of the CRC and the next *
156  * byte of the data to be checked. *
157  * *
158  \*******************************************************************/
159 
160 unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte ) {
161 
162  unsigned short short_c, short_p;
163 
164  short_c = 0x00ff & (unsigned short) c;
165  short_p = (unsigned short)(( 0x00ff & (unsigned short) prev_byte ) << 8);
166 
167  if ( crc & 0x8000 ) crc = (unsigned short)(( crc << 1 ) ^ P_SICK);
168  else crc = (unsigned short)(crc << 1);
169 
170  crc &= 0xffff;
171  crc ^= ( short_c | short_p );
172 
173  return crc;
174 
175 } /* update_crc_sick */
176 
177 
178 
179  /*******************************************************************\
180  * *
181  * unsigned short update_crc_16( unsigned short crc, char c ); *
182  * *
183  * The function update_crc_16 calculates a new CRC-16 value *
184  * based on the previous value of the CRC and the next byte *
185  * of the data to be checked. *
186  * *
187  \*******************************************************************/
188 
189 unsigned short update_crc_16( unsigned short crc, char c ) {
190 
191  unsigned short tmp, short_c;
192 
193  short_c = 0x00ff & (unsigned short) c;
194 
195  if ( ! crc_tab16_init ) init_crc16_tab();
196 
197  tmp = crc ^ short_c;
198  // Note: when masking by 0xff, range is limited to unsigned char
199  // which fits within unsigned int.
200  crc = (crc >> 8) ^ crc_tab16[ (unsigned int)(tmp & 0xff) ];
201 
202  return crc;
203 
204 } /* update_crc_16 */
205 
206 
207 
208  /*******************************************************************\
209  * *
210  * unsigned short update_crc_kermit( unsigned short crc, char c ); *
211  * *
212  * The function update_crc_kermit calculates a new CRC value *
213  * based on the previous value of the CRC and the next byte *
214  * of the data to be checked. *
215  * *
216  \*******************************************************************/
217 
218 unsigned short update_crc_kermit( unsigned short crc, char c ) {
219 
220  unsigned short tmp, short_c;
221 
222  short_c = 0x00ff & (unsigned short) c;
223 
225 
226  tmp = crc ^ short_c;
227  crc = (crc >> 8) ^ crc_tabkermit[ tmp & 0xff ];
228 
229  return crc;
230 
231 } /* update_crc_kermit */
232 
233 
234 
235  /*******************************************************************\
236  * *
237  * unsigned short update_crc_dnp( unsigned short crc, char c ); *
238  * *
239  * The function update_crc_dnp calculates a new CRC-DNP value *
240  * based on the previous value of the CRC and the next byte *
241  * of the data to be checked. *
242  * *
243  \*******************************************************************/
244 
245 unsigned short update_crc_dnp( unsigned short crc, char c ) {
246 
247  unsigned short tmp, short_c;
248 
249  short_c = 0x00ff & (unsigned short) c;
250 
251  if ( ! crc_tabdnp_init ) init_crcdnp_tab();
252 
253  tmp = crc ^ short_c;
254  crc = (crc >> 8) ^ crc_tabdnp[ tmp & 0xff ];
255 
256  return crc;
257 
258 } /* update_crc_dnp */
259 
260 
261 
262  /*******************************************************************\
263  * *
264  * unsigned long update_crc_32( unsigned long crc, char c ); *
265  * *
266  * The function update_crc_32 calculates a new CRC-32 value *
267  * based on the previous value of the CRC and the next byte *
268  * of the data to be checked. *
269  * *
270  \*******************************************************************/
271 
272 unsigned long update_crc_32( unsigned long crc, char c ) {
273 
274  unsigned long tmp, long_c;
275 
276  long_c = 0x000000ffL & (unsigned long) c;
277 
278  if ( ! crc_tab32_init ) init_crc32_tab();
279 
280  tmp = crc ^ long_c;
281  crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
282 
283  return crc;
284 
285 } /* update_crc_32 */
286 
287 
288 
289  /*******************************************************************\
290  * *
291  * static void init_crc16_tab( void ); *
292  * *
293  * The function init_crc16_tab() is used to fill the array *
294  * for calculation of the CRC-16 with values. *
295  * *
296  \*******************************************************************/
297 
298 static void init_crc16_tab( void ) {
299 
300  int i, j;
301  unsigned short crc, c;
302 
303  for (i=0; i<256; i++) {
304 
305  crc = 0;
306  c = (unsigned short) i;
307 
308  for (j=0; j<8; j++) {
309 
310  if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_16;
311  else crc = crc >> 1;
312 
313  c = c >> 1;
314  }
315 
316  crc_tab16[i] = crc;
317  }
318 
320 
321 } /* init_crc16_tab */
322 
323 
324 
325  /*******************************************************************\
326  * *
327  * static void init_crckermit_tab( void ); *
328  * *
329  * The function init_crckermit_tab() is used to fill the array *
330  * for calculation of the CRC Kermit with values. *
331  * *
332  \*******************************************************************/
333 
334 static void init_crckermit_tab( void ) {
335 
336  int i, j;
337  unsigned short crc, c;
338 
339  for (i=0; i<256; i++) {
340 
341  crc = 0;
342  c = (unsigned short) i;
343 
344  for (j=0; j<8; j++) {
345 
346  if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_KERMIT;
347  else crc = crc >> 1;
348 
349  c = c >> 1;
350  }
351 
352  crc_tabkermit[i] = crc;
353  }
354 
356 
357 } /* init_crckermit_tab */
358 
359 
360 
361  /*******************************************************************\
362  * *
363  * static void init_crcdnp_tab( void ); *
364  * *
365  * The function init_crcdnp_tab() is used to fill the array *
366  * for calculation of the CRC-DNP with values. *
367  * *
368  \*******************************************************************/
369 
370 static void init_crcdnp_tab( void ) {
371 
372  int i, j;
373  unsigned short crc, c;
374 
375  for (i=0; i<256; i++) {
376 
377  crc = 0;
378  c = (unsigned short) i;
379 
380  for (j=0; j<8; j++) {
381 
382  if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_DNP;
383  else crc = crc >> 1;
384 
385  c = c >> 1;
386  }
387 
388  crc_tabdnp[i] = crc;
389  }
390 
392 
393 } /* init_crcdnp_tab */
394 
395 
396 
397  /*******************************************************************\
398  * *
399  * static void init_crc32_tab( void ); *
400  * *
401  * The function init_crc32_tab() is used to fill the array *
402  * for calculation of the CRC-32 with values. *
403  * *
404  \*******************************************************************/
405 
406 static void init_crc32_tab( void ) {
407 
408  int i, j;
409  unsigned long crc;
410 
411  for (i=0; i<256; i++) {
412 
413  crc = (unsigned long) i;
414 
415  for (j=0; j<8; j++) {
416 
417  if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
418  else crc = crc >> 1;
419  }
420 
421  crc_tab32[i] = crc;
422  }
423 
425 
426 } /* init_crc32_tab */
427 
428 
429 
430  /*******************************************************************\
431  * *
432  * static void init_crcccitt_tab( void ); *
433  * *
434  * The function init_crcccitt_tab() is used to fill the array *
435  * for calculation of the CRC-CCITT with values. *
436  * *
437  \*******************************************************************/
438 
439 static void init_crcccitt_tab( void ) {
440 
441  int i, j;
442  unsigned short crc, c;
443 
444  for (i=0; i<256; i++) {
445 
446  crc = 0;
447  c = (unsigned short)(((unsigned short) i) << 8);
448 
449  for (j=0; j<8; j++) {
450 
451  if ( (crc ^ c) & 0x8000 ) crc = (unsigned short)(( crc << 1 ) ^ P_CCITT);
452  else crc = (unsigned short)(crc << 1);
453 
454  c = (unsigned short)(c << 1);
455  }
456 
457  crc_tabccitt[i] = crc;
458  }
459 
461 
462 } /* init_crcccitt_tab */
static unsigned short crc_tab16[256]
Definition: lib_crc.c:97
unsigned short update_crc_dnp(unsigned short crc, char c)
Definition: lib_crc.c:245
#define P_32
Definition: lib_crc.c:66
static void init_crc32_tab(void)
Definition: lib_crc.c:406
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:160
#define CRC_FALSE
Definition: lib_crc.h:62
static unsigned short crc_tabkermit[256]
Definition: lib_crc.c:101
#define P_16
Definition: lib_crc.c:65
unsigned long update_crc_32(unsigned long crc, char c)
Definition: lib_crc.c:272
static unsigned long crc_tab32[256]
Definition: lib_crc.c:98
unsigned short update_crc_16(unsigned short crc, char c)
Definition: lib_crc.c:189
static int crc_tabdnp_init
Definition: lib_crc.c:94
static unsigned short crc_tabccitt[256]
Definition: lib_crc.c:99
static int crc_tab32_init
Definition: lib_crc.c:92
static void init_crc16_tab(void)
Definition: lib_crc.c:298
static void init_crckermit_tab(void)
Definition: lib_crc.c:334
static int crc_tabccitt_init
Definition: lib_crc.c:93
static unsigned short crc_tabdnp[256]
Definition: lib_crc.c:100
unsigned short update_crc_ccitt(unsigned short crc, char c)
Definition: lib_crc.c:132
static void init_crcdnp_tab(void)
Definition: lib_crc.c:370
static int crc_tabkermit_init
Definition: lib_crc.c:95
#define P_SICK
Definition: lib_crc.c:70
unsigned short update_crc_kermit(unsigned short crc, char c)
Definition: lib_crc.c:218
#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:439
#define P_CCITT
Definition: lib_crc.c:67