Repository navigation
Conversation
Add an "overload" RX sensor on each AD9361 frontend, next to "rssi". It returns the five RX overload signals of the chain, read from registers 0x2B8 (RX1) and 0x2B9 (RX2): bit 4 large LMT overload bit 3 small LMT overload bit 2 large ADC overload bit 1 small ADC overload bit 0 digital saturation UHD already programs the thresholds of these detectors (0x104 to 0x108) in both gain modes, but never read the result, so the host had no way to know that the receiver overloaded. Counting full-scale samples on the host catches ADC clipping, but not an overload of the RF front end (LMT) caused by a strong signal outside the captured band, which can leave intermodulation products in the band with no other sign of it. The bits are sticky: they stay set until the next gain change, so a slow poll does not miss short bursts. The sensor is published by ad936x_manager, so it appears on B2xx devices. get_overload() has a default implementation in ad9361_ctrl that throws not_implemented_error, so the E3xx RPC interface (e3xx_ad9361_iface) builds unchanged; E3xx sensors come from MPM and are not affected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
@hgi586 Thanks for the contribution! I agree this is a good idea. I was wondering if there's a way to disentangle the bits (i.e., not having to require the reader to mask-and-shift to identify individual sensor values), but that depends on the stickiness of that register. Do you know if reading the register clears it? If not, how is it cleared? |
|
I can report on the experimental results with the spectrum analyzer block in Cyberether using a B210 clone for a pr submitted. The clipping is a short message that appears momentarily with a number related to how frequently the clipping happened. From memory , the cyberether block (patch) has it's own counter for a given measurement period. It is intended as a message to the user to reduce the gain input on the spectrum analyzer block. As the gain is reduced , the message appears with much less frequency. The other message : adc overload is apparently reset by the Cyberether app (in the patch submitted) when the user reduces the gain (from my failing memory) . The important case of overload of the input rf stage as opposed to the a to d has not been tested yet. This monitoring applies also to any other blocks or apps that read a-d samples from that part on whatever hardware platform names that use the part. All of the digital signal processing found in textbooks and their elaborate math implicitly assumes that the processing system is operated in a linear region. When this condition is not met , artifacts appear as a result of the non linear operation that are not covered by the linear models. So all software in whatever environment that use this Analog Device part should monitor those internal registers and warn users or change receiver settings. There are 2 other registers that appear to set the threshold of this monitoring. The current tests used the default values in uhd. There is a possibility that further testing of the overload characteristic of the rf stage require an additional patch to those default values in uhd. |
Pull Request Details
Description
On AD9361-based devices, UHD exposes the
rssi,tempandlo_lockedRX sensors, but nothing tells the host that the receiver overloaded. Counting full-scale samples on the host catches ADC clipping, but not an overload of the RF front end (LMT) caused by a strong signal outside the captured band. That overload can leave intermodulation products in the band with no other sign of it.The AD9361 already reports both kinds of overload. Registers 0x2B8 (RX1) and 0x2B9 (RX2) ("Ovrg Sigs" in Analog Devices'
ad9361_regs.h) hold:UHD already programs these detectors' thresholds (0x104 to 0x108) in both gain modes, but it never reads the status.
This PR adds an
overloadRX sensor on each AD9361 frontend, next torssi, read withget_rx_sensor("overload", chan). It returns the five bits as an integer. The change followsget_rssi()throughad9361_device_t,ad9361_ctrlandad936x_manager. It also adds a short "Frontend sensors" subsection to the B200 manual, which did not list the frontend sensors so far.ad9361_ctrl::get_overload()has a default implementation that throwsnot_implemented_error, soe3xx_ad9361_ifacebuilds unchanged. Onlyad936x_managerpublishes the sensor, so it appears on B2xx only; E3xx sensors come from MPM and are not affected.If you would prefer separate boolean sensors (for example
adc_overloadandlmt_overload) to one integer, I can change it.I have signed the Individual CLA and am sending it to contribute@ettus.com, referencing this pull request.
For transparency: I asked for this feature and directed the work. An AI coding assistant (Claude Code) helped write the change and run the measurements, and I validated them on my hardware.
Related Issue
None. I described the proposal on the usrp-users mailing list beforehand and had no reply yet.
Which devices/areas does this affect?
overloadRX sensor per frontend, read-only. Nothing is written to the AD9361, and streaming and gain control are unchanged.Testing Done
Hardware: a B210-class board (a clone with an AD9361), with UHD 4.9.0.1 built from the v4.9.0.1 tag plus this change. The same change rebased onto current master, with no conflicts, builds with the B200 target without warnings.
Check on master: with this branch,
uhd_usrp_probeliststemp, rssi, overload, lo_lockedon RX frontends A and B. A shorter rerun of the test below, at 3 s per gain step, gave the same behaviour:Setup: manual gain, 30.72 MS/s at 915 MHz, receiving a nearby 1 W meter-reading transmitter in the 902-928 MHz band. A second thread polled the sensor about 9,000 times per second, with no effect on streaming. Meanwhile the host counted sc16 samples at full scale, for 5 s per gain step.
Observations:
Not tested: no unit test was added, since the existing tests have no AD9361 register mock. The patch was not run through clang-format, because it was not installed. Formatting was matched by hand to the surrounding code.
Checklist
MPM compat, noc_shell, specific RFNoC block, ...)
🤖 Generated with Claude Code