| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
Add the Filter API to n3xx specifically for the AD937x device. The TX
filter is limited to 32 taps, and the RX filter is limited to 48 taps.
This feature requires MPM version 4.2 or later on the device.
Co-authored-by: bpadalino <bpadalino@gmail.com>
Signed-off-by: mattprost <matt.prost@ni.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allow users to control the Mykonos frontend bandwidth settings for
Rx and Tx. Note that this operation requires the daughterboard to
re-initialize, so it may take some time. Values for frontend filter
settings were derived using ADI's AD9371 Filter Wizard.
This feature requires MPM version 4.1 or later on the device.
Co-authored-by: bpadalino <bpadalino@gmail.com>
Signed-off-by: mattprost <matt.prost@ni.com>
|
|
|
|
|
|
|
|
|
| |
This allows the user to get the current state of the tx atr bits and set
them back to a given state. This is useful for the n310 when resetting
the front end, in order to avoid any tx power out of the frontend when
the init_cals are run.
Signed-off-by: mattprost <matt.prost@ni.com>
|
|
|
|
|
|
|
|
|
|
|
| |
Enabled with the "tx_replay_buffer" device argument. Buffers TX data in
DRAM using the Replay block (version 1.1 or higher required), allowing
more buffering of data on the device. May reduce underruns for certain
applications. The Replay block is currently limited to 32 play
commands, so fewer calls to send() with larger buffers will perform
better than more calls with smaller buffers.
Signed-off-by: michael-west <michael.west@ettus.com>
|
|
|
|
|
|
| |
Add support for reading the number of supported SPI slaves from
the device. This has become necessary because we may have bitfiles
with different capabilities and we want to report this back correctly.
|
|
|
|
|
|
|
|
|
|
|
|
| |
For certain frequencies, the LMX2592 will sporadically fail to lock upon
the very first tune. When this happens, subsequent tunes (even to the same
frequency) do lock. This issue seems to be resolved by programming the FCAL
adjustment register fields (FCAL_LPFD_ADJ/FCAL_HPFD_ADJ) as described in
the LMX2592 datasheet. These fields adjust the FCAL calibration speed to
better accomodate PFD frequencies below 20MHz or above 100MHz.
This patch also fixes a few name typos in the register map that were
directly in the scope of this change.
|
|
|
|
|
|
| |
This fixes an issue with setting the active channel source in MPM, and
additionally allows opening up the more flexible API in the future without
requiring a filesystem update.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The power that corresponds to a certain gain values depends on the
frequency band we are in. At the edges of these bands discontinuities
can occur (the gain necessary to achieve the same power value changes
non-continuously). The power calibration does a linear interpolation
between two neighbor points in the calibration data set to find at
best fitting value. We therefore have to make sure that this interpolation
does not cross discontinuities.
This is a minimal invasive approach. It adds values at discontinuities
for the lower and the upper band. The power calibration format uses
the frequency for a power to gain mapping as a map key. Therefore two
gain to power mappings cannot be stored for the same frequency as it
would be needed for the discontinuity. Instead the mapping for the
lower band is stored at the discontinuity frequency itself. The mapping
for the upper band is stored at the frequency + 1Hz. The calibration
will therefore still fail to yield proper results within this
sub-Hertz range. The frequency lookup in the power calibration manager
now uses round instead of truncation to find the best mapping frequency
in the calibration table.
With this, searching for neighbor data points now ensures that the data
points used belong to the same band (except for the range of
(f_discontinuity, f_discontinuity + 1Hz) ).
This commit does not solve the issue for calibration data generated
with usrp_power_cal.py because the Python interface has no means to
detect band edges for the USRP it is calibrating.
|
|
|
|
|
|
|
|
| |
Make sure no active components are connected to the TX frontend during
next boot. This avoids configurations that could generate unwanted tones
during operations such as the Mykonos init cals.
Signed-off-by: mattprost <matt.prost@ni.com>
|
| |
|
|
|
|
|
|
|
| |
The FSRU (aka EISCAT) was never supported in UHD 4.0. The FPGA
repository never had the relevant files, and the block controller also
never existed. This removes all the corresponding files from MPM, as
well as some references from makefiles.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This fixes the following warnings:
```
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2335:5: warning: \
delete called on non-final 'uhd::rfnoc::x400::x400_gpio_port_mapping' that has \
virtual functions but non-virtual destructor [-Wdelete-non-virtual-dtor]
delete __ptr;
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2648:7: note: in \
instantiation of member function 'std::__1::default_delete<uhd::rfnoc::x400::x4\
00_gpio_port_mapping>::operator()' requested here
__ptr_.second()(__tmp);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2602:19: note: in\
instantiation of member function 'std::__1::unique_ptr<uhd::rfnoc::x400::x400_g\
pio_port_mapping, std::__1::default_delete<uhd::rfnoc::x400::x400_gpio_port_map\
ping> >::reset' requested here
~unique_ptr() { reset(); }
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:4063:21: note: in\
instantiation of member function 'std::__1::unique_ptr<uhd::rfnoc::x400::x400_g\
pio_port_mapping, std::__1::default_delete<uhd::rfnoc::x400::x400_gpio_port_map\
ping> >::~unique_ptr' requested here
unique_ptr<_Yp> __hold(__p);
^
/Users/rfmibuild/myagent/_work/76/s/host/lib/usrp/x400/x400_radio_control.cpp:1\
92:33: note: in instantiation of function template specialization 'std::__1::sh\
ared_ptr<uhd::mapper::gpio_port_mapper>::shared_ptr<uhd::rfnoc::x400::x400_gpio\
_port_mapping>' requested here
auto gpio_port_mapper = std::shared_ptr<uhd::mapper::gpio_port_mapper>(
```
and:
```
/Users/rfmibuild/myagent/_work/76/s/host/lib/usrp/x400/x400_gpio_control.cpp:15\
4:75: warning: adding 'const uint32_t' (aka 'const unsigned int') to a string d\
oes not append to the string [-Wstring-plus-int]
"Could not find corresponding GPIO pin number for given SPI pin " + value);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
/Users/rfmibuild/myagent/_work/76/s/host/lib/usrp/x400/x400_gpio_control.cpp:15\
4:75: note: use array indexing to silence this warning
"Could not find corresponding GPIO pin number for given SPI pin " + value);
^
& [ ]
```
|
|
|
|
|
| |
This allows viewing or, conceivably, customizing the tuning table that
ZBX uses, depending on the particular needs of the end user.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In 716ed77, refactoring was performed to merge `set_tx_subdev_spec()`
and `set_rx_subdev_spec()` via the use of a shared helper function,
`_set_subdev_spec()`, which factors out differences in the two
directions by accepting lambda functions from the caller. However, there
were two bugs introduced in the refactoring:
- The channel map parameter, which is either `_rx_chans` or `_tx_chans`
based on direction, was passed by value and not reference, so changes
made by the function were not persisted in the member variables
maintained in the `multi_usrp_rfnoc` class.
- The connection removal loop checks for the presence of an SEP block on
an edge as its termination condition. In the pre-refactored code, the
direction determined whether the source or destination of the edge was
checked for the SEP. However, in the refactoring, the source of the edge
is checked for both TX and RX. While this works for the
`set_tx_subdev_spec()` call, it breaks the `set_rx_subdev_spec()` call.
This commit fixes the issue by adding another lambda parameter to the
`set_subdev_spec()` function, which puts the onus of the edge check on
the direction-specific code to ensure it is looking at the correct side
of the edge.
|
|
|
|
|
|
| |
The FPGA GPIO registers don't exactly match the pin numbering on the
front panel and in the docs. This commit changes the algorithm so that
the API presented to the user matches the front panel.
|
| |
|
|
|
|
|
|
|
|
| |
This commit disables x4xx_radio_block_test on macOS
because the platform has stricter casting and symbol
export rules, which causes this test to fail.
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem was that TwinRX has a special LED configuration (unlike most
other daughterboards): Since it has two channels, it is possible to
stream RX from both SMA ports. In that case, we would light up both LEDs
in green (which was not happening, only one LED would light up,
depending on which antenna was set last).
This fixes the problem and turns on both LEDs when both channels are
used, and both SMA ports are selected.
Note that the reason for this issue was an incorrect porting of this
code from UHD 3. There, we had separate LED ATR objects per channel.
|
| |
|
|
|
|
|
|
|
| |
The E3xx devices have one LO per TX/RX, respectively. That means when
changing the frequency on channel 0, the frequency on channel 1 also
gets changed. The code didn't track this change properly: When setting
channel 1, channel 0's frequency didn't match.
|
|
|
|
|
|
|
|
|
|
| |
The host code was calculating and programming a 32-bit value for the DSP
frequency, but the DDS modules in the FPGA only use the upper 24-bits.
This led to inaccurate frequency values being returned. This change
corrects the resolution of the value on the host side so an accurate
value is returned.
Signed-off-by: michael-west <michael.west@ettus.com>
|
|
|
|
|
| |
This change simply refactors these methods so that the core of the algorithm
is no longer duplicated between them.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We have noticed that on 1 GbE connections, MTU discovery can become
unreliable. Since we now use the MTU directly for deriving spp and other
values, a correct MTU is important.
Because we don't have a way of knowing if MTU discovery worked or not,
we add some heuristics in form of a plausibility check. For now, the
only rule in this check is if that the detected MTU is a bit larger than
1472 bytes, we coerce down to 1472, because this is such a standard
value (most 1 GbE interfaces default to an IPv4 MTU of 1500 bytes).
For the cases where the interface MTU is set to be between 1500 and 1528
bytes, this would cause a very minor performance loss. We accept this
performance loss as it is small, and those cases are very rare. MTUs are
usually 1500 bytes, or >= 8000 bytes for high-speed links using jumbo
frames.
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
Getting the time from the mb_controller is slow, so try to get the time
from the Radio on the fast path first.
Signed-off-by: michael-west <michael.west@ettus.com>
|
|
|
|
|
|
|
|
|
|
| |
The times on the device can glitch if either the tick rate changes or
the number of active chains changes. This throws off the time if the
user gets streamers, changes the sample rate, or changes the tick rate
after synchronizing the time. This change re-synchronizes the times
automatically in those cases.
Signed-off-by: michael-west <michael.west@ettus.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
This gets closer to what our hardware can actually support. See the
comments for further explanations.
This has the side-effect of patching an issue on X410 (using 200 MHz
images) where garbage samples would get injected (one per packet). It
is not, however, the final fix for that problem.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
This implements the GPIO API for X410 through get_gpio_attr and
set_gpio_attr. In ATR mode, which channel's ATR state is chosen by the
set_gpio_src call, setting e.g. DB0_RF0 for channel 0 or DB0_RF1 for
channel 1. In manual mode, all 24 bits (for both ports) are set in
a single register write.
Although the front panel of the device has two ports, labelled GPIO0 and
GPIO1, this API exposes them as though they were a single 24-bit GPIO
port.
|
|
|
|
|
|
|
| |
Refactors register addresses into a gpio_atr_offsets structure which
contains the various register addresses. This allows creating other
devices with different GPIO register layouts with greater ease, and
eliminates the use of macros (yay!)
|
|
|
|
| |
Thanks to Mait for pointing these out!
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
Replaced by std::numeric_limits<>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
As GitHub user marcosino points out, we're running the AD9361 in
overclocked mode. This is because the driver was written with no longer
valid recommendations.
We add a comment and some debug messages to clarify this. Should there
be RF impairments (signal integrity or other) because of overclocking,
users would be able to check DEBUG log statements to correlate with
overclocked configurations.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The previous behaviour of UHD for setting gain was:
1. Set "Mask Clr Atten Update". This will avoid "Immediately Update TPC
Atten" to be cleared.
2. Then, assert "Immediately Update TPC Atten".
3. Poke the LSBs of the attenuation value.
4. Poke the MSB of the attenuation value.
This order of operations has the downside of causing large Tx power
spikes when setting the attenuation, because you need both registers to
properly set the attenuation, but we are updating the gain immediately,
even between the two attenuation register's update.
Moreover, the upstream Linux driver for AD9361 by ADI also does not
do this. We therefore change the procedure to match the kernel driver
behaviour, which is:
0. [During initialization: Clear "Mask Clr Atten Update"
1. Poke the attenuation registers
2. Then, assert "Immediately Update TPC Atten".
This avoids Tx power spikes. It also reduces the Tx-gain procedure to
3 pokes instead of 4.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
So, both the set_tx_antenna_switches and set_rx_antenna_switches functions
configure the TX0_ANT_11 register (which controls the final switch before
the TX/RX port, switching it between the three TX paths and the RX path).
The RX antenna configuration code will, if the RX antenna is set to TX/RX,
configure that switch to the TX/RX->RX path when the ATR is set to RX.
However, the TX antenna config code will always configure that switch to
the "bypass" path, for both the 0X and RX ATR modes, regardless of whether
the RX side actually needs that path.
Ergo, this change makes set_tx_antenna_switches only configure that
switch when it is configuring the XX or TX modes.
|
|
|
|
|
| |
Error message was not adapted when support for 11.52 MHz and 23.04 MHz
references was added. Fixing this.
|
| |
|
|
|
|
|
| |
This allows UHD clients to determine, for example, whether the currently
loaded filesystem is up-to-date.
|