| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
| |
- Add notes on playback and record behaviour
- Improve docs for play()
Co-authored-by: Wade Fife <wade.fife@ettus.com>
|
|
|
|
|
|
|
| |
rfnoc::connect_through_blocks(), unlike rfnoc_graph::connect(), did not
have an argument to declare a back-edge. This patch remedies this
situation by adding a skip_property_propagation argument that works
exactly as with rfnoc_graph::connect().
|
|
|
|
|
| |
The sw_iface entry in the `control` section is yet underdefined, so we
can remove it from the block descriptors.
|
| |
|
|
|
|
|
|
|
|
|
| |
This adds DRAM support to E31x devices. Due to the size of the DDR3
memory controller, it is not enabled by default. You can include the
memory controller IP in the build by adding the DRAM environment
variable to your build. For example:
DRAM=1 make E310_SG3
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Throughout UHD, we often do floating-point comparisons for frequency
ranges that require resilience to floating point rounding errors. Most
of the time the checks look like this:
```cpp
if (fp_compare_epsilon<double>(freq) > boundary) {
// ...
}
```
The exception is the N320 daughterboard control, which uses a custom
epsilon:
```cpp
if (fp_compare_epsilon<double>(freq,
RHODIUM_FREQ_COMPARE_EPSILON) > boundary) {
// ...
}
```
This was, for the most part, not by design, but because authors simply
didn't think about which epsilon value was appropriate for the frequency
comparison. This was complicated by the fact that fp_compare_epsilon
previously had some issues.
This patch introduces FREQ_COMPARE_EPSILON, which is a sensible default
value for fp_compare_epsilon when doing frequency comparisons (note that
fp_compare_delta already had such a value).
Also, it introduces freq_compare_epsilon(x), which is a shorthand for
fp_compare_epsilon<double>(x, FREQ_COMPARE_EPSILON).
We then replace all occurrences of fp_compare_epsilon<double> which are
specific to frequency checks with freq_compare_epsilon.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
UHD had an issue where the design of fp_compare_epsilon and its usage
differed. In fact, the *only* usage of fp_compare_epsilon outside of
unit tests was to do a fuzzy frequency comparison, and it always took
a form like this:
```cpp
// The argument EPSILON may be implied, i.e., using the default
if (fp_compare_epsilon<double>(test_freq, EPSILON) < boundary_freq) {
// ...
}
```
However, the API of fp_compare_epsilon was such that it would apply
DOUBLE_PRECISION_EPSILON to part of the frequency comparison, thus
rendering the argument EPSILON obsolete. When the default EPSILON was
used, this was OK, but only when the floating point type of
fp_compare_epsilon<> was `double`, and not `float`.
As an example, consider the following:
```
if (fp_compare_epsilon<double>(1e9 + x, LITTLE_EPSILON) == 1e9) {
// ....
}
double BIG_EPSILON = x * 10;
if (fp_compare_epsilon<double>(1e9 + x, BIG_EPSILON) == 1e9) {
// ....
}
```
If you expect the second comparison to pass even if the first failed,
then you are not alone. However, that's not what UHD would do. Because
of the aforementioned behaviour, it would use DOUBLE_PRECISION_EPSILON
for the right hand comparison, which would fail again.
Instead of fixing the instances of fp_compare_epsilon throughout UHD,
this patch changes the comparison algorithm from "very close with
tolerance epsilon" to "close enough with tolerance epsilon". This
requires only one side to be close to the other, using its own epsilon,
so the aforementioned example would always pass on the second check.
However, this exposed a second bug in fp_compare_epsilon. For
greater-/less-than comparisons, it would use epsilon like a delta value,
i.e., it would check if
a + epsilon < b - epsilon
That means that if a < b, but (b-a) < 2*epsilon, this check would return
"false", i.e., it would report that a >= b, which is incorrect. These
operators are now changed such that they first check equality of a and
b using the algorithm described in the code, and then compare the values
of a and b (ignoring epsilon) directly. A unit test for this case was
added.
|
|
|
|
|
|
| |
This changes the return value of connect_through_blocks() from void to
a list of edges. If the connection can be made, then it will now return
the list of connections between the source block and port.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously, the default was DROP. For almost all RFNoC blocks, this is
not a good default. It is very easy to crash USRPs by not properly
propagating the MTU. For example, the following flow graph:
Radio -> DDC -> FIR -> Streamer
would crash an X310 when not manually setting an spp value. The reason
is: The Radio block has an output buffer of 8192 bytes, capable of
handling 2044 samples per packet. However, that's too big for the
Ethernet portion of the X310, which would cause the X310 to lose
connection between UHD and firmware. If the FIR were configured to
propagate MTU, the Host->USRP connection (which has an MTU of <= 8000)
would limit the MTU on all links, and the spp value would automatically
be reduced to 1996 (or less).
This commit uses the post_init() feature to check the user set an MTU in
the constructor, and sets it to the default if that didn't happen. This
doesn't solve all problems (the new default of ONE_TO_ONE) could also be
incorrect, but is a much more suitable default.
As a consequence, this has a minor change in how
set_mtu_forwarding_policy() can be used: It now must be called during
the constructor. Before, the rule was that it may only be called once,
but that could also have happened, e.g., during the first property
resolution. Now, the constructor is the last time block authors can
choose an MTU forwarding policy.
|
|
|
|
|
|
|
|
| |
This method allows running a fixed set of rules to check the internal
consistency of a block. This may be necessary, because blocks authors
may incorrectly implement a certain design rule, and we want the ability
to not start an RFNoC graph with blocks that have rule violations which
we can write checks for.
|
|
|
|
|
|
|
|
|
|
| |
uhd::dict gets typedefed into board_eeprom_t, which is used by applications
like uhd_usrp_probe, so this should be considered as part of the API.
fs_path is also an API, but because of MSVC build issues it
was not marked as so. Instead mark with UHD_API_HEADER.
Signed-off-by: Steven Koo <steven.koo@ni.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
UHD_API sets the visibility for the symbols. Adding UHD_API fixes
casting issues seen on macOS. However this breaks Windows because
UHD_API sets __declspec(dllexport) and __declspec(dllimport) which
doesn't make sense for header/inline only definitions. This change
adds UHD_API_HEADER to denote entrypoints for this case. It sets
the visibility flags for Linux/Mac but does not set the
__declspec on Windows.
Signed-off-by: Steven Koo <steven.koo@ni.com>
|
|
|
|
|
| |
Add SPI Core host implementation for x410 and a discoverable
feature to make it accessible.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Throughout UHD, we are using a random mix of __FUNCTION__, __func__,
__PRETTY_FUNCTION__, and BOOST_CURRENT_FUNCTION. Note that the first two
macros are non-standard (although many compilers understand them), and
the last requires Boost. __func__ is available since C++11, but is not
the best choice because the C++ standard doesn't require it to be of any
specific value.
We thus define UHD_FUNCTION and UHD_PRETTY_FUNCTION as portable macros.
The former simply contains the undecorated function name, the latter the
expanded function with full signature.
As it happens, our currently supported compilers didn't have any issues
using non-standard macros, so the main fix here is the removal of the
Boost macros and the harmonization of the other macros.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An RFNoC block (like the radio) might require a minimal number of
items in each clock cycle, e.g. the radio has to process
SPC (samples per cycle). Because data in RFNoC is transmitted and
processed in packets, we have to make sure the items inside these
packets are a multiple of the items processed in each cycle.
This commit adds an atomic item size properties which is set by
the radio and adapted by the streamers. The streamers adapt the
SPP property of the radio block controller depending on the MTU
value. This might lead to an SPP value which does not align with
the SPC value of the radio block, hence we add a property resolver
for the atomic item size.
|
| |
|
|
|
|
|
| |
This removes the tcp_zero_copy interface, which is not supported by any
USRP.
|
|
|
|
|
|
|
| |
This allows constructing a multi_usrp using a string constant:
```
auto usrp = uhd::usrp::multi_usrp::make("type=x4xx");
```
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Add data packet payload field
- Add metadata support
- Add missing management fields (OpsPending, ExtendedInfo).
- Add missing control fields (byte_enable, data, has_time)
- Update offsets for management OpPayload fields.
- Make the field names more consistent, readable, and consistent
with the RFNoC specification.
- Display value of fields in addition to name.
- Fix timestamp, eob, and eov offsets
|
|
|
|
|
|
| |
The ops pending for each operation was stored implicitly in the data
structure. This adds it explicitly, which is useful for debugging
and packet dissection.
|
| |
|
|
|
|
|
|
|
| |
This constant was generally harmful, since it was only correct under
certain circumstances (64 bit CHDR with timestamps). The X3x0 code was
the last place it was being used, and we remove it without substitute
because it was not doing anything useful here.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These two values where being mixed up in the code. To summarize:
- The MTU is the max CHDR packet size, including header & timestamp.
- The max payload is the total number of bytes regular payload plus
metadata that can be fit into into a CHDR packet. It is strictly
smaller than the MTU. For example, for 64-bit CHDR widths, if
a timestamp is desired, the max payload is 16 bytes smaller than
the MTU.
The other issue was that we were using a magic constant (DEFAULT_SPP)
which was causing conflicts with MTUs and max payloads.
This constant was harmful in multiple ways:
- The explanatory comment was incorrect (it stated it would cap packets
to 1500 bytes, which it didn't)
- It imposed random, hardcoded values that interfered with an 'spp
discovery', i.e., the ability to derive a good spp value from MTUs
- The current value capped packet sizes to 8000 bytes CHDR packets, even
when we wanted to use bigger ones
This patch changes the following:
- noc_block_base now has improved docs for MTU, and additional APIs
(get_max_payload_size(), get_chdr_hdr_len()) which return the
current payload size given MTU and CHDR width, and the CHDR header
length.
- The internally used graph nodes for TX and RX streamers also get
equipped with the same new two API calls.
- The radio, siggen, and replay block all where doing different
calculations for their spp/ipp values. Now, they all use the max
payload value to calculate spp/ipp. Unit tests where adapted
accordingly. Usage of DEFAULT_SPP was removed.
- The replay block used a hardcoded 16 bytes for header lengths, which
was replaced by get_chdr_hdr_len()
- The TX and RX streamers where discarding the MTU value and using the
max payload size as the MTU, which then propagated throughout the
graph. Now, both values are stored and can be used where appropriate.
|
|
|
|
|
| |
This adds some more explanatory comments around active and static
connections.
|
|
|
|
|
|
| |
Add API calls to Radio control to get ticks and time.
Signed-off-by: michael-west <michael.west@ettus.com>
|
|
|
|
|
|
|
| |
This provides every block controller with a copy of its CHDR width.
Note: mock blocks always get configured with a 64-bit CHDR width, to
retain API compatibility.
|
|
|
|
|
|
|
| |
This allows consumers of UHD compiling with C++11 to include this file
(which is now included via noc_block_base) by turning a switch statement
into a functionally equivalent (albeit less readable) nested ternary
statement.
|
|
|
|
|
|
| |
This lets Doxygen create a page in the UHD manual that lists all RFNoC
block controllers. It will be accessible under Manual -> Modules ->
RFNoC -> RFNoC Blocks shipped with UHD.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This removes some constants from UHD that were left over from RFNoC/UHD
3.x. They are unused.
rfnoc_rx_to_file had a commented-out section that was also UHD-3 only.
Note that rfnoc/constants.hpp is pretty bare now, and could be removed.
However, it is in the public header section, so we shall leave the used
constants where they are.
This requires fixing includes in mgmt_portal.cpp.
|
|
|
|
|
|
|
| |
C++ syntax cleanup. g++ 11 is now more picky about syntax, and flags
errors rather than ignores use of template-id for a destructor.
Thanks to mait for these fixes!
|
|
|
|
|
|
| |
This adds a section on GPIO bank names to multi_usrp.hpp, and clarifies
the difference between the multi_usrp and RFNoC APIs regarding GPIO
control.
|
|
|
|
|
|
|
|
|
| |
In multiple places in the UHD code, we were doing the same calculation
for a wrapped frequency (wrap it into the first Nyquist zone). This math
was using boost::math, too. Instead of editing every instance, we create
a new function, uhd::math::wrap_frequency(), and replace all of its
separate implementations with this function. The new function also no
longer relies on boost::math::sign.
|
|
|
|
|
| |
We've been having issues with moving locations of Boost headers for this
function, and it's simple enough to implement ourselves.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a very mechanical task that could almost have been done with
sed. Boost versions of mutexes and locks were removed, and replaced with
std:: versions. The replacement tables are as follows:
== Mutexes ==
- boost::mutex -> std::mutex
- boost::recursive_mutex -> std::recursive_mutex
Mutexes behave identically between Boost and std:: and have the same
API.
== Locks ==
C++11 has only two types of lock that we use/need in UHD:
- std::lock_guard: Identical to boost::lock_guard
- std::unique_lock: Identical to boost::unique_lock
Boost also has boost::mutex::scoped_lock, which is a typedef for
boost::unique_lock<>. However, we often have used scoped_lock where we
meant to use lock_guard<>. The name is a bit misleading, "scoped lock"
sounding a bit like an RAII mechanism. Therefore, some previous
boost::mutex::scoped_lock are now std::lock_guard<>.
std::unique_lock is required when doing more than RAII locking (i.e.,
unlocking, relocking, usage with condition variables, etc.).
== Condition Variables ==
Condition variables were out of the scope of this lock/mutex change, but
in UHD, we inconsistently use boost::condition vs.
boost::condition_variable. The former is a templated version of the
latter, and thus works fine with std::mutex'es. Therefore, some
boost::condition_variable where changed to boost::condition.
All locks and mutexes use `#include <mutex>`. The corresponding Boost
includes were removed. In some cases, this exposed issues with implicit
Boost includes elsewhere. The missing explicit includes were added.
|
| |
|
|
|
|
|
|
|
|
|
| |
The variable max_size_bytes has a different name in the source than in
the header and is not self-explanatory in both. Therefore when comparing
against it in the assertion in line 142 one could assume that a number
of bytes needs to be compared with a byte value. Change variable to
`buff_size` in source and header file to avoid confusion and add
documentation.
|
| |
|
|
|
|
|
|
|
| |
The previous commit fixed a bug in the DUC, where get_frequency_range()
reported incorrect values. The DDC did not have this bug, but we port
the updates to the unit tests and the documentation from the DUC to the
DDC for consistency's sake.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The tuning range of the DUC depends on the output sample rate (which is
larger), but it was using the input sample rate. This was causing a bug
where for Tx, the DSP tuning range was limited when using multi_usrp API,
and thus would not allow to DSP-tune beyond the current sampling rate.
In this patch, we also re-use the existing calculation of the sampling
rate, and harmonize that code between duc_block_control and
ddc_block_control.
Consider the following Python REPL code:
>>> import uhd
>>> U = uhd.usrp.MultiUSRP('type=x300')
>>> U.set_rx_rate(10e6)
>>> U.set_tx_rate(10e6)
>>> # Creating a streaming is required, or the input rate will not be
>>> # set:
>>> S = U.get_tx_stream(uhd.usrp.StreamArgs("fc32", "sc16"))
>>> treq = uhd.types.TuneRequest(1e9)
>>> treq.rf_freq = 1e9
>>> treq.dsp_freq = 50e6
>>> treq.dsp_freq_policy = uhd.types.TuneRequestPolicy.manual
>>> treq.rf_freq_policy = uhd.types.TuneRequestPolicy.manual
>>> tres = U.set_rx_freq(treq, 0)
>>> print(str(tres))
Tune Result:
Target RF Freq: 1000.000000 (MHz)
Actual RF Freq: 1000.000000 (MHz)
Target DSP Freq: 50.000000 (MHz)
Actual DSP Freq: 5.000000 (MHz)
>>> # Note the last two lines: The *target* DSP freq was already clipped
>>> # to 5 MHz. These lines show 50.0 MHz when this patch is applied.
This bugfix is accompanied some related changes:
- The unit test is amended to verify the behaviour
- The API documentation is amended with details on its behaviour
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In current implementation it is not possible to find all blocks of
a device by calling find_blocks("0/"). The same is true for the
block count. This is caused by the valid block id regex which
requires a block name. This regex is used to validate the block
name as well as to match block ids in search.
This fix looses the requirement for the block name to allow
searches by device number and block count and also extends the
is_valid_block_id method to require the block name match to be
non empty (which restores the previous behaviour at this point).
|
|
|
|
|
|
|
| |
We allow underscore in RFNoC's block names but the regular
expressions only allowed the underscore in the block name RE. This
fix adds the underscore to the block id RE as well as adapts the
unit tests accordingly.
|