hackrf: implement BB lowpass filter control

To use the default (automatic) bandwidth filter selection, this should
be set to 0.
This commit is contained in:
Dimitri Stolnikov 2013-04-15 23:36:55 +02:00
parent 8578eee7ce
commit afd56f4b5a
7 changed files with 134 additions and 9 deletions

View File

@ -37,9 +37,8 @@ self.\$(id).set_gain_mode(\$gain_mode$(n), $n)
self.\$(id).set_gain(\$gain$(n), $n) self.\$(id).set_gain(\$gain$(n), $n)
self.\$(id).set_if_gain(\$if_gain$(n), $n) self.\$(id).set_if_gain(\$if_gain$(n), $n)
self.\$(id).set_bb_gain(\$bb_gain$(n), $n) self.\$(id).set_bb_gain(\$bb_gain$(n), $n)
\#if \$ant$(n)()
self.\$(id).set_antenna(\$ant$(n), $n) self.\$(id).set_antenna(\$ant$(n), $n)
\#end if self.\$(id).set_bandwidth(\$bw$(n), $n)
\#end if \#end if
#end for #end for
</make> </make>
@ -53,6 +52,7 @@ self.\$(id).set_antenna(\$ant$(n), $n)
<callback>set_if_gain(\$if_gain$(n), $n)</callback> <callback>set_if_gain(\$if_gain$(n), $n)</callback>
<callback>set_bb_gain(\$bb_gain$(n), $n)</callback> <callback>set_bb_gain(\$bb_gain$(n), $n)</callback>
<callback>set_antenna(\$ant$(n), $n)</callback> <callback>set_antenna(\$ant$(n), $n)</callback>
<callback>set_bandwidth(\$bw$(n), $n)</callback>
#end for #end for
<param> <param>
<name>$(dir.title())put Type</name> <name>$(dir.title())put Type</name>
@ -183,6 +183,9 @@ Antenna:
For devices with only one antenna, this may be left blank. For devices with only one antenna, this may be left blank.
Otherwise, the user should specify one of the possible antenna choices. 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: See the OsmoSDR project page for more detailed documentation:
http://sdr.osmocom.org/trac/ http://sdr.osmocom.org/trac/
http://sdr.osmocom.org/trac/wiki/rtl-sdr http://sdr.osmocom.org/trac/wiki/rtl-sdr
@ -276,6 +279,21 @@ PARAMS_TMPL = """
\#end if \#end if
</hide> </hide>
</param> </param>
<param>
<name>Ch$(n): Bandwidth (Hz)</name>
<key>bw$(n)</key>
<value>0</value>
<type>real</type>
<hide>
\#if not \$nchan() > $n
all
\#elif \$bw$(n)()
none
\#else
part
\#end if
</hide>
</param>
""" """
def parse_tmpl(_tmpl, **kwargs): def parse_tmpl(_tmpl, **kwargs):

View File

@ -263,6 +263,27 @@ public:
*/ */
virtual void set_iq_balance( const std::complex<double> &correction, virtual void set_iq_balance( const std::complex<double> &correction,
size_t chan = 0 ) = 0; 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 */ #endif /* INCLUDED_OSMOSDR_SOURCE_C_H */

View File

@ -625,13 +625,13 @@ std::string hackrf_source_c::get_antenna( size_t chan )
return "ANT"; 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; int ret;
// osmosdr::meta_range_t bandwidths = get_bandwidth_range( chan ); // osmosdr::meta_range_t bandwidths = get_bandwidth_range( chan );
if ( bandwidth == 0.0 ) if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */
return; bandwidth = _sample_rate;
if ( _dev ) { if ( _dev ) {
/* compute best default value depending on sample rate (auto filter) */ /* 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__ ) ); throw std::runtime_error( std::string( __FUNCTION__ ) );
} }
} }
return _bandwidth;
} }
double hackrf_source_c::get_bandwidth( size_t chan ) double hackrf_source_c::get_bandwidth( size_t chan )

View File

@ -113,7 +113,7 @@ private:
std::string set_antenna( const std::string & antenna, size_t chan = 0 ); std::string set_antenna( const std::string & antenna, size_t chan = 0 );
std::string get_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 ); double get_bandwidth( size_t chan = 0 );
osmosdr::meta_range_t get_bandwidth_range( size_t chan = 0 ); osmosdr::meta_range_t get_bandwidth_range( size_t chan = 0 );

View File

@ -561,8 +561,8 @@ double osmosdr_source_c_impl::set_bb_gain( double gain, size_t chan )
BOOST_FOREACH( osmosdr_src_iface *dev, _devs ) BOOST_FOREACH( osmosdr_src_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) if ( chan == channel++ )
if ( _if_gain[ chan ] != gain ) { if ( _bb_gain[ chan ] != gain ) {
_if_gain[ chan ] = gain; _bb_gain[ chan ] = gain;
return dev->set_bb_gain( gain, dev_chan ); return dev->set_bb_gain( gain, dev_chan );
} }
@ -662,3 +662,39 @@ void osmosdr_source_c_impl::set_iq_balance( const std::complex<double> &correcti
} }
#endif #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();
}

View File

@ -66,6 +66,10 @@ public:
void set_iq_balance_mode( int mode, size_t chan = 0 ); void set_iq_balance_mode( int mode, size_t chan = 0 );
void set_iq_balance( const std::complex<double> &correction, size_t chan = 0 ); void set_iq_balance( const std::complex<double> &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: private:
osmosdr_source_c_impl (const std::string & args); // private constructor osmosdr_source_c_impl (const std::string & args); // private constructor
@ -73,19 +77,22 @@ private:
// access the private constructor. // access the private constructor.
friend osmosdr_source_c_sptr osmosdr_make_source_c (const std::string & args); friend osmosdr_source_c_sptr osmosdr_make_source_c (const std::string & args);
std::vector< osmosdr_src_iface * > _devs;
double _sample_rate; double _sample_rate;
std::map< size_t, double > _center_freq; std::map< size_t, double > _center_freq;
std::map< size_t, double > _freq_corr; std::map< size_t, double > _freq_corr;
std::map< size_t, bool > _gain_mode; std::map< size_t, bool > _gain_mode;
std::map< size_t, double > _gain; std::map< size_t, double > _gain;
std::map< size_t, double > _if_gain; std::map< size_t, double > _if_gain;
std::map< size_t, double > _bb_gain;
std::map< size_t, std::string > _antenna; std::map< size_t, std::string > _antenna;
std::vector< osmosdr_src_iface * > _devs;
#ifdef HAVE_IQBALANCE #ifdef HAVE_IQBALANCE
std::vector< iqbalance_fix_cc * > _iq_fix; std::vector< iqbalance_fix_cc * > _iq_fix;
std::vector< iqbalance_optimize_c * > _iq_opt; std::vector< iqbalance_optimize_c * > _iq_opt;
std::map< size_t, std::pair<float, float> > _vals; std::map< size_t, std::pair<float, float> > _vals;
#endif #endif
std::map< size_t, double > _bandwidth;
}; };
#endif /* INCLUDED_OSMOSDR_SOURCE_C_IMPL_H */ #endif /* INCLUDED_OSMOSDR_SOURCE_C_IMPL_H */

View File

@ -216,6 +216,47 @@ public:
* \return the actual antenna's name * \return the actual antenna's name
*/ */
virtual std::string get_antenna( size_t chan = 0 ) = 0; 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<double> &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 #endif // OSMOSDR_SRC_IFACE_H