📄 ups17b.asm
字号:
; device is configured
device_configured:
iord USB_EP1_TX_Config ; NAK IN packets until data is
and A,7Fh ; ready on endpoint one
or A, 10h ; enable endpoint one
iowr USB_EP1_TX_Config
mov A, [interrupt_mask] ; enable endpoint one interrupts
or A, 10h
mov [interrupt_mask], A
iord USB_Status_Control ; NAK IN packets until data is
and A,0EFh ; ready on endpoint one
iowr USB_Status_Control
done_configuration:
ret ; return
; Clear the endpoint stall feature for the selected endpoint. This
; should also set the data 0/1 bit to Data0 if endpoint one is selected.
ClearEndpointStall:
mov A, [wValue] ; load wValue (which feature)
cmp A, endpoint_stalled ; test for valid feature
jnz SendStall ; stall unsupported features
;
; clear endpoint one stall feature
;
call no_data_control ; handshake with host
mov A,0
mov [endpoint_stall], A ; not stalled
iord USB_EP1_TX_Config ; clear data 0/1 bit
and A, ~DataToggle
iowr USB_EP1_TX_Config
iord USB_Status_Control ; NAK IN packets until data is
and A,0EFh ; ready on endpoint one
iowr USB_Status_Control
ret ; return
; Set the endpoint stall feature for the selected endpoint.
SetEndpointStall:
mov A, [wValue] ; load wValue
cmp A, endpoint_stalled ; test for valid feature
jnz SendStall ; stall unsupported features
call no_data_control ; handshake with host
mov A,1
mov [endpoint_stall], A ; stalled
mov A, 30h ; stall endpoint one
iowr USB_EP1_TX_Config
ret ; return
; The device status is a 16-bit value (two bytes) with only D[1:0]
; defined. D0=0 specifies bus-powered, which never changes. D1
; reflects the status of the device_remote_wakeup feature. This
; feature can either be disabled (D1=0) or enabled (D1=1).
GetDeviceStatus:
mov A, 2 ; send two bytes
mov [data_count], A
mov A, (get_dev_status_table - control_read_table)
add A, [remote_wakeup_status] ; get correct remote wakeup
jmp execute ; send device status to host
; There are five descriptor types. The descriptor type will be in
; the high byte of wValue. The descriptor index will be in the low
; byte of wValue. The standard request to a device supports three
; of these types: device, configuration, and string. The standard
; request does not support interface or endpoint descriptor types.
GetDescriptor:
mov A, [wValueHi] ; load descriptor type
;------------------------------------------------------------------------
; Test for standard descriptor types first.
; 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
;------------------------------------------------------------------------
; Then 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 ***
jmp SendStall ; stall unsupported functions
; Return the current device configuration to the host. The possible
; values are zero (unconfigured) and one (configured).
GetConfiguration:
mov A, 1 ; send one byte
mov [data_count], A
mov A, (get_configuration_status_table - control_read_table)
add A, [configuration_status] ; get correct configuration
jmp execute ; send configuration to host
; The interface status is a 16-bit value (two bytes) that is always
; zero for both bytes.
GetInterfaceStatus:
mov A, 2 ; send two bytes
mov [data_count], A
mov A, (get_interface_status_table - control_read_table)
jmp execute ; send interface status to host
; The endpoint status is a 16-bit value (two bytes) with only one
; bit (D0) defined. If D0=0, then the selected endpoint is not
; stalled. If D0=1, then the selected endpoint is stalled.
GetEndpointStatus:
mov A, 2 ; send two bytes
mov [data_count], A
mov A, [endpoint_stall]
asl A ; select the correct entry
add A, (get_endpoint_status_table - control_read_table)
jmp execute ; send endpoint status to host
;------------------------------------------------------------------------
; Set Report
SetReport:
mov A, [wValue]
cmp A, 03h
jz set_ID3
jmp SendStall ; *** unknown report ***
; SetReport ID3 is used to send a test command to the UPS
set_ID3:
call set_reportID3
ret
; Set Idle silences a particular report on the interrupt pipe until a new
; event occurs or the specified amount of time (wValue) passes.
SetIdle:
jmp SendStall ; *** not supported ***
; Set Protocol switches between the boot protocol and the report protocol.
; For boot protocol, wValue=0. For report protocol, wValue=1.
SetProtocol:
mov A, [wValue] ; load wValue
mov [protocol_status], A ; write new protocol value
call no_data_control ; handshake with host
ret ; return
; Get Report allows the host to receive a report via the control pipe.
; The report type is specified in the wValue high byte while the low
; byte has a report ID.
GetReport:
mov A, [wValue]
cmp A, 1h
jz get_ID1
cmp A, 2h
jz get_ID2
cmp A, 3h
jz get_ID3
cmp A, 4h
jz get_ID4
cmp A, 5h
jz get_ID5
jmp SendStall ; unknown report
get_ID1:
mov A, 0Dh
mov [data_count], A
mov A, 01h
mov [data_send], A ; Report ID
mov [data_send + 1], A ; Flow ID
mov [data_send + 0Ah], A ; Manufacturer name index
mov A, 02h
mov [data_send + 0Bh], A ; Product index
mov A, 03h
mov [data_send + 0Ch], A ; Serial Number index
call get_reportID1
call control_send
jmp GetReport_end
get_ID2:
mov A, 10h
mov [data_count], A
mov A, 02h
mov [data_send], A ; Report ID
mov A, 03h
mov [data_send + 1], A ; Flow ID
call get_reportID2
call control_send
jmp GetReport_end
get_ID3:
mov A, 09h
mov [data_count], A
mov A, 03h
mov [data_send], A ; Report ID
mov A, 01h
mov [data_send + 1], A ; Battery System ID
call get_reportID3
call control_send
jmp GetReport_end
get_ID4:
mov A, 08h
mov [data_count], A
mov A, 04h
mov [data_send], A ; Report ID
mov A, 01h
mov [data_send + 1], A ; Power Converter ID
mov A, 11h
mov [data_send + 2], A ; Input and Flow ID
call get_reportID4
call control_send
jmp GetReport_end
get_ID5:
mov A, 09h
mov [data_count], A
mov A, 05h
mov [data_send], A ; Report ID
mov A, 13h
mov [data_send + 1], A ; Output and Flow ID
call get_reportID5
call control_send
GetReport_end:
ret
;**********************************************************
; supports hid reports larger than 256 bytes
;**********************************************************
GetReportDescriptor:
mov A, 7h
index Class_Descriptor
mov [low_data_count], A ; save descriptor length
mov [data_count], A ; save descriptor length
mov A, 8h
index Class_Descriptor
mov [hi_data_count], A ; save descriptor length
cmp A, 0h
jnz sixteen_bits
; 8 bits ( < 256 bytes in length)
; mov A, (end_hid_report_desc_table - hid_report_desc_table)
; mov [data_count], A ; save descriptor length
mov A, (hid_report_desc_table - control_read_table)
call execute ; send descriptor to host
jmp GetReportDescriptor_end
sixteen_bits:
call control_read_16
GetReportDescriptor_end:
ret ; return
; Get Idle reads the current idle rate for a particular input report.
GetIdle:
jmp SendStall ; *** not supported ***
; Get Protocol sends the current protocol status back to the host.
GetProtocol:
mov A, 1 ; send one byte
mov [data_count], A
mov A, (get_protocol_status_table - control_read_table)
add A, [protocol_status] ; get correct configuration
jmp execute ; send protocol to host
;========================================================================
; Standard Get Descriptor routines
;
; Return the device descriptor to the host.
GetDeviceDescriptor:
mov A, 0 ; load the device descriptor length
index device_desc_table
mov [data_count], A ; save the device descriptor length
mov A, (device_desc_table - control_read_table)
jmp execute ; send the device descriptor
; Return the configuration, interface, and endpoint descriptors.
GetConfigurationDescriptor:
mov A, (end_config_desc_table - config_desc_table)
mov [data_count], A ; save the descriptor length
mov A, (config_desc_table - control_read_table)
execute: ; send the descriptors
mov [data_start], A ; save start index
call get_descriptor_length ; correct the descriptor length
call control_read ; perform control read function
ret ; return
GetStringDescriptor:
mov A, [wValue]
cmp A, 0h
jz LanguageString
cmp A, 01h
jz ManufacturerString
cmp A, 02h
jz ProductString
cmp A, 03h
jz SerialNumString
; No other strings supported
jmp SendStall ; *** not supported ***
LanguageString:
mov A, (USBStringDescription1 - USBStringLanguageDescription)
mov [data_count], A ; save the descriptor length
mov A, (USBStringLanguageDescription - control_read_table)
jmp execute ; send the string descriptor
; Commented parts show how these strings could be implemented if ROM
; was used
ManufacturerString:
; mov A, ( USBStringDescription2 - USBStringDescription1)
; mov [data_count], A ; save the descriptor length
; mov A, (USBStringDescription1 - control_read_table)
; jmp execute ; send the string descriptor
call put_iManufacturer_String
call arrange_strings
jmp end_string_desc
ProductString:
; mov A, ( USBStringDescription3 - USBStringDescription2)
; mov [data_count], A ; save the descriptor length
; mov A, (USBStringDescription2 - control_read_table)
; jmp execute ; send the string descriptor
call put_iProduct_String
call arrange_strings
jmp end_string_desc
SerialNumString:
; mov A, ( USBStringEnd - USBStringDescription3)
; mov [data_count], A ; save the descriptor length
; mov A, (USBStringDescription3 - control_read_table)
; jmp execute ; send the string descriptor
call put_iSerialNumber_String
call arrange_strings
end_string_desc:
ret
;------------------------------------------------------------------------
; HID class Get Descriptor routines
;
; Return the HID descriptor and enable endpoint one.
GetHIDDescriptor:
mov A, (Endpoint_Descriptor - Class_Descriptor)
mov [data_count], A ; save descriptor length
mov A, ( Class_Descriptor - control_read_table)
call execute ; send descriptor to host
ret ; return
;**********USB library main routines*******************
;******************************************************
; The host sometimes lies about the number of bytes it
; wants from a descriptor. Any request to get descriptor
; should return the lesser of the number of bytes requested
; or the actual length of the descriptor.
get_descriptor_length:
mov A, [wLengthHi] ; load requested transfer length
cmp A, 0 ; confirm high byte is zero
jnz use_actual_length ; no requests should be longer than 256b
mov A, [wLength] ; test low byte against zero
cmp A, 0
jz use_actual_length ; must request some data
cmp A, [data_count] ; compare to the amount of data
jnc use_actual_length
mov [data_count], A ; use requested length
use_actual_length:
ret ; return
;========================================================================
; function: no_data_control
; purpose: performs the no-data control operation
; as defined by the USB specifications
no_data_control:
mov A, C0h ; set up the transfer
iowr USB_EP0_TX_Config ; register for data1
; and 0 byte transfer
mov A, [interrupt_mask] ; enable interrupts
iowr Global_Interrupt
wait_nodata_sent:
iord USB_EP0_TX_Config ; wait for the data to be
and A, 80h ; transferred
jnz wait_nodata_sent
ret ; return to caller
;========================================================================
;******************************************************
;
; function: Control_read
; Purpose: Performs the control read operation
; as defined by the USB s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -