2003-11-18 Theodore A. Roth
* include/avr/crc16.h (_crc16_update): Add line break to dox.
(_crc_xmodem_update): Ditto.
* include/avr/crc16.h (_crc_ccitt_update): New function.
[Submitted by Tomas Vanek ]
Index: include/avr/crc16.h
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/include/avr/crc16.h,v
retrieving revision 1.4
diff -u -p -r1.4 crc16.h
--- include/avr/crc16.h 11 Nov 2003 18:49:59 -0000 1.4
+++ include/avr/crc16.h 18 Nov 2003 18:41:42 -0000
@@ -54,7 +54,7 @@
/** \ingroup avr_crc
Optimized CRC-16 calcutation.
- Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
+ Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
Initial value: 0xffff
This CRC is normally used in disk-drive controllers. */
@@ -99,7 +99,7 @@ _crc16_update(uint16_t __crc, uint8_t __
/** \ingroup avr_crc
Optimized CRC-XMODEM calculation.
- Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
+ Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
Initial value: 0x0
This is the CRC used by the Xmodem-CRC protocol.
@@ -164,6 +164,72 @@ _crc_xmodem_update(uint16_t __crc, uint8
"eor %B0,%A0" "\n\t" /* ret.hi is now ready. */
"mov %A0,%1" "\n\t" /* ret.lo is now ready. */
: "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2)
+ : "r" (__data), "0" (__crc)
+ : "r0"
+ );
+ return __ret;
+}
+
+/** \ingroup avr_crc
+ Optimized CRC-CCITT calculation.
+
+ Polynomial: x^16 + x^12 + x^5 + 1 (0x8408)
+ Initial value: 0xffff
+
+ This is the CRC used by PPP and IrDA.
+
+ See RFC1171 (PPP protocol) and IrDA IrLAP 1.1
+
+ \note Although the CCITT polynomial is the same as that used by the Xmodem
+ protocol, they are quite different. The difference is in how the bits are
+ shifted through the alorgithm. Xmodem shifts the MSB of the CRC and the
+ input first, while CCITT shifts the LSB of the CRC and the input first.
+
+ The following is the equivalent functionality written in C.
+
+ \code
+ uint16_t
+ crc_ccitt_update (uint16_t crc, uint8_t data)
+ {
+ data ^= lo8 (crc);
+ data ^= data << 4;
+
+ return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4)
+ ^ ((uint16_t)data << 3));
+ }
+ \endcode */
+
+static inline uint16_t
+_crc_ccitt_update (uint16_t __crc, uint8_t __data)
+{
+ uint16_t __ret;
+
+ __asm__ (
+ "eor %A0,%1" "\n\t"
+
+ "mov __tmp_reg__,%A0" "\n\t"
+ "swap %A0" "\n\t"
+ "andi %A0,0xf0" "\n\t"
+ "eor %A0,__tmp_reg__" "\n\t"
+
+ "mov __tmp_reg__,%B0" "\n\t"
+
+ "mov %B0,%A0" "\n\t"
+
+ "swap %A0" "\n\t"
+ "andi %A0,0x0f" "\n\t"
+ "eor __tmp_reg__,%A0" "\n\t"
+
+ "lsr %A0" "\n\t"
+ "eor %B0,%A0" "\n\t"
+
+ "eor %A0,%B0" "\n\t"
+ "lsl %A0" "\n\t"
+ "lsl %A0" "\n\t"
+ "lsl %A0" "\n\t"
+ "eor %A0,__tmp_reg__"
+
+ : "=d" (__ret)
: "r" (__data), "0" (__crc)
: "r0"
);