Rev Author Line No. Line
3331 kaklik 1 ; ======================================================================
2 ; Calculate and append CRC
3 ;
4 ; The CRC is calculated 4 bits at a time, using a precomputed table of
5 ; 16 values. Each value is 16 bits, but only the 8 significant bits are
6 ; stored. The table should not cross a 256-byte page. The check.py script
7 ; will check for this.
8 ;
9 ; A bitwise algorithm would be a little smaller, but takes more time.
10 ; In fact, it takes too much time for the USB controller in my laptop.
11 ; The poll frequently is so high, that a lot of time is spent in the
12 ; interrupt handler, sending NAK packets, leaving little time for the
13 ; actual checksum calculation. An 8 bit algoritm would be even faster,
14 ; but requires a lookup table of 512 bytes.
15 ;
16 ; Copyright (C) 2006 Dick Streefland
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  
24 ; ----------------------------------------------------------------------
25 ; void crc(unsigned char *data, unsigned char len);
26 ; ----------------------------------------------------------------------
27 #define data r24
28 #define len r22
29  
30 #define b r18
31 #define tmp r19
32 #define zl r20
33 #define crc_l r24
34 #define crc_h r25
35  
36 .text
37 .global crc
38 .type crc, @function
39 crc:
40 ; crc = 0xffff
41 movw XL, r24
42 ldi crc_h, 0xff
43 ldi crc_l, 0xff
44 lsl len
45 breq done
46 ldi zl, lo8(crc4tab)
47 ldi ZH, hi8(crc4tab)
48  
49 next_nibble:
50 ; b = (len & 1 ? b >> 4 : *data++)
51 swap b
52 sbrs len, 0
53 ld b, X+
54  
55 ; index = (crc ^ b) & 0x0f
56 mov ZL, crc_l
57 eor ZL, b
58 andi ZL, 0x0f
59  
60 ; crc >>= 4
61 swap crc_h
62 swap crc_l
63 andi crc_l, 0x0f
64 mov tmp, crc_h
65 andi tmp, 0xf0
66 or crc_l, tmp
67 andi crc_h, 0x0f
68  
69 ; crc ^= crc4tab[index]
70 add ZL, zl
71 lpm tmp, Z+
72 eor crc_h, tmp
73 andi tmp, 1
74 eor crc_h, tmp
75 eor crc_l, tmp
76  
77 ; next nibble
78 dec len
79 brne next_nibble
80  
81 done:
82 ; crc ^= 0xffff
83 com crc_l
84 com crc_h
85  
86 ; append crc to buffer
87 st X+, crc_l
88 st X+, crc_h
89  
90 ret
91  
92 ; ----------------------------------------------------------------------
93 ; CRC table. As bits 1..8 are always zero, omit them.
94 ; ----------------------------------------------------------------------
95 .section .progmem.crc,"a",@progbits
96 ;;; .align 4 ; avoid crossing a page boundary
97 crc4tab:
98 .byte 0x00+0x00
99 .byte 0xcc+0x01
100 .byte 0xd8+0x01
101 .byte 0x14+0x00
102 .byte 0xf0+0x01
103 .byte 0x3c+0x00
104 .byte 0x28+0x00
105 .byte 0xe4+0x01
106 .byte 0xa0+0x01
107 .byte 0x6c+0x00
108 .byte 0x78+0x00
109 .byte 0xb4+0x01
110 .byte 0x50+0x00
111 .byte 0x9c+0x01
112 .byte 0x88+0x01
113 .byte 0x44+0x00
114 /* ---------------------------------------------------------------------- *\
115 #!/usr/bin/python
116 for crc in range(16):
117 for bit in range(4):
118 xor = crc & 1
119 crc >>= 1
120 if xor:
121 crc ^= 0xA001 # X^16 + X^15 + X^2 + 1 (reversed)
122 print "\t.byte\t0x%02x+0x%02x" % (crc >> 8, crc & 0xff)
123 \* ---------------------------------------------------------------------- */