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

📄 usbdrvasm12.s

📁 从一个德国人网站上下载的基于6813的USB转并口的驱动和源码
💻 S
📖 第 1 页 / 共 2 页
字号:
ignorePacket:    clr     shift    sts     usbCurrentTok, shiftdoReturn:    pop     cnt    pop     x3    pop     x2    pop     x1    pop     shift    pop     YHsofError:    pop     YL    out     SREG, YL    pop     YL    reti#if USB_CFG_HAVE_INTRIN_ENDPOINT && USB_CFG_HAVE_INTRIN_ENDPOINT3handleIn3:                      ;1 [38] (branch taken)    lds     cnt, usbTxLen3      ;2 [40]    sbrc    cnt, 4              ;2 [42]    rjmp    sendCntAndReti      ;0 43 + 17 = 60 until SOP    sts     usbTxLen3, x1       ;2 [44] x1 == USBPID_NAK from above    ldi     YL, lo8(usbTxBuf3)  ;1 [45]    ldi     YH, hi8(usbTxBuf3)  ;1 [46]    rjmp    usbSendAndReti      ;2 [48] + 13 = 61 until SOP (violates the spec by 1 cycle)#endif;Setup and Out are followed by a data packet two bit times (16 cycles) after;the end of SE0. The sync code allows up to 40 cycles delay from the start of;the sync pattern until the first bit is sampled. That's a total of 56 cycles.handleSetupOrOut:               ;1 [29] (branch taken)#if USB_CFG_IMPLEMENT_FN_WRITEOUT   /* if we have data for second OUT endpoint, set usbCurrentTok to -1 */    sbrc    x3, 7               ;1 [30] skip if endpoint 0    ldi     token, -1           ;1 [31] indicate that this is endpoint 1 OUT#endif    sts     usbCurrentTok, token;2 [33]    pop     cnt                 ;2 [35]    pop     x3                  ;2 [37]    pop     x2                  ;2 [39]    pop     x1                  ;2 [41]    pop     shift               ;2 [43]    pop     YH                  ;2 [45]    USB_LOAD_PENDING(YL)        ;1 [46]    sbrc    YL, USB_INTR_PENDING_BIT;1 [47] check whether data is already arriving    rjmp    waitForJ            ;2 [49] save the pops and pushes -- a new interrupt is aready pending    rjmp    sofError            ;2 not an error, but it does the pops and reti we wanthandleData:                     ;1 [15] (branch taken)    lds     token, usbCurrentTok;2 [17]    tst     token               ;1 [18]    breq    doReturn            ;1 [19]    lds     x2, usbRxLen        ;2 [21]    tst     x2                  ;1 [22]    brne    sendNakAndReti      ;1 [23]; 2006-03-11: The following two lines fix a problem where the device was not; recognized if usbPoll() was called less frequently than once every 4 ms.    cpi     cnt, 4              ;1 [24] zero sized data packets are status phase only -- ignore and ack    brmi    sendAckAndReti      ;1 [25] keep rx buffer clean -- we must not NAK next SETUP    sts     usbRxLen, cnt       ;2 [27] store received data, swap buffers    sts     usbRxToken, token   ;2 [29]    lds     x2, usbInputBufOffset;2 [31] swap buffers    ldi     cnt, USB_BUFSIZE    ;1 [32]    sub     cnt, x2             ;1 [33]    sts     usbInputBufOffset, cnt;2 [35] buffers now swapped    rjmp    sendAckAndReti      ;2 [37] + 19 = 56 until SOPhandleIn:                       ;1 [25] (branch taken);We don't send any data as long as the C code has not processed the current;input data and potentially updated the output data. That's more efficient;in terms of code size than clearing the tx buffers when a packet is received.    lds     x1, usbRxLen        ;2 [27]    cpi     x1, 1               ;1 [28] negative values are flow control, 0 means "buffer free"    brge    sendNakAndReti      ;1 [29] unprocessed input packet?    ldi     x1, USBPID_NAK      ;1 [30] prepare value for usbTxLen#if USB_CFG_HAVE_INTRIN_ENDPOINT    sbrc    x3, 7               ;2 [33] x3 contains addr + endpoint    rjmp    handleIn1           ;0#endif    lds     cnt, usbTxLen       ;2 [34]    sbrc    cnt, 4              ;2 [36] all handshake tokens have bit 4 set    rjmp    sendCntAndReti      ;0 37 + 17 = 54 until SOP    sts     usbTxLen, x1        ;2 [38] x1 == USBPID_NAK from above    ldi     YL, lo8(usbTxBuf)   ;1 [39]    ldi     YH, hi8(usbTxBuf)   ;1 [40]    rjmp    usbSendAndReti      ;2 [42] + 14 = 56 until SOP; Comment about when to set usbTxLen to USBPID_NAK:; We should set it back when we receive the ACK from the host. This would; be simple to implement: One static variable which stores whether the last; tx was for endpoint 0 or 1 and a compare in the receiver to distinguish the; ACK. However, we set it back immediately when we send the package,; assuming that no error occurs and the host sends an ACK. We save one byte; RAM this way and avoid potential problems with endless retries. The rest of; the driver assumes error-free transfers anyway.#if USB_CFG_HAVE_INTRIN_ENDPOINT    /* placed here due to relative jump range */handleIn1:                      ;1 [33] (branch taken)#if USB_CFG_HAVE_INTRIN_ENDPOINT3; 2006-06-10 as suggested by O.Tamura: support second INTR IN / BULK IN endpoint    ldd     x2, y+2             ;2 [35]    sbrc    x2, 0               ;2 [37]    rjmp    handleIn3           ;0#endif    lds     cnt, usbTxLen1      ;2 [39]    sbrc    cnt, 4              ;2 [41] all handshake tokens have bit 4 set    rjmp    sendCntAndReti      ;0 42 + 17 = 59 until SOP    sts     usbTxLen1, x1       ;2 [43] x1 == USBPID_NAK from above    ldi     YL, lo8(usbTxBuf1)  ;1 [44]    ldi     YH, hi8(usbTxBuf1)  ;1 [45]    rjmp    usbSendAndReti      ;2 [47] + 13 = 60 until SOP#endif;----------------------------------------------------------------------------; Transmitting data;----------------------------------------------------------------------------bitstuff0:                  ;1 (for branch taken)    eor     x1, x4          ;1    ldi     x2, 0           ;1    out     USBOUT, x1      ;1 <-- out    rjmp    didStuff0       ;2 branch back 2 cycles earlierbitstuff1:                  ;1 (for branch taken)    eor     x1, x4          ;1    rjmp    didStuff1       ;2 we know that C is clear, jump back to do OUT and ror 0 into x2bitstuff2:                  ;1 (for branch taken)    eor     x1, x4          ;1    rjmp    didStuff2       ;2 jump back 4 cycles earlier and do out and ror 0 into x2bitstuff3:                  ;1 (for branch taken)    eor     x1, x4          ;1    rjmp    didStuff3       ;2 jump back earlier and ror 0 into x2bitstuff4:                  ;1 (for branch taken)    eor     x1, x4          ;1    ldi     x2, 0           ;1    out     USBOUT, x1      ;1 <-- out    rjmp    didStuff4       ;2 jump back 2 cycles earliersendNakAndReti:                 ;0 [-19] 19 cycles until SOP    ldi     x3, USBPID_NAK      ;1 [-18]    rjmp    usbSendX3           ;2 [-16]sendAckAndReti:                 ;0 [-19] 19 cycles until SOP    ldi     x3, USBPID_ACK      ;1 [-18]    rjmp    usbSendX3           ;2 [-16]sendCntAndReti:                 ;0 [-17] 17 cycles until SOP    mov     x3, cnt             ;1 [-16]usbSendX3:                      ;0 [-16]    ldi     YL, 20              ;1 [-15] 'x3' is R20    ldi     YH, 0               ;1 [-14]    ldi     cnt, 2              ;1 [-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...x4, shift, cnt, Y;Numbers in brackets are time since first bit of sync pattern is sentusbSendAndReti:             ;0 [-13] timing: 13 cycles until SOP    in      x2, USBDDR      ;1 [-12]    ori     x2, USBMASK     ;1 [-11]    sbi     USBOUT, USBMINUS;2 [-9] prepare idle state; D+ and D- must have been 0 (no pullups)    in      x1, USBOUT      ;1 [-8] port mirror for tx loop    out     USBDDR, x2      ;1 [-7] <- acquire bus; need not init x2 (bitstuff history) because sync starts with 0    push    x4              ;2 [-5]    ldi     x4, USBMASK     ;1 [-4] exor mask    ldi     shift, 0x80     ;1 [-3] sync byte is first byte senttxLoop:                     ;       [62]    sbrs    shift, 0        ;1 [-2] [62]    eor     x1, x4          ;1 [-1] [63]    out     USBOUT, x1      ;1 [0] <-- out bit 0    ror     shift           ;1 [1]    ror     x2              ;1 [2]didStuff0:    cpi     x2, 0xfc        ;1 [3]    brsh    bitstuff0       ;1 [4]    sbrs    shift, 0        ;1 [5]    eor     x1, x4          ;1 [6]    ror     shift           ;1 [7]didStuff1:    out     USBOUT, x1      ;1 [8] <-- out bit 1    ror     x2              ;1 [9]    cpi     x2, 0xfc        ;1 [10]    brsh    bitstuff1       ;1 [11]    sbrs    shift, 0        ;1 [12]    eor     x1, x4          ;1 [13]    ror     shift           ;1 [14]didStuff2:    ror     x2              ;1 [15]    out     USBOUT, x1      ;1 [16] <-- out bit 2    cpi     x2, 0xfc        ;1 [17]    brsh    bitstuff2       ;1 [18]    sbrs    shift, 0        ;1 [19]    eor     x1, x4          ;1 [20]    ror     shift           ;1 [21]didStuff3:    ror     x2              ;1 [22]    cpi     x2, 0xfc        ;1 [23]    out     USBOUT, x1      ;1 [24] <-- out bit 3    brsh    bitstuff3       ;1 [25]    nop2                    ;2 [27]    ld      x3, y+          ;2 [29]    sbrs    shift, 0        ;1 [30]    eor     x1, x4          ;1 [31]    out     USBOUT, x1      ;1 [32] <-- out bit 4    ror     shift           ;1 [33]    ror     x2              ;1 [34]didStuff4:    cpi     x2, 0xfc        ;1 [35]    brsh    bitstuff4       ;1 [36]    sbrs    shift, 0        ;1 [37]    eor     x1, x4          ;1 [38]    ror     shift           ;1 [39]didStuff5:    out     USBOUT, x1      ;1 [40] <-- out bit 5    ror     x2              ;1 [41]    cpi     x2, 0xfc        ;1 [42]    brsh    bitstuff5       ;1 [43]    sbrs    shift, 0        ;1 [44]    eor     x1, x4          ;1 [45]    ror     shift           ;1 [46]didStuff6:    ror     x2              ;1 [47]    out     USBOUT, x1      ;1 [48] <-- out bit 6    cpi     x2, 0xfc        ;1 [49]    brsh    bitstuff6       ;1 [50]    sbrs    shift, 0        ;1 [51]    eor     x1, x4          ;1 [52]    ror     shift           ;1 [53]didStuff7:    ror     x2              ;1 [54]    cpi     x2, 0xfc        ;1 [55]    out     USBOUT, x1      ;1 [56] <-- out bit 7    brsh    bitstuff7       ;1 [57]    mov     shift, x3       ;1 [58]    dec     cnt             ;1 [59]    brne    txLoop          ;1/2 [60/61];make SE0:    cbr     x1, USBMASK     ;1 [61] prepare SE0 [spec says EOP may be 15 to 18 cycles]    pop     x4              ;2 [63];brackets are cycles from start of SE0 now    out     USBOUT, x1      ;1 [0] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle    nop2                    ;2 [2];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    lds     x2, usbNewDeviceAddr;2 [4]    subi    YL, 20 + 2      ;1 [5]    sbci    YH, 0           ;1 [6]    breq    skipAddrAssign  ;2 [8]    sts     usbDeviceAddr, x2;0  if not skipped: SE0 is one cycle longerskipAddrAssign:;end of usbDeviceAddress transfer    ldi     x2, 1<<USB_INTR_PENDING_BIT;1 [9] int0 occurred during TX -- clear pending flag    USB_STORE_PENDING(x2)   ;1 [10]    ori     x1, USBIDLE     ;1 [11]    in      x2, USBDDR      ;1 [12]    cbr     x2, USBMASK     ;1 [13] set both pins to input    mov     x3, x1          ;1 [14]    cbr     x3, USBMASK     ;1 [15] configure no pullup on both pins    out     USBOUT, x1      ;1 [16] <-- out J (idle) -- end of SE0 (EOP signal)    out     USBDDR, x2      ;1 [17] <-- release bus now    out     USBOUT, x3      ;1 [18] <-- ensure no pull-up resistors are active    rjmp    doReturnbitstuff5:                  ;1 (for branch taken)    eor     x1, x4          ;1    rjmp    didStuff5       ;2 same trick as above...bitstuff6:                  ;1 (for branch taken)    eor     x1, x4          ;1    rjmp    didStuff6       ;2 same trick as above...bitstuff7:                  ;1 (for branch taken)    eor     x1, x4          ;1    rjmp    didStuff7       ;2 same trick as above...

⌨️ 快捷键说明

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