; ======================================================================; Calculate and append CRC;; There are two versions of the CRC16 calculation, selectable by the; USBTINY_FAST_CRC macro. The default implementation calculates one bit; at a time, and is compact but relatively slow. The "fast" version; processes 4 bits at a time, and is about twice as fast, but 42 bytes; larger.;; The fast version calculates 4 bits at a time, using a precomputed table; of 16 values. Each value is 16 bits, but only the 8 significant bits; are stored. The table should not cross a 256-byte page. The check.py; script will check for this. An 8 bit algoritm would be even faster,; but requires a lookup table of 512 bytes.;; Copyright 2006-2010 Dick Streefland;; This is free software, licensed under the terms of the GNU General; Public License as published by the Free Software Foundation.; ======================================================================#include "def.h"#if USBTINY_FAST_CRC; ----------------------------------------------------------------------; void crc(unsigned char *data, unsigned char len);; ----------------------------------------------------------------------#define data r24#define len r22#define b r18#define tmp r19#define zl r20#define crc_l r24#define crc_h r25.text.global crc.type crc, @functioncrc:; crc = 0xffffmovw XL, r24ldi crc_h, 0xffldi crc_l, 0xffldi zl, lo8(crc4tab)ldi ZH, hi8(crc4tab)rjmp entrynext_byte:; crc ^= bld b, X+eor crc_l, b; index1 = crc & 0x0fmov ZL, crc_landi ZL, 0x0f; tmp = crc4tab[index1]add ZL, zllpm tmp, Z+; index2 = (crc >> 4)mov ZL, crc_lswap ZL; crc >>= 8mov crc_l, crc_h; index2 = (index2 ^ tmp) & 0xfmov crc_h, tmpandi tmp, 1eor ZL, tmpandi ZL, 0x0f; treat upper byte of CRC remainderswap crc_hmov tmp, crc_handi crc_h, 0x0fandi tmp, 0xe0eor crc_l, tmp; crc ^= crc4tab[index]add ZL, zllpm tmp, Z+eor crc_h, tmpandi tmp, 1eor crc_h, tmpeor crc_l, tmpentry:; next bytedec lenbrpl next_bytedone:; crc ^= 0xffffcom crc_lcom crc_h; append crc to bufferst X+, crc_lst X+, crc_hret; ----------------------------------------------------------------------; CRC table. As bits 1..8 are always zero, omit them.; ----------------------------------------------------------------------.section .progmem.crc,"a",@progbits;;; .align 4 ; crude way to avoid crossing a page boundarycrc4tab:.byte 0x00+0x00.byte 0xcc+0x01.byte 0xd8+0x01.byte 0x14+0x00.byte 0xf0+0x01.byte 0x3c+0x00.byte 0x28+0x00.byte 0xe4+0x01.byte 0xa0+0x01.byte 0x6c+0x00.byte 0x78+0x00.byte 0xb4+0x01.byte 0x50+0x00.byte 0x9c+0x01.byte 0x88+0x01.byte 0x44+0x00/* ---------------------------------------------------------------------- *\#!/usr/bin/pythonfor crc in range(16):for bit in range(4):xor = crc & 1crc >>= 1if xor:crc ^= 0xA001 # X^16 + X^15 + X^2 + 1 (reversed)print "\t.byte\t0x%02x+0x%02x" % (crc >> 8, crc & 0xff)\* ---------------------------------------------------------------------- */#else; ----------------------------------------------------------------------; void crc(unsigned char *data, unsigned char len);; ----------------------------------------------------------------------#define data r24#define len r22#define b r18#define con_01 r19#define con_a0 r20#define crc_l r24#define crc_h r25.text.global crc.type crc, @functioncrc:movw XL, r24ldi crc_h, 0xffldi crc_l, 0xfftst lenbreq done1ldi con_a0, 0xa0ldi con_01, 0x01next_byte:ld b, X+eor crc_l, bldi b, 8next_bit:lsr crc_hror crc_lbrcc noxoreor crc_h, con_a0eor crc_l, con_01noxor:dec bbrne next_bitdec lenbrne next_bytedone1:com crc_lcom crc_hst X+, crc_lst X+, crc_hret#endif