| 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_ */ |