[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Discuss-gnuradio] USB speed data point
From: |
Eric Blossom |
Subject: |
Re: [Discuss-gnuradio] USB speed data point |
Date: |
Fri, 27 Oct 2006 10:40:12 -0700 |
User-agent: |
Mutt/1.5.9i |
On Fri, Oct 27, 2006 at 09:40:06AM -0700, address@hidden wrote:
> Hi -
>
> I'm bringing up a board
> http://recycle.lbl.gov/llrf4/
> with a hardware and software USB stack based on and (for this purpose)
> equivalent to the GNU Radio design, and measured its USB data transfer
> capabilities more carefully than I have done before. There is a
> distant possibility someone on this list might make use of the result,
> so here it is:
>
> Reading only, on a lightly loaded AMD64 3500+ machine (2.2 GHz,
> dual-channel RAM), I can sustain 35.7 MByte/sec without errors.
> Attempting 35.8 MByte/sec, packets get dropped left and right.
> The host end of the USB is a VT8237 Chipset, seemingly run in
> EHCI mode by Linux-2.6.16 (Debian sid 2.6.16-2-amd64-k8).
>
> I think the limitation is on the 8051 end.
I concur (recalling measurements made a long time ago).
As I recall, the limiting factor is the time to get through the main
loop in the FX2. I believe that without much trouble you could cut
the time to 1/2 of what it currently is.
E.g., there's a check in the loop that's always true and thus could be
removed. Also, the loop body could be recoded in assembler. See
FIXME's below
> One 512-byte packet takes
> 8.53 microseconds to cross the USB channel, and the 35.7 MByte/sec
> sustained rate implies the 8051 sets up the next packet in only 5.81
> microseconds. I don't think there is any pipelining at this level.
>
> - Larry
static void
main_loop (void)
{
setup_flowstate_common ();
while (!(GPIFTRIG & bmGPIF_IDLE)) // FIXME add this code to ensure loop
invariant
;
while (1){
if (usb_setup_packet_avail ())
usb_handle_setup_packet ();
if (GPIFTRIG & bmGPIF_IDLE){ // FIXME This is always true, remove the test
// OK, GPIF is idle. Let's try to give it some work.
// First check for underruns and overruns
if (UC_BOARD_HAS_FPGA && (USRP_PA & (bmPA_TX_UNDERRUN |
bmPA_RX_OVERRUN))){
// record the under/over run
if (USRP_PA & bmPA_TX_UNDERRUN)
g_tx_underrun = 1;
if (USRP_PA & bmPA_RX_OVERRUN)
g_rx_overrun = 1;
// tell the FPGA to clear the flags
fpga_clear_flags ();
}
// Next see if there are any "OUT" packets waiting for our attention,
// and if so, if there's room in the FPGA's FIFO for them.
if (g_tx_enable && !(EP24FIFOFLGS & 0x02)){ // USB end point fifo is not
empty...
if (fpga_has_room_for_packet ()){ // ... and FPGA has room for
packet
GPIFTCB1 = 0x01; SYNCDELAY;
GPIFTCB0 = 0x00; SYNCDELAY;
setup_flowstate_write ();
SYNCDELAY;
GPIFTRIG = bmGPIF_EP2_START | bmGPIF_WRITE; // start the xfer
SYNCDELAY;
while (!(GPIFTRIG & bmGPIF_IDLE)){
// wait for the transaction to complete
}
}
}
// See if there are any requests for "IN" packets, and if so
// whether the FPGA's got any packets for us.
if (g_rx_enable && !(EP6CS & bmEPFULL)){ // USB end point fifo is not
full...
if (fpga_has_packet_avail ()){ // ... and FPGA has packet
available
GPIFTCB1 = 0x01; SYNCDELAY;
GPIFTCB0 = 0x00; SYNCDELAY;
setup_flowstate_read ();
SYNCDELAY;
GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer
SYNCDELAY;
while (!(GPIFTRIG & bmGPIF_IDLE)){
// wait for the transaction to complete
}
SYNCDELAY;
INPKTEND = 6; // tell USB we filled buffer (6 is our endpoint num)
}
}
}
}
}
Eric