diff options
| author | Lane Kolbly <lane.kolbly@ni.com> | 2021-12-07 16:47:26 -0600 | 
|---|---|---|
| committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2022-01-05 10:28:39 -0600 | 
| commit | 1880c6915d47aee1e8d6a6713da126767c9af9cf (patch) | |
| tree | ed52e29f122a9d73080f79af02494e576bdab884 /host | |
| parent | 7deb56e2123785141e44969937f0ae902ea19c00 (diff) | |
| download | uhd-1880c6915d47aee1e8d6a6713da126767c9af9cf.tar.gz uhd-1880c6915d47aee1e8d6a6713da126767c9af9cf.tar.bz2 uhd-1880c6915d47aee1e8d6a6713da126767c9af9cf.zip | |
host: rf_control: Add internal antenna API abstraction.
Diffstat (limited to 'host')
| -rw-r--r-- | host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp | 102 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp | 18 | ||||
| -rw-r--r-- | host/lib/rfnoc/rf_control/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/rfnoc/rf_control/antenna.cpp | 84 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/zbx/zbx_dboard.cpp | 46 | ||||
| -rw-r--r-- | host/tests/CMakeLists.txt | 1 | 
6 files changed, 203 insertions, 49 deletions
| diff --git a/host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp b/host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp new file mode 100644 index 000000000..bd36fc869 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp @@ -0,0 +1,102 @@ +// +// Copyright 2021 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#pragma once + +#include <uhd/property_tree.hpp> +#include <uhd/rfnoc/rf_control/core_iface.hpp> +#include <unordered_map> +#include <functional> +#include <memory> +#include <string> +#include <vector> + +namespace uhd { namespace rfnoc { namespace rf_control { + +/*! Interface for setting and getting the current antenna. + */ +class antenna_iface +{ +public: +    using sptr = std::shared_ptr<antenna_iface>; + +    virtual ~antenna_iface() = default; + +    /*! Return a list of valid antenna for channel \p chan. +     * +     * \return The selected antenna. +     */ +    virtual std::vector<std::string> get_antennas(const size_t chan) const = 0; + +    /*! Select antenna \p for channel \p chan. +     * +     * \throws uhd::value_error if \p ant is not a valid value. +     */ +    virtual void set_antenna(const std::string& ant, const size_t chan) = 0; + +    /*! Return the selected antenna for channel \p chan. +     * +     * \return The selected antenna. +     */ +    virtual std::string get_antenna(const size_t chan) const = 0; +}; + +/*! Class for getting and setting antennas out of an enumerated set, where + * the API calls for the antenna actually map to property nodes. + */ +class enumerated_antenna : public antenna_iface +{ +public: +    using prop_path = std::function<fs_path(const size_t chan)>; + +    /*! Constructs an enumerated_antenna class. +     * +     * \param tree The property tree the nodes are on +     * \param prop_path_generator Closure to generate the property path given the channel. +     * \param possible_antennas A vector of legal antennas. +     * \param compat_map A map of alternative names for antennas. +     */ +    enumerated_antenna(uhd::property_tree::sptr tree, +        prop_path prop_path_generator, +        const std::vector<std::string>& possible_antennas, +        const std::unordered_map<std::string, std::string>& compat_map); + +    virtual ~enumerated_antenna() = default; + +    std::vector<std::string> get_antennas(const size_t chan) const override; +    void set_antenna(const std::string& ant, const size_t chan) override; +    std::string get_antenna(const size_t chan) const override; + +private: +    // The property tree & node used to implement the API +    uhd::property_tree::sptr _tree; +    prop_path _prop_path_generator; + +    std::vector<std::string> _possible_antennas; +    const std::unordered_map<std::string, std::string>& _compat_map; +}; + +/*! Partially implements core_iface for antenna, redirecting to one of two + * subobjects for RX or TX. + */ +class antenna_radio_control_mixin : virtual public core_iface +{ +public: +    virtual ~antenna_radio_control_mixin() = default; + +    std::string get_tx_antenna(const size_t chan) const override; +    std::vector<std::string> get_tx_antennas(const size_t chan) const override; +    void set_tx_antenna(const std::string& ant, const size_t chan) override; +    std::string get_rx_antenna(const size_t chan) const override; +    std::vector<std::string> get_rx_antennas(const size_t chan) const override; +    void set_rx_antenna(const std::string& ant, const size_t chan) override; + +protected: +    antenna_iface::sptr _rx_antenna; +    antenna_iface::sptr _tx_antenna; +}; + +}}} // namespace uhd::rfnoc::rf_control diff --git a/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp b/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp index 0a52d7bdf..6e1d31381 100644 --- a/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp +++ b/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp @@ -21,6 +21,7 @@  #include <uhd/types/wb_iface.hpp>  #include <uhdlib/experts/expert_factory.hpp>  #include <uhdlib/rfnoc/rf_control/dboard_iface.hpp> +#include <uhdlib/rfnoc/rf_control/antenna_iface.hpp>  #include <uhdlib/usrp/common/mpmd_mb_controller.hpp>  #include <uhdlib/usrp/common/pwr_cal_mgr.hpp>  #include <uhdlib/usrp/common/rpc.hpp> @@ -40,7 +41,9 @@ const static uint16_t ZBX_PID = 0x4002;  /*! Provide access to a ZBX radio.   */ -class zbx_dboard_impl : public uhd::usrp::x400::x400_dboard_iface +class zbx_dboard_impl : +    public uhd::usrp::x400::x400_dboard_iface, +    public uhd::rfnoc::rf_control::antenna_radio_control_mixin  {  public:      using sptr                  = std::shared_ptr<zbx_dboard_impl>; @@ -109,17 +112,6 @@ public:          return _rx_gain_profile_api;      } -    void set_tx_antenna(const std::string& ant, const size_t chan) override; -    void set_rx_antenna(const std::string& ant, const size_t chan) override; -    std::vector<std::string> get_tx_antennas(const size_t /*chan*/) const override -    { -        return TX_ANTENNAS; -    } -    std::vector<std::string> get_rx_antennas(const size_t /*chan*/) const override -    { -        return RX_ANTENNAS; -    } -      double set_tx_frequency(const double freq, const size_t chan) override;      double set_rx_frequency(const double freq, const size_t chan) override;      uhd::freq_range_t get_tx_frequency_range(const size_t /*chan*/) const override @@ -239,8 +231,6 @@ public:       * Radio Identification API Calls       *************************************************************************/ -    std::string get_tx_antenna(size_t chan) const override; -    std::string get_rx_antenna(size_t chan) const override;      double get_tx_frequency(size_t chan) override;      double get_rx_frequency(size_t chan) override;      double get_rx_bandwidth(size_t chan) override; diff --git a/host/lib/rfnoc/rf_control/CMakeLists.txt b/host/lib/rfnoc/rf_control/CMakeLists.txt index 11c7e57ef..f55c9a8a1 100644 --- a/host/lib/rfnoc/rf_control/CMakeLists.txt +++ b/host/lib/rfnoc/rf_control/CMakeLists.txt @@ -9,5 +9,6 @@  ########################################################################  LIBUHD_APPEND_SOURCES( +    ${CMAKE_CURRENT_SOURCE_DIR}/antenna.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/gain_profile.cpp  ) diff --git a/host/lib/rfnoc/rf_control/antenna.cpp b/host/lib/rfnoc/rf_control/antenna.cpp new file mode 100644 index 000000000..50153f3f0 --- /dev/null +++ b/host/lib/rfnoc/rf_control/antenna.cpp @@ -0,0 +1,84 @@ +// +// Copyright 2021 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/antenna_iface.hpp> +#include <stddef.h> +#include <string> +#include <vector> + +namespace uhd { namespace rfnoc { namespace rf_control { + +enumerated_antenna::enumerated_antenna(uhd::property_tree::sptr tree, +    prop_path prop_path_generator, +    const std::vector<std::string>& possible_antennas, +    const std::unordered_map<std::string, std::string>& compat_map) +    : _tree(tree) +    , _prop_path_generator(prop_path_generator) +    , _possible_antennas(possible_antennas) +    , _compat_map(compat_map) +{ +} + +std::vector<std::string> enumerated_antenna::get_antennas(const size_t) const +{ +    return _possible_antennas; +} + +void enumerated_antenna::set_antenna(const std::string& ant, const size_t chan) +{ +    if (!_compat_map.count(ant)) { +        assert_has(_possible_antennas, ant, "antenna"); +    } + +    auto path = _prop_path_generator(chan); + +    _tree->access<std::string>(path).set(ant); +} + +std::string enumerated_antenna::get_antenna(const size_t chan) const +{ +    auto path = _prop_path_generator(chan); +    return _tree->access<std::string>(path).get(); +} + +std::string antenna_radio_control_mixin::get_tx_antenna(const size_t chan) const +{ +    return _tx_antenna->get_antenna(chan); +} + +std::vector<std::string> antenna_radio_control_mixin::get_tx_antennas( +    const size_t chan) const +{ +    return _tx_antenna->get_antennas(chan); +} + +void antenna_radio_control_mixin::set_tx_antenna( +    const std::string& ant, const size_t chan) +{ +    _tx_antenna->set_antenna(ant, chan); +} + +std::string antenna_radio_control_mixin::get_rx_antenna(const size_t chan) const +{ +    return _rx_antenna->get_antenna(chan); +} + +std::vector<std::string> antenna_radio_control_mixin::get_rx_antennas( +    const size_t chan) const +{ +    return _rx_antenna->get_antennas(chan); +} + +void antenna_radio_control_mixin::set_rx_antenna( +    const std::string& ant, const size_t chan) +{ +    _rx_antenna->set_antenna(ant, chan); +} + +}}} // namespace uhd::rfnoc::rf_control diff --git a/host/lib/usrp/dboard/zbx/zbx_dboard.cpp b/host/lib/usrp/dboard/zbx/zbx_dboard.cpp index d41302c8f..2a01425b6 100644 --- a/host/lib/usrp/dboard/zbx/zbx_dboard.cpp +++ b/host/lib/usrp/dboard/zbx/zbx_dboard.cpp @@ -48,6 +48,17 @@ zbx_dboard_impl::zbx_dboard_impl(register_iface& reg_iface,      RFNOC_LOG_TRACE("Entering zbx_dboard_impl ctor...");      RFNOC_LOG_TRACE("Radio slot: " << _radio_slot); +    _rx_antenna = std::make_shared<uhd::rfnoc::rf_control::enumerated_antenna>(tree, +        [this](size_t chan) { +            return this->_get_frontend_path(RX_DIRECTION, chan) / "antenna" / "value"; +        }, +        RX_ANTENNAS, RX_ANTENNA_NAME_COMPAT_MAP); +    _tx_antenna = std::make_shared<uhd::rfnoc::rf_control::enumerated_antenna>(tree, +        [this](size_t chan) { +            return this->_get_frontend_path(TX_DIRECTION, chan) / "antenna" / "value"; +        }, +        TX_ANTENNAS, TX_ANTENNA_NAME_COMPAT_MAP); +      _tx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>(          ZBX_GAIN_PROFILES, ZBX_GAIN_PROFILE_DEFAULT, ZBX_NUM_CHANS);      _rx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>( @@ -89,29 +100,6 @@ std::string zbx_dboard_impl::get_unique_id() const  /******************************************************************************   * API Calls   *****************************************************************************/ -void zbx_dboard_impl::set_tx_antenna(const std::string& ant, const size_t chan) -{ -    RFNOC_LOG_TRACE("Setting TX antenna to " << ant << " for chan " << chan); -    if (!TX_ANTENNA_NAME_COMPAT_MAP.count(ant)) { -        assert_has(TX_ANTENNAS, ant, "tx antenna"); -    } -    const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan); - -    _tree->access<std::string>(fe_path / "antenna" / "value").set(ant); -} - -void zbx_dboard_impl::set_rx_antenna(const std::string& ant, const size_t chan) -{ -    RFNOC_LOG_TRACE("Setting RX antenna to " << ant << " for chan " << chan); -    if (!RX_ANTENNA_NAME_COMPAT_MAP.count(ant)) { -        assert_has(RX_ANTENNAS, ant, "rx antenna"); -    } - -    const fs_path fe_path = _get_frontend_path(RX_DIRECTION, chan); - -    _tree->access<std::string>(fe_path / "antenna" / "value").set(ant); -} -  double zbx_dboard_impl::set_tx_frequency(const double req_freq, const size_t chan)  {      const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan); @@ -592,18 +580,6 @@ double zbx_dboard_impl::get_rx_lo_freq(const std::string& name, size_t chan)      return _tree->access<double>(fe_path / "los" / name / "freq" / "value").get();  } -std::string zbx_dboard_impl::get_tx_antenna(size_t chan) const -{ -    const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan); -    return _tree->access<std::string>(fe_path / "antenna" / "value").get(); -} - -std::string zbx_dboard_impl::get_rx_antenna(size_t chan) const -{ -    const fs_path fe_path = _get_frontend_path(RX_DIRECTION, chan); -    return _tree->access<std::string>(fe_path / "antenna" / "value").get(); -} -  double zbx_dboard_impl::get_tx_frequency(size_t chan)  {      const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan); diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt index d8e26890a..758d2bbf0 100644 --- a/host/tests/CMakeLists.txt +++ b/host/tests/CMakeLists.txt @@ -376,6 +376,7 @@ IF(ENABLE_X400)          ${UHD_SOURCE_DIR}/lib/usrp/x400/x400_rfdc_control.cpp          ${UHD_SOURCE_DIR}/lib/usrp/x400/adc_self_calibration.cpp          ${UHD_SOURCE_DIR}/lib/rfnoc/radio_control_impl.cpp +        ${UHD_SOURCE_DIR}/lib/rfnoc/rf_control/antenna.cpp          ${UHD_SOURCE_DIR}/lib/rfnoc/rf_control/gain_profile.cpp          ${UHD_SOURCE_DIR}/lib/usrp/mpmd/mpmd_mb_controller.cpp          ${UHD_SOURCE_DIR}/lib/usrp/dboard/zbx/zbx_dboard.cpp | 
