📄 usbhidio.asm
字号:
mov A, [bRequest] ; load bRequest
; Get Status bRequest = 0
cmp A, get_status
jz GetDeviceStatus
; Get Descriptor bRequest = 6
cmp A, get_descriptor
jz GetDescriptor
; Get Configuration bRequest = 8
cmp A, get_configuration
jz GetConfiguration
;Stall unsupported requests.
jmp SendStall
;Device to host with interface as recipient
RequestType81:
mov A, [bRequest] ; load bRequest
; Get Status bRequest = 0
cmp A, get_status
jz GetInterfaceStatus
; Get Interface returns the selected alternate setting.
; This firmware supports no alternate settings.
; Get Interface bRequest = 10 *** not supported ***
;The HID class defines one more request for bmRequestType=10000001
; Get Descriptor bRequest = 6
cmp A, get_descriptor
jz GetDescriptor
;Stall unsupported functions
jmp SendStall
;Device to host with endpoint as recipient
RequestType82:
mov A, [bRequest] ; load bRequest
; Get Status bRequest = 0
cmp A, get_status
jz GetEndpointStatus
; Get Descriptor bRequest = 6
cmp A, get_descriptor
jz GetDescriptor
; Sync Frame bRequest = 12 *** not supported ***
;Stall unsupported functions.
jmp SendStall
;Check for HID class requests
;Host to device with endpoint as recipient
RequestType21:
mov A, [bRequest] ; load bRequest
; Set Report bRequest = 9
cmp A, set_report
jz SetReport
; Set Idle bRequest = 10
cmp A, set_idle
jz SetIdle
; Set Protocol bRequest = 11
cmp A, set_protocol
jz SetProtocol
;Stall unsupported requests
jmp SendStall
RequestType22:
mov A, [bRequest] ; load bRequest
; Set Report bRequest = 9
cmp A, set_report
jz SetReport
;Stall unsupported requests
jmp SendStall
;Device to host with endpoint as recipient
RequestTypeA1:
mov A, [bRequest] ; load bRequest
; Get Report bRequest = 1
cmp A, get_report
jz GetReport
; Get Idle bRequest = 2
cmp A, get_idle
jz GetIdle
; Get Protocol bRequest = 3
cmp A, get_protocol
jz GetProtocol
;Stall unsupported requests
jmp SendStall
;----------------------------------------------------------------------
;Control transfer, stage three
;Process the request.
;----------------------------------------------------------------------
;The host controls whether or not a device can request a remote wakeup.
; Disable the remote wakeup capability.
ClearRemoteWakeup:
mov A, [wValue]
cmp A, device_remote_wakeup
jnz SendStall
;Handshake by sending a data packet
call Send0ByteDataPacket
mov A, DISABLE_REMOTE_WAKEUP
mov [remote_wakeup_status], A
ret
; Enable the remote wakeup capability.
SetRemoteWakeup:
mov A, [wValue]
cmp A, device_remote_wakeup
;If not a match, stall.
jnz SendStall
;Handshake by sending a 0-byte data packet
call Send0ByteDataPacket
;Perform the request.
mov A, ENABLE_REMOTE_WAKEUP
mov [remote_wakeup_status], A
ret
SetAddress:
; Set the device address to match wValue in the Setup packet.
;Complete the requested action after completing the transaction.
;Handshake by sending a 0-byte data packet.
call Send0ByteDataPacket
;Perform the request
mov A, [wValue]
iowr USB_Device_Address
ret
SetConfiguration:
;Unconfigured: wValue=0, configured: wValue=1.
;Also clear any stall condition and set Data 0/1 to Data0.
;Handshake by sending a 0-byte data packet.
call Send0ByteDataPacket
;Save the configuration status.
mov A, [wValue]
mov [configuration_status], A
;Clear any stall condtion
mov A, 0
mov [endpoint_stall], A
;Set data 0/1 to Data0
iord USB_EP1_TX_Config
and A, ~DataToggle
;Set the configuration status.
iowr USB_EP1_TX_Config
mov A, [configuration_status]
cmp A, 0
;If configured, jump.
jnz device_configured
;If unconfigured:
;Disable Endpoint 1
iord USB_EP1_TX_Config
and A, EFh
iowr USB_EP1_TX_Config
;Disable Endpoint 1 interrupts.
mov A, [interrupt_mask]
and A, EFh
mov [interrupt_mask], A
jmp done_configuration
;If configured:
device_configured:
;Send NAK in response to IN packets
iord USB_EP1_TX_Config
and A,7Fh
;Enable Endpoint 1
or A, 10h
iowr USB_EP1_TX_Config
;Enable interrupts: Endpoint 1 and GPIO
mov A, [interrupt_mask]
or A, 50h
mov [interrupt_mask], A
;Send NAK in response to Endpoint 0 OUT packets.
iord USB_Status_Control
and A,0EFh
iowr USB_Status_Control
done_configuration:
ret
ClearEndpointStall:
;Clear the stall (halt) condition for Endpoint 1.
;wValue = 0.
mov A, [wValue]
cmp A, endpoint_stalled
;If endpoint_stalled = 0, the endpoint isn't stalled
;and there's nothing to clear. Return a Stall for the request.
jnz SendStall
;
;Clear Endpoint 1 stall
;Handshake by sending a 0-byte data packet
call Send0ByteDataPacket
;Clear the stall condition
mov A,0
mov [endpoint_stall], A
;Set Data 0/1 to Data0
iord USB_EP1_TX_Config
and A, ~DataToggle
iowr USB_EP1_TX_Config
;Send NAK in response to Endpoint 0 OUT packets.
iord USB_Status_Control
and A,0EFh
iowr USB_Status_Control
ret
;Stall Endpoint 1
SetEndpointStall:
;wValue = 0.
mov A, [wValue]
cmp A, endpoint_stalled
;If endpoint_stalled = 1, the endpoint is already stalled,
;so return a Stall for this request.
jnz SendStall
;Handshake by sending a 0-byte data packet.
call Send0ByteDataPacket
;Stall the endpoint.
mov A,1
mov [endpoint_stall], A
mov A, 30h
iowr USB_EP1_TX_Config
ret
GetDeviceStatus:
;Device Status is a 2-byte value.
;Bit 0 must be 0 (bus-powered).
;Bit 1 is remote wakeup: 0=disabled, 1=enabled.
;All other bits are unused.
;Return to status bytes to the host.
mov A, 2
mov [data_count], A
;control_read_table holds the two possible values for device status.
;Get the address of the first value.
mov A, (get_dev_status_table - control_read_table)
;Add an index value to select the correct value.
add A, [remote_wakeup_status]
;Send the value.
jmp SendDescriptor
GetDescriptor:
;The high byte of wValue contains the descriptor type.
;The low byte of wValue contains the descriptor index.
mov A, [wValueHi] ; load descriptor type
;Test for standard descriptor types first.
;Supported descriptor types are device, configuration, string.
;Unsupported descriptor types are interface, endpoint.
; Get Descriptor (device) wValueHi = 1
cmp A, device
jz GetDeviceDescriptor
; Get Descriptor (configuration) wValueHi = 2
cmp A, configuration
jz GetConfigurationDescriptor
; Get Descriptor (string) wValueHi = 3
cmp A, string
jz GetStringDescriptor
; Test for HID-class descriptor types.
; Get Descriptor (HID) wValueHi = 21h
cmp A, HID
jz GetHIDDescriptor
; Get Descriptor (report) wValueHi = 22h
cmp A, report
jz GetReportDescriptor
; Get Descriptor (physical) wValueHi = 23h *** not supported ***
;Stall unsupported requests.
jmp SendStall
GetConfiguration:
;Send the current device configuration.
;0 = unconfigured, 1 = configured.
;Send 1 byte
mov A, 1
mov [data_count], A
;Get the address of the data to send.
mov A, (get_configuration_status_table - control_read_table)
;Add an index to point to the correct configuration.
add A, [configuration_status]
;Send the data.
jmp SendDescriptor
GetInterfaceStatus:
;Interface status is 2 bytes, which are always 0.
;Send 2 bytes.
mov A, 2
mov [data_count], A
;Get the address of the data to send.
mov A, (get_interface_status_table - control_read_table)
;Send the data.
jmp SendDescriptor
GetEndpointStatus:
;Endpoint status is 2 bytes.
;Bit 0 = 0 when the endpoint is not stalled.
;Bit 0 = 1 when the endpoint is stalled.
;All other bits are unused.
;Send 2 bytes.
mov A, 2
mov [data_count], A
;Get the stall status.
mov A, [endpoint_stall]
;Shift left to get an index (0 or 2) to point to data
;in the endpoint status table
asl A
;Get the address of the data to send.
add A, (get_endpoint_status_table - control_read_table)
;Send the data.
jmp SendDescriptor
SetReport:
;The CY7C63000 doesn't support interrupt-mode OUT transfers.
;So the host uses Control transfers with Set_Report requests
;to get data from the device.
;Get the report data.
;For debugging: set Port 0, bit 0 =1 to show that we're here.
; iord Port0_Data
; or a, 1
; iowr Port0_Data
;Find out how many bytes to read. This value is in WLength.
;Save the length in data_count.
mov A, [wLength]
mov [data_count], A
;Enable receiving data at Endpoint 0 by setting the EnableOuts bit
;The bit clears following any Setup or OUT transaction.
iord USB_Status_Control
or A, 10h
;Clear the StatusOuts bit to disable automatic sending of ACK after
;receiving a valid status packet in a Control read (IN) transfer.
;Otherwise, the USB engine will respond to a data OUT packet with a Stall.
and A, F7h
iowr USB_Status_Control
;Now we're ready to receive the report data.
;An Endpoint 0 OUT interrupt indicates the arrival of the report data.
ret
SetIdle:
jmp SendStall ; *** not supported ***
SetProtocol:
;Switches between a boot protocol (wValue=0) and report protocol (wValue=1).
;This firmware doesn't distinguish between protocols.
mov A, [wValue]
mov [protocol_status], A
call Send0ByteDataPacket
ret
GetReport:
;Sends a report to the host.
;The high byte of wValue contains the report type.
;The low byte of wValue contains the report ID.
;Not supported (Use interrupt transfers to send data.)
jmp SendStall
GetReportDescriptor:
;Save the descriptor length
mov A, (end_hid_report_desc_table - hid_report_desc_table)
mov [data_count], A
;Get the descriptor's starting address.
mov A, (hid_report_desc_table - control_read_table)
call SendDescriptor
ret
GetIdle:
;Not supported
jmp SendStall
GetProtocol:
;Send the current protocol status.
;Send 1 byte.
mov A, 1
mov [data_count], A
;Get the address of the data to send.
mov A, (get_protocol_status_table - control_read_table)
;Add an index that points to the correct data.
add A, [protocol_status]
;Send the data.
jmp SendDescriptor
; Standard Get Descriptor routines
;
;Send the device descriptor.
GetDeviceDescriptor:
;Get the length of the descriptor
;(stored in the first byte in the device descriptor table).
mov A, 0
index device_desc_table
mov [data_count], A
;Get the starting address of the descriptor.
mov A, (device_desc_table - control_read_table)
;Send the descriptor.
jmp SendDescriptor
GetConfigurationDescriptor:
;Send the configuration descriptor.
;Get the length of the descriptor.
mov A, (end_config_desc_table - config_desc_table)
mov [data_count], A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -