aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/x300/x300_radio_ctrl_impl.cpp')
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.cpp1092
1 files changed, 648 insertions, 444 deletions
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
index d0aadc55a..9057180e4 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
@@ -6,19 +6,19 @@
#include "x300_radio_ctrl_impl.hpp"
#include "x300_dboard_iface.hpp"
-#include <uhd/usrp/dboard_eeprom.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/usrp/dboard_iface.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/transport/chdr.hpp>
+#include <uhd/usrp/dboard_eeprom.hpp>
+#include <uhd/usrp/dboard_iface.hpp>
+#include <uhd/utils/log.hpp>
#include <uhd/utils/math.hpp>
#include <uhd/utils/safe_call.hpp>
#include <uhdlib/rfnoc/wb_iface_adapter.hpp>
-#include <uhdlib/usrp/cores/gpio_atr_3000.hpp>
#include <uhdlib/usrp/common/apply_corrections.hpp>
+#include <uhdlib/usrp/cores/gpio_atr_3000.hpp>
#include <boost/algorithm/string.hpp>
-#include <boost/make_shared.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
+#include <boost/make_shared.hpp>
#include <chrono>
#include <thread>
@@ -33,26 +33,26 @@ static const size_t IO_MASTER_RADIO = 0;
* Structors
***************************************************************************/
UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)
- , _ignore_cal_file(false)
+, _ignore_cal_file(false)
{
- UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::ctor() " ;
+ UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::ctor() ";
////////////////////////////////////////////////////////////////////
// Set up basic info
////////////////////////////////////////////////////////////////////
- _radio_type = (get_block_id().get_block_count() == 0) ? PRIMARY : SECONDARY;
- _radio_slot = (get_block_id().get_block_count() == 0) ? "A" : "B";
+ _radio_type = (get_block_id().get_block_count() == 0) ? PRIMARY : SECONDARY;
+ _radio_slot = (get_block_id().get_block_count() == 0) ? "A" : "B";
_radio_clk_rate = _tree->access<double>("master_clock_rate").get();
////////////////////////////////////////////////////////////////////
// Set up peripherals
////////////////////////////////////////////////////////////////////
wb_iface::sptr ctrl = _get_ctrl(IO_MASTER_RADIO);
- _regs = boost::make_shared<radio_regmap_t>(_radio_type==PRIMARY?0:1);
+ _regs = boost::make_shared<radio_regmap_t>(_radio_type == PRIMARY ? 0 : 1);
_regs->initialize(*ctrl, true);
- //Only Radio0 has the ADC/DAC reset bits. Those bits are reserved for Radio1
- if (_radio_type==PRIMARY) {
+ // Only Radio0 has the ADC/DAC reset bits. Those bits are reserved for Radio1
+ if (_radio_type == PRIMARY) {
_regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
_regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
_regs->misc_outs_reg.flush();
@@ -67,84 +67,100 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)
////////////////////////////////////////////////////////////////
_spi = spi_core_3000::make(ctrl,
regs::sr_addr(radio_ctrl_impl::regs::SPI),
- regs::rb_addr(radio_ctrl_impl::regs::RB_SPI)
- );
+ regs::rb_addr(radio_ctrl_impl::regs::RB_SPI));
_adc = x300_adc_ctrl::make(_spi, DB_ADC_SEN);
_dac = x300_dac_ctrl::make(_spi, DB_DAC_SEN, _radio_clk_rate);
- if (_radio_type==PRIMARY) {
- _fp_gpio = gpio_atr::gpio_atr_3000::make(ctrl,
- regs::sr_addr(regs::FP_GPIO),
- regs::rb_addr(regs::RB_FP_GPIO)
- );
- for(const gpio_atr::gpio_attr_map_t::value_type attr: gpio_atr::gpio_attr_map) {
- switch (attr.first){
+ if (_radio_type == PRIMARY) {
+ _fp_gpio = gpio_atr::gpio_atr_3000::make(
+ ctrl, regs::sr_addr(regs::FP_GPIO), regs::rb_addr(regs::RB_FP_GPIO));
+ for (const gpio_atr::gpio_attr_map_t::value_type attr : gpio_atr::gpio_attr_map) {
+ switch (attr.first) {
case usrp::gpio_atr::GPIO_SRC:
- _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second)
- .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
- .add_coerced_subscriber([this](const std::vector<std::string>&){
- throw uhd::runtime_error("This device does not support setting the GPIO_SRC attribute.");
- });
+ _tree
+ ->create<std::vector<std::string>>(
+ fs_path("gpio") / "FP0" / attr.second)
+ .set(std::vector<std::string>(
+ 32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
+ .add_coerced_subscriber([this](const std::vector<std::string>&) {
+ throw uhd::runtime_error("This device does not support "
+ "setting the GPIO_SRC attribute.");
+ });
break;
case usrp::gpio_atr::GPIO_CTRL:
case usrp::gpio_atr::GPIO_DDR:
- _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second)
- .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
- .add_coerced_subscriber([this, attr](const std::vector<std::string> str_val){
- uint32_t val = 0;
- for(size_t i = 0 ; i < str_val.size() ; i++){
- val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i;
- }
- _fp_gpio->set_gpio_attr(attr.first, val);
- });
+ _tree
+ ->create<std::vector<std::string>>(
+ fs_path("gpio") / "FP0" / attr.second)
+ .set(std::vector<std::string>(
+ 32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
+ .add_coerced_subscriber(
+ [this, attr](const std::vector<std::string> str_val) {
+ uint32_t val = 0;
+ for (size_t i = 0; i < str_val.size(); i++) {
+ val += usrp::gpio_atr::gpio_attr_value_pair
+ .at(attr.second)
+ .at(str_val[i])
+ << i;
+ }
+ _fp_gpio->set_gpio_attr(attr.first, val);
+ });
break;
case usrp::gpio_atr::GPIO_READBACK:
_tree->create<uint32_t>(fs_path("gpio") / "FP0" / "READBACK")
- .set_publisher([this](){
- return _fp_gpio->read_gpio();
- });
+ .set_publisher([this]() { return _fp_gpio->read_gpio(); });
break;
default:
_tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second)
- .set(0)
- .add_coerced_subscriber([this, attr](const uint32_t val){
- _fp_gpio->set_gpio_attr(attr.first, val);
- });
+ .set(0)
+ .add_coerced_subscriber([this, attr](const uint32_t val) {
+ _fp_gpio->set_gpio_attr(attr.first, val);
+ });
}
-
}
}
////////////////////////////////////////////////////////////////
// create legacy codec control objects
////////////////////////////////////////////////////////////////
- _tree->create<int>("rx_codecs" / _radio_slot / "gains"); //phony property so this dir exists
- _tree->create<int>("tx_codecs" / _radio_slot / "gains"); //phony property so this dir exists
+ _tree->create<int>(
+ "rx_codecs" / _radio_slot / "gains"); // phony property so this dir exists
+ _tree->create<int>(
+ "tx_codecs" / _radio_slot / "gains"); // phony property so this dir exists
_tree->create<std::string>("rx_codecs" / _radio_slot / "name").set("ads62p48");
_tree->create<std::string>("tx_codecs" / _radio_slot / "name").set("ad9146");
- _tree->create<meta_range_t>("rx_codecs" / _radio_slot / "gains" / "digital" / "range").set(meta_range_t(0, 6.0, 0.5));
+ _tree->create<meta_range_t>("rx_codecs" / _radio_slot / "gains" / "digital" / "range")
+ .set(meta_range_t(0, 6.0, 0.5));
_tree->create<double>("rx_codecs" / _radio_slot / "gains" / "digital" / "value")
- .add_coerced_subscriber(boost::bind(&x300_adc_ctrl::set_gain, _adc, _1)).set(0)
- ;
+ .add_coerced_subscriber(boost::bind(&x300_adc_ctrl::set_gain, _adc, _1))
+ .set(0);
////////////////////////////////////////////////////////////////
// create front-end objects
////////////////////////////////////////////////////////////////
for (size_t i = 0; i < _get_num_radios(); i++) {
- _leds[i] = gpio_atr::gpio_atr_3000::make_write_only(_get_ctrl(i), regs::sr_addr(regs::LEDS));
- _leds[i]->set_atr_mode(usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL);
+ _leds[i] = gpio_atr::gpio_atr_3000::make_write_only(
+ _get_ctrl(i), regs::sr_addr(regs::LEDS));
+ _leds[i]->set_atr_mode(
+ usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL);
- _rx_fe_map[i].core = rx_frontend_core_3000::make(_get_ctrl(i), regs::sr_addr(x300_regs::RX_FE_BASE));
+ _rx_fe_map[i].core = rx_frontend_core_3000::make(
+ _get_ctrl(i), regs::sr_addr(x300_regs::RX_FE_BASE));
_rx_fe_map[i].core->set_adc_rate(_radio_clk_rate);
_rx_fe_map[i].core->set_dc_offset(rx_frontend_core_3000::DEFAULT_DC_OFFSET_VALUE);
- _rx_fe_map[i].core->set_dc_offset_auto(rx_frontend_core_3000::DEFAULT_DC_OFFSET_ENABLE);
- _rx_fe_map[i].core->populate_subtree(_tree->subtree(_root_path / "rx_fe_corrections" / i));
+ _rx_fe_map[i].core->set_dc_offset_auto(
+ rx_frontend_core_3000::DEFAULT_DC_OFFSET_ENABLE);
+ _rx_fe_map[i].core->populate_subtree(
+ _tree->subtree(_root_path / "rx_fe_corrections" / i));
- _tx_fe_map[i].core = tx_frontend_core_200::make(_get_ctrl(i), regs::sr_addr(x300_regs::TX_FE_BASE));
+ _tx_fe_map[i].core = tx_frontend_core_200::make(
+ _get_ctrl(i), regs::sr_addr(x300_regs::TX_FE_BASE));
_tx_fe_map[i].core->set_dc_offset(tx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE);
- _tx_fe_map[i].core->set_iq_balance(tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE);
- _tx_fe_map[i].core->populate_subtree(_tree->subtree(_root_path / "tx_fe_corrections" / i));
+ _tx_fe_map[i].core->set_iq_balance(
+ tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE);
+ _tx_fe_map[i].core->populate_subtree(
+ _tree->subtree(_root_path / "tx_fe_corrections" / i));
////////////////////////////////////////////////////////////////
// Bind the daughterboard command time to the motherboard level property
@@ -152,16 +168,19 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)
if (_tree->exists(fs_path("time") / "cmd")) {
_tree->access<time_spec_t>(fs_path("time") / "cmd")
- .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i));
+ .add_coerced_subscriber(
+ boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i));
}
}
////////////////////////////////////////////////////////////////
// Update default SPP (overwrites the default value from the XML file)
////////////////////////////////////////////////////////////////
- const size_t max_bytes_header = uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t);
- const size_t default_spp = (_tree->access<size_t>("mtu/recv").get() - max_bytes_header)
- / (2 * sizeof(int16_t));
+ const size_t max_bytes_header =
+ uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t);
+ const size_t default_spp =
+ (_tree->access<size_t>("mtu/recv").get() - max_bytes_header)
+ / (2 * sizeof(int16_t));
_tree->access<int>(get_arg_path("spp") / "value").set(default_spp);
}
@@ -173,21 +192,19 @@ x300_radio_ctrl_impl::~x300_radio_ctrl_impl()
_tree->remove(fs_path("tx_codecs" / _radio_slot));
_tree->remove(_root_path / "rx_fe_corrections");
_tree->remove(_root_path / "tx_fe_corrections");
- if (_radio_type==PRIMARY) {
- for(const gpio_atr::gpio_attr_map_t::value_type attr: gpio_atr::gpio_attr_map) {
+ if (_radio_type == PRIMARY) {
+ for (const gpio_atr::gpio_attr_map_t::value_type attr :
+ gpio_atr::gpio_attr_map) {
_tree->remove(fs_path("gpio") / "FP0" / attr.second);
}
}
// Reset peripherals
- if (_radio_type==PRIMARY) {
+ if (_radio_type == PRIMARY) {
_regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
_regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
- }
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0);
- _regs->misc_outs_reg.flush();
- )
-
+ } _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0);
+ _regs->misc_outs_reg.flush();)
}
/****************************************************************************
@@ -197,102 +214,129 @@ double x300_radio_ctrl_impl::set_rate(double rate)
{
const double actual_rate = get_rate();
if (not uhd::math::frequencies_are_equal(rate, actual_rate)) {
- UHD_LOGGER_WARNING("X300 RADIO") << "Requesting invalid sampling rate from device: " << rate/1e6 << " MHz. Actual rate is: " << actual_rate/1e6 << " MHz." ;
+ UHD_LOGGER_WARNING("X300 RADIO")
+ << "Requesting invalid sampling rate from device: " << rate / 1e6
+ << " MHz. Actual rate is: " << actual_rate / 1e6 << " MHz.";
}
// On X3x0, tick rate can't actually be changed at runtime
return actual_rate;
}
-void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t &time, const size_t chan)
+void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t& time, const size_t chan)
{
- if (_tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) {
- _tree->access<time_spec_t>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd")
- ).set(time);
+ if (_tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) {
+ _tree
+ ->access<time_spec_t>(
+ fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))
+ .set(time);
}
}
-void x300_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan)
+void x300_radio_ctrl_impl::set_tx_antenna(const std::string& ant, const size_t chan)
{
- _tree->access<std::string>(
- fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value")
- ).set(ant);
+ _tree
+ ->access<std::string>(
+ fs_path("dboards" / _radio_slot / "tx_frontends"
+ / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
+ .set(ant);
}
std::string x300_radio_ctrl_impl::get_tx_antenna(const size_t chan)
{
- return _tree->access<std::string>(
- fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value")
- ).get();
+ return _tree
+ ->access<std::string>(
+ fs_path("dboards" / _radio_slot / "tx_frontends"
+ / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
+ .get();
}
-void x300_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t chan)
+void x300_radio_ctrl_impl::set_rx_antenna(const std::string& ant, const size_t chan)
{
- _tree->access<std::string>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value")
- ).set(ant);
+ _tree
+ ->access<std::string>(
+ fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
+ .set(ant);
}
std::string x300_radio_ctrl_impl::get_rx_antenna(const size_t chan)
{
- return _tree->access<std::string>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value")
- ).get();
+ return _tree
+ ->access<std::string>(
+ fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
+ .get();
}
double x300_radio_ctrl_impl::set_tx_frequency(const double freq, const size_t chan)
{
- return _tree->access<double>(
- fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "freq" / "value")
- ).set(freq).get();
+ return _tree
+ ->access<double>(fs_path("dboards" / _radio_slot / "tx_frontends"
+ / _tx_fe_map.at(chan).db_fe_name / "freq" / "value"))
+ .set(freq)
+ .get();
}
double x300_radio_ctrl_impl::get_tx_frequency(const size_t chan)
{
- return _tree->access<double>(
- fs_path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "freq" / "value")
- ).get();
+ return _tree
+ ->access<double>(fs_path("dboards" / _radio_slot / "tx_frontends"
+ / _tx_fe_map.at(chan).db_fe_name / "freq" / "value"))
+ .get();
}
double x300_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan)
{
- return _tree->access<double>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "freq" / "value")
- ).set(freq).get();
+ return _tree
+ ->access<double>(fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "freq" / "value"))
+ .set(freq)
+ .get();
}
double x300_radio_ctrl_impl::get_rx_frequency(const size_t chan)
{
- return _tree->access<double>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "freq" / "value")
- ).get();
+ return _tree
+ ->access<double>(fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "freq" / "value"))
+ .get();
}
double x300_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan)
{
- return _tree->access<double>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value")
- ).set(bandwidth).get();
+ return _tree
+ ->access<double>(
+ fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value"))
+ .set(bandwidth)
+ .get();
}
double x300_radio_ctrl_impl::get_rx_bandwidth(const size_t chan)
{
- return _tree->access<double>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value")
- ).get();
+ return _tree
+ ->access<double>(
+ fs_path("dboards" / _radio_slot / "rx_frontends"
+ / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value"))
+ .get();
}
double x300_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan)
{
- //TODO: This is extremely hacky!
- fs_path path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name / "gains");
+ // TODO: This is extremely hacky!
+ fs_path path("dboards" / _radio_slot / "tx_frontends" / _tx_fe_map.at(chan).db_fe_name
+ / "gains");
std::vector<std::string> gain_stages = _tree->list(path);
if (gain_stages.size() == 1) {
- const double actual_gain = _tree->access<double>(path / gain_stages[0] / "value").set(gain).get();
+ const double actual_gain =
+ _tree->access<double>(path / gain_stages[0] / "value").set(gain).get();
radio_ctrl_impl::set_tx_gain(actual_gain, chan);
return gain;
} else {
- UHD_LOGGER_WARNING("X300 RADIO") << "set_tx_gain: could not apply gain for this daughterboard.";
+ UHD_LOGGER_WARNING("X300 RADIO")
+ << "set_tx_gain: could not apply gain for this daughterboard.";
radio_ctrl_impl::set_tx_gain(0.0, chan);
return 0.0;
}
@@ -300,15 +344,18 @@ double x300_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan)
double x300_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan)
{
- //TODO: This is extremely hacky!
- fs_path path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "gains");
+ // TODO: This is extremely hacky!
+ fs_path path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name
+ / "gains");
std::vector<std::string> gain_stages = _tree->list(path);
if (gain_stages.size() == 1) {
- const double actual_gain = _tree->access<double>(path / gain_stages[0] / "value").set(gain).get();
+ const double actual_gain =
+ _tree->access<double>(path / gain_stages[0] / "value").set(gain).get();
radio_ctrl_impl::set_rx_gain(actual_gain, chan);
return gain;
} else {
- UHD_LOGGER_WARNING("X300 RADIO") << "set_rx_gain: could not apply gain for this daughterboard.";
+ UHD_LOGGER_WARNING("X300 RADIO")
+ << "set_rx_gain: could not apply gain for this daughterboard.";
radio_ctrl_impl::set_tx_gain(0.0, chan);
return 0.0;
}
@@ -317,79 +364,105 @@ double x300_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan)
std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_names(const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
std::vector<std::string> lo_names;
if (_tree->exists(rx_fe_fe_root / "los")) {
- for(const std::string &name: _tree->list(rx_fe_fe_root / "los")) {
+ for (const std::string& name : _tree->list(rx_fe_fe_root / "los")) {
lo_names.push_back(name);
}
}
return lo_names;
}
-std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_sources(const std::string &name, const size_t chan)
+std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_sources(
+ const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
- //Special value ALL_LOS support atomically sets the source for all LOs
- return _tree->access< std::vector<std::string> >(rx_fe_fe_root / "los" / ALL_LOS / "source" / "options").get();
+ // Special value ALL_LOS support atomically sets the source for all LOs
+ return _tree
+ ->access<std::vector<std::string>>(
+ rx_fe_fe_root / "los" / ALL_LOS / "source" / "options")
+ .get();
} else {
return std::vector<std::string>();
}
} else {
if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree->access< std::vector<std::string> >(rx_fe_fe_root / "los" / name / "source" / "options").get();
+ return _tree
+ ->access<std::vector<std::string>>(
+ rx_fe_fe_root / "los" / name / "source" / "options")
+ .get();
} else {
throw uhd::runtime_error("Could not find LO stage " + name);
}
}
} else {
// If the daughterboard doesn't expose it's LO(s) then it can only be internal
- return std::vector<std::string> (1, "internal");
+ return std::vector<std::string>(1, "internal");
}
}
-void x300_radio_ctrl_impl::set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan)
+void x300_radio_ctrl_impl::set_rx_lo_source(
+ const std::string& src, const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
- //Special value ALL_LOS support atomically sets the source for all LOs
- _tree->access<std::string>(rx_fe_fe_root / "los" / ALL_LOS / "source" / "value").set(src);
+ // Special value ALL_LOS support atomically sets the source for all LOs
+ _tree
+ ->access<std::string>(
+ rx_fe_fe_root / "los" / ALL_LOS / "source" / "value")
+ .set(src);
} else {
- for(const std::string &n: _tree->list(rx_fe_fe_root / "los")) {
+ for (const std::string& n : _tree->list(rx_fe_fe_root / "los")) {
this->set_rx_lo_source(src, n, chan);
}
}
} else {
if (_tree->exists(rx_fe_fe_root / "los")) {
- _tree->access<std::string>(rx_fe_fe_root / "los" / name / "source" / "value").set(src);
+ _tree
+ ->access<std::string>(
+ rx_fe_fe_root / "los" / name / "source" / "value")
+ .set(src);
} else {
throw uhd::runtime_error("Could not find LO stage " + name);
}
}
} else {
- throw uhd::runtime_error("This device does not support manual configuration of LOs");
+ throw uhd::runtime_error(
+ "This device does not support manual configuration of LOs");
}
}
-const std::string x300_radio_ctrl_impl::get_rx_lo_source(const std::string &name, const size_t chan)
+const std::string x300_radio_ctrl_impl::get_rx_lo_source(
+ const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
- //Special value ALL_LOS support atomically sets the source for all LOs
- return _tree->access<std::string>(rx_fe_fe_root / "los" / ALL_LOS / "source" / "value").get();
+ // Special value ALL_LOS support atomically sets the source for all LOs
+ return _tree
+ ->access<std::string>(
+ rx_fe_fe_root / "los" / ALL_LOS / "source" / "value")
+ .get();
} else {
if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree->access<std::string>(rx_fe_fe_root / "los" / name / "source" / "value").get();
+ return _tree
+ ->access<std::string>(
+ rx_fe_fe_root / "los" / name / "source" / "value")
+ .get();
} else {
throw uhd::runtime_error("Could not find LO stage " + name);
}
@@ -400,17 +473,20 @@ const std::string x300_radio_ctrl_impl::get_rx_lo_source(const std::string &name
}
}
-void x300_radio_ctrl_impl::set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan)
+void x300_radio_ctrl_impl::set_rx_lo_export_enabled(
+ bool enabled, const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
- //Special value ALL_LOS support atomically sets the source for all LOs
- _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export").set(enabled);
+ // Special value ALL_LOS support atomically sets the source for all LOs
+ _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export")
+ .set(enabled);
} else {
- for(const std::string &n: _tree->list(rx_fe_fe_root / "los")) {
+ for (const std::string& n : _tree->list(rx_fe_fe_root / "los")) {
this->set_rx_lo_export_enabled(enabled, n, chan);
}
}
@@ -422,17 +498,20 @@ void x300_radio_ctrl_impl::set_rx_lo_export_enabled(bool enabled, const std::str
}
}
} else {
- throw uhd::runtime_error("This device does not support manual configuration of LOs");
+ throw uhd::runtime_error(
+ "This device does not support manual configuration of LOs");
}
}
-bool x300_radio_ctrl_impl::get_rx_lo_export_enabled(const std::string &name, const size_t chan)
+bool x300_radio_ctrl_impl::get_rx_lo_export_enabled(
+ const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
- //Special value ALL_LOS support atomically sets the source for all LOs
+ // Special value ALL_LOS support atomically sets the source for all LOs
return _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export").get();
} else {
if (_tree->exists(rx_fe_fe_root / "los")) {
@@ -447,56 +526,73 @@ bool x300_radio_ctrl_impl::get_rx_lo_export_enabled(const std::string &name, con
}
}
-double x300_radio_ctrl_impl::set_rx_lo_freq(double freq, const std::string &name, const size_t chan)
+double x300_radio_ctrl_impl::set_rx_lo_freq(
+ double freq, const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
- throw uhd::runtime_error("LO frequency must be set for each stage individually");
+ throw uhd::runtime_error(
+ "LO frequency must be set for each stage individually");
} else {
if (_tree->exists(rx_fe_fe_root / "los")) {
- _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").set(freq);
- return _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").get();
+ _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value")
+ .set(freq);
+ return _tree
+ ->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value")
+ .get();
} else {
throw uhd::runtime_error("Could not find LO stage " + name);
}
}
} else {
- throw uhd::runtime_error("This device does not support manual configuration of LOs");
+ throw uhd::runtime_error(
+ "This device does not support manual configuration of LOs");
}
}
-double x300_radio_ctrl_impl::get_rx_lo_freq(const std::string &name, const size_t chan)
+double x300_radio_ctrl_impl::get_rx_lo_freq(const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
- throw uhd::runtime_error("LO frequency must be retrieved for each stage individually");
+ throw uhd::runtime_error(
+ "LO frequency must be retrieved for each stage individually");
} else {
if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value").get();
+ return _tree
+ ->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value")
+ .get();
} else {
throw uhd::runtime_error("Could not find LO stage " + name);
}
}
} else {
// Return actual RF frequency if the daughterboard doesn't expose it's LO(s)
- return _tree->access<double>(rx_fe_fe_root / "freq" /" value").get();
+ return _tree->access<double>(rx_fe_fe_root / "freq" / " value").get();
}
}
-freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range(const std::string &name, const size_t chan)
+freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range(
+ const std::string& name, const size_t chan)
{
- fs_path rx_fe_fe_root = fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
+ fs_path rx_fe_fe_root = fs_path(
+ "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
if (_tree->exists(rx_fe_fe_root / "los")) {
if (name == ALL_LOS) {
- throw uhd::runtime_error("LO frequency range must be retrieved for each stage individually");
+ throw uhd::runtime_error(
+ "LO frequency range must be retrieved for each stage individually");
} else {
if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree->access<freq_range_t>(rx_fe_fe_root / "los" / name / "freq" / "range").get();
+ return _tree
+ ->access<freq_range_t>(
+ rx_fe_fe_root / "los" / name / "freq" / "range")
+ .get();
} else {
throw uhd::runtime_error("Could not find LO stage " + name);
}
@@ -508,21 +604,19 @@ freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range(const std::string &name,
}
template <typename map_type>
-static size_t _get_chan_from_map(std::map<size_t, map_type> map, const std::string &fe)
+static size_t _get_chan_from_map(std::map<size_t, map_type> map, const std::string& fe)
{
for (auto it = map.begin(); it != map.end(); ++it) {
if (it->second.db_fe_name == fe) {
return it->first;
}
-
}
- throw uhd::runtime_error(str(
- boost::format("Invalid daughterboard frontend name: %s")
- % fe
- ));
+ throw uhd::runtime_error(
+ str(boost::format("Invalid daughterboard frontend name: %s") % fe));
}
-size_t x300_radio_ctrl_impl::get_chan_from_dboard_fe(const std::string &fe, const uhd::direction_t direction)
+size_t x300_radio_ctrl_impl::get_chan_from_dboard_fe(
+ const std::string& fe, const uhd::direction_t direction)
{
switch (direction) {
case uhd::TX_DIRECTION:
@@ -534,7 +628,8 @@ size_t x300_radio_ctrl_impl::get_chan_from_dboard_fe(const std::string &fe, cons
}
}
-std::string x300_radio_ctrl_impl::get_dboard_fe_from_chan(const size_t chan, const uhd::direction_t direction)
+std::string x300_radio_ctrl_impl::get_dboard_fe_from_chan(
+ const size_t chan, const uhd::direction_t direction)
{
switch (direction) {
case uhd::TX_DIRECTION:
@@ -565,61 +660,83 @@ double x300_radio_ctrl_impl::get_output_samp_rate(size_t chan)
std::vector<std::string> x300_radio_ctrl_impl::get_gpio_banks() const
{
std::vector<std::string> banks{"RX", "TX"};
- // These pairs are the same, but RXA/TXA are from pre-rfnoc era and are kept for backward compat:
- banks.push_back("RX"+_radio_slot);
- banks.push_back("TX"+_radio_slot);
+ // These pairs are the same, but RXA/TXA are from pre-rfnoc era and are kept for
+ // backward compat:
+ banks.push_back("RX" + _radio_slot);
+ banks.push_back("TX" + _radio_slot);
if (_fp_gpio) {
banks.push_back("FP0");
}
return banks;
}
-void x300_radio_ctrl_impl::set_gpio_attr(
- const std::string &bank,
- const std::string &attr,
- const uint32_t value,
- const uint32_t mask
-) {
+void x300_radio_ctrl_impl::set_gpio_attr(const std::string& bank,
+ const std::string& attr,
+ const uint32_t value,
+ const uint32_t mask)
+{
if (bank == "FP0" and _fp_gpio) {
- const uint32_t current = _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get();
+ const uint32_t current =
+ _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get();
const uint32_t new_value = (current & ~mask) | (value & mask);
_tree->access<uint32_t>(fs_path("gpio") / bank / attr).set(new_value);
return;
}
- if (bank.size() > 2 and bank[1] == 'X')
- {
- const std::string name = bank.substr(2);
- const dboard_iface::unit_t unit = (bank[0] == 'R')? dboard_iface::UNIT_RX : dboard_iface::UNIT_TX;
- dboard_iface::sptr iface = _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
- if (attr == "CTRL") iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask));
- if (attr == "DDR") iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask));
- if (attr == "OUT") iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_0X") iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_RX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_TX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_XX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask));
+ if (bank.size() > 2 and bank[1] == 'X') {
+ const std::string name = bank.substr(2);
+ const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX
+ : dboard_iface::UNIT_TX;
+ dboard_iface::sptr iface =
+ _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
+ if (attr == "CTRL")
+ iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask));
+ if (attr == "DDR")
+ iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask));
+ if (attr == "OUT")
+ iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_0X")
+ iface->set_atr_reg(
+ unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_RX")
+ iface->set_atr_reg(
+ unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_TX")
+ iface->set_atr_reg(
+ unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_XX")
+ iface->set_atr_reg(
+ unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask));
}
}
uint32_t x300_radio_ctrl_impl::get_gpio_attr(
- const std::string &bank,
- const std::string &attr
-) {
+ const std::string& bank, const std::string& attr)
+{
if (bank == "FP0" and _fp_gpio) {
return uint32_t(_tree->access<uint64_t>(fs_path("gpio") / bank / attr).get());
}
if (bank.size() > 2 and bank[1] == 'X') {
- const std::string name = bank.substr(2);
- const dboard_iface::unit_t unit = (bank[0] == 'R')? dboard_iface::UNIT_RX : dboard_iface::UNIT_TX;
- dboard_iface::sptr iface = _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
- if (attr == "CTRL") return iface->get_pin_ctrl(unit);
- if (attr == "DDR") return iface->get_gpio_ddr(unit);
- if (attr == "OUT") return iface->get_gpio_out(unit);
- if (attr == "ATR_0X") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE);
- if (attr == "ATR_RX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY);
- if (attr == "ATR_TX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY);
- if (attr == "ATR_XX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX);
- if (attr == "READBACK") return iface->read_gpio(unit);
+ const std::string name = bank.substr(2);
+ const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX
+ : dboard_iface::UNIT_TX;
+ dboard_iface::sptr iface =
+ _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
+ if (attr == "CTRL")
+ return iface->get_pin_ctrl(unit);
+ if (attr == "DDR")
+ return iface->get_gpio_ddr(unit);
+ if (attr == "OUT")
+ return iface->get_gpio_out(unit);
+ if (attr == "ATR_0X")
+ return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE);
+ if (attr == "ATR_RX")
+ return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY);
+ if (attr == "ATR_TX")
+ return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY);
+ if (attr == "ATR_XX")
+ return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX);
+ if (attr == "READBACK")
+ return iface->read_gpio(unit);
}
return 0;
}
@@ -627,11 +744,10 @@ uint32_t x300_radio_ctrl_impl::get_gpio_attr(
/****************************************************************************
* Radio control and setup
***************************************************************************/
-void x300_radio_ctrl_impl::setup_radio(
- uhd::i2c_iface::sptr zpu_i2c,
- x300_clock_ctrl::sptr clock,
- bool ignore_cal_file,
- bool verbose)
+void x300_radio_ctrl_impl::setup_radio(uhd::i2c_iface::sptr zpu_i2c,
+ x300_clock_ctrl::sptr clock,
+ bool ignore_cal_file,
+ bool verbose)
{
_self_cal_adc_capture_delay(verbose);
_ignore_cal_file = ignore_cal_file;
@@ -644,57 +760,56 @@ void x300_radio_ctrl_impl::setup_radio(
static const size_t TX_EEPROM_ADDR = 0x4;
static const size_t GDB_EEPROM_ADDR = 0x1;
const static std::vector<size_t> EEPROM_ADDRS{
- RX_EEPROM_ADDR,
- TX_EEPROM_ADDR,
- GDB_EEPROM_ADDR
- };
+ RX_EEPROM_ADDR, TX_EEPROM_ADDR, GDB_EEPROM_ADDR};
const static std::vector<std::string> EEPROM_PATHS{
- "rx_eeprom",
- "tx_eeprom",
- "gdb_eeprom"
- };
+ "rx_eeprom", "tx_eeprom", "gdb_eeprom"};
const size_t DB_OFFSET = (_radio_slot == "A") ? 0x0 : 0x2;
- const fs_path db_path = ("dboards" / _radio_slot);
+ const fs_path db_path = ("dboards" / _radio_slot);
for (size_t i = 0; i < EEPROM_ADDRS.size(); i++) {
const size_t addr = EEPROM_ADDRS[i] + DB_OFFSET;
- //Load EEPROM
+ // Load EEPROM
_db_eeproms[addr].load(*zpu_i2c, BASE_ADDR | addr);
- //Add to tree
+ // Add to tree
_tree->create<dboard_eeprom_t>(db_path / EEPROM_PATHS[i])
.set(_db_eeproms[addr])
.add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::_set_db_eeprom,
- this, zpu_i2c, (BASE_ADDR | addr), _1));
+ this,
+ zpu_i2c,
+ (BASE_ADDR | addr),
+ _1));
}
- //create a new dboard interface
+ // create a new dboard interface
x300_dboard_iface_config_t db_config;
db_config.gpio = gpio_atr::db_gpio_atr_3000::make(_get_ctrl(IO_MASTER_RADIO),
radio_ctrl_impl::regs::sr_addr(radio_ctrl_impl::regs::GPIO),
- radio_ctrl_impl::regs::rb_addr(radio_ctrl_impl::regs::RB_DB_GPIO)
- );
- db_config.spi = _spi;
+ radio_ctrl_impl::regs::rb_addr(radio_ctrl_impl::regs::RB_DB_GPIO));
+ db_config.spi = _spi;
db_config.rx_spi_slaveno = DB_RX_SEN;
db_config.tx_spi_slaveno = DB_TX_SEN;
- db_config.i2c = zpu_i2c;
- db_config.clock = clock;
- db_config.which_rx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_RX : X300_CLOCK_WHICH_DB1_RX;
- db_config.which_tx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_TX : X300_CLOCK_WHICH_DB1_TX;
- db_config.dboard_slot = (_radio_slot == "A")? 0 : 1;
+ db_config.i2c = zpu_i2c;
+ db_config.clock = clock;
+ db_config.which_rx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_RX
+ : X300_CLOCK_WHICH_DB1_RX;
+ db_config.which_tx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_TX
+ : X300_CLOCK_WHICH_DB1_TX;
+ db_config.dboard_slot = (_radio_slot == "A") ? 0 : 1;
db_config.cmd_time_ctrl = _get_ctrl(IO_MASTER_RADIO);
- //create a new dboard manager
- boost::shared_ptr<x300_dboard_iface> db_iface = boost::make_shared<x300_dboard_iface>(db_config);
- _db_manager = dboard_manager::make(
- _db_eeproms[RX_EEPROM_ADDR + DB_OFFSET],
+ // create a new dboard manager
+ boost::shared_ptr<x300_dboard_iface> db_iface =
+ boost::make_shared<x300_dboard_iface>(db_config);
+ _db_manager = dboard_manager::make(_db_eeproms[RX_EEPROM_ADDR + DB_OFFSET],
_db_eeproms[TX_EEPROM_ADDR + DB_OFFSET],
_db_eeproms[GDB_EEPROM_ADDR + DB_OFFSET],
- db_iface, _tree->subtree(db_path),
+ db_iface,
+ _tree->subtree(db_path),
true // defer daughterboard intitialization
);
size_t rx_chan = 0, tx_chan = 0;
- for(const std::string& fe: _db_manager->get_rx_frontends()) {
+ for (const std::string& fe : _db_manager->get_rx_frontends()) {
if (rx_chan >= _get_num_radios()) {
break;
}
@@ -702,12 +817,14 @@ void x300_radio_ctrl_impl::setup_radio(
db_iface->add_rx_fe(fe, _rx_fe_map[rx_chan].core);
const fs_path fe_path(db_path / "rx_frontends" / fe);
const std::string conn = _tree->access<std::string>(fe_path / "connection").get();
- const double if_freq = (_tree->exists(fe_path / "if_freq/value")) ?
- _tree->access<double>(fe_path / "if_freq/value").get() : 0.0;
+ const double if_freq =
+ (_tree->exists(fe_path / "if_freq/value"))
+ ? _tree->access<double>(fe_path / "if_freq/value").get()
+ : 0.0;
_rx_fe_map[rx_chan].core->set_fe_connection(usrp::fe_connection_t(conn, if_freq));
rx_chan++;
}
- for(const std::string& fe: _db_manager->get_tx_frontends()) {
+ for (const std::string& fe : _db_manager->get_tx_frontends()) {
if (tx_chan >= _get_num_radios()) {
break;
}
@@ -722,40 +839,63 @@ void x300_radio_ctrl_impl::setup_radio(
// Initialize the daughterboards now that frontend cores and connections exist
_db_manager->initialize_dboards();
- //now that dboard is created -- register into rx antenna event
+ // now that dboard is created -- register into rx antenna event
if (not _rx_fe_map.empty()) {
for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_tree->exists(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value")) {
- // We need a desired subscriber for antenna/value because the experts don't coerce that property.
- _tree->access<std::string>(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value")
- .add_desired_subscriber(boost::bind(&x300_radio_ctrl_impl::_update_atr_leds, this, _1, i));
- _update_atr_leds(_tree->access<std::string>
- (db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name / "antenna" / "value").get(), i);
+ if (_tree->exists(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name
+ / "antenna" / "value")) {
+ // We need a desired subscriber for antenna/value because the experts
+ // don't coerce that property.
+ _tree
+ ->access<std::string>(db_path / "rx_frontends"
+ / _rx_fe_map[i].db_fe_name / "antenna"
+ / "value")
+ .add_desired_subscriber(boost::bind(
+ &x300_radio_ctrl_impl::_update_atr_leds, this, _1, i));
+ _update_atr_leds(_tree
+ ->access<std::string>(db_path / "rx_frontends"
+ / _rx_fe_map[i].db_fe_name
+ / "antenna" / "value")
+ .get(),
+ i);
} else {
- _update_atr_leds("", i); //init anyway, even if never called
+ _update_atr_leds("", i); // init anyway, even if never called
}
}
}
- //bind frontend corrections to the dboard freq props
+ // bind frontend corrections to the dboard freq props
const fs_path db_tx_fe_path = db_path / "tx_frontends";
if (not _tx_fe_map.empty()) {
for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_tree->exists(db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) {
- _tree->access<double>(db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")
- .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_tx_fe_corrections, this, db_path,
- _root_path / "tx_fe_corrections" / _tx_fe_map[i].db_fe_name, _1));
+ if (_tree->exists(
+ db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) {
+ _tree
+ ->access<double>(
+ db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")
+ .add_coerced_subscriber(
+ boost::bind(&x300_radio_ctrl_impl::set_tx_fe_corrections,
+ this,
+ db_path,
+ _root_path / "tx_fe_corrections" / _tx_fe_map[i].db_fe_name,
+ _1));
}
}
}
const fs_path db_rx_fe_path = db_path / "rx_frontends";
if (not _rx_fe_map.empty()) {
for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_tree->exists(db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) {
- _tree->access<double>(db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")
- .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_rx_fe_corrections, this, db_path,
- _root_path / "rx_fe_corrections" / _tx_fe_map[i].db_fe_name,
- _1));
+ if (_tree->exists(
+ db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) {
+ _tree
+ ->access<double>(
+ db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")
+ .add_coerced_subscriber(
+ boost::bind(&x300_radio_ctrl_impl::set_rx_fe_corrections,
+ this,
+ db_path,
+ _root_path / "rx_fe_corrections" / _tx_fe_map[i].db_fe_name,
+ _1));
}
}
}
@@ -764,7 +904,7 @@ void x300_radio_ctrl_impl::setup_radio(
// Set tick rate
////////////////////////////////////////////////////////////////
const double tick_rate = get_output_samp_rate(0);
- if (_radio_type==PRIMARY) {
+ if (_radio_type == PRIMARY) {
// Slot A is the highlander timekeeper
_tree->access<double>("tick_rate").set(tick_rate);
}
@@ -772,20 +912,16 @@ void x300_radio_ctrl_impl::setup_radio(
}
void x300_radio_ctrl_impl::set_rx_fe_corrections(
- const fs_path &db_path,
- const fs_path &rx_fe_corr_path,
- const double lo_freq
-) {
+ const fs_path& db_path, const fs_path& rx_fe_corr_path, const double lo_freq)
+{
if (not _ignore_cal_file) {
apply_rx_fe_corrections(_tree, db_path, rx_fe_corr_path, lo_freq);
}
}
void x300_radio_ctrl_impl::set_tx_fe_corrections(
- const fs_path &db_path,
- const fs_path &tx_fe_corr_path,
- const double lo_freq
-) {
+ const fs_path& db_path, const fs_path& tx_fe_corr_path, const double lo_freq)
+{
if (not _ignore_cal_file) {
apply_tx_fe_corrections(_tree, db_path, tx_fe_corr_path, lo_freq);
}
@@ -793,7 +929,7 @@ void x300_radio_ctrl_impl::set_tx_fe_corrections(
void x300_radio_ctrl_impl::reset_codec()
{
- if (_radio_type==PRIMARY) { //ADC/DAC reset lines only exist in Radio0
+ if (_radio_type == PRIMARY) { // ADC/DAC reset lines only exist in Radio0
_regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
_regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
_regs->misc_outs_reg.flush();
@@ -809,29 +945,34 @@ void x300_radio_ctrl_impl::reset_codec()
void x300_radio_ctrl_impl::self_test_adc(uint32_t ramp_time_ms)
{
- //Bypass all front-end corrections
+ // Bypass all front-end corrections
for (size_t i = 0; i < _get_num_radios(); i++) {
_rx_fe_map[i].core->bypass_all(true);
}
- //Test basic patterns
- _adc->set_test_word("ones", "ones"); _check_adc(0xfffcfffc);
- _adc->set_test_word("zeros", "zeros"); _check_adc(0x00000000);
- _adc->set_test_word("ones", "zeros"); _check_adc(0xfffc0000);
- _adc->set_test_word("zeros", "ones"); _check_adc(0x0000fffc);
+ // Test basic patterns
+ _adc->set_test_word("ones", "ones");
+ _check_adc(0xfffcfffc);
+ _adc->set_test_word("zeros", "zeros");
+ _check_adc(0x00000000);
+ _adc->set_test_word("ones", "zeros");
+ _check_adc(0xfffc0000);
+ _adc->set_test_word("zeros", "ones");
+ _check_adc(0x0000fffc);
for (size_t k = 0; k < 14; k++) {
_adc->set_test_word("zeros", "custom", 1 << k);
- _check_adc(1 << (k+2));
+ _check_adc(1 << (k + 2));
}
for (size_t k = 0; k < 14; k++) {
_adc->set_test_word("custom", "zeros", 1 << k);
- _check_adc(1 << (k+18));
+ _check_adc(1 << (k + 18));
}
- //Turn on ramp pattern test
+ // Turn on ramp pattern test
_adc->set_test_word("ramp", "ramp");
_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- //Sleep added for SPI transactions to finish and ramp to start before checker is enabled.
+ // Sleep added for SPI transactions to finish and ramp to start before checker is
+ // enabled.
std::this_thread::sleep_for(std::chrono::microseconds(1000));
_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
@@ -855,37 +996,46 @@ void x300_radio_ctrl_impl::self_test_adc(uint32_t ramp_time_ms)
else
q_status = "Not Locked!";
- //Return to normal mode
+ // Return to normal mode
_adc->set_test_word("normal", "normal");
if ((i_status != "Good") or (q_status != "Good")) {
throw uhd::runtime_error(
- (boost::format("ADC self-test failed for %s. Ramp checker status: {ADC_A=%s, ADC_B=%s}")%unique_id()%i_status%q_status).str());
+ (boost::format(
+ "ADC self-test failed for %s. Ramp checker status: {ADC_A=%s, ADC_B=%s}")
+ % unique_id() % i_status % q_status)
+ .str());
}
- //Restore front-end corrections
+ // Restore front-end corrections
for (size_t i = 0; i < _get_num_radios(); i++) {
_rx_fe_map[i].core->bypass_all(false);
}
}
-void x300_radio_ctrl_impl::extended_adc_test(const std::vector<x300_radio_ctrl_impl::sptr>& radios, double duration_s)
+void x300_radio_ctrl_impl::extended_adc_test(
+ const std::vector<x300_radio_ctrl_impl::sptr>& radios, double duration_s)
{
static const size_t SECS_PER_ITER = 5;
- UHD_LOGGER_INFO("X300 RADIO") << boost::format("Running Extended ADC Self-Test (Duration=%.0fs, %ds/iteration)...")
- % duration_s % SECS_PER_ITER;
+ UHD_LOGGER_INFO("X300 RADIO")
+ << boost::format(
+ "Running Extended ADC Self-Test (Duration=%.0fs, %ds/iteration)...")
+ % duration_s % SECS_PER_ITER;
- size_t num_iters = static_cast<size_t>(ceil(duration_s/SECS_PER_ITER));
+ size_t num_iters = static_cast<size_t>(ceil(duration_s / SECS_PER_ITER));
size_t num_failures = 0;
for (size_t iter = 0; iter < num_iters; iter++) {
- //Run self-test
- UHD_LOGGER_INFO("X300 RADIO") << boost::format("Extended ADC Self-Test Iteration %06d... ") % (iter+1);
+ // Run self-test
+ UHD_LOGGER_INFO("X300 RADIO")
+ << boost::format("Extended ADC Self-Test Iteration %06d... ") % (iter + 1);
try {
for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->self_test_adc((SECS_PER_ITER*1000)/radios.size());
+ radios[i]->self_test_adc((SECS_PER_ITER * 1000) / radios.size());
}
- UHD_LOGGER_INFO("X300 RADIO") << boost::format("Extended ADC Self-Test Iteration %06d passed ") % (iter+1);
- } catch(std::exception &e) {
+ UHD_LOGGER_INFO("X300 RADIO")
+ << boost::format("Extended ADC Self-Test Iteration %06d passed ")
+ % (iter + 1);
+ } catch (std::exception& e) {
num_failures++;
UHD_LOGGER_ERROR("X300 RADIO") << e.what();
}
@@ -894,75 +1044,82 @@ void x300_radio_ctrl_impl::extended_adc_test(const std::vector<x300_radio_ctrl_i
UHD_LOGGER_INFO("X300 RADIO") << "Extended ADC Self-Test PASSED";
} else {
throw uhd::runtime_error(
- (boost::format("Extended ADC Self-Test FAILED!!! (%d/%d failures)\n") % num_failures % num_iters).str());
+ (boost::format("Extended ADC Self-Test FAILED!!! (%d/%d failures)\n")
+ % num_failures % num_iters)
+ .str());
}
}
-void x300_radio_ctrl_impl::synchronize_dacs(const std::vector<x300_radio_ctrl_impl::sptr>& radios)
+void x300_radio_ctrl_impl::synchronize_dacs(
+ const std::vector<x300_radio_ctrl_impl::sptr>& radios)
{
- if (radios.size() < 2) return; //Nothing to synchronize
+ if (radios.size() < 2)
+ return; // Nothing to synchronize
//**PRECONDITION**
- //This function assumes that all the VITA times in "radios" are synchronized
- //to a common reference. Currently, this function is called in get_tx_stream
- //which also has the same precondition.
+ // This function assumes that all the VITA times in "radios" are synchronized
+ // to a common reference. Currently, this function is called in get_tx_stream
+ // which also has the same precondition.
- //Get a rough estimate of the cumulative command latency
+ // Get a rough estimate of the cumulative command latency
boost::posix_time::ptime t_start = boost::posix_time::microsec_clock::local_time();
for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->user_reg_read64(regs::RB_TIME_NOW); //Discard value. We are just timing the call
+ radios[i]->user_reg_read64(
+ regs::RB_TIME_NOW); // Discard value. We are just timing the call
}
boost::posix_time::time_duration t_elapsed =
boost::posix_time::microsec_clock::local_time() - t_start;
- //Add 100% of headroom + uncertainty to the command time
- uint64_t t_sync_us = (t_elapsed.total_microseconds() * 2) + 16000 /*Scheduler latency*/;
+ // Add 100% of headroom + uncertainty to the command time
+ uint64_t t_sync_us =
+ (t_elapsed.total_microseconds() * 2) + 16000 /*Scheduler latency*/;
std::string err_str;
- //Try to sync 3 times before giving up
- for (size_t attempt = 0; attempt < 3; attempt++)
- {
- try
- {
- //Reinitialize and resync all DACs
+ // Try to sync 3 times before giving up
+ for (size_t attempt = 0; attempt < 3; attempt++) {
+ try {
+ // Reinitialize and resync all DACs
for (size_t i = 0; i < radios.size(); i++) {
radios[i]->_dac->sync();
}
- //Set tick rate and make sure FRAMEP/N is 0
+ // Set tick rate and make sure FRAMEP/N is 0
for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->set_command_tick_rate(radios[i]->_radio_clk_rate, IO_MASTER_RADIO);
- radios[i]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0);
+ radios[i]->set_command_tick_rate(
+ radios[i]->_radio_clk_rate, IO_MASTER_RADIO);
+ radios[i]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0);
}
- //Pick radios[0] as the time reference.
- uhd::time_spec_t sync_time =
- radios[0]->_time64->get_time_now() + uhd::time_spec_t(((double)t_sync_us)/1e6);
+ // Pick radios[0] as the time reference.
+ uhd::time_spec_t sync_time = radios[0]->_time64->get_time_now()
+ + uhd::time_spec_t(((double)t_sync_us) / 1e6);
- //Send the sync command
+ // Send the sync command
for (size_t i = 0; i < radios.size(); i++) {
radios[i]->set_command_time(sync_time, IO_MASTER_RADIO);
- //Arm FRAMEP/N sync pulse by asserting a rising edge
- radios[i]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 1);
+ // Arm FRAMEP/N sync pulse by asserting a rising edge
+ radios[i]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 1);
}
- //Reset FRAMEP/N to 0 after 2 clock cycles
+ // Reset FRAMEP/N to 0 after 2 clock cycles
for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->set_command_time(sync_time + (2.0 / radios[i]->_radio_clk_rate), IO_MASTER_RADIO);
- radios[i]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0);
+ radios[i]->set_command_time(
+ sync_time + (2.0 / radios[i]->_radio_clk_rate), IO_MASTER_RADIO);
+ radios[i]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0);
radios[i]->set_command_time(uhd::time_spec_t(0.0), IO_MASTER_RADIO);
}
- //Wait and check status
+ // Wait and check status
std::this_thread::sleep_for(std::chrono::microseconds(t_sync_us));
for (size_t i = 0; i < radios.size(); i++) {
radios[i]->_dac->verify_sync();
}
return;
- }
- catch (const uhd::runtime_error &e)
- {
+ } catch (const uhd::runtime_error& e) {
err_str = e.what();
UHD_LOGGER_TRACE("X300 RADIO") << "Retrying DAC synchronization: " << err_str;
}
@@ -978,144 +1135,165 @@ double x300_radio_ctrl_impl::self_cal_adc_xfer_delay(
{
UHD_LOGGER_INFO("X300 RADIO") << "Running ADC transfer delay self-cal: ";
- //Effective resolution of the self-cal.
+ // Effective resolution of the self-cal.
static const size_t NUM_DELAY_STEPS = 100;
- double master_clk_period = (1.0e9 / clock->get_master_clock_rate()); //in ns
- double delay_start = 0.0;
- double delay_range = 2 * master_clk_period;
- double delay_incr = delay_range / NUM_DELAY_STEPS;
+ double master_clk_period = (1.0e9 / clock->get_master_clock_rate()); // in ns
+ double delay_start = 0.0;
+ double delay_range = 2 * master_clk_period;
+ double delay_incr = delay_range / NUM_DELAY_STEPS;
double cached_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_ADC0);
- double fpga_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_FPGA);
+ double fpga_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_FPGA);
- //Iterate through several values of delays and measure ADC data integrity
- std::vector< std::pair<double,bool> > results;
+ // Iterate through several values of delays and measure ADC data integrity
+ std::vector<std::pair<double, bool>> results;
for (size_t i = 0; i < NUM_DELAY_STEPS; i++) {
- //Delay the ADC clock (will set both Ch0 and Ch1 delays)
- double delay = clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, delay_incr*i + delay_start);
+ // Delay the ADC clock (will set both Ch0 and Ch1 delays)
+ double delay =
+ clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, delay_incr * i + delay_start);
wait_for_clk_locked(0.1);
uint32_t err_code = 0;
for (size_t r = 0; r < radios.size(); r++) {
- //Test each channel (I and Q) individually so as to not accidentally trigger
- //on the data from the other channel if there is a swap
+ // Test each channel (I and Q) individually so as to not accidentally trigger
+ // on the data from the other channel if there is a swap
// -- Test I Channel --
- //Put ADC in ramp test mode. Tie the other channel to all ones.
+ // Put ADC in ramp test mode. Tie the other channel to all ones.
radios[r]->_adc->set_test_word("ramp", "ones");
- //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- //and count deviations from the expected value
- radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- //50ms @ 200MHz = 10 million samples
+ // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
+ // and count deviations from the expected value
+ radios[r]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ radios[r]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
+ // 50ms @ 200MHz = 10 million samples
std::this_thread::sleep_for(std::chrono::milliseconds(50));
- if (radios[r]->_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED)) {
- err_code += radios[r]->_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR);
+ if (radios[r]->_regs->misc_ins_reg.read(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED)) {
+ err_code += radios[r]->_regs->misc_ins_reg.get(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR);
} else {
- err_code += 100; //Increment error code by 100 to indicate no lock
+ err_code += 100; // Increment error code by 100 to indicate no lock
}
// -- Test Q Channel --
- //Put ADC in ramp test mode. Tie the other channel to all ones.
+ // Put ADC in ramp test mode. Tie the other channel to all ones.
radios[r]->_adc->set_test_word("ones", "ramp");
- //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- //and count deviations from the expected value
- radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- //50ms @ 200MHz = 10 million samples
+ // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
+ // and count deviations from the expected value
+ radios[r]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ radios[r]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
+ // 50ms @ 200MHz = 10 million samples
std::this_thread::sleep_for(std::chrono::milliseconds(50));
- if (radios[r]->_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED)) {
- err_code += radios[r]->_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR);
+ if (radios[r]->_regs->misc_ins_reg.read(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED)) {
+ err_code += radios[r]->_regs->misc_ins_reg.get(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR);
} else {
- err_code += 100; //Increment error code by 100 to indicate no lock
+ err_code += 100; // Increment error code by 100 to indicate no lock
}
}
- //UHD_LOGGER_INFO("X300 RADIO") << (boost::format("XferDelay=%fns, Error=%d") % delay % err_code);
- results.push_back(std::pair<double,bool>(delay, err_code==0));
+ // UHD_LOGGER_INFO("X300 RADIO") << (boost::format("XferDelay=%fns, Error=%d") %
+ // delay % err_code);
+ results.push_back(std::pair<double, bool>(delay, err_code == 0));
}
- //Calculate the valid window
+ // Calculate the valid window
int win_start_idx = -1, win_stop_idx = -1, cur_start_idx = -1, cur_stop_idx = -1;
for (size_t i = 0; i < results.size(); i++) {
- std::pair<double,bool>& item = results[i];
- if (item.second) { //If data is stable
- if (cur_start_idx == -1) { //This is the first window
+ std::pair<double, bool>& item = results[i];
+ if (item.second) { // If data is stable
+ if (cur_start_idx == -1) { // This is the first window
cur_start_idx = i;
- cur_stop_idx = i;
- } else { //We are extending the window
+ cur_stop_idx = i;
+ } else { // We are extending the window
cur_stop_idx = i;
}
} else {
- if (cur_start_idx == -1) { //We haven't yet seen valid data
- //Do nothing
- } else if (win_start_idx == -1) { //We passed the first valid window
+ if (cur_start_idx == -1) { // We haven't yet seen valid data
+ // Do nothing
+ } else if (win_start_idx == -1) { // We passed the first valid window
win_start_idx = cur_start_idx;
- win_stop_idx = cur_stop_idx;
- } else { //Update cached window if current window is larger
- double cur_win_len = results[cur_stop_idx].first - results[cur_start_idx].first;
- double cached_win_len = results[win_stop_idx].first - results[win_start_idx].first;
+ win_stop_idx = cur_stop_idx;
+ } else { // Update cached window if current window is larger
+ double cur_win_len =
+ results[cur_stop_idx].first - results[cur_start_idx].first;
+ double cached_win_len =
+ results[win_stop_idx].first - results[win_start_idx].first;
if (cur_win_len > cached_win_len) {
win_start_idx = cur_start_idx;
- win_stop_idx = cur_stop_idx;
+ win_stop_idx = cur_stop_idx;
}
}
- //Reset current window
+ // Reset current window
cur_start_idx = -1;
- cur_stop_idx = -1;
+ cur_stop_idx = -1;
}
}
if (win_start_idx == -1) {
- throw uhd::runtime_error("self_cal_adc_xfer_delay: Self calibration failed. Convergence error.");
+ throw uhd::runtime_error(
+ "self_cal_adc_xfer_delay: Self calibration failed. Convergence error.");
}
- double win_center = (results[win_stop_idx].first + results[win_start_idx].first) / 2.0;
+ double win_center =
+ (results[win_stop_idx].first + results[win_start_idx].first) / 2.0;
double win_length = results[win_stop_idx].first - results[win_start_idx].first;
- if (win_length < master_clk_period/4) {
- throw uhd::runtime_error("self_cal_adc_xfer_delay: Self calibration failed. Valid window too narrow.");
+ if (win_length < master_clk_period / 4) {
+ throw uhd::runtime_error(
+ "self_cal_adc_xfer_delay: Self calibration failed. Valid window too narrow.");
}
- //Cycle slip the relative delay by a clock cycle to prevent sample misalignment
- //fpga_clk_delay > 0 and 0 < win_center < 2*(1/MCR) so one cycle slip is all we need
- bool cycle_slip = (win_center-fpga_clk_delay >= master_clk_period);
+ // Cycle slip the relative delay by a clock cycle to prevent sample misalignment
+ // fpga_clk_delay > 0 and 0 < win_center < 2*(1/MCR) so one cycle slip is all we need
+ bool cycle_slip = (win_center - fpga_clk_delay >= master_clk_period);
if (cycle_slip) {
win_center -= master_clk_period;
}
if (apply_delay) {
- //Apply delay
- win_center = clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, win_center); //Sets ADC0 and ADC1
+ // Apply delay
+ win_center = clock->set_clock_delay(
+ X300_CLOCK_WHICH_ADC0, win_center); // Sets ADC0 and ADC1
wait_for_clk_locked(0.1);
- //Validate
+ // Validate
for (size_t r = 0; r < radios.size(); r++) {
radios[r]->self_test_adc(2000);
}
} else {
- //Restore delay
- clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, cached_clk_delay); //Sets ADC0 and ADC1
+ // Restore delay
+ clock->set_clock_delay(
+ X300_CLOCK_WHICH_ADC0, cached_clk_delay); // Sets ADC0 and ADC1
}
- //Teardown
+ // Teardown
for (size_t r = 0; r < radios.size(); r++) {
radios[r]->_adc->set_test_word("normal", "normal");
- radios[r]->_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ radios[r]->_regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
}
- UHD_LOGGER_INFO("X300 RADIO") << (boost::format("ADC transfer delay self-cal done (FPGA->ADC=%.3fns%s, Window=%.3fns)") %
- (win_center-fpga_clk_delay) % (cycle_slip?" +cyc":"") % win_length);
+ UHD_LOGGER_INFO("X300 RADIO")
+ << (boost::format(
+ "ADC transfer delay self-cal done (FPGA->ADC=%.3fns%s, Window=%.3fns)")
+ % (win_center - fpga_clk_delay) % (cycle_slip ? " +cyc" : "")
+ % win_length);
return win_center;
}
/****************************************************************************
* Helpers
***************************************************************************/
-void x300_radio_ctrl_impl::_update_atr_leds(const std::string &rx_ant, const size_t chan)
+void x300_radio_ctrl_impl::_update_atr_leds(const std::string& rx_ant, const size_t chan)
{
// The "RX1" port is used by TwinRX and the "TX/RX" port is used by all
// other full-duplex dboards. We need to handle both here.
const bool is_txrx = (rx_ant == "TX/RX" or rx_ant == "RX1");
- const int TXRX_RX = (1 << 0);
- const int TXRX_TX = (1 << 1);
- const int RX2_RX = (1 << 2);
+ const int TXRX_RX = (1 << 0);
+ const int TXRX_TX = (1 << 1);
+ const int RX2_RX = (1 << 2);
_leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_IDLE, 0);
_leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, is_txrx ? TXRX_RX : RX2_RX);
_leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, TXRX_TX);
@@ -1124,76 +1302,91 @@ void x300_radio_ctrl_impl::_update_atr_leds(const std::string &rx_ant, const siz
void x300_radio_ctrl_impl::_self_cal_adc_capture_delay(bool print_status)
{
- if (print_status) UHD_LOGGER_INFO("X300 RADIO") << "Running ADC capture delay self-cal...";
+ if (print_status)
+ UHD_LOGGER_INFO("X300 RADIO") << "Running ADC capture delay self-cal...";
- static const uint32_t NUM_DELAY_STEPS = 32; //The IDELAYE2 element has 32 steps
- static const uint32_t NUM_RETRIES = 2; //Retry self-cal if it fails in warmup situations
- static const int32_t MIN_WINDOW_LEN = 4;
+ static const uint32_t NUM_DELAY_STEPS = 32; // The IDELAYE2 element has 32 steps
+ static const uint32_t NUM_RETRIES =
+ 2; // Retry self-cal if it fails in warmup situations
+ static const int32_t MIN_WINDOW_LEN = 4;
int32_t win_start = -1, win_stop = -1;
uint32_t iter = 0;
while (iter++ < NUM_RETRIES) {
for (uint32_t dly_tap = 0; dly_tap < NUM_DELAY_STEPS; dly_tap++) {
- //Apply delay
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, dly_tap);
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
+ // Apply delay
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, dly_tap);
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
uint32_t err_code = 0;
// -- Test I Channel --
- //Put ADC in ramp test mode. Tie the other channel to all ones.
+ // Put ADC in ramp test mode. Tie the other channel to all ones.
_adc->set_test_word("ramp", "ones");
- //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- //and count deviations from the expected value
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- //5ms @ 200MHz = 1 million samples
+ // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
+ // and count deviations from the expected value
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
+ // 5ms @ 200MHz = 1 million samples
std::this_thread::sleep_for(std::chrono::milliseconds(5));
- if (_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_LOCKED)) {
- err_code += _regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_ERROR);
+ if (_regs->misc_ins_reg.read(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_LOCKED)) {
+ err_code += _regs->misc_ins_reg.get(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_ERROR);
} else {
- err_code += 100; //Increment error code by 100 to indicate no lock
+ err_code += 100; // Increment error code by 100 to indicate no lock
}
// -- Test Q Channel --
- //Put ADC in ramp test mode. Tie the other channel to all ones.
+ // Put ADC in ramp test mode. Tie the other channel to all ones.
_adc->set_test_word("ones", "ramp");
- //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- //and count deviations from the expected value
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- //5ms @ 200MHz = 1 million samples
+ // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
+ // and count deviations from the expected value
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
+ // 5ms @ 200MHz = 1 million samples
std::this_thread::sleep_for(std::chrono::milliseconds(5));
- if (_regs->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_LOCKED)) {
- err_code += _regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_ERROR);
+ if (_regs->misc_ins_reg.read(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_LOCKED)) {
+ err_code += _regs->misc_ins_reg.get(
+ radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_ERROR);
} else {
- err_code += 100; //Increment error code by 100 to indicate no lock
+ err_code += 100; // Increment error code by 100 to indicate no lock
}
if (err_code == 0) {
- if (win_start == -1) { //This is the first window
+ if (win_start == -1) { // This is the first window
win_start = dly_tap;
- win_stop = dly_tap;
- } else { //We are extending the window
+ win_stop = dly_tap;
+ } else { // We are extending the window
win_stop = dly_tap;
}
} else {
- if (win_start != -1) { //A valid window turned invalid
+ if (win_start != -1) { // A valid window turned invalid
if (win_stop - win_start >= MIN_WINDOW_LEN) {
- break; //Valid window found
+ break; // Valid window found
} else {
- win_start = -1; //Reset window
+ win_start = -1; // Reset window
}
}
}
- //UHD_LOGGER_INFO("X300 RADIO") << (boost::format("CapTap=%d, Error=%d") % dly_tap % err_code);
+ // UHD_LOGGER_INFO("X300 RADIO") << (boost::format("CapTap=%d, Error=%d") %
+ // dly_tap % err_code);
}
- //Retry the self-cal if it fails
- if ((win_start == -1 || (win_stop - win_start) < MIN_WINDOW_LEN) && iter < NUM_RETRIES /*not last iteration*/) {
+ // Retry the self-cal if it fails
+ if ((win_start == -1 || (win_stop - win_start) < MIN_WINDOW_LEN)
+ && iter < NUM_RETRIES /*not last iteration*/) {
win_start = -1;
- win_stop = -1;
+ win_stop = -1;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
} else {
break;
@@ -1203,46 +1396,55 @@ void x300_radio_ctrl_impl::_self_cal_adc_capture_delay(bool print_status)
_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
if (win_start == -1) {
- throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. Convergence error.");
+ throw uhd::runtime_error(
+ "self_cal_adc_capture_delay: Self calibration failed. Convergence error.");
}
- if (win_stop-win_start < MIN_WINDOW_LEN) {
- throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. Valid window too narrow.");
+ if (win_stop - win_start < MIN_WINDOW_LEN) {
+ throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. "
+ "Valid window too narrow.");
}
uint32_t ideal_tap = (win_stop + win_start) / 2;
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, ideal_tap);
+ _regs->misc_outs_reg.write(
+ radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, ideal_tap);
_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
_regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
if (print_status) {
- double tap_delay = (1.0e12 / _radio_clk_rate) / (2*32); //in ps
- UHD_LOGGER_INFO("X300 RADIO") << boost::format("ADC capture delay self-cal done (Tap=%d, Window=%d, TapDelay=%.3fps, Iter=%d)") % ideal_tap % (win_stop-win_start) % tap_delay % iter;
+ double tap_delay = (1.0e12 / _radio_clk_rate) / (2 * 32); // in ps
+ UHD_LOGGER_INFO("X300 RADIO")
+ << boost::format("ADC capture delay self-cal done (Tap=%d, Window=%d, "
+ "TapDelay=%.3fps, Iter=%d)")
+ % ideal_tap % (win_stop - win_start) % tap_delay % iter;
}
}
void x300_radio_ctrl_impl::_check_adc(const uint32_t val)
{
- //Wait for previous control transaction to flush
+ // Wait for previous control transaction to flush
user_reg_read64(regs::RB_TEST);
- //Wait for ADC test pattern to propagate
+ // Wait for ADC test pattern to propagate
std::this_thread::sleep_for(std::chrono::microseconds(5));
- //Read value of RX readback register and verify
- uint32_t adc_rb = static_cast<uint32_t>(user_reg_read64(regs::RB_TEST)>>32);
- adc_rb ^= 0xfffc0000; //adapt for I inversion in FPGA
+ // Read value of RX readback register and verify
+ uint32_t adc_rb = static_cast<uint32_t>(user_reg_read64(regs::RB_TEST) >> 32);
+ adc_rb ^= 0xfffc0000; // adapt for I inversion in FPGA
if (val != adc_rb) {
throw uhd::runtime_error(
- (boost::format("ADC self-test failed for %s. (Exp=0x%x, Got=0x%x)")%unique_id()%val%adc_rb).str());
+ (boost::format("ADC self-test failed for %s. (Exp=0x%x, Got=0x%x)")
+ % unique_id() % val % adc_rb)
+ .str());
}
}
-void x300_radio_ctrl_impl::_set_db_eeprom(i2c_iface::sptr i2c, const size_t addr, const uhd::usrp::dboard_eeprom_t &db_eeprom)
+void x300_radio_ctrl_impl::_set_db_eeprom(
+ i2c_iface::sptr i2c, const size_t addr, const uhd::usrp::dboard_eeprom_t& db_eeprom)
{
db_eeprom.store(*i2c, addr);
_db_eeproms[addr] = db_eeprom;
}
-void x300_radio_ctrl_impl::_set_command_time(const time_spec_t &spec, const size_t port)
+void x300_radio_ctrl_impl::_set_command_time(const time_spec_t& spec, const size_t port)
{
set_fe_cmd_time(spec, port);
}
@@ -1251,15 +1453,16 @@ void x300_radio_ctrl_impl::_set_command_time(const time_spec_t &spec, const size
***************************************************************************/
bool x300_radio_ctrl_impl::check_radio_config()
{
- UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::check_radio_config() " ;
+ UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::check_radio_config() ";
const fs_path rx_fe_path = fs_path("dboards" / _radio_slot / "rx_frontends");
for (size_t chan = 0; chan < _num_rx_channels; chan++) {
if (_tree->exists(rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled")) {
const bool chan_active = _is_streamer_active(uhd::RX_DIRECTION, chan);
if (chan_active) {
- _tree->access<bool>(rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled")
- .set(chan_active)
- ;
+ _tree
+ ->access<bool>(
+ rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled")
+ .set(chan_active);
}
}
}
@@ -1269,9 +1472,10 @@ bool x300_radio_ctrl_impl::check_radio_config()
if (_tree->exists(tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled")) {
const bool chan_active = _is_streamer_active(uhd::TX_DIRECTION, chan);
if (chan_active) {
- _tree->access<bool>(tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled")
- .set(chan_active)
- ;
+ _tree
+ ->access<bool>(
+ tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled")
+ .set(chan_active);
}
}
}