F´ Flight Software - C/C++ Documentation NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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
96static unsigned short crc_tab16[256];
97static unsigned long crc_tab32[256];
98static unsigned short crc_tabccitt[256];
99static unsigned short crc_tabdnp[256];
100static 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
113static void init_crc16_tab( void );
114static void init_crc32_tab( void );
115static void init_crcccitt_tab( void );
116static void init_crcdnp_tab( void );
117static 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
131unsigned 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
159unsigned 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
188unsigned 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
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
215unsigned 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
242unsigned 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
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
269unsigned 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
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
295static 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
331static 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
367static 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
403static 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
436static 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 */
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:215
static void init_crcdnp_tab(void)
Definition lib_crc.c:367
static void init_crc32_tab(void)
Definition lib_crc.c:403
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:269
static void init_crcccitt_tab(void)
Definition lib_crc.c:436
unsigned short update_crc_dnp(unsigned short crc, char c)
Definition lib_crc.c:242
#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:295
static int crc_tab16_init
Definition lib_crc.c:90
static void init_crckermit_tab(void)
Definition lib_crc.c:331
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:58
#define CRC_TRUE
Definition lib_crc.h:59