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

📄 usbdrvasm15.inc

📁 AVR单片机模拟USB代码.可实现中断,控制传输,低速设备
💻 INC
📖 第 1 页 / 共 2 页
字号:
/* Name: usbdrvasm15.inc * Project: AVR USB driver * Author: contributed by V. Bosch * Creation Date: 2007-08-06 * 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 15 MHz version of the asssembler part of the USB driver. Itrequires a 15 MHz crystal (not a ceramic resonator and not a calibrated RCoscillator).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!*/;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes;nominal frequency: 15 MHz -> 10.0 cycles per bit, 80.0 cycles per byte; Numbers in brackets are clocks counted from center of last sync bit; when instruction starts;----------------------------------------------------------------------------; order of registers pushed: ;	YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4;----------------------------------------------------------------------------USB_INTR_VECTOR:                  push    YL                   ;2 	push only what is necessary to sync with edge ASAP    in      YL, SREG             ;1     push    YL                   ;2 ;----------------------------------------------------------------------------; 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      ;1 <-- sample: wait for D- == 1    rjmp    waitForJ		 ;2 ;-------------------------------------------------------------------------------; The following code results in a sampling window of < 1/4 bit ;	which meets the spec.;-------------------------------------------------------------------------------waitForK:			 ;-     sbis    USBIN, USBMINUS      ;1 [00] <-- sample    rjmp    foundK               ;2 [01]    sbis    USBIN, USBMINUS	 ;	 <-- sample    rjmp    foundK    sbis    USBIN, USBMINUS	 ;	 <-- sample    rjmp    foundK    sbis    USBIN, USBMINUS	 ;	 <-- sample    rjmp    foundK    sbis    USBIN, USBMINUS	 ;	 <-- sample    rjmp    foundK    sbis    USBIN, USBMINUS	 ;	 <-- sample    rjmp    foundK#if USB_COUNT_SOF    lds     YL, usbSofCount    inc     YL    sts     usbSofCount, YL#endif  /* USB_COUNT_SOF */    rjmp    sofError;------------------------------------------------------------------------------; {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;------------------------------------------------------------------------------foundK:                          ;- [02]    lds     YL, usbInputBufOffset;2 [03+04]	tx loop    push    YH                   ;2 [05+06]    clr     YH                   ;1 [07]    subi    YL, lo8(-(usbRxBuf)) ;1 [08] 	[rx loop init]    sbci    YH, hi8(-(usbRxBuf)) ;1 [09] 	[rx loop init]    push    shift                ;2 [10+11]    ser	    shift		 ;1 [12]    sbis    USBIN, USBMINUS      ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early)    rjmp    haveTwoBitsK         ;2 [00] [14]    pop     shift                ;2 	 [15+16] undo the push from before    pop     YH 			 ;2 	 [17+18] undo the push from before    rjmp    waitForK             ;2 	 [19+20] this was not the end of sync, retry; The entire loop from waitForK until rjmp waitForK above must not exceed two; bit times (= 20 cycles).;----------------------------------------------------------------------------; push more registers and initialize values while we sample the first bits:;----------------------------------------------------------------------------haveTwoBitsK:			;- [01]    push    x1              	;2 [02+03]    push    x2              	;2 [04+05]    push    x3              	;2 [06+07]    push    bitcnt              ;2 [08+09]	    in      x1, USBIN       	;1 [00] [10] <-- sample bit 0    bst     x1, USBMINUS    	;1 [01]    bld     shift, 0        	;1 [02]    push    cnt             	;2 [03+04]    ldi     cnt, USB_BUFSIZE	;1 [05]     push    x4              	;2 [06+07] tx loop    rjmp    rxLoop          	;2 [08];----------------------------------------------------------------------------; Receiver loop (numbers in brackets are cycles within byte after instr);----------------------------------------------------------------------------unstuff0:               	;- [07] (branch taken)    andi    x3, ~0x01   	;1 [08]    mov     x1, x2      	;1 [09] x2 contains last sampled (stuffed) bit    in      x2, USBIN   	;1 [00] [10] <-- sample bit 1 again    andi    x2, USBMASK 	;1 [01]    breq    se0Hop         	;1 [02] SE0 check for bit 1     ori     shift, 0x01 	;1 [03] 0b00000001    nop				;1 [04]    rjmp    didUnstuff0 	;2 [05];-----------------------------------------------------unstuff1:               	;- [05] (branch taken)    mov     x2, x1      	;1 [06] x1 contains last sampled (stuffed) bit    andi    x3, ~0x02   	;1 [07]    ori     shift, 0x02 	;1 [08] 0b00000010    nop                 	;1 [09]    in      x1, USBIN   	;1 [00] [10] <-- sample bit 2 again    andi    x1, USBMASK 	;1 [01]    breq    se0Hop         	;1 [02] SE0 check for bit 2     rjmp    didUnstuff1 	;2 [03];-----------------------------------------------------unstuff2:               	;- [05] (branch taken)    andi    x3, ~0x04   	;1 [06]    ori     shift, 0x04 	;1 [07] 0b00000100    mov     x1, x2      	;1 [08] x2 contains last sampled (stuffed) bit    nop                 	;1 [09]    in      x2, USBIN   	;1 [00] [10] <-- sample bit 3    andi    x2, USBMASK 	;1 [01]    breq    se0Hop         	;1 [02] SE0 check for bit 3     rjmp    didUnstuff2 	;2 [03];-----------------------------------------------------unstuff3:               	;- [00] [10]  (branch taken)    in      x2, USBIN   	;1 [01] [11] <-- sample stuffed bit 3 one cycle too late    andi    x2, USBMASK 	;1 [02]    breq    se0Hop         	;1 [03] SE0 check for stuffed bit 3     andi    x3, ~0x08   	;1 [04]    ori     shift, 0x08 	;1 [05] 0b00001000    rjmp    didUnstuff3 	;2 [06];----------------------------------------------------------------------------; extra jobs done during bit interval:;; bit 0:    store, clear [SE0 is unreliable here due to bit dribbling in hubs], ; 		overflow check, jump to the head of rxLoop; bit 1:    SE0 check; bit 2:    SE0 check, recovery from delay [bit 0 tasks took too long]; bit 3:    SE0 check, recovery from delay [bit 0 tasks took too long]; bit 4:    SE0 check, none; bit 5:    SE0 check, none; bit 6:    SE0 check, none; bit 7:    SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others;----------------------------------------------------------------------------rxLoop:				;- [09]    in      x2, USBIN   	;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed)    andi    x2, USBMASK 	;1 [01]    brne    SkipSe0Hop		;1 [02]se0Hop:				;- [02]    rjmp    se0         	;2 [03] SE0 check for bit 1 SkipSe0Hop:			;- [03]    ser     x3          	;1 [04]    andi    shift, 0xf9 	;1 [05] 0b11111001    breq    unstuff0    	;1 [06]didUnstuff0:			;- [06]    eor     x1, x2      	;1 [07]    bst     x1, USBMINUS	;1 [08]    bld     shift, 1    	;1 [09]     in      x1, USBIN   	;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed)    andi    x1, USBMASK 	;1 [01]    breq    se0Hop         	;1 [02] SE0 check for bit 2     andi    shift, 0xf3 	;1 [03] 0b11110011    breq    unstuff1    	;1 [04] do remaining work for bit 1didUnstuff1:			;- [04]    eor     x2, x1      	;1 [05]    bst     x2, USBMINUS	;1 [06]    bld     shift, 2    	;1 [07]    nop2			;2 [08+09]    in      x2, USBIN   	;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed)    andi    x2, USBMASK 	;1 [01]    breq    se0Hop         	;1 [02] SE0 check for bit 3     andi    shift, 0xe7 	;1 [03] 0b11100111    breq    unstuff2    	;1 [04]didUnstuff2:			;- [04]    eor     x1, x2      	;1 [05]    bst     x1, USBMINUS	;1 [06]    bld     shift, 3    	;1 [07]didUnstuff3:			;- [07]    andi    shift, 0xcf 	;1 [08] 0b11001111    breq    unstuff3    	;1 [09]    in      x1, USBIN   	;1 [00] [10] <-- sample bit 4    andi    x1, USBMASK 	;1 [01]    breq    se0Hop         	;1 [02] SE0 check for bit 4    eor     x2, x1      	;1 [03]    bst     x2, USBMINUS	;1 [04]    bld     shift, 4    	;1 [05]didUnstuff4:			;- [05]    andi    shift, 0x9f 	;1 [06] 0b10011111    breq    unstuff4    	;1 [07]    nop2			;2 [08+09]

⌨️ 快捷键说明

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