aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/b200/CMakeLists.txt2
-rw-r--r--host/lib/usrp/e300/e300_impl.hpp2
-rw-r--r--host/lib/usrp/e300/e300_io_impl.cpp48
3 files changed, 43 insertions, 9 deletions
diff --git a/host/lib/usrp/b200/CMakeLists.txt b/host/lib/usrp/b200/CMakeLists.txt
index a08c4bd03..ce89b5d80 100644
--- a/host/lib/usrp/b200/CMakeLists.txt
+++ b/host/lib/usrp/b200/CMakeLists.txt
@@ -20,7 +20,7 @@
########################################################################
########################################################################
-# Conditionally configure the B100 support
+# Conditionally configure the B200 support
########################################################################
LIBUHD_REGISTER_COMPONENT("B200" ENABLE_B200 ON "ENABLE_LIBUHD;ENABLE_USB" OFF)
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp
index a4170ee42..c7d683f58 100644
--- a/host/lib/usrp/e300/e300_impl.hpp
+++ b/host/lib/usrp/e300/e300_impl.hpp
@@ -70,6 +70,8 @@ static std::string E300_SERVER_I2C_PORT = "21761";
static std::string E300_SERVER_SENSOR_PORT = "21762";
static const double E300_RX_SW_BUFF_FULLNESS = 0.9; //Buffer should be half full
+static const size_t E300_RX_FC_REQUEST_FREQ = 32; // per flow ctrl window
+static const size_t E300_TX_FC_RESPONSE_FREQ = 8; // per flow ctrl window
// crossbar settings
static const boost::uint8_t E300_RADIO_DEST_PREFIX_TX = 0;
diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp
index dcb6f2afe..fa4915ed1 100644
--- a/host/lib/usrp/e300/e300_io_impl.cpp
+++ b/host/lib/usrp/e300/e300_io_impl.cpp
@@ -25,6 +25,7 @@
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/bind.hpp>
#include <uhd/utils/tasks.hpp>
+#include <uhd/utils/log.hpp>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
@@ -226,6 +227,18 @@ void e300_impl::_handle_overflow(
}
}
+static size_t get_rx_flow_control_window(size_t frame_size, size_t sw_buff_size, double fullness_factor)
+{
+ if (fullness_factor < 0.01 || fullness_factor > 1) {
+ throw uhd::value_error("recv_buff_fullness must be between 0.01 and 1 inclusive (1% to 100%)");
+ }
+
+ size_t window_in_pkts = (static_cast<size_t>(sw_buff_size * fullness_factor) / frame_size);
+ if (window_in_pkts == 0) {
+ throw uhd::value_error("recv_buff_size must be larger than the recv_frame_size.");
+ }
+ return window_in_pkts;
+}
static void handle_rx_flowctrl(
const boost::uint32_t sid,
@@ -457,25 +470,38 @@ rx_streamer::sptr e300_impl::get_rx_stream(const uhd::stream_args_t &args_)
id.num_outputs = 1;
my_streamer->set_converter(id);
+ perif.framer->clear();
perif.framer->set_nsamps_per_packet(spp); //seems to be a good place to set this
perif.framer->set_sid((data_sid << 16) | (data_sid >> 16));
perif.framer->setup(args);
perif.ddc->setup(args);
+
+ // flow control setup
+ const size_t frame_size = data_xports.recv->get_recv_frame_size();
+ const size_t num_frames = data_xports.recv->get_num_recv_frames();
+ const size_t fc_window = get_rx_flow_control_window(
+ frame_size,num_frames * frame_size,
+ E300_RX_SW_BUFF_FULLNESS);
+ const size_t fc_handle_window = std::max<size_t>(1, fc_window / E300_RX_FC_REQUEST_FREQ);
+
+ UHD_LOG << "RX Flow Control Window = " << fc_window
+ << ", RX Flow Control Handler Window = "
+ << fc_handle_window << std::endl;
+
+ perif.framer->configure_flow_control(fc_window);
+ boost::shared_ptr<e300_rx_fc_cache_t> fc_cache(new e300_rx_fc_cache_t());
+
my_streamer->set_xport_chan_get_buff(stream_i, boost::bind(
&zero_copy_if::get_recv_buff, data_xports.recv, _1
), true /*flush*/);
my_streamer->set_overflow_handler(stream_i,
- boost::bind(&rx_vita_core_3000::handle_overflow, perif.framer)
+ boost::bind(&e300_impl::_handle_overflow, this, boost::ref(perif),
+ boost::weak_ptr<uhd::rx_streamer>(my_streamer))
);
- //setup flow control
- const size_t fc_window = data_xports.recv->get_num_recv_frames();
- perif.framer->configure_flow_control(fc_window);
- boost::shared_ptr<e300_rx_fc_cache_t> fc_cache(new e300_rx_fc_cache_t());
my_streamer->set_xport_handle_flowctrl(stream_i,
boost::bind(&handle_rx_flowctrl, data_sid, data_xports.send, fc_cache, _1),
- static_cast<size_t>(static_cast<double>(fc_window) * E300_RX_SW_BUFF_FULLNESS),
- true/*init*/);
+ fc_handle_window, true/*init*/);
my_streamer->set_issue_stream_cmd(stream_i,
boost::bind(&rx_vita_core_3000::issue_stream_command, perif.framer, _1)
@@ -564,7 +590,13 @@ tx_streamer::sptr e300_impl::get_tx_stream(const uhd::stream_args_t &args_)
//flow control setup
const size_t fc_window = data_xports.send->get_num_send_frames();
- perif.deframer->configure_flow_control(0/*cycs off*/, fc_window/8/*pkts*/);
+ const size_t fc_handle_window = std::max<size_t>(1, fc_window/E300_TX_FC_RESPONSE_FREQ);
+
+ UHD_LOG << "TX Flow Control Window = " << fc_window
+ << ", TX Flow Control Handler Window = "
+ << fc_handle_window << std::endl;
+
+ perif.deframer->configure_flow_control(0/*cycs off*/, fc_handle_window/*pkts*/);
boost::shared_ptr<e300_tx_fc_cache_t> fc_cache(new e300_tx_fc_cache_t());
fc_cache->stream_channel = stream_i;
fc_cache->device_channel = args.channels[stream_i];