diff --git a/HackRF_Settings.cpp b/HackRF_Settings.cpp index 9451dc3..0319062 100644 --- a/HackRF_Settings.cpp +++ b/HackRF_Settings.cpp @@ -41,6 +41,7 @@ SoapyHackRF::SoapyHackRF( const SoapySDR::Kwargs &args ) _rx_stream.samplerate=0; _rx_stream.bandwidth=0; _rx_stream.overflow = false; + _rx_stream.bias = false; _tx_stream.vga_gain=0; _tx_stream.amp_gain=0; @@ -50,6 +51,7 @@ SoapyHackRF::SoapyHackRF( const SoapySDR::Kwargs &args ) _tx_stream.burst_samps=0; _tx_stream.burst_end=false; _tx_stream.underflow = false; + _tx_stream.bias = false; _current_mode=HACKRF_TRANSCEIVER_MODE_OFF; @@ -69,6 +71,14 @@ SoapyHackRF::SoapyHackRF( const SoapySDR::Kwargs &args ) _current_bandwidth=0; + _current_bias=false; + + if (args.count("bias_tx")) + _tx_stream.bias = args.at("bias_tx") == "true"; + + if (args.count("bias_rx")) + _rx_stream.bias = args.at("bias_rx") == "true"; + int ret = hackrf_open_by_serial(_serial.c_str(), &_dev); if ( ret != HACKRF_SUCCESS ) { @@ -174,13 +184,20 @@ SoapySDR::ArgInfoList SoapyHackRF::getSettingInfo(void) const { SoapySDR::ArgInfoList setArgs; - SoapySDR::ArgInfo biastxArg; - biastxArg.key="bias_tx"; - biastxArg.value="false"; - biastxArg.name="Antenna Bias"; - biastxArg.description="Antenna port power control."; - biastxArg.type=SoapySDR::ArgInfo::BOOL; - setArgs.push_back(biastxArg); + SoapySDR::ArgInfo biasArg; + biasArg.key="bias_tx"; + biasArg.value="false"; + biasArg.name="Antenna Bias (TX)"; + biasArg.description="Antenna port power control on TX."; + biasArg.type=SoapySDR::ArgInfo::BOOL; + setArgs.push_back(biasArg); + + biasArg.key="bias_rx"; + biasArg.value="false"; + biasArg.name="Antenna Bias (RX)"; + biasArg.description="Antenna port power control on RX."; + biasArg.type=SoapySDR::ArgInfo::BOOL; + setArgs.push_back(biasArg); return setArgs; } @@ -190,21 +207,35 @@ void SoapyHackRF::writeSetting(const std::string &key, const std::string &value) if(key=="bias_tx"){ std::lock_guard lock(_device_mutex); _tx_stream.bias=(value=="true") ? true : false; - int ret=hackrf_set_antenna_enable(_dev,_tx_stream.bias); - if(ret!=HACKRF_SUCCESS){ - SoapySDR_logf(SOAPY_SDR_INFO,"Failed to apply antenna bias voltage"); + if (_current_mode==HACKRF_TRANSCEIVER_MODE_TX) { + _current_bias=_tx_stream.bias; + int ret=hackrf_set_antenna_enable(_dev,_current_bias); + if(ret!=HACKRF_SUCCESS) + SoapySDR_logf(SOAPY_SDR_INFO,"Failed to apply antenna bias voltage (TX)"); + } + } else if(key=="bias_rx"){ + + std::lock_guard lock(_device_mutex); + _rx_stream.bias=(value=="true") ? true : false; + if (_current_mode == HACKRF_TRANSCEIVER_MODE_RX) { + _current_bias=_rx_stream.bias; + int ret=hackrf_set_antenna_enable(_dev,_current_bias); + if(ret!=HACKRF_SUCCESS) + SoapySDR_logf(SOAPY_SDR_INFO,"Failed to apply antenna bias voltage (RX)"); } } - } std::string SoapyHackRF::readSetting(const std::string &key) const { if (key == "bias_tx") { return _tx_stream.bias?"true":"false"; + } else if (key == "bias_rx") { + return _rx_stream.bias?"true":"false"; } + return ""; } /******************************************************************* diff --git a/HackRF_Streaming.cpp b/HackRF_Streaming.cpp index 9ea8514..2806ad7 100644 --- a/HackRF_Streaming.cpp +++ b/HackRF_Streaming.cpp @@ -283,7 +283,6 @@ int SoapyHackRF::activateStream( const long long timeNs, const size_t numElems ) { - if(stream == RX_STREAM){ std::lock_guard lock(_device_mutex); @@ -339,7 +338,15 @@ int SoapyHackRF::activateStream( } } - SoapySDR_logf(SOAPY_SDR_DEBUG, "Start RX"); + // Bias voltage. Since this setting may be provided as a device argument, + // it may not take effect until streaming is enabled for the first time. + if(_current_bias != _rx_stream.bias) { + _current_bias = _rx_stream.bias; + SoapySDR_logf(SOAPY_SDR_DEBUG, "activateStream - Set RX bias voltage to %s", _current_bias ? "enabled" : "disabled"); + hackrf_set_antenna_enable(_dev,_current_bias); + } + + SoapySDR_logf(SOAPY_SDR_DEBUG, "Start RX", _current_bias); //reset buffer tracking before streaming { @@ -369,6 +376,8 @@ int SoapyHackRF::activateStream( hackrf_set_amp_enable(_dev,(_current_amp > 0)?1 : 0 ); hackrf_set_lna_gain(_dev,_rx_stream.lna_gain); hackrf_set_vga_gain(_dev,_rx_stream.vga_gain); + _current_bias = _rx_stream.bias; + hackrf_set_antenna_enable(_dev,_current_bias); hackrf_start_rx(_dev,_hackrf_rx_callback,(void *) this); ret=hackrf_is_streaming(_dev); } @@ -434,11 +443,17 @@ int SoapyHackRF::activateStream( SoapySDR_logf(SOAPY_SDR_DEBUG, "activateStream - Set RX bandwidth to %d", _current_bandwidth); hackrf_set_baseband_filter_bandwidth(_dev,_current_bandwidth); } + } + // Bias voltage. Since this setting may be provided as a device argument, + // it may not take effect until streaming is enabled for the first time. + if(_current_bias != _tx_stream.bias) { + _current_bias = _tx_stream.bias; + SoapySDR_logf(SOAPY_SDR_DEBUG, "activateStream - Set TX bias voltage to %s", _current_bias ? "enabled" : "disabled"); + hackrf_set_antenna_enable(_dev,_current_bias); } SoapySDR_logf( SOAPY_SDR_DEBUG, "Start TX" ); - int ret = hackrf_start_tx( _dev, _hackrf_tx_callback, (void *) this ); if (ret != HACKRF_SUCCESS) { @@ -461,7 +476,8 @@ int SoapyHackRF::activateStream( _current_amp=_rx_stream.amp_gain; hackrf_set_amp_enable(_dev,(_current_amp > 0)?1 : 0 ); hackrf_set_txvga_gain(_dev,_tx_stream.vga_gain); - hackrf_set_antenna_enable(_dev,_tx_stream.bias); + _current_bias = _tx_stream.bias; + hackrf_set_antenna_enable(_dev,_current_bias); hackrf_start_tx(_dev,_hackrf_tx_callback,(void *) this); ret=hackrf_is_streaming(_dev); } diff --git a/SoapyHackRF.hpp b/SoapyHackRF.hpp index a6591bd..1973706 100644 --- a/SoapyHackRF.hpp +++ b/SoapyHackRF.hpp @@ -332,7 +332,7 @@ class SoapyHackRF : public SoapySDR::Device double samplerate; uint32_t bandwidth; uint64_t frequency; - + bool bias; bool overflow; }; @@ -366,6 +366,8 @@ class SoapyHackRF : public SoapySDR::Device uint8_t _current_amp; + bool _current_bias; + /// Mutex protecting all use of the hackrf device _dev and other instance variables. /// Most of the hackrf API is thread-safe because it only calls libusb, however /// the activateStream() method in this library can close and re-open the device,