diff options
author | Martin Braun <martin.braun@ettus.com> | 2018-07-30 16:52:54 -0700 |
---|---|---|
committer | Brent Stapleton <bstapleton@g.hmc.edu> | 2018-10-11 17:54:23 -0700 |
commit | b66f3701a7c3c34b08f3e977c385f8343fa2c852 (patch) | |
tree | 612caff96a5e439d58f4b50f03c9d62a11547e6f /host/lib/usrp/multi_usrp.cpp | |
parent | bf3d9ac2f4574feccc6578bc3eb743e7be07f50f (diff) | |
download | uhd-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.cpp | 166 |
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) |