📄 hidtherm.asm
字号:
send_interface_descriptor:
mov A, INTERFACE_DESC_SIZE
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, ENDPOINT_DESC_SIZE ; assign endpoint desc size
mov [maximum_data_count], A
mov A, [ep0_dmabuff + WVALUELO] ; find requested endpoint #
cmp A, 02h
jz send_endpoint2_desc:
send_endpoint1_desc:
mov A, (endpoint1_desc_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
send_endpoint2_desc:
mov A, (endpoint2_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
get_device_status:
mov A, DEVICE_STATUS_LENGTH
mov [maximum_data_count], A
mov A, (device_status_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
mov A, (interface_alternate_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
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, [ep0_dmabuff + WINDEXHI]
cmp A, 02h
jz clear_endpoint2_feature
clear_endpoint1_feature:
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
clear_endpoint2_feature:
mov A, 00h ; clear endpoint 1 stall
mov [ep2_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, [ep0_dmabuff + WINDEXHI] ; check which endpoint to stall
cmp A, 02h
jz set_endpoint2_feature
set_endpoint1_feature:
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
set_endpoint2_feature:
mov A, FFh ; stall endpoint 2
mov [ep2_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, [ep0_dmabuff + WINDEXHI] ; check which endpoint status is being asked for
cmp A, 02h
jz get_endpoint2_status
get_endpoint1_status:
mov A, [ep1_stall] ; test if endpoint 1 stalled
and A, FFh
jnz endpoint1_stalled
endpoint1_not_stalled: ; send no-stall status
mov A, (endpoint_nostall_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
endpoint1_stalled: ; send stall status
mov A, (endpoint_stall_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
get_endpoint2_status:
mov A, [ep2_stall] ; test if endpoint 1 stalled
and A, FFh
jnz endpoint2_stalled
endpoint2_not_stalled: ; send no-stall status
mov A, (endpoint_nostall_table - control_read_table)
mov [data_start], A
jmp initialize_control_read
endpoint2_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 endpoint 1. This
; interrupt happens every time a host sends an
; IN on endpoint 1. The data to send (NAK, STALL, or
; report packet) is already loaded, so this routine
; gets called after the IN transaction has
; taken place.
;
;*******************************************************
Endpoint1:
push A
; check to see if we ACK'd the last IN token
iord ep1_mode
and A, EP_ACK
jz endpoint1_set_response
; the ACK bit is sticky, so we have to clear it in firmware
mov A, NAK_IN
iowr ep1_mode
; change data toggle
mov A, 80h
xor [ep1_data_toggle], A
; clear the button report data, if any
mov A, 00h
mov [ep1_dmabuff0], A
; clear the report pending flag
mov A, NO_REPORT_PENDING
mov [event_machine], A
; set the next response to and IN token
endpoint1_set_response:
mov A, [ep1_stall] ; if endpoint is set to stall, then set
cmp A, FFh ; mode to stall
jnz endpoint1_done
mov A, STALL_IN_OUT ; set endpoint to stall (if stall flag is set)
iowr ep1_mode
endpoint1_done:
pop A
reti
;*******************************************************
;
; Interrupt handler: endpoint2
; Purpose: This interrupt routine handles endpoint 2. This
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -