mirror of https://github.com/tinygo-org/tinygo.git
deadprogram
2 years ago
committed by
Ron Evans
15 changed files with 1190 additions and 266 deletions
@ -1,179 +0,0 @@ |
|||
package usb |
|||
|
|||
import "runtime/volatile" |
|||
|
|||
// DeviceDescBank is the USB device endpoint descriptor.
|
|||
type DeviceDescBank struct { |
|||
ADDR volatile.Register32 |
|||
PCKSIZE volatile.Register32 |
|||
EXTREG volatile.Register16 |
|||
STATUS_BK volatile.Register8 |
|||
_reserved [5]volatile.Register8 |
|||
} |
|||
|
|||
type DeviceDescriptor struct { |
|||
DeviceDescBank [2]DeviceDescBank |
|||
} |
|||
|
|||
type Descriptor struct { |
|||
Device []byte |
|||
Configuration []byte |
|||
HID map[uint16][]byte |
|||
} |
|||
|
|||
func (d *Descriptor) Configure(idVendor, idProduct uint16) { |
|||
d.Device[8] = byte(idVendor) |
|||
d.Device[9] = byte(idVendor >> 8) |
|||
d.Device[10] = byte(idProduct) |
|||
d.Device[11] = byte(idProduct >> 8) |
|||
|
|||
d.Configuration[2] = byte(len(d.Configuration)) |
|||
d.Configuration[3] = byte(len(d.Configuration) >> 8) |
|||
} |
|||
|
|||
var DescriptorCDC = Descriptor{ |
|||
Device: []byte{ |
|||
0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, |
|||
}, |
|||
Configuration: []byte{ |
|||
0x09, 0x02, 0x4b, 0x00, 0x02, 0x01, 0x00, 0xa0, 0x32, |
|||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, |
|||
0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, |
|||
0x05, 0x24, 0x00, 0x10, 0x01, |
|||
0x04, 0x24, 0x02, 0x06, |
|||
0x05, 0x24, 0x06, 0x00, 0x01, |
|||
0x05, 0x24, 0x01, 0x01, 0x01, |
|||
0x07, 0x05, 0x81, 0x03, 0x10, 0x00, 0x10, |
|||
0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, |
|||
0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, |
|||
0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, |
|||
}, |
|||
} |
|||
|
|||
var DescriptorCDCHID = Descriptor{ |
|||
Device: []byte{ |
|||
0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, |
|||
}, |
|||
Configuration: []byte{ |
|||
0x09, 0x02, 0x64, 0x00, 0x03, 0x01, 0x00, 0xa0, 0x32, |
|||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, |
|||
0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, |
|||
0x05, 0x24, 0x00, 0x10, 0x01, |
|||
0x04, 0x24, 0x02, 0x06, |
|||
0x05, 0x24, 0x06, 0x00, 0x01, |
|||
0x05, 0x24, 0x01, 0x01, 0x01, |
|||
0x07, 0x05, 0x81, 0x03, 0x10, 0x00, 0x10, |
|||
0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, |
|||
0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, |
|||
0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, |
|||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, |
|||
0x09, 0x21, 0x01, 0x01, 0x00, 0x01, 0x22, 0x7E, 0x00, |
|||
0x07, 0x05, 0x84, 0x03, 0x40, 0x00, 0x01, |
|||
}, |
|||
HID: map[uint16][]byte{ |
|||
2: []byte{ |
|||
// keyboard and mouse
|
|||
0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x85, 0x02, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, |
|||
0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x03, 0x95, 0x06, |
|||
0x75, 0x08, 0x15, 0x00, 0x25, 0xFF, 0x05, 0x07, 0x19, 0x00, 0x29, 0xFF, 0x81, 0x00, 0xc0, 0x05, |
|||
0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, |
|||
0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, |
|||
0x03, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, |
|||
0x03, 0x81, 0x06, 0xc0, 0xc0, |
|||
|
|||
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
|
|||
}, |
|||
}, |
|||
} |
|||
|
|||
var DescriptorCDCMIDI = Descriptor{ |
|||
Device: []byte{ |
|||
0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, |
|||
}, |
|||
Configuration: []byte{ |
|||
0x09, 0x02, 0xaf, 0x00, 0x04, 0x01, 0x00, 0xa0, 0x32, |
|||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, |
|||
0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, |
|||
0x05, 0x24, 0x00, 0x10, 0x01, |
|||
0x04, 0x24, 0x02, 0x06, |
|||
0x05, 0x24, 0x06, 0x00, 0x01, |
|||
0x05, 0x24, 0x01, 0x01, 0x01, |
|||
0x07, 0x05, 0x81, 0x03, 0x10, 0x00, 0x10, |
|||
0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, |
|||
0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, |
|||
0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, |
|||
0x08, 0x0b, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, |
|||
0x09, 0x04, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, |
|||
0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x03, |
|||
0x09, 0x04, 0x03, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, |
|||
0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, |
|||
0x06, 0x24, 0x02, 0x01, 0x01, 0x00, |
|||
0x06, 0x24, 0x02, 0x02, 0x02, 0x00, |
|||
0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, |
|||
0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x01, 0x01, 0x00, |
|||
0x09, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, |
|||
0x05, 0x25, 0x01, 0x01, 0x01, |
|||
0x09, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, |
|||
0x05, 0x25, 0x01, 0x01, 0x03, |
|||
}, |
|||
} |
|||
|
|||
var DescriptorCDCJoystick = Descriptor{ |
|||
Device: []byte{ |
|||
0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, |
|||
0x41, 0x23, 0x36, 0x80, 0x00, 0x01, 0x01, 0x02, |
|||
0x03, 0x01, |
|||
}, |
|||
Configuration: []byte{ |
|||
// Configuration Descriptor Header
|
|||
0x09, 0x02, |
|||
0x6b, 0x00, // Total Length: 0x006b(107)
|
|||
0x03, 0x01, 0x00, 0xa0, 0xfa, |
|||
// InterfaceAssociation Descriptoy
|
|||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, |
|||
// InterfaceSescriptor(CDC-Ctrl)
|
|||
0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, |
|||
// Communication Descriptor
|
|||
0x05, 0x24, 0x00, 0x10, 0x01, |
|||
// Communication Descriptor
|
|||
0x05, 0x24, 0x01, 0x01, 0x01, |
|||
// Communication Descriptor
|
|||
0x04, 0x24, 0x02, 0x06, |
|||
// Communication Descriptor
|
|||
0x05, 0x24, 0x06, 0x00, 0x01, |
|||
// ENDPOINT Descriptor
|
|||
0x07, 0x05, 0x81, 0x03, 0x10, 0x00, 0x40, |
|||
// InterfaceSescriptor(CDC-Data)
|
|||
0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, |
|||
// ENDPOINT Descriptor
|
|||
0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, |
|||
// ENDPOINT Descriptor
|
|||
0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, |
|||
// InterfaceSescriptor(HID)
|
|||
0x09, 0x04, 0x02, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, |
|||
// HID Descriptor
|
|||
0x09, // bLength: 9
|
|||
0x21, // bDescriptorType: 0x21(HID)
|
|||
0x11, 0x01, // bcdHID: 0x111
|
|||
0x00, // bCountryCode: Not Supported
|
|||
0x01, // bNumDescriptors: 1
|
|||
0x22, // Type: HID Report
|
|||
0x00, 0x00, // Length
|
|||
// ENDPOINT Descriptor
|
|||
0x07, 0x05, 0x84, 0x03, 0x40, 0x00, 0x01, |
|||
// ENDPOINT Descriptor
|
|||
0x07, 0x05, 0x05, 0x03, 0x40, 0x00, 0x01, |
|||
}, |
|||
HID: map[uint16][]byte{}, |
|||
} |
@ -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) |
|||
} |
@ -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 |
|||
} |
@ -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) |
|||
} |
@ -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) |
|||
} |
@ -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
|
|||
}, |
|||
}, |
|||
} |
@ -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) |
|||
} |
@ -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{}, |
|||
} |
@ -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(), |
|||
}), |
|||
} |
Loading…
Reference in new issue