?? mouse.asm
字號:
mov A, (interface_alternate_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
set_interface_idle: ; SET IDLE
mov A, [ep0_dmabuff + WVALUEHI] ; test if new idle time
cmp A, 00h ; disables idle timer
jz idle_timer_disable
mov A, [idle_timer] ; test if less than 4ms left
cmp A, 01h
jz set_idle_last_not_expired
mov A, [ep0_dmabuff + WVALUEHI] ; test if time left less than
sub A, [idle_timer] ; new idle value
jnc set_idle_new_timer_less
jmp set_idle_normal
idle_timer_disable:
mov [idle], A ; disable idle timer
jmp set_idle_done
set_idle_last_not_expired:
mov A, EVENT_PENDING ; send report immediately
mov [event_machine], A
mov A, 00h ; reset idle prescaler
mov [idle_prescaler], A
mov A, [ep0_dmabuff + WVALUEHI] ; set new idle value
mov [idle_timer], A
mov [idle], A
jmp set_idle_done
set_idle_new_timer_less:
mov A, 00h
mov [idle_prescaler], A ; reset idle prescaler
mov A, [ep0_dmabuff + WVALUEHI]
mov [idle_timer], A ; update idle time value
mov [idle], A
jmp set_idle_done
set_idle_normal:
mov A, 00h ; reset idle prescaler
mov [idle_prescaler], A
mov A, [ep0_dmabuff + WVALUEHI] ; update idle time value
mov [idle_timer], A
mov [idle], A
set_idle_done:
mov A, NO_CHANGE_PENDING ; respond with no-data control
mov [ep0_in_flag], A ; transaction
jmp initialize_no_data_control
set_interface_protocol: ; SET PROTOCOL
mov A, [ep0_dmabuff + WVALUELO]
mov [protocol], A ; set protocol value
mov A, NO_CHANGE_PENDING
mov [ep0_in_flag], A ; respond with no-data control
jmp initialize_no_data_control ; transaction
get_interface_report: ; GET REPORT
mov A, DATA_TOGGLE ; set data toggle to DATA ONE
mov [ep0_data_toggle], A
mov A, NAK_IN_OUT ; clear setup bit to write to
iowr ep0_mode ; endpoint fifo
mov A, [ep1_dmabuff0] ; copy over button data
mov [ep0_dmabuff0], A
mov A, [ep1_dmabuff1] ; copy horizontal data
mov [ep0_dmabuff1], A
mov A, [ep1_dmabuff2] ; copy vertical data
mov [ep0_dmabuff2], A
mov A, TRANS_CONTROL_READ
mov [ep0_transtype], A
mov A, CONTROL_READ_DATA ; set state machine state
mov [ep0_in_machine], A
mov X, 03h ; set number of byte to transfer to 3
jmp dmabuffer_load_done ; jump to finish transfer
get_interface_idle: ; GET IDLE
mov A, DATA_TOGGLE ; set data toggle to DATA ONE
mov [ep0_data_toggle], A
mov A, NAK_IN_OUT ; clear setup bit to write to
iowr ep0_mode ; endpoint fifo
mov A, [idle] ; copy over idle time
mov [ep0_dmabuff0], A
mov A, TRANS_CONTROL_READ
mov [ep0_transtype], A
mov A, CONTROL_READ_DATA ; set state machine state
mov [ep0_in_machine], A
mov X, 01h ; set number of byte to transfer to 3
jmp dmabuffer_load_done ; jump to finish transfer
get_interface_protocol: ; GET PROTOCOL
mov A, INTERFACE_PROTOCOL_LENGTH
mov [maximum_data_count], A ; get offset of device descriptor table
mov A, [protocol]
and A, 01h
jz boot_protocol
report_protocol:
mov A, (interface_report_protocol - control_read_table)
mov [data_start], A
jmp initialize_control_read ; get ready to send data
boot_protocol:
mov A, (interface_boot_protocol - control_read_table)
mov [data_start], A
jmp initialize_control_read ; get ready to send data
get_interface_hid: ; GET HID REPORT DESCRIPTOR
mov A, [ep0_dmabuff + WVALUEHI]
cmp A, 22h ; test if report request
jz get_hid_report_desc
cmp A, 21h ; test if class request
jz get_hid_desc
jmp request_not_supported
get_hid_desc:
mov A, 00h
index hid_desc_table
mov [maximum_data_count], A ; get offset of device descriptor table
mov A, (hid_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read ; get ready to send data
get_hid_report_desc:
mov A, 07h
index hid_desc_table
mov [maximum_data_count], A ; get offset of device descriptor table
mov A, (hid_report_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read ; get ready to send data
;;************ ENDPOINT REQUESTS ************
clear_endpoint_feature: ; CLEAR FEATURE
mov A, [ep0_dmabuff + WVALUELO]
cmp A, ENDPOINT_STALL
jnz request_not_supported
mov A, 00h ; clear endpoint 1 stall
mov [ep1_stall], A
mov A, NO_CHANGE_PENDING ; respond with no-data control
mov [ep0_in_flag], A
jmp initialize_no_data_control
set_endpoint_feature: ; SET FEATURE
mov A, [ep0_dmabuff + WVALUELO]
cmp A, ENDPOINT_STALL
jnz request_not_supported
mov A, FFh ; stall endpoint 1
mov [ep1_stall], A
mov A, NO_CHANGE_PENDING ; respond with no-data control
mov [ep0_in_flag], A
jmp initialize_no_data_control
get_endpoint_status: ; GET STATUS
mov A, ENDPOINT_STALL_LENGTH
mov [maximum_data_count], A
mov A, [ep1_stall] ; test if endpoint 1 stalled
and A, FFh
jnz endpoint_stalled
endpoint_not_stalled: ; send no-stall status
mov A, (endpoint_nostall_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
endpoint_stalled: ; send stall status
mov A, (endpoint_stall_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
;;***************** CONTROL READ TRANSACTION **************
initialize_control_read:
mov A, TRANS_CONTROL_READ ; set transaction type to control read
mov [ep0_transtype], A
mov A, DATA_TOGGLE ; set data toggle to DATA ONE
mov [ep0_data_toggle], A
; if wLengthhi == 0
mov A, [ep0_dmabuff + WLENGTHHI] ; find lesser of requested and maximum
cmp A, 00h
jnz initialize_control_read_done
; and wLengthlo < maximum_data_count
mov A, [ep0_dmabuff + WLENGTHLO] ; find lesser of requested and maximum
cmp A, [maximum_data_count] ; response lengths
jnc initialize_control_read_done
; then maximum_data_count >= wLengthlo
mov A, [ep0_dmabuff + WLENGTHLO]
mov [maximum_data_count], A
initialize_control_read_done:
jmp control_read_data_stage ; send first packet
;;***************** CONTROL WRITE TRANSACTION *************
initialize_control_write:
mov A, TRANS_CONTROL_WRITE ; set transaction type to control write
mov [ep0_transtype], A
mov A, DATA_TOGGLE ; set accepted data toggle
mov [ep0_data_toggle], A
mov A, ACK_OUT_NAK_IN ; set mode
iowr ep0_mode
pop A
pop X
reti
;;***************** NO DATA CONTROL TRANSACTION ***********
initialize_no_data_control:
mov A, TRANS_NO_DATA_CONTROL ; set transaction type to no data control
mov [ep0_transtype], A
mov A, STATUS_IN_ONLY ; set SIE for STATUS IN mode
iowr ep0_mode
pop A
pop X
reti
;;***************** UNSUPPORTED TRANSACTION ***************
request_not_supported:
iord ep0_mode
mov A, STALL_IN_OUT ; send a stall to indicate that the request
iowr ep0_mode ; is not supported
pop A
pop X
reti
;**********************************************************
;**********************************
; IN - CONTROL READ DATA STAGE
; - CONTROL WRITE STATUS STAGE
; - NO DATA CONTROL STATUS STAGE
ep0_in_received:
mov A, [ep0_transtype]
jacc ep0_in_jumptable
;**********************************
control_read_data_stage:
mov X, 00h
mov A, [maximum_data_count]
cmp A, 00h ; has all been sent
jz dmabuffer_load_done
dmabuffer_load:
mov A, X ; check if 8 byte ep0 dma
cmp A, 08h ; buffer is full
jz dmabuffer_load_done
mov A, [data_start] ; read data from desc. table
index control_read_table
mov [X + ep0_dmabuff0], A
inc X ; increment buffer offset
inc [data_start] ; increment descriptor table pointer
dec [maximum_data_count] ; decrement number of bytes requested
jz dmabuffer_load_done
jmp dmabuffer_load ; loop to load more data
dmabuffer_load_done:
iord ep0_count ; unlock counter register
mov A, X ; find number of bytes loaded
or A, [ep0_data_toggle] ; or data toggle
iowr ep0_count ; write ep0 count register
mov A, ACK_IN_STATUS_OUT ; set endpoint mode to ack next IN
iowr ep0_mode ; or STATUS OUT
mov A, DATA_TOGGLE ; toggle data toggle
xor [ep0_data_toggle], A
pop A
pop X
reti
;**********************************
control_write_status_stage:
mov A, STATUS_IN_ONLY
iowr ep0_mode
mov A, TRANS_NONE
mov [ep0_transtype], A
pop A
pop X
reti
;**********************************
no_data_control_status_stage:
mov A, [ep0_in_flag] ; end of no-data control transaction
cmp A, ADDRESS_CHANGE_PENDING
jnz no_data_status_done
change_address:
mov A, [pending_data] ; change the device address if this
or A, ADDRESS_ENABLE ; data is pending
iowr usb_address
no_data_status_done: ; otherwise set to stall in/out until
mov A, STALL_IN_OUT ; a new setup
iowr ep0_mode
mov A, TRANS_NONE
mov [ep0_transtype], A
pop A
pop X
reti
;**********************************************************
;**********************************
; OUT - CONTROL READ STATUS STAGE
; - CONTROL WRITE DATA STAGE
; - ERROR DURING NO DATA CONTROL TRANSACTION
ep0_out_received:
mov A, [ep0_transtype]
jacc ep0_out_jumptable
;**********************************
control_read_status_stage:
mov A, STATUS_OUT_ONLY
iowr ep0_mode
mov A, TRANS_NONE
mov [ep0_transtype], A
pop A
pop X
reti
;**********************************
control_write_data_stage:
mov A, ep0_count ; check that data is valid
and A, DATA_VALID
jz control_write_data_stage_done
iord ep0_count ; check for correct data toggle
and A, DATA_TOGGLE
xor A, [ep0_data_toggle]
jnz control_write_data_stage_done
; get data and transfer it to a buffer here
mov A, DATA_TOGGLE
xor [ep0_data_toggle], A
control_write_data_stage_done:
pop A
pop X
reti
;**********************************
no_data_control_error:
mov A, STALL_IN_OUT
iowr ep0_mode
mov A, TRANS_NONE
mov [ep0_transtype], A
pop A
pop X
reti
;*******************************************************
;
; Interrupt handler: Endpoint1
; Purpose: This interrupt routine handles the specially
; reserved data endpoint 1 (for a mouse). This
; interrupt happens every time a host sends an
; IN on endpoint 1. The data to send (NAK or 3
; byte packet) is already loaded, so this routine
; just prepares the dma buffers for the next packet
;
;*******************************************************
Endpoint1:
push A
iord ep1_mode ; if the interrupt was caused by
and A, EP_ACK ; a NAK or STALL, then just set
jz endpoint1_set_response ; response and return
;**********************************
; change data toggle
mov A, 80h
xor [ep1_data_toggle], A
;**********************************
; clear endpoint variables
mov A, 00h ; clear x,y,z cursor change values
mov [ep1_dmabuff1], A
mov [ep1_dmabuff2], A
mov [ep1_dmabuff3], A
;**********************************
; set response
endpoint1_set_response:
mov A, [ep1_stall] ; if endpoint is set to stall, then set
cmp A, FFh ; mode to stall
jnz endpoint1_nak
mov A, STALL_IN_OUT
iowr ep1_mode
jmp endpoint1_done
endpoint1_nak:
mov A, NAK_IN ; clear the ACK and STALL bits
iowr ep1_mode
endpoint1_done:
pop A
reti
;*******************************************************
;
; Interrupt: Wakeup
; Purpose: This interrupt happens during USB suspend
; when the microcontroller wakes up due to the
; internal wakeup timer. The buttons and optics
; are then polled for any change in state. If
; a change occurs then a wakeup/resume signal
; is forced on the bus by this microcontroller.
;
;*******************************************************
Wakeup:
push A
;**********************************
; reset watchdog
iowr watchdog
;**********************************
; test if remote wakeup is enabled
mov A, [remote_wakeup]
cmp A, 00h
jz wakeup_done
;**********************************
; wait for a couple wakeup times to pass
; some hosts mess up if we drive a remote wakeup after 100ms
mov A, 05h
cmp A, [wakeup_timer]
jz test_buttons
inc [wakeup_timer]
jmp wakeup_done
;**********************************
; test for button status change
test_buttons:
mov A, 00h
mov [int_temp], A
wakeup_left_button_read:
iord LEFT_BUTTON_PORT
and A, LEFT_BUTTON
jnz wakeup_right_button_read
mov A, HID_LEFT_MOUSE_BUTTON
or [int_temp], A
wakeup_right_button_read:
iord RIGHT_BUTTON_PORT
and A, RIGHT_BUTTON
jnz wakeup_middle_button_read
mov A, HID_RIGHT_MOUSE_BUTTON
or [int_temp], A
wakeup_middle_button_read:
iord MIDDLE_BUTTON_PORT
and A, MIDDLE_BUTTON
jnz wakeup_button_read_done
mov A, HID_MIDDLE_MOUSE_BUTTON
or [int_temp], A
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -