aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/multi_usrp.cpp
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2018-07-30 16:52:54 -0700
committerBrent Stapleton <bstapleton@g.hmc.edu>2018-10-11 17:54:23 -0700
commitb66f3701a7c3c34b08f3e977c385f8343fa2c852 (patch)
tree612caff96a5e439d58f4b50f03c9d62a11547e6f /host/lib/usrp/multi_usrp.cpp
parentbf3d9ac2f4574feccc6578bc3eb743e7be07f50f (diff)
downloaduhd-b66f3701a7c3c34b08f3e977c385f8343fa2c852.tar.gz
uhd-b66f3701a7c3c34b08f3e977c385f8343fa2c852.tar.bz2
uhd-b66f3701a7c3c34b08f3e977c385f8343fa2c852.zip
multi_usrp: Add sync_source API
The sync_source API is an atomic setter for all sync-related settings. If supported by the underlying USRP, it can be faster to call set_sync_source() rather than sequentially calling set_clock_source() and set_time_source(). If the underlying device does not support the sync_source API, it will fall back to the set_clock_source() and set_time_source() APIs, making this change backward-compatiple.
Diffstat (limited to 'host/lib/usrp/multi_usrp.cpp')
-rw-r--r--host/lib/usrp/multi_usrp.cpp166
1 files changed, 160 insertions, 6 deletions
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 4fb76cafa..019502ee7 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -722,7 +722,20 @@ public:
void set_time_source(const std::string &source, const size_t mboard){
if (mboard != ALL_MBOARDS){
- _tree->access<std::string>(mb_root(mboard) / "time_source" / "value").set(source);
+ const auto time_source_path =
+ mb_root(mboard) / "time_source/value";
+ const auto sync_source_path =
+ mb_root(mboard) / "sync_source/value";
+ if (_tree->exists(time_source_path)) {
+ _tree->access<std::string>(time_source_path).set(source);
+ } else if (_tree->exists(sync_source_path)) {
+ auto sync_source =
+ _tree->access<device_addr_t>(sync_source_path).get();
+ sync_source["time_source"] = source;
+ _tree->access<device_addr_t>(sync_source_path).set(sync_source);
+ } else {
+ throw uhd::runtime_error("Can't set time source on this device.");
+ }
return;
}
for (size_t m = 0; m < get_num_mboards(); m++){
@@ -731,16 +744,53 @@ public:
}
std::string get_time_source(const size_t mboard){
- return _tree->access<std::string>(mb_root(mboard) / "time_source" / "value").get();
+ const auto time_source_path = mb_root(mboard) / "time_source/value";
+ if (_tree->exists(time_source_path)) {
+ return _tree->access<std::string>(time_source_path).get();
+ } else if (_tree->exists(mb_root(mboard) / "sync_source/value")) {
+ auto sync_source = _tree->access<device_addr_t>(
+ mb_root(mboard) / "sync_source" / "value").get();
+ if (sync_source.has_key("time_source")) {
+ return sync_source.get("time_source");
+ }
+ }
+ throw uhd::runtime_error("Cannot query time_source on this device!");
}
std::vector<std::string> get_time_sources(const size_t mboard){
- return _tree->access<std::vector<std::string> >(mb_root(mboard) / "time_source" / "options").get();
+ const auto time_source_path = mb_root(mboard) / "time_source/options";
+ if (_tree->exists(time_source_path)) {
+ return _tree->access<std::vector<std::string>>(time_source_path)
+ .get();
+ } else if (_tree->exists(mb_root(mboard) / "sync_source/options")) {
+ const auto sync_sources = get_sync_sources(mboard);
+ std::vector<std::string> time_sources;
+ for (const auto& sync_source : sync_sources) {
+ if (sync_source.has_key("time_source")) {
+ time_sources.push_back(sync_source.get("time_source"));
+ }
+ }
+ }
+ throw uhd::runtime_error("Cannot query time_source on this device!");
}
void set_clock_source(const std::string &source, const size_t mboard){
if (mboard != ALL_MBOARDS){
- _tree->access<std::string>(mb_root(mboard) / "clock_source" / "value").set(source);
+ const auto clock_source_path =
+ mb_root(mboard) / "clock_source/value";
+ const auto sync_source_path =
+ mb_root(mboard) / "sync_source/value";
+ if (_tree->exists(clock_source_path)) {
+ _tree->access<std::string>(clock_source_path).set(source);
+ } else if (_tree->exists(sync_source_path)) {
+ auto sync_source =
+ _tree->access<device_addr_t>(sync_source_path).get();
+ sync_source["clock_source"] = source;
+ _tree->access<device_addr_t>(sync_source_path).set(sync_source);
+ } else {
+ throw uhd::runtime_error(
+ "Can't set clock source on this device.");
+ }
return;
}
for (size_t m = 0; m < get_num_mboards(); m++){
@@ -749,11 +799,115 @@ public:
}
std::string get_clock_source(const size_t mboard){
- return _tree->access<std::string>(mb_root(mboard) / "clock_source" / "value").get();
+ const auto clock_source_path = mb_root(mboard) / "clock_source/value";
+ if (_tree->exists(clock_source_path)) {
+ return _tree->access<std::string>(
+ mb_root(mboard) / "clock_source" / "value").get();
+ } else if (_tree->exists(mb_root(mboard) / "sync_source/value")) {
+ auto sync_source = _tree->access<device_addr_t>(
+ mb_root(mboard) / "sync_source" / "value").get();
+ if (sync_source.has_key("clock_source")) {
+ return sync_source.get("clock_source");
+ }
+ }
+ throw uhd::runtime_error("Cannot query clock_source on this device!");
+ }
+
+ void set_sync_source(
+ const std::string &clock_source,
+ const std::string &time_source,
+ const size_t mboard
+ ) {
+ device_addr_t sync_args;
+ sync_args["clock_source"] = clock_source;
+ sync_args["time_source"] = time_source;
+ set_sync_source(sync_args, mboard);
+ }
+
+ void set_sync_source(
+ const device_addr_t& sync_source,
+ const size_t mboard
+ ) {
+ if (mboard != ALL_MBOARDS) {
+ const auto sync_source_path =
+ mb_root(mboard) / "sync_source/value";
+ if (_tree->exists(sync_source_path)) {
+ _tree->access<device_addr_t>(sync_source_path)
+ .set(sync_source);
+ } else if (_tree->exists(mb_root(mboard) / "clock_source/value")
+ and _tree->exists(mb_root(mboard) / "time_source/value")
+ and sync_source.has_key("clock_source")
+ and sync_source.has_key("time_source")) {
+ const std::string clock_source = sync_source["clock_source"];
+ const std::string time_source = sync_source["time_source"];
+ set_clock_source(clock_source, mboard);
+ set_time_source(time_source, mboard);
+ } else {
+ throw uhd::runtime_error(
+ "Can't set sync source on this device.");
+ }
+ return;
+ }
+ for (size_t m = 0; m < get_num_mboards(); m++){
+ this->set_sync_source(sync_source, m);
+ }
+
+ }
+
+ device_addr_t get_sync_source(const size_t mboard)
+ {
+ const auto sync_source_path = mb_root(mboard) / "sync_source/value";
+ if (_tree->exists(sync_source_path)) {
+ return _tree->access<device_addr_t>(sync_source_path).get();
+ }
+ // If this path is not there, we fall back to the oldschool method and
+ // convert to a new-fangled sync source dictionary
+ const std::string clock_source = get_clock_source(mboard);
+ const std::string time_source = get_time_source(mboard);
+ device_addr_t sync_source;
+ sync_source["clock_source"] = clock_source;
+ sync_source["time_source"] = time_source;
+ return sync_source;
+ }
+
+ std::vector<device_addr_t> get_sync_sources(const size_t mboard)
+ {
+ const auto sync_source_path = mb_root(mboard) / "sync_source/options";
+ if (_tree->exists(sync_source_path)) {
+ return _tree->access<std::vector<device_addr_t>>(sync_source_path).get();
+ }
+ // If this path is not there, we fall back to the oldschool method and
+ // convert to a new-fangled sync source dictionary
+ const auto clock_sources = get_clock_sources(mboard);
+ const auto time_sources = get_time_sources(mboard);
+ std::vector<device_addr_t> sync_sources;
+ for (const auto& clock_source : clock_sources) {
+ for (const auto& time_source : time_sources) {
+ device_addr_t sync_source;
+ sync_source["clock_source"] = clock_source;
+ sync_source["time_source"] = time_source;
+ sync_sources.push_back(sync_source);
+ }
+ }
+
+ return sync_sources;
}
std::vector<std::string> get_clock_sources(const size_t mboard){
- return _tree->access<std::vector<std::string> >(mb_root(mboard) / "clock_source" / "options").get();
+ const auto clock_source_path = mb_root(mboard) / "clock_source/options";
+ if (_tree->exists(clock_source_path)) {
+ return _tree->access<std::vector<std::string>>(clock_source_path)
+ .get();
+ } else if (_tree->exists(mb_root(mboard) / "sync_source/options")) {
+ const auto sync_sources = get_sync_sources(mboard);
+ std::vector<std::string> clock_sources;
+ for (const auto& sync_source : sync_sources) {
+ if (sync_source.has_key("clock_source")) {
+ clock_sources.push_back(sync_source.get("clock_source"));
+ }
+ }
+ }
+ throw uhd::runtime_error("Cannot query clock_source on this device!");
}
void set_clock_source_out(const bool enb, const size_t mboard)