📄 usbled.asm
字号:
ret
SetAddress:
; Set the device address to the wValue in the SETUP packet.
;Unlike other requests, 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 condition for an endpoint.
;For endpoint 1, also set Data 0/1 to Data 0.
mov A, [wValue]
cmp A, endpoint_stalled
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:
mov A, [wValue]
cmp A, endpoint_stalled
;Not a match, so stall
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 two bytes.
;Bit 0 must be 0 (bus-powered).
;Bit 1 is remote wakeup: 0=disabled, 1=enabled.
;All other bits are unused.
;Send two bytes.
mov A, 2
mov [data_count], A
;The 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 bytes.
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) for 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.
;debug: 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 is cleared following any Setup or Out transaction.
iord USB_Status_Control
or A, 10h
;Clear the StatusOuts bit to disable auto-Ack after receiving a valid
;status packet in response to 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 signals 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
;Get the starting address of the descriptor.
mov A, (config_desc_table - control_read_table)
;Send the descriptor.
jmp SendDescriptor
GetStringDescriptor:
;Use the string index to find out which string it is.
mov A, [wValue]
cmp A, 0h
jz LanguageString
cmp A, 01h
jz ManufacturerString
cmp A, 02h
jz ProductString
; cmp A, 03h
; jz SerialNumString
; cmp A, 04h
; jz ConfigurationString
; cmp A, 05h
; jz InterfaceString
; No other strings supported
jmp SendStall
SendDescriptor:
;The starting address of the descriptor is in the accumulator. Save it.
mov [data_start], A
;Get the descriptor length.
call get_descriptor_length
;Send the descriptor.
call control_read
ret
;Send the requested string.
;For each, store the descriptor length in data_count, then send the descriptor.
LanguageString:
mov A, (USBStringDescription1 - USBStringLanguageDescription)
mov [data_count], A
mov A, (USBStringLanguageDescription - control_read_table)
jmp SendDescriptor
ManufacturerString:
mov A, ( USBStringDescription2 - USBStringDescription1)
mov [data_count], A
mov A, (USBStringDescription1 - control_read_table)
jmp SendDescriptor
ProductString:
mov A, ( USBStringDescription3 - USBStringDescription2)
mov [data_count], A
mov A, (USBStringDescription2 - control_read_table)
jmp SendDescriptor
;SerialNumString:
; mov A, ( USBStringDescription4 - USBStringDescription3)
; mov [data_count], A
; mov A, (USBStringDescription3 - control_read_table)
; jmp SendDescriptor
;ConfigurationString:
; mov A, ( USBStringDescription5 - USBStringDescription4)
; mov [data_count], A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -