diff options
Diffstat (limited to 'host')
| -rw-r--r-- | host/include/uhd/usrp/multi_usrp.hpp | 51 | ||||
| -rw-r--r-- | host/lib/usrp/multi_usrp.cpp | 166 | 
2 files changed, 211 insertions, 6 deletions
diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index efb4b5eed..73fb58332 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -389,6 +389,57 @@ public:       */      virtual std::vector<std::string> get_clock_sources(const size_t mboard) = 0; +    /*! Set the reference/synchronization sources for the USRP device +     * +     * This is a shorthand for calling +     * `set_sync_source(device_addr_t("clock_source=$CLOCK_SOURCE,time_source=$TIME_SOURCE"))` +     * +     * \param clock_source A string representing the clock source +     * \param time_source A string representing the time source +     * \param mboard which motherboard to set the config +     * \throws uhd::value_error if the sources don't actually exist +     */ +    virtual void set_sync_source( +        const std::string &clock_source, +        const std::string &time_source, +        const size_t mboard = ALL_MBOARDS +    ) = 0; + +    /*! Set the reference/synchronization sources for the USRP device +     * +     * Typically, this will set both clock and time source in a single call. For +     * some USRPs, this may be significantly faster than calling +     * set_time_source() and set_clock_source() individually. +     * +     * Example: +     * ~~~{.cpp} +     * auto usrp = uhd::usrp::multi_usrp::make(""); +     * usrp->set_sync_source(device_addr_t("clock_source=external,time_source=external")); +     * ~~~ +     * +     * \param sync_source A dictionary representing the various source settings. +     * \param mboard which motherboard to set the config +     * \throws uhd::value_error if the sources don't actually exist +     */ +    virtual void set_sync_source( +        const device_addr_t& sync_source, +        const size_t mboard = ALL_MBOARDS +    ) = 0; + +    /*! Get the currently set sync source. +     * +     * \param mboard which motherboard to get the config +     * \return the dictionary representing the sync source settings +     */ +    virtual device_addr_t get_sync_source(const size_t mboard) = 0; + +    /*! Get a list of available sync sources +     * +     * \param mboard which motherboard to get the config +     * \return the dictionary representing the sync source settings +     */ +    virtual std::vector<device_addr_t> get_sync_sources(const size_t mboard) = 0; +      /*!       * Send the clock source to an output connector.       * This call is only applicable on devices with reference outputs. 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)  | 
