aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/include/uhdlib
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-06-05 16:37:20 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:25 -0800
commit67ea15ad4b57c36f8b0dc80a87cf0ac16b585d34 (patch)
tree542b19787085fec32022cd8ef8d70def39885003 /host/lib/include/uhdlib
parentd420f4968f7bd78afa4f27aaf5abcf26d0f61f4c (diff)
downloaduhd-67ea15ad4b57c36f8b0dc80a87cf0ac16b585d34.tar.gz
uhd-67ea15ad4b57c36f8b0dc80a87cf0ac16b585d34.tar.bz2
uhd-67ea15ad4b57c36f8b0dc80a87cf0ac16b585d34.zip
rfnoc: add reg_iface_adapter
This converts from register_iface& to wb_iface::sptr. Useful for connecting new block controllers with older interfaces.
Diffstat (limited to 'host/lib/include/uhdlib')
-rw-r--r--host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp b/host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp
new file mode 100644
index 000000000..55153c229
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/reg_iface_adapter.hpp
@@ -0,0 +1,121 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_REG2WBIF_ADAPTER_HPP
+#define INCLUDED_LIBUHD_RFNOC_REG2WBIF_ADAPTER_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/rfnoc/register_iface.hpp>
+#include <uhd/types/wb_iface.hpp>
+#include <boost/make_shared.hpp>
+
+//! Convenience macro to generate a reg_iface_adapter from within an RFNoC block
+#define RFNOC_MAKE_WB_IFACE(BASE_OFFSET, CHAN) \
+ boost::make_shared<reg_iface_adapter>( \
+ [this]() -> register_iface& { return regs(); }, \
+ [this, chan = CHAN]() { return get_command_time(chan); }, \
+ [this, chan = CHAN]( \
+ const uhd::time_spec_t& time) { set_command_time(time, chan); }, \
+ BASE_OFFSET)
+
+namespace uhd { namespace rfnoc {
+
+/*! register_iface to wb_iface adapter
+ *
+ * From within a noc_block_base derivative, this call will work to create a
+ * wb_iface:
+ *
+ * wb_iface::sptr ctrl = boost::make_shared<reg_iface_adapter>(
+ * [this]() -> register_iface& { return regs(); }, offset);
+ *
+ * Or you use the macro:
+ * wb_iface::sptr ctrl = RFNOC_MAKE_WB_IFACE(offset, chan);
+ */
+class UHD_API reg_iface_adapter : public uhd::timed_wb_iface
+{
+public:
+ using regs_accessor_t = std::function<register_iface&(void)>;
+ using time_accessor_t = std::function<uhd::time_spec_t(void)>;
+ using time_setter_t = std::function<void(const uhd::time_spec_t&)>;
+
+ /*!
+ * \param regs_accessor Function object to retrieve the register_iface
+ * reference
+ * \param time_accessor Function object to get the current command time
+ * \param time_setter Function object to set the command time
+ * \param base_offset Base offset for all peeks and pokes. If base_offset
+ * is set to 0x80000, peek32(4) will poke 0x80004.
+ */
+ reg_iface_adapter(regs_accessor_t&& regs_accessor,
+ time_accessor_t&& time_accessor,
+ time_setter_t&& time_setter,
+ const uint32_t base_offset = 0)
+ : _regs_accessor(std::move(regs_accessor))
+ , _time_accessor(std::move(time_accessor))
+ , _time_setter(std::move(time_setter))
+ , _base_offset(base_offset)
+ {
+ // nop
+ }
+
+ /*! Timeless constructor: All command times will be executed ASAP, setting
+ * time does nothing
+ *
+ * \param regs_accessor Function object to retrieve the register_iface
+ * reference
+ * \param base_offset Base offset for all peeks and pokes. If base_offset
+ * is set to 0x80000, peek32(4) will poke 0x80004.
+ */
+ reg_iface_adapter(regs_accessor_t&& regs_accessor, const uint32_t base_offset = 0)
+ : _regs_accessor(std::move(regs_accessor))
+ , _time_accessor([]() { return uhd::time_spec_t::ASAP; })
+ , _time_setter([](const uhd::time_spec_t&) { /* nop */ })
+ , _base_offset(base_offset)
+ {
+ // nop
+ }
+
+ void poke32(const uhd::wb_iface::wb_addr_type addr, const uint32_t data)
+ {
+ _regs_accessor().poke32(_base_offset + addr, data, _time_accessor());
+ }
+
+ void poke64(const uhd::wb_iface::wb_addr_type addr, const uint64_t data)
+ {
+ _regs_accessor().poke64(_base_offset + addr, data, _time_accessor());
+ }
+
+ uint32_t peek32(const uhd::wb_iface::wb_addr_type addr)
+ {
+ return _regs_accessor().peek32(_base_offset + addr, _time_accessor());
+ }
+
+ uint64_t peek64(const uhd::wb_iface::wb_addr_type addr)
+ {
+ return _regs_accessor().peek64(_base_offset + addr, _time_accessor());
+ }
+
+ uhd::time_spec_t get_time(void)
+ {
+ return _time_accessor();
+ }
+
+ void set_time(const uhd::time_spec_t& t)
+ {
+ _time_setter(t);
+ }
+
+private:
+ regs_accessor_t _regs_accessor;
+ time_accessor_t _time_accessor;
+ time_setter_t _time_setter;
+ uint32_t _base_offset;
+};
+
+
+}} /* namespace uhd::rfnoc */
+
+#endif /* INCLUDED_LIBUHD_RFNOC_REG2WBIF_ADAPTER_HPP */