EttusResearch / uhd

The USRP™ Hardware Driver Repository
http://uhd.ettus.com
Other
973 stars 653 forks source link

'MultiUSRP' object has no attribute 'get_user_settings_iface' Python #786

Open GillesC opened 3 days ago

GillesC commented 3 days ago

Issue Description

get_user_settings_iface is not an attribute of the MultiUSRP object in the Python API.

The user register key was provided in the address together with our custom FPGA image.

usrp = uhd.usrp.MultiUSRP(
            "enable_user_regs, fpga=usrp_b210_fpga_loopback_ctrl.bin, mode_n=integer"
        )

Setup Details

linux; GNU C++ version 8.3.0; Boost_106700; UHD_4.1.0.HEAD-0-g25d617ca

Expected Behavior

get_user_settings_iface to be an attribute of MultiUSRP, in order to write the user registers.

Alternatives

We are open to alternative means to write the user registers. Albeit, preferably in Python ;).

mbr0wn commented 2 days ago

This is a legit issue. @GillesC are you able to build UHD yourself? If so, I can give you a patch to try out. If you could give us feedback on if it works as if in C++, that would speed up the process of fixing this (this is not a high-priority issue for us right now, and we'd have to build a custom bitfile for testing).

Here's the patch:

From d34c8dafdac827d63dcff19b55097fa0e4376afe Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@ettus.com>
Date: Thu, 26 Sep 2024 09:53:14 +0200
Subject: [PATCH] python: Add bindings for (timed_)wb_iface and
 get_user_settings_iface()

This enables calling multi_usrp::get_user_settings_iface() from the
Python API. It also allows any other Python API in the future to access
wb_iface and timed_wb_iface.
---
 host/lib/types/types_python.hpp     | 13 +++++++++++++
 host/lib/usrp/multi_usrp_python.cpp |  4 ++++
 2 files changed, 17 insertions(+)

diff --git a/host/lib/types/types_python.hpp b/host/lib/types/types_python.hpp
index 3591174db..893ee1e05 100644
--- a/host/lib/types/types_python.hpp
+++ b/host/lib/types/types_python.hpp
@@ -12,6 +12,7 @@
 #include <uhd/types/dict.hpp>
 #include <uhd/types/direction.hpp>
 #include <uhd/types/stream_cmd.hpp>
+#include <uhd/types/wb_iface.hpp>
 #include <pybind11/stl.h>
 #include <map>
 #include <string>
@@ -137,6 +138,18 @@ void export_types(py::module& m)

         ;
+
+    py::class_<uhd::wb_iface>(m, "wb_iface")
+        .def("poke64", &uhd::wb_iface::poke64)
+        .def("peek64", &uhd::wb_iface::peek64)
+        .def("poke32", &uhd::wb_iface::poke32)
+        .def("peek32", &uhd::wb_iface::peek32)
+        .def("poke16", &uhd::wb_iface::poke16)
+        .def("peek16", &uhd::wb_iface::peek16);
+
+    py::class_<uhd::timed_wb_iface, uhd::wb_iface>(m, "timed_wb_iface")
+        .def("get_time", &uhd::timed_wb_iface::get_time)
+        .def("set_time", &uhd::timed_wb_iface::set_time);
 }

 #endif /* INCLUDED_UHD_TYPES_PYTHON_HPP */
diff --git a/host/lib/usrp/multi_usrp_python.cpp b/host/lib/usrp/multi_usrp_python.cpp
index 479a86dcd..a2d25fbef 100644
--- a/host/lib/usrp/multi_usrp_python.cpp
+++ b/host/lib/usrp/multi_usrp_python.cpp
@@ -197,6 +197,10 @@ void export_multi_usrp(py::module& m)
         .def("get_tx_filter_names"     , &multi_usrp::get_tx_filter_names)
         .def("get_tx_filter"           , &multi_usrp::get_tx_filter)
         .def("set_tx_filter"           , &multi_usrp::set_tx_filter)
+
+        // Low-level register access
+        .def("set_user_register"       , &multi_usrp::set_user_register, py::arg("addr"), py::arg("data"), py::arg("mboard") = ALL_MBOARDS)
+        .def("get_user_settings_iface" , &multi_usrp::get_user_settings_iface, py::arg("chan") = 0)
         // clang-format off
         ;
     // clang-format on
-- 
2.34.1
GillesC commented 2 days ago

I have patched and compiled, and it seems to work. I'll have to double-check, as I am not entirely sure our user register FPGA code is working. But it looks like it. So, I'll conclude that your changes worked.

Thanks! (I'll leave the issue open, till it is merged. Please close if you would rather close it now.)