github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/usb/descriptor/hid.go (about)

     1  package descriptor
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"errors"
     7  )
     8  
     9  var configurationCDCHID = [configurationTypeLen]byte{
    10  	configurationTypeLen,
    11  	TypeConfiguration,
    12  	0x64, 0x00, // adjust length as needed
    13  	0x03, // number of interfaces
    14  	0x01, // configuration value
    15  	0x00, // index to string description
    16  	0xa0, // attributes
    17  	0x32, // maxpower
    18  }
    19  
    20  var ConfigurationCDCHID = ConfigurationType{
    21  	data: configurationCDCHID[:],
    22  }
    23  
    24  var interfaceHID = [interfaceTypeLen]byte{
    25  	interfaceTypeLen,
    26  	TypeInterface,
    27  	0x02, // InterfaceNumber
    28  	0x00, // AlternateSetting
    29  	0x02, // NumEndpoints
    30  	0x03, // InterfaceClass
    31  	0x00, // InterfaceSubClass
    32  	0x00, // InterfaceProtocol
    33  	0x00, // Interface
    34  }
    35  
    36  var InterfaceHID = InterfaceType{
    37  	data: interfaceHID[:],
    38  }
    39  
    40  const (
    41  	ClassHIDTypeLen = 9
    42  )
    43  
    44  type ClassHIDType struct {
    45  	data []byte
    46  }
    47  
    48  func (d ClassHIDType) Bytes() []byte {
    49  	return d.data[:]
    50  }
    51  
    52  func (d ClassHIDType) Length(v uint8) {
    53  	d.data[0] = byte(v)
    54  }
    55  
    56  func (d ClassHIDType) Type(v uint8) {
    57  	d.data[1] = byte(v)
    58  }
    59  
    60  func (d ClassHIDType) HID(v uint16) {
    61  	binary.LittleEndian.PutUint16(d.data[2:4], v)
    62  }
    63  
    64  func (d ClassHIDType) CountryCode(v uint8) {
    65  	d.data[4] = byte(v)
    66  }
    67  
    68  func (d ClassHIDType) NumDescriptors(v uint8) {
    69  	d.data[5] = byte(v)
    70  }
    71  
    72  func (d ClassHIDType) ClassType(v uint8) {
    73  	d.data[6] = byte(v)
    74  }
    75  
    76  func (d ClassHIDType) ClassLength(v uint16) {
    77  	binary.LittleEndian.PutUint16(d.data[7:9], v)
    78  }
    79  
    80  var errNoClassHIDFound = errors.New("no classHID found")
    81  
    82  // FindClassHIDType tries to find the ClassHID class in the descriptor.
    83  func FindClassHIDType(des, class []byte) (ClassHIDType, error) {
    84  	if len(des) < ClassHIDTypeLen || len(class) == 0 {
    85  		return ClassHIDType{}, errNoClassHIDFound
    86  	}
    87  
    88  	// search only for ClassHIDType without the ClassLength,
    89  	// in case it has already been set.
    90  	idx := bytes.Index(des, class[:ClassHIDTypeLen-2])
    91  	if idx == -1 {
    92  		return ClassHIDType{}, errNoClassHIDFound
    93  	}
    94  
    95  	return ClassHIDType{data: des[idx : idx+ClassHIDTypeLen]}, nil
    96  }
    97  
    98  var classHID = [ClassHIDTypeLen]byte{
    99  	ClassHIDTypeLen,
   100  	TypeClassHID,
   101  	0x11, // HID version L
   102  	0x01, // HID version H
   103  	0x00, // CountryCode
   104  	0x01, // NumDescriptors
   105  	0x22, // ClassType
   106  	0x90, // ClassLength L
   107  	0x00, // ClassLength H
   108  }
   109  
   110  var ClassHID = ClassHIDType{
   111  	data: classHID[:],
   112  }
   113  
   114  var CDCHID = Descriptor{
   115  	Device: DeviceCDC.Bytes(),
   116  	Configuration: Append([][]byte{
   117  		ConfigurationCDCHID.Bytes(),
   118  		InterfaceAssociationCDC.Bytes(),
   119  		InterfaceCDCControl.Bytes(),
   120  		ClassSpecificCDCHeader.Bytes(),
   121  		ClassSpecificCDCACM.Bytes(),
   122  		ClassSpecificCDCUnion.Bytes(),
   123  		ClassSpecificCDCCallManagement.Bytes(),
   124  		EndpointEP1IN.Bytes(),
   125  		InterfaceCDCData.Bytes(),
   126  		EndpointEP2OUT.Bytes(),
   127  		EndpointEP3IN.Bytes(),
   128  		InterfaceHID.Bytes(),
   129  		ClassHID.Bytes(),
   130  		EndpointEP4IN.Bytes(),
   131  		EndpointEP5OUT.Bytes(),
   132  	}),
   133  	HID: map[uint16][]byte{
   134  		2: Append([][]byte{
   135  			HIDUsagePageGenericDesktop,
   136  			HIDUsageDesktopKeyboard,
   137  			HIDCollectionApplication,
   138  			HIDReportID(2),
   139  
   140  			HIDUsagePageKeyboard,
   141  			HIDUsageMinimum(224),
   142  			HIDUsageMaximum(231),
   143  			HIDLogicalMinimum(0),
   144  			HIDLogicalMaximum(1),
   145  			HIDReportSize(1),
   146  			HIDReportCount(8),
   147  			HIDInputDataVarAbs,
   148  			HIDReportCount(1),
   149  			HIDReportSize(8),
   150  			HIDInputConstVarAbs,
   151  			HIDReportCount(3),
   152  			HIDReportSize(1),
   153  			HIDUsagePageLED,
   154  			HIDUsageMinimum(1),
   155  			HIDUsageMaximum(3),
   156  			HIDOutputDataVarAbs,
   157  			HIDReportCount(5),
   158  			HIDReportSize(1),
   159  			HIDOutputConstVarAbs,
   160  			HIDReportCount(6),
   161  			HIDReportSize(8),
   162  			HIDLogicalMinimum(0),
   163  			HIDLogicalMaximum(255),
   164  
   165  			HIDUsagePageKeyboard,
   166  			HIDUsageMinimum(0),
   167  			HIDUsageMaximum(255),
   168  			HIDInputDataAryAbs,
   169  			HIDCollectionEnd,
   170  
   171  			HIDUsagePageGenericDesktop,
   172  			HIDUsageDesktopMouse,
   173  			HIDCollectionApplication,
   174  			HIDUsageDesktopPointer,
   175  			HIDCollectionPhysical,
   176  			HIDReportID(1),
   177  
   178  			HIDUsagePageButton,
   179  			HIDUsageMinimum(1),
   180  			HIDUsageMaximum(5),
   181  			HIDLogicalMinimum(0),
   182  			HIDLogicalMaximum(1),
   183  			HIDReportCount(5),
   184  			HIDReportSize(1),
   185  			HIDInputDataVarAbs,
   186  			HIDReportCount(1),
   187  			HIDReportSize(3),
   188  			HIDInputConstVarAbs,
   189  
   190  			HIDUsagePageGenericDesktop,
   191  			HIDUsageDesktopX,
   192  			HIDUsageDesktopY,
   193  			HIDUsageDesktopWheel,
   194  			HIDLogicalMinimum(-127),
   195  			HIDLogicalMaximum(127),
   196  			HIDReportSize(8),
   197  			HIDReportCount(3),
   198  			HIDInputDataVarRel,
   199  			HIDCollectionEnd,
   200  			HIDCollectionEnd,
   201  
   202  			HIDUsagePageConsumer,
   203  			HIDUsageConsumerControl,
   204  			HIDCollectionApplication,
   205  			HIDReportID(3),
   206  			HIDLogicalMinimum(0),
   207  			HIDLogicalMaximum(8191),
   208  			HIDUsageMinimum(0),
   209  			HIDUsageMaximum(0x1FFF),
   210  			HIDReportSize(16),
   211  			HIDReportCount(1),
   212  			HIDInputDataAryAbs,
   213  			HIDCollectionEnd}),
   214  	},
   215  }