⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbdrvasm128.inc

📁 USBasp
💻 INC
📖 第 1 页 / 共 2 页
字号:
    breq    unstuff0c           ;[04]    in      phase, USBIN        ;[05] <- phase    rjmp    bit1AfterClr        ;[06]unstuff0c:    in      phase, USBIN        ;[06] <- phase (one cycle too late)    andi    fix, ~(1 << 0)      ;[07]    ifioclr USBIN, USBMINUS     ;[00]    ifioset USBIN, USBPLUS      ;[01]    rjmp    bit0IsSet           ;[02] executed if first expr false or second true    rjmp    se0AndStore         ;[03] executed only if both bits 0bit0IsSet:    ifrclr  phase, USBMINUS     ;[04] check phase only if D- changed    lpm                         ;[05]    in      phase, USBIN        ;[06] <- phase (one cycle too late)    ori     shift, 1 << 0       ;[07]bit1AfterSet:    andi    phase, USBMASK      ;[08]    ifioclr USBIN, USBMINUS     ;[09] <--- sample 1    rjmp    bit1IsClr           ;[10]    andi    shift, ~(7 << 1)    ;[11]    breq    unstuff1s           ;[12]    in      phase, USBIN        ;[13] <- phase    nop                         ;[14]    rjmp    bit2AfterSet        ;[15]unstuff1s:    in      phase, USBIN        ;[14] <- phase (one cycle too late)    andi    fix, ~(1 << 1)      ;[15]    nop2                        ;[08]    nop2                        ;[10]bit1IsClr:    ifrset  phase, USBMINUS     ;[12] check phase only if D- changed    lpm                         ;[13]    in      phase, USBIN        ;[14] <- phase (one cycle too late)    breq    se0AndStore         ;[15] if we come from unstuff1s, Z bit is never set    ori     shift, 1 << 1       ;[16]bit2AfterClr:    ifioset USBIN, USBMINUS     ;[17] <--- sample 2    rjmp    bit2IsSet           ;[18]    andi    shift, ~(7 << 2)    ;[19]    breq    unstuff2c           ;[20]    in      phase, USBIN        ;[21] <- phase    rjmp    bit3AfterClr        ;[22]unstuff2c:    in      phase, USBIN        ;[22] <- phase (one cycle too late)    andi    fix, ~(1 << 2)      ;[23]    nop2                        ;[16]    nop2                        ;[18]bit2IsSet:    ifrclr  phase, USBMINUS     ;[20] check phase only if D- changed    lpm                         ;[21]    in      phase, USBIN        ;[22] <- phase (one cycle too late)    ori     shift, 1 << 2       ;[23]bit3AfterSet:    st      y+, data            ;[24]entryAfterSet:    ifioclr USBIN, USBMINUS     ;[26] <--- sample 3    rjmp    bit3IsClr           ;[27]    andi    shift, ~(7 << 3)    ;[28]    breq    unstuff3s           ;[29]    in      phase, USBIN        ;[30] <- phase    rjmp    bit4AfterSet        ;[31]unstuff3s:    in      phase, USBIN        ;[31] <- phase (one cycle too late)    andi    fix, ~(1 << 3)      ;[32]    nop2                        ;[25]    nop2                        ;[27]bit3IsClr:    ifrset  phase, USBMINUS     ;[29] check phase only if D- changed    lpm                         ;[30]    in      phase, USBIN        ;[31] <- phase (one cycle too late)    ori     shift, 1 << 3       ;[32]bit4AfterClr:    mov     data, fix           ;[33] undo this move by swapping defines#undef  fix#define fix     x1#undef  data#define data    x2    ifioset USBIN, USBMINUS     ;[34] <--- sample 4    rjmp    bit4IsSet           ;[35]    andi    shift, ~(7 << 4)    ;[36]    breq    unstuff4c           ;[37]    in      phase, USBIN        ;[38] <- phase    rjmp    bit5AfterClr        ;[39]unstuff4c:    in      phase, USBIN        ;[39] <- phase (one cycle too late)    andi    fix, ~(1 << 4)      ;[40]    nop2                        ;[33]    nop2                        ;[35]bit4IsSet:    ifrclr  phase, USBMINUS     ;[37] check phase only if D- changed    lpm                         ;[38]    in      phase, USBIN        ;[39] <- phase (one cycle too late)    ori     shift, 1 << 4       ;[40]bit5AfterSet:    ser     data                ;[41]    ifioclr USBIN, USBMINUS     ;[42] <--- sample 5    rjmp    bit5IsClr           ;[43]    andi    shift, ~(7 << 5)    ;[44]    breq    unstuff5s           ;[45]    in      phase, USBIN        ;[46] <- phase    rjmp    bit6AfterSet        ;[47]unstuff5s:    in      phase, USBIN        ;[47] <- phase (one cycle too late)    andi    fix, ~(1 << 5)      ;[48]    nop2                        ;[41]    nop2                        ;[43]bit5IsClr:    ifrset  phase, USBMINUS     ;[45] check phase only if D- changed    lpm                         ;[46]    in      phase, USBIN        ;[47] <- phase (one cycle too late)    ori     shift, 1 << 5       ;[48]bit6AfterClr:    subi    cnt, 1              ;[49]    brcs    overflow            ;[50]    ifioset USBIN, USBMINUS     ;[51] <--- sample 6    rjmp    bit6IsSet           ;[52]    andi    shift, ~(3 << 6)    ;[53]    cpi     shift, 2            ;[54]    in      phase, USBIN        ;[55] <- phase    brlt    unstuff6c           ;[56]    rjmp    bit7AfterClr        ;[57]unstuff6c:    andi    fix, ~(1 << 6)      ;[50]    lpm                         ;[51]bit6IsSet:    ifrclr  phase, USBMINUS     ;[54] check phase only if D- changed    lpm                         ;[55]    in      phase, USBIN        ;[56] <- phase (one cycle too late)    ori     shift, 1 << 6       ;[57]bit7AfterSet:    ifioclr USBIN, USBMINUS     ;[59] <--- sample 7    rjmp    bit7IsClr           ;[60]    andi    shift, ~(1 << 7)    ;[61]    cpi     shift, 4            ;[62]    in      phase, USBIN        ;[63] <- phase    brlt    unstuff7s           ;[64]    rjmp    bit0AfterSet        ;[65] -> [00] == [67]unstuff7s:    andi    fix, ~(1 << 7)      ;[58]    nop                         ;[59]    rjmp    bit7IsClr           ;[60]macro POP_STANDARD ; 14 cycles    pop     r0    pop     cnt    pop     x3    pop     x2    pop     x1    pop     shift    pop     YH    endmmacro POP_RETI     ; 5 cycles    pop     YL    out     SREG, YL    pop     YL    endm#include "asmcommon.inc";----------------------------------------------------------------------------; Transmitting data;----------------------------------------------------------------------------txByteLoop:txBitloop:stuffN1Delay:                   ;     [03]    ror     shift               ;[-5] [11] [63]    brcc    doExorN1            ;[-4]      [64]    subi    x3, 1               ;[-3]    brne    commonN1            ;[-2]    lsl     shift               ;[-1] compensate ror after rjmp stuffDelay    nop                         ;[00] stuffing consists of just waiting 8 cycles    rjmp    stuffN1Delay        ;[01] after ror, C bit is reliably clearsendNakAndReti:    ldi     cnt, USBPID_NAK ;[-19]    rjmp    sendCntAndReti  ;[-18]sendAckAndReti:    ldi     cnt, USBPID_ACK ;[-17]sendCntAndReti:    mov     r0, cnt         ;[-16]    ldi     YL, 0           ;[-15] R0 address is 0    ldi     YH, 0           ;[-14]    ldi     cnt, 2          ;[-13];   rjmp    usbSendAndReti      fallthrough; USB spec says:; idle = J; J = (D+ = 0), (D- = 1) or USBOUT = 0x01; K = (D+ = 1), (D- = 0) or USBOUT = 0x02; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles);usbSend:;pointer to data in 'Y';number of bytes in 'cnt' -- including sync byte;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt];Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)usbSendAndReti:    in      x2, USBDDR          ;[-10] 10 cycles until SOP    ori     x2, USBMASK         ;[-9]    sbi     USBOUT, USBMINUS    ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups)    out     USBDDR, x2          ;[-6] <--- acquire bus    in      x1, USBOUT          ;[-5] port mirror for tx loop    ldi     shift, 0x40         ;[-4] sync byte is first byte sent (we enter loop after ror)    ldi     x2, USBMASK         ;[-3]doExorN1:    eor     x1, x2              ;[-2] [06] [62]    ldi     x3, 6               ;[-1] [07] [63]commonN1:stuffN2Delay:    out     USBOUT, x1          ;[00] [08] [64] <--- set bit    ror     shift               ;[01]    brcc    doExorN2            ;[02]    subi    x3, 1               ;[03]    brne    commonN2            ;[04]    lsl     shift               ;[05] compensate ror after rjmp stuffDelay    rjmp    stuffN2Delay        ;[06] after ror, C bit is reliably cleardoExorN2:    eor     x1, x2              ;[04] [12]    ldi     x3, 6               ;[05] [13]commonN2:    nop2                        ;[06] [14]    subi    cnt, 171            ;[08] [16] trick: (3 * 171) & 0xff = 1    out     USBOUT, x1          ;[09] [17] <--- set bit    brcs    txBitloop           ;[10]      [27] [44]stuff6Delay:    ror     shift               ;[45] [53]    brcc    doExor6             ;[46]    subi    x3, 1               ;[47]    brne    common6             ;[48]    lsl     shift               ;[49] compensate ror after rjmp stuffDelay    nop                         ;[50] stuffing consists of just waiting 8 cycles    rjmp    stuff6Delay         ;[51] after ror, C bit is reliably cleardoExor6:    eor     x1, x2              ;[48] [56]    ldi     x3, 6               ;[49]common6:stuff7Delay:    ror     shift               ;[50] [58]    out     USBOUT, x1          ;[51] <--- set bit    brcc    doExor7             ;[52]    subi    x3, 1               ;[53]    brne    common7             ;[54]    lsl     shift               ;[55] compensate ror after rjmp stuffDelay    rjmp    stuff7Delay         ;[56] after ror, C bit is reliably cleardoExor7:    eor     x1, x2              ;[54] [62]    ldi     x3, 6               ;[55]common7:    ld      shift, y+           ;[56]    nop                         ;[58]    tst     cnt                 ;[59]    out     USBOUT, x1          ;[60] [00]<--- set bit    brne    txByteLoop          ;[61] [01];make SE0:    cbr     x1, USBMASK         ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles]    lds     x2, usbNewDeviceAddr;[03]    lsl     x2                  ;[05] we compare with left shifted address    subi    YL, 2 + 0           ;[06] Only assign address on data packets, not ACK/NAK in r0    sbci    YH, 0               ;[07]    out     USBOUT, x1          ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:;set address only after data packet was sent, not after handshake    breq    skipAddrAssign      ;[01]    sts     usbDeviceAddr, x2   ; if not skipped: SE0 is one cycle longerskipAddrAssign:;end of usbDeviceAddress transfer    ldi     x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag    USB_STORE_PENDING(x2)       ;[04]    ori     x1, USBIDLE         ;[05]    in      x2, USBDDR          ;[06]    cbr     x2, USBMASK         ;[07] set both pins to input    mov     x3, x1              ;[08]    cbr     x3, USBMASK         ;[09] configure no pullup on both pins    lpm                         ;[10]    lpm                         ;[13]    out     USBOUT, x1          ;[16] <-- out J (idle) -- end of SE0 (EOP signal)    out     USBDDR, x2          ;[17] <-- release bus now    out     USBOUT, x3          ;[18] <-- ensure no pull-up resistors are active    rjmp    doReturn/*****************************************************************************The following PHP script generates a code skeleton for the receiver routine:<?phpfunction printCmdBuffer($thisBit){global $cycle;    $nextBit = ($thisBit + 1) % 8;    $s = ob_get_contents();    ob_end_clean();    $s = str_replace("#", $thisBit, $s);    $s = str_replace("@", $nextBit, $s);    $lines = explode("\n", $s);    for($i = 0; $i < count($lines); $i++){        $s = $lines[$i];        if(ereg("\\[([0-9-][0-9])\\]", $s, $regs)){            $c = $cycle + (int)$regs[1];            $s = ereg_replace("\\[[0-9-][0-9]\\]", sprintf("[%02d]", $c), $s);        }        if(strlen($s) > 0)            echo "$s\n";    }}function printBit($isAfterSet, $bitNum){    ob_start();    if($isAfterSet){?>    ifioclr USBIN, USBMINUS     ;[00] <--- sample    rjmp    bit#IsClr           ;[01]    andi    shift, ~(7 << #)    ;[02]    breq    unstuff#s           ;[03]    in      phase, USBIN        ;[04] <- phase    rjmp    bit@AfterSet        ;[05]unstuff#s:    in      phase, USBIN        ;[05] <- phase (one cycle too late)    andi    fix, ~(1 << #)      ;[06]    nop2                        ;[-1]    nop2                        ;[01]bit#IsClr:    ifrset  phase, USBMINUS     ;[03] check phase only if D- changed    lpm                         ;[04]    in      phase, USBIN        ;[05] <- phase (one cycle too late)    ori     shift, 1 << #       ;[06]<?php    }else{?>    ifioset USBIN, USBMINUS     ;[00] <--- sample    rjmp    bit#IsSet           ;[01]    andi    shift, ~(7 << #)    ;[02]    breq    unstuff#c           ;[03]    in      phase, USBIN        ;[04] <- phase    rjmp    bit@AfterClr        ;[05]unstuff#c:    in      phase, USBIN        ;[05] <- phase (one cycle too late)    andi    fix, ~(1 << #)      ;[06]    nop2                        ;[-1]    nop2                        ;[01]bit#IsSet:    ifrclr  phase, USBMINUS     ;[03] check phase only if D- changed    lpm                         ;[04]    in      phase, USBIN        ;[05] <- phase (one cycle too late)    ori     shift, 1 << #       ;[06]<?php    }    printCmdBuffer($bitNum);}$bitStartCycles = array(1, 9, 17, 26, 34, 42, 51, 59);for($i = 0; $i < 16; $i++){    $bit = $i % 8;    $emitClrCode = ($i + (int)($i / 8)) % 2;    $cycle = $bitStartCycles[$bit];    if($emitClrCode){        printf("bit%dAfterClr:\n", $bit);    }else{        printf("bit%dAfterSet:\n", $bit);    }    ob_start();    echo "    *****                       ;[-1]\n";    printCmdBuffer($bit);    printBit(!$emitClrCode, $bit);    if($i == 7)        echo "\n";}?>*****************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -