diff options
-rw-r--r-- | host/include/uhd/rfnoc/noc_block_make_args.hpp | 3 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/chdr_ctrl_endpoint.hpp | 4 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/clock_iface.hpp | 64 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp | 5 | ||||
-rw-r--r-- | host/lib/rfnoc/chdr_ctrl_endpoint.cpp | 8 | ||||
-rw-r--r-- | host/lib/rfnoc/ctrlport_endpoint.cpp | 37 |
6 files changed, 98 insertions, 23 deletions
diff --git a/host/include/uhd/rfnoc/noc_block_make_args.hpp b/host/include/uhd/rfnoc/noc_block_make_args.hpp index 8a4b1f5ad..c9b530589 100644 --- a/host/include/uhd/rfnoc/noc_block_make_args.hpp +++ b/host/include/uhd/rfnoc/noc_block_make_args.hpp @@ -13,6 +13,7 @@ namespace uhd { namespace rfnoc { +class clock_iface; /*! Data structure to hold the arguments passed into the noc_block_base ctor * * We want to hide these from the user, so she can't futz around with them. @@ -35,6 +36,8 @@ struct noc_block_base::make_args_t //! Register interface to this block's register space register_iface::sptr reg_iface; + //! Clock interface object that is shared with the reg_iface + std::shared_ptr<clock_iface> clk_iface; //! The subtree for this block uhd::property_tree::sptr tree; }; diff --git a/host/lib/include/uhdlib/rfnoc/chdr_ctrl_endpoint.hpp b/host/lib/include/uhdlib/rfnoc/chdr_ctrl_endpoint.hpp index afaa22306..29f4da7c2 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_ctrl_endpoint.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_ctrl_endpoint.hpp @@ -38,8 +38,8 @@ public: virtual ctrlport_endpoint::sptr get_ctrlport_ep(uint16_t port, size_t buff_capacity, size_t max_outstanding_async_msgs, - double ctrl_clk_freq, - double timebase_freq) = 0; + const clock_iface& client_clk, + const clock_iface& timebase_clk) = 0; //! Returns the number of dropped packets due to misclassification virtual size_t get_num_drops() const = 0; diff --git a/host/lib/include/uhdlib/rfnoc/clock_iface.hpp b/host/lib/include/uhdlib/rfnoc/clock_iface.hpp new file mode 100644 index 000000000..807382f13 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/clock_iface.hpp @@ -0,0 +1,64 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_UHD_RFNOC_CLOCK_IFACE_HPP +#define INCLUDED_UHD_RFNOC_CLOCK_IFACE_HPP + +#include <uhd/config.hpp> +#include <atomic> +#include <string> + +namespace uhd { namespace rfnoc { + +class clock_iface +{ +public: + clock_iface(const std::string& name) : _name(name) + { + _is_running = false; + _freq = 0.0; + } + + clock_iface() = delete; + clock_iface(const clock_iface& rhs) = delete; + clock_iface(clock_iface&& rhs) = delete; + + clock_iface& operator=(const clock_iface& fraction) = delete; + + inline const std::string& get_name() const + { + return _name; + } + + inline bool is_running() const + { + return _is_running; + } + + inline void set_running(bool is_running) + { + _is_running = is_running; + } + + inline double get_freq() const + { + return _freq; + } + + inline void set_freq(double freq) + { + _freq = freq; + } + +private: + const std::string _name; + std::atomic<bool> _is_running; + std::atomic<double> _freq; +}; + +}} // namespace uhd::rfnoc + +#endif /* INCLUDED_UHD_RFNOC_CLOCK_IFACE_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp b/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp index d135f284c..00ebe38b9 100644 --- a/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp +++ b/host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp @@ -9,6 +9,7 @@ #include <uhd/rfnoc/register_iface.hpp> #include <uhdlib/rfnoc/chdr/chdr_types.hpp> +#include <uhdlib/rfnoc/clock_iface.hpp> #include <memory> namespace uhd { namespace rfnoc { @@ -51,8 +52,8 @@ public: uint16_t local_port, size_t buff_capacity, size_t max_outstanding_async_msgs, - double ctrl_clk_freq, - double timebase_freq); + const clock_iface& client_clk, + const clock_iface& timebase_clk); }; // class ctrlport_endpoint diff --git a/host/lib/rfnoc/chdr_ctrl_endpoint.cpp b/host/lib/rfnoc/chdr_ctrl_endpoint.cpp index cab90fb49..6ded83c0f 100644 --- a/host/lib/rfnoc/chdr_ctrl_endpoint.cpp +++ b/host/lib/rfnoc/chdr_ctrl_endpoint.cpp @@ -67,8 +67,8 @@ public: virtual ctrlport_endpoint::sptr get_ctrlport_ep(uint16_t port, size_t buff_capacity, size_t max_outstanding_async_msgs, - double ctrl_clk_freq, - double timebase_freq) + const clock_iface& client_clk, + const clock_iface& timebase_clk) { std::lock_guard<std::mutex> lock(_mutex); @@ -93,8 +93,8 @@ public: port, buff_capacity, max_outstanding_async_msgs, - ctrl_clk_freq, - timebase_freq); + client_clk, + timebase_clk); _endpoint_map.insert(std::make_pair(port, ctrlport_ep)); UHD_LOG_DEBUG("RFNOC", boost::format("Created ctrlport endpoint for port %d on EPID %d") % port diff --git a/host/lib/rfnoc/ctrlport_endpoint.cpp b/host/lib/rfnoc/ctrlport_endpoint.cpp index 69f45ab9e..d5f4ef98c 100644 --- a/host/lib/rfnoc/ctrlport_endpoint.cpp +++ b/host/lib/rfnoc/ctrlport_endpoint.cpp @@ -41,15 +41,15 @@ public: uint16_t local_port, size_t buff_capacity, size_t max_outstanding_async_msgs, - double ctrl_clk_freq, - double timebase_freq) + const clock_iface& client_clk, + const clock_iface& timebase_clk) : _handle_send(send_fcn) , _my_epid(my_epid) , _local_port(local_port) , _buff_capacity(buff_capacity) , _max_outstanding_async_msgs(max_outstanding_async_msgs) - , _ctrl_clk_freq(ctrl_clk_freq) - , _timebase_freq(timebase_freq) + , _client_clk(client_clk) + , _timebase_clk(timebase_clk) { } @@ -166,7 +166,7 @@ public: // Send request auto request = send_request_packet(OP_POLL, addr, - {data, mask, static_cast<uint32_t>(timeout.get_real_secs() * _ctrl_clk_freq)}, + {data, mask, static_cast<uint32_t>(timeout.to_ticks(_client_clk.get_freq()))}, timestamp, timeout_time); // Optionally wait for an ACK @@ -182,7 +182,7 @@ public: // Send request auto request = send_request_packet(OP_SLEEP, 0, - {static_cast<uint32_t>(duration.get_real_secs() * _ctrl_clk_freq)}, + {static_cast<uint32_t>(duration.to_ticks(_client_clk.get_freq()))}, uhd::time_spec_t::ASAP, timeout_time); // Optionally wait for an ACK @@ -313,10 +313,17 @@ private: { std::unique_lock<std::mutex> lock(_mutex); + if (!_client_clk.is_running()) { + throw uhd::system_error("Ctrlport client clock is not running"); + } + // Convert from uhd::time_spec to timestamp boost::optional<uint64_t> timestamp; if (time_spec != time_spec_t::ASAP) { - timestamp = time_spec.to_ticks(_timebase_freq); + if (!_timebase_clk.is_running()) { + throw uhd::system_error("Timebase clock is not running"); + } + timestamp = time_spec.to_ticks(_timebase_clk.get_freq()); } // Assemble the control payload @@ -428,10 +435,10 @@ private: const size_t _buff_capacity; //! The max number of outstanding async messages that a block can have at any time const size_t _max_outstanding_async_msgs; - //! The clock rate of the clock that drives the ctrlport endpoint - const double _ctrl_clk_freq; - //! The clock rate of the primary timebase used for timed commands - const double _timebase_freq; + //! The clock that drives the ctrlport endpoint + const clock_iface& _client_clk; + //! The clock that drives the timing logic for the ctrlport endpoint + const clock_iface& _timebase_clk; //! The function to call to handle an async message async_msg_callback_t _handle_async_msg = async_msg_callback_t(); @@ -458,14 +465,14 @@ ctrlport_endpoint::sptr ctrlport_endpoint::make(const send_fn_t& handle_send, uint16_t local_port, size_t buff_capacity, size_t max_outstanding_async_msgs, - double ctrl_clk_freq, - double timebase_freq) + const clock_iface& client_clk, + const clock_iface& timebase_clk) { return std::make_shared<ctrlport_endpoint_impl>(handle_send, this_epid, local_port, buff_capacity, max_outstanding_async_msgs, - ctrl_clk_freq, - timebase_freq); + client_clk, + timebase_clk); } |