Пример #1
0
        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);
        }
Пример #2
0
        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();
        }
Пример #3
0
        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();
            }
        }
Пример #4
0
        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);
                }
            }
        }