Beispiel #1
0
    static void usbDump(int numPackets)
    {
        // Packets are saved during the collapsing process
        PacketQueue pktQ = new PacketQueue();

        // Info for the packet that was just read
        PacketInfo curPacket;

        // Collapsing counts and time collapsing started
        CollapseInfo collapseInfo = new CollapseInfo();

        CollapseState state = CollapseState.IDLE;
        bool          reRun = false;

        byte pid          = 0;
        int  signalErrors = 0;
        int  packetnum    = 0;

        samplerateKHz = BeagleApi.bg_samplerate(beagle, 0);

        int idle_samples = IDLE_THRESHOLD * samplerateKHz;

        // Configure Beagle 480 for realtime capture
        BeagleApi.bg_usb480_capture_configure(beagle,
                                              BeagleUsb480CaptureMode.BG_USB480_CAPTURE_REALTIME,
                                              BeagleUsb2TargetSpeed.BG_USB2_AUTO_SPEED_DETECT);

        // Filter packets intended for the Beagle analyzer. This is only
        // relevant when one host controller is being used.
        BeagleApi.bg_usb480_hw_filter_config(beagle,
                                             BeagleApi.BG_USB2_HW_FILTER_SELF);

        // Start the capture
        if (BeagleApi.bg_enable(beagle, BeagleProtocol.BG_PROTOCOL_USB) !=
            (int)BeagleStatus.BG_OK)
        {
            Console.Write("error: could not enable USB capture; exiting...\n");
            Environment.Exit(1);
        }

        // Output the header...
        Console.Write("index,time(ns),USB,status,pid,data0 ... dataN(*)\n");
        Console.Out.Flush();

        // ...then start decoding packets
        while (packetnum < numPackets || (numPackets == 0))
        {
            curPacket = pktQ.getTail();

            curPacket.length = BeagleApi.bg_usb480_read(
                beagle,
                ref curPacket.status,
                ref curPacket.events,
                ref curPacket.timeSop,
                ref curPacket.timeDuration,
                ref curPacket.timeDataOffset,
                1024,
                curPacket.data);

            curPacket.timeSopNS =
                timestampToNS(curPacket.timeSop, samplerateKHz);

            // Exit if observed end of capture
            if ((curPacket.status &
                 BeagleApi.BG_READ_USB_END_OF_CAPTURE) != 0)
            {
                usbPrintSummaryPacket(ref packetnum, collapseInfo,
                                      ref signalErrors);
                break;
            }

            // Check for invalid packet or Beagle error
            if (curPacket.length < 0)
            {
                String errorStatus = "";
                errorStatus += String.Format("error={0:d}", curPacket.length);
                usbPrintPacket(packetnum, curPacket, errorStatus);
                break;
            }

            // Check for USB error
            if (curPacket.status == BeagleApi.BG_READ_USB_ERR_BAD_SIGNALS)
            {
                ++signalErrors;
            }

            // Set the PID for collapsing state machine below.  Treat
            // KEEP_ALIVEs as packets.
            if (curPacket.length > 0)
            {
                pid = curPacket.data[0];
            }
            else if ((curPacket.events &
                      BeagleApi.BG_EVENT_USB_KEEP_ALIVE) != 0 &&
                     (curPacket.status &
                      BeagleApi.BG_READ_USB_ERR_BAD_PID) == 0)
            {
                pid = (byte)PacketGroup.KEEP_ALIVE;
            }
            else
            {
                pid = 0;
            }

            // Collapse these packets approprietly:
            // KEEP_ALIVE* SOF* (IN (ACK|NAK))* (PING NAK)*
            // (SPLIT (OUT|SETUP) NYET)* (SPLIT IN (ACK|NYET|NACK))*

            // If the time elapsed since collapsing began is greater than
            // the threshold, output the counts and zero out the counters.
            if (curPacket.timeSop - collapseInfo.timeSop >=
                (ulong)idle_samples)
            {
                usbPrintSummaryPacket(ref packetnum, collapseInfo,
                                      ref signalErrors);
            }

            while (true)
            {
                reRun = false;
                switch (state)
                {
                // The initial state of the state machine.  Collapse SOFs
                // and KEEP_ALIVEs.  Save IN, PING, or SPLIT packets and
                // move to the next state for the next packet.  Otherwise,
                // print the collapsed packet counts and the current
                // packet.
                case CollapseState.IDLE:
                    switch (pid)
                    {
                    case (byte)PacketGroup.KEEP_ALIVE:
                        collapse(PacketGroup.KEEP_ALIVE, collapseInfo, pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_SOF:
                        collapse(PacketGroup.SOF, collapseInfo, pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_IN:
                        pktQ.savePacket();
                        state = CollapseState.IN;
                        break;

                    case BeagleApi.BG_USB_PID_PING:
                        pktQ.savePacket();
                        state = CollapseState.PING;
                        break;

                    case BeagleApi.BG_USB_PID_SPLIT:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT;
                        break;

                    default:
                        usbPrintSummaryPacket(ref packetnum, collapseInfo,
                                              ref signalErrors);

                        if (curPacket.length > 0 || curPacket.events != 0 ||
                            (curPacket.status != 0 &&
                             curPacket.status != BeagleApi.BG_READ_TIMEOUT))
                        {
                            usbPrintPacket(packetnum, curPacket, null);
                            packetnum++;
                        }
                        break;
                    }
                    break;

                // Collapsing IN+ACK or IN+NAK.  Otherwise, output any
                // saved packets and rerun the collapsing state machine
                // on the current packet.
                case CollapseState.IN:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_ACK:
                        collapse(PacketGroup.IN_ACK, collapseInfo, pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_NAK:
                        collapse(PacketGroup.IN_NAK, collapseInfo, pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing PING+NAK
                case CollapseState.PING:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NAK:
                        collapse(PacketGroup.PING_NAK, collapseInfo, pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Expecting an IN, OUT, or SETUP
                case CollapseState.SPLIT:
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_IN:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT_IN;
                        break;

                    case BeagleApi.BG_USB_PID_OUT:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT_OUT;
                        break;

                    case BeagleApi.BG_USB_PID_SETUP:
                        pktQ.savePacket();
                        state = CollapseState.SPLIT_SETUP;
                        break;

                    default:
                        state = CollapseState.IDLE;
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing SPLIT+IN+NYET, SPLIT+IN+NAK, SPLIT+IN+ACK
                case CollapseState.SPLIT_IN:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NYET:
                        collapse(PacketGroup.SPLIT_IN_NYET, collapseInfo,
                                 pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_NAK:
                        collapse(PacketGroup.SPLIT_IN_NAK, collapseInfo,
                                 pktQ);
                        break;

                    case BeagleApi.BG_USB_PID_ACK:
                        collapse(PacketGroup.SPLIT_IN_ACK, collapseInfo,
                                 pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing SPLIT+OUT+NYET
                case CollapseState.SPLIT_OUT:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NYET:
                        collapse(PacketGroup.SPLIT_OUT_NYET, collapseInfo,
                                 pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;

                // Collapsing SPLIT+SETUP+NYET
                case CollapseState.SPLIT_SETUP:
                    state = CollapseState.IDLE;
                    switch (pid)
                    {
                    case BeagleApi.BG_USB_PID_NYET:
                        collapse(PacketGroup.SPLIT_SETUP_NYET, collapseInfo,
                                 pktQ);
                        break;

                    default:
                        reRun = true;
                        break;
                    }
                    break;
                }

                if (reRun == false)
                {
                    break;
                }

                // The state machine is about to be re-run.  This
                // means that a complete packet sequence wasn't collapsed
                // and there are packets in the queue that need to be
                // output before we can process the current packet.
                outputSaved(ref packetnum, ref signalErrors,
                            collapseInfo, pktQ);
            }
        }

        // Stop the capture
        BeagleApi.bg_disable(beagle);
    }
Beispiel #2
0
    static void usbDump(int numPackets, int timeoutMS)
    {
        long start, elapsedTime;

        // Set up variables
        byte[] packet    = new byte[1024];
        int    packetnum = 0;

        samplerateKhz = BeagleApi.bg_samplerate(beagle, 0);

        // Configure Beagle 480 for delayed-download capture
        BeagleApi.bg_usb480_capture_configure(beagle,
                                              BeagleUsb480CaptureMode.BG_USB480_CAPTURE_DELAYED_DOWNLOAD,
                                              BeagleUsb2TargetSpeed.BG_USB2_AUTO_SPEED_DETECT);

        // Enable the hardware filtering.  This will filter out packets with
        // the same device address as the Beagle analyzer and also filter
        // the PID packet groups listed below.
        BeagleApi.bg_usb480_hw_filter_config(beagle,
                                             BeagleApi.BG_USB2_HW_FILTER_SELF |
                                             BeagleApi.BG_USB2_HW_FILTER_PID_SOF |
                                             BeagleApi.BG_USB2_HW_FILTER_PID_IN |
                                             BeagleApi.BG_USB2_HW_FILTER_PID_PING |
                                             BeagleApi.BG_USB2_HW_FILTER_PID_PRE |
                                             BeagleApi.BG_USB2_HW_FILTER_PID_SPLIT);

        // Start the capture portion of the delayed-download capture
        if (BeagleApi.bg_enable(beagle, BeagleProtocol.BG_PROTOCOL_USB) !=
            (int)BeagleStatus.BG_OK)
        {
            Console.Write("error: could not enable USB capture; exiting...\n");
            Environment.Exit(1);
        }

        // Wait until timeout period elapses or the hardware buffer on
        // the Beagle USB 480 fills
        Console.Write("Hardware buffer usage:\n");
        start = timeMicroseconds();

        while (true)
        {
            uint bufferSize  = 0;
            uint bufferUsage = 0;
            byte bufferFull  = 0;

            // Poll the hardware buffer status
            BeagleApi.bg_usb480_hw_buffer_stats(beagle, ref bufferSize,
                                                ref bufferUsage,
                                                ref bufferFull);

            // Print out the progress
            elapsedTime = (timeMicroseconds() - start) / 1000;

            printProgress(bufferUsage / (bufferSize / 100),
                          ((double)elapsedTime) / 1000,
                          bufferUsage, bufferSize);

            // If timed out or buffer is full, exit loop
            if (bufferFull != 0 ||
                (timeoutMS != 0 && elapsedTime > timeoutMS))
            {
                break;
            }

            // Sleep for 150 milliseconds
            BeagleApi.bg_sleep_ms(150);
        }

        // Start the download portion of the delayed-download capture
        //
        // Output the header...
        Console.Write("\nindex,time(ns),USB,status,pid,data0 ... dataN(*)\n");
        Console.Out.Flush();

        // ...then start decoding packets
        while (packetnum < numPackets || (numPackets == 0))
        {
            uint  status         = 0;
            uint  events         = 0;
            ulong timeSop        = 0;
            ulong timeSopNS      = 0;
            ulong timeDuration   = 0;
            uint  timeDataOffset = 0;

            // Calling bg_usb480_read will automatically stop the
            // capture portion of the delayed-download capture and
            // will begin downloading the capture results.
            int length = BeagleApi.bg_usb480_read(
                beagle, ref status, ref events,
                ref timeSop, ref timeDuration,
                ref timeDataOffset, 1024, packet);

            timeSopNS = TIMESTAMP_TO_NS(timeSop, samplerateKhz);

            // Check for invalid packet or Beagle error
            if (length < 0)
            {
                String errorStatus = "";
                errorStatus += String.Format("error={0:d}", length);
                usbPrintPacket(packetnum, timeSopNS, status, events,
                               errorStatus, null);
                break;
            }

            // Output the current transaction
            if (length > 0 || events != 0 ||
                (status != 0 && status != BeagleApi.BG_READ_TIMEOUT))
            {
                String packetData = usbPrintDataPacket(ref packet,
                                                       length);
                usbPrintPacket(packetnum, timeSopNS, status,
                               events, null, packetData);
                ++packetnum;
            }

            // Exit if observe end of capture
            if ((status & BeagleApi.BG_READ_USB_END_OF_CAPTURE) != 0)
            {
                break;
            }
        }

        // Stop the capture
        BeagleApi.bg_disable(beagle);
    }