f4exb / sdrangel

SDR Rx/Tx software for Airspy, Airspy HF+, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay and FunCube
GNU General Public License v3.0
2.73k stars 421 forks source link

Get ADALM-PLUTO limits from libiio #72

Closed rgetz closed 6 years ago

rgetz commented 6 years ago

Let me know if you want to to send you a pull request.

Although it's a little obtuse, the AD9363 datasheet defines "RF bandwidth" as 20MHz. This is not the max sample rate (which is still 61.44 MSPS), but the limit on the RF filters before the ADC/after the DAC. That's what they mean by "Rx Bandwidth" and "Tx Bandwidth".

This can be seen in the DIGITAL DATA TIMING section. (where it references 61.44 MSPS).

I also was looking at a few things - and wanted your opinion.

It's pretty useful to see the AGC setting when in fast/slow attack modes - just read: dev 'ad9361-phy', channel 'voltage0' (input), attr 'hardwaregain', value '73.000000 dB' when the device is in fast/slow attack ACG mode. That will tell you the setting of the ACG, and can be helpful when debugging things.

The device has it's own state. Right now, when you start up sdrangle - it over-writes some - but not all (for example, I see a:

DevicePlutoSDRBox::set_params: Unable to write channel attribute out_altvoltage0_RX_LO_frequency=0: Invalid argument (-22)

on startup, when it tries to set the LO frequency to zero (on master, not on dev branch).

Improved debug (to get the libiio error string):

--- a/devices/plutosdr/deviceplutosdrbox.cpp
+++ b/devices/plutosdr/deviceplutosdrbox.cpp
@@ -150,6 +150,7 @@ void DevicePlutoSDRBox::set_params(DeviceType devType,
         if (ret < 0)
         {
             std::string item;
+           char errstr[256];

             switch (type)
             {
@@ -166,7 +167,8 @@ void DevicePlutoSDRBox::set_params(DeviceType devType,
                 item = "unknown";
                 break;
             }
-            std::cerr << "DevicePlutoSDRBox::set_params: Unable to write " << item << " attribute " << key << "=" << val << ": " << ret << std::endl;
+            iio_strerror(-ret, errstr, 255);
+            std::cerr << "DevicePlutoSDRBox::set_params: Unable to write " << item << " attribute " << key << "=" << val << ": " << errstr << " (" << ret << ") " << std::endl;
         }
         else
         {

I assume patches should be on dev?

Thanks

f4exb commented 6 years ago

Hello,

your patch is usable once you copy it in edit mode. It does not render correctly in Github. I applied the patch and it works as expected returning the error string which indeed could be useful.

For the AGC display this could be interesting. I'll have a look.

I doubt you could ever reach 61.44 MSPS on USB2 anyway. USB2 is 480 Mbit/s and that's a theoretical limit. With 16 bit I/Q samples this makes a maximum of 15 MSPS.

rgetz commented 6 years ago

Sorry - that is why I was wondering about the pull request. It's funny that the github trackers don't allow git diff to be copied/pasted/applied easier.

For sure you can't reach 61.44MSPS without dropping samples. As you stated - you aren't going to reach 20 either. It is super interesting if you just want to look with the FFT, and see what's there. Capture all the FM band to see relative signal strengths. You will get DMA underruns/overflows, and lost data, but for just looking to see what's there - it's still super interesting.

f4exb commented 6 years ago

I wrote the code for AGC display that will appear at the right of the gain setting value. That was fairly easy considering the RSSI is already there.

For the 61.44MSPS you have also to consider that the largest hardware filter is at 14 MHz on Rx so it makes it even more useless for spectrum exploration. The only interest would be to oversample and decimate. Considering other limitations I don't think that going over 20 MSPS has any value.

rgetz commented 6 years ago

Which filter are you talking about?

The AD9363 baseand analog filters is 10MHz baseband (I and Q) so 20MHz RF. The IIO attribute is thr RF bandwidth.

The AD9364 baseband analog filters are 28 MHz baseband (I and Q) so 56MHz RF.

https://github.com/analogdevicesinc/linux/blob/xcomm_zynq/drivers/iio/adc/ad9361.c#L856

I'm not sure where you are getting 14MHz from.

But this gets to an architectural question - why not just try the write, it it works - great. If it fails, just update the GUI with the clamped value that the driver has (do a read). That way - it doesn't matter if you are talking to a AD9363 based device, or a AD9364 based one. The only thing that should care is the driver, not the GUI??

rgetz commented 6 years ago

BTW - I tried out the dev branch - it looks great. Thanks.

f4exb commented 6 years ago

The limits come from some documentation somewhere. Maybe these were the complex limits then the actual bandwidth is twice that. It also seems that the libiio interface uses full bandwidth and not complex half bandwidth but this is not very clear. I will have to try what it really does with actual signals.

If there was an API in libiio to get the limits I would be glad to use it like what is done with RTL-SDR to get the amplifier discrete steps. Unfortunately I don't think this exists with libiio and the trial and error that you suggest is just very bad design.

rgetz commented 6 years ago

I had a quick discussion with a few kernel side IIO developers - there is a in kernel interface for min/max/step size, but there is no sysfs, and therefor no libiio exposure to that. I will see what I can continue to poke along, but it might take longer on my side (so I will close this for now).

But - the limits are complex, there is a difference between what gets programmed in (which is the -3dB point) of the RF filter and the "bandwidth spec on the datasheet". (Which I know is super confusing). For now, I just just changed the limits myself, and it's super useful to me.

rgetz commented 6 years ago

And thanks for displaying the ACG settings - that's awesome.

rgetz commented 6 years ago

There is upstream support now in the IIO kernel framework; the format is [START STEP STOP]

https://elixir.free-electrons.com/linux/v4.14-rc6/source/drivers/iio/industrialio-core.c#L724

We will need to backport a few pieces to get it working in the kernel we ship in Pluto – but will add it to the AD9361-phy driver as soon as our development teams get back from ELCE. (which is on this week).

Then it should be a matter of testing it out in libiio a few weeks later, and then it should be good to go.

As things get updated, and released, I will let you know (since you are correct - it will make things easier for everyone).

-Robin

rgetz commented 6 years ago

Some of these are static while others are dynamic, but they are all exposed by the device.

The notation without square brackets is purely a list. While with brackets it’s [min step max]

grep "" *available

calib_mode_available:auto manual manual_tx_quad tx_quad rf_dc_offs rssi_gain_step dcxo_tune_coarse_available:[0 0 0] dcxo_tune_fine_available:[0 0 0] ensm_mode_available:sleep wait alert fdd pinctrl pinctrl_fdd_indep in_voltage0_hardwaregain_available:[-3 1 71] in_voltage_gain_control_mode_available:manual fast_attack slow_attack hybrid in_voltage_rf_bandwidth_available:[200000 1 56000000] in_voltage_rf_port_select_available:A_BALANCED B_BALANCED C_BALANCED A_N A_P B_N B_P C_N C_P TX_MONITOR1 TX_MONITOR2 TX_MONITOR1_2 in_voltage_sampling_frequency_available:[520833 1 61440000] out_altvoltage0_RX_LO_frequency_available:[70000000 1 6000000000] out_altvoltage1_TX_LO_frequency_available:[46875001 1 6000000000] out_voltage0_hardwaregain_available:[0 250 89750] out_voltage_rf_bandwidth_available:[200000 1 40000000] out_voltage_rf_port_select_available:A B out_voltage_sampling_frequency_available:[520833 1 61440000] trx_rate_governor_available:nominal highest_osr xo_correction_available:[39992000 1 40008000]

Thoughts? Would that provide what you were looking for?

Thanks -robin

unixpunk commented 6 years ago

Hi all, not sure if this SoapySDRUtil output helps.

-- Device identification driver=Library version: 0.12 (git tag: 6f6ced3) hardware=Backend version: 0.12 (git tag: v0.12 ) ad9361-phy,model=ad9364 ad9361-phy,xo_correction=39999893 fw_version=v0.26 hw_model=Analog Devices PlutoSDR Rev.B (Z7010-AD9363) hw_model_variant=0 hw_serial=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx local,kernel=4.9.0-10194-g40c2158 usb,idProduct=b673 usb,idVendor=0456 usb,product=PlutoSDR (ADALM-PLUTO) usb,release=2.0 usb,serial=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx usb,vendor=Analog Devices Inc.

-- Peripheral summary Channels: 1 Rx, 1 Tx Timestamps: NO

-- RX Channel 0 Full-duplex: YES Supports AGC: NO Stream formats: CS8, CS16, CF32 Native format: CS16 [full-scale=2048] Antennas: A_BALANCED Corrections: DC removal Full gain range: [0, 89] dB PGA gain range: [0, 89] dB Full freq range: [70, 6000] MHz RF freq range: [70, 6000] MHz Sample rates: 0.065105, 1, 2, 3, 4, 6, 7, 8, 9, 10 MSps Filter bandwidths: 0.2, 1, 2, 3, 4, 6, 7, 8, 9, 10 MHz

-- TX Channel 0 Full-duplex: YES Supports AGC: NO Stream formats: CS8, CS16, CF32 Native format: CS16 [full-scale=2048] Antennas: A Corrections: DC removal Full gain range: [0, 89] dB PGA gain range: [0, 89] dB Full freq range: [70, 6000] MHz RF freq range: [70, 6000] MHz Sample rates: 0.065105, 1, 2, 3, 4, 6, 7, 8, 9, 10 MSps Filter bandwidths: 0.2, 1, 2, 3, 4, 6, 7, 8, 9, 10 MHz

rgetz commented 6 years ago

SoapySDRUtil is, making things up, based on it's understanding - which isn't correct. I wouldn't recommend anyone to use it, unless they had no choice. Since sdrangel supports libiio directly - that is what it should stick with.

For example: sample rates are settable to 5Hz increments (not 1MSps like Soapy reports) Analog Filter bandwidths are much smaller than 1MSPS, but are based on the base band PLL settings, and can vary quiet a bit. The digital FIR bandwidths are dependent on the sample rate, and the decimation rates of the half band filters, and the limits of the filter coefficients (16-bits).

If the device identifies as a AD9363, the limits are 325 - 3800 MHz. If it identifies as an AD9364, its 70-6000 MHz. The SoapySDRUtil isn't doing things properly yet.

-Robin

unixpunk commented 6 years ago

Ah I see, then the Pluto plugin for Soapy is where the assumptions are then. Mine does have the 70-6000 mod, so that is accurate, and I was able to tune that low in sdrangel as well last I recall.

f4exb commented 6 years ago

At the moment this is fixed in SDRangel assuming the hackers around would do the 70-6000 MHz mod :smile:

f4exb commented 6 years ago

Closing as it works with hardcoded limits

rgetz commented 6 years ago

I will send a PR - I have wasted time updating firmware (which doesn't have the wide tuning range modification by default), and then using SDRangel, which doesn't tell you that things aren't working. You try to tune to an FM radio station, and you just recieve noise, since the radio is tuned to 325 MHz, but the interface says 90.9 MHz....

Pull requests should be done on dev?

f4exb commented 6 years ago

Hello Robin,

yes dev is always the most up to date. I am going to merge to master any time soon.

Best regards, Edouard.

On Sun, 01 Apr 2018 15:05:10 +0000 (UTC) Robin Getz notifications@github.com wrote:

I will send a PR - I have wasted time updating firmware (which doesn't have the wide tuning range modification by default), and then using SDRangel, which doesn't tell you that things aren't working. You try to tune to an FM radio station, and you just recieve noise, since the radio is tuned to 325 MHz, but the interface says 90.9 MHz....

Pull requests should be done on dev?

-- You are receiving this because you modified the open/close state. Reply to this email directly or view it on GitHub: https://github.com/f4exb/sdrangel/issues/72#issuecomment-377792915

-- F4EXB f4exb06@free.fr