machine/usb: refactoring descriptors into subpackage for modularity

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram
2023-04-02 12:12:32 +02:00
committed by Ron Evans
parent 6a2dd35fe6
commit 2ab7ee6a8a
15 changed files with 1190 additions and 266 deletions
+168
View File
@@ -0,0 +1,168 @@
package descriptor
const (
cdcFunctionalHeader = 0
cdcFunctionalCallManagement = 0x1
cdcFunctionalACM = 0x2
cdcFunctionalDirect = 0x3
cdcFunctionalRinger = 0x4
cdcFunctionalCall = 0x5
cdcFunctionalUnion = 0x6
cdcFunctionalCountry = 0x7
cdcFunctionalOperational = 0x8
cdcFunctionalUSB = 0x9
cdcFunctionalNetwork = 0xa
cdcFunctionalProtocol = 0xb
cdcFunctionalExtension = 0xc
cdcFunctionalMulti = 0xd
cdcFunctionalCAPI = 0xe
cdcFunctionalEthernet = 0xf
cdcFunctionalATM = 0x10
)
var classSpecificCDCHeader = [classSpecificTypeLen]byte{
classSpecificTypeLen,
TypeClassSpecific,
cdcFunctionalHeader,
0x10, //
0x1, //
}
var ClassSpecificCDCHeader = ClassSpecificType{
data: classSpecificCDCHeader[:],
}
var classSpecificCDCCallManagement = [classSpecificTypeLen]byte{
classSpecificTypeLen,
TypeClassSpecific,
cdcFunctionalCallManagement,
0x0, //
0x1, //
}
var ClassSpecificCDCCallManagement = ClassSpecificType{
data: classSpecificCDCCallManagement[:],
}
var classSpecificCDCACM = [classSpecificTypeLen]byte{
4,
TypeClassSpecific,
cdcFunctionalACM,
0x2, //
}
var ClassSpecificCDCACM = ClassSpecificType{
data: classSpecificCDCACM[:],
}
var classSpecificCDCUnion = [classSpecificTypeLen]byte{
classSpecificTypeLen,
TypeClassSpecific,
cdcFunctionalUnion,
0x0, //
0x1, //
}
var ClassSpecificCDCUnion = ClassSpecificType{
data: classSpecificCDCUnion[:],
}
var interfaceAssociationCDC = [interfaceAssociationTypeLen]byte{
interfaceAssociationTypeLen,
TypeInterfaceAssociation,
0x00, // FirstInterface
0x02, // InterfaceCount
0x02, // FunctionClass
0x02, // FunctionSubClass
0x01, // FunctionProtocol
0x00, // Function
}
var InterfaceAssociationCDC = InterfaceAssociationType{
data: interfaceAssociationCDC[:],
}
var deviceCDC = [deviceTypeLen]byte{
deviceTypeLen,
TypeDevice,
0x00, 0x02, // USB version
0xef, // device class
0x02, // device subclass
0x01, // protocol
0x40, // maxpacketsize
0x86, 0x28, // vendor id
0x2d, 0x80, // product id
0x00, 0x01, // device
0x01, // manufacturer
0x02, // product
0x03, // SerialNumber
0x01, // NumConfigurations
}
var DeviceCDC = DeviceType{
data: deviceCDC[:],
}
var configurationCDC = [configurationTypeLen]byte{
configurationTypeLen,
TypeConfiguration,
0x4b, 0x00, // adjust length as needed
0x02, // number of interfaces
0x01, // configuration value
0x00, // index to string description
0xa0, // attributes
0x32, // maxpower
}
var ConfigurationCDC = ConfigurationType{
data: configurationCDC[:],
}
var interfaceCDCControl = [interfaceTypeLen]byte{
interfaceTypeLen,
TypeInterface,
0x00, // InterfaceNumber
0x00, // AlternateSetting
0x01, // NumEndpoints
0x02, // InterfaceClass
0x02, // InterfaceSubClass
0x01, // InterfaceProtocol
0x00, // Interface
}
var InterfaceCDCControl = InterfaceType{
data: interfaceCDCControl[:],
}
var interfaceCDCData = [interfaceTypeLen]byte{
interfaceTypeLen,
TypeInterface,
0x01, // InterfaceNumber
0x00, // AlternateSetting
0x02, // NumEndpoints
0x0a, // InterfaceClass
0x00, // InterfaceSubClass
0x00, // InterfaceProtocol
0x00, // Interface
}
var InterfaceCDCData = InterfaceType{
data: interfaceCDCData[:],
}
var CDC = Descriptor{
Device: DeviceCDC.Bytes(),
Configuration: appendSlices([][]byte{
ConfigurationCDC.Bytes(),
InterfaceAssociationCDC.Bytes(),
InterfaceCDCControl.Bytes(),
ClassSpecificCDCHeader.Bytes(),
ClassSpecificCDCCallManagement.Bytes(),
ClassSpecificCDCACM.Bytes(),
ClassSpecificCDCUnion.Bytes(),
EndpointEP1IN.Bytes(),
InterfaceCDCData.Bytes(),
EndpointEP2OUT.Bytes(),
EndpointEP3IN.Bytes(),
}),
}
@@ -0,0 +1,17 @@
package descriptor
const (
classSpecificTypeLen = 5
)
type ClassSpecificType struct {
data []byte
}
func (d ClassSpecificType) Bytes() []byte {
return d.data[:d.data[0]]
}
func (d ClassSpecificType) Length(v uint8) {
d.data[0] = byte(v)
}
@@ -0,0 +1,49 @@
package descriptor
import (
"encoding/binary"
)
const (
configurationTypeLen = 9
)
type ConfigurationType struct {
data []byte
}
func (d ConfigurationType) Bytes() []byte {
return d.data
}
func (d ConfigurationType) Length(v uint8) {
d.data[0] = byte(v)
}
func (d ConfigurationType) Type(v uint8) {
d.data[1] = byte(v)
}
func (d ConfigurationType) TotalLength(v uint16) {
binary.LittleEndian.PutUint16(d.data[2:4], v)
}
func (d ConfigurationType) NumInterfaces(v uint8) {
d.data[4] = byte(v)
}
func (d ConfigurationType) ConfigurationValue(v uint8) {
d.data[5] = byte(v)
}
func (d ConfigurationType) Configuration(v uint8) {
d.data[6] = byte(v)
}
func (d ConfigurationType) Attributes(v uint8) {
d.data[7] = byte(v)
}
func (d ConfigurationType) MaxPower(v uint8) {
d.data[8] = byte(v)
}
+63
View File
@@ -0,0 +1,63 @@
package descriptor
import (
"runtime/volatile"
)
const (
TypeDevice = 0x1
TypeConfiguration = 0x2
TypeString = 0x3
TypeInterface = 0x4
TypeEndpoint = 0x5
TypeDeviceQualifier = 0x6
TypeInterfaceAssociation = 0xb
TypeClassHID = 0x21
TypeHIDReport = 0x22
TypeClassSpecific = 0x24
TypeClassSpecificEndpoint = 0x25
)
// DeviceDescBank is the USB device endpoint .
type DeviceDescBank struct {
ADDR volatile.Register32
PCKSIZE volatile.Register32
EXTREG volatile.Register16
STATUS_BK volatile.Register8
_reserved [5]volatile.Register8
}
type Device struct {
DeviceDescBank [2]DeviceDescBank
}
type Descriptor struct {
Device []byte
Configuration []byte
HID map[uint16][]byte
}
func (d *Descriptor) Configure(idVendor, idProduct uint16) {
dev := DeviceType{d.Device}
dev.VendorID(idVendor)
dev.ProductID(idProduct)
conf := ConfigurationType{d.Configuration}
conf.TotalLength(uint16(len(d.Configuration)))
}
func appendSlices[T any](slices [][]T) []T {
var size, pos int
for _, s := range slices {
size += len(s)
}
result := make([]T, size)
for _, s := range slices {
pos += copy(result[pos:], s)
}
return result
}
+73
View File
@@ -0,0 +1,73 @@
package descriptor
import (
"encoding/binary"
)
const (
deviceTypeLen = 18
)
type DeviceType struct {
data []byte
}
func (d DeviceType) Bytes() []byte {
return d.data
}
func (d DeviceType) Length(v uint8) {
d.data[0] = byte(v)
}
func (d DeviceType) Type(v uint8) {
d.data[1] = byte(v)
}
func (d DeviceType) USB(v uint16) {
binary.LittleEndian.PutUint16(d.data[2:4], v)
}
func (d DeviceType) DeviceClass(v uint8) {
d.data[4] = byte(v)
}
func (d DeviceType) DeviceSubClass(v uint8) {
d.data[5] = byte(v)
}
func (d DeviceType) DeviceProtocol(v uint8) {
d.data[6] = byte(v)
}
func (d DeviceType) MaxPacketSize0(v uint8) {
d.data[7] = byte(v)
}
func (d DeviceType) VendorID(v uint16) {
binary.LittleEndian.PutUint16(d.data[8:10], v)
}
func (d DeviceType) ProductID(v uint16) {
binary.LittleEndian.PutUint16(d.data[10:12], v)
}
func (d DeviceType) Device(v uint16) {
binary.LittleEndian.PutUint16(d.data[12:14], v)
}
func (d DeviceType) Manufacturer(v uint8) {
d.data[14] = byte(v)
}
func (d DeviceType) Product(v uint8) {
d.data[15] = byte(v)
}
func (d DeviceType) SerialNumber(v uint8) {
d.data[16] = byte(v)
}
func (d DeviceType) NumConfigurations(v uint8) {
d.data[17] = byte(v)
}
+111
View File
@@ -0,0 +1,111 @@
package descriptor
import (
"encoding/binary"
)
var endpointEP1IN = [endpointTypeLen]byte{
endpointTypeLen,
TypeEndpoint,
0x81, // EndpointAddress
0x03, // Attributes
0x10, // MaxPacketSizeL
0x00, // MaxPacketSizeH
0x10, // Interval
}
var EndpointEP1IN = EndpointType{
data: endpointEP1IN[:],
}
var endpointEP2OUT = [endpointTypeLen]byte{
endpointTypeLen,
TypeEndpoint,
0x02, // EndpointAddress
0x02, // Attributes
0x40, // MaxPacketSizeL
0x00, // MaxPacketSizeH
0x00, // Interval
}
var EndpointEP2OUT = EndpointType{
data: endpointEP2OUT[:],
}
var endpointEP3IN = [endpointTypeLen]byte{
endpointTypeLen,
TypeEndpoint,
0x83, // EndpointAddress
0x02, // Attributes
0x40, // MaxPacketSizeL
0x00, // MaxPacketSizeH
0x00, // Interval
}
var EndpointEP3IN = EndpointType{
data: endpointEP3IN[:],
}
var endpointEP4IN = [endpointTypeLen]byte{
endpointTypeLen,
TypeEndpoint,
0x84, // EndpointAddress
0x03, // Attributes
0x40, // MaxPacketSizeL
0x00, // MaxPacketSizeH
0x01, // Interval
}
var EndpointEP4IN = EndpointType{
data: endpointEP4IN[:],
}
var endpointEP5OUT = [endpointTypeLen]byte{
endpointTypeLen,
TypeEndpoint,
0x05, // EndpointAddress
0x03, // Attributes
0x40, // MaxPacketSizeL
0x00, // MaxPacketSizeH
0x01, // Interval
}
var EndpointEP5OUT = EndpointType{
data: endpointEP5OUT[:],
}
const (
endpointTypeLen = 7
)
type EndpointType struct {
data []byte
}
func (d EndpointType) Bytes() []byte {
return d.data
}
func (d EndpointType) Length(v uint8) {
d.data[0] = byte(v)
}
func (d EndpointType) Type(v uint8) {
d.data[1] = byte(v)
}
func (d EndpointType) EndpointAddress(v uint8) {
d.data[2] = byte(v)
}
func (d EndpointType) Attributes(v uint8) {
d.data[3] = byte(v)
}
func (d EndpointType) MaxPacketSize(v uint16) {
binary.LittleEndian.PutUint16(d.data[4:6], v)
}
func (d EndpointType) Interval(v uint8) {
d.data[6] = byte(v)
}
+189
View File
@@ -0,0 +1,189 @@
package descriptor
import (
"bytes"
"encoding/binary"
)
var configurationCDCHID = [configurationTypeLen]byte{
configurationTypeLen,
TypeConfiguration,
0x64, 0x00, // adjust length as needed
0x03, // number of interfaces
0x01, // configuration value
0x00, // index to string description
0xa0, // attributes
0x32, // maxpower
}
var ConfigurationCDCHID = ConfigurationType{
data: configurationCDCHID[:],
}
var interfaceHID = [interfaceTypeLen]byte{
interfaceTypeLen,
TypeInterface,
0x02, // InterfaceNumber
0x00, // AlternateSetting
0x01, // NumEndpoints
0x03, // InterfaceClass
0x00, // InterfaceSubClass
0x00, // InterfaceProtocol
0x00, // Interface
}
var InterfaceHID = InterfaceType{
data: interfaceHID[:],
}
const (
ClassHIDTypeLen = 9
)
type ClassHIDType struct {
data []byte
}
func (d ClassHIDType) Bytes() []byte {
return d.data[:]
}
func (d ClassHIDType) Length(v uint8) {
d.data[0] = byte(v)
}
func (d ClassHIDType) Type(v uint8) {
d.data[1] = byte(v)
}
func (d ClassHIDType) HID(v uint16) {
binary.LittleEndian.PutUint16(d.data[2:4], v)
}
func (d ClassHIDType) CountryCode(v uint8) {
d.data[4] = byte(v)
}
func (d ClassHIDType) NumDescriptors(v uint8) {
d.data[5] = byte(v)
}
func (d ClassHIDType) ClassType(v uint8) {
d.data[6] = byte(v)
}
func (d ClassHIDType) ClassLength(v uint16) {
binary.LittleEndian.PutUint16(d.data[7:9], v)
}
func FindClassHIDType(data, section []byte) ClassHIDType {
idx := bytes.Index(data, section)
return ClassHIDType{data: data[idx : idx+ClassHIDTypeLen]}
}
var classHID = [ClassHIDTypeLen]byte{
ClassHIDTypeLen,
TypeClassHID,
0x11, // HID version L
0x01, // HID version H
0x00, // CountryCode
0x01, // NumDescriptors
0x22, // ClassType
0x7E, // ClassLength L
0x00, // ClassLength H
}
var ClassHID = ClassHIDType{
data: classHID[:],
}
var CDCHID = Descriptor{
Device: DeviceCDC.Bytes(),
Configuration: appendSlices([][]byte{
ConfigurationCDCHID.Bytes(),
InterfaceAssociationCDC.Bytes(),
InterfaceCDCControl.Bytes(),
ClassSpecificCDCHeader.Bytes(),
ClassSpecificCDCACM.Bytes(),
ClassSpecificCDCUnion.Bytes(),
ClassSpecificCDCCallManagement.Bytes(),
EndpointEP1IN.Bytes(),
InterfaceCDCData.Bytes(),
EndpointEP2OUT.Bytes(),
EndpointEP3IN.Bytes(),
InterfaceHID.Bytes(),
ClassHID.Bytes(),
EndpointEP4IN.Bytes(),
}),
HID: map[uint16][]byte{
2: []byte{
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
0x85, 0x02, // Report ID (2)
0x05, 0x07, // Usage Page (KeyCodes)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data, Variable, Absolute), Modifier byte
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, //
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0),
0x25, 0xFF, //
0x05, 0x07, // Usage Page (KeyCodes)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xFF, // Usage Maximum (255)
0x81, 0x00, // Input (Data, Array), Key arrays (6 bytes)
0xc0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xa1, 0x01, // Collection (Application)
0x09, 0x01, // Usage (Pointer)
0xa1, 0x00, // Collection (Physical)
0x85, 0x01, // Report ID (1)
0x05, 0x09, // Usage Page (Buttons)
0x19, 0x01, // Usage Minimum (01)
0x29, 0x03, // Usage Maximun (03)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x03, // Report Count (3)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute), ;3 button bits
0x95, 0x01, // Report Count (1)
0x75, 0x05, // Report Size (5)
0x81, 0x03, //
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x38, //
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7f, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x03, // Report Count (3)
0x81, 0x06, // Input (Data, Variable, Relative), 2 position bytes (X & Y)
0xc0, // End Collection
0xc0, // End Collection
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x03, // Report ID (3)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x1F, // Logical Maximum (8191)
0x19, 0x00, // Usage Minimum (Unassigned)
0x2A, 0xFF, 0x1F, // Usage Maximum (0x1FFF)
0x75, 0x10, // Report Size (16)
0x95, 0x01, // Report Count (1)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
},
},
}
+49
View File
@@ -0,0 +1,49 @@
package descriptor
const (
interfaceTypeLen = 9
)
type InterfaceType struct {
data []byte
}
func (d InterfaceType) Bytes() []byte {
return d.data
}
func (d InterfaceType) Length(v uint8) {
d.data[0] = byte(v)
}
func (d InterfaceType) Type(v uint8) {
d.data[1] = byte(v)
}
func (d InterfaceType) InterfaceNumber(v uint8) {
d.data[2] = byte(v)
}
func (d InterfaceType) AlternateSetting(v uint8) {
d.data[3] = byte(v)
}
func (d InterfaceType) NumEndpoints(v uint8) {
d.data[4] = byte(v)
}
func (d InterfaceType) InterfaceClass(v uint8) {
d.data[5] = byte(v)
}
func (d InterfaceType) InterfaceSubClass(v uint8) {
d.data[6] = byte(v)
}
func (d InterfaceType) InterfaceProtocol(v uint8) {
d.data[7] = byte(v)
}
func (d InterfaceType) Interface(v uint8) {
d.data[8] = byte(v)
}
@@ -0,0 +1,45 @@
package descriptor
const (
interfaceAssociationTypeLen = 8
)
type InterfaceAssociationType struct {
data []byte
}
func (d InterfaceAssociationType) Bytes() []byte {
return d.data
}
func (d InterfaceAssociationType) Length(v uint8) {
d.data[0] = byte(v)
}
func (d InterfaceAssociationType) Type(v uint8) {
d.data[1] = byte(v)
}
func (d InterfaceAssociationType) FirstInterface(v uint8) {
d.data[2] = byte(v)
}
func (d InterfaceAssociationType) InterfaceCount(v uint8) {
d.data[3] = byte(v)
}
func (d InterfaceAssociationType) FunctionClass(v uint8) {
d.data[4] = byte(v)
}
func (d InterfaceAssociationType) FunctionSubClass(v uint8) {
d.data[5] = byte(v)
}
func (d InterfaceAssociationType) FunctionProtocol(v uint8) {
d.data[6] = byte(v)
}
func (d InterfaceAssociationType) Function(v uint8) {
d.data[7] = byte(v)
}
+145
View File
@@ -0,0 +1,145 @@
package descriptor
var deviceJoystick = [deviceTypeLen]byte{
deviceTypeLen,
TypeDevice,
0x00, 0x02, // USB version
0xef, // device class
0x02, // subclass
0x01, // protocol
0x40, // maxpacketsize
0x41, 0x23, // vendor id
0x36, 0x80, // product id
0x00, 0x01, // device
0x01, // manufacturer
0x02, // product
0x03, // SerialNumber
0x01, // NumConfigurations
}
var DeviceJoystick = DeviceType{
data: deviceJoystick[:],
}
var configurationCDCJoystick = [configurationTypeLen]byte{
configurationTypeLen,
TypeConfiguration,
0x6b, 0x00, // adjust length as needed
0x03, // number of interfaces
0x01, // configuration value
0x00, // index to string description
0xa0, // attributes
0xfa, // maxpower
}
var ConfigurationCDCJoystick = ConfigurationType{
data: configurationCDCJoystick[:],
}
var interfaceHIDJoystick = [interfaceTypeLen]byte{
interfaceTypeLen,
TypeInterface,
0x02, // InterfaceNumber
0x00, // AlternateSetting
0x02, // NumEndpoints
0x03, // InterfaceClass
0x00, // InterfaceSubClass
0x00, // InterfaceProtocol
0x00, // Interface
}
var InterfaceHIDJoystick = InterfaceType{
data: interfaceHIDJoystick[:],
}
var classHIDJoystick = [ClassHIDTypeLen]byte{
ClassHIDTypeLen,
TypeClassHID,
0x11, // HID version L
0x01, // HID version H
0x00, // CountryCode
0x01, // NumDescriptors
0x22, // ClassType
0x00, // ClassLength L
0x00, // ClassLength H
}
var ClassHIDJoystick = ClassHIDType{
data: classHIDJoystick[:],
}
var JoystickDefaultHIDReport = []byte{
0x05, 0x01, // Usage page
0x09, 0x04, // Joystick
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x01, // REPORT_ID (1)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x10, // REPORT_COUNT (16)
0x55, 0x00, // Unit Exponent (-16)
0x65, 0x00, // Unit (0x00)
0x81, 0x02, // INPUT (Data/Var/Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop Controls)
0x09, 0x39, // USAGE(Hat Switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x07, // LOGICAL_MAXIMUM (7)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x3b, 0x01, // PHYSICAL_MAXIMUM(315)
0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
0x75, 0x04, // REPORT_SIZE (4)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data/Var/Abs)
0x09, 0x39, // USAGE(Hat Switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x07, // LOGICAL_MAXIMUM (7)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x3b, 0x01, // PHYSICAL_MAXIMUM(315)
0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
0x75, 0x04, // REPORT_SIZE (4)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data/Var/Abs)
0x09, 0x01, // USAGE (Pointer)
0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767)
0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
0x75, 0x10, // REPORT_SIZE (16bits)
0x95, 0x06, // REPORT_COUNT (6)
0xa1, 0x00, // COLLECTION (Physical)
0x09, 0x30, // USAGE(X)
0x09, 0x31, // USAGE(Y)
0x09, 0x32, // USAGE(Z)
0x09, 0x33, // USAGE(RX)
0x09, 0x34, // USAGE(RY)
0x09, 0x35, // USAGE(RZ)
0x81, 0x02, // INPUT (Data/Var/Abs)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
}
// CDCJoystick requires that you append the JoystickDescriptor
// to the Configuration before using. This is in order to support
// custom configurations.
var CDCJoystick = Descriptor{
Device: DeviceJoystick.Bytes(),
Configuration: appendSlices([][]byte{
ConfigurationCDCJoystick.Bytes(),
InterfaceAssociationCDC.Bytes(),
InterfaceCDCControl.Bytes(),
ClassSpecificCDCHeader.Bytes(),
ClassSpecificCDCACM.Bytes(),
ClassSpecificCDCUnion.Bytes(),
ClassSpecificCDCCallManagement.Bytes(),
EndpointEP1IN.Bytes(),
InterfaceCDCData.Bytes(),
EndpointEP2OUT.Bytes(),
EndpointEP3IN.Bytes(),
InterfaceHIDJoystick.Bytes(),
ClassHIDJoystick.Bytes(),
EndpointEP4IN.Bytes(),
EndpointEP5OUT.Bytes(),
}),
HID: map[uint16][]byte{},
}
+249
View File
@@ -0,0 +1,249 @@
package descriptor
var interfaceAssociationMIDI = [interfaceAssociationTypeLen]byte{
interfaceAssociationTypeLen,
TypeInterfaceAssociation,
0x02, // EndpointAddress
0x02, // Attributes
0x01, // MaxPacketSizeL
0x01, // MaxPacketSizeH
0x00, // Interval
0x00, // Interval
}
var InterfaceAssociationMIDI = InterfaceAssociationType{
data: interfaceAssociationMIDI[:],
}
var interfaceAudio = [interfaceTypeLen]byte{
interfaceTypeLen,
TypeInterface,
0x02, // InterfaceNumber
0x00, // AlternateSetting
0x00, // NumEndpoints
0x01, // InterfaceClass
0x01, // InterfaceSubClass
0x00, // InterfaceProtocol
0x00, // Interface
}
var InterfaceAudio = InterfaceType{
data: interfaceAudio[:],
}
var interfaceMIDIStreaming = [interfaceTypeLen]byte{
interfaceTypeLen,
TypeInterface,
0x03, // InterfaceNumber
0x00, // AlternateSetting
0x02, // NumEndpoints
0x01, // InterfaceClass
0x03, // InterfaceSubClass
0x00, // InterfaceProtocol
0x00, // Interface
}
var InterfaceMIDIStreaming = InterfaceType{
data: interfaceMIDIStreaming[:],
}
const classSpecificAudioTypeLen = 9
var classSpecificAudioInterface = [classSpecificAudioTypeLen]byte{
classSpecificAudioTypeLen,
TypeClassSpecific,
0x01,
0x00, //
0x01, //
0x09,
0x00,
0x01,
0x03,
}
var ClassSpecificAudioInterface = ClassSpecificType{
data: classSpecificAudioInterface[:],
}
const classSpecificMIDIHeaderLen = 7
var classSpecificMIDIHeader = [classSpecificMIDIHeaderLen]byte{
classSpecificMIDIHeaderLen,
TypeClassSpecific,
0x01,
0x00, //
0x01, //
0x41,
0x00,
}
var ClassSpecificMIDIHeader = ClassSpecificType{
data: classSpecificMIDIHeader[:],
}
const classSpecificMIDIInJackLen = 6
var classSpecificMIDIInJack1 = [classSpecificMIDIInJackLen]byte{
classSpecificMIDIInJackLen,
TypeClassSpecific,
0x02, // MIDI In jack
0x01, // Jack type (embedded)
0x01, // Jack ID
0x00, // iJack
}
var ClassSpecificMIDIInJack1 = ClassSpecificType{
data: classSpecificMIDIInJack1[:],
}
var classSpecificMIDIInJack2 = [classSpecificMIDIInJackLen]byte{
classSpecificMIDIInJackLen,
TypeClassSpecific,
0x02, // MIDI In jack
0x02, // Jack type (external)
0x02, // Jack ID
0x00, // iJack
}
var ClassSpecificMIDIInJack2 = ClassSpecificType{
data: classSpecificMIDIInJack2[:],
}
const classSpecificMIDIOutJackLen = 9
var classSpecificMIDIOutJack1 = [classSpecificMIDIOutJackLen]byte{
classSpecificMIDIOutJackLen,
TypeClassSpecific,
0x03, // MIDI Out jack
0x01, // Jack type (embedded)
0x03, // Jack ID
0x01, // number of input pins
0x02, // source ID
0x01, // source pin
0x00, // iJack
}
var ClassSpecificMIDIOutJack1 = ClassSpecificType{
data: classSpecificMIDIOutJack1[:],
}
var classSpecificMIDIOutJack2 = [classSpecificMIDIOutJackLen]byte{
classSpecificMIDIOutJackLen,
TypeClassSpecific,
0x03, // MIDI Out jack
0x02, // Jack type (external)
0x04, // Jack ID
0x01, // number of input pins
0x01, // source ID
0x01, // source pin
0x00, // iJack
}
var ClassSpecificMIDIOutJack2 = ClassSpecificType{
data: classSpecificMIDIOutJack2[:],
}
const classSpecificMIDIEndpointLen = 5
var classSpecificMIDIOutEndpoint = [classSpecificMIDIEndpointLen]byte{
classSpecificMIDIEndpointLen,
TypeClassSpecificEndpoint,
0x01, // CS endpoint
0x01, // number MIDI IN jacks
0x01, // assoc Jack ID
}
var ClassSpecificMIDIOutEndpoint = ClassSpecificType{
data: classSpecificMIDIOutEndpoint[:],
}
var classSpecificMIDIInEndpoint = [classSpecificMIDIEndpointLen]byte{
classSpecificMIDIEndpointLen,
TypeClassSpecificEndpoint,
0x01, // CS endpoint
0x01, // number MIDI Out jacks
0x03, // assoc Jack ID
}
var ClassSpecificMIDIInEndpoint = ClassSpecificType{
data: classSpecificMIDIInEndpoint[:],
}
const endpointMIDITypeLen = 9
var endpointEP6IN = [endpointMIDITypeLen]byte{
endpointMIDITypeLen,
TypeEndpoint,
0x86, // EndpointAddress
0x02, // Attributes
0x40, // MaxPacketSizeL
0x00, // MaxPacketSizeH
0x00, // Interval
0x00, // refresh
0x00, // sync address
}
var EndpointEP6IN = EndpointType{
data: endpointEP6IN[:],
}
var endpointEP7OUT = [endpointMIDITypeLen]byte{
endpointMIDITypeLen,
TypeEndpoint,
0x07, // EndpointAddress
0x02, // Attributes
0x40, // MaxPacketSizeL
0x00, // MaxPacketSizeH
0x00, // Interval
0x00, // refresh
0x00, // sync address
}
var EndpointEP7OUT = EndpointType{
data: endpointEP7OUT[:],
}
var configurationCDCMIDI = [configurationTypeLen]byte{
configurationTypeLen,
TypeConfiguration,
0xaf, 0x00, // adjust length as needed
0x04, // number of interfaces
0x01, // configuration value
0x00, // index to string description
0xa0, // attributes
0x32, // maxpower
}
var ConfigurationCDCMIDI = ConfigurationType{
data: configurationCDCMIDI[:],
}
var CDCMIDI = Descriptor{
Device: DeviceCDC.Bytes(),
Configuration: appendSlices([][]byte{
ConfigurationCDCMIDI.Bytes(),
InterfaceAssociationCDC.Bytes(),
InterfaceCDCControl.Bytes(),
ClassSpecificCDCHeader.Bytes(),
ClassSpecificCDCACM.Bytes(),
ClassSpecificCDCUnion.Bytes(),
ClassSpecificCDCCallManagement.Bytes(),
EndpointEP1IN.Bytes(),
InterfaceCDCData.Bytes(),
EndpointEP2OUT.Bytes(),
EndpointEP3IN.Bytes(),
InterfaceAssociationMIDI.Bytes(),
InterfaceAudio.Bytes(),
ClassSpecificAudioInterface.Bytes(),
InterfaceMIDIStreaming.Bytes(),
ClassSpecificMIDIHeader.Bytes(),
ClassSpecificMIDIInJack1.Bytes(),
ClassSpecificMIDIInJack2.Bytes(),
ClassSpecificMIDIOutJack1.Bytes(),
ClassSpecificMIDIOutJack2.Bytes(),
EndpointEP7OUT.Bytes(),
ClassSpecificMIDIOutEndpoint.Bytes(),
EndpointEP6IN.Bytes(),
ClassSpecificMIDIInEndpoint.Bytes(),
}),
}