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

📄 mouse.asm

📁 CY7C63231 mouse 源码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;******************************************************
;
;	file: 		Low Cost Mouse firmware
;	Date: 		10/20/2000
;	Description:This code provides the functionality  
;				for a USB HID compliant mouse.
;	Target:		Cypress CY7C63231
;
; Overview
;  		There are four main tasks: 
;			* USB 
;			* buttons 
;			* optics 
;			* suspend/resume 
;
;   	The system is started in the reset() routine at reset. 
;		This routine initializes the USB variables, the IO ports, 
;		the mouse logic, and the data space. All USB 
;		communication occurs on an interrupt basis.
; USB
;  		Endpoint 0 is used to support Control Transfers and 
;		vendor specific requests.  During enumeration setup
;		commands are sent to endpoint1 to initialize the
;		USB device and to extract configuration information
;		from the device
;
;		Endpoint 1 is used to transfer interrupt data back to
;		the host.  In this case we transfer data from the 
;		button and optics back to the host. 
; Buttons
;		The buttons are read and debounced every millisecond in
;		the main task loop.
; Optics
;		The optics are continuously polled in the main loop.  The
;		quadrature state of the optics tells us which direction
;		the mouse is moving in.  This data is sent back to the
;		host as an offset from the last time the mouse was polled
;		for data by the host.
; Suspend/Resume
;		Every millisecond, the USB is polled for activity.  If no
;		activity occurs for three milliseconds, then it is assumed
;		that the USB is in suspend.  Because this device supports
;		remote wakeup, pressing the buttons or moving the mouse
;		causes the firmware to send resume signalling back to the
;		host to wakeup and resume operation.
;
; Endpoint1 packet definition
;
; Byte  Usage
;  0	Button Data 7-3 Not used, 2=middle, 1=right, 0=left
;  1	horizontal displacement measured via the optics
;  2	vertical displacement measured via the optics
;  3	Wheel displacement 0x01 for forward, 0xFF for backward
;
;
; Port Usage
;
;			 -------------------
;  		X0	| P0[0]		P0[4]	|  Z1	
;  		X1	| P0[1]		P0[5]	|  Z0	
;  		Y0	| P0[2]		P0[6]	|  OPTIC CONTROL	
;  		Y1	| P0[3] 	P0[7]	|  LEFT	
;  	 RIGHT	| P1[0]		P1[1]	|  MIDDLE	
;			| P1[2]		P1[3]	|	
;	GND		| VSS		D+/SCLK	|  D+
;	GND		| VPP		D-/SDATA|  D-	
;	PULLUP	| VREG		VCC		|	+5
;			| XTALIN	XTALOUT	|
;			 -------------------
;
; Revisions:
;			10/20/2000 - Creation 
;
;**********************************************************
;
;		Copyright 2000 Cypress Semiconductor
;	This code is provided by Cypress as a reference.  Cypress 
;	makes no claims or warranties to this firmware's 
;	suitability for any application. 
;
;********************************************************** 

	CPU	63231

	XPAGEON

	INCLUDE	"632xx.inc"
	INCLUDE "USB.inc"


;**************************************
; EP0 IN TRANSACTION STATE MACHINE
EP0_IN_IDLE:				equ	00h
CONTROL_READ_DATA:			equ	02h
NO_DATA_STATUS:				equ	04h
EP0_IN_STALL:				equ	06h

;**************************************
; EP0 NO-DATA CONTROL FLAGS
ADDRESS_CHANGE_PENDING:		equ	00h
NO_CHANGE_PENDING:			equ	02h

;**************************************
; RESPONSE SIZES
DEVICE_STATUS_LENGTH:		equ	2
DEVICE_CONFIG_LENGTH:		equ	1
ENDPOINT_STALL_LENGTH:		equ 2
INTERFACE_STATUS_LENGTH:	equ 2
INTERFACE_ALTERNATE_LENGTH:	equ	1
INTERFACE_PROTOCOL_LENGTH:	equ	1

;**************************************
; INTERFACE CONSTANTS

LEFT_BUTTON_PORT:			equ	port0
LEFT_BUTTON:				equ	80h
RIGHT_BUTTON_PORT:			equ	port1
RIGHT_BUTTON:				equ	01h
MIDDLE_BUTTON_PORT:			equ	port1
MIDDLE_BUTTON:				equ	02h

HID_LEFT_MOUSE_BUTTON:		equ	01h
HID_RIGHT_MOUSE_BUTTON:		equ	02h
HID_MIDDLE_MOUSE_BUTTON:	equ	04h

X_OPTICS_PORT:				equ	port0
X0:							equ	01h
X1:							equ	02h

Y_OPTICS_PORT:				equ	port0
Y0:							equ	04h
Y1:							equ	08h

Z_OPTICS_PORT:				equ port0
Z0:							equ	20h
Z1:							equ	10h

OPTIC_CONTROL_PORT:			equ	port0
OPTIC_CONTROL:				equ	40h

; button debounce time
BUTTON_DEBOUNCE:			equ 15

;**************************************
; BUTTON STATE MACHINE
NO_BUTTON_DATA_PENDING:		equ	00h
BUTTON_DATA_PENDING:		equ	02h

;**************************************
; OPTICS STATE MACHINE
NO_OPTIC_DATA_PENDING:		equ	00h
OPTIC_DATA_PENDING:			equ	02h

;**************************************
; EVENT STATE MACHINE
NO_EVENT_PENDING:			equ	00h
EVENT_PENDING:				equ	02h

;**************************************
; TRANSACTION TYPES
TRANS_NONE:					equ	00h
TRANS_CONTROL_READ:			equ	02h
TRANS_CONTROL_WRITE:		equ	04h
TRANS_NO_DATA_CONTROL:		equ	06h


;**************************************
; DATA MEMORY VARIABLES
suspend_count:				equ	20h			; usb suspend counter
ep1_data_toggle:			equ	21h			; endpoint 1 data toggle
ep0_data_toggle: 			equ	22h			; endpoint 0 data toggle
data_start:					equ	23h			; ROM table address, start of data
data_count:					equ	24h			; data count to return to host
maximum_data_count:			equ	25h			; maximum size of data to return to host
ep0_in_machine:				equ	26h			; endpoint 0 IN state machine
ep0_in_flag:				equ	27h			; endpoint 0 flag for no-data control
configuration:				equ	28h			; configured/not configured state
remote_wakeup:				equ	29h			; remote wakeup on/off
ep1_stall:					equ	2Ah			; endpoint 1 stall on/off
idle:						equ	2Bh			; HID idle timer
protocol:					equ	2Ch			; mouse protocol boot/report
debounce_count:				equ	2Dh			; debounce counters for buttons
optic_status:				equ	2Eh			; current optic status
current_button_state:		equ	2Fh			; current button status 
x_state:					equ	30h			; current optics x state
y_state:					equ	31h			; current optics y state
button_machine:				equ	32h			; buttons/optics state machine
temp:						equ	33h			; temporary register
event_machine:				equ	34h			; state machine for sending data back to host
pending_data:				equ	35h			; data pending during no-data control
last_button_state:			equ	36h			; last read value of buttons
x_current_state:			equ	37h			; y-axis current state
y_current_state:			equ	38h			; x-axis current state
z_current_state:			equ	39h			; z-axis current state
x_last_state:				equ	3Ah			; last read y-axis optics
y_last_state:				equ	3Bh			; last read x-axis optics
z_last_state:				equ	3Ch			; last read z-axis optics
int_temp:					equ	3Dh			; interrupt routine temp variable
idle_timer:					equ	3Eh			; HID idle timer
idle_prescaler:				equ	3Fh			; HID idle prescale (4ms)
ep0_transtype:				equ	40h			; Endpoint 0 transaction type
wakeup_timer:				equ	41h			; wakeup timer minimum count

;**********************************************************
; Interrupt vector table

ORG 00h			

jmp	Main									; Reset vector		

jmp	Bus_reset								; USB reset / PS2 interrupt

jmp	Error									; 128us interrupt

jmp	1ms_timer								; 1.024ms interrupt

jmp	Endpoint0								; Endpoint 0 interrupt

jmp	Endpoint1								; Endpoint 1 interrupt

jmp	Error									; Reserved

jmp	Error									; Reserved

jmp	Error									; Reserved

jmp	Error									; Reserved

jmp	Error									; GPIO interrupt vector

jmp	Wakeup									; Wake-up interrupt vector 


;**********************************************************
; Program listing

ORG  1Ah
Error: halt

;**********************************************************
;
;	Interrupt handler: Main
;	Purpose: The program jumps to this routine when
;		 the microcontroller has a power on reset.
;
;**********************************************************

Main:

	;**********************************
	; set wakeup timer interval and disable XTALOUT 
	mov		A, WAKEUP_ADJUST2 | WAKEUP_ADJUST0 | PRECISION_CLK | INTERNAL_CLK 
	iowr	clock_config

	;**********************************
	; setup data memory stack pointer
	mov		A, 20h
	swap	A, dsp		

	;**********************************
	; clear variables
	mov		A, 00h		
	mov		[ep0_in_machine], A
	mov		[configuration], A
	mov		[ep1_stall], A
	mov		[idle], A
	mov		[suspend_count], A
	mov		[debounce_count], A
	mov		[x_state], A
	mov		[y_state], A
	mov		[ep1_dmabuff0], A
	mov		[ep1_dmabuff1], A
	mov		[ep1_dmabuff2], A
	mov		[ep1_dmabuff3], A
	mov		[button_machine], A
	mov		[x_last_state], A
	mov		[y_last_state], A
	mov		[z_last_state], A
	mov		[int_temp], A
	mov		[idle_timer], A
	mov		[idle_prescaler], A
	mov		[event_machine], A
	mov		[ep0_transtype], A
	mov		[current_button_state], A
	mov		[last_button_state], A
	mov		[wakeup_timer], A

	mov		A, HID_REPORT
	mov		[protocol], A

	mov		A, SET
	mov		[remote_wakeup], A

	
	;**********************************
	; set port I/O configuration
	; *** NOTE - this is configured for the particular
	; hardware you are dealing with.  You will need to change
	; this section for the particular hardware you are working
	; on

	mov		A, LEFT_BUTTON
	iowr	port0

	mov		A, RIGHT_BUTTON | MIDDLE_BUTTON
	iowr	port1

	mov		A, OPTIC_CONTROL							; set button pins in resistive mode 
	iowr	port0_mode0
	mov		A, LEFT_BUTTON | OPTIC_CONTROL 
	iowr	port0_mode1

	mov		A, 00h									; remember that we have to drive
	iowr	port1_mode0								; unused pins to meet suspend current
	mov		A, (RIGHT_BUTTON | MIDDLE_BUTTON | FCh )
	iowr	port1_mode1


	;**********************************
	; enable USB address for endpoint 0
	mov		A, ADDRESS_ENABLE
	iowr	usb_address

	;**********************************
	; enable global interrupts
	mov		A, (1MS_INT | USB_RESET_INT)
	iowr 	global_int

	mov 	A, EP0_INT			
	iowr 	endpoint_int

	ei

	;**********************************
	; enable USB pullup resistor
	mov		A, VREG_ENABLE  
	iowr	usb_status


task_loop:

	;**********************************
	; main loop watchdog clear
	iowr watchdog


; this routine allows the user to map the button pins whereever
; they want, as long as all the buttons remain on the same port.
; in order to change the button ports you must change the mask
; in the pin mask constants above and change the definition of the 
; "button_port."  You must also change the way the port mode
; is initialized in the reset routine.
	mov		A, [button_machine]				; read buttons every millisecond
	jacc	button_machine_jumptable

	button_task:
	mov		A, [current_button_state]		; read button states
 	cmp		A, [last_button_state]
	jz		button_state_same:

	button_state_different:					; if the button state has changed, then
		mov		[last_button_state], A		; reset the debounce timer and set 
		mov		A, 00h						; last button value to the one just read
		mov		[debounce_count], A
		jmp		button_task_done
	
	button_state_same:		
		mov		A, BUTTON_DEBOUNCE - 1		; if at debounce count-1 then send
		cmp		A, [debounce_count]			; new value to host 
		jz		set_button_event

		increment_debounce_counter:			; otherwise increment debounce count
			mov		A, [debounce_count]		; if it's not already at the 
			cmp		A, BUTTON_DEBOUNCE		; BUTTON_DEBOUNCE value
			jz		button_task_done
			inc		[debounce_count]
			jmp		button_task_done

		set_button_event:					; set event pending to signal packet
			inc		[debounce_count]		; needs to be sent to host
			mov		A, EVENT_PENDING
			mov		[event_machine], A

			mov		A, [current_button_state]
			mov		[ep1_dmabuff0], A

			button_task_done:
			mov		A, NO_BUTTON_DATA_PENDING
			mov		[button_machine], A

		no_button_task:


; this routine allows the user to map the optics pins whereever
; they want, as long as all the optics sets remain on the same port.
; in order to change the optic ports you must change the mask
; in the pin mask constants above.  You must also change the way 
;the port mode is initialized in the reset routine.

	optic_task:
		mov		A, 00h						; reset optic values
		mov		[x_current_state], A
		mov		[y_current_state], A
		mov		[z_current_state], A	

		read_x_optics:
			iord	X_OPTICS_PORT
			mov		X, A
			read_x0:
				and		A, X0
				jz		read_x1
				mov		A, 01h
				or		[x_current_state], A
			read_x1:
				mov		A, X
				and		A, X1
				jz		read_y_optics
				mov		A, 02h
				or		[x_current_state], A

		read_y_optics:
			iord	Y_OPTICS_PORT
			mov		X, A
			read_y0:
				and		A, Y0
				jz		read_y1
				mov		A, 01h
				or		[y_current_state], A
			read_y1:
				mov		A, X
				and		A, Y1
				jz		read_z_optics
				mov		A, 02h
				or		[y_current_state], A

		read_z_optics:
			iord	Z_OPTICS_PORT
			mov		X, A
			read_z0:
				and		A, Z0
				jz		read_z1
				mov		A, 01h
				or		[z_current_state], A
			read_z1:
				mov		A, X
				and		A, Z1
				jz		analyze_x_optics
				mov		A, 02h
				or		[z_current_state], A

		analyze_x_optics:
			mov		A, [x_last_state]
			asl		A
			asl		A
			or		A, [x_current_state]
			asl		A
			jacc	x_jumptable				; jump to transition state

			x_increment:
				inc		[ep1_dmabuff1]		; increment mouse cursor change	
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
				jmp		analyze_y_optics					
			x_decrement:
				dec		[ep1_dmabuff1]		; decrement mouse cursor change
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host

 		analyze_y_optics:
			mov		A, [y_last_state]
			asl		A
			asl		A
			or		A, [y_current_state]
			asl		A
			jacc	y_jumptable				; jump to transition state

			y_increment:
				inc		[ep1_dmabuff2]		; increment mouse cursor change	
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
				jmp		analyze_z_optics					
			y_decrement:
				dec		[ep1_dmabuff2]		; decrement mouse cursor change
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host

		analyze_z_optics:
			mov		A, [z_last_state]
			asl		A
			asl		A
			or		A, [z_current_state]
			asl		A
			jacc	z_jumptable				; jump to transition state

			z_forward:
				mov		A, 01h
				mov		[ep1_dmabuff3], A	; increment mouse wheel change	
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
				jmp		optic_task_done					
			z_backward:
				mov		A, FFh
				mov		[ep1_dmabuff3], A	; decrement mouse wheel change
				mov		A, EVENT_PENDING	; set event pending to signal data to
				mov		[event_machine], A	; send to the host
	
	optic_task_done:
		mov		A, [x_current_state]

⌨️ 快捷键说明

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