diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/convert/convert_impl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_impl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/b100/b100_impl.hpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_impl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_impl.hpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/multi_usrp.cpp | 41 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.hpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 9 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_impl.hpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_io_impl.cpp | 35 | 
12 files changed, 85 insertions, 16 deletions
| diff --git a/host/lib/convert/convert_impl.cpp b/host/lib/convert/convert_impl.cpp index dc7f8f9dc..c7907ed83 100644 --- a/host/lib/convert/convert_impl.cpp +++ b/host/lib/convert/convert_impl.cpp @@ -134,6 +134,7 @@ UHD_STATIC_BLOCK(convert_register_item_sizes){      convert::register_bytes_per_item("sc64", sizeof(std::complex<boost::int64_t>));      convert::register_bytes_per_item("sc32", sizeof(std::complex<boost::int32_t>));      convert::register_bytes_per_item("sc16", sizeof(std::complex<boost::int16_t>)); +    convert::register_bytes_per_item("sc12", 3 * sizeof(std::complex<boost::int8_t>));      convert::register_bytes_per_item("sc8", sizeof(std::complex<boost::int8_t>));      //register standard real types diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index a47856b07..cb32a596c 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -515,6 +515,7 @@ b100_impl::b100_impl(const device_addr_t &device_addr){      _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/tx_frontends").at(0)));      _tree->access<std::string>(mb_path / "clock_source/value").set("internal");      _tree->access<std::string>(mb_path / "time_source/value").set("none"); +    _tree->create<double>(mb_path / "link_max_rate").set(B100_MAX_RATE_USB2);  }  b100_impl::~b100_impl(void){ diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index 7d71d5ec3..b6752681e 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -54,6 +54,7 @@ static const boost::uint32_t B100_CTRL_MSG_SID = 20;  static const double          B100_DEFAULT_TICK_RATE = 64e6;  static const size_t          B100_MAX_PKT_BYTE_LIMIT = 2048;  static const std::string     B100_EEPROM_MAP_KEY = "B100"; +static const size_t          B100_MAX_RATE_USB2  =  32000000; // bytes/s  #define I2C_ADDR_TX_A       (I2C_DEV_EEPROM | 0x4)  #define I2C_ADDR_RX_A       (I2C_DEV_EEPROM | 0x5) diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index 9dd3a424d..84310a9fe 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -250,6 +250,7 @@ b200_impl::b200_impl(const device_addr_t &device_addr)          ctrl_xport_args      );      while (_ctrl_transport->get_recv_buff(0.0)){} //flush ctrl xport +    _tree->create<double>(mb_path / "link_max_rate").set((usb_speed == 3) ? B200_MAX_RATE_USB3 : B200_MAX_RATE_USB2);      ////////////////////////////////////////////////////////////////////      // Async task structure diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp index 7d98a8f8d..c3508c550 100644 --- a/host/lib/usrp/b200/b200_impl.hpp +++ b/host/lib/usrp/b200/b200_impl.hpp @@ -47,11 +47,13 @@  static const boost::uint8_t  B200_FW_COMPAT_NUM_MAJOR = 0x04;  static const boost::uint8_t  B200_FW_COMPAT_NUM_MINOR = 0x00;  static const boost::uint16_t B200_FPGA_COMPAT_NUM = 0x03; -static const double          B200_LINK_RATE_BPS = (5e9)/8; //practical link rate (5 Gbps)  static const double          B200_BUS_CLOCK_RATE = 100e6;  static const double          B200_DEFAULT_TICK_RATE = 32e6;  static const boost::uint32_t B200_GPSDO_ST_NONE = 0x83; +static const size_t B200_MAX_RATE_USB2              =  32000000; // bytes/s +static const size_t B200_MAX_RATE_USB3              = 500000000; // bytes/s +  #define FLIP_SID(sid) (((sid)<<16)|((sid)>>16))  static const boost::uint32_t B200_CTRL0_MSG_SID = 0x00000010; diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index f08709669..4883b2410 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -24,6 +24,7 @@  #include <uhd/usrp/dboard_id.hpp>  #include <uhd/usrp/mboard_eeprom.hpp>  #include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/convert.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/thread.hpp>  #include <boost/foreach.hpp> @@ -103,6 +104,8 @@ static meta_range_t make_overall_tune_range(      return range;  } + +  /***********************************************************************   * Gain helper functions   **********************************************************************/ @@ -589,6 +592,11 @@ public:      /*******************************************************************       * RX methods       ******************************************************************/ +    rx_streamer::sptr get_rx_stream(const stream_args_t &args) { +        _check_link_rate(args, false); +        return this->get_device()->get_rx_stream(args); +    } +      void set_rx_subdev_spec(const subdev_spec_t &spec, size_t mboard){          if (mboard != ALL_MBOARDS){              _tree->access<subdev_spec_t>(mb_root(mboard) / "rx_subdev_spec").set(spec); @@ -770,6 +778,11 @@ public:      /*******************************************************************       * TX methods       ******************************************************************/ +    tx_streamer::sptr get_tx_stream(const stream_args_t &args) { +        _check_link_rate(args, true); +        return this->get_device()->get_tx_stream(args); +    } +      void set_tx_subdev_spec(const subdev_spec_t &spec, size_t mboard){          if (mboard != ALL_MBOARDS){              _tree->access<subdev_spec_t>(mb_root(mboard) / "tx_subdev_spec").set(spec); @@ -1178,6 +1191,34 @@ private:          }          return gg;      } + +    //! \param is_tx True for tx +    // Assumption is that all mboards use the same link +    bool _check_link_rate(const stream_args_t &args, bool is_tx) { +        bool link_rate_is_ok = true; +        size_t bytes_per_sample = convert::get_bytes_per_item(args.otw_format); +        double max_link_rate = 0; +        double sum_rate = 0; +        BOOST_FOREACH(const size_t chan, args.channels) { +            mboard_chan_pair mcp = is_tx ? tx_chan_to_mcp(chan) : rx_chan_to_mcp(chan); +            if (_tree->exists(mb_root(mcp.mboard) / "link_max_rate")) { +                max_link_rate = std::max( +                    max_link_rate, +                   _tree->access<double>(mb_root(mcp.mboard) / "link_max_rate").get() +                ); +            } +            sum_rate += is_tx ? get_tx_rate(chan) : get_rx_rate(chan); +        } +        if (max_link_rate > 0 and (max_link_rate / bytes_per_sample) < sum_rate) { +            UHD_MSG(warning) << boost::format( +                "The total sum of rates (%f MSps on %u channels) exceeds the maximum capacity of the connection.\n" +                "This can cause %s." +            ) % (sum_rate/1e6) % args.channels.size() % (is_tx ? "underruns (U)" : "overflows (O)")  << std::endl; +            link_rate_is_ok = false; +        } + +        return link_rate_is_ok; +    }  };  /*********************************************************************** diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 3b902b343..3eaac9839 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -409,7 +409,7 @@ usrp1_impl::usrp1_impl(const device_addr_t &device_addr){          _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(_rx_subdev_spec);      if (_tree->list(mb_path / "tx_dsps").size() > 0)          _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(_tx_subdev_spec); - +    _tree->create<double>(mb_path / "link_max_rate").set(USRP1_MAX_RATE_USB2);  }  usrp1_impl::~usrp1_impl(void){ diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp index da9fe8b16..012bc0794 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.hpp +++ b/host/lib/usrp/usrp1/usrp1_impl.hpp @@ -39,6 +39,7 @@  #define INCLUDED_USRP1_IMPL_HPP  static const std::string USRP1_EEPROM_MAP_KEY = "B000"; +static const size_t      USRP1_MAX_RATE_USB2  =  32000000; // bytes/s  #define FR_RB_CAPS          3  #define FR_MODE             13 diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 16d9b9a54..25f661656 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -442,6 +442,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){              _mbc[mb].spiface = _mbc[mb].iface;              break;          } +        _tree->create<double>(mb_path / "link_max_rate").set(USRP2_LINK_RATE_BPS);          ////////////////////////////////////////////////////////////////          // setup the mboard eeprom diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index e492b2238..f5e53678c 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -392,6 +392,8 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)          //Tell the quirks object which FIFOs carry TX stream data          const uint32_t tx_data_fifos[2] = {X300_RADIO_DEST_PREFIX_TX, X300_RADIO_DEST_PREFIX_TX + 3};          mb.rio_fpga_interface->get_kernel_proxy().get_rio_quirks().register_tx_streams(tx_data_fifos); + +        _tree->create<double>(mb_path / "link_max_rate").set(X300_MAX_RATE_PCIE);      }      BOOST_FOREACH(const std::string &key, dev_addr.keys()) @@ -456,6 +458,8 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)                  << "UHD will use the auto-detected max frame size for this connection."                  << std::endl;          } + +        _tree->create<double>(mb_path / "link_max_rate").set(X300_MAX_RATE_10GIGE);      }      //create basic communication @@ -1133,11 +1137,14 @@ x300_impl::both_xports_t x300_impl::make_transport(          if (mb.loaded_fpga_image == "HGS") {              if (mb.router_dst_here == X300_XB_DST_E0) {                  eth_data_rec_frame_size = X300_1GE_DATA_FRAME_MAX_SIZE; +                _tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_1GIGE);              } else if (mb.router_dst_here == X300_XB_DST_E1) {                  eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE; +                _tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE);              }          } else if (mb.loaded_fpga_image == "XGS") { -                eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE; +            eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE; +            _tree->access<double>("/mboards/"+boost::lexical_cast<std::string>(mb_index) / "link_max_rate").set(X300_MAX_RATE_10GIGE);          }          if (eth_data_rec_frame_size == 0) { diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 692427f31..4b3efc845 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -85,6 +85,10 @@ static const size_t X300_RX_MAX_HDR_LEN             =           // bytes      + sizeof(uhd::transport::vrt::if_packet_info_t().sid)  // SID      + sizeof(uhd::transport::vrt::if_packet_info_t().tsf); // Timestamp +static const size_t X300_MAX_RATE_PCIE              = 800000000; // bytes/s +static const size_t X300_MAX_RATE_10GIGE            = 800000000; // bytes/s +static const size_t X300_MAX_RATE_1GIGE             = 100000000; // bytes/s +  #define X300_RADIO_DEST_PREFIX_TX 0  #define X300_RADIO_DEST_PREFIX_CTRL 1  #define X300_RADIO_DEST_PREFIX_RX 2 diff --git a/host/lib/usrp/x300/x300_io_impl.cpp b/host/lib/usrp/x300/x300_io_impl.cpp index 09ed1d705..9263c9b44 100644 --- a/host/lib/usrp/x300/x300_io_impl.cpp +++ b/host/lib/usrp/x300/x300_io_impl.cpp @@ -242,6 +242,8 @@ struct x300_tx_fc_guts_t      boost::shared_ptr<x300_impl::async_md_type> old_async_queue;  }; +#define X300_ASYNC_EVENT_CODE_FLOW_CTRL 0 +  static size_t get_tx_flow_control_window(size_t frame_size, const device_addr_t& tx_args)  {      double hw_buff_size = tx_args.cast<double>("send_buff_size", X300_TX_HW_BUFF_SIZE); @@ -283,23 +285,28 @@ static void handle_tx_async_msgs(boost::shared_ptr<x300_tx_fc_guts_t> guts, zero          return;      } -    //catch the flow control packets and react -    if (endian_conv(packet_buff[if_packet_info.num_header_words32+0]) == 0) -    { -        const size_t seq = endian_conv(packet_buff[if_packet_info.num_header_words32+1]); -        guts->seq_queue.push_with_haste(seq); -        return; -    } -      //fill in the async metadata      async_metadata_t metadata;      load_metadata_from_buff(          endian_conv, metadata, if_packet_info, packet_buff,          clock->get_master_clock_rate(), guts->stream_channel); -    guts->async_queue->push_with_pop_on_full(metadata); -    metadata.channel = guts->device_channel; -    guts->old_async_queue->push_with_pop_on_full(metadata); -    standard_async_msg_prints(metadata); + +    //The FC response and the burst ack are two indicators that the radio +    //consumed packets. Use them to update the FC metadata +    if (metadata.event_code == X300_ASYNC_EVENT_CODE_FLOW_CTRL or +        metadata.event_code == async_metadata_t::EVENT_CODE_BURST_ACK +    ) { +        const size_t seq = metadata.user_payload[0]; +        guts->seq_queue.push_with_pop_on_full(seq); +    } + +    //FC responses don't propagate up to the user so filter them here +    if (metadata.event_code != X300_ASYNC_EVENT_CODE_FLOW_CTRL) { +        guts->async_queue->push_with_pop_on_full(metadata); +        metadata.channel = guts->device_channel; +        guts->old_async_queue->push_with_pop_on_full(metadata); +        standard_async_msg_prints(metadata); +    }  }  static managed_send_buffer::sptr get_tx_buff_with_flowctrl( @@ -319,7 +326,9 @@ static managed_send_buffer::sptr get_tx_buff_with_flowctrl(      }      managed_send_buffer::sptr buff = xport->get_send_buff(timeout); -    if (buff) guts->last_seq_out++; //update seq, this will actually be a send +    if (buff) { +        guts->last_seq_out++; //update seq, this will actually be a send +    }      return buff;  } | 
