diff options
-rw-r--r-- | grc/gen_osmosdr_blocks.py | 50 | ||||
-rw-r--r-- | include/osmosdr/osmosdr_source_c.h | 10 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_src_c.cc | 61 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_src_c.h | 2 | ||||
-rw-r--r-- | lib/osmosdr_source_c_impl.cc | 22 | ||||
-rw-r--r-- | lib/osmosdr_source_c_impl.h | 3 | ||||
-rw-r--r-- | lib/osmosdr_src_iface.h | 10 | ||||
-rw-r--r-- | lib/rtl/rtl_source_c.cc | 61 | ||||
-rw-r--r-- | lib/rtl/rtl_source_c.h | 2 |
9 files changed, 143 insertions, 78 deletions
diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py index 8e9fbc2..d5631ca 100644 --- a/grc/gen_osmosdr_blocks.py +++ b/grc/gen_osmosdr_blocks.py @@ -26,7 +26,7 @@ MAIN_TMPL = """\ <category>Sources</category> <throttle>1</throttle> <import>import osmosdr</import> - <make>osmosdr.$(sourk)_c( args="nchan=" + str(\$nchan) + " " + \$args ) + <make>osmosdr.$(sourk)_c( args="nchan=" + str(\$nchan) + " " + \$args ) self.\$(id).set_sample_rate(\$sample_rate) #for $n in range($max_nchan) \#if \$nchan() > $n @@ -34,18 +34,20 @@ self.\$(id).set_center_freq(\$freq$(n), $n) self.\$(id).set_freq_corr(\$corr$(n), $n) self.\$(id).set_gain_mode(\$gain_mode$(n), $n) self.\$(id).set_gain(\$gain$(n), $n) +self.\$(id).set_if_gain(\$if_gain$(n), $n) \#if \$ant$(n)() self.\$(id).set_antenna(\$ant$(n), $n) \#end if \#end if #end for -</make> + </make> <callback>set_sample_rate(\$sample_rate)</callback> #for $n in range($max_nchan) <callback>set_center_freq(\$freq$(n), $n)</callback> <callback>set_freq_corr(\$corr$(n), $n)</callback> <callback>set_gain_mode(\$gain_mode$(n), $n)</callback> <callback>set_gain(\$gain$(n), $n)</callback> + <callback>set_if_gain(\$if_gain$(n), $n)</callback> <callback>set_antenna(\$ant$(n), $n)</callback> #end for <param> @@ -100,18 +102,15 @@ self.\$(id).set_antenna(\$ant$(n), $n) <doc> The OsmoSDR $sourk.title() block: -While primarily being developed for the OsmoSDR hardware, this block also -supports the FunCube Dongle, Ettus UHD, rtl-sdr radios and cfile source. -By using the OsmoSDR block you can take advantage of a common software api in -your application(s) independent of the underlying radio hardware. +While primarily being developed for the OsmoSDR hardware, this block also supports the FunCube Dongle, Ettus UHD, rtl-sdr radios and cfile source. +By using the OsmoSDR block you can take advantage of a common software api in your application(s) independent of the underlying radio hardware. Output Type: This parameter controls the data type of the stream in gnuradio. Device Arguments: The device argument is a delimited string used to locate devices on your system. -Use the device id or name (if applicable) to specify a certain device or list -of devices. If left blank, the first device found will be used. +Use the device id or name (if applicable) to specify a certain device or list of devices. If left blank, the first device found will be used. Examples (some arguments may be optional): fcd=0 @@ -133,14 +132,18 @@ The center frequency is the overall frequency of the RF chain. Freq. Corr.: The frequency correction factor in parts per million (ppm). Leave 0 if unknown. -Gain: -Overall gain of the device's signal path. For the new gain value to be applied, -the manual gain mode must be enabled first. - Gain Mode: Chooses between the manual (default) and automatic gain mode where appropriate. Currently, only rtlsdr devices support automatic gain mode. +Gain: +Overall gain of the device's signal path. For the new gain value to be applied, the manual gain mode must be enabled first. + +IF Gain: +Overall IF gain of the device's signal path. For the new gain value to be applied, the manual gain mode must be enabled first. +This setting has only effect for rtl-sdr and OsmoSDR devices with E4000 tuners. +Observations lead to an useful gain range from 15 to 30dB. + Antenna: For devices with only one antenna, this may be left blank. Otherwise, the user should specify one of the possible antenna choices. @@ -157,7 +160,7 @@ PARAMS_TMPL = """ <param> <name>Ch$(n): Frequency (Hz)</name> <key>freq$(n)</key> - <value>0</value> + <value>100e6</value> <type>real</type> <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide> </param> @@ -169,13 +172,6 @@ PARAMS_TMPL = """ <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide> </param> <param> - <name>Ch$(n): Gain (dB)</name> - <key>gain$(n)</key> - <value>0</value> - <type>real</type> - <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide> - </param> - <param> <name>Ch$(n): Gain Mode</name> <key>gain_mode$(n)</key> <value>0</value> @@ -191,6 +187,20 @@ PARAMS_TMPL = """ </option> </param> <param> + <name>Ch$(n): Gain (dB)</name> + <key>gain$(n)</key> + <value>10</value> + <type>real</type> + <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide> + </param> + <param> + <name>Ch$(n): IF Gain (dB)</name> + <key>if_gain$(n)</key> + <value>20</value> + <type>real</type> + <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide> + </param> + <param> <name>Ch$(n): Antenna</name> <key>ant$(n)</key> <value></value> diff --git a/include/osmosdr/osmosdr_source_c.h b/include/osmosdr/osmosdr_source_c.h index 425902d..55a9a0f 100644 --- a/include/osmosdr/osmosdr_source_c.h +++ b/include/osmosdr/osmosdr_source_c.h @@ -198,6 +198,16 @@ public: virtual double get_gain( const std::string & name, size_t chan = 0 ) = 0; /*! + * Set the IF gain for the underlying radio hardware. + * This function will automatically distribute the desired gain value over + * available IF gain stages in an appropriate way and return the actual value. + * \param gain the gain in dB + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double set_if_gain( double gain, size_t chan = 0 ) = 0; + + /*! * Get the available antennas of the underlying radio hardware. * \param chan the channel index 0 to N-1 * \return a vector of strings containing the names of available antennas diff --git a/lib/osmosdr/osmosdr_src_c.cc b/lib/osmosdr/osmosdr_src_c.cc index bba0550..68c4a27 100644 --- a/lib/osmosdr/osmosdr_src_c.cc +++ b/lib/osmosdr/osmosdr_src_c.cc @@ -131,6 +131,8 @@ osmosdr_src_c::osmosdr_src_c (const std::string &args) if (ret < 0) throw std::runtime_error("Failed to reset usb buffers."); + set_if_gain( 24 ); /* preset to a reasonable default (non-GRC use case) */ + _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *)); for(unsigned int i = 0; i < _buf_num; ++i) @@ -410,6 +412,34 @@ bool osmosdr_src_c::get_gain_mode( size_t chan ) double osmosdr_src_c::set_gain( double gain, size_t chan ) { osmosdr::gain_range_t rf_gains = osmosdr_src_c::get_gain_range( chan ); + + if (_dev) { + osmosdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) ); + } + + return get_gain( chan ); +} + +double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t chan) +{ + return set_gain( gain, chan ); +} + +double osmosdr_src_c::get_gain( size_t chan ) +{ + if ( _dev ) + return ((double)osmosdr_get_tuner_gain( _dev )) / 10.0; + + return 0; +} + +double osmosdr_src_c::get_gain( const std::string & name, size_t chan ) +{ + return get_gain( chan ); +} + +double osmosdr_src_c::set_if_gain(double gain, size_t chan) +{ std::vector< osmosdr::gain_range_t > if_gains; if_gains += osmosdr::gain_range_t(-3, 6, 9); @@ -419,9 +449,6 @@ double osmosdr_src_c::set_gain( double gain, size_t chan ) if_gains += osmosdr::gain_range_t(3, 15, 3); if_gains += osmosdr::gain_range_t(3, 15, 3); - double rf_gain = rf_gains.clip(gain); - double missing_gain = gain - rf_gain; - std::map< int, double > gains; /* initialize with min gains */ @@ -432,7 +459,7 @@ double osmosdr_src_c::set_gain( double gain, size_t chan ) for (int i = if_gains.size() - 1; i >= 0; i--) { osmosdr::gain_range_t range = if_gains[ i ]; - double error = missing_gain; + double error = gain; for( double g = range.start(); g <= range.stop(); g += range.step() ) { @@ -444,7 +471,7 @@ double osmosdr_src_c::set_gain( double gain, size_t chan ) sum += gains[ j + 1 ]; } - double err = abs(missing_gain - sum); + double err = abs(gain - sum); if (err < error) { error = err; gains[ i + 1 ] = g; @@ -452,7 +479,7 @@ double osmosdr_src_c::set_gain( double gain, size_t chan ) } } #if 0 - std::cerr << missing_gain << " => "; double sum = 0; + std::cerr << gain << " => "; double sum = 0; for (unsigned int i = 0; i < gains.size(); i++) { sum += gains[ i + 1 ]; std::cerr << gains[ i + 1 ] << " "; @@ -460,32 +487,12 @@ double osmosdr_src_c::set_gain( double gain, size_t chan ) std::cerr << " = " << sum << std::endl; #endif if (_dev) { - osmosdr_set_tuner_gain( _dev, int(rf_gain * 10.0) ); - for (unsigned int stage = 1; stage <= gains.size(); stage++) { osmosdr_set_tuner_if_gain( _dev, stage, int(gains[ stage ] * 10.0)); } } - return get_gain( chan ); -} - -double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t chan) -{ - return set_gain( gain, chan ); -} - -double osmosdr_src_c::get_gain( size_t chan ) -{ - if ( _dev ) - return ((double)osmosdr_get_tuner_gain( _dev )) / 10.0; - - return 0; -} - -double osmosdr_src_c::get_gain( const std::string & name, size_t chan ) -{ - return get_gain( chan ); + return gain; } std::vector< std::string > osmosdr_src_c::get_antennas( size_t chan ) diff --git a/lib/osmosdr/osmosdr_src_c.h b/lib/osmosdr/osmosdr_src_c.h index 227ccae..9156454 100644 --- a/lib/osmosdr/osmosdr_src_c.h +++ b/lib/osmosdr/osmosdr_src_c.h @@ -105,6 +105,8 @@ private: 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 ); + 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 ); diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc index 4c5c3f9..5eec5c8 100644 --- a/lib/osmosdr_source_c_impl.cc +++ b/lib/osmosdr_source_c_impl.cc @@ -227,7 +227,7 @@ double osmosdr_source_c_impl::set_sample_rate(double rate) if (_sample_rate != rate) { BOOST_FOREACH( osmosdr_src_iface *dev, _devs ) - sample_rate = dev->set_sample_rate(rate); + sample_rate = dev->set_sample_rate(rate); _sample_rate = sample_rate; } @@ -382,7 +382,7 @@ double osmosdr_source_c_impl::set_gain( double gain, const std::string & name, s BOOST_FOREACH( osmosdr_src_iface *dev, _devs ) for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) if ( chan == channel++ ) - return dev->set_gain( gain, name, dev_chan ); + return dev->set_gain( gain, name, dev_chan ); return 0; } @@ -409,6 +409,20 @@ double osmosdr_source_c_impl::get_gain( const std::string & name, size_t chan ) return 0; } +double osmosdr_source_c_impl::set_if_gain(double gain, size_t chan) +{ + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _devs ) + for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) + if ( chan == channel++ ) + if ( _if_gain[ chan ] != gain ) { + _if_gain[ chan ] = gain; + return dev->set_if_gain( gain, dev_chan ); + } + + return 0; +} + std::vector< std::string > osmosdr_source_c_impl::get_antennas( size_t chan ) { size_t channel = 0; @@ -427,8 +441,8 @@ std::string osmosdr_source_c_impl::set_antenna( const std::string & antenna, siz for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) if ( chan == channel++ ) if ( _antenna[ chan ] != antenna ) { - _antenna[ chan ] = antenna; - return dev->set_antenna( antenna, dev_chan ); + _antenna[ chan ] = antenna; + return dev->set_antenna( antenna, dev_chan ); } return ""; diff --git a/lib/osmosdr_source_c_impl.h b/lib/osmosdr_source_c_impl.h index 1bdf6b3..a34bf3b 100644 --- a/lib/osmosdr_source_c_impl.h +++ b/lib/osmosdr_source_c_impl.h @@ -51,6 +51,8 @@ public: 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 ); + 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 ); @@ -67,6 +69,7 @@ private: std::map< size_t, double > _freq_corr; std::map< size_t, bool > _gain_mode; std::map< size_t, double > _gain; + std::map< size_t, double > _if_gain; std::map< size_t, std::string > _antenna; std::vector< osmosdr_src_iface * > _devs; }; diff --git a/lib/osmosdr_src_iface.h b/lib/osmosdr_src_iface.h index b9ab9f8..a169e0d 100644 --- a/lib/osmosdr_src_iface.h +++ b/lib/osmosdr_src_iface.h @@ -176,6 +176,16 @@ public: virtual double get_gain( const std::string & name, size_t chan = 0 ) = 0; /*! + * Set the IF gain for the underlying radio hardware. + * This function will automatically distribute the desired gain value over + * available IF gain stages in an appropriate way and return the actual value. + * \param gain the gain in dB + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double set_if_gain( double gain, size_t chan = 0 ) { return 0; } + + /*! * Get the available antennas of the underlying radio hardware. * \param chan the channel index 0 to N-1 * \return a vector of strings containing the names of available antennas diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc index 3a16bff..18db321 100644 --- a/lib/rtl/rtl_source_c.cc +++ b/lib/rtl/rtl_source_c.cc @@ -158,6 +158,8 @@ rtl_source_c::rtl_source_c (const std::string &args) if (ret < 0) throw std::runtime_error("Failed to reset usb buffers."); + set_if_gain( 24 ); /* preset to a reasonable default (non-GRC use case) */ + _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *)); for(unsigned int i = 0; i < _buf_num; ++i) @@ -441,6 +443,34 @@ bool rtl_source_c::get_gain_mode( size_t chan ) double rtl_source_c::set_gain( double gain, size_t chan ) { osmosdr::gain_range_t rf_gains = rtl_source_c::get_gain_range( chan ); + + if (_dev) { + rtlsdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) ); + } + + return get_gain( chan ); +} + +double rtl_source_c::set_gain( double gain, const std::string & name, size_t chan) +{ + return set_gain( gain, chan ); +} + +double rtl_source_c::get_gain( size_t chan ) +{ + if ( _dev ) + return ((double)rtlsdr_get_tuner_gain( _dev )) / 10.0; + + return 0; +} + +double rtl_source_c::get_gain( const std::string & name, size_t chan ) +{ + return get_gain( chan ); +} + +double rtl_source_c::set_if_gain(double gain, size_t chan) +{ std::vector< osmosdr::gain_range_t > if_gains; if_gains += osmosdr::gain_range_t(-3, 6, 9); @@ -450,9 +480,6 @@ double rtl_source_c::set_gain( double gain, size_t chan ) if_gains += osmosdr::gain_range_t(3, 15, 3); if_gains += osmosdr::gain_range_t(3, 15, 3); - double rf_gain = rf_gains.clip(gain); - double missing_gain = gain - rf_gain; - std::map< int, double > gains; /* initialize with min gains */ @@ -463,7 +490,7 @@ double rtl_source_c::set_gain( double gain, size_t chan ) for (int i = if_gains.size() - 1; i >= 0; i--) { osmosdr::gain_range_t range = if_gains[ i ]; - double error = missing_gain; + double error = gain; for( double g = range.start(); g <= range.stop(); g += range.step() ) { @@ -475,7 +502,7 @@ double rtl_source_c::set_gain( double gain, size_t chan ) sum += gains[ j + 1 ]; } - double err = abs(missing_gain - sum); + double err = abs(gain - sum); if (err < error) { error = err; gains[ i + 1 ] = g; @@ -483,7 +510,7 @@ double rtl_source_c::set_gain( double gain, size_t chan ) } } #if 0 - std::cerr << missing_gain << " => "; double sum = 0; + std::cerr << gain << " => "; double sum = 0; for (unsigned int i = 0; i < gains.size(); i++) { sum += gains[ i + 1 ]; std::cerr << gains[ i + 1 ] << " "; @@ -491,32 +518,12 @@ double rtl_source_c::set_gain( double gain, size_t chan ) std::cerr << " = " << sum << std::endl; #endif if (_dev) { - rtlsdr_set_tuner_gain( _dev, int(rf_gain * 10.0) ); - for (unsigned int stage = 1; stage <= gains.size(); stage++) { rtlsdr_set_tuner_if_gain( _dev, stage, int(gains[ stage ] * 10.0)); } } - return get_gain( chan ); -} - -double rtl_source_c::set_gain( double gain, const std::string & name, size_t chan) -{ - return set_gain( gain, chan ); -} - -double rtl_source_c::get_gain( size_t chan ) -{ - if ( _dev ) - return ((double)rtlsdr_get_tuner_gain( _dev )) / 10.0; - - return 0; -} - -double rtl_source_c::get_gain( const std::string & name, size_t chan ) -{ - return get_gain( chan ); + return gain; } std::vector< std::string > rtl_source_c::get_antennas( size_t chan ) diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h index 70dcf0e..5f4ccdd 100644 --- a/lib/rtl/rtl_source_c.h +++ b/lib/rtl/rtl_source_c.h @@ -106,6 +106,8 @@ public: 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 ); + 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 ); |