F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 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 
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  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 
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 
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 
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 
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 
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)(((unsigned short) i) << 8);
445 
446  for (j=0; j<8; j++) {
447 
448  if ( (crc ^ c) & 0x8000 ) crc = (unsigned short)(( crc << 1 ) ^ P_CCITT);
449  else crc = (unsigned short)(crc << 1);
450 
451  c = (unsigned short)(c << 1);
452  }
453 
454  crc_tabccitt[i] = crc;
455  }
456 
458 
459 } /* init_crcccitt_tab */
init_crckermit_tab
static void init_crckermit_tab(void)
Definition: lib_crc.c:331
P_SICK
#define P_SICK
Definition: lib_crc.c:69
crc_tabccitt_init
static int crc_tabccitt_init
Definition: lib_crc.c:92
crc_tabkermit_init
static int crc_tabkermit_init
Definition: lib_crc.c:94
init_crcdnp_tab
static void init_crcdnp_tab(void)
Definition: lib_crc.c:367
update_crc_sick
unsigned short update_crc_sick(unsigned short crc, char c, char prev_byte)
Definition: lib_crc.c:159
crc_tabccitt
static unsigned short crc_tabccitt[256]
Definition: lib_crc.c:98
crc_tab16_init
static int crc_tab16_init
Definition: lib_crc.c:90
CRC_TRUE
#define CRC_TRUE
Definition: lib_crc.h:59
P_32
#define P_32
Definition: lib_crc.c:65
init_crcccitt_tab
static void init_crcccitt_tab(void)
Definition: lib_crc.c:436
crc_tab32
static unsigned long crc_tab32[256]
Definition: lib_crc.c:97
crc_tab32_init
static int crc_tab32_init
Definition: lib_crc.c:91
update_crc_16
unsigned short update_crc_16(unsigned short crc, char c)
Definition: lib_crc.c:188
crc_tabdnp
static unsigned short crc_tabdnp[256]
Definition: lib_crc.c:99
init_crc32_tab
static void init_crc32_tab(void)
Definition: lib_crc.c:403
P_DNP
#define P_DNP
Definition: lib_crc.c:67
CRC_FALSE
#define CRC_FALSE
Definition: lib_crc.h:58
update_crc_kermit
unsigned short update_crc_kermit(unsigned short crc, char c)
Definition: lib_crc.c:215
crc_tabdnp_init
static int crc_tabdnp_init
Definition: lib_crc.c:93
P_CCITT
#define P_CCITT
Definition: lib_crc.c:66
P_16
#define P_16
Definition: lib_crc.c:64
update_crc_ccitt
unsigned short update_crc_ccitt(unsigned short crc, char c)
Definition: lib_crc.c:131
lib_crc.h
init_crc16_tab
static void init_crc16_tab(void)
Definition: lib_crc.c:295
update_crc_dnp
unsigned short update_crc_dnp(unsigned short crc, char c)
Definition: lib_crc.c:242
crc_tabkermit
static unsigned short crc_tabkermit[256]
Definition: lib_crc.c:100
P_KERMIT
#define P_KERMIT
Definition: lib_crc.c:68
update_crc_32
unsigned long update_crc_32(unsigned long crc, char c)
Definition: lib_crc.c:269
crc_tab16
static unsigned short crc_tab16[256]
Definition: lib_crc.c:96