aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300
diff options
context:
space:
mode:
authorDerek Kozel <derek.kozel@ettus.com>2017-03-14 17:56:41 -0700
committerMartin Braun <martin.braun@ettus.com>2017-03-24 19:06:09 -0700
commit4d3572494e979bb94a929a0485813c0ba3fcc453 (patch)
treefa7f0fe771d0364c49a312f75e722da188d6f733 /host/lib/usrp/x300
parent51cbfdfd7e7c071914442005139894496ddf6039 (diff)
downloaduhd-4d3572494e979bb94a929a0485813c0ba3fcc453.tar.gz
uhd-4d3572494e979bb94a929a0485813c0ba3fcc453.tar.bz2
uhd-4d3572494e979bb94a929a0485813c0ba3fcc453.zip
RFNoC: Exposed LO sharing functions in radio block
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.cpp192
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.hpp13
2 files changed, 205 insertions, 0 deletions
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
index c84b2ba44..8692871b8 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
@@ -275,6 +275,198 @@ double x300_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan)
}
+std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_names(const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ std::vector<std::string> lo_names;
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ for(const std::string &name: _tree->list(rx_fe_fe_root / "los")) {
+ lo_names.push_back(name);
+ }
+ }
+ return lo_names;
+}
+
+std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_sources(const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
+ //Special value ALL_LOS support atomically sets the source for all LOs
+ return _tree->access< std::vector<std::string> >(rx_fe_fe_root / "los" / ALL_LOS / "source" / "options").get();
+ } else {
+ return std::vector<std::string>();
+ }
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ return _tree->access< std::vector<std::string> >(rx_fe_fe_root / "los" / name / "source" / "options").get();
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ // If the daughterboard doesn't expose it's LO(s) then it can only be internal
+ return std::vector<std::string> (1, "internal");
+ }
+}
+
+void x300_radio_ctrl_impl::set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
+ //Special value ALL_LOS support atomically sets the source for all LOs
+ _tree->access<std::string>(rx_fe_fe_root / "los" / ALL_LOS / "source" / "value").set(src);
+ } else {
+ for(const std::string &n: _tree->list(rx_fe_fe_root / "los")) {
+ this->set_rx_lo_source(src, n, chan);
+ }
+ }
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ _tree->access<std::string>(rx_fe_fe_root / "los" / name / "source" / "value").set(src);
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ throw uhd::runtime_error("This device does not support manual configuration of LOs");
+ }
+}
+
+const std::string x300_radio_ctrl_impl::get_rx_lo_source(const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ //Special value ALL_LOS support atomically sets the source for all LOs
+ return _tree->access<std::string>(rx_fe_fe_root / "los" / ALL_LOS / "source" / "value").get();
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ return _tree->access<std::string>(rx_fe_fe_root / "los" / name / "source" / "value").get();
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ // If the daughterboard doesn't expose it's LO(s) then it can only be internal
+ return "internal";
+ }
+}
+
+void x300_radio_ctrl_impl::set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
+ //Special value ALL_LOS support atomically sets the source for all LOs
+ _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export").set(enabled);
+ } else {
+ for(const std::string &n: _tree->list(rx_fe_fe_root / "los")) {
+ this->set_rx_lo_export_enabled(enabled, n, chan);
+ }
+ }
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ _tree->access<bool>(rx_fe_fe_root / "los" / name / "export").set(enabled);
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ throw uhd::runtime_error("This device does not support manual configuration of LOs");
+ }
+}
+
+bool x300_radio_ctrl_impl::get_rx_lo_export_enabled(const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ //Special value ALL_LOS support atomically sets the source for all LOs
+ return _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export").get();
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ return _tree->access<bool>(rx_fe_fe_root / "los" / name / "export").get();
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ // If the daughterboard doesn't expose it's LO(s), assume it cannot export
+ return false;
+ }
+}
+
+double x300_radio_ctrl_impl::set_rx_lo_freq(double freq, const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ throw uhd::runtime_error("LO frequency must be set for each stage individually");
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").set(freq);
+ return _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").get();
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ throw uhd::runtime_error("This device does not support manual configuration of LOs");
+ }
+}
+
+double x300_radio_ctrl_impl::get_rx_lo_freq(const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ throw uhd::runtime_error("LO frequency must be retrieved for each stage individually");
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ return _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").get();
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ // Return actual RF frequency if the daughterboard doesn't expose it's LO(s)
+ return _tree->access<double>(rx_fe_fe_root / "freq" /" value").get();
+ }
+}
+
+freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range(const std::string &name, const size_t chan)
+{
+ fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ if (name == ALL_LOS) {
+ throw uhd::runtime_error("LO frequency range must be retrieved for each stage individually");
+ } else {
+ if (_tree->exists(rx_fe_fe_root / "los")) {
+ return _tree->access<freq_range_t>(rx_fe_fe_root / "los" / name / "freq" / "range").get();
+ } else {
+ throw uhd::runtime_error("Could not find LO stage " + name);
+ }
+ }
+ } else {
+ // Return the actual RF range if the daughterboard doesn't expose it's LO(s)
+ return _tree->access<meta_range_t>(rx_fe_fe_root / "freq" / "range").get();
+ }
+}
+
template <typename map_type>
static size_t _get_chan_from_map(std::map<size_t, map_type> map, const std::string &fe)
{
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
index 80cd94215..27633fa9a 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
@@ -64,6 +64,19 @@ public:
double set_tx_gain(const double gain, const size_t chan);
double set_rx_gain(const double gain, const size_t chan);
+ std::vector<std::string> get_rx_lo_names(const size_t chan);
+ std::vector<std::string> get_rx_lo_sources(const std::string &name, const size_t chan);
+ freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan);
+
+ void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan);
+ const std::string get_rx_lo_source(const std::string &name, const size_t chan);
+
+ void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan);
+ bool get_rx_lo_export_enabled(const std::string &name, const size_t chan);
+
+ double set_rx_lo_freq(double freq, const std::string &name, const size_t chan);
+ double get_rx_lo_freq(const std::string &name, 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);