aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/rfnoc
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/rfnoc')
-rw-r--r--host/lib/rfnoc/radio_control_impl.cpp22
-rw-r--r--host/lib/rfnoc/rfnoc_rx_streamer.cpp49
2 files changed, 28 insertions, 43 deletions
diff --git a/host/lib/rfnoc/radio_control_impl.cpp b/host/lib/rfnoc/radio_control_impl.cpp
index 9d7257108..e400033b3 100644
--- a/host/lib/rfnoc/radio_control_impl.cpp
+++ b/host/lib/rfnoc/radio_control_impl.cpp
@@ -6,6 +6,7 @@
#include <uhd/exception.hpp>
#include <uhd/utils/log.hpp>
+#include <uhd/rfnoc/mb_controller.hpp>
#include <uhdlib/rfnoc/radio_control_impl.hpp>
#include <uhdlib/utils/compat_check.hpp>
#include <map>
@@ -63,6 +64,8 @@ const uint32_t radio_control_impl::regmap::RX_CMD_TIMED_POS;
const uhd::fs_path radio_control_impl::DB_PATH("dboard");
const uhd::fs_path radio_control_impl::FE_PATH("frontends");
+static constexpr double OVERRUN_RESTART_DELAY = 0.05;
+
/****************************************************************************
* Structors
***************************************************************************/
@@ -74,7 +77,6 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args)
, _spc(_radio_width & 0xFFFF)
, _last_stream_cmd(
get_num_output_ports(), uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS)
- , _restart_cont(get_num_output_ports(), false)
{
uhd::assert_fpga_compat(MAJOR_COMPAT,
MINOR_COMPAT,
@@ -110,16 +112,6 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args)
return;
}
issue_stream_cmd(stream_cmd_action->stream_cmd, port);
- if (stream_cmd_action->stream_cmd.stream_mode
- == uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS
- && _restart_cont.at(port)) {
- RFNOC_LOG_TRACE("Received stop command after reporting overrun, will now "
- "request restart.");
- _restart_cont[port] = false;
- auto restart_request_action =
- action_info::make(ACTION_KEY_RX_RESTART_REQ);
- post_action({res_source_info::OUTPUT_EDGE, port}, restart_request_action);
- }
});
register_action_handler(ACTION_KEY_RX_RESTART_REQ,
[this](const res_source_info& src, action_info::sptr /*action*/) {
@@ -131,9 +123,10 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args)
}
auto stream_cmd_action = stream_cmd_action_info::make(
uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
- // FIXME
- // stream_cmd_action->stream_cmd.stream_now = false;
- // stream_cmd_action->stream_cmd.time_spec = get_time_now() + DELTA;
+ stream_cmd_action->stream_cmd.stream_now = false;
+ stream_cmd_action->stream_cmd.time_spec =
+ get_mb_controller()->get_timekeeper(0)->get_time_now() +
+ uhd::time_spec_t(OVERRUN_RESTART_DELAY);
const size_t port = src.instance;
if (port > get_num_output_ports()) {
RFNOC_LOG_WARNING("Received stream command to invalid output port!");
@@ -962,7 +955,6 @@ void radio_control_impl::async_message_handler(
rx_event_action->error_code = uhd::rx_metadata_t::ERROR_CODE_OVERFLOW;
const bool cont_mode = _last_stream_cmd.at(chan).stream_mode
== stream_cmd_t::STREAM_MODE_START_CONTINUOUS;
- _restart_cont[chan] = cont_mode;
rx_event_action->args["cont_mode"] = std::to_string(cont_mode);
RFNOC_LOG_TRACE("Posting overrun event action message.");
post_action(res_source_info{res_source_info::OUTPUT_EDGE, chan},
diff --git a/host/lib/rfnoc/rfnoc_rx_streamer.cpp b/host/lib/rfnoc/rfnoc_rx_streamer.cpp
index cfa88b292..b50e2fe15 100644
--- a/host/lib/rfnoc/rfnoc_rx_streamer.cpp
+++ b/host/lib/rfnoc/rfnoc_rx_streamer.cpp
@@ -18,16 +18,18 @@ using namespace uhd::rfnoc;
const std::string STREAMER_ID = "RxStreamer";
static std::atomic<uint64_t> streamer_inst_ctr;
-rfnoc_rx_streamer::rfnoc_rx_streamer(const size_t num_chans,
- const uhd::stream_args_t stream_args)
+rfnoc_rx_streamer::rfnoc_rx_streamer(
+ const size_t num_chans, const uhd::stream_args_t stream_args)
: rx_streamer_impl<chdr_rx_data_xport>(num_chans, stream_args)
, _unique_id(STREAMER_ID + "#" + std::to_string(streamer_inst_ctr++))
, _stream_args(stream_args)
{
+ set_overrun_handler([this]() { this->_handle_overrun(); });
+
// No block to which to forward properties or actions
set_prop_forwarding_policy(forwarding_policy_t::DROP);
set_action_forwarding_policy(forwarding_policy_t::DROP);
- //
+
register_action_handler(ACTION_KEY_RX_EVENT,
[this](const res_source_info& src, action_info::sptr action) {
rx_event_action_info::sptr rx_event_action =
@@ -38,10 +40,6 @@ rfnoc_rx_streamer::rfnoc_rx_streamer(const size_t num_chans,
}
_handle_rx_event_action(src, rx_event_action);
});
- register_action_handler(ACTION_KEY_RX_RESTART_REQ,
- [this](const res_source_info& src, action_info::sptr action) {
- _handle_restart_request(src, action);
- });
register_action_handler(ACTION_KEY_STREAM_CMD,
[this](const res_source_info& src, action_info::sptr action) {
stream_cmd_action_info::sptr stream_cmd_action =
@@ -117,6 +115,15 @@ bool rfnoc_rx_streamer::check_topology(
return node_t::check_topology(connected_inputs, connected_outputs);
}
+void rfnoc_rx_streamer::_handle_overrun()
+{
+ if (_overrun_handling_mode) {
+ RFNOC_LOG_TRACE("Requesting restart from overrun-reporting node...");
+ post_action({res_source_info::INPUT_EDGE, _overrun_channel},
+ action_info::make(ACTION_KEY_RX_RESTART_REQ));
+ }
+}
+
void rfnoc_rx_streamer::_register_props(const size_t chan,
const std::string& otw_format)
{
@@ -178,6 +185,7 @@ void rfnoc_rx_streamer::_handle_rx_event_action(
RFNOC_LOG_TRACE("Ignoring duplicate overrun message.");
return;
}
+ _overrun_channel = src.instance;
RFNOC_LOG_TRACE(
"Switching to overrun-handling mode: Stopping all upstream producers...");
auto stop_action =
@@ -188,32 +196,17 @@ void rfnoc_rx_streamer::_handle_rx_event_action(
post_action({res_source_info::INPUT_EDGE, i}, stop_action);
}
if (!rx_event_action->args.cast<bool>("cont_mode", false)) {
- // FIXME wait until it's safe to restart radios
- // If we don't need to restart, that's all we need to do
+ // If we don't need to restart, that's all we need to do. Clear this
+ // flag before setting the stopped due to overrun status below to
+ // avoid a potential race condition with the overrun handler.
_overrun_handling_mode = false;
}
+ // Tell the streamer to flag an overrun to the user after the data that
+ // was buffered prior to the overrun is read.
+ set_stopped_due_to_overrun();
}
}
-void rfnoc_rx_streamer::_handle_restart_request(
- const res_source_info& src, action_info::sptr)
-{
- // FIXME: Now we need to wait until it's safe to restart the radios.
- // A flush would achieve this, albeit at the cost of possibly losing
- // samples.
- // The earliest we can restart is when the FIFOs in upstream producers
- // are empty.
- RFNOC_LOG_TRACE("Waiting for FIFOs to clear");
-
- std::this_thread::sleep_for(100ms);
-
- // Once it's safe to restart the radios, we ask a radio to send us a
- // stream command with its current time.
- RFNOC_LOG_TRACE("Requesting restart from overrun-reporting node...");
- post_action({res_source_info::INPUT_EDGE, src.instance},
- action_info::make(ACTION_KEY_RX_RESTART_REQ));
-}
-
void rfnoc_rx_streamer::_handle_stream_cmd_action(
const res_source_info& src, stream_cmd_action_info::sptr stream_cmd_action)
{