diff options
author | Martin Braun <martin.braun@ettus.com> | 2017-12-05 11:17:03 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-12-06 10:59:28 -0800 |
commit | 77adcffe0689f120fee71854ec0f627a32991f79 (patch) | |
tree | f53f89049a2e5f8f543ccf01139d2a37d27b6125 /host/lib | |
parent | 8a9da7c66aaec826e756ab2411b9d40aa3f1f10c (diff) | |
download | uhd-77adcffe0689f120fee71854ec0f627a32991f79.tar.gz uhd-77adcffe0689f120fee71854ec0f627a32991f79.tar.bz2 uhd-77adcffe0689f120fee71854ec0f627a32991f79.zip |
multi_usrp: Expose APIs for TX LO controls
Reviewed-By: Ashish Chaudhari <ashish@ettus.com>
Reviewed-By: Derek Kozel <derek.kozel@ettus.com>
Diffstat (limited to 'host/lib')
-rw-r--r-- | host/lib/usrp/multi_usrp.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 3dcfe3bd9..d7d925f3c 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -870,6 +870,9 @@ public: return _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "freq" / "range").get(); } + /************************************************************************** + * LO controls + *************************************************************************/ std::vector<std::string> get_rx_lo_names(size_t chan = 0){ std::vector<std::string> lo_names; if (_tree->exists(rx_rf_fe_root(chan) / "los")) { @@ -1035,6 +1038,223 @@ public: } } + std::vector<std::string> get_tx_lo_names(const size_t chan = 0){ + std::vector<std::string> lo_names; + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + for (const std::string &name : _tree->list(tx_rf_fe_root(chan) / "los")) { + lo_names.push_back(name); + } + } + return lo_names; + } + + void set_tx_lo_source( + const std::string &src, + const std::string &name = ALL_LOS, + const size_t chan = 0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (name == ALL_LOS) { + if (_tree->exists(tx_rf_fe_root(chan) / "los" / ALL_LOS)) { + // Special value ALL_LOS support atomically sets the source + // for all LOs + _tree->access<std::string>( + tx_rf_fe_root(chan) / "los" / ALL_LOS / + "source" / "value" + ).set(src); + } else { + for (const auto &n : _tree->list(tx_rf_fe_root(chan) / "los")) { + this->set_tx_lo_source(src, n, chan); + } + } + } else { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + _tree->access<std::string>( + tx_rf_fe_root(chan) / "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 get_tx_lo_source( + const std::string &name = ALL_LOS, + const size_t chan = 0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + return _tree->access<std::string>( + tx_rf_fe_root(chan) / "los" / name / "source" / "value" + ).get(); + } else { + throw uhd::runtime_error("Could not find LO stage " + name); + } + } else { + // If the daughterboard doesn't expose its LO(s) then it can only + // be internal + return "internal"; + } + } + + std::vector<std::string> get_tx_lo_sources( + const std::string &name = ALL_LOS, + const size_t chan = 0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (name == ALL_LOS) { + if (_tree->exists(tx_rf_fe_root(chan) / "los" / ALL_LOS)) { + // Special value ALL_LOS support atomically sets the source + // for all LOs + return _tree->access<std::vector<std::string>>( + tx_rf_fe_root(chan) / "los" / ALL_LOS / + "source" / "options" + ).get(); + } else { + return std::vector<std::string>(); + } + } else { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + return _tree->access< std::vector<std::string> >(tx_rf_fe_root(chan) / "los" / name / "source" / "options").get(); + } else { + throw uhd::runtime_error("Could not find LO stage " + name); + } + } + } else { + // If the daughterboard doesn't expose its LO(s) then it can only + // be internal + return std::vector<std::string>(1, "internal"); + } + } + + void set_tx_lo_export_enabled( + const bool enabled, + const std::string &name = ALL_LOS, + const size_t chan=0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (name == ALL_LOS) { + if (_tree->exists(tx_rf_fe_root(chan) / "los" / ALL_LOS)) { + //Special value ALL_LOS support atomically sets the source for all LOs + _tree->access<bool>(tx_rf_fe_root(chan) / "los" / ALL_LOS / "export").set(enabled); + } else { + for(const std::string &n: _tree->list(tx_rf_fe_root(chan) / "los")) { + this->set_tx_lo_export_enabled(enabled, n, chan); + } + } + } else { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + _tree->access<bool>(tx_rf_fe_root(chan) / "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 get_tx_lo_export_enabled( + const std::string &name = ALL_LOS, + const size_t chan = 0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + return _tree->access<bool>( + tx_rf_fe_root(chan) / "los" / name / "export" + ).get(); + } else { + throw uhd::runtime_error("Could not find LO stage " + name); + } + } else { + // If the daughterboard doesn't expose its LO(s), assume it cannot + // export + return false; + } + } + + double set_tx_lo_freq( + const double freq, + const std::string &name = ALL_LOS, + const size_t chan = 0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (name == ALL_LOS) { + throw uhd::runtime_error("LO frequency must be set for each " + "stage individually"); + } else { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + return _tree->access<double>( + tx_rf_fe_root(chan) / "los" / name / "freq" / "value" + ).set(freq).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 get_tx_lo_freq( + const std::string &name = ALL_LOS, + const size_t chan = 0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (name == ALL_LOS) { + throw uhd::runtime_error("LO frequency must be retrieved for " + "each stage individually"); + } else { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + return _tree->access<double>(tx_rf_fe_root(chan) / "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 + // its LO(s) + return _tree->access<double>( + tx_rf_fe_root(chan) / "freq" /" value" + ).get(); + } + } + + freq_range_t get_tx_lo_freq_range( + const std::string &name = ALL_LOS, + const size_t chan = 0 + ) { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + if (name == ALL_LOS) { + throw uhd::runtime_error("LO frequency range must be retrieved " + "for each stage individually"); + } else { + if (_tree->exists(tx_rf_fe_root(chan) / "los")) { + return _tree->access<freq_range_t>( + tx_rf_fe_root(chan) / "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 + // its LO(s) + return _tree->access<meta_range_t>( + tx_rf_fe_root(chan) / "freq" / "range" + ).get(); + } + } + + /************************************************************************** + * Gain control + *************************************************************************/ void set_rx_gain(double gain, const std::string &name, size_t chan){ /* Check if any AGC mode is enable and if so warn the user */ if (chan != ALL_CHANS) { |