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) | 
