1 |
/* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz |
/* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz |
2 |
|
Copyright (c) 2005, Joerg Wunsch |
3 |
All rights reserved. |
All rights reserved. |
4 |
|
|
5 |
Redistribution and use in source and binary forms, with or without |
Redistribution and use in source and binary forms, with or without |
34 |
#ifndef _UTIL_CRC16_H_ |
#ifndef _UTIL_CRC16_H_ |
35 |
#define _UTIL_CRC16_H_ |
#define _UTIL_CRC16_H_ |
36 |
|
|
37 |
#include <inttypes.h> |
#include <stdint.h> |
38 |
|
|
39 |
/** \defgroup util_crc <util/crc16.h>: CRC Computations |
/** \defgroup util_crc <util/crc16.h>: CRC Computations |
40 |
\code#include <util/crc16.h>\endcode |
\code#include <util/crc16.h>\endcode |
41 |
|
|
42 |
This header file provides a optimized inline functions for calculating 16 |
This header file provides a optimized inline functions for calculating |
43 |
bit cyclic redundancy checks (CRC) using common polynomials. |
cyclic redundancy checks (CRC) using common polynomials. |
44 |
|
|
45 |
\par References: |
\par References: |
46 |
|
|
55 |
Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e |
Jack Crenshaw's "Implementing CRCs" article in the January 1992 isue of \e |
56 |
Embedded \e Systems \e Programming. This may be difficult to find, but it |
Embedded \e Systems \e Programming. This may be difficult to find, but it |
57 |
explains CRC's in very clear and concise terms. Well worth the effort to |
explains CRC's in very clear and concise terms. Well worth the effort to |
58 |
obtain a copy. */ |
obtain a copy. |
59 |
|
|
60 |
|
A typical application would look like: |
61 |
|
|
62 |
|
\code |
63 |
|
// Dallas iButton test vector. |
64 |
|
uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 }; |
65 |
|
|
66 |
|
int |
67 |
|
checkcrc(void) |
68 |
|
{ |
69 |
|
uint8_t crc = 0, i; |
70 |
|
|
71 |
|
for (i = 0; i < sizeof serno / sizeof serno[0]; i++) |
72 |
|
crc = _crc_ibutton_update(crc, serno[i]); |
73 |
|
|
74 |
|
return crc; // must be 0 |
75 |
|
} |
76 |
|
\endcode |
77 |
|
*/ |
78 |
|
|
79 |
/** \ingroup util_crc |
/** \ingroup util_crc |
80 |
Optimized CRC-16 calcutation. |
Optimized CRC-16 calculation. |
81 |
|
|
82 |
Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)<br> |
Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)<br> |
83 |
Initial value: 0xffff |
Initial value: 0xffff |
261 |
return __ret; |
return __ret; |
262 |
} |
} |
263 |
|
|
264 |
|
/** \ingroup util_crc |
265 |
|
Optimized Dallas (now Maxim) iButton 8-bit CRC calculation. |
266 |
|
|
267 |
|
Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)<br> |
268 |
|
Initial value: 0x0 |
269 |
|
|
270 |
|
See http://www.maxim-ic.com/appnotes.cfm/appnote_number/27 |
271 |
|
|
272 |
|
The following is the equivalent functionality written in C. |
273 |
|
|
274 |
|
\code |
275 |
|
uint8_t |
276 |
|
_crc_ibutton_update(uint8_t crc, uint8_t data) |
277 |
|
{ |
278 |
|
uint8_t i; |
279 |
|
|
280 |
|
crc = crc ^ data; |
281 |
|
for (i = 0; i < 8; i++) |
282 |
|
{ |
283 |
|
if (crc & 0x01) |
284 |
|
crc = (crc >> 1) ^ 0x8C; |
285 |
|
else |
286 |
|
crc >>= 1; |
287 |
|
} |
288 |
|
|
289 |
|
return crc; |
290 |
|
} |
291 |
|
\endcode |
292 |
|
*/ |
293 |
|
|
294 |
|
static __inline__ uint8_t |
295 |
|
_crc_ibutton_update(uint8_t __crc, uint8_t __data) |
296 |
|
{ |
297 |
|
uint8_t __i, __pattern; |
298 |
|
__asm__ __volatile__ ( |
299 |
|
" eor %0, %4" "\n\t" |
300 |
|
" ldi %1, 8" "\n\t" |
301 |
|
" ldi %2, 0x8C" "\n\t" |
302 |
|
"1: bst %0, 0" "\n\t" |
303 |
|
" lsr %0" "\n\t" |
304 |
|
" brtc 2f" "\n\t" |
305 |
|
" eor %0, %2" "\n\t" |
306 |
|
"2: dec %1" "\n\t" |
307 |
|
" brne 1b" "\n\t" |
308 |
|
: "=r" (__crc), "=d" (__i), "=d" (__pattern) |
309 |
|
: "0" (__crc), "r" (__data)); |
310 |
|
return __crc; |
311 |
|
} |
312 |
|
|
313 |
#endif /* _UTIL_CRC16_H_ */ |
#endif /* _UTIL_CRC16_H_ */ |