diff options
Diffstat (limited to 'host/lib/usrp/dboard')
6 files changed, 133 insertions, 39 deletions
| diff --git a/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp b/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp index 4792dcac6..13cc52d49 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp @@ -67,12 +67,6 @@ namespace {   * passes). Frequencies need to be chosen to allow as much of the full   * bandwidth through unattenuated.   */ -constexpr double MAGNESIUM_RX_BAND1_MIN_FREQ = 430e6; -constexpr double MAGNESIUM_RX_BAND2_MIN_FREQ = 600e6; -constexpr double MAGNESIUM_RX_BAND3_MIN_FREQ = 1050e6; -constexpr double MAGNESIUM_RX_BAND4_MIN_FREQ = 1600e6; -constexpr double MAGNESIUM_RX_BAND5_MIN_FREQ = 2100e6; -constexpr double MAGNESIUM_RX_BAND6_MIN_FREQ = 2700e6;  /* Note on the TX filter bank:   * @@ -96,13 +90,12 @@ constexpr double MAGNESIUM_RX_BAND6_MIN_FREQ = 2700e6;   * through unattenuated (so don't go all the way up to the cutoff frequency   * of that filter, OK).   */ -constexpr double MAGNESIUM_TX_BAND1_MIN_FREQ = 723.17e6; -constexpr double MAGNESIUM_TX_BAND2_MIN_FREQ = 1623.17e6; -constexpr double MAGNESIUM_TX_BAND3_MIN_FREQ = 3323.17e6; +  } // namespace +  magnesium_radio_ctrl_impl::rx_band magnesium_radio_ctrl_impl::_map_freq_to_rx_band( -    const double freq) +    const band_map_t band_map, const double freq)  {      magnesium_radio_ctrl_impl::rx_band band; @@ -110,17 +103,17 @@ magnesium_radio_ctrl_impl::rx_band magnesium_radio_ctrl_impl::_map_freq_to_rx_ba          band = rx_band::INVALID_BAND;      } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) {          band = rx_band::LOWBAND; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND1_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(1)) {          band = rx_band::BAND0; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND2_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(2)) {          band = rx_band::BAND1; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND3_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(3)) {          band = rx_band::BAND2; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND4_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(4)) {          band = rx_band::BAND3; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND5_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(5)) {          band = rx_band::BAND4; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND6_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(6)) {          band = rx_band::BAND5;      } else if (fp_compare_epsilon<double>(freq) <= MAGNESIUM_MAX_FREQ) {          band = rx_band::BAND6; @@ -132,7 +125,7 @@ magnesium_radio_ctrl_impl::rx_band magnesium_radio_ctrl_impl::_map_freq_to_rx_ba  }  magnesium_radio_ctrl_impl::tx_band magnesium_radio_ctrl_impl::_map_freq_to_tx_band( -    const double freq) +    const band_map_t band_map, const double freq)  {      magnesium_radio_ctrl_impl::tx_band band; @@ -140,11 +133,11 @@ magnesium_radio_ctrl_impl::tx_band magnesium_radio_ctrl_impl::_map_freq_to_tx_ba          band = tx_band::INVALID_BAND;      } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) {          band = tx_band::LOWBAND; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND1_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(1)) {          band = tx_band::BAND0; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND2_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(2)) {          band = tx_band::BAND1; -    } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND3_MIN_FREQ) { +    } else if (fp_compare_epsilon<double>(freq) < band_map.at(3)) {          band = tx_band::BAND2;      } else if (fp_compare_epsilon<double>(freq) <= MAGNESIUM_MAX_FREQ) {          band = tx_band::BAND3; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp index 3c66a3b62..679816af8 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp @@ -132,7 +132,7 @@ void magnesium_radio_ctrl_impl::_update_rx_freq_switches(const double freq,      auto rx_sw4           = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM;      auto rx_sw5           = magnesium_cpld_ctrl::RX_SW5_FILTER1100X1575MHZFROM;      auto rx_sw6           = magnesium_cpld_ctrl::RX_SW6_BYPASSPATHFROMSWITCH2; -    const auto band       = _map_freq_to_rx_band(freq); +    const auto band       = _map_freq_to_rx_band(_rx_band_map, freq);      const bool is_lowband = (band == rx_band::LOWBAND);      const auto select_lowband_mixer_path =          is_lowband ? magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND @@ -235,7 +235,7 @@ void magnesium_radio_ctrl_impl::_update_tx_freq_switches(const double freq,      auto tx_sw1           = magnesium_cpld_ctrl::TX_SW1_SHUTDOWNTXSW1;      auto tx_sw2           = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP6400MHZ;      auto tx_sw3           = magnesium_cpld_ctrl::TX_SW3_BYPASSPATHTOTRXSW; -    const auto band       = _map_freq_to_tx_band(freq); +    const auto band       = _map_freq_to_tx_band(_tx_band_map, freq);      const bool is_lowband = (band == tx_band::LOWBAND);      const auto select_lowband_mixer_path =          is_lowband ? magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp index 1370fde3a..b66bd2efd 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp @@ -7,6 +7,7 @@  #include "magnesium_constants.hpp"  #include "magnesium_gain_table.hpp"  #include "magnesium_radio_ctrl_impl.hpp" +#include <uhd/exception.hpp>  #include <uhd/utils/log.hpp>  using namespace uhd; @@ -27,23 +28,36 @@ double magnesium_radio_ctrl_impl::_set_all_gain(                   << chan                   << ", "                      "dir=" -                 << dir); +                 << dir << ")");      const size_t ad9371_chan = chan;      auto chan_sel            = static_cast<magnesium_cpld_ctrl::chan_sel_t>(chan); -    gain_tuple_t gain_tuple  = (dir == RX_DIRECTION) -                                  ? get_rx_gain_tuple(gain, _map_freq_to_rx_band(freq)) -                                  : get_tx_gain_tuple(gain, _map_freq_to_tx_band(freq)); +    gain_tuple_t gain_tuple; +    std::string gp = _gain_profile[dir]; -    if (_gain_profile[dir] == "manual") { +    UHD_LOG_TRACE(unique_id(), "Gain profile: " << gp); +    if (gp == "manual") {          UHD_LOG_TRACE(unique_id(), "Manual gain mode. Getting gain from property tree.");          gain_tuple = {DSA_MAX_GAIN - _dsa_att[dir],              ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN)                  - _ad9371_att[dir],              _amp_bypass[dir]}; -    } else if (_gain_profile[dir] == "default") { +    } else if (gp.find("default") != gp.npos) {          UHD_LOG_TRACE(unique_id(), "Getting gain from gain table."); +        gain_tuple = +            (dir == RX_DIRECTION) +                ? get_rx_gain_tuple(gain, _map_freq_to_rx_band(_rx_band_map, freq)) +                : get_tx_gain_tuple(gain, _map_freq_to_tx_band(_tx_band_map, freq)); +        if (gp == "default_rf_filter_bypass_always_on") { +            UHD_LOG_TRACE(unique_id(), "Enable filter bypass for all gains"); +            gain_tuple.bypass = true; +        } else if (gp == "default_rf_filter_bypass_always_off") { +            UHD_LOG_TRACE(unique_id(), "Disable filter bypass for all gains"); +            gain_tuple.bypass = false; +        }      } else { -        UHD_LOG_ERROR(unique_id(), "Unsupported gain mode: " << _gain_profile[dir]) +        UHD_LOG_ERROR(unique_id(), "Unsupported gain mode: " << gp); +        throw uhd::value_error( +            str(boost::format("[%s] Unsupported gain mode: %s") % unique_id() % gp));      }      const double ad9371_gain =          ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) @@ -89,8 +103,7 @@ double magnesium_radio_ctrl_impl::_dsa_set_att(      const double att, const size_t chan, const direction_t dir)  {      UHD_LOG_TRACE(unique_id(), -        __func__ << "(att=" -                 << "att dB, chan=" << chan << ", dir=" << dir << ")") +        __func__ << "(att=" << att << "dB, chan=" << chan << ", dir=" << dir << ")")      const uint32_t dsa_val = 2 * att;      _set_dsa_val(chan, dir, dsa_val); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp index c216b0777..405d5955e 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp @@ -202,7 +202,7 @@ double magnesium_radio_ctrl_impl::set_tx_frequency(      UHD_ASSERT_THROW(adf4351_source == "internal");      double coerced_if_freq = freq; -    if (_map_freq_to_tx_band(freq) == tx_band::LOWBAND) { +    if (_map_freq_to_tx_band(_tx_band_map, freq) == tx_band::LOWBAND) {          _is_low_band[TX_DIRECTION]    = true;          const double desired_low_freq = MAGNESIUM_TX_IF_FREQ - freq;          coerced_if_freq = @@ -273,7 +273,7 @@ double magnesium_radio_ctrl_impl::set_rx_frequency(      UHD_ASSERT_THROW(adf4351_source == "internal");      double coerced_if_freq = freq; -    if (_map_freq_to_rx_band(freq) == rx_band::LOWBAND) { +    if (_map_freq_to_rx_band(_rx_band_map, freq) == rx_band::LOWBAND) {          _is_low_band[RX_DIRECTION]    = true;          const double desired_low_freq = MAGNESIUM_RX_IF_FREQ - freq;          coerced_if_freq = @@ -422,7 +422,7 @@ double magnesium_radio_ctrl_impl::_set_rx_gain(          this->get_rx_frequency(chan),          chan,          RX_DIRECTION); -    return clip_gain; // not really any coreced here (only clip) for individual gain +    return clip_gain; // not really any coerced here (only clip) for individual gain  }  double magnesium_radio_ctrl_impl::_get_rx_gain( @@ -698,6 +698,44 @@ std::string magnesium_radio_ctrl_impl::get_dboard_fe_from_chan(  } +void magnesium_radio_ctrl_impl::_remap_band_limits( +    const std::string band_map, const uhd::direction_t dir) +{ +    const size_t dflt_band_size = (dir == RX_DIRECTION) ? _rx_band_map.size() +                                                        : _tx_band_map.size(); + +    std::vector<std::string> band_map_split; +    double band_lim; + +    UHD_LOG_DEBUG(unique_id(), "Using user specified frequency band limits"); +    boost::split(band_map_split, band_map, boost::is_any_of(";")); +    if (band_map_split.size() != dflt_band_size) { +        throw uhd::runtime_error(( +            boost::format( +                "size %s of given frequency band map doesn't match the required size: %s") +            % band_map_split.size() % dflt_band_size) +                                     .str()); +    } +    UHD_LOG_DEBUG(unique_id(), "newly used band limits: "); +    for (size_t i = 0; i < band_map_split.size(); i++) { +        try { +            band_lim = std::stod(band_map_split.at(i)); +        } catch (...) { +            throw uhd::value_error( +                (boost::format("error while converting given frequency string %s " +                               "to a double value") +                    % band_map_split.at(i)) +                    .str()); +        } +        UHD_LOG_DEBUG(unique_id(), "band " << i << " limit: " << band_lim << "Hz"); +        if (dir == RX_DIRECTION) +            _rx_band_map.at(i) = band_lim; +        else +            _tx_band_map.at(i) = band_lim; +    } +} + +  void magnesium_radio_ctrl_impl::set_rpc_client(      uhd::rpc_client::sptr rpcc, const uhd::device_addr_t& block_args)  { @@ -719,6 +757,30 @@ void magnesium_radio_ctrl_impl::set_rpc_client(          _identify_with_leds(identify_duration);      } +    if (block_args.has_key("tx_gain_profile")) { +        UHD_LOG_INFO(unique_id(), +            "Using user specified TX gain profile: " << block_args.get( +                "tx_gain_profile")); +        _gain_profile[TX_DIRECTION] = block_args.get("tx_gain_profile"); +    } + +    if (block_args.has_key("rx_gain_profile")) { +        UHD_LOG_INFO(unique_id(), +            "Using user specified RX gain profile: " << block_args.get( +                "rx_gain_profile")); +        _gain_profile[RX_DIRECTION] = block_args.get("rx_gain_profile"); +    } + +    if (block_args.has_key("rx_band_map")) { +        UHD_LOG_INFO(unique_id(), "Using user specified RX band limits"); +        _remap_band_limits(block_args.get("rx_band_map"), RX_DIRECTION); +    } + +    if (block_args.has_key("tx_band_map")) { +        UHD_LOG_INFO(unique_id(), "Using user specified TX band limits"); +        _remap_band_limits(block_args.get("tx_band_map"), TX_DIRECTION); +    } +      // Note: MCR gets set during the init() call (prior to this), which takes      // in arguments from the device args. So if block_args contains a      // master_clock_rate key, then it should better be whatever the device is @@ -771,7 +833,7 @@ bool magnesium_radio_ctrl_impl::get_lo_lock_status(const direction_t dir)          _rpcc->request_with_token<bool>(_rpc_prefix + "get_ad9371_lo_lock", trx);      UHD_LOG_TRACE(unique_id(),          "AD9371 " << trx << " LO reports lock: " << (lo_lock ? "Yes" : "No")); -    if (lo_lock and _map_freq_to_rx_band(freq) == rx_band::LOWBAND) { +    if (lo_lock and _map_freq_to_rx_band(_rx_band_map, freq) == rx_band::LOWBAND) {          lo_lock =              lo_lock              && _rpcc->request_with_token<bool>(_rpc_prefix + "get_lowband_lo_lock", trx); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp index dcadb5dea..165e3c996 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp @@ -29,6 +29,8 @@ namespace uhd { namespace rfnoc {   *   * This daughterboard is used on the USRP N310 and N300.   */ + +  class magnesium_radio_ctrl_impl : public radio_ctrl_impl, public rpc_block_ctrl  {  public: @@ -50,6 +52,19 @@ public:      //! Frequency bands for TX. Bands are a function of the analog filter banks      enum class tx_band { INVALID_BAND, LOWBAND, BAND0, BAND1, BAND2, BAND3 }; +    typedef std::unordered_map<size_t, double> band_map_t; + +    band_map_t rx_band_map_dflt = {{0, 0.0}, +        {1, 430e6}, +        {2, 600e6}, +        {3, 1050e6}, +        {4, 1600e6}, +        {5, 2100e6}, +        {6, 2700e6}}; + +    band_map_t tx_band_map_dflt = { +        {0, 0.0}, {1, 723.17e6}, {2, 1623.17e6}, {3, 3323.17e6}}; +      /************************************************************************       * Structors       ***********************************************************************/ @@ -146,10 +161,10 @@ private:      //! Map a frequency in Hz to an rx_band value. Will return      //  rx_band::INVALID_BAND if the frequency is out of range. -    rx_band _map_freq_to_rx_band(const double freq); +    rx_band _map_freq_to_rx_band(const band_map_t band_map, const double freq);      //! Map a frequency in Hz to an tx_band value. Will return      //  tx_band::INVALID_BAND if the frequency is out of range. -    tx_band _map_freq_to_tx_band(const double freq); +    tx_band _map_freq_to_tx_band(const band_map_t band_map, const double freq);      /**************************************************************************       * Sensors @@ -179,6 +194,8 @@ private:      void _update_freq(const size_t chan, const uhd::direction_t dir); +    void _remap_band_limits(const std::string band_map, const uhd::direction_t dir); +      /**************************************************************************       * CPLD Controls (implemented in magnesium_radio_ctrl_cpld.cpp)       *************************************************************************/ @@ -207,6 +224,7 @@ private:          const std::string name,          const double freq,          const size_t chan); +      /**************************************************************************       * Private attributes       *************************************************************************/ @@ -289,6 +307,9 @@ private:      bool _rx_bypass_lnas = true;      bool _tx_bypass_amp  = true; +    band_map_t _rx_band_map = rx_band_map_dflt; +    band_map_t _tx_band_map = tx_band_map_dflt; +      //! TRX switch state of 2 channels      std::map<magnesium_cpld_ctrl::chan_sel_t, magnesium_cpld_ctrl::sw_trx_t> _sw_trx = {          {magnesium_cpld_ctrl::CHAN1, diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp index 422b07ebb..89db61428 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp @@ -28,7 +28,10 @@ constexpr char MAGNESIUM_DEFAULT_RX_ANTENNA[] = "RX2";  constexpr char MAGNESIUM_DEFAULT_TX_ANTENNA[] = "TX/RX";  //! Magnesium gain profile options -const std::vector<std::string> MAGNESIUM_GP_OPTIONS = {"manual", "default"}; +const std::vector<std::string> MAGNESIUM_GP_OPTIONS = {"manual", +    "default", +    "default_rf_filter_bypass_always_on", +    "default_rf_filter_bypass_always_off"};  } // namespace  //! Helper function to extract single value of port number. @@ -261,10 +264,11 @@ void magnesium_radio_ctrl_impl::_init_frontend_subtree(          });      subtree->create<std::vector<std::string>>(tx_fe_path / "gains/all/profile/options") -        .set({"manual", "default"}); +        .set(MAGNESIUM_GP_OPTIONS);      subtree->create<std::string>(tx_fe_path / "gains/all/profile/value")          .set_coercer([this](const std::string& profile) { +            // check if given profile is valid, otherwise use default profile              std::string return_profile = profile;              if (std::find(                      MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) @@ -300,6 +304,7 @@ void magnesium_radio_ctrl_impl::_init_frontend_subtree(      subtree->create<std::string>(rx_fe_path / "gains/all/profile/value")          .set_coercer([this](const std::string& profile) { +            // check if given profile is valid, otherwise use default profile              std::string return_profile = profile;              if (std::find(                      MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) | 
