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