Rev 3331 Rev 3332
1 ; ====================================================================== 1 ; ======================================================================
2 ; USB interrupt handler 2 ; USB interrupt handler
3 ; 3 ;
4 ; This is the handler for the interrupt caused by the initial rising edge 4 ; This is the handler for the interrupt caused by the initial rising edge
5 ; on the D+ USB signal. The NRZI encoding and bit stuffing are removed, 5 ; on the D+ USB signal. The NRZI encoding and bit stuffing are removed,
6 ; and the packet is saved in one of the two input buffers. In some cases, 6 ; and the packet is saved in one of the two input buffers. In some cases,
7 ; a reply packet is sent right away. 7 ; a reply packet is sent right away.
8 ; 8 ;
9 ; When a DATA0/DATA1 packet directly follows a SETUP or OUT packet, while 9 ; When a DATA0/DATA1 packet directly follows a SETUP or OUT packet, while
10 ; this interrupt handler is not yet finished, there would be no time to 10 ; this interrupt handler is not yet finished, there would be no time to
11 ; return and take another interrupt. In that case, the second packet is 11 ; return and take another interrupt. In that case, the second packet is
12 ; decoded directly in the same invocation. 12 ; decoded directly in the same invocation.
13 ; 13 ;
14 ; This code is *extremely* time critical. For instance, there is not a 14 ; This code is *extremely* time critical. For instance, there is not a
15 ; single spare cycle in the receiver loop, and only two in the transmitter 15 ; single spare cycle in the receiver loop, and only two in the transmitter
16 ; loop. In addition, the various code paths are laid out in such a way that 16 ; loop. In addition, the various code paths are laid out in such a way that
17 ; the various USB timeouts are not violated, in particular the maximum time 17 ; the various USB timeouts are not violated, in particular the maximum time
18 ; between the reception of a packet and the reply, which is 6.5 bit times 18 ; between the reception of a packet and the reply, which is 6.5 bit times
19 ; for a detachable cable (TRSPIPD1), and 7.5 bit times for a captive cable 19 ; for a detachable cable (TRSPIPD1), and 7.5 bit times for a captive cable
20 ; (TRSPIPD2). The worst-case delay here is 51 cycles, which is just below 20 ; (TRSPIPD2). The worst-case delay here is 51 cycles, which is just below
21 ; the 52 cycles for a detachable cable. 21 ; the 52 cycles for a detachable cable.
22 ; 22 ;
23 ; The interrupt handler must be reached within 34 cycles after D+ goes high 23 ; The interrupt handler must be reached within 34 cycles after D+ goes high
24 ; for the first time, so the interrupts should not be disabled for longer 24 ; for the first time, so the interrupts should not be disabled for longer
25 ; than 34-4-2=28 cycles. 25 ; than 34-4-2=28 cycles.
26 ; 26 ;
27 ; The end-of-packet (EOP) is sampled in the second bit, because the USB 27 ; The end-of-packet (EOP) is sampled in the second bit, because the USB
28 ; standard allows the EOP to be delayed by up to one bit. As the EOP 28 ; standard allows the EOP to be delayed by up to one bit. As the EOP
29 ; duration is two bits, this is not a problem. 29 ; duration is two bits, this is not a problem.
30 ; 30 ;
31 ; Stack usage including the return address: 11 bytes. 31 ; Stack usage including the return address: 11 bytes.
32 ; 32 ;
33 ; Copyright (C) 2006 Dick Streefland 33 ; Copyright (C) 2006 Dick Streefland
34 ; 34 ;
35 ; This is free software, licensed under the terms of the GNU General 35 ; This is free software, licensed under the terms of the GNU General
36 ; Public License as published by the Free Software Foundation. 36 ; Public License as published by the Free Software Foundation.
37 ; ====================================================================== 37 ; ======================================================================
38   38  
39 #include "def.h" 39 #include "def.h"
40   40  
41 ; ---------------------------------------------------------------------- 41 ; ----------------------------------------------------------------------
42 ; local data 42 ; local data
43 ; ---------------------------------------------------------------------- 43 ; ----------------------------------------------------------------------
44 .data 44 .data
45 tx_ack: .byte USB_PID_ACK ; ACK packet 45 tx_ack: .byte USB_PID_ACK ; ACK packet
46 tx_nak: .byte USB_PID_NAK ; NAK packet 46 tx_nak: .byte USB_PID_NAK ; NAK packet
47 .lcomm token_pid, 1 ; PID of most recent token packet 47 .lcomm token_pid, 1 ; PID of most recent token packet
48   48  
49 ; ---------------------------------------------------------------------- 49 ; ----------------------------------------------------------------------
50 ; register definitions 50 ; register definitions
51 ; ---------------------------------------------------------------------- 51 ; ----------------------------------------------------------------------
52 // receiver: 52 // receiver:
53 #define count r16 53 #define count r16
54 #define usbmask r17 54 #define usbmask r17
55 #define odd r18 55 #define odd r18
56 #define byte r19 56 #define byte r19
57 #define fixup r20 57 #define fixup r20
58 #define even r22 58 #define even r22
59   59  
60 // transmitter: 60 // transmitter:
61 #define output odd 61 #define output odd
62 #define done fixup 62 #define done fixup
63 #define next even 63 #define next even
64   64  
65 // control: 65 // control:
66 #define pid odd 66 #define pid odd
67 #define addr usbmask 67 #define addr usbmask
68 #define tmp fixup 68 #define tmp fixup
69   69  
70 #define nop2 rjmp .+0 // not .+2 for some strange reason 70 #define nop2 rjmp .+0 // not .+2 for some strange reason
71   71  
72 ; ---------------------------------------------------------------------- 72 ; ----------------------------------------------------------------------
73 ; interrupt handler 73 ; interrupt handler
74 ; ---------------------------------------------------------------------- 74 ; ----------------------------------------------------------------------
75 .text 75 .text
76 .global USB_INT_VECTOR 76 .global USB_INT_VECTOR
77 .type USB_INT_VECTOR, @function 77 .type USB_INT_VECTOR, @function
78 ; ---------------------------------------------------------------------- 78 ; ----------------------------------------------------------------------
79 ; This handler must be reached no later than 34 cycles after D+ goes high 79 ; This handler must be reached no later than 34 cycles after D+ goes high
80 ; for the first time. 80 ; for the first time.
81 ; ---------------------------------------------------------------------- 81 ; ----------------------------------------------------------------------
82 USB_INT_VECTOR: 82 USB_INT_VECTOR:
83 ; save registers 83 ; save registers
84 push count 84 push count
85 push usbmask 85 push usbmask
86 push odd 86 push odd
87 push YH 87 push YH
88 push YL 88 push YL
89 in count, SREG 89 in count, SREG
90 push count 90 push count
91   91  
92 ; ---------------------------------------------------------------------- 92 ; ----------------------------------------------------------------------
93 ; Synchronize to the pattern 10101011 on D+. This code must be reached 93 ; Synchronize to the pattern 10101011 on D+. This code must be reached
94 ; no later than 47 cycles after D+ goes high for the first time. 94 ; no later than 47 cycles after D+ goes high for the first time.
95 ; ---------------------------------------------------------------------- 95 ; ----------------------------------------------------------------------
96 sync: 96 sync:
97 ; wait until D+ == 0 97 ; wait until D+ == 0
98 sbic USB_IN, USBTINY_DPLUS 98 sbic USB_IN, USBTINY_DPLUS
99 rjmp sync ; jump if D+ == 1 99 rjmp sync ; jump if D+ == 1
100 resync: 100 resync:
101 ; sync on 0-->1 transition on D+ with a 2 cycle resolution 101 ; sync on 0-->1 transition on D+ with a 2 cycle resolution
102 sbic USB_IN, USBTINY_DPLUS 102 sbic USB_IN, USBTINY_DPLUS
103 rjmp sync6 ; jump if D+ == 1 103 rjmp sync6 ; jump if D+ == 1
104 sbic USB_IN, USBTINY_DPLUS 104 sbic USB_IN, USBTINY_DPLUS
105 rjmp sync6 ; jump if D+ == 1 105 rjmp sync6 ; jump if D+ == 1
106 sbic USB_IN, USBTINY_DPLUS 106 sbic USB_IN, USBTINY_DPLUS
107 rjmp sync6 ; jump if D+ == 1 107 rjmp sync6 ; jump if D+ == 1
108 sbic USB_IN, USBTINY_DPLUS 108 sbic USB_IN, USBTINY_DPLUS
109 rjmp sync6 ; jump if D+ == 1 109 rjmp sync6 ; jump if D+ == 1
110 sbic USB_IN, USBTINY_DPLUS 110 sbic USB_IN, USBTINY_DPLUS
111 rjmp sync6 ; jump if D+ == 1 111 rjmp sync6 ; jump if D+ == 1
112 ldi count, 1<<USB_INT_PENDING_BIT 112 ldi count, 1<<USB_INT_PENDING_BIT
113 out USB_INT_PENDING, count 113 out USB_INT_PENDING, count
114 rjmp return ; ==> false start, bail out 114 rjmp return ; ==> false start, bail out
115   115  
116 sync6: 116 sync6:
117 ; we are now between -1 and +1 cycle from the center of the bit 117 ; we are now between -1 and +1 cycle from the center of the bit
118 ; following the 0-->1 transition 118 ; following the 0-->1 transition
119 lds YL, usb_rx_off 119 lds YL, usb_rx_off
120 clr YH 120 clr YH
121 subi YL, lo8(-(usb_rx_buf)) ; Y = & usb_rx_buf[usb_rx_off] 121 subi YL, lo8(-(usb_rx_buf)) ; Y = & usb_rx_buf[usb_rx_off]
122 sbci YH, hi8(-(usb_rx_buf)) 122 sbci YH, hi8(-(usb_rx_buf))
123 ldi count, USB_BUFSIZE ; limit on number of bytes to receive 123 ldi count, USB_BUFSIZE ; limit on number of bytes to receive
124 ldi usbmask, USB_MASK ; why is there no eori instruction? 124 ldi usbmask, USB_MASK ; why is there no eori instruction?
125 ldi odd, USB_MASK_DPLUS 125 ldi odd, USB_MASK_DPLUS
126   126  
127 sync7: 127 sync7:
128 ; the last sync bit should also be 1 128 ; the last sync bit should also be 1
129 sbis USB_IN, USBTINY_DPLUS ; bit 7 of sync byte? 129 sbis USB_IN, USBTINY_DPLUS ; bit 7 of sync byte?
130 rjmp resync ; no, wait for next transition 130 rjmp resync ; no, wait for next transition
131 push byte 131 push byte
132 push fixup 132 push fixup
133 push even 133 push even
134   134  
135 ; ---------------------------------------------------------------------- 135 ; ----------------------------------------------------------------------
136 ; receiver loop 136 ; receiver loop
137 ; ---------------------------------------------------------------------- 137 ; ----------------------------------------------------------------------
138 in even, USB_IN ; sample bit 0 138 in even, USB_IN ; sample bit 0
139 ldi byte, 0x80 ; load sync byte for correct unstuffing 139 ldi byte, 0x80 ; load sync byte for correct unstuffing
140 rjmp rxentry ; 2 cycles 140 rjmp rxentry ; 2 cycles
141   141  
142 rxloop: 142 rxloop:
143 in even, USB_IN ; sample bit 0 143 in even, USB_IN ; sample bit 0
144 or fixup, byte 144 or fixup, byte
145 st Y+, fixup ; 2 cycles 145 st Y+, fixup ; 2 cycles
146 rxentry: 146 rxentry:
147 clr fixup 147 clr fixup
148 andi even, USB_MASK 148 andi even, USB_MASK
149 eor odd, even 149 eor odd, even
150 subi odd, 1 150 subi odd, 1
151 in odd, USB_IN ; sample bit 1 151 in odd, USB_IN ; sample bit 1
152 andi odd, USB_MASK 152 andi odd, USB_MASK
153 breq eop ; ==> EOP detected 153 breq eop ; ==> EOP detected
154 ror byte 154 ror byte
155 cpi byte, 0xfc 155 cpi byte, 0xfc
156 brcc skip0 156 brcc skip0
157 skipped0: 157 skipped0:
158 eor even, odd 158 eor even, odd
159 subi even, 1 159 subi even, 1
160 in even, USB_IN ; sample bit 2 160 in even, USB_IN ; sample bit 2
161 andi even, USB_MASK 161 andi even, USB_MASK
162 ror byte 162 ror byte
163 cpi byte, 0xfc 163 cpi byte, 0xfc
164 brcc skip1 164 brcc skip1
165 skipped1: 165 skipped1:
166 eor odd, even 166 eor odd, even
167 subi odd, 1 167 subi odd, 1
168 ror byte 168 ror byte
169 in odd, USB_IN ; sample bit 3 169 in odd, USB_IN ; sample bit 3
170 andi odd, USB_MASK 170 andi odd, USB_MASK
171 cpi byte, 0xfc 171 cpi byte, 0xfc
172 brcc skip2 172 brcc skip2
173 eor even, odd 173 eor even, odd
174 subi even, 1 174 subi even, 1
175 ror byte 175 ror byte
176 skipped2: 176 skipped2:
177 cpi byte, 0xfc 177 cpi byte, 0xfc
178 in even, USB_IN ; sample bit 4 178 in even, USB_IN ; sample bit 4
179 andi even, USB_MASK 179 andi even, USB_MASK
180 brcc skip3 180 brcc skip3
181 eor odd, even 181 eor odd, even
182 subi odd, 1 182 subi odd, 1
183 ror byte 183 ror byte
184 skipped4: 184 skipped4:
185 cpi byte, 0xfc 185 cpi byte, 0xfc
186 skipped3: 186 skipped3:
187 brcc skip4 187 brcc skip4
188 in odd, USB_IN ; sample bit 5 188 in odd, USB_IN ; sample bit 5
189 andi odd, USB_MASK 189 andi odd, USB_MASK
190 eor even, odd 190 eor even, odd
191 subi even, 1 191 subi even, 1
192 ror byte 192 ror byte
193 skipped5: 193 skipped5:
194 cpi byte, 0xfc 194 cpi byte, 0xfc
195 brcc skip5 195 brcc skip5
196 dec count 196 dec count
197 in even, USB_IN ; sample bit 6 197 in even, USB_IN ; sample bit 6
198 brmi overflow ; ==> overflow 198 brmi overflow ; ==> overflow
199 andi even, USB_MASK 199 andi even, USB_MASK
200 eor odd, even 200 eor odd, even
201 subi odd, 1 201 subi odd, 1
202 ror byte 202 ror byte
203 skipped6: 203 skipped6:
204 cpi byte, 0xfc 204 cpi byte, 0xfc
205 brcc skip6 205 brcc skip6
206 in odd, USB_IN ; sample bit 7 206 in odd, USB_IN ; sample bit 7
207 andi odd, USB_MASK 207 andi odd, USB_MASK
208 eor even, odd 208 eor even, odd
209 subi even, 1 209 subi even, 1
210 ror byte 210 ror byte
211 cpi byte, 0xfc 211 cpi byte, 0xfc
212 brcs rxloop ; 2 cycles 212 brcs rxloop ; 2 cycles
213 rjmp skip7 213 rjmp skip7
214   214  
215 eop: 215 eop:
216 rjmp eop2 216 rjmp eop2
217 overflow: 217 overflow:
218 rjmp ignore 218 rjmp ignore
219   219  
220 ; ---------------------------------------------------------------------- 220 ; ----------------------------------------------------------------------
221 ; out-of-line code to skip stuffing bits 221 ; out-of-line code to skip stuffing bits
222 ; ---------------------------------------------------------------------- 222 ; ----------------------------------------------------------------------
223 skip0: ; 1+6 cycles 223 skip0: ; 1+6 cycles
224 eor even, usbmask 224 eor even, usbmask
225 in odd, USB_IN ; resample bit 1 225 in odd, USB_IN ; resample bit 1
226 andi odd, USB_MASK 226 andi odd, USB_MASK
227 cbr byte, (1<<7) 227 cbr byte, (1<<7)
228 sbr fixup, (1<<0) 228 sbr fixup, (1<<0)
229 rjmp skipped0 229 rjmp skipped0
230   230  
231 skip1: ; 2+5 cycles 231 skip1: ; 2+5 cycles
232 cbr byte, (1<<7) 232 cbr byte, (1<<7)
233 sbr fixup, (1<<1) 233 sbr fixup, (1<<1)
234 in even, USB_IN ; resample bit 2 234 in even, USB_IN ; resample bit 2
235 andi even, USB_MASK 235 andi even, USB_MASK
236 eor odd, usbmask 236 eor odd, usbmask
237 rjmp skipped1 237 rjmp skipped1
238   238  
239 skip2: ; 3+7 cycles 239 skip2: ; 3+7 cycles
240 cbr byte, (1<<7) 240 cbr byte, (1<<7)
241 sbr fixup, (1<<2) 241 sbr fixup, (1<<2)
242 eor even, usbmask 242 eor even, usbmask
243 in odd, USB_IN ; resample bit 3 243 in odd, USB_IN ; resample bit 3
244 andi odd, USB_MASK 244 andi odd, USB_MASK
245 eor even, odd 245 eor even, odd
246 subi even, 1 246 subi even, 1
247 ror byte 247 ror byte
248 rjmp skipped2 248 rjmp skipped2
249   249  
250 skip3: ; 4+7 cycles 250 skip3: ; 4+7 cycles
251 cbr byte, (1<<7) 251 cbr byte, (1<<7)
252 sbr fixup, (1<<3) 252 sbr fixup, (1<<3)
253 eor odd, usbmask 253 eor odd, usbmask
254 ori byte, 1 254 ori byte, 1
255 in even, USB_IN ; resample bit 4 255 in even, USB_IN ; resample bit 4
256 andi even, USB_MASK 256 andi even, USB_MASK
257 eor odd, even 257 eor odd, even
258 subi odd, 1 258 subi odd, 1
259 ror byte 259 ror byte
260 rjmp skipped3 260 rjmp skipped3
261   261  
262 skip4: ; 5 cycles 262 skip4: ; 5 cycles
263 cbr byte, (1<<7) 263 cbr byte, (1<<7)
264 sbr fixup, (1<<4) 264 sbr fixup, (1<<4)
265 eor even, usbmask 265 eor even, usbmask
266 rjmp skipped4 266 rjmp skipped4
267   267  
268 skip5: ; 5 cycles 268 skip5: ; 5 cycles
269 cbr byte, (1<<7) 269 cbr byte, (1<<7)
270 sbr fixup, (1<<5) 270 sbr fixup, (1<<5)
271 eor odd, usbmask 271 eor odd, usbmask
272 rjmp skipped5 272 rjmp skipped5
273   273  
274 skip6: ; 5 cycles 274 skip6: ; 5 cycles
275 cbr byte, (1<<7) 275 cbr byte, (1<<7)
276 sbr fixup, (1<<6) 276 sbr fixup, (1<<6)
277 eor even, usbmask 277 eor even, usbmask
278 rjmp skipped6 278 rjmp skipped6
279   279  
280 skip7: ; 7 cycles 280 skip7: ; 7 cycles
281 cbr byte, (1<<7) 281 cbr byte, (1<<7)
282 sbr fixup, (1<<7) 282 sbr fixup, (1<<7)
283 eor odd, usbmask 283 eor odd, usbmask
284 nop2 284 nop2
285 rjmp rxloop 285 rjmp rxloop
286   286  
287 ; ---------------------------------------------------------------------- 287 ; ----------------------------------------------------------------------
288 ; end-of-packet detected (worst-case: 3 cycles after end of SE0) 288 ; end-of-packet detected (worst-case: 3 cycles after end of SE0)
289 ; ---------------------------------------------------------------------- 289 ; ----------------------------------------------------------------------
290 eop2: 290 eop2:
291 ; clear pending interrupt (SE0+3) 291 ; clear pending interrupt (SE0+3)
292 ldi byte, 1<<USB_INT_PENDING_BIT 292 ldi byte, 1<<USB_INT_PENDING_BIT
293 out USB_INT_PENDING, byte ; clear pending bit at end of packet 293 out USB_INT_PENDING, byte ; clear pending bit at end of packet
294 ; ignore packets shorter than 3 bytes 294 ; ignore packets shorter than 3 bytes
295 subi count, USB_BUFSIZE 295 subi count, USB_BUFSIZE
296 neg count ; count = packet length 296 neg count ; count = packet length
297 cpi count, 3 297 cpi count, 3
298 brlo ignore 298 brlo ignore
299 ; get PID 299 ; get PID
300 sub YL, count 300 sub YL, count
301 ld pid, Y 301 ld pid, Y
302 ; check for DATA0/DATA1 first, as this is the critical path (SE0+12) 302 ; check for DATA0/DATA1 first, as this is the critical path (SE0+12)
303 cpi pid, USB_PID_DATA0 303 cpi pid, USB_PID_DATA0
304 breq is_data ; handle DATA0 packet 304 breq is_data ; handle DATA0 packet
305 cpi pid, USB_PID_DATA1 305 cpi pid, USB_PID_DATA1
306 breq is_data ; handle DATA1 packet 306 breq is_data ; handle DATA1 packet
307 ; check ADDR (SE0+16) 307 ; check ADDR (SE0+16)
308 ldd addr, Y+1 308 ldd addr, Y+1
309 andi addr, 0x7f 309 andi addr, 0x7f
310 lds tmp, usb_address 310 lds tmp, usb_address
311 cp addr, tmp ; is this packet for me? 311 cp addr, tmp ; is this packet for me?
312 brne ignore ; no, ignore 312 brne ignore ; no, ignore
313 ; check for other PIDs (SE0+23) 313 ; check for other PIDs (SE0+23)
314 cpi pid, USB_PID_IN 314 cpi pid, USB_PID_IN
315 breq is_in ; handle IN packet 315 breq is_in ; handle IN packet
316 cpi pid, USB_PID_SETUP 316 cpi pid, USB_PID_SETUP
317 breq is_setup_out ; handle SETUP packet 317 breq is_setup_out ; handle SETUP packet
318 cpi pid, USB_PID_OUT 318 cpi pid, USB_PID_OUT
319 breq is_setup_out ; handle OUT packet 319 breq is_setup_out ; handle OUT packet
320   320  
321 ; ---------------------------------------------------------------------- 321 ; ----------------------------------------------------------------------
322 ; exit point for ignored packets 322 ; exit point for ignored packets
323 ; ---------------------------------------------------------------------- 323 ; ----------------------------------------------------------------------
324 ignore: 324 ignore:
325 clr tmp 325 clr tmp
326 sts token_pid, tmp 326 sts token_pid, tmp
327 pop even 327 pop even
328 pop fixup 328 pop fixup
329 pop byte 329 pop byte
330 rjmp return 330 rjmp return
331   331  
332 ; ---------------------------------------------------------------------- 332 ; ----------------------------------------------------------------------
333 ; Handle SETUP/OUT (SE0+30) 333 ; Handle SETUP/OUT (SE0+30)
334 ; ---------------------------------------------------------------------- 334 ; ----------------------------------------------------------------------
335 is_setup_out: 335 is_setup_out:
336 sts token_pid, pid ; save PID of token packet 336 sts token_pid, pid ; save PID of token packet
337 pop even 337 pop even
338 pop fixup 338 pop fixup
339 pop byte 339 pop byte
340 in count, USB_INT_PENDING ; next packet already started? 340 in count, USB_INT_PENDING ; next packet already started?
341 sbrc count, USB_INT_PENDING_BIT 341 sbrc count, USB_INT_PENDING_BIT
342 rjmp sync ; yes, get it right away (SE0+42) 342 rjmp sync ; yes, get it right away (SE0+42)
343   343  
344 ; ---------------------------------------------------------------------- 344 ; ----------------------------------------------------------------------
345 ; restore registers and return from interrupt 345 ; restore registers and return from interrupt
346 ; ---------------------------------------------------------------------- 346 ; ----------------------------------------------------------------------
347 return: 347 return:
348 pop count 348 pop count
349 out SREG, count 349 out SREG, count
350 pop YL 350 pop YL
351 pop YH 351 pop YH
352 pop odd 352 pop odd
353 pop usbmask 353 pop usbmask
354 pop count 354 pop count
355 reti 355 reti
356   356  
357 ; ---------------------------------------------------------------------- 357 ; ----------------------------------------------------------------------
358 ; Handle IN (SE0+26) 358 ; Handle IN (SE0+26)
359 ; ---------------------------------------------------------------------- 359 ; ----------------------------------------------------------------------
360 is_in: 360 is_in:
361 lds count, usb_tx_len 361 lds count, usb_tx_len
362 tst count ; data ready? 362 tst count ; data ready?
363 breq nak ; no, reply with NAK 363 breq nak ; no, reply with NAK
364 lds tmp, usb_rx_len 364 lds tmp, usb_rx_len
365 tst tmp ; unprocessed input packet? 365 tst tmp ; unprocessed input packet?
366 brne nak ; yes, don't send old data for new packet 366 brne nak ; yes, don't send old data for new packet
367 sts usb_tx_len, tmp ; buffer is available again (after reti) 367 sts usb_tx_len, tmp ; buffer is available again (after reti)
368 ldi YL, lo8(usb_tx_buf) 368 ldi YL, lo8(usb_tx_buf)
369 ldi YH, hi8(usb_tx_buf) 369 ldi YH, hi8(usb_tx_buf)
370 rjmp send_packet ; SE0+40, SE0 --> SOP <= 51 370 rjmp send_packet ; SE0+40, SE0 --> SOP <= 51
371   371  
372 ; ---------------------------------------------------------------------- 372 ; ----------------------------------------------------------------------
373 ; Handle DATA0/DATA1 (SE0+17) 373 ; Handle DATA0/DATA1 (SE0+17)
374 ; ---------------------------------------------------------------------- 374 ; ----------------------------------------------------------------------
375 is_data: 375 is_data:
376 lds pid, token_pid 376 lds pid, token_pid
377 tst pid ; data following our SETUP/OUT 377 tst pid ; data following our SETUP/OUT
378 breq ignore ; no, ignore 378 breq ignore ; no, ignore
379 lds tmp, usb_rx_len 379 lds tmp, usb_rx_len
380 tst tmp ; buffer free? 380 tst tmp ; buffer free?
381 brne nak ; no, reply with NAK 381 brne nak ; no, reply with NAK
382 sts usb_rx_len, count ; pass buffer length 382 sts usb_rx_len, count ; pass buffer length
383 sts usb_rx_token, pid ; pass PID of token (SETUP or OUT) 383 sts usb_rx_token, pid ; pass PID of token (SETUP or OUT)
384 lds count, usb_rx_off ; switch to other input buffer 384 lds count, usb_rx_off ; switch to other input buffer
385 ldi tmp, USB_BUFSIZE 385 ldi tmp, USB_BUFSIZE
386 sub tmp, count 386 sub tmp, count
387 sts usb_rx_off, tmp 387 sts usb_rx_off, tmp
388   388  
389 ; ---------------------------------------------------------------------- 389 ; ----------------------------------------------------------------------
390 ; send ACK packet (SE0+35) 390 ; send ACK packet (SE0+35)
391 ; ---------------------------------------------------------------------- 391 ; ----------------------------------------------------------------------
392 ack: 392 ack:
393 ldi YL, lo8(tx_ack) 393 ldi YL, lo8(tx_ack)
394 ldi YH, hi8(tx_ack) 394 ldi YH, hi8(tx_ack)
395 rjmp send_token 395 rjmp send_token
396   396  
397 ; ---------------------------------------------------------------------- 397 ; ----------------------------------------------------------------------
398 ; send NAK packet (SE0+36) 398 ; send NAK packet (SE0+36)
399 ; ---------------------------------------------------------------------- 399 ; ----------------------------------------------------------------------
400 nak: 400 nak:
401 ldi YL, lo8(tx_nak) 401 ldi YL, lo8(tx_nak)
402 ldi YH, hi8(tx_nak) 402 ldi YH, hi8(tx_nak)
403 send_token: 403 send_token:
404 ldi count, 1 ; SE0+40, SE0 --> SOP <= 51 404 ldi count, 1 ; SE0+40, SE0 --> SOP <= 51
405   405  
406 ; ---------------------------------------------------------------------- 406 ; ----------------------------------------------------------------------
407 ; acquire the bus and send a packet (11 cycles to SOP) 407 ; acquire the bus and send a packet (11 cycles to SOP)
408 ; ---------------------------------------------------------------------- 408 ; ----------------------------------------------------------------------
409 send_packet: 409 send_packet:
410 in output, USB_OUT 410 in output, USB_OUT
411 cbr output, USB_MASK 411 cbr output, USB_MASK
412 ori output, USB_MASK_DMINUS 412 ori output, USB_MASK_DMINUS
413 in usbmask, USB_DDR 413 in usbmask, USB_DDR
414 ori usbmask, USB_MASK 414 ori usbmask, USB_MASK
415 out USB_OUT, output ; idle state 415 out USB_OUT, output ; idle state
416 out USB_DDR, usbmask ; acquire bus 416 out USB_DDR, usbmask ; acquire bus
417 ldi usbmask, USB_MASK 417 ldi usbmask, USB_MASK
418 ldi byte, 0x80 ; start with sync byte 418 ldi byte, 0x80 ; start with sync byte
419   419  
420 ; ---------------------------------------------------------------------- 420 ; ----------------------------------------------------------------------
421 ; transmitter loop 421 ; transmitter loop
422 ; ---------------------------------------------------------------------- 422 ; ----------------------------------------------------------------------
423 txloop: 423 txloop:
424 sbrs byte, 0 424 sbrs byte, 0
425 eor output, usbmask 425 eor output, usbmask
426 out USB_OUT, output ; output bit 0 426 out USB_OUT, output ; output bit 0
427 ror byte 427 ror byte
428 ror done 428 ror done
429 stuffed0: 429 stuffed0:
430 cpi done, 0xfc 430 cpi done, 0xfc
431 brcc stuff0 431 brcc stuff0
432 sbrs byte, 0 432 sbrs byte, 0
433 eor output, usbmask 433 eor output, usbmask
434 ror byte 434 ror byte
435 stuffed1: 435 stuffed1:
436 out USB_OUT, output ; output bit 1 436 out USB_OUT, output ; output bit 1
437 ror done 437 ror done
438 cpi done, 0xfc 438 cpi done, 0xfc
439 brcc stuff1 439 brcc stuff1
440 sbrs byte, 0 440 sbrs byte, 0
441 eor output, usbmask 441 eor output, usbmask
442 ror byte 442 ror byte
443 nop 443 nop
444 stuffed2: 444 stuffed2:
445 out USB_OUT, output ; output bit 2 445 out USB_OUT, output ; output bit 2
446 ror done 446 ror done
447 cpi done, 0xfc 447 cpi done, 0xfc
448 brcc stuff2 448 brcc stuff2
449 sbrs byte, 0 449 sbrs byte, 0
450 eor output, usbmask 450 eor output, usbmask
451 ror byte 451 ror byte
452 nop 452 nop
453 stuffed3: 453 stuffed3:
454 out USB_OUT, output ; output bit 3 454 out USB_OUT, output ; output bit 3
455 ror done 455 ror done
456 cpi done, 0xfc 456 cpi done, 0xfc
457 brcc stuff3 457 brcc stuff3
458 sbrs byte, 0 458 sbrs byte, 0
459 eor output, usbmask 459 eor output, usbmask
460 ld next, Y+ ; 2 cycles 460 ld next, Y+ ; 2 cycles
461 out USB_OUT, output ; output bit 4 461 out USB_OUT, output ; output bit 4
462 ror byte 462 ror byte
463 ror done 463 ror done
464 stuffed4: 464 stuffed4:
465 cpi done, 0xfc 465 cpi done, 0xfc
466 brcc stuff4 466 brcc stuff4
467 sbrs byte, 0 467 sbrs byte, 0
468 eor output, usbmask 468 eor output, usbmask
469 ror byte 469 ror byte
470 stuffed5: 470 stuffed5:
471 out USB_OUT, output ; output bit 5 471 out USB_OUT, output ; output bit 5
472 ror done 472 ror done
473 cpi done, 0xfc 473 cpi done, 0xfc
474 brcc stuff5 474 brcc stuff5
475 sbrs byte, 0 475 sbrs byte, 0
476 eor output, usbmask 476 eor output, usbmask
477 ror byte 477 ror byte
478 stuffed6: 478 stuffed6:
479 ror done 479 ror done
480 out USB_OUT, output ; output bit 6 480 out USB_OUT, output ; output bit 6
481 cpi done, 0xfc 481 cpi done, 0xfc
482 brcc stuff6 482 brcc stuff6
483 sbrs byte, 0 483 sbrs byte, 0
484 eor output, usbmask 484 eor output, usbmask
485 ror byte 485 ror byte
486 mov byte, next 486 mov byte, next
487 stuffed7: 487 stuffed7:
488 ror done 488 ror done
489 out USB_OUT, output ; output bit 7 489 out USB_OUT, output ; output bit 7
490 cpi done, 0xfc 490 cpi done, 0xfc
491 brcc stuff7 491 brcc stuff7
492 dec count 492 dec count
493 brpl txloop ; 2 cycles 493 brpl txloop ; 2 cycles
494   494  
495 rjmp gen_eop 495 rjmp gen_eop
496   496  
497 ; ---------------------------------------------------------------------- 497 ; ----------------------------------------------------------------------
498 ; out-of-line code to insert stuffing bits 498 ; out-of-line code to insert stuffing bits
499 ; ---------------------------------------------------------------------- 499 ; ----------------------------------------------------------------------
500 stuff0: ; 2+3 500 stuff0: ; 2+3
501 eor output, usbmask 501 eor output, usbmask
502 clr done 502 clr done
503 out USB_OUT, output 503 out USB_OUT, output
504 rjmp stuffed0 504 rjmp stuffed0
505   505  
506 stuff1: ; 3 506 stuff1: ; 3
507 eor output, usbmask 507 eor output, usbmask
508 rjmp stuffed1 508 rjmp stuffed1
509   509  
510 stuff2: ; 3 510 stuff2: ; 3
511 eor output, usbmask 511 eor output, usbmask
512 rjmp stuffed2 512 rjmp stuffed2
513   513  
514 stuff3: ; 3 514 stuff3: ; 3
515 eor output, usbmask 515 eor output, usbmask
516 rjmp stuffed3 516 rjmp stuffed3
517   517  
518 stuff4: ; 2+3 518 stuff4: ; 2+3
519 eor output, usbmask 519 eor output, usbmask
520 clr done 520 clr done
521 out USB_OUT, output 521 out USB_OUT, output
522 rjmp stuffed4 522 rjmp stuffed4
523   523  
524 stuff5: ; 3 524 stuff5: ; 3
525 eor output, usbmask 525 eor output, usbmask
526 rjmp stuffed5 526 rjmp stuffed5
527   527  
528 stuff6: ; 3 528 stuff6: ; 3
529 eor output, usbmask 529 eor output, usbmask
530 rjmp stuffed6 530 rjmp stuffed6
531   531  
532 stuff7: ; 3 532 stuff7: ; 3
533 eor output, usbmask 533 eor output, usbmask
534 rjmp stuffed7 534 rjmp stuffed7
535   535  
536 ; ---------------------------------------------------------------------- 536 ; ----------------------------------------------------------------------
537 ; generate EOP, release the bus, and return from interrupt 537 ; generate EOP, release the bus, and return from interrupt
538 ; ---------------------------------------------------------------------- 538 ; ----------------------------------------------------------------------
539 gen_eop: 539 gen_eop:
540 cbr output, USB_MASK 540 cbr output, USB_MASK
541 out USB_OUT, output ; output SE0 for 2 bit times 541 out USB_OUT, output ; output SE0 for 2 bit times
542 pop even 542 pop even
543 pop fixup 543 pop fixup
544 pop byte 544 pop byte
545 ldi count, 1<<USB_INT_PENDING_BIT 545 ldi count, 1<<USB_INT_PENDING_BIT
546 out USB_INT_PENDING, count ; interrupt was triggered by transmit 546 out USB_INT_PENDING, count ; interrupt was triggered by transmit
547 pop YH ; this is the saved SREG 547 pop YH ; this is the saved SREG
548 pop YL 548 pop YL
549 in usbmask, USB_DDR 549 in usbmask, USB_DDR
550 mov count, output 550 mov count, output
551 ori output, USB_MASK_DMINUS 551 ori output, USB_MASK_DMINUS
552 out USB_OUT, output ; output J state for 1 bit time 552 out USB_OUT, output ; output J state for 1 bit time
553 cbr usbmask, USB_MASK 553 cbr usbmask, USB_MASK
554 out SREG, YH 554 out SREG, YH
555 pop YH 555 pop YH
556 pop odd ; is the same register as output! 556 pop odd ; is the same register as output!
557 nop 557 nop
558 out USB_DDR, usbmask ; release bus 558 out USB_DDR, usbmask ; release bus
559 out USB_OUT, count ; disable D- pullup 559 out USB_OUT, count ; disable D- pullup
560 pop usbmask 560 pop usbmask
561 pop count 561 pop count
562 reti 562 reti