[PATCH 1/3] - Added support for manual gain modes of AirspyHF+ - TODO support for AGC threshold level

Kieren Rasmussen rascustoms at gmail.com
Thu Aug 23 14:29:48 UTC 2018


From: Kieren Rasmussen <kieren at wolftechpc.com.au>

---
 README                            |   1 +
 grc/gen_osmosdr_blocks.py         |   2 +
 lib/airspyhf/airspyhf_source_c.cc | 102 ++++++++++++++++++++++++++++--
 lib/airspyhf/airspyhf_source_c.h  |   9 +++
 4 files changed, 110 insertions(+), 4 deletions(-)

diff --git a/README b/README
index 67fa475..6f8ece3 100644
--- a/README
+++ b/README
@@ -11,6 +11,7 @@ as well supports:
  * gnuradio .cfile input through libgnuradio-blocks
  * RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
  * AirSpy Wideband Receiver through libairspy
+ * AirSpy HF+ through libairspyhf
  * CCCamp 2015 rad1o Badge through libhackrf
  * Great Scott Gadgets HackRF through libhackrf
  * Nuand LLC bladeRF through libbladeRF library
diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py
index d1f2b1a..5932395 100644
--- a/grc/gen_osmosdr_blocks.py
+++ b/grc/gen_osmosdr_blocks.py
@@ -219,6 +219,7 @@ While primarily being developed for the OsmoSDR hardware, this block as well sup
  * gnuradio .cfile input through libgnuradio-blocks
  * RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
  * AirSpy Wideband Receiver through libairspy
+ * AirSpy HF+ through libairspyhf
 #end if
 #if $sourk == 'sink':
  * gnuradio .cfile output through libgnuradio-blocks
@@ -260,6 +261,7 @@ Lines ending with ... mean it's possible to bind devices together by specifying
   cloudiq=127.0.0.1[:50000]
   sdr-iq=/dev/ttyUSB0
   airspy=0[,bias=0|1][,linearity][,sensitivity]
+  airspyhf=0
 #end if
 #if $sourk == 'sink':
   file='/path/to/your file',rate=1e6[,freq=100e6][,append=true][,throttle=true] ...
diff --git a/lib/airspyhf/airspyhf_source_c.cc b/lib/airspyhf/airspyhf_source_c.cc
index f4b3533..e4dbe5f 100644
--- a/lib/airspyhf/airspyhf_source_c.cc
+++ b/lib/airspyhf/airspyhf_source_c.cc
@@ -384,38 +384,132 @@ double airspyhf_source_c::get_freq_corr( size_t chan )
 
 std::vector<std::string> airspyhf_source_c::get_gain_names( size_t chan )
 {
-  return std::vector<std::string>();
+  std::vector<std::string> names;
+  names += "LNA";
+  names += "ATT";
+
+  return names;
 }
 
 osmosdr::gain_range_t airspyhf_source_c::get_gain_range( size_t chan )
 {
-  return osmosdr::gain_range_t();
+  // Based on libairspyhf +6db with LNA and 0 to -48dB with Attenuation
+  return osmosdr::gain_range_t(-48, 6, 6);
 }
 
 osmosdr::gain_range_t airspyhf_source_c::get_gain_range( const std::string & name, size_t chan )
 {
+  if ("LNA" == name) {
+    return osmosdr::gain_range_t(0, 6, 6);
+  } else if ("ATT" == name) {
+    return osmosdr::gain_range_t(-48, 0, 6);
+  }
   return osmosdr::gain_range_t();
 }
 
+bool airspyhf_source_c::set_gain_mode( bool automatic, size_t chan )
+{
+  if ( automatic ) {
+    airspyhf_set_hf_agc( _dev, 1 );
+  } else {
+    airspyhf_set_hf_agc( _dev, 0 );
+  }
+  _auto_gain = automatic;
+
+  return get_gain_mode(chan);
+}
+
+bool airspyhf_source_c::get_gain_mode( size_t chan )
+{
+  return _auto_gain;
+}
 
 double airspyhf_source_c::set_gain( double gain, size_t chan )
 {
+  osmosdr::gain_range_t gains = get_gain_range(chan);
+
+  if(_dev) {
+    double clip_gain = gains.clip(gain, true);
+
+    if (clip_gain > 0) {
+      if (set_lna_gain(clip_gain, chan) == clip_gain && set_att_gain(0, chan) == 0) {
+        _gain = clip_gain;
+      }
+    } else {
+      if (set_lna_gain(0, chan) == 0 && set_att_gain(clip_gain, chan) == 0) {
+        _gain = clip_gain;
+      }
+    }
+  }
+
   return gain;
 }
 
 double airspyhf_source_c::set_gain( double gain, const std::string & name, size_t chan)
 {
+  if ("LNA" == name) {
+    return set_lna_gain(gain, chan);
+  } else if ("ATT" == name) {
+    return set_att_gain(gain, chan);
+  }
+
   return gain;
 }
 
 double airspyhf_source_c::get_gain( size_t chan )
 {
-  return 0.0;
+  return _gain;
 }
 
 double airspyhf_source_c::get_gain( const std::string & name, size_t chan )
 {
-  return 0.0;
+  if ("LNA" == name) {
+    return _lna_gain;
+  } else if ("ATT" == name) {
+    return _att_gain;
+  }
+
+  return get_gain(chan);
+}
+
+double airspyhf_source_c::set_lna_gain( double gain, size_t chan )
+{
+  int ret = AIRSPYHF_SUCCESS;
+  osmosdr::gain_range_t gains = get_gain_range( "LNA", chan );
+
+  if (_dev) {
+    double clip_gain = gains.clip( gain, true );
+    uint8_t value = (uint8_t) ((clip_gain > 0) ? 1 : 0);
+
+    ret = airspyhf_set_hf_lna( _dev, value );
+    if ( AIRSPYHF_SUCCESS == ret ) {
+      _lna_gain = clip_gain;
+    } else {
+      AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_lna_gain", value ) )
+    }
+  }
+
+  return _lna_gain;
+}
+
+double airspyhf_source_c::set_att_gain( double gain, size_t chan )
+{
+  int ret = AIRSPYHF_SUCCESS;
+  osmosdr::gain_range_t gains = get_gain_range( "LNA", chan );
+
+  if (_dev) {
+    double clip_gain = gains.clip( gain, true );
+    uint8_t value = (uint8_t) (clip_gain / -6);
+
+    ret = airspyhf_set_hf_att( _dev, value );
+    if ( AIRSPYHF_SUCCESS == ret ) {
+      _att_gain = clip_gain;
+    } else {
+      AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_att_gain", value ) )
+    }
+  }
+
+  return _lna_gain;
 }
 
 std::vector< std::string > airspyhf_source_c::get_antennas( size_t chan )
diff --git a/lib/airspyhf/airspyhf_source_c.h b/lib/airspyhf/airspyhf_source_c.h
index cfb8c89..d464d07 100644
--- a/lib/airspyhf/airspyhf_source_c.h
+++ b/lib/airspyhf/airspyhf_source_c.h
@@ -88,11 +88,16 @@ public:
   std::vector<std::string> get_gain_names( size_t chan = 0 );
   osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
   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_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_lna_gain( double gain, size_t chan = 0 );
+  double set_att_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 );
   std::string get_antenna( size_t chan = 0 );
@@ -112,6 +117,10 @@ private:
   double _sample_rate;
   double _center_freq;
   double _freq_corr;
+  bool _auto_gain;
+  double _gain;
+  double _lna_gain;
+  double _att_gain;
 };
 
 #endif /* INCLUDED_AIRSPY_SOURCE_C_H */
-- 
2.18.0



More information about the osmocom-sdr mailing list