Rev Author Line No. Line
3331 kaklik 1 ; ======================================================================
2 ; Calculate and append CRC
3 ;
3333 kaklik 4 ; There are two versions of the CRC16 calculation, selectable by the
5 ; USBTINY_FAST_CRC macro. The default implementation calculates one bit
6 ; at a time, and is compact but relatively slow. The "fast" version
7 ; processes 4 bits at a time, and is about twice as fast, but 42 bytes
8 ; larger.
3331 kaklik 9 ;
3333 kaklik 10 ; The fast version calculates 4 bits at a time, using a precomputed table
11 ; of 16 values. Each value is 16 bits, but only the 8 significant bits
12 ; are stored. The table should not cross a 256-byte page. The check.py
13 ; script will check for this. An 8 bit algoritm would be even faster,
3331 kaklik 14 ; but requires a lookup table of 512 bytes.
15 ;
3333 kaklik 16 ; Copyright 2006-2010 Dick Streefland
3331 kaklik 17 ;
18 ; This is free software, licensed under the terms of the GNU General
19 ; Public License as published by the Free Software Foundation.
20 ; ======================================================================
21  
22 #include "def.h"
23  
3333 kaklik 24 #if USBTINY_FAST_CRC
3331 kaklik 25 ; ----------------------------------------------------------------------
26 ; void crc(unsigned char *data, unsigned char len);
27 ; ----------------------------------------------------------------------
28 #define data r24
29 #define len r22
30  
31 #define b r18
32 #define tmp r19
33 #define zl r20
34 #define crc_l r24
35 #define crc_h r25
36  
37 .text
38 .global crc
39 .type crc, @function
40 crc:
41 ; crc = 0xffff
42 movw XL, r24
43 ldi crc_h, 0xff
44 ldi crc_l, 0xff
45 ldi zl, lo8(crc4tab)
46 ldi ZH, hi8(crc4tab)
3333 kaklik 47 rjmp entry
3331 kaklik 48  
3333 kaklik 49 next_byte:
50 ; crc ^= b
3331 kaklik 51 ld b, X+
3333 kaklik 52 eor crc_l, b
3331 kaklik 53  
3333 kaklik 54 ; index1 = crc & 0x0f
3331 kaklik 55 mov ZL, crc_l
56 andi ZL, 0x0f
57  
3333 kaklik 58 ; tmp = crc4tab[index1]
59 add ZL, zl
60 lpm tmp, Z+
61  
62 ; index2 = (crc >> 4)
63 mov ZL, crc_l
64 swap ZL
65  
66 ; crc >>= 8
67 mov crc_l, crc_h
68  
69 ; index2 = (index2 ^ tmp) & 0xf
70 mov crc_h, tmp
71 andi tmp, 1
72 eor ZL, tmp
73 andi ZL, 0x0f
74  
75 ; treat upper byte of CRC remainder
3331 kaklik 76 swap crc_h
77 mov tmp, crc_h
78 andi crc_h, 0x0f
3333 kaklik 79 andi tmp, 0xe0
80 eor crc_l, tmp
3331 kaklik 81  
82 ; crc ^= crc4tab[index]
83 add ZL, zl
84 lpm tmp, Z+
85 eor crc_h, tmp
86 andi tmp, 1
87 eor crc_h, tmp
88 eor crc_l, tmp
89  
3333 kaklik 90 entry:
91 ; next byte
3331 kaklik 92 dec len
3333 kaklik 93 brpl next_byte
3331 kaklik 94  
95 done:
96 ; crc ^= 0xffff
97 com crc_l
98 com crc_h
99  
100 ; append crc to buffer
101 st X+, crc_l
102 st X+, crc_h
103  
104 ret
105  
106 ; ----------------------------------------------------------------------
107 ; CRC table. As bits 1..8 are always zero, omit them.
108 ; ----------------------------------------------------------------------
109 .section .progmem.crc,"a",@progbits
3333 kaklik 110 ;;; .align 4 ; crude way to avoid crossing a page boundary
3331 kaklik 111 crc4tab:
112 .byte 0x00+0x00
113 .byte 0xcc+0x01
114 .byte 0xd8+0x01
115 .byte 0x14+0x00
116 .byte 0xf0+0x01
117 .byte 0x3c+0x00
118 .byte 0x28+0x00
119 .byte 0xe4+0x01
120 .byte 0xa0+0x01
121 .byte 0x6c+0x00
122 .byte 0x78+0x00
123 .byte 0xb4+0x01
124 .byte 0x50+0x00
125 .byte 0x9c+0x01
126 .byte 0x88+0x01
127 .byte 0x44+0x00
128 /* ---------------------------------------------------------------------- *\
129 #!/usr/bin/python
130 for crc in range(16):
131 for bit in range(4):
132 xor = crc & 1
133 crc >>= 1
134 if xor:
135 crc ^= 0xA001 # X^16 + X^15 + X^2 + 1 (reversed)
136 print "\t.byte\t0x%02x+0x%02x" % (crc >> 8, crc & 0xff)
137 \* ---------------------------------------------------------------------- */
3333 kaklik 138 #else
139 ; ----------------------------------------------------------------------
140 ; void crc(unsigned char *data, unsigned char len);
141 ; ----------------------------------------------------------------------
142 #define data r24
143 #define len r22
144  
145 #define b r18
146 #define con_01 r19
147 #define con_a0 r20
148 #define crc_l r24
149 #define crc_h r25
150  
151 .text
152 .global crc
153 .type crc, @function
154 crc:
155 movw XL, r24
156 ldi crc_h, 0xff
157 ldi crc_l, 0xff
158 tst len
159 breq done1
160 ldi con_a0, 0xa0
161 ldi con_01, 0x01
162 next_byte:
163 ld b, X+
164 eor crc_l, b
165 ldi b, 8
166 next_bit:
167 lsr crc_h
168 ror crc_l
169 brcc noxor
170 eor crc_h, con_a0
171 eor crc_l, con_01
172 noxor:
173 dec b
174 brne next_bit
175 dec len
176 brne next_byte
177 done1:
178 com crc_l
179 com crc_h
180 st X+, crc_l
181 st X+, crc_h
182 ret
183 #endif