diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-08-01 14:51:31 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 11:49:34 -0800 |
commit | 1e51dd7774017cbad84315284596417636ab044d (patch) | |
tree | 689d32b7b55e51c26871ef1ae9364cf00dba4bc0 | |
parent | b89c53c0691c6d70fb24561243a930bbcc32363b (diff) | |
download | uhd-1e51dd7774017cbad84315284596417636ab044d.tar.gz uhd-1e51dd7774017cbad84315284596417636ab044d.tar.bz2 uhd-1e51dd7774017cbad84315284596417636ab044d.zip |
rfnoc: radio: Add async message validation
This adds a method to the radio to check if an async message is valid,
which can be used to ack async messages immediately.
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp | 5 | ||||
-rw-r--r-- | host/lib/rfnoc/radio_control_impl.cpp | 48 |
2 files changed, 53 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp index fc90035f7..5440c1e37 100644 --- a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp +++ b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp @@ -278,6 +278,11 @@ protected: std::vector<property_t<double>> _samp_rate_out; private: + //! Validator for the async messages + // + // We only know about overruns, underruns, and late commands/packets. + bool async_message_validator(uint32_t addr, const std::vector<uint32_t>& data); + //! Receiver for the async messages // // This block will receive all async messages. The following async messages diff --git a/host/lib/rfnoc/radio_control_impl.cpp b/host/lib/rfnoc/radio_control_impl.cpp index 9648b5dbf..2094f4096 100644 --- a/host/lib/rfnoc/radio_control_impl.cpp +++ b/host/lib/rfnoc/radio_control_impl.cpp @@ -250,6 +250,10 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args) regmap::SWREG_RX_ERR + regmap::SWREG_CHAN_OFFSET * rx_chan); } // Now register a function to receive the async messages + regs().register_async_msg_validator( + [this](uint32_t addr, const std::vector<uint32_t>& data) { + return this->async_message_validator(addr, data); + }); regs().register_async_msg_handler([this](uint32_t addr, const std::vector<uint32_t>& data, boost::optional<uint64_t> timestamp) { @@ -838,6 +842,50 @@ void radio_control_impl::issue_stream_cmd( /****************************************************************************** * Private methods *****************************************************************************/ +bool radio_control_impl::async_message_validator( + uint32_t addr, const std::vector<uint32_t>& data) +{ + if (data.empty()) { + return false; + } + // For these calculations, see below + const uint32_t addr_base = (addr >= regmap::SWREG_RX_ERR) ? regmap::SWREG_RX_ERR + : regmap::SWREG_TX_ERR; + const uint32_t chan = (addr - addr_base) / regmap::SWREG_CHAN_OFFSET; + const uint32_t addr_offset = addr % regmap::SWREG_CHAN_OFFSET; + const uint32_t code = data[0]; + if (addr_offset > 0) { + return false; + } + if (addr_base == regmap::SWREG_RX_ERR) { + if (chan > get_num_output_ports()) { + return false; + } + switch (code) { + case err_codes::ERR_RX_OVERRUN: + return true; + case err_codes::ERR_RX_LATE_CMD: + return true; + default: + return false; + } + } + if (addr_base == regmap::SWREG_TX_ERR) { + if (chan > get_num_input_ports()) { + return false; + } + switch (code) { + case err_codes::ERR_TX_UNDERRUN: + return true; + case err_codes::ERR_TX_LATE_DATA: + return true; + default: + return false; + } + } + return false; +} + void radio_control_impl::async_message_handler( uint32_t addr, const std::vector<uint32_t>& data, boost::optional<uint64_t> timestamp) { |