1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 8 using System; 9 using System.Linq; 10 using System.Collections.Generic; 11 12 using Antmicro.Migrant; 13 using Antmicro.Renode.Core; 14 using Antmicro.Renode.Core.USB; 15 using Antmicro.Renode.Core.Structure.Registers; 16 using Antmicro.Renode.Logging; 17 using Antmicro.Renode.Peripherals.Bus; 18 using Antmicro.Renode.Peripherals.USB; 19 using Antmicro.Renode.Peripherals.Miscellaneous; 20 using Antmicro.Renode.Utilities; 21 22 namespace Antmicro.Renode.Peripherals.USB 23 { 24 public class NRF_USBD : IUSBDevice, IDoubleWordPeripheral, IProvidesRegisterCollection<DoubleWordRegisterCollection>, IKnownSize, INRFEventProvider 25 { NRF_USBD(IMachine machine, short maximumPacketSize = 64)26 public NRF_USBD(IMachine machine, short maximumPacketSize = 64) 27 { 28 this.machine = machine; 29 USBCore = new USBDeviceCore(this, customSetupPacketHandler: HandleSetupPacket); 30 registers = new DoubleWordRegisterCollection(this); 31 IRQ = new GPIO(); 32 interruptManager = new InterruptManager<Events>(this, IRQ, "UsbIrq"); 33 events = new IFlagRegisterField[(int)Events.EpData + 1]; 34 epInDataStatus = new bool[EndpointCount]; 35 epInStatus = new bool[EndpointCount]; 36 this.maximumPacketSize = maximumPacketSize; 37 InitiateUSBCore(); 38 DefineRegisters(); 39 } 40 Reset()41 public void Reset() 42 { 43 interruptManager.Reset(); 44 registers.Reset(); 45 } 46 47 public USBDeviceCore USBCore { get; } 48 ReadDoubleWord(long offset)49 public uint ReadDoubleWord(long offset) 50 { 51 return registers.Read(offset); 52 } 53 WriteDoubleWord(long offset, uint value)54 public void WriteDoubleWord(long offset, uint value) 55 { 56 registers.Write(offset, value); 57 } 58 59 [IrqProvider] 60 public GPIO IRQ { get; } 61 public long Size => 0x1000; 62 63 public event Action<uint> EventTriggered; 64 HandleSetupPacket(SetupPacket packet, byte[] arg2, Action<byte[]> action)65 private void HandleSetupPacket(SetupPacket packet, byte[] arg2, Action<byte[]> action) 66 { 67 // Note: this method handled some setup packets in the model instead of relying them to the simulated software 68 // This is a simplification that needs to be resolved in the future 69 this.Log(LogLevel.Noisy, "Received SetupPacket. Request: {0}", packet.Request); 70 setupPacket = packet; 71 SetEvent(Events.Ep0Setup); 72 setupPacketResultCallback = action; 73 74 switch(packet.Request) 75 { 76 case (byte)StandardRequest.SetAddress: 77 USBCore.Address = (byte)setupPacket.Value; 78 setupPacketResultCallback(Array.Empty<byte>()); 79 break; 80 case (byte)StandardRequest.SetConfiguration: 81 setupPacketResultCallback(Array.Empty<byte>()); 82 break; 83 } 84 } 85 GetData(ushort epNumber)86 private void GetData(ushort epNumber) 87 { 88 this.Log(LogLevel.Noisy, "Reading data from EP number: {0}", epNumber); 89 // Every pointer to endpoint data and endpoint count is n * 0x14 away from endpoint's 0, where n is number of endpoint. 90 // E.g: pointer to second endpoint data would be: (2 * 0x14 + address of endpoint 0) 91 uint endpointIn = registers.Read((0x14 * epNumber) + (long)Registers.Endpoint0In); 92 uint endpointInCount = registers.Read((0x14 * epNumber) + (long)Registers.Endpoint0InCount); 93 var usbPacket = machine.GetSystemBus(this).ReadBytes(endpointIn, (int)endpointInCount); 94 95 if(epNumber == 0) 96 { 97 setupPacketResultCallback(usbPacket); 98 endpoint0InCount.Value = endpointInCount; 99 } 100 else if(usbPacket.Length != 0) 101 { 102 deviceToHostEndpoint.HandlePacket(usbPacket); 103 } 104 DataAcknowledged(epNumber); 105 } 106 DataAcknowledged(ushort epNumber)107 private void DataAcknowledged(ushort epNumber) 108 { 109 epInDataStatus[epNumber] = true; 110 111 SetEvent(Events.Started); 112 SetEvent(Events.EndEpIn0 + epNumber); 113 SetEvent(Events.EpData); 114 115 // Special event for control endpoint 116 if(epNumber == 0) 117 { 118 SetEvent(Events.Ep0DataDone); 119 } 120 } 121 122 private void SetEvent(Events @event) 123 { 124 interruptManager.SetInterrupt(@event); 125 events[(int)@event].Value = true; 126 // Events registers start at 0x100, they are apart of each other by 4 bytes. 127 EventTriggered?.Invoke((uint)@event * 4 + 0x100); 128 } 129 DefineTask(Registers register, Action<ushort> callback, ushort epNumber, string name)130 private void DefineTask(Registers register, Action<ushort> callback, ushort epNumber, string name) 131 { 132 register.Define(this, name: name) 133 .WithFlag(0, FieldMode.Write, writeCallback: (_, value) => { if(value) callback(epNumber); }) 134 .WithReservedBits(1, 31); 135 } 136 DefineEvent(Registers register, Events @event, string name)137 private void DefineEvent(Registers register, Events @event, string name) 138 { 139 register.Define(this, name: name) 140 .WithFlag(0, out events[(int)@event], writeCallback: (_, value) => 141 { 142 if(!value) 143 { 144 interruptManager.SetInterrupt(@event, false); 145 } 146 }) 147 .WithReservedBits(1, 31); 148 } 149 DefineRegisters()150 private void DefineRegisters() 151 { 152 DefineTask(Registers.TasksStartEpIn0, GetData, 0, "TASKS_STARTEPIN0"); 153 DefineTask(Registers.TasksStartEpIn1, GetData, 1, "TASKS_STARTEPIN1"); 154 DefineTask(Registers.TasksStartEpIn2, GetData, 2, "TASKS_STARTEPIN2"); 155 DefineTask(Registers.TasksStartEpIn3, GetData, 3, "TASKS_STARTEPIN3"); 156 DefineTask(Registers.TasksStartEpIn4, GetData, 4, "TASKS_STARTEPIN4"); 157 DefineTask(Registers.TasksStartEpIn5, GetData, 5, "TASKS_STARTEPIN5"); 158 DefineTask(Registers.TasksStartEpIn6, GetData, 6, "TASKS_STARTEPIN6"); 159 DefineTask(Registers.TasksStartEpIn7, GetData, 7, "TASKS_STARTEPIN7"); 160 DefineTask(Registers.TasksEp0Status, (_) => {}, 0, "TASKS_EP0STATUS"); 161 DefineEvent(Registers.EventsUsbReset, Events.UsbReset, "EVENTS_USBRESET"); 162 DefineEvent(Registers.EventsEp0Setup, Events.Ep0Setup, "EVENTS_EP0SETUP"); 163 DefineEvent(Registers.EventsStarted, Events.Started, "EVENTS_STARTED"); 164 DefineEvent(Registers.EventsEndEpIn0, Events.EndEpIn0, "EVENTS_ENDEPIN0"); 165 DefineEvent(Registers.EventsEndEpIn1, Events.EndEpIn1, "EVENTS_ENDEPIN1"); 166 DefineEvent(Registers.EventsEndEpIn2, Events.EndEpIn2, "EVENTS_ENDEPIN2"); 167 DefineEvent(Registers.EventsEndEpIn3, Events.EndEpIn3, "EVENTS_ENDEPIN3"); 168 DefineEvent(Registers.EventsEndEpIn4, Events.EndEpIn4, "EVENTS_ENDEPIN4"); 169 DefineEvent(Registers.EventsEndEpIn5, Events.EndEpIn5, "EVENTS_ENDEPIN5"); 170 DefineEvent(Registers.EventsEndEpIn6, Events.EndEpIn6, "EVENTS_ENDEPIN6"); 171 DefineEvent(Registers.EventsEndEpIn7, Events.EndEpIn7, "EVENTS_ENDEPIN7"); 172 DefineEvent(Registers.EventsEp0DataDone, Events.Ep0DataDone, "EVENTS_EP0DATADONE"); 173 DefineEvent(Registers.EventsEpData, Events.EpData, "EVENTS_EPDATA"); 174 175 registers.AddRegister((long)Registers.InterruptEnable, 176 interruptManager.GetInterruptEnableSetRegister<DoubleWordRegister>()); 177 178 Registers.EventCause.Define(this) 179 .WithTaggedFlag("EVENT_ISOOUTCRC", 0) 180 .WithTaggedFlag("EVENT_SUSPEND", 8) 181 .WithTaggedFlag("EVENT_RESUME", 9) 182 .WithTaggedFlag("EVENT_USBWUALLOWED", 10) 183 .WithFlag(11, name: "EVENT_READY") 184 .WithReservedBits(12, 20); 185 186 Registers.EndpointStatus.Define(this) 187 .WithFlag(0, writeCallback: (_, val) => {epInStatus[0] = val;}, valueProviderCallback: _ => epInStatus[0], name: "EPIN1") 188 .WithFlag(1, writeCallback: (_, val) => {epInStatus[1] = val;}, valueProviderCallback: _ => epInStatus[1], name: "EPIN1") 189 .WithFlag(2, writeCallback: (_, val) => {epInStatus[2] = val;}, valueProviderCallback: _ => epInStatus[2], name: "EPIN2") 190 .WithFlag(3, writeCallback: (_, val) => {epInStatus[3] = val;}, valueProviderCallback: _ => epInStatus[3], name: "EPIN3") 191 .WithFlag(4, writeCallback: (_, val) => {epInStatus[4] = val;}, valueProviderCallback: _ => epInStatus[4], name: "EPIN4") 192 .WithFlag(5, writeCallback: (_, val) => {epInStatus[5] = val;}, valueProviderCallback: _ => epInStatus[5], name: "EPIN5") 193 .WithFlag(6, writeCallback: (_, val) => {epInStatus[6] = val;}, valueProviderCallback: _ => epInStatus[6], name: "EPIN6") 194 .WithFlag(7, writeCallback: (_, val) => {epInStatus[7] = val;}, valueProviderCallback: _ => epInStatus[7], name: "EPIN7") 195 .WithReservedBits(8, 8) 196 .WithTaggedFlag("EPOUT0", 16) 197 .WithTaggedFlag("EPOUT1", 17) 198 .WithTaggedFlag("EPOUT2", 18) 199 .WithTaggedFlag("EPOUT3", 19) 200 .WithTaggedFlag("EPOUT4", 20) 201 .WithTaggedFlag("EPOUT5", 21) 202 .WithTaggedFlag("EPOUT6", 22) 203 .WithTaggedFlag("EPOUT7", 23) 204 .WithTaggedFlag("EPOUT8", 24) 205 .WithReservedBits(25, 7); 206 207 Registers.EndpointDataStatus.Define(this) 208 .WithReservedBits(0, 1) // Ep0 has no data status 209 .WithFlag(1, writeCallback: (_, val) => {epInDataStatus[1] = val;}, valueProviderCallback: _ => epInDataStatus[1], name: "EPIN1") 210 .WithFlag(2, writeCallback: (_, val) => {epInDataStatus[2] = val;}, valueProviderCallback: _ => epInDataStatus[2], name: "EPIN2") 211 .WithFlag(3, writeCallback: (_, val) => {epInDataStatus[3] = val;}, valueProviderCallback: _ => epInDataStatus[3], name: "EPIN3") 212 .WithFlag(4, writeCallback: (_, val) => {epInDataStatus[4] = val;}, valueProviderCallback: _ => epInDataStatus[4], name: "EPIN4") 213 .WithFlag(5, writeCallback: (_, val) => {epInDataStatus[5] = val;}, valueProviderCallback: _ => epInDataStatus[5], name: "EPIN5") 214 .WithFlag(6, writeCallback: (_, val) => {epInDataStatus[6] = val;}, valueProviderCallback: _ => epInDataStatus[6], name: "EPIN6") 215 .WithFlag(7, writeCallback: (_, val) => {epInDataStatus[7] = val;}, valueProviderCallback: _ => epInDataStatus[7], name: "EPIN7") 216 .WithReservedBits(8, 9) 217 .WithTaggedFlag("EPOUT1", 17) 218 .WithTaggedFlag("EPOUT2", 18) 219 .WithTaggedFlag("EPOUT3", 19) 220 .WithTaggedFlag("EPOUT4", 20) 221 .WithTaggedFlag("EPOUT5", 21) 222 .WithTaggedFlag("EPOUT6", 22) 223 .WithTaggedFlag("EPOUT7", 23) 224 .WithReservedBits(24, 8); 225 226 Registers.UsbAddress.Define(this) 227 .WithValueField(0, 7, out usbAddress, FieldMode.Read) 228 .WithReservedBits(7, 24); 229 230 Registers.bmRequestType.Define(this) 231 .WithTag("RECIPIENT", 0, 5) 232 .WithValueField(5, 2, FieldMode.Read, valueProviderCallback: _ => 0, name: "TYPE") 233 .WithValueField(7, 1, FieldMode.Read, name: "DIRECTION", 234 valueProviderCallback: _ => (ulong)setupPacket.Direction) 235 .WithReservedBits(8, 24); 236 237 Registers.bRequest.Define(this) 238 .WithValueField(0, 8, FieldMode.Read, valueProviderCallback: _ => setupPacket.Request) 239 .WithReservedBits(8, 24); 240 241 Registers.wValueLow.Define(this) 242 .WithValueField(0, 8, FieldMode.Read, valueProviderCallback: _ => (byte)(setupPacket.Value & 0xFF)) 243 .WithReservedBits(8, 24); 244 245 Registers.wValueHigh.Define(this) 246 .WithValueField(0, 8, FieldMode.Read, valueProviderCallback: _ => (byte)(setupPacket.Value >> 8 & 0xFF)) 247 .WithReservedBits(8, 24); 248 249 Registers.wIndexLow.Define(this) 250 .WithValueField(0, 8, FieldMode.Read, valueProviderCallback: _ => setupPacket.Index) 251 .WithReservedBits(8, 24); 252 253 Registers.wLengthLow.Define(this) 254 .WithValueField(0, 8, FieldMode.Read, valueProviderCallback: _ => setupPacket.Count) 255 .WithReservedBits(8, 24); 256 257 Registers.Enable.Define(this) 258 .WithFlag(0, out usbEnable, name: "ENABLE") 259 .WithReservedBits(1, 31); 260 261 Registers.UsbPullup.Define(this) 262 .WithFlag(0, out usbPullup, name: "CONNECT") 263 .WithReservedBits(1, 31); 264 265 Registers.DataToggle.Define(this) 266 .WithValueField(0, 3, valueField: out dataToggleEndpoint, name: "EP") 267 .WithFlag(7, out dataToggleInputOutput, name: "IO") 268 .WithValueField(8, 2, valueField: out dataToggleValue, name: "VALUE") 269 .WithReservedBits(10, 22) 270 .WithWriteCallback((_, __) => HandleToggle()); 271 272 Registers.EndpointInEnable.Define(this) 273 .WithFlag(0, out ep0InEnabled, name: "IN0") 274 .WithTaggedFlag("IN1", 1) 275 .WithTaggedFlag("IN2", 2) 276 .WithTaggedFlag("IN3", 3) 277 .WithTaggedFlag("IN4", 4) 278 .WithTaggedFlag("IN5", 5) 279 .WithTaggedFlag("IN6", 6) 280 .WithTaggedFlag("IN7", 7) 281 .WithTaggedFlag("ISOIN", 8) 282 .WithReservedBits(9, 23); 283 284 Registers.EndpointOutEnable.Define(this) 285 .WithFlag(0, out ep0OutEnabled, name: "OUT0") 286 .WithTaggedFlag("OUT1", 1) 287 .WithTaggedFlag("OUT2", 2) 288 .WithTaggedFlag("OUT3", 3) 289 .WithTaggedFlag("OUT4", 4) 290 .WithTaggedFlag("OUT5", 5) 291 .WithTaggedFlag("OUT6", 6) 292 .WithTaggedFlag("OUT7", 7) 293 .WithTaggedFlag("ISOOUT", 8) 294 .WithReservedBits(9, 23); 295 296 Registers.EndpointStall.Define(this) 297 .WithValueField(0, 3, out epstallEndpoint, name: "EP") 298 .WithReservedBits(3, 4) 299 .WithFlag(7, out epstallIO, name: "IO") 300 .WithFlag(8, out epstallStall, name: "STALL") 301 .WithReservedBits(9, 23) 302 .WithWriteCallback((_, __) => HandleStalling()); 303 304 Registers.IsoInConfig.Define(this) // This is last thing happening in nRF5340, after this the enumeration should start 305 .WithTaggedFlag("RESPONSE", 0) 306 .WithReservedBits(1, 31); 307 308 309 Registers.Endpoint0In.Define(this) 310 .WithValueField(0, 32, name: "EPIN0", valueField: out endpoint0In); 311 Registers.Endpoint0InCount.Define(this) 312 .WithValueField(0, 8, name: "EPIN0_MAXCNT", valueField: out endpoint0InCount) 313 .WithReservedBits(8, 24); 314 315 Registers.Endpoint1In.Define(this) 316 .WithValueField(0, 32, name: "EPIN1"); 317 Registers.Endpoint1InCount.Define(this) 318 .WithValueField(0, 8, name: "EPIN1_MAXCNT") 319 .WithReservedBits(8, 24); 320 321 Registers.Endpoint2In.Define(this) 322 .WithValueField(0, 32, name: "EPIN2"); 323 Registers.Endpoint2InCount.Define(this) 324 .WithValueField(0, 8, name: "EPIN2_MAXCNT") 325 .WithReservedBits(8, 24); 326 327 Registers.Endpoint3In.Define(this) 328 .WithValueField(0, 32, name: "EPIN3"); 329 Registers.Endpoint3InCount.Define(this) 330 .WithValueField(0, 8, name: "EPIN3_MAXCNT") 331 .WithReservedBits(8, 24); 332 333 Registers.Endpoint4In.Define(this) 334 .WithValueField(0, 32, name: "EPIN4"); 335 Registers.Endpoint4InCount.Define(this) 336 .WithValueField(0, 8, name: "EPIN4_MAXCNT") 337 .WithReservedBits(8, 24); 338 339 Registers.Endpoint5In.Define(this) 340 .WithValueField(0, 32, name: "EPIN5"); 341 Registers.Endpoint5InCount.Define(this) 342 .WithValueField(0, 8, name: "EPIN5_MAXCNT") 343 .WithReservedBits(8, 24); 344 345 Registers.Endpoint6In.Define(this) 346 .WithValueField(0, 32, name: "EPIN6"); 347 Registers.Endpoint6InCount.Define(this) 348 .WithValueField(0, 8, name: "EPIN6_MAXCNT") 349 .WithReservedBits(8, 24); 350 351 Registers.Endpoint7In.Define(this) 352 .WithValueField(0, 32, name: "EPIN7"); 353 Registers.Endpoint7InCount.Define(this) 354 .WithValueField(0, 8, name: "EPIN7_MAXCNT") 355 .WithReservedBits(8, 24); 356 } 357 HandleToggle()358 private void HandleToggle() 359 { 360 if(dataToggleValue.Value == 0) 361 { 362 this.Log(LogLevel.Noisy, "Selecting EP #{0}, {1}", dataToggleEndpoint.Value, dataToggleInputOutput.Value ? "in" : "out"); 363 return; 364 } 365 this.Log(LogLevel.Noisy, "Accessing EP #{0}, {1}; DATA{2}", dataToggleEndpoint.Value, dataToggleInputOutput.Value==false ? "out" : "in", dataToggleValue.Value == 1 ? "0" : "1"); 366 } 367 HandleStalling()368 private void HandleStalling() 369 { 370 // This is useful for debugging, as software may stall endpoint 371 // on wrong/unsupported tokens 372 this.Log(LogLevel.Noisy, "{0} EP #{1}, {2}", epstallStall.Value == true ? "Stalling" : "Unstalling", epstallEndpoint.Value, epstallIO.Value==false ? "out" : "in"); 373 } 374 InitiateUSBCore()375 private void InitiateUSBCore() 376 { 377 // Define all possible endpoints as available right away 378 // This is to be improved in the future and should reflect what software returns as a result of enumaration, but will require support from `USB` subsystem in Renode 379 USBConfiguration config = new USBConfiguration(this, 0, "").WithInterface( 380 configure: x => 381 x.WithEndpoint( 382 Direction.DeviceToHost, 383 EndpointTransferType.Control, 384 maximumPacketSize, 385 0x10, 386 out _) 387 .WithEndpoint( 388 Direction.DeviceToHost, 389 EndpointTransferType.Bulk, 390 maximumPacketSize, 391 0x10, 392 out deviceToHostEndpoint) 393 .WithEndpoint( 394 Direction.DeviceToHost, 395 EndpointTransferType.Bulk, 396 maximumPacketSize, 397 0x10, 398 out _) 399 .WithEndpoint( 400 Direction.DeviceToHost, 401 EndpointTransferType.Bulk, 402 maximumPacketSize, 403 0x10, 404 out _) 405 .WithEndpoint( 406 Direction.DeviceToHost, 407 EndpointTransferType.Bulk, 408 maximumPacketSize, 409 0x10, 410 out _) 411 .WithEndpoint( 412 Direction.DeviceToHost, 413 EndpointTransferType.Bulk, 414 maximumPacketSize, 415 0x10, 416 out _) 417 .WithEndpoint( 418 Direction.DeviceToHost, 419 EndpointTransferType.Bulk, 420 maximumPacketSize, 421 0x10, 422 out _) 423 .WithEndpoint( 424 Direction.DeviceToHost, 425 EndpointTransferType.Bulk, 426 maximumPacketSize, 427 0x10, 428 out _) 429 .WithEndpoint( 430 Direction.HostToDevice, 431 EndpointTransferType.Control, 432 maximumPacketSize, 433 0x10, 434 out _) 435 .WithEndpoint( 436 Direction.HostToDevice, 437 EndpointTransferType.Bulk, 438 maximumPacketSize, 439 0x10, 440 out _) 441 .WithEndpoint( 442 Direction.HostToDevice, 443 EndpointTransferType.Bulk, 444 maximumPacketSize, 445 0x10, 446 out _) 447 .WithEndpoint( 448 Direction.HostToDevice, 449 EndpointTransferType.Bulk, 450 maximumPacketSize, 451 0x10, 452 out _) 453 .WithEndpoint( 454 Direction.HostToDevice, 455 EndpointTransferType.Bulk, 456 maximumPacketSize, 457 0x10, 458 out _) 459 .WithEndpoint( 460 Direction.HostToDevice, 461 EndpointTransferType.Bulk, 462 maximumPacketSize, 463 0x10, 464 out _) 465 .WithEndpoint( 466 Direction.HostToDevice, 467 EndpointTransferType.Bulk, 468 maximumPacketSize, 469 0x10, 470 out _) 471 .WithEndpoint( 472 Direction.HostToDevice, 473 EndpointTransferType.Bulk, 474 maximumPacketSize, 475 0x10, 476 out _)); 477 USBCore.SelectedConfiguration = config; 478 } 479 480 DoubleWordRegisterCollection IProvidesRegisterCollection<DoubleWordRegisterCollection>.RegistersCollection => registers; 481 482 private USBEndpoint deviceToHostEndpoint; 483 private Action<byte[]> setupPacketResultCallback; 484 private readonly IMachine machine; 485 private readonly bool[] epInDataStatus; 486 private readonly bool[] epInStatus; 487 488 private readonly InterruptManager<Events> interruptManager; 489 private readonly IFlagRegisterField[] events; 490 491 private SetupPacket setupPacket; 492 493 private IValueRegisterField endpoint0In; 494 private IValueRegisterField endpoint0InCount; 495 private IValueRegisterField dataToggleEndpoint; 496 private IFlagRegisterField dataToggleInputOutput; 497 private IValueRegisterField dataToggleValue; 498 499 private IValueRegisterField usbAddress; 500 private IValueRegisterField epstallEndpoint; 501 private IFlagRegisterField epstallIO; 502 private IFlagRegisterField epstallStall; 503 504 private IFlagRegisterField usbPullup; 505 private IFlagRegisterField usbEnable; 506 private IFlagRegisterField ep0InEnabled; 507 private IFlagRegisterField ep0OutEnabled; 508 509 private readonly short maximumPacketSize; 510 private readonly DoubleWordRegisterCollection registers; 511 512 private const ushort EndpointCount = 8; 513 514 private enum Events 515 { 516 UsbReset = 0, 517 Started = 1, 518 EndEpIn0 = 2, 519 EndEpIn1 = 3, 520 EndEpIn2 = 4, 521 EndEpIn3 = 5, 522 EndEpIn4 = 6, 523 EndEpIn5 = 7, 524 EndEpIn6 = 8, 525 EndEpIn7 = 9, 526 Ep0DataDone = 10, 527 EndIsoIn = 11, 528 EndEpOut0 = 12, 529 EndEpOut1 = 13, 530 EndEpOut2 = 14, 531 EndEpOut3 = 15, 532 EndEpOut4 = 16, 533 EndEpOut5 = 17, 534 EndEpOut6 = 18, 535 EndEpOut7 = 19, 536 EndIsoOut = 20, 537 StartOfFrame = 21, 538 UsbEvent = 22, 539 Ep0Setup = 23, 540 EpData = 24 541 } 542 543 private enum Registers : long 544 { 545 TasksStartEpIn0 = 0x004, 546 TasksStartEpIn1 = 0x008, 547 TasksStartEpIn2 = 0x00C, 548 TasksStartEpIn3 = 0x010, 549 TasksStartEpIn4 = 0x014, 550 TasksStartEpIn5 = 0x018, 551 TasksStartEpIn6 = 0x01C, 552 TasksStartEpIn7 = 0x020, 553 TasksStartIsoIn = 0x024, 554 TasksStartEpOut0 = 0x028, 555 TasksStartEpOut1 = 0x02C, 556 TasksStartEpOut2 = 0x030, 557 TasksStartEpOut3 = 0x034, 558 TasksStartEpOut4 = 0x038, 559 TasksStartEpOut5 = 0x03C, 560 TasksStartEpOut6 = 0x040, 561 TasksStartEpOut7 = 0x044, 562 TasksStartIsoOut = 0x048, 563 TasksEp0RcvOut = 0x04C, 564 TasksEp0Status = 0x050, 565 TasksEp0Stall = 0x054, 566 TasksDPDMDrive = 0x058, 567 TasksDPDMNODrive = 0x05C, 568 EventsUsbReset = 0x100, 569 EventsStarted = 0x104, 570 EventsEndEpIn0 = 0x108, 571 EventsEndEpIn1 = 0x10C, 572 EventsEndEpIn2 = 0x110, 573 EventsEndEpIn3 = 0x114, 574 EventsEndEpIn4 = 0x118, 575 EventsEndEpIn5 = 0x11C, 576 EventsEndEpIn6 = 0x120, 577 EventsEndEpIn7 = 0x124, 578 EventsEp0DataDone = 0x128, 579 EventsEndIsoIn = 0x12C, 580 EventsEndEpOut0 = 0x130, 581 EventsEndEpOut1 = 0x134, 582 EventsEndEpOut2 = 0x138, 583 EventsEndEpOut3 = 0x13C, 584 EventsEndEpOut4 = 0x140, 585 EventsEndEpOut5 = 0x144, 586 EventsEndEpOut6 = 0x148, 587 EventsEndEpOut7 = 0x14C, 588 EventsEndIsoOut = 0x150, 589 EventsStartOfFrame = 0x154, 590 EventsUsbEvent = 0x158, 591 EventsEp0Setup = 0x15C, 592 EventsEpData = 0x160, 593 InterruptEnable = 0x300, 594 UsbPullup = 0x504, 595 DataToggle = 0x50C, 596 IsoSplit = 0x51C, 597 IsoInConfig = 0x530, 598 HaltedEndpointOut0 = 0x444, 599 EndpointStall = 0x518, 600 EventCause = 0x400, 601 EndpointStatus = 0x468, 602 EndpointDataStatus = 0x46c, 603 UsbAddress = 0x470, 604 bmRequestType = 0x480, 605 bRequest = 0x484, 606 wValueLow = 0x488, 607 wValueHigh = 0x48C, 608 wIndexLow = 0x490, 609 wIndexHigh = 0x494, 610 wLengthLow = 0x498, 611 wLengthHigh = 0x49C, 612 Enable = 0x500, 613 EndpointInEnable = 0x510, 614 EndpointOutEnable = 0x514, 615 Endpoint0In = 0x600, 616 Endpoint0InCount = 0x604, 617 Endpoint0InAmount = 0x608, 618 Endpoint1In = 0x614, 619 Endpoint1InCount = 0x618, 620 Endpoint2In = 0x628, 621 Endpoint2InCount = 0x62C, 622 Endpoint2Amount = 0x630, 623 Endpoint3In = 0x63C, 624 Endpoint3InCount = 0x640, 625 Endpoint4In = 0x650, 626 Endpoint4InCount = 0x654, 627 Endpoint5In = 0x664, 628 Endpoint5InCount = 0x668, 629 Endpoint6In = 0x678, 630 Endpoint6InCount = 0x67C, 631 Endpoint7In = 0x68C, 632 Endpoint7InCount = 0x690, 633 634 Endpoint0Out = 0x700, 635 Endpoint0OutCount = 0x704, 636 Endpoint0OutAmount = 0x708, 637 Endpoint1Out = 0x714, 638 Endpoint1OutCount = 0x718, 639 Endpoint2Out = 0x728, 640 Endpoint2OutCount = 0x72C, 641 } 642 } 643 } 644