Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USE_LOWIF #26

Closed
ahooper opened this issue Apr 20, 2023 · 8 comments
Closed

USE_LOWIF #26

ahooper opened this issue Apr 20, 2023 · 8 comments
Assignees

Comments

@ahooper
Copy link

ahooper commented Apr 20, 2023

Thank you for providing this package! I had a problem using it to receive WWVB on 60 kHz. That resolved when I disabled USE_LOWIF and the agc initializations. The flowgraph tunes the RSP to 250 kHz with 300 kHz bandwidth, 500 kHz sample rate. Without this I saw an approximately 2 Hz modulation that swamped the weak signal.

diff --git a/lib/rsp_impl.cc b/lib/rsp_impl.cc
index 312999a..4e288a1 100644
--- a/lib/rsp_impl.cc
+++ b/lib/rsp_impl.cc
@@ -13,7 +13,7 @@
 #include "rsp_impl.h"
 #include "sdrplay_api.h"

-#define USE_LOWIF    // to be consistent with the current behavior
+//#define USE_LOWIF    // to be consistent with the current behavior

 namespace gr {
 namespace sdrplay3 {
@@ -171,7 +172,9 @@ double rsp_impl::set_sample_rate(const double rate)
         }
         sample_rate = rate;
         if_type = sdrplay_api_IF_Zero;
+#ifdef USE_LOWIF
     }
+#endif /* USE_LOWIF */
     update_sample_rate_and_decimation(fsHz, decimation, if_type);
     return get_sample_rate();
 }
@@ -452,12 +455,14 @@ const int (&rsp_impl::get_lna_state_range(const std::vector<int> rf_gRs) const)[
 bool rsp_impl::set_gain_mode(bool automatic)
 {
     sdrplay_api_AgcT *agc = &rx_channel_params->ctrlParams.agc;
+#if 0
     agc->setPoint_dBfs = 0;
     agc->attack_ms = 0;
     agc->decay_ms = 0;
     agc->decay_delay_ms = 0;
     agc->decay_threshold_dB = 0;
     agc->syncUpdate = 0;
+#endif
     if (automatic && agc->enable != sdrplay_api_AGC_CTRL_EN) {
         // enable AGC
         agc->enable = sdrplay_api_AGC_CTRL_EN;

RSPdx with gnuradio 3.10.6.0 from homebrew on Mac M2 arm64 Ventura 13.3.1

@fventuri fventuri self-assigned this Apr 21, 2023
@fventuri
Copy link
Owner

@ahooper - good catch about the missing #ifdef USE_LOWIF for the closing braces!

I also thought it would be useful to have USE_LOWIF as a configurable define with cmake, so now you can just run:

cmake -DUSE_LOWIF=OFF ..

and it should use Zero IF for any selected sample rate.

Regarding the AGC initializations, I agree with you that they should be removed; I also made the AGC (when enabled) use the SDRplay API AGC mode defined by sdrplay_api_AGC_50HZ, since I see this is what the API selects by default. Of course, if you select automatic gain mode to false, the code will set the AGC in the API to sdrplay_api_AGC_DISABLE.

I just pushed these changes to the main branch; please give it a try when you have time, and let me know if they work for your use case.

Franco

@ahooper
Copy link
Author

ahooper commented Apr 22, 2023

Yes, that update works with cmake -DUSE_LOWIF=OFF. For USE_LOWIF section shouldn't it be fsHz = 2000e3;?

#ifdef USE_LOWIF
    if (rate == 62.5e3 || rate == 125e3 || rate == 250e3 || rate == 500e3 ||
        rate == 1000e3 || rate == 2000e3) {
        decimation = int(2000e3 / rate);
        fsHz = 6000e3;
        sample_rate = 2000e3 / decimation;
        if_type = sdrplay_api_IF_1_620;
    } else {
#endif /* USE_LOWIF */

@fventuri
Copy link
Owner

@ahooper - there's a little known aspect of the SDRplay API (or perhaps of the Mirics hardware, not sure), that goes like this:

  1. when the selected IF is 0 (Zero-IF or ZIF), then any sample rate >= 2Msps (and <= 10.66Msps) is allowed, and the 'output' sample rate from the API (i.e. the actual sample rate measured by counting the number of samples received in the RX callback divided by the time) is exactly fsHz
  2. however for very specific combinations of requested sample rate (fsHz), non zero IF (Low-IF or LIF), and IF bandwidth, the output sample rate (i.e. the sample rate that can be measured counting the samples returned in the RX callbacks) is a fraction of fsHz by some integr factor (which depends on the combination of values above). As far as I know the only place where these combinations are documented is in the SDRplay API specification guide in the description of the function sdrplay_api_Init() (which is on page 26 in the 3.07 version), where they have a table at the beginning with these combinations of sample rate, IF frequency, and IF bandwidth. As far as I know these are the only cases where the user can select a non zero IF.

This is why a few months ago I wrote a couple of test programs (that you can find in these two repositories: https://github.com/fventuri/single-tuner-expriments and https://github.com/fventuri/dual-tuner-experiments), where you can play around with all the different combinations of these values, and see what is the actual sample rate; give it a try and feel free to experiment with them.
For instance with the single tuner one I found out that turning off DC offset correction and IQ imbalance correction (which are on by default) seems to return the original sample values from the ADC, without any changes, so perhaps this is something you could try out.

Franco

@ahooper
Copy link
Author

ahooper commented Apr 23, 2023

Thank you, that helps me understand what you are doing with USE_LOWIF. It is a surprise though to have non-zero IF activated in the default build just on the condition of a low effective source block sample rate.

@fventuri
Copy link
Owner

The choice of Low-IF by default comes from a suggestion from SDRplay back a couple of years ago when I was working on the SoapySDR module SoapySDRPlay3 (see here: pothosware/SoapySDRPlay3#23 (comment)); as he says, it is used to remove the DC spike when the center (LO) frequency is exactly the same of the tuning frequency.
I think (but I am not 100% sure) that also their Windows SDR program SDRuno use the same choice of Low-IF by default.

Franco

@ahooper
Copy link
Author

ahooper commented Apr 24, 2023

OK, the SoapySDRPlay3#23 issue, and SoapySDRPlay2#62 it references, helped me understand LOWIF better. I tried using LOWIF, but still get better results without it and doing my own offset tuning. I'll work on it some more to see what I am missing.

@ahooper ahooper closed this as completed Apr 24, 2023
@fventuri
Copy link
Owner

Since the internals of the SDRplay API are proprietary, if you still continue having that problem with Low-IF, I suggest that you open a technical support ticket with SDRplay (https://www.sdrplay.com/help/).
Also try the utility single_tuner_recorder in the single-tuner-experiments repository (https://github.com/fventuri/single-tuner-experiments) to see if things are better with it, since it does not use this SoapySDRPlay3 module.

Franco

@ahooper
Copy link
Author

ahooper commented Apr 25, 2023

I was able to get my flow working with Low-IF on, by choosing a different offset tuning frequency. Thanks for helping me get there!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants