aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorThomas Vogel <thomas.vogel@ni.com>2019-07-01 17:12:08 +0200
committerBrent Stapleton <brent.stapleton@ettus.com>2019-07-24 11:16:37 -0700
commite76988c579e5e154416d94c27be89bd5f6dc56fa (patch)
treefb4b9fc6ca91c8a3778b296b2890e3dd08e5252d /host
parent8b294082d4804198c45b0acb1ad6393e4f6ef0da (diff)
downloaduhd-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')
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_bands.cpp33
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp4
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp31
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp70
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp25
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp9
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)