aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/rfnoc/noc_block_make_args.hpp3
-rw-r--r--host/lib/include/uhdlib/rfnoc/chdr_ctrl_endpoint.hpp4
-rw-r--r--host/lib/include/uhdlib/rfnoc/clock_iface.hpp64
-rw-r--r--host/lib/include/uhdlib/rfnoc/ctrlport_endpoint.hpp5
-rw-r--r--host/lib/rfnoc/chdr_ctrl_endpoint.cpp8
-rw-r--r--host/lib/rfnoc/ctrlport_endpoint.cpp37
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);
}