1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using Antmicro.Renode.Peripherals.Input; 10 using System.Collections.Generic; 11 using Antmicro.Renode.Logging; 12 using Antmicro.Renode.Core; 13 14 namespace Antmicro.Renode.Peripherals.USBDeprecated 15 { 16 public class USBTablet :IUSBPeripheral, IAbsolutePositionPointerInput 17 { USBTablet()18 public USBTablet() 19 { 20 Reset(); 21 } 22 23 public event Action<uint> SendInterrupt; 24 public event Action <uint> SendPacket 25 { 26 add {} 27 remove {} 28 } 29 GetSpeed()30 public USBDeviceSpeed GetSpeed() 31 { 32 return USBDeviceSpeed.Low; 33 } 34 ClearFeature(USBPacket packet, USBSetupPacket setupPacket)35 public void ClearFeature(USBPacket packet, USBSetupPacket setupPacket) 36 { 37 throw new NotImplementedException(); 38 } 39 GetConfiguration()40 public byte[] GetConfiguration() 41 { 42 throw new NotImplementedException(); 43 } 44 SetAddress(uint address)45 public void SetAddress(uint address) 46 { 47 deviceAddress = address; 48 } 49 GetInterface(USBPacket packet, USBSetupPacket setupPacket)50 public byte[] GetInterface(USBPacket packet, USBSetupPacket setupPacket) 51 { 52 throw new NotImplementedException(); 53 } 54 GetStatus(USBPacket packet, USBSetupPacket setupPacket)55 public byte[] GetStatus(USBPacket packet, USBSetupPacket setupPacket) 56 { 57 var arr = new byte[2]; 58 return arr; 59 } 60 SetConfiguration(USBPacket packet, USBSetupPacket setupPacket)61 public void SetConfiguration(USBPacket packet, USBSetupPacket setupPacket) 62 { 63 64 } 65 SetDescriptor(USBPacket packet, USBSetupPacket setupPacket)66 public void SetDescriptor(USBPacket packet, USBSetupPacket setupPacket) 67 { 68 throw new NotImplementedException(); 69 } 70 SetFeature(USBPacket packet, USBSetupPacket setupPacket)71 public void SetFeature(USBPacket packet, USBSetupPacket setupPacket) 72 { 73 throw new NotImplementedException(); 74 } 75 SetInterface(USBPacket packet, USBSetupPacket setupPacket)76 public void SetInterface(USBPacket packet, USBSetupPacket setupPacket) 77 { 78 throw new NotImplementedException(); 79 } 80 ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket)81 public byte[] ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket) 82 { 83 throw new NotImplementedException(); 84 } 85 ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket)86 public void ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket) 87 { 88 throw new NotImplementedException(); 89 } 90 ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket)91 public byte[] ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket) 92 { 93 return controlPacket; 94 } 95 ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket)96 public void ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket) 97 { 98 99 } 100 SetDataToggle(byte endpointNumber)101 public void SetDataToggle(byte endpointNumber) 102 { 103 throw new NotImplementedException(); 104 } 105 CleanDataToggle(byte endpointNumber)106 public void CleanDataToggle(byte endpointNumber) 107 { 108 throw new NotImplementedException(); 109 } 110 GetDataToggle(byte endpointNumber)111 public bool GetDataToggle(byte endpointNumber) 112 { 113 throw new NotImplementedException(); 114 } 115 ToggleDataToggle(byte endpointNumber)116 public void ToggleDataToggle(byte endpointNumber) 117 { 118 throw new NotImplementedException(); 119 } 120 GetAddress()121 public uint GetAddress() 122 { 123 return deviceAddress; 124 } 125 WriteInterrupt(USBPacket packet)126 public byte[] WriteInterrupt(USBPacket packet) 127 { 128 lock(thisLock) 129 { 130 if(changeState) 131 { 132 buffer[5] = 0; 133 changeState = false; 134 return this.buffer; 135 } 136 else 137 return null; 138 } 139 } 140 GetDataBulk(USBPacket packet)141 public byte[] GetDataBulk(USBPacket packet) 142 { 143 return null; 144 } 145 GetDataControl(USBPacket packet)146 public byte[] GetDataControl(USBPacket packet) 147 { 148 return controlPacket; 149 } 150 GetTransferStatus()151 public byte GetTransferStatus() 152 { 153 return 0; 154 } 155 GetDescriptor(USBPacket packet, USBSetupPacket setupPacket)156 public byte[] GetDescriptor(USBPacket packet, USBSetupPacket setupPacket) 157 { 158 DescriptorType type; 159 type = (DescriptorType)((setupPacket.value & 0xff00) >> 8); 160 uint index = (uint)(setupPacket.value & 0xff); 161 switch(type) 162 { 163 case DescriptorType.Device: 164 controlPacket = new byte[deviceDescriptor.ToArray().Length]; 165 deviceDescriptor.ToArray().CopyTo(controlPacket, 0); 166 return deviceDescriptor.ToArray(); 167 case DescriptorType.Configuration: 168 controlPacket = new byte[configurationDescriptor.ToArray().Length]; 169 configurationDescriptor.ToArray().CopyTo(controlPacket, 0); 170 controlPacket = tabletConfigDescriptor; 171 return configurationDescriptor.ToArray(); 172 case DescriptorType.DeviceQualifier: 173 controlPacket = new byte[deviceQualifierDescriptor.ToArray().Length]; 174 deviceQualifierDescriptor.ToArray().CopyTo(controlPacket, 0); 175 return deviceQualifierDescriptor.ToArray(); 176 case DescriptorType.InterfacePower: 177 throw new NotImplementedException("Interface Power Descriptor is not yet implemented. Please contact AntMicro for further support."); 178 case DescriptorType.OtherSpeedConfiguration: 179 controlPacket = new byte[otherConfigurationDescriptor.ToArray().Length]; 180 otherConfigurationDescriptor.ToArray().CopyTo(controlPacket, 0); 181 return otherConfigurationDescriptor.ToArray(); 182 case DescriptorType.String: 183 if(index == 0) 184 { 185 stringDescriptor = new StringUSBDescriptor(1); 186 stringDescriptor.LangId[0] = EnglishLangId; 187 } 188 else 189 { 190 stringDescriptor = new StringUSBDescriptor(stringValues[setupPacket.index][index]); 191 } 192 controlPacket = new byte[stringDescriptor.ToArray().Length]; 193 stringDescriptor.ToArray().CopyTo(controlPacket, 0); 194 return stringDescriptor.ToArray(); 195 case (DescriptorType)0x22: 196 controlPacket = tabletHIDReportDescriptor; 197 break; 198 default: 199 this.Log(LogLevel.Warning, "Unsupported mouse request!!!"); 200 return null; 201 } 202 return null; 203 } 204 WriteDataBulk(USBPacket packet)205 public void WriteDataBulk(USBPacket packet) 206 { 207 208 } 209 WriteDataControl(USBPacket packet)210 public void WriteDataControl(USBPacket packet) 211 { 212 213 } 214 Reset()215 public void Reset() 216 { 217 x = y = 0; 218 otherConfigurationDescriptor = new ConfigurationUSBDescriptor(); 219 deviceQualifierDescriptor = new DeviceQualifierUSBDescriptor(); 220 endpointDescriptor = new EndpointUSBDescriptor[3]; 221 for(int i = 0; i < NumberOfEndpoints; i++) 222 { 223 endpointDescriptor[i] = new EndpointUSBDescriptor(); 224 } 225 fillEndpointsDescriptors(endpointDescriptor); 226 interfaceDescriptor[0].EndpointDescriptor = endpointDescriptor; 227 configurationDescriptor.InterfaceDescriptor = interfaceDescriptor; 228 229 mstate = 0; 230 changeState = false; 231 buffer = new byte[6]; 232 } 233 Press(MouseButton button)234 public void Press(MouseButton button) 235 { 236 lock(thisLock) 237 { 238 mstate = (byte)button; 239 buffer[0] = mstate; 240 buffer[1] = (byte)(x & byte.MaxValue); 241 // x small 242 buffer[2] = (byte)((x >> 8) & 127); 243 // x big 244 buffer[3] = (byte)(y & byte.MaxValue); 245 // y small 246 buffer[4] = (byte)((y >> 8) & 127); 247 // y big 248 changeState = true; 249 } 250 Refresh(); 251 } 252 Release(MouseButton button)253 public void Release(MouseButton button) 254 { 255 lock(thisLock) 256 { 257 buffer[0] = mstate = 0; 258 buffer[1] = (byte)(x & byte.MaxValue); 259 // x small 260 buffer[2] = (byte)((x >> 8) & 127); 261 // x big 262 buffer[3] = (byte)(y & byte.MaxValue); 263 // y small 264 buffer[4] = (byte)((y >> 8) & 127); 265 // y big 266 changeState = true; 267 } 268 Refresh(); 269 } 270 MoveTo(int x, int y)271 public void MoveTo(int x, int y) 272 { 273 lock(thisLock) 274 { 275 this.x = x; 276 this.y = y; 277 buffer[0] = mstate; 278 buffer[1] = (byte)(x & byte.MaxValue); 279 // x small 280 buffer[2] = (byte)((x >> 8) & 127); 281 // x big 282 buffer[3] = (byte)(y & byte.MaxValue); 283 // y small 284 buffer[4] = (byte)((y >> 8) & 127); 285 // y big 286 changeState = true; 287 } 288 Refresh(); 289 } 290 291 public int MaxX 292 { 293 get 294 { 295 return 32767; 296 } 297 } 298 299 public int MaxY 300 { 301 get 302 { 303 return 32767; 304 } 305 } 306 307 public int MinX 308 { 309 get 310 { 311 return 0; 312 } 313 } 314 315 public int MinY 316 { 317 get 318 { 319 return 0; 320 } 321 } 322 fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc)323 private void fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc) 324 { 325 endpointDesc[0].EndpointNumber = 1; 326 endpointDesc[0].InEnpoint = true; 327 endpointDesc[0].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Interrupt; 328 endpointDesc[0].MaxPacketSize = 0x0008; 329 endpointDesc[0].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization; 330 endpointDesc[0].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data; 331 endpointDesc[0].Interval = 0x0a; 332 } 333 Refresh()334 private void Refresh() 335 { 336 if(deviceAddress != 0) 337 { 338 SendInterrupt(deviceAddress); 339 } 340 } 341 342 private const byte NumX = 28; 343 private const byte NumY = 16; 344 private const ushort EnglishLangId = 0x09; 345 private const byte NumberOfEndpoints = 2; 346 347 private uint deviceAddress; 348 private Object thisLock = new Object(); 349 private DeviceQualifierUSBDescriptor deviceQualifierDescriptor; 350 private ConfigurationUSBDescriptor otherConfigurationDescriptor; 351 private StringUSBDescriptor stringDescriptor = null; 352 private EndpointUSBDescriptor[] endpointDescriptor; 353 private byte[] controlPacket; 354 private Byte[] buffer; 355 private int x; 356 private int y; 357 private byte mstate = 0; 358 private bool changeState = false; 359 private Dictionary<ushort, string[]> stringValues = new Dictionary<ushort, string[]>() { {EnglishLangId, new string[] { 360 "", 361 "1", 362 "HID Tablet", 363 "AntMicro", 364 "", 365 "", 366 "HID Tablet", 367 "Configuration" 368 } 369 } 370 }; 371 private InterfaceUSBDescriptor[] interfaceDescriptor = new[] {new InterfaceUSBDescriptor { 372 AlternateSetting = 0, 373 InterfaceNumber = 0x00, 374 NumberOfEndpoints = 1, 375 InterfaceClass = 0x03, 376 InterfaceProtocol = 0x02, 377 InterfaceSubClass = 0x01, 378 InterfaceIndex = 0x07 379 } 380 }; 381 private ConfigurationUSBDescriptor configurationDescriptor = new ConfigurationUSBDescriptor() { 382 ConfigurationIndex = 0, 383 SelfPowered = true, 384 NumberOfInterfaces = 1, 385 RemoteWakeup = true, 386 MaxPower = 50, //500mA 387 ConfigurationValue = 1 388 }; 389 390 private StandardUSBDescriptor deviceDescriptor = new StandardUSBDescriptor { 391 DeviceClass = 0x00, 392 DeviceSubClass = 0x00, 393 USB = 0x0100, 394 DeviceProtocol = 0x00, 395 MaxPacketSize = 8, 396 VendorId = 0x80ee, 397 ProductId = 0x0021, 398 Device = 0x0000, 399 ManufacturerIndex = 3, 400 ProductIndex = 2, 401 SerialNumberIndex = 1, 402 NumberOfConfigurations = 1 403 }; 404 405 private byte[] tabletConfigDescriptor = { 406 0x09, 407 0x02, 408 0x22, 0x00, 409 0x01, 410 0x01, 411 0x05, 412 0xa0, 413 50, 414 0x09, 415 0x04, 416 0x00, 417 0x00, 418 0x01, 419 0x03, 420 0x01, 421 0x02, 422 0x07, 423 0x09, 424 0x21, 425 0x01, 0x00, 426 0x00, 427 0x01, 428 0x22, 429 74, 0, 430 0x07, 431 0x05, 432 0x81, 433 0x03, 434 0x04, 0x00, 435 0x0a 436 }; 437 private byte[] tabletHIDReportDescriptor = { 438 0x05, 0x01, 439 0x09, 0x01, 440 0xa1, 0x01, 441 0x09, 0x01, 442 0xa1, 0x00, 443 0x05, 0x09, 444 0x19, 0x01, 445 0x29, 0x03, 446 0x15, 0x00, 447 0x25, 0x01, 448 0x95, 0x03, 449 0x75, 0x01, 450 0x81, 0x02, 451 0x95, 0x01, 452 0x75, 0x05, 453 0x81, 0x01, 454 0x05, 0x01, 455 0x09, 0x30, 456 0x09, 0x31, 457 0x15, 0x00, 458 0x26, 0xff, 0x7f, 459 0x35, 0x00, 460 0x46, 0xff, 0x7f, 461 0x75, 0x10, 462 0x95, 0x02, 463 0x81, 0x02, 464 0x05, 0x01, 465 0x09, 0x38, 466 0x15, 0x81, 467 0x25, 0x7f, 468 0x35, 0x00, 469 0x45, 0x00, 470 0x75, 0x08, 471 0x95, 0x01, 472 0x81, 0x06, 473 0xc0, 474 0xc0, 475 }; 476 } 477 } 478 479