rfnoc: python: Expose ref_clk_calibration feature

This enables the ref_clk_calibration_iface discoverable feature in
Python. It can be used like this:

```python
mb_ctrl = graph.get_mb_controller(0)
ref_cal = mb_ctrl.get_ref_clk_calibration()
ref_cal.set_ref_clk_tuning_word(0x24a)
word = ref_cal.get_ref_clk_tuning_word()
ref_cal.store_ref_clk_tuning_word(word)
```

This feature is also exposed as a devtest.
This commit is contained in:
Martin Braun 2026-05-22 19:59:20 +02:00 committed by Martin Braun
parent 9fb2a5dfc2
commit 8f6e756608
5 changed files with 49 additions and 0 deletions

View File

@ -11,6 +11,7 @@
#include <uhd/features/discoverable_feature.hpp>
#include <uhd/features/gpio_power_iface.hpp>
#include <uhd/features/gps_iface.hpp>
#include <uhd/features/ref_clk_calibration_iface.hpp>
#include <uhd/rfnoc/block_id.hpp>
#include <uhd/rfnoc/filter_node.hpp>
#include <uhd/rfnoc/graph_edge.hpp>
@ -280,6 +281,14 @@ void export_rfnoc(py::module& m)
.def("get_sensors", &uhd::features::gps_iface::get_sensors)
.def("send_cmd", &uhd::features::gps_iface::send_cmd);
py::class_<uhd::features::ref_clk_calibration_iface>(m, "ref_clk_calibration")
.def("set_ref_clk_tuning_word",
&uhd::features::ref_clk_calibration_iface::set_ref_clk_tuning_word)
.def("get_ref_clk_tuning_word",
&uhd::features::ref_clk_calibration_iface::get_ref_clk_tuning_word)
.def("store_ref_clk_tuning_word",
&uhd::features::ref_clk_calibration_iface::store_ref_clk_tuning_word);
py::class_<detail::filter_node>(m, "filter_node")
.def("get_rx_filter_names", &detail::filter_node::get_rx_filter_names)
.def("get_rx_filter", &detail::filter_node::get_rx_filter)
@ -331,6 +340,12 @@ void export_rfnoc(py::module& m)
[](mb_controller& self) {
return &self.get_feature<uhd::features::gps_iface>();
},
py::return_value_policy::reference_internal)
.def(
"get_ref_clk_calibration",
[](mb_controller& self) {
return &self.get_feature<uhd::features::ref_clk_calibration_iface>();
},
py::return_value_policy::reference_internal);
py::class_<timekeeper, PyTimekeeper, timekeeper::sptr>(m, "timekeeper")

View File

@ -131,3 +131,4 @@ from list_sensors_test import ListSensorsTest
from python_api_test import UhdPythonApiTest
from rx_multi_spc_timed_commands_test import RxMultiSpcTimedCommandsTest
from tx_multi_spc_timed_commands_test import TxMultiSpcTimedCommandsTest
from ref_clk_calibration_test import RefClkCalibrationTest

View File

@ -90,3 +90,4 @@ from list_sensors_test import ListSensorsTest
from python_api_test import UhdPythonApiTest
from rx_multi_spc_timed_commands_test import RxMultiSpcTimedCommandsTest
from tx_multi_spc_timed_commands_test import TxMultiSpcTimedCommandsTest
from ref_clk_calibration_test import RefClkCalibrationTest

View File

@ -67,5 +67,6 @@ from list_sensors_test import ListSensorsTest
from python_api_test import UhdPythonApiTest
from rx_multi_spc_timed_commands_test import RxMultiSpcTimedCommandsTest
from tx_multi_spc_timed_commands_test import TxMultiSpcTimedCommandsTest
from ref_clk_calibration_test import RefClkCalibrationTest
from trigger_test import TxTriggerTest

View File

@ -0,0 +1,31 @@
#!/usr/bin/env python3
#
# Copyright 2026 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
"""Test the ref_clk_calibration feature."""
from uhd_test_base import UHDPythonTestCase
class RefClkCalibrationTest(UHDPythonTestCase):
"""Test ref_clk_calibration feature.
Reads the current tuning word and writes it back. Does not call
store_ref_clk_tuning_word to avoid modifying EEPROM during the test.
"""
test_name = "RefClkCalibrationTest"
def run_test(self, test_name, test_args):
"""Run test and report results."""
import uhd
usrp = uhd.usrp.MultiUSRP(self.args_str)
ref_cal = usrp.get_mb_controller().get_ref_clk_calibration()
word = ref_cal.get_ref_clk_tuning_word()
self.log.info("Current ref_clk tuning word: 0x%X", word)
ref_cal.set_ref_clk_tuning_word(word)
return {"passed": True}