Years ago I found this assembly implementation of CRC-16 and have been using it for eeprom memory verification:
//============================================================================= // Copyright Atmel Corporation 2003. All Rights Reserved. // // File: crc.asm // Compiler: IAR Atmel AVR Assembler // Output Size: // Created: 20-Feb-2003 JP (Atmel Finland) // Modified: // // Support Mail: avr@atmel.com // // Description: CRC calculation routine // // Other Info: //============================================================================= //============================================================================= // Polynome used in CRC calculations #define CRC_POLYNOME 0x8005 //0x1021 //============================================================================= PUBLIC CRC RSEG CODE //============================================================================= // CRC calculation routine CRC: ldi r20, 0x08 ldi r21, LOW(CRC_POLYNOME) ldi r22, HIGH(CRC_POLYNOME) CRC_Loop: ; Rotate left. If MSb is 1 -> divide with Generator-polynome. lsl r18 rol r16 rol r17 brcc CRC_SkipEor eor r16, r21 eor r17, r22 CRC_SkipEor: dec r20 brne CRC_Loop ret //============================================================================= END
The header file contains this:
extern CPU_INT16U CRC(CPU_INT16U crc, CPU_INT08U ch);
The CRC is used like this:
CPU_INT08U TestBuffer[10u] = {0x31u,0x32u,0x33u,0x34u,0x35u,0x36u,0x37u,0x38u,0x39u}; // test sequence of "123456789" static CPU_INT16U crc_test(void) { CPU_INT16U crc = 0u; for (CPU_INT16U ii=0u; ii < 9u; ii++) { crc = CRC(crc, TestBuffer[ii]); } return crc; }
In the above example, the computed result is 0xD52E. However, my other two implementations (one in c# and one on a Renesas RX62N) yield a result of 0xBB3D. This is the expected result according to Michael Barr's article - near the end there is a table of expected results for an input of "123456789". Can anyone see an error in the above assembly? Or provide me with known working assembly for a CRC16 implementation?