diff options
author | Moritz Fischer <moritz.fischer@ettus.com> | 2015-02-23 13:30:17 -0800 |
---|---|---|
committer | Ashish Chaudhari <ashish@ettus.com> | 2015-02-26 13:40:16 -0800 |
commit | 78be3d548be78ffd871a0563499a6df0bfdf14b4 (patch) | |
tree | 4bd9956811fb41cc3617396be7fefa37570165fc | |
parent | 64bad562c25a93540effb78e4289cf90df4898af (diff) | |
download | uhd-78be3d548be78ffd871a0563499a6df0bfdf14b4.tar.gz uhd-78be3d548be78ffd871a0563499a6df0bfdf14b4.tar.bz2 uhd-78be3d548be78ffd871a0563499a6df0bfdf14b4.zip |
e300: fc: This should fix the RX flow control.
Two issues:
- Call the correct overflow handler e300_impl vs rx_vita
- Don't lie about buffer sizes and window sizes
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
-rw-r--r-- | host/lib/usrp/e300/e300_impl.hpp | 1 | ||||
-rw-r--r-- | host/lib/usrp/e300/e300_io_impl.cpp | 40 |
2 files changed, 34 insertions, 7 deletions
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp index a4170ee42..59e0d59ce 100644 --- a/host/lib/usrp/e300/e300_impl.hpp +++ b/host/lib/usrp/e300/e300_impl.hpp @@ -70,6 +70,7 @@ 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 // 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..a1d0a8da1 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) |