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

📄 bwmeter.a51

📁 USB带宽测试的程序
💻 A51
字号:
;--------------------------------------------------------------------------
; BWmeter.A51 2-07-02 LTH
;
; A USB 2.0 High-Speed (480 Mbits/sec) bandwidth meter.
;
; Serves as endless, no-wait, source and sink of bulk packets. Measures the 
; number of packets delivered/consumed by the host per microframe.
;
; Correct operation can be determined by glancing at the four FX2 Dev Board LEDs:
;	L1 	L2	L3	L4
;	ON	ON	ON	OFF
;
; L1 is ON for USB high-speed operation (off for full-speed). Indicates you're connected
; to a full-speed host, and the USB host driver is working.
; L2-L3 toggle once per SOF, proving that the code is running.
; L4 comes on only if the code causes any USB NAK's (was used for debug only).
;
; Endpoints used:
; EP1: Bulk IN 64 bytes (retrieves packet buffer history, displays in control panel)
; EP2, EP4: Bulk OUT, double-buffered 512 bytes (endless data sink)
; EP6, EP8: Bulk IN,  double-buffered 512 bytes (endliss data source)
;
; NOTE: By using these FX2 default endpoints for Interface 0/Alt Setting 1, 
; no USB enumeration code is required.
;
; Registers used:
;	r0 is pointer to 64-byte buffer that holds packets-per-frame (ppf) history
;	dptr used as a data transfer pointer
; 
; Operating Instructions:
;
; 1.	Plug in board, load Cypress USB EzMr application (Control Panel).
; 2.	Check LED1 (D5) for ON, indicating high-speed operation. If not, go to 3a.
; 3.	LED2 and LED3 (D4-D3) should both be on, indicating receipt of SOF packets.
;	3a.	Check the port, driver, software, BIOS, etc.
; 4.	Click 'Set Iface', then 'Get Pipes' buttons. (Sets the default Interface 0/AltSetting 1). 	
; 	4a. 	If you don't see the 5 pipes, 0-5, go to 3a.
; 5.	Set up a bulk transfer: EP8-IN (default), type 8192 in LENGTH box. [can also use EP6-IN]
; 6.	Click BulkTrans. *** You should see the screen fill with blocks of 0's and 1's.
; 	NOTE: The 'ping' buffer has 0's, the 'pong' buffer has 1's. Last byte shows number of IN's. 
; 	*** The 7-seg readout leaps to life, showing the max IN packets received in a microframe.
; 7.	In Bulk Transfer Pipe dropdown menu, select '1: Endpoint 1 IN'. Leave length at 8192.
; 8.	Click BulkTrans. This 64-byte record shows the results of the EP8-IN bulk transfer. 
;	Each byte is the number of IN packets received by the host in a microframe. '0' a microframe
; 	with no IN packets.
; 	NOTE: It's OK to leave the length at 8192 for the 64-byte EP1-IN. Since the default USB device
; 	reports EP1 MaxPacketSize=512, a 64 byte packet represents a short packet and terminates any IN
;	transfer request of under 512 bytes. This saves repeatedly re-typing 64 for EP1 and 8192 for EP8.
; 9.	An EP1-IN transfer clears the 7-seg readout and resets the analyzer for another try.
; 10.	If at any time, LED4 (D2) lights, the analyzer has incurred wait states (NAK). Debug only.
; 11.	Same instructions for EP4-OUT [can also use EP2-OUT], except send OUT packets instead of INS.
;
; EP8-IN packs its two buffers with data values 00 and 01; EP6-IN uses EF and FF.
; Note: Hitting the EP1-OUT button (by accident) does not hang the system since this program responds
; 	to an EP1-OUT request by re-arming the endpoint.
;--------------------------------------------------------------------------
$NOMOD51		; disable predefined 8051 registers
;--------------------------------------------------------------------------
$include (fx2regs.inc)
$include (handy.mac)		; handy macros: LDREG, bit test, lights on/off
$list
NAME		BWmeter
bHSM		equ	7	; in USBCS--High Speed Mode
bSOF		equ	1	; in USBIRQ register--an SOF has arrived

		ISEG AT 90H	; stack
stack:		ds	40
;
		DSEG 	at 	20H	; bit-addressable registers
flags:		ds	1		; NOTE: all flags in this byte initialze to 0
PKTbuf_full	equ	flags.0
F_LEDtog	equ	flags.1		; alternate L2-L3 every SOF
blankflag	equ	flags.2		; blank LED if 1
F_found_HS	equ	flags.3		; found the high speed mode
F_gotPacket	equ	flags.4		; got an IN or an OUT packet
did_once	equ	flags.5		; to do stuff only once when PKTbuf just filled
;
		DSEG	at	30H	; gp registers
ppf:		ds	1		; packets per frame
InCnt:		ds	1		; number of IN-8 transfers
displaydigit:	ds	1		; hex digit to display
maxppf:		ds	1		; max packets in a microframe
PKTbuf:		ds	64		; 64-byte ppf-history buffer
;
		CSEG	AT	0	
		LJMP	start		; jump over the interrupt vectors
; -------------------------------------------------
		org	0080h		
; -------------------------------------------------
digit_table:	db	0C0h,0F9h,0A4h,0B0h,99h,92h,82h,0F8h,80h,98h,88h,83h,0C6h,0A1h,86h,08Eh
start:		mov	SP,#stack-1	; set stack
		LDREG	USBCS,#0	; clear RENUM bit and CONNECT (if disconnected)
;
; Comment out two of the following three statements to set 8051 clock speed
;
;		LDREG	CPUCS,#02h	; 12 MHz, CKOUT enabled (default)
;		LDREG	CPUCS,#0Ah	; 24 MHz, CKOUT enabled
		LDREG	CPUCS,#12H	; 48 MHz, CKOUT enabled
;
; initialize variables, buffers & pointers
;
init:		call	lites_out	
		call	reset_FIFOS
		call	arm_EP24	; arm the OUT endpoints
		call 	fill_and_arm_EP8_buffers	; with 00's and 01's
		call	fill_and_arm_EP6_buffers	; with EF's and FF's
		mov	InCnt,#2	; two packets are already posted-for-delivery
		mov	r0,#PKTbuf	; initialize packet buffer pointer
		mov	ppf,#0		; IN packets per frame counter
		mov	maxppf,#0	; max over long haul
		mov	flags,#0	; all flags in this byte init to zero
		setb	blankflag	; blank the display
		call	display_hex
;********************************************************************************
; Main Loop. Poll flags
;********************************************************************************
mainloop:	mov	a,EP2468STAT	; *** Check for EP8 full flag
		jb	acc.7,m0	; EP8 is full--don't need to update
		call	Update_EP8	; got a free buffer--fill and arm it
		sjmp	m1		; skip EP6 test
m0:		jb	acc.5,m1	; EP6 is full--don't need to update
		call	Update_EP6	; got a free buffer--fill and arm it
;
m1:		mov	a,EP2468STAT	; *** Check for EP4OUT-EMPTY
		jb	acc.2,m10	; EP4OUT is empty--move on	
		call	Update_EP4	; it has OUT data--re-arm it
		sjmp	m2
m10:		jb	acc.0,m2	; *** Check for EP2OUT empty
		call	Update_EP2	; EP2OUT has OUT data--re-arm it
;
m2:		RDREG	USBIRQ		; *** Check for SOF	
		jnb	acc.1,m3	; USBIRQ.1=SOF: no SOF yet
		mov	a,#00000010b	; b1 is SOF IRQ flag
		movx	@dptr,a		; clear the request bit
		call	got_SOF	
		sjmp	mainloop
;
m3:		RDREG	IBNIRQ		; *** Check for EP8 IBN (In-Bulk-NAK)
		jnb	acc.5,m3a	; IBNIRQ.5 is EP8-NAK
		mov	a,#00100000b	; EP4-IBN IRQ bit is bit 5
		movx	@dptr,a		; clear the bit
		L4_ON			; turn on light #4
;
m3a:		RDREG	NAKIRQ		; *** Check for EP4 PING-NAK
		jnb	acc.5,m4	; bit 5 is EP4
		mov	a,#00100000b
		movx	@dptr,a		; clear the bit
		L4_ON			; turn on light #4
;
m4:		RDREG	EP1INCS		; *** Check for EP1-IN buffer free
		jb	acc.1,m4a	; bit 1 is BUSY bit
		LDREG	EP1INBC,#64	; arm it for 64 byte transfer
		jmp	init		; *** START OVER
;
m4a:		RDREG	EP1OUTCS	; *** Did someone send EP1-OUT data?
		jb	acc.1,m5	; busy--waiting for USB data
		mov	dptr,#EP1OUTBC	; any value in acc will do
		movx	@dptr,a		; Re-arm it so we don't hang the control panel
;
; *** Check for high-speed operation
;
m5:		jb	F_found_HS,m6	; don't need to check for HS mode any more
		JBL	USBCS,bHSM,m6	; check the HS operation bit
		L1_ON			; found it ON
		setb	F_found_HS	; set flag so won't continue checking
;
; Do the following operations only once when the PKTbuffer fills (to 64).
;
m6:		jb	did_once,mainloop	; already displayed the max ppf &  updated EP1-IN buffer
 		jnb	PKTbuf_full,mainloop	; history buffer not full yet
		setb	did_once		; Do the stuff below only once
;
; *** Load EP1-IN with 64 bytes of ppf history
;
		mov	r7,#64			; loop counter
		mov	r0,#PKTbuf		; r0 points to 64-byte ppf history buffer
		mov	dptr,#EP1INBUF		; dptr points to destination (endpoint FIFO)
xfr:		mov	a,@r0			; get byte from PKTbuf
		inc 	r0			; bump source pointer
		movx	@dptr,a			; store byte in EP1INBUF
		inc	dptr			; bump dest pointer
		djnz	r7,xfr			; do it 64 times
;
		clr	blankflag		; (don't blank the display in 'display_hex' call)		 
		mov	displaydigit,maxppf	; display max packets per frame
		call	display_hex
		jmp	mainloop		; go again
; -----------------------------------------------------------------------------------------------
; An EP8 buffer is available. Update last byte in buffer, and dispatch another packet
; -----------------------------------------------------------------------------------------------
Update_EP8:	inc	InCnt			; total number of IN packets
		setb	F_gotPacket		; tell SOF service routine we're in business
		LDREG	EP8FIFOBUF+511,InCnt	; put IN count into last buffer byte		
		inc	ppf			; bump the packets-per-frame count
		LDREG	EP8BCL,#0		; re-arm (512 bytes)--NOTE: EP8BCH fixed at 2
		ret				; back to loop
; -----------------------------------------------------------------------------------------------
; An EP6 buffer is available. Update last byte in buffer, and dispatch another packet
; -----------------------------------------------------------------------------------------------
Update_EP6:	inc	InCnt			; total number of IN packets
		setb	F_gotPacket		; tell SOF service routine we're in business
		LDREG	EP6FIFOBUF+511,InCnt	; put IN count into last buffer byte		
		inc	ppf			; bump the packets-per-frame count
		LDREG	EP6BCL,#0		; re-arm (512 bytes)--NOTE: EP6BCH fixed at 2
		ret				; back to loop
; -----------------------------------------------------------------------------------------------
; An EP4 buffer has data. Re-arm the endpoint (drop the data)
; -----------------------------------------------------------------------------------------------
Update_EP4:	setb	F_gotPacket	; tell SOF service routine we're in business
		inc	ppf		; bump the packets-per-frame count
		LDREG	EP4BCL,#80h	; re-arm the endpoint (skip bit set)
		ret			; back to loop
; -----------------------------------------------------------------------------------------------
; An EP2 buffer has data. Re-arm the endpoint (drop the data)
; -----------------------------------------------------------------------------------------------
Update_EP2:	setb	F_gotPacket	; tell SOF service routine we're in business
		inc	ppf		; bump the packets-per-frame count
		LDREG	EP2BCL,#80h	; re-arm the endpoint (skip bit set)
		ret			; back to loop
; -----------------------------------------------------------------------------------------------
; Got an SOF. Toggle lights, store ppf in buffer, clear ppf, update max. Uses AUTOPTR1 -> PKTbuf
; -----------------------------------------------------------------------------------------------
got_SOF:	cpl	F_LEDtog	; *** Toggle the middle lights to indicate we're running
		jnb	F_LEDtog,gs0
		L2_OFF
		L3_ON
		sjmp	gs1
gs0:		L2_ON
		L3_OFF
gs1:		jnb	F_gotPacket,gs3	; no INS or OUTS yet...bail out
gs2:		jb	PKTbuf_full,gs3	; 64-byte ppf-history buffer is full...bail out
		mov	@r0,ppf		; not full--stash another ppf value,	
		inc	r0		; and bump the pointer
;
		mov	a,maxppf	; *** update maxppf
		cjne	a,ppf,$+3	; just to set the cy bit
		jnc	notbigger	; maxppf-ppf: cy=1 if maxppf < ppf
		mov	maxppf,ppf	; found a higer one, update maxppf
notbigger:	mov	ppf,#0		; reset packet count
;
		mov	a,r0		; *** check for full PKTbuf (64 byte limit)
		cjne	a,#PKTbuf+64,gs3
		setb	PKTbuf_full	; set the 'full' (don't update any more) flag
gs3:		ret
; -----------
; Subroutines
; -----------
; Reset the endpoint FIFOSto the power-on state. (Busy bits, pointers, etc.)
; This is done for repeated code load/debug cycles. Need to restore the part to the
; power-on state so logic that was set during last debug session does not carry over
; into the next debug session.
;
reset_FIFOS:	mov	dptr,#FIFORESET	
		mov	a,#80h	
		movx	@dptr,a		; first set this bit to NAK any traffic
		mov	a,#02h		; then clear individual FIFOS
		nop			; Syncronization delay (TRM Sec 15.14)
		movx	@dptr,a		; EP2
		mov	a,#04h
		nop
		movx	@dptr,a		; EP4
		mov	a,#06h
		nop
		movx	@dptr,a		; EP6
		mov	a,#08h
		nop
		movx	@dptr,a		; EP8
		mov	a,#0
		nop
		movx	@dptr,a		; clear the NAK bit
		ret
;
fill_and_arm_EP8_buffers:
		mov	a,#00h		; fill first buffer with 0's
		mov	dptr,#EP8FIFOBUF
		call	fill_EP68_IN
		LDREG	EP8FIFOBUF+511,#1	; mark packet #1
		LDREG	EP8BCH,#2	; Arm EP8-IN: 200h is 512 bytes
		LDREG	EP8BCL,#0	; arm it
;
		mov	a,#01h		; fill second buffer with 1's
		mov	dptr,#EP8FIFOBUF
		call	fill_EP68_IN
		LDREG	EP8FIFOBUF+511,#2	; mark packet #2
		LDREG	EP8BCH,#2
		LDREG	EP8BCL,#0	; arm it
		ret
;
fill_and_arm_EP6_buffers:
		mov	a,#0FEh		; fill first buffer with FE's
		mov	dptr,#EP6FIFOBUF
		call	fill_EP68_IN
		LDREG	EP6FIFOBUF+511,#1	; mark packet #1
		LDREG	EP6BCH,#2	; Arm EP6-IN: 200h is 512 bytes
		LDREG	EP6BCL,#0	; arm it
;
		mov	a,#0FFh		; fill second buffer with 1's
		mov	dptr,#EP6FIFOBUF
		call	fill_EP68_IN
		LDREG	EP6FIFOBUF+511,#2	; mark packet #2
		LDREG	EP6BCH,#2
		LDREG	EP6BCL,#0	; arm it
		ret
;
fill_EP68_IN:	mov	r5,#0
		mov	r6,#2		; 2 times 256
fill:		movx	@dptr,a		; fill 512 byte buffer with value in a
		inc	dptr
		djnz	r5,fill
		djnz	r6,fill
		ret
;
; Arm the OUT endpoints (EP2 & EP4). Unlike EZ-USB, the FX2 OUT endpoints come up unarmed. 
; We need to write the byte count twice to account for the double-buffering
;
arm_EP24:	LDREG	EP2BCL,#80h	; set the 'skip' bit (b7) so OUT packets not 
		LDREG	EP2BCL,#80h	; transferred to ext interface which would hang the
		LDREG	EP4BCL,#80h	; OUT transfers since there's nothing to re-arm the ep
		LDREG	EP4BCL,#80h
		ret
;
lites_out:	L1_OFF			; debug lights off
		L2_OFF
		L3_OFF
		L4_OFF
		ret
;-----------
display_hex:
;-----------
; Call with blankflag=0 to display digit in 'displaydigit', =1 to blank the display.
;
		call	stop_check	; make sure the last operation is not in progress
		mov	dptr,#I2CS	; set the START bit
		mov	a,#80h		; b7=start bit
		movx	@dptr,a
;	
		mov	dptr,#I2DAT	; first data byte is address+direc
		mov	a,#42h		; IO expander address, bit b0=0 means write
		movx	@dptr,a
		call	wait_done	; wait for i2c transmit complete
;
		jnb	blankflag,show
		mov	a,#0FFh		; all off
		sjmp	dh2
show:		mov	dptr,#digit_table
		mov	a,displaydigit
		movc	a,@a+dptr
dh2:		mov	dptr,#I2DAT	; write the data byte
		movx	@dptr,a
		call	wait_done
;
		mov	dptr,#I2CS	; set the STOP bit
		mov	a,#01000000b
		movx	@dptr,a
		ret
;
stop_check:	mov	dptr,#I2CS
stck:		movx	a,@dptr
		jb	acc.6,stck
		ret
;
wait_done:	mov	dptr,#I2CS	; select DPTR1
cd1:		movx	a,@dptr
		jnb	acc.0,cd1
		ret		
		END


⌨️ 快捷键说明

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