From afd56f4b5a5c9ac107aaca91364239c0ce61634d Mon Sep 17 00:00:00 2001 From: Dimitri Stolnikov Date: Mon, 15 Apr 2013 23:36:55 +0200 Subject: [PATCH] hackrf: implement BB lowpass filter control To use the default (automatic) bandwidth filter selection, this should be set to 0. --- grc/gen_osmosdr_blocks.py | 22 ++++++++++++++-- include/osmosdr/osmosdr_source_c.h | 21 +++++++++++++++ lib/hackrf/hackrf_source_c.cc | 8 +++--- lib/hackrf/hackrf_source_c.h | 2 +- lib/osmosdr_source_c_impl.cc | 40 +++++++++++++++++++++++++++-- lib/osmosdr_source_c_impl.h | 9 ++++++- lib/osmosdr_src_iface.h | 41 ++++++++++++++++++++++++++++++ 7 files changed, 134 insertions(+), 9 deletions(-) diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py index 76231aa..84d1e15 100644 --- a/grc/gen_osmosdr_blocks.py +++ b/grc/gen_osmosdr_blocks.py @@ -37,9 +37,8 @@ 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) self.\$(id).set_bb_gain(\$bb_gain$(n), $n) -\#if \$ant$(n)() self.\$(id).set_antenna(\$ant$(n), $n) -\#end if +self.\$(id).set_bandwidth(\$bw$(n), $n) \#end if #end for @@ -53,6 +52,7 @@ self.\$(id).set_antenna(\$ant$(n), $n) set_if_gain(\$if_gain$(n), $n) set_bb_gain(\$bb_gain$(n), $n) set_antenna(\$ant$(n), $n) + set_bandwidth(\$bw$(n), $n) #end for $(dir.title())put Type @@ -183,6 +183,9 @@ Antenna: For devices with only one antenna, this may be left blank. Otherwise, the user should specify one of the possible antenna choices. +Bandwidth: +Set the bandpass filter on the radio frontend. To use the default (automatic) bandwidth filter setting, this should be zero. + See the OsmoSDR project page for more detailed documentation: http://sdr.osmocom.org/trac/ http://sdr.osmocom.org/trac/wiki/rtl-sdr @@ -276,6 +279,21 @@ PARAMS_TMPL = """ \#end if + + Ch$(n): Bandwidth (Hz) + bw$(n) + 0 + real + + \#if not \$nchan() > $n + all + \#elif \$bw$(n)() + none + \#else + part + \#end if + + """ def parse_tmpl(_tmpl, **kwargs): diff --git a/include/osmosdr/osmosdr_source_c.h b/include/osmosdr/osmosdr_source_c.h index dd4505c..8410849 100644 --- a/include/osmosdr/osmosdr_source_c.h +++ b/include/osmosdr/osmosdr_source_c.h @@ -263,6 +263,27 @@ public: */ virtual void set_iq_balance( const std::complex &correction, size_t chan = 0 ) = 0; + + /*! + * Set the bandpass filter on the radio frontend. + * \param bandwidth the filter bandwidth in Hz + * \param chan the channel index 0 to N-1 + * \return the actual filter bandwidth in Hz + */ + virtual double set_bandwidth( double bandwidth, size_t chan = 0 ) = 0; + + /*! + * Get the actual bandpass filter setting on the radio frontend. + * \param chan the channel index 0 to N-1 + * \return the actual filter bandwidth in Hz + */ + virtual double get_bandwidth( size_t chan = 0 ) = 0; + + /*! + * Get the possible bandpass filter settings on the radio frontend. + * \return a range of bandwidths in Hz + */ + virtual osmosdr::meta_range_t get_bandwidth_range( size_t chan = 0 ) = 0; }; #endif /* INCLUDED_OSMOSDR_SOURCE_C_H */ diff --git a/lib/hackrf/hackrf_source_c.cc b/lib/hackrf/hackrf_source_c.cc index 5543ea0..e5db62c 100644 --- a/lib/hackrf/hackrf_source_c.cc +++ b/lib/hackrf/hackrf_source_c.cc @@ -625,13 +625,13 @@ std::string hackrf_source_c::get_antenna( size_t chan ) return "ANT"; } -void hackrf_source_c::set_bandwidth( double bandwidth, size_t chan ) +double hackrf_source_c::set_bandwidth( double bandwidth, size_t chan ) { int ret; // osmosdr::meta_range_t bandwidths = get_bandwidth_range( chan ); - if ( bandwidth == 0.0 ) - return; + if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */ + bandwidth = _sample_rate; if ( _dev ) { /* compute best default value depending on sample rate (auto filter) */ @@ -643,6 +643,8 @@ void hackrf_source_c::set_bandwidth( double bandwidth, size_t chan ) throw std::runtime_error( std::string( __FUNCTION__ ) ); } } + + return _bandwidth; } double hackrf_source_c::get_bandwidth( size_t chan ) diff --git a/lib/hackrf/hackrf_source_c.h b/lib/hackrf/hackrf_source_c.h index ea14944..3e60749 100644 --- a/lib/hackrf/hackrf_source_c.h +++ b/lib/hackrf/hackrf_source_c.h @@ -113,7 +113,7 @@ private: std::string set_antenna( const std::string & antenna, size_t chan = 0 ); std::string get_antenna( size_t chan = 0 ); - void set_bandwidth( double bandwidth, size_t chan = 0 ); + double set_bandwidth( double bandwidth, size_t chan = 0 ); double get_bandwidth( size_t chan = 0 ); osmosdr::meta_range_t get_bandwidth_range( size_t chan = 0 ); diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc index fcac3cb..568e7b4 100644 --- a/lib/osmosdr_source_c_impl.cc +++ b/lib/osmosdr_source_c_impl.cc @@ -561,8 +561,8 @@ double osmosdr_source_c_impl::set_bb_gain( double gain, size_t chan ) 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; + if ( _bb_gain[ chan ] != gain ) { + _bb_gain[ chan ] = gain; return dev->set_bb_gain( gain, dev_chan ); } @@ -662,3 +662,39 @@ void osmosdr_source_c_impl::set_iq_balance( const std::complex &correcti } #endif } + +double osmosdr_source_c_impl::set_bandwidth( double bandwidth, 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 ( _bandwidth[ chan ] != bandwidth ) { + _bandwidth[ chan ] = bandwidth; + return dev->set_bandwidth( bandwidth, dev_chan ); + } + + return 0; +} + +double osmosdr_source_c_impl::get_bandwidth( 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++ ) + return dev->get_bandwidth( dev_chan ); + + return 0; +} + +osmosdr::meta_range_t osmosdr_source_c_impl::get_bandwidth_range( 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++ ) + return dev->get_bandwidth_range( dev_chan ); + + return osmosdr::meta_range_t(); +} diff --git a/lib/osmosdr_source_c_impl.h b/lib/osmosdr_source_c_impl.h index 92c8d38..6c252d4 100644 --- a/lib/osmosdr_source_c_impl.h +++ b/lib/osmosdr_source_c_impl.h @@ -66,6 +66,10 @@ public: void set_iq_balance_mode( int mode, size_t chan = 0 ); void set_iq_balance( const std::complex &correction, size_t chan = 0 ); + double set_bandwidth( double bandwidth, size_t chan = 0 ); + double get_bandwidth( size_t chan = 0 ); + osmosdr::meta_range_t get_bandwidth_range( size_t chan = 0 ); + private: osmosdr_source_c_impl (const std::string & args); // private constructor @@ -73,19 +77,22 @@ private: // access the private constructor. friend osmosdr_source_c_sptr osmosdr_make_source_c (const std::string & args); + std::vector< osmosdr_src_iface * > _devs; + double _sample_rate; std::map< size_t, double > _center_freq; 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, double > _bb_gain; std::map< size_t, std::string > _antenna; - std::vector< osmosdr_src_iface * > _devs; #ifdef HAVE_IQBALANCE std::vector< iqbalance_fix_cc * > _iq_fix; std::vector< iqbalance_optimize_c * > _iq_opt; std::map< size_t, std::pair > _vals; #endif + std::map< size_t, double > _bandwidth; }; #endif /* INCLUDED_OSMOSDR_SOURCE_C_IMPL_H */ diff --git a/lib/osmosdr_src_iface.h b/lib/osmosdr_src_iface.h index 6c149f9..d9fa362 100644 --- a/lib/osmosdr_src_iface.h +++ b/lib/osmosdr_src_iface.h @@ -216,6 +216,47 @@ public: * \return the actual antenna's name */ virtual std::string get_antenna( size_t chan = 0 ) = 0; + + /*! + * Set the RX frontend IQ balance mode. + * + * \param mode iq balance correction mode: 0 = Off, 1 = Manual, 2 = Automatic + * \param chan the channel index 0 to N-1 + */ + virtual void set_iq_balance_mode( int mode, size_t chan = 0 ) + { return; } + + /*! + * Set the RX frontend IQ balance correction. + * Use this to adjust the magnitude and phase of I and Q. + * + * \param correction the complex correction value + * \param chan the channel index 0 to N-1 + */ + virtual void set_iq_balance( const std::complex &correction, size_t chan = 0 ) + { return; } + + /*! + * Set the bandpass filter on the radio frontend. + * \param bandwidth the filter bandwidth in Hz + * \param chan the channel index 0 to N-1 + * \return the actual filter bandwidth in Hz + */ + virtual double set_bandwidth( double bandwidth, size_t chan = 0 ) { return 0; } + + /*! + * Get the actual bandpass filter setting on the radio frontend. + * \param chan the channel index 0 to N-1 + * \return the actual filter bandwidth in Hz + */ + virtual double get_bandwidth( size_t chan = 0 ) { return 0; } + + /*! + * Get the possible bandpass filter settings on the radio frontend. + * \return a range of bandwidths in Hz + */ + virtual osmosdr::meta_range_t get_bandwidth_range( size_t chan = 0 ) + { return osmosdr::meta_range_t(); } }; #endif // OSMOSDR_SRC_IFACE_H