diff options
author | Thomas Vogel <thomas.vogel@ni.com> | 2019-07-01 17:12:08 +0200 |
---|---|---|
committer | Brent Stapleton <brent.stapleton@ettus.com> | 2019-07-24 11:16:37 -0700 |
commit | e76988c579e5e154416d94c27be89bd5f6dc56fa (patch) | |
tree | fb4b9fc6ca91c8a3778b296b2890e3dd08e5252d /host | |
parent | 8b294082d4804198c45b0acb1ad6393e4f6ef0da (diff) | |
download | uhd-e76988c579e5e154416d94c27be89bd5f6dc56fa.tar.gz uhd-e76988c579e5e154416d94c27be89bd5f6dc56fa.tar.bz2 uhd-e76988c579e5e154416d94c27be89bd5f6dc56fa.zip |
n310: add capability to control RF filter bypass and freq.band limits
With the keywords "rx_gain_profile", "tx_gain_profile" and the new
values "default_bypass_always_off" and "default_bypass_always_on" the
customer can control whether the filter bypass shall be applied as
defined in the gain-table or whether to switch the bypass to ON or OFF
for all gains.
With the keywords "rx_band_map" and "tx_band_map" the user can define
custom frequency borders for the band mapping.
These new keywords can be used in the uhd.con, e.g.:
[type=n3xx]
rx_gain_profile=default_bypass_always_off
tx_gain_profile=default_bypass_always_on
rx_band_map=431e6;601e6;1051e6;1601e6;2101e6;2701e6
tx_band_map=723.18e6;1623.18e6;3323.18e6
Diffstat (limited to 'host')
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) |