Some blocks (e.g., the fosphor block) don't have parameters in their
respective YAMLs, but the GRC file importer makes the assumption that
there are always parameters, and will crash on a faulty dictionary
lookup when that's not the case. This conditionally checks parameters,
making the lack of parameters non-fatal.
Introduce 64-bit SPI transaction methods into the common spi_iface API,
default implementation throws an uhd::unsupported_operation exception.
Add explicit 32-bit aliases for the old/existing SPI transactions
methods.
Expose the width-specific operations through the RFNoC Python bindings.
msg_task_impl's constructor waits on _start_cv until _running is set,
checking the predicate under _mutex. task_loop() set _running and
called notify_one() without taking _mutex, so a notification sent
after the constructor had checked the predicate but before it started
to wait was lost, and the constructor then blocked forever.
The condition-variable handshake replaced a boost::barrier, which
cannot lose a wakeup, in 3855516f6f ("lib: Remove boost::thread usage
from USB transports"), so UHD 4.10.0.0 and 4.11.0.0 are affected. On
a B210 the hang leaves b200_impl's constructor blocked in
msg_task::make() right after "Operating over USB 3.". It shows up
most when the device is opened at a real-time priority, as SDR
applications that raise their priority before opening the device do.
Set _running while holding _mutex, then notify.
RFNoC's `multi_usrp` did not fully propagate `set_master_clock_rate()`
to the DUC/DDC chain.
Before this change, `set_master_clock_rate()` updated only the radio
rate. If a channel had a DUC or DDC, the adjacent converter rate was
left stale:
- TX: the DUC output rate was not updated to the new radio rate
- RX: the DDC input rate was not updated to the new radio rate
That caused follow-up `set_tx_rate()` / `set_rx_rate()` calls on the
same `multi_usrp` object to operate on outdated DUC/DDC state. In
practice, after changing the master clock, setting the channel sample
rate could be coerced unexpectedly because interpolation/decimation was
derived from the old converter-side rate.
This change updates `multi_usrp_rfnoc` so that `set_master_clock_rate()`:
- propagates the new radio rate to the attached DUC/DDC
- reapplies the previously requested per-channel TX/RX rate so the
DUC/DDC continues to follow the user-requested sample rate
Note that property propagation by itself is insufficient here, because
multi_usrp_rfnoc caches RX and TX rates, and these caches require
manual updating.
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Add nib310rio-dev to the Debian build dependencies so the UHD package
build fails if the B310 userspace header is unavailable instead of
silently disabling B300 support.
The Ubuntu installer pipeline downloads the nib310rio Debian package
artifact and exposes it to pbuilder as a local apt repository. This lets
pbuilder satisfy the new dependency inside the clean build root where
CMake checks for nib310rio/nib310rio.h.
Because X440 images now can also contain DDC/DUC we cannot direct
connect the radio with the replay block anymore. Instead we have
to rely on the uhd.rfnoc util connect_through_blocks function
which will find a route through the statically connected DDC/DUC
if they are present or connect the SEPs directly if they are not.
rfnoc_rx_replay_samples_to_file.py could hang and then abort with
"Timeout while loading replay buffer!" whenever the requested sample
rate was not an integer divisor of the master clock rate. For example,
requesting 200 Msps at an MCR of 368.64 MHz would leave the record
buffer stuck at exactly 50% fullness.
Two problems combined to cause this:
First, the rate was read back from the DDC before the graph was
committed. At that point the DDC's input sample rate property is not
yet valid, so set_output_rate() falls back to setting the output edge
property and returns the uncoerced, requested rate. The example then
reported a rate that the DDC never actually applied.
Second, run_capture() derived the number of samples to request from the
radio with int(radio_rate / rate), truncating instead of rounding. With
a radio rate of 368.64 Msps and a nominal rate of 200 Msps this yielded
a ratio of 1 rather than the decimation the DDC had actually settled on,
so the radio was told to produce only half the samples needed to fill
the record buffer.
The rate is now read back with get_output_rate() after graph.commit(),
when property propagation has completed, and the user is warned when
the requested rate had to be coerced. The rate ratio is computed with
rounding, so the radio is asked for the full number of samples the
record buffer needs.
While here, fix two related issues in the readback path. The DDC port
is now taken from the destination port of the discovered edge rather
than assuming it matches the radio channel index, and the rate is read
per channel (from the DDC where one is present, otherwise from the
radio) so that chains without a DDC are not ignored. Rates are compared
against a tolerance rather than for exact float equality.
Signed-off-by: Virendra Kakade <virendra.kakade@ni.com>
- Fix target link libraries (UHD::uhd instead of uhd)
- Updated README
- Better describe the different ways to build the FPGA bitfiles
- Mention pybind11 requirement
- Add x410 image core to CMakeList to enable using make for this image
UHD hosts <4.10 speak mprpc and unconditionally connect to the RPC port
(49601) of any device they discover. When they reach a gRPC-based MPM
device, the protocol mismatch crashes uhd_find_device.
UHd host 4.10, prevents this by using rpc_version key from discovery
response and skips RPC attempt if mprpc device found during
uhd_find_devices.
This change moves the RPC port to 49602. Now, old UHD <4.10 hosts can
still discover both mprpc and grpc devices. But their mprpc connection
attempt on 49601 during uhd_find_devices is refused by grpc device
(running on new rpc port 49602) and is marked as not reachable instead
of crashing.
Since with the availability of discoverable features in Python it is
possible to use the front panel SPI of the X4xx series from there, this
example shows how to do this. It is pretty much on par with the C++
version.
The main RPC channel can sit idle for a long time (e.g. an interactive
Python session) while only the claim-loop channel sees traffic. Without
keepalive, gRPC self-closes the idle transport (~30 min) and the next
RPC fails re-establishing within its per-call deadline.
With this change the client now pings every 30 s to keep the channel
warm, and the server is configured to accept that cadence instead of
replying GOAWAY "too_many_pings".
Updated the references to DDC and DUC RFNoC blocks to reflect the
new split between legacy(singlesample) and wideband(multisample)
implementations.
Updated the related manual references as well as the C++ block
controller API comments that are pulled in by doxygen.
Also fixed a minor outdated comment in the FPGA source code.