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 }