The way how self-cal gets triggered and what can be done with it has
changed during the development of X440. This reflects these changes
and explains them.
This removes the ADC self-cal during X4xx bootup and when a new FPGA
bitfile was loaded because we now do this when the clocking
configuration was changed. This improves RF performance for X410 and
is required for the flexible sample rates of X440.
While the self-cal that is executed within a UHD session already had the
user-configurable parameters, this was not yet the case for this
stand-alone utility. This commit adds this.
With DPDK 21.11 installed at a non-standard path, the UHD build process failed
to find its shared libraries (librte_*.so) while linking libuhd.so. The
-l flags were passed to the linker as bare filenames, but the -L flag was not
passed to specify the library search path (although that information was
provided to cmake by pkg-config). This patch uses the full path to DPDK
libraries at link time instead of bare filenames, which fixes this case.
- Mention J400 and the ability to do GPIO on there
- Provide some examples on auto-MCR and its effects
- Add comments that changing MCR has ill effects on time synchronization
In GCC 13 release some C++ Standard Library headers no longer
include other headers that were being used internally.
This means some headers that were implicit, now need to be included
in C++ programs explicitly.
This includes <cstdint>, and therefore compile of uhd host with
gcc-13 is broken without explicitly including this header.
The benchmark_rate test for x440 would require more than the 1GbE connection at the minimum rate
Since devtests cannot require special cabling, skip this devtest on x440
To follow Xilinx' recommendations for self-cal usage this adds
startup_tile() to the cal_mode selection and we query if the cal_mode
was set properly. Since we do this, on the host side we allow the full
first Nyquist zone to be used for self-cal.
Exposes the following ADC self-cal parameters on X4xx devices to be used
in the argument string:
-cal_freq
-cal_dac_mux_i
-cal_dac_mux_q
-cal_tone_duration
-cal_ch_list
-cal_delay
When calling tx_waveforms.py with the --dram option, it will internally
use DramTransmitter and first upload the signal before transmitting it
from DRAM.
- Move the configuration of SPLL and MMCM into its own method
- In set_master_clock_rate(), call this with intermediate clock settings
if we decide that going direct from one clock setting to another would
cause harm/failures
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Before this commit, set_sync_source() would require the master clock
rate to be set after reclocking, but would pull it out of the
X4xxClockManager object (using the _master_clock_rates attribute). Now,
the new master clock rate is passed to set_sync_source() via the args
argument.
Note that it is still possible (for backward compat) to not provide
a new MCR, in which case the assumption is that the current MCR still
remains valid.
This avoids unnecessary statefulness of this function and fixes an issue
where during init(), external reference clock frequencies would be
validated against the wrong master clock rates.
This enables querying the converter rate through the sensor API:
```python
>>> U = uhd.usrp.MultiUSRP("type=x4xx")
>>> print(U.get_tx_sensor('rfdc_rate').to_real())
3000000000.0
```
This change ensures that ADC selfcal is triggered during session start
if the clocking was reconfigured. So it saves time if several
consecutive sessions are opened with always the same settings.
It also makes the ADC self cal run if in an open session either
set_clock_source(), set_time_source() or set_sync_source() are called
and a clock reconfiguration was triggered by that.
- Main fix: Append 'r' prefix to regex strings where necessary
- Fix some other linter issues that are considered poor practices
- Change line endings to unix
Subdev specs can now be iterated over in Python as in C++:
```python
specs = usrp.get_rx_subdev_spec(0)
for spec in specs:
print(spec.to_string())
```
This would previously fail, because Pybind11 did not know that the
subdev spec was iterable.
This allows TxStreamer.recv_async_msg() to return the metadata instead
of modifying it in-place. The old API is still available.
```python
md = tx_streamer.recv_async_msg(timeout) # Returns None or metadata
```
This also removes uncessary schedule triggers for other branches. The triggers
for those branches are contained in the version of this file in those branches.
This changes the default master clock rate for X440 to 368.64 MHz which
results in a converter rate of 2.94912 GSps which is in line with what
X410 uses.
The factory rfnoc_graph::make() did previously not make use of
rfnoc::detail::make_rfnoc_graph(), which it should have. The purpose of
make_rfnoc_graph() is to avoid creating the same rfnoc_graph twice, the
same way that uhd::device::make() avoids that.
For example, the following code would raise an exception:
```python
U1 = uhd.rfnoc.RfnocGraph("addr=192.168.10.2")
U2 = uhd.rfnoc.RfnocGraph("addr=192.168.10.2")
```
The reason is, it would try to create the same rfnoc_graph object twice,
but the underlying rfnoc_device would be shared between those graphs.
With this fix, UHD will identify the second call to rfnoc_graph::make()
as a duplicate, and return the same object from a cache of weak
pointers. This is the same mechanism that multi_usrp uses for the exact
same purpose. Note that multi_usrp, even with RFNoC devices, did not
suffer from this issue, because it always called directly into
make_rfnoc_graph().
As an advanced, and generally not recommended use case, this even allows
the following:
```python
U = uhd.usrp.MultiUSRP("addr=192.168.10.2")
G = uhd.rfnoc.RfnocGraph("addr=192.168.10.2")
```
This is in general not recommended, because it is possible to get the
MultiUSRP and RfnocGraph objects out of sync (in a normal MultiUSRP
operation, the multi_usrp object owns the rfnoc_graph object to avoid
just that). However, there are some possibly interesting corner cases
where having direct access to the underlying rfnoc_graph object can be
useful. One such case could be to create faux multi_usrp like object
using Python's introspection features.
Changes:
- X410 Honors the force_reinit flag now (like N310). When given, it will
force a reinit of all clocking settings.
- When master_clock_rate is not given, and nothing else changes, then
clocking configuration will be skipped. This shaves approx. 3s of
startup time and avoids issues that can occur during clocking
configuration.
- If anything changes, incl. clock/time source, then full clock
configuration is still done.
- Multi-tile sync is done in all cases, as that happens outside of init()