diff options
Diffstat (limited to 'host/lib/rfnoc/radio_control_impl.cpp')
-rw-r--r-- | host/lib/rfnoc/radio_control_impl.cpp | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/host/lib/rfnoc/radio_control_impl.cpp b/host/lib/rfnoc/radio_control_impl.cpp index 018f54d9e..4ed0c4b60 100644 --- a/host/lib/rfnoc/radio_control_impl.cpp +++ b/host/lib/rfnoc/radio_control_impl.cpp @@ -74,6 +74,7 @@ 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, @@ -99,7 +100,8 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args) "Received stream command: " << stream_cmd_action->stream_cmd.stream_mode << " to " << src.to_string()); if (src.type != res_source_info::OUTPUT_EDGE) { - RFNOC_LOG_WARNING("Received stream command, but not to output port! Ignoring."); + RFNOC_LOG_WARNING( + "Received stream command, but not to output port! Ignoring."); return; } const size_t port = src.instance; @@ -108,6 +110,36 @@ 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*/) { + RFNOC_LOG_TRACE("Received restart request command to " << src.to_string()); + if (src.type != res_source_info::OUTPUT_EDGE) { + RFNOC_LOG_WARNING( + "Received stream command, but not to output port! Ignoring."); + return; + } + 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; + const size_t port = src.instance; + if (port > get_num_output_ports()) { + RFNOC_LOG_WARNING("Received stream command to invalid output port!"); + return; + } + post_action({res_source_info::OUTPUT_EDGE, port}, stream_cmd_action); }); // Register spp properties and resolvers _spp_prop.reserve(get_num_output_ports()); @@ -827,6 +859,11 @@ void radio_control_impl::async_message_handler( } switch (addr_base + addr_offset) { case regmap::SWREG_TX_ERR: { + if (chan > get_num_input_ports()) { + RFNOC_LOG_WARNING( + "Cannot process TX-related async message to invalid chan " << chan); + return; + } switch (code) { case err_codes::ERR_TX_UNDERRUN: UHD_LOG_FASTPATH("U"); @@ -838,11 +875,20 @@ void radio_control_impl::async_message_handler( break; } case regmap::SWREG_RX_ERR: { + if (chan > get_num_input_ports()) { + RFNOC_LOG_WARNING( + "Cannot process RX-related async message to invalid chan " << chan); + return; + } switch (code) { case err_codes::ERR_RX_OVERRUN: { UHD_LOG_FASTPATH("O"); auto rx_event_action = rx_event_action_info::make(); 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}, rx_event_action); |