📄 mouse.asm
字号:
mov [x_last_state], A
mov A, [y_current_state]
mov [y_last_state], A
mov A, [z_current_state]
mov [z_last_state], A
; this task sends data out endpoint 1 if the endpoint is configured
; and not set to stall
mov A, [event_machine]
jacc event_machine_jumptable
event_pending:
; if not configured then skip data transfer
mov A, [configuration]
cmp A, 01h
jnz event_task_done
; if stalled then skip data transfer
mov A, [ep1_stall]
cmp A, FFh
jz event_task_done
; We have to determine which protocol is currently enabled
; and send the format that is supported by that protocol
mov A, [protocol]
cmp A, HID_REPORT
jnz boot_protocol_report
hid_protocol_report:
mov A, 04h ; set endpoint 1 to send 3 bytes
or A, [ep1_data_toggle]
iowr ep1_count
mov A, ACK_IN ; set to ack on endpoint 1
iowr ep1_mode
jmp event_task_done
boot_protocol_report:
mov A, 03h ; set endpoint 1 to send 3 bytes
or A, [ep1_data_toggle]
iowr ep1_count
mov A, ACK_IN ; set to ack on endpoint 1
iowr ep1_mode
event_task_done:
mov A, NO_EVENT_PENDING ; clear pending events
mov [event_machine], A
no_event_task:
jmp task_loop
;*******************************************************
;
; Interrupt handler: Bus_reset
; Purpose: The program jumps to this routine when
; the host causes a USB reset.
;
;*******************************************************
Bus_reset:
mov A, STALL_IN_OUT ; set to STALL INs&OUTs
iowr ep0_mode
mov A, ADDRESS_ENABLE ; enable USB address 0
iowr usb_address
mov A, DISABLE ; disable endpoint1
iowr ep1_mode
mov A, 00h ; reset program stack pointer
mov psp,a
jmp Main
;*******************************************************
;
; Interrupt: 1ms_clear_control
; Purpose: This interrupt handler sets a flag to indicate
; it's time to read the buttons in the main task loop,
; watches for USB suspend, and handles the HID idle
; timer.
;
;*******************************************************
1ms_timer:
push A
;**********************************
; poll buttons for button on/off state
mov A, [button_machine]
cmp A, BUTTON_DATA_PENDING
jz 1ms_suspend_timer
; if the main task has read the buttons, then we need to re-read the
; buttons and set the pending flag
mov A, 00h
mov [current_button_state], A
left_button_read:
iord LEFT_BUTTON_PORT
and A, LEFT_BUTTON
jnz right_button_read
mov A, HID_LEFT_MOUSE_BUTTON
or [current_button_state], A
right_button_read:
iord RIGHT_BUTTON_PORT
and A, RIGHT_BUTTON
jnz middle_button_read
mov A, HID_RIGHT_MOUSE_BUTTON
or [current_button_state], A
middle_button_read:
iord MIDDLE_BUTTON_PORT
and A, MIDDLE_BUTTON
jnz button_read_done
mov A, HID_MIDDLE_MOUSE_BUTTON
or [current_button_state], A
button_read_done:
mov A, BUTTON_DATA_PENDING
mov [button_machine], A
;**********************************
; check for no bus activity/usb suspend
1ms_suspend_timer:
iord usb_status ; read bus activity bit
and A, BUS_ACTIVITY ; mask off activity bit
jnz bus_activity
inc [suspend_count] ; increment suspend counter
mov A, [suspend_count]
cmp A, 04h ; if no bus activity for 3-4ms,
jz usb_suspend ; then go into low power suspend
jmp idle_timer_handler
usb_suspend:
;******************************
; disable unused pins
; buttons are already resistively pulled up
; optics inputs are pulled down by external resistors
; must turn off LED
; NOTE - this firmware must change for each pin out
mov A, OPTIC_CONTROL | LEFT_BUTTON
iowr OPTIC_CONTROL_PORT
; enable wakeup timer interrupt
mov A, (WAKEUP_INT | USB_RESET_INT)
iowr global_int
; suspend execution
mov A, (SUSPEND | RUN) ; set suspend bit
ei
iowr control
nop
di
; look for bus activity, if none go back into suspend
iord usb_status
and A, BUS_ACTIVITY
jz usb_suspend
; re-enable the optics in the case of the host wakeup
mov A, LEFT_BUTTON
iowr OPTIC_CONTROL_PORT
; re-enable interrupts
mov A, (1MS_INT | USB_RESET_INT)
iowr global_int
; reset wakeup timer
mov A, 00h
mov [wakeup_timer], A
bus_activity:
mov A, 00h ; reset suspend counter
mov [suspend_count], A
iord usb_status
and A, ~(BUS_ACTIVITY | 10h) ; clear bus activity bit
iowr usb_status
;**********************************
; handle HID SET_IDLE request
idle_timer_handler:
mov A, [idle]
cmp A, 00h
jz ms_timer_done
inc [idle_prescaler]
mov A, [idle_prescaler]
cmp A, 04h
jz decrement_idle_timer
jmp ms_timer_done
decrement_idle_timer:
mov A, 00h
mov [idle_prescaler], A
dec [idle_timer]
jz reset_idle_timer
jmp ms_timer_done
reset_idle_timer:
mov A, [idle]
mov [idle_timer], A
mov A, EVENT_PENDING
mov [event_machine], A
ms_timer_done:
pop A
reti
;*******************************************************
;
; Interrupt: Endpoint0
; Purpose: Usb control endpoint handler. This interrupt
; handler formulates responses to SETUP and
; CONTROL READ, and NO-DATA CONTROL transactions.
;
;*******************************************************
Endpoint0:
push X
push A
iord ep0_mode
and A, EP0_ACK
jz ep0_done
iord ep0_mode
asl A
jc ep0_setup_received
asl A
jc ep0_in_received
asl A
jc ep0_out_received
ep0_done:
pop A
pop X
reti
ep0_setup_received:
mov A, NAK_IN_OUT ; clear setup bit to enable
iowr ep0_mode ; writes to EP0 DMA buffer
mov A, [ep0_dmabuff + BMREQUESTTYPE] ; compact bmRequestType into 5 bit field
and A, E3h ; clear bits 4-3-2, these unused for our purposes
push A ; store value
asr A ; move bits 7-6-5 into 4-3-2's place
asr A
asr A
mov [int_temp], A ; store shifted value
pop A ; get original value
or A, [int_temp] ; or the two to get the 5-bit field
and A, 1Fh ; clear bits 7-6-5 (asr wraps bit7)
asl A ; shift to index jumptable
jacc bmRequestType_jumptable ; jump to handle bmRequestType
h2d_std_device:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc h2d_std_device_jumptable
h2d_std_interface:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc h2d_std_interface_jumptable
h2d_std_endpoint:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc h2d_std_endpoint_jumptable
h2d_class_interface:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc h2d_class_interface_jumptable
d2h_std_device:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc d2h_std_device_jumptable
d2h_std_interface:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc d2h_std_interface_jumptable
d2h_std_endpoint:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc d2h_std_endpoint_jumptable
d2h_class_interface:
mov A, [ep0_dmabuff + BREQUEST]
asl A
jacc d2h_class_interface_jumptable
;;************ DEVICE REQUESTS **************
clear_device_feature: ; CLEAR FEATURE
mov A, [ep0_dmabuff + WVALUELO]
cmp A, DEVICE_REMOTE_WAKEUP
jnz request_not_supported
mov A, 00h ; disable remote wakeup capability
mov [remote_wakeup], A
mov A, NO_CHANGE_PENDING
mov [ep0_in_flag], A
jmp initialize_no_data_control
set_device_feature: ; SET FEATURE
mov A, [ep0_dmabuff + WVALUELO]
cmp A, DEVICE_REMOTE_WAKEUP
jnz request_not_supported
mov A, FFh ; enable remote wakeup capability
mov [remote_wakeup], A
mov A, NO_CHANGE_PENDING
mov [ep0_in_flag], A
jmp initialize_no_data_control
set_device_address: ; SET ADDRESS
mov A, ADDRESS_CHANGE_PENDING ; set flag to indicate we
mov [ep0_in_flag], A ; need to change address on
mov A, [ep0_dmabuff + WVALUELO]
mov [pending_data], A
jmp initialize_no_data_control
set_device_configuration: ; SET CONFIGURATION
mov A, [ep0_dmabuff + WVALUELO]
cmp A, 01h
jz configure_device
unconfigure_device: ; set device as unconfigured
mov [configuration], A
mov A, DISABLE ; disable endpoint 1
iowr ep1_mode
mov A, EP0_INT ; turn off endpoint 1 interrupts
iowr endpoint_int
jmp set_device_configuration_done
configure_device: ; set device as configured
mov [configuration], A
mov A, [ep1_stall] ; if endpoint 1 is stalled
and A, FFh
jz ep1_nak_in_out
mov A, STALL_IN_OUT ; set endpoint 1 mode to stall
iowr ep1_mode
jmp ep1_set_int
ep1_nak_in_out:
mov A, NAK_IN_OUT ; otherwise set it to NAK in/out
iowr ep1_mode
ep1_set_int:
mov A, EP0_INT | EP1_INT ; enable endpoint 1 interrupts
iowr endpoint_int
mov A, 00h
mov [ep1_data_toggle], A ; reset the data toggle
mov [ep1_dmabuff0], A ; reset endpoint 1 fifo values
mov [ep1_dmabuff1], A
mov [ep1_dmabuff2], A
set_device_configuration_done:
mov A, NO_CHANGE_PENDING
mov [ep0_in_flag], A
jmp initialize_no_data_control
get_device_status: ; GET STATUS
mov A, DEVICE_STATUS_LENGTH
mov [maximum_data_count], A
mov A, [remote_wakeup] ; test remote wakeup status
and A, FFh
jz remote_wakeup_disabled
remote_wakeup_enabled: ; send remote wakeup enabled status
mov A, (device_status_wakeup_enabled - control_read_table)
mov [data_start], A
jmp initialize_control_read
remote_wakeup_disabled: ; send remote wakeup disabled status
mov A, (device_status_wakeup_disabled - control_read_table)
mov [data_start], A
jmp initialize_control_read
get_device_descriptor: ; GET DESCRIPTOR
mov A, [ep0_dmabuff + WVALUEHI]
asl A
jacc get_device_descriptor_jumptable
send_device_descriptor:
mov A, 00h
index device_desc_table
mov [maximum_data_count], A
mov A, (device_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
send_configuration_descriptor:
mov A, 02h
index config_desc_table:
mov [maximum_data_count], A
mov A, (config_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
send_string_descriptor:
mov A, [ep0_dmabuff + WVALUELO]
asl A
jacc string_jumptable:
language_string:
mov A, 00h
index ilanguage_string
mov [maximum_data_count], A
mov A, (ilanguage_string - control_read_table)
mov [data_start], A
jmp initialize_control_read
manufacturer_string:
mov A, 00h
index imanufacturer_string
mov [maximum_data_count], A
mov A, (imanufacturer_string - control_read_table)
mov [data_start], A
jmp initialize_control_read
product_string:
mov A, 00h
index iproduct_string
mov [maximum_data_count], A
mov A, (iproduct_string - control_read_table)
mov [data_start], A
jmp initialize_control_read
configuration_string:
mov A, 00h
index iconfiguration_string
mov [maximum_data_count], A
mov A, (iconfiguration_string - control_read_table)
mov [data_start], A
jmp initialize_control_read
send_interface_descriptor:
mov A, 00h
index interface_desc_table
mov [maximum_data_count], A
mov A, (interface_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
send_endpoint_descriptor:
mov A, 00h
index endpoint_desc_table
mov [maximum_data_count], A
mov A, (endpoint_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
get_device_configuration: ; GET CONFIGURATION
mov A, DEVICE_CONFIG_LENGTH
mov [maximum_data_count], A
mov A, [configuration] ; test configuration status
and A, FFh
jz device_unconfigured
device_configured: ; send configured status
mov A, (device_configured_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
device_unconfigured: ; send unconfigured status
mov A, (device_unconfigured_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
;;************ INTERFACE REQUESTS ***********
set_interface_interface: ; SET INTERFACE
mov A, [ep0_dmabuff + WVALUELO]
cmp A, 00h ; there are no alternate interfaces
jz alternate_supported ; for this device
alternate_not_supported: ; if the host requests any other
jmp request_not_supported ; alternate than 0, stall.
alternate_supported:
mov A, NO_CHANGE_PENDING
mov [ep0_in_flag], A
jmp initialize_no_data_control
get_interface_status: ; GET STATUS
mov A, INTERFACE_STATUS_LENGTH
mov [maximum_data_count], A
mov A, (interface_status_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
get_interface_interface: ; GET INTERFACE
mov A, INTERFACE_ALTERNATE_LENGTH
mov [maximum_data_count], A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -