diff options
| -rw-r--r-- | host/lib/transport/libusb1_zero_copy.cpp | 17 | ||||
| -rw-r--r-- | host/lib/transport/usb_zero_copy_wrapper.cpp | 100 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_impl.cpp | 5 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_impl.hpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_regs.hpp | 17 | ||||
| -rw-r--r-- | host/lib/usrp/b100/io_impl.cpp | 10 | ||||
| -rw-r--r-- | host/lib/usrp/e100/e100_impl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/e100/e100_impl.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/e100/e100_regs.hpp | 17 | ||||
| -rw-r--r-- | host/lib/usrp/e100/io_impl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/io_impl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.hpp | 2 | 
15 files changed, 105 insertions, 80 deletions
| diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 28d6cdd5b..3e67264cd 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -80,13 +80,14 @@ UHD_INLINE bool wait_for_completion(libusb_context *ctx, const double timeout, b   **********************************************************************/  class libusb_zero_copy_mrb : public managed_recv_buffer{  public: -    libusb_zero_copy_mrb(libusb_transfer *lut): +    libusb_zero_copy_mrb(libusb_transfer *lut, const size_t frame_size):          _ctx(libusb::session::get_global_session()->get_context()), -        _lut(lut), _expired(false) { /* NOP */ } +        _lut(lut), _expired(false), _frame_size(frame_size) { /* NOP */ }      void release(void){          if (_expired) return;          completed = false; +        _lut->length = _frame_size; //always reset length          UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);          _expired = true;      } @@ -109,6 +110,7 @@ private:      libusb_context *_ctx;      libusb_transfer *_lut;      bool _expired; +    const size_t _frame_size;  };  /*********************************************************************** @@ -118,9 +120,9 @@ private:   **********************************************************************/  class libusb_zero_copy_msb : public managed_send_buffer{  public: -    libusb_zero_copy_msb(libusb_transfer *lut): +    libusb_zero_copy_msb(libusb_transfer *lut, const size_t frame_size):          _ctx(libusb::session::get_global_session()->get_context()), -        _lut(lut), _expired(false) { /* NOP */ } +        _lut(lut), _expired(false), _frame_size(frame_size) { /* NOP */ }      void commit(size_t len){          if (_expired) return; @@ -144,11 +146,12 @@ public:  private:      void *get_buff(void) const{return _lut->buffer;} -    size_t get_size(void) const{return _lut->length;} +    size_t get_size(void) const{return _frame_size;}      libusb_context *_ctx;      libusb_transfer *_lut;      bool _expired; +    const size_t _frame_size;  };  /*********************************************************************** @@ -184,7 +187,7 @@ public:              libusb_transfer *lut = libusb_alloc_transfer(0);              UHD_ASSERT_THROW(lut != NULL); -            _mrb_pool.push_back(boost::shared_ptr<libusb_zero_copy_mrb>(new libusb_zero_copy_mrb(lut))); +            _mrb_pool.push_back(boost::shared_ptr<libusb_zero_copy_mrb>(new libusb_zero_copy_mrb(lut, this->get_recv_frame_size())));              libusb_fill_bulk_transfer(                  lut,                                                    // transfer @@ -207,7 +210,7 @@ public:              libusb_transfer *lut = libusb_alloc_transfer(0);              UHD_ASSERT_THROW(lut != NULL); -            _msb_pool.push_back(boost::shared_ptr<libusb_zero_copy_msb>(new libusb_zero_copy_msb(lut))); +            _msb_pool.push_back(boost::shared_ptr<libusb_zero_copy_msb>(new libusb_zero_copy_msb(lut, this->get_send_frame_size())));              libusb_fill_bulk_transfer(                  lut,                                                    // transfer diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp index 74f07f956..07105cad3 100644 --- a/host/lib/transport/usb_zero_copy_wrapper.cpp +++ b/host/lib/transport/usb_zero_copy_wrapper.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -18,17 +18,13 @@  #include <uhd/transport/usb_zero_copy.hpp>  #include <uhd/transport/bounded_buffer.hpp>  #include <uhd/transport/buffer_pool.hpp> +#include <uhd/utils/byteswap.hpp> +#include <uhd/utils/msg.hpp>  #include <boost/foreach.hpp>  #include <vector>  #include <iostream>  using namespace uhd::transport; -bool debug = true; - -static inline size_t next_boundary(size_t length, size_t boundary){ -    //pad to the boundary, assumes boundary is a power of 2 -    return (length + (boundary-1)) & ~(boundary-1); -}  /***********************************************************************   * USB zero copy wrapper - managed receive buffer @@ -45,7 +41,7 @@ public:          _mrb.reset();      } -    sptr get_new(managed_recv_buffer::sptr mrb, const void *mem, size_t len){ +    UHD_INLINE sptr get_new(managed_recv_buffer::sptr mrb, const void *mem, size_t len){          _mrb = mrb;          _mem = mem;          _len = len; @@ -67,28 +63,46 @@ private:   **********************************************************************/  class usb_zero_copy_wrapper_msb : public managed_send_buffer{  public: -    usb_zero_copy_wrapper_msb(bounded_buffer<usb_zero_copy_wrapper_msb *> &queue, size_t boundary): -        _queue(queue), _boundary(boundary){/*NOP*/} +    usb_zero_copy_wrapper_msb(const usb_zero_copy::sptr internal, const size_t fragmentation_size): +        _internal(internal), _fragmentation_size(fragmentation_size){/*NOP*/}      void commit(size_t len){ -        if (_msb.get() == NULL) return; -        _msb->commit(len); -        _queue.push_with_haste(this); -        _msb.reset(); +        if (len == 0) return; + +        //get a reference to the VITA header before incrementing +        const boost::uint32_t vita_header = reinterpret_cast<const boost::uint32_t *>(_mem_buffer_tip)[0]; + +        _bytes_in_buffer += len; +        _mem_buffer_tip += len; + +        //extract VITA end of packet flag, we must force flush under eof conditions +        const bool eop = (uhd::wtohx(vita_header) & (0x1 << 24)) != 0; +        const bool full = _bytes_in_buffer >= (_last_send_buff->size() - _fragmentation_size); +        if (eop or full){ +            _last_send_buff->commit(_bytes_in_buffer); +            _last_send_buff.reset(); +        }      } -    sptr get_new(managed_send_buffer::sptr msb){ -        _msb = msb; +    UHD_INLINE sptr get_new(const double timeout){ +        if (not _last_send_buff){ +            _last_send_buff = _internal->get_send_buff(timeout); +            if (not _last_send_buff) return sptr(); +            _mem_buffer_tip = _last_send_buff->cast<char *>(); +            _bytes_in_buffer = 0; +        }          return make_managed_buffer(this);      }  private: -    void *get_buff(void) const{return _msb->cast<void *>();} -    size_t get_size(void) const{return _msb->size();} - -    bounded_buffer<usb_zero_copy_wrapper_msb *> &_queue; -    size_t _boundary; -    managed_send_buffer::sptr _msb; +    void *get_buff(void) const{return reinterpret_cast<void *>(_mem_buffer_tip);} +    size_t get_size(void) const{return _fragmentation_size;} + +    usb_zero_copy::sptr _internal; +    const size_t _fragmentation_size; +    managed_send_buffer::sptr _last_send_buff; +    size_t _bytes_in_buffer; +    char *_mem_buffer_tip;  };  /*********************************************************************** @@ -96,23 +110,15 @@ private:   **********************************************************************/  class usb_zero_copy_wrapper : public usb_zero_copy{  public: -    usb_zero_copy_wrapper( -        sptr usb_zc, size_t usb_frame_boundary -    ): +    usb_zero_copy_wrapper(sptr usb_zc, const size_t frame_boundary):          _internal_zc(usb_zc), -        _usb_frame_boundary(usb_frame_boundary),          _available_recv_buffs(this->get_num_recv_frames()), -        _available_send_buffs(this->get_num_send_frames()),          _mrb_pool(this->get_num_recv_frames(), usb_zero_copy_wrapper_mrb(_available_recv_buffs)), -        _msb_pool(this->get_num_send_frames(), usb_zero_copy_wrapper_msb(_available_send_buffs, usb_frame_boundary)) +        _the_only_msb(usb_zero_copy_wrapper_msb(usb_zc, frame_boundary))      {          BOOST_FOREACH(usb_zero_copy_wrapper_mrb &mrb, _mrb_pool){              _available_recv_buffs.push_with_haste(&mrb);          } - -        BOOST_FOREACH(usb_zero_copy_wrapper_msb &msb, _msb_pool){ -            _available_send_buffs.push_with_haste(&msb); -        }      }      managed_recv_buffer::sptr get_recv_buff(double timeout){ @@ -128,18 +134,17 @@ public:              //extract this packet's memory address and length in bytes              const char *mem = _last_recv_buff->cast<const char *>() + _last_recv_offset;              const boost::uint32_t *mem32 = reinterpret_cast<const boost::uint32_t *>(mem); -            size_t len = (mem32[0] & 0xffff)*sizeof(boost::uint32_t); //length in bytes (from VRT header) -             +            const size_t len = (uhd::wtohx(mem32[0]) & 0xffff)*sizeof(boost::uint32_t); //length in bytes (from VRT header) +              managed_recv_buffer::sptr recv_buff; //the buffer to be returned to the user -                          recv_buff = wmrb->get_new(_last_recv_buff, mem, len); -            _last_recv_offset = next_boundary(_last_recv_offset + len, 4); -             +            _last_recv_offset += len; +              //check if this receive buffer has been exhausted              if (_last_recv_offset >= _last_recv_buff->size()) {                  _last_recv_buff.reset();              } -             +              return recv_buff;          } @@ -156,16 +161,7 @@ public:      }      managed_send_buffer::sptr get_send_buff(double timeout){ -        managed_send_buffer::sptr send_buff = _internal_zc->get_send_buff(timeout); -         -        //attempt to get a wrapper for a managed send buffer -        usb_zero_copy_wrapper_msb *wmsb = NULL; -        if (send_buff.get() and _available_send_buffs.pop_with_haste(wmsb)){ -            return wmsb->get_new(send_buff); -        } - -        //otherwise return a null sptr for failure -        return managed_send_buffer::sptr(); +        return _the_only_msb.get_new(timeout);      }      size_t get_num_send_frames(void) const{ @@ -178,15 +174,13 @@ public:  private:      sptr _internal_zc; -    size_t _usb_frame_boundary;      bounded_buffer<usb_zero_copy_wrapper_mrb *> _available_recv_buffs; -    bounded_buffer<usb_zero_copy_wrapper_msb *> _available_send_buffs;      std::vector<usb_zero_copy_wrapper_mrb> _mrb_pool; -    std::vector<usb_zero_copy_wrapper_msb> _msb_pool; -     +    usb_zero_copy_wrapper_msb _the_only_msb; +      //buffer to store partially-received VRT packets in      buffer_pool::sptr _fragment_mem; -     +      //state for last recv buffer to create multiple managed buffers      managed_recv_buffer::sptr _last_recv_buff;      size_t _last_recv_offset; diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 87aee9568..455efa2fe 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -229,7 +229,8 @@ b100_impl::b100_impl(const device_addr_t &device_addr){              2, 6,          // IN interface, endpoint              1, 2,          // OUT interface, endpoint              data_xport_args    // param hints -        ) +        ), +        B100_MAX_PKT_BYTE_LIMIT      );      //////////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 433f45aef..49a3139f0 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -52,6 +52,7 @@ static const boost::uint16_t B100_FPGA_COMPAT_NUM = 0x09;  static const boost::uint32_t B100_RX_SID_BASE = 2;  static const boost::uint32_t B100_TX_ASYNC_SID = 1;  static const double          B100_DEFAULT_TICK_RATE = 64e6; +static const size_t          B100_MAX_PKT_BYTE_LIMIT = 2048;  //! Make a b100 dboard interface  uhd::usrp::dboard_iface::sptr make_b100_dboard_iface( diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp index b625e65a5..b87a0ad73 100644 --- a/host/lib/usrp/b100/b100_regs.hpp +++ b/host/lib/usrp/b100/b100_regs.hpp @@ -1,4 +1,19 @@ - +// +// Copyright 2010-2012 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +//  ////////////////////////////////////////////////////////////////  // diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index 7c07c6349..b1a44d70e 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -211,7 +211,7 @@ rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t &args_){          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used      ; -    const size_t bpp = 2048 - hdr_size; //limited by FPGA pkt buffer size +    const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size;      const size_t bpi = convert::get_bytes_per_item(args.otw_format);      const size_t spp = unsigned(args.args.cast<double>("spp", bpp/bpi)); @@ -260,10 +260,6 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){      args.otw_format = args.otw_format.empty()? "sc16" : args.otw_format;      args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; -    if (args.otw_format == "sc8"){ -        throw uhd::value_error("USRP TX requested wire format not implemented in FPGA: " + args.otw_format); -    } -      //calculate packet size      static const size_t hdr_size = 0          + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) @@ -271,7 +267,7 @@ tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t &args_){          - sizeof(vrt::if_packet_info_t().sid) //no stream id ever used          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used      ; -    static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; +    static const size_t bpp = B100_MAX_PKT_BYTE_LIMIT - hdr_size;      const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format);      //make the new streamer given the samples per packet diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index cd6143a16..8ab6ab533 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by diff --git a/host/lib/usrp/e100/e100_impl.hpp b/host/lib/usrp/e100/e100_impl.hpp index e641aeea9..1d36cb2ac 100644 --- a/host/lib/usrp/e100/e100_impl.hpp +++ b/host/lib/usrp/e100/e100_impl.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by diff --git a/host/lib/usrp/e100/e100_regs.hpp b/host/lib/usrp/e100/e100_regs.hpp index 265086540..eee27b5b3 100644 --- a/host/lib/usrp/e100/e100_regs.hpp +++ b/host/lib/usrp/e100/e100_regs.hpp @@ -1,4 +1,19 @@ - +// +// Copyright 2010-2012 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +//  ////////////////////////////////////////////////////////////////  // diff --git a/host/lib/usrp/e100/io_impl.cpp b/host/lib/usrp/e100/io_impl.cpp index 2b64e7f17..4d530585b 100644 --- a/host/lib/usrp/e100/io_impl.cpp +++ b/host/lib/usrp/e100/io_impl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index e9d9b65c2..f3cad188a 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 9b6c1c2f0..f19f49e28 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 206016972..7101e040a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index c060f75b5..882a61f80 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 8f714cbbc..5d39e527d 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by | 
