public ArduinoLoader(CortexM cpu, ulong binaryLoadAddress = 0x10000) { USBEndpoint interruptEndpoint = null; this.cpu = cpu; this.machine = cpu.GetMachine(); this.binaryLoadAddress = binaryLoadAddress; USBCore = new USBDeviceCore(this, classCode: USBClassCode.CommunicationsCDCControl, maximalPacketSize: PacketSize.Size16, vendorId: 0x2341, productId: 0x805a, deviceReleaseNumber: 0x0100) .WithConfiguration(configure: c => c .WithInterface(new Antmicro.Renode.Core.USB.CDC.Interface(this, identifier: 0, subClassCode: 0x2, protocol: 0x1, descriptors: new [] { new FunctionalDescriptor(CdcFunctionalDescriptorType.Interface, CdcFunctionalDescriptorSubtype.Header, 0x10, 0x01), new FunctionalDescriptor(CdcFunctionalDescriptorType.Interface, CdcFunctionalDescriptorSubtype.CallManagement, 0x01, 0x01), new FunctionalDescriptor(CdcFunctionalDescriptorType.Interface, CdcFunctionalDescriptorSubtype.AbstractControlManagement, 0x02), new FunctionalDescriptor(CdcFunctionalDescriptorType.Interface, CdcFunctionalDescriptorSubtype.Union, 0x00, 0x01) }) .WithEndpoint(Direction.DeviceToHost, EndpointTransferType.Interrupt, maximumPacketSize: 0x08, interval: 0x0a, createdEndpoint: out interruptEndpoint)) .WithInterface(new USBInterface(this, identifier: 1, classCode: USBClassCode.CDCData, subClassCode: 0x0, protocol: 0x0) .WithEndpoint(id: 2, direction: Direction.HostToDevice, transferType: EndpointTransferType.Bulk, maximumPacketSize: 0x20, interval: 0x0, createdEndpoint: out hostToDeviceEndpoint) .WithEndpoint(id: 3, direction: Direction.DeviceToHost, transferType: EndpointTransferType.Bulk, maximumPacketSize: 0x20, interval: 0x0, createdEndpoint: out deviceToHostEndpoint))); // when asked, say that nothing interesting happened interruptEndpoint.NonBlocking = true; deviceToHostEndpoint.NonBlocking = true; hostToDeviceEndpoint.DataWritten += HandleData; sramBuffer = new byte[BufferSize]; flashBuffer = new byte[BufferSize]; binarySync = new AutoResetEvent(false); }
private void HandleBulkOut(USBEndpoint endpoint) { if (endpoint != null) { if (sendByteCount.Value != sendQueue.Count) { this.Log(LogLevel.Warning, "Requested to send BULK out {0} bytes of data, but there are {1} bytes in the queue.", sendByteCount.Value, sendQueue.Count); } var bytesToSend = sendQueue.DequeueRange((int)sendByteCount.Value); this.Log(LogLevel.Noisy, "Writing {0} bytes to the device", bytesToSend.Length); endpoint.WriteData(bytesToSend); sendDataBufferAvailableInterruptRequest.Value = true; } hostTransferDoneInterruptRequest.Value = true; UpdateInterrupts(); }
private void HandleBulkIn(USBEndpoint endpoint) { if (endpoint != null) { this.Log(LogLevel.Noisy, "Initiated read from the device"); endpoint.SetDataReadCallbackOneShot((_, data) => { this.Log(LogLevel.Noisy, "Received data from the device"); #if DEBUG_PACKETS this.Log(LogLevel.Noisy, Misc.PrettyPrintCollectionHex(data)); #endif EnqueueReceiveData(data); hostTransferDoneInterruptRequest.Value = true; UpdateInterrupts(); }); } else { hostTransferDoneInterruptRequest.Value = true; UpdateInterrupts(); } }
private void HandleHostTransfer(uint ep, bool setup, bool outnin, bool hs) { if (setup && hs) { this.Log(LogLevel.Error, "Both SETUP and HS bits set for a host transfer - ignoring it!"); return; } var device = this.ChildCollection.Values.FirstOrDefault(x => x.USBCore.Address == deviceAddress.Value); if (device == null) { this.Log(LogLevel.Warning, "Tried to send setup packet to a device with address 0x{0:X}, but it's not connected", deviceAddress.Value); // setting the IRQ is necessary to allow communication right after the usb device address has changed hostTransferDoneInterruptRequest.Value = true; UpdateInterrupts(); return; } if (setup) { this.Log(LogLevel.Noisy, "Setup TX"); if (ep != 0) { this.Log(LogLevel.Error, "This model does not support SETUP packets on EP different than 0"); return; } HandleSetup(device); } else if (hs) { this.Log(LogLevel.Noisy, "Handshake {0}", outnin ? "out" : "in"); hostTransferDoneInterruptRequest.Value = true; UpdateInterrupts(); } else { USBEndpoint endpoint = null; if (ep != 0) { endpoint = device.USBCore.GetEndpoint((int)ep); if (endpoint == null) { this.Log(LogLevel.Error, "Tried to access a non-existing EP #{0}", ep); hostTransferDoneInterruptRequest.Value = true; UpdateInterrupts(); return; } } if (outnin) { this.Log(LogLevel.Noisy, "Bulk out"); HandleBulkOut(endpoint); } else { this.Log(LogLevel.Noisy, "Bulk in"); HandleBulkIn(endpoint); } } }