Line 7... |
Line 7... |
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 |
|
Line 43... |
Line 49... |
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: |
Line 289... |
Line 296... |
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 |
Line 353... |
Line 365... |
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) |
Line 385... |
Line 396... |
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: |