Rev 3332 Rev 3333
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: