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

📄 usbdrvasm165.s

📁 从一个德国人网站上下载的基于6813的USB转并口的驱动和源码
💻 S
📖 第 1 页 / 共 2 页
字号:
/* Name: usbdrvasm165.S * Project: AVR USB driver * Author: Christian Starkjohann * Creation Date: 2007-04-22 * Tabsize: 4 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) * Revision: $Id$ *//* Do not link this file! Link usbdrvasm.S instead, which includes the * appropriate implementation! *//*General Description:This file is the 16.5 MHz version of the USB driver. It is intended for theATTiny45 and similar controllers running on 16.5 MHz internal RC oscillator.This version contains a phase locked loop in the receiver routine to cope withslight clock rate deviations of up to +/- 1%.See usbdrv.h for a description of the entire driver.Since almost all of this code is timing critical, don't change unless youreally know what you are doing! Many parts require not only a maximum numberof CPU cycles, but even an exact number of cycles!*/;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled;max allowable interrupt latency: 59 cycles -> max 52 cycles interrupt disable;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes;nominal frequency: 16.5 MHz -> 11 cycles per bit; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%); Numbers in brackets are clocks counted from center of last sync bit; when instruction startsUSB_INTR_VECTOR:;order of registers pushed: r0, SREG [sofError], YL, YH, shift, x1, x2, x3, x4, cnt    push    r0                  ;[-23] push only what is necessary to sync with edge ASAP    in      r0, SREG            ;[-21]    push    r0                  ;[-20];----------------------------------------------------------------------------; Synchronize with sync pattern:;----------------------------------------------------------------------------;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K];sync up with J to K edge during sync pattern -- use fastest possible loops;first part has no timeout because it waits for IDLE or SE1 (== disconnected)waitForJ:    sbis    USBIN, USBMINUS     ;[-18] wait for D- == 1    rjmp    waitForJwaitForK:;The following code results in a sampling window of < 1/4 bit which meets the spec.    sbis    USBIN, USBMINUS     ;[-15]    rjmp    foundK              ;[-14]    sbis    USBIN, USBMINUS    rjmp    foundK    sbis    USBIN, USBMINUS    rjmp    foundK    sbis    USBIN, USBMINUS    rjmp    foundK    sbis    USBIN, USBMINUS    rjmp    foundK    sbis    USBIN, USBMINUS    rjmp    foundK#if USB_COUNT_SOF    lds     YL, usbSofCount    inc     YL    sts     usbSofCount, YL#endif  /* USB_COUNT_SOF */    rjmp    sofErrorfoundK:                         ;[-12];{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling];we have 1 bit time for setup purposes, then sample again. Numbers in brackets;are cycles from center of first sync (double K) bit after the instruction    push    YL                  ;[-12];   [---]                       ;[-11]    push    YH                  ;[-10];   [---]                       ;[-9]    lds     YL, usbInputBufOffset;[-8];   [---]                       ;[-7]    clr     YH                  ;[-6]    subi    YL, lo8(-(usbRxBuf));[-5] [rx loop init]    sbci    YH, hi8(-(usbRxBuf));[-4] [rx loop init]    mov     r0, x2              ;[-3] [rx loop init]    sbis    USBIN, USBMINUS     ;[-2] we want two bits K (sample 2 cycles too early)    rjmp    haveTwoBitsK        ;[-1]    pop     YH                  ;[0] undo the pushes from before    pop     YL                  ;[2]    rjmp    waitForK            ;[4] this was not the end of sync, retry; The entire loop from waitForK until rjmp waitForK above must not exceed two; bit times (= 22 cycles).;----------------------------------------------------------------------------; push more registers and initialize values while we sample the first bits:;----------------------------------------------------------------------------haveTwoBitsK:               ;[1]    push    shift           ;[1]    push    x1              ;[3]    push    x2              ;[5]    push    x3              ;[7]    ldi     shift, 0xff     ;[9] [rx loop init]    ori     x3, 0xff        ;[10] [rx loop init] == ser x3, clear zero flag    in      x1, USBIN       ;[11] <-- sample bit 0    bst     x1, USBMINUS    ;[12]    bld     shift, 0        ;[13]    push    x4              ;[14] == phase;   [---]                   ;[15]    push    cnt             ;[16];   [---]                   ;[17]    ldi     phase, 0        ;[18] [rx loop init]    ldi     cnt, USB_BUFSIZE;[19] [rx loop init]    rjmp    rxbit1          ;[20];   [---]                   ;[21];----------------------------------------------------------------------------; Receiver loop (numbers in brackets are cycles within byte after instr);----------------------------------------------------------------------------/*byte oriented operations done during loop:bit 0: store databit 1: SE0 checkbit 2: overflow checkbit 3: catch upbit 4: rjmp to achieve conditional jump rangebit 5: PLLbit 6: catch upbit 7: jump, fixup bitstuff; 87 [+ 2] cycles------------------------------------------------------------------*/continueWithBit5:    in      x2, USBIN       ;[055] <-- bit 5    eor     r0, x2          ;[056]    or      phase, r0       ;[057]    sbrc    phase, USBMINUS ;[058]    lpm                     ;[059] optional nop3; modifies r0    in      phase, USBIN    ;[060] <-- phase    eor     x1, x2          ;[061]    bst     x1, USBMINUS    ;[062]    bld     shift, 5        ;[063]    andi    shift, 0x3f     ;[064]    in      x1, USBIN       ;[065] <-- bit 6    breq    unstuff5        ;[066] *** unstuff escape    eor     phase, x1       ;[067]    eor     x2, x1          ;[068]    bst     x2, USBMINUS    ;[069]    bld     shift, 6        ;[070]didUnstuff6:                ;[   ]    in      r0, USBIN       ;[071] <-- phase    cpi     shift, 0x02     ;[072]    brlo    unstuff6        ;[073] *** unstuff escapedidUnstuff5:                ;[   ]    nop2                    ;[074];   [---]                   ;[075]    in      x2, USBIN       ;[076] <-- bit 7    eor     x1, x2          ;[077]    bst     x1, USBMINUS    ;[078]    bld     shift, 7        ;[079]didUnstuff7:                ;[   ]    eor     r0, x2          ;[080]    or      phase, r0       ;[081]    in      r0, USBIN       ;[082] <-- phase    cpi     shift, 0x04     ;[083]    brsh    rxLoop          ;[084];   [---]                   ;[085]unstuff7:                   ;[   ]    andi    x3, ~0x80       ;[085]    ori     shift, 0x80     ;[086]    in      x2, USBIN       ;[087] <-- sample stuffed bit 7    nop                     ;[088]    rjmp    didUnstuff7     ;[089];   [---]                   ;[090]                            ;[080]unstuff5:                   ;[067]    eor     phase, x1       ;[068]    andi    x3, ~0x20       ;[069]    ori     shift, 0x20     ;[070]    in      r0, USBIN       ;[071] <-- phase    mov     x2, x1          ;[072]    nop                     ;[073]    nop2                    ;[074];   [---]                   ;[075]    in      x1, USBIN       ;[076] <-- bit 6    eor     r0, x1          ;[077]    or      phase, r0       ;[078]    eor     x2, x1          ;[079]    bst     x2, USBMINUS    ;[080]    bld     shift, 6        ;[081] no need to check bitstuffing, we just had one    in      r0, USBIN       ;[082] <-- phase    rjmp    didUnstuff5     ;[083];   [---]                   ;[084]                            ;[074]unstuff6:                   ;[074]    andi    x3, ~0x40       ;[075]    in      x1, USBIN       ;[076] <-- bit 6 again    ori     shift, 0x40     ;[077]    nop2                    ;[078];   [---]                   ;[079]    rjmp    didUnstuff6     ;[080];   [---]                   ;[081]                            ;[071]unstuff0:                   ;[013]    eor     r0, x2          ;[014]    or      phase, r0       ;[015]    andi    x2, USBMASK     ;[016] check for SE0    in      r0, USBIN       ;[017] <-- phase    breq    didUnstuff0     ;[018] direct jump to se0 would be too long    andi    x3, ~0x01       ;[019]    ori     shift, 0x01     ;[020]    mov     x1, x2          ;[021] mov existing sample    in      x2, USBIN       ;[022] <-- bit 1 again    rjmp    didUnstuff0     ;[023];   [---]                   ;[024]                            ;[014]unstuff1:                   ;[024]    eor     r0, x1          ;[025]    or      phase, r0       ;[026]    andi    x3, ~0x02       ;[027]    in      r0, USBIN       ;[028] <-- phase    ori     shift, 0x02     ;[029]    mov     x2, x1          ;[030]    rjmp    didUnstuff1     ;[031];   [---]                   ;[032]                            ;[022]unstuff2:                   ;[035]    eor     r0, x2          ;[036]    or      phase, r0       ;[037]    andi    x3, ~0x04       ;[038]    in      r0, USBIN       ;[039] <-- phase    ori     shift, 0x04     ;[040]    mov     x1, x2          ;[041]    rjmp    didUnstuff2     ;[042];   [---]                   ;[043]                            ;[033]unstuff3:                   ;[043]    in      x2, USBIN       ;[044] <-- bit 3 again    eor     r0, x2          ;[045]    or      phase, r0       ;[046]    andi    x3, ~0x08       ;[047]    ori     shift, 0x08     ;[048]    nop                     ;[049]    in      r0, USBIN       ;[050] <-- phase    rjmp    didUnstuff3     ;[051];   [---]                   ;[052]                            ;[042]unstuff4:                   ;[053]    andi    x3, ~0x10       ;[054]    in      x1, USBIN       ;[055] <-- bit 4 again    ori     shift, 0x10     ;[056]    rjmp    didUnstuff4     ;[057];   [---]                   ;[058]                            ;[048]rxLoop:                     ;[085]    eor     x3, shift       ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others    in      x1, USBIN       ;[000] <-- bit 0    st      y+, x3          ;[001];   [---]                   ;[002]    eor     r0, x1          ;[003]    or      phase, r0       ;[004]    eor     x2, x1          ;[005]    in      r0, USBIN       ;[006] <-- phase    ser     x3              ;[007]    bst     x2, USBMINUS    ;[008]    bld     shift, 0        ;[009]    andi    shift, 0xf9     ;[010]rxbit1:                     ;[   ]    in      x2, USBIN       ;[011] <-- bit 1    breq    unstuff0        ;[012] *** unstuff escape    andi    x2, USBMASK     ;[013] SE0 check for bit 1didUnstuff0:                ;[   ] Z only set if we detected SE0 in bitstuff    breq    se0             ;[014]    eor     r0, x2          ;[015]    or      phase, r0       ;[016]    in      r0, USBIN       ;[017] <-- phase    eor     x1, x2          ;[018]    bst     x1, USBMINUS    ;[019]    bld     shift, 1        ;[020]    andi    shift, 0xf3     ;[021]didUnstuff1:                ;[   ]    in      x1, USBIN       ;[022] <-- bit 2

⌨️ 快捷键说明

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