diff options
Diffstat (limited to 'host/lib')
11 files changed, 237 insertions, 76 deletions
| diff --git a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp index f60319d32..2a93fbfa5 100644 --- a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp +++ b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp @@ -11,6 +11,8 @@  #include <uhd/rfnoc/radio_control.hpp>  #include <uhdlib/features/discoverable_feature_registry.hpp>  #include <uhdlib/usrp/common/pwr_cal_mgr.hpp> +#include <uhd/rfnoc/rf_control/core_iface.hpp> +#include <uhdlib/rfnoc/rf_control/gain_profile_iface.hpp>  #include <unordered_map>  #include <mutex> @@ -322,6 +324,9 @@ protected:      // simply leave these empty.      std::vector<uhd::usrp::pwr_cal_mgr::sptr> _tx_pwr_mgr; +    rf_control::gain_profile_iface::sptr _tx_gain_profile_api; +    rf_control::gain_profile_iface::sptr _rx_gain_profile_api; +  private:      //! Validator for the async messages      // diff --git a/host/lib/include/uhdlib/rfnoc/rf_control/dboard_iface.hpp b/host/lib/include/uhdlib/rfnoc/rf_control/dboard_iface.hpp new file mode 100644 index 000000000..1651a1580 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/rf_control/dboard_iface.hpp @@ -0,0 +1,41 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#pragma once + +#include <uhd/rfnoc/rf_control/core_iface.hpp> +#include <uhdlib/rfnoc/rf_control/gain_profile_iface.hpp> +#include <uhdlib/usrp/common/pwr_cal_mgr.hpp> +#include <memory> + +namespace uhd { namespace rfnoc { namespace rf_control { + +/*! Interface that daughterboards expose to the motherboard radio_control + * + * This interface contains everything required for a daughterboard to implement + * all the methods required for radio_control. For the most part, this class + * just includes accessors to objects which implement the required functionality. + * This class also directly implements core_iface for the remainder. + */ +class dboard_iface : public core_iface +{ +public: +    using sptr = std::shared_ptr<dboard_iface>; + +    virtual ~dboard_iface() = default; + +    virtual gain_profile_iface::sptr get_tx_gain_profile_api() = 0; +    virtual gain_profile_iface::sptr get_rx_gain_profile_api() = 0; + +    virtual size_t get_chan_from_dboard_fe( +        const std::string&, uhd::direction_t) const                                  = 0; +    virtual std::string get_dboard_fe_from_chan(size_t chan, uhd::direction_t) const = 0; + +    virtual std::vector<uhd::usrp::pwr_cal_mgr::sptr>& get_pwr_mgr( +        uhd::direction_t trx) = 0; +}; + +}}} // namespace uhd::rfnoc::rf_control diff --git a/host/lib/include/uhdlib/rfnoc/rf_control/gain_profile_iface.hpp b/host/lib/include/uhdlib/rfnoc/rf_control/gain_profile_iface.hpp new file mode 100644 index 000000000..f93a42936 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/rf_control/gain_profile_iface.hpp @@ -0,0 +1,86 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#pragma once + +#include <memory> +#include <string> +#include <vector> + +namespace uhd { namespace rfnoc { namespace rf_control { + +/*! Interface for gain profile API commands + * + * This interface contains methods to configure the current gain profile of the + * device. Note that this interface is RX/TX agnostic, it does not provide + * specialized methods for RX and TX. + */ +class gain_profile_iface +{ +public: +    using sptr = std::shared_ptr<gain_profile_iface>; + +    virtual ~gain_profile_iface() = default; + +    /*! Return a list of TX gain profiles for this radio +     */ +    virtual std::vector<std::string> get_gain_profile_names(const size_t chan) const = 0; + +    /*! Set the gain profile +     */ +    virtual void set_gain_profile(const std::string& profile, const size_t chan) = 0; + +    /*! Return the gain profile +     */ +    virtual std::string get_gain_profile(const size_t chan) const = 0; +}; + +/*! "Default" implementation for gain_profile_iface + * + * This class implements gain_profile_iface such that the device is always + * and can only be configured using a single "default" gain profile. Setting + * a gain profile which is not the default profile is an error, and getting the + * gain profile will always return the default profile. + */ +class default_gain_profile : public gain_profile_iface +{ +public: +    std::vector<std::string> get_gain_profile_names(const size_t chan) const override; + +    void set_gain_profile(const std::string& profile, const size_t chan) override; +    std::string get_gain_profile(const size_t chan) const override; + +private: +    static const std::string DEFAULT_GAIN_PROFILE; +}; + +/*! "Enumerated" implementation for gain_profile_iface + * + * This class implements gain_profile_iface so that the gain profile can only be + * one of several different enumerated values. Setting an invalid gain profile + * is an error. Retrieving a gain profile will always return one of the + * enumerated gain profiles. + */ +class enumerated_gain_profile : public gain_profile_iface +{ +public: +    enumerated_gain_profile(const std::vector<std::string>& possible_profiles, +        const std::string& default_profile, +        size_t num_channels); + +    void set_gain_profile(const std::string& profile, const size_t chan) override; + +    std::string get_gain_profile(const size_t chan) const override; + +    std::vector<std::string> get_gain_profile_names(const size_t) const override; + +private: +    std::vector<std::string> _possible_profiles; + +    std::vector<std::string> _gain_profile; +}; + +}}} // namespace uhd::rfnoc::rf_control diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt index 33da287fe..53bca9b45 100644 --- a/host/lib/rfnoc/CMakeLists.txt +++ b/host/lib/rfnoc/CMakeLists.txt @@ -61,3 +61,4 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/window_block_control.cpp  ) +INCLUDE_SUBDIRECTORY(rf_control) diff --git a/host/lib/rfnoc/radio_control_impl.cpp b/host/lib/rfnoc/radio_control_impl.cpp index f9347b9e7..e20f5d4f6 100644 --- a/host/lib/rfnoc/radio_control_impl.cpp +++ b/host/lib/rfnoc/radio_control_impl.cpp @@ -253,6 +253,10 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args)                                            boost::optional<uint64_t> timestamp) {          this->async_message_handler(addr, data, timestamp);      }); + +    // Set the default gain profiles +    _rx_gain_profile_api = std::make_shared<rf_control::default_gain_profile>(); +    _tx_gain_profile_api = std::make_shared<rf_control::default_gain_profile>();  } /* ctor */  /****************************************************************************** @@ -436,42 +440,34 @@ void radio_control_impl::set_rx_agc(const bool, const size_t)      throw uhd::not_implemented_error("set_rx_agc() is not supported on this radio!");  } -void radio_control_impl::set_tx_gain_profile(const std::string& profile, const size_t) +void radio_control_impl::set_tx_gain_profile(const std::string& profile, const size_t chan)  { -    if (profile != DEFAULT_GAIN_PROFILE) { -        throw uhd::value_error( -            std::string("set_tx_gain_profile(): Unknown gain profile: `") + profile -            + "'"); -    } +    _tx_gain_profile_api->set_gain_profile(profile, chan);  } -void radio_control_impl::set_rx_gain_profile(const std::string& profile, const size_t) +void radio_control_impl::set_rx_gain_profile(const std::string& profile, const size_t chan)  { -    if (profile != DEFAULT_GAIN_PROFILE) { -        throw uhd::value_error( -            std::string("set_rx_gain_profile(): Unknown gain profile: `") + profile -            + "'"); -    } +    _rx_gain_profile_api->set_gain_profile(profile, chan);  } -std::vector<std::string> radio_control_impl::get_tx_gain_profile_names(const size_t) const +std::vector<std::string> radio_control_impl::get_tx_gain_profile_names(const size_t chan) const  { -    return {DEFAULT_GAIN_PROFILE}; +    return _tx_gain_profile_api->get_gain_profile_names(chan);  } -std::vector<std::string> radio_control_impl::get_rx_gain_profile_names(const size_t) const +std::vector<std::string> radio_control_impl::get_rx_gain_profile_names(const size_t chan) const  { -    return {DEFAULT_GAIN_PROFILE}; +    return _rx_gain_profile_api->get_gain_profile_names(chan);  } -std::string radio_control_impl::get_tx_gain_profile(const size_t) const +std::string radio_control_impl::get_tx_gain_profile(const size_t chan) const  { -    return DEFAULT_GAIN_PROFILE; +    return _tx_gain_profile_api->get_gain_profile(chan);  } -std::string radio_control_impl::get_rx_gain_profile(const size_t) const +std::string radio_control_impl::get_rx_gain_profile(const size_t chan) const  { -    return DEFAULT_GAIN_PROFILE; +    return _rx_gain_profile_api->get_gain_profile(chan);  }  double radio_control_impl::set_tx_bandwidth(const double bandwidth, const size_t chan) diff --git a/host/lib/rfnoc/rf_control/CMakeLists.txt b/host/lib/rfnoc/rf_control/CMakeLists.txt new file mode 100644 index 000000000..11c7e57ef --- /dev/null +++ b/host/lib/rfnoc/rf_control/CMakeLists.txt @@ -0,0 +1,13 @@ +# +# Copyright 2020 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +######################################################################## +# This file included, use CMake directory variables +######################################################################## + +LIBUHD_APPEND_SOURCES( +    ${CMAKE_CURRENT_SOURCE_DIR}/gain_profile.cpp +) diff --git a/host/lib/rfnoc/rf_control/gain_profile.cpp b/host/lib/rfnoc/rf_control/gain_profile.cpp new file mode 100644 index 000000000..54ccb9006 --- /dev/null +++ b/host/lib/rfnoc/rf_control/gain_profile.cpp @@ -0,0 +1,68 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include <uhd/exception.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/utils/log.hpp> +#include <uhdlib/rfnoc/rf_control/gain_profile_iface.hpp> +#include <stddef.h> +#include <string> +#include <vector> + +namespace uhd { namespace rfnoc { namespace rf_control { + +const std::string default_gain_profile::DEFAULT_GAIN_PROFILE = "default"; + +std::vector<std::string> default_gain_profile::get_gain_profile_names(const size_t) const +{ +    return {DEFAULT_GAIN_PROFILE}; +} + +void default_gain_profile::set_gain_profile(const std::string& profile, const size_t) +{ +    if (profile != DEFAULT_GAIN_PROFILE) { +        throw uhd::value_error( +            std::string("set_tx_gain_profile(): Unknown gain profile: `") + profile +            + "'"); +    } +} + +std::string default_gain_profile::get_gain_profile(const size_t) const +{ +    return DEFAULT_GAIN_PROFILE; +} + +enumerated_gain_profile::enumerated_gain_profile( +    const std::vector<std::string>& possible_profiles, +    const std::string& default_profile, +    size_t num_channels) +    : _possible_profiles(possible_profiles), _gain_profile(num_channels, default_profile) +{ +} + +void enumerated_gain_profile::set_gain_profile( +    const std::string& profile, const size_t chan) +{ +    if (!uhd::has(_possible_profiles, profile)) { +        const std::string err_msg = ("Invalid gain profile provided: " + profile); +        UHD_LOG_ERROR("gain_profile", err_msg); +        throw uhd::key_error(err_msg); +    } +    _gain_profile.at(chan) = profile; +} + +std::string enumerated_gain_profile::get_gain_profile(const size_t chan) const +{ +    return _gain_profile.at(chan); +} + +std::vector<std::string> enumerated_gain_profile::get_gain_profile_names( +    const size_t) const +{ +    return _possible_profiles; +} + +}}} // namespace uhd::rfnoc::rf_control diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp index 5eb0f63a5..879885640 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp @@ -103,6 +103,10 @@ magnesium_radio_control_impl::magnesium_radio_control_impl(make_args_ptr make_ar  {      RFNOC_LOG_TRACE("Entering magnesium_radio_control_impl ctor...");      UHD_ASSERT_THROW(get_block_id().get_block_count() < 2); + +    _tx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>(MAGNESIUM_GP_OPTIONS, "default", MAGNESIUM_NUM_CHANS); +    _rx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>(MAGNESIUM_GP_OPTIONS, "default", MAGNESIUM_NUM_CHANS); +      const char radio_slot_name[2] = {'A', 'B'};      _radio_slot                   = radio_slot_name[get_block_id().get_block_count()];      RFNOC_LOG_TRACE("Radio slot: " << _radio_slot); @@ -363,28 +367,6 @@ double magnesium_radio_control_impl::set_tx_bandwidth(      return AD9371_TX_MAX_BANDWIDTH;  } -void magnesium_radio_control_impl::set_tx_gain_profile( -    const std::string& profile, const size_t) -{ -    if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) -        == MAGNESIUM_GP_OPTIONS.end()) { -        RFNOC_LOG_ERROR("Invalid TX gain profile: " << profile); -        throw uhd::key_error("Invalid TX gain profile!"); -    } -    _gain_profile[TX_DIRECTION] = profile; -} - -void magnesium_radio_control_impl::set_rx_gain_profile( -    const std::string& profile, const size_t) -{ -    if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) -        == MAGNESIUM_GP_OPTIONS.end()) { -        RFNOC_LOG_ERROR("Invalid RX gain profile: " << profile); -        throw uhd::key_error("Invalid RX gain profile!"); -    } -    _gain_profile[RX_DIRECTION] = profile; -} -  double magnesium_radio_control_impl::set_tx_gain(const double gain, const size_t chan)  {      std::lock_guard<std::recursive_mutex> l(_set_lock); @@ -716,28 +698,6 @@ uhd::gain_range_t magnesium_radio_control_impl::get_rx_gain_range(      throw uhd::key_error("Invalid RX gain name!");  } -std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_profile_names( -    const size_t) const -{ -    return MAGNESIUM_GP_OPTIONS; -} - -std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_profile_names( -    const size_t) const -{ -    return MAGNESIUM_GP_OPTIONS; -} - -std::string magnesium_radio_control_impl::get_tx_gain_profile(const size_t) const -{ -    return _gain_profile.at(TX_DIRECTION); -} - -std::string magnesium_radio_control_impl::get_rx_gain_profile(const size_t) const -{ -    return _gain_profile.at(RX_DIRECTION); -} -  meta_range_t magnesium_radio_control_impl::get_tx_bandwidth_range(size_t) const  {      return meta_range_t(AD9371_TX_MIN_BANDWIDTH, AD9371_TX_MAX_BANDWIDTH); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp index fc8c79b5a..e8c252605 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp @@ -87,8 +87,6 @@ public:      double set_rx_gain(const double gain, const std::string& name, const size_t chan);      double set_tx_bandwidth(const double bandwidth, const size_t chan);      double set_rx_bandwidth(const double bandwidth, const size_t chan); -    void set_tx_gain_profile(const std::string& profile, const size_t chan); -    void set_rx_gain_profile(const std::string& profile, const size_t chan);      // Getters      std::vector<std::string> get_tx_antennas(const size_t chan) const; @@ -103,10 +101,6 @@ public:      uhd::gain_range_t get_tx_gain_range(const std::string&, const size_t) const;      uhd::gain_range_t get_rx_gain_range(const size_t) const;      uhd::gain_range_t get_rx_gain_range(const std::string&, const size_t) const; -    std::vector<std::string> get_tx_gain_profile_names(const size_t chan) const; -    std::vector<std::string> get_rx_gain_profile_names(const size_t chan) const; -    std::string get_tx_gain_profile(const size_t chan) const; -    std::string get_rx_gain_profile(const size_t chan) const;      uhd::meta_range_t get_tx_bandwidth_range(size_t chan) const;      uhd::meta_range_t get_rx_bandwidth_range(size_t chan) const; @@ -351,9 +345,6 @@ private:      //! All gain      double _all_rx_gain = 0.0;      double _all_tx_gain = 0.0; -    //! Gain profile -    std::map<direction_t, std::string> _gain_profile = { -        {RX_DIRECTION, "default"}, {TX_DIRECTION, "default"}};      bool _rx_bypass_lnas = true;      bool _tx_bypass_amp  = true; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp index b06222205..72d8d564c 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp @@ -31,7 +31,7 @@ double magnesium_radio_control_impl::_set_all_gain(      const size_t ad9371_chan = chan;      auto chan_sel            = static_cast<magnesium_cpld_ctrl::chan_sel_t>(chan);      gain_tuple_t gain_tuple; -    std::string gp = _gain_profile[dir]; +    std::string gp = dir == RX_DIRECTION ? get_rx_gain_profile(0) : get_tx_gain_profile(0);      RFNOC_LOG_TRACE("Gain profile: " << gp);      if (gp == "manual") { diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp index d9bf5c3d2..82da7ec75 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp @@ -51,13 +51,13 @@ void magnesium_radio_control_impl::_init_defaults()      if (block_args.has_key("tx_gain_profile")) {          RFNOC_LOG_INFO("Using user specified TX gain profile: " << block_args.get(                             "tx_gain_profile")); -        _gain_profile[TX_DIRECTION] = block_args.get("tx_gain_profile"); +        set_tx_gain_profile(block_args.get("tx_gain_profile"), 0);      }      if (block_args.has_key("rx_gain_profile")) {          RFNOC_LOG_INFO("Using user specified RX gain profile: " << block_args.get(                             "rx_gain_profile")); -        _gain_profile[RX_DIRECTION] = block_args.get("rx_gain_profile"); +        set_rx_gain_profile(block_args.get("rx_gain_profile"), 0);      }      if (block_args.has_key("rx_band_map")) { | 
