📄 usb_cls_hid.asm
字号:
USB_CB_h2d_cls_ifc_09:
call Find_Report
NULL_PTR_CHECK .not_supported
jmp USB_GetTableEntry
.not_supported:
jmp USB_Not_Supported_Local1
ENDIF
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_CB_h2d_cls_ifc_10
;
; DESCRIPTION: Set Idle
;
;****************************************************************
; HID CLASS INTERFACE OUT REQUEST: Set_Idle
;****************************************************************
;
; bmRequestType : (OUT | CLASS | INTERFACE) = 21h
; bRequest : SET_IDLE = 0Ah
; wValue : DURATION | REPORT ID = xxxxh
; wIndex : INTERFACE = --xxh
; wLength : ZERO = 0000h
;
; The SET_IDLE request silences a particular input report (or all
; input reports) on a specific interface until a new event occurs
; or the specified amount of time passes.
;
;****************************************************************
; Note: This function does not support multiple reports per interface.
;****************************************************************
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
;
; RETURNS:
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_h2d_cls_ifc_10 & USB_UM_SUPPLIED)
export USB_CB_h2d_cls_ifc_10
USB_CB_h2d_cls_ifc_10:
; TODO: Verify that report numbers 1 to n (or 0 to n-1)
mov A, REG[USB_EP0DATA+wValueLo] ; Get the report number
cmp A, 0 ; We don't support report by report idle
jnz USB_Not_Supported_Local1
mov A, REG[USB_EP0DATA+wIndexLo] ; Get the interface number
cmp A, 1 ; Range Check
jnc USB_Not_Supported_Local1
mov X, A ; Interface Number becomes an index
mov A, REG[USB_EP0DATA+wValueHi] ; Get the duration
mov [X+USB_IdleReload], A ; Save the reload immediately
cmp A, 0 ; Is this request setting the duration to indefinite?
jz .reload ; If so, reload the timer
; Otherwise, we need to determine if we reset the current expiry
; (HID Spec says to send the next report if we are within 4 ms (1 count)
; of sending the next report
cmp [X+USB_IdleTimer], 1 ; Within 4 ms?
jz .done ; Jump to let the timer expire "naturally"
; Jump or Flow here to reload the timer
.reload:
mov [x+USB_IdleTimer], A ; Reload the timer
.done:
jmp USB_NoDataStageControlTransfer
ENDIF
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_CB_h2d_cls_ifc_11
;
; DESCRIPTION: Set Idle
;
;****************************************************************
; HID CLASS INTERFACE OUT REQUEST: Set_Protocol
;****************************************************************
;
; bmRequestType : (OUT | CLASS | INTERFACE) = 21h
; bRequest : SET_PROTOCOL = 0Bh
; wValue : DURATION | REPORT ID = xxxxh
; wIndex : PROTOCOL = --xxh
; wLength : ZERO = 0000h
;
; The SET_PROTOCOL request switches between the boot protocol and
; the report protocol (or vice versa).
;
;****************************************************************
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
;
; RETURNS:
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_h2d_cls_ifc_11 & USB_UM_SUPPLIED)
export USB_CB_h2d_cls_ifc_11
USB_CB_h2d_cls_ifc_11:
mov A, REG[USB_EP0DATA+wIndexLo] ; Get the interface number
cmp A, 1 ; Range check
jnc USB_Not_Supported_Local1
mov X, A ; Save the interface number
mov A, REG[USB_EP0DATA+wValueLo] ; Get the protocol
cmp A, (1+1) ; Must be zero or one
jnc USB_Not_Supported_Local1
mov [X + USB_Protocol], A ; Save the new protocol
jmp USB_NoDataStageControlTransfer
ENDIF
;-----------------------------------------------------------------------------
; FUNCTION NAME: Find_Report
;
; DESCRIPTION: Scan the HID Report Tree and return a pointer to the
; HID Report Transfer Descriptor (TD) or NULL
; This function is called in during the processing of
; GET_REPORT or SET_REPORT HID Class Requests.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
;
; RETURNS:
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
Find_Report:
call USB_GetInterfaceLookupTable ; Point the the interface lookup table
; The first entry of the table point to the report table.
mov [USB_t2],USB_t1 ; Set the GETWORD destination
call USB_GETWORD ; Get the pointer to the transfer descriptor table
; ITempW has the address
mov A, REG[USB_EP0DATA+wIndexLo] ; Get the interface number
mov [USB_t2], A ; Use the UM temp var--Selector
mov A, [USB_t1] ; Get the Table Address MSB
mov X, [USB_t1+1] ; Get the Table Address LSB
asl [USB_t2] ; Convert the index to offset
swap A, X
add A, [USB_t2]
swap A, X
adc A, 0 ; A:X now points to the table entry we want
; Get the pointer to the Report Type Table
GET_WORD
; Dereference to the requested Report Type
push A ; Don't loose the pointer MSB
mov A, REG[USB_EP0DATA+wValueHi] ; Get the Report Type
dec A ; Make it 0 based
mov [USB_t2], A ; Use the UM temp var--Selector
pop A ; Get the MSB back
push A ; Don't loose the pointer MSB
romx ; Get the table size
cmp A, [USB_t2] ; Range check
jc .not_supported_pop_1
pop A ; Get the MSB back
inc X ; Point to the next entry
adc A, 0 ;
LT_INDEX_TO_OFFSET USB_t2 ; Convert the index to offset
swap A, X
add A, [USB_t2]
swap A, X
adc A, 0 ; A:X now points to the table entry we want
; Get the pointer to the requested Report Table
GET_WORD ; A:X points to the
NULL_PTR_CHECK .not_supported ; Null Table entries indicated not supported
; Dereference to the requested TRANSFER DESCRIPTOR
push A ; Don't loose the pointer MSB
mov A, REG[USB_EP0DATA+wValueLo] ; Get the Report ID
mov [USB_t2], A ; Use the UM temp var--Selector
pop A ; Get the MSB back
push A ; Don't loose the pointer MSB
romx ; Get the table size
cmp A, [USB_t2] ; Range check
jc .not_supported_pop_1
pop A ; Get the MSB back
ret ; Finished A:X point to the TD
.not_supported_pop_1:
pop A ; Restore the stack
.not_supported:
mov A, 0 ; Return a null pointer
mov X, A ;
ret
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_GetInterfaceLookupTable
;
; DESCRIPTION: Point to the interface lookup table
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
;
; RETURNS:
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
export USB_GetInterfaceLookupTable:
USB_GetInterfaceLookupTable:
call USB_GET_CONFIG_TABLE_ENTRY ; Get the CONFIG_LOOKUP entry
swap A, X ; Second entry points to the HID_LOOKUP table
add A, 2 ; So add two
swap A, X ;
adc A, 0 ; Don't forget the carry
mov [USB_t2],USB_t1 ; Set the GETWORD destination
call USB_GETWORD ; Get the pointer to the HID_LOOKUP table
; ITempW has the address
mov A, [USB_t1] ; Get the table address MSB
mov X, [USB_t1+1] ; Get the table address LSB
ret
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; USB 2nd Tier Dispactch Jump Tables for HID Class Requests (based on bRequest)
;-----------------------------------------------------------------------------
; FUNCTION NAME: ; USB 2nd Tier Dispactch Jump Table
;
; DESCRIPTION: The following tables dispatch to the Standard request handler
; functions. (Assumes bmRequestType(5:6) is 0, Standard)
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
;
; RETURNS:
;
; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
; THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
.LITERAL
USB_DT_h2d_cls_ifc:
;-----------------------------------------------------------------------------
jmp USB_CB_h2d_cls_ifc_00
jmp USB_CB_h2d_cls_ifc_01
jmp USB_CB_h2d_cls_ifc_02
jmp USB_CB_h2d_cls_ifc_03
jmp USB_CB_h2d_cls_ifc_04
jmp USB_CB_h2d_cls_ifc_05
jmp USB_CB_h2d_cls_ifc_06
jmp USB_CB_h2d_cls_ifc_07
jmp USB_CB_h2d_cls_ifc_08
jmp USB_CB_h2d_cls_ifc_09
jmp USB_CB_h2d_cls_ifc_10
jmp USB_CB_h2d_cls_ifc_11
jmp USB_CB_h2d_cls_ifc_12
USB_DT_h2d_cls_ifc_End:
USB_DT_h2d_cls_ifc_Size: equ (USB_DT_h2d_cls_ifc_End-USB_DT_h2d_cls_ifc) / 2
USB_DT_h2d_cls_ifc_Dispatch::
mov A, REG[USB_EP0DATA + bRequest] ; Get the request number
DISPATCHER USB_DT_h2d_cls_ifc, USB_DT_h2d_cls_ifc_Size, USB_Not_Supported_Local1
.ENDLITERAL
;-----------------------------------------------------------------------------
.LITERAL
USB_DT_d2h_cls_ifc:
;-----------------------------------------------------------------------------
jmp USB_CB_d2h_cls_ifc_00
jmp USB_CB_d2h_cls_ifc_01
jmp USB_CB_d2h_cls_ifc_02
jmp USB_CB_d2h_cls_ifc_03
USB_DT_d2h_cls_ifc_End:
USB_DT_d2h_cls_ifc_Size: equ (USB_DT_d2h_cls_ifc_End-USB_DT_d2h_cls_ifc) / 2
USB_DT_d2h_cls_ifc_Dispatch::
mov A, REG[USB_EP0DATA + bRequest] ; Get the request number
DISPATCHER USB_DT_d2h_cls_ifc, USB_DT_d2h_cls_ifc_Size, USB_Not_Supported_Local1
.ENDLITERAL
IF (USB_CB_SRC_d2h_cls_ifc_00 & USB_NOT_SUPPORTED)
export USB_CB_d2h_cls_ifc_00
USB_CB_d2h_cls_ifc_00:
ENDIF
IF (USB_CB_SRC_d2h_cls_ifc_01 & USB_NOT_SUPPORTED)
export USB_CB_d2h_cls_ifc_01
USB_CB_d2h_cls_ifc_01:
ENDIF
IF (USB_CB_SRC_d2h_cls_ifc_02 & USB_NOT_SUPPORTED)
export USB_CB_d2h_cls_ifc_02
USB_CB_d2h_cls_ifc_02:
ENDIF
IF (USB_CB_SRC_d2h_cls_ifc_03 & USB_NOT_SUPPORTED)
export USB_CB_d2h_cls_ifc_03
USB_CB_d2h_cls_ifc_03:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_00 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_00
USB_CB_h2d_cls_ifc_00:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_01 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_01
USB_CB_h2d_cls_ifc_01:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_02 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_02
USB_CB_h2d_cls_ifc_02:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_03 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_03
USB_CB_h2d_cls_ifc_03:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_04 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_04
USB_CB_h2d_cls_ifc_04:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_05 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_05
USB_CB_h2d_cls_ifc_05:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_06 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_06
USB_CB_h2d_cls_ifc_06:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_07 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_07
USB_CB_h2d_cls_ifc_07:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_08 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_08
USB_CB_h2d_cls_ifc_08:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_09 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_09
USB_CB_h2d_cls_ifc_09:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_10 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_10
USB_CB_h2d_cls_ifc_10:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_11 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_11
USB_CB_h2d_cls_ifc_11:
ENDIF
IF (USB_CB_SRC_h2d_cls_ifc_12 & USB_NOT_SUPPORTED)
export USB_CB_h2d_cls_ifc_12
USB_CB_h2d_cls_ifc_12:
ENDIF
jmp USB_Not_Supported_Local1
; End of File USB_cls_hid.asm
USB_Not_Supported_Local1:
ljmp USB_Not_Supported
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -