/* A fast CRC16 algorithm, serial progessing */ #include // CRC definitions CRC_POLYNOM = 0xA001 CRC_INIT = 0xFFFF // register name assignment zero = 1 next = 19 crc_l = 20 crc_h = 21 data_cnt = 22 ; 22-25, mixed order! polynom_l = 26 polynom_h = 27 data_ptr = 30 ; Z .macro crc_bit ror next ror crc_h ror crc_l brcc no_xor\@ eor crc_l, polynom_l eor crc_h, polynom_h no_xor\@: .endm .text .global calculate_crc /* uint16_t calculate_crc(uint32_t app_end); registers r23 r22 r25 r24 */ calculate_crc: ldi crc_l, lo8(CRC_INIT) ldi crc_h, hi8(CRC_INIT) ldi polynom_l, lo8(CRC_POLYNOM) ldi polynom_h, hi8(CRC_POLYNOM) sts RAMPZ, zero ldi data_ptr, 0 ; 24 bit data pointer ldi data_ptr+1, 0 crc_loop: elpm next, Z+ ; 3 cycles crc_bit ; 6*8 cycles crc_bit crc_bit crc_bit crc_bit crc_bit crc_bit crc_bit subi r24, 1 ; -1, 24 bit sbc r25, zero sbc r22, zero brne crc_loop ; 56 cycles / byte mov r24, crc_l ; return CRC mov r25, crc_h ret