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