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