1 /* Name: usbdrvasm128.inc
 
   2  * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
 
   3  * Author: Christian Starkjohann
 
   4  * Creation Date: 2008-10-11
 
   6  * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
 
   7  * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
 
  11 /* Do not link this file! Link usbdrvasm.S instead, which includes the
 
  12  * appropriate implementation!
 
  17 This file is the 12.8 MHz version of the USB driver. It is intended for use
 
  18 with the internal RC oscillator. Although 12.8 MHz is outside the guaranteed
 
  19 calibration range of the oscillator, almost all AVRs can reach this frequency.
 
  20 This version contains a phase locked loop in the receiver routine to cope with
 
  21 slight clock rate deviations of up to +/- 1%.
 
  23 See usbdrv.h for a description of the entire driver.
 
  27 Although it may seem very handy to save the crystal and use the internal
 
  28 RC oscillator of the CPU, this method (and this module) has some serious
 
  30 (1) The guaranteed calibration range of the oscillator is only 8.1 MHz.
 
  31 They typical range is 14.5 MHz and most AVRs can actually reach this rate.
 
  32 (2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
 
  33 the write procedure is timed from the RC oscillator.
 
  34 (3) End Of Packet detection (SE0) should be in bit 1, bit it is only checked
 
  35 if bits 0 and 1 both read as 0 on D- and D+ read as 0 in the middle. This may
 
  36 cause problems with old hubs which delay SE0 by up to one cycle.
 
  37 (4) Code size is much larger than that of the other modules.
 
  39 Since almost all of this code is timing critical, don't change unless you
 
  40 really know what you are doing! Many parts require not only a maximum number
 
  41 of CPU cycles, but even an exact number of cycles!
 
  44 ======================
 
  45 min frequency: 67 cycles for 8 bit -> 12.5625 MHz
 
  46 max frequency: 69.286 cycles for 8 bit -> 12.99 MHz
 
  47 nominal frequency: 12.77 MHz ( = sqrt(min * max))
 
  49 sampling positions: (next even number in range [+/- 0.5])
 
  50 cycle index range: 0 ... 66
 
  52 .5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125
 
  53 [0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59]
 
  55 bit number:     0   1   2   3   4   5   6   7
 
  56 spare cycles    1   2   1   2   1   1   1   0
 
  58 operations to perform:      duration cycle
 
  60     eor     fix, shift          1 -> 00
 
  61     andi    phase, USBMASK      1 -> 08
 
  62     breq    se0                 1 -> 16 (moved to 11)
 
  63     st      y+, data            2 -> 24, 25
 
  69 layout of samples and operations:
 
  74 0:  *00* [01]  02   03   04  <05>  06   07
 
  75 1:  *08* [09]  10   11   12  <13>  14   15  *16*
 
  76 2:  [17]  18   19   20  <21>  22   23
 
  77 3:  *24* *25* [26]  27   28   29  <30>  31   32
 
  78 4:  *33* [34]  35   36   37  <38>  39   40
 
  79 5:  *41* [42]  43   44   45  <46>  47   48
 
  80 6:  *49* *50* [51]  52   53   54  <55>  56   57   58
 
  81 7:  [59]  60   61   62  <63>  64   65   66
 
  82 *****************************************************************************/
 
  84 /* we prefer positive expressions (do if condition) instead of negative
 
  85  * (skip if condition), therefore use defines for skip instructions:
 
  92 /* The registers "fix" and "data" swap their meaning during the loop. Use
 
  93  * defines to keep their name constant.
 
  97 #undef phase        /* phase has a default definition to x4 */
 
 102 ;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0
 
 103     push    YL              ;2 push only what is necessary to sync with edge ASAP
 
 106 ;----------------------------------------------------------------------------
 
 107 ; Synchronize with sync pattern:
 
 108 ;----------------------------------------------------------------------------
 
 109 ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
 
 110 ;sync up with J to K edge during sync pattern -- use fastest possible loops
 
 111 ;The first part waits at most 1 bit long since we must be in sync pattern.
 
 112 ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
 
 113 ;waitForJ, ensure that this prerequisite is met.
 
 117     brne    waitForJ        ; just make sure we have ANY timeout
 
 119 ;The following code results in a sampling window of 1/4 bit which meets the spec.
 
 128     sbis    USBIN, USBMINUS ;[0]
 
 134 #endif  /* USB_COUNT_SOF */
 
 141 ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
 
 142 ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
 
 143 ;are cycles from center of first sync (double K) bit after the instruction
 
 145     lds     YL, usbInputBufOffset;[4]
 
 147     subi    YL, lo8(-(usbRxBuf));[7]
 
 148     sbci    YH, hi8(-(usbRxBuf));[8]
 
 150     sbis    USBIN, USBMINUS     ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5]
 
 151     rjmp    haveTwoBitsK        ;[10]
 
 152     pop     YH                  ;[11] undo the push from before
 
 153     rjmp    waitForK            ;[13] this was not the end of sync, retry
 
 155 ;----------------------------------------------------------------------------
 
 156 ; push more registers and initialize values while we sample the first bits:
 
 157 ;----------------------------------------------------------------------------
 
 164     ldi     shift, 0x80         ;[18] prevent bit-unstuffing but init low bits to 0
 
 165     ifioset USBIN, USBMINUS     ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5]
 
 166     ori     shift, 1<<0         ;[02]
 
 170     ifioset USBIN, USBMINUS     ;[09] <--- bit 1
 
 171     ori     shift, 1<<1         ;[10]
 
 173     ldi     cnt, USB_BUFSIZE    ;[12]
 
 174     mov     data, shift         ;[13]
 
 177     ifioset USBIN, USBMINUS     ;[17] <--- bit 2
 
 178     ori     data, 3<<2          ;[18] store in bit 2 AND bit 3
 
 179     eor     shift, data         ;[19] do nrzi decoding
 
 180     andi    data, 1<<3          ;[20]
 
 181     in      phase, USBIN        ;[21] <- phase
 
 182     brne    jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1
 
 184     rjmp    entryAfterClr       ;[24]
 
 186     rjmp    entryAfterSet       ;[24]
 
 188 ;----------------------------------------------------------------------------
 
 189 ; Receiver loop (numbers in brackets are cycles within byte after instr)
 
 190 ;----------------------------------------------------------------------------
 
 197     ifrclr  phase, USBMINUS     ;[62] check phase only if D- changed
 
 199     in      phase, USBIN        ;[64] <- phase (one cycle too late)
 
 200     ori     shift, 1 << 7       ;[65]
 
 202 ;;;;rjmp    bit0AfterSet        ; -> [00] == [67] moved block up to save jump
 
 208 #define data    x1  /* we now have result in data, fix is reset to 0xff */
 
 209     ifioclr USBIN, USBMINUS     ;[01] <--- sample 0
 
 211     andi    shift, ~(7 << 0)    ;[03]
 
 213     in      phase, USBIN        ;[05] <- phase
 
 214     rjmp    bit1AfterSet        ;[06]
 
 216     in      phase, USBIN        ;[06] <- phase (one cycle too late)
 
 217     andi    fix, ~(1 << 0)      ;[07]
 
 218     ifioclr USBIN, USBMINUS     ;[00]
 
 219     ifioset USBIN, USBPLUS      ;[01]
 
 220     rjmp    bit0IsClr           ;[02] executed if first expr false or second true
 
 221 se0AndStore:                    ; executed only if both bits 0
 
 222     st      y+, x1              ;[15/17] cycles after start of byte
 
 226     ifrset  phase, USBMINUS     ;[04] check phase only if D- changed
 
 228     in      phase, USBIN        ;[06] <- phase (one cycle too late)
 
 229     ori     shift, 1 << 0       ;[07]
 
 231     andi    phase, USBMASK      ;[08]
 
 232     ifioset USBIN, USBMINUS     ;[09] <--- sample 1
 
 234     breq    se0AndStore         ;[11] if D- was 0 in bits 0 AND 1 and D+ was 0 in between, we have SE0
 
 235     andi    shift, ~(7 << 1)    ;[12]
 
 236     in      phase, USBIN        ;[13] <- phase
 
 238     rjmp    bit2AfterClr        ;[15]
 
 240     andi    fix, ~(1 << 1)      ;[16]
 
 244     ifrclr  phase, USBMINUS     ;[12] check phase only if D- changed
 
 246     in      phase, USBIN        ;[14] <- phase (one cycle too late)
 
 247     ori     shift, 1 << 1       ;[15]
 
 250     ifioclr USBIN, USBMINUS     ;[17] <--- sample 2
 
 252     andi    shift, ~(7 << 2)    ;[19]
 
 254     in      phase, USBIN        ;[21] <- phase
 
 255     rjmp    bit3AfterSet        ;[22]
 
 257     in      phase, USBIN        ;[22] <- phase (one cycle too late)
 
 258     andi    fix, ~(1 << 2)      ;[23]
 
 262     ifrset  phase, USBMINUS     ;[20] check phase only if D- changed
 
 264     in      phase, USBIN        ;[22] <- phase (one cycle too late)
 
 265     ori     shift, 1 << 2       ;[23]
 
 269     ifioset USBIN, USBMINUS     ;[26] <--- sample 3
 
 271     andi    shift, ~(7 << 3)    ;[28]
 
 273     in      phase, USBIN        ;[30] <- phase
 
 274     rjmp    bit4AfterClr        ;[31]
 
 276     in      phase, USBIN        ;[31] <- phase (one cycle too late)
 
 277     andi    fix, ~(1 << 3)      ;[32]
 
 281     ifrclr  phase, USBMINUS     ;[29] check phase only if D- changed
 
 283     in      phase, USBIN        ;[31] <- phase (one cycle too late)
 
 284     ori     shift, 1 << 3       ;[32]
 
 286     mov     data, fix           ;[33] undo this move by swapping defines
 
 291     ifioclr USBIN, USBMINUS     ;[34] <--- sample 4
 
 293     andi    shift, ~(7 << 4)    ;[36]
 
 295     in      phase, USBIN        ;[38] <- phase
 
 296     rjmp    bit5AfterSet        ;[39]
 
 298     in      phase, USBIN        ;[39] <- phase (one cycle too late)
 
 299     andi    fix, ~(1 << 4)      ;[40]
 
 303     ifrset  phase, USBMINUS     ;[37] check phase only if D- changed
 
 305     in      phase, USBIN        ;[39] <- phase (one cycle too late)
 
 306     ori     shift, 1 << 4       ;[40]
 
 309     ifioset USBIN, USBMINUS     ;[42] <--- sample 5
 
 311     andi    shift, ~(7 << 5)    ;[44]
 
 313     in      phase, USBIN        ;[46] <- phase
 
 314     rjmp    bit6AfterClr        ;[47]
 
 316     in      phase, USBIN        ;[47] <- phase (one cycle too late)
 
 317     andi    fix, ~(1 << 5)      ;[48]
 
 321     ifrclr  phase, USBMINUS     ;[45] check phase only if D- changed
 
 323     in      phase, USBIN        ;[47] <- phase (one cycle too late)
 
 324     ori     shift, 1 << 5       ;[48]
 
 327     brcs    jumpToOverflow      ;[50]
 
 328     ifioclr USBIN, USBMINUS     ;[51] <--- sample 6
 
 330     andi    shift, ~(3 << 6)    ;[53]
 
 332     in      phase, USBIN        ;[55] <- phase
 
 334     rjmp    bit7AfterSet        ;[57]
 
 340     andi    fix, ~(1 << 6)      ;[50]
 
 343     ifrset  phase, USBMINUS     ;[54] check phase only if D- changed
 
 345     in      phase, USBIN        ;[56] <- phase (one cycle too late)
 
 346     ori     shift, 1 << 6       ;[57]
 
 349     ifioset USBIN, USBMINUS     ;[59] <--- sample 7
 
 351     andi    shift, ~(1 << 7)    ;[61]
 
 353     in      phase, USBIN        ;[63] <- phase
 
 355     rjmp    bit0AfterClr        ;[65] -> [00] == [67]
 
 357     andi    fix, ~(1 << 7)      ;[58]
 
 362     ifrset  phase, USBMINUS     ;[62] check phase only if D- changed
 
 364     in      phase, USBIN        ;[64] <- phase (one cycle too late)
 
 365     ori     shift, 1 << 7       ;[65]
 
 367 ;;;;rjmp    bit0AfterClr        ; -> [00] == [67] moved block up to save jump
 
 373 #define data    x1  /* we now have result in data, fix is reset to 0xff */
 
 374     ifioset USBIN, USBMINUS     ;[01] <--- sample 0
 
 376     andi    shift, ~(7 << 0)    ;[03]
 
 378     in      phase, USBIN        ;[05] <- phase
 
 379     rjmp    bit1AfterClr        ;[06]
 
 381     in      phase, USBIN        ;[06] <- phase (one cycle too late)
 
 382     andi    fix, ~(1 << 0)      ;[07]
 
 383     ifioclr USBIN, USBMINUS     ;[00]
 
 384     ifioset USBIN, USBPLUS      ;[01]
 
 385     rjmp    bit0IsSet           ;[02] executed if first expr false or second true
 
 386     rjmp    se0AndStore         ;[03] executed only if both bits 0
 
 388     ifrclr  phase, USBMINUS     ;[04] check phase only if D- changed
 
 390     in      phase, USBIN        ;[06] <- phase (one cycle too late)
 
 391     ori     shift, 1 << 0       ;[07]
 
 393     andi    shift, ~(7 << 1)    ;[08] compensated by "ori shift, 1<<1" if bit1IsClr
 
 394     ifioclr USBIN, USBMINUS     ;[09] <--- sample 1
 
 397     nop2                        ;[12] do not check for SE0 if bit 0 was 1
 
 398     in      phase, USBIN        ;[14] <- phase (one cycle too late)
 
 399     rjmp    bit2AfterSet        ;[15]
 
 401     in      phase, USBIN        ;[13] <- phase
 
 402     andi    fix, ~(1 << 1)      ;[14]
 
 406     ifrset  phase, USBMINUS     ;[12] check phase only if D- changed
 
 408     in      phase, USBIN        ;[14] <- phase (one cycle too late)
 
 409     ori     shift, 1 << 1       ;[15]
 
 412     ifioset USBIN, USBMINUS     ;[17] <--- sample 2
 
 414     andi    shift, ~(7 << 2)    ;[19]
 
 416     in      phase, USBIN        ;[21] <- phase
 
 417     rjmp    bit3AfterClr        ;[22]
 
 419     in      phase, USBIN        ;[22] <- phase (one cycle too late)
 
 420     andi    fix, ~(1 << 2)      ;[23]
 
 424     ifrclr  phase, USBMINUS     ;[20] check phase only if D- changed
 
 426     in      phase, USBIN        ;[22] <- phase (one cycle too late)
 
 427     ori     shift, 1 << 2       ;[23]
 
 431     ifioclr USBIN, USBMINUS     ;[26] <--- sample 3
 
 433     andi    shift, ~(7 << 3)    ;[28]
 
 435     in      phase, USBIN        ;[30] <- phase
 
 436     rjmp    bit4AfterSet        ;[31]
 
 438     in      phase, USBIN        ;[31] <- phase (one cycle too late)
 
 439     andi    fix, ~(1 << 3)      ;[32]
 
 443     ifrset  phase, USBMINUS     ;[29] check phase only if D- changed
 
 445     in      phase, USBIN        ;[31] <- phase (one cycle too late)
 
 446     ori     shift, 1 << 3       ;[32]
 
 448     mov     data, fix           ;[33] undo this move by swapping defines
 
 453     ifioset USBIN, USBMINUS     ;[34] <--- sample 4
 
 455     andi    shift, ~(7 << 4)    ;[36]
 
 457     in      phase, USBIN        ;[38] <- phase
 
 458     rjmp    bit5AfterClr        ;[39]
 
 460     in      phase, USBIN        ;[39] <- phase (one cycle too late)
 
 461     andi    fix, ~(1 << 4)      ;[40]
 
 465     ifrclr  phase, USBMINUS     ;[37] check phase only if D- changed
 
 467     in      phase, USBIN        ;[39] <- phase (one cycle too late)
 
 468     ori     shift, 1 << 4       ;[40]
 
 471     ifioclr USBIN, USBMINUS     ;[42] <--- sample 5
 
 473     andi    shift, ~(7 << 5)    ;[44]
 
 475     in      phase, USBIN        ;[46] <- phase
 
 476     rjmp    bit6AfterSet        ;[47]
 
 478     in      phase, USBIN        ;[47] <- phase (one cycle too late)
 
 479     andi    fix, ~(1 << 5)      ;[48]
 
 483     ifrset  phase, USBMINUS     ;[45] check phase only if D- changed
 
 485     in      phase, USBIN        ;[47] <- phase (one cycle too late)
 
 486     ori     shift, 1 << 5       ;[48]
 
 490     ifioset USBIN, USBMINUS     ;[51] <--- sample 6
 
 492     andi    shift, ~(3 << 6)    ;[53]
 
 494     in      phase, USBIN        ;[55] <- phase
 
 496     rjmp    bit7AfterClr        ;[57]
 
 498     andi    fix, ~(1 << 6)      ;[50]
 
 501     ifrclr  phase, USBMINUS     ;[54] check phase only if D- changed
 
 503     in      phase, USBIN        ;[56] <- phase (one cycle too late)
 
 504     ori     shift, 1 << 6       ;[57]
 
 506     ifioclr USBIN, USBMINUS     ;[59] <--- sample 7
 
 508     andi    shift, ~(1 << 7)    ;[61]
 
 510     in      phase, USBIN        ;[63] <- phase
 
 512     rjmp    bit0AfterSet        ;[65] -> [00] == [67]
 
 514     andi    fix, ~(1 << 7)      ;[58]
 
 518 macro POP_STANDARD ; 14 cycles
 
 527 macro POP_RETI     ; 5 cycles
 
 533 #include "asmcommon.inc"
 
 535 ;----------------------------------------------------------------------------
 
 537 ;----------------------------------------------------------------------------
 
 542     ror     shift               ;[-5] [11] [63]
 
 543     brcc    doExorN1            ;[-4]      [64]
 
 546     lsl     shift               ;[-1] compensate ror after rjmp stuffDelay
 
 547     nop                         ;[00] stuffing consists of just waiting 8 cycles
 
 548     rjmp    stuffN1Delay        ;[01] after ror, C bit is reliably clear
 
 551     ldi     cnt, USBPID_NAK ;[-19]
 
 552     rjmp    sendCntAndReti  ;[-18]
 
 554     ldi     cnt, USBPID_ACK ;[-17]
 
 557     ldi     YL, 0           ;[-15] R0 address is 0
 
 560 ;   rjmp    usbSendAndReti      fallthrough
 
 564 ; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
 
 565 ; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
 
 566 ; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
 
 569 ;pointer to data in 'Y'
 
 570 ;number of bytes in 'cnt' -- including sync byte
 
 571 ;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt]
 
 572 ;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
 
 574     in      x2, USBDDR          ;[-10] 10 cycles until SOP
 
 575     ori     x2, USBMASK         ;[-9]
 
 576     sbi     USBOUT, USBMINUS    ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups)
 
 577     out     USBDDR, x2          ;[-6] <--- acquire bus
 
 578     in      x1, USBOUT          ;[-5] port mirror for tx loop
 
 579     ldi     shift, 0x40         ;[-4] sync byte is first byte sent (we enter loop after ror)
 
 580     ldi     x2, USBMASK         ;[-3]
 
 582     eor     x1, x2              ;[-2] [06] [62]
 
 583     ldi     x3, 6               ;[-1] [07] [63]
 
 586     out     USBOUT, x1          ;[00] [08] [64] <--- set bit
 
 591     lsl     shift               ;[05] compensate ror after rjmp stuffDelay
 
 592     rjmp    stuffN2Delay        ;[06] after ror, C bit is reliably clear
 
 594     eor     x1, x2              ;[04] [12]
 
 598     subi    cnt, 171            ;[08] [16] trick: (3 * 171) & 0xff = 1
 
 599     out     USBOUT, x1          ;[09] [17] <--- set bit
 
 600     brcs    txBitloop           ;[10]      [27] [44]
 
 607     lsl     shift               ;[49] compensate ror after rjmp stuffDelay
 
 608     nop                         ;[50] stuffing consists of just waiting 8 cycles
 
 609     rjmp    stuff6Delay         ;[51] after ror, C bit is reliably clear
 
 611     eor     x1, x2              ;[48] [56]
 
 616     out     USBOUT, x1          ;[51] <--- set bit
 
 620     lsl     shift               ;[55] compensate ror after rjmp stuffDelay
 
 621     rjmp    stuff7Delay         ;[56] after ror, C bit is reliably clear
 
 623     eor     x1, x2              ;[54] [62]
 
 629     out     USBOUT, x1          ;[60] [00]<--- set bit
 
 630     brne    txByteLoop          ;[61] [01]
 
 632     cbr     x1, USBMASK         ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles]
 
 633     lds     x2, usbNewDeviceAddr;[03]
 
 634     lsl     x2                  ;[05] we compare with left shifted address
 
 635     subi    YL, 2 + 0           ;[06] Only assign address on data packets, not ACK/NAK in r0
 
 637     out     USBOUT, x1          ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
 
 638 ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
 
 639 ;set address only after data packet was sent, not after handshake
 
 640     breq    skipAddrAssign      ;[01]
 
 641     sts     usbDeviceAddr, x2   ; if not skipped: SE0 is one cycle longer
 
 643 ;end of usbDeviceAddress transfer
 
 644     ldi     x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag
 
 645     USB_STORE_PENDING(x2)       ;[04]
 
 646     ori     x1, USBIDLE         ;[05]
 
 648     cbr     x2, USBMASK         ;[07] set both pins to input
 
 650     cbr     x3, USBMASK         ;[09] configure no pullup on both pins
 
 653     out     USBOUT, x1          ;[16] <-- out J (idle) -- end of SE0 (EOP signal)
 
 654     out     USBDDR, x2          ;[17] <-- release bus now
 
 655     out     USBOUT, x3          ;[18] <-- ensure no pull-up resistors are active
 
 660 /*****************************************************************************
 
 661 The following PHP script generates a code skeleton for the receiver routine:
 
 665 function printCmdBuffer($thisBit)
 
 669     $nextBit = ($thisBit + 1) % 8;
 
 670     $s = ob_get_contents();
 
 672     $s = str_replace("#", $thisBit, $s);
 
 673     $s = str_replace("@", $nextBit, $s);
 
 674     $lines = explode("\n", $s);
 
 675     for($i = 0; $i < count($lines); $i++){
 
 677         if(ereg("\\[([0-9-][0-9])\\]", $s, $regs)){
 
 678             $c = $cycle + (int)$regs[1];
 
 679             $s = ereg_replace("\\[[0-9-][0-9]\\]", sprintf("[%02d]", $c), $s);
 
 686 function printBit($isAfterSet, $bitNum)
 
 691     ifioclr USBIN, USBMINUS     ;[00] <--- sample
 
 693     andi    shift, ~(7 << #)    ;[02]
 
 695     in      phase, USBIN        ;[04] <- phase
 
 696     rjmp    bit@AfterSet        ;[05]
 
 698     in      phase, USBIN        ;[05] <- phase (one cycle too late)
 
 699     andi    fix, ~(1 << #)      ;[06]
 
 703     ifrset  phase, USBMINUS     ;[03] check phase only if D- changed
 
 705     in      phase, USBIN        ;[05] <- phase (one cycle too late)
 
 706     ori     shift, 1 << #       ;[06]
 
 710     ifioset USBIN, USBMINUS     ;[00] <--- sample
 
 712     andi    shift, ~(7 << #)    ;[02]
 
 714     in      phase, USBIN        ;[04] <- phase
 
 715     rjmp    bit@AfterClr        ;[05]
 
 717     in      phase, USBIN        ;[05] <- phase (one cycle too late)
 
 718     andi    fix, ~(1 << #)      ;[06]
 
 722     ifrclr  phase, USBMINUS     ;[03] check phase only if D- changed
 
 724     in      phase, USBIN        ;[05] <- phase (one cycle too late)
 
 725     ori     shift, 1 << #       ;[06]
 
 728     printCmdBuffer($bitNum);
 
 731 $bitStartCycles = array(1, 9, 17, 26, 34, 42, 51, 59);
 
 732 for($i = 0; $i < 16; $i++){
 
 734     $emitClrCode = ($i + (int)($i / 8)) % 2;
 
 735     $cycle = $bitStartCycles[$bit];
 
 737         printf("bit%dAfterClr:\n", $bit);
 
 739         printf("bit%dAfterSet:\n", $bit);
 
 742     echo "    *****                       ;[-1]\n";
 
 743     printCmdBuffer($bit);
 
 744     printBit(!$emitClrCode, $bit);
 
 750 *****************************************************************************/