aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorMark Meserve <mark.meserve@ni.com>2017-09-01 15:21:29 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:04:01 -0800
commitb43ab2705bdd3a26d5bff012cfd54fbf6775ffb9 (patch)
tree642c567fdae357a0c7983b85a1637978f5ea4201 /host
parentf141f71180e397fa21d23385f154da138bef0a81 (diff)
downloaduhd-b43ab2705bdd3a26d5bff012cfd54fbf6775ffb9.tar.gz
uhd-b43ab2705bdd3a26d5bff012cfd54fbf6775ffb9.tar.bz2
uhd-b43ab2705bdd3a26d5bff012cfd54fbf6775ffb9.zip
N310: Updated controls for Mg daughterboard
- Adds most API calls - Adds prop tree nodes
Diffstat (limited to 'host')
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_magnesium.xml12
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp267
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp26
3 files changed, 234 insertions, 71 deletions
diff --git a/host/include/uhd/rfnoc/blocks/radio_magnesium.xml b/host/include/uhd/rfnoc/blocks/radio_magnesium.xml
index a67e2722f..aa9ae5a6a 100644
--- a/host/include/uhd/rfnoc/blocks/radio_magnesium.xml
+++ b/host/include/uhd/rfnoc/blocks/radio_magnesium.xml
@@ -37,24 +37,12 @@
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</sink>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </sink>
<source>
<name>out0</name>
<type>sc16</type>
<!--<vlen>$spp</vlen>-->
<!--<pkt_size>%vlen</pkt_size>-->
</source>
- <source>
- <name>out1</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </source>
</ports>
</nocblock>
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 cc51562aa..53d1f7dab 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
@@ -21,6 +21,7 @@
#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/transport/chdr.hpp>
#include <uhd/utils/math.hpp>
+#include <uhd/types/direction.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/make_shared.hpp>
#include <boost/format.hpp>
@@ -31,8 +32,18 @@ using namespace uhd::usrp;
using namespace uhd::rfnoc;
static const size_t IO_MASTER_RADIO = 0;
+
+// TODO: some of these values are duplicated in ad937x_device.cpp
static const double MAGNESIUM_TICK_RATE = 125e6; // Hz
static const double MAGNESIUM_RADIO_RATE = 125e6; // Hz
+static const double MAGNESIUM_MIN_FREQ = 300e6; // Hz
+static const double MAGNESIUM_MAX_FREQ = 6e9; // Hz
+static const double MAGNESIUM_MIN_RX_GAIN = 0.0; // dB
+static const double MAGNESIUM_MAX_RX_GAIN = 30.0; // dB
+static const double MAGNESIUM_RX_GAIN_STEP = 0.5;
+static const double MAGNESIUM_MIN_TX_GAIN = 0.0; // dB
+static const double MAGNESIUM_MAX_TX_GAIN = 41.95; // dB
+static const double MAGNESIUM_TX_GAIN_STEP = 0.05;
static const double MAGNESIUM_CENTER_FREQ = 2.5e9; // Hz
static const double MAGNESIUM_DEFAULT_GAIN = 0.0; // dB
static const double MAGNESIUM_DEFAULT_BANDWIDTH = 40e6; // Hz TODO: fix
@@ -69,6 +80,19 @@ std::string _get_which(direction_t dir, size_t chan)
return ss.str();
}
+fs_path magnesium_radio_ctrl_impl::_get_fe_path(size_t chan, direction_t dir)
+{
+ switch (dir)
+ {
+ case TX_DIRECTION:
+ return fs_path("dboards" / _radio_slot / "tx_frontends" / get_dboard_fe_from_chan(chan, TX_DIRECTION));
+ case RX_DIRECTION:
+ return fs_path("dboards" / _radio_slot / "rx_frontends" / get_dboard_fe_from_chan(chan, RX_DIRECTION));
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+}
+
UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(magnesium_radio_ctrl)
{
UHD_LOG_TRACE("MAGNESIUM", "magnesium_radio_ctrl_impl::ctor() ");
@@ -78,9 +102,9 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(magnesium_radio_ctrl)
const size_t num_rx_chans = get_output_ports().size();
- UHD_ASSERT_THROW(num_rx_chans == MAGNESIUM_NUM_RX_CHANS);
+ //UHD_ASSERT_THROW(num_rx_chans == MAGNESIUM_NUM_RX_CHANS);
const size_t num_tx_chans = get_input_ports().size();
- UHD_ASSERT_THROW(num_tx_chans == MAGNESIUM_NUM_TX_CHANS);
+ //UHD_ASSERT_THROW(num_tx_chans == MAGNESIUM_NUM_TX_CHANS);
UHD_LOG_TRACE("MAGNESIUM", "Setting tick rate to " << MAGNESIUM_TICK_RATE / 1e6 << " MHz");
radio_ctrl_impl::set_rate(MAGNESIUM_TICK_RATE);
@@ -104,56 +128,104 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(magnesium_radio_ctrl)
// For use with multi_usrp APIs etc.
// For legacy prop tree init:
// TODO: determine DB number
- fs_path fe_base = fs_path("dboards") / _radio_slot;
- std::vector<std::string> fe({ "rx_frontends" , "tx_frontends" });
- std::vector<std::string> ant({ "RX" , "TX" });
+ const fs_path fe_base = fs_path("dboards") / _radio_slot;
+ const std::vector<uhd::direction_t> dir({ RX_DIRECTION, TX_DIRECTION });
+ const std::vector<std::string> fe({ "rx_frontends", "tx_frontends" });
+ const std::vector<std::string> ant({ "RX" , "TX" });
+ const std::vector<size_t> num_chans({ MAGNESIUM_NUM_RX_CHANS , MAGNESIUM_NUM_TX_CHANS });
+ const size_t RX_IDX = 0, TX_IDX = 1;
- UHD_ASSERT_THROW(MAGNESIUM_NUM_RX_CHANS == MAGNESIUM_NUM_TX_CHANS);
for (size_t fe_idx = 0; fe_idx < fe.size(); ++fe_idx)
{
- fs_path fe_direction_path = fe_base / fe[fe_idx];
- for (size_t chan = 0; chan < MAGNESIUM_NUM_RX_CHANS; ++chan) {
- fs_path fe_path = fe_direction_path / chan;
+ const fs_path fe_direction_path = fe_base / fe[fe_idx];
+ for (size_t chan = 0; chan < num_chans[fe_idx]; ++chan)
+ {
+ const fs_path fe_path = fe_direction_path / chan;
UHD_LOG_TRACE("MAGNESIUM", "Adding FE at " << fe_path);
+ // Shared TX/RX attributes
_tree->create<std::string>(fe_path / "name")
.set(str(boost::format("Magnesium %s %d") % ant[fe_idx] % chan))
;
_tree->create<std::string>(fe_path / "connection")
.set("IQ")
;
- // TODO: fix antenna name
- _tree->create<std::string>(fe_path / "antenna" / "value")
- .set(str(boost::format("%s%d") % ant[fe_idx] % (chan+1)))
- .add_coerced_subscriber(boost::bind(&magnesium_radio_ctrl_impl::set_rx_antenna, this, _1, chan))
- .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_antenna, this, chan))
- ;
- _tree->create<std::vector<std::string>>(fe_path / "antenna" / "options")
- .set(std::vector<std::string>(1, str(boost::format("%s%d") % ant[fe_idx] % (chan + 1))))
- ;
- _tree->create<double>(fe_path / "freq" / "value")
- .set(MAGNESIUM_CENTER_FREQ)
- .set_coercer(boost::bind(&magnesium_radio_ctrl_impl::set_rx_frequency, this, _1, chan))
- .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_frequency, this, chan))
- ;
- _tree->create<meta_range_t>(fe_path / "freq" / "range")
- .set(meta_range_t(MAGNESIUM_CENTER_FREQ, MAGNESIUM_CENTER_FREQ))
- ;
- _tree->create<double>(fe_path / "gains" / "null" / "value")
- .set(MAGNESIUM_DEFAULT_GAIN)
- .set_coercer(boost::bind(&magnesium_radio_ctrl_impl::set_rx_gain, this, _1, chan))
- .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_gain, this, chan))
- ;
- _tree->create<meta_range_t>(fe_path / "gains" / "null" / "range")
- .set(meta_range_t(MAGNESIUM_DEFAULT_GAIN, MAGNESIUM_DEFAULT_GAIN))
- ;
- _tree->create<double>(fe_path / "bandwidth" / "value")
- .set(MAGNESIUM_DEFAULT_BANDWIDTH)
- .set_coercer(boost::bind(&magnesium_radio_ctrl_impl::set_rx_bandwidth, this, _1, chan))
- .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_bandwidth, this, chan))
- ;
+ {
+ // TODO: fix antenna name
+ // Now witness the firepower of this fully armed and operational lambda
+ auto coerced_lambda = [this, chan, dir = dir[fe_idx]](const std::string &ant)
+ {
+ return this->_set_antenna(ant, chan, dir);
+ };
+ auto publisher_lambda = [this, chan, dir = dir[fe_idx]]()
+ {
+ return this->_get_antenna(chan, dir);
+ };
+ _tree->create<std::string>(fe_path / "antenna" / "value")
+ .set(str(boost::format("%s%d") % ant[fe_idx] % (chan + 1)))
+ .add_coerced_subscriber(coerced_lambda)
+ .set_publisher(publisher_lambda);
+ // TODO: fix options
+ _tree->create<std::vector<std::string>>(fe_path / "antenna" / "options")
+ .set(std::vector<std::string>(1, str(boost::format("%s%d") % ant[fe_idx] % (chan + 1))));
+ }
+ {
+ auto coerced_lambda = [this, chan, dir = dir[fe_idx]](const double freq)
+ {
+ return this->_set_frequency(freq, chan, dir);
+ };
+ auto publisher_lambda = [this, chan, dir = dir[fe_idx]]()
+ {
+ return this->_get_frequency(chan, dir);
+ };
+ _tree->create<double>(fe_path / "freq" / "value")
+ .set(MAGNESIUM_CENTER_FREQ)
+ .set_coercer(coerced_lambda)
+ .set_publisher(publisher_lambda);
+ _tree->create<meta_range_t>(fe_path / "freq" / "range")
+ .set(meta_range_t(MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ));
+ }
+ {
+ auto coerced_lambda = [this, chan, dir = dir[fe_idx]](const double gain)
+ {
+ return this->_set_gain(gain, chan, dir);
+ };
+ auto publisher_lambda = [this, chan, dir = dir[fe_idx]]()
+ {
+ return this->_get_gain(chan, dir);
+ };
+ auto min_gain = (fe_idx == RX_IDX) ? MAGNESIUM_MIN_RX_GAIN : MAGNESIUM_MIN_TX_GAIN;
+ auto max_gain = (fe_idx == RX_IDX) ? MAGNESIUM_MAX_RX_GAIN : MAGNESIUM_MAX_TX_GAIN;
+ auto gain_step = (fe_idx == RX_IDX) ? MAGNESIUM_RX_GAIN_STEP : MAGNESIUM_TX_GAIN_STEP;
+ // TODO: change from null
+ _tree->create<double>(fe_path / "gains" / "null" / "value")
+ .set(MAGNESIUM_DEFAULT_GAIN)
+ .set_coercer(coerced_lambda)
+ .set_publisher(publisher_lambda);
+ _tree->create<meta_range_t>(fe_path / "gains" / "null" / "range")
+ .set(meta_range_t(min_gain, max_gain, gain_step));
+ }
+ // TODO: set up read/write of bandwidth properties correctly
+ if (fe_idx == RX_IDX)
+ {
+ auto coerced_lambda = [this, chan](const double bw)
+ {
+ return this->set_rx_bandwidth(bw, chan);
+ };
+ auto publisher_lambda = [this, chan]()
+ {
+ return this->get_rx_bandwidth(chan);
+ };
+ _tree->create<double>(fe_path / "bandwidth" / "value")
+ .set(MAGNESIUM_DEFAULT_BANDWIDTH)
+ .set_coercer(coerced_lambda)
+ .set_publisher(publisher_lambda);
+ }
+ else {
+ _tree->create<double>(fe_path / "bandwidth" / "value")
+ .set(MAGNESIUM_DEFAULT_BANDWIDTH);
+ }
_tree->create<meta_range_t>(fe_path / "bandwidth" / "range")
- .set(meta_range_t(MAGNESIUM_DEFAULT_BANDWIDTH, MAGNESIUM_DEFAULT_BANDWIDTH))
- ;
+ .set(meta_range_t(MAGNESIUM_DEFAULT_BANDWIDTH, MAGNESIUM_DEFAULT_BANDWIDTH));
}
}
@@ -187,32 +259,27 @@ double magnesium_radio_ctrl_impl::set_rate(double rate)
void magnesium_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan)
{
- // TODO: implement
- UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set Tx antenna");
- // CPLD control?
+ _set_antenna(ant, chan, TX_DIRECTION);
}
void magnesium_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t chan)
{
- // TODO: implement
- UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set Rx antenna");
- // CPLD control?
+ _set_antenna(ant, chan, RX_DIRECTION);
}
double magnesium_radio_ctrl_impl::set_tx_frequency(const double freq, const size_t chan)
{
- return _set_freq(freq, chan, TX_DIRECTION);
+ return _set_frequency(freq, chan, TX_DIRECTION);
}
double magnesium_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan)
{
- return _set_freq(freq, chan, RX_DIRECTION);
+ return _set_frequency(freq, chan, RX_DIRECTION);
}
double magnesium_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan)
{
- // TODO: implement
- return get_rx_bandwidth(chan);
+ return _set_bandwidth(bandwidth, chan, RX_DIRECTION);
}
double magnesium_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan)
@@ -225,15 +292,50 @@ double magnesium_radio_ctrl_impl::set_rx_gain(const double gain, const size_t ch
return _set_gain(gain, chan, RX_DIRECTION);
}
+std::string magnesium_radio_ctrl_impl::get_tx_antenna(const size_t chan) /* const */
+{
+ return _get_antenna(chan, TX_DIRECTION);
+}
+
+std::string magnesium_radio_ctrl_impl::get_rx_antenna(const size_t chan) /* const */
+{
+ return _get_antenna(chan, RX_DIRECTION);
+}
+
+double magnesium_radio_ctrl_impl::get_tx_frequency(const size_t chan) /* const */
+{
+ return _get_frequency(chan, TX_DIRECTION);
+}
+
+double magnesium_radio_ctrl_impl::get_rx_frequency(const size_t chan) /* const */
+{
+ return _get_frequency(chan, RX_DIRECTION);
+}
+
+double magnesium_radio_ctrl_impl::get_tx_gain(const size_t chan) /* const */
+{
+ return _get_gain(chan, TX_DIRECTION);
+}
+
+double magnesium_radio_ctrl_impl::get_rx_gain(const size_t chan) /* const */
+{
+ return _get_gain(chan, RX_DIRECTION);
+}
+
+double magnesium_radio_ctrl_impl::get_rx_bandwidth(const size_t chan) /* const */
+{
+ return _get_bandwidth(chan, RX_DIRECTION);
+}
+
size_t magnesium_radio_ctrl_impl::get_chan_from_dboard_fe(const std::string &fe, const direction_t dir)
{
- UHD_LOG_TRACE("MAGNESIUM", "get_chan_from_dboard_fe " << fe << " returns " << boost::lexical_cast<size_t>(fe));
+ // UHD_LOG_TRACE("MAGNESIUM", "get_chan_from_dboard_fe " << fe << " returns " << boost::lexical_cast<size_t>(fe));
return boost::lexical_cast<size_t>(fe);
}
std::string magnesium_radio_ctrl_impl::get_dboard_fe_from_chan(const size_t chan, const direction_t dir)
{
- UHD_LOG_TRACE("MAGNESIUM", "get_dboard_fe_from_chan " << chan << " returns " << std::to_string(chan));
+ // UHD_LOG_TRACE("MAGNESIUM", "get_dboard_fe_from_chan " << chan << " returns " << std::to_string(chan));
return std::to_string(chan);
}
@@ -251,18 +353,71 @@ void magnesium_radio_ctrl_impl::set_rpc_client(
_block_args = block_args;
}
-double magnesium_radio_ctrl_impl::_set_freq(const double freq, const size_t chan, const direction_t dir)
+double magnesium_radio_ctrl_impl::_set_frequency(const double freq, const size_t chan, const direction_t dir)
{
+ // TODO: there is only one LO per RX or TX, so changing frequency will affect the adjacent channel in the same direction
+ // Update the adjacent channel when this occurs
auto which = _get_which(dir, chan);
UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "set_freq on " << which << " with " << freq);
- return _rpcc->request_with_token<double>(_slot_prefix + "set_freq", which, freq, false);
+ auto retval = _rpcc->request_with_token<double>(_slot_prefix + "set_freq", which, freq, false);
+ UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "set_freq returned " << retval);
+ return retval;
}
double magnesium_radio_ctrl_impl::_set_gain(const double gain, const size_t chan, const direction_t dir)
{
auto which = _get_which(dir, chan);
UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "set_gain on " << which << " with " << gain);
- return _rpcc->request_with_token<double>(_slot_prefix + "set_gain", which, gain);
+ auto retval = _rpcc->request_with_token<double>(_slot_prefix + "set_gain", which, gain);
+ UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "set_gain returned " << retval);
+ return retval;
+}
+
+void magnesium_radio_ctrl_impl::_set_antenna(const std::string &ant, const size_t chan, const direction_t dir)
+{
+ // TODO: implement
+ UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set antenna");
+ // CPLD control?
+}
+
+double magnesium_radio_ctrl_impl::_set_bandwidth(const double bandwidth, const size_t chan, const direction_t dir)
+{
+ // TODO: implement
+ UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set bandwidth");
+ return get_rx_bandwidth(chan);
+}
+
+double magnesium_radio_ctrl_impl::_get_frequency(const size_t chan, const direction_t dir)
+{
+ auto which = _get_which(dir, chan);
+ UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "get_freq on " << which);
+ auto retval = _rpcc->request_with_token<double>(_slot_prefix + "get_freq", which);
+ UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "get_freq returned " << retval);
+ return retval;
+}
+
+double magnesium_radio_ctrl_impl::_get_gain(const size_t chan, const direction_t dir)
+{
+ auto which = _get_which(dir, chan);
+ UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "get_gain on " << which);
+ auto retval = _rpcc->request_with_token<double>(_slot_prefix + "get_gain", which);
+ UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "get_gain returned " << retval);
+ return retval;
+}
+
+std::string magnesium_radio_ctrl_impl::_get_antenna(const size_t chan, const direction_t dir)
+{
+ // TODO: implement
+ UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to get antenna");
+ return "RX1";
+ // CPLD control?
+}
+
+double magnesium_radio_ctrl_impl::_get_bandwidth(const size_t chan, const direction_t dir)
+{
+ // TODO: implement
+ UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to get bandwidth");
+ return MAGNESIUM_DEFAULT_BANDWIDTH;
}
UHD_RFNOC_BLOCK_REGISTER(magnesium_radio_ctrl, "MagnesiumRadio");
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 0bb1b26b8..9535be824 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
@@ -54,6 +54,16 @@ public:
double set_tx_gain(const double gain, const size_t chan);
double set_rx_gain(const double gain, const size_t chan);
+ std::string get_tx_antenna(const size_t chan);
+ std::string get_rx_antenna(const size_t chan);
+
+ double get_tx_frequency(const size_t chan);
+ double get_rx_frequency(const size_t chan);
+ double get_rx_bandwidth(const size_t chan);
+
+ double get_tx_gain(const size_t chan);
+ double get_rx_gain(const size_t chan);
+
size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t dir);
std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir);
@@ -65,11 +75,21 @@ public:
);
private:
- double _set_freq(const double freq, const size_t chan, const direction_t dir);
- double _set_gain(const double gain, const size_t chan, const direction_t dir);
-
std::string _radio_slot;
std::string _slot_prefix;
+
+ fs_path _get_fe_path(size_t chan, direction_t dir);
+
+ double _set_frequency(const double freq, const size_t chan, const direction_t dir);
+ double _set_gain(const double gain, const size_t chan, const direction_t dir);
+ void _set_antenna(const std::string &ant, const size_t chan, const direction_t dir);
+ double _set_bandwidth(const double bandwidth, const size_t chan, const direction_t dir);
+
+ double _get_frequency(const size_t chan, const direction_t dir);
+ double _get_gain(const size_t chan, const direction_t dir);
+ std::string _get_antenna(const size_t chan, const direction_t dir);
+ double _get_bandwidth(const size_t chan, const direction_t dir);
+
//! Additional block args; gets set during set_rpc_client()
uhd::device_addr_t _block_args;