discuss-gnuradio
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]