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