📄 usbled.asm
字号:
; mov A, (USBStringDescription4 - control_read_table)
; jmp SendDescriptor
;InterfaceString:
; mov A, ( USBStringEnd - USBStringDescription5)
; mov [data_count], A
; mov A, (USBStringDescription5 - control_read_table)
; jmp SendDescriptor
; HID class Get Descriptor routines
;
GetHIDDescriptor:
;Send the HID descriptor and enable endpoint 1.
;Get the length of the descriptor.
mov A, (Endpoint_Descriptor - Class_Descriptor)
mov [data_count], A
;Get the descriptor's starting address.
mov A, ( Class_Descriptor - control_read_table)
;Send the descriptor.
call SendDescriptor
ret
;======================================================================
;USB support routines
;======================================================================
get_descriptor_length:
;The host sometimes lies about the number of bytes it
; wants from a descriptor.
;A request to get a descriptor should return the smaller of the number
;of bytes requested or the actual length of the descriptor.
;Get the requested number of bytes to send
mov A, [wLengthHi]
;If the requested high byte is >0,
;ignore the high byte and use the firmware's value.
;(255 bytes is the maximum allowed.)
cmp A, 0
jnz use_actual_length
;If the low byte =0, use the firmware's value.
mov A, [wLength]
cmp A, 0
jz use_actual_length
;If the requested number of bytes => the firmware's value,
;use the firmware's value.
cmp A, [data_count]
jnc use_actual_length
;If the requested number of bytes < the firmware's value,
;use the requested number of bytes.
mov [data_count], A
use_actual_length:
ret
Send0ByteDataPacket:
;Send a data packet with 0 bytes.
;Use this handshake after receiving an OUT data packet.
;Enable responding to IN packets.
;Set Data 0/1 to Data 1.
mov A, C0h
iowr USB_EP0_TX_Config
;Enable interrupts.
mov A, [interrupt_mask]
iowr Global_Interrupt
WaitForDataToTransfer:
;Wait for the data to transfer.
;Bit 7 of USB_EP0_TX_Config is cleared when the host acknowledges
;receiving the data.
iord USB_EP0_TX_Config
and A, 80h
jnz WaitForDataToTransfer
ret
control_read:
;Do a Control Read transfer
;The device receives a Setup packet,
;sends 0 or more data packets (IN),
;and receives a status packet (OUT).
;Before calling this routine, the firmware must set 2 values:
;data_start is the starting address of the descriptor to send,
;expressed as an offset from the control read table.
;data_count is number of bytes in the descriptor.
push X
;Clear the Data 0/1 bit.
mov A, 00h
mov [endp0_data_toggle], A
control_read_data_stage:
mov X, 00h
mov A, 00h
mov [loop_counter], A
;Clear the setup bit.
iowr USB_EP0_RX_Status
;Check setup bit.
iord USB_EP0_RX_Status
and A, 01h
;If not cleared, another setup packet has arrived,
;so exit the routine.
jnz control_read_status_stage
;Set StatusOuts bit to enable auto-ACK of IN data packets
mov A, 08h
iowr USB_Status_Control
;If there is no data packet, do the handshake.
mov A, [data_count]
cmp A, 00h
jz control_read_status_stage
;Copy the data to send into endpoint 0's FIFO.
;The X register indexes the address in the FIFO.
dma_load_loop:
;Get the data's starting address.
mov A, [data_start]
index control_read_table
;Place the byte in the USB FIFO.
mov [X + Endpoint_0], A
;Increment the data address, the FIFO address, and the counter.
inc [data_start]
inc X
inc [loop_counter]
;Decrement the count.
dec [data_count]
;If the count = 0, there's no more data to send.
jz dma_load_done
;If 8 bytes have been sent, it's the maximum.
mov A, [loop_counter]
cmp A, 08h
jnz dma_load_loop
dma_load_done:
;Send the data.
;Check the Setup bit.
;If it's not 0, another Setup packet has arrived,
;so exit the routine.
iord USB_EP0_RX_Status
and A, 01h
jnz control_read_status_stage
;Set the value of the bits in the USB_EP0_TX_Config register.
;Toggle the Data 0/1 bit.
mov A, [endp0_data_toggle]
xor A, 40h
mov [endp0_data_toggle], A
;Enable responding to IN packets.
or A, 80h
;The low 4 bits hold the number of bytes to send.
or A, [loop_counter]
iowr USB_EP0_TX_Config
;Enable interrupts
mov A, [interrupt_mask]
iowr Global_Interrupt
wait_control_read:
;Wait for the data to transfer,
;indicated by Bit 7 = 0.
iord USB_EP0_TX_Config
and A, 80h
;Find out if there is more data to send.
jz control_read_data_stage
iord USB_EP0_RX_Status
;Wait for the host to send an OUT packet to acknowledge.
and A, 02h
jz wait_control_read
control_read_status_stage:
;The host has acknowledged the transfer, so the transaction is complete.
pop X
mov A, [interrupt_mask]
iowr Global_Interrupt
ret
;======================================================================
;Lookup Tables
;Contain the descriptors and the codes for status indicators.
;The firmware accesses the information by referencing a specific
;table's address as an offset from the control_read_table.
;======================================================================
control_read_table:
device_desc_table:
db 12h ; Descriptor length (18 bytes)
db 01h ; Descriptor type (Device)
db 10h,01h ; Complies with USB Spec. Release (0110h = release 1.10)
db 00h ; Class code (0)
db 00h ; Subclass code (0)
db 00h ; Protocol (No specific protocol)
db 08h ; Max. packet size for EP0 (8 bytes)
db 34h,12h ; Vendor ID (usb book, 1234h)
db 78h,56h ; Product ID (5678)
db 01h,00h ; Device release number (0001)
db 01h ; Mfr string descriptor index
db 02h ; Product string descriptor index
db 00h ; Serial Number string descriptor index (None)
db 01h ; Number of possible configurations (1)
end_device_desc_table:
config_desc_table:
db 09h ; Descriptor length (9 bytes)
db 02h ; Descriptor type (Configuration)
db 22h,00h ; Total data length (34 bytes)
db 01h ; Interface supported (1)
db 01h ; Configuration value (1)
db 00h ; Index of string descriptor (None)
db 80h ; Configuration (Bus powered)
db 32h ; Maximum power consumption (100mA)
Interface_Descriptor:
db 09h ; Descriptor length (9 bytes)
db 04h ; Descriptor type (Interface)
db 00h ; Number of interface (0)
db 00h ; Alternate setting (0)
db 01h ; Number of interface endpoint (1)
db 03h ; Class code ()
db 00h ; Subclass code ()
db 00h ; Protocol code ()
db 00h ; Index of string()
Class_Descriptor:
db 09h ; Descriptor length (9 bytes)
db 21h ; Descriptor type (HID)
db 00h,01h ; HID class release number (1.00)
db 00h ; Localized country code (None)
db 01h ; # of HID class dscrptr to follow (1)
db 22h ; Report descriptor type (HID)
; Total length of report descriptor
db (end_hid_report_desc_table - hid_report_desc_table),00h
Endpoint_Descriptor:
db 07h ; Descriptor length (7 bytes)
db 05h ; Descriptor type (Endpoint)
db 81h ; Encoded address (Respond to IN, 1 endpoint)
db 03h ; Endpoint attribute (Interrupt transfer)
db 06h,00h ; Maximum packet size (6 bytes)
db 0Ah ; Polling interval (10 ms)
end_config_desc_table:
;----------------------------------------------------------------------
;The HID-report descriptor table
;----------------------------------------------------------------------
hid_report_desc_table:
db 06h, A0h, FFh ; Usage Page (vendor defined) FFA0
db 09h, A5h ; Usage (vendor defined)
db A1h, 01h ; Collection (Application)
db 09h, A6h ; Usage (vendor defined)
db A1h, 00h ; Collection (Physical)
db 06h, A0h, FFh ; Usage Page (vendor defined)
;The input report
db 09h, A7h ; usage - vendor defined
db 09h, A8h ; usage - vendor defined
db 15h, 80h ; Logical Minimum (-127)
db 25h, 7Fh ; Logical Maximum (128)
db 35h, 00h ; Physical Minimum (0)
db 45h, FFh ; Physical Maximum (255)
; db 66h, 00h, 00h; Unit (None (2 bytes))
db 75h, 08h ; Report Size (8) (bits)
db 95h, 01h ; Report Count (2) (fields)
db 81h, 02h ; Input (Data, Variable, Absolute)
;The output report
db 09h, A9h ; usage - vendor defined
db 09h, AAh ; usage - vendor defined
db 15h, 80h ; Logical Minimum (-127)
db 25h, 7Fh ; Logical Maximum (128)
db 35h, 00h ; Physical Minimum (0)
db 45h, FFh ; Physical Maximum (255)
; db 66h, 00h, 00h; Unit (None (2 bytes))
db 75h, 08h ; Report Size (8) (bits)
db 95h, 01h ; Report Count (2) (fields)
db 91h, 02h ; Output (Data, Variable, Absolute)
db C0h ; End Collection
db C0h ; End Collection
end_hid_report_desc_table:
;----------------------------------------------------------------------
;String Descriptors
;----------------------------------------------------------------------
;Define the strings
; string 0
USBStringLanguageDescription:
db 04h ; Length
db 03h ; Type (3=string)
db 09h ; Language: English
db 04h ; Sub-language: US
; string 1
USBStringDescription1: ; IManufacturerName
db 0Ch ; Length
db 03h ; Type (3=string)
dsu "USB Complete" ;
; string 2
USBStringDescription2: ; IProduct
db 0Ah ; Length
db 03h ; Type (3=string)
dsu "HID Sample" ;
;string 3
;If the firmware contains a serial number, it must be unique
;for each device or the devices may not enumerate properly.
USBStringDescription3: ; serial number
; string 4
;USBStringDescription4: ; configuration string descriptor
; db 14h ; Length
; db 03h ; Type (3=string)
; dsu "Sample HID" ;
;string 5
;USBStringDescription5: ; configuration string descriptor
; db 32h ; Length
; db 03h ; Type (3=string)
; dsu "EndPoint1 Interrupt Pipe" ;
USBStringEnd:
;----------------------------------------------------------------------
;Status information.
;The status can be either device, interface, or endpoint.
;An index selects the correct value.
;----------------------------------------------------------------------
get_dev_status_table:
db 00h, 00h ; remote wakeup disabled, bus powered
db 02h, 00h ; remote wakeup enabled, bus powered
get_interface_status_table:
db 00h, 00h ; always return both bytes zero
get_endpoint_status_table:
db 00h, 00h ; not stalled
db 01h, 00h ; stalled
get_configuration_status_table:
db 00h ; not configured
db 01h ; configured
get_protocol_status_table:
db 00h ; boot protocol
db 01h ; report protocol
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -