Beispiel #1
0
    static void usbDump(int numPackets)
    {
        // Set up variables
        byte[] packet = new byte[1024];

        int timingSize =
            BeagleApi.bg_bit_timing_size(BeagleProtocol.BG_PROTOCOL_USB, 1024);

        uint[] timing = new uint[timingSize];

        byte[] savedIn       = new byte[64];
        uint[] savedInTiming = new uint[8 * 64];
        ulong  savedInSop    = 0;
        int    savedInLength = 0;
        uint   savedInStatus = 0;
        uint   savedInEvents = 0;

        ulong countSop   = 0;
        int   sofCount   = 0;
        int   preCount   = 0;
        int   inAckCount = 0;
        int   inNakCount = 0;

        byte pid        = 0;
        int  syncErrors = 0;
        int  packetnum  = 0;

        samplerateKhz = BeagleApi.bg_samplerate(beagle, 0);

        int idleSamples = IDLE_THRESHOLD * samplerateKhz;

        // Open the connection to the Beagle.  Default to port 0.
        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))
        {
            uint  status         = 0;
            uint  events         = 0;
            ulong timeSop        = 0;
            ulong timeSopNS      = 0;
            ulong timeDuration   = 0;
            uint  timeDataOffset = 0;

            int length = BeagleApi.bg_usb12_read_bit_timing(
                beagle, ref status, ref events, ref timeSop,
                ref timeDuration, ref timeDataOffset,
                1024, packet, timingSize, timing);

            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;
            }

            // Check for USB error
            if (status == BeagleApi.BG_READ_USB_ERR_BAD_SYNC)
            {
                ++syncErrors;
            }

            if (length > 0)
            {
                pid = packet[0];
            }
            else
            {
                pid = 0;
            }

            // Check the PID and collapse appropriately:
            // SOF* PRE* (IN (ACK|NAK))*
            // If we have saved summary information, and we have
            // hit an error, received a non-summary packet, or
            // have exceeded the idle time, then dump out the
            // summary information before continuing
            if (status != BeagleApi.BG_READ_OK || usbTrigger(pid) ||
                ((int)(timeSop - countSop) >= idleSamples))
            {
                int offset =
                    usbPrintSummaryPacket(packetnum, countSop,
                                          sofCount, preCount, inAckCount,
                                          inNakCount, syncErrors);

                sofCount   = 0;
                preCount   = 0;
                inAckCount = 0;
                inNakCount = 0;
                syncErrors = 0;
                countSop   = timeSop;

                // Adjust the packet index if any events were printed by
                // usbPrintSummaryPacket.
                packetnum += offset;
            }

            // Now handle the current packet based on its packet ID
            switch (pid)
            {
            case BeagleApi.BG_USB_PID_SOF:
                // Increment the SOF counter
                ++sofCount;
                break;

            case BeagleApi.BG_USB_PID_PRE:
                // Increment the PRE counter
                ++preCount;
                break;

            case BeagleApi.BG_USB_PID_IN:
                // If the transaction is an IN, don't display it yet and
                // save the transaction.
                // If the following transaction is an ACK or NAK,
                // increment the appropriate IN/ACK or IN/NAK counter.
                // If the next transaction is not an ACK or NAK,
                // display the saved IN transaction .
                System.Array.Copy(packet, 0, savedIn, 0, length);
                System.Array.Copy(timing, 0, savedInTiming, 0, length * 8);

                savedInSop    = timeSop;
                savedInLength = length;
                savedInStatus = status;
                savedInEvents = events;
                break;

            case BeagleApi.BG_USB_PID_NAK:
                goto case BeagleApi.BG_USB_PID_ACK;

            case BeagleApi.BG_USB_PID_ACK:
                // If the last transaction was IN, increment the appropriate
                // counter and don't display the transaction.
                if (savedInLength > 0)
                {
                    savedInLength = 0;

                    if (pid == BeagleApi.BG_USB_PID_ACK)
                    {
                        ++inAckCount;
                    }
                    else
                    {
                        ++inNakCount;
                    }

                    break;
                }
                goto default;

            default:
                // If the last transaction was IN, output it
                if (savedInLength > 0)
                {
                    ulong saved_in_sop_ns =
                        TIMESTAMP_TO_NS(savedInSop, samplerateKhz);

                    String packetData = usbPrintDataPacket
                                            (ref savedIn,
                                            savedInLength);
                    usbPrintPacket(packetnum, saved_in_sop_ns, savedInStatus,
                                   savedInEvents, null, packetData);
                    ++packetnum;

                    savedInLength = 0;
                }

                // 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;
                }
                countSop = timeSop + timeDuration;
                break;
            }
        }

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