tinygo/src/machine/usb/descriptor/hid.go
2023-08-07 14:00:32 +02:00

215 строки
4,5 КиБ
Go

package descriptor
import (
"bytes"
"encoding/binary"
"errors"
)
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
0x02, // 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)
}
var errNoClassHIDFound = errors.New("no classHID found")
// FindClassHIDType tries to find the ClassHID class in the descriptor.
func FindClassHIDType(des, class []byte) (ClassHIDType, error) {
if len(des) < ClassHIDTypeLen || len(class) == 0 {
return ClassHIDType{}, errNoClassHIDFound
}
// search only for ClassHIDType without the ClassLength,
// in case it has already been set.
idx := bytes.Index(des, class[:ClassHIDTypeLen-2])
if idx == -1 {
return ClassHIDType{}, errNoClassHIDFound
}
return ClassHIDType{data: des[idx : idx+ClassHIDTypeLen]}, nil
}
var classHID = [ClassHIDTypeLen]byte{
ClassHIDTypeLen,
TypeClassHID,
0x11, // HID version L
0x01, // HID version H
0x00, // CountryCode
0x01, // NumDescriptors
0x22, // ClassType
0x90, // ClassLength L
0x00, // ClassLength H
}
var ClassHID = ClassHIDType{
data: classHID[:],
}
var CDCHID = Descriptor{
Device: DeviceCDC.Bytes(),
Configuration: Append([][]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(),
EndpointEP5OUT.Bytes(),
}),
HID: map[uint16][]byte{
2: Append([][]byte{
HIDUsagePageGenericDesktop,
HIDUsageDesktopKeyboard,
HIDCollectionApplication,
HIDReportID(2),
HIDUsagePageKeyboard,
HIDUsageMinimum(224),
HIDUsageMaximum(231),
HIDLogicalMinimum(0),
HIDLogicalMaximum(1),
HIDReportSize(1),
HIDReportCount(8),
HIDInputDataVarAbs,
HIDReportCount(1),
HIDReportSize(8),
HIDInputConstVarAbs,
HIDReportCount(3),
HIDReportSize(1),
HIDUsagePageLED,
HIDUsageMinimum(1),
HIDUsageMaximum(3),
HIDOutputDataVarAbs,
HIDReportCount(5),
HIDReportSize(1),
HIDOutputConstVarAbs,
HIDReportCount(6),
HIDReportSize(8),
HIDLogicalMinimum(0),
HIDLogicalMaximum(255),
HIDUsagePageKeyboard,
HIDUsageMinimum(0),
HIDUsageMaximum(255),
HIDInputDataAryAbs,
HIDCollectionEnd,
HIDUsagePageGenericDesktop,
HIDUsageDesktopMouse,
HIDCollectionApplication,
HIDUsageDesktopPointer,
HIDCollectionPhysical,
HIDReportID(1),
HIDUsagePageButton,
HIDUsageMinimum(1),
HIDUsageMaximum(5),
HIDLogicalMinimum(0),
HIDLogicalMaximum(1),
HIDReportCount(5),
HIDReportSize(1),
HIDInputDataVarAbs,
HIDReportCount(1),
HIDReportSize(3),
HIDInputConstVarAbs,
HIDUsagePageGenericDesktop,
HIDUsageDesktopX,
HIDUsageDesktopY,
HIDUsageDesktopWheel,
HIDLogicalMinimum(-127),
HIDLogicalMaximum(127),
HIDReportSize(8),
HIDReportCount(3),
HIDInputDataVarRel,
HIDCollectionEnd,
HIDCollectionEnd,
HIDUsagePageConsumer,
HIDUsageConsumerControl,
HIDCollectionApplication,
HIDReportID(3),
HIDLogicalMinimum(0),
HIDLogicalMaximum(8191),
HIDUsageMinimum(0),
HIDUsageMaximum(0x1FFF),
HIDReportSize(16),
HIDReportCount(1),
HIDInputDataAryAbs,
HIDCollectionEnd}),
},
}