?? mouse.asm
字號:
;******************************************************
;
; 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 + -