rtlsdr bandwith + lna/mixer/vga gains with patch to gr-osmosdr

161 views
Skip to first unread message

Luigi Tarenga

unread,
Dec 13, 2016, 8:24:45 AM12/13/16
to Gqrx SDR
hi guys,
as mentioned in a previous thread I started looking at the analog IF bandwidth with rtlsdr.
Thanks to Csete I started studying gr-osmosdr and librtlsdr. It came out that enabling the
bandwidth was simple as adding one function. I made a further step and tried to enable
the single gains tuning in r820t via gqrx gui. By patching only gr-osmosdr I got it even if
I think that for code clarity if would be better to modify librtlsdr and gr-osmosdr. Anyway
this is a screenshot of what I get when opening an rtlsdr device with extended_mode=1
in the driver options:


note the 3 gains and the ability to tune the bandwitdth.
Now I have to make some stability test and maybe some cleaning in the code (some stupid
comments left and so on) then the next step is to contact the gr-osmosdr dev team and
asking them to accept my patch (I hope they will not require big changes).
I will keep you updated.

Luigi

Luigi Tarenga

unread,
Dec 13, 2016, 8:35:03 AM12/13/16
to Gqrx SDR
oops... I forgot to show the code...

diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc
index 93328b8..ffe17f7 100644
--- a/lib/rtl/rtl_source_c.cc
+++ b/lib/rtl/rtl_source_c.cc
@@ -88,7 +88,11 @@ rtl_source_c::rtl_source_c (const std::string &args)
     _no_tuner(false),
     _auto_gain(false),
     _if_gain(0),
-    _skipped(0)
+    _lna_gain(0),
+    _mix_gain(0),
+    _vga_gain(0),
+    _skipped(0),
+       _extended_mode(0)
 {
   int ret;
   int index;
@@ -150,6 +154,9 @@ rtl_source_c::rtl_source_c (const std::string &args)
   if (dict.count("offset_tune"))
     offset_tune = boost::lexical_cast< unsigned int >( dict["offset_tune"] );
 
+  if (dict.count("extended_mode"))
+    _extended_mode = boost::lexical_cast< bool >( dict["extended_mode"] );
+
   _buf_num = _buf_len = _buf_head = _buf_used = _buf_offset = 0;
 
   if (dict.count("buffers"))
@@ -528,8 +535,22 @@ std::vector<std::string> rtl_source_c::get_gain_names( size_t chan )
     if ( rtlsdr_get_tuner_type(_dev) == RTLSDR_TUNER_E4000 ) {
       names += "IF";
     }
+
+    /* luigi */
+    if ( rtlsdr_get_tuner_type(_dev) == RTLSDR_TUNER_R820T ) {
+      if ( _extended_mode ) {
+        names += "MIX";
+        names += "IF";
+      }
+    }
   }
 
+  std::cerr << "gain names: ";
+
+  for (std::vector< std::string >::const_iterator i = names.begin(); i != names.end(); ++i)
+    std::cerr << *i << ' ';
+
+  std::cerr << std::endl;
   return names;
 }
 
@@ -553,8 +574,27 @@ osmosdr::gain_range_t rtl_source_c::get_gain_range( size_t chan )
 
 osmosdr::gain_range_t rtl_source_c::get_gain_range( const std::string & name, size_t chan )
 {
-  if ( "IF" == name ) {
-    if ( _dev ) {
+
+  if ( _dev ) {
+    if ( rtlsdr_get_tuner_type(_dev) == RTLSDR_TUNER_R820T ) {
+      if ( _extended_mode ) {
+        if ( "LNA" == name ) {
+          return osmosdr::gain_range_t( 0, 15, 1 );
+        }
+
+        if ( "MIX" == name ) {
+          return osmosdr::gain_range_t( 0, 15, 1 );
+        }
+
+        if ( "IF" == name ) {
+          return osmosdr::gain_range_t( 0, 15, 1 );
+        }
+
+        return osmosdr::gain_range_t();
+      }
+    }
+
+    if ( "IF" == name ) {
       if ( rtlsdr_get_tuner_type(_dev) == RTLSDR_TUNER_E4000 ) {
         return osmosdr::gain_range_t(3, 56, 1);
       } else {
@@ -584,6 +624,17 @@ bool rtl_source_c::get_gain_mode( size_t chan )
   return _auto_gain;
 }
 
+/* luigi */
+double rtl_source_c::set_bandwidth( double bandwidth, size_t chan )
+{
+  if (_dev) {
+    std::cerr << "Setting tuner bandwidth to " << bandwidth << " Hz." << std::endl;
+    return (double)rtlsdr_set_tuner_bandwidth( _dev, (uint32_t)bandwidth);
+  }
+
+  return 0;
+}
+
 double rtl_source_c::set_gain( double gain, size_t chan )
 {
   osmosdr::gain_range_t rf_gains = rtl_source_c::get_gain_range( chan );
@@ -595,8 +646,58 @@ double rtl_source_c::set_gain( double gain, size_t chan )
   return get_gain( chan );
 }
 
+double rtl_source_c::set_lna_gain( double gain, size_t chan )
+{
+  osmosdr::gain_range_t gains = rtl_source_c::get_gain_range( "LNA", chan );
+
+  if (_dev) {
+    _lna_gain = gains.clip(gain);
+    return rtlsdr_set_tuner_gain_ext( _dev, int(_lna_gain), int(_mix_gain), int(_vga_gain) );
+  }
+
+  return 0;
+}
+
+double rtl_source_c::set_mix_gain( double gain, size_t chan )
+{
+  osmosdr::gain_range_t gains = rtl_source_c::get_gain_range( "MIX", chan );
+
+  if (_dev) {
+    _mix_gain = gains.clip(gain);
+    return rtlsdr_set_tuner_gain_ext( _dev, int(_lna_gain), int(_mix_gain), int(_vga_gain) );
+  }
+
+  return 0;
+}
+
+double rtl_source_c::set_vga_gain( double gain, size_t chan )
+{
+  osmosdr::gain_range_t gains = rtl_source_c::get_gain_range( "IF", chan );
+
+  if (_dev) {
+    _vga_gain = gains.clip(gain);
+    return rtlsdr_set_tuner_gain_ext( _dev, int(_lna_gain), int(_mix_gain), int(_vga_gain) );
+  }
+
+  return 0;
+}
+
 double rtl_source_c::set_gain( double gain, const std::string & name, size_t chan)
 {
+  if ( _extended_mode ) {
+    if ( "LNA" == name ) {
+      return set_lna_gain( gain, chan );
+    }
+
+    if ( "MIX" == name ) {
+      return set_mix_gain( gain, chan );
+    }
+
+    if ( "IF" == name ) {
+      return set_vga_gain( gain, chan );
+    }
+  }
+
   if ( "IF" == name ) {
     return set_if_gain( gain, chan );
   }
@@ -614,6 +715,20 @@ double rtl_source_c::get_gain( size_t chan )
 
 double rtl_source_c::get_gain( const std::string & name, size_t chan )
 {
+  if ( _extended_mode ) {
+    if ( "LNA" == name ) {
+      return _lna_gain;
+    }
+
+    if ( "MIX" == name ) {
+      return _mix_gain;
+    }
+
+    if ( "IF" == name ) {
+      return _vga_gain;
+    }
+  }
+
   if ( "IF" == name ) {
     return _if_gain;
   }
diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h
index 76de400..bb20e5c 100644
--- a/lib/rtl/rtl_source_c.h
+++ b/lib/rtl/rtl_source_c.h
@@ -101,12 +101,16 @@ public:
   osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
   bool set_gain_mode( bool automatic, size_t chan = 0 );
   bool get_gain_mode( size_t chan = 0 );
+  double set_bandwidth( double bandwidth, size_t chan = 0 );
   double set_gain( double gain, size_t chan = 0 );
   double set_gain( double gain, const std::string & name, size_t chan = 0 );
   double get_gain( size_t chan = 0 );
   double get_gain( const std::string & name, size_t chan = 0 );
 
   double set_if_gain( double gain, size_t chan = 0 );
+  double set_lna_gain( double gain, size_t chan = 0 );
+  double set_mix_gain( double gain, size_t chan = 0 );
+  double set_vga_gain( double gain, size_t chan = 0 );
 
   std::vector< std::string > get_antennas( size_t chan = 0 );
   std::string set_antenna( const std::string & antenna, size_t chan = 0 );
@@ -141,7 +145,12 @@ private:
   bool _no_tuner;
   bool _auto_gain;
   double _if_gain;
+  double _lna_gain;
+  double _mix_gain;
+  double _vga_gain;
   unsigned int _skipped;
+
+  bool _extended_mode;
 };
 
 #endif /* INCLUDED_RTLSDR_SOURCE_C_H */

Alexandru Csete

unread,
Dec 14, 2016, 10:58:46 AM12/14/16
to gq...@googlegroups.com
Hi Luigi,

Thanks for the update. Regarding modifying librtlsdr, I recommend you
take a look at
https://github.com/librtlsdr/librtlsdr
as it seems to contain many improvements over the original library. It
should be 100% ABI compatible and we are considering using this for
the Ubuntu PPA package.

Alex
> --
> You received this message because you are subscribed to the Google Groups
> "Gqrx SDR" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to gqrx+uns...@googlegroups.com.
> To post to this group, send email to gq...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/gqrx/0b3aa3e4-4a46-4218-bea7-722271657dc0%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Luigi Tarenga

unread,
Dec 22, 2016, 4:52:12 PM12/22/16
to Gqrx SDR
Hi Alex,
yes, I was looking at portin one patch back in the original tree but I don't know if it is
a good investment of time... I need to patch gr-osmosdr so I need  a fork of that too...
I'm thinking about possible solutions....

I want to update you about another things I'm lookin, FIR filter in the rtl2832u chip
check this out:
https://www.reddit.com/r/RTLSDR/comments/5jqk5h/playing_with_rtl2832u_fir_filter/
look at the screenshot of gqrx I made. I think I made an even better filter... I want to
write a patch thath include some selectable filters or a a way to load them  of pass
coefficient by dev string.

see ya and merry christmas!
Luigi
Reply all
Reply to author
Forward
0 new messages