/* A fast CRC16 algorithm optimized for polynom 0xA001, CRC init 0xFFFF */ #include #include "main.h" // register name assignment zero = 1 max_l = 18 max_h = 19 max_hlo = 20 crc_l = 22 crc_h = 23 next = 24 data_ptr = 30 ; Z + RAMPZ .text .global calculate_crc_asm /* uint16_t calculate_crc_asm(); registers */ calculate_crc_asm: push r0 ldi max_l, lo8(APP_END_ADR); ldi max_h, hi8(APP_END_ADR); ldi max_hlo, hlo8(APP_END_ADR); sts RAMPZ, zero ; 24 bit data pointer mov data_ptr, zero mov data_ptr+1, zero ldi crc_l, 0xFF ldi crc_h, 0xFF crc_loop: elpm next, Z+ ; 3 cycles ; magic CRC calculation, optimized to polynom 0xA001 eor r22, r24 mov r24, r22 swap r24 eor r24, r22 mov r0, r24 lsr r24 lsr r24 eor r24, r0 mov r0, r24 lsr r24 eor r24, r0 andi r24, 0x07 mov r0, r22 mov r22, r23 lsr r24 ror r0 ror r24 mov r23, r0 eor r22, r24 lsr r0 ror r24 eor r23, r0 eor r22, r24 cp data_ptr, max_l cpc data_ptr+1, max_h lds next, RAMPZ cpc next, max_hlo brne crc_loop ; 33 cycles / byte mov r24, crc_l ; return CRC mov r25, crc_h pop r0 ret