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()
Both stopping streams and overrun handling use the action interface of
RFNoC. This has the consequence/side effect that there can be scenarios
where attempts to stop a stream and overrun handling can interfere with
one another.
Consider the following scenario:
```python
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
stream_cmd.stream_now = True
rx_streamer.issue_stream_cmd(stream_cmd)
time.sleep(1) # Something slows down app, causes overrun
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.stop_cont)
rx_streamer.issue_stream_cmd(stream_cmd)
while metadata.error_code != uhd.types.RXMetadataErrorCode.timeout:
samps_read = rx_streamer.recv(recv_buffer, metadata)
```
If the RX rate is too much for the system to handle, then the following
can happen:
Because something caused an overrun to happen, the streamer is in
overrun handling mode. There is now a back-and-forth between the
streamer and the radio to get continuous streaming up and running again.
The stop command is not properly executed, causing the final loop to
never terminate.
This fix modifies the RX streamer to stop any overrun handling
perations if a stop-command was issued.
This script can be used to query which thresholds are seen as sufficient
for the ADC self-cal to work properly. Bigger deviations in these values
/may/ indicate problems with the device but should not be taken as the
ground truth.
Co-authored-by: Lars Amsel <lars.amsel@ni.com>