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" );