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