From aa4c097728b2f60e296134d4a24e20dc34f63967 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Tue, 26 Sep 2023 15:42:54 +0200 Subject: [PATCH] uhd: rfnoc: rx radio: Add 'stream_cmd' message handler This allows sending stream commands to the RFNoC RX Radio block. Note that unlike the usrp_source, the RFNoC RX Radio block does not automatically initiate a stream, so this message port adds another option (besides calling issue_stream_cmd() directly) to start streaming in RFNoC-only flow graphs. Signed-off-by: Martin Braun --- gr-uhd/include/gnuradio/uhd/cmd_keys.h | 1 + gr-uhd/lib/rfnoc_rx_radio_impl.cc | 61 ++++++++++++++++++++++++++ gr-uhd/lib/rfnoc_rx_radio_impl.h | 3 ++ gr-uhd/lib/usrp_block_impl.cc | 6 +++ 4 files changed, 71 insertions(+) diff --git a/gr-uhd/include/gnuradio/uhd/cmd_keys.h b/gr-uhd/include/gnuradio/uhd/cmd_keys.h index d0b0d183574..729d3abb976 100644 --- a/gr-uhd/include/gnuradio/uhd/cmd_keys.h +++ b/gr-uhd/include/gnuradio/uhd/cmd_keys.h @@ -36,6 +36,7 @@ GR_UHD_API const pmt::pmt_t cmd_direction_key(); GR_UHD_API const pmt::pmt_t cmd_tag_key(); GR_UHD_API const pmt::pmt_t cmd_gpio_key(); GR_UHD_API const pmt::pmt_t cmd_pc_clock_resync_key(); +GR_UHD_API const pmt::pmt_t cmd_stream_cmd_key(); GR_UHD_API const pmt::pmt_t direction_rx(); GR_UHD_API const pmt::pmt_t direction_tx(); diff --git a/gr-uhd/lib/rfnoc_rx_radio_impl.cc b/gr-uhd/lib/rfnoc_rx_radio_impl.cc index 08a13db6941..52d88773c08 100644 --- a/gr-uhd/lib/rfnoc_rx_radio_impl.cc +++ b/gr-uhd/lib/rfnoc_rx_radio_impl.cc @@ -12,6 +12,7 @@ #include "rfnoc_rx_radio_impl.h" #include +#include namespace gr { namespace uhd { @@ -33,6 +34,14 @@ rfnoc_rx_radio::sptr rfnoc_rx_radio::make(rfnoc_graph::sptr graph, rfnoc_rx_radio_impl::rfnoc_rx_radio_impl(::uhd::rfnoc::noc_block_base::sptr block_ref) : rfnoc_block(block_ref), d_radio_ref(get_block_ref<::uhd::rfnoc::radio_control>()) { +#define REGISTER_CMD_HANDLER(key, _handler) \ + register_msg_cmd_handler( \ + key, [this](const pmt::pmt_t& var, int chan, const pmt::pmt_t& msg) { \ + this->_handler(var, chan, msg); \ + }) + // Register default command handlers: + REGISTER_CMD_HANDLER(pmt::symbol_to_string(cmd_stream_cmd_key()), + _cmd_handler_stream_cmd); } rfnoc_rx_radio_impl::~rfnoc_rx_radio_impl() {} @@ -148,5 +157,57 @@ void rfnoc_rx_radio_impl::enable_rx_timestamps(const bool enable, const size_t c return d_radio_ref->enable_rx_timestamps(enable, chan); } + +/****************************************************************************** + * Command handlers + *****************************************************************************/ +void rfnoc_rx_radio_impl::_cmd_handler_stream_cmd(const pmt::pmt_t& cmd_p, + int chan_i, + const pmt::pmt_t& msg) +{ + ::uhd::stream_cmd_t cmd(::uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + const std::string stream_mode_str = pmt::write_string( + pmt::dict_ref(cmd_p, pmt::mp("stream_mode"), pmt::mp("start_cont"))); + if (stream_mode_str == "start_cont") { + // All set already + } else if (stream_mode_str == "stop_cont") { + cmd.stream_mode = ::uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; + } else if (stream_mode_str == "num_done") { + cmd.stream_mode = ::uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE; + } else if (stream_mode_str == "num_more") { + cmd.stream_mode = ::uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE; + } else { + d_logger->warn("Invalid stream command in command message: {}", stream_mode_str); + return; + } + + cmd.stream_now = + pmt::to_bool(pmt::dict_ref(cmd_p, pmt::mp("stream_now"), pmt::mp(false))); + cmd.num_samps = pmt::to_long(pmt::dict_ref(cmd_p, pmt::mp("num_samps"), pmt::mp(0))); + + if (pmt::dict_has_key(cmd_p, cmd_time_key())) { + pmt::pmt_t timespec_p = pmt::dict_ref(msg, cmd_time_key(), pmt::PMT_NIL); + if (timespec_p == pmt::PMT_NIL) { + cmd.time_spec = ::uhd::time_spec_t(0.0); + } else { + ::uhd::time_spec_t timespec( + time_t(pmt::to_uint64(pmt::car(timespec_p))), // Full secs + pmt::to_double(pmt::cdr(timespec_p)) // Frac secs + ); + cmd.time_spec = timespec; + } + } else if (!cmd.stream_now) { + static const double reasonable_delay = 0.1; // s + cmd.time_spec = d_radio_ref->get_time_now() + reasonable_delay; + } + + d_logger->debug("Received command message: issue stream command ({})", + stream_mode_str); + + const size_t chan = (chan_i == -1) ? ALL_CHANS : static_cast(chan_i); + + issue_stream_cmd(cmd, chan); +} + } /* namespace uhd */ } /* namespace gr */ diff --git a/gr-uhd/lib/rfnoc_rx_radio_impl.h b/gr-uhd/lib/rfnoc_rx_radio_impl.h index dc08dd607c5..87110fc1444 100644 --- a/gr-uhd/lib/rfnoc_rx_radio_impl.h +++ b/gr-uhd/lib/rfnoc_rx_radio_impl.h @@ -49,6 +49,9 @@ class rfnoc_rx_radio_impl : public rfnoc_rx_radio void enable_rx_timestamps(const bool enable, const size_t chan) override; private: + // Default handlers + void _cmd_handler_stream_cmd(const pmt::pmt_t& cmd, int chan, const pmt::pmt_t& msg); + ::uhd::rfnoc::radio_control::sptr d_radio_ref; }; diff --git a/gr-uhd/lib/usrp_block_impl.cc b/gr-uhd/lib/usrp_block_impl.cc index 989363195ee..959702e6922 100644 --- a/gr-uhd/lib/usrp_block_impl.cc +++ b/gr-uhd/lib/usrp_block_impl.cc @@ -122,6 +122,12 @@ const pmt::pmt_t gr::uhd::cmd_gpio_key() return val; } +const pmt::pmt_t gr::uhd::cmd_stream_cmd_key() +{ + static const pmt::pmt_t val = pmt::mp("stream_cmd"); + return val; +} + const pmt::pmt_t gr::uhd::direction_rx() { static const pmt::pmt_t val = pmt::mp("RX");