mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
ad9361: Fix bandwidth warnings and ranges
Allows full bandwidth range to user. Reviewed-by: Michael West <michael.west@ettus.com> Reviewed-by: Martin Braun <martin.braun@ettus.com>
This commit is contained in:
parent
bbfa2a6870
commit
34fc6362a5
@ -70,16 +70,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
//! get the freq range for the frontend which
|
||||
//! get the freq range
|
||||
static uhd::meta_range_t get_rf_freq_range(void)
|
||||
{
|
||||
return uhd::meta_range_t(50e6, 6e9);
|
||||
}
|
||||
|
||||
//! get the filter range for the frontend which
|
||||
static uhd::meta_range_t get_bw_filter_range(const std::string &/*which*/)
|
||||
static uhd::meta_range_t get_bw_filter_range(void)
|
||||
{
|
||||
return uhd::meta_range_t(200e3, 56e6);
|
||||
return uhd::meta_range_t(ad9361_device_t::AD9361_MIN_BW, ad9361_device_t::AD9361_MAX_BW);
|
||||
}
|
||||
|
||||
//! get the clock rate range for the frontend
|
||||
|
||||
@ -233,10 +233,24 @@ public:
|
||||
|
||||
double set_bw_filter(const std::string &which, const double bw)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(_mutex);
|
||||
|
||||
ad9361_device_t::direction_t direction = _get_direction_from_antenna(which);
|
||||
return _device.set_bw_filter(direction, bw);
|
||||
double actual_bw = bw;
|
||||
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(_mutex);
|
||||
actual_bw = _device.set_bw_filter(direction, bw);
|
||||
}
|
||||
|
||||
const double min_bw = ad9361_device_t::AD9361_MIN_BW;
|
||||
const double max_bw = ad9361_device_t::AD9361_MAX_BW;
|
||||
if (bw < min_bw or bw > max_bw)
|
||||
{
|
||||
UHD_LOGGER_WARNING("AD936X") << boost::format(
|
||||
"The requested bandwidth %f MHz is out of range (%f - %f MHz).\n"
|
||||
"The bandwidth has been forced to %f MHz.\n"
|
||||
) % (bw/1e6) % (min_bw/1e6) % (max_bw/1e6) % (actual_bw/1e6);
|
||||
}
|
||||
return actual_bw;
|
||||
}
|
||||
|
||||
std::vector<std::string> get_filter_names(const std::string &which)
|
||||
|
||||
@ -85,7 +85,8 @@ const double ad9361_device_t::AD9361_MIN_CLOCK_RATE = 220e3;
|
||||
const double ad9361_device_t::AD9361_MAX_CLOCK_RATE = 61.44e6;
|
||||
const double ad9361_device_t::AD9361_CAL_VALID_WINDOW = 100e6;
|
||||
// Max bandwdith is due to filter rolloff in analog filter stage
|
||||
const double ad9361_device_t::AD9361_RECOMMENDED_MAX_BANDWIDTH = 56e6;
|
||||
const double ad9361_device_t::AD9361_MIN_BW = 200e3;
|
||||
const double ad9361_device_t::AD9361_MAX_BW = 56e6;
|
||||
|
||||
/* Startup RF frequencies */
|
||||
const double ad9361_device_t::DEFAULT_RX_FREQ = 800e6;
|
||||
@ -2409,20 +2410,20 @@ double ad9361_device_t::set_bw_filter(direction_t direction, const double rf_bw)
|
||||
{
|
||||
//both low pass filters are programmed to the same bw. However, their cutoffs will differ.
|
||||
//Together they should create the requested bb bw.
|
||||
double set_analog_bb_bw = 0;
|
||||
//Select rf_bw if it is between AD9361_MIN_BW & AD9361_MAX_BW.
|
||||
const double clipped_bw = std::min(std::max(rf_bw, AD9361_MIN_BW), AD9361_MAX_BW);
|
||||
if(direction == RX)
|
||||
{
|
||||
_rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(rf_bw); //returns bb bw
|
||||
_rx_tia_lp_bw = _calibrate_rx_TIAs(rf_bw);
|
||||
_rx_analog_bw = _rx_bb_lp_bw;
|
||||
set_analog_bb_bw = _rx_analog_bw;
|
||||
_rx_bb_lp_bw = _calibrate_baseband_rx_analog_filter(clipped_bw); //returns bb bw
|
||||
_rx_tia_lp_bw = _calibrate_rx_TIAs(clipped_bw);
|
||||
_rx_analog_bw = clipped_bw;
|
||||
} else {
|
||||
_tx_bb_lp_bw = _calibrate_baseband_tx_analog_filter(rf_bw); //returns bb bw
|
||||
_tx_sec_lp_bw = _calibrate_secondary_tx_filter(rf_bw);
|
||||
_tx_analog_bw = _tx_bb_lp_bw;
|
||||
set_analog_bb_bw = _tx_analog_bw;
|
||||
_tx_bb_lp_bw = _calibrate_baseband_tx_analog_filter(clipped_bw); //returns bb bw
|
||||
_tx_sec_lp_bw = _calibrate_secondary_tx_filter(clipped_bw);
|
||||
_tx_analog_bw = clipped_bw;
|
||||
}
|
||||
return (2.0 * set_analog_bb_bw);
|
||||
|
||||
return (clipped_bw);
|
||||
}
|
||||
|
||||
void ad9361_device_t::_set_fir_taps(direction_t direction, chain_t chain, const std::vector<int16_t>& taps)
|
||||
|
||||
@ -160,7 +160,8 @@ public:
|
||||
static const double AD9361_MAX_CLOCK_RATE;
|
||||
static const double AD9361_MIN_CLOCK_RATE;
|
||||
static const double AD9361_CAL_VALID_WINDOW;
|
||||
static const double AD9361_RECOMMENDED_MAX_BANDWIDTH;
|
||||
static const double AD9361_MIN_BW;
|
||||
static const double AD9361_MAX_BW;
|
||||
static const double DEFAULT_RX_FREQ;
|
||||
static const double DEFAULT_TX_FREQ;
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ using namespace uhd::usrp;
|
||||
* Default values
|
||||
***************************************************************************/
|
||||
const double ad936x_manager::DEFAULT_GAIN = 0;
|
||||
const double ad936x_manager::DEFAULT_BANDWIDTH = 56e6;
|
||||
const double ad936x_manager::DEFAULT_BANDWIDTH = ad9361_device_t::AD9361_MAX_BW;
|
||||
const double ad936x_manager::DEFAULT_TICK_RATE = 16e6;
|
||||
const double ad936x_manager::DEFAULT_FREQ = 100e6; // Hz
|
||||
const uint32_t ad936x_manager::DEFAULT_DECIM = 128;
|
||||
@ -47,8 +47,12 @@ public:
|
||||
));
|
||||
}
|
||||
for (size_t i = 1; i <= _n_frontends; i++) {
|
||||
_rx_frontends.push_back(str(boost::format("RX%d") % i));
|
||||
_tx_frontends.push_back(str(boost::format("TX%d") % i));
|
||||
const std::string rx_fe_str = str(boost::format("RX%d") % i);
|
||||
const std::string tx_fe_str = str(boost::format("TX%d") % i);
|
||||
_rx_frontends.push_back(rx_fe_str);
|
||||
_tx_frontends.push_back(tx_fe_str);
|
||||
_bw[rx_fe_str] = 0.0;
|
||||
_bw[tx_fe_str] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,14 +190,27 @@ public:
|
||||
|
||||
bool check_bandwidth(double rate, const std::string dir)
|
||||
{
|
||||
if (rate > _codec_ctrl->get_bw_filter_range(dir).stop()) {
|
||||
double bw = _bw[dir == "Rx" ? "RX1" : "TX1"];
|
||||
if (bw == 0.) //0 indicates bandwidth is default value.
|
||||
{
|
||||
double max_bw = ad9361_device_t::AD9361_MAX_BW;
|
||||
double min_bw = ad9361_device_t::AD9361_MIN_BW;
|
||||
if (rate > max_bw)
|
||||
{
|
||||
UHD_LOGGER_WARNING("AD936X")
|
||||
<< "Selected " << dir << " bandwidth (" << (rate/1e6) << " MHz) exceeds\n"
|
||||
<< "analog frontend filter bandwidth (" << (_codec_ctrl->get_bw_filter_range(dir).stop()/1e6) << " MHz)."
|
||||
<< "Selected " << dir << " sample rate (" << (rate/1e6) << " MHz) is greater than\n"
|
||||
<< "analog frontend filter bandwidth (" << (max_bw/1e6) << " MHz)."
|
||||
;
|
||||
return false;
|
||||
}
|
||||
else if (rate < min_bw)
|
||||
{
|
||||
UHD_LOGGER_WARNING("AD936X")
|
||||
<< "Selected " << dir << " sample rate (" << (rate/1e6) << " MHz) is less than\n"
|
||||
<< "analog frontend filter bandwidth (" << (min_bw/1e6) << " MHz)."
|
||||
;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return (rate <= bw);
|
||||
}
|
||||
|
||||
void populate_frontend_subtree(
|
||||
@ -236,15 +253,17 @@ public:
|
||||
|
||||
// Analog Bandwidths
|
||||
subtree->create<double>("bandwidth/value")
|
||||
.set(ad936x_manager::DEFAULT_BANDWIDTH)
|
||||
.set_coercer([this, key](const double bw){
|
||||
return this->_codec_ctrl->set_bw_filter(key, bw);
|
||||
})
|
||||
.set(DEFAULT_BANDWIDTH)
|
||||
.set_coercer([this,key](double bw) {
|
||||
return set_bw_filter(key, bw);
|
||||
}
|
||||
)
|
||||
;
|
||||
subtree->create<meta_range_t>("bandwidth/range")
|
||||
.set_publisher([key](){
|
||||
return ad9361_ctrl::get_bw_filter_range(key);
|
||||
})
|
||||
.set_publisher([key]() {
|
||||
return ad9361_ctrl::get_bw_filter_range();
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
// LO Tuning
|
||||
@ -321,6 +340,18 @@ private:
|
||||
std::vector<std::string> _rx_frontends;
|
||||
//! List of valid TX frontend names (TX1, TX2)
|
||||
std::vector<std::string> _tx_frontends;
|
||||
|
||||
//! Current bandwidths
|
||||
std::map<std::string,double> _bw;
|
||||
|
||||
//! Function to set bandwidth so it is tracked here
|
||||
double set_bw_filter(const std::string& which, const double bw)
|
||||
{
|
||||
double actual_bw = _codec_ctrl->set_bw_filter(which, bw);
|
||||
_bw[which] = actual_bw;
|
||||
return actual_bw;
|
||||
}
|
||||
|
||||
}; /* class ad936x_manager_impl */
|
||||
|
||||
ad936x_manager::sptr ad936x_manager::make(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user