📄 mouse.asm
字号:
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
; flag that interrupt went off during processing.
inc [int_flag]
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
wakeup_button_read_done:
mov A, [int_temp]
xor A, [current_button_state]
jnz force_wakeup
;**********************************
; test for optics status change
; turn on optics
; mov A, LEFT_BUTTON
; iowr OPTIC_CONTROL_PORT
; wait 100us for phototransistors to turn on
; mov A, 80h
; optic_delay:
; dec A
; jnz optic_delay
; test x-axis for change
; mov A, 00h
; mov [int_temp], A
; test_x0:
; iord X_OPTICS_PORT
; mov X, A
; and A, X0
; jz test_x1
; mov A, 01h
; or [int_temp], A
; test_x1:
; mov A, X
; and A, X1
; jz test_x
; mov A, 02h
; or [int_temp], A
; test_x:
; mov A, [int_temp]
; cmp A, [x_last_state]
; jnz force_wakeup
; test y-axis for change
; mov A, 00h
; mov [int_temp], A
; test_y0:
; iord Y_OPTICS_PORT
; mov X, A
; and A, Y0
; jz test_y1
; mov A, 01h
; or [int_temp], A
; test_y1:
; mov A, X
; and A, Y1
; jz test_y
; mov A, 02h
; or [int_temp], A
; test_y:
; mov A, [int_temp]
; cmp A, [y_last_state]
; jnz force_wakeup
; test z-axis for change
; mov A, 00h
; mov [int_temp], A
; test_z0:
; iord Z_OPTICS_PORT
; mov X, A
; and A, Z0
; jz test_z1
; mov A, 01h
; or [int_temp], A
; test_z1:
; mov A, X
; and A, Z1
; jz test_z
; mov A, 02h
; or [int_temp], A
;
; test_z:
; mov A, [int_temp]
; cmp A, [z_last_state]
; jnz force_wakeup
;
; if there is no change in the optics, then we need to go back to sleep
; mov A, OPTIC_CONTROL
; iowr OPTIC_CONTROL_PORT
pop A
reti
;**********************************
; force resume for 14ms
force_wakeup:
mov A, VREG_ENABLE | CONTROL1 ; force J
iowr usb_status
mov A, VREG_ENABLE | CONTROL0 ; force K
iowr usb_status
mov A, 48h ; wait 14ms
outer_wakeup_timer:
push A
iowr watchdog
mov A, FFh
inner_wakeup_timer:
dec A
jnz inner_wakeup_timer
pop A
dec A
jnz outer_wakeup_timer
mov A, VREG_ENABLE | BUS_ACTIVITY ; disable forcing and signal
iowr usb_status ; that we are about to have
; bus activity
wakeup_done:
pop A
reti
;**********************************************************
; USB REQUEST JUMP TABLES
;**********************************************************
XPAGEOFF
ORG C00h
; bmRequestTypes commented out are not used for this device,
; but may be used for your device. They are kept here as
; an example of how to use this jumptable.
bmRequestType_jumptable:
jmp h2d_std_device ; 00
jmp h2d_std_interface ; 01
jmp h2d_std_endpoint ; 02
jmp request_not_supported ; h2d_std_other 03
jmp request_not_supported ; h2d_class_device 04
jmp h2d_class_interface ; 05
jmp request_not_supported ; h2d_class_endpoint 06
jmp request_not_supported ; h2d_class_other 07
jmp request_not_supported ; h2d_vendor_device 08
jmp request_not_supported ; h2d_vendor_interface 09
jmp request_not_supported ; h2d_vendor_endpoint 0A
jmp request_not_supported ; h2d_vendor_other 0B
jmp request_not_supported ; 0C
jmp request_not_supported ; 0D
jmp request_not_supported ; 0E
jmp request_not_supported ; 0F
jmp d2h_std_device ; 10
jmp d2h_std_interface ; 11
jmp d2h_std_endpoint ; 12
jmp request_not_supported ; d2h_std_other 13
jmp request_not_supported ; d2h_class_device 14
jmp d2h_class_interface ; 15
jmp request_not_supported ; d2h_class_endpoint 16
jmp request_not_supported ; d2h_class_other 17
jmp request_not_supported ; d2h_vendor_device 18
jmp request_not_supported ; d2h_vendor_interface 19
jmp request_not_supported ; d2h_vendor_endpoint 1A
jmp request_not_supported ; d2h_vendor_other 1B
jmp request_not_supported ; 1C
jmp request_not_supported ; 1D
jmp request_not_supported ; 1E
jmp request_not_supported ; 1F
h2d_std_device_jumptable:
jmp request_not_supported ; 00
jmp clear_device_feature ; 01
jmp request_not_supported ; 02
jmp set_device_feature ; 03
jmp request_not_supported ; 04
jmp set_device_address ; 05
jmp request_not_supported ; 06
jmp request_not_supported ; set_device_descriptor 07
jmp request_not_supported ; 08
jmp set_device_configuration; 09
h2d_std_interface_jumptable:
jmp request_not_supported ; 00
jmp request_not_supported ; clear_interface
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -