diff options
Diffstat (limited to 'host/lib/usrp/dboard')
54 files changed, 6006 insertions, 5008 deletions
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 81a7aa534..5e8ac310e 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -7,11 +7,11 @@ #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/utils/assert_has.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/log.hpp> #include <uhd/usrp/dboard_base.hpp> #include <uhd/usrp/dboard_manager.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/static.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> @@ -22,37 +22,29 @@ using namespace uhd::usrp; * Constants **********************************************************************/ namespace { - constexpr uint32_t BASIC_TX_PID = 0x0000; - constexpr uint32_t BASIC_RX_PID = 0x0001; - constexpr uint32_t LF_TX_PID = 0x000E; - constexpr uint32_t LF_RX_PID = 0x000F; - - constexpr double BASIC_MAX_BANDWIDTH = 250e6; // Hz - constexpr double LF_MAX_BANDWIDTH = 32e6; // Hz - - - const std::map<std::string, double> subdev_bandwidth_scalar{ - {"A", 1.0}, - {"B", 1.0}, - {"AB", 2.0}, - {"BA", 2.0} - }; - - const uhd::dict<std::string, std::string> sd_name_to_conn = - boost::assign::map_list_of - ("AB", "IQ") - ("BA", "QI") - ("A", "I") - ("B", "Q") - ; -} +constexpr uint32_t BASIC_TX_PID = 0x0000; +constexpr uint32_t BASIC_RX_PID = 0x0001; +constexpr uint32_t LF_TX_PID = 0x000E; +constexpr uint32_t LF_RX_PID = 0x000F; + +constexpr double BASIC_MAX_BANDWIDTH = 250e6; // Hz +constexpr double LF_MAX_BANDWIDTH = 32e6; // Hz + + +const std::map<std::string, double> subdev_bandwidth_scalar{ + {"A", 1.0}, {"B", 1.0}, {"AB", 2.0}, {"BA", 2.0}}; + +const uhd::dict<std::string, std::string> sd_name_to_conn = + boost::assign::map_list_of("AB", "IQ")("BA", "QI")("A", "I")("B", "Q"); +} // namespace /*********************************************************************** * The basic and lf boards: * They share a common class because only the frequency bounds differ. **********************************************************************/ -class basic_rx : public rx_dboard_base{ +class basic_rx : public rx_dboard_base +{ public: basic_rx(ctor_args_t args, double max_freq); virtual ~basic_rx(void); @@ -63,7 +55,8 @@ private: double _max_freq; }; -class basic_tx : public tx_dboard_base{ +class basic_tx : public tx_dboard_base +{ public: basic_tx(ctor_args_t args, double max_freq); virtual ~basic_tx(void); @@ -75,167 +68,171 @@ private: /*********************************************************************** * Register the basic and LF dboards **********************************************************************/ -static dboard_base::sptr make_basic_rx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_basic_rx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_rx(args, BASIC_MAX_BANDWIDTH)); } -static dboard_base::sptr make_basic_tx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_basic_tx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_tx(args, BASIC_MAX_BANDWIDTH)); } -static dboard_base::sptr make_lf_rx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_lf_rx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_rx(args, LF_MAX_BANDWIDTH)); } -static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new basic_tx(args, LF_MAX_BANDWIDTH)); } -UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){ - dboard_manager::register_dboard(BASIC_TX_PID, &make_basic_tx, "Basic TX", sd_name_to_conn.keys()); - dboard_manager::register_dboard(BASIC_RX_PID, &make_basic_rx, "Basic RX", sd_name_to_conn.keys()); - dboard_manager::register_dboard(LF_TX_PID, &make_lf_tx, "LF TX", sd_name_to_conn.keys()); - dboard_manager::register_dboard(LF_RX_PID, &make_lf_rx, "LF RX", sd_name_to_conn.keys()); +UHD_STATIC_BLOCK(reg_basic_and_lf_dboards) +{ + dboard_manager::register_dboard( + BASIC_TX_PID, &make_basic_tx, "Basic TX", sd_name_to_conn.keys()); + dboard_manager::register_dboard( + BASIC_RX_PID, &make_basic_rx, "Basic RX", sd_name_to_conn.keys()); + dboard_manager::register_dboard( + LF_TX_PID, &make_lf_tx, "LF TX", sd_name_to_conn.keys()); + dboard_manager::register_dboard( + LF_RX_PID, &make_lf_rx, "LF RX", sd_name_to_conn.keys()); } /*********************************************************************** * Basic and LF RX dboard **********************************************************************/ basic_rx::basic_rx(ctor_args_t args, double max_freq) - : rx_dboard_base(args), - _max_freq(max_freq) + : rx_dboard_base(args), _max_freq(max_freq) { const std::string fe_name(get_subdev_name()); const std::string fe_conn(sd_name_to_conn[fe_name]); - const std::string db_name(str( - boost::format("%s (%s)") - % ((get_rx_id() == BASIC_RX_PID) ? "BasicRX" : "LFRX") - % fe_name)); + const std::string db_name( + str(boost::format("%s (%s)") + % ((get_rx_id() == BASIC_RX_PID) ? "BasicRX" : "LFRX") % fe_name)); UHD_LOG_TRACE("BASICRX", - "Initializing driver for: " << db_name << - " IQ connection type: " << fe_conn); + "Initializing driver for: " << db_name << " IQ connection type: " << fe_conn); const bool has_fe_conn_settings = get_iface()->has_set_fe_connection(dboard_iface::UNIT_RX); UHD_LOG_TRACE("BASICRX", - "Access to FE connection settings: " - << (has_fe_conn_settings ? "Yes" : "No")); + "Access to FE connection settings: " << (has_fe_conn_settings ? "Yes" : "No")); - std::vector<std::string> antenna_options = has_fe_conn_settings - ? sd_name_to_conn.keys() - : std::vector<std::string>(1, ""); + std::vector<std::string> antenna_options = + has_fe_conn_settings ? sd_name_to_conn.keys() : std::vector<std::string>(1, ""); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->create<std::string>("name").set(db_name); - this->get_rx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_rx_subtree()->create<double>("freq/value") - .set_publisher([](){ return 0.0; }); - this->get_rx_subtree()->create<meta_range_t>("freq/range") + this->get_rx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_rx_subtree()->create<double>("freq/value").set_publisher([]() { + return 0.0; + }); + this->get_rx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(-_max_freq, +_max_freq)); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(has_fe_conn_settings ? fe_name : ""); if (has_fe_conn_settings) { - this->get_rx_subtree()->access<std::string>("antenna/value") - .add_coerced_subscriber([this](const std::string& ant){ - this->set_rx_ant(ant); - }) - ; + this->get_rx_subtree() + ->access<std::string>("antenna/value") + .add_coerced_subscriber( + [this](const std::string& ant) { this->set_rx_ant(ant); }); } - this->get_rx_subtree()->create<std::vector<std::string>>("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(antenna_options); - this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_rx_subtree()->create<std::string>("connection") + this->get_rx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_rx_subtree() + ->create<std::string>("connection") .set(sd_name_to_conn[get_subdev_name()]); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set(subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t( - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq, - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq)); - - //disable RX dboard clock by default + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") + .set(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq, + subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq)); + + // disable RX dboard clock by default this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, false); - //set GPIOs to output 0x0000 to decrease noise pickup + // set GPIOs to output 0x0000 to decrease noise pickup this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0000); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0xFFFF); this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0x0000); } -basic_rx::~basic_rx(void){ +basic_rx::~basic_rx(void) +{ /* NOP */ } void basic_rx::set_rx_ant(const std::string& ant) { UHD_ASSERT_THROW(get_iface()->has_set_fe_connection(dboard_iface::UNIT_RX)); - UHD_LOG_TRACE("BASICRX", - "Setting antenna value to: " << ant); - get_iface()->set_fe_connection( - dboard_iface::UNIT_RX, + UHD_LOG_TRACE("BASICRX", "Setting antenna value to: " << ant); + get_iface()->set_fe_connection(dboard_iface::UNIT_RX, get_subdev_name(), - usrp::fe_connection_t(sd_name_to_conn[ant], 0.0 /* IF */) - ); + usrp::fe_connection_t(sd_name_to_conn[ant], 0.0 /* IF */)); } /*********************************************************************** * Basic and LF TX dboard **********************************************************************/ -basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args){ +basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args) +{ _max_freq = max_freq; - //this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); + // this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// if (get_tx_id() == BASIC_TX_PID) { this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("BasicTX (%s)") % get_subdev_name() - ))); - } - else { + std::string(str(boost::format("BasicTX (%s)") % get_subdev_name()))); + } else { this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("LFTX (%s)") % get_subdev_name() - ))); + std::string(str(boost::format("LFTX (%s)") % get_subdev_name()))); } - this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_tx_subtree()->create<double>("freq/value") - .set_publisher([](){ return 0.0; }); - this->get_tx_subtree()->create<meta_range_t>("freq/range") + this->get_tx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_tx_subtree()->create<double>("freq/value").set_publisher([]() { + return 0.0; + }); + this->get_tx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(-_max_freq, +_max_freq)); - this->get_tx_subtree()->create<std::string>("antenna/value") - .set(""); - this->get_tx_subtree()->create<std::vector<std::string>>("antenna/options") - .set({""}); - this->get_tx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_tx_subtree()->create<std::string>("connection") + this->get_tx_subtree()->create<std::string>("antenna/value").set(""); + this->get_tx_subtree()->create<std::vector<std::string>>("antenna/options").set({""}); + this->get_tx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_tx_subtree() + ->create<std::string>("connection") .set(sd_name_to_conn[get_subdev_name()]); - this->get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_tx_subtree()->create<double>("bandwidth/value") - .set(subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t( - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq, - subdev_bandwidth_scalar.at(get_subdev_name())*_max_freq)); - - //disable TX dboard clock by default + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_tx_subtree() + ->create<double>("bandwidth/value") + .set(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq, + subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq)); + + // disable TX dboard clock by default this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, false); - //set GPIOs to output 0x0000 to decrease noise pickup + // set GPIOs to output 0x0000 to decrease noise pickup this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, 0x0000); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, 0xFFFF); this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, 0x0000); } -basic_tx::~basic_tx(void){ +basic_tx::~basic_tx(void) +{ /* NOP */ } diff --git a/host/lib/usrp/dboard/db_cbx.cpp b/host/lib/usrp/dboard/db_cbx.cpp index c08ae11ae..40bc49861 100644 --- a/host/lib/usrp/dboard/db_cbx.cpp +++ b/host/lib/usrp/dboard/db_cbx.cpp @@ -17,22 +17,30 @@ using namespace boost::assign; /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::cbx::cbx(sbx_xcvr *_self_sbx_xcvr) { - //register the handle to our base CBX class +sbx_xcvr::cbx::cbx(sbx_xcvr* _self_sbx_xcvr) +{ + // register the handle to our base CBX class self_base = _self_sbx_xcvr; - _txlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = max287x_iface::make<max2870>(std::bind(&sbx_xcvr::cbx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); } -sbx_xcvr::cbx::~cbx(void){ +sbx_xcvr::cbx::~cbx(void) +{ /* NOP */ } -void sbx_xcvr::cbx::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) +void sbx_xcvr::cbx::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) - { + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } @@ -41,39 +49,40 @@ void sbx_xcvr::cbx::write_lo_regs(dboard_iface::unit_t unit, const std::vector<u /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::cbx::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - UHD_LOGGER_TRACE("CBX") << boost::format( - "CBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double sbx_xcvr::cbx::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("CBX") << boost::format("CBX tune: target frequency %f MHz") + % (target_freq / 1e6); - //clip the input + // clip the input target_freq = cbx_freq_range.clip(target_freq); - double ref_freq = self_base->get_iface()->get_clock_rate(unit); + double ref_freq = self_base->get_iface()->get_clock_rate(unit); double target_pfd_freq = 25e6; - double actual_freq = 0.0; + double actual_freq = 0.0; /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); - if (unit == dboard_iface::UNIT_RX) - { - actual_freq = _rxlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + if (unit == dboard_iface::UNIT_RX) { + actual_freq = + _rxlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); _rxlo->commit(); } else { - actual_freq = _txlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + actual_freq = + _txlo->set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); _txlo->set_output_power((actual_freq == sbx_tx_lo_2dbm.clip(actual_freq)) - ? max287x_iface::OUTPUT_POWER_2DBM - : max287x_iface::OUTPUT_POWER_5DBM); + ? max287x_iface::OUTPUT_POWER_2DBM + : max287x_iface::OUTPUT_POWER_5DBM); _txlo->commit(); } return actual_freq; } - diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 6e4d482be..238dbd95e 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -37,24 +37,23 @@ using namespace boost::assign; **********************************************************************/ static const freq_range_t dbsrx_freq_range(0.8e9, 2.4e9); -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t dbsrx_bandwidth_range(2.0*4.0e6, 2.0*33.0e6); +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t dbsrx_bandwidth_range(2.0 * 4.0e6, 2.0 * 33.0e6); static const freq_range_t dbsrx_pfd_freq_range(0.15e6, 2.01e6); static const std::vector<std::string> dbsrx_antennas = list_of("J3"); -static const uhd::dict<std::string, gain_range_t> dbsrx_gain_ranges = map_list_of - ("GC1", gain_range_t(0, 56, 0.5)) - ("GC2", gain_range_t(0, 24, 1)) -; +static const uhd::dict<std::string, gain_range_t> dbsrx_gain_ranges = + map_list_of("GC1", gain_range_t(0, 56, 0.5))("GC2", gain_range_t(0, 24, 1)); static const double usrp1_gpio_clock_rate_limit = 4e6; /*********************************************************************** * The DBSRX dboard class **********************************************************************/ -class dbsrx : public rx_dboard_base{ +class dbsrx : public rx_dboard_base +{ public: dbsrx(ctor_args_t args); virtual ~dbsrx(void); @@ -65,65 +64,74 @@ private: uhd::dict<std::string, double> _gains; max2118_write_regs_t _max2118_write_regs; max2118_read_regs_t _max2118_read_regs; - uint8_t _max2118_addr(void){ - return (this->get_iface()->get_special_props().mangle_i2c_addrs)? 0x65 : 0x67; + uint8_t _max2118_addr(void) + { + return (this->get_iface()->get_special_props().mangle_i2c_addrs) ? 0x65 : 0x67; }; double set_lo_freq(double target_freq); - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_bandwidth(double bandwidth); - void send_reg(uint8_t start_reg, uint8_t stop_reg){ + void send_reg(uint8_t start_reg, uint8_t stop_reg) + { start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x5)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x5)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x5)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t) - 1){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 ? sizeof(uint32_t) - 1 : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t) - 1) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 + ? sizeof(uint32_t) - 1 + : stop_reg - start_addr + 1; - //create buffer for register data (+1 for start address) + // create buffer for register data (+1 for start address) byte_vector_t regs_vector(num_bytes + 1); - //first byte is the address of first register + // first byte is the address of first register regs_vector[0] = start_addr; - //get the register data - for(int i=0; i<num_bytes; i++){ - regs_vector[1+i] = _max2118_write_regs.get_reg(start_addr+i); - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes ; + // get the register data + for (int i = 0; i < num_bytes; i++) { + regs_vector[1 + i] = _max2118_write_regs.get_reg(start_addr + i); + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: send reg 0x%02x, value 0x%04x, start_addr = " + "0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[1 + i]) + % int(start_addr) % num_bytes; } - //send the data - this->get_iface()->write_i2c( - _max2118_addr(), regs_vector - ); + // send the data + this->get_iface()->write_i2c(_max2118_addr(), regs_vector); } } - void read_reg(uint8_t start_reg, uint8_t stop_reg){ + void read_reg(uint8_t start_reg, uint8_t stop_reg) + { static const uint8_t status_addr = 0x0; - start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x1)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x1)); + start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x1)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x1)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t)){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) ? sizeof(uint32_t) : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t)) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) + ? sizeof(uint32_t) + : stop_reg - start_addr + 1; - //create buffer for register data + // create buffer for register data byte_vector_t regs_vector(num_bytes); - //read from i2c - regs_vector = this->get_iface()->read_i2c( - _max2118_addr(), num_bytes - ); + // read from i2c + regs_vector = this->get_iface()->read_i2c(_max2118_addr(), num_bytes); - for(uint8_t i=0; i < num_bytes; i++){ - if (i + start_addr >= status_addr){ + for (uint8_t i = 0; i < num_bytes; i++) { + if (i + start_addr >= status_addr) { _max2118_read_regs.set_reg(i + start_addr, regs_vector[i]); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: read reg 0x%02x, value 0x%04x, start_addr = " + "0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[i]) % int(start_addr) + % num_bytes; } } } @@ -132,15 +140,14 @@ private: * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ + sensor_value_t get_locked(void) + { read_reg(0x0, 0x0); - //mask and return lock detect + // mask and return lock detect bool locked = 5 >= _max2118_read_regs.adc and _max2118_read_regs.adc >= 2; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: locked %d" - ) % locked ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX: locked %d") % locked; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -149,190 +156,214 @@ private: /*********************************************************************** * Register the DBSRX dboard **********************************************************************/ -static dboard_base::sptr make_dbsrx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_dbsrx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new dbsrx(args)); } -UHD_STATIC_BLOCK(reg_dbsrx_dboard){ - //register the factory function for the rx dbid (others version) +UHD_STATIC_BLOCK(reg_dbsrx_dboard) +{ + // register the factory function for the rx dbid (others version) dboard_manager::register_dboard(0x000D, &make_dbsrx, "DBSRX"); - //register the factory function for the rx dbid (USRP1 version) + // register the factory function for the rx dbid (USRP1 version) dboard_manager::register_dboard(0x0002, &make_dbsrx, "DBSRX"); } /*********************************************************************** * Structors **********************************************************************/ -dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ - //warn user about incorrect DBID on USRP1, requires R193 populated - if (this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x000D) - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: incorrect dbid\n" - "Expected dbid 0x0002 and R193\n" - "found dbid == %d\n" - "Please see the daughterboard app notes" - ) % this->get_rx_id().to_pp_string(); - - //warn user about incorrect DBID on non-USRP1, requires R194 populated - if (not this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x0002) - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: incorrect dbid\n" - "Expected dbid 0x000D and R194\n" - "found dbid == %d\n" - "Please see the daughterboard app notes" - ) % this->get_rx_id().to_pp_string(); - - //send initial register settings +dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args) +{ + // warn user about incorrect DBID on USRP1, requires R193 populated + if (this->get_iface()->get_special_props().soft_clock_divider + and this->get_rx_id() == 0x000D) + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: incorrect dbid\n" + "Expected dbid 0x0002 and R193\n" + "found dbid == %d\n" + "Please see the daughterboard app notes") + % this->get_rx_id().to_pp_string(); + + // warn user about incorrect DBID on non-USRP1, requires R194 populated + if (not this->get_iface()->get_special_props().soft_clock_divider + and this->get_rx_id() == 0x0002) + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: incorrect dbid\n" + "Expected dbid 0x000D and R194\n" + "found dbid == %d\n" + "Please see the daughterboard app notes") + % this->get_rx_id().to_pp_string(); + + // send initial register settings this->send_reg(0x0, 0x5); - //set defaults for LO, gains, and filter bandwidth + // set defaults for LO, gains, and filter bandwidth double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX); - _bandwidth = 0.8*codec_rate/2.0; // default to anti-alias at different codec_rate + _bandwidth = 0.8 * codec_rate / 2.0; // default to anti-alias at different codec_rate //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("DBSRX"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("DBSRX"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&dbsrx::get_locked, this)); - for(const std::string &name: dbsrx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + for (const std::string& name : dbsrx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&dbsrx::set_gain, this, std::placeholders::_1, name)) .set(dbsrx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(dbsrx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&dbsrx::set_lo_freq, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(dbsrx_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(dbsrx_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(dbsrx_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(dbsrx_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") + this->get_rx_subtree()->create<std::string>("connection").set("IQ"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") .set_coercer(std::bind(&dbsrx::set_bandwidth, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(dbsrx_bandwidth_range); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr - if (this->get_iface()->get_special_props().soft_clock_divider){ - this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock when on USRP1 - } - else{ + if (this->get_iface()->get_special_props().soft_clock_divider) { + this->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock when on USRP1 + } else { this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs } - //now its safe to set inital freq and bw - this->get_rx_subtree()->access<double>("freq/value") - .set(dbsrx_freq_range.start()); - this->get_rx_subtree()->access<double>("bandwidth/value") - .set(2.0*_bandwidth); //_bandwidth in lowpass, convert to complex bandpass + // now its safe to set inital freq and bw + this->get_rx_subtree()->access<double>("freq/value").set(dbsrx_freq_range.start()); + this->get_rx_subtree() + ->access<double>("bandwidth/value") + .set(2.0 * _bandwidth); //_bandwidth in lowpass, convert to complex bandpass } -dbsrx::~dbsrx(void){ -} +dbsrx::~dbsrx(void) {} /*********************************************************************** * Tuning **********************************************************************/ -double dbsrx::set_lo_freq(double target_freq){ +double dbsrx::set_lo_freq(double target_freq) +{ target_freq = dbsrx_freq_range.clip(target_freq); - double actual_freq=0.0, pfd_freq=0.0, ref_clock=0.0; - int R=0, N=0, r=0, m=0; + double actual_freq = 0.0, pfd_freq = 0.0, ref_clock = 0.0; + int R = 0, N = 0, r = 0, m = 0; bool update_filter_settings = false; - //choose refclock - std::vector<double> clock_rates = this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX); + // choose refclock + std::vector<double> clock_rates = + this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX); const double max_clock_rate = uhd::sorted(clock_rates).back(); - for(auto ref_clock: uhd::reversed(uhd::sorted(clock_rates))){ - //USRP1 feeds the DBSRX clock from a FPGA GPIO line. - //make sure that this clock does not exceed rate limit. - if (this->get_iface()->get_special_props().soft_clock_divider){ - if (ref_clock > usrp1_gpio_clock_rate_limit) continue; + for (auto ref_clock : uhd::reversed(uhd::sorted(clock_rates))) { + // USRP1 feeds the DBSRX clock from a FPGA GPIO line. + // make sure that this clock does not exceed rate limit. + if (this->get_iface()->get_special_props().soft_clock_divider) { + if (ref_clock > usrp1_gpio_clock_rate_limit) + continue; } - if (ref_clock > 27.0e6) continue; - if (size_t(max_clock_rate/ref_clock)%2 == 1) continue; //reject asymmetric clocks (odd divisors) + if (ref_clock > 27.0e6) + continue; + if (size_t(max_clock_rate / ref_clock) % 2 == 1) + continue; // reject asymmetric clocks (odd divisors) - //choose m_divider such that filter tuning constraint is met + // choose m_divider such that filter tuning constraint is met m = 31; - while ((ref_clock/m < 1e6 or ref_clock/m > 2.5e6) and m > 0){ m--; } + while ((ref_clock / m < 1e6 or ref_clock / m > 2.5e6) and m > 0) { + m--; + } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: trying ref_clock %f and m_divider %d" - ) % (ref_clock) % m ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: trying ref_clock %f and m_divider %d") % (ref_clock) + % m; - if (m >= 32) continue; + if (m >= 32) + continue; - //choose R - for(auto r = 0; r <= 6; r += 1) { - //compute divider from setting - R = 1 << (r+1); - UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX R:%d\n") % R ; + // choose R + for (auto r = 0; r <= 6; r += 1) { + // compute divider from setting + R = 1 << (r + 1); + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX R:%d\n") % R; - //compute PFD compare frequency = ref_clock/R + // compute PFD compare frequency = ref_clock/R pfd_freq = ref_clock / R; - //constrain the PFD frequency to specified range - if ((pfd_freq < dbsrx_pfd_freq_range.start()) or (pfd_freq > dbsrx_pfd_freq_range.stop())) continue; + // constrain the PFD frequency to specified range + if ((pfd_freq < dbsrx_pfd_freq_range.start()) + or (pfd_freq > dbsrx_pfd_freq_range.stop())) + continue; - //compute N - N = int(std::floor(target_freq/pfd_freq)); + // compute N + N = int(std::floor(target_freq / pfd_freq)); - //constrain N to specified range - if ((N < 256) or (N > 32768)) continue; + // constrain N to specified range + if ((N < 256) or (N > 32768)) + continue; goto done_loop; } } - done_loop: +done_loop: - //Assert because we failed to find a suitable combination of ref_clock, R and N + // Assert because we failed to find a suitable combination of ref_clock, R and N UHD_ASSERT_THROW(ref_clock <= 27.0e6 and ref_clock >= 0.0); - UHD_ASSERT_THROW(m and ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6); - UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) and (pfd_freq <= dbsrx_pfd_freq_range.stop())); + UHD_ASSERT_THROW(m and ref_clock / m >= 1e6 and ref_clock / m <= 2.5e6); + UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) + and (pfd_freq <= dbsrx_pfd_freq_range.stop())); UHD_ASSERT_THROW((N >= 256) and (N <= 32768)); - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: choose ref_clock (current: %f, new: %f) and m_divider %d" - ) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % ref_clock % m ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format( + "DBSRX: choose ref_clock (current: %f, new: %f) and m_divider %d") + % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % ref_clock + % m; - //if ref_clock or m divider changed, we need to update the filter settings - if (ref_clock != this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) or m != _max2118_write_regs.m_divider) update_filter_settings = true; + // if ref_clock or m divider changed, we need to update the filter settings + if (ref_clock != this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) + or m != _max2118_write_regs.m_divider) + update_filter_settings = true; - //compute resulting output frequency + // compute resulting output frequency actual_freq = pfd_freq * N; - //apply ref_clock, R, and N settings + // apply ref_clock, R, and N settings this->get_iface()->set_clock_rate(dboard_iface::UNIT_RX, ref_clock); ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); _max2118_write_regs.m_divider = m; - _max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t) r; + _max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t)r; _max2118_write_regs.set_n_divider(N); _max2118_write_regs.ade_vco_ade_read = max2118_write_regs_t::ADE_VCO_ADE_READ_ENABLED; - //compute prescaler variables - int scaler = actual_freq > 1125e6 ? 2 : 4; - _max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 : max2118_write_regs_t::DIV2_DIV2; + // compute prescaler variables + int scaler = actual_freq > 1125e6 ? 2 : 4; + _max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 + : max2118_write_regs_t::DIV2_DIV2; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: scaler %d, actual_freq %f MHz, register bit: %d" - ) % scaler % (actual_freq/1e6) % int(_max2118_write_regs.div2) ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX: scaler %d, actual_freq %f MHz, register bit: %d") + % scaler % (actual_freq / 1e6) % int(_max2118_write_regs.div2); - //compute vco frequency and select vco + // compute vco frequency and select vco double vco_freq = actual_freq * scaler; if (vco_freq < 2433e6) _max2118_write_regs.osc_band = 0; @@ -351,82 +382,94 @@ double dbsrx::set_lo_freq(double target_freq){ else _max2118_write_regs.osc_band = 7; - //send settings over i2c + // send settings over i2c send_reg(0x0, 0x4); - //check vtune for lock condition + // check vtune for lock condition read_reg(0x0, 0x0); UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: initial guess for vco %d, vtune adc %d" - ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) ; - - //if we are out of lock for chosen vco, change vco - while ((_max2118_read_regs.adc == 0) or (_max2118_read_regs.adc == 7)){ - - //vtune is too low, try lower frequency vco - if (_max2118_read_regs.adc == 0){ - if (_max2118_write_regs.osc_band == 0){ - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" - ) % int(_max2118_write_regs.osc_band); - UHD_ASSERT_THROW(_max2118_read_regs.adc != 0); //just to cause a throw + "DBSRX: initial guess for vco %d, vtune adc %d") + % int(_max2118_write_regs.osc_band) + % int(_max2118_read_regs.adc); + + // if we are out of lock for chosen vco, change vco + while ((_max2118_read_regs.adc == 0) or (_max2118_read_regs.adc == 7)) { + // vtune is too low, try lower frequency vco + if (_max2118_read_regs.adc == 0) { + if (_max2118_write_regs.osc_band == 0) { + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: Tuning exceeded vco range, " + "_max2118_write_regs.osc_band == %d\n") + % int(_max2118_write_regs.osc_band); + UHD_ASSERT_THROW(_max2118_read_regs.adc != 0); // just to cause a throw } - if (_max2118_write_regs.osc_band <= 0) break; + if (_max2118_write_regs.osc_band <= 0) + break; _max2118_write_regs.osc_band -= 1; } - //vtune is too high, try higher frequency vco - if (_max2118_read_regs.adc == 7){ - if (_max2118_write_regs.osc_band == 7){ - UHD_LOGGER_WARNING("DBSRX") << boost::format( - "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" - ) % int(_max2118_write_regs.osc_band); - UHD_ASSERT_THROW(_max2118_read_regs.adc != 7); //just to cause a throw + // vtune is too high, try higher frequency vco + if (_max2118_read_regs.adc == 7) { + if (_max2118_write_regs.osc_band == 7) { + UHD_LOGGER_WARNING("DBSRX") + << boost::format("DBSRX: Tuning exceeded vco range, " + "_max2118_write_regs.osc_band == %d\n") + % int(_max2118_write_regs.osc_band); + UHD_ASSERT_THROW(_max2118_read_regs.adc != 7); // just to cause a throw } - if (_max2118_write_regs.osc_band >= 7) break; + if (_max2118_write_regs.osc_band >= 7) + break; _max2118_write_regs.osc_band += 1; } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: trying vco %d, vtune adc %d" - ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX: trying vco %d, vtune adc %d") + % int(_max2118_write_regs.osc_band) + % int(_max2118_read_regs.adc); - //update vco selection and check vtune + // update vco selection and check vtune send_reg(0x2, 0x2); read_reg(0x0, 0x0); - //allow for setup time before checking condition again + // allow for setup time before checking condition again std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX: final vco %d, vtune adc %d" - ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX: final vco %d, vtune adc %d") + % int(_max2118_write_regs.osc_band) + % int(_max2118_read_regs.adc); - //select charge pump bias current - if (_max2118_read_regs.adc <= 2) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA; - else if (_max2118_read_regs.adc >= 5) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA; - else _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA; + // select charge pump bias current + if (_max2118_read_regs.adc <= 2) + _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA; + else if (_max2118_read_regs.adc >= 5) + _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA; + else + _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA; - //update charge pump bias current setting + // update charge pump bias current setting send_reg(0x2, 0x2); - //compute actual tuned frequency - _lo_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) / std::pow(2.0,(1 + _max2118_write_regs.r_divider)) * _max2118_write_regs.get_n_divider(); + // compute actual tuned frequency + _lo_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) + / std::pow(2.0, (1 + _max2118_write_regs.r_divider)) + * _max2118_write_regs.get_n_divider(); - //debug output of calculated variables + // debug output of calculated variables UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX tune:\n") - << boost::format(" VCO=%d, CP=%d, PFD Freq=%fMHz\n") % int(_max2118_write_regs.osc_band) % _max2118_write_regs.cp_current % (pfd_freq/1e6) - << boost::format(" R=%d, N=%f, scaler=%d, div2=%d\n") % R % N % scaler % int(_max2118_write_regs.div2) - << boost::format(" Ref Freq=%fMHz\n") % (ref_clock/1e6) - << boost::format(" Target Freq=%fMHz\n") % (target_freq/1e6) - << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq/1e6) - << boost::format(" VCO Freq=%fMHz\n") % (vco_freq/1e6) - ; - - if (update_filter_settings) set_bandwidth(_bandwidth); + << boost::format(" VCO=%d, CP=%d, PFD Freq=%fMHz\n") + % int(_max2118_write_regs.osc_band) % _max2118_write_regs.cp_current + % (pfd_freq / 1e6) + << boost::format(" R=%d, N=%f, scaler=%d, div2=%d\n") % R % N % scaler + % int(_max2118_write_regs.div2) + << boost::format(" Ref Freq=%fMHz\n") % (ref_clock / 1e6) + << boost::format(" Target Freq=%fMHz\n") % (target_freq / 1e6) + << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq / 1e6) + << boost::format(" VCO Freq=%fMHz\n") % (vco_freq / 1e6); + + if (update_filter_settings) + set_bandwidth(_bandwidth); get_locked(); return _lo_freq; @@ -441,22 +484,22 @@ double dbsrx::set_lo_freq(double target_freq){ * \param gain the requested gain in dB * \return 5 bit the register value */ -static int gain_to_gc2_vga_reg(double &gain){ +static int gain_to_gc2_vga_reg(double& gain) +{ int reg = 0; - gain = dbsrx_gain_ranges["GC2"].clip(gain); + gain = dbsrx_gain_ranges["GC2"].clip(gain); // Half dB steps from 0-5dB, 1dB steps from 5-24dB if (gain < 5) { - reg = boost::math::iround(31.0 - gain/0.5); + reg = boost::math::iround(31.0 - gain / 0.5); gain = double(boost::math::iround(gain) * 0.5); } else { - reg = boost::math::iround(22.0 - (gain - 4.0)); + reg = boost::math::iround(22.0 - (gain - 4.0)); gain = double(boost::math::iround(gain)); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX GC2 Gain: %f dB, reg: %d" - ) % gain % reg ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX GC2 Gain: %f dB, reg: %d") % gain + % reg; return reg; } @@ -467,38 +510,39 @@ static int gain_to_gc2_vga_reg(double &gain){ * \param gain the requested gain in dB * \return dac voltage value */ -static double gain_to_gc1_rfvga_dac(double &gain){ - //clip the input +static double gain_to_gc1_rfvga_dac(double& gain) +{ + // clip the input gain = dbsrx_gain_ranges["GC1"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = 1.2, min_volts = 2.7; - static const double slope = (max_volts-min_volts)/dbsrx_gain_ranges["GC1"].stop(); + static const double slope = (max_volts - min_volts) / dbsrx_gain_ranges["GC1"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX GC1 Gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX GC1 Gain: %f dB, dac_volts: %f V") + % gain % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double dbsrx::set_gain(double gain, const std::string &name){ +double dbsrx::set_gain(double gain, const std::string& name) +{ assert_has(dbsrx_gain_ranges.keys(), name, "dbsrx gain name"); - if (name == "GC2"){ + if (name == "GC2") { _max2118_write_regs.gc2 = gain_to_gc2_vga_reg(gain); send_reg(0x5, 0x5); - } - else if(name == "GC1"){ - //write the new voltage to the aux dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else if (name == "GC1") { + // write the new voltage to the aux dac + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); _gains[name] = gain; return gain; @@ -507,29 +551,36 @@ double dbsrx::set_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -double dbsrx::set_bandwidth(double bandwidth){ - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; +double dbsrx::set_bandwidth(double bandwidth) +{ + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - //clip the input + // clip the input bandwidth = dbsrx_bandwidth_range.clip(bandwidth); double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); - //NOTE: _max2118_write_regs.m_divider set in set_lo_freq + // NOTE: _max2118_write_regs.m_divider set in set_lo_freq - //compute f_dac setting - _max2118_write_regs.f_dac = uhd::clip<int>(int((((bandwidth*_max2118_write_regs.m_divider)/ref_clock) - 4)/0.145),0,127); + // compute f_dac setting + _max2118_write_regs.f_dac = uhd::clip<int>( + int((((bandwidth * _max2118_write_regs.m_divider) / ref_clock) - 4) / 0.145), + 0, + 127); - //determine actual bandwidth - _bandwidth = double((ref_clock/(_max2118_write_regs.m_divider))*(4+0.145*_max2118_write_regs.f_dac)); + // determine actual bandwidth + _bandwidth = double((ref_clock / (_max2118_write_regs.m_divider)) + * (4 + 0.145 * _max2118_write_regs.f_dac)); UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX Filter Bandwidth: %f MHz, m: %d, f_dac: %d\n" - ) % (_bandwidth/1e6) % int(_max2118_write_regs.m_divider) % int(_max2118_write_regs.f_dac) ; + "DBSRX Filter Bandwidth: %f MHz, m: %d, f_dac: %d\n") + % (_bandwidth / 1e6) + % int(_max2118_write_regs.m_divider) + % int(_max2118_write_regs.f_dac); this->send_reg(0x3, 0x4); - //convert lowpass back to complex bandpass bandwidth - return 2.0*_bandwidth; + // convert lowpass back to complex bandpass bandwidth + return 2.0 * _bandwidth; } diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp index 2d800467c..19c058ada 100644 --- a/host/lib/usrp/dboard/db_dbsrx2.cpp +++ b/host/lib/usrp/dboard/db_dbsrx2.cpp @@ -33,22 +33,21 @@ using namespace boost::assign; **********************************************************************/ static const freq_range_t dbsrx2_freq_range(0.8e9, 2.3e9); -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t dbsrx2_bandwidth_range(2.0*4.0e6, 2.0*40.0e6); +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t dbsrx2_bandwidth_range(2.0 * 4.0e6, 2.0 * 40.0e6); static const int dbsrx2_ref_divider = 4; // Hitachi HMC426 divider (U7) static const std::vector<std::string> dbsrx2_antennas = list_of("J3"); -static const uhd::dict<std::string, gain_range_t> dbsrx2_gain_ranges = map_list_of - ("GC1", gain_range_t(0, 73, 0.05)) - ("BBG", gain_range_t(0, 15, 1)) -; +static const uhd::dict<std::string, gain_range_t> dbsrx2_gain_ranges = + map_list_of("GC1", gain_range_t(0, 73, 0.05))("BBG", gain_range_t(0, 15, 1)); /*********************************************************************** * The DBSRX2 dboard class **********************************************************************/ -class dbsrx2 : public rx_dboard_base{ +class dbsrx2 : public rx_dboard_base +{ public: dbsrx2(ctor_args_t args); virtual ~dbsrx2(void); @@ -59,74 +58,81 @@ private: uhd::dict<std::string, double> _gains; max2112_write_regs_t _max2112_write_regs; max2112_read_regs_t _max2112_read_regs; - uint8_t _max2112_addr(){ //0x60 or 0x61 depending on which side - return (this->get_iface()->get_special_props().mangle_i2c_addrs)? 0x60 : 0x61; + uint8_t _max2112_addr() + { // 0x60 or 0x61 depending on which side + return (this->get_iface()->get_special_props().mangle_i2c_addrs) ? 0x60 : 0x61; } double set_lo_freq(double target_freq); - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_bandwidth(double bandwidth); - void send_reg(uint8_t start_reg, uint8_t stop_reg){ + void send_reg(uint8_t start_reg, uint8_t stop_reg) + { start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0xB)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xB)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xB)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t) - 1){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 ? sizeof(uint32_t) - 1 : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t) - 1) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 + ? sizeof(uint32_t) - 1 + : stop_reg - start_addr + 1; - //create buffer for register data (+1 for start address) + // create buffer for register data (+1 for start address) byte_vector_t regs_vector(num_bytes + 1); - //first byte is the address of first register + // first byte is the address of first register regs_vector[0] = start_addr; - //get the register data - for(int i=0; i<num_bytes; i++){ - regs_vector[1+i] = _max2112_write_regs.get_reg(start_addr+i); - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX2: send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes ; + // get the register data + for (int i = 0; i < num_bytes; i++) { + regs_vector[1 + i] = _max2112_write_regs.get_reg(start_addr + i); + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX2: send reg 0x%02x, value 0x%04x, start_addr " + "= 0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[1 + i]) + % int(start_addr) % num_bytes; } - //send the data - this->get_iface()->write_i2c( - _max2112_addr(), regs_vector - ); + // send the data + this->get_iface()->write_i2c(_max2112_addr(), regs_vector); } } - void read_reg(uint8_t start_reg, uint8_t stop_reg){ + void read_reg(uint8_t start_reg, uint8_t stop_reg) + { static const uint8_t status_addr = 0xC; - start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0xD)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xD)); + start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0xD)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0xD)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t)){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) ? sizeof(uint32_t) : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t)) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) + ? sizeof(uint32_t) + : stop_reg - start_addr + 1; - //create address to start reading register data + // create address to start reading register data byte_vector_t address_vector(1); address_vector[0] = start_addr; - //send the address - this->get_iface()->write_i2c( - _max2112_addr(), address_vector - ); + // send the address + this->get_iface()->write_i2c(_max2112_addr(), address_vector); - //create buffer for register data + // create buffer for register data byte_vector_t regs_vector(num_bytes); - //read from i2c - regs_vector = this->get_iface()->read_i2c( - _max2112_addr(), num_bytes - ); + // read from i2c + regs_vector = this->get_iface()->read_i2c(_max2112_addr(), num_bytes); - for(uint8_t i=0; i < num_bytes; i++){ - if (i + start_addr >= status_addr){ + for (uint8_t i = 0; i < num_bytes; i++) { + if (i + start_addr >= status_addr) { _max2112_read_regs.set_reg(i + start_addr, regs_vector[i]); } - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX2: read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes ; + UHD_LOGGER_TRACE("DBSRX") + << boost::format("DBSRX2: read reg 0x%02x, value 0x%04x, start_addr " + "= 0x%04x, num_bytes %d") + % int(start_addr + i) % int(regs_vector[i]) % int(start_addr) + % num_bytes; } } } @@ -135,15 +141,16 @@ private: * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ + sensor_value_t get_locked(void) + { read_reg(0xC, 0xD); - //mask and return lock detect - bool locked = (_max2112_read_regs.ld & _max2112_read_regs.vasa & _max2112_read_regs.vase) != 0; + // mask and return lock detect + bool locked = + (_max2112_read_regs.ld & _max2112_read_regs.vasa & _max2112_read_regs.vase) + != 0; - UHD_LOGGER_TRACE("DBSRX") << boost::format( - "DBSRX2 locked: %d" - ) % locked ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 locked: %d") % locked; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -154,124 +161,135 @@ private: **********************************************************************/ // FIXME 0x67 is the default i2c address on USRP2 // need to handle which side for USRP1 with different address -static dboard_base::sptr make_dbsrx2(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_dbsrx2(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new dbsrx2(args)); } -UHD_STATIC_BLOCK(reg_dbsrx2_dboard){ - //register the factory function for the rx dbid +UHD_STATIC_BLOCK(reg_dbsrx2_dboard) +{ + // register the factory function for the rx dbid dboard_manager::register_dboard(0x0012, &make_dbsrx2, "DBSRX2"); } /*********************************************************************** * Structors **********************************************************************/ -dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args){ - //send initial register settings +dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args) +{ + // send initial register settings send_reg(0x0, 0xB); - //for (uint8_t addr=0; addr<=12; addr++) this->send_reg(addr, addr); + // for (uint8_t addr=0; addr<=12; addr++) this->send_reg(addr, addr); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("DBSRX"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("DBSRX"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&dbsrx2::get_locked, this)); - for(const std::string &name: dbsrx2_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + for (const std::string& name : dbsrx2_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&dbsrx2::set_gain, this, std::placeholders::_1, name)) .set(dbsrx2_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(dbsrx2_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&dbsrx2::set_lo_freq, this, std::placeholders::_1)) .set(dbsrx2_freq_range.start()); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(dbsrx2_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(dbsrx2_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(dbsrx2_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(dbsrx2_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("QI"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); + this->get_rx_subtree()->create<std::string>("connection").set("QI"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX); - this->get_rx_subtree()->create<double>("bandwidth/value") + this->get_rx_subtree() + ->create<double>("bandwidth/value") .set_coercer(std::bind(&dbsrx2::set_bandwidth, this, std::placeholders::_1)) - .set(2.0*(0.8*codec_rate/2.0)); //bandwidth in lowpass, convert to complex bandpass - //default to anti-alias at different codec_rate - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + .set(2.0 + * (0.8 * codec_rate + / 2.0)); // bandwidth in lowpass, convert to complex bandpass + // default to anti-alias at different codec_rate + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(dbsrx2_bandwidth_range); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs get_locked(); } -dbsrx2::~dbsrx2(void){ -} +dbsrx2::~dbsrx2(void) {} /*********************************************************************** * Tuning **********************************************************************/ -double dbsrx2::set_lo_freq(double target_freq){ - //target_freq = dbsrx2_freq_range.clip(target_freq); +double dbsrx2::set_lo_freq(double target_freq) +{ + // target_freq = dbsrx2_freq_range.clip(target_freq); - //variables used in the calculation below - int scaler = target_freq >= 1125e6 ? 2 : 4; + // variables used in the calculation below + int scaler = target_freq >= 1125e6 ? 2 : 4; double ref_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); int R, intdiv, fracdiv, ext_div; double N; - //compute tuning variables + // compute tuning variables ext_div = dbsrx2_ref_divider; // 12MHz < ref_freq/ext_divider < 30MHz - R = 1; //Divide by 1 is the only tested value + R = 1; // Divide by 1 is the only tested value - N = (target_freq*R*ext_div)/(ref_freq); //actual spec range is (19, 251) - intdiv = int(std::floor(N)); // if (intdiv < 19 or intdiv > 251) continue; - fracdiv = boost::math::iround((N - intdiv)*double(1 << 20)); + N = (target_freq * R * ext_div) / (ref_freq); // actual spec range is (19, 251) + intdiv = int(std::floor(N)); // if (intdiv < 19 or intdiv > 251) continue; + fracdiv = boost::math::iround((N - intdiv) * double(1 << 20)); - //calculate the actual freq from the values above - N = double(intdiv) + double(fracdiv)/double(1 << 20); - _lo_freq = (N*ref_freq)/(R*ext_div); + // calculate the actual freq from the values above + N = double(intdiv) + double(fracdiv) / double(1 << 20); + _lo_freq = (N * ref_freq) / (R * ext_div); - //load new counters into registers + // load new counters into registers _max2112_write_regs.set_n_divider(intdiv); _max2112_write_regs.set_f_divider(fracdiv); _max2112_write_regs.r_divider = R; - _max2112_write_regs.d24 = scaler == 4 ? max2112_write_regs_t::D24_DIV4 : max2112_write_regs_t::D24_DIV2; + _max2112_write_regs.d24 = scaler == 4 ? max2112_write_regs_t::D24_DIV4 + : max2112_write_regs_t::D24_DIV2; - //debug output of calculated variables + // debug output of calculated variables UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 tune:\n") - << boost::format(" R=%d, N=%f, scaler=%d, ext_div=%d\n") % R % N % scaler % ext_div - << boost::format(" int=%d, frac=%d, d24=%d\n") % intdiv % fracdiv % int(_max2112_write_regs.d24) - << boost::format(" Ref Freq=%fMHz\n") % (ref_freq/1e6) - << boost::format(" Target Freq=%fMHz\n") % (target_freq/1e6) - << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq/1e6) - ; - - //send the registers 0x0 through 0x7 - //writing register 0x4 (F divider LSB) starts the VCO auto seletion so it must be written last + << boost::format(" R=%d, N=%f, scaler=%d, ext_div=%d\n") % R % N % scaler + % ext_div + << boost::format(" int=%d, frac=%d, d24=%d\n") % intdiv % fracdiv + % int(_max2112_write_regs.d24) + << boost::format(" Ref Freq=%fMHz\n") % (ref_freq / 1e6) + << boost::format(" Target Freq=%fMHz\n") % (target_freq / 1e6) + << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq / 1e6); + + // send the registers 0x0 through 0x7 + // writing register 0x4 (F divider LSB) starts the VCO auto seletion so it must be + // written last send_reg(0x5, 0x7); send_reg(0x0, 0x4); - //FIXME: probably unnecessary to call get_locked here - //get_locked(); + // FIXME: probably unnecessary to call get_locked here + // get_locked(); return _lo_freq; } @@ -285,15 +303,14 @@ double dbsrx2::set_lo_freq(double target_freq){ * \param gain the requested gain in dB * \return 4 bit the register value */ -static int gain_to_bbg_vga_reg(double &gain){ +static int gain_to_bbg_vga_reg(double& gain) +{ int reg = boost::math::iround(dbsrx2_gain_ranges["BBG"].clip(gain)); gain = double(reg); - UHD_LOGGER_TRACE("DBSRX") - << boost::format("DBSRX2 BBG Gain:\n") - << boost::format(" %f dB, bbg: %d") % gain % reg - ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 BBG Gain:\n") + << boost::format(" %f dB, bbg: %d") % gain % reg; return reg; } @@ -304,39 +321,41 @@ static int gain_to_bbg_vga_reg(double &gain){ * \param gain the requested gain in dB * \return dac voltage value */ -static double gain_to_gc1_rfvga_dac(double &gain){ - //clip the input +static double gain_to_gc1_rfvga_dac(double& gain) +{ + // clip the input gain = dbsrx2_gain_ranges["GC1"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = 0.5, min_volts = 2.7; - static const double slope = (max_volts-min_volts)/dbsrx2_gain_ranges["GC1"].stop(); + static const double slope = + (max_volts - min_volts) / dbsrx2_gain_ranges["GC1"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("DBSRX") - << boost::format("DBSRX2 GC1 Gain:\n") - << boost::format(" %f dB, dac_volts: %f V") % gain % dac_volts - ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 GC1 Gain:\n") + << boost::format(" %f dB, dac_volts: %f V") % gain + % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double dbsrx2::set_gain(double gain, const std::string &name){ +double dbsrx2::set_gain(double gain, const std::string& name) +{ assert_has(dbsrx2_gain_ranges.keys(), name, "dbsrx2 gain name"); - if (name == "BBG"){ + if (name == "BBG") { _max2112_write_regs.bbg = gain_to_bbg_vga_reg(gain); send_reg(0x9, 0x9); - } - else if(name == "GC1"){ - //write the new voltage to the aux dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else if (name == "GC1") { + // write the new voltage to the aux dac + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); _gains[name] = gain; return gain; @@ -345,23 +364,23 @@ double dbsrx2::set_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -double dbsrx2::set_bandwidth(double bandwidth){ - //clip the input +double dbsrx2::set_bandwidth(double bandwidth) +{ + // clip the input bandwidth = dbsrx2_bandwidth_range.clip(bandwidth); - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - _max2112_write_regs.lp = int((bandwidth/1e6 - 4)/0.29 + 12); - _bandwidth = double(4 + (_max2112_write_regs.lp - 12) * 0.29)*1e6; + _max2112_write_regs.lp = int((bandwidth / 1e6 - 4) / 0.29 + 12); + _bandwidth = double(4 + (_max2112_write_regs.lp - 12) * 0.29) * 1e6; - UHD_LOGGER_TRACE("DBSRX") - << boost::format("DBSRX2 Bandwidth:\n") - << boost::format(" %f MHz, lp: %f V") % (_bandwidth/1e6) % int(_max2112_write_regs.lp) - ; + UHD_LOGGER_TRACE("DBSRX") << boost::format("DBSRX2 Bandwidth:\n") + << boost::format(" %f MHz, lp: %f V") + % (_bandwidth / 1e6) % int(_max2112_write_regs.lp); this->send_reg(0x8, 0x8); - //convert lowpass back to complex bandpass bandwidth - return 2.0*_bandwidth; + // convert lowpass back to complex bandpass bandwidth + return 2.0 * _bandwidth; } diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 1bf4a7228..05f5c9a0e 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -6,21 +6,21 @@ // // IO Pin functions -#define POWER_IO (1 << 7) // Low enables power supply -#define ANTSW_IO (1 << 6) // On TX DB, 0 = TX, 1 = RX, on RX DB 0 = main ant, 1 = RX2 -#define MIXER_IO (1 << 5) // Enable appropriate mixer -#define LOCKDET_MASK (1 << 2) // Input pin +#define POWER_IO (1 << 7) // Low enables power supply +#define ANTSW_IO (1 << 6) // On TX DB, 0 = TX, 1 = RX, on RX DB 0 = main ant, 1 = RX2 +#define MIXER_IO (1 << 5) // Enable appropriate mixer +#define LOCKDET_MASK (1 << 2) // Input pin // Mixer constants -#define MIXER_ENB MIXER_IO -#define MIXER_DIS 0 +#define MIXER_ENB MIXER_IO +#define MIXER_DIS 0 // Antenna constants -#define ANT_TX 0 //the tx line is transmitting -#define ANT_RX ANTSW_IO //the tx line is receiving -#define ANT_TXRX 0 //the rx line is on txrx -#define ANT_RX2 ANTSW_IO //the rx line in on rx2 -#define ANT_XX 0 //dont care how the antenna is set +#define ANT_TX 0 // the tx line is transmitting +#define ANT_RX ANTSW_IO // the tx line is receiving +#define ANT_TXRX 0 // the rx line is on txrx +#define ANT_RX2 ANTSW_IO // the rx line in on rx2 +#define ANT_XX 0 // dont care how the antenna is set #include "adf4360_regs.hpp" #include <uhd/types/dict.hpp> @@ -49,37 +49,33 @@ static const std::vector<std::string> rfx_tx_antennas = list_of("TX/RX")("CAL"); static const std::vector<std::string> rfx_rx_antennas = list_of("TX/RX")("RX2")("CAL"); -static const uhd::dict<std::string, gain_range_t> rfx_rx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 70, 0.022)) -; +static const uhd::dict<std::string, gain_range_t> rfx_rx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 70, 0.022)); -static const uhd::dict<std::string, gain_range_t> rfx400_rx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 45, 0.022)) -; +static const uhd::dict<std::string, gain_range_t> rfx400_rx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 45, 0.022)); /*********************************************************************** * The RFX series of dboards **********************************************************************/ -class rfx_xcvr : public xcvr_dboard_base{ +class rfx_xcvr : public xcvr_dboard_base +{ public: rfx_xcvr( - ctor_args_t args, - const freq_range_t &freq_range, - bool rx_div2, bool tx_div2 - ); + ctor_args_t args, const freq_range_t& freq_range, bool rx_div2, bool tx_div2); virtual ~rfx_xcvr(void); private: const freq_range_t _freq_range; const uhd::dict<std::string, gain_range_t> _rx_gain_ranges; const uhd::dict<dboard_iface::unit_t, bool> _div2; - std::string _rx_ant; + std::string _rx_ant; uhd::dict<std::string, double> _rx_gains; uint16_t _power_up; - void set_rx_ant(const std::string &ant); - void set_tx_ant(const std::string &ant); - double set_rx_gain(double gain, const std::string &name); + void set_rx_ant(const std::string& ant); + void set_tx_ant(const std::string& ant); + double set_rx_gain(double gain, const std::string& name); /*! * Set the LO frequency for the particular dboard unit. @@ -94,7 +90,8 @@ private: * \param unit which unit rx or tx * \return sensor for locked */ - sensor_value_t get_locked(dboard_iface::unit_t unit){ + sensor_value_t get_locked(dboard_iface::unit_t unit) + { const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -108,33 +105,44 @@ private: /*********************************************************************** * Register the RFX dboards (min freq, max freq, rx div2, tx div2) **********************************************************************/ -static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(400e6, 500e6), true, true)); } -static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(750e6, 1050e6), true, true)); } -static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1500e6, 2100e6), false, false)); +static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(1500e6, 2100e6), false, false)); } -static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1150e6, 1450e6), true, true)); +static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(1150e6, 1450e6), true, true)); } -static dboard_base::sptr make_rfx_flex2200(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2000e6, 2400e6), false, false)); +static dboard_base::sptr make_rfx_flex2200(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(2000e6, 2400e6), false, false)); } -static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2300e6, 2900e6), false, false)); +static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t args) +{ + return dboard_base::sptr( + new rfx_xcvr(args, freq_range_t(2300e6, 2900e6), false, false)); } -UHD_STATIC_BLOCK(reg_rfx_dboards){ - dboard_manager::register_dboard(0x0024, 0x0028, &make_rfx_flex400, "RFX400"); - dboard_manager::register_dboard(0x0025, 0x0029, &make_rfx_flex900, "RFX900"); +UHD_STATIC_BLOCK(reg_rfx_dboards) +{ + dboard_manager::register_dboard(0x0024, 0x0028, &make_rfx_flex400, "RFX400"); + dboard_manager::register_dboard(0x0025, 0x0029, &make_rfx_flex900, "RFX900"); dboard_manager::register_dboard(0x0034, 0x0035, &make_rfx_flex1800, "RFX1800"); dboard_manager::register_dboard(0x0026, 0x002a, &make_rfx_flex1200, "RFX1200"); dboard_manager::register_dboard(0x002c, 0x002d, &make_rfx_flex2200, "RFX2200"); @@ -145,217 +153,274 @@ UHD_STATIC_BLOCK(reg_rfx_dboards){ * Structors **********************************************************************/ rfx_xcvr::rfx_xcvr( - ctor_args_t args, - const freq_range_t &freq_range, - bool rx_div2, bool tx_div2 -): - xcvr_dboard_base(args), - _freq_range(freq_range), - _rx_gain_ranges((get_rx_id() == 0x0024)? - rfx400_rx_gain_ranges : rfx_rx_gain_ranges - ), - _div2(map_list_of - (dboard_iface::UNIT_RX, rx_div2) - (dboard_iface::UNIT_TX, tx_div2) - ), - _power_up((get_rx_id() == 0x0024 && get_tx_id() == 0x0028) ? POWER_IO : 0) + ctor_args_t args, const freq_range_t& freq_range, bool rx_div2, bool tx_div2) + : xcvr_dboard_base(args) + , _freq_range(freq_range) + , _rx_gain_ranges( + (get_rx_id() == 0x0024) ? rfx400_rx_gain_ranges : rfx_rx_gain_ranges) + , _div2(map_list_of(dboard_iface::UNIT_RX, rx_div2)(dboard_iface::UNIT_TX, tx_div2)) + , _power_up((get_rx_id() == 0x0024 && get_tx_id() == 0x0028) ? POWER_IO : 0) { //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// - if(get_rx_id() == 0x0024) this->get_rx_subtree()->create<std::string>("name").set("RFX400 RX"); - else if(get_rx_id() == 0x0025) this->get_rx_subtree()->create<std::string>("name").set("RFX900 RX"); - else if(get_rx_id() == 0x0034) this->get_rx_subtree()->create<std::string>("name").set("RFX1800 RX"); - else if(get_rx_id() == 0x0026) this->get_rx_subtree()->create<std::string>("name").set("RFX1200 RX"); - else if(get_rx_id() == 0x002c) this->get_rx_subtree()->create<std::string>("name").set("RFX2200 RX"); - else if(get_rx_id() == 0x0027) this->get_rx_subtree()->create<std::string>("name").set("RFX2400 RX"); - else this->get_rx_subtree()->create<std::string>("name").set("RFX RX"); - - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (get_rx_id() == 0x0024) + this->get_rx_subtree()->create<std::string>("name").set("RFX400 RX"); + else if (get_rx_id() == 0x0025) + this->get_rx_subtree()->create<std::string>("name").set("RFX900 RX"); + else if (get_rx_id() == 0x0034) + this->get_rx_subtree()->create<std::string>("name").set("RFX1800 RX"); + else if (get_rx_id() == 0x0026) + this->get_rx_subtree()->create<std::string>("name").set("RFX1200 RX"); + else if (get_rx_id() == 0x002c) + this->get_rx_subtree()->create<std::string>("name").set("RFX2200 RX"); + else if (get_rx_id() == 0x0027) + this->get_rx_subtree()->create<std::string>("name").set("RFX2400 RX"); + else + this->get_rx_subtree()->create<std::string>("name").set("RFX RX"); + + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_RX)); - for(const std::string &name: _rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&rfx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : _rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&rfx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) .set(_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(_rx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((_freq_range.start() + _freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) + .set((_freq_range.start() + _freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&rfx_xcvr::set_rx_ant, this, std::placeholders::_1)) + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&rfx_xcvr::set_rx_ant, this, std::placeholders::_1)) .set("RX2"); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(rfx_rx_antennas); this->get_rx_subtree()->create<std::string>("connection").set("QI"); - this->get_rx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); - this->get_rx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*20.0e6, 2*20.0e6)); + this->get_rx_subtree() + ->create<double>("bandwidth/value") + .set(2 * 20.0e6); // 20MHz low-pass, we want complex double-sided + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * 20.0e6, 2 * 20.0e6)); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// - if(get_tx_id() == 0x0028) this->get_tx_subtree()->create<std::string>("name").set("RFX400 TX"); - else if(get_tx_id() == 0x0029) this->get_tx_subtree()->create<std::string>("name").set("RFX900 TX"); - else if(get_tx_id() == 0x0035) this->get_tx_subtree()->create<std::string>("name").set("RFX1800 TX"); - else if(get_tx_id() == 0x002a) this->get_tx_subtree()->create<std::string>("name").set("RFX1200 TX"); - else if(get_tx_id() == 0x002d) this->get_tx_subtree()->create<std::string>("name").set("RFX2200 TX"); - else if(get_tx_id() == 0x002b) this->get_tx_subtree()->create<std::string>("name").set("RFX2400 TX"); - else this->get_tx_subtree()->create<std::string>("name").set("RFX TX"); - - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (get_tx_id() == 0x0028) + this->get_tx_subtree()->create<std::string>("name").set("RFX400 TX"); + else if (get_tx_id() == 0x0029) + this->get_tx_subtree()->create<std::string>("name").set("RFX900 TX"); + else if (get_tx_id() == 0x0035) + this->get_tx_subtree()->create<std::string>("name").set("RFX1800 TX"); + else if (get_tx_id() == 0x002a) + this->get_tx_subtree()->create<std::string>("name").set("RFX1200 TX"); + else if (get_tx_id() == 0x002d) + this->get_tx_subtree()->create<std::string>("name").set("RFX2200 TX"); + else if (get_tx_id() == 0x002b) + this->get_tx_subtree()->create<std::string>("name").set("RFX2400 TX"); + else + this->get_tx_subtree()->create<std::string>("name").set("RFX TX"); + + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_TX)); - this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((_freq_range.start() + _freq_range.stop())/2.0); + this->get_tx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) + .set((_freq_range.start() + _freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(_freq_range); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&rfx_xcvr::set_tx_ant, this, std::placeholders::_1)).set(rfx_tx_antennas.at(0)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&rfx_xcvr::set_tx_ant, this, std::placeholders::_1)) + .set(rfx_tx_antennas.at(0)); + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(rfx_tx_antennas); this->get_tx_subtree()->create<std::string>("connection").set("IQ"); - this->get_tx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_tx_subtree()->create<bool>("use_lo_offset").set(true); - this->get_tx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*20.0e6, 2*20.0e6)); - - //enable the clocks that we need + this->get_tx_subtree() + ->create<double>("bandwidth/value") + .set(2 * 20.0e6); // 20MHz low-pass, we want complex double-sided + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * 20.0e6, 2 * 20.0e6)); + + // enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) uint16_t output_enables = POWER_IO | ANTSW_IO | MIXER_IO; this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, output_enables); this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, output_enables); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, output_enables); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, output_enables); - //setup the tx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB); - - //setup the rx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB); + // setup the tx atr (this does not change with antenna) + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_TX | MIXER_ENB); + + // setup the rx atr (this does not change with antenna) + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_RX2 | MIXER_ENB); } -rfx_xcvr::~rfx_xcvr(void){ +rfx_xcvr::~rfx_xcvr(void) +{ /* NOP */ } /*********************************************************************** * Antenna Handling **********************************************************************/ -void rfx_xcvr::set_rx_ant(const std::string &ant){ - //validate input +void rfx_xcvr::set_rx_ant(const std::string& ant) +{ + // validate input assert_has(rfx_rx_antennas, ant, "rfx rx antenna name"); - //set the rx atr regs that change with antenna setting + // set the rx atr regs that change with antenna setting if (ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TXRX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TXRX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | ANT_TXRX ); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | - ((ant == "TX/RX")? ANT_TXRX : ANT_RX2)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_TXRX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_TXRX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + _power_up | MIXER_ENB | ANT_TXRX); + } else { + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_XX | MIXER_DIS); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_RX2 | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + _power_up | MIXER_ENB | ((ant == "TX/RX") ? ANT_TXRX : ANT_RX2)); } - //shadow the setting + // shadow the setting _rx_ant = ant; } -void rfx_xcvr::set_tx_ant(const std::string &ant){ +void rfx_xcvr::set_tx_ant(const std::string& ant) +{ assert_has(rfx_tx_antennas, ant, "rfx tx antenna name"); - //set the tx atr regs that change with antenna setting + // set the tx atr regs that change with antenna setting if (ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_RX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX | MIXER_ENB); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_RX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_RX | MIXER_ENB); + } else { + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + _power_up | ANT_TX | MIXER_ENB); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _power_up | ANT_TX | MIXER_ENB); } } /*********************************************************************** * Gain Handling **********************************************************************/ -static double rx_pga0_gain_to_dac_volts(double &gain, double range){ - //voltage level constants (negative slope) +static double rx_pga0_gain_to_dac_volts(double& gain, double range) +{ + // voltage level constants (negative slope) static const double max_volts = .2, min_volts = 1.2; - static const double slope = (max_volts-min_volts)/(range); + static const double slope = (max_volts - min_volts) / (range); - //calculate the voltage for the aux dac - double dac_volts = uhd::clip<double>(gain*slope + min_volts, max_volts, min_volts); + // calculate the voltage for the aux dac + double dac_volts = uhd::clip<double>(gain * slope + min_volts, max_volts, min_volts); - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double rfx_xcvr::set_rx_gain(double gain, const std::string &name){ +double rfx_xcvr::set_rx_gain(double gain, const std::string& name) +{ assert_has(_rx_gain_ranges.keys(), name, "rfx rx gain name"); - if(name == "PGA0"){ - double dac_volts = rx_pga0_gain_to_dac_volts(gain, - (_rx_gain_ranges["PGA0"].stop() - _rx_gain_ranges["PGA0"].start())); + if (name == "PGA0") { + double dac_volts = rx_pga0_gain_to_dac_volts( + gain, (_rx_gain_ranges["PGA0"].stop() - _rx_gain_ranges["PGA0"].start())); - //write the new voltage to the aux dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, dac_volts); + // write the new voltage to the aux dac + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, dac_volts); return gain; - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); } /*********************************************************************** * Tuning **********************************************************************/ -double rfx_xcvr::set_lo_freq( - dboard_iface::unit_t unit, - double target_freq -){ - UHD_LOGGER_TRACE("RFX") << boost::format( - "RFX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double rfx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("RFX") << boost::format("RFX tune: target frequency %f MHz") + % (target_freq / 1e6); - //clip the input + // clip the input target_freq = _freq_range.clip(target_freq); - if (_div2[unit]) target_freq *= 2; + if (_div2[unit]) + target_freq *= 2; - //rfx400 rx is a special case with div2 in mixer, so adf4360 must output fundamental + // rfx400 rx is a special case with div2 in mixer, so adf4360 must output fundamental bool is_rx_rfx400 = ((get_rx_id() == 0x0024) && unit != dboard_iface::UNIT_TX); - //map prescalers to the register enums - static const uhd::dict<int, adf4360_regs_t::prescaler_value_t> prescaler_to_enum = map_list_of - (8, adf4360_regs_t::PRESCALER_VALUE_8_9) - (16, adf4360_regs_t::PRESCALER_VALUE_16_17) - (32, adf4360_regs_t::PRESCALER_VALUE_32_33) - ; + // map prescalers to the register enums + static const uhd::dict<int, adf4360_regs_t::prescaler_value_t> prescaler_to_enum = + map_list_of(8, adf4360_regs_t::PRESCALER_VALUE_8_9)( + 16, adf4360_regs_t::PRESCALER_VALUE_16_17)( + 32, adf4360_regs_t::PRESCALER_VALUE_32_33); - //map band select clock dividers to enums - static const uhd::dict<int, adf4360_regs_t::band_select_clock_div_t> bandsel_to_enum = map_list_of - (1, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_1) - (2, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_2) - (4, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_4) - (8, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_8) - ; + // map band select clock dividers to enums + static const uhd::dict<int, adf4360_regs_t::band_select_clock_div_t> bandsel_to_enum = + map_list_of(1, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_1)( + 2, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_2)( + 4, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_4)( + 8, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_8); - double actual_freq=0, ref_freq = this->get_iface()->get_clock_rate(unit); - int R=0, BS=0, P=0, B=0, A=0; + double actual_freq = 0, ref_freq = this->get_iface()->get_clock_rate(unit); + int R = 0, BS = 0, P = 0, B = 0, A = 0; /* * The goal here to to loop through possible R dividers, @@ -393,10 +458,11 @@ double rfx_xcvr::set_lo_freq( done_loop: UHD_LOGGER_TRACE("RFX") << boost::format( - "RFX tune: R=%d, BS=%d, P=%d, B=%d, A=%d, DIV2=%d" - ) % R % BS % P % B % A % int(_div2[unit] && (!is_rx_rfx400)) ; + "RFX tune: R=%d, BS=%d, P=%d, B=%d, A=%d, DIV2=%d") + % R % BS % P % B % A + % int(_div2[unit] && (!is_rx_rfx400)); - //load the register values + // load the register values adf4360_regs_t regs; regs.core_power_level = adf4360_regs_t::CORE_POWER_LEVEL_10MA; regs.counter_operation = adf4360_regs_t::COUNTER_OPERATION_NORMAL; @@ -413,33 +479,31 @@ done_loop: regs.a_counter = A; regs.b_counter = B; regs.cp_gain_1 = adf4360_regs_t::CP_GAIN_1_SET1; - regs.divide_by_2_output = (_div2[unit] && (!is_rx_rfx400)) ? // Special case RFX400 RX Mixer divides by two - adf4360_regs_t::DIVIDE_BY_2_OUTPUT_DIV2 : - adf4360_regs_t::DIVIDE_BY_2_OUTPUT_FUND ; - regs.divide_by_2_prescaler = adf4360_regs_t::DIVIDE_BY_2_PRESCALER_FUND; - regs.r_counter = R; - regs.ablpw = adf4360_regs_t::ABLPW_3_0NS; - regs.lock_detect_precision = adf4360_regs_t::LOCK_DETECT_PRECISION_5CYCLES; - regs.test_mode_bit = 0; - regs.band_select_clock_div = bandsel_to_enum[BS]; - - //write the registers - std::vector<adf4360_regs_t::addr_t> addrs = list_of //correct power-up sequence to write registers (R, C, N) - (adf4360_regs_t::ADDR_RCOUNTER) - (adf4360_regs_t::ADDR_CONTROL) - (adf4360_regs_t::ADDR_NCOUNTER) - ; - for(adf4360_regs_t::addr_t addr: addrs){ + regs.divide_by_2_output = (_div2[unit] && (!is_rx_rfx400)) + ? // Special case RFX400 RX Mixer divides by two + adf4360_regs_t::DIVIDE_BY_2_OUTPUT_DIV2 + : adf4360_regs_t::DIVIDE_BY_2_OUTPUT_FUND; + regs.divide_by_2_prescaler = adf4360_regs_t::DIVIDE_BY_2_PRESCALER_FUND; + regs.r_counter = R; + regs.ablpw = adf4360_regs_t::ABLPW_3_0NS; + regs.lock_detect_precision = adf4360_regs_t::LOCK_DETECT_PRECISION_5CYCLES; + regs.test_mode_bit = 0; + regs.band_select_clock_div = bandsel_to_enum[BS]; + + // write the registers + std::vector<adf4360_regs_t::addr_t> addrs = + list_of // correct power-up sequence to write registers (R, C, N) + (adf4360_regs_t::ADDR_RCOUNTER)(adf4360_regs_t::ADDR_CONTROL)( + adf4360_regs_t::ADDR_NCOUNTER); + for (adf4360_regs_t::addr_t addr : addrs) { this->get_iface()->write_spi( - unit, spi_config_t::EDGE_RISE, - regs.get_reg(addr), 24 - ); + unit, spi_config_t::EDGE_RISE, regs.get_reg(addr), 24); } - //return the actual frequency - if (_div2[unit]) actual_freq /= 2; - UHD_LOGGER_TRACE("RFX") << boost::format( - "RFX tune: actual frequency %f MHz" - ) % (actual_freq/1e6) ; + // return the actual frequency + if (_div2[unit]) + actual_freq /= 2; + UHD_LOGGER_TRACE("RFX") << boost::format("RFX tune: actual frequency %f MHz") + % (actual_freq / 1e6); return actual_freq; } diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp index dc49a97aa..f79b70f53 100644 --- a/host/lib/usrp/dboard/db_sbx_common.cpp +++ b/host/lib/usrp/dboard/db_sbx_common.cpp @@ -16,11 +16,13 @@ using namespace boost::assign; /*********************************************************************** * Register the SBX dboard (min freq, max freq, rx div2, tx div2) **********************************************************************/ -static dboard_base::sptr make_sbx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_sbx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new sbx_xcvr(args)); } -UHD_STATIC_BLOCK(reg_sbx_dboards){ +UHD_STATIC_BLOCK(reg_sbx_dboards) +{ dboard_manager::register_dboard(0x0054, 0x0055, &make_sbx, "SBX"); dboard_manager::register_dboard(0x0065, 0x0064, &make_sbx, "SBX v4"); dboard_manager::register_dboard(0x0067, 0x0066, &make_sbx, "CBX"); @@ -33,71 +35,75 @@ UHD_STATIC_BLOCK(reg_sbx_dboards){ /*********************************************************************** * Gain Handling **********************************************************************/ -static int rx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int rx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = sbx_rx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation and update iobits for atr + // convert to attenuation and update iobits for atr double attn = sbx_rx_gain_ranges["PGA0"].stop() - gain; - //calculate the RX attenuation - int attn_code = int(floor(attn*2)); - int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; + // calculate the RX attenuation + int attn_code = int(floor(attn * 2)); + int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK ; + UHD_LOGGER_TRACE("SBX") + << boost::format("SBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK; - //the actual gain setting - gain = sbx_rx_gain_ranges["PGA0"].stop() - double(attn_code)/2; + // the actual gain setting + gain = sbx_rx_gain_ranges["PGA0"].stop() - double(attn_code) / 2; return iobits; } -static int tx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int tx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = sbx_tx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation and update iobits for atr + // convert to attenuation and update iobits for atr double attn = sbx_tx_gain_ranges["PGA0"].stop() - gain; - //calculate the TX attenuation - int attn_code = int(floor(attn*2)); - int iobits = ((~attn_code) << TX_ATTN_SHIFT) & TX_ATTN_MASK; + // calculate the TX attenuation + int attn_code = int(floor(attn * 2)); + int iobits = ((~attn_code) << TX_ATTN_SHIFT) & TX_ATTN_MASK; - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK ; + UHD_LOGGER_TRACE("SBX") + << boost::format("SBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK; - //the actual gain setting - gain = sbx_tx_gain_ranges["PGA0"].stop() - double(attn_code)/2; + // the actual gain setting + gain = sbx_tx_gain_ranges["PGA0"].stop() - double(attn_code) / 2; return iobits; } -double sbx_xcvr::set_tx_gain(double gain, const std::string &name){ +double sbx_xcvr::set_tx_gain(double gain, const std::string& name) +{ assert_has(sbx_tx_gain_ranges.keys(), name, "sbx tx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { tx_pga0_gain_to_iobits(gain); _tx_gains[name] = gain; - //write the new gain to atr regs + // write the new gain to atr regs update_atr(); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); return _tx_gains[name]; } -double sbx_xcvr::set_rx_gain(double gain, const std::string &name){ +double sbx_xcvr::set_rx_gain(double gain, const std::string& name) +{ assert_has(sbx_rx_gain_ranges.keys(), name, "sbx rx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { rx_pga0_gain_to_iobits(gain); _rx_gains[name] = gain; - //write the new gain to atr regs + // write the new gain to atr regs update_atr(); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); return _rx_gains[name]; } @@ -105,26 +111,27 @@ double sbx_xcvr::set_rx_gain(double gain, const std::string &name){ /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ - switch(get_rx_id().to_uint16()) { +sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args) +{ + switch (get_rx_id().to_uint16()) { case 0x0054: - db_actual = sbx_versionx_sptr(new sbx_version3(this)); - freq_range = sbx_freq_range; + db_actual = sbx_versionx_sptr(new sbx_version3(this)); + freq_range = sbx_freq_range; enable_rx_lo_filter = sbx_enable_rx_lo_filter; enable_tx_lo_filter = sbx_enable_tx_lo_filter; break; case 0x0065: case 0x0069: case 0x0083: - db_actual = sbx_versionx_sptr(new sbx_version4(this)); - freq_range = sbx_freq_range; + db_actual = sbx_versionx_sptr(new sbx_version4(this)); + freq_range = sbx_freq_range; enable_rx_lo_filter = sbx_enable_rx_lo_filter; enable_tx_lo_filter = sbx_enable_tx_lo_filter; break; case 0x0067: case 0x0085: - db_actual = sbx_versionx_sptr(new cbx(this)); - freq_range = cbx_freq_range; + db_actual = sbx_versionx_sptr(new cbx(this)); + freq_range = cbx_freq_range; enable_rx_lo_filter = cbx_enable_rx_lo_filter; enable_tx_lo_filter = cbx_enable_tx_lo_filter; break; @@ -139,40 +146,56 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ this->get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); uint16_t rx_id = get_rx_id().to_uint16(); - if(rx_id == 0x0054) this->get_rx_subtree()->create<std::string>("name").set("SBXv3 RX"); - else if(rx_id == 0x0065) this->get_rx_subtree()->create<std::string>("name").set("SBXv4 RX"); - else if(rx_id == 0x0067) this->get_rx_subtree()->create<std::string>("name").set("CBX RX"); - else if(rx_id == 0x0083) this->get_rx_subtree()->create<std::string>("name").set("SBX-120 RX"); - else if(rx_id == 0x0085) this->get_rx_subtree()->create<std::string>("name").set("CBX-120 RX"); - else this->get_rx_subtree()->create<std::string>("name").set("SBX/CBX RX"); - - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (rx_id == 0x0054) + this->get_rx_subtree()->create<std::string>("name").set("SBXv3 RX"); + else if (rx_id == 0x0065) + this->get_rx_subtree()->create<std::string>("name").set("SBXv4 RX"); + else if (rx_id == 0x0067) + this->get_rx_subtree()->create<std::string>("name").set("CBX RX"); + else if (rx_id == 0x0083) + this->get_rx_subtree()->create<std::string>("name").set("SBX-120 RX"); + else if (rx_id == 0x0085) + this->get_rx_subtree()->create<std::string>("name").set("CBX-120 RX"); + else + this->get_rx_subtree()->create<std::string>("name").set("SBX/CBX RX"); + + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_RX)); - for(const std::string &name: sbx_rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&sbx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : sbx_rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&sbx_xcvr::set_rx_gain, this, std::placeholders::_1, name)) .set(sbx_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(sbx_rx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((freq_range.start() + freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) + .set((freq_range.start() + freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&sbx_xcvr::set_rx_ant, this, std::placeholders::_1)) + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&sbx_xcvr::set_rx_ant, this, std::placeholders::_1)) .set("RX2"); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(sbx_rx_antennas); this->get_rx_subtree()->create<std::string>("connection").set("IQ"); - this->get_rx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); - //Value of bw low-pass dependent on board, we want complex double-sided + // Value of bw low-pass dependent on board, we want complex double-sided double rx_bw = ((rx_id != 0x0083) && (rx_id != 0x0085)) ? 20.0e6 : 60.0e6; - this->get_rx_subtree()->create<double>("bandwidth/value").set(2*rx_bw); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*rx_bw, 2*rx_bw)); + this->get_rx_subtree()->create<double>("bandwidth/value").set(2 * rx_bw); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * rx_bw, 2 * rx_bw)); //////////////////////////////////////////////////////////////////// // Register TX properties @@ -180,156 +203,180 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ this->get_tx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); uint16_t tx_id = get_tx_id().to_uint16(); - if(tx_id == 0x0055) this->get_tx_subtree()->create<std::string>("name").set("SBXv3 TX"); - else if(tx_id == 0x0064) this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX"); - else if(tx_id == 0x0066) this->get_tx_subtree()->create<std::string>("name").set("CBX TX"); - else if(tx_id == 0x0082) this->get_tx_subtree()->create<std::string>("name").set("SBX-120 TX"); - else if(tx_id == 0x0084) this->get_tx_subtree()->create<std::string>("name").set("CBX-120 TX"); - else this->get_tx_subtree()->create<std::string>("name").set("SBX/CBX TX"); - - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + if (tx_id == 0x0055) + this->get_tx_subtree()->create<std::string>("name").set("SBXv3 TX"); + else if (tx_id == 0x0064) + this->get_tx_subtree()->create<std::string>("name").set("SBXv4 TX"); + else if (tx_id == 0x0066) + this->get_tx_subtree()->create<std::string>("name").set("CBX TX"); + else if (tx_id == 0x0082) + this->get_tx_subtree()->create<std::string>("name").set("SBX-120 TX"); + else if (tx_id == 0x0084) + this->get_tx_subtree()->create<std::string>("name").set("CBX-120 TX"); + else + this->get_tx_subtree()->create<std::string>("name").set("SBX/CBX TX"); + + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_TX)); - for(const std::string &name: sbx_tx_gain_ranges.keys()){ - this->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&sbx_xcvr::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : sbx_tx_gain_ranges.keys()) { + this->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&sbx_xcvr::set_tx_gain, this, std::placeholders::_1, name)) .set(sbx_tx_gain_ranges[name].start()); - this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(sbx_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((freq_range.start() + freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind( + &sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) + .set((freq_range.start() + freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(freq_range); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&sbx_xcvr::set_tx_ant, this, std::placeholders::_1)) + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&sbx_xcvr::set_tx_ant, this, std::placeholders::_1)) .set(sbx_tx_antennas.at(0)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(sbx_tx_antennas); this->get_tx_subtree()->create<std::string>("connection").set("QI"); - this->get_tx_subtree()->create<bool>("enabled").set(true); //always enabled + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); - //Value of bw low-pass dependent on board, we want complex double-sided + // Value of bw low-pass dependent on board, we want complex double-sided double tx_bw = ((tx_id != 0x0082) && (tx_id != 0x0084)) ? 20.0e6 : 60.0e6; - this->get_tx_subtree()->create<double>("bandwidth/value").set(2*tx_bw); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*tx_bw, 2*tx_bw)); + this->get_tx_subtree()->create<double>("bandwidth/value").set(2 * tx_bw); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * tx_bw, 2 * tx_bw)); - //enable the clocks that we need + // enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) - this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO)); - this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO)); - this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO)); - this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO)); + // set the gpio directions and atr controls (identically) + this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK | TX_LED_IO)); + this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK | RX_LED_IO)); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK | TX_LED_IO)); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK | RX_LED_IO)); - //Initialize ATR registers after direction and pin ctrl configuration + // Initialize ATR registers after direction and pin ctrl configuration update_atr(); - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x" - ) % RXIO_MASK % TXIO_MASK ; + UHD_LOGGER_TRACE("SBX") << boost::format("SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x") + % RXIO_MASK % TXIO_MASK; } -sbx_xcvr::~sbx_xcvr(void){ +sbx_xcvr::~sbx_xcvr(void) +{ /* NOP */ } /*********************************************************************** * Antenna Handling **********************************************************************/ -void sbx_xcvr::update_atr(void){ - //calculate atr pins +void sbx_xcvr::update_atr(void) +{ + // calculate atr pins int rx_pga0_iobits = rx_pga0_gain_to_iobits(_rx_gains["PGA0"]); int tx_pga0_iobits = tx_pga0_gain_to_iobits(_tx_gains["PGA0"]); - int rx_lo_lpf_en = (_rx_lo_freq == enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN : 0; - int tx_lo_lpf_en = (_tx_lo_freq == enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN : 0; - int rx_ld_led = _rx_lo_lock_cache ? 0 : RX_LED_LD; - int tx_ld_led = _tx_lo_lock_cache ? 0 : TX_LED_LD; + int rx_lo_lpf_en = (_rx_lo_freq == enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN + : 0; + int tx_lo_lpf_en = (_tx_lo_freq == enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN + : 0; + int rx_ld_led = _rx_lo_lock_cache ? 0 : RX_LED_LD; + int tx_ld_led = _tx_lo_lock_cache ? 0 : TX_LED_LD; int rx_ant_led = _rx_ant == "TX/RX" ? RX_LED_RX1RX2 : 0; int tx_ant_led = _tx_ant == "TX/RX" ? 0 : TX_LED_TXRX; - //setup the tx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_IDLE, 0 | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | ANT_XX | TX_MIXER_DIS); - - //setup the rx atr (this does not change with antenna) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_IDLE, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | ANT_XX | RX_MIXER_DIS); - - //set the RX atr regs that change with antenna setting - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_RX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \ - | ((_rx_ant != "RX2")? ANT_TXRX : ANT_RX2)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_TX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_DIS \ - | ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, rx_pga0_iobits | rx_lo_lpf_en \ - | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \ - | ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2)); - - //set the TX atr regs that change with antenna setting - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_RX_ONLY, 0 | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_DIS \ - | ((_rx_ant != "RX2")? ANT_RX : ANT_TX)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_TX_ONLY, tx_pga0_iobits | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \ - | ((_tx_ant == "CAL")? ANT_RX : ANT_TX)); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, tx_pga0_iobits | tx_lo_lpf_en \ - | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \ - | ((_tx_ant == "CAL")? ANT_RX : ANT_TX)); + // setup the tx atr (this does not change with antenna) + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + 0 | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | ANT_XX | TX_MIXER_DIS); + + // setup the rx atr (this does not change with antenna) + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP | ANT_XX + | RX_MIXER_DIS); + + // set the RX atr regs that change with antenna setting + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP + | RX_MIXER_ENB | ((_rx_ant != "RX2") ? ANT_TXRX : ANT_RX2)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP + | RX_MIXER_DIS | ((_rx_ant == "CAL") ? ANT_TXRX : ANT_RX2)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP + | RX_MIXER_ENB | ((_rx_ant == "CAL") ? ANT_TXRX : ANT_RX2)); + + // set the TX atr regs that change with antenna setting + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + 0 | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_DIS + | ((_rx_ant != "RX2") ? ANT_RX : ANT_TX)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP + | TX_MIXER_ENB | ((_tx_ant == "CAL") ? ANT_RX : ANT_TX)); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP + | TX_MIXER_ENB | ((_tx_ant == "CAL") ? ANT_RX : ANT_TX)); } -void sbx_xcvr::set_rx_ant(const std::string &ant){ - //validate input +void sbx_xcvr::set_rx_ant(const std::string& ant) +{ + // validate input assert_has(sbx_rx_antennas, ant, "sbx rx antenna name"); - //shadow the setting + // shadow the setting _rx_ant = ant; - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs update_atr(); } -void sbx_xcvr::set_tx_ant(const std::string &ant){ +void sbx_xcvr::set_tx_ant(const std::string& ant) +{ assert_has(sbx_tx_antennas, ant, "sbx tx antenna name"); - //shadow the setting + // shadow the setting _tx_ant = ant; - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs update_atr(); } /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { +double sbx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ const double actual = db_actual->set_lo_freq(unit, target_freq); - if (unit == dboard_iface::UNIT_RX){ + if (unit == dboard_iface::UNIT_RX) { _rx_lo_lock_cache = false; - _rx_lo_freq = actual; + _rx_lo_freq = actual; } - if (unit == dboard_iface::UNIT_TX){ + if (unit == dboard_iface::UNIT_TX) { _tx_lo_lock_cache = false; - _tx_lo_freq = actual; + _tx_lo_freq = actual; } update_atr(); return actual; } -sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) { +sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) +{ const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; bool& lock_cache = (unit == dboard_iface::UNIT_RX) ? _rx_lo_lock_cache : _tx_lo_lock_cache; diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp index 9c09f21a3..c11f0bbe2 100644 --- a/host/lib/usrp/dboard/db_sbx_common.hpp +++ b/host/lib/usrp/dboard/db_sbx_common.hpp @@ -10,73 +10,76 @@ #include <uhdlib/usrp/common/max287x.hpp> // LO Related -#define ADF435X_CE (1 << 3) -#define ADF435X_PDBRF (1 << 2) -#define ADF435X_MUXOUT (1 << 1) // INPUT!!! -#define LOCKDET_MASK (1 << 0) // INPUT!!! +#define ADF435X_CE (1 << 3) +#define ADF435X_PDBRF (1 << 2) +#define ADF435X_MUXOUT (1 << 1) // INPUT!!! +#define LOCKDET_MASK (1 << 0) // INPUT!!! // Common IO Pins -#define LO_LPF_EN (1 << 15) +#define LO_LPF_EN (1 << 15) // TX IO Pins -#define TRSW (1 << 14) // 0 = TX, 1 = RX -#define TX_LED_TXRX (1 << 7) // LED for TX Antenna Selection TX/RX -#define TX_LED_LD (1 << 6) // LED for TX Lock Detect -#define DIS_POWER_TX (1 << 5) // on UNIT_TX, 0 powers up TX -#define TX_ENABLE (1 << 4) // on UNIT_TX, 0 disables TX Mixer +#define TRSW (1 << 14) // 0 = TX, 1 = RX +#define TX_LED_TXRX (1 << 7) // LED for TX Antenna Selection TX/RX +#define TX_LED_LD (1 << 6) // LED for TX Lock Detect +#define DIS_POWER_TX (1 << 5) // on UNIT_TX, 0 powers up TX +#define TX_ENABLE (1 << 4) // on UNIT_TX, 0 disables TX Mixer // RX IO Pins -#define LNASW (1 << 14) // 0 = TX/RX, 1 = RX2 -#define RX_LED_RX1RX2 (1 << 7) // LED for RX Antenna Selection RX1/RX2 -#define RX_LED_LD (1 << 6) // LED for RX Lock Detect -#define DIS_POWER_RX (1 << 5) // on UNIT_RX, 0 powers up RX -#define RX_DISABLE (1 << 4) // on UNIT_RX, 1 disables RX Mixer and Baseband -#define RX_ATTN_SHIFT 8 //lsb of RX Attenuator Control -#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) //valid bits of RX Attenuator Control +#define LNASW (1 << 14) // 0 = TX/RX, 1 = RX2 +#define RX_LED_RX1RX2 (1 << 7) // LED for RX Antenna Selection RX1/RX2 +#define RX_LED_LD (1 << 6) // LED for RX Lock Detect +#define DIS_POWER_RX (1 << 5) // on UNIT_RX, 0 powers up RX +#define RX_DISABLE (1 << 4) // on UNIT_RX, 1 disables RX Mixer and Baseband +#define RX_ATTN_SHIFT 8 // lsb of RX Attenuator Control +#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) // valid bits of RX Attenuator Control // TX Attenuator Pins -#define TX_ATTN_SHIFT 8 // lsb of TX Attenuator Control -#define TX_ATTN_MASK (63 << TX_ATTN_SHIFT) // valid bits of TX Attenuator Control +#define TX_ATTN_SHIFT 8 // lsb of TX Attenuator Control +#define TX_ATTN_MASK (63 << TX_ATTN_SHIFT) // valid bits of TX Attenuator Control // Mixer functions -#define TX_MIXER_ENB (ADF435X_PDBRF|TX_ENABLE) -#define TX_MIXER_DIS 0 +#define TX_MIXER_ENB (ADF435X_PDBRF | TX_ENABLE) +#define TX_MIXER_DIS 0 -#define RX_MIXER_ENB (ADF435X_PDBRF) -#define RX_MIXER_DIS 0 +#define RX_MIXER_ENB (ADF435X_PDBRF) +#define RX_MIXER_DIS 0 // Pin functions -#define TX_LED_IO (TX_LED_TXRX|TX_LED_LD) // LED gpio lines, pull down for LED -#define TXIO_MASK (LO_LPF_EN|TRSW|ADF435X_CE|ADF435X_PDBRF|TX_ATTN_MASK|DIS_POWER_TX|TX_ENABLE) +#define TX_LED_IO (TX_LED_TXRX | TX_LED_LD) // LED gpio lines, pull down for LED +#define TXIO_MASK \ + (LO_LPF_EN | TRSW | ADF435X_CE | ADF435X_PDBRF | TX_ATTN_MASK | DIS_POWER_TX \ + | TX_ENABLE) -#define RX_LED_IO (RX_LED_RX1RX2|RX_LED_LD) // LED gpio lines, pull down for LED -#define RXIO_MASK (LO_LPF_EN|LNASW|ADF435X_CE|ADF435X_PDBRF|RX_ATTN_MASK|DIS_POWER_RX|RX_DISABLE) +#define RX_LED_IO (RX_LED_RX1RX2 | RX_LED_LD) // LED gpio lines, pull down for LED +#define RXIO_MASK \ + (LO_LPF_EN | LNASW | ADF435X_CE | ADF435X_PDBRF | RX_ATTN_MASK | DIS_POWER_RX \ + | RX_DISABLE) // Power functions -#define TX_POWER_UP (ADF435X_CE) -#define TX_POWER_DOWN (DIS_POWER_TX) +#define TX_POWER_UP (ADF435X_CE) +#define TX_POWER_DOWN (DIS_POWER_TX) -#define RX_POWER_UP (ADF435X_CE) -#define RX_POWER_DOWN (DIS_POWER_RX) +#define RX_POWER_UP (ADF435X_CE) +#define RX_POWER_DOWN (DIS_POWER_RX) // Antenna constants -#define ANT_TX TRSW //the tx line is transmitting -#define ANT_RX 0 //the tx line is receiving -#define ANT_TXRX 0 //the rx line is on txrx -#define ANT_RX2 LNASW //the rx line in on rx2 -#define ANT_XX LNASW //dont care how the antenna is set +#define ANT_TX TRSW // the tx line is transmitting +#define ANT_RX 0 // the tx line is receiving +#define ANT_TXRX 0 // the rx line is on txrx +#define ANT_RX2 LNASW // the rx line in on rx2 +#define ANT_XX LNASW // dont care how the antenna is set #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> #include <uhd/types/sensors.hpp> +#include <uhd/usrp/dboard_base.hpp> +#include <uhd/usrp/dboard_manager.hpp> +#include <uhd/utils/algorithm.hpp> #include <uhd/utils/assert_has.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/static.hpp> -#include <uhd/utils/algorithm.hpp> - -#include <uhd/usrp/dboard_base.hpp> -#include <uhd/usrp/dboard_manager.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> #include <boost/math/special_functions/round.hpp> @@ -94,57 +97,45 @@ using namespace boost::assign; static const freq_range_t sbx_freq_range(400e6, 4.4e9); static const freq_range_t cbx_freq_range(1200e6, 6.0e9); -static const freq_range_t sbx_tx_lo_2dbm = list_of - (range_t(0.35e9, 0.37e9)) -; +static const freq_range_t sbx_tx_lo_2dbm = list_of(range_t(0.35e9, 0.37e9)); -static const freq_range_t sbx_enable_tx_lo_filter = list_of - (range_t(0.4e9, 1.5e9)) -; +static const freq_range_t sbx_enable_tx_lo_filter = list_of(range_t(0.4e9, 1.5e9)); -static const freq_range_t sbx_enable_rx_lo_filter = list_of - (range_t(0.4e9, 1.5e9)) -; +static const freq_range_t sbx_enable_rx_lo_filter = list_of(range_t(0.4e9, 1.5e9)); -static const freq_range_t cbx_enable_tx_lo_filter = list_of - (range_t(1.2e9, 2e9)) -; +static const freq_range_t cbx_enable_tx_lo_filter = list_of(range_t(1.2e9, 2e9)); -static const freq_range_t cbx_enable_rx_lo_filter = list_of - (range_t(1.2e9, 2e9)) -; +static const freq_range_t cbx_enable_rx_lo_filter = list_of(range_t(1.2e9, 2e9)); static const std::vector<std::string> sbx_tx_antennas = list_of("TX/RX")("CAL"); static const std::vector<std::string> sbx_rx_antennas = list_of("TX/RX")("RX2")("CAL"); -static const uhd::dict<std::string, gain_range_t> sbx_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31.5, double(0.5))) -; +static const uhd::dict<std::string, gain_range_t> sbx_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31.5, double(0.5))); -static const uhd::dict<std::string, gain_range_t> sbx_rx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31.5, double(0.5))) -; +static const uhd::dict<std::string, gain_range_t> sbx_rx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31.5, double(0.5))); /*********************************************************************** * The SBX dboard **********************************************************************/ -class sbx_xcvr : public xcvr_dboard_base{ +class sbx_xcvr : public xcvr_dboard_base +{ public: sbx_xcvr(ctor_args_t args); virtual ~sbx_xcvr(void); protected: - uhd::dict<std::string, double> _tx_gains, _rx_gains; - double _rx_lo_freq, _tx_lo_freq; - std::string _tx_ant, _rx_ant; + double _rx_lo_freq, _tx_lo_freq; + std::string _tx_ant, _rx_ant; bool _rx_lo_lock_cache, _tx_lo_lock_cache; - void set_rx_ant(const std::string &ant); - void set_tx_ant(const std::string &ant); - double set_rx_gain(double gain, const std::string &name); - double set_tx_gain(double gain, const std::string &name); + void set_rx_ant(const std::string& ant); + void set_tx_ant(const std::string& ant); + double set_rx_gain(double gain, const std::string& name); + double set_tx_gain(double gain, const std::string& name); void update_atr(void); @@ -175,7 +166,8 @@ protected: * This class is an abstract base class, and thus is impossible to * instantiate. */ - class sbx_versionx { + class sbx_versionx + { public: sbx_versionx() {} virtual ~sbx_versionx(void) {} @@ -186,19 +178,21 @@ protected: /*! * Version 3 of the SBX Daughterboard */ - class sbx_version3 : public sbx_versionx { + class sbx_version3 : public sbx_versionx + { public: - sbx_version3(sbx_xcvr *_self_sbx_xcvr); + sbx_version3(sbx_xcvr* _self_sbx_xcvr); virtual ~sbx_version3(void); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); /*! This is the registered instance of the wrapper class, sbx_base. */ - sbx_xcvr *self_base; + sbx_xcvr* self_base; + private: adf435x_iface::sptr _txlo; adf435x_iface::sptr _rxlo; - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); }; /*! @@ -206,19 +200,21 @@ protected: * * The only difference in the fourth revision is the ADF4351 vs the ADF4350. */ - class sbx_version4 : public sbx_versionx { + class sbx_version4 : public sbx_versionx + { public: - sbx_version4(sbx_xcvr *_self_sbx_xcvr); + sbx_version4(sbx_xcvr* _self_sbx_xcvr); virtual ~sbx_version4(void); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); /*! This is the registered instance of the wrapper class, sbx_base. */ - sbx_xcvr *self_base; + sbx_xcvr* self_base; + private: adf435x_iface::sptr _txlo; adf435x_iface::sptr _rxlo; - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); }; /*! @@ -231,17 +227,19 @@ protected: * There is also no LO filter switching required on CBX, but the GPIO is left * blank so we don't worry about it. */ - class cbx : public sbx_versionx { + class cbx : public sbx_versionx + { public: - cbx(sbx_xcvr *_self_sbx_xcvr); + cbx(sbx_xcvr* _self_sbx_xcvr); virtual ~cbx(void); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); /*! This is the registered instance of the wrapper class, sbx_base. */ - sbx_xcvr *self_base; + sbx_xcvr* self_base; + private: - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); max287x_iface::sptr _txlo; max287x_iface::sptr _rxlo; }; @@ -253,15 +251,15 @@ protected: freq_range_t freq_range; /*! - * Frequency range to use the LO LPF in RX; this is set in the constructor - * to correspond either to SBX or CBX. - */ + * Frequency range to use the LO LPF in RX; this is set in the constructor + * to correspond either to SBX or CBX. + */ freq_range_t enable_rx_lo_filter; /*! - * Frequency range to use the LO LPF in TX; this is set in the constructor - * to correspond either to SBX or CBX. - */ + * Frequency range to use the LO LPF in TX; this is set in the constructor + * to correspond either to SBX or CBX. + */ freq_range_t enable_tx_lo_filter; /*! @@ -275,4 +273,3 @@ protected: typedef std::shared_ptr<sbx_versionx> sbx_versionx_sptr; sbx_versionx_sptr db_actual; }; - diff --git a/host/lib/usrp/dboard/db_sbx_version3.cpp b/host/lib/usrp/dboard/db_sbx_version3.cpp index 835b2f725..215c50c40 100644 --- a/host/lib/usrp/dboard/db_sbx_version3.cpp +++ b/host/lib/usrp/dboard/db_sbx_version3.cpp @@ -18,21 +18,29 @@ using namespace boost::assign; /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::sbx_version3::sbx_version3(sbx_xcvr *_self_sbx_xcvr) { - //register the handle to our base SBX class +sbx_xcvr::sbx_version3::sbx_version3(sbx_xcvr* _self_sbx_xcvr) +{ + // register the handle to our base SBX class self_base = _self_sbx_xcvr; - _txlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4350(std::bind(&sbx_xcvr::sbx_version3::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); } -sbx_xcvr::sbx_version3::~sbx_version3(void){ +sbx_xcvr::sbx_version3::~sbx_version3(void) +{ /* NOP */ } -void sbx_xcvr::sbx_version3::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) +void sbx_xcvr::sbx_version3::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) - { + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } @@ -40,42 +48,44 @@ void sbx_xcvr::sbx_version3::write_lo_regs(dboard_iface::unit_t unit, const std: /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("SBX") << boost::format("SBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); lo_iface->set_reference_freq(self_base->get_iface()->get_clock_rate(unit)); - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler( + target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); - //Configure the LO + // Configure the LO double actual_freq = 0.0; actual_freq = lo_iface->set_frequency(sbx_freq_range.clip(target_freq), is_int_n); - if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { + if ((unit == dboard_iface::UNIT_TX) + and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_2DBM); } else { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; } - diff --git a/host/lib/usrp/dboard/db_sbx_version4.cpp b/host/lib/usrp/dboard/db_sbx_version4.cpp index 5c76a1b12..cf6dc4553 100644 --- a/host/lib/usrp/dboard/db_sbx_version4.cpp +++ b/host/lib/usrp/dboard/db_sbx_version4.cpp @@ -18,22 +18,30 @@ using namespace boost::assign; /*********************************************************************** * Structors **********************************************************************/ -sbx_xcvr::sbx_version4::sbx_version4(sbx_xcvr *_self_sbx_xcvr) { - //register the handle to our base SBX class +sbx_xcvr::sbx_version4::sbx_version4(sbx_xcvr* _self_sbx_xcvr) +{ + // register the handle to our base SBX class self_base = _self_sbx_xcvr; - _txlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4351(std::bind(&sbx_xcvr::sbx_version4::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); } -sbx_xcvr::sbx_version4::~sbx_version4(void){ +sbx_xcvr::sbx_version4::~sbx_version4(void) +{ /* NOP */ } -void sbx_xcvr::sbx_version4::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) +void sbx_xcvr::sbx_version4::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) - { + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } @@ -42,42 +50,44 @@ void sbx_xcvr::sbx_version4::write_lo_regs(dboard_iface::unit_t unit, const std: /*********************************************************************** * Tuning **********************************************************************/ -double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - UHD_LOGGER_TRACE("SBX") << boost::format( - "SBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; +double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + UHD_LOGGER_TRACE("SBX") << boost::format("SBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); lo_iface->set_reference_freq(self_base->get_iface()->get_clock_rate(unit)); - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(target_freq > 3.6e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(target_freq > 3.6e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //Configure the LO + // Configure the LO double actual_freq = 0.0; actual_freq = lo_iface->set_frequency(sbx_freq_range.clip(target_freq), is_int_n); - if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { + if ((unit == dboard_iface::UNIT_TX) + and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_2DBM); } else { lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; } - diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index cd238ddc8..02fed018c 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -10,13 +10,13 @@ // RX IO Functions -//ADC/DAC functions: -//DAC 1: RF AGC -//DAC 2: IF AGC +// ADC/DAC functions: +// DAC 1: RF AGC +// DAC 2: IF AGC -//min freq: 50e6 -//max freq: 860e6 -//gain range: [0:1dB:115dB] +// min freq: 50e6 +// max freq: 860e6 +// gain range: [0:1dB:115dB] #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> @@ -51,79 +51,140 @@ static const freq_range_t tvrx_freq_range(50e6, 860e6); static const std::vector<std::string> tvrx_antennas = list_of("RX"); -static const uhd::dict<std::string, freq_range_t> tvrx_freq_ranges = map_list_of - ("VHFLO", freq_range_t(50e6, 158e6)) - ("VHFHI", freq_range_t(158e6, 454e6)) - ("UHF" , freq_range_t(454e6, 860e6)) -; - -static const boost::array<double, 17> vhflo_gains_db = - {{-6.00000, -6.00000, -6.00000, -4.00000, 0.00000, - 5.00000, 10.00000, 17.40000, 26.30000, 36.00000, - 43.00000, 48.00000, 49.50000, 50.10000, 50.30000, - 50.30000, 50.30000}}; - -static const boost::array<double, 17> vhfhi_gains_db = - {{-13.3000, -13.3000, -13.3000, -1.0000, 7.7000, - 11.0000, 14.7000, 19.3000, 26.1000, 36.0000, - 42.7000, 46.0000, 47.0000, 47.8000, 48.2000, - 48.2000, 48.2000}}; - -static const boost::array<double, 17> uhf_gains_db = - {{-8.0000, -8.0000, -7.0000, 4.0000, 10.2000, - 14.5000, 17.5000, 20.0000, 24.5000, 30.8000, - 37.0000, 39.8000, 40.7000, 41.6000, 42.6000, - 43.2000, 43.8000}}; - -static const boost::array<double, 17> tvrx_if_gains_db = - {{-1.50000, -1.50000, -1.50000, -1.00000, 0.20000, - 2.10000, 4.30000, 6.40000, 9.00000, 12.00000, - 14.80000, 18.20000, 26.10000, 32.50000, 32.50000, - 32.50000, 32.50000}}; - -//gain linearization data -//this is from the datasheet and is dB vs. volts (below) -//i tried to curve fit this, but it's really just so nonlinear that you'd -//need dang near as many coefficients as to just map it like this and interp. -//these numbers are culled from the 4937DI5 datasheet and are probably totally inaccurate -//but if it's better than the old linear fit i'm happy -static const uhd::dict<std::string, boost::array<double, 17> > tvrx_rf_gains_db = map_list_of - ("VHFLO", vhflo_gains_db) - ("VHFHI", vhfhi_gains_db) - ("UHF" , uhf_gains_db) -; - -//sample voltages for the above points -static const boost::array<double, 17> tvrx_gains_volts = - {{0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0}}; - -static uhd::dict<std::string, gain_range_t> get_tvrx_gain_ranges(void) { +static const uhd::dict<std::string, freq_range_t> tvrx_freq_ranges = + map_list_of("VHFLO", freq_range_t(50e6, 158e6))("VHFHI", freq_range_t(158e6, 454e6))( + "UHF", freq_range_t(454e6, 860e6)); + +static const boost::array<double, 17> vhflo_gains_db = {{-6.00000, + -6.00000, + -6.00000, + -4.00000, + 0.00000, + 5.00000, + 10.00000, + 17.40000, + 26.30000, + 36.00000, + 43.00000, + 48.00000, + 49.50000, + 50.10000, + 50.30000, + 50.30000, + 50.30000}}; + +static const boost::array<double, 17> vhfhi_gains_db = {{-13.3000, + -13.3000, + -13.3000, + -1.0000, + 7.7000, + 11.0000, + 14.7000, + 19.3000, + 26.1000, + 36.0000, + 42.7000, + 46.0000, + 47.0000, + 47.8000, + 48.2000, + 48.2000, + 48.2000}}; + +static const boost::array<double, 17> uhf_gains_db = {{-8.0000, + -8.0000, + -7.0000, + 4.0000, + 10.2000, + 14.5000, + 17.5000, + 20.0000, + 24.5000, + 30.8000, + 37.0000, + 39.8000, + 40.7000, + 41.6000, + 42.6000, + 43.2000, + 43.8000}}; + +static const boost::array<double, 17> tvrx_if_gains_db = {{-1.50000, + -1.50000, + -1.50000, + -1.00000, + 0.20000, + 2.10000, + 4.30000, + 6.40000, + 9.00000, + 12.00000, + 14.80000, + 18.20000, + 26.10000, + 32.50000, + 32.50000, + 32.50000, + 32.50000}}; + +// gain linearization data +// this is from the datasheet and is dB vs. volts (below) +// i tried to curve fit this, but it's really just so nonlinear that you'd +// need dang near as many coefficients as to just map it like this and interp. +// these numbers are culled from the 4937DI5 datasheet and are probably totally inaccurate +// but if it's better than the old linear fit i'm happy +static const uhd::dict<std::string, boost::array<double, 17>> tvrx_rf_gains_db = + map_list_of("VHFLO", vhflo_gains_db)("VHFHI", vhfhi_gains_db)("UHF", uhf_gains_db); + +// sample voltages for the above points +static const boost::array<double, 17> tvrx_gains_volts = {{0.8, + 1.0, + 1.2, + 1.4, + 1.6, + 1.8, + 2.0, + 2.2, + 2.4, + 2.6, + 2.8, + 3.0, + 3.2, + 3.4, + 3.6, + 3.8, + 4.0}}; + +static uhd::dict<std::string, gain_range_t> get_tvrx_gain_ranges(void) +{ double rfmax = 0.0, rfmin = FLT_MAX; - for(const std::string range: tvrx_rf_gains_db.keys()) { - double my_max = tvrx_rf_gains_db[range].back(); //we're assuming it's monotonic - double my_min = tvrx_rf_gains_db[range].front(); //if it's not this is wrong wrong wrong - if(my_max > rfmax) rfmax = my_max; - if(my_min < rfmin) rfmin = my_min; + for (const std::string range : tvrx_rf_gains_db.keys()) { + double my_max = tvrx_rf_gains_db[range].back(); // we're assuming it's monotonic + double my_min = + tvrx_rf_gains_db[range].front(); // if it's not this is wrong wrong wrong + if (my_max > rfmax) + rfmax = my_max; + if (my_min < rfmin) + rfmin = my_min; } double ifmin = tvrx_if_gains_db.front(); double ifmax = tvrx_if_gains_db.back(); - return map_list_of - ("RF", gain_range_t(rfmin, rfmax, (rfmax-rfmin)/4096.0)) - ("IF", gain_range_t(ifmin, ifmax, (ifmax-ifmin)/4096.0)) - ; + return map_list_of("RF", gain_range_t(rfmin, rfmax, (rfmax - rfmin) / 4096.0))( + "IF", gain_range_t(ifmin, ifmax, (ifmax - ifmin) / 4096.0)); } -static const double opamp_gain = 1.22; //onboard DAC opamp gain -static const double tvrx_if_freq = 43.75e6; //IF freq of TVRX module -static const uint16_t reference_divider = 640; //clock reference divider to use +static const double opamp_gain = 1.22; // onboard DAC opamp gain +static const double tvrx_if_freq = 43.75e6; // IF freq of TVRX module +static const uint16_t reference_divider = 640; // clock reference divider to use static const double reference_freq = 4.0e6; /*********************************************************************** * The tvrx dboard class **********************************************************************/ -class tvrx : public rx_dboard_base{ +class tvrx : public rx_dboard_base +{ public: tvrx(ctor_args_t args); virtual ~tvrx(void); @@ -132,116 +193,119 @@ private: uhd::dict<std::string, double> _gains; double _lo_freq; tuner_4937di5_regs_t _tuner_4937di5_regs; - uint8_t _tuner_4937di5_addr(void){ - return (this->get_iface()->get_special_props().mangle_i2c_addrs)? 0x61 : 0x60; //ok really? we could rename that call + uint8_t _tuner_4937di5_addr(void) + { + return (this->get_iface()->get_special_props().mangle_i2c_addrs) + ? 0x61 + : 0x60; // ok really? we could rename that call }; - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_freq(double freq); - void update_regs(void){ + void update_regs(void) + { byte_vector_t regs_vector(4); - //get the register data - for(int i=0; i<4; i++){ + // get the register data + for (int i = 0; i < 4; i++) { regs_vector[i] = _tuner_4937di5_regs.get_reg(i); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "tvrx: send reg 0x%02x, value 0x%04x" - ) % int(i) % int(regs_vector[i]) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("tvrx: send reg 0x%02x, value 0x%04x") % int(i) + % int(regs_vector[i]); } - //send the data - this->get_iface()->write_i2c( - _tuner_4937di5_addr(), regs_vector - ); + // send the data + this->get_iface()->write_i2c(_tuner_4937di5_addr(), regs_vector); } - }; /*********************************************************************** * Register the tvrx dboard **********************************************************************/ -static dboard_base::sptr make_tvrx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_tvrx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new tvrx(args)); } -UHD_STATIC_BLOCK(reg_tvrx_dboard){ - //register the factory function for the rx dbid +UHD_STATIC_BLOCK(reg_tvrx_dboard) +{ + // register the factory function for the rx dbid dboard_manager::register_dboard(0x0040, &make_tvrx, "TVRX"); } /*********************************************************************** * Structors **********************************************************************/ -tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){ +tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args) +{ //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("TVRX"); - this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists - for(const std::string &name: get_tvrx_gain_ranges().keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + this->get_rx_subtree()->create<std::string>("name").set("TVRX"); + this->get_rx_subtree()->create<int>("sensors"); // phony property so this dir exists + for (const std::string& name : get_tvrx_gain_ranges().keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&tvrx::set_gain, this, std::placeholders::_1, name)); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(get_tvrx_gain_ranges()[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&tvrx::set_freq, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(tvrx_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .set(tvrx_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(tvrx_freq_range); + this->get_rx_subtree()->create<std::string>("antenna/value").set(tvrx_antennas.at(0)); + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(tvrx_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("I"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set(6.0e6); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree()->create<std::string>("connection").set("I"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree()->create<double>("bandwidth/value").set(6.0e6); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(6.0e6, 6.0e6)); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr - if (this->get_iface()->get_special_props().soft_clock_divider){ + if (this->get_iface()->get_special_props().soft_clock_divider) { this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock - } - else{ + } else { this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs } - //send initial register settings if necessary + // send initial register settings if necessary - //set default freq - _lo_freq = tvrx_freq_range.start() + tvrx_if_freq; //init _lo_freq to a sane default + // set default freq + _lo_freq = tvrx_freq_range.start() + tvrx_if_freq; // init _lo_freq to a sane default this->get_rx_subtree()->access<double>("freq/value").set(tvrx_freq_range.start()); - //set default gains - for(const std::string &name: get_tvrx_gain_ranges().keys()){ - this->get_rx_subtree()->access<double>("gains/"+name+"/value") + // set default gains + for (const std::string& name : get_tvrx_gain_ranges().keys()) { + this->get_rx_subtree() + ->access<double>("gains/" + name + "/value") .set(get_tvrx_gain_ranges()[name].start()); } } -tvrx::~tvrx(void){ -} +tvrx::~tvrx(void) {} /*! Return a string corresponding to the relevant band * \param freq the frequency of interest * \return a string corresponding to the band */ -static std::string get_band(double freq) { - for(const std::string &band: tvrx_freq_ranges.keys()) { - if(freq >= tvrx_freq_ranges[band].start() && freq <= tvrx_freq_ranges[band].stop()){ - UHD_LOGGER_TRACE("TVRX") << "Band: " << band ; +static std::string get_band(double freq) +{ + for (const std::string& band : tvrx_freq_ranges.keys()) { + if (freq >= tvrx_freq_ranges[band].start() + && freq <= tvrx_freq_ranges[band].stop()) { + UHD_LOGGER_TRACE("TVRX") << "Band: " << band; return band; } } @@ -259,33 +323,39 @@ static std::string get_band(double freq) { * \return a voltage to feed the TVRX analog gain */ -static double gain_interp(double gain, const boost::array<double, 17>& db_vector, const boost::array<double, 17>& volts_vector) { +static double gain_interp(double gain, + const boost::array<double, 17>& db_vector, + const boost::array<double, 17>& volts_vector) +{ double volts; - gain = uhd::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here + gain = uhd::clip<double>( + gain, db_vector.front(), db_vector.back()); // let's not get carried away here uint8_t gain_step = 0; - //find which bin we're in - for(size_t i = 0; i < db_vector.size()-1; i++) { - if (gain >= db_vector[i] && gain <= db_vector[i+1]) { + // find which bin we're in + for (size_t i = 0; i < db_vector.size() - 1; i++) { + if (gain >= db_vector[i] && gain <= db_vector[i + 1]) { gain_step = uhd::narrow_cast<uint8_t>(i); } } - //find the current slope for linear interpolation + // find the current slope for linear interpolation double slope = (volts_vector[gain_step + 1] - volts_vector[gain_step]) - / (db_vector[gain_step + 1] - db_vector[gain_step]); + / (db_vector[gain_step + 1] - db_vector[gain_step]); - //the problem here is that for gains approaching the maximum, the voltage slope becomes infinite - //i.e., a small change in gain requires an infinite change in voltage - //to cope, we limit the slope + // the problem here is that for gains approaching the maximum, the voltage slope + // becomes infinite i.e., a small change in gain requires an infinite change in + // voltage to cope, we limit the slope - if(slope == std::numeric_limits<double>::infinity()) + if (slope == std::numeric_limits<double>::infinity()) return volts_vector[gain_step]; - //use the volts per dB slope to find the final interpolated voltage + // use the volts per dB slope to find the final interpolated voltage volts = volts_vector[gain_step] + (slope * (gain - db_vector[gain_step])); - UHD_LOGGER_TRACE("TVRX") << "Gain interp: gain: " << gain << ", gain_step: " << int(gain_step) << ", slope: " << slope << ", volts: " << volts ; + UHD_LOGGER_TRACE("TVRX") << "Gain interp: gain: " << gain + << ", gain_step: " << int(gain_step) << ", slope: " << slope + << ", volts: " << volts; return volts; } @@ -297,23 +367,24 @@ static double gain_interp(double gain, const boost::array<double, 17>& db_vector * \return dac voltage value */ -static double rf_gain_to_voltage(double gain, double lo_freq){ - //clip the input +static double rf_gain_to_voltage(double gain, double lo_freq) +{ + // clip the input gain = get_tvrx_gain_ranges()["RF"].clip(gain); - //first we need to find out what band we're in, because gains are different across different bands + // first we need to find out what band we're in, because gains are different across + // different bands std::string band = get_band(lo_freq - tvrx_if_freq); - //this is the voltage at the TVRX gain input + // this is the voltage at the TVRX gain input double gain_volts = gain_interp(gain, tvrx_rf_gains_db[band], tvrx_gains_volts); - //this is the voltage at the USRP DAC output + // this is the voltage at the USRP DAC output double dac_volts = gain_volts / opamp_gain; dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "tvrx RF AGC gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("TVRX") << boost::format("tvrx RF AGC gain: %f dB, dac_volts: %f V") + % gain % dac_volts; return dac_volts; } @@ -325,31 +396,34 @@ static double rf_gain_to_voltage(double gain, double lo_freq){ * \return dac voltage value */ -static double if_gain_to_voltage(double gain){ - //clip the input +static double if_gain_to_voltage(double gain) +{ + // clip the input gain = get_tvrx_gain_ranges()["IF"].clip(gain); double gain_volts = gain_interp(gain, tvrx_if_gains_db, tvrx_gains_volts); - double dac_volts = gain_volts / opamp_gain; + double dac_volts = gain_volts / opamp_gain; dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "tvrx IF AGC gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("TVRX") << boost::format("tvrx IF AGC gain: %f dB, dac_volts: %f V") + % gain % dac_volts; return dac_volts; } -double tvrx::set_gain(double gain, const std::string &name){ +double tvrx::set_gain(double gain, const std::string& name) +{ assert_has(get_tvrx_gain_ranges().keys(), name, "tvrx gain name"); - if (name == "RF"){ - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_B, rf_gain_to_voltage(gain, _lo_freq)); - } - else if(name == "IF"){ - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, if_gain_to_voltage(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + if (name == "RF") { + this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, + dboard_iface::AUX_DAC_B, + rf_gain_to_voltage(gain, _lo_freq)); + } else if (name == "IF") { + this->get_iface()->write_aux_dac( + dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, if_gain_to_voltage(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); _gains[name] = gain; return gain; @@ -360,44 +434,55 @@ double tvrx::set_gain(double gain, const std::string &name){ * \param freq the requested frequency */ -double tvrx::set_freq(double freq) { - freq = tvrx_freq_range.clip(freq); +double tvrx::set_freq(double freq) +{ + freq = tvrx_freq_range.clip(freq); std::string prev_band = get_band(_lo_freq - tvrx_if_freq); - std::string new_band = get_band(freq); + std::string new_band = get_band(freq); - double target_lo_freq = freq + tvrx_if_freq; //the desired LO freq for high-side mixing - double f_ref = reference_freq / double(reference_divider); //your tuning step size + double target_lo_freq = + freq + tvrx_if_freq; // the desired LO freq for high-side mixing + double f_ref = reference_freq / double(reference_divider); // your tuning step size - int divisor = int((target_lo_freq + (f_ref * 4.0)) / (f_ref * 8)); //the divisor we'll use - double actual_lo_freq = (f_ref * 8 * divisor); //the LO freq we'll actually get + int divisor = + int((target_lo_freq + (f_ref * 4.0)) / (f_ref * 8)); // the divisor we'll use + double actual_lo_freq = (f_ref * 8 * divisor); // the LO freq we'll actually get - if((divisor & ~0x7fff)) UHD_THROW_INVALID_CODE_PATH(); + if ((divisor & ~0x7fff)) + UHD_THROW_INVALID_CODE_PATH(); - //now we update the registers + // now we update the registers _tuner_4937di5_regs.db1 = (divisor >> 8) & 0xff; _tuner_4937di5_regs.db2 = divisor & 0xff; - if(new_band == "VHFLO") _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFLO; - else if(new_band == "VHFHI") _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFHI; - else if(new_band == "UHF") _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_UHF; - else UHD_THROW_INVALID_CODE_PATH(); + if (new_band == "VHFLO") + _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFLO; + else if (new_band == "VHFHI") + _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_VHFHI; + else if (new_band == "UHF") + _tuner_4937di5_regs.bandsel = tuner_4937di5_regs_t::BANDSEL_UHF; + else + UHD_THROW_INVALID_CODE_PATH(); _tuner_4937di5_regs.power = tuner_4937di5_regs_t::POWER_OFF; update_regs(); - //ok don't forget to reset RF gain here if the new band != the old band - //we do this because the gains are different for different band settings - //not FAR off, but we do this to be consistent - if(prev_band != new_band) set_gain(_gains["RF"], "RF"); + // ok don't forget to reset RF gain here if the new band != the old band + // we do this because the gains are different for different band settings + // not FAR off, but we do this to be consistent + if (prev_band != new_band) + set_gain(_gains["RF"], "RF"); - UHD_LOGGER_TRACE("TVRX") << boost::format("set_freq: target LO: %f f_ref: %f divisor: %i actual LO: %f") % target_lo_freq % f_ref % divisor % actual_lo_freq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("set_freq: target LO: %f f_ref: %f divisor: %i actual LO: %f") + % target_lo_freq % f_ref % divisor % actual_lo_freq; - _lo_freq = actual_lo_freq; //for rx props + _lo_freq = actual_lo_freq; // for rx props - //Check the the IF if larger than the dsp rate and apply a corrective adjustment - //so that the cordic will be tuned to a possible rate within its range. + // Check the the IF if larger than the dsp rate and apply a corrective adjustment + // so that the cordic will be tuned to a possible rate within its range. const double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX); - if (tvrx_if_freq >= codec_rate/2){ + if (tvrx_if_freq >= codec_rate / 2) { return _lo_freq - codec_rate; } diff --git a/host/lib/usrp/dboard/db_tvrx2.cpp b/host/lib/usrp/dboard/db_tvrx2.cpp index 5767243d9..0f1673633 100644 --- a/host/lib/usrp/dboard/db_tvrx2.cpp +++ b/host/lib/usrp/dboard/db_tvrx2.cpp @@ -70,34 +70,50 @@ using namespace boost::assign; /*********************************************************************** * The TVRX2 types **********************************************************************/ -struct tvrx2_tda18272_rfcal_result_t { - int8_t delta_c; - int8_t c_offset; - tvrx2_tda18272_rfcal_result_t(void): delta_c(0), c_offset(0){} +struct tvrx2_tda18272_rfcal_result_t +{ + int8_t delta_c; + int8_t c_offset; + tvrx2_tda18272_rfcal_result_t(void) : delta_c(0), c_offset(0) {} }; -struct tvrx2_tda18272_rfcal_coeffs_t { - uint8_t cal_number; - int32_t RF_A1; - int32_t RF_B1; - tvrx2_tda18272_rfcal_coeffs_t(void): cal_number(0), RF_A1(0), RF_B1(0) {} - tvrx2_tda18272_rfcal_coeffs_t(uint32_t num): RF_A1(0), RF_B1(0) { cal_number = num; } +struct tvrx2_tda18272_rfcal_coeffs_t +{ + uint8_t cal_number; + int32_t RF_A1; + int32_t RF_B1; + tvrx2_tda18272_rfcal_coeffs_t(void) : cal_number(0), RF_A1(0), RF_B1(0) {} + tvrx2_tda18272_rfcal_coeffs_t(uint32_t num) : RF_A1(0), RF_B1(0) + { + cal_number = num; + } }; -struct tvrx2_tda18272_cal_map_t { - boost::array<uint32_t, 4> cal_freq; - boost::array<uint8_t, 4> c_offset; - tvrx2_tda18272_cal_map_t(boost::array<uint32_t, 4> freqs, boost::array<uint8_t, 4> offsets) - { cal_freq = freqs; c_offset = offsets; } +struct tvrx2_tda18272_cal_map_t +{ + boost::array<uint32_t, 4> cal_freq; + boost::array<uint8_t, 4> c_offset; + tvrx2_tda18272_cal_map_t( + boost::array<uint32_t, 4> freqs, boost::array<uint8_t, 4> offsets) + { + cal_freq = freqs; + c_offset = offsets; + } }; -struct tvrx2_tda18272_freq_map_t { - uint32_t rf_max; - uint8_t c_prog; - uint8_t gain_taper; - uint8_t rf_band; - tvrx2_tda18272_freq_map_t( uint32_t max, uint8_t c, uint8_t taper, uint8_t band) - { rf_max = max; c_prog = c; gain_taper = taper; rf_band = band; } +struct tvrx2_tda18272_freq_map_t +{ + uint32_t rf_max; + uint8_t c_prog; + uint8_t gain_taper; + uint8_t rf_band; + tvrx2_tda18272_freq_map_t(uint32_t max, uint8_t c, uint8_t taper, uint8_t band) + { + rf_max = max; + c_prog = c; + gain_taper = taper; + rf_band = band; + } }; /*********************************************************************** @@ -743,7 +759,8 @@ static const uhd::dict<std::string, gain_range_t> tvrx2_gain_ranges = map_list_o /*********************************************************************** * The TVRX2 dboard class **********************************************************************/ -class tvrx2 : public rx_dboard_base{ +class tvrx2 : public rx_dboard_base +{ public: tvrx2(ctor_args_t args); virtual ~tvrx2(void); @@ -763,7 +780,7 @@ private: bool set_enabled(bool); double set_lo_freq(double target_freq); - double set_gain(double gain, const std::string &name); + double set_gain(double gain, const std::string& name); double set_bandwidth(double bandwidth); void set_scaled_rf_freq(double rf_freq); @@ -785,22 +802,22 @@ private: void wait_irq(void); void test_rf_filter_robustness(void); -/*********************************************************************** - * The TVRX2 class helper functions - **********************************************************************/ + /*********************************************************************** + * The TVRX2 class helper functions + **********************************************************************/ /*! * Is the IRQ set or cleared? * \return true for set */ - bool get_irq(void){ + bool get_irq(void) + { read_reg(0x8, 0x8); - //return irq status + // return irq status bool irq = _tda18272hnm_regs.irq_status == tda18272hnm_regs_t::IRQ_STATUS_SET; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): IRQ %d" - ) % (get_subdev_name()) % irq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): IRQ %d") % (get_subdev_name()) % irq; return irq; } @@ -810,15 +827,16 @@ private: * Check POR logic for reset state (causes POR to clear) * \return true for reset */ - bool get_power_reset(void){ + bool get_power_reset(void) + { read_reg(0x5, 0x5); - //return POR state + // return POR state bool por = _tda18272hnm_regs.por == tda18272hnm_regs_t::POR_RESET; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): POR %d" - ) % (get_subdev_name()) % int(_tda18272hnm_regs.por) ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): POR %d") + % (get_subdev_name()) + % int(_tda18272hnm_regs.por); return por; } @@ -827,15 +845,15 @@ private: * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ + sensor_value_t get_locked(void) + { read_reg(0x5, 0x5); - //return lock detect + // return lock detect bool locked = _tda18272hnm_regs.lo_lock == tda18272hnm_regs_t::LO_LOCK_LOCKED; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): locked %d" - ) % (get_subdev_name()) % locked ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): locked %d") % (get_subdev_name()) % locked; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -845,21 +863,26 @@ private: * Read the RSSI from the aux adc * \return the rssi sensor in dB(m?) FIXME */ - sensor_value_t get_rssi(void){ - //Launch RSSI calculation with MSM statemachine - _tda18272hnm_regs.set_reg(0x19, 0x80); //set MSM_byte_1 for rssi calculation - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching rssi calculation + sensor_value_t get_rssi(void) + { + // Launch RSSI calculation with MSM statemachine + _tda18272hnm_regs.set_reg(0x19, 0x80); // set MSM_byte_1 for rssi calculation + _tda18272hnm_regs.set_reg( + 0x1A, 0x01); // set MSM_byte_2 for launching rssi calculation send_reg(0x19, 0x1A); wait_irq(); - //read rssi in dBuV + // read rssi in dBuV read_reg(0x7, 0x7); - //calculate the rssi from the voltage - double rssi_dBuV = 40.0 + double(((110.0 - 40.0)/128.0) * _tda18272hnm_regs.get_reg(0x7)); - double rssi = rssi_dBuV - 107.0; //convert to dBm in 50ohm environment ( -108.8 if 75ohm ) FIXME + // calculate the rssi from the voltage + double rssi_dBuV = + 40.0 + double(((110.0 - 40.0) / 128.0) * _tda18272hnm_regs.get_reg(0x7)); + double rssi = + rssi_dBuV + - 107.0; // convert to dBm in 50ohm environment ( -108.8 if 75ohm ) FIXME return sensor_value_t("RSSI", rssi, "dBm"); } @@ -868,19 +891,20 @@ private: * Read the Temperature from the registers * \return the temp in degC */ - sensor_value_t get_temp(void){ - //Enable Temperature reading + sensor_value_t get_temp(void) + { + // Enable Temperature reading _tda18272hnm_regs.tm_on = tda18272hnm_regs_t::TM_ON_SENSOR_ON; send_reg(0x4, 0x4); - //read temp in degC + // read temp in degC read_reg(0x3, 0x3); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Temperature %f C" - ) % (get_subdev_name()) % (double(_tda18272hnm_regs.tm_d)) ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): Temperature %f C") + % (get_subdev_name()) + % (double(_tda18272hnm_regs.tm_d)); - //Disable Temperature reading + // Disable Temperature reading _tda18272hnm_regs.tm_on = tda18272hnm_regs_t::TM_ON_SENSOR_OFF; send_reg(0x4, 0x4); @@ -891,194 +915,205 @@ private: /*********************************************************************** * Register the TVRX2 dboard **********************************************************************/ -static dboard_base::sptr make_tvrx2(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_tvrx2(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new tvrx2(args)); } -UHD_STATIC_BLOCK(reg_tvrx2_dboard){ - //register the factory function for the rx dbid - dboard_manager::register_dboard(0x0046, &make_tvrx2, "TVRX2", tvrx2_sd_name_to_conn.keys()); +UHD_STATIC_BLOCK(reg_tvrx2_dboard) +{ + // register the factory function for the rx dbid + dboard_manager::register_dboard( + 0x0046, &make_tvrx2, "TVRX2", tvrx2_sd_name_to_conn.keys()); } /*********************************************************************** * Structors **********************************************************************/ -tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args){ - //FIXME for USRP1, we can only support one TVRX2 installed - - _rfcal_results = map_list_of - ( 0, tvrx2_tda18272_rfcal_result_t() ) - ( 1, tvrx2_tda18272_rfcal_result_t() ) - ( 2, tvrx2_tda18272_rfcal_result_t() ) - ( 3, tvrx2_tda18272_rfcal_result_t() ) - ( 4, tvrx2_tda18272_rfcal_result_t() ) - ( 5, tvrx2_tda18272_rfcal_result_t() ) - ( 6, tvrx2_tda18272_rfcal_result_t() ) - ( 7, tvrx2_tda18272_rfcal_result_t() ) - ( 8, tvrx2_tda18272_rfcal_result_t() ) - ( 9, tvrx2_tda18272_rfcal_result_t() ) - ( 10, tvrx2_tda18272_rfcal_result_t() ) - ( 11, tvrx2_tda18272_rfcal_result_t() ) - ; - - _rfcal_coeffs = map_list_of - ( 0, tvrx2_tda18272_rfcal_coeffs_t(0) ) - ( 1, tvrx2_tda18272_rfcal_coeffs_t(1) ) - ( 2, tvrx2_tda18272_rfcal_coeffs_t(3) ) - ( 3, tvrx2_tda18272_rfcal_coeffs_t(4) ) - ( 4, tvrx2_tda18272_rfcal_coeffs_t(6) ) - ( 5, tvrx2_tda18272_rfcal_coeffs_t(7) ) - ( 6, tvrx2_tda18272_rfcal_coeffs_t(9) ) - ( 7, tvrx2_tda18272_rfcal_coeffs_t(10) ) - ; - - //set defaults for LO, gains, and filter bandwidth +tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args) +{ + // FIXME for USRP1, we can only support one TVRX2 installed + + _rfcal_results = map_list_of(0, tvrx2_tda18272_rfcal_result_t())( + 1, tvrx2_tda18272_rfcal_result_t())(2, tvrx2_tda18272_rfcal_result_t())( + 3, tvrx2_tda18272_rfcal_result_t())(4, tvrx2_tda18272_rfcal_result_t())( + 5, tvrx2_tda18272_rfcal_result_t())(6, tvrx2_tda18272_rfcal_result_t())( + 7, tvrx2_tda18272_rfcal_result_t())(8, tvrx2_tda18272_rfcal_result_t())( + 9, tvrx2_tda18272_rfcal_result_t())(10, tvrx2_tda18272_rfcal_result_t())( + 11, tvrx2_tda18272_rfcal_result_t()); + + _rfcal_coeffs = map_list_of(0, tvrx2_tda18272_rfcal_coeffs_t(0))( + 1, tvrx2_tda18272_rfcal_coeffs_t(1))(2, tvrx2_tda18272_rfcal_coeffs_t(3))( + 3, tvrx2_tda18272_rfcal_coeffs_t(4))(4, tvrx2_tda18272_rfcal_coeffs_t(6))( + 5, tvrx2_tda18272_rfcal_coeffs_t(7))(6, tvrx2_tda18272_rfcal_coeffs_t(9))( + 7, tvrx2_tda18272_rfcal_coeffs_t(10)); + + // set defaults for LO, gains, and filter bandwidth _bandwidth = 10e6; _if_freq = 12.5e6; _enabled = false; - //send initial register settings - //this->read_reg(0x0, 0x43); - //this->send_reg(0x0, 0x43); + // send initial register settings + // this->read_reg(0x0, 0x43); + // this->send_reg(0x0, 0x43); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("TVRX2"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("TVRX2"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&tvrx2::get_locked, this)); - this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/rssi") .set_publisher(std::bind(&tvrx2::get_rssi, this)); - this->get_rx_subtree()->create<sensor_value_t>("sensors/temperature") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/temperature") .set_publisher(std::bind(&tvrx2::get_temp, this)); - for(const std::string &name: tvrx2_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") + for (const std::string& name : tvrx2_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") .set_coercer(std::bind(&tvrx2::set_gain, this, std::placeholders::_1, name)); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(tvrx2_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&tvrx2::set_lo_freq, this, std::placeholders::_1)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(tvrx2_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(tvrx2_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") .set(tvrx2_sd_name_to_antennas[get_subdev_name()]); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(list_of(tvrx2_sd_name_to_antennas[get_subdev_name()])); - this->get_rx_subtree()->create<std::string>("connection") + this->get_rx_subtree() + ->create<std::string>("connection") .set(tvrx2_sd_name_to_conn[get_subdev_name()]); - this->get_rx_subtree()->create<bool>("enabled") + this->get_rx_subtree() + ->create<bool>("enabled") .set_coercer(std::bind(&tvrx2::set_enabled, this, std::placeholders::_1)) .set(_enabled); - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") .set_coercer(std::bind(&tvrx2::set_bandwidth, this, std::placeholders::_1)) .set(_bandwidth); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(tvrx2_bandwidth_range); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0); // All unused in atr this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, OUTPUT_MASK); // Set outputs - //configure ref_clock + // configure ref_clock double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); if (ref_clock == 64.0e6) { this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV4); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Dividing Refclock by 4" - ) % (get_subdev_name()) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): Dividing Refclock by 4") % (get_subdev_name()); - _freq_scalar = (4*16.0e6)/(this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)); + _freq_scalar = + (4 * 16.0e6) / (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)); } else if (ref_clock == 100e6) { - this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Dividing Refclock by 6" - ) % (get_subdev_name()) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): Dividing Refclock by 6") % (get_subdev_name()); - _freq_scalar = (6*16.0e6)/this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); - } else if (ref_clock == 200e6) { - UHD_LOGGER_WARNING("TVRX") << boost::format("ref_clock was 200e6, setting ref_clock divider for 100e6.") ; + _freq_scalar = + (6 * 16.0e6) / this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); + } else if (ref_clock == 200e6) { + UHD_LOGGER_WARNING("TVRX") + << boost::format("ref_clock was 200e6, setting ref_clock divider for 100e6."); this->get_iface()->set_clock_rate(dboard_iface::UNIT_RX, 100e6); this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Dividing Refclock by 6" - ) % (get_subdev_name()) ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s): Dividing Refclock by 6") % (get_subdev_name()); - _freq_scalar = (6*16.0e6)/this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); + _freq_scalar = + (6 * 16.0e6) / this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX); } else { this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6); - UHD_LOGGER_WARNING("TVRX") << boost::format("Unsupported ref_clock %0.2f, valid options 64e6, 100e6, 200e6") % ref_clock ; + UHD_LOGGER_WARNING("TVRX") + << boost::format( + "Unsupported ref_clock %0.2f, valid options 64e6, 100e6, 200e6") + % ref_clock; _freq_scalar = 1.0; } - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Refclock %f Hz, scalar = %f" - ) % (get_subdev_name()) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % _freq_scalar ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): Refclock %f Hz, scalar = %f") + % (get_subdev_name()) + % (this->get_iface()->get_clock_rate( + dboard_iface::UNIT_RX)) + % _freq_scalar; _tda18272hnm_regs.irq_polarity = tda18272hnm_regs_t::IRQ_POLARITY_RAISED_VCC; - _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE; + _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE; send_reg(0x37, 0x37); send_reg(0xA, 0xA); - send_reg(0x31, 0x31); //N_CP_Current - send_reg(0x36, 0x36); //RSSI_Clock - send_reg(0x24, 0x25); //AGC1_Do_step - send_reg(0x2C, 0x2C); //AGC1_Do_step - send_reg(0x2E, 0x2E); //AGC2_Do_step - send_reg(0x0E, 0x0E); //AGCs_Up_step_assym - send_reg(0x11, 0x11); //AGCs_Do_step_assym - - //intialize i2c - //soft_calibration(); - //tvrx2_tda18272_init_rfcal(); + send_reg(0x31, 0x31); // N_CP_Current + send_reg(0x36, 0x36); // RSSI_Clock + send_reg(0x24, 0x25); // AGC1_Do_step + send_reg(0x2C, 0x2C); // AGC1_Do_step + send_reg(0x2E, 0x2E); // AGC2_Do_step + send_reg(0x0E, 0x0E); // AGCs_Up_step_assym + send_reg(0x11, 0x11); // AGCs_Do_step_assym + + // intialize i2c + // soft_calibration(); + // tvrx2_tda18272_init_rfcal(); transition_0(); } -bool tvrx2::set_enabled(bool enable){ - if (enable == _enabled) return _enabled; +bool tvrx2::set_enabled(bool enable) +{ + if (enable == _enabled) + return _enabled; - if (enable and not _enabled){ - //setup tuner parameters + if (enable and not _enabled) { + // setup tuner parameters transition_1(); transition_2(int(tvrx2_freq_range.start())); test_rf_filter_robustness(); - for(const std::string &name: tvrx2_gain_ranges.keys()){ - this->get_rx_subtree()->access<double>("gains/"+name+"/value") + for (const std::string& name : tvrx2_gain_ranges.keys()) { + this->get_rx_subtree() + ->access<double>("gains/" + name + "/value") .set(tvrx2_gain_ranges[name].start()); } - this->get_rx_subtree()->access<double>("bandwidth/value") + this->get_rx_subtree() + ->access<double>("bandwidth/value") .set(_bandwidth); // default bandwidth from datasheet - //transition_2 equivalent - this->get_rx_subtree()->access<double>("freq/value") + // transition_2 equivalent + this->get_rx_subtree() + ->access<double>("freq/value") .set(tvrx2_freq_range.start()); - //enter standby mode + // enter standby mode transition_3(); _enabled = true; } else { - //enter standby mode + // enter standby mode transition_3(); _enabled = false; } @@ -1086,10 +1121,10 @@ bool tvrx2::set_enabled(bool enable){ return _enabled; } -tvrx2::~tvrx2(void){ - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s): Called Destructor" - ) % (get_subdev_name()) ; +tvrx2::~tvrx2(void) +{ + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 (%s): Called Destructor") + % (get_subdev_name()); UHD_SAFE_CALL(if (_enabled) set_enabled(false);) } @@ -1097,84 +1132,101 @@ tvrx2::~tvrx2(void){ /*********************************************************************** * TDA18272 Register IO Functions **********************************************************************/ -void tvrx2::set_scaled_rf_freq(double rf_freq){ - _tda18272hnm_regs.set_rf_freq(uint32_t(_freq_scalar*rf_freq/1e3)); +void tvrx2::set_scaled_rf_freq(double rf_freq) +{ + _tda18272hnm_regs.set_rf_freq(uint32_t(_freq_scalar * rf_freq / 1e3)); } -double tvrx2::get_scaled_rf_freq(void){ - return _tda18272hnm_regs.get_rf_freq()*1e3/_freq_scalar; +double tvrx2::get_scaled_rf_freq(void) +{ + return _tda18272hnm_regs.get_rf_freq() * 1e3 / _freq_scalar; } -void tvrx2::set_scaled_if_freq(double if_freq){ - _tda18272hnm_regs.if_freq = int(_freq_scalar*if_freq/(50e3)); //max 12.8MHz?? +void tvrx2::set_scaled_if_freq(double if_freq) +{ + _tda18272hnm_regs.if_freq = int(_freq_scalar * if_freq / (50e3)); // max 12.8MHz?? } -double tvrx2::get_scaled_if_freq(void){ - return _tda18272hnm_regs.if_freq*50e3/_freq_scalar; +double tvrx2::get_scaled_if_freq(void) +{ + return _tda18272hnm_regs.if_freq * 50e3 / _freq_scalar; } -void tvrx2::send_reg(uint8_t start_reg, uint8_t stop_reg){ +void tvrx2::send_reg(uint8_t start_reg, uint8_t stop_reg) +{ start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x43)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t) - 1){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 ? sizeof(uint32_t) - 1 : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t) - 1) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) - 1 + ? sizeof(uint32_t) - 1 + : stop_reg - start_addr + 1; - //create buffer for register data (+1 for start address) + // create buffer for register data (+1 for start address) byte_vector_t regs_vector(num_bytes + 1); - //first byte is the address of first register + // first byte is the address of first register regs_vector[0] = start_addr; - //get the register data - for(int i=0; i<num_bytes; i++){ - regs_vector[1+i] = _tda18272hnm_regs.get_reg(start_addr+i); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s, 0x%02x): send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % (get_subdev_name()) % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes ; + // get the register data + for (int i = 0; i < num_bytes; i++) { + regs_vector[1 + i] = _tda18272hnm_regs.get_reg(start_addr + i); + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s, 0x%02x): send reg 0x%02x, value 0x%04x, " + "start_addr = 0x%04x, num_bytes %d") + % (get_subdev_name()) + % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) + % int(start_addr + i) % int(regs_vector[1 + i]) % int(start_addr) + % num_bytes; } - //send the data + // send the data this->get_iface()->write_i2c( - tvrx2_sd_name_to_i2c_addr[get_subdev_name()], regs_vector - ); + tvrx2_sd_name_to_i2c_addr[get_subdev_name()], regs_vector); } } -void tvrx2::read_reg(uint8_t start_reg, uint8_t stop_reg){ +void tvrx2::read_reg(uint8_t start_reg, uint8_t stop_reg) +{ static const uint8_t status_addr = 0x0; - start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x43)); - stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); + start_reg = uint8_t(uhd::clip(int(start_reg), 0x0, 0x43)); + stop_reg = uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43)); - for(uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(uint32_t)){ - int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) ? sizeof(uint32_t) : stop_reg - start_addr + 1; + for (uint8_t start_addr = start_reg; start_addr <= stop_reg; + start_addr += sizeof(uint32_t)) { + int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(uint32_t)) + ? sizeof(uint32_t) + : stop_reg - start_addr + 1; - //create buffer for starting address + // create buffer for starting address byte_vector_t start_address_vector(1); - //first byte is the address of first register + // first byte is the address of first register start_address_vector[0] = start_addr; - //send the start address + // send the start address this->get_iface()->write_i2c( - tvrx2_sd_name_to_i2c_addr[get_subdev_name()], start_address_vector - ); + tvrx2_sd_name_to_i2c_addr[get_subdev_name()], start_address_vector); - //create buffer for register data + // create buffer for register data byte_vector_t regs_vector(num_bytes); - //read from i2c + // read from i2c regs_vector = this->get_iface()->read_i2c( - tvrx2_sd_name_to_i2c_addr[get_subdev_name()], num_bytes - ); + tvrx2_sd_name_to_i2c_addr[get_subdev_name()], num_bytes); - for(uint8_t i=0; i < num_bytes; i++){ - if (i + start_addr >= status_addr){ + for (uint8_t i = 0; i < num_bytes; i++) { + if (i + start_addr >= status_addr) { _tda18272hnm_regs.set_reg(i + start_addr, regs_vector[i]); } - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s, 0x%02x): read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" - ) % (get_subdev_name()) % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes ; + UHD_LOGGER_TRACE("TVRX") + << boost::format("TVRX2 (%s, 0x%02x): read reg 0x%02x, value 0x%04x, " + "start_addr = 0x%04x, num_bytes %d") + % (get_subdev_name()) + % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) + % int(start_addr + i) % int(regs_vector[i]) % int(start_addr) + % num_bytes; } } } @@ -1185,56 +1237,65 @@ void tvrx2::read_reg(uint8_t start_reg, uint8_t stop_reg){ **********************************************************************/ freq_range_t tvrx2::get_tda18272_rfcal_result_freq_range(uint32_t result) { - - uhd::dict<uint32_t, freq_range_t> result_to_cal_freq_ranges_map = map_list_of - ( 0, freq_range_t( - (double) tvrx2_tda18272_cal_map[0].cal_freq[_tda18272hnm_regs.rfcal_freq0] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] * _freq_scalar - ) ) - ( 1, freq_range_t( - (double) tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] * _freq_scalar - ) ) - ( 2, freq_range_t( - (double) tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] * _freq_scalar - ) ) - ( 3, freq_range_t( - (double) tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] * _freq_scalar - ) ) - ( 4, freq_range_t( - (double) tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] * _freq_scalar - ) ) - ( 5, freq_range_t( - (double) tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] * _freq_scalar - ) ) - ( 6, freq_range_t( - (double) tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] * _freq_scalar - ) ) - ( 7, freq_range_t( - (double) tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] * _freq_scalar - ) ) - ( 8, freq_range_t( - (double) tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] * _freq_scalar - ) ) - ( 9, freq_range_t( - (double) tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] * _freq_scalar - ) ) - (10, freq_range_t( - (double) tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] * _freq_scalar, - (double) tvrx2_tda18272_cal_map[11].cal_freq[_tda18272hnm_regs.rfcal_freq11] * _freq_scalar - ) ) - ; + uhd::dict<uint32_t, freq_range_t> result_to_cal_freq_ranges_map = map_list_of(0, + freq_range_t( + (double)tvrx2_tda18272_cal_map[0].cal_freq[_tda18272hnm_regs.rfcal_freq0] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] + * _freq_scalar))(1, + freq_range_t( + (double)tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] + * _freq_scalar))(2, + freq_range_t( + (double)tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] + * _freq_scalar))(3, + freq_range_t( + (double)tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] + * _freq_scalar))(4, + freq_range_t( + (double)tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] + * _freq_scalar))(5, + freq_range_t( + (double)tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] + * _freq_scalar))(6, + freq_range_t( + (double)tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] + * _freq_scalar))(7, + freq_range_t( + (double)tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] + * _freq_scalar))(8, + freq_range_t( + (double)tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] + * _freq_scalar))(9, + freq_range_t( + (double)tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] + * _freq_scalar))(10, + freq_range_t( + (double)tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] + * _freq_scalar, + (double)tvrx2_tda18272_cal_map[11].cal_freq[_tda18272hnm_regs.rfcal_freq11] + * _freq_scalar)); if (result < 11) - return result_to_cal_freq_ranges_map[result]; + return result_to_cal_freq_ranges_map[result]; else return freq_range_t(0.0, 0.0); } @@ -1245,53 +1306,52 @@ freq_range_t tvrx2::get_tda18272_rfcal_result_freq_range(uint32_t result) */ void tvrx2::tvrx2_tda18272_init_rfcal(void) { - /* read byte 0x38-0x43 */ read_reg(0x38, 0x43); - uhd::dict<uint32_t, uint8_t> result_to_cal_regs = map_list_of - ( 0, _tda18272hnm_regs.rfcal_log_1) - ( 1, _tda18272hnm_regs.rfcal_log_2) - ( 2, _tda18272hnm_regs.rfcal_log_3) - ( 3, _tda18272hnm_regs.rfcal_log_4) - ( 4, _tda18272hnm_regs.rfcal_log_5) - ( 5, _tda18272hnm_regs.rfcal_log_6) - ( 6, _tda18272hnm_regs.rfcal_log_7) - ( 7, _tda18272hnm_regs.rfcal_log_8) - ( 8, _tda18272hnm_regs.rfcal_log_9) - ( 9, _tda18272hnm_regs.rfcal_log_10) - (10, _tda18272hnm_regs.rfcal_log_11) - (11, _tda18272hnm_regs.rfcal_log_12) - ; + uhd::dict<uint32_t, uint8_t> result_to_cal_regs = + map_list_of(0, _tda18272hnm_regs.rfcal_log_1)(1, _tda18272hnm_regs.rfcal_log_2)( + 2, _tda18272hnm_regs.rfcal_log_3)(3, _tda18272hnm_regs.rfcal_log_4)( + 4, _tda18272hnm_regs.rfcal_log_5)(5, _tda18272hnm_regs.rfcal_log_6)( + 6, _tda18272hnm_regs.rfcal_log_7)(7, _tda18272hnm_regs.rfcal_log_8)( + 8, _tda18272hnm_regs.rfcal_log_9)(9, _tda18272hnm_regs.rfcal_log_10)( + 10, _tda18272hnm_regs.rfcal_log_11)(11, _tda18272hnm_regs.rfcal_log_12); // Loop through rfcal_log_* registers, initialize _rfcal_results - for(const uint32_t &result: result_to_cal_regs.keys()) - _rfcal_results[result].delta_c = result_to_cal_regs[result] > 63 ? result_to_cal_regs[result] - 128 : result_to_cal_regs[result]; + for (const uint32_t& result : result_to_cal_regs.keys()) + _rfcal_results[result].delta_c = result_to_cal_regs[result] > 63 + ? result_to_cal_regs[result] - 128 + : result_to_cal_regs[result]; /* read byte 0x26-0x2B */ read_reg(0x26, 0x2B); // Loop through rfcal_byte_* registers, initialize _rfcal_coeffs - for(const uint32_t &subband: _rfcal_coeffs.keys()) - { + for (const uint32_t& subband : _rfcal_coeffs.keys()) { freq_range_t subband_freqs; uint32_t result = _rfcal_coeffs[subband].cal_number; subband_freqs = get_tda18272_rfcal_result_freq_range(result); - _rfcal_coeffs[subband].RF_B1 = _rfcal_results[result].delta_c + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset]; + _rfcal_coeffs[subband].RF_B1 = + _rfcal_results[result].delta_c + + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset]; - uint32_t quotient = (((_rfcal_results[result+1].delta_c + tvrx2_tda18272_cal_map[result+1].c_offset[_rfcal_results[result].c_offset]) - - (_rfcal_results[result].delta_c + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset])) * 1000000); + uint32_t quotient = (((_rfcal_results[result + 1].delta_c + + tvrx2_tda18272_cal_map[result + 1] + .c_offset[_rfcal_results[result].c_offset]) + - (_rfcal_results[result].delta_c + + tvrx2_tda18272_cal_map[result] + .c_offset[_rfcal_results[result].c_offset])) + * 1000000); - uint32_t divisor = ((int32_t)(subband_freqs.stop() - subband_freqs.start())/1000); + uint32_t divisor = + ((int32_t)(subband_freqs.stop() - subband_freqs.start()) / 1000); _rfcal_coeffs[subband].RF_A1 = quotient / divisor; - } - } /* @@ -1299,97 +1359,101 @@ void tvrx2::tvrx2_tda18272_init_rfcal(void) */ void tvrx2::tvrx2_tda18272_tune_rf_filter(uint32_t uRF) { - uint32_t uCounter = 0; - uint8_t cal_result = 0; - uint32_t uRFCal0 = 0; - uint32_t uRFCal1 = 0; - uint8_t subband = 0; - int32_t cProg = 0; - uint8_t gain_taper = 0; - uint8_t RFBand = 0; - int32_t RF_A1 = 0; - int32_t RF_B1 = 0; - freq_range_t subband_freqs; + uint32_t uCounter = 0; + uint8_t cal_result = 0; + uint32_t uRFCal0 = 0; + uint32_t uRFCal1 = 0; + uint8_t subband = 0; + int32_t cProg = 0; + uint8_t gain_taper = 0; + uint8_t RFBand = 0; + int32_t RF_A1 = 0; + int32_t RF_B1 = 0; + freq_range_t subband_freqs; /* read byte 0x26-0x2B */ read_reg(0x26, 0x2B); subband_freqs = get_tda18272_rfcal_result_freq_range(1); - uRFCal0 = uint32_t(subband_freqs.start()); + uRFCal0 = uint32_t(subband_freqs.start()); subband_freqs = get_tda18272_rfcal_result_freq_range(4); - uRFCal1 = uint32_t(subband_freqs.start()); + uRFCal1 = uint32_t(subband_freqs.start()); - if(uRF < uRFCal0) + if (uRF < uRFCal0) subband = 0; - else if(uRF < 145700000) + else if (uRF < 145700000) subband = 1; - else if(uRF < uRFCal1) + else if (uRF < uRFCal1) subband = 2; - else if(uRF < 367400000) + else if (uRF < 367400000) subband = 3; - else - { + else { subband_freqs = get_tda18272_rfcal_result_freq_range(7); - uRFCal0 = uint32_t(subband_freqs.start()); + uRFCal0 = uint32_t(subband_freqs.start()); subband_freqs = get_tda18272_rfcal_result_freq_range(10); - uRFCal1 = uint32_t(subband_freqs.start()); + uRFCal1 = uint32_t(subband_freqs.start()); - if(uRF < uRFCal0) + if (uRF < uRFCal0) subband = 4; - else if(uRF < 625000000) + else if (uRF < 625000000) subband = 5; - else if(uRF < uRFCal1) + else if (uRF < uRFCal1) subband = 6; else subband = 7; } - cal_result = _rfcal_coeffs[subband].cal_number; + cal_result = _rfcal_coeffs[subband].cal_number; subband_freqs = get_tda18272_rfcal_result_freq_range(cal_result); - uRFCal0 = uint32_t(subband_freqs.start()); + uRFCal0 = uint32_t(subband_freqs.start()); RF_A1 = _rfcal_coeffs[subband].RF_A1; RF_B1 = _rfcal_coeffs[subband].RF_B1; uCounter = 0; - do uCounter ++; - while (uRF >= tvrx2_tda18272_freq_map[uCounter].rf_max && uCounter < TVRX2_TDA18272_FREQ_MAP_ENTRIES); + do + uCounter++; + while (uRF >= tvrx2_tda18272_freq_map[uCounter].rf_max + && uCounter < TVRX2_TDA18272_FREQ_MAP_ENTRIES); - cProg = tvrx2_tda18272_freq_map[uCounter - 1].c_prog; + cProg = tvrx2_tda18272_freq_map[uCounter - 1].c_prog; gain_taper = tvrx2_tda18272_freq_map[uCounter - 1].gain_taper; - RFBand = tvrx2_tda18272_freq_map[uCounter - 1].rf_band; + RFBand = tvrx2_tda18272_freq_map[uCounter - 1].rf_band; - cProg = (int32_t)(cProg + RF_B1 + (RF_A1*((int32_t)(uRF - uRFCal0)/1000))/1000000); + cProg = + (int32_t)(cProg + RF_B1 + (RF_A1 * ((int32_t)(uRF - uRFCal0) / 1000)) / 1000000); - if(cProg>255) cProg = 255; - if(cProg<0) cProg = 0; + if (cProg > 255) + cProg = 255; + if (cProg < 0) + cProg = 0; _tda18272hnm_regs.rf_filter_bypass = 1; - _tda18272hnm_regs.rf_filter_cap = (uint8_t) cProg; - _tda18272hnm_regs.gain_taper = gain_taper; - _tda18272hnm_regs.rf_filter_band = RFBand; - - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Software Calibration:\n" - "\tRF Filter Bypass = %d\n" - "\tRF Filter Cap = %d\n" - "\tRF Filter Band = %d\n" - "\tGain Taper = %d\n") - % (get_subdev_name()) - % int(_tda18272hnm_regs.rf_filter_bypass) - % int(_tda18272hnm_regs.rf_filter_cap) - % int(_tda18272hnm_regs.rf_filter_band) - % int(_tda18272hnm_regs.gain_taper) - ; + _tda18272hnm_regs.rf_filter_cap = (uint8_t)cProg; + _tda18272hnm_regs.gain_taper = gain_taper; + _tda18272hnm_regs.rf_filter_band = RFBand; + + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Software Calibration:\n" + "\tRF Filter Bypass = %d\n" + "\tRF Filter Cap = %d\n" + "\tRF Filter Band = %d\n" + "\tGain Taper = %d\n") + % (get_subdev_name()) + % int(_tda18272hnm_regs.rf_filter_bypass) + % int(_tda18272hnm_regs.rf_filter_cap) + % int(_tda18272hnm_regs.rf_filter_band) + % int(_tda18272hnm_regs.gain_taper); send_reg(0x2c, 0x2f); } -void tvrx2::soft_calibration(void){ - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Software Calibration: Initialize Tuner, Calibrate and Standby\n") % (get_subdev_name()) ; +void tvrx2::soft_calibration(void) +{ + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Software Calibration: " + "Initialize Tuner, Calibrate and Standby\n") + % (get_subdev_name()); - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON; @@ -1414,20 +1478,20 @@ void tvrx2::soft_calibration(void){ send_reg(0x26, 0x2B); - _tda18272hnm_regs.set_reg(0x19, 0x3B); //set MSM_byte_1 for calibration per datasheet - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration + _tda18272hnm_regs.set_reg(0x19, 0x3B); // set MSM_byte_1 for calibration per datasheet + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration send_reg(0x19, 0x1A); wait_irq(); - send_reg(0x1D, 0x1D); //Fmax_LO - send_reg(0x0C, 0x0C); //LT_Enable - send_reg(0x1B, 0x1B); //PSM_AGC1 - send_reg(0x0C, 0x0C); //AGC1_6_15dB + send_reg(0x1D, 0x1D); // Fmax_LO + send_reg(0x0C, 0x0C); // LT_Enable + send_reg(0x1B, 0x1B); // PSM_AGC1 + send_reg(0x0C, 0x0C); // AGC1_6_15dB - //set spread spectrum for clock - //FIXME: NXP turns clock spread on and off + // set spread spectrum for clock + // FIXME: NXP turns clock spread on and off // based on where clock spurs would be relative to RF frequency // we should do this also _tda18272hnm_regs.digital_clock = tda18272hnm_regs_t::DIGITAL_CLOCK_SPREAD_OFF; @@ -1437,18 +1501,19 @@ void tvrx2::soft_calibration(void){ else //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO; _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ; - + send_reg(0x14, 0x14); - _tda18272hnm_regs.set_reg(0x36, 0x0E); //sets clock mode + _tda18272hnm_regs.set_reg(0x36, 0x0E); // sets clock mode send_reg(0x36, 0x36); - //go to standby mode + // go to standby mode _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; send_reg(0x6, 0x6); } -void tvrx2::test_rf_filter_robustness(void){ +void tvrx2::test_rf_filter_robustness(void) +{ typedef uhd::dict<std::string, std::string> tvrx2_filter_ratings_t; typedef uhd::dict<std::string, double> tvrx2_filter_margins_t; @@ -1457,62 +1522,123 @@ void tvrx2::test_rf_filter_robustness(void){ read_reg(0x38, 0x43); - uhd::dict<std::string, uint8_t> filter_cal_regs = map_list_of - ("VHFLow_0", 0x38) - ("VHFLow_1", 0x3a) - ("VHFHigh_0", 0x3b) - ("VHFHigh_1", 0x3d) - ("UHFLow_0", 0x3e) - ("UHFLow_1", 0x40) - ("UHFHigh_0", 0x41) - ("UHFHigh_1", 0x43) - ; - - for(const std::string &name: filter_cal_regs.keys()){ + uhd::dict<std::string, uint8_t> filter_cal_regs = map_list_of("VHFLow_0", 0x38)( + "VHFLow_1", 0x3a)("VHFHigh_0", 0x3b)("VHFHigh_1", 0x3d)("UHFLow_0", 0x3e)( + "UHFLow_1", 0x40)("UHFHigh_0", 0x41)("UHFHigh_1", 0x43); + + for (const std::string& name : filter_cal_regs.keys()) { uint8_t cal_result = _tda18272hnm_regs.get_reg(filter_cal_regs[name]); if (cal_result & 0x80) { _filter_ratings.set(name, "E"); _filter_margins.set(name, 0.0); - } - else { + } else { double partial; if (name == "VHFLow_0") - partial = 100 * (45 - 39.8225 * (1 + (0.31 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / 45.0; + partial = 100 + * (45 + - 39.8225 + * (1 + + (0.31 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / 45.0; else if (name == "VHFLow_1") - partial = 100 * (152.1828 * (1 + (1.53 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (144.896 - 6)) / (144.896 - 6); + partial = 100 + * (152.1828 + * (1 + + (1.53 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (144.896 - 6)) + / (144.896 - 6); else if (name == "VHFHigh_0") - partial = 100 * ((144.896 + 6) - 135.4063 * (1 + (0.27 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (144.896 + 6); + partial = 100 + * ((144.896 + 6) + - 135.4063 + * (1 + + (0.27 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / (144.896 + 6); else if (name == "VHFHigh_1") - partial = 100 * (383.1455 * (1 + (0.91 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (367.104 - 8)) / (367.104 - 8); + partial = 100 + * (383.1455 + * (1 + + (0.91 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (367.104 - 8)) + / (367.104 - 8); else if (name == "UHFLow_0") - partial = 100 * ((367.104 + 8) - 342.6224 * (1 + (0.21 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (367.104 + 8); + partial = 100 + * ((367.104 + 8) + - 342.6224 + * (1 + + (0.21 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / (367.104 + 8); else if (name == "UHFLow_1") - partial = 100 * (662.5595 * (1 + (0.33 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (624.128 - 2)) / (624.128 - 2); + partial = 100 + * (662.5595 + * (1 + + (0.33 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (624.128 - 2)) + / (624.128 - 2); else if (name == "UHFHigh_0") - partial = 100 * ((624.128 + 2) - 508.2747 * (1 + (0.23 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (624.128 + 2); + partial = 100 + * ((624.128 + 2) + - 508.2747 + * (1 + + (0.23 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0)) + / (624.128 + 2); else if (name == "UHFHigh_1") - partial = 100 * (947.8913 * (1 + (0.3 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (866 - 14)) / (866 - 14); + partial = 100 + * (947.8913 + * (1 + + (0.3 + * (cal_result < 64 ? cal_result + : cal_result - 128)) + / 1.0 / 100.0) + - (866 - 14)) + / (866 - 14); else UHD_THROW_INVALID_CODE_PATH(); - _filter_margins.set(name, 0.0024 * partial * partial * partial - 0.101 * partial * partial + 1.629 * partial + 1.8266); + _filter_margins.set(name, + 0.0024 * partial * partial * partial - 0.101 * partial * partial + + 1.629 * partial + 1.8266); _filter_ratings.set(name, _filter_margins[name] >= 0.0 ? "H" : "L"); } } std::stringstream robustness_message; - robustness_message << boost::format("TVRX2 (%s): RF Filter Robustness Results:") % (get_subdev_name()); - for(const std::string &name: uhd::sorted(_filter_ratings.keys())){ - robustness_message << boost::format("\t%s:\tMargin = %0.2f,\tRobustness = %c") % name % (_filter_margins[name]) % (_filter_ratings[name]); + robustness_message << boost::format("TVRX2 (%s): RF Filter Robustness Results:") + % (get_subdev_name()); + for (const std::string& name : uhd::sorted(_filter_ratings.keys())) { + robustness_message << boost::format("\t%s:\tMargin = %0.2f,\tRobustness = %c") + % name % (_filter_margins[name]) + % (_filter_ratings[name]); } UHD_LOGGER_DEBUG("TVRX") << robustness_message.str(); @@ -1521,14 +1647,17 @@ void tvrx2::test_rf_filter_robustness(void){ /*********************************************************************** * TDA18272 State Functions **********************************************************************/ -void tvrx2::transition_0(void){ - //Transition 0: Initialize Tuner and place in standby - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 0: Initialize Tuner, Calibrate and Standby\n") % (get_subdev_name()) ; +void tvrx2::transition_0(void) +{ + // Transition 0: Initialize Tuner and place in standby + UHD_LOGGER_TRACE("TVRX") + << boost::format( + "\nTVRX2 (%s): Transition 0: Initialize Tuner, Calibrate and Standby\n") + % (get_subdev_name()); - //Check for Power-On Reset, if reset, initialze tuner + // Check for Power-On Reset, if reset, initialze tuner if (get_power_reset()) { - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON; @@ -1537,24 +1666,25 @@ void tvrx2::transition_0(void){ read_reg(0x19, 0x1A); - _tda18272hnm_regs.set_reg(0x19, 0x3B); //set MSM_byte_1 for calibration per datasheet - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration + _tda18272hnm_regs.set_reg( + 0x19, 0x3B); // set MSM_byte_1 for calibration per datasheet + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration send_reg(0x19, 0x1A); wait_irq(); } - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - send_reg(0x1D, 0x1D); //Fmax_LO - send_reg(0x0C, 0x0C); //LT_Enable - send_reg(0x1B, 0x1B); //PSM_AGC1 - send_reg(0x0C, 0x0C); //AGC1_6_15dB + send_reg(0x1D, 0x1D); // Fmax_LO + send_reg(0x0C, 0x0C); // LT_Enable + send_reg(0x1B, 0x1B); // PSM_AGC1 + send_reg(0x0C, 0x0C); // AGC1_6_15dB - //set spread spectrum for clock - //FIXME: NXP turns clock spread on and off + // set spread spectrum for clock + // FIXME: NXP turns clock spread on and off // based on where clock spurs would be relative to RF frequency // we should do this also _tda18272hnm_regs.digital_clock = tda18272hnm_regs_t::DIGITAL_CLOCK_SPREAD_OFF; @@ -1564,199 +1694,224 @@ void tvrx2::transition_0(void){ else //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO; _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ; - + send_reg(0x14, 0x14); - _tda18272hnm_regs.set_reg(0x36, 0x0E); //sets clock mode + _tda18272hnm_regs.set_reg(0x36, 0x0E); // sets clock mode send_reg(0x36, 0x36); - //go to standby mode + // go to standby mode _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; send_reg(0x6, 0x6); } -void tvrx2::transition_1(void){ - //Transition 1: Select TV Standard +void tvrx2::transition_1(void) +{ + // Transition 1: Select TV Standard UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 1: Select TV Standard\n") % (get_subdev_name()) ; + "\nTVRX2 (%s): Transition 1: Select TV Standard\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Choose IF Byte 1 Setting + // Choose IF Byte 1 Setting //_tda18272hnm_regs.if_hp_fc = tda18272hnm_regs_t::IF_HP_FC_0_4MHZ; //_tda18272hnm_regs.if_notch = tda18272hnm_regs_t::IF_NOTCH_OFF; //_tda18272hnm_regs.lp_fc_offset = tda18272hnm_regs_t::LP_FC_OFFSET_0_PERCENT; //_tda18272hnm_regs.lp_fc = tda18272hnm_regs_t::LP_FC_10_0MHZ; - //send_reg(0x13, 0x13); + // send_reg(0x13, 0x13); - //Choose IR Mixer Byte 2 Setting + // Choose IR Mixer Byte 2 Setting //_tda18272hnm_regs.hi_pass = tda18272hnm_regs_t::HI_PASS_DISABLE; //_tda18272hnm_regs.dc_notch = tda18272hnm_regs_t::DC_NOTCH_OFF; send_reg(0x23, 0x23); - //Set AGC TOP Bytes + // Set AGC TOP Bytes send_reg(0x0C, 0x13); - //Set PSM Byt1 + // Set PSM Byt1 send_reg(0x1B, 0x1B); - //Choose IF Frequency, setting is 50KHz steps + // Choose IF Frequency, setting is 50KHz steps set_scaled_if_freq(_if_freq); send_reg(0x15, 0x15); } -void tvrx2::transition_2(int rf_freq){ - //Transition 2: Select RF Frequency after changing TV Standard - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 2: Select RF Frequency after changing TV Standard\n") % (get_subdev_name()) ; +void tvrx2::transition_2(int rf_freq) +{ + // Transition 2: Select RF Frequency after changing TV Standard + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Transition 2: Select RF " + "Frequency after changing TV Standard\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Wake up from Standby - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; + // Wake up from Standby + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON; - + send_reg(0x6, 0x6); - - //Set Clock Mode + + // Set Clock Mode _tda18272hnm_regs.set_reg(0x36, 0x00); send_reg(0x36, 0x36); - - //Set desired RF Frequency + + // Set desired RF Frequency set_scaled_rf_freq(rf_freq); send_reg(0x16, 0x18); - - //Lock PLL and tune RF Filters - _tda18272hnm_regs.set_reg(0x19, 0x41); //set MSM_byte_1 for RF Filters Tuning, PLL Locking - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration - + + // Lock PLL and tune RF Filters + _tda18272hnm_regs.set_reg( + 0x19, 0x41); // set MSM_byte_1 for RF Filters Tuning, PLL Locking + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration + send_reg(0x19, 0x1A); - + wait_irq(); tvrx2_tda18272_tune_rf_filter(rf_freq); ////LO Lock state in Reg 0x5 LSB - //read_reg(0x6, 0x6); - + // read_reg(0x6, 0x6); } -void tvrx2::transition_3(void){ - //Transition 3: Standby Mode +void tvrx2::transition_3(void) +{ + // Transition 3: Standby Mode UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 3: Standby Mode\n") % (get_subdev_name()) ; + "\nTVRX2 (%s): Transition 3: Standby Mode\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Set clock mode + // Set clock mode _tda18272hnm_regs.set_reg(0x36, 0x0E); send_reg(0x36, 0x36); - //go to standby mode - _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; + // go to standby mode + _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY; _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_OFF; _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_OFF; send_reg(0x6, 0x6); } -void tvrx2::transition_4(int rf_freq){ - //Transition 4: Change RF Frequency without changing TV Standard - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Transition 4: Change RF Frequency without changing TV Standard\n") % (get_subdev_name()) ; +void tvrx2::transition_4(int rf_freq) +{ + // Transition 4: Change RF Frequency without changing TV Standard + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): Transition 4: Change RF " + "Frequency without changing TV Standard\n") + % (get_subdev_name()); - //send magic xtal_cal_dac setting + // send magic xtal_cal_dac setting send_reg(0x65, 0x65); - //Set desired RF Frequency + // Set desired RF Frequency set_scaled_rf_freq(rf_freq); send_reg(0x16, 0x18); - - //Lock PLL and tune RF Filters - _tda18272hnm_regs.set_reg(0x19, 0x41); //set MSM_byte_1 for RF Filters Tuning, PLL Locking - _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration - + + // Lock PLL and tune RF Filters + _tda18272hnm_regs.set_reg( + 0x19, 0x41); // set MSM_byte_1 for RF Filters Tuning, PLL Locking + _tda18272hnm_regs.set_reg(0x1A, 0x01); // set MSM_byte_2 for launching calibration + send_reg(0x19, 0x1A); - + wait_irq(); tvrx2_tda18272_tune_rf_filter(rf_freq); ////LO Lock state in Reg 0x5 LSB - //read_reg(0x5, 0x6); - + // read_reg(0x5, 0x6); } -void tvrx2::wait_irq(void){ - int timeout = 20; //irq waiting timeout in milliseconds - //int irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & int(tvrx2_sd_name_to_irq_io[get_subdev_name()])); +void tvrx2::wait_irq(void) +{ + int timeout = 20; // irq waiting timeout in milliseconds + // int irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & + // int(tvrx2_sd_name_to_irq_io[get_subdev_name()])); bool irq = get_irq(); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Waiting on IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format( + "\nTVRX2 (%s): Waiting on IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") + % (get_subdev_name()) % get_subdev_name() + % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq; while (not irq and timeout > 0) { - //irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]); + // irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & + // tvrx2_sd_name_to_irq_io[get_subdev_name()]); irq = get_irq(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); timeout -= 1; } - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): IRQ Raised, subdev = %d, mask = 0x%x, Status: 0x%x, Timeout: %d\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq % timeout ; + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): IRQ Raised, subdev = %d, " + "mask = 0x%x, Status: 0x%x, Timeout: %d\n") + % (get_subdev_name()) % get_subdev_name() + % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) + % irq % timeout; read_reg(0xA, 0xB); - //UHD_ASSERT_THROW(timeout > 0); - if(timeout <= 0) UHD_LOGGER_WARNING("TVRX") << boost::format( - "\nTVRX2 (%s): Timeout waiting on IRQ\n") % (get_subdev_name()) ; + // UHD_ASSERT_THROW(timeout > 0); + if (timeout <= 0) + UHD_LOGGER_WARNING("TVRX") + << boost::format("\nTVRX2 (%s): Timeout waiting on IRQ\n") + % (get_subdev_name()); _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE; send_reg(0xA, 0xA); read_reg(0xA, 0xB); - irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]) > 0; + irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) + & tvrx2_sd_name_to_irq_io[get_subdev_name()]) + > 0; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): Cleared IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq ; + UHD_LOGGER_TRACE("TVRX") + << boost::format( + "\nTVRX2 (%s): Cleared IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") + % (get_subdev_name()) % get_subdev_name() + % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq; } - /*********************************************************************** * Tuning **********************************************************************/ -double tvrx2::set_lo_freq(double target_freq){ - //target_freq = std::clip(target_freq, tvrx2_freq_range.min, tvrx2_freq_range.max); +double tvrx2::set_lo_freq(double target_freq) +{ + // target_freq = std::clip(target_freq, tvrx2_freq_range.min, tvrx2_freq_range.max); read_reg(0x6, 0x6); if (_tda18272hnm_regs.sm == tda18272hnm_regs_t::SM_STANDBY) { - transition_2(int(target_freq + _bandwidth/2 - get_scaled_if_freq())); + transition_2(int(target_freq + _bandwidth / 2 - get_scaled_if_freq())); } else { - transition_4(int(target_freq + _bandwidth/2 - get_scaled_if_freq())); + transition_4(int(target_freq + _bandwidth / 2 - get_scaled_if_freq())); } read_reg(0x16, 0x18); - //compute actual tuned frequency + // compute actual tuned frequency _lo_freq = get_scaled_rf_freq() + get_scaled_if_freq(); // - _bandwidth/2; - //debug output of calculated variables - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): LO Frequency\n" - "\tRequested: \t%f\n" - "\tComputed: \t%f\n" - "\tReadback: \t%f\n" - "\tIF Frequency: \t%f\n") % (get_subdev_name()) % target_freq % double(int(target_freq/1e3)*1e3) % get_scaled_rf_freq() % get_scaled_if_freq() ; + // debug output of calculated variables + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): LO Frequency\n" + "\tRequested: \t%f\n" + "\tComputed: \t%f\n" + "\tReadback: \t%f\n" + "\tIF Frequency: \t%f\n") + % (get_subdev_name()) % target_freq + % double(int(target_freq / 1e3) * 1e3) + % get_scaled_rf_freq() % get_scaled_if_freq(); get_locked(); test_rf_filter_robustness(); - UHD_LOGGER_TRACE("TVRX") << boost::format( - "\nTVRX2 (%s): RSSI = %f dBm\n" - ) % (get_subdev_name()) % (get_rssi().to_real()) ; + UHD_LOGGER_TRACE("TVRX") << boost::format("\nTVRX2 (%s): RSSI = %f dBm\n") + % (get_subdev_name()) % (get_rssi().to_real()); return _lo_freq; } @@ -1767,37 +1922,40 @@ double tvrx2::set_lo_freq(double target_freq){ /* * Convert the requested gain into a dac voltage */ -static double gain_to_if_gain_dac(double &gain){ - //clip the input +static double gain_to_if_gain_dac(double& gain) +{ + // clip the input gain = tvrx2_gain_ranges["IF"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = double(1.7), min_volts = double(0.5); - static const double slope = (max_volts-min_volts)/tvrx2_gain_ranges["IF"].stop(); + static const double slope = (max_volts - min_volts) / tvrx2_gain_ranges["IF"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 IF Gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("TVRX") << boost::format("TVRX2 IF Gain: %f dB, dac_volts: %f V") + % gain % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } -double tvrx2::set_gain(double gain, const std::string &name){ +double tvrx2::set_gain(double gain, const std::string& name) +{ assert_has(tvrx2_gain_ranges.keys(), name, "tvrx2 gain name"); - if (name == "IF"){ - //write voltage to aux_dac - this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, tvrx2_sd_name_to_dac[get_subdev_name()], gain_to_if_gain_dac(gain)); - } - else UHD_THROW_INVALID_CODE_PATH(); + if (name == "IF") { + // write voltage to aux_dac + this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, + tvrx2_sd_name_to_dac[get_subdev_name()], + gain_to_if_gain_dac(gain)); + } else + UHD_THROW_INVALID_CODE_PATH(); - //shadow gain setting + // shadow gain setting _gains[name] = gain; return gain; @@ -1806,45 +1964,48 @@ double tvrx2::set_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -static tda18272hnm_regs_t::lp_fc_t bandwidth_to_lp_fc_reg(double &bandwidth){ - int reg = uhd::clip(boost::math::iround((bandwidth-5.0e6)/1.0e6), 0, 4); - - switch(reg){ - case 0: - bandwidth = 1.7e6; - return tda18272hnm_regs_t::LP_FC_1_7MHZ; - case 1: - bandwidth = 6e6; - return tda18272hnm_regs_t::LP_FC_6_0MHZ; - case 2: - bandwidth = 7e6; - return tda18272hnm_regs_t::LP_FC_7_0MHZ; - case 3: - bandwidth = 8e6; - return tda18272hnm_regs_t::LP_FC_8_0MHZ; - case 4: - bandwidth = 10e6; - return tda18272hnm_regs_t::LP_FC_10_0MHZ; +static tda18272hnm_regs_t::lp_fc_t bandwidth_to_lp_fc_reg(double& bandwidth) +{ + int reg = uhd::clip(boost::math::iround((bandwidth - 5.0e6) / 1.0e6), 0, 4); + + switch (reg) { + case 0: + bandwidth = 1.7e6; + return tda18272hnm_regs_t::LP_FC_1_7MHZ; + case 1: + bandwidth = 6e6; + return tda18272hnm_regs_t::LP_FC_6_0MHZ; + case 2: + bandwidth = 7e6; + return tda18272hnm_regs_t::LP_FC_7_0MHZ; + case 3: + bandwidth = 8e6; + return tda18272hnm_regs_t::LP_FC_8_0MHZ; + case 4: + bandwidth = 10e6; + return tda18272hnm_regs_t::LP_FC_10_0MHZ; } UHD_THROW_INVALID_CODE_PATH(); } -double tvrx2::set_bandwidth(double bandwidth){ - //clip the input +double tvrx2::set_bandwidth(double bandwidth) +{ + // clip the input bandwidth = tvrx2_bandwidth_range.clip(bandwidth); - //compute low pass cutoff frequency setting + // compute low pass cutoff frequency setting _tda18272hnm_regs.lp_fc = bandwidth_to_lp_fc_reg(bandwidth); - //shadow bandwidth setting + // shadow bandwidth setting _bandwidth = bandwidth; - //update register + // update register send_reg(0x13, 0x13); UHD_LOGGER_TRACE("TVRX") << boost::format( - "TVRX2 (%s) Bandwidth (lp_fc): %f Hz, reg: %d" - ) % (get_subdev_name()) % _bandwidth % (int(_tda18272hnm_regs.lp_fc)) ; + "TVRX2 (%s) Bandwidth (lp_fc): %f Hz, reg: %d") + % (get_subdev_name()) % _bandwidth + % (int(_tda18272hnm_regs.lp_fc)); return _bandwidth; } diff --git a/host/lib/usrp/dboard/db_twinrx.cpp b/host/lib/usrp/dboard/db_twinrx.cpp index 9f9efd158..258dc95a4 100644 --- a/host/lib/usrp/dboard/db_twinrx.cpp +++ b/host/lib/usrp/dboard/db_twinrx.cpp @@ -39,76 +39,105 @@ class twinrx_rcvr_fe : public rx_dboard_base { public: twinrx_rcvr_fe( - ctor_args_t args, - expert_container::sptr expert, - twinrx_ctrl::sptr ctrl - ) : - rx_dboard_base(args), _expert(expert), _ctrl(ctrl), - _ch_name(dboard_ctor_args_t::cast(args).sd_name) + ctor_args_t args, expert_container::sptr expert, twinrx_ctrl::sptr ctrl) + : rx_dboard_base(args) + , _expert(expert) + , _ctrl(ctrl) + , _ch_name(dboard_ctor_args_t::cast(args).sd_name) { //--------------------------------------------------------- // Add user-visible, channel specific properties to front-end tree //--------------------------------------------------------- - //Generic - get_rx_subtree()->create<std::string>("name") - .set("TwinRX RX" + _ch_name); - get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - get_rx_subtree()->create<std::string>("connection") - .set(_ch_name == "0" ? "II" : "QQ"); //Ch->ADC port mapping + // Generic + get_rx_subtree()->create<std::string>("name").set("TwinRX RX" + _ch_name); + get_rx_subtree()->create<bool>("use_lo_offset").set(false); + get_rx_subtree() + ->create<std::string>("connection") + .set(_ch_name == "0" ? "II" : "QQ"); // Ch->ADC port mapping static const double BW = 80e6; - get_rx_subtree()->create<double>("bandwidth/value") - .set(BW); - get_rx_subtree()->create<meta_range_t>("bandwidth/range") + get_rx_subtree()->create<double>("bandwidth/value").set(BW); + get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(BW, BW)); // Command Time - expert_factory::add_data_node<time_spec_t>(_expert, prepend_ch("time/rx_frontend", _ch_name), time_spec_t(0.0)); - expert_factory::add_prop_node<time_spec_t>(_expert, get_rx_subtree(), - "time/cmd", prepend_ch("time/cmd", _ch_name), time_spec_t(0.0)); + expert_factory::add_data_node<time_spec_t>( + _expert, prepend_ch("time/rx_frontend", _ch_name), time_spec_t(0.0)); + expert_factory::add_prop_node<time_spec_t>(_expert, + get_rx_subtree(), + "time/cmd", + prepend_ch("time/cmd", _ch_name), + time_spec_t(0.0)); - //Frequency Specific - get_rx_subtree()->create<meta_range_t>("freq/range") + // Frequency Specific + get_rx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(10e6, 6.0e9)); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "freq/value", prepend_ch("freq/desired", _ch_name), prepend_ch("freq/coerced", _ch_name), - 1.0e9, AUTO_RESOLVE_ON_READ_WRITE); - get_rx_subtree()->create<device_addr_t>("tune_args") - .set(device_addr_t()); + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "freq/value", + prepend_ch("freq/desired", _ch_name), + prepend_ch("freq/coerced", _ch_name), + 1.0e9, + AUTO_RESOLVE_ON_READ_WRITE); + get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); static const double DEFAULT_IF_FREQ = 150e6; meta_range_t if_freq_range; - if_freq_range.push_back(range_t(-DEFAULT_IF_FREQ-(BW/2), -DEFAULT_IF_FREQ+(BW/2))); - if_freq_range.push_back(range_t( DEFAULT_IF_FREQ-(BW/2), DEFAULT_IF_FREQ+(BW/2))); - get_rx_subtree()->create<meta_range_t>("if_freq/range") - .set(if_freq_range); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "if_freq/value", prepend_ch("if_freq/desired", _ch_name), prepend_ch("if_freq/coerced", _ch_name), - DEFAULT_IF_FREQ, AUTO_RESOLVE_ON_WRITE); - - //LO Specific - get_rx_subtree()->create<meta_range_t>("los/LO1/freq/range") + if_freq_range.push_back( + range_t(-DEFAULT_IF_FREQ - (BW / 2), -DEFAULT_IF_FREQ + (BW / 2))); + if_freq_range.push_back( + range_t(DEFAULT_IF_FREQ - (BW / 2), DEFAULT_IF_FREQ + (BW / 2))); + get_rx_subtree()->create<meta_range_t>("if_freq/range").set(if_freq_range); + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "if_freq/value", + prepend_ch("if_freq/desired", _ch_name), + prepend_ch("if_freq/coerced", _ch_name), + DEFAULT_IF_FREQ, + AUTO_RESOLVE_ON_WRITE); + + // LO Specific + get_rx_subtree() + ->create<meta_range_t>("los/LO1/freq/range") .set(freq_range_t(2.0e9, 6.8e9)); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "los/LO1/freq/value", prepend_ch("los/LO1/freq/desired", _ch_name), prepend_ch("los/LO1/freq/coerced", _ch_name), - 0.0, AUTO_RESOLVE_ON_READ_WRITE); - get_rx_subtree()->create<meta_range_t>("los/LO2/freq/range") + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "los/LO1/freq/value", + prepend_ch("los/LO1/freq/desired", _ch_name), + prepend_ch("los/LO1/freq/coerced", _ch_name), + 0.0, + AUTO_RESOLVE_ON_READ_WRITE); + get_rx_subtree() + ->create<meta_range_t>("los/LO2/freq/range") .set(freq_range_t(1.0e9, 3.0e9)); - expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), - "los/LO2/freq/value", prepend_ch("los/LO2/freq/desired", _ch_name), prepend_ch("los/LO2/freq/coerced", _ch_name), - 0.0, AUTO_RESOLVE_ON_READ_WRITE); - get_rx_subtree()->create<std::vector<std::string>>("los/all/source/options") + expert_factory::add_dual_prop_node<double>(_expert, + get_rx_subtree(), + "los/LO2/freq/value", + prepend_ch("los/LO2/freq/desired", _ch_name), + prepend_ch("los/LO2/freq/coerced", _ch_name), + 0.0, + AUTO_RESOLVE_ON_READ_WRITE); + get_rx_subtree() + ->create<std::vector<std::string>>("los/all/source/options") .set({"internal", "external", "companion", "disabled", "reimport"}); - expert_factory::add_prop_node<std::string>(_expert, get_rx_subtree(), - "los/all/source/value", prepend_ch("los/all/source", _ch_name), - "internal", AUTO_RESOLVE_ON_WRITE); - expert_factory::add_prop_node<bool>(_expert, get_rx_subtree(), - "los/all/export", prepend_ch("los/all/export", _ch_name), - false, AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<std::string>(_expert, + get_rx_subtree(), + "los/all/source/value", + prepend_ch("los/all/source", _ch_name), + "internal", + AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<bool>(_expert, + get_rx_subtree(), + "los/all/export", + prepend_ch("los/all/export", _ch_name), + false, + AUTO_RESOLVE_ON_WRITE); // LO1 Charge Pump - get_rx_subtree()->create<meta_range_t>("los/LO1/charge_pump/range") + get_rx_subtree() + ->create<meta_range_t>("los/LO1/charge_pump/range") .set(_ctrl->get_lo1_charge_pump_range()); expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), @@ -119,7 +148,8 @@ public: AUTO_RESOLVE_ON_READ_WRITE); // LO2 Charge Pump - get_rx_subtree()->create<meta_range_t>("los/LO2/charge_pump/range") + get_rx_subtree() + ->create<meta_range_t>("los/LO2/charge_pump/range") .set(_ctrl->get_lo2_charge_pump_range()); expert_factory::add_dual_prop_node<double>(_expert, get_rx_subtree(), @@ -129,29 +159,44 @@ public: 1.25e-6, AUTO_RESOLVE_ON_READ_WRITE); - //Gain Specific - get_rx_subtree()->create<meta_range_t>("gains/all/range") + // Gain Specific + get_rx_subtree() + ->create<meta_range_t>("gains/all/range") .set(gain_range_t(0, 93, double(1.0))); - expert_factory::add_prop_node<double>(_expert, get_rx_subtree(), - "gains/all/value", prepend_ch("gain", _ch_name), - 0.0, AUTO_RESOLVE_ON_WRITE); - get_rx_subtree()->create<std::vector<std::string> >("gains/all/profile/options") + expert_factory::add_prop_node<double>(_expert, + get_rx_subtree(), + "gains/all/value", + prepend_ch("gain", _ch_name), + 0.0, + AUTO_RESOLVE_ON_WRITE); + get_rx_subtree() + ->create<std::vector<std::string>>("gains/all/profile/options") .set({"low-noise", "low-distortion", "default"}); - expert_factory::add_prop_node<std::string>(_expert, get_rx_subtree(), - "gains/all/profile/value", prepend_ch("gain_profile", _ch_name), - "default", AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<std::string>(_expert, + get_rx_subtree(), + "gains/all/profile/value", + prepend_ch("gain_profile", _ch_name), + "default", + AUTO_RESOLVE_ON_WRITE); - //Antenna Specific - get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + // Antenna Specific + get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set({"RX1", "RX2"}); - expert_factory::add_prop_node<std::string>(_expert, get_rx_subtree(), - "antenna/value", prepend_ch("antenna", _ch_name), - (_ch_name == "0" ? "RX1" : "RX2"), AUTO_RESOLVE_ON_WRITE); - expert_factory::add_prop_node<bool>(_expert, get_rx_subtree(), - "enabled", prepend_ch("enabled", _ch_name), - false, AUTO_RESOLVE_ON_WRITE); - - //Readback + expert_factory::add_prop_node<std::string>(_expert, + get_rx_subtree(), + "antenna/value", + prepend_ch("antenna", _ch_name), + (_ch_name == "0" ? "RX1" : "RX2"), + AUTO_RESOLVE_ON_WRITE); + expert_factory::add_prop_node<bool>(_expert, + get_rx_subtree(), + "enabled", + prepend_ch("enabled", _ch_name), + false, + AUTO_RESOLVE_ON_WRITE); + + // Readback get_rx_subtree() ->create<sensor_value_t>("sensors/lo_locked") .set_publisher([this]() { return this->get_lo_locked(); }); @@ -159,55 +204,53 @@ public: //--------------------------------------------------------- // Add internal channel-specific data nodes to expert //--------------------------------------------------------- - expert_factory::add_data_node<lo_inj_side_t>(_expert, - prepend_ch("ch/LO1/inj_side", _ch_name), INJ_LOW_SIDE); - expert_factory::add_data_node<lo_inj_side_t>(_expert, - prepend_ch("ch/LO2/inj_side", _ch_name), INJ_LOW_SIDE); - expert_factory::add_data_node<twinrx_ctrl::signal_path_t>(_expert, - prepend_ch("ch/signal_path", _ch_name), twinrx_ctrl::PATH_LOWBAND); - expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>(_expert, - prepend_ch("ch/lb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); - expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>(_expert, - prepend_ch("ch/hb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ch/lb_preamp_presel", _ch_name), false); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ant/lb_preamp_presel", _ch_name), false); - expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>(_expert, - prepend_ch("ch/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); - expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>(_expert, - prepend_ch("ant/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ch/preamp2", _ch_name), false); - expert_factory::add_data_node<bool>(_expert, - prepend_ch("ant/preamp2", _ch_name), false); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ch/input_atten", _ch_name), 0); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ant/input_atten", _ch_name), 0); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ch/lb_atten", _ch_name), 0); - expert_factory::add_data_node<uint8_t>(_expert, - prepend_ch("ch/hb_atten", _ch_name), 0); - expert_factory::add_data_node<twinrx_ctrl::lo_source_t>(_expert, - prepend_ch("ch/LO1/source", _ch_name), twinrx_ctrl::LO_INTERNAL); - expert_factory::add_data_node<twinrx_ctrl::lo_source_t>(_expert, - prepend_ch("ch/LO2/source", _ch_name), twinrx_ctrl::LO_INTERNAL); - expert_factory::add_data_node<lo_synth_mapping_t>(_expert, - prepend_ch("synth/LO1/mapping", _ch_name), MAPPING_NONE); - expert_factory::add_data_node<lo_synth_mapping_t>(_expert, - prepend_ch("synth/LO2/mapping", _ch_name), MAPPING_NONE); - + expert_factory::add_data_node<lo_inj_side_t>( + _expert, prepend_ch("ch/LO1/inj_side", _ch_name), INJ_LOW_SIDE); + expert_factory::add_data_node<lo_inj_side_t>( + _expert, prepend_ch("ch/LO2/inj_side", _ch_name), INJ_LOW_SIDE); + expert_factory::add_data_node<twinrx_ctrl::signal_path_t>( + _expert, prepend_ch("ch/signal_path", _ch_name), twinrx_ctrl::PATH_LOWBAND); + expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>( + _expert, prepend_ch("ch/lb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); + expert_factory::add_data_node<twinrx_ctrl::preselector_path_t>( + _expert, prepend_ch("ch/hb_presel", _ch_name), twinrx_ctrl::PRESEL_PATH1); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ch/lb_preamp_presel", _ch_name), false); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ant/lb_preamp_presel", _ch_name), false); + expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>( + _expert, prepend_ch("ch/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); + expert_factory::add_data_node<twinrx_ctrl::preamp_state_t>( + _expert, prepend_ch("ant/preamp1", _ch_name), twinrx_ctrl::PREAMP_BYPASS); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ch/preamp2", _ch_name), false); + expert_factory::add_data_node<bool>( + _expert, prepend_ch("ant/preamp2", _ch_name), false); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ch/input_atten", _ch_name), 0); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ant/input_atten", _ch_name), 0); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ch/lb_atten", _ch_name), 0); + expert_factory::add_data_node<uint8_t>( + _expert, prepend_ch("ch/hb_atten", _ch_name), 0); + expert_factory::add_data_node<twinrx_ctrl::lo_source_t>( + _expert, prepend_ch("ch/LO1/source", _ch_name), twinrx_ctrl::LO_INTERNAL); + expert_factory::add_data_node<twinrx_ctrl::lo_source_t>( + _expert, prepend_ch("ch/LO2/source", _ch_name), twinrx_ctrl::LO_INTERNAL); + expert_factory::add_data_node<lo_synth_mapping_t>( + _expert, prepend_ch("synth/LO1/mapping", _ch_name), MAPPING_NONE); + expert_factory::add_data_node<lo_synth_mapping_t>( + _expert, prepend_ch("synth/LO2/mapping", _ch_name), MAPPING_NONE); } - virtual ~twinrx_rcvr_fe(void) - { - } + virtual ~twinrx_rcvr_fe(void) {} sensor_value_t get_lo_locked() { - bool locked = true; - twinrx_ctrl::channel_t ch = (_ch_name == "0") ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; + bool locked = true; + twinrx_ctrl::channel_t ch = (_ch_name == "0") ? twinrx_ctrl::CH1 + : twinrx_ctrl::CH2; locked &= _ctrl->read_lo1_locked(ch); locked &= _ctrl->read_lo2_locked(ch); return sensor_value_t("LO", locked, "locked", "unlocked"); @@ -215,8 +258,8 @@ public: private: expert_container::sptr _expert; - twinrx_ctrl::sptr _ctrl; - const std::string _ch_name; + twinrx_ctrl::sptr _ctrl; + const std::string _ch_name; }; /*! @@ -233,23 +276,23 @@ public: twinrx_rcvr(ctor_args_t args) : rx_dboard_base(args) { - _db_iface = get_iface(); - twinrx_gpio::sptr gpio_iface = std::make_shared<twinrx_gpio>(_db_iface); + _db_iface = get_iface(); + twinrx_gpio::sptr gpio_iface = std::make_shared<twinrx_gpio>(_db_iface); twinrx_cpld_regmap::sptr cpld_regs = std::make_shared<twinrx_cpld_regmap>(); cpld_regs->initialize(*gpio_iface, false); - _ctrl = twinrx_ctrl::make(_db_iface, gpio_iface, cpld_regs, get_rx_id()); + _ctrl = twinrx_ctrl::make(_db_iface, gpio_iface, cpld_regs, get_rx_id()); _expert = expert_factory::create_container("twinrx_expert"); } - virtual ~twinrx_rcvr(void) - { - } + virtual ~twinrx_rcvr(void) {} - inline expert_container::sptr get_expert() { + inline expert_container::sptr get_expert() + { return _expert; } - inline twinrx_ctrl::sptr get_ctrl() { + inline twinrx_ctrl::sptr get_ctrl() + { return _ctrl; } @@ -258,38 +301,49 @@ public: //--------------------------------------------------------- // Add internal channel-agnostic data nodes to expert //--------------------------------------------------------- - expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>(_expert, - "com/LO1/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); - expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>(_expert, - "com/LO2/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); - expert_factory::add_data_node<twinrx_ctrl::antenna_mapping_t>(_expert, - "com/ant_mapping", twinrx_ctrl::ANTX_NATIVE); - expert_factory::add_data_node<twinrx_ctrl::cal_mode_t>(_expert, - "com/cal_mode", twinrx_ctrl::CAL_DISABLED); - expert_factory::add_data_node<bool>(_expert, - "com/synth/LO1/hopping_enabled", false); - expert_factory::add_data_node<bool>(_expert, - "com/synth/LO2/hopping_enabled", false); + expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>( + _expert, "com/LO1/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); + expert_factory::add_data_node<twinrx_ctrl::lo_export_source_t>( + _expert, "com/LO2/export_source", twinrx_ctrl::LO_EXPORT_DISABLED); + expert_factory::add_data_node<twinrx_ctrl::antenna_mapping_t>( + _expert, "com/ant_mapping", twinrx_ctrl::ANTX_NATIVE); + expert_factory::add_data_node<twinrx_ctrl::cal_mode_t>( + _expert, "com/cal_mode", twinrx_ctrl::CAL_DISABLED); + expert_factory::add_data_node<bool>( + _expert, "com/synth/LO1/hopping_enabled", false); + expert_factory::add_data_node<bool>( + _expert, "com/synth/LO2/hopping_enabled", false); //--------------------------------------------------------- // Add workers to expert //--------------------------------------------------------- - //Channel (front-end) specific - for(const std::string& fe: _fe_names) { - expert_factory::add_worker_node<twinrx_freq_path_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_freq_coercion_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_chan_gain_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_scheduling_expert>(_expert, _expert->node_retriever(), fe); - expert_factory::add_worker_node<twinrx_nyquist_expert>(_expert, _expert->node_retriever(), fe, _db_iface); + // Channel (front-end) specific + for (const std::string& fe : _fe_names) { + expert_factory::add_worker_node<twinrx_freq_path_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_freq_coercion_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_chan_gain_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_scheduling_expert>( + _expert, _expert->node_retriever(), fe); + expert_factory::add_worker_node<twinrx_nyquist_expert>( + _expert, _expert->node_retriever(), fe, _db_iface); } - //Channel (front-end) agnostic - expert_factory::add_worker_node<twinrx_lo_config_expert>(_expert, _expert->node_retriever()); - expert_factory::add_worker_node<twinrx_lo_mapping_expert>(_expert, _expert->node_retriever(), STAGE_LO1); - expert_factory::add_worker_node<twinrx_lo_mapping_expert>(_expert, _expert->node_retriever(), STAGE_LO2); - expert_factory::add_worker_node<twinrx_antenna_expert>(_expert, _expert->node_retriever()); - expert_factory::add_worker_node<twinrx_ant_gain_expert>(_expert, _expert->node_retriever()); - expert_factory::add_worker_node<twinrx_settings_expert>(_expert, _expert->node_retriever(), _ctrl); + // Channel (front-end) agnostic + expert_factory::add_worker_node<twinrx_lo_config_expert>( + _expert, _expert->node_retriever()); + expert_factory::add_worker_node<twinrx_lo_mapping_expert>( + _expert, _expert->node_retriever(), STAGE_LO1); + expert_factory::add_worker_node<twinrx_lo_mapping_expert>( + _expert, _expert->node_retriever(), STAGE_LO2); + expert_factory::add_worker_node<twinrx_antenna_expert>( + _expert, _expert->node_retriever()); + expert_factory::add_worker_node<twinrx_ant_gain_expert>( + _expert, _expert->node_retriever()); + expert_factory::add_worker_node<twinrx_settings_expert>( + _expert, _expert->node_retriever(), _ctrl); /*//Expert debug code std::ofstream dot_file("/tmp/twinrx.dot", std::ios::out); @@ -316,24 +370,27 @@ public: } protected: - inline void add_twinrx_fe(const std::string& name) { + inline void add_twinrx_fe(const std::string& name) + { _fe_names.push_back(name); } private: typedef std::map<std::string, dboard_base::sptr> twinrx_fe_map_t; - dboard_iface::sptr _db_iface; - twinrx_ctrl::sptr _ctrl; - std::vector<std::string> _fe_names; - expert_container::sptr _expert; + dboard_iface::sptr _db_iface; + twinrx_ctrl::sptr _ctrl; + std::vector<std::string> _fe_names; + expert_container::sptr _expert; }; /*! * Initialization Sequence for each TwinRX board: * - make_twinrx_container is called which creates an instance of twinrx_rcvr - * - twinrx_rcvr::make_twinrx_fe is called with channel "0" which creates an instance of twinrx_rcvr_fe - * - twinrx_rcvr::make_twinrx_fe is called with channel "1" which creates an instance of twinrx_rcvr_fe + * - twinrx_rcvr::make_twinrx_fe is called with channel "0" which creates an instance of + * twinrx_rcvr_fe + * - twinrx_rcvr::make_twinrx_fe is called with channel "1" which creates an instance of + * twinrx_rcvr_fe * - twinrx_rcvr::initialize is called with finishes the init sequence * */ @@ -344,27 +401,21 @@ static dboard_base::sptr make_twinrx_container(dboard_base::ctor_args_t args) UHD_STATIC_BLOCK(reg_twinrx_dboards) { - dboard_manager::register_dboard_restricted( - twinrx::TWINRX_REV_A_ID, + dboard_manager::register_dboard_restricted(twinrx::TWINRX_REV_A_ID, &twinrx_rcvr::make_twinrx_fe, "TwinRX Rev A", {"0", "1"}, - &make_twinrx_container - ); + &make_twinrx_container); - dboard_manager::register_dboard_restricted( - twinrx::TWINRX_REV_B_ID, + dboard_manager::register_dboard_restricted(twinrx::TWINRX_REV_B_ID, &twinrx_rcvr::make_twinrx_fe, "TwinRX Rev B", {"0", "1"}, - &make_twinrx_container - ); + &make_twinrx_container); - dboard_manager::register_dboard_restricted( - twinrx::TWINRX_REV_C_ID, + dboard_manager::register_dboard_restricted(twinrx::TWINRX_REV_C_ID, &twinrx_rcvr::make_twinrx_fe, "TwinRX Rev C", {"0", "1"}, - &make_twinrx_container - ); + &make_twinrx_container); } diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp index 3771c9f2d..8ac96a2fe 100644 --- a/host/lib/usrp/dboard/db_ubx.cpp +++ b/host/lib/usrp/dboard/db_ubx.cpp @@ -34,8 +34,7 @@ using namespace uhd::usrp; /*********************************************************************** * UBX Data Structures **********************************************************************/ -enum ubx_gpio_field_id_t -{ +enum ubx_gpio_field_id_t { SPI_ADDR, TX_EN_N, RX_EN_N, @@ -51,34 +50,33 @@ enum ubx_gpio_field_id_t TXLO2_SYNC }; -enum ubx_cpld_field_id_t -{ - TXHB_SEL = 0, - TXLB_SEL = 1, - TXLO1_FSEL1 = 2, - TXLO1_FSEL2 = 3, - TXLO1_FSEL3 = 4, - RXHB_SEL = 5, - RXLB_SEL = 6, - RXLO1_FSEL1 = 7, - RXLO1_FSEL2 = 8, - RXLO1_FSEL3 = 9, - SEL_LNA1 = 10, - SEL_LNA2 = 11, - TXLO1_FORCEON = 12, - TXLO2_FORCEON = 13, - TXMOD_FORCEON = 14, +enum ubx_cpld_field_id_t { + TXHB_SEL = 0, + TXLB_SEL = 1, + TXLO1_FSEL1 = 2, + TXLO1_FSEL2 = 3, + TXLO1_FSEL3 = 4, + RXHB_SEL = 5, + RXLB_SEL = 6, + RXLO1_FSEL1 = 7, + RXLO1_FSEL2 = 8, + RXLO1_FSEL3 = 9, + SEL_LNA1 = 10, + SEL_LNA2 = 11, + TXLO1_FORCEON = 12, + TXLO2_FORCEON = 13, + TXMOD_FORCEON = 14, TXMIXER_FORCEON = 15, - TXDRV_FORCEON = 16, - RXLO1_FORCEON = 17, - RXLO2_FORCEON = 18, + TXDRV_FORCEON = 16, + RXLO1_FORCEON = 17, + RXLO2_FORCEON = 18, RXDEMOD_FORCEON = 19, RXMIXER_FORCEON = 20, - RXDRV_FORCEON = 21, - RXAMP_FORCEON = 22, - RXLNA1_FORCEON = 23, - RXLNA2_FORCEON = 24, - CAL_ENABLE = 25 + RXDRV_FORCEON = 21, + RXAMP_FORCEON = 22, + RXLNA1_FORCEON = 23, + RXLNA2_FORCEON = 24, + CAL_ENABLE = 25 }; struct ubx_gpio_field_info_t @@ -88,7 +86,7 @@ struct ubx_gpio_field_info_t uint32_t offset; uint32_t mask; uint32_t width; - enum {OUTPUT,INPUT} direction; + enum { OUTPUT, INPUT } direction; bool is_atr_controlled; uint32_t atr_idle; uint32_t atr_tx; @@ -125,12 +123,12 @@ struct ubx_cpld_reg_t }; enum spi_dest_t { - TXLO1 = 0x0, // 0x00: TXLO1, the main TXLO from 400MHz to 6000MHz - TXLO2 = 0x1, // 0x01: TXLO2, the low band mixer TXLO 10MHz to 400MHz - RXLO1 = 0x2, // 0x02: RXLO1, the main RXLO from 400MHz to 6000MHz - RXLO2 = 0x3, // 0x03: RXLO2, the low band mixer RXLO 10MHz to 400MHz - CPLD = 0x4 // 0x04: CPLD SPI Register - }; + TXLO1 = 0x0, // 0x00: TXLO1, the main TXLO from 400MHz to 6000MHz + TXLO2 = 0x1, // 0x01: TXLO2, the low band mixer TXLO 10MHz to 400MHz + RXLO1 = 0x2, // 0x02: RXLO1, the main RXLO from 400MHz to 6000MHz + RXLO2 = 0x3, // 0x03: RXLO2, the low band mixer RXLO 10MHz to 400MHz + CPLD = 0x4 // 0x04: CPLD SPI Register +}; /*********************************************************************** * UBX Constants @@ -198,11 +196,11 @@ static const ubx_gpio_field_info_t ubx_v1_gpio_info[] = { /*********************************************************************** * Macros for routing and writing SPI registers **********************************************************************/ -#define ROUTE_SPI(iface, dest) \ +#define ROUTE_SPI(iface, dest) \ set_gpio_field(SPI_ADDR, dest); \ write_gpio(); -#define WRITE_SPI(iface, val) \ +#define WRITE_SPI(iface, val) \ iface->write_spi(dboard_iface::UNIT_TX, spi_config_t::EDGE_RISE, val, 32); /*********************************************************************** @@ -213,91 +211,85 @@ class ubx_xcvr : public xcvr_dboard_base public: ubx_xcvr(ctor_args_t args) : xcvr_dboard_base(args) { - double bw = 40e6; + double bw = 40e6; double pfd_freq_max = 25e6; //////////////////////////////////////////////////////////////////// // Setup GPIO hardware //////////////////////////////////////////////////////////////////// - _iface = get_iface(); + _iface = get_iface(); dboard_id_t rx_id = get_rx_id(); dboard_id_t tx_id = get_tx_id(); - size_t revision = 1; // default to rev A + size_t revision = 1; // default to rev A // Get revision if programmed const std::string revision_str = get_rx_eeprom().revision; - if (not revision_str.empty()) - { + if (not revision_str.empty()) { revision = boost::lexical_cast<size_t>(revision_str); } _high_isolation = false; if (rx_id == UBX_PROTO_V3_RX_ID and tx_id == UBX_PROTO_V3_TX_ID) { _rev = 0; - } - else if (rx_id == UBX_PROTO_V4_RX_ID and tx_id == UBX_PROTO_V4_TX_ID) { + } else if (rx_id == UBX_PROTO_V4_RX_ID and tx_id == UBX_PROTO_V4_TX_ID) { _rev = 1; - } - else if (rx_id == UBX_V1_40MHZ_RX_ID and tx_id == UBX_V1_40MHZ_TX_ID) { + } else if (rx_id == UBX_V1_40MHZ_RX_ID and tx_id == UBX_V1_40MHZ_TX_ID) { _rev = 1; - } - else if (rx_id == UBX_V2_40MHZ_RX_ID and tx_id == UBX_V2_40MHZ_TX_ID) { + } else if (rx_id == UBX_V2_40MHZ_RX_ID and tx_id == UBX_V2_40MHZ_TX_ID) { _rev = 2; - if (revision >= 4) - { + if (revision >= 4) { _high_isolation = true; } - } - else if (rx_id == UBX_V1_160MHZ_RX_ID and tx_id == UBX_V1_160MHZ_TX_ID) { - bw = 160e6; + } else if (rx_id == UBX_V1_160MHZ_RX_ID and tx_id == UBX_V1_160MHZ_TX_ID) { + bw = 160e6; _rev = 1; - } - else if (rx_id == UBX_V2_160MHZ_RX_ID and tx_id == UBX_V2_160MHZ_TX_ID) { - bw = 160e6; + } else if (rx_id == UBX_V2_160MHZ_RX_ID and tx_id == UBX_V2_160MHZ_TX_ID) { + bw = 160e6; _rev = 2; - if (revision >= 4) - { + if (revision >= 4) { _high_isolation = true; } - } - else if (rx_id == UBX_LP_160MHZ_RX_ID and tx_id == UBX_LP_160MHZ_TX_ID) { + } else if (rx_id == UBX_LP_160MHZ_RX_ID and tx_id == UBX_LP_160MHZ_TX_ID) { // The LP version behaves and looks like a regular UBX-160 v2 - bw = 160e6; - _rev = 2; - } - else if (rx_id == UBX_TDD_160MHZ_RX_ID and tx_id == UBX_TDD_160MHZ_TX_ID) { - bw = 160e6; + bw = 160e6; _rev = 2; + } else if (rx_id == UBX_TDD_160MHZ_RX_ID and tx_id == UBX_TDD_160MHZ_TX_ID) { + bw = 160e6; + _rev = 2; _high_isolation = true; - } - else { + } else { UHD_THROW_INVALID_CODE_PATH(); } - switch(_rev) - { - case 0: - for (size_t i = 0; i < sizeof(ubx_proto_gpio_info) / sizeof(ubx_gpio_field_info_t); i++) - _gpio_map[ubx_proto_gpio_info[i].id] = ubx_proto_gpio_info[i]; - pfd_freq_max = 25e6; - break; - case 1: - case 2: - for (size_t i = 0; i < sizeof(ubx_v1_gpio_info) / sizeof(ubx_gpio_field_info_t); i++) - _gpio_map[ubx_v1_gpio_info[i].id] = ubx_v1_gpio_info[i]; - pfd_freq_max = 50e6; - break; + switch (_rev) { + case 0: + for (size_t i = 0; + i < sizeof(ubx_proto_gpio_info) / sizeof(ubx_gpio_field_info_t); + i++) + _gpio_map[ubx_proto_gpio_info[i].id] = ubx_proto_gpio_info[i]; + pfd_freq_max = 25e6; + break; + case 1: + case 2: + for (size_t i = 0; + i < sizeof(ubx_v1_gpio_info) / sizeof(ubx_gpio_field_info_t); + i++) + _gpio_map[ubx_v1_gpio_info[i].id] = ubx_v1_gpio_info[i]; + pfd_freq_max = 50e6; + break; } // Initialize GPIO registers - memset(&_tx_gpio_reg,0,sizeof(ubx_gpio_reg_t)); - memset(&_rx_gpio_reg,0,sizeof(ubx_gpio_reg_t)); - for (std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t>::iterator entry = _gpio_map.begin(); entry != _gpio_map.end(); entry++) - { + memset(&_tx_gpio_reg, 0, sizeof(ubx_gpio_reg_t)); + memset(&_rx_gpio_reg, 0, sizeof(ubx_gpio_reg_t)); + for (std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t>::iterator entry = + _gpio_map.begin(); + entry != _gpio_map.end(); + entry++) { ubx_gpio_field_info_t info = entry->second; - ubx_gpio_reg_t *reg = (info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); + ubx_gpio_reg_t* reg = + (info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); if (info.direction == ubx_gpio_field_info_t::INPUT) reg->ddr |= info.mask; - if (info.is_atr_controlled) - { + if (info.is_atr_controlled) { reg->atr_mask |= info.mask; reg->atr_idle |= (info.atr_idle << info.offset) & info.mask; reg->atr_tx |= (info.atr_tx << info.offset) & info.mask; @@ -309,44 +301,40 @@ public: // Enable the reference clocks that we need _rx_target_pfd_freq = pfd_freq_max; _tx_target_pfd_freq = pfd_freq_max; - if (_rev >= 1) - { + if (_rev >= 1) { bool can_set_clock_rate = true; // set dboard clock rates to as close to the max PFD freq as possible - if (_iface->get_clock_rate(dboard_iface::UNIT_RX) > pfd_freq_max) - { - std::vector<double> rates = _iface->get_clock_rates(dboard_iface::UNIT_RX); + if (_iface->get_clock_rate(dboard_iface::UNIT_RX) > pfd_freq_max) { + std::vector<double> rates = + _iface->get_clock_rates(dboard_iface::UNIT_RX); double highest_rate = 0.0; - for(double rate: rates) - { + for (double rate : rates) { if (rate <= pfd_freq_max and rate > highest_rate) highest_rate = rate; } try { _iface->set_clock_rate(dboard_iface::UNIT_RX, highest_rate); - } catch (const uhd::not_implemented_error &) { - UHD_LOG_WARNING("UBX", - "Unable to set dboard clock rate - phase will vary" - ); + } catch (const uhd::not_implemented_error&) { + UHD_LOG_WARNING( + "UBX", "Unable to set dboard clock rate - phase will vary"); can_set_clock_rate = false; } _rx_target_pfd_freq = highest_rate; } - if (can_set_clock_rate and _iface->get_clock_rate(dboard_iface::UNIT_TX) > pfd_freq_max) - { - std::vector<double> rates = _iface->get_clock_rates(dboard_iface::UNIT_TX); + if (can_set_clock_rate + and _iface->get_clock_rate(dboard_iface::UNIT_TX) > pfd_freq_max) { + std::vector<double> rates = + _iface->get_clock_rates(dboard_iface::UNIT_TX); double highest_rate = 0.0; - for(double rate: rates) - { + for (double rate : rates) { if (rate <= pfd_freq_max and rate > highest_rate) highest_rate = rate; } try { _iface->set_clock_rate(dboard_iface::UNIT_TX, highest_rate); - } catch (const uhd::not_implemented_error &) { - UHD_LOG_WARNING("UBX", - "Unable to set dboard clock rate - phase will vary" - ); + } catch (const uhd::not_implemented_error&) { + UHD_LOG_WARNING( + "UBX", "Unable to set dboard clock rate - phase will vary"); } _tx_target_pfd_freq = highest_rate; } @@ -373,97 +361,127 @@ public: write_gpio(); // Configure ATR - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _tx_gpio_reg.atr_idle); - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx); - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx); - _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _tx_gpio_reg.atr_full_duplex); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _rx_gpio_reg.atr_idle); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx); - _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _rx_gpio_reg.atr_full_duplex); + _iface->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _tx_gpio_reg.atr_idle); + _iface->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx); + _iface->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx); + _iface->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _tx_gpio_reg.atr_full_duplex); + _iface->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _rx_gpio_reg.atr_idle); + _iface->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx); + _iface->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx); + _iface->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + _rx_gpio_reg.atr_full_duplex); // Engage ATR control (1 is ATR control, 0 is manual control) _iface->set_pin_ctrl(dboard_iface::UNIT_TX, _tx_gpio_reg.atr_mask); _iface->set_pin_ctrl(dboard_iface::UNIT_RX, _rx_gpio_reg.atr_mask); // bring CPLD out of reset - std::this_thread::sleep_for(std::chrono::milliseconds(20)); // hold CPLD reset for minimum of 20 ms + std::this_thread::sleep_for( + std::chrono::milliseconds(20)); // hold CPLD reset for minimum of 20 ms set_gpio_field(CPLD_RST_N, 1); write_gpio(); // Initialize LOs - if (_rev == 0) - { - _txlo1 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); - _txlo2 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); - _rxlo1 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); - _rxlo2 = max287x_iface::make<max2870>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); + if (_rev == 0) { + _txlo1 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); + _txlo2 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); + _rxlo1 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); + _rxlo2 = max287x_iface::make<max2870>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); std::vector<max287x_iface::sptr> los{_txlo1, _txlo2, _rxlo1, _rxlo2}; - for(max287x_iface::sptr lo: los) - { + for (max287x_iface::sptr lo : los) { lo->set_auto_retune(false); lo->set_muxout_mode(max287x_iface::MUXOUT_DLD); lo->set_ld_pin_mode(max287x_iface::LD_PIN_MODE_DLD); } - } - else if (_rev == 1 or _rev == 2) - { - _txlo1 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); - _txlo2 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); - _rxlo1 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); - _rxlo2 = max287x_iface::make<max2871>(std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); + } else if (_rev == 1 or _rev == 2) { + _txlo1 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO1, std::placeholders::_1)); + _txlo2 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, TXLO2, std::placeholders::_1)); + _rxlo1 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO1, std::placeholders::_1)); + _rxlo2 = max287x_iface::make<max2871>( + std::bind(&ubx_xcvr::write_spi_regs, this, RXLO2, std::placeholders::_1)); std::vector<max287x_iface::sptr> los{_txlo1, _txlo2, _rxlo1, _rxlo2}; - for(max287x_iface::sptr lo: los) - { + for (max287x_iface::sptr lo : los) { lo->set_auto_retune(false); - //lo->set_cycle_slip_mode(true); // tried it - caused longer lock times + // lo->set_cycle_slip_mode(true); // tried it - caused longer lock times lo->set_charge_pump_current(max287x_iface::CHARGE_PUMP_CURRENT_5_12MA); lo->set_muxout_mode(max287x_iface::MUXOUT_SYNC); lo->set_ld_pin_mode(max287x_iface::LD_PIN_MODE_DLD); } - } - else - { + } else { UHD_THROW_INVALID_CODE_PATH(); } // Initialize CPLD register _prev_cpld_value = 0xFFFF; - _cpld_reg.value = 0; + _cpld_reg.value = 0; write_cpld_reg(); //////////////////////////////////////////////////////////////////// // Register power save properties //////////////////////////////////////////////////////////////////// - get_rx_subtree()->create<std::vector<std::string> >("power_mode/options") + get_rx_subtree() + ->create<std::vector<std::string>>("power_mode/options") .set(ubx_power_modes); - get_rx_subtree()->create<std::string>("power_mode/value") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_power_mode, this, std::placeholders::_1)) + get_rx_subtree() + ->create<std::string>("power_mode/value") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_power_mode, this, std::placeholders::_1)) .set("performance"); - get_rx_subtree()->create<std::vector<std::string> >("xcvr_mode/options") + get_rx_subtree() + ->create<std::vector<std::string>>("xcvr_mode/options") .set(ubx_xcvr_modes); - get_rx_subtree()->create<std::string>("xcvr_mode/value") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_xcvr_mode, this, std::placeholders::_1)) + get_rx_subtree() + ->create<std::string>("xcvr_mode/value") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_xcvr_mode, this, std::placeholders::_1)) .set("FDX"); - get_rx_subtree()->create<std::vector<std::string> >("temp_comp_mode/options") + get_rx_subtree() + ->create<std::vector<std::string>>("temp_comp_mode/options") .set(ubx_temp_comp_modes); get_rx_subtree() ->create<std::string>("temp_comp_mode/value") .add_coerced_subscriber( [this](std::string mode) { this->set_temp_comp_mode(mode); }) .set("disabled"); - get_tx_subtree()->create<std::vector<std::string> >("power_mode/options") + get_tx_subtree() + ->create<std::vector<std::string>>("power_mode/options") .set(ubx_power_modes); - get_tx_subtree()->create<std::string>("power_mode/value") - .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("power_mode/value"), std::placeholders::_1)) - .set_publisher(std::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("power_mode/value"))); - get_tx_subtree()->create<std::vector<std::string> >("xcvr_mode/options") + get_tx_subtree() + ->create<std::string>("power_mode/value") + .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, + &get_rx_subtree()->access<std::string>("power_mode/value"), + std::placeholders::_1)) + .set_publisher(std::bind(&uhd::property<std::string>::get, + &get_rx_subtree()->access<std::string>("power_mode/value"))); + get_tx_subtree() + ->create<std::vector<std::string>>("xcvr_mode/options") .set(ubx_xcvr_modes); - get_tx_subtree()->create<std::string>("xcvr_mode/value") - .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("xcvr_mode/value"), std::placeholders::_1)) - .set_publisher(std::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("xcvr_mode/value"))); - get_tx_subtree()->create<std::vector<std::string> >("temp_comp_mode/options") + get_tx_subtree() + ->create<std::string>("xcvr_mode/value") + .add_coerced_subscriber(std::bind(&uhd::property<std::string>::set, + &get_rx_subtree()->access<std::string>("xcvr_mode/value"), + std::placeholders::_1)) + .set_publisher(std::bind(&uhd::property<std::string>::get, + &get_rx_subtree()->access<std::string>("xcvr_mode/value"))); + get_tx_subtree() + ->create<std::vector<std::string>>("temp_comp_mode/options") .set(ubx_temp_comp_modes); get_tx_subtree() ->create<std::string>("temp_comp_mode/value") @@ -483,83 +501,84 @@ public: // Register TX properties //////////////////////////////////////////////////////////////////// get_tx_subtree()->create<std::string>("name").set("UBX TX"); - get_tx_subtree()->create<device_addr_t>("tune_args") - .set(device_addr_t()); - get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + get_tx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); + get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&ubx_xcvr::get_locked, this, "TXLO")); - get_tx_subtree()->create<double>("gains/PGA0/value") - .set_coercer(std::bind(&ubx_xcvr::set_tx_gain, this, std::placeholders::_1)).set(0); - get_tx_subtree()->create<meta_range_t>("gains/PGA0/range") - .set(ubx_tx_gain_range); - get_tx_subtree()->create<double>("freq/value") + get_tx_subtree() + ->create<double>("gains/PGA0/value") + .set_coercer(std::bind(&ubx_xcvr::set_tx_gain, this, std::placeholders::_1)) + .set(0); + get_tx_subtree()->create<meta_range_t>("gains/PGA0/range").set(ubx_tx_gain_range); + get_tx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&ubx_xcvr::set_tx_freq, this, std::placeholders::_1)) .set(ubx_freq_range.start()); - get_tx_subtree()->create<meta_range_t>("freq/range") - .set(ubx_freq_range); - get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + get_tx_subtree()->create<meta_range_t>("freq/range").set(ubx_freq_range); + get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(ubx_tx_antennas); - get_tx_subtree()->create<std::string>("antenna/value") + get_tx_subtree() + ->create<std::string>("antenna/value") .set_coercer(std::bind(&ubx_xcvr::set_tx_ant, this, std::placeholders::_1)) .set(ubx_tx_antennas.at(0)); - get_tx_subtree()->create<std::string>("connection") - .set("QI"); - get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - get_tx_subtree()->create<double>("bandwidth/value") - .set(bw); - get_tx_subtree()->create<meta_range_t>("bandwidth/range") + get_tx_subtree()->create<std::string>("connection").set("QI"); + get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + get_tx_subtree()->create<bool>("use_lo_offset").set(false); + get_tx_subtree()->create<double>("bandwidth/value").set(bw); + get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(bw, bw)); - get_tx_subtree()->create<int64_t>("sync_delay") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_sync_delay, this, true, std::placeholders::_1)) + get_tx_subtree() + ->create<int64_t>("sync_delay") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_sync_delay, this, true, std::placeholders::_1)) .set(0); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// get_rx_subtree()->create<std::string>("name").set("UBX RX"); - get_rx_subtree()->create<device_addr_t>("tune_args") - .set(device_addr_t()); - get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); + get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&ubx_xcvr::get_locked, this, "RXLO")); - get_rx_subtree()->create<double>("gains/PGA0/value") + get_rx_subtree() + ->create<double>("gains/PGA0/value") .set_coercer(std::bind(&ubx_xcvr::set_rx_gain, this, std::placeholders::_1)) .set(0); - get_rx_subtree()->create<meta_range_t>("gains/PGA0/range") - .set(ubx_rx_gain_range); - get_rx_subtree()->create<double>("freq/value") + get_rx_subtree()->create<meta_range_t>("gains/PGA0/range").set(ubx_rx_gain_range); + get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&ubx_xcvr::set_rx_freq, this, std::placeholders::_1)) .set(ubx_freq_range.start()); - get_rx_subtree()->create<meta_range_t>("freq/range") - .set(ubx_freq_range); - get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + get_rx_subtree()->create<meta_range_t>("freq/range").set(ubx_freq_range); + get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(ubx_rx_antennas); - get_rx_subtree()->create<std::string>("antenna/value") - .set_coercer(std::bind(&ubx_xcvr::set_rx_ant, this, std::placeholders::_1)).set("RX2"); - get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - get_rx_subtree()->create<double>("bandwidth/value") - .set(bw); - get_rx_subtree()->create<meta_range_t>("bandwidth/range") + get_rx_subtree() + ->create<std::string>("antenna/value") + .set_coercer(std::bind(&ubx_xcvr::set_rx_ant, this, std::placeholders::_1)) + .set("RX2"); + get_rx_subtree()->create<std::string>("connection").set("IQ"); + get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + get_rx_subtree()->create<bool>("use_lo_offset").set(false); + get_rx_subtree()->create<double>("bandwidth/value").set(bw); + get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(bw, bw)); - get_rx_subtree()->create<int64_t>("sync_delay") - .add_coerced_subscriber(std::bind(&ubx_xcvr::set_sync_delay, this, false, std::placeholders::_1)) + get_rx_subtree() + ->create<int64_t>("sync_delay") + .add_coerced_subscriber( + std::bind(&ubx_xcvr::set_sync_delay, this, false, std::placeholders::_1)) .set(0); } virtual ~ubx_xcvr(void) { - UHD_SAFE_CALL - ( + UHD_SAFE_CALL( // Shutdown synthesizers - _txlo1->shutdown(); - _txlo2->shutdown(); - _rxlo1->shutdown(); + _txlo1->shutdown(); _txlo2->shutdown(); _rxlo1->shutdown(); _rxlo2->shutdown(); // Reset CPLD values @@ -578,17 +597,16 @@ public: set_gpio_field(TXLO2_SYNC, 0); set_gpio_field(RXLO1_SYNC, 0); set_gpio_field(RXLO1_SYNC, 0); - write_gpio(); - ) + write_gpio();) } private: - enum power_mode_t {PERFORMANCE,POWERSAVE}; - enum xcvr_mode_t {FDX, TDD, TX, RX, FAST_TDD}; + enum power_mode_t { PERFORMANCE, POWERSAVE }; + enum xcvr_mode_t { FDX, TDD, TX, RX, FAST_TDD }; /*********************************************************************** - * Helper Functions - **********************************************************************/ + * Helper Functions + **********************************************************************/ void write_spi_reg(spi_dest_t dest, uint32_t value) { boost::mutex::scoped_lock lock(_spi_mutex); @@ -600,7 +618,7 @@ private: { boost::mutex::scoped_lock lock(_spi_mutex); ROUTE_SPI(_iface, dest); - for(uint32_t value: values) + for (uint32_t value : values) WRITE_SPI(_iface, value); } @@ -611,8 +629,7 @@ private: void write_cpld_reg() { - if (_cpld_reg.value != _prev_cpld_value) - { + if (_cpld_reg.value != _prev_cpld_value) { write_spi_reg(CPLD, _cpld_reg.value); _prev_cpld_value = _cpld_reg.value; } @@ -621,15 +638,17 @@ private: void set_gpio_field(ubx_gpio_field_id_t id, uint32_t value) { // Look up field info - std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t>::iterator entry = _gpio_map.find(id); + std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t>::iterator entry = + _gpio_map.find(id); if (entry == _gpio_map.end()) return; ubx_gpio_field_info_t field_info = entry->second; if (field_info.direction == ubx_gpio_field_info_t::OUTPUT) return; - ubx_gpio_reg_t *reg = (field_info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); + ubx_gpio_reg_t* reg = + (field_info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); uint32_t _value = reg->value; - uint32_t _mask = reg->mask; + uint32_t _mask = reg->mask; // Set field and mask _value &= ~field_info.mask; @@ -637,10 +656,9 @@ private: _mask |= field_info.mask; // Mark whether register is dirty or not - if (_value != reg->value) - { + if (_value != reg->value) { reg->value = _value; - reg->mask = _mask; + reg->mask = _mask; reg->dirty = true; } } @@ -648,13 +666,15 @@ private: uint32_t get_gpio_field(ubx_gpio_field_id_t id) { // Look up field info - std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t>::iterator entry = _gpio_map.find(id); + std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t>::iterator entry = + _gpio_map.find(id); if (entry == _gpio_map.end()) return 0; ubx_gpio_field_info_t field_info = entry->second; - if (field_info.direction == ubx_gpio_field_info_t::INPUT) - { - ubx_gpio_reg_t *reg = (field_info.unit == dboard_iface::UNIT_TX ? &_tx_gpio_reg : &_rx_gpio_reg); + if (field_info.direction == ubx_gpio_field_info_t::INPUT) { + ubx_gpio_reg_t* reg = (field_info.unit == dboard_iface::UNIT_TX + ? &_tx_gpio_reg + : &_rx_gpio_reg); return (reg->value >> field_info.offset) & field_info.mask; } @@ -669,25 +689,24 @@ private: void write_gpio() { - if (_tx_gpio_reg.dirty) - { - _iface->set_gpio_out(dboard_iface::UNIT_TX, _tx_gpio_reg.value, _tx_gpio_reg.mask); + if (_tx_gpio_reg.dirty) { + _iface->set_gpio_out( + dboard_iface::UNIT_TX, _tx_gpio_reg.value, _tx_gpio_reg.mask); _tx_gpio_reg.dirty = false; - _tx_gpio_reg.mask = 0; + _tx_gpio_reg.mask = 0; } - if (_rx_gpio_reg.dirty) - { - _iface->set_gpio_out(dboard_iface::UNIT_RX, _rx_gpio_reg.value, _rx_gpio_reg.mask); + if (_rx_gpio_reg.dirty) { + _iface->set_gpio_out( + dboard_iface::UNIT_RX, _rx_gpio_reg.value, _rx_gpio_reg.mask); _rx_gpio_reg.dirty = false; - _rx_gpio_reg.mask = 0; + _rx_gpio_reg.mask = 0; } } void sync_phase(uhd::time_spec_t cmd_time, uhd::direction_t dir) { // Send phase sync signal only if the command time is set - if (cmd_time != uhd::time_spec_t(0.0)) - { + if (cmd_time != uhd::time_spec_t(0.0)) { // Delay 400 microseconds to allow LOs to lock cmd_time += uhd::time_spec_t(0.0004); @@ -703,14 +722,17 @@ private: // multiple of the system reference, and the device time has been // set on a PPS edge sampled by the system reference clock. - const double pfd_freq = _iface->get_clock_rate(dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); - const double tick_rate = _iface->get_codec_rate(dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); + const double pfd_freq = _iface->get_clock_rate( + dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); + const double tick_rate = _iface->get_codec_rate( + dir == TX_DIRECTION ? dboard_iface::UNIT_TX : dboard_iface::UNIT_RX); const int64_t ticks_per_pfd_cycle = (int64_t)(tick_rate / pfd_freq); // Convert time to ticks int64_t ticks = cmd_time.to_ticks(tick_rate); // Align time to next falling edge of dboard clock - ticks += ticks_per_pfd_cycle - (ticks % ticks_per_pfd_cycle) + (ticks_per_pfd_cycle / 2); + ticks += ticks_per_pfd_cycle - (ticks % ticks_per_pfd_cycle) + + (ticks_per_pfd_cycle / 2); // Add any user specified delay ticks += dir == TX_DIRECTION ? _tx_sync_delay : _rx_sync_delay; // Set the command time @@ -718,20 +740,22 @@ private: _iface->set_command_time(cmd_time); // Assert SYNC - ubx_gpio_field_info_t lo1_field_info = _gpio_map.find(dir == TX_DIRECTION ? TXLO1_SYNC : RXLO1_SYNC)->second; - ubx_gpio_field_info_t lo2_field_info = _gpio_map.find(dir == TX_DIRECTION ? TXLO2_SYNC : RXLO2_SYNC)->second; + ubx_gpio_field_info_t lo1_field_info = + _gpio_map.find(dir == TX_DIRECTION ? TXLO1_SYNC : RXLO1_SYNC)->second; + ubx_gpio_field_info_t lo2_field_info = + _gpio_map.find(dir == TX_DIRECTION ? TXLO2_SYNC : RXLO2_SYNC)->second; uint16_t value = (1 << lo1_field_info.offset) | (1 << lo2_field_info.offset); - uint16_t mask = lo1_field_info.mask | lo2_field_info.mask; + uint16_t mask = lo1_field_info.mask | lo2_field_info.mask; dboard_iface::unit_t unit = lo1_field_info.unit; UHD_ASSERT_THROW(lo1_field_info.unit == lo2_field_info.unit); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, value, mask); - cmd_time += uhd::time_spec_t(1/pfd_freq); + cmd_time += uhd::time_spec_t(1 / pfd_freq); _iface->set_command_time(cmd_time); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, value, mask); - cmd_time += uhd::time_spec_t(1/pfd_freq); + cmd_time += uhd::time_spec_t(1 / pfd_freq); _iface->set_command_time(cmd_time); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, value, mask); - cmd_time += uhd::time_spec_t(1/pfd_freq); + cmd_time += uhd::time_spec_t(1 / pfd_freq); _iface->set_command_time(cmd_time); _iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, value, mask); @@ -747,18 +771,15 @@ private: /*********************************************************************** * Board Control Handling **********************************************************************/ - sensor_value_t get_locked(const std::string &pll_name) + sensor_value_t get_locked(const std::string& pll_name) { boost::mutex::scoped_lock lock(_mutex); assert_has(ubx_plls, pll_name, "ubx pll name"); - if(pll_name == "TXLO") - { + if (pll_name == "TXLO") { _txlo_locked = (get_gpio_field(TX_LO_LOCKED) != 0); return sensor_value_t("TXLO", _txlo_locked, "locked", "unlocked"); - } - else if(pll_name == "RXLO") - { + } else if (pll_name == "RXLO") { _rxlo_locked = (get_gpio_field(RX_LO_LOCKED) != 0); return sensor_value_t("RXLO", _rxlo_locked, "locked", "unlocked"); } @@ -766,9 +787,9 @@ private: return sensor_value_t("Unknown", false, "locked", "unlocked"); } - std::string set_tx_ant(const std::string &ant) + std::string set_tx_ant(const std::string& ant) { - //validate input + // validate input assert_has(ubx_tx_antennas, ant, "ubx tx antenna name"); set_cpld_field(CAL_ENABLE, (ant == "CAL")); write_cpld_reg(); @@ -776,10 +797,10 @@ private: } // Set RX antennas - std::string set_rx_ant(const std::string &ant) + std::string set_rx_ant(const std::string& ant) { boost::mutex::scoped_lock lock(_mutex); - //validate input + // validate input assert_has(ubx_rx_antennas, ant, "ubx rx antenna name"); // There can be long transients on TX, so force on the TX PA @@ -788,14 +809,18 @@ private: // is set to TX/RX (to prevent higher noise floor on RX). // Setting the xcvr_mode to TDD will force on the PA when // not in powersave mode regardless of the board revision. - if (ant == "TX/RX") - { + if (ant == "TX/RX") { set_gpio_field(RX_ANT, 0); - // Force on TX PA for boards with high isolation or if the user sets the TDD mode - set_cpld_field(TXDRV_FORCEON, (_power_mode == POWERSAVE ? 0 : _high_isolation or _xcvr_mode == TDD ? 1 : 0)); + // Force on TX PA for boards with high isolation or if the user sets the TDD + // mode + set_cpld_field(TXDRV_FORCEON, + (_power_mode == POWERSAVE + ? 0 + : _high_isolation or _xcvr_mode == TDD ? 1 : 0)); } else { set_gpio_field(RX_ANT, 1); - set_cpld_field(TXDRV_FORCEON, (_power_mode == POWERSAVE ? 0 : 1)); // Keep PA on + set_cpld_field( + TXDRV_FORCEON, (_power_mode == POWERSAVE ? 0 : 1)); // Keep PA on } write_gpio(); write_cpld_reg(); @@ -809,12 +834,14 @@ private: double set_tx_gain(double gain) { boost::mutex::scoped_lock lock(_mutex); - gain = ubx_tx_gain_range.clip(gain); - int attn_code = int(std::floor(gain * 2)); + gain = ubx_tx_gain_range.clip(gain); + int attn_code = int(std::floor(gain * 2)); _ubx_tx_atten_val = ((attn_code & 0x3F) << 10); set_gpio_field(TX_GAIN, attn_code); write_gpio(); - UHD_LOGGER_TRACE("UBX") << boost::format("UBX TX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain % attn_code % _ubx_tx_atten_val ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX TX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain + % attn_code % _ubx_tx_atten_val; _tx_gain = gain; return gain; } @@ -822,26 +849,28 @@ private: double set_rx_gain(double gain) { boost::mutex::scoped_lock lock(_mutex); - gain = ubx_rx_gain_range.clip(gain); - int attn_code = int(std::floor(gain * 2)); + gain = ubx_rx_gain_range.clip(gain); + int attn_code = int(std::floor(gain * 2)); _ubx_rx_atten_val = ((attn_code & 0x3F) << 10); set_gpio_field(RX_GAIN, attn_code); write_gpio(); - UHD_LOGGER_TRACE("UBX") << boost::format("UBX RX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain % attn_code % _ubx_rx_atten_val ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX RX Gain: %f dB, Code: %d, IO Bits 0x%04x") % gain + % attn_code % _ubx_rx_atten_val; _rx_gain = gain; return gain; } /*********************************************************************** - * Frequency Handling - **********************************************************************/ + * Frequency Handling + **********************************************************************/ double set_tx_freq(double freq) { boost::mutex::scoped_lock lock(_mutex); double freq_lo1 = 0.0; double freq_lo2 = 0.0; double ref_freq = _iface->get_clock_rate(dboard_iface::UNIT_TX); - bool is_int_n = false; + bool is_int_n = false; /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to @@ -849,20 +878,18 @@ private: * performance on some mixers. The default is fractional tuning. */ property_tree::sptr subtree = this->get_tx_subtree(); - device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - UHD_LOGGER_TRACE("UBX") << boost::format("UBX TX: the requested frequency is %f MHz") % (freq/1e6) ; + device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); + is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX TX: the requested frequency is %f MHz") % (freq / 1e6); double target_pfd_freq = _tx_target_pfd_freq; - if (is_int_n and tune_args.has_key("int_n_step")) - { + if (is_int_n and tune_args.has_key("int_n_step")) { target_pfd_freq = tune_args.cast<double>("int_n_step", _tx_target_pfd_freq); - if (target_pfd_freq > _tx_target_pfd_freq) - { + if (target_pfd_freq > _tx_target_pfd_freq) { UHD_LOGGER_WARNING("UBX") - << boost::format("Requested int_n_step of %f MHz too large, clipping to %f MHz") - % (target_pfd_freq/1e6) - % (_tx_target_pfd_freq/1e6) - ; + << boost::format( + "Requested int_n_step of %f MHz too large, clipping to %f MHz") + % (target_pfd_freq / 1e6) % (_tx_target_pfd_freq / 1e6); target_pfd_freq = _tx_target_pfd_freq; } } @@ -873,43 +900,39 @@ private: // Power up/down LOs if (_txlo1->is_shutdown()) _txlo1->power_up(); - if (_txlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < (500*fMHz))) + if (_txlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < (500 * fMHz))) _txlo2->power_up(); - else if (freq >= 500*fMHz and _power_mode == POWERSAVE) + else if (freq >= 500 * fMHz and _power_mode == POWERSAVE) _txlo2->shutdown(); // Set up LOs for phase sync if command time is set uhd::time_spec_t cmd_time = _iface->get_command_time(); - if (cmd_time != uhd::time_spec_t(0.0)) - { + if (cmd_time != uhd::time_spec_t(0.0)) { _txlo1->config_for_sync(true); if (not _txlo2->is_shutdown()) _txlo2->config_for_sync(true); - } - else - { + } else { _txlo1->config_for_sync(false); if (not _txlo2->is_shutdown()) _txlo2->config_for_sync(false); } // Set up registers for the requested frequency - if (freq < (500*fMHz)) - { + if (freq < (500 * fMHz)) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 1); set_cpld_field(TXLO1_FSEL1, 0); set_cpld_field(TXLB_SEL, 1); set_cpld_field(TXHB_SEL, 0); // Set LO1 to IF of 2100 MHz (offset from RX IF to reduce leakage) - freq_lo1 = _txlo1->set_frequency(2100*fMHz, ref_freq, target_pfd_freq, is_int_n); + freq_lo1 = + _txlo1->set_frequency(2100 * fMHz, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); // Set LO2 to IF minus desired frequency - freq_lo2 = _txlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); + freq_lo2 = _txlo2->set_frequency( + freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); _txlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= (500*fMHz)) && (freq <= (800*fMHz))) - { + } else if ((freq >= (500 * fMHz)) && (freq <= (800 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 0); set_cpld_field(TXLO1_FSEL1, 1); @@ -917,9 +940,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq > (800*fMHz)) && (freq <= (1000*fMHz))) - { + } else if ((freq > (800 * fMHz)) && (freq <= (1000 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 0); set_cpld_field(TXLO1_FSEL1, 1); @@ -927,9 +948,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); - } - else if ((freq > (1000*fMHz)) && (freq <= (2200*fMHz))) - { + } else if ((freq > (1000 * fMHz)) && (freq <= (2200 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 1); set_cpld_field(TXLO1_FSEL1, 0); @@ -937,9 +956,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq > (2200*fMHz)) && (freq <= (2500*fMHz))) - { + } else if ((freq > (2200 * fMHz)) && (freq <= (2500 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 0); set_cpld_field(TXLO1_FSEL2, 1); set_cpld_field(TXLO1_FSEL1, 0); @@ -947,9 +964,7 @@ private: set_cpld_field(TXHB_SEL, 1); freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq > (2500*fMHz)) && (freq <= (6000*fMHz))) - { + } else if ((freq > (2500 * fMHz)) && (freq <= (6000 * fMHz))) { set_cpld_field(TXLO1_FSEL3, 1); set_cpld_field(TXLO1_FSEL2, 0); set_cpld_field(TXLO1_FSEL1, 0); @@ -962,35 +977,37 @@ private: // To reduce the number of commands issued to the device, write to the // SPI destination already addressed first. This avoids the writes to // the GPIO registers to route the SPI to the same destination. - switch (get_gpio_field(SPI_ADDR)) - { - case TXLO1: - _txlo1->commit(); - if (freq < (500*fMHz)) _txlo2->commit(); - write_cpld_reg(); - break; - case TXLO2: - if (freq < (500*fMHz)) _txlo2->commit(); - _txlo1->commit(); - write_cpld_reg(); - break; - default: - write_cpld_reg(); - _txlo1->commit(); - if (freq < (500*fMHz)) _txlo2->commit(); - break; + switch (get_gpio_field(SPI_ADDR)) { + case TXLO1: + _txlo1->commit(); + if (freq < (500 * fMHz)) + _txlo2->commit(); + write_cpld_reg(); + break; + case TXLO2: + if (freq < (500 * fMHz)) + _txlo2->commit(); + _txlo1->commit(); + write_cpld_reg(); + break; + default: + write_cpld_reg(); + _txlo1->commit(); + if (freq < (500 * fMHz)) + _txlo2->commit(); + break; } - if (cmd_time != uhd::time_spec_t(0.0) and _txlo1->can_sync()) - { + if (cmd_time != uhd::time_spec_t(0.0) and _txlo1->can_sync()) { sync_phase(cmd_time, TX_DIRECTION); } - _tx_freq = freq_lo1 - freq_lo2; + _tx_freq = freq_lo1 - freq_lo2; _txlo1_freq = freq_lo1; _txlo2_freq = freq_lo2; - UHD_LOGGER_TRACE("UBX") << boost::format("UBX TX: the actual frequency is %f MHz") % (_tx_freq/1e6) ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX TX: the actual frequency is %f MHz") % (_tx_freq / 1e6); return _tx_freq; } @@ -1001,24 +1018,22 @@ private: double freq_lo1 = 0.0; double freq_lo2 = 0.0; double ref_freq = _iface->get_clock_rate(dboard_iface::UNIT_RX); - bool is_int_n = false; + bool is_int_n = false; - UHD_LOGGER_TRACE("UBX") << boost::format("UBX RX: the requested frequency is %f MHz") % (freq/1e6) ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX RX: the requested frequency is %f MHz") % (freq / 1e6); property_tree::sptr subtree = this->get_rx_subtree(); - device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); + device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); + is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); double target_pfd_freq = _rx_target_pfd_freq; - if (is_int_n and tune_args.has_key("int_n_step")) - { + if (is_int_n and tune_args.has_key("int_n_step")) { target_pfd_freq = tune_args.cast<double>("int_n_step", _rx_target_pfd_freq); - if (target_pfd_freq > _rx_target_pfd_freq) - { + if (target_pfd_freq > _rx_target_pfd_freq) { UHD_LOGGER_WARNING("UBX") - << boost::format("Requested int_n_step of %f Mhz too large, clipping to %f MHz") - % (target_pfd_freq/1e6) - % (_rx_target_pfd_freq/1e6) - ; + << boost::format( + "Requested int_n_step of %f Mhz too large, clipping to %f MHz") + % (target_pfd_freq / 1e6) % (_rx_target_pfd_freq / 1e6); target_pfd_freq = _rx_target_pfd_freq; } } @@ -1029,29 +1044,25 @@ private: // Power up/down LOs if (_rxlo1->is_shutdown()) _rxlo1->power_up(); - if (_rxlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < 500*fMHz)) + if (_rxlo2->is_shutdown() and (_power_mode == PERFORMANCE or freq < 500 * fMHz)) _rxlo2->power_up(); - else if (freq >= 500*fMHz and _power_mode == POWERSAVE) + else if (freq >= 500 * fMHz and _power_mode == POWERSAVE) _rxlo2->shutdown(); // Set up LOs for phase sync if command time is set uhd::time_spec_t cmd_time = _iface->get_command_time(); - if (cmd_time != uhd::time_spec_t(0.0)) - { + if (cmd_time != uhd::time_spec_t(0.0)) { _rxlo1->config_for_sync(true); if (not _rxlo2->is_shutdown()) _rxlo2->config_for_sync(true); - } - else - { + } else { _rxlo1->config_for_sync(false); if (not _rxlo2->is_shutdown()) _rxlo2->config_for_sync(false); } // Work with frequencies - if (freq < 100*fMHz) - { + if (freq < 100 * fMHz) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 1); @@ -1059,15 +1070,16 @@ private: set_cpld_field(RXLO1_FSEL1, 0); set_cpld_field(RXLB_SEL, 1); set_cpld_field(RXHB_SEL, 0); - // Set LO1 to IF of 2380 MHz (2440 MHz filter center minus 60 MHz offset to minimize LO leakage) - freq_lo1 = _rxlo1->set_frequency(2380*fMHz, ref_freq, target_pfd_freq, is_int_n); + // Set LO1 to IF of 2380 MHz (2440 MHz filter center minus 60 MHz offset to + // minimize LO leakage) + freq_lo1 = + _rxlo1->set_frequency(2380 * fMHz, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); // Set LO2 to IF minus desired frequency - freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); + freq_lo2 = _rxlo2->set_frequency( + freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); _rxlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 100*fMHz) && (freq < 500*fMHz)) - { + } else if ((freq >= 100 * fMHz) && (freq < 500 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 1); @@ -1076,14 +1088,14 @@ private: set_cpld_field(RXLB_SEL, 1); set_cpld_field(RXHB_SEL, 0); // Set LO1 to IF of 2440 (center of filter) - freq_lo1 = _rxlo1->set_frequency(2440*fMHz, ref_freq, target_pfd_freq, is_int_n); + freq_lo1 = + _rxlo1->set_frequency(2440 * fMHz, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); // Set LO2 to IF minus desired frequency - freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); + freq_lo2 = _rxlo2->set_frequency( + freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 500*fMHz) && (freq < 800*fMHz)) - { + } else if ((freq >= 500 * fMHz) && (freq < 800 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 0); @@ -1093,9 +1105,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 800*fMHz) && (freq < 1000*fMHz)) - { + } else if ((freq >= 800 * fMHz) && (freq < 1000 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 0); @@ -1105,9 +1115,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM); - } - else if ((freq >= 1000*fMHz) && (freq < 1500*fMHz)) - { + } else if ((freq >= 1000 * fMHz) && (freq < 1500 * fMHz)) { set_cpld_field(SEL_LNA1, 0); set_cpld_field(SEL_LNA2, 1); set_cpld_field(RXLO1_FSEL3, 0); @@ -1117,9 +1125,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 1500*fMHz) && (freq < 2200*fMHz)) - { + } else if ((freq >= 1500 * fMHz) && (freq < 2200 * fMHz)) { set_cpld_field(SEL_LNA1, 1); set_cpld_field(SEL_LNA2, 0); set_cpld_field(RXLO1_FSEL3, 0); @@ -1129,9 +1135,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 2200*fMHz) && (freq < 2500*fMHz)) - { + } else if ((freq >= 2200 * fMHz) && (freq < 2500 * fMHz)) { set_cpld_field(SEL_LNA1, 1); set_cpld_field(SEL_LNA2, 0); set_cpld_field(RXLO1_FSEL3, 0); @@ -1141,9 +1145,7 @@ private: set_cpld_field(RXHB_SEL, 1); freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n); _rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM); - } - else if ((freq >= 2500*fMHz) && (freq <= 6000*fMHz)) - { + } else if ((freq >= 2500 * fMHz) && (freq <= 6000 * fMHz)) { set_cpld_field(SEL_LNA1, 1); set_cpld_field(SEL_LNA2, 0); set_cpld_field(RXLO1_FSEL3, 1); @@ -1158,47 +1160,48 @@ private: // To reduce the number of commands issued to the device, write to the // SPI destination already addressed first. This avoids the writes to // the GPIO registers to route the SPI to the same destination. - switch (get_gpio_field(SPI_ADDR)) - { - case RXLO1: - _rxlo1->commit(); - if (freq < (500*fMHz)) _rxlo2->commit(); - write_cpld_reg(); - break; - case RXLO2: - if (freq < (500*fMHz)) _rxlo2->commit(); - _rxlo1->commit(); - write_cpld_reg(); - break; - default: - write_cpld_reg(); - _rxlo1->commit(); - if (freq < (500*fMHz)) _rxlo2->commit(); - break; + switch (get_gpio_field(SPI_ADDR)) { + case RXLO1: + _rxlo1->commit(); + if (freq < (500 * fMHz)) + _rxlo2->commit(); + write_cpld_reg(); + break; + case RXLO2: + if (freq < (500 * fMHz)) + _rxlo2->commit(); + _rxlo1->commit(); + write_cpld_reg(); + break; + default: + write_cpld_reg(); + _rxlo1->commit(); + if (freq < (500 * fMHz)) + _rxlo2->commit(); + break; } - if (cmd_time != uhd::time_spec_t(0.0) and _rxlo1->can_sync()) - { + if (cmd_time != uhd::time_spec_t(0.0) and _rxlo1->can_sync()) { sync_phase(cmd_time, RX_DIRECTION); } - _rx_freq = freq_lo1 - freq_lo2; + _rx_freq = freq_lo1 - freq_lo2; _rxlo1_freq = freq_lo1; _rxlo2_freq = freq_lo2; - UHD_LOGGER_TRACE("UBX") << boost::format("UBX RX: the actual frequency is %f MHz") % (_rx_freq/1e6) ; + UHD_LOGGER_TRACE("UBX") + << boost::format("UBX RX: the actual frequency is %f MHz") % (_rx_freq / 1e6); return _rx_freq; } /*********************************************************************** - * Setting Modes - **********************************************************************/ + * Setting Modes + **********************************************************************/ void set_power_mode(std::string mode) { boost::mutex::scoped_lock lock(_mutex); - if (mode == "performance") - { + if (mode == "performance") { // performance mode attempts to reduce tuning and settling time // as much as possible without adding noise. @@ -1231,9 +1234,7 @@ private: write_cpld_reg(); _power_mode = PERFORMANCE; - } - else if (mode == "powersave") - { + } else if (mode == "powersave") { // powersave mode attempts to use the least amount of power possible // by powering on components only when needed. Longer tuning and // settling times are expected. @@ -1270,26 +1271,17 @@ private: // the board is in TX, RX, or full duplex mode // to reduce power consumption and RF noise. boost::to_upper(mode); - if (mode == "FDX") - { + if (mode == "FDX") { _xcvr_mode = FDX; - } - else if (mode == "TDD") - { + } else if (mode == "TDD") { _xcvr_mode = TDD; set_cpld_field(TXDRV_FORCEON, 1); write_cpld_reg(); - } - else if (mode == "TX") - { + } else if (mode == "TX") { _xcvr_mode = TX; - } - else if (mode == "RX") - { + } else if (mode == "RX") { _xcvr_mode = RX; - } - else - { + } else { throw uhd::value_error("invalid xcvr_mode"); } } @@ -1321,14 +1313,14 @@ private: } /*********************************************************************** - * Variables - **********************************************************************/ + * Variables + **********************************************************************/ dboard_iface::sptr _iface; boost::mutex _spi_mutex; boost::mutex _mutex; ubx_cpld_reg_t _cpld_reg; uint32_t _prev_cpld_value; - std::map<ubx_gpio_field_id_t,ubx_gpio_field_info_t> _gpio_map; + std::map<ubx_gpio_field_id_t, ubx_gpio_field_info_t> _gpio_map; std::shared_ptr<max287x_iface> _txlo1; std::shared_ptr<max287x_iface> _txlo2; std::shared_ptr<max287x_iface> _rxlo1; @@ -1368,12 +1360,20 @@ static dboard_base::sptr make_ubx(dboard_base::ctor_args_t args) UHD_STATIC_BLOCK(reg_ubx_dboards) { - dboard_manager::register_dboard(UBX_PROTO_V3_RX_ID, UBX_PROTO_V3_TX_ID, &make_ubx, "UBX v0.3"); - dboard_manager::register_dboard(UBX_PROTO_V4_RX_ID, UBX_PROTO_V4_TX_ID, &make_ubx, "UBX v0.4"); - dboard_manager::register_dboard(UBX_V1_40MHZ_RX_ID, UBX_V1_40MHZ_TX_ID, &make_ubx, "UBX-40 v1"); - dboard_manager::register_dboard(UBX_V1_160MHZ_RX_ID, UBX_V1_160MHZ_TX_ID, &make_ubx, "UBX-160 v1"); - dboard_manager::register_dboard(UBX_V2_40MHZ_RX_ID, UBX_V2_40MHZ_TX_ID, &make_ubx, "UBX-40 v2"); - dboard_manager::register_dboard(UBX_V2_160MHZ_RX_ID, UBX_V2_160MHZ_TX_ID, &make_ubx, "UBX-160 v2"); - dboard_manager::register_dboard(UBX_LP_160MHZ_RX_ID, UBX_LP_160MHZ_TX_ID, &make_ubx, "UBX-160-LP"); - dboard_manager::register_dboard(UBX_TDD_160MHZ_RX_ID, UBX_TDD_160MHZ_TX_ID, &make_ubx, "UBX-TDD"); + dboard_manager::register_dboard( + UBX_PROTO_V3_RX_ID, UBX_PROTO_V3_TX_ID, &make_ubx, "UBX v0.3"); + dboard_manager::register_dboard( + UBX_PROTO_V4_RX_ID, UBX_PROTO_V4_TX_ID, &make_ubx, "UBX v0.4"); + dboard_manager::register_dboard( + UBX_V1_40MHZ_RX_ID, UBX_V1_40MHZ_TX_ID, &make_ubx, "UBX-40 v1"); + dboard_manager::register_dboard( + UBX_V1_160MHZ_RX_ID, UBX_V1_160MHZ_TX_ID, &make_ubx, "UBX-160 v1"); + dboard_manager::register_dboard( + UBX_V2_40MHZ_RX_ID, UBX_V2_40MHZ_TX_ID, &make_ubx, "UBX-40 v2"); + dboard_manager::register_dboard( + UBX_V2_160MHZ_RX_ID, UBX_V2_160MHZ_TX_ID, &make_ubx, "UBX-160 v2"); + dboard_manager::register_dboard( + UBX_LP_160MHZ_RX_ID, UBX_LP_160MHZ_TX_ID, &make_ubx, "UBX-160-LP"); + dboard_manager::register_dboard( + UBX_TDD_160MHZ_RX_ID, UBX_TDD_160MHZ_TX_ID, &make_ubx, "UBX-TDD"); } diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index 2640ad607..f6587b4b3 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -6,15 +6,15 @@ // #include <uhd/types/ranges.hpp> -#include <uhd/utils/assert_has.hpp> -#include <uhd/utils/static.hpp> -#include <uhd/utils/log.hpp> #include <uhd/usrp/dboard_base.hpp> #include <uhd/usrp/dboard_manager.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/static.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> -#include <vector> #include <tuple> +#include <vector> using namespace uhd; using namespace uhd::usrp; @@ -23,26 +23,26 @@ using namespace boost::assign; /*********************************************************************** * Utility functions **********************************************************************/ -static void warn_if_old_rfx(const dboard_id_t &dboard_id, const std::string &xx){ - typedef std::tuple<std::string, dboard_id_t, dboard_id_t> old_ids_t; //name, rx_id, tx_id - static const std::vector<old_ids_t> old_rfx_ids = list_of - (old_ids_t("Flex 400 Classic", 0x0004, 0x0008)) - (old_ids_t("Flex 900 Classic", 0x0005, 0x0009)) - (old_ids_t("Flex 1200 Classic", 0x0006, 0x000a)) - (old_ids_t("Flex 1800 Classic", 0x0030, 0x0031)) - (old_ids_t("Flex 2400 Classic", 0x0007, 0x000b)) - ; - for(const old_ids_t &old_id: old_rfx_ids){ - std::string name; dboard_id_t rx_id, tx_id; +static void warn_if_old_rfx(const dboard_id_t& dboard_id, const std::string& xx) +{ + typedef std::tuple<std::string, dboard_id_t, dboard_id_t> + old_ids_t; // name, rx_id, tx_id + static const std::vector<old_ids_t> old_rfx_ids = + list_of(old_ids_t("Flex 400 Classic", 0x0004, 0x0008))( + old_ids_t("Flex 900 Classic", 0x0005, 0x0009))( + old_ids_t("Flex 1200 Classic", 0x0006, 0x000a))( + old_ids_t("Flex 1800 Classic", 0x0030, 0x0031))( + old_ids_t("Flex 2400 Classic", 0x0007, 0x000b)); + for (const old_ids_t& old_id : old_rfx_ids) { + std::string name; + dboard_id_t rx_id, tx_id; std::tie(name, rx_id, tx_id) = old_id; - if ( - (xx == "RX" and rx_id == dboard_id) or - (xx == "TX" and tx_id == dboard_id) - ) UHD_LOGGER_WARNING("unknown_db") << boost::format( - "Detected %s daughterboard %s\n" - "This board requires modification to use.\n" - "See the daughterboard application notes.\n" - ) % xx % name; + if ((xx == "RX" and rx_id == dboard_id) or (xx == "TX" and tx_id == dboard_id)) + UHD_LOGGER_WARNING("unknown_db") + << boost::format("Detected %s daughterboard %s\n" + "This board requires modification to use.\n" + "See the daughterboard application notes.\n") + % xx % name; } } @@ -50,12 +50,14 @@ static void warn_if_old_rfx(const dboard_id_t &dboard_id, const std::string &xx) * The unknown boards: * Like a basic board, but with only one subdev. **********************************************************************/ -class unknown_rx : public rx_dboard_base{ +class unknown_rx : public rx_dboard_base +{ public: unknown_rx(ctor_args_t args); }; -class unknown_tx : public tx_dboard_base{ +class unknown_tx : public tx_dboard_base +{ public: unknown_tx(ctor_args_t args); }; @@ -63,15 +65,18 @@ public: /*********************************************************************** * Register the unknown dboards **********************************************************************/ -static dboard_base::sptr make_unknown_rx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_unknown_rx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new unknown_rx(args)); } -static dboard_base::sptr make_unknown_tx(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_unknown_tx(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new unknown_tx(args)); } -UHD_STATIC_BLOCK(reg_unknown_dboards){ +UHD_STATIC_BLOCK(reg_unknown_dboards) +{ dboard_manager::register_dboard(0xfff0, &make_unknown_tx, "Unknown TX"); dboard_manager::register_dboard(0xfff1, &make_unknown_rx, "Unknown RX"); } @@ -79,71 +84,61 @@ UHD_STATIC_BLOCK(reg_unknown_dboards){ /*********************************************************************** * Unknown RX dboard **********************************************************************/ -unknown_rx::unknown_rx(ctor_args_t args) : rx_dboard_base(args){ +unknown_rx::unknown_rx(ctor_args_t args) : rx_dboard_base(args) +{ warn_if_old_rfx(this->get_rx_id(), "RX"); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("%s - %s") - % get_rx_id().to_pp_string() - % get_subdev_name() - ))); - this->get_rx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_rx_subtree()->create<double>("freq/value") - .set(double(0.0)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") + this->get_rx_subtree()->create<std::string>("name").set(std::string( + str(boost::format("%s - %s") % get_rx_id().to_pp_string() % get_subdev_name()))); + this->get_rx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_rx_subtree()->create<double>("freq/value").set(double(0.0)); + this->get_rx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(double(0.0), double(0.0))); - this->get_rx_subtree()->create<std::string>("antenna/value") - .set(""); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree()->create<std::string>("antenna/value").set(""); + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(list_of("")); - this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set(double(0.0)); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_rx_subtree()->create<std::string>("connection").set("IQ"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree()->create<double>("bandwidth/value").set(double(0.0)); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(0.0, 0.0)); } /*********************************************************************** * Unknown TX dboard **********************************************************************/ -unknown_tx::unknown_tx(ctor_args_t args) : tx_dboard_base(args){ +unknown_tx::unknown_tx(ctor_args_t args) : tx_dboard_base(args) +{ warn_if_old_rfx(this->get_tx_id(), "TX"); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("%s - %s") - % get_tx_id().to_pp_string() - % get_subdev_name() - ))); - this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists - this->get_tx_subtree()->create<double>("freq/value") - .set(double(0.0)); - this->get_tx_subtree()->create<meta_range_t>("freq/range") + this->get_tx_subtree()->create<std::string>("name").set(std::string( + str(boost::format("%s - %s") % get_tx_id().to_pp_string() % get_subdev_name()))); + this->get_tx_subtree()->create<int>("gains"); // phony property so this dir exists + this->get_tx_subtree()->create<double>("freq/value").set(double(0.0)); + this->get_tx_subtree() + ->create<meta_range_t>("freq/range") .set(freq_range_t(double(0.0), double(0.0))); - this->get_tx_subtree()->create<std::string>("antenna/value") - .set(""); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree()->create<std::string>("antenna/value").set(""); + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(list_of("")); - this->get_tx_subtree()->create<int>("sensors"); //phony property so this dir exists - this->get_tx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_tx_subtree()->create<double>("bandwidth/value") - .set(double(0.0)); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_tx_subtree()->create<int>("sensors"); // phony property so this dir exists + this->get_tx_subtree()->create<std::string>("connection").set("IQ"); + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_tx_subtree()->create<double>("bandwidth/value").set(double(0.0)); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(freq_range_t(0.0, 0.0)); } diff --git a/host/lib/usrp/dboard/db_wbx_common.cpp b/host/lib/usrp/dboard/db_wbx_common.cpp index 4651de76a..df89e3779 100644 --- a/host/lib/usrp/dboard/db_wbx_common.cpp +++ b/host/lib/usrp/dboard/db_wbx_common.cpp @@ -22,23 +22,24 @@ using namespace boost::assign; /*********************************************************************** * Gain-related functions **********************************************************************/ -static int rx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int rx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = wbx_rx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation + // convert to attenuation double attn = wbx_rx_gain_ranges["PGA0"].stop() - gain; - //calculate the attenuation - int attn_code = boost::math::iround(attn*2); - int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; + // calculate the attenuation + int attn_code = boost::math::iround(attn * 2); + int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK ; + UHD_LOGGER_TRACE("WBX") + << boost::format("WBX RX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK; - //the actual gain setting - gain = wbx_rx_gain_ranges["PGA0"].stop() - double(attn_code)/2; + // the actual gain setting + gain = wbx_rx_gain_ranges["PGA0"].stop() - double(attn_code) / 2; return iobits; } @@ -47,9 +48,9 @@ static int rx_pga0_gain_to_iobits(double &gain){ /*********************************************************************** * WBX Common Implementation **********************************************************************/ -wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){ - - //enable the clocks that we need +wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args) +{ + // enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); @@ -59,38 +60,47 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){ uint16_t rx_id = this->get_rx_id().to_uint16(); this->get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_RX)); - for(const std::string &name: wbx_rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : wbx_rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&wbx_base::set_rx_gain, this, std::placeholders::_1, name)) .set(wbx_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_rx_gain_ranges[name]); } this->get_rx_subtree()->create<std::string>("connection").set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::set_rx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_rx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber( + std::bind(&wbx_base::set_rx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); - //Value of bw low-pass dependent on board, we want complex double-sided + // Value of bw low-pass dependent on board, we want complex double-sided double bw = (rx_id != 0x0081) ? 20.0e6 : 60.0e6; - this->get_rx_subtree()->create<double>("bandwidth/value").set(2*bw); - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*bw, 2*bw)); - this->get_tx_subtree()->create<double>("bandwidth/value").set(2*bw); - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(2*bw, 2*bw)); + this->get_rx_subtree()->create<double>("bandwidth/value").set(2 * bw); + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * bw, 2 * bw)); + this->get_tx_subtree()->create<double>("bandwidth/value").set(2 * bw); + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") + .set(freq_range_t(2 * bw, 2 * bw)); this->get_tx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t()); - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_TX)); this->get_tx_subtree()->create<std::string>("connection").set("IQ"); this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); // instantiate subclass foo - switch(rx_id) { + switch (rx_id) { case 0x0053: db_actual = wbx_versionx_sptr(new wbx_version2(this)); return; @@ -107,49 +117,54 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){ /* We didn't recognize the version of the board... */ UHD_THROW_INVALID_CODE_PATH(); } - } -wbx_base::~wbx_base(void){ +wbx_base::~wbx_base(void) +{ /* NOP */ } /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::set_rx_enabled(bool enb){ +void wbx_base::set_rx_enabled(bool enb) +{ this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, - (enb)? RX_POWER_UP : RX_POWER_DOWN, RX_POWER_UP | RX_POWER_DOWN - ); + (enb) ? RX_POWER_UP : RX_POWER_DOWN, + RX_POWER_UP | RX_POWER_DOWN); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::set_rx_gain(double gain, const std::string &name){ +double wbx_base::set_rx_gain(double gain, const std::string& name) +{ assert_has(wbx_rx_gain_ranges.keys(), name, "wbx rx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { uint16_t io_bits = rx_pga0_gain_to_iobits(gain); - _rx_gains[name] = gain; + _rx_gains[name] = gain; - //write the new gain to rx gpio outputs + // write the new gain to rx gpio outputs this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, io_bits, RX_ATTN_MASK); - } - else UHD_THROW_INVALID_CODE_PATH(); - return _rx_gains[name]; //returned shadowed + } else + UHD_THROW_INVALID_CODE_PATH(); + return _rx_gains[name]; // returned shadowed } /*********************************************************************** * Tuning **********************************************************************/ -sensor_value_t wbx_base::get_locked(dboard_iface::unit_t unit){ +sensor_value_t wbx_base::get_locked(dboard_iface::unit_t unit) +{ const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; return sensor_value_t("LO", locked, "locked", "unlocked"); } -void wbx_base::wbx_versionx::write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) { - for(uint32_t reg: regs) { +void wbx_base::wbx_versionx::write_lo_regs( + dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) +{ + for (uint32_t reg : regs) { self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32); } } diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp index 9425b041c..e7beabd8b 100644 --- a/host/lib/usrp/dboard/db_wbx_common.hpp +++ b/host/lib/usrp/dboard/db_wbx_common.hpp @@ -12,96 +12,93 @@ #include <uhdlib/usrp/common/adf435x.hpp> // LO Related -#define ADF435X_CE (1 << 3) -#define ADF435X_PDBRF (1 << 2) -#define ADF435X_MUXOUT (1 << 1) // INPUT!!! -#define LOCKDET_MASK (1 << 0) // INPUT!!! +#define ADF435X_CE (1 << 3) +#define ADF435X_PDBRF (1 << 2) +#define ADF435X_MUXOUT (1 << 1) // INPUT!!! +#define LOCKDET_MASK (1 << 0) // INPUT!!! // TX IO Pins -#define TX_PUP_5V (1 << 7) // enables 5.0V power supply -#define TX_PUP_3V (1 << 6) // enables 3.3V supply -#define TXMOD_EN (1 << 4) // on UNIT_TX, 1 enables TX Modulator +#define TX_PUP_5V (1 << 7) // enables 5.0V power supply +#define TX_PUP_3V (1 << 6) // enables 3.3V supply +#define TXMOD_EN (1 << 4) // on UNIT_TX, 1 enables TX Modulator // RX IO Pins -#define RX_PUP_5V (1 << 7) // enables 5.0V power supply -#define RX_PUP_3V (1 << 6) // enables 3.3V supply -#define RXBB_PDB (1 << 4) // on UNIT_RX, 1 powers up RX baseband +#define RX_PUP_5V (1 << 7) // enables 5.0V power supply +#define RX_PUP_3V (1 << 6) // enables 3.3V supply +#define RXBB_PDB (1 << 4) // on UNIT_RX, 1 powers up RX baseband // TX Attenuator Pins (v3 only) -#define TX_ATTN_16 (1 << 14) -#define TX_ATTN_8 (1 << 5) -#define TX_ATTN_4 (1 << 4) -#define TX_ATTN_2 (1 << 3) -#define TX_ATTN_1 (1 << 1) -#define TX_ATTN_MASK (TX_ATTN_16|TX_ATTN_8|TX_ATTN_4|TX_ATTN_2|TX_ATTN_1) // valid bits of TX Attenuator Control - -#define RX_ATTN_SHIFT 8 //lsb of RX Attenuator Control -#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) //valid bits of RX Attenuator Control +#define TX_ATTN_16 (1 << 14) +#define TX_ATTN_8 (1 << 5) +#define TX_ATTN_4 (1 << 4) +#define TX_ATTN_2 (1 << 3) +#define TX_ATTN_1 (1 << 1) +#define TX_ATTN_MASK \ + (TX_ATTN_16 | TX_ATTN_8 | TX_ATTN_4 | TX_ATTN_2 \ + | TX_ATTN_1) // valid bits of TX Attenuator Control + +#define RX_ATTN_SHIFT 8 // lsb of RX Attenuator Control +#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) // valid bits of RX Attenuator Control // Mixer functions -#define TX_MIXER_ENB (TXMOD_EN|ADF435X_PDBRF) // for v3, TXMOD_EN tied to ADF435X_PDBRF rather than separate -#define TX_MIXER_DIS 0 +#define TX_MIXER_ENB \ + (TXMOD_EN \ + | ADF435X_PDBRF) // for v3, TXMOD_EN tied to ADF435X_PDBRF rather than separate +#define TX_MIXER_DIS 0 -#define RX_MIXER_ENB (RXBB_PDB|ADF435X_PDBRF) -#define RX_MIXER_DIS 0 +#define RX_MIXER_ENB (RXBB_PDB | ADF435X_PDBRF) +#define RX_MIXER_DIS 0 // Power functions -#define TX_POWER_UP (TX_PUP_5V|TX_PUP_3V) // high enables power supply -#define TX_POWER_DOWN 0 +#define TX_POWER_UP (TX_PUP_5V | TX_PUP_3V) // high enables power supply +#define TX_POWER_DOWN 0 -#define RX_POWER_UP (RX_PUP_5V|RX_PUP_3V|ADF435X_CE) // high enables power supply -#define RX_POWER_DOWN 0 +#define RX_POWER_UP (RX_PUP_5V | RX_PUP_3V | ADF435X_CE) // high enables power supply +#define RX_POWER_DOWN 0 #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> #include <uhd/types/sensors.hpp> +#include <uhd/usrp/dboard_base.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/static.hpp> -#include <uhd/usrp/dboard_base.hpp> #include <boost/assign/list_of.hpp> #include <boost/format.hpp> -#include <memory> #include <boost/math/special_functions/round.hpp> #include <functional> +#include <memory> -namespace uhd{ namespace usrp{ +namespace uhd { namespace usrp { /*********************************************************************** * The WBX Common dboard constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_rx_gain_ranges = boost::assign::map_list_of - ("PGA0", gain_range_t(0, 31.5, 0.5)); +static const uhd::dict<std::string, gain_range_t> wbx_rx_gain_ranges = + boost::assign::map_list_of("PGA0", gain_range_t(0, 31.5, 0.5)); -static const freq_range_t wbx_tx_lo_5dbm = boost::assign::list_of - (range_t(0.05e9, 1.7e9)) - (range_t(1.9e9, 2.2e9)) -; +static const freq_range_t wbx_tx_lo_5dbm = + boost::assign::list_of(range_t(0.05e9, 1.7e9))(range_t(1.9e9, 2.2e9)); -static const freq_range_t wbx_tx_lo_m1dbm = boost::assign::list_of - (range_t(1.7e9, 1.9e9)) -; +static const freq_range_t wbx_tx_lo_m1dbm = boost::assign::list_of(range_t(1.7e9, 1.9e9)); -static const freq_range_t wbx_rx_lo_5dbm = boost::assign::list_of - (range_t(0.05e9, 1.4e9)) -; +static const freq_range_t wbx_rx_lo_5dbm = boost::assign::list_of(range_t(0.05e9, 1.4e9)); -static const freq_range_t wbx_rx_lo_2dbm = boost::assign::list_of - (range_t(1.4e9, 2.2e9)) -; +static const freq_range_t wbx_rx_lo_2dbm = boost::assign::list_of(range_t(1.4e9, 2.2e9)); /*********************************************************************** * The WBX dboard base class **********************************************************************/ -class wbx_base : public xcvr_dboard_base{ +class wbx_base : public xcvr_dboard_base +{ public: wbx_base(ctor_args_t args); virtual ~wbx_base(void); protected: - virtual double set_rx_gain(double gain, const std::string &name); + virtual double set_rx_gain(double gain, const std::string& name); virtual void set_rx_enabled(bool enb); @@ -121,29 +118,32 @@ protected: * This class is an abstract base class, and thus is impossible to * instantiate. */ - class wbx_versionx { + class wbx_versionx + { public: - wbx_versionx():self_base(NULL) {} + wbx_versionx() : self_base(NULL) {} virtual ~wbx_versionx(void) {} - virtual double set_tx_gain(double gain, const std::string &name) = 0; - virtual void set_tx_enabled(bool enb) = 0; + virtual double set_tx_gain(double gain, const std::string& name) = 0; + virtual void set_tx_enabled(bool enb) = 0; virtual double set_lo_freq(dboard_iface::unit_t unit, double target_freq) = 0; /*! This is the registered instance of the wrapper class, wbx_base. */ - wbx_base *self_base; + wbx_base* self_base; - property_tree::sptr get_rx_subtree(void){ + property_tree::sptr get_rx_subtree(void) + { return self_base->get_rx_subtree(); } - property_tree::sptr get_tx_subtree(void){ + property_tree::sptr get_tx_subtree(void) + { return self_base->get_tx_subtree(); } adf435x_iface::sptr _txlo; adf435x_iface::sptr _rxlo; - void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s); + void write_lo_regs(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs); }; @@ -152,12 +152,13 @@ protected: * * Basically the original release of the DB. */ - class wbx_version2 : public wbx_versionx { + class wbx_version2 : public wbx_versionx + { public: - wbx_version2(wbx_base *_self_wbx_base); + wbx_version2(wbx_base* _self_wbx_base); virtual ~wbx_version2(void); - double set_tx_gain(double gain, const std::string &name); + double set_tx_gain(double gain, const std::string& name); void set_tx_enabled(bool enb); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); }; @@ -167,12 +168,13 @@ protected: * * Fixed a problem with the AGC from Version 2. */ - class wbx_version3 : public wbx_versionx { + class wbx_version3 : public wbx_versionx + { public: - wbx_version3(wbx_base *_self_wbx_base); + wbx_version3(wbx_base* _self_wbx_base); virtual ~wbx_version3(void); - double set_tx_gain(double gain, const std::string &name); + double set_tx_gain(double gain, const std::string& name); void set_tx_enabled(bool enb); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); }; @@ -182,12 +184,13 @@ protected: * * Upgrades the Frequnecy Synthensizer from ADF4350 to ADF4351. */ - class wbx_version4 : public wbx_versionx { + class wbx_version4 : public wbx_versionx + { public: - wbx_version4(wbx_base *_self_wbx_base); + wbx_version4(wbx_base* _self_wbx_base); virtual ~wbx_version4(void); - double set_tx_gain(double gain, const std::string &name); + double set_tx_gain(double gain, const std::string& name); void set_tx_enabled(bool enb); double set_lo_freq(dboard_iface::unit_t unit, double target_freq); }; @@ -208,6 +211,6 @@ protected: }; -}} //namespace uhd::usrp +}} // namespace uhd::usrp #endif /* INCLUDED_LIBUHD_USRP_DBOARD_DB_WBX_COMMON_HPP */ diff --git a/host/lib/usrp/dboard/db_wbx_simple.cpp b/host/lib/usrp/dboard/db_wbx_simple.cpp index 98eb96c1f..35675a081 100644 --- a/host/lib/usrp/dboard/db_wbx_simple.cpp +++ b/host/lib/usrp/dboard/db_wbx_simple.cpp @@ -6,11 +6,12 @@ // // Antenna constants -#define ANTSW_IO ((1 << 15)) // on UNIT_TX, 0 = TX, 1 = RX, on UNIT_RX 0 = main ant, 1 = RX2 -#define ANT_TX 0 //the tx line is transmitting -#define ANT_RX ANTSW_IO //the tx line is receiving -#define ANT_TXRX 0 //the rx line is on txrx -#define ANT_RX2 ANTSW_IO //the rx line in on rx2 +#define ANTSW_IO \ + ((1 << 15)) // on UNIT_TX, 0 = TX, 1 = RX, on UNIT_RX 0 = main ant, 1 = RX2 +#define ANT_TX 0 // the tx line is transmitting +#define ANT_RX ANTSW_IO // the tx line is receiving +#define ANT_TXRX 0 // the rx line is on txrx +#define ANT_RX2 ANTSW_IO // the rx line in on rx2 #include "db_wbx_common.hpp" #include <uhd/usrp/dboard_manager.hpp> @@ -34,122 +35,154 @@ static const std::vector<std::string> wbx_rx_antennas = list_of("TX/RX")("RX2")( /*********************************************************************** * The WBX simple implementation **********************************************************************/ -class wbx_simple : public wbx_base{ +class wbx_simple : public wbx_base +{ public: wbx_simple(ctor_args_t args); virtual ~wbx_simple(void); private: - void set_rx_ant(const std::string &ant); - void set_tx_ant(const std::string &ant); + void set_rx_ant(const std::string& ant); + void set_tx_ant(const std::string& ant); std::string _rx_ant; }; /*********************************************************************** * Register the WBX simple implementation **********************************************************************/ -static dboard_base::sptr make_wbx_simple(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_wbx_simple(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new wbx_simple(args)); } /*********************************************************************** * ID Numbers for WBX daughterboard combinations. **********************************************************************/ -UHD_STATIC_BLOCK(reg_wbx_simple_dboards){ +UHD_STATIC_BLOCK(reg_wbx_simple_dboards) +{ dboard_manager::register_dboard(0x0053, 0x0052, &make_wbx_simple, "WBX"); dboard_manager::register_dboard(0x0053, 0x004f, &make_wbx_simple, "WBX + Simple GDB"); dboard_manager::register_dboard(0x0057, 0x0056, &make_wbx_simple, "WBX v3"); - dboard_manager::register_dboard(0x0057, 0x004f, &make_wbx_simple, "WBX v3 + Simple GDB"); + dboard_manager::register_dboard( + 0x0057, 0x004f, &make_wbx_simple, "WBX v3 + Simple GDB"); dboard_manager::register_dboard(0x0063, 0x0062, &make_wbx_simple, "WBX v4"); - dboard_manager::register_dboard(0x0063, 0x004f, &make_wbx_simple, "WBX v4 + Simple GDB"); + dboard_manager::register_dboard( + 0x0063, 0x004f, &make_wbx_simple, "WBX v4 + Simple GDB"); dboard_manager::register_dboard(0x0081, 0x0080, &make_wbx_simple, "WBX-120"); - dboard_manager::register_dboard(0x0081, 0x004f, &make_wbx_simple, "WBX-120 + Simple GDB"); + dboard_manager::register_dboard( + 0x0081, 0x004f, &make_wbx_simple, "WBX-120 + Simple GDB"); } /*********************************************************************** * Structors **********************************************************************/ -wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){ - +wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args) +{ //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->access<std::string>("name").set( - std::string(str(boost::format("%s+GDB") % this->get_rx_subtree()->access<std::string>("name").get() - ))); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&wbx_simple::set_rx_ant, this, std::placeholders::_1)) + std::string(str(boost::format("%s+GDB") + % this->get_rx_subtree()->access<std::string>("name").get()))); + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&wbx_simple::set_rx_ant, this, std::placeholders::_1)) .set("RX2"); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(wbx_rx_antennas); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// this->get_tx_subtree()->access<std::string>("name").set( - std::string(str(boost::format("%s+GDB") % this->get_tx_subtree()->access<std::string>("name").get() - ))); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&wbx_simple::set_tx_ant, this, std::placeholders::_1)) + std::string(str(boost::format("%s+GDB") + % this->get_tx_subtree()->access<std::string>("name").get()))); + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&wbx_simple::set_tx_ant, this, std::placeholders::_1)) .set(wbx_tx_antennas.at(0)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(wbx_tx_antennas); - //set the gpio directions and atr controls (antenna switches all under ATR) + // set the gpio directions and atr controls (antenna switches all under ATR) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO); this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO); - //setup ATR for the antenna switches (constant) - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, ANT_RX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); - - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); + // setup ATR for the antenna switches (constant) + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, ANT_RX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); + + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); } -wbx_simple::~wbx_simple(void){ +wbx_simple::~wbx_simple(void) +{ /* NOP */ } /*********************************************************************** * Antennas **********************************************************************/ -void wbx_simple::set_rx_ant(const std::string &ant){ - //validate input +void wbx_simple::set_rx_ant(const std::string& ant) +{ + // validate input assert_has(wbx_rx_antennas, ant, "wbx rx antenna name"); - //shadow the setting + // shadow the setting _rx_ant = ant; - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs if (_rx_ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2), ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO); + } else { + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + ((_rx_ant == "TX/RX") ? ANT_TXRX : ANT_RX2), + ANTSW_IO); } } -void wbx_simple::set_tx_ant(const std::string &ant){ +void wbx_simple::set_tx_ant(const std::string& ant) +{ assert_has(wbx_tx_antennas, ant, "wbx tx antenna name"); - //write the new antenna setting to atr regs + // write the new antenna setting to atr regs if (ant == "CAL") { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO); - } - else { - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO); + } else { + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); } } diff --git a/host/lib/usrp/dboard/db_wbx_version2.cpp b/host/lib/usrp/dboard/db_wbx_version2.cpp index a8605942b..890436cdb 100644 --- a/host/lib/usrp/dboard/db_wbx_version2.cpp +++ b/host/lib/usrp/dboard/db_wbx_version2.cpp @@ -28,32 +28,32 @@ using namespace boost::assign; /*********************************************************************** * WBX Version 2 Constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_v2_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 25, 0.05)) -; +static const uhd::dict<std::string, gain_range_t> wbx_v2_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 25, 0.05)); static const freq_range_t wbx_v2_freq_range(68.75e6, 2.2e9); /*********************************************************************** * Gain-related functions **********************************************************************/ -static double tx_pga0_gain_to_dac_volts(double &gain){ - //clip the input +static double tx_pga0_gain_to_dac_volts(double& gain) +{ + // clip the input gain = wbx_v2_tx_gain_ranges["PGA0"].clip(gain); - //voltage level constants + // voltage level constants static const double max_volts = 0.5, min_volts = 1.4; - static const double slope = (max_volts-min_volts)/wbx_v2_tx_gain_ranges["PGA0"].stop(); + static const double slope = + (max_volts - min_volts) / wbx_v2_tx_gain_ranges["PGA0"].stop(); - //calculate the voltage for the aux dac - double dac_volts = gain*slope + min_volts; + // calculate the voltage for the aux dac + double dac_volts = gain * slope + min_volts; - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX TX Gain: %f dB, dac_volts: %f V" - ) % gain % dac_volts ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX TX Gain: %f dB, dac_volts: %f V") % gain + % dac_volts; - //the actual gain setting - gain = (dac_volts - min_volts)/slope; + // the actual gain setting + gain = (dac_volts - min_volts) / slope; return dac_volts; } @@ -62,150 +62,206 @@ static double tx_pga0_gain_to_dac_volts(double &gain){ /*********************************************************************** * WBX Version 2 Implementation **********************************************************************/ -wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) { - //register our handle on the primary wbx_base instance +wbx_base::wbx_version2::wbx_version2(wbx_base* _self_wbx_base) +{ + // register our handle on the primary wbx_base instance self_base = _self_wbx_base; - _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->create<std::string>("name").set("WBXv2 RX"); - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)) + .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v2_freq_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// this->get_tx_subtree()->create<std::string>("name").set("WBXv2 TX"); - for(const std::string &name: wbx_v2_tx_gain_ranges.keys()){ - self_base->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::wbx_version2::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : wbx_v2_tx_gain_ranges.keys()) { + self_base->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer(std::bind( + &wbx_base::wbx_version2::set_tx_gain, this, std::placeholders::_1, name)) .set(wbx_v2_tx_gain_ranges[name].start()); - self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + self_base->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_v2_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version2::set_lo_freq, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)) + .set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v2_freq_range); - this->get_tx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::wbx_version2::set_tx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_tx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber(std::bind( + &wbx_base::wbx_version2::set_tx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled - //set attenuator control bits + // set attenuator control bits int v2_iobits = ADF435X_CE; - int v2_tx_mod = TXMOD_EN|ADF435X_PDBRF; + int v2_tx_mod = TXMOD_EN | ADF435X_PDBRF; - //set the gpio directions and atr controls + // set the gpio directions and atr controls self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v2_tx_mod); - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB|ADF435X_PDBRF); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TX_PUP_5V|TX_PUP_3V|v2_tx_mod|v2_iobits); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK); - - //setup ATR for the mixer enables (always enabled to prevent phase slip between bursts) - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod); - - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB | ADF435X_PDBRF); + self_base->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_TX, TX_PUP_5V | TX_PUP_3V | v2_tx_mod | v2_iobits); + self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, + RX_PUP_5V | RX_PUP_3V | ADF435X_CE | RXBB_PDB | ADF435X_PDBRF | RX_ATTN_MASK); + + // setup ATR for the mixer enables (always enabled to prevent phase slip between + // bursts) + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + v2_tx_mod, + TX_MIXER_DIS | v2_tx_mod); + + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); } -wbx_base::wbx_version2::~wbx_version2(void){ +wbx_base::wbx_version2::~wbx_version2(void) +{ /* NOP */ } /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::wbx_version2::set_tx_enabled(bool enb){ +void wbx_base::wbx_version2::set_tx_enabled(bool enb) +{ self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, - (enb)? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN | ADF435X_CE); + (enb) ? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, + TX_POWER_UP | TX_POWER_DOWN | ADF435X_CE); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::wbx_version2::set_tx_gain(double gain, const std::string &name){ +double wbx_base::wbx_version2::set_tx_gain(double gain, const std::string& name) +{ assert_has(wbx_v2_tx_gain_ranges.keys(), name, "wbx tx gain name"); - if(name == "PGA0"){ - double dac_volts = tx_pga0_gain_to_dac_volts(gain); + if (name == "PGA0") { + double dac_volts = tx_pga0_gain_to_dac_volts(gain); self_base->_tx_gains[name] = gain; - //write the new voltage to the aux dac - self_base->get_iface()->write_aux_dac(dboard_iface::UNIT_TX, dboard_iface::AUX_DAC_A, dac_volts); - } - else UHD_THROW_INVALID_CODE_PATH(); - return self_base->_tx_gains[name]; //shadowed + // write the new voltage to the aux dac + self_base->get_iface()->write_aux_dac( + dboard_iface::UNIT_TX, dboard_iface::AUX_DAC_A, dac_volts); + } else + UHD_THROW_INVALID_CODE_PATH(); + return self_base->_tx_gains[name]; // shadowed } /*********************************************************************** * Tuning **********************************************************************/ -double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - //clip to tuning range +double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + // clip to tuning range target_freq = wbx_v2_freq_range.clip(target_freq); - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - double reference_freq = self_base->get_iface()->get_clock_rate(unit); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + double reference_freq = self_base->get_iface()->get_clock_rate(unit); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_reference_freq(reference_freq); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //frequency must 2x the target frequency + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // frequency must 2x the target frequency double synth_target_freq = target_freq * 2; - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(synth_target_freq > 3e9 ? - adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(synth_target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //The feedback of the divided frequency must be disabled whenever the target frequency - //divided by the minimum PFD frequency cannot meet the minimum integer divider (N) value. - //If it is disabled, additional phase ambiguity will be introduced. With a minimum PFD - //frequency of 10 MHz, synthesizer frequencies below 230 MHz (LO frequencies below 115 MHz) - //will have too much ambiguity to synchronize. + // The feedback of the divided frequency must be disabled whenever the target + // frequency divided by the minimum PFD frequency cannot meet the minimum integer + // divider (N) value. If it is disabled, additional phase ambiguity will be + // introduced. With a minimum PFD frequency of 10 MHz, synthesizer frequencies below + // 230 MHz (LO frequencies below 115 MHz) will have too much ambiguity to synchronize. lo_iface->set_feedback_select( - (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() ? - adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL)); + (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() + ? adf435x_iface::FB_SEL_DIVIDED + : adf435x_iface::FB_SEL_FUNDAMENTAL)); double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //actual_freq must /2 the synth_actual_freq + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // actual_freq must /2 the synth_actual_freq double actual_freq = synth_actual_freq / 2; if (unit == dboard_iface::UNIT_RX) { - lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_2DBM); } else { - lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM); + lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_M1DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp index 43c1d9652..51902b3aa 100644 --- a/host/lib/usrp/dboard/db_wbx_version3.cpp +++ b/host/lib/usrp/dboard/db_wbx_version3.cpp @@ -27,37 +27,34 @@ using namespace boost::assign; /*********************************************************************** * WBX Version 3 Constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_v3_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31, 1.0)) -; +static const uhd::dict<std::string, gain_range_t> wbx_v3_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31, 1.0)); static const freq_range_t wbx_v3_freq_range(68.75e6, 2.2e9); /*********************************************************************** * Gain-related functions **********************************************************************/ -static int tx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int tx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = wbx_v3_tx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation + // convert to attenuation double attn = wbx_v3_tx_gain_ranges["PGA0"].stop() - gain; - //calculate the attenuation + // calculate the attenuation int attn_code = boost::math::iround(attn); - int iobits = ( - (attn_code & 16 ? 0 : TX_ATTN_16) | - (attn_code & 8 ? 0 : TX_ATTN_8) | - (attn_code & 4 ? 0 : TX_ATTN_4) | - (attn_code & 2 ? 0 : TX_ATTN_2) | - (attn_code & 1 ? 0 : TX_ATTN_1) - ) & TX_ATTN_MASK; - - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK ; - - //the actual gain setting + int iobits = ((attn_code & 16 ? 0 : TX_ATTN_16) | (attn_code & 8 ? 0 : TX_ATTN_8) + | (attn_code & 4 ? 0 : TX_ATTN_4) | (attn_code & 2 ? 0 : TX_ATTN_2) + | (attn_code & 1 ? 0 : TX_ATTN_1)) + & TX_ATTN_MASK; + + UHD_LOGGER_TRACE("WBX") + << boost::format("WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK; + + // the actual gain setting gain = wbx_v3_tx_gain_ranges["PGA0"].stop() - double(attn_code); return iobits; @@ -67,85 +64,112 @@ static int tx_pga0_gain_to_iobits(double &gain){ /*********************************************************************** * WBX Common Implementation **********************************************************************/ -wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) { - //register our handle on the primary wbx_base instance +wbx_base::wbx_version3::wbx_version3(wbx_base* _self_wbx_base) +{ + // register our handle on the primary wbx_base instance self_base = _self_wbx_base; - _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4350(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// this->get_rx_subtree()->create<std::string>("name").set("WBXv3 RX"); - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop())/2.0); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)) + .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v3_freq_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// this->get_tx_subtree()->create<std::string>("name").set("WBXv3 TX"); - for(const std::string &name: wbx_v3_tx_gain_ranges.keys()){ - self_base->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::wbx_version3::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : wbx_v3_tx_gain_ranges.keys()) { + self_base->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer(std::bind( + &wbx_base::wbx_version3::set_tx_gain, this, std::placeholders::_1, name)) .set(wbx_v3_tx_gain_ranges[name].start()); - self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + self_base->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_v3_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version3::set_lo_freq, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)) + .set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v3_freq_range); - this->get_tx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::wbx_version3::set_tx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_tx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber(std::bind( + &wbx_base::wbx_version3::set_tx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled - //set attenuator control bits + // set attenuator control bits int v3_iobits = TX_ATTN_MASK; int v3_tx_mod = ADF435X_PDBRF; - //set the gpio directions and atr controls - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, \ - v3_tx_mod|v3_iobits); - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, \ - RXBB_PDB|ADF435X_PDBRF); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, \ - TX_PUP_5V|TX_PUP_3V|v3_tx_mod|v3_iobits); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, \ - RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK); - - //setup ATR for the mixer enables (always enabled to prevent phase - //slip between bursts). set TX gain iobits to min gain (max attenuation) - //when RX_ONLY or IDLE to suppress LO leakage - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_IDLE, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_RX_ONLY, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_TX_ONLY, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, v3_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); - - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_IDLE, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_TX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_RX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); + // set the gpio directions and atr controls + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v3_tx_mod | v3_iobits); + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB | ADF435X_PDBRF); + self_base->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_TX, TX_PUP_5V | TX_PUP_3V | v3_tx_mod | v3_iobits); + self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, + RX_PUP_5V | RX_PUP_3V | ADF435X_CE | RXBB_PDB | ADF435X_PDBRF | RX_ATTN_MASK); + + // setup ATR for the mixer enables (always enabled to prevent phase + // slip between bursts). set TX gain iobits to min gain (max attenuation) + // when RX_ONLY or IDLE to suppress LO leakage + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + v3_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); + + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); } -wbx_base::wbx_version3::~wbx_version3(void){ +wbx_base::wbx_version3::~wbx_version3(void) +{ /* NOP */ } @@ -153,90 +177,100 @@ wbx_base::wbx_version3::~wbx_version3(void){ /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::wbx_version3::set_tx_enabled(bool enb){ +void wbx_base::wbx_version3::set_tx_enabled(bool enb) +{ self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, - (enb)? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN | 0); + (enb) ? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, + TX_POWER_UP | TX_POWER_DOWN | 0); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::wbx_version3::set_tx_gain(double gain, const std::string &name){ +double wbx_base::wbx_version3::set_tx_gain(double gain, const std::string& name) +{ assert_has(wbx_v3_tx_gain_ranges.keys(), name, "wbx tx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { uint16_t io_bits = tx_pga0_gain_to_iobits(gain); self_base->_tx_gains[name] = gain; - //write the new gain to tx gpio outputs - //Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); - } - else UHD_THROW_INVALID_CODE_PATH(); - return self_base->_tx_gains[name]; //shadow + // write the new gain to tx gpio outputs + // Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR + // states + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); + } else + UHD_THROW_INVALID_CODE_PATH(); + return self_base->_tx_gains[name]; // shadow } /*********************************************************************** * Tuning **********************************************************************/ -double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - //clip to tuning range +double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + // clip to tuning range target_freq = wbx_v3_freq_range.clip(target_freq); - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - double reference_freq = self_base->get_iface()->get_clock_rate(unit); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + double reference_freq = self_base->get_iface()->get_clock_rate(unit); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_reference_freq(reference_freq); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //frequency must 2x the target frequency + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // frequency must 2x the target frequency double synth_target_freq = target_freq * 2; - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(synth_target_freq > 3e9 ? - adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(synth_target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //The feedback of the divided frequency must be disabled whenever the target frequency - //divided by the minimum PFD frequency cannot meet the minimum integer divider (N) value. - //If it is disabled, additional phase ambiguity will be introduced. With a minimum PFD - //frequency of 10 MHz, synthesizer frequencies below 230 MHz (LO frequencies below 115 MHz) - //will have too much ambiguity to synchronize. + // The feedback of the divided frequency must be disabled whenever the target + // frequency divided by the minimum PFD frequency cannot meet the minimum integer + // divider (N) value. If it is disabled, additional phase ambiguity will be + // introduced. With a minimum PFD frequency of 10 MHz, synthesizer frequencies below + // 230 MHz (LO frequencies below 115 MHz) will have too much ambiguity to synchronize. lo_iface->set_feedback_select( - (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() ? - adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL)); + (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() + ? adf435x_iface::FB_SEL_DIVIDED + : adf435x_iface::FB_SEL_FUNDAMENTAL)); double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //actual_freq must /2 the synth_actual_freq + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // actual_freq must /2 the synth_actual_freq double actual_freq = synth_actual_freq / 2; if (unit == dboard_iface::UNIT_RX) { - lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_2DBM); } else { - lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM); + lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_M1DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp index 6755fb6eb..54c0a9c21 100644 --- a/host/lib/usrp/dboard/db_wbx_version4.cpp +++ b/host/lib/usrp/dboard/db_wbx_version4.cpp @@ -27,9 +27,8 @@ using namespace boost::assign; /*********************************************************************** * WBX Version 4 Constants **********************************************************************/ -static const uhd::dict<std::string, gain_range_t> wbx_v4_tx_gain_ranges = map_list_of - ("PGA0", gain_range_t(0, 31, 1.0)) -; +static const uhd::dict<std::string, gain_range_t> wbx_v4_tx_gain_ranges = + map_list_of("PGA0", gain_range_t(0, 31, 1.0)); static const freq_range_t wbx_v4_freq_range(25.0e6, 2.2e9); @@ -37,28 +36,26 @@ static const freq_range_t wbx_v4_freq_range(25.0e6, 2.2e9); /*********************************************************************** * Gain-related functions **********************************************************************/ -static int tx_pga0_gain_to_iobits(double &gain){ - //clip the input +static int tx_pga0_gain_to_iobits(double& gain) +{ + // clip the input gain = wbx_v4_tx_gain_ranges["PGA0"].clip(gain); - //convert to attenuation + // convert to attenuation double attn = wbx_v4_tx_gain_ranges["PGA0"].stop() - gain; - //calculate the attenuation + // calculate the attenuation int attn_code = boost::math::iround(attn); - int iobits = ( - (attn_code & 16 ? 0 : TX_ATTN_16) | - (attn_code & 8 ? 0 : TX_ATTN_8) | - (attn_code & 4 ? 0 : TX_ATTN_4) | - (attn_code & 2 ? 0 : TX_ATTN_2) | - (attn_code & 1 ? 0 : TX_ATTN_1) - ) & TX_ATTN_MASK; - - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" - ) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK ; - - //the actual gain setting + int iobits = ((attn_code & 16 ? 0 : TX_ATTN_16) | (attn_code & 8 ? 0 : TX_ATTN_8) + | (attn_code & 4 ? 0 : TX_ATTN_4) | (attn_code & 2 ? 0 : TX_ATTN_2) + | (attn_code & 1 ? 0 : TX_ATTN_1)) + & TX_ATTN_MASK; + + UHD_LOGGER_TRACE("WBX") + << boost::format("WBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x") + % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK; + + // the actual gain setting gain = wbx_v4_tx_gain_ranges["PGA0"].stop() - double(attn_code); return iobits; @@ -68,91 +65,122 @@ static int tx_pga0_gain_to_iobits(double &gain){ /*********************************************************************** * WBX Common Implementation **********************************************************************/ -wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) { - //register our handle on the primary wbx_base instance +wbx_base::wbx_version4::wbx_version4(wbx_base* _self_wbx_base) +{ + // register our handle on the primary wbx_base instance self_base = _self_wbx_base; - _txlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, std::placeholders::_1)); - _rxlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, std::placeholders::_1)); + _txlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)); + _rxlo = adf435x_iface::make_adf4351(std::bind(&wbx_base::wbx_versionx::write_lo_regs, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)); //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// uint16_t rx_id = _self_wbx_base->get_rx_id().to_uint16(); - if(rx_id == 0x0063) this->get_rx_subtree()->create<std::string>("name").set("WBXv4 RX"); - else if(rx_id == 0x0081) this->get_rx_subtree()->create<std::string>("name").set("WBX-120 RX"); - this->get_rx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_RX, std::placeholders::_1)) - .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0); + if (rx_id == 0x0063) + this->get_rx_subtree()->create<std::string>("name").set("WBXv4 RX"); + else if (rx_id == 0x0081) + this->get_rx_subtree()->create<std::string>("name").set("WBX-120 RX"); + this->get_rx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, + this, + dboard_iface::UNIT_RX, + std::placeholders::_1)) + .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop()) / 2.0); this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// - //get_tx_id() will always return GDB ID, so use RX ID to determine WBXv4 vs. WBX-120 - if(rx_id == 0x0063) this->get_tx_subtree()->create<std::string>("name").set("WBXv4 TX"); - else if(rx_id == 0x0081) this->get_tx_subtree()->create<std::string>("name").set("WBX-120 TX"); - for(const std::string &name: wbx_v4_tx_gain_ranges.keys()){ - self_base->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&wbx_base::wbx_version4::set_tx_gain, this, std::placeholders::_1, name)) + // get_tx_id() will always return GDB ID, so use RX ID to determine WBXv4 vs. WBX-120 + if (rx_id == 0x0063) + this->get_tx_subtree()->create<std::string>("name").set("WBXv4 TX"); + else if (rx_id == 0x0081) + this->get_tx_subtree()->create<std::string>("name").set("WBX-120 TX"); + for (const std::string& name : wbx_v4_tx_gain_ranges.keys()) { + self_base->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer(std::bind( + &wbx_base::wbx_version4::set_tx_gain, this, std::placeholders::_1, name)) .set(wbx_v4_tx_gain_ranges[name].start()); - self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + self_base->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(wbx_v4_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") - .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_TX, std::placeholders::_1)) - .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0); + this->get_tx_subtree() + ->create<double>("freq/value") + .set_coercer(std::bind(&wbx_base::wbx_version4::set_lo_freq, + this, + dboard_iface::UNIT_TX, + std::placeholders::_1)) + .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop()) / 2.0); this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range); - this->get_tx_subtree()->create<bool>("enabled") - .add_coerced_subscriber(std::bind(&wbx_base::wbx_version4::set_tx_enabled, this, std::placeholders::_1)) - .set(true); //start enabled + this->get_tx_subtree() + ->create<bool>("enabled") + .add_coerced_subscriber(std::bind( + &wbx_base::wbx_version4::set_tx_enabled, this, std::placeholders::_1)) + .set(true); // start enabled - //set attenuator control bits + // set attenuator control bits int v4_iobits = TX_ATTN_MASK; int v4_tx_mod = ADF435X_PDBRF; - //set the gpio directions and atr controls - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, \ - v4_tx_mod|v4_iobits); - self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, \ - RXBB_PDB|ADF435X_PDBRF); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, \ - TX_PUP_5V|TX_PUP_3V|v4_tx_mod|v4_iobits); - self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, \ - RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK); - - //setup ATR for the mixer enables (always enabled to prevent phase slip - //between bursts) set TX gain iobits to min gain (max attenuation) when - //RX_ONLY or IDLE to suppress LO leakage - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_IDLE, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_RX_ONLY, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_TX_ONLY, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, v4_tx_mod, \ - TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); - - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_IDLE, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_TX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_RX_ONLY, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \ - gpio_atr::ATR_REG_FULL_DUPLEX, \ - RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); + // set the gpio directions and atr controls + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v4_tx_mod | v4_iobits); + self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB | ADF435X_PDBRF); + self_base->get_iface()->set_gpio_ddr( + dboard_iface::UNIT_TX, TX_PUP_5V | TX_PUP_3V | v4_tx_mod | v4_iobits); + self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, + RX_PUP_5V | RX_PUP_3V | ADF435X_CE | RXBB_PDB | ADF435X_PDBRF | RX_ATTN_MASK); + + // setup ATR for the mixer enables (always enabled to prevent phase slip + // between bursts) set TX gain iobits to min gain (max attenuation) when + // RX_ONLY or IDLE to suppress LO leakage + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + v4_tx_mod, + TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod); + + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_IDLE, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_TX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_RX_ONLY, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); + self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + RX_MIXER_ENB, + RX_MIXER_DIS | RX_MIXER_ENB); } -wbx_base::wbx_version4::~wbx_version4(void){ +wbx_base::wbx_version4::~wbx_version4(void) +{ /* NOP */ } @@ -160,29 +188,35 @@ wbx_base::wbx_version4::~wbx_version4(void){ /*********************************************************************** * Enables **********************************************************************/ -void wbx_base::wbx_version4::set_tx_enabled(bool enb) { +void wbx_base::wbx_version4::set_tx_enabled(bool enb) +{ self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, - (enb)? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN | 0); + (enb) ? TX_POWER_UP | ADF435X_CE : TX_POWER_DOWN, + TX_POWER_UP | TX_POWER_DOWN | 0); } /*********************************************************************** * Gain Handling **********************************************************************/ -double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string &name) { +double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string& name) +{ assert_has(wbx_v4_tx_gain_ranges.keys(), name, "wbx tx gain name"); - if(name == "PGA0"){ + if (name == "PGA0") { uint16_t io_bits = tx_pga0_gain_to_iobits(gain); self_base->_tx_gains[name] = gain; - //write the new gain to tx gpio outputs - //Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); - self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); + // write the new gain to tx gpio outputs + // Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR + // states + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK); + self_base->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); return self_base->_tx_gains[name]; } @@ -190,62 +224,66 @@ double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string &name) /*********************************************************************** * Tuning **********************************************************************/ -double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { - //clip to tuning range +double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double target_freq) +{ + // clip to tuning range target_freq = wbx_v4_freq_range.clip(target_freq); - UHD_LOGGER_TRACE("WBX") << boost::format( - "WBX tune: target frequency %f MHz" - ) % (target_freq/1e6) ; + UHD_LOGGER_TRACE("WBX") << boost::format("WBX tune: target frequency %f MHz") + % (target_freq / 1e6); /* * If the user sets 'mode_n=integer' in the tuning args, the user wishes to * tune in Integer-N mode, which can result in better spur * performance on some mixers. The default is fractional tuning. */ - property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree() - : self_base->get_tx_subtree(); + property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) + ? self_base->get_rx_subtree() + : self_base->get_tx_subtree(); device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get(); - bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer"); - double reference_freq = self_base->get_iface()->get_clock_rate(unit); + bool is_int_n = boost::iequals(tune_args.get("mode_n", ""), "integer"); + double reference_freq = self_base->get_iface()->get_clock_rate(unit); - //Select the LO + // Select the LO adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo; lo_iface->set_reference_freq(reference_freq); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //frequency must 2x the target frequency. This introduces a 180 degree phase - //ambiguity when trying to synchronize the phase of multiple boards. + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // frequency must 2x the target frequency. This introduces a 180 degree phase + // ambiguity when trying to synchronize the phase of multiple boards. double synth_target_freq = target_freq * 2; - //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) - lo_iface->set_prescaler(synth_target_freq > 3.6e9 ? - adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5); + // Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) + lo_iface->set_prescaler(synth_target_freq > 3.6e9 ? adf435x_iface::PRESCALER_8_9 + : adf435x_iface::PRESCALER_4_5); - //The feedback of the divided frequency must be disabled whenever the target frequency - //divided by the minimum PFD frequency cannot meet the minimum integer divider (N) value. - //If it is disabled, additional phase ambiguity will be introduced. With a minimum PFD - //frequency of 10 MHz, synthesizer frequencies below 230 MHz (LO frequencies below 115 MHz) - //will have too much ambiguity to synchronize. + // The feedback of the divided frequency must be disabled whenever the target + // frequency divided by the minimum PFD frequency cannot meet the minimum integer + // divider (N) value. If it is disabled, additional phase ambiguity will be + // introduced. With a minimum PFD frequency of 10 MHz, synthesizer frequencies below + // 230 MHz (LO frequencies below 115 MHz) will have too much ambiguity to synchronize. lo_iface->set_feedback_select( - (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() ? - adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL)); + (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() + ? adf435x_iface::FB_SEL_DIVIDED + : adf435x_iface::FB_SEL_FUNDAMENTAL)); double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n); - //The mixer has a divide-by-2 stage on the LO port so the synthesizer - //actual_freq must /2 the synth_actual_freq + // The mixer has a divide-by-2 stage on the LO port so the synthesizer + // actual_freq must /2 the synth_actual_freq double actual_freq = synth_actual_freq / 2; if (unit == dboard_iface::UNIT_RX) { - lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM); + lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_2DBM); } else { - lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? - adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM); + lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) + ? adf435x_iface::OUTPUT_POWER_5DBM + : adf435x_iface::OUTPUT_POWER_M1DBM); } - //Write to hardware + // Write to hardware lo_iface->commit(); return actual_freq; diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index 40fdca0a5..d42a56562 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -6,36 +6,38 @@ // // TX IO Pins -#define HB_PA_OFF_TXIO (1 << 15) // 5GHz PA, 1 = off, 0 = on -#define LB_PA_OFF_TXIO (1 << 14) // 2.4GHz PA, 1 = off, 0 = on -#define ANTSEL_TX1_RX2_TXIO (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX -#define ANTSEL_TX2_RX1_TXIO (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX -#define TX_EN_TXIO (1 << 11) // 1 = TX on, 0 = TX off -#define AD9515DIV_TXIO (1 << 4) // 1 = Div by 3, 0 = Div by 2 +#define HB_PA_OFF_TXIO (1 << 15) // 5GHz PA, 1 = off, 0 = on +#define LB_PA_OFF_TXIO (1 << 14) // 2.4GHz PA, 1 = off, 0 = on +#define ANTSEL_TX1_RX2_TXIO (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX +#define ANTSEL_TX2_RX1_TXIO (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX +#define TX_EN_TXIO (1 << 11) // 1 = TX on, 0 = TX off +#define AD9515DIV_TXIO (1 << 4) // 1 = Div by 3, 0 = Div by 2 -#define TXIO_MASK (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO | ANTSEL_TX1_RX2_TXIO | ANTSEL_TX2_RX1_TXIO | TX_EN_TXIO | AD9515DIV_TXIO) +#define TXIO_MASK \ + (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO | ANTSEL_TX1_RX2_TXIO | ANTSEL_TX2_RX1_TXIO \ + | TX_EN_TXIO | AD9515DIV_TXIO) // TX IO Functions -#define HB_PA_TXIO LB_PA_OFF_TXIO -#define LB_PA_TXIO HB_PA_OFF_TXIO -#define TX_ENB_TXIO TX_EN_TXIO -#define TX_DIS_TXIO (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO) -#define AD9515DIV_3_TXIO AD9515DIV_TXIO -#define AD9515DIV_2_TXIO 0 +#define HB_PA_TXIO LB_PA_OFF_TXIO +#define LB_PA_TXIO HB_PA_OFF_TXIO +#define TX_ENB_TXIO TX_EN_TXIO +#define TX_DIS_TXIO (HB_PA_OFF_TXIO | LB_PA_OFF_TXIO) +#define AD9515DIV_3_TXIO AD9515DIV_TXIO +#define AD9515DIV_2_TXIO 0 // RX IO Pins -#define LOCKDET_RXIO (1 << 15) // This is an INPUT!!! -#define POWER_RXIO (1 << 14) // 1 = power on, 0 = shutdown -#define RX_EN_RXIO (1 << 13) // 1 = RX on, 0 = RX off -#define RX_HP_RXIO (1 << 12) // 0 = Fc set by rx_hpf, 1 = 600 KHz +#define LOCKDET_RXIO (1 << 15) // This is an INPUT!!! +#define POWER_RXIO (1 << 14) // 1 = power on, 0 = shutdown +#define RX_EN_RXIO (1 << 13) // 1 = RX on, 0 = RX off +#define RX_HP_RXIO (1 << 12) // 0 = Fc set by rx_hpf, 1 = 600 KHz #define RXIO_MASK (POWER_RXIO | RX_EN_RXIO | RX_HP_RXIO) // RX IO Functions -#define POWER_UP_RXIO POWER_RXIO -#define POWER_DOWN_RXIO 0 -#define RX_ENB_RXIO RX_EN_RXIO -#define RX_DIS_RXIO 0 +#define POWER_UP_RXIO POWER_RXIO +#define POWER_DOWN_RXIO 0 +#define RX_ENB_RXIO RX_EN_RXIO +#define RX_DIS_RXIO 0 #include "max2829_regs.hpp" #include <uhd/types/dict.hpp> @@ -63,45 +65,32 @@ using namespace boost::assign; /*********************************************************************** * The XCVR 2450 constants **********************************************************************/ -static const freq_range_t xcvr_freq_range = list_of - (range_t(2.4e9, 2.5e9)) - (range_t(4.9e9, 6.0e9)) -; - -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t xcvr_tx_bandwidth_range = list_of - (range_t(2.0*12e6)) - (range_t(2.0*18e6)) - (range_t(2.0*24e6)) -; - -//Multiplied by 2.0 for conversion to complex bandpass from lowpass -static const freq_range_t xcvr_rx_bandwidth_range = list_of - (range_t(2.0*0.9*7.5e6, 2.0*1.1*7.5e6)) - (range_t(2.0*0.9*9.5e6, 2.0*1.1*9.5e6)) - (range_t(2.0*0.9*14e6, 2.0*1.1*14e6)) - (range_t(2.0*0.9*18e6, 2.0*1.1*18e6)) -; +static const freq_range_t xcvr_freq_range = + list_of(range_t(2.4e9, 2.5e9))(range_t(4.9e9, 6.0e9)); + +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t xcvr_tx_bandwidth_range = + list_of(range_t(2.0 * 12e6))(range_t(2.0 * 18e6))(range_t(2.0 * 24e6)); + +// Multiplied by 2.0 for conversion to complex bandpass from lowpass +static const freq_range_t xcvr_rx_bandwidth_range = + list_of(range_t(2.0 * 0.9 * 7.5e6, 2.0 * 1.1 * 7.5e6))( + range_t(2.0 * 0.9 * 9.5e6, 2.0 * 1.1 * 9.5e6))(range_t( + 2.0 * 0.9 * 14e6, 2.0 * 1.1 * 14e6))(range_t(2.0 * 0.9 * 18e6, 2.0 * 1.1 * 18e6)); static const std::vector<std::string> xcvr_antennas = list_of("J1")("J2"); -static const uhd::dict<std::string, gain_range_t> xcvr_tx_gain_ranges = map_list_of - ("VGA", gain_range_t(0, 30, 0.5)) - ("BB", gain_range_t(0, 5, 1.5)) -; -static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = map_list_of - ("LNA", gain_range_t(list_of - (range_t(0)) - (range_t(15)) - (range_t(30.5)) - )) - ("VGA", gain_range_t(0, 62, 2.0)) -; +static const uhd::dict<std::string, gain_range_t> xcvr_tx_gain_ranges = + map_list_of("VGA", gain_range_t(0, 30, 0.5))("BB", gain_range_t(0, 5, 1.5)); +static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = + map_list_of("LNA", gain_range_t(list_of(range_t(0))(range_t(15))(range_t(30.5))))( + "VGA", gain_range_t(0, 62, 2.0)); /*********************************************************************** * The XCVR 2450 dboard class **********************************************************************/ -class xcvr2450 : public xcvr_dboard_base{ +class xcvr2450 : public xcvr_dboard_base +{ public: xcvr2450(ctor_args_t args); virtual ~xcvr2450(void); @@ -116,35 +105,38 @@ private: double set_lo_freq(double target_freq); double set_lo_freq_core(double target_freq); - void set_tx_ant(const std::string &ant); - void set_rx_ant(const std::string &ant); - double set_tx_gain(double gain, const std::string &name); - double set_rx_gain(double gain, const std::string &name); + void set_tx_ant(const std::string& ant); + void set_rx_ant(const std::string& ant); + double set_tx_gain(double gain, const std::string& name); + double set_rx_gain(double gain, const std::string& name); double set_rx_bandwidth(double bandwidth); double set_tx_bandwidth(double bandwidth); void update_atr(void); void spi_reset(void); - void send_reg(uint8_t addr){ + void send_reg(uint8_t addr) + { uint32_t value = _max2829_regs.get_reg(addr); - UHD_LOGGER_TRACE("XCVR2450") << boost::format( - "XCVR2450: send reg 0x%02x, value 0x%05x" - ) % int(addr) % value ; + UHD_LOGGER_TRACE("XCVR2450") + << boost::format("XCVR2450: send reg 0x%02x, value 0x%05x") % int(addr) + % value; this->get_iface()->write_spi( - dboard_iface::UNIT_RX, - spi_config_t::EDGE_RISE, - value, 24 - ); + dboard_iface::UNIT_RX, spi_config_t::EDGE_RISE, value, 24); } - static bool is_highband(double freq){return freq > 3e9;} + static bool is_highband(double freq) + { + return freq > 3e9; + } /*! * Get the lock detect status of the LO. * \return sensor for locked */ - sensor_value_t get_locked(void){ - const bool locked = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & LOCKDET_RXIO) != 0; + sensor_value_t get_locked(void) + { + const bool locked = + (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & LOCKDET_RXIO) != 0; return sensor_value_t("LO", locked, "locked", "unlocked"); } @@ -152,22 +144,30 @@ private: * Read the RSSI from the aux adc * \return the rssi sensor in dBm */ - sensor_value_t get_rssi(void){ + sensor_value_t get_rssi(void) + { //*FIXME* RSSI depends on LNA Gain Setting (datasheet pg 16 top middle chart) double max_power = 0.0; - switch(_max2829_regs.rx_lna_gain){ - case 0: - case 1: max_power = 0; break; - case 2: max_power = -15; break; - case 3: max_power = -30.5; break; + switch (_max2829_regs.rx_lna_gain) { + case 0: + case 1: + max_power = 0; + break; + case 2: + max_power = -15; + break; + case 3: + max_power = -30.5; + break; } - //constants for the rssi calculation + // constants for the rssi calculation static const double min_v = 2.5, max_v = 0.5; static const double rssi_dyn_range = 60.0; - //calculate the rssi from the voltage - double voltage = this->get_iface()->read_aux_adc(dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B); - double rssi = max_power - rssi_dyn_range*(voltage - min_v)/(max_v - min_v); + // calculate the rssi from the voltage + double voltage = this->get_iface()->read_aux_adc( + dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B); + double rssi = max_power - rssi_dyn_range * (voltage - min_v) / (max_v - min_v); return sensor_value_t("RSSI", rssi, "dBm"); } }; @@ -175,12 +175,14 @@ private: /*********************************************************************** * Register the XCVR 2450 dboard **********************************************************************/ -static dboard_base::sptr make_xcvr2450(dboard_base::ctor_args_t args){ +static dboard_base::sptr make_xcvr2450(dboard_base::ctor_args_t args) +{ return dboard_base::sptr(new xcvr2450(args)); } -UHD_STATIC_BLOCK(reg_xcvr2450_dboard){ - //register the factory function for the rx and tx dbids +UHD_STATIC_BLOCK(reg_xcvr2450_dboard) +{ + // register the factory function for the rx and tx dbids dboard_manager::register_dboard(0x0061, 0x0060, &make_xcvr2450, "XCVR2450"); dboard_manager::register_dboard(0x0061, 0x0059, &make_xcvr2450, "XCVR2450 - r2.1"); } @@ -188,13 +190,14 @@ UHD_STATIC_BLOCK(reg_xcvr2450_dboard){ /*********************************************************************** * Structors **********************************************************************/ -xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){ - spi_reset(); //prepare the spi +xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args) +{ + spi_reset(); // prepare the spi _rx_bandwidth = 9.5e6; _tx_bandwidth = 12.0e6; - //setup the misc max2829 registers + // setup the misc max2829 registers _max2829_regs.mimo_select = max2829_regs_t::MIMO_SELECT_MIMO; _max2829_regs.band_sel_mimo = max2829_regs_t::BAND_SEL_MIMO_MIMO; _max2829_regs.pll_cp_select = max2829_regs_t::PLL_CP_SELECT_4MA; @@ -212,223 +215,261 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){ _max2829_regs.tx_vga_linearity = max2829_regs_t::TX_VGA_LINEARITY_78; _max2829_regs.tx_upconv_linearity = max2829_regs_t::TX_UPCONV_LINEARITY_78; - //send initial register settings - for(uint8_t reg = 0x2; reg <= 0xC; reg++){ + // send initial register settings + for (uint8_t reg = 0x2; reg <= 0xC; reg++) { this->send_reg(reg); } //////////////////////////////////////////////////////////////////// // Register RX properties //////////////////////////////////////////////////////////////////// - this->get_rx_subtree()->create<std::string>("name") - .set("XCVR2450 RX"); - this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_rx_subtree()->create<std::string>("name").set("XCVR2450 RX"); + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&xcvr2450::get_locked, this)); - this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi") + this->get_rx_subtree() + ->create<sensor_value_t>("sensors/rssi") .set_publisher(std::bind(&xcvr2450::get_rssi, this)); - for(const std::string &name: xcvr_rx_gain_ranges.keys()){ - this->get_rx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&xcvr2450::set_rx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : xcvr_rx_gain_ranges.keys()) { + this->get_rx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&xcvr2450::set_rx_gain, this, std::placeholders::_1, name)) .set(xcvr_rx_gain_ranges[name].start()); - this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_rx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(xcvr_rx_gain_ranges[name]); } - this->get_rx_subtree()->create<double>("freq/value") + this->get_rx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&xcvr2450::set_lo_freq, this, std::placeholders::_1)) .set(double(2.45e9)); - this->get_rx_subtree()->create<meta_range_t>("freq/range") - .set(xcvr_freq_range); - this->get_rx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&xcvr2450::set_rx_ant, this, std::placeholders::_1)) + this->get_rx_subtree()->create<meta_range_t>("freq/range").set(xcvr_freq_range); + this->get_rx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&xcvr2450::set_rx_ant, this, std::placeholders::_1)) .set(xcvr_antennas.at(0)); - this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_rx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(xcvr_antennas); - this->get_rx_subtree()->create<std::string>("connection") - .set("IQ"); - this->get_rx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_rx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_rx_subtree()->create<double>("bandwidth/value") - .set_coercer(std::bind(&xcvr2450::set_rx_bandwidth, this, std::placeholders::_1)) //complex bandpass bandwidth - .set(2.0*_rx_bandwidth); //_rx_bandwidth in lowpass, convert to complex bandpass - this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_rx_subtree()->create<std::string>("connection").set("IQ"); + this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_rx_subtree() + ->create<double>("bandwidth/value") + .set_coercer(std::bind(&xcvr2450::set_rx_bandwidth, + this, + std::placeholders::_1)) // complex bandpass bandwidth + .set(2.0 * _rx_bandwidth); //_rx_bandwidth in lowpass, convert to complex bandpass + this->get_rx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(xcvr_rx_bandwidth_range); //////////////////////////////////////////////////////////////////// // Register TX properties //////////////////////////////////////////////////////////////////// - this->get_tx_subtree()->create<std::string>("name") - .set("XCVR2450 TX"); - this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") + this->get_tx_subtree()->create<std::string>("name").set("XCVR2450 TX"); + this->get_tx_subtree() + ->create<sensor_value_t>("sensors/lo_locked") .set_publisher(std::bind(&xcvr2450::get_locked, this)); - for(const std::string &name: xcvr_tx_gain_ranges.keys()){ - this->get_tx_subtree()->create<double>("gains/"+name+"/value") - .set_coercer(std::bind(&xcvr2450::set_tx_gain, this, std::placeholders::_1, name)) + for (const std::string& name : xcvr_tx_gain_ranges.keys()) { + this->get_tx_subtree() + ->create<double>("gains/" + name + "/value") + .set_coercer( + std::bind(&xcvr2450::set_tx_gain, this, std::placeholders::_1, name)) .set(xcvr_tx_gain_ranges[name].start()); - this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") + this->get_tx_subtree() + ->create<meta_range_t>("gains/" + name + "/range") .set(xcvr_tx_gain_ranges[name]); } - this->get_tx_subtree()->create<double>("freq/value") + this->get_tx_subtree() + ->create<double>("freq/value") .set_coercer(std::bind(&xcvr2450::set_lo_freq, this, std::placeholders::_1)) .set(double(2.45e9)); - this->get_tx_subtree()->create<meta_range_t>("freq/range") - .set(xcvr_freq_range); - this->get_tx_subtree()->create<std::string>("antenna/value") - .add_coerced_subscriber(std::bind(&xcvr2450::set_tx_ant, this, std::placeholders::_1)) + this->get_tx_subtree()->create<meta_range_t>("freq/range").set(xcvr_freq_range); + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .add_coerced_subscriber( + std::bind(&xcvr2450::set_tx_ant, this, std::placeholders::_1)) .set(xcvr_antennas.at(1)); - this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") .set(xcvr_antennas); - this->get_tx_subtree()->create<std::string>("connection") - .set("QI"); - this->get_tx_subtree()->create<bool>("enabled") - .set(true); //always enabled - this->get_tx_subtree()->create<bool>("use_lo_offset") - .set(false); - this->get_tx_subtree()->create<double>("bandwidth/value") - .set_coercer(std::bind(&xcvr2450::set_tx_bandwidth, this, std::placeholders::_1)) //complex bandpass bandwidth - .set(2.0*_tx_bandwidth); //_tx_bandwidth in lowpass, convert to complex bandpass - this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") + this->get_tx_subtree()->create<std::string>("connection").set("QI"); + this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled + this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); + this->get_tx_subtree() + ->create<double>("bandwidth/value") + .set_coercer(std::bind(&xcvr2450::set_tx_bandwidth, + this, + std::placeholders::_1)) // complex bandpass bandwidth + .set(2.0 * _tx_bandwidth); //_tx_bandwidth in lowpass, convert to complex bandpass + this->get_tx_subtree() + ->create<meta_range_t>("bandwidth/range") .set(xcvr_tx_bandwidth_range); - //enable only the clocks we need + // enable only the clocks we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); - //set the gpio directions and atr controls (identically) + // set the gpio directions and atr controls (identically) this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXIO_MASK); this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXIO_MASK); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TXIO_MASK); this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RXIO_MASK); } -xcvr2450::~xcvr2450(void){ +xcvr2450::~xcvr2450(void) +{ UHD_SAFE_CALL(spi_reset();) } -void xcvr2450::spi_reset(void){ - //spi reset mode: global enable = off, tx and rx enable = on - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, TX_ENB_TXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO); +void xcvr2450::spi_reset(void) +{ + // spi reset mode: global enable = off, tx and rx enable = on + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, TX_ENB_TXIO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO); std::this_thread::sleep_for(std::chrono::milliseconds(10)); - //take it back out of spi reset mode and wait a bit - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO); + // take it back out of spi reset mode and wait a bit + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } /*********************************************************************** * Update ATR regs which change with Antenna or Freq **********************************************************************/ -void xcvr2450::update_atr(void){ - //calculate tx atr pins - int band_sel = (xcvr2450::is_highband(_lo_freq))? HB_PA_TXIO : LB_PA_TXIO; - int tx_ant_sel = (_tx_ant == "J1")? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; - int rx_ant_sel = (_rx_ant == "J2")? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; - int xx_ant_sel = tx_ant_sel; //Prefer the tx antenna selection for full duplex, - //due to the issue that USRP1 will take the value of full duplex for its TXATR. - int ad9515div = (_ad9515div == 3)? AD9515DIV_3_TXIO : AD9515DIV_2_TXIO; - - //set the tx registers - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, band_sel | ad9515div | TX_DIS_TXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel); - - //set the rx registers - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO); - this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, POWER_UP_RXIO | RX_DIS_RXIO); +void xcvr2450::update_atr(void) +{ + // calculate tx atr pins + int band_sel = (xcvr2450::is_highband(_lo_freq)) ? HB_PA_TXIO : LB_PA_TXIO; + int tx_ant_sel = (_tx_ant == "J1") ? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; + int rx_ant_sel = (_rx_ant == "J2") ? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO; + int xx_ant_sel = tx_ant_sel; // Prefer the tx antenna selection for full duplex, + // due to the issue that USRP1 will take the value of full duplex for its TXATR. + int ad9515div = (_ad9515div == 3) ? AD9515DIV_3_TXIO : AD9515DIV_2_TXIO; + + // set the tx registers + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_IDLE, + band_sel | ad9515div | TX_DIS_TXIO); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_RX_ONLY, + band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_TX_ONLY, + band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, + gpio_atr::ATR_REG_FULL_DUPLEX, + band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel); + + // set the rx registers + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO); + this->get_iface()->set_atr_reg( + dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO); + this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, + gpio_atr::ATR_REG_FULL_DUPLEX, + POWER_UP_RXIO | RX_DIS_RXIO); } /*********************************************************************** * Tuning **********************************************************************/ -double xcvr2450::set_lo_freq(double target_freq){ - //tune the LO and sleep a bit for lock - //if not locked, try some carrier offsets +double xcvr2450::set_lo_freq(double target_freq) +{ + // tune the LO and sleep a bit for lock + // if not locked, try some carrier offsets double actual = 0.0; - for (double offset = 0.0; offset <= 3e6; offset+=1e6){ + for (double offset = 0.0; offset <= 3e6; offset += 1e6) { actual = this->set_lo_freq_core(target_freq + offset); std::this_thread::sleep_for(std::chrono::milliseconds(50)); - if (this->get_locked().to_bool()) break; + if (this->get_locked().to_bool()) + break; } return actual; } -double xcvr2450::set_lo_freq_core(double target_freq){ - - //clip the input to the range +double xcvr2450::set_lo_freq_core(double target_freq) +{ + // clip the input to the range target_freq = xcvr_freq_range.clip(target_freq); - //variables used in the calculation below - double scaler = xcvr2450::is_highband(target_freq)? (4.0/5.0) : (4.0/3.0); + // variables used in the calculation below + double scaler = xcvr2450::is_highband(target_freq) ? (4.0 / 5.0) : (4.0 / 3.0); double ref_freq = this->get_iface()->get_codec_rate(dboard_iface::UNIT_TX); int R, intdiv = 131, fracdiv = 0; - //loop through values until we get a match - for(_ad9515div = 2; _ad9515div <= 3; _ad9515div++){ - for(R = 1; R <= 7; R++){ - double N = (target_freq*scaler*R*_ad9515div)/ref_freq; - intdiv = int(std::floor(N)); - fracdiv = boost::math::iround((N - intdiv)*double(1 << 16)); - //actual minimum is 128, but most chips seems to require higher to lock - if (intdiv < 131 or intdiv > 255) continue; - //constraints met: exit loop + // loop through values until we get a match + for (_ad9515div = 2; _ad9515div <= 3; _ad9515div++) { + for (R = 1; R <= 7; R++) { + double N = (target_freq * scaler * R * _ad9515div) / ref_freq; + intdiv = int(std::floor(N)); + fracdiv = boost::math::iround((N - intdiv) * double(1 << 16)); + // actual minimum is 128, but most chips seems to require higher to lock + if (intdiv < 131 or intdiv > 255) + continue; + // constraints met: exit loop goto done_loop; } - } done_loop: + } +done_loop: - //calculate the actual freq from the values above - double N = double(intdiv) + double(fracdiv)/double(1 << 16); - _lo_freq = (N*ref_freq)/(scaler*R*_ad9515div); + // calculate the actual freq from the values above + double N = double(intdiv) + double(fracdiv) / double(1 << 16); + _lo_freq = (N * ref_freq) / (scaler * R * _ad9515div); UHD_LOGGER_TRACE("XCVR2450") << boost::format("XCVR2450 tune:\n") - << boost::format(" R=%d, N=%f, ad9515=%d, scaler=%f\n") % R % N % _ad9515div % scaler - << boost::format(" Ref Freq=%fMHz\n") % (ref_freq/1e6) - << boost::format(" Target Freq=%fMHz\n") % (target_freq/1e6) - << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq/1e6) - ; - - //high-high band or low-high band? - if(_lo_freq > (5.35e9 + 5.47e9)/2.0){ - UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using high-high band" ; - _max2829_regs.band_select_802_11a = max2829_regs_t::BAND_SELECT_802_11A_5_47GHZ_TO_5_875GHZ; - }else{ - UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using low-high band" ; - _max2829_regs.band_select_802_11a = max2829_regs_t::BAND_SELECT_802_11A_4_9GHZ_TO_5_35GHZ; + << boost::format(" R=%d, N=%f, ad9515=%d, scaler=%f\n") % R % N % _ad9515div + % scaler + << boost::format(" Ref Freq=%fMHz\n") % (ref_freq / 1e6) + << boost::format(" Target Freq=%fMHz\n") % (target_freq / 1e6) + << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq / 1e6); + + // high-high band or low-high band? + if (_lo_freq > (5.35e9 + 5.47e9) / 2.0) { + UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using high-high band"; + _max2829_regs.band_select_802_11a = + max2829_regs_t::BAND_SELECT_802_11A_5_47GHZ_TO_5_875GHZ; + } else { + UHD_LOGGER_TRACE("XCVR2450") << "XCVR2450 tune: Using low-high band"; + _max2829_regs.band_select_802_11a = + max2829_regs_t::BAND_SELECT_802_11A_4_9GHZ_TO_5_35GHZ; } - //new band select settings and ad9515 divider + // new band select settings and ad9515 divider this->update_atr(); const bool div_ext(this->get_tx_id() == 0x0059); - if (div_ext) - { - this->get_iface()->set_clock_rate(dboard_iface::UNIT_TX, ref_freq/_ad9515div); - } - else - { + if (div_ext) { + this->get_iface()->set_clock_rate(dboard_iface::UNIT_TX, ref_freq / _ad9515div); + } else { this->get_iface()->set_clock_rate(dboard_iface::UNIT_TX, ref_freq); } - //load new counters into registers + // load new counters into registers _max2829_regs.int_div_ratio_word = intdiv; _max2829_regs.frac_div_ratio_lsb = fracdiv & 0x3; _max2829_regs.frac_div_ratio_msb = fracdiv >> 2; - this->send_reg(0x3); //integer - this->send_reg(0x4); //fractional + this->send_reg(0x3); // integer + this->send_reg(0x4); // fractional - //load the reference divider and band select into registers - //toggle the bandswitch from off to automatic (which really means start) + // load the reference divider and band select into registers + // toggle the bandswitch from off to automatic (which really means start) _max2829_regs.ref_divider = R; - _max2829_regs.band_select = (xcvr2450::is_highband(_lo_freq))? - max2829_regs_t::BAND_SELECT_5GHZ : - max2829_regs_t::BAND_SELECT_2_4GHZ ; + _max2829_regs.band_select = (xcvr2450::is_highband(_lo_freq)) + ? max2829_regs_t::BAND_SELECT_5GHZ + : max2829_regs_t::BAND_SELECT_2_4GHZ; _max2829_regs.vco_bandswitch = max2829_regs_t::VCO_BANDSWITCH_DISABLE; this->send_reg(0x5); - _max2829_regs.vco_bandswitch = max2829_regs_t::VCO_BANDSWITCH_AUTOMATIC;; + _max2829_regs.vco_bandswitch = max2829_regs_t::VCO_BANDSWITCH_AUTOMATIC; + ; this->send_reg(0x5); return _lo_freq; @@ -437,16 +478,18 @@ double xcvr2450::set_lo_freq_core(double target_freq){ /*********************************************************************** * Antenna Handling **********************************************************************/ -void xcvr2450::set_tx_ant(const std::string &ant){ +void xcvr2450::set_tx_ant(const std::string& ant) +{ assert_has(xcvr_antennas, ant, "xcvr antenna name"); - _tx_ant = ant; - this->update_atr(); //sets the atr to the new antenna setting + _tx_ant = ant; + this->update_atr(); // sets the atr to the new antenna setting } -void xcvr2450::set_rx_ant(const std::string &ant){ +void xcvr2450::set_rx_ant(const std::string& ant) +{ assert_has(xcvr_antennas, ant, "xcvr antenna name"); _rx_ant = ant; - this->update_atr(); //sets the atr to the new antenna setting + this->update_atr(); // sets the atr to the new antenna setting } /*********************************************************************** @@ -458,16 +501,20 @@ void xcvr2450::set_rx_ant(const std::string &ant){ * \param gain the requested gain in dB * \return 6 bit the register value */ -static int gain_to_tx_vga_reg(double &gain){ - //calculate the register value - int reg = uhd::clip(boost::math::iround(gain*60/30.0) + 3, 0, 63); +static int gain_to_tx_vga_reg(double& gain) +{ + // calculate the register value + int reg = uhd::clip(boost::math::iround(gain * 60 / 30.0) + 3, 0, 63); - //calculate the actual gain value - if (reg < 4) gain = 0; - else if (reg < 48) gain = double(reg/2 - 1); - else gain = double(reg/2.0 - 1.5); + // calculate the actual gain value + if (reg < 4) + gain = 0; + else if (reg < 48) + gain = double(reg / 2 - 1); + else + gain = double(reg / 2.0 - 1.5); - //return register value + // return register value return reg; } @@ -477,21 +524,22 @@ static int gain_to_tx_vga_reg(double &gain){ * \param gain the requested gain in dB * \return gain enum value */ -static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){ - int reg = uhd::clip(boost::math::iround(gain*3/5.0), 0, 3); - switch(reg){ - case 0: - gain = 0; - return max2829_regs_t::TX_BASEBAND_GAIN_0DB; - case 1: - gain = 2; - return max2829_regs_t::TX_BASEBAND_GAIN_2DB; - case 2: - gain = 3.5; - return max2829_regs_t::TX_BASEBAND_GAIN_3_5DB; - case 3: - gain = 5; - return max2829_regs_t::TX_BASEBAND_GAIN_5DB; +static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double& gain) +{ + int reg = uhd::clip(boost::math::iround(gain * 3 / 5.0), 0, 3); + switch (reg) { + case 0: + gain = 0; + return max2829_regs_t::TX_BASEBAND_GAIN_0DB; + case 1: + gain = 2; + return max2829_regs_t::TX_BASEBAND_GAIN_2DB; + case 2: + gain = 3.5; + return max2829_regs_t::TX_BASEBAND_GAIN_3_5DB; + case 3: + gain = 5; + return max2829_regs_t::TX_BASEBAND_GAIN_5DB; } UHD_THROW_INVALID_CODE_PATH(); } @@ -502,9 +550,10 @@ static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){ * \param gain the requested gain in dB * \return 5 bit the register value */ -static int gain_to_rx_vga_reg(double &gain){ - int reg = uhd::clip(boost::math::iround(gain/2.0), 0, 31); - gain = double(reg*2); +static int gain_to_rx_vga_reg(double& gain) +{ + int reg = uhd::clip(boost::math::iround(gain / 2.0), 0, 31); + gain = double(reg * 2); return reg; } @@ -514,44 +563,51 @@ static int gain_to_rx_vga_reg(double &gain){ * \param gain the requested gain in dB * \return 2 bit the register value */ -static int gain_to_rx_lna_reg(double &gain){ - int reg = uhd::clip(boost::math::iround(gain*2/30.5) + 1, 0, 3); - switch(reg){ - case 0: - case 1: gain = 0; break; - case 2: gain = 15; break; - case 3: gain = 30.5; break; +static int gain_to_rx_lna_reg(double& gain) +{ + int reg = uhd::clip(boost::math::iround(gain * 2 / 30.5) + 1, 0, 3); + switch (reg) { + case 0: + case 1: + gain = 0; + break; + case 2: + gain = 15; + break; + case 3: + gain = 30.5; + break; } return reg; } -double xcvr2450::set_tx_gain(double gain, const std::string &name){ +double xcvr2450::set_tx_gain(double gain, const std::string& name) +{ assert_has(xcvr_tx_gain_ranges.keys(), name, "xcvr tx gain name"); - if (name == "VGA"){ + if (name == "VGA") { _max2829_regs.tx_vga_gain = gain_to_tx_vga_reg(gain); send_reg(0xC); - } - else if(name == "BB"){ + } else if (name == "BB") { _max2829_regs.tx_baseband_gain = gain_to_tx_bb_reg(gain); send_reg(0x9); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); _tx_gains[name] = gain; return gain; } -double xcvr2450::set_rx_gain(double gain, const std::string &name){ +double xcvr2450::set_rx_gain(double gain, const std::string& name) +{ assert_has(xcvr_rx_gain_ranges.keys(), name, "xcvr rx gain name"); - if (name == "VGA"){ + if (name == "VGA") { _max2829_regs.rx_vga_gain = gain_to_rx_vga_reg(gain); send_reg(0xB); - } - else if(name == "LNA"){ + } else if (name == "LNA") { _max2829_regs.rx_lna_gain = gain_to_rx_lna_reg(gain); send_reg(0xB); - } - else UHD_THROW_INVALID_CODE_PATH(); + } else + UHD_THROW_INVALID_CODE_PATH(); _rx_gains[name] = gain; return gain; @@ -561,116 +617,128 @@ double xcvr2450::set_rx_gain(double gain, const std::string &name){ /*********************************************************************** * Bandwidth Handling **********************************************************************/ -static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg(double &bandwidth){ - int reg = uhd::clip(boost::math::iround((bandwidth-6.0e6)/6.0e6), 1, 3); - - switch(reg){ - case 1: // bandwidth < 15MHz - bandwidth = 12e6; - return max2829_regs_t::TX_LPF_COARSE_ADJ_12MHZ; - case 2: // 15MHz < bandwidth < 21MHz - bandwidth = 18e6; - return max2829_regs_t::TX_LPF_COARSE_ADJ_18MHZ; - case 3: // bandwidth > 21MHz - bandwidth = 24e6; - return max2829_regs_t::TX_LPF_COARSE_ADJ_24MHZ; +static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg( + double& bandwidth) +{ + int reg = uhd::clip(boost::math::iround((bandwidth - 6.0e6) / 6.0e6), 1, 3); + + switch (reg) { + case 1: // bandwidth < 15MHz + bandwidth = 12e6; + return max2829_regs_t::TX_LPF_COARSE_ADJ_12MHZ; + case 2: // 15MHz < bandwidth < 21MHz + bandwidth = 18e6; + return max2829_regs_t::TX_LPF_COARSE_ADJ_18MHZ; + case 3: // bandwidth > 21MHz + bandwidth = 24e6; + return max2829_regs_t::TX_LPF_COARSE_ADJ_24MHZ; } UHD_THROW_INVALID_CODE_PATH(); } -static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg(double &bandwidth, double requested_bandwidth){ - int reg = uhd::clip(boost::math::iround((requested_bandwidth/bandwidth)/0.05), 18, 22); - - switch(reg){ - case 18: // requested_bandwidth < 92.5% - bandwidth = 0.9 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_90; - case 19: // 92.5% < requested_bandwidth < 97.5% - bandwidth = 0.95 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_95; - case 20: // 97.5% < requested_bandwidth < 102.5% - bandwidth = 1.0 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_100; - case 21: // 102.5% < requested_bandwidth < 107.5% - bandwidth = 1.05 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_105; - case 22: // 107.5% < requested_bandwidth - bandwidth = 1.1 * bandwidth; - return max2829_regs_t::RX_LPF_FINE_ADJ_110; +static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg( + double& bandwidth, double requested_bandwidth) +{ + int reg = + uhd::clip(boost::math::iround((requested_bandwidth / bandwidth) / 0.05), 18, 22); + + switch (reg) { + case 18: // requested_bandwidth < 92.5% + bandwidth = 0.9 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_90; + case 19: // 92.5% < requested_bandwidth < 97.5% + bandwidth = 0.95 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_95; + case 20: // 97.5% < requested_bandwidth < 102.5% + bandwidth = 1.0 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_100; + case 21: // 102.5% < requested_bandwidth < 107.5% + bandwidth = 1.05 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_105; + case 22: // 107.5% < requested_bandwidth + bandwidth = 1.1 * bandwidth; + return max2829_regs_t::RX_LPF_FINE_ADJ_110; } UHD_THROW_INVALID_CODE_PATH(); } -static max2829_regs_t::rx_lpf_coarse_adj_t bandwidth_to_rx_lpf_coarse_reg(double &bandwidth){ - int reg = uhd::clip(boost::math::iround((bandwidth-7.0e6)/1.0e6), 0, 11); - - switch(reg){ - case 0: // bandwidth < 7.5MHz - case 1: // 7.5MHz < bandwidth < 8.5MHz - bandwidth = 7.5e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_7_5MHZ; - case 2: // 8.5MHz < bandwidth < 9.5MHz - case 3: // 9.5MHz < bandwidth < 10.5MHz - case 4: // 10.5MHz < bandwidth < 11.5MHz - bandwidth = 9.5e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_9_5MHZ; - case 5: // 11.5MHz < bandwidth < 12.5MHz - case 6: // 12.5MHz < bandwidth < 13.5MHz - case 7: // 13.5MHz < bandwidth < 14.5MHz - case 8: // 14.5MHz < bandwidth < 15.5MHz - bandwidth = 14e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_14MHZ; - case 9: // 15.5MHz < bandwidth < 16.5MHz - case 10: // 16.5MHz < bandwidth < 17.5MHz - case 11: // 17.5MHz < bandwidth - bandwidth = 18e6; - return max2829_regs_t::RX_LPF_COARSE_ADJ_18MHZ; +static max2829_regs_t::rx_lpf_coarse_adj_t bandwidth_to_rx_lpf_coarse_reg( + double& bandwidth) +{ + int reg = uhd::clip(boost::math::iround((bandwidth - 7.0e6) / 1.0e6), 0, 11); + + switch (reg) { + case 0: // bandwidth < 7.5MHz + case 1: // 7.5MHz < bandwidth < 8.5MHz + bandwidth = 7.5e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_7_5MHZ; + case 2: // 8.5MHz < bandwidth < 9.5MHz + case 3: // 9.5MHz < bandwidth < 10.5MHz + case 4: // 10.5MHz < bandwidth < 11.5MHz + bandwidth = 9.5e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_9_5MHZ; + case 5: // 11.5MHz < bandwidth < 12.5MHz + case 6: // 12.5MHz < bandwidth < 13.5MHz + case 7: // 13.5MHz < bandwidth < 14.5MHz + case 8: // 14.5MHz < bandwidth < 15.5MHz + bandwidth = 14e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_14MHZ; + case 9: // 15.5MHz < bandwidth < 16.5MHz + case 10: // 16.5MHz < bandwidth < 17.5MHz + case 11: // 17.5MHz < bandwidth + bandwidth = 18e6; + return max2829_regs_t::RX_LPF_COARSE_ADJ_18MHZ; } UHD_THROW_INVALID_CODE_PATH(); } -double xcvr2450::set_rx_bandwidth(double bandwidth){ +double xcvr2450::set_rx_bandwidth(double bandwidth) +{ double requested_bandwidth = bandwidth; - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - //compute coarse low pass cutoff frequency setting + // compute coarse low pass cutoff frequency setting _max2829_regs.rx_lpf_coarse_adj = bandwidth_to_rx_lpf_coarse_reg(bandwidth); - //compute fine low pass cutoff frequency setting - _max2829_regs.rx_lpf_fine_adj = bandwidth_to_rx_lpf_fine_reg(bandwidth, requested_bandwidth); + // compute fine low pass cutoff frequency setting + _max2829_regs.rx_lpf_fine_adj = + bandwidth_to_rx_lpf_fine_reg(bandwidth, requested_bandwidth); - //shadow bandwidth setting + // shadow bandwidth setting _rx_bandwidth = bandwidth; - //update register + // update register send_reg(0x7); - UHD_LOGGER_TRACE("XCVR2450") << boost::format( - "XCVR2450 RX Bandwidth (lp_fc): %f Hz, coarse reg: %d, fine reg: %d" - ) % _rx_bandwidth % (int(_max2829_regs.rx_lpf_coarse_adj)) % (int(_max2829_regs.rx_lpf_fine_adj)) ; + UHD_LOGGER_TRACE("XCVR2450") + << boost::format( + "XCVR2450 RX Bandwidth (lp_fc): %f Hz, coarse reg: %d, fine reg: %d") + % _rx_bandwidth % (int(_max2829_regs.rx_lpf_coarse_adj)) + % (int(_max2829_regs.rx_lpf_fine_adj)); - return 2.0*_rx_bandwidth; + return 2.0 * _rx_bandwidth; } -double xcvr2450::set_tx_bandwidth(double bandwidth){ - //convert complex bandpass to lowpass bandwidth - bandwidth = bandwidth/2.0; +double xcvr2450::set_tx_bandwidth(double bandwidth) +{ + // convert complex bandpass to lowpass bandwidth + bandwidth = bandwidth / 2.0; - //compute coarse low pass cutoff frequency setting + // compute coarse low pass cutoff frequency setting _max2829_regs.tx_lpf_coarse_adj = bandwidth_to_tx_lpf_coarse_reg(bandwidth); - //shadow bandwidth setting + // shadow bandwidth setting _tx_bandwidth = bandwidth; - //update register + // update register send_reg(0x7); - UHD_LOGGER_TRACE("XCVR2450") << boost::format( - "XCVR2450 TX Bandwidth (lp_fc): %f Hz, coarse reg: %d" - ) % _tx_bandwidth % (int(_max2829_regs.tx_lpf_coarse_adj)) ; + UHD_LOGGER_TRACE("XCVR2450") + << boost::format("XCVR2450 TX Bandwidth (lp_fc): %f Hz, coarse reg: %d") + % _tx_bandwidth % (int(_max2829_regs.tx_lpf_coarse_adj)); - //convert lowpass back to complex bandpass bandwidth - return 2.0*_tx_bandwidth; + // convert lowpass back to complex bandpass bandwidth + return 2.0 * _tx_bandwidth; } diff --git a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp index 8b8daa681..a0d0eeb22 100644 --- a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp +++ b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.cpp @@ -28,162 +28,147 @@ e31x_radio_control_impl::~e31x_radio_control_impl() /****************************************************************************** * API Calls *****************************************************************************/ -uint32_t e31x_radio_control_impl::get_tx_switches( - const size_t chan, - const double freq -) { - RFNOC_LOG_TRACE( - "Update all TX freq related switches. f=" << freq << " Hz, " - ); +uint32_t e31x_radio_control_impl::get_tx_switches(const size_t chan, const double freq) +{ + RFNOC_LOG_TRACE("Update all TX freq related switches. f=" << freq << " Hz, "); - size_t fe_chan = _fe_swap ? (chan ? 0 : 1): chan; + size_t fe_chan = _fe_swap ? (chan ? 0 : 1) : chan; - auto tx_sw1 = TX_SW1_LB_2750; // SW1 = 0 + auto tx_sw1 = TX_SW1_LB_2750; // SW1 = 0 auto vctxrx_sw = VCTXRX_SW_OFF; - auto tx_bias = (fe_chan == 0) ? TX1_BIAS_LB_ON: TX2_BIAS_LB_ON; + auto tx_bias = (fe_chan == 0) ? TX1_BIAS_LB_ON : TX2_BIAS_LB_ON; const auto band = e3xx_radio_control_impl::map_freq_to_tx_band(freq); - switch(band) { - case tx_band::LB_80: - tx_sw1 = TX_SW1_LB_80; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_160: - tx_sw1 = TX_SW1_LB_160; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_225: - tx_sw1 = TX_SW1_LB_225; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_400: - tx_sw1 = TX_SW1_LB_400; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_575: - tx_sw1 = TX_SW1_LB_575; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_1000: - tx_sw1 = TX_SW1_LB_1000; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_1700: - tx_sw1 = TX_SW1_LB_1700; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::LB_2750: - tx_sw1 = TX_SW1_LB_2750; - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB: VCTXRX2_SW_TX_LB; - break; - case tx_band::HB: - tx_sw1 = TX_SW1_LB_80; - vctxrx_sw = VCTXRX_SW_TX_HB; - tx_bias = (fe_chan == 0) ? TX1_BIAS_HB_ON: TX2_BIAS_HB_ON; - break; - case tx_band::INVALID_BAND: - RFNOC_LOG_ERROR( - "Cannot map TX frequency to band: " << freq); - UHD_THROW_INVALID_CODE_PATH(); - break; + switch (band) { + case tx_band::LB_80: + tx_sw1 = TX_SW1_LB_80; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_160: + tx_sw1 = TX_SW1_LB_160; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_225: + tx_sw1 = TX_SW1_LB_225; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_400: + tx_sw1 = TX_SW1_LB_400; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_575: + tx_sw1 = TX_SW1_LB_575; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_1000: + tx_sw1 = TX_SW1_LB_1000; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_1700: + tx_sw1 = TX_SW1_LB_1700; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::LB_2750: + tx_sw1 = TX_SW1_LB_2750; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_TX_LB : VCTXRX2_SW_TX_LB; + break; + case tx_band::HB: + tx_sw1 = TX_SW1_LB_80; + vctxrx_sw = VCTXRX_SW_TX_HB; + tx_bias = (fe_chan == 0) ? TX1_BIAS_HB_ON : TX2_BIAS_HB_ON; + break; + case tx_band::INVALID_BAND: + RFNOC_LOG_ERROR("Cannot map TX frequency to band: " << freq); + UHD_THROW_INVALID_CODE_PATH(); + break; } RFNOC_LOG_TRACE("TX band = " << int(band) << "TX SW1 = " << tx_sw1 << "TX VCTXRX_SW = " << vctxrx_sw << "TX_BIAS = " << tx_bias); - auto tx_regs = 0 | - vctxrx_sw << VCTXRX_SW_SHIFT | - tx_bias << TX_BIAS_SHIFT | - tx_sw1 << TX_SW1_SHIFT; + auto tx_regs = 0 | vctxrx_sw << VCTXRX_SW_SHIFT | tx_bias << TX_BIAS_SHIFT + | tx_sw1 << TX_SW1_SHIFT; return tx_regs; } uint32_t e31x_radio_control_impl::get_rx_switches( - const size_t chan, - const double freq, - const std::string &ant -){ + const size_t chan, const double freq, const std::string& ant) +{ RFNOC_LOG_TRACE("Update all E310 RX freq related switches. f=" << freq << " Hz, "); - size_t fe_chan = _fe_swap ? (chan ? 0 : 1): chan; + size_t fe_chan = _fe_swap ? (chan ? 0 : 1) : chan; // Default to OFF - auto rx_sw1 = RX_SW1_OFF; - auto rx_swc = RX_SWC_OFF; - auto rx_swb = RX_SWB_OFF; + auto rx_sw1 = RX_SW1_OFF; + auto rx_swc = RX_SWC_OFF; + auto rx_swb = RX_SWB_OFF; auto vctxrx_sw = VCTXRX_SW_OFF; - auto vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_LB: VCRX_RX_SW_LB; + auto vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_LB : VCRX_RX_SW_LB; if (ant == "TX/RX") { - vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_RX: VCTXRX2_SW_RX; + vctxrx_sw = (fe_chan == 0) ? VCTXRX1_SW_RX : VCTXRX2_SW_RX; } const auto band = e3xx_radio_control_impl::map_freq_to_rx_band(freq); - switch(band) { - case rx_band::LB_B2: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B2: RX2_SW1_LB_B2; - rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B2: RX2_SWC_LB_B2; - rx_swb = RX_SWB_OFF; - break; - case rx_band::LB_B3: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B3: RX2_SW1_LB_B3; - rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B3: RX2_SWC_LB_B3; - rx_swb = RX_SWB_OFF; - break; - case rx_band::LB_B4: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B4: RX2_SW1_LB_B4; - rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B4: RX2_SWC_LB_B4; - rx_swb = RX_SWB_OFF; - break; - case rx_band::LB_B5: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B5: RX2_SW1_LB_B5; - rx_swc = RX_SWC_OFF; - rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B5: RX2_SWB_LB_B5; - break; - case rx_band::LB_B6: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B6: RX2_SW1_LB_B6; - rx_swc = RX_SWC_OFF; - rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B6: RX2_SWB_LB_B6; - break; - case rx_band::LB_B7: - rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B7: RX2_SW1_LB_B7; - rx_swc = RX_SWC_OFF; - rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B7: RX2_SWB_LB_B7; - break; - case rx_band::HB: - rx_sw1 = RX_SW1_OFF; - rx_swc = RX_SWC_OFF; - rx_swb = RX_SWB_OFF; - vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_HB: VCRX_RX_SW_HB; - break; - case rx_band::INVALID_BAND: - RFNOC_LOG_ERROR("Cannot map RX frequency to band: " << freq); - UHD_THROW_INVALID_CODE_PATH(); - break; + switch (band) { + case rx_band::LB_B2: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B2 : RX2_SW1_LB_B2; + rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B2 : RX2_SWC_LB_B2; + rx_swb = RX_SWB_OFF; + break; + case rx_band::LB_B3: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B3 : RX2_SW1_LB_B3; + rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B3 : RX2_SWC_LB_B3; + rx_swb = RX_SWB_OFF; + break; + case rx_band::LB_B4: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B4 : RX2_SW1_LB_B4; + rx_swc = (fe_chan == 0) ? RX1_SWC_LB_B4 : RX2_SWC_LB_B4; + rx_swb = RX_SWB_OFF; + break; + case rx_band::LB_B5: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B5 : RX2_SW1_LB_B5; + rx_swc = RX_SWC_OFF; + rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B5 : RX2_SWB_LB_B5; + break; + case rx_band::LB_B6: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B6 : RX2_SW1_LB_B6; + rx_swc = RX_SWC_OFF; + rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B6 : RX2_SWB_LB_B6; + break; + case rx_band::LB_B7: + rx_sw1 = (fe_chan == 0) ? RX1_SW1_LB_B7 : RX2_SW1_LB_B7; + rx_swc = RX_SWC_OFF; + rx_swb = (fe_chan == 0) ? RX1_SWB_LB_B7 : RX2_SWB_LB_B7; + break; + case rx_band::HB: + rx_sw1 = RX_SW1_OFF; + rx_swc = RX_SWC_OFF; + rx_swb = RX_SWB_OFF; + vcrx_sw = (ant == "TX/RX") ? VCRX_TXRX_SW_HB : VCRX_RX_SW_HB; + break; + case rx_band::INVALID_BAND: + RFNOC_LOG_ERROR("Cannot map RX frequency to band: " << freq); + UHD_THROW_INVALID_CODE_PATH(); + break; } RFNOC_LOG_TRACE("RX SW1=" << rx_sw1 << " RX SWC=" << rx_swc << " RX SWB=" << rx_swb << " RX VCRX_SW=" << vcrx_sw << " RX VCTXRX_SW=" << vctxrx_sw); - auto rx_regs = 0 | - vcrx_sw << VCRX_SW_SHIFT | - vctxrx_sw << VCTXRX_SW_SHIFT | - rx_swc << RX_SWC_SHIFT | - rx_swb << RX_SWB_SHIFT | - rx_sw1 << RX_SW1_SHIFT; + auto rx_regs = 0 | vcrx_sw << VCRX_SW_SHIFT | vctxrx_sw << VCTXRX_SW_SHIFT + | rx_swc << RX_SWC_SHIFT | rx_swb << RX_SWB_SHIFT + | rx_sw1 << RX_SW1_SHIFT; return rx_regs; } uint32_t e31x_radio_control_impl::get_idle_switches() { - uint32_t idle_regs = VCRX_SW_OFF << VCRX_SW_SHIFT | - VCTXRX_SW_OFF << VCTXRX_SW_SHIFT | - TX_BIAS_OFF << TX_BIAS_SHIFT | - RX_SWC_OFF << RX_SWC_SHIFT | - RX_SWB_OFF << RX_SWB_SHIFT | - RX_SW1_OFF << RX_SW1_SHIFT | - TX_SW1_LB_2750 << TX_SW1_SHIFT; + uint32_t idle_regs = VCRX_SW_OFF << VCRX_SW_SHIFT | VCTXRX_SW_OFF << VCTXRX_SW_SHIFT + | TX_BIAS_OFF << TX_BIAS_SHIFT | RX_SWC_OFF << RX_SWC_SHIFT + | RX_SWB_OFF << RX_SWB_SHIFT | RX_SW1_OFF << RX_SW1_SHIFT + | TX_SW1_LB_2750 << TX_SW1_SHIFT; return idle_regs; } diff --git a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp index 1c37f4077..04fa800e2 100644 --- a/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp +++ b/host/lib/usrp/dboard/e3xx/e31x_radio_control_impl.hpp @@ -6,10 +6,10 @@ // #ifndef INCLUDED_LIBUHD_RFNOC_E31X_RADIO_CTRL_IMPL_HPP -#define INCLUDED_LIBUHD_RFNOC_E31X_RADIO_CTRL_IMPL_HPP +# define INCLUDED_LIBUHD_RFNOC_E31X_RADIO_CTRL_IMPL_HPP -#include "e3xx_constants.hpp" -#include "e3xx_radio_control_impl.hpp" +# include "e3xx_constants.hpp" +# include "e3xx_radio_control_impl.hpp" namespace { static constexpr char E31x_GPIO_BANK[] = "INT0"; @@ -41,11 +41,11 @@ private: * ATR/ Switches Types *************************************************************************/ enum tx_sw1_t { - TX_SW1_LB_80 = 7, - TX_SW1_LB_160 = 6, - TX_SW1_LB_225 = 5, - TX_SW1_LB_400 = 4, - TX_SW1_LB_575 = 3, + TX_SW1_LB_80 = 7, + TX_SW1_LB_160 = 6, + TX_SW1_LB_225 = 5, + TX_SW1_LB_400 = 4, + TX_SW1_LB_575 = 3, TX_SW1_LB_1000 = 2, TX_SW1_LB_1700 = 1, TX_SW1_LB_2750 = 0, @@ -53,12 +53,12 @@ private: }; enum vctxrx_sw_t { - VCTXRX_SW_TX_HB = 3, + VCTXRX_SW_TX_HB = 3, VCTXRX1_SW_TX_LB = 1, - VCTXRX1_SW_RX = 2, + VCTXRX1_SW_RX = 2, VCTXRX2_SW_TX_LB = 2, - VCTXRX2_SW_RX = 1, - VCTXRX_SW_OFF = 0, + VCTXRX2_SW_RX = 1, + VCTXRX_SW_OFF = 0, }; enum rx_sw1_t { @@ -74,7 +74,7 @@ private: RX1_SW1_LB_B5 = 1, RX1_SW1_LB_B6 = 3, RX1_SW1_LB_B7 = 5, - RX_SW1_OFF = 7 + RX_SW1_OFF = 7 }; enum rx_swc_t { @@ -84,7 +84,7 @@ private: RX1_SWC_LB_B2 = 2, RX1_SWC_LB_B3 = 3, RX1_SWC_LB_B4 = 1, - RX_SWC_OFF = 0 + RX_SWC_OFF = 0 }; enum rx_swb_t { @@ -94,15 +94,15 @@ private: RX1_SWB_LB_B5 = 2, RX1_SWB_LB_B6 = 3, RX1_SWB_LB_B7 = 1, - RX_SWB_OFF = 0 + RX_SWB_OFF = 0 }; enum vcrx_sw_t { - VCRX_RX_SW_LB = 1, - VCRX_RX_SW_HB = 2, + VCRX_RX_SW_LB = 1, + VCRX_RX_SW_HB = 2, VCRX_TXRX_SW_LB = 2, VCRX_TXRX_SW_HB = 1, - VCRX_SW_OFF = 0 //or 3 + VCRX_SW_OFF = 0 // or 3 }; // (TX_ENABLEB, TX_ENABLEA) @@ -111,7 +111,7 @@ private: TX1_BIAS_LB_ON = 2, TX2_BIAS_HB_ON = 1, TX2_BIAS_LB_ON = 2, - TX_BIAS_OFF = 0 + TX_BIAS_OFF = 0 }; /************************************************************************ @@ -123,15 +123,9 @@ private: }; uint32_t get_rx_switches( - const size_t chan, - const double freq, - const std::string &ant - ); - - uint32_t get_tx_switches( - const size_t chan, - const double freq - ); + const size_t chan, const double freq, const std::string& ant); + + uint32_t get_tx_switches(const size_t chan, const double freq); uint32_t get_idle_switches(); diff --git a/host/lib/usrp/dboard/e3xx/e31x_regs.hpp b/host/lib/usrp/dboard/e3xx/e31x_regs.hpp index 15ce90743..11d92b953 100644 --- a/host/lib/usrp/dboard/e3xx/e31x_regs.hpp +++ b/host/lib/usrp/dboard/e3xx/e31x_regs.hpp @@ -10,17 +10,16 @@ #include <uhd/config.hpp> #include <cstdint> -static const uint32_t VCRX_SW_SHIFT = 14; -static const uint32_t VCTXRX_SW_SHIFT = 12; -static const uint32_t TX_BIAS_SHIFT = 10; -static const uint32_t RX_SWC_SHIFT = 8; -static const uint32_t RX_SWB_SHIFT = 6; -static const uint32_t RX_SW1_SHIFT = 3; -static const uint32_t TX_SW1_SHIFT = 0; +static const uint32_t VCRX_SW_SHIFT = 14; +static const uint32_t VCTXRX_SW_SHIFT = 12; +static const uint32_t TX_BIAS_SHIFT = 10; +static const uint32_t RX_SWC_SHIFT = 8; +static const uint32_t RX_SWB_SHIFT = 6; +static const uint32_t RX_SW1_SHIFT = 3; +static const uint32_t TX_SW1_SHIFT = 0; -static const uint32_t LED_RX_RX_SHIFT = 2; -static const uint32_t LED_TXRX_TX_SHIFT = 1; -static const uint32_t LED_TXRX_RX_SHIFT = 0; +static const uint32_t LED_RX_RX_SHIFT = 2; +static const uint32_t LED_TXRX_TX_SHIFT = 1; +static const uint32_t LED_TXRX_RX_SHIFT = 0; #endif /* INCLUDED_E31X_REGS_HPP */ - diff --git a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp index d9cadc86f..acd0be211 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.cpp @@ -147,10 +147,12 @@ ad9361_ctrl::sptr make_rpc(rpc_client::sptr rpcc) /*! Helper function to convert direction and channel to the 'which' required by most Catalina driver functions */ -std::string get_which_ad9361_chain(const direction_t dir, const size_t chan, const bool fe_swap) +std::string get_which_ad9361_chain( + const direction_t dir, const size_t chan, const bool fe_swap) { UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); UHD_ASSERT_THROW(chan == 0 or chan == 1); size_t ad9361_chan = fe_swap ? (chan ? 0 : 1) : chan; - return str(boost::format("%s%d") % (dir == RX_DIRECTION ? "RX" : "TX") % (ad9361_chan + 1)); + return str( + boost::format("%s%d") % (dir == RX_DIRECTION ? "RX" : "TX") % (ad9361_chan + 1)); } diff --git a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp index 129015420..fe694b05c 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_ad9361_iface.hpp @@ -5,7 +5,7 @@ // #ifndef INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP -#define INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP +# define INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP # include <uhd/types/direction.hpp> # include <uhd/types/filters.hpp> @@ -22,7 +22,8 @@ using namespace uhd::usrp; static constexpr size_t E3XX_TUNE_TIMEOUT = 60000; static constexpr size_t E3XX_RATE_TIMEOUT = 60000; ad9361_ctrl::sptr make_rpc(rpc_client::sptr rpcc); -std::string get_which_ad9361_chain(const direction_t dir, const size_t chan, const bool fe_swap=false); +std::string get_which_ad9361_chain( + const direction_t dir, const size_t chan, const bool fe_swap = false); #endif /* INCLUDED_LIBUHD_RFNOC_E3XX_AD9361_IFACE_HPP */ // vim: sw=4 et: diff --git a/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp b/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp index d3dc99fec..e28acf3b9 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_bands.cpp @@ -49,17 +49,27 @@ * E31x frequency bands: * * For RX: (chan here is fe_chan - swapped) - * Band Freq RX_BSEL-210 RXC_BSEL-10 RXB_BSEL-10 RX2 TX/RX - * VCRX_V1_V2 VCTXRX_V1_V2 - * chan1 | chan2 chan1 | chan2 chan1 | chan2 RX ant | TXRX ant chan2 | chan1 - * ---------------------------------------------------------------------------------------------------- - * LB_B2: < 450 RF5 100 RF6 101 J2 10 J1 01 -- 00 -- 00 01 10 J2 10 J1 01 - * LB_B3: 450-700 RF3 010 RF4 011 J3 11 J3 11 -- 00 -- 00 01 10 J2 10 J1 01 - * LB_B4: 700-1200 RF1 000 RF2 001 J1 01 J2 10 -- 00 -- 00 01 10 J2 10 J1 01 - * LB_B5: 1200-1800 RF2 001 RF1 000 -- 00 -- 00 J2 10 J1 01 01 10 J2 10 J1 01 - * LB_B6: 1800-2350 RF4 011 RF3 010 -- 00 -- 00 J3 11 J3 11 01 10 J2 10 J1 01 - * LB_B7: 2350-2600 RF6 101 RF5 100 -- 00 -- 00 J1 01 J2 10 01 10 J2 10 J1 01 - * HB: 2600+ --- 111 --- 111 -- 00 -- 00 -- 00 -- 00 10 01 J2 10 J1 01 + * Band Freq RX_BSEL-210 RXC_BSEL-10 RXB_BSEL-10 RX2 TX/RX + * VCRX_V1_V2 + VCTXRX_V1_V2 + * chan1 | chan2 chan1 | chan2 chan1 | chan2 RX ant | TXRX ant + chan2 | chan1 + * + ---------------------------------------------------------------------------------------------------- + * LB_B2: < 450 RF5 100 RF6 101 J2 10 J1 01 -- 00 -- 00 01 10 J2 10 + J1 01 + * LB_B3: 450-700 RF3 010 RF4 011 J3 11 J3 11 -- 00 -- 00 01 10 J2 10 + J1 01 + * LB_B4: 700-1200 RF1 000 RF2 001 J1 01 J2 10 -- 00 -- 00 01 10 J2 10 + J1 01 + * LB_B5: 1200-1800 RF2 001 RF1 000 -- 00 -- 00 J2 10 J1 01 01 10 J2 10 + J1 01 + * LB_B6: 1800-2350 RF4 011 RF3 010 -- 00 -- 00 J3 11 J3 11 01 10 J2 10 + J1 01 + * LB_B7: 2350-2600 RF6 101 RF5 100 -- 00 -- 00 J1 01 J2 10 01 10 J2 10 + J1 01 + * HB: 2600+ --- 111 --- 111 -- 00 -- 00 -- 00 -- 00 10 01 J2 10 + J1 01 * * * For TX: @@ -131,7 +141,8 @@ constexpr double E3XX_TX_LB_2750_MIN_FREQ = 1842.6e6; constexpr double E3XX_TX_HB_MIN_FREQ = 2940.0e6; } // namespace -e3xx_radio_control_impl::rx_band e3xx_radio_control_impl::map_freq_to_rx_band(const double freq) +e3xx_radio_control_impl::rx_band e3xx_radio_control_impl::map_freq_to_rx_band( + const double freq) { e3xx_radio_control_impl::rx_band band; @@ -158,7 +169,8 @@ e3xx_radio_control_impl::rx_band e3xx_radio_control_impl::map_freq_to_rx_band(co return band; } -e3xx_radio_control_impl::tx_band e3xx_radio_control_impl::map_freq_to_tx_band(const double freq) +e3xx_radio_control_impl::tx_band e3xx_radio_control_impl::map_freq_to_tx_band( + const double freq) { e3xx_radio_control_impl::tx_band band; diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp index bc9ed9169..49a9a9bda 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp @@ -75,7 +75,7 @@ void e3xx_radio_control_impl::deinit() * API Calls *****************************************************************************/ bool e3xx_radio_control_impl::check_topology(const std::vector<size_t>& connected_inputs, - const std::vector<size_t>& connected_outputs) + const std::vector<size_t>& connected_outputs) { if (!node_t::check_topology(connected_inputs, connected_outputs)) { return false; @@ -112,7 +112,7 @@ bool e3xx_radio_control_impl::check_topology(const std::vector<size_t>& connecte RFNOC_LOG_TRACE("RX FE0 Active: " << rx_fe0_active); RFNOC_LOG_TRACE("RX FE1 Active: " << rx_fe1_active); - //setup the active chains in the codec + // setup the active chains in the codec if (connected_inputs.size() + connected_outputs.size() == 0) { // Ensure at least one RX chain is enabled so AD9361 outputs a sample clock this->set_streaming_mode(true, false, true, false); @@ -252,19 +252,21 @@ void e3xx_radio_control_impl::set_rx_agc(const bool enb, const size_t chan) _ad9361->set_agc(rx_fe, enb); } -double e3xx_radio_control_impl::set_rx_bandwidth(const double bandwidth, const size_t chan) +double e3xx_radio_control_impl::set_rx_bandwidth( + const double bandwidth, const size_t chan) { std::lock_guard<std::mutex> l(_set_lock); - double clipped_bw = - _ad9361->set_bw_filter(get_which_ad9361_chain(RX_DIRECTION, chan, _fe_swap), bandwidth); + double clipped_bw = _ad9361->set_bw_filter( + get_which_ad9361_chain(RX_DIRECTION, chan, _fe_swap), bandwidth); return radio_control_impl::set_rx_bandwidth(clipped_bw, chan); } -double e3xx_radio_control_impl::set_tx_bandwidth(const double bandwidth, const size_t chan) +double e3xx_radio_control_impl::set_tx_bandwidth( + const double bandwidth, const size_t chan) { std::lock_guard<std::mutex> l(_set_lock); - double clipped_bw = - _ad9361->set_bw_filter(get_which_ad9361_chain(TX_DIRECTION, chan, _fe_swap), bandwidth); + double clipped_bw = _ad9361->set_bw_filter( + get_which_ad9361_chain(TX_DIRECTION, chan, _fe_swap), bandwidth); return radio_control_impl::set_tx_bandwidth(clipped_bw, chan); } @@ -429,7 +431,7 @@ void e3xx_radio_control_impl::loopback_self_test(const size_t chan) // Set 2R2T mode, stream on all channels this->set_streaming_mode(true, true, true, true); // This was in there in the E320 code, but the comments didn't make sense: - //this->set_streaming_mode(true, true, true, true); + // this->set_streaming_mode(true, true, true, true); // Set maximum rate for 2R2T mode /* FIXME * We're directly setting the master clock rate here because we want to @@ -457,29 +459,34 @@ void e3xx_radio_control_impl::loopback_self_test(const size_t chan) boost::hash_combine(hash, i); const uint32_t word32 = uint32_t(hash) & 0xfff0fff0; // Write test word to codec_idle idle register (on TX side) - regs().poke32( - regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_TX_IDLE_VALUE, word32); + regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_TX_IDLE_VALUE, + word32); // Read back values - TX is lower 32-bits and RX is upper 32-bits const uint32_t rb_tx = - regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_TX_IDLE_VALUE); + regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_TX_IDLE_VALUE); const uint32_t rb_rx = - regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_RX_DATA); + regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_RX_DATA); // Compare TX and RX values to test word bool test_fail = word32 != rb_tx or word32 != rb_rx; if (test_fail) { RFNOC_LOG_WARNING( "CODEC loopback test failed! " - << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") - % word32 % rb_tx % rb_rx); + << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") + % word32 % rb_tx % rb_rx); throw uhd::runtime_error("CODEC loopback test failed."); } } RFNOC_LOG_INFO("CODEC loopback test passed"); // Zero out the idle data. - regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + regmap::REG_TX_IDLE_VALUE, 0); + regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET + + regmap::REG_TX_IDLE_VALUE, + 0); // Take AD936x out of loopback mode _ad9361->data_port_loopback(false); diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp index f49cde64a..d5714634c 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.hpp @@ -9,11 +9,11 @@ #define INCLUDED_LIBUHD_RFNOC_E3XX_RADIO_CTRL_IMPL_HPP #include "e3xx_ad9361_iface.hpp" +#include <uhd/rfnoc/filter_node.hpp> #include <uhd/types/eeprom.hpp> #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include <uhd/rfnoc/filter_node.hpp> #include <uhdlib/rfnoc/radio_control_impl.hpp> #include <uhdlib/usrp/common/mpmd_mb_controller.hpp> #include <uhdlib/usrp/cores/gpio_atr_3000.hpp> @@ -22,22 +22,23 @@ namespace uhd { namespace rfnoc { namespace e3xx_regs { - constexpr uint32_t PERIPH_BASE = 0x80000; - constexpr uint32_t PERIPH_REG_OFFSET = 8; - constexpr uint32_t PERIPH_REG_CHAN_OFFSET = 0x800; - constexpr uint32_t SR_LEDS = PERIPH_BASE + 176 * PERIPH_REG_OFFSET; - constexpr uint32_t SR_FP_GPIO = PERIPH_BASE + 184 * PERIPH_REG_OFFSET; - constexpr uint32_t SR_DB_GPIO = PERIPH_BASE + 192 * PERIPH_REG_OFFSET; +constexpr uint32_t PERIPH_BASE = 0x80000; +constexpr uint32_t PERIPH_REG_OFFSET = 8; +constexpr uint32_t PERIPH_REG_CHAN_OFFSET = 0x800; +constexpr uint32_t SR_LEDS = PERIPH_BASE + 176 * PERIPH_REG_OFFSET; +constexpr uint32_t SR_FP_GPIO = PERIPH_BASE + 184 * PERIPH_REG_OFFSET; +constexpr uint32_t SR_DB_GPIO = PERIPH_BASE + 192 * PERIPH_REG_OFFSET; - constexpr uint32_t RB_DB_GPIO = PERIPH_BASE + 19 * PERIPH_REG_OFFSET; - constexpr uint32_t RB_FP_GPIO = PERIPH_BASE + 20 * PERIPH_REG_OFFSET; +constexpr uint32_t RB_DB_GPIO = PERIPH_BASE + 19 * PERIPH_REG_OFFSET; +constexpr uint32_t RB_FP_GPIO = PERIPH_BASE + 20 * PERIPH_REG_OFFSET; -} +} // namespace e3xx_regs /*! \brief Provide access to an E3xx radio. */ -class e3xx_radio_control_impl : public radio_control_impl, public uhd::rfnoc::detail::filter_node +class e3xx_radio_control_impl : public radio_control_impl, + public uhd::rfnoc::detail::filter_node { public: //! Frequency bands for RX. Bands are a function of the analog filter banks @@ -78,7 +79,7 @@ public: void deinit(); bool check_topology(const std::vector<size_t>& connected_inputs, - const std::vector<size_t>& connected_outputs); + const std::vector<size_t>& connected_outputs); /************************************************************************ * radio_control API calls @@ -87,8 +88,8 @@ public: uhd::meta_range_t get_rate_range() const; // Setters - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); double set_tx_gain(const double gain, const size_t chan); @@ -144,7 +145,10 @@ public: /************************************************************************** * Radio Identification API Calls *************************************************************************/ - std::string get_slot_name() const { return "A"; } + std::string get_slot_name() const + { + return "A"; + } virtual size_t get_chan_from_dboard_fe( const std::string& fe, const uhd::direction_t direction) const; virtual std::string get_dboard_fe_from_chan( diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp index 6ecf4ff2a..f44bdaeb7 100644 --- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp +++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp @@ -103,8 +103,10 @@ void e3xx_radio_control_impl::_init_peripherals() usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL); } RFNOC_LOG_TRACE("Initializing front-panel GPIO control...") - _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make( - _wb_ifaces.at(0), e3xx_regs::SR_FP_GPIO, e3xx_regs::RB_FP_GPIO, e3xx_regs::PERIPH_REG_OFFSET); + _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make(_wb_ifaces.at(0), + e3xx_regs::SR_FP_GPIO, + e3xx_regs::RB_FP_GPIO, + e3xx_regs::PERIPH_REG_OFFSET); auto block_args = get_block_args(); @@ -123,9 +125,9 @@ void e3xx_radio_control_impl::_init_frontend_subtree( { const fs_path tx_fe_path = fs_path("tx_frontends") / chan_idx; const fs_path rx_fe_path = fs_path("rx_frontends") / chan_idx; - RFNOC_LOG_TRACE( - "Adding non-RFNoC block properties for channel " - << chan_idx << " to prop tree path " << tx_fe_path << " and " << rx_fe_path); + RFNOC_LOG_TRACE("Adding non-RFNoC block properties for channel " + << chan_idx << " to prop tree path " << tx_fe_path << " and " + << rx_fe_path); // TX Standard attributes subtree->create<std::string>(tx_fe_path / "name").set("E3xx"); subtree->create<std::string>(tx_fe_path / "connection").set("IQ"); @@ -242,7 +244,8 @@ void e3xx_radio_control_impl::_init_frontend_subtree( auto rx_sensor_names = get_rx_sensor_names(chan_idx); for (const auto& rx_sensor_name : rx_sensor_names) { RFNOC_LOG_TRACE("Adding RX sensor " << rx_sensor_name); - get_tree()->create<sensor_value_t>(rx_fe_path / "sensors" / rx_sensor_name) + get_tree() + ->create<sensor_value_t>(rx_fe_path / "sensors" / rx_sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -253,7 +256,8 @@ void e3xx_radio_control_impl::_init_frontend_subtree( auto tx_sensor_names = get_tx_sensor_names(chan_idx); for (const auto& tx_sensor_name : tx_sensor_names) { RFNOC_LOG_TRACE("Adding TX sensor " << tx_sensor_name); - get_tree()->create<sensor_value_t>(tx_fe_path / "sensors" / tx_sensor_name) + get_tree() + ->create<sensor_value_t>(tx_fe_path / "sensors" / tx_sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -301,4 +305,3 @@ void e3xx_radio_control_impl::_init_codec() this->set_tx_bandwidth(E3XX_DEFAULT_BANDWIDTH, chan); } } - diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp index f71b1aa4e..adb93ced7 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp @@ -42,7 +42,7 @@ double magnesium_ad9371_iface::set_frequency( const double freq, const size_t chan, const direction_t dir) { // Note: This sets the frequency for both channels (1 and 2). - auto which = _get_which(dir, chan); + auto which = _get_which(dir, chan); auto actual_freq = request<double>(MAGNESIUM_TUNE_TIMEOUT, "set_freq", which, freq, false); UHD_LOG_TRACE(_log_prefix, _rpc_prefix << "set_freq returned " << actual_freq); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp index 2374a4503..2cb691025 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp @@ -55,10 +55,7 @@ private: { UHD_LOG_TRACE(_log_prefix, "[RPC] Calling " << func_name); return _rpcc->request_with_token<return_type>( - timeout_ms, - _rpc_prefix + func_name, - std::forward<Args>(args)... - ); + timeout_ms, _rpc_prefix + func_name, std::forward<Args>(args)...); }; //! Reference to the RPC client diff --git a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp index 3d670e4a3..dedb9e924 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp @@ -110,6 +110,6 @@ static constexpr uint32_t RB_MISC_IO = PERIPH_BASE + 16 * PERIPH_REG_OFFSET; static constexpr uint32_t RB_SPI = PERIPH_BASE + 17 * PERIPH_REG_OFFSET; static constexpr uint32_t RB_DB_GPIO = PERIPH_BASE + 19 * PERIPH_REG_OFFSET; static constexpr uint32_t RB_FP_GPIO = PERIPH_BASE + 20 * PERIPH_REG_OFFSET; -} +} // namespace n310_regs #endif /* INCLUDED_LIBUHD_MAGNESIUM_CONSTANTS_HPP */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp index 8f4ee0caa..27341673c 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_cpld_ctrl.hpp @@ -11,9 +11,9 @@ #include "adf4351_regs.hpp" #include "magnesium_cpld_regs.hpp" #include <uhd/types/serial.hpp> +#include <functional> #include <memory> #include <mutex> -#include <functional> //! Controls the CPLD on a Magnesium daughterboard // diff --git a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp index 6ba91a248..feff1d6f9 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp @@ -30,13 +30,13 @@ struct gain_tuple_t /*! Given a gain index, return a tuple of gain-related settings (Rx) */ -gain_tuple_t get_rx_gain_tuple( - const double gain_index, const uhd::rfnoc::magnesium_radio_control_impl::rx_band band_); +gain_tuple_t get_rx_gain_tuple(const double gain_index, + const uhd::rfnoc::magnesium_radio_control_impl::rx_band band_); /*! Given a gain index, return a tuple of gain-related settings (Tx) */ -gain_tuple_t get_tx_gain_tuple( - const double gain_index, const uhd::rfnoc::magnesium_radio_control_impl::tx_band band_); +gain_tuple_t get_tx_gain_tuple(const double gain_index, + const uhd::rfnoc::magnesium_radio_control_impl::tx_band band_); } /* namespace magnesium */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp index 28a7b0c41..e4d446f95 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp @@ -15,12 +15,11 @@ #include <uhd/utils/algorithm.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/math.hpp> -#include <uhd/rfnoc/registry.hpp> #include <boost/algorithm/string.hpp> #include <boost/format.hpp> -#include <memory> #include <cmath> #include <cstdlib> +#include <memory> #include <sstream> using namespace uhd; @@ -206,7 +205,8 @@ double magnesium_radio_control_impl::set_rate(double requested_rate) return _master_clock_rate; } -void magnesium_radio_control_impl::set_tx_antenna(const std::string& ant, const size_t chan) +void magnesium_radio_control_impl::set_tx_antenna( + const std::string& ant, const size_t chan) { if (ant != get_tx_antenna(chan)) { throw uhd::value_error( @@ -216,7 +216,8 @@ void magnesium_radio_control_impl::set_tx_antenna(const std::string& ant, const // We can't actually set the TX antenna, so let's stop here. } -void magnesium_radio_control_impl::set_rx_antenna(const std::string& ant, const size_t chan) +void magnesium_radio_control_impl::set_rx_antenna( + const std::string& ant, const size_t chan) { UHD_ASSERT_THROW(chan <= MAGNESIUM_NUM_CHANS); if (std::find(MAGNESIUM_RX_ANTENNAS.begin(), MAGNESIUM_RX_ANTENNAS.end(), ant) @@ -233,7 +234,8 @@ void magnesium_radio_control_impl::set_rx_antenna(const std::string& ant, const radio_control_impl::set_rx_antenna(ant, chan); } -double magnesium_radio_control_impl::set_tx_frequency(const double req_freq, const size_t chan) +double magnesium_radio_control_impl::set_tx_frequency( + const double req_freq, const size_t chan) { const double freq = MAGNESIUM_FREQ_RANGE.clip(req_freq); RFNOC_LOG_TRACE("set_tx_frequency(f=" << freq << ", chan=" << chan << ")"); @@ -269,7 +271,8 @@ double magnesium_radio_control_impl::set_tx_frequency(const double req_freq, con return radio_control_impl::get_tx_frequency(chan); } -void magnesium_radio_control_impl::_update_gain(const size_t chan, const uhd::direction_t dir) +void magnesium_radio_control_impl::_update_gain( + const size_t chan, const uhd::direction_t dir) { const std::string fe = (dir == TX_DIRECTION) ? "tx_frontends" : "rx_frontends"; const double freq = (dir == TX_DIRECTION) ? this->get_tx_frequency(chan) @@ -277,7 +280,8 @@ void magnesium_radio_control_impl::_update_gain(const size_t chan, const uhd::di this->_set_all_gain(this->_get_all_gain(chan, dir), freq, chan, dir); } -void magnesium_radio_control_impl::_update_freq(const size_t chan, const uhd::direction_t dir) +void magnesium_radio_control_impl::_update_freq( + const size_t chan, const uhd::direction_t dir) { const std::string ad9371_source = dir == TX_DIRECTION ? this->get_tx_lo_source(MAGNESIUM_LO1, chan) @@ -301,7 +305,8 @@ void magnesium_radio_control_impl::_update_freq(const size_t chan, const uhd::di } } -double magnesium_radio_control_impl::set_rx_frequency(const double req_freq, const size_t chan) +double magnesium_radio_control_impl::set_rx_frequency( + const double req_freq, const size_t chan) { const double freq = MAGNESIUM_FREQ_RANGE.clip(req_freq); RFNOC_LOG_TRACE("set_rx_frequency(f=" << freq << ", chan=" << chan << ")"); @@ -366,8 +371,7 @@ double magnesium_radio_control_impl::set_tx_bandwidth( void magnesium_radio_control_impl::set_tx_gain_profile( const std::string& profile, const size_t) { - if (std::find( - MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) + if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) == MAGNESIUM_GP_OPTIONS.end()) { RFNOC_LOG_ERROR("Invalid TX gain profile: " << profile); throw uhd::key_error("Invalid TX gain profile!"); @@ -378,8 +382,7 @@ void magnesium_radio_control_impl::set_tx_gain_profile( void magnesium_radio_control_impl::set_rx_gain_profile( const std::string& profile, const size_t) { - if (std::find( - MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) + if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile) == MAGNESIUM_GP_OPTIONS.end()) { RFNOC_LOG_ERROR("Invalid RX gain profile: " << profile); throw uhd::key_error("Invalid RX gain profile!"); @@ -592,12 +595,14 @@ uhd::freq_range_t magnesium_radio_control_impl::get_rx_frequency_range(const siz return meta_range_t(MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ, 1.0); } -std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_names(const size_t) const +std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_names( + const size_t) const { return {MAGNESIUM_GAIN1, MAGNESIUM_GAIN2, MAGNESIUM_AMP}; } -std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_names(const size_t) const +std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_names( + const size_t) const { return {MAGNESIUM_GAIN1, MAGNESIUM_GAIN2, MAGNESIUM_AMP}; } @@ -710,7 +715,8 @@ std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_profile_names return MAGNESIUM_GP_OPTIONS; } -std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_profile_names(const size_t ) const +std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_profile_names( + const size_t) const { return MAGNESIUM_GP_OPTIONS; } @@ -761,7 +767,7 @@ std::vector<std::string> magnesium_radio_control_impl::get_rx_lo_sources( freq_range_t magnesium_radio_control_impl::get_rx_lo_freq_range( const std::string& name, const size_t /*chan*/ -) const + ) const { if (name == MAGNESIUM_LO1) { return freq_range_t{ADF4351_MIN_FREQ, ADF4351_MAX_FREQ}; @@ -790,7 +796,7 @@ void magnesium_radio_control_impl::set_rx_lo_source( const std::string magnesium_radio_control_impl::get_rx_lo_source( const std::string& name, const size_t /*chan*/ -) const + ) const { if (name == MAGNESIUM_LO1) { // TODO: should we use this from cache? @@ -860,14 +866,14 @@ double magnesium_radio_control_impl::get_rx_lo_freq( // TX LO std::vector<std::string> magnesium_radio_control_impl::get_tx_lo_names( const size_t /*chan*/ -) const + ) const { return std::vector<std::string>{MAGNESIUM_LO1, MAGNESIUM_LO2}; } std::vector<std::string> magnesium_radio_control_impl::get_tx_lo_sources( const std::string& name, const size_t /*chan*/ -) const + ) const { if (name == MAGNESIUM_LO2) { return std::vector<std::string>{"internal"}; @@ -960,7 +966,8 @@ double magnesium_radio_control_impl::set_tx_lo_freq( return return_freq; } -double magnesium_radio_control_impl::get_tx_lo_freq(const std::string& name, const size_t chan) +double magnesium_radio_control_impl::get_tx_lo_freq( + const std::string& name, const size_t chan) { RFNOC_LOG_TRACE("get_tx_lo_freq(name=" << name << ")"); std::string source = this->get_tx_lo_source(name, chan); @@ -1106,7 +1113,8 @@ std::vector<std::string> magnesium_radio_control_impl::get_rx_sensor_names(size_ return sensor_names; } -sensor_value_t magnesium_radio_control_impl::get_rx_sensor(const std::string& name, size_t chan) +sensor_value_t magnesium_radio_control_impl::get_rx_sensor( + const std::string& name, size_t chan) { if (name == "lo_locked") { return sensor_value_t( @@ -1124,7 +1132,8 @@ std::vector<std::string> magnesium_radio_control_impl::get_tx_sensor_names(size_ return sensor_names; } -sensor_value_t magnesium_radio_control_impl::get_tx_sensor(const std::string& name, size_t chan) +sensor_value_t magnesium_radio_control_impl::get_tx_sensor( + const std::string& name, size_t chan) { if (name == "lo_locked") { return sensor_value_t( @@ -1137,7 +1146,8 @@ sensor_value_t magnesium_radio_control_impl::get_tx_sensor(const std::string& na /************************************************************************** * node_t API Calls *************************************************************************/ -void magnesium_radio_control_impl::set_command_time(uhd::time_spec_t time, const size_t chan) +void magnesium_radio_control_impl::set_command_time( + uhd::time_spec_t time, const size_t chan) { node_t::set_command_time(time, chan); _wb_ifaces.at(chan)->set_time(time); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp index c6d8e0338..3c965866e 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp @@ -14,15 +14,15 @@ #include "magnesium_ad9371_iface.hpp" #include "magnesium_cpld_ctrl.hpp" #include "magnesium_cpld_regs.hpp" -#include <iostream> +#include <uhd/types/eeprom.hpp> #include <uhd/types/serial.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <uhd/usrp/gpio_defs.hpp> -#include <uhd/types/eeprom.hpp> #include <uhdlib/rfnoc/radio_control_impl.hpp> #include <uhdlib/usrp/common/adf435x.hpp> #include <uhdlib/usrp/common/mpmd_mb_controller.hpp> #include <uhdlib/usrp/cores/gpio_atr_3000.hpp> +#include <iostream> #include <mutex> namespace uhd { namespace rfnoc { @@ -77,8 +77,8 @@ public: double set_rate(double rate); // Setters - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); double set_tx_gain(const double gain, const size_t chan); @@ -157,13 +157,15 @@ public: /************************************************************************** * Radio Identification API Calls *************************************************************************/ - std::string get_slot_name() const { return _radio_slot; } + std::string get_slot_name() const + { + return _radio_slot; + } size_t get_chan_from_dboard_fe( const std::string& fe, const uhd::direction_t direction) const; std::string get_dboard_fe_from_chan( const size_t chan, const uhd::direction_t direction) const; - std::string get_fe_name( - const size_t chan, const uhd::direction_t direction) const; + std::string get_fe_name(const size_t chan, const uhd::direction_t direction) const; /************************************************************************** * node_t API Calls diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp index 41f99cd68..a4decdaaa 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_cpld.cpp @@ -120,12 +120,11 @@ void magnesium_radio_control_impl::_update_rx_freq_switches(const double freq, const bool bypass_lnas, const magnesium_cpld_ctrl::chan_sel_t chan_sel) { - RFNOC_LOG_TRACE( - "Update all RX freq related switches. f=" << freq - << " Hz, " - "bypass LNAS: " - << (bypass_lnas ? "Yes" : "No") - << ", chan=" << chan_sel); + RFNOC_LOG_TRACE("Update all RX freq related switches. f=" + << freq + << " Hz, " + "bypass LNAS: " + << (bypass_lnas ? "Yes" : "No") << ", chan=" << chan_sel); auto rx_sw2 = magnesium_cpld_ctrl::RX_SW2_BYPASSPATHTOSWITCH6; auto rx_sw3 = magnesium_cpld_ctrl::RX_SW3_SHUTDOWNSW3; auto rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp index f515b2e33..b06222205 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp @@ -7,8 +7,8 @@ #include "magnesium_constants.hpp" #include "magnesium_gain_table.hpp" #include "magnesium_radio_control.hpp" -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> +#include <uhd/utils/log.hpp> using namespace uhd; using namespace uhd::usrp; @@ -61,14 +61,13 @@ double magnesium_radio_control_impl::_set_all_gain( const double ad9371_gain = ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) - gain_tuple.ad9371_att; - RFNOC_LOG_TRACE( - "AD9371 attenuation==" << gain_tuple.ad9371_att - << " dB, " - "AD9371 gain==" - << ad9371_gain - << " dB, " - "DSA attenuation == " - << gain_tuple.dsa_att << " dB."); + RFNOC_LOG_TRACE("AD9371 attenuation==" << gain_tuple.ad9371_att + << " dB, " + "AD9371 gain==" + << ad9371_gain + << " dB, " + "DSA attenuation == " + << gain_tuple.dsa_att << " dB."); _ad9371->set_gain(ad9371_gain, ad9371_chan, dir); _dsa_set_att(gain_tuple.dsa_att, chan, dir); if (dir == RX_DIRECTION or dir == DX_DIRECTION) { @@ -101,9 +100,8 @@ double magnesium_radio_control_impl::_get_all_gain( double magnesium_radio_control_impl::_dsa_set_att( const double att, const size_t chan, const direction_t dir) { - RFNOC_LOG_TRACE( - __func__ << "(att=" - << "att dB, chan=" << chan << ", dir=" << dir << ")") + RFNOC_LOG_TRACE(__func__ << "(att=" + << "att dB, chan=" << chan << ", dir=" << dir << ")") const uint32_t dsa_val = 2 * att; _set_dsa_val(chan, dir, dsa_val); diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp index 6595cb113..d9bf5c3d2 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp @@ -9,8 +9,8 @@ #include <uhd/types/eeprom.hpp> #include <uhd/types/sensors.hpp> #include <uhd/utils/log.hpp> -#include <uhdlib/usrp/cores/spi_core_3000.hpp> #include <uhdlib/rfnoc/reg_iface_adapter.hpp> +#include <uhdlib/usrp/cores/spi_core_3000.hpp> #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/split.hpp> @@ -25,8 +25,8 @@ namespace { enum slave_select_t { SEN_CPLD = 1, SEN_TX_LO = 2, SEN_RX_LO = 4, SEN_PHASE_DAC = 8 }; -constexpr double MAGNESIUM_DEFAULT_FREQ = 2.5e9; // Hz -constexpr double MAGNESIUM_DEFAULT_BANDWIDTH = 100e6; // Hz +constexpr double MAGNESIUM_DEFAULT_FREQ = 2.5e9; // Hz +constexpr double MAGNESIUM_DEFAULT_BANDWIDTH = 100e6; // Hz } // namespace @@ -148,10 +148,12 @@ void magnesium_radio_control_impl::_init_frontend_subtree( << chan_idx << " to prop tree path " << tx_fe_path << " and " << rx_fe_path); // TX Standard attributes - subtree->create<std::string>(tx_fe_path / "name").set(get_fe_name(chan_idx, TX_DIRECTION)); + subtree->create<std::string>(tx_fe_path / "name") + .set(get_fe_name(chan_idx, TX_DIRECTION)); subtree->create<std::string>(tx_fe_path / "connection").set("IQ"); // RX Standard attributes - subtree->create<std::string>(rx_fe_path / "name").set(get_fe_name(chan_idx, RX_DIRECTION)); + subtree->create<std::string>(rx_fe_path / "name") + .set(get_fe_name(chan_idx, RX_DIRECTION)); subtree->create<std::string>(rx_fe_path / "connection").set("IQ"); // TX Antenna subtree->create<std::string>(tx_fe_path / "antenna" / "value") @@ -160,7 +162,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_tx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(tx_fe_path / "antenna" / "options") - .set_publisher([this](){ return get_tx_antennas(0); }) + .set_publisher([this]() { return get_tx_antennas(0); }) .add_coerced_subscriber([](const std::vector<std::string>&) { throw uhd::runtime_error("Attempting to update antenna options!"); }); @@ -171,7 +173,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_rx_antenna(chan_idx); }); subtree->create<std::vector<std::string>>(rx_fe_path / "antenna" / "options") - .set_publisher([this](){ return get_rx_antennas(0); }) + .set_publisher([this]() { return get_rx_antennas(0); }) .add_coerced_subscriber([](const std::vector<std::string>&) { throw uhd::runtime_error("Attempting to update antenna options!"); }); @@ -182,7 +184,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_tx_frequency(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "freq" / "range") - .set_publisher([this, chan_idx](){ return get_tx_frequency_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_tx_frequency_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update freq range!"); }); @@ -193,7 +195,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_rx_frequency(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "freq" / "range") - .set_publisher([this, chan_idx](){ return get_rx_frequency_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_rx_frequency_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update freq range!"); }); @@ -205,7 +207,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_tx_bandwidth(chan_idx); }); subtree->create<meta_range_t>(tx_fe_path / "bandwidth" / "range") - .set_publisher([this, chan_idx](){ return get_tx_bandwidth_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_tx_bandwidth_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update bandwidth range!"); }); @@ -217,7 +219,7 @@ void magnesium_radio_control_impl::_init_frontend_subtree( }) .set_publisher([this, chan_idx]() { return this->get_rx_bandwidth(chan_idx); }); subtree->create<meta_range_t>(rx_fe_path / "bandwidth" / "range") - .set_publisher([this, chan_idx](){ return get_rx_bandwidth_range(chan_idx); }) + .set_publisher([this, chan_idx]() { return get_rx_bandwidth_range(chan_idx); }) .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update bandwidth range!"); }); @@ -230,13 +232,16 @@ void magnesium_radio_control_impl::_init_frontend_subtree( .set_coercer([this, chan_idx, gain_name](const double gain) { return this->set_tx_gain(gain, gain_name, chan_idx); }) - .set_publisher( - [this, chan_idx, gain_name]() { return get_tx_gain(gain_name, chan_idx); }); + .set_publisher([this, chan_idx, gain_name]() { + return get_tx_gain(gain_name, chan_idx); + }); subtree->create<meta_range_t>(tx_fe_path / "gains" / gain_name / "range") .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this, gain_name, chan_idx]() { return get_tx_gain_range(gain_name, chan_idx); }); + .set_publisher([this, gain_name, chan_idx]() { + return get_tx_gain_range(gain_name, chan_idx); + }); } subtree->create<std::vector<std::string>>(tx_fe_path / "gains/all/profile/options") .set_publisher( @@ -256,13 +261,16 @@ void magnesium_radio_control_impl::_init_frontend_subtree( .set_coercer([this, chan_idx, gain_name](const double gain) { return this->set_rx_gain(gain, gain_name, chan_idx); }) - .set_publisher( - [this, chan_idx, gain_name]() { return get_rx_gain(gain_name, chan_idx); }); + .set_publisher([this, chan_idx, gain_name]() { + return get_rx_gain(gain_name, chan_idx); + }); subtree->create<meta_range_t>(rx_fe_path / "gains" / gain_name / "range") .add_coerced_subscriber([](const meta_range_t&) { throw uhd::runtime_error("Attempting to update gain range!"); }) - .set_publisher([this, gain_name, chan_idx]() { return get_rx_gain_range(gain_name, chan_idx); }); + .set_publisher([this, gain_name, chan_idx]() { + return get_rx_gain_range(gain_name, chan_idx); + }); } subtree->create<std::vector<std::string>>(rx_fe_path / "gains/all/profile/options") .set_publisher( @@ -375,7 +383,8 @@ void magnesium_radio_control_impl::_init_frontend_subtree( auto rx_sensor_names = get_rx_sensor_names(chan_idx); for (const auto& sensor_name : rx_sensor_names) { RFNOC_LOG_TRACE("Adding RX sensor " << sensor_name); - get_tree()->create<sensor_value_t>(rx_fe_path / "sensors" / sensor_name) + get_tree() + ->create<sensor_value_t>(rx_fe_path / "sensors" / sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -386,7 +395,8 @@ void magnesium_radio_control_impl::_init_frontend_subtree( auto tx_sensor_names = get_tx_sensor_names(chan_idx); for (const auto& sensor_name : tx_sensor_names) { RFNOC_LOG_TRACE("Adding TX sensor " << sensor_name); - get_tree()->create<sensor_value_t>(tx_fe_path / "sensors" / sensor_name) + get_tree() + ->create<sensor_value_t>(tx_fe_path / "sensors" / sensor_name) .add_coerced_subscriber([](const sensor_value_t&) { throw uhd::runtime_error("Attempting to write to sensor!"); }) @@ -403,7 +413,8 @@ void magnesium_radio_control_impl::_init_prop_tree() } // DB EEPROM - get_tree()->create<eeprom_map_t>("eeprom") + get_tree() + ->create<eeprom_map_t>("eeprom") .add_coerced_subscriber( [this](const eeprom_map_t& db_eeprom) { set_db_eeprom(db_eeprom); }) .set_publisher([this]() { return get_db_eeprom(); }); @@ -446,4 +457,3 @@ void magnesium_radio_control_impl::_init_mpm() _n3xx_timekeeper->update_tick_rate(_master_clock_rate); radio_control_impl::set_rate(_master_clock_rate); } - diff --git a/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp b/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp index 9e0a1d3d3..9f72135dd 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_bands.cpp @@ -14,58 +14,58 @@ using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; namespace { - constexpr double FREQ_COMPARE_EPSILON = 1e-5; +constexpr double FREQ_COMPARE_EPSILON = 1e-5; - /* Note on the RX filter bank: - * - * The RX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the - * lowest frequency band. BAND7 is the highest frequency band. - * - * The following constants define lower cutoff frequencies for each band. - * RHODIUM_RX_BAND1_MIN_FREQ is the cutover frequency for switching from - * BAND0 to BAND1, and so on. - * - * Bands 1-7 have both high- and low-pass filters (effectively band - * passes). Band 0 has only low-pass filters. Frequencies have been - * chosen to allow as much of the full bandwidth through unattenuated. - * - * Switch selection logic for these bands can be found in - * rhodium_radio_control_impl::_update_rx_freq_switches() - */ - constexpr double RHODIUM_RX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; - constexpr double RHODIUM_RX_BAND1_MIN_FREQ = 450e6; - constexpr double RHODIUM_RX_BAND2_MIN_FREQ = 760e6; - constexpr double RHODIUM_RX_BAND3_MIN_FREQ = 1100e6; - constexpr double RHODIUM_RX_BAND4_MIN_FREQ = 1410e6; - constexpr double RHODIUM_RX_BAND5_MIN_FREQ = 2050e6; - constexpr double RHODIUM_RX_BAND6_MIN_FREQ = 3000e6; - constexpr double RHODIUM_RX_BAND7_MIN_FREQ = 4500e6; +/* Note on the RX filter bank: + * + * The RX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the + * lowest frequency band. BAND7 is the highest frequency band. + * + * The following constants define lower cutoff frequencies for each band. + * RHODIUM_RX_BAND1_MIN_FREQ is the cutover frequency for switching from + * BAND0 to BAND1, and so on. + * + * Bands 1-7 have both high- and low-pass filters (effectively band + * passes). Band 0 has only low-pass filters. Frequencies have been + * chosen to allow as much of the full bandwidth through unattenuated. + * + * Switch selection logic for these bands can be found in + * rhodium_radio_control_impl::_update_rx_freq_switches() + */ +constexpr double RHODIUM_RX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; +constexpr double RHODIUM_RX_BAND1_MIN_FREQ = 450e6; +constexpr double RHODIUM_RX_BAND2_MIN_FREQ = 760e6; +constexpr double RHODIUM_RX_BAND3_MIN_FREQ = 1100e6; +constexpr double RHODIUM_RX_BAND4_MIN_FREQ = 1410e6; +constexpr double RHODIUM_RX_BAND5_MIN_FREQ = 2050e6; +constexpr double RHODIUM_RX_BAND6_MIN_FREQ = 3000e6; +constexpr double RHODIUM_RX_BAND7_MIN_FREQ = 4500e6; - /* Note on the TX filter bank: - * - * The TX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the - * lowest frequency band. BAND7 is the highest frequency band. - * - * The following constants define lower cutoff frequencies for each band. - * RHODIUM_TX_BAND1_MIN_FREQ is the cutover frequency for switching from - * BAND0 to BAND1, and so on. - * - * All filters on the TX filter bank are low pass filters (no high pass - * filters). Frequencies have been chosen to allow as much of the full - * bandwidth through unattenuated. - * - * Switch selection logic for these bands can be found in - * rhodium_radio_control_impl::_update_tx_freq_switches() - */ - constexpr double RHODIUM_TX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; - constexpr double RHODIUM_TX_BAND1_MIN_FREQ = 450e6; - constexpr double RHODIUM_TX_BAND2_MIN_FREQ = 650e6; - constexpr double RHODIUM_TX_BAND3_MIN_FREQ = 1000e6; - constexpr double RHODIUM_TX_BAND4_MIN_FREQ = 1350e6; - constexpr double RHODIUM_TX_BAND5_MIN_FREQ = 1900e6; - constexpr double RHODIUM_TX_BAND6_MIN_FREQ = 3000e6; - constexpr double RHODIUM_TX_BAND7_MIN_FREQ = 4100e6; -} +/* Note on the TX filter bank: + * + * The TX path has 8 bands, which we call BAND0 through BAND7. BAND0 is the + * lowest frequency band. BAND7 is the highest frequency band. + * + * The following constants define lower cutoff frequencies for each band. + * RHODIUM_TX_BAND1_MIN_FREQ is the cutover frequency for switching from + * BAND0 to BAND1, and so on. + * + * All filters on the TX filter bank are low pass filters (no high pass + * filters). Frequencies have been chosen to allow as much of the full + * bandwidth through unattenuated. + * + * Switch selection logic for these bands can be found in + * rhodium_radio_control_impl::_update_tx_freq_switches() + */ +constexpr double RHODIUM_TX_BAND0_MIN_FREQ = RHODIUM_MIN_FREQ; +constexpr double RHODIUM_TX_BAND1_MIN_FREQ = 450e6; +constexpr double RHODIUM_TX_BAND2_MIN_FREQ = 650e6; +constexpr double RHODIUM_TX_BAND3_MIN_FREQ = 1000e6; +constexpr double RHODIUM_TX_BAND4_MIN_FREQ = 1350e6; +constexpr double RHODIUM_TX_BAND5_MIN_FREQ = 1900e6; +constexpr double RHODIUM_TX_BAND6_MIN_FREQ = 3000e6; +constexpr double RHODIUM_TX_BAND7_MIN_FREQ = 4100e6; +} // namespace rhodium_radio_control_impl::rx_band rhodium_radio_control_impl::_map_freq_to_rx_band( const double freq) @@ -132,4 +132,3 @@ bool rhodium_radio_control_impl::_is_tx_lowband(const double freq) { return _map_freq_to_tx_band(freq) == tx_band::TX_BAND_0; } - diff --git a/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp b/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp index 69e6bf676..cc6a70dc3 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp @@ -8,9 +8,9 @@ #define INCLUDED_LIBUHD_RHODIUM_CONSTANTS_HPP #include <array> -#include <vector> -#include <string> #include <cstddef> +#include <string> +#include <vector> static constexpr double RHODIUM_FREQ_COMPARE_EPSILON = 1e-5; @@ -26,37 +26,34 @@ static constexpr double RHODIUM_LO1_MIN_FREQ = 450e6; // Hz static constexpr double RHODIUM_LO1_MAX_FREQ = 6e9; // Hz static constexpr double RHODIUM_LO1_REF_FREQ = 122.88e6; // Hz -static constexpr double RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ = 0.975e9; // Hz +static constexpr double RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ = 0.975e9; // Hz static constexpr double RHODIUM_LO_2_25_GHZ_LPF_THRESHOLD_FREQ = 2.3e9; // Hz static constexpr double RHODIUM_LOWBAND_FREQ = 450e6; // Hz -static constexpr double RHODIUM_RX_IF_FREQ = 2.44e9; // Hz -static constexpr double RHODIUM_TX_IF_FREQ = 1.95e9; // Hz +static constexpr double RHODIUM_RX_IF_FREQ = 2.44e9; // Hz +static constexpr double RHODIUM_TX_IF_FREQ = 1.95e9; // Hz -static constexpr double RX_MIN_GAIN = 0.0; -static constexpr double RX_MAX_GAIN = 60.0; +static constexpr double RX_MIN_GAIN = 0.0; +static constexpr double RX_MAX_GAIN = 60.0; static constexpr double RX_GAIN_STEP = 1.0; -static constexpr double TX_MIN_GAIN = 0.0; -static constexpr double TX_MAX_GAIN = 60.0; +static constexpr double TX_MIN_GAIN = 0.0; +static constexpr double TX_MAX_GAIN = 60.0; static constexpr double TX_GAIN_STEP = 1.0; -static constexpr double LO_MIN_GAIN = 0.0; -static constexpr double LO_MAX_GAIN = 30.0; +static constexpr double LO_MIN_GAIN = 0.0; +static constexpr double LO_MAX_GAIN = 30.0; static constexpr double LO_GAIN_STEP = 1.0; -static constexpr double LO_MIN_POWER = 0.0; -static constexpr double LO_MAX_POWER = 63.0; +static constexpr double LO_MIN_POWER = 0.0; +static constexpr double LO_MAX_POWER = 63.0; static constexpr double LO_POWER_STEP = 1.0; static constexpr double RHODIUM_DEFAULT_BANDWIDTH = 250e6; // Hz static const std::vector<std::string> RHODIUM_RX_ANTENNAS = { - "TX/RX", "RX2", "CAL", "TERM" -}; + "TX/RX", "RX2", "CAL", "TERM"}; -static const std::vector<std::string> RHODIUM_TX_ANTENNAS = { - "TX/RX", "CAL", "TERM" -}; +static const std::vector<std::string> RHODIUM_TX_ANTENNAS = {"TX/RX", "CAL", "TERM"}; // These names are taken from radio_rhodium.xml static constexpr char SPUR_DODGING_PROP_NAME[] = "spur_dodging"; @@ -69,13 +66,13 @@ static constexpr char RHODIUM_DEFAULT_HB_SPUR_REDUCTION_MODE[] = "disabled"; static constexpr char RHODIUM_FPGPIO_BANK[] = "FP0"; static constexpr uint32_t RHODIUM_GPIO_MASK = 0x1F; -static constexpr uint32_t SW10_GPIO_MASK = 0x3; -static constexpr uint32_t LED_GPIO_MASK = 0x1C; +static constexpr uint32_t SW10_GPIO_MASK = 0x3; +static constexpr uint32_t LED_GPIO_MASK = 0x1C; -static constexpr uint32_t SW10_FROMTXLOWBAND = 0x0; +static constexpr uint32_t SW10_FROMTXLOWBAND = 0x0; static constexpr uint32_t SW10_FROMTXHIGHBAND = 0x1; -static constexpr uint32_t SW10_ISOLATION = 0x2; -static constexpr uint32_t SW10_TORX = 0x3; +static constexpr uint32_t SW10_ISOLATION = 0x2; +static constexpr uint32_t SW10_TORX = 0x3; static constexpr uint32_t LED_RX = 0x04; static constexpr uint32_t LED_RX2 = 0x08; @@ -95,12 +92,8 @@ static constexpr char RHODIUM_LO_POWER[] = "lo"; static constexpr char RHODIUM_FE_NAME[] = "Rhodium"; static constexpr int NUM_LO_OUTPUT_PORT_NAMES = 4; -static constexpr std::array<const char*, NUM_LO_OUTPUT_PORT_NAMES> LO_OUTPUT_PORT_NAMES = { - "LO_OUT_0", - "LO_OUT_1", - "LO_OUT_2", - "LO_OUT_3" -}; +static constexpr std::array<const char*, NUM_LO_OUTPUT_PORT_NAMES> LO_OUTPUT_PORT_NAMES = + {"LO_OUT_0", "LO_OUT_1", "LO_OUT_2", "LO_OUT_3"}; static constexpr size_t RHODIUM_NUM_CHANS = 1; diff --git a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp index 8d294bc48..0617cbd94 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.cpp @@ -6,8 +6,8 @@ #include "rhodium_cpld_ctrl.hpp" #include "rhodium_constants.hpp" -#include <uhd/utils/math.hpp> #include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> #include <boost/format.hpp> #include <chrono> @@ -15,115 +15,100 @@ using namespace uhd; using namespace uhd::math::fp_compare; namespace { - //! Address of the CPLD scratch register - constexpr uint8_t CPLD_REGS_SCRATCH = 0x05; - //! Address of the CPLD gain table selection register - constexpr uint8_t CPLD_REGS_GAIN_TBL_SEL = 0x06; - - constexpr uint32_t MAX_GAIN_INDEX = 60; - constexpr uint32_t MAX_LO_GAIN_INDEX = 30; - - //! RX Demodulator Adjustment thresholds - constexpr double RX_DEMOD_ADJ_1500OHM_THRESHOLD = 3e9; - constexpr double RX_DEMOD_ADJ_200OHM_THRESHOLD = 4.5e9; - - /* - Unlike other CPLD fields, gain control doesn't use a register and instead - commands are directly sent over SPI. The format of these 24-bit commands is - as follows. - 23:22 Table select (1 = RX, 2 = TX) - 21:16 Gain index - 15:14 Reserved - 13 Write enable for DSA1 - 12:7 Reserved - 6 Write enable for DSA2 - 5:0 Reserved - The CPLD replies with the current attenuation settings as follows, but we - ignore this reply in our code. - 23:13 Reserved - 12:7 Current attenuator setting for DSA1 - 6 Reserved - 5:0 Current attenuator setting for DSA2 - */ - //! Gain loader constants - constexpr size_t GAIN_CTRL_TABLE_FIELD = 22; - constexpr size_t GAIN_CTRL_INDEX_FIELD = 16; - constexpr size_t GAIN_CTRL_DSA1_FIELD = 13; - constexpr size_t GAIN_CTRL_DSA2_FIELD = 6; - - constexpr uint32_t GAIN_CTRL_TABLE_RX = 1; - constexpr uint32_t GAIN_CTRL_TABLE_TX = 2; - constexpr uint32_t GAIN_CTRL_DSA1_WRITE_ENABLE = 1; - constexpr uint32_t GAIN_CTRL_DSA2_WRITE_ENABLE = 1; - - /* - Similar to gain control, LO control doesn't use a register and instead - commands are directly sent over SPI. The format of these 24-bit commands is - as follows: - 23:22 Table select (Always 3 = LO) - 21:16 Attenuator setting - 15:14 Reserved - 13 Write enable for RX LO DSA - 12:7 Reserved - 6 Write enable for TX LO DSA - 5:0 Reserved - The CPLD replies with the current attenuator settings as follows, but we - ignore this reply in our code. - 23:13 Reserved - 12:7 Current attenuator setting for RX LO DSA - 6 Reserved - 5:0 Current attenuator setting for TX LO DSA - */ - //! LO Gain loader constants - constexpr size_t LO_GAIN_CTRL_TABLE_FIELD = 22; - constexpr size_t LO_GAIN_CTRL_INDEX_FIELD = 16; - constexpr size_t LO_GAIN_CTRL_RX_LO_FIELD = 13; - constexpr size_t LO_GAIN_CTRL_TX_LO_FIELD = 6; - - constexpr uint32_t LO_GAIN_CTRL_TABLE_LO = 3; - constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_ENABLE = 1; - constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_DISABLE = 0; - constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_ENABLE = 1; - constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_DISABLE = 0; -} - -rhodium_cpld_ctrl::rhodium_cpld_ctrl( - write_spi_t write_fn, - read_spi_t read_fn -) +//! Address of the CPLD scratch register +constexpr uint8_t CPLD_REGS_SCRATCH = 0x05; +//! Address of the CPLD gain table selection register +constexpr uint8_t CPLD_REGS_GAIN_TBL_SEL = 0x06; + +constexpr uint32_t MAX_GAIN_INDEX = 60; +constexpr uint32_t MAX_LO_GAIN_INDEX = 30; + +//! RX Demodulator Adjustment thresholds +constexpr double RX_DEMOD_ADJ_1500OHM_THRESHOLD = 3e9; +constexpr double RX_DEMOD_ADJ_200OHM_THRESHOLD = 4.5e9; + +/* +Unlike other CPLD fields, gain control doesn't use a register and instead +commands are directly sent over SPI. The format of these 24-bit commands is +as follows. + 23:22 Table select (1 = RX, 2 = TX) + 21:16 Gain index + 15:14 Reserved + 13 Write enable for DSA1 + 12:7 Reserved + 6 Write enable for DSA2 + 5:0 Reserved +The CPLD replies with the current attenuation settings as follows, but we +ignore this reply in our code. + 23:13 Reserved + 12:7 Current attenuator setting for DSA1 + 6 Reserved + 5:0 Current attenuator setting for DSA2 +*/ +//! Gain loader constants +constexpr size_t GAIN_CTRL_TABLE_FIELD = 22; +constexpr size_t GAIN_CTRL_INDEX_FIELD = 16; +constexpr size_t GAIN_CTRL_DSA1_FIELD = 13; +constexpr size_t GAIN_CTRL_DSA2_FIELD = 6; + +constexpr uint32_t GAIN_CTRL_TABLE_RX = 1; +constexpr uint32_t GAIN_CTRL_TABLE_TX = 2; +constexpr uint32_t GAIN_CTRL_DSA1_WRITE_ENABLE = 1; +constexpr uint32_t GAIN_CTRL_DSA2_WRITE_ENABLE = 1; + +/* +Similar to gain control, LO control doesn't use a register and instead +commands are directly sent over SPI. The format of these 24-bit commands is +as follows: + 23:22 Table select (Always 3 = LO) + 21:16 Attenuator setting + 15:14 Reserved + 13 Write enable for RX LO DSA + 12:7 Reserved + 6 Write enable for TX LO DSA + 5:0 Reserved +The CPLD replies with the current attenuator settings as follows, but we +ignore this reply in our code. + 23:13 Reserved + 12:7 Current attenuator setting for RX LO DSA + 6 Reserved + 5:0 Current attenuator setting for TX LO DSA +*/ +//! LO Gain loader constants +constexpr size_t LO_GAIN_CTRL_TABLE_FIELD = 22; +constexpr size_t LO_GAIN_CTRL_INDEX_FIELD = 16; +constexpr size_t LO_GAIN_CTRL_RX_LO_FIELD = 13; +constexpr size_t LO_GAIN_CTRL_TX_LO_FIELD = 6; + +constexpr uint32_t LO_GAIN_CTRL_TABLE_LO = 3; +constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_ENABLE = 1; +constexpr uint32_t LO_GAIN_CTRL_RX_LO_WRITE_DISABLE = 0; +constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_ENABLE = 1; +constexpr uint32_t LO_GAIN_CTRL_TX_LO_WRITE_DISABLE = 0; +} // namespace + +rhodium_cpld_ctrl::rhodium_cpld_ctrl(write_spi_t write_fn, read_spi_t read_fn) { - _write_reg_fn = [write_fn](const uint8_t addr, const uint32_t data){ + _write_reg_fn = [write_fn](const uint8_t addr, const uint32_t data) { UHD_LOG_TRACE("RH_CPLD", - str(boost::format("Writing to CPLD: 0x%02X -> 0x%04X") - % uint32_t(addr) % data)); - const uint32_t spi_transaction = 0 - | ((addr & 0x7F) << 17) - | data - ; - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("SPI Transaction: 0x%04X") - % spi_transaction)); + str(boost::format("Writing to CPLD: 0x%02X -> 0x%04X") % uint32_t(addr) + % data)); + const uint32_t spi_transaction = 0 | ((addr & 0x7F) << 17) | data; + UHD_LOG_TRACE( + "RH_CPLD", str(boost::format("SPI Transaction: 0x%04X") % spi_transaction)); write_fn(spi_transaction); }; _write_raw_fn = [write_fn](const uint32_t data) { - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("Writing to CPLD: 0x%06X") - % data)); - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("SPI Transaction: 0x%06X") - % data)); + UHD_LOG_TRACE("RH_CPLD", str(boost::format("Writing to CPLD: 0x%06X") % data)); + UHD_LOG_TRACE("RH_CPLD", str(boost::format("SPI Transaction: 0x%06X") % data)); write_fn(data); }; - _read_reg_fn = [read_fn](const uint8_t addr){ + _read_reg_fn = [read_fn](const uint8_t addr) { UHD_LOG_TRACE("RH_CPLD", - str(boost::format("Reading from CPLD address 0x%02X") - % uint32_t(addr))); - const uint32_t spi_transaction = (1<<16) - | ((addr & 0x7F) << 17) - ; - UHD_LOG_TRACE("RH_CPLD", - str(boost::format("SPI Transaction: 0x%04X") - % spi_transaction)); + str(boost::format("Reading from CPLD address 0x%02X") % uint32_t(addr))); + const uint32_t spi_transaction = (1 << 16) | ((addr & 0x7F) << 17); + UHD_LOG_TRACE( + "RH_CPLD", str(boost::format("SPI Transaction: 0x%04X") % spi_transaction)); return read_fn(spi_transaction); }; @@ -162,26 +147,23 @@ uint16_t rhodium_cpld_ctrl::get_scratch() return get_reg(CPLD_REGS_SCRATCH); } -void rhodium_cpld_ctrl::set_tx_switches( - const tx_sw2_t tx_sw2, +void rhodium_cpld_ctrl::set_tx_switches(const tx_sw2_t tx_sw2, const tx_sw3_sw4_t tx_sw3_sw4, const tx_sw5_t tx_sw5, const tx_hb_lb_sel_t tx_hb_lb_sel, - const bool defer_commit -) { + const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring TX band selection switches."\ - " sw2=" << tx_sw2 << - " sw3_sw4=" << tx_sw3_sw4 << - " sw5=" << tx_sw5 << - " hb_lb_sel=" << tx_hb_lb_sel - ); + "Configuring TX band selection switches." + " sw2=" + << tx_sw2 << " sw3_sw4=" << tx_sw3_sw4 << " sw5=" << tx_sw5 + << " hb_lb_sel=" << tx_hb_lb_sel); std::lock_guard<std::mutex> l(_set_mutex); - _regs.tx_sw2 = rhodium_cpld_regs_t::tx_sw2_t(tx_sw2); - _regs.tx_sw3_sw4 = rhodium_cpld_regs_t::tx_sw3_sw4_t(tx_sw3_sw4); - _regs.tx_sw5 = rhodium_cpld_regs_t::tx_sw5_t(tx_sw5); + _regs.tx_sw2 = rhodium_cpld_regs_t::tx_sw2_t(tx_sw2); + _regs.tx_sw3_sw4 = rhodium_cpld_regs_t::tx_sw3_sw4_t(tx_sw3_sw4); + _regs.tx_sw5 = rhodium_cpld_regs_t::tx_sw5_t(tx_sw5); _regs.tx_hb_lb_sel = rhodium_cpld_regs_t::tx_hb_lb_sel_t(tx_hb_lb_sel); if (not defer_commit) { @@ -189,29 +171,25 @@ void rhodium_cpld_ctrl::set_tx_switches( } } -void rhodium_cpld_ctrl::set_rx_switches( - const rx_sw2_sw7_t rx_sw2_sw7, +void rhodium_cpld_ctrl::set_rx_switches(const rx_sw2_sw7_t rx_sw2_sw7, const rx_sw3_t rx_sw3, const rx_sw4_sw5_t rx_sw4_sw5, const rx_sw6_t rx_sw6, const rx_hb_lb_sel_t rx_hb_lb_sel, - const bool defer_commit -) { + const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring RX band selection switches."\ - " sw2_sw7=" << rx_sw2_sw7 << - " sw3=" << rx_sw3 << - " sw4_sw5=" << rx_sw4_sw5 << - " sw6=" << rx_sw6 << - " hb_lb_sel=" << rx_hb_lb_sel - ); + "Configuring RX band selection switches." + " sw2_sw7=" + << rx_sw2_sw7 << " sw3=" << rx_sw3 << " sw4_sw5=" << rx_sw4_sw5 + << " sw6=" << rx_sw6 << " hb_lb_sel=" << rx_hb_lb_sel); std::lock_guard<std::mutex> l(_set_mutex); - _regs.rx_sw2_sw7 = rhodium_cpld_regs_t::rx_sw2_sw7_t(rx_sw2_sw7); - _regs.rx_sw3 = rhodium_cpld_regs_t::rx_sw3_t(rx_sw3); - _regs.rx_sw4_sw5 = rhodium_cpld_regs_t::rx_sw4_sw5_t(rx_sw4_sw5); - _regs.rx_sw6 = rhodium_cpld_regs_t::rx_sw6_t(rx_sw6); + _regs.rx_sw2_sw7 = rhodium_cpld_regs_t::rx_sw2_sw7_t(rx_sw2_sw7); + _regs.rx_sw3 = rhodium_cpld_regs_t::rx_sw3_t(rx_sw3); + _regs.rx_sw4_sw5 = rhodium_cpld_regs_t::rx_sw4_sw5_t(rx_sw4_sw5); + _regs.rx_sw6 = rhodium_cpld_regs_t::rx_sw6_t(rx_sw6); _regs.rx_hb_lb_sel = rhodium_cpld_regs_t::rx_hb_lb_sel_t(rx_hb_lb_sel); if (not defer_commit) { @@ -220,19 +198,16 @@ void rhodium_cpld_ctrl::set_rx_switches( } void rhodium_cpld_ctrl::set_rx_input_switches( - const rx_sw1_t rx_sw1, - const cal_iso_sw_t cal_iso_sw, - const bool defer_commit -) { + const rx_sw1_t rx_sw1, const cal_iso_sw_t cal_iso_sw, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring RX input selection switches."\ - " sw1=" << rx_sw1 << - " cal_iso=" << cal_iso_sw - ); + "Configuring RX input selection switches." + " sw1=" + << rx_sw1 << " cal_iso=" << cal_iso_sw); std::lock_guard<std::mutex> l(_set_mutex); - _regs.rx_sw1 = rhodium_cpld_regs_t::rx_sw1_t(rx_sw1); + _regs.rx_sw1 = rhodium_cpld_regs_t::rx_sw1_t(rx_sw1); _regs.cal_iso_sw = rhodium_cpld_regs_t::cal_iso_sw_t(cal_iso_sw); if (not defer_commit) { @@ -241,13 +216,12 @@ void rhodium_cpld_ctrl::set_rx_input_switches( } void rhodium_cpld_ctrl::set_tx_output_switches( - const tx_sw1_t tx_sw1, - const bool defer_commit -) { + const tx_sw1_t tx_sw1, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", - "Configuring TX output selection switches."\ - " sw1=" << tx_sw1 - ); + "Configuring TX output selection switches." + " sw1=" + << tx_sw1); std::lock_guard<std::mutex> l(_set_mutex); @@ -259,9 +233,8 @@ void rhodium_cpld_ctrl::set_tx_output_switches( } void rhodium_cpld_ctrl::set_rx_lo_source( - const rx_lo_input_sel_t rx_lo_input_sel, - const bool defer_commit -) { + const rx_lo_input_sel_t rx_lo_input_sel, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Setting RX LO source to " << rx_lo_input_sel); std::lock_guard<std::mutex> l(_set_mutex); @@ -273,9 +246,8 @@ void rhodium_cpld_ctrl::set_rx_lo_source( } void rhodium_cpld_ctrl::set_tx_lo_source( - const tx_lo_input_sel_t tx_lo_input_sel, - const bool defer_commit -) { + const tx_lo_input_sel_t tx_lo_input_sel, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Setting TX LO source to " << tx_lo_input_sel); std::lock_guard<std::mutex> l(_set_mutex); @@ -286,29 +258,32 @@ void rhodium_cpld_ctrl::set_tx_lo_source( } } -void rhodium_cpld_ctrl::set_rx_lo_path( - const double freq, - const bool defer_commit -) { +void rhodium_cpld_ctrl::set_rx_lo_path(const double freq, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Configuring RX LO filter and settings. freq=" << freq); std::lock_guard<std::mutex> l(_set_mutex); auto freq_compare = fp_compare_epsilon<double>(freq, RHODIUM_FREQ_COMPARE_EPSILON); if (freq_compare < RX_DEMOD_ADJ_1500OHM_THRESHOLD) { - _regs.rx_demod_adj = rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_1500_OHM; + _regs.rx_demod_adj = + rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_1500_OHM; } else if (freq_compare < RX_DEMOD_ADJ_200OHM_THRESHOLD) { - _regs.rx_demod_adj = rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_200_OHM; + _regs.rx_demod_adj = + rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_200_OHM; } else { _regs.rx_demod_adj = rhodium_cpld_regs_t::rx_demod_adj_t::RX_DEMOD_ADJ_RES_OPEN; } if (freq_compare < RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ) { - _regs.rx_lo_filter_sel = rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_0_9GHZ_LPF; + _regs.rx_lo_filter_sel = + rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_0_9GHZ_LPF; } else if (freq_compare < RHODIUM_LO_2_25_GHZ_LPF_THRESHOLD_FREQ) { - _regs.rx_lo_filter_sel = rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_2_25GHZ_LPF; + _regs.rx_lo_filter_sel = + rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_2_25GHZ_LPF; } else { - _regs.rx_lo_filter_sel = rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_5_85GHZ_LPF; + _regs.rx_lo_filter_sel = + rhodium_cpld_regs_t::rx_lo_filter_sel_t::RX_LO_FILTER_SEL_5_85GHZ_LPF; } if (not defer_commit) { @@ -316,21 +291,22 @@ void rhodium_cpld_ctrl::set_rx_lo_path( } } -void rhodium_cpld_ctrl::set_tx_lo_path( - const double freq, - const bool defer_commit -) { +void rhodium_cpld_ctrl::set_tx_lo_path(const double freq, const bool defer_commit) +{ UHD_LOG_TRACE("RH_CPLD", "Configuring TX LO filter and settings. freq=" << freq); std::lock_guard<std::mutex> l(_set_mutex); auto freq_compare = fp_compare_epsilon<double>(freq, RHODIUM_FREQ_COMPARE_EPSILON); if (freq_compare < RHODIUM_LO_0_9_GHZ_LPF_THRESHOLD_FREQ) { - _regs.tx_lo_filter_sel = rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_0_9GHZ_LPF; + _regs.tx_lo_filter_sel = + rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_0_9GHZ_LPF; } else if (freq_compare < RHODIUM_LO_2_25_GHZ_LPF_THRESHOLD_FREQ) { - _regs.tx_lo_filter_sel = rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_2_25GHZ_LPF; + _regs.tx_lo_filter_sel = + rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_2_25GHZ_LPF; } else { - _regs.tx_lo_filter_sel = rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_5_85GHZ_LPF; + _regs.tx_lo_filter_sel = + rhodium_cpld_regs_t::tx_lo_filter_sel_t::TX_LO_FILTER_SEL_5_85GHZ_LPF; } if (not defer_commit) { @@ -338,43 +314,35 @@ void rhodium_cpld_ctrl::set_tx_lo_path( } } -void rhodium_cpld_ctrl::set_gain_index( - const uint32_t index, +void rhodium_cpld_ctrl::set_gain_index(const uint32_t index, const gain_band_t band, const uhd::direction_t dir, - const bool defer_commit -) { + const bool defer_commit) +{ UHD_ASSERT_THROW(index <= MAX_GAIN_INDEX); UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); - if (band == HIGH) - { - if (dir == RX_DIRECTION) - { + if (band == HIGH) { + if (dir == RX_DIRECTION) { _regs.rx_gain_tbl_sel = rhodium_cpld_regs_t::RX_GAIN_TBL_SEL_HIGHBAND; - } - else { + } else { _regs.tx_gain_tbl_sel = rhodium_cpld_regs_t::TX_GAIN_TBL_SEL_HIGHBAND; } } else { - if (dir == RX_DIRECTION) - { + if (dir == RX_DIRECTION) { _regs.rx_gain_tbl_sel = rhodium_cpld_regs_t::RX_GAIN_TBL_SEL_LOWBAND; - } - else { + } else { _regs.tx_gain_tbl_sel = rhodium_cpld_regs_t::TX_GAIN_TBL_SEL_LOWBAND; } } - const uint8_t table_id = (dir == RX_DIRECTION) ? - GAIN_CTRL_TABLE_RX : - GAIN_CTRL_TABLE_TX; + const uint8_t table_id = (dir == RX_DIRECTION) ? GAIN_CTRL_TABLE_RX + : GAIN_CTRL_TABLE_TX; - const uint32_t cmd = - (table_id << GAIN_CTRL_TABLE_FIELD) | - (index << GAIN_CTRL_INDEX_FIELD) | - (GAIN_CTRL_DSA1_WRITE_ENABLE << GAIN_CTRL_DSA1_FIELD) | - (GAIN_CTRL_DSA2_WRITE_ENABLE << GAIN_CTRL_DSA2_FIELD); + const uint32_t cmd = (table_id << GAIN_CTRL_TABLE_FIELD) + | (index << GAIN_CTRL_INDEX_FIELD) + | (GAIN_CTRL_DSA1_WRITE_ENABLE << GAIN_CTRL_DSA1_FIELD) + | (GAIN_CTRL_DSA2_WRITE_ENABLE << GAIN_CTRL_DSA2_FIELD); std::lock_guard<std::mutex> l(_set_mutex); _gain_queue.emplace_back(cmd); @@ -385,28 +353,25 @@ void rhodium_cpld_ctrl::set_gain_index( } void rhodium_cpld_ctrl::set_lo_gain( - const uint32_t index, - const uhd::direction_t dir, - const bool defer_commit -) { + const uint32_t index, const uhd::direction_t dir, const bool defer_commit) +{ UHD_ASSERT_THROW(index <= MAX_LO_GAIN_INDEX); // The DSA has 0-30 dB of attenuation in 1 dB steps // This index directly controls the attenuation value of the LO DSA, // so reverse the gain value to write the value const uint32_t attenuation = MAX_LO_GAIN_INDEX - index; - const uint8_t set_rx = (dir == RX_DIRECTION or dir == DX_DIRECTION) ? - LO_GAIN_CTRL_RX_LO_WRITE_ENABLE : - LO_GAIN_CTRL_RX_LO_WRITE_DISABLE; - const uint8_t set_tx = (dir == TX_DIRECTION or dir == DX_DIRECTION) ? - LO_GAIN_CTRL_TX_LO_WRITE_ENABLE : - LO_GAIN_CTRL_TX_LO_WRITE_DISABLE; - - const uint32_t cmd = - (LO_GAIN_CTRL_TABLE_LO << LO_GAIN_CTRL_TABLE_FIELD) | - (attenuation << LO_GAIN_CTRL_INDEX_FIELD) | - (set_rx << LO_GAIN_CTRL_RX_LO_FIELD) | - (set_tx << LO_GAIN_CTRL_TX_LO_FIELD); + const uint8_t set_rx = (dir == RX_DIRECTION or dir == DX_DIRECTION) + ? LO_GAIN_CTRL_RX_LO_WRITE_ENABLE + : LO_GAIN_CTRL_RX_LO_WRITE_DISABLE; + const uint8_t set_tx = (dir == TX_DIRECTION or dir == DX_DIRECTION) + ? LO_GAIN_CTRL_TX_LO_WRITE_ENABLE + : LO_GAIN_CTRL_TX_LO_WRITE_DISABLE; + + const uint32_t cmd = (LO_GAIN_CTRL_TABLE_LO << LO_GAIN_CTRL_TABLE_FIELD) + | (attenuation << LO_GAIN_CTRL_INDEX_FIELD) + | (set_rx << LO_GAIN_CTRL_RX_LO_FIELD) + | (set_tx << LO_GAIN_CTRL_TX_LO_FIELD); std::lock_guard<std::mutex> l(_set_mutex); _gain_queue.emplace_back(cmd); @@ -431,9 +396,7 @@ void rhodium_cpld_ctrl::_loopback_test() if (actual != random_number) { UHD_LOGGER_ERROR("RH_CPLD") << "CPLD scratch loopback failed! " - << boost::format("Expected: 0x%04X Got: 0x%04X") - % random_number % actual - ; + << boost::format("Expected: 0x%04X Got: 0x%04X") % random_number % actual; throw uhd::runtime_error("CPLD scratch loopback failed!"); } UHD_LOG_TRACE("RH_CPLD", "CPLD scratch loopback test passed!"); @@ -442,33 +405,27 @@ void rhodium_cpld_ctrl::_loopback_test() void rhodium_cpld_ctrl::commit(const bool save_all) { UHD_LOGGER_TRACE("RH_CPLD") - << "Storing register cache " - << (save_all ? "completely" : "selectively") - << " to CPLD via SPI..." - ; - auto changed_addrs = save_all ? - _regs.get_all_addrs() : - _regs.get_changed_addrs<size_t>(); - for (const auto addr: changed_addrs) { + << "Storing register cache " << (save_all ? "completely" : "selectively") + << " to CPLD via SPI..."; + auto changed_addrs = save_all ? _regs.get_all_addrs() + : _regs.get_changed_addrs<size_t>(); + for (const auto addr : changed_addrs) { _write_reg_fn(addr, _regs.get_reg(addr)); } _regs.save_state(); UHD_LOG_TRACE("RH_CPLD", - "Storing cache complete: " \ - "Updated " << changed_addrs.size() << " registers.") - ; + "Storing cache complete: " + "Updated " + << changed_addrs.size() << " registers."); - UHD_LOGGER_TRACE("RH_CPLD") - << "Writing queued gain commands " - << "to CPLD via SPI..." - ; + UHD_LOGGER_TRACE("RH_CPLD") << "Writing queued gain commands " + << "to CPLD via SPI..."; for (const auto cmd : _gain_queue) { _write_raw_fn(cmd); } UHD_LOG_TRACE("RH_CPLD", - "Writing queued gain commands complete: " \ - "Wrote " << _gain_queue.size() << " commands.") - ; + "Writing queued gain commands complete: " + "Wrote " + << _gain_queue.size() << " commands."); _gain_queue.clear(); } - diff --git a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp index d60ae6e66..18b0b8c78 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_cpld_ctrl.hpp @@ -38,14 +38,14 @@ public: }; enum tx_sw1_t { - TX_SW1_TOLOWBAND = 0, - TX_SW1_TOSWITCH2 = 1, + TX_SW1_TOLOWBAND = 0, + TX_SW1_TOSWITCH2 = 1, TX_SW1_TOCALLOOPBACK = 2, - TX_SW1_ISOLATION = 3 + TX_SW1_ISOLATION = 3 }; enum tx_sw2_t { - TX_SW2_FROMSWITCH3 = 0, + TX_SW2_FROMSWITCH3 = 0, TX_SW2_FROMTXFILTERLP6000MHZ = 1, TX_SW2_FROMTXFILTERLP4100MHZ = 2, TX_SW2_FROMTXFILTERLP3000MHZ = 3 @@ -62,23 +62,23 @@ public: TX_SW5_TOTXFILTERLP3000MHZ = 0, TX_SW5_TOTXFILTERLP4100MHZ = 1, TX_SW5_TOTXFILTERLP6000MHZ = 2, - TX_SW5_TOSWITCH4 = 3 + TX_SW5_TOSWITCH4 = 3 }; enum rx_sw1_t { RX_SW1_FROMCALLOOPBACK = 0, - RX_SW1_FROMRX2INPUT = 1, - RX_SW1_ISOLATION = 2, - RX_SW1_FROMTXRXINPUT = 3 + RX_SW1_FROMRX2INPUT = 1, + RX_SW1_ISOLATION = 2, + RX_SW1_FROMTXRXINPUT = 3 }; enum rx_sw2_sw7_t { - RX_SW2_SW7_LOWBANDFILTERBANK = 0, + RX_SW2_SW7_LOWBANDFILTERBANK = 0, RX_SW2_SW7_HIGHBANDFILTERBANK = 1 }; enum rx_sw3_t { - RX_SW3_TOSWITCH4 = 0, + RX_SW3_TOSWITCH4 = 0, RX_SW3_TOFILTER4500X6000MHZ = 1, RX_SW3_TOFILTER3000X4500MHZ = 2, RX_SW3_TOFILTER2050X3000MHZ = 3 @@ -95,52 +95,33 @@ public: RX_SW6_FROMFILTER2050X3000MHZ = 0, RX_SW6_FROMFILTER3000X4500MHZ = 1, RX_SW6_FROMFILTER4500X6000MHZ = 2, - RX_SW6_FROMSWITCH5 = 3, + RX_SW6_FROMSWITCH5 = 3, }; - enum cal_iso_sw_t { - CAL_ISO_ISOLATION = 0, - CAL_ISO_CALLOOPBACK = 1 - }; + enum cal_iso_sw_t { CAL_ISO_ISOLATION = 0, CAL_ISO_CALLOOPBACK = 1 }; - enum tx_hb_lb_sel_t { - TX_HB_LB_SEL_LOWBAND = 0, - TX_HB_LB_SEL_HIGHBAND = 1 - }; + enum tx_hb_lb_sel_t { TX_HB_LB_SEL_LOWBAND = 0, TX_HB_LB_SEL_HIGHBAND = 1 }; - enum tx_lo_input_sel_t { - TX_LO_INPUT_SEL_INTERNAL = 0, - TX_LO_INPUT_SEL_EXTERNAL = 1 - }; + enum tx_lo_input_sel_t { TX_LO_INPUT_SEL_INTERNAL = 0, TX_LO_INPUT_SEL_EXTERNAL = 1 }; - enum rx_hb_lb_sel_t { - RX_HB_LB_SEL_LOWBAND = 0, - RX_HB_LB_SEL_HIGHBAND = 1 - }; + enum rx_hb_lb_sel_t { RX_HB_LB_SEL_LOWBAND = 0, RX_HB_LB_SEL_HIGHBAND = 1 }; - enum rx_lo_input_sel_t { - RX_LO_INPUT_SEL_INTERNAL = 1, - RX_LO_INPUT_SEL_EXTERNAL = 0 - }; + enum rx_lo_input_sel_t { RX_LO_INPUT_SEL_INTERNAL = 1, RX_LO_INPUT_SEL_EXTERNAL = 0 }; - enum rx_demod_adj { - RX_DEMOD_OPEN = 0, - RX_DEMOD_200OHM = 1, - RX_DEMOD_1500OHM = 2 - }; + enum rx_demod_adj { RX_DEMOD_OPEN = 0, RX_DEMOD_200OHM = 1, RX_DEMOD_1500OHM = 2 }; enum tx_lo_filter_sel_t { - TX_LO_FILTER_SEL_0_9GHZ_LPF = 0, + TX_LO_FILTER_SEL_0_9GHZ_LPF = 0, TX_LO_FILTER_SEL_5_85GHZ_LPF = 1, TX_LO_FILTER_SEL_2_25GHZ_LPF = 2, - TX_LO_FILTER_SEL_ISOLATION = 3 + TX_LO_FILTER_SEL_ISOLATION = 3 }; enum rx_lo_filter_sel_t { - RX_LO_FILTER_SEL_0_9GHZ_LPF = 0, + RX_LO_FILTER_SEL_0_9GHZ_LPF = 0, RX_LO_FILTER_SEL_5_85GHZ_LPF = 1, RX_LO_FILTER_SEL_2_25GHZ_LPF = 2, - RX_LO_FILTER_SEL_ISOLATION = 3 + RX_LO_FILTER_SEL_ISOLATION = 3 }; /*! Constructor. @@ -148,10 +129,7 @@ public: * \param write_spi_fn SPI write function * \param read_spi_fn SPI read function */ - rhodium_cpld_ctrl( - write_spi_t write_spi_fn, - read_spi_t read_spi_fn - ); + rhodium_cpld_ctrl(write_spi_t write_spi_fn, read_spi_t read_spi_fn); /************************************************************************** * API @@ -187,13 +165,11 @@ public: * \param tx_hb_lb_sel Power on the highband or lowband amplifier * \param tx_lo_filter_sel Select LPF filter for LO */ - void set_tx_switches( - const tx_sw2_t tx_sw2, + void set_tx_switches(const tx_sw2_t tx_sw2, const tx_sw3_sw4_t tx_sw3_sw4, const tx_sw5_t tx_sw5, const tx_hb_lb_sel_t tx_hb_lb_sel, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! Frequency-related settings, receive side * @@ -204,14 +180,12 @@ public: * \param rx_hb_lb_sel Power on the highband or lowband amplifier * \param rx_lo_filter_sel Select LPF filter for LO */ - void set_rx_switches( - const rx_sw2_sw7_t rx_sw2_sw7, + void set_rx_switches(const rx_sw2_sw7_t rx_sw2_sw7, const rx_sw3_t rx_sw3, const rx_sw4_sw5_t rx_sw4_sw5, const rx_sw6_t rx_sw6, const rx_hb_lb_sel_t rx_hb_lb_sel, - const bool defer_commit = false - ); + const bool defer_commit = false); /*! Input switches for RX side * @@ -220,91 +194,72 @@ public: * \param rx_sw1 Input selection of RX path * \param cal_iso_sw Terminates the calibration loopback path */ - void set_rx_input_switches( - const rx_sw1_t rx_sw1, + void set_rx_input_switches(const rx_sw1_t rx_sw1, const cal_iso_sw_t cal_iso_sw, - const bool defer_commit = false - ); - - /*! Output switches for TX side - * - * Note: These are not frequency dependent. - * - * \param tx_sw1 Output selection of TX path - */ - void set_tx_output_switches( - const tx_sw1_t tx_sw1, - const bool defer_commit = false - ); - - /*! Input switch for RX LO - * - * \param rx_lo_input_sel Selects RX LO source - */ + const bool defer_commit = false); + + /*! Output switches for TX side + * + * Note: These are not frequency dependent. + * + * \param tx_sw1 Output selection of TX path + */ + void set_tx_output_switches(const tx_sw1_t tx_sw1, const bool defer_commit = false); + + /*! Input switch for RX LO + * + * \param rx_lo_input_sel Selects RX LO source + */ void set_rx_lo_source( - const rx_lo_input_sel_t rx_lo_input_sel, - const bool defer_commit = false - ); - - /*! Input switch for TX LO - * - * \param tx_lo_input_sel Selects TX LO source - */ + const rx_lo_input_sel_t rx_lo_input_sel, const bool defer_commit = false); + + /*! Input switch for TX LO + * + * \param tx_lo_input_sel Selects TX LO source + */ void set_tx_lo_source( - const tx_lo_input_sel_t tx_lo_input_sel, - const bool defer_commit = false - ); - - /*! Configure RX LO filter, synth, and mixer settings - * - * \param freq RX LO Frequency - */ - void set_rx_lo_path( - const double freq, - const bool defer_commit = false - ); - - /*! Configure TX LO filter, synth, and mixer settings - * - * \param freq TX LO Frequency - */ - void set_tx_lo_path( - const double freq, - const bool defer_commit = false - ); - - - /*! Gain index setting for the RF frontend - * - * Sets the gain index to one of the predefined values that have been - * loaded into the CPLD by gain table loader in MPM. - * - * \param index Index of the gain table entry to apply (0-60) - * \param band Selects which table to use (lowband or highband) - * \param dir Selects which RF frontend to apply to (RX or TX) - */ - void set_gain_index( - const uint32_t index, + const tx_lo_input_sel_t tx_lo_input_sel, const bool defer_commit = false); + + /*! Configure RX LO filter, synth, and mixer settings + * + * \param freq RX LO Frequency + */ + void set_rx_lo_path(const double freq, const bool defer_commit = false); + + /*! Configure TX LO filter, synth, and mixer settings + * + * \param freq TX LO Frequency + */ + void set_tx_lo_path(const double freq, const bool defer_commit = false); + + + /*! Gain index setting for the RF frontend + * + * Sets the gain index to one of the predefined values that have been + * loaded into the CPLD by gain table loader in MPM. + * + * \param index Index of the gain table entry to apply (0-60) + * \param band Selects which table to use (lowband or highband) + * \param dir Selects which RF frontend to apply to (RX or TX) + */ + void set_gain_index(const uint32_t index, const gain_band_t band, const uhd::direction_t dir, - const bool defer_commit = false - ); - - /*! Gain setting for LO1 - * - * Sets the attenuation of the RX LO1 DSA or TX LO1 DSA. - * - * Note: This function uses gain as a parameter, although it is - * setting an attenuation. - * - * \param index Gain value to apply (0-30) - * \param dir Selects which LO to apply to (RX, TX, or DX) - */ - void set_lo_gain( - const uint32_t index, + const bool defer_commit = false); + + /*! Gain setting for LO1 + * + * Sets the attenuation of the RX LO1 DSA or TX LO1 DSA. + * + * Note: This function uses gain as a parameter, although it is + * setting an attenuation. + * + * \param index Gain value to apply (0-30) + * \param dir Selects which LO to apply to (RX, TX, or DX) + */ + void set_lo_gain(const uint32_t index, const uhd::direction_t dir, - const bool defer_commit = false - ); + const bool defer_commit = false); private: //! Write function: Take address / data pair, craft SPI transaction diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp index 54c6333bc..f8ec47c18 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp @@ -18,9 +18,9 @@ #include <uhdlib/utils/narrow.hpp> #include <boost/algorithm/string.hpp> #include <boost/format.hpp> -#include <memory> #include <cmath> #include <cstdlib> +#include <memory> #include <sstream> using namespace uhd; @@ -29,16 +29,16 @@ using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; namespace { - constexpr char RX_FE_CONNECTION_LOWBAND[] = "QI"; - constexpr char RX_FE_CONNECTION_HIGHBAND[] = "IQ"; - constexpr char TX_FE_CONNECTION_LOWBAND[] = "QI"; - constexpr char TX_FE_CONNECTION_HIGHBAND[] = "IQ"; +constexpr char RX_FE_CONNECTION_LOWBAND[] = "QI"; +constexpr char RX_FE_CONNECTION_HIGHBAND[] = "IQ"; +constexpr char TX_FE_CONNECTION_LOWBAND[] = "QI"; +constexpr char TX_FE_CONNECTION_HIGHBAND[] = "IQ"; - constexpr double DEFAULT_IDENTIFY_DURATION = 5.0; // seconds +constexpr double DEFAULT_IDENTIFY_DURATION = 5.0; // seconds - constexpr uint64_t SET_RATE_RPC_TIMEOUT_MS = 10000; +constexpr uint64_t SET_RATE_RPC_TIMEOUT_MS = 10000; -} +} // namespace /****************************************************************************** @@ -51,8 +51,7 @@ rhodium_radio_control_impl::rhodium_radio_control_impl(make_args_ptr make_args) UHD_ASSERT_THROW(get_block_id().get_block_count() < 2); const char radio_slot_name[] = {'A', 'B'}; _radio_slot = radio_slot_name[get_block_id().get_block_count()]; - _rpc_prefix = - (_radio_slot == "A") ? "db_0_" : "db_1_"; + _rpc_prefix = (_radio_slot == "A") ? "db_0_" : "db_1_"; RFNOC_LOG_TRACE("Radio slot: " << _radio_slot); UHD_ASSERT_THROW(get_num_input_ports() == RHODIUM_NUM_CHANS); UHD_ASSERT_THROW(get_num_output_ports() == RHODIUM_NUM_CHANS); @@ -207,14 +206,12 @@ double rhodium_radio_control_impl::set_tx_frequency(const double freq, const siz const bool is_highband = !_is_tx_lowband(coerced_target_freq); - const double target_lo_freq = is_highband ? - coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; - const double actual_lo_freq = - set_tx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); - const double coerced_freq = is_highband ? - actual_lo_freq : _get_lowband_lo_freq() - actual_lo_freq; - const auto conn = is_highband ? - TX_FE_CONNECTION_HIGHBAND : TX_FE_CONNECTION_LOWBAND; + const double target_lo_freq = + is_highband ? coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; + const double actual_lo_freq = set_tx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); + const double coerced_freq = is_highband ? actual_lo_freq + : _get_lowband_lo_freq() - actual_lo_freq; + const auto conn = is_highband ? TX_FE_CONNECTION_HIGHBAND : TX_FE_CONNECTION_LOWBAND; // update the cached frequency value now so calls to set gain and update // switches will read the new frequency @@ -224,7 +221,8 @@ double rhodium_radio_control_impl::set_tx_frequency(const double freq, const siz set_tx_gain(radio_control_impl::get_tx_gain(chan), 0); if (_get_highband_spur_reduction_enabled(TX_DIRECTION)) { - if (_get_timed_command_enabled() and _is_tx_lowband(old_freq) != not is_highband) { + if (_get_timed_command_enabled() + and _is_tx_lowband(old_freq) != not is_highband) { RFNOC_LOG_WARNING( "Timed tuning commands that transition between lowband and highband, 450 " "MHz, do not function correctly when highband_spur_reduction is enabled! " @@ -260,14 +258,12 @@ double rhodium_radio_control_impl::set_rx_frequency(const double freq, const siz const bool is_highband = !_is_rx_lowband(coerced_target_freq); - const double target_lo_freq = is_highband ? - coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; - const double actual_lo_freq = - set_rx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); - const double coerced_freq = is_highband ? - actual_lo_freq : _get_lowband_lo_freq() - actual_lo_freq; - const auto conn = is_highband ? - RX_FE_CONNECTION_HIGHBAND : RX_FE_CONNECTION_LOWBAND; + const double target_lo_freq = + is_highband ? coerced_target_freq : _get_lowband_lo_freq() - coerced_target_freq; + const double actual_lo_freq = set_rx_lo_freq(target_lo_freq, RHODIUM_LO1, chan); + const double coerced_freq = is_highband ? actual_lo_freq + : _get_lowband_lo_freq() - actual_lo_freq; + const auto conn = is_highband ? RX_FE_CONNECTION_HIGHBAND : RX_FE_CONNECTION_LOWBAND; // update the cached frequency value now so calls to set gain and update // switches will read the new frequency @@ -277,7 +273,8 @@ double rhodium_radio_control_impl::set_rx_frequency(const double freq, const siz set_rx_gain(radio_control_impl::get_rx_gain(chan), 0); if (_get_highband_spur_reduction_enabled(RX_DIRECTION)) { - if (_get_timed_command_enabled() and _is_rx_lowband(old_freq) != not is_highband) { + if (_get_timed_command_enabled() + and _is_rx_lowband(old_freq) != not is_highband) { RFNOC_LOG_WARNING( "Timed tuning commands that transition between lowband and highband, 450 " "MHz, do not function correctly when highband_spur_reduction is enabled! " @@ -313,17 +310,17 @@ double rhodium_radio_control_impl::set_tx_gain(const double gain, const size_t c RFNOC_LOG_TRACE("set_tx_gain(gain=" << gain << ", chan=" << chan << ")"); UHD_ASSERT_THROW(chan == 0); - auto freq = this->get_tx_frequency(chan); + auto freq = this->get_tx_frequency(chan); auto index = get_tx_gain_range(chan).clip(gain); - auto old_band = _is_tx_lowband(_tx_frequency_at_last_gain_write) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; - auto new_band = _is_tx_lowband(freq) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; + auto old_band = _is_tx_lowband(_tx_frequency_at_last_gain_write) + ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; + auto new_band = _is_tx_lowband(freq) ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; - // The CPLD requires a rewrite of the gain control command on a change of lowband or highband + // The CPLD requires a rewrite of the gain control command on a change of lowband or + // highband if (radio_control_impl::get_tx_gain(chan) != index or old_band != new_band) { RFNOC_LOG_TRACE("Writing new TX gain index: " << index); _cpld->set_gain_index(index, new_band, TX_DIRECTION); @@ -342,17 +339,17 @@ double rhodium_radio_control_impl::set_rx_gain(const double gain, const size_t c RFNOC_LOG_TRACE("set_rx_gain(gain=" << gain << ", chan=" << chan << ")"); UHD_ASSERT_THROW(chan == 0); - auto freq = this->get_rx_frequency(chan); + auto freq = this->get_rx_frequency(chan); auto index = get_rx_gain_range(chan).clip(gain); - auto old_band = _is_rx_lowband(_rx_frequency_at_last_gain_write) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; - auto new_band = _is_rx_lowband(freq) ? - rhodium_cpld_ctrl::gain_band_t::LOW : - rhodium_cpld_ctrl::gain_band_t::HIGH; + auto old_band = _is_rx_lowband(_rx_frequency_at_last_gain_write) + ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; + auto new_band = _is_rx_lowband(freq) ? rhodium_cpld_ctrl::gain_band_t::LOW + : rhodium_cpld_ctrl::gain_band_t::HIGH; - // The CPLD requires a rewrite of the gain control command on a change of lowband or highband + // The CPLD requires a rewrite of the gain control command on a change of lowband or + // highband if (radio_control_impl::get_rx_gain(chan) != index or old_band != new_band) { RFNOC_LOG_TRACE("Writing new RX gain index: " << index); _cpld->set_gain_index(index, new_band, RX_DIRECTION); @@ -398,13 +395,13 @@ void rhodium_radio_control_impl::_update_atr( const auto rx_ant = (dir == RX_DIRECTION) ? ant : get_rx_antenna(0); const auto tx_ant = (dir == TX_DIRECTION) ? ant : get_tx_antenna(0); - const auto sw10_tx = _is_tx_lowband(get_tx_frequency(0)) ? - SW10_FROMTXLOWBAND : SW10_FROMTXHIGHBAND; + const auto sw10_tx = _is_tx_lowband(get_tx_frequency(0)) ? SW10_FROMTXLOWBAND + : SW10_FROMTXHIGHBAND; const uint32_t atr_idle = SW10_ISOLATION; - const uint32_t atr_rx = [rx_ant]{ + const uint32_t atr_rx = [rx_ant] { if (rx_ant == "TX/RX") { return SW10_TORX | LED_RX; } else if (rx_ant == "RX2") { @@ -414,8 +411,7 @@ void rhodium_radio_control_impl::_update_atr( } }(); - const uint32_t atr_tx = (tx_ant == "TX/RX") ? - (sw10_tx | LED_TX) : SW10_ISOLATION; + const uint32_t atr_tx = (tx_ant == "TX/RX") ? (sw10_tx | LED_TX) : SW10_ISOLATION; const uint32_t atr_dx = [tx_ant, rx_ant, sw10_tx] { uint32_t sw10_return; diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp index 8cee33f17..4d2bc38ad 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.hpp @@ -71,8 +71,8 @@ public: double set_rate(double rate); // Setters - void set_tx_antenna(const std::string &ant, const size_t chan); - void set_rx_antenna(const std::string &ant, const size_t chan); + void set_tx_antenna(const std::string& ant, const size_t chan); + void set_rx_antenna(const std::string& ant, const size_t chan); double set_tx_frequency(const double freq, const size_t chan); double set_rx_frequency(const double freq, const size_t chan); void set_tx_tune_args(const uhd::device_addr_t&, const size_t chan); @@ -163,8 +163,10 @@ public: * ??? calls ***********************************************************************/ // LO Distribution Control - void set_tx_lo_output_enabled(const bool enabled, const std::string& port_name, const size_t chan); - void set_rx_lo_output_enabled(const bool enabled, const std::string& port_name, const size_t chan); + void set_tx_lo_output_enabled( + const bool enabled, const std::string& port_name, const size_t chan); + void set_rx_lo_output_enabled( + const bool enabled, const std::string& port_name, const size_t chan); bool get_tx_lo_output_enabled(const std::string& port_name, const size_t chan); bool get_rx_lo_output_enabled(const std::string& port_name, const size_t chan); @@ -172,27 +174,29 @@ public: //! Set the external gain for a TX LO // Out of range values will be coerced - double set_tx_lo_gain(const double gain, const std::string &name, const size_t chan); + double set_tx_lo_gain(const double gain, const std::string& name, const size_t chan); //! Set the external gain for an RX LO // Out of range values will be coerced - double set_rx_lo_gain(const double gain, const std::string &name, const size_t chan); + double set_rx_lo_gain(const double gain, const std::string& name, const size_t chan); - double get_tx_lo_gain(const std::string &name, const size_t chan); - double get_rx_lo_gain(const std::string &name, const size_t chan); + double get_tx_lo_gain(const std::string& name, const size_t chan); + double get_rx_lo_gain(const std::string& name, const size_t chan); // LO Output Power Control //! Set the output power setting of a TX LO // Out of range values will be coerced - double set_tx_lo_power(const double power, const std::string &name, const size_t chan); + double set_tx_lo_power( + const double power, const std::string& name, const size_t chan); //! Set the output power setting of a RX LO // Out of range values will be coerced - double set_rx_lo_power(const double power, const std::string &name, const size_t chan); + double set_rx_lo_power( + const double power, const std::string& name, const size_t chan); - double get_tx_lo_power(const std::string &name, const size_t chan); - double get_rx_lo_power(const std::string &name, const size_t chan); + double get_tx_lo_power(const std::string& name, const size_t chan); + double get_rx_lo_power(const std::string& name, const size_t chan); private: @@ -239,42 +243,28 @@ private: void _init_mpm_sensors(const direction_t dir, const size_t chan_idx); //! Get the frequency range for an LO - freq_range_t _get_lo_freq_range(const std::string &name) const; + freq_range_t _get_lo_freq_range(const std::string& name) const; //! Get the current lowband intermediate frequency double _get_lowband_lo_freq() const; //! Configure LO1's export - void _set_lo1_export_enabled( - const bool enabled, - const direction_t dir - ); + void _set_lo1_export_enabled(const bool enabled, const direction_t dir); //! Validate that port_name is valid, and that LO distribution functions // can be called in this instance void _validate_output_port( - const std::string& port_name, - const std::string& function_name - ); + const std::string& port_name, const std::string& function_name); //! Configure LO Distribution board's termination switches void _set_lo_output_enabled( - const bool enabled, - const std::string& port_name, - const direction_t dir - ); + const bool enabled, const std::string& port_name, const direction_t dir); - bool _get_lo_output_enabled( - const std::string& port_name, - const direction_t dir - ); + bool _get_lo_output_enabled(const std::string& port_name, const direction_t dir); //! Configure LO1's output power // Out of range values will be coerced to [0-63] - double _set_lo1_power( - const double power, - const direction_t dir - ); + double _set_lo1_power(const double power, const direction_t dir); //! Flash all front end LEDs at 1 Hz for the specified amount of time void _identify_with_leds(double identify_duration); @@ -328,29 +318,21 @@ private: * Frontend Controls *************************************************************************/ - void _set_tx_fe_connection(const std::string &conn); - void _set_rx_fe_connection(const std::string &conn); + void _set_tx_fe_connection(const std::string& conn); + void _set_rx_fe_connection(const std::string& conn); std::string _get_tx_fe_connection() const; std::string _get_rx_fe_connection() const; /************************************************************************** * CPLD Controls (implemented in rhodium_radio_ctrl_cpld.cpp) *************************************************************************/ - void _update_rx_freq_switches( - const double freq - ); + void _update_rx_freq_switches(const double freq); - void _update_tx_freq_switches( - const double freq - ); + void _update_tx_freq_switches(const double freq); - void _update_rx_input_switches( - const std::string &input - ); + void _update_rx_input_switches(const std::string& input); - void _update_tx_output_switches( - const std::string &output - ); + void _update_tx_output_switches(const std::string& output); /************************************************************************** * Private attributes @@ -412,7 +394,7 @@ private: //! Saved frontend connection for DSP core std::string _rx_fe_connection; std::string _tx_fe_connection; - //! Desired RF frequency + //! Desired RF frequency std::map<direction_t, double> _desired_rf_freq = { {RX_DIRECTION, 2.44e9}, {TX_DIRECTION, 2.44e9}}; //! Frequency at which gain setting was last applied. The CPLD requires a new gain @@ -446,8 +428,8 @@ private: bool _lo_dist_present = false; //! LO Distribution board output status - bool _lo_dist_rx_out_enabled[4] = { false, false, false, false }; - bool _lo_dist_tx_out_enabled[4] = { false, false, false, false }; + bool _lo_dist_rx_out_enabled[4] = {false, false, false, false}; + bool _lo_dist_tx_out_enabled[4] = {false, false, false, false}; std::unordered_map<uhd::direction_t, uhd::device_addr_t, std::hash<size_t>> _tune_args{{uhd::RX_DIRECTION, uhd::device_addr_t()}, @@ -477,4 +459,3 @@ private: }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_RFNOC_RHODIUM_RADIO_CTRL_IMPL_HPP */ - diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp index 85ed3ddb7..3752a2e70 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp @@ -7,11 +7,11 @@ #include "twinrx_ctrl.hpp" #include "twinrx_ids.hpp" +#include <uhd/utils/math.hpp> +#include <uhd/utils/safe_call.hpp> #include <uhdlib/usrp/common/adf435x.hpp> #include <uhdlib/usrp/common/adf535x.hpp> #include <uhdlib/utils/narrow.hpp> -#include <uhd/utils/math.hpp> -#include <uhd/utils/safe_call.hpp> #include <chrono> #include <thread> @@ -20,39 +20,44 @@ using namespace usrp; using namespace dboard::twinrx; namespace { - typedef twinrx_cpld_regmap rm; - - typedef enum { LO1, LO2 } lo_t; +typedef twinrx_cpld_regmap rm; - inline uint32_t bool2bin(bool x) { return x ? 1 : 0; } +typedef enum { LO1, LO2 } lo_t; - const double TWINRX_DESIRED_REFERENCE_FREQ = 50e6; - const double TWINRX_REV_AB_PFD_FREQ = 6.25e6; - const double TWINRX_REV_C_PFD_FREQ = 12.5e6; - const double TWINRX_SPI_CLOCK_FREQ = 3e6; +inline uint32_t bool2bin(bool x) +{ + return x ? 1 : 0; } -class twinrx_ctrl_impl : public twinrx_ctrl { +const double TWINRX_DESIRED_REFERENCE_FREQ = 50e6; +const double TWINRX_REV_AB_PFD_FREQ = 6.25e6; +const double TWINRX_REV_C_PFD_FREQ = 12.5e6; +const double TWINRX_SPI_CLOCK_FREQ = 3e6; +} // namespace + +class twinrx_ctrl_impl : public twinrx_ctrl +{ public: - twinrx_ctrl_impl( - dboard_iface::sptr db_iface, + twinrx_ctrl_impl(dboard_iface::sptr db_iface, twinrx_gpio::sptr gpio_iface, twinrx_cpld_regmap::sptr cpld_regmap, - const dboard_id_t rx_id - ) : _db_iface(db_iface), _gpio_iface(gpio_iface), _cpld_regs(cpld_regmap) + const dboard_id_t rx_id) + : _db_iface(db_iface), _gpio_iface(gpio_iface), _cpld_regs(cpld_regmap) { // SPI configuration _spi_config.use_custom_divider = true; _spi_config.divider = uhd::narrow_cast<size_t>(std::ceil( _db_iface->get_codec_rate(dboard_iface::UNIT_TX) / TWINRX_SPI_CLOCK_FREQ)); - //Initialize dboard clocks + // Initialize dboard clocks bool found_rate = false; - for(double rate: _db_iface->get_clock_rates(dboard_iface::UNIT_TX)) { - found_rate |= uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); + for (double rate : _db_iface->get_clock_rates(dboard_iface::UNIT_TX)) { + found_rate |= + uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); } - for(double rate: _db_iface->get_clock_rates(dboard_iface::UNIT_RX)) { - found_rate |= uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); + for (double rate : _db_iface->get_clock_rates(dboard_iface::UNIT_RX)) { + found_rate |= + uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ); } if (not found_rate) { throw uhd::runtime_error("TwinRX not supported on this motherboard"); @@ -63,7 +68,7 @@ public: _db_iface->set_clock_enabled(dboard_iface::UNIT_TX, true); _db_iface->set_clock_enabled(dboard_iface::UNIT_RX, true); - //Initialize default switch and attenuator states + // Initialize default switch and attenuator states set_chan_enabled(BOTH, false, false); set_preamp1(BOTH, PREAMP_BYPASS, false); set_preamp2(BOTH, false, false); @@ -82,7 +87,7 @@ public: set_crossover_cal_mode(CAL_DISABLED, false); _cpld_regs->flush(); - //Turn on power and wait for power good + // Turn on power and wait for power good _gpio_iface->set_field(twinrx_gpio::FIELD_SWPS_EN, 1); size_t timeout_ms = 100; while (_gpio_iface->get_field(twinrx_gpio::FIELD_SWPS_PWR_GOOD) == 0) { @@ -98,7 +103,7 @@ public: _gpio_iface->set_field(twinrx_gpio::FIELD_LO2_CE_CH1, 1); _gpio_iface->set_field(twinrx_gpio::FIELD_LO2_CE_CH2, 1); - //Initialize synthesizers + // Initialize synthesizers for (size_t i = 0; i < NUM_CHANS; i++) { // LO1 if (rx_id == twinrx::TWINRX_REV_C_ID) { @@ -108,8 +113,7 @@ public: }, [this](uint32_t microseconds) { _db_iface->sleep(boost::chrono::microseconds(microseconds)); - } - ); + }); _lo1_iface[i]->set_pfd_freq(TWINRX_REV_C_PFD_FREQ); } else { _lo1_iface[i] = adf535x_iface::make_adf5355( @@ -118,8 +122,7 @@ public: }, [this](uint32_t microseconds) { _db_iface->sleep(boost::chrono::microseconds(microseconds)); - } - ); + }); _lo1_iface[i]->set_pfd_freq(TWINRX_REV_AB_PFD_FREQ); } _lo1_iface[i]->set_output_power(adf535x_iface::OUTPUT_POWER_5DBM); @@ -128,11 +131,10 @@ public: _lo1_iface[i]->set_frequency(3e9, 1.0e3); // LO2 - _lo2_iface[i] = adf435x_iface::make_adf4351( - [this](const std::vector<uint32_t>& regs) { + _lo2_iface[i] = + adf435x_iface::make_adf4351([this](const std::vector<uint32_t>& regs) { _write_lo_spi(dboard_iface::UNIT_RX, regs); - } - ); + }); _lo2_iface[i]->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); _lo2_iface[i]->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM); _lo2_iface[i]->set_reference_freq(TWINRX_DESIRED_REFERENCE_FREQ); @@ -145,10 +147,8 @@ public: ~twinrx_ctrl_impl() { - UHD_SAFE_CALL( - boost::lock_guard<boost::mutex> lock(_mutex); - _gpio_iface->set_field(twinrx_gpio::FIELD_SWPS_EN, 0); - ) + UHD_SAFE_CALL(boost::lock_guard<boost::mutex> lock(_mutex); + _gpio_iface->set_field(twinrx_gpio::FIELD_SWPS_EN, 0);) } void commit() @@ -171,80 +171,117 @@ public: _cpld_regs->if0_reg0.set(rm::if0_reg0_t::AMP_LO2_EN_CH2, bool2bin(enabled)); _chan_enabled[size_t(CH2)] = enabled; } - _set_lo1_amp(_chan_enabled[size_t(CH1)], _chan_enabled[size_t(CH2)], _lo1_src[size_t(CH2)]); - if (commit) _commit(); + _set_lo1_amp(_chan_enabled[size_t(CH1)], + _chan_enabled[size_t(CH2)], + _lo1_src[size_t(CH2)]); + if (commit) + _commit(); } void set_preamp1(channel_t ch, preamp_state_t value, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::SWPA1_CTL_CH1, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf2_reg2.set(rm::rf2_reg2_t::SWPA2_CTRL_CH1, bool2bin(value==PREAMP_BYPASS)); - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::HB_PREAMP_EN_CH1, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::LB_PREAMP_EN_CH1, bool2bin(value==PREAMP_LOWBAND)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::SWPA1_CTL_CH1, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf2_reg2.set( + rm::rf2_reg2_t::SWPA2_CTRL_CH1, bool2bin(value == PREAMP_BYPASS)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::HB_PREAMP_EN_CH1, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::LB_PREAMP_EN_CH1, bool2bin(value == PREAMP_LOWBAND)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SWPA1_CTRL_CH2, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf2_reg5.set(rm::rf2_reg5_t::SWPA2_CTRL_CH2, bool2bin(value==PREAMP_BYPASS)); - _cpld_regs->rf0_reg5.set(rm::rf0_reg5_t::HB_PREAMP_EN_CH2, bool2bin(value==PREAMP_HIGHBAND)); - _cpld_regs->rf2_reg6.set(rm::rf2_reg6_t::LB_PREAMP_EN_CH2, bool2bin(value==PREAMP_LOWBAND)); - } - if (commit) _commit(); + _cpld_regs->rf0_reg7.set( + rm::rf0_reg7_t::SWPA1_CTRL_CH2, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf2_reg5.set( + rm::rf2_reg5_t::SWPA2_CTRL_CH2, bool2bin(value == PREAMP_BYPASS)); + _cpld_regs->rf0_reg5.set( + rm::rf0_reg5_t::HB_PREAMP_EN_CH2, bool2bin(value == PREAMP_HIGHBAND)); + _cpld_regs->rf2_reg6.set( + rm::rf2_reg6_t::LB_PREAMP_EN_CH2, bool2bin(value == PREAMP_LOWBAND)); + } + if (commit) + _commit(); } void set_preamp2(channel_t ch, bool enabled, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::SWPA4_CTRL_CH1, bool2bin(not enabled)); + _cpld_regs->rf2_reg7.set( + rm::rf2_reg7_t::SWPA4_CTRL_CH1, bool2bin(not enabled)); _cpld_regs->rf2_reg3.set(rm::rf2_reg3_t::PREAMP2_EN_CH1, bool2bin(enabled)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SWPA4_CTRL_CH2, bool2bin(not enabled)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SWPA4_CTRL_CH2, bool2bin(not enabled)); _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::PREAMP2_EN_CH2, bool2bin(enabled)); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lb_preamp_preselector(channel_t ch, bool enabled, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SWPA3_CTRL_CH1, bool2bin(not enabled)); + _cpld_regs->rf0_reg7.set( + rm::rf0_reg7_t::SWPA3_CTRL_CH1, bool2bin(not enabled)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg1.set(rm::rf0_reg1_t::SWPA3_CTRL_CH2, bool2bin(not enabled)); + _cpld_regs->rf0_reg1.set( + rm::rf0_reg1_t::SWPA3_CTRL_CH2, bool2bin(not enabled)); } - if (commit) _commit(); + if (commit) + _commit(); } void set_signal_path(channel_t ch, signal_path_t path, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf2_reg2.set(rm::rf2_reg2_t::SW11_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg2.set(rm::rf1_reg2_t::SW12_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::HB_PRESEL_PGA_EN_CH1, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::SW6_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg3.set(rm::if0_reg3_t::SW13_CTRL_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::AMP_LB_IF1_EN_CH1, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg0.set(rm::if0_reg0_t::AMP_HB_IF1_EN_CH1, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf1_reg2.set(rm::rf1_reg2_t::AMP_HB_EN_CH1, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf2_reg2.set(rm::rf2_reg2_t::AMP_LB_EN_CH1, bool2bin(path==PATH_LOWBAND)); + _cpld_regs->rf2_reg2.set( + rm::rf2_reg2_t::SW11_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg2.set( + rm::rf1_reg2_t::SW12_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg6.set( + rm::rf1_reg6_t::HB_PRESEL_PGA_EN_CH1, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf0_reg2.set( + rm::rf0_reg2_t::SW6_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg3.set( + rm::if0_reg3_t::SW13_CTRL_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg2.set( + rm::if0_reg2_t::AMP_LB_IF1_EN_CH1, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg0.set( + rm::if0_reg0_t::AMP_HB_IF1_EN_CH1, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf1_reg2.set( + rm::rf1_reg2_t::AMP_HB_EN_CH1, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf2_reg2.set( + rm::rf2_reg2_t::AMP_LB_EN_CH1, bool2bin(path == PATH_LOWBAND)); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::SW11_CTRL_CH2, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW12_CTRL_CH2, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->rf1_reg2.set(rm::rf1_reg2_t::HB_PRESEL_PGA_EN_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SW6_CTRL_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->if0_reg6.set(rm::if0_reg6_t::SW13_CTRL_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::AMP_LB_IF1_EN_CH2, bool2bin(path==PATH_LOWBAND)); - _cpld_regs->if0_reg6.set(rm::if0_reg6_t::AMP_HB_IF1_EN_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::AMP_HB_EN_CH2, bool2bin(path==PATH_HIGHBAND)); - _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::AMP_LB_EN_CH2, bool2bin(path==PATH_LOWBAND)); - } - if (commit) _commit(); + _cpld_regs->rf2_reg7.set( + rm::rf2_reg7_t::SW11_CTRL_CH2, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg7.set( + rm::rf1_reg7_t::SW12_CTRL_CH2, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->rf1_reg2.set( + rm::rf1_reg2_t::HB_PRESEL_PGA_EN_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SW6_CTRL_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->if0_reg6.set( + rm::if0_reg6_t::SW13_CTRL_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->if0_reg2.set( + rm::if0_reg2_t::AMP_LB_IF1_EN_CH2, bool2bin(path == PATH_LOWBAND)); + _cpld_regs->if0_reg6.set( + rm::if0_reg6_t::AMP_HB_IF1_EN_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf1_reg7.set( + rm::rf1_reg7_t::AMP_HB_EN_CH2, bool2bin(path == PATH_HIGHBAND)); + _cpld_regs->rf2_reg7.set( + rm::rf2_reg7_t::AMP_LB_EN_CH2, bool2bin(path == PATH_LOWBAND)); + } + if (commit) + _commit(); } void set_lb_preselector(channel_t ch, preselector_path_t path, bool commit = true) @@ -252,11 +289,24 @@ public: boost::lock_guard<boost::mutex> lock(_mutex); uint32_t sw7val = 0, sw8val = 0; switch (path) { - case PRESEL_PATH1: sw7val = 3; sw8val = 1; break; - case PRESEL_PATH2: sw7val = 2; sw8val = 0; break; - case PRESEL_PATH3: sw7val = 0; sw8val = 2; break; - case PRESEL_PATH4: sw7val = 1; sw8val = 3; break; - default: UHD_THROW_INVALID_CODE_PATH(); + case PRESEL_PATH1: + sw7val = 3; + sw8val = 1; + break; + case PRESEL_PATH2: + sw7val = 2; + sw8val = 0; + break; + case PRESEL_PATH3: + sw7val = 0; + sw8val = 2; + break; + case PRESEL_PATH4: + sw7val = 1; + sw8val = 3; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } if (ch == CH1 or ch == BOTH) { _cpld_regs->rf0_reg3.set(rm::rf0_reg3_t::SW7_CTRL_CH1, sw7val); @@ -266,7 +316,8 @@ public: _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SW7_CTRL_CH2, sw7val); _cpld_regs->rf2_reg7.set(rm::rf2_reg7_t::SW8_CTRL_CH2, sw8val); } - if (commit) _commit(); + if (commit) + _commit(); } void set_hb_preselector(channel_t ch, preselector_path_t path, bool commit = true) @@ -274,11 +325,32 @@ public: boost::lock_guard<boost::mutex> lock(_mutex); uint32_t sw9ch1val = 0, sw10ch1val = 0, sw9ch2val = 0, sw10ch2val = 0; switch (path) { - case PRESEL_PATH1: sw9ch1val = 3; sw10ch1val = 0; sw9ch2val = 0; sw10ch2val = 3; break; - case PRESEL_PATH2: sw9ch1val = 1; sw10ch1val = 2; sw9ch2val = 1; sw10ch2val = 1; break; - case PRESEL_PATH3: sw9ch1val = 2; sw10ch1val = 1; sw9ch2val = 2; sw10ch2val = 2; break; - case PRESEL_PATH4: sw9ch1val = 0; sw10ch1val = 3; sw9ch2val = 3; sw10ch2val = 0; break; - default: UHD_THROW_INVALID_CODE_PATH(); + case PRESEL_PATH1: + sw9ch1val = 3; + sw10ch1val = 0; + sw9ch2val = 0; + sw10ch2val = 3; + break; + case PRESEL_PATH2: + sw9ch1val = 1; + sw10ch1val = 2; + sw9ch2val = 1; + sw10ch2val = 1; + break; + case PRESEL_PATH3: + sw9ch1val = 2; + sw10ch1val = 1; + sw9ch2val = 2; + sw10ch2val = 2; + break; + case PRESEL_PATH4: + sw9ch1val = 0; + sw10ch1val = 3; + sw9ch2val = 3; + sw10ch2val = 0; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } if (ch == CH1 or ch == BOTH) { _cpld_regs->rf0_reg5.set(rm::rf0_reg5_t::SW9_CTRL_CH1, sw9ch1val); @@ -288,104 +360,129 @@ public: _cpld_regs->rf0_reg3.set(rm::rf0_reg3_t::SW9_CTRL_CH2, sw9ch2val); _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW10_CTRL_CH2, sw10ch2val); } - if (commit) _commit(); - + if (commit) + _commit(); } void set_input_atten(channel_t ch, uint8_t atten, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf0_reg0.set(rm::rf0_reg0_t::ATTEN_IN_CH1, atten&0x1F); + _cpld_regs->rf0_reg0.set(rm::rf0_reg0_t::ATTEN_IN_CH1, atten & 0x1F); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf0_reg4.set(rm::rf0_reg4_t::ATTEN_IN_CH2, atten&0x1F); + _cpld_regs->rf0_reg4.set(rm::rf0_reg4_t::ATTEN_IN_CH2, atten & 0x1F); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lb_atten(channel_t ch, uint8_t atten, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf2_reg0.set(rm::rf2_reg0_t::ATTEN_LB_CH1, atten&0x1F); + _cpld_regs->rf2_reg0.set(rm::rf2_reg0_t::ATTEN_LB_CH1, atten & 0x1F); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf2_reg4.set(rm::rf2_reg4_t::ATTEN_LB_CH2, atten&0x1F); + _cpld_regs->rf2_reg4.set(rm::rf2_reg4_t::ATTEN_LB_CH2, atten & 0x1F); } - if (commit) _commit(); + if (commit) + _commit(); } void set_hb_atten(channel_t ch, uint8_t atten, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf1_reg0.set(rm::rf1_reg0_t::ATTEN_HB_CH1, atten&0x1F); + _cpld_regs->rf1_reg0.set(rm::rf1_reg0_t::ATTEN_HB_CH1, atten & 0x1F); } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf1_reg4.set(rm::rf1_reg4_t::ATTEN_HB_CH2, atten&0x1F); + _cpld_regs->rf1_reg4.set(rm::rf1_reg4_t::ATTEN_HB_CH2, atten & 0x1F); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lo1_source(channel_t ch, lo_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->rf1_reg5.set(rm::rf1_reg5_t::SW14_CTRL_CH2, bool2bin(source!=LO_COMPANION)); - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW15_CTRL_CH1, bool2bin(source==LO_EXTERNAL||source==LO_REIMPORT)); - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW16_CTRL_CH1, bool2bin(source!=LO_INTERNAL)); + _cpld_regs->rf1_reg5.set( + rm::rf1_reg5_t::SW14_CTRL_CH2, bool2bin(source != LO_COMPANION)); + _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW15_CTRL_CH1, + bool2bin(source == LO_EXTERNAL || source == LO_REIMPORT)); + _cpld_regs->rf1_reg1.set( + rm::rf1_reg1_t::SW16_CTRL_CH1, bool2bin(source != LO_INTERNAL)); _lo1_src[size_t(CH1)] = source; } if (ch == CH2 or ch == BOTH) { - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW14_CTRL_CH1, bool2bin(source==LO_COMPANION)); - _cpld_regs->rf1_reg5.set(rm::rf1_reg5_t::SW15_CTRL_CH2, bool2bin(source!=LO_INTERNAL)); - _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::SW16_CTRL_CH2, bool2bin(source==LO_INTERNAL)); + _cpld_regs->rf1_reg1.set( + rm::rf1_reg1_t::SW14_CTRL_CH1, bool2bin(source == LO_COMPANION)); + _cpld_regs->rf1_reg5.set( + rm::rf1_reg5_t::SW15_CTRL_CH2, bool2bin(source != LO_INTERNAL)); + _cpld_regs->rf1_reg6.set( + rm::rf1_reg6_t::SW16_CTRL_CH2, bool2bin(source == LO_INTERNAL)); _lo1_src[size_t(CH2)] = source; - _set_lo1_amp(_chan_enabled[size_t(CH1)], _chan_enabled[size_t(CH2)], _lo1_src[size_t(CH2)]); + _set_lo1_amp(_chan_enabled[size_t(CH1)], + _chan_enabled[size_t(CH2)], + _lo1_src[size_t(CH2)]); } - if (commit) _commit(); + if (commit) + _commit(); } void set_lo2_source(channel_t ch, lo_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (ch == CH1 or ch == BOTH) { - _cpld_regs->if0_reg0.set(rm::if0_reg0_t::SW19_CTRL_CH2, bool2bin(source==LO_COMPANION)); - _cpld_regs->if0_reg1.set(rm::if0_reg1_t::SW20_CTRL_CH1, bool2bin(source==LO_COMPANION)); - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW21_CTRL_CH1, bool2bin(source==LO_INTERNAL)); + _cpld_regs->if0_reg0.set( + rm::if0_reg0_t::SW19_CTRL_CH2, bool2bin(source == LO_COMPANION)); + _cpld_regs->if0_reg1.set( + rm::if0_reg1_t::SW20_CTRL_CH1, bool2bin(source == LO_COMPANION)); + _cpld_regs->if0_reg4.set( + rm::if0_reg4_t::SW21_CTRL_CH1, bool2bin(source == LO_INTERNAL)); _lo2_src[size_t(CH1)] = source; } if (ch == CH2 or ch == BOTH) { - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW19_CTRL_CH1, bool2bin(source==LO_EXTERNAL||source==LO_REIMPORT)); - _cpld_regs->if0_reg0.set(rm::if0_reg0_t::SW20_CTRL_CH2, bool2bin(source==LO_INTERNAL||source==LO_DISABLED)); - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW21_CTRL_CH2, bool2bin(source==LO_INTERNAL)); + _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW19_CTRL_CH1, + bool2bin(source == LO_EXTERNAL || source == LO_REIMPORT)); + _cpld_regs->if0_reg0.set(rm::if0_reg0_t::SW20_CTRL_CH2, + bool2bin(source == LO_INTERNAL || source == LO_DISABLED)); + _cpld_regs->if0_reg4.set( + rm::if0_reg4_t::SW21_CTRL_CH2, bool2bin(source == LO_INTERNAL)); _lo2_src[size_t(CH2)] = source; } - if (commit) _commit(); + if (commit) + _commit(); } void set_lo1_export_source(lo_export_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); - //SW22 may conflict with the cal switch but this attr takes priority and we assume - //that the cal switch is disabled (by disabling it!) + // SW22 may conflict with the cal switch but this attr takes priority and we + // assume that the cal switch is disabled (by disabling it!) _set_cal_mode(CAL_DISABLED, source); - _cpld_regs->rf1_reg3.set(rm::rf1_reg3_t::SW23_CTRL, bool2bin(source!=LO_CH1_SYNTH)); + _cpld_regs->rf1_reg3.set( + rm::rf1_reg3_t::SW23_CTRL, bool2bin(source != LO_CH1_SYNTH)); _lo1_export = source; - if (commit) _commit(); + if (commit) + _commit(); } void set_lo2_export_source(lo_export_source_t source, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); - _cpld_regs->if0_reg7.set(rm::if0_reg7_t::SW24_CTRL_CH2, bool2bin(source==LO_CH2_SYNTH)); - _cpld_regs->if0_reg4.set(rm::if0_reg4_t::SW25_CTRL, bool2bin(source!=LO_CH1_SYNTH)); - _cpld_regs->if0_reg3.set(rm::if0_reg3_t::SW24_CTRL_CH1, bool2bin(source!=LO_CH1_SYNTH)); + _cpld_regs->if0_reg7.set( + rm::if0_reg7_t::SW24_CTRL_CH2, bool2bin(source == LO_CH2_SYNTH)); + _cpld_regs->if0_reg4.set( + rm::if0_reg4_t::SW25_CTRL, bool2bin(source != LO_CH1_SYNTH)); + _cpld_regs->if0_reg3.set( + rm::if0_reg3_t::SW24_CTRL_CH1, bool2bin(source != LO_CH1_SYNTH)); _lo2_export = source; - if (commit) _commit(); + if (commit) + _commit(); } void set_antenna_mapping(antenna_mapping_t mapping, bool commit = true) @@ -396,40 +493,60 @@ public: switch_path_t path1, path2; switch (mapping) { - case ANTX_NATIVE: - path1 = CONNECT; path2 = CONNECT; break; - case ANT1_SHARED: - path1 = EXPORT; path2 = IMPORT; break; - case ANT2_SHARED: - path1 = IMPORT; path2 = EXPORT; break; - case ANTX_SWAPPED: - path1 = SWAP; path2 = SWAP; break; - default: - path1 = TERM; path2 = TERM; break; - } - - _cpld_regs->rf0_reg5.set(rm::rf0_reg5_t::SW3_CTRL_CH1, bool2bin(path1==EXPORT||path1==SWAP)); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::SW4_CTRL_CH1, bool2bin(!(path1==IMPORT||path1==SWAP))); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::SW5_CTRL_CH1, bool2bin(path1==CONNECT)); - _cpld_regs->rf0_reg7.set(rm::rf0_reg7_t::SW3_CTRL_CH2, bool2bin(path2==EXPORT||path2==SWAP)); - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SW4_CTRL_CH2, bool2bin(path2==IMPORT||path2==SWAP)); - _cpld_regs->rf0_reg6.set(rm::rf0_reg6_t::SW5_CTRL_CH2, bool2bin(path2==CONNECT)); - - if (commit) _commit(); + case ANTX_NATIVE: + path1 = CONNECT; + path2 = CONNECT; + break; + case ANT1_SHARED: + path1 = EXPORT; + path2 = IMPORT; + break; + case ANT2_SHARED: + path1 = IMPORT; + path2 = EXPORT; + break; + case ANTX_SWAPPED: + path1 = SWAP; + path2 = SWAP; + break; + default: + path1 = TERM; + path2 = TERM; + break; + } + + _cpld_regs->rf0_reg5.set( + rm::rf0_reg5_t::SW3_CTRL_CH1, bool2bin(path1 == EXPORT || path1 == SWAP)); + _cpld_regs->rf0_reg2.set( + rm::rf0_reg2_t::SW4_CTRL_CH1, bool2bin(!(path1 == IMPORT || path1 == SWAP))); + _cpld_regs->rf0_reg2.set( + rm::rf0_reg2_t::SW5_CTRL_CH1, bool2bin(path1 == CONNECT)); + _cpld_regs->rf0_reg7.set( + rm::rf0_reg7_t::SW3_CTRL_CH2, bool2bin(path2 == EXPORT || path2 == SWAP)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SW4_CTRL_CH2, bool2bin(path2 == IMPORT || path2 == SWAP)); + _cpld_regs->rf0_reg6.set( + rm::rf0_reg6_t::SW5_CTRL_CH2, bool2bin(path2 == CONNECT)); + + if (commit) + _commit(); } void set_crossover_cal_mode(cal_mode_t cal_mode, bool commit = true) { boost::lock_guard<boost::mutex> lock(_mutex); if (_lo1_export == LO_CH1_SYNTH && cal_mode == CAL_CH2) { - throw uhd::runtime_error("cannot enable cal crossover on CH2 when LO1 in CH1 is exported"); + throw uhd::runtime_error( + "cannot enable cal crossover on CH2 when LO1 in CH1 is exported"); } if (_lo1_export == LO_CH2_SYNTH && cal_mode == CAL_CH1) { - throw uhd::runtime_error("cannot enable cal crossover on CH1 when LO1 in CH2 is exported"); + throw uhd::runtime_error( + "cannot enable cal crossover on CH1 when LO1 in CH2 is exported"); } _set_cal_mode(cal_mode, _lo1_export); - if (commit) _commit(); + if (commit) + _commit(); } double set_lo1_synth_freq(channel_t ch, double freq, bool commit = true) @@ -439,15 +556,18 @@ public: double coerced_freq = 0.0; if (ch == CH1 or ch == BOTH) { - coerced_freq = _lo1_iface[size_t(CH1)]->set_frequency(freq, RESOLUTION, false); + coerced_freq = + _lo1_iface[size_t(CH1)]->set_frequency(freq, RESOLUTION, false); _lo1_freq[size_t(CH1)] = tune_freq_t(freq); } if (ch == CH2 or ch == BOTH) { - coerced_freq = _lo1_iface[size_t(CH2)]->set_frequency(freq, RESOLUTION, false); + coerced_freq = + _lo1_iface[size_t(CH2)]->set_frequency(freq, RESOLUTION, false); _lo1_freq[size_t(CH2)] = tune_freq_t(freq); } - if (commit) _commit(); + if (commit) + _commit(); return coerced_freq; } @@ -465,7 +585,8 @@ public: _lo2_freq[size_t(CH2)] = tune_freq_t(freq); } - if (commit) _commit(); + if (commit) + _commit(); return coerced_freq; } @@ -525,10 +646,12 @@ public: bool locked = true; if (ch == CH1 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH1) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH1) == 1); } if (ch == CH2 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH2) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO1_MUXOUT_CH2) == 1); } return locked; } @@ -539,102 +662,124 @@ public: bool locked = true; if (ch == CH1 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH1) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH1) == 1); } if (ch == CH2 or ch == BOTH) { - locked = locked && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH2) == 1); + locked = locked + && (_gpio_iface->get_field(twinrx_gpio::FIELD_LO2_MUXOUT_CH2) == 1); } return locked; } -private: //Functions +private: // Functions void _set_cal_mode(cal_mode_t cal_mode, lo_export_source_t lo1_export_src) { - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::SW17_CTRL_CH1, bool2bin(cal_mode!=CAL_CH1)); - _cpld_regs->rf1_reg6.set(rm::rf1_reg6_t::SW17_CTRL_CH2, bool2bin(cal_mode!=CAL_CH2)); - _cpld_regs->rf1_reg5.set(rm::rf1_reg5_t::SW18_CTRL_CH1, bool2bin(cal_mode!=CAL_CH1)); - _cpld_regs->rf2_reg3.set(rm::rf2_reg3_t::SW18_CTRL_CH2, bool2bin(cal_mode!=CAL_CH2)); - _cpld_regs->rf1_reg3.set(rm::rf1_reg3_t::SW22_CTRL_CH1, bool2bin((lo1_export_src!=LO_CH1_SYNTH)||(cal_mode==CAL_CH1))); - _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW22_CTRL_CH2, bool2bin((lo1_export_src!=LO_CH2_SYNTH)||(cal_mode==CAL_CH2))); + _cpld_regs->rf1_reg1.set( + rm::rf1_reg1_t::SW17_CTRL_CH1, bool2bin(cal_mode != CAL_CH1)); + _cpld_regs->rf1_reg6.set( + rm::rf1_reg6_t::SW17_CTRL_CH2, bool2bin(cal_mode != CAL_CH2)); + _cpld_regs->rf1_reg5.set( + rm::rf1_reg5_t::SW18_CTRL_CH1, bool2bin(cal_mode != CAL_CH1)); + _cpld_regs->rf2_reg3.set( + rm::rf2_reg3_t::SW18_CTRL_CH2, bool2bin(cal_mode != CAL_CH2)); + _cpld_regs->rf1_reg3.set(rm::rf1_reg3_t::SW22_CTRL_CH1, + bool2bin((lo1_export_src != LO_CH1_SYNTH) || (cal_mode == CAL_CH1))); + _cpld_regs->rf1_reg7.set(rm::rf1_reg7_t::SW22_CTRL_CH2, + bool2bin((lo1_export_src != LO_CH2_SYNTH) || (cal_mode == CAL_CH2))); } void _set_lo1_amp(bool ch1_enabled, bool ch2_enabled, lo_source_t ch2_lo1_src) { // AMP_LO1_EN_CH1 also controls the amp for the external LO1 port, // which could be in use by ch2 - _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::AMP_LO1_EN_CH1, bool2bin( - ch1_enabled || (ch2_enabled && (ch2_lo1_src == LO_EXTERNAL || ch2_lo1_src == LO_REIMPORT)))); + _cpld_regs->rf1_reg1.set(rm::rf1_reg1_t::AMP_LO1_EN_CH1, + bool2bin( + ch1_enabled + || (ch2_enabled + && (ch2_lo1_src == LO_EXTERNAL || ch2_lo1_src == LO_REIMPORT)))); } void _config_lo_route(lo_t lo, channel_t channel) { - //Route SPI LEs through CPLD (will not assert them) - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH1, bool2bin(lo == LO1 and (channel == CH1 or channel == BOTH))); - _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH2, bool2bin(lo == LO1 and (channel == CH2 or channel == BOTH))); + // Route SPI LEs through CPLD (will not assert them) + _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH1, + bool2bin(lo == LO1 and (channel == CH1 or channel == BOTH))); + _cpld_regs->rf0_reg2.set(rm::rf0_reg2_t::LO1_LE_CH2, + bool2bin(lo == LO1 and (channel == CH2 or channel == BOTH))); _cpld_regs->rf0_reg2.flush(); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH1, bool2bin(lo == LO2 and (channel == CH1 or channel == BOTH))); - _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH2, bool2bin(lo == LO2 and (channel == CH2 or channel == BOTH))); + _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH1, + bool2bin(lo == LO2 and (channel == CH1 or channel == BOTH))); + _cpld_regs->if0_reg2.set(rm::if0_reg2_t::LO2_LE_CH2, + bool2bin(lo == LO2 and (channel == CH2 or channel == BOTH))); _cpld_regs->if0_reg2.flush(); } - void _write_lo_spi(dboard_iface::unit_t unit, const std::vector<uint32_t> ®s) + void _write_lo_spi(dboard_iface::unit_t unit, const std::vector<uint32_t>& regs) { - for(uint32_t reg: regs) { + for (uint32_t reg : regs) { _db_iface->write_spi(unit, _spi_config, reg, 32); } } void _commit() { - //Commit everything except the LO synthesizers + // Commit everything except the LO synthesizers _cpld_regs->flush(); // Disable unused LO synthesizers - _lo1_enable[size_t(CH1)] = _lo1_src[size_t(CH1)] == LO_INTERNAL || - _lo1_src[size_t(CH2)] == LO_COMPANION || - _lo1_export == LO_CH1_SYNTH; - - _lo1_enable[size_t(CH2)] = _lo1_src[size_t(CH2)] == LO_INTERNAL || - _lo1_src[size_t(CH1)] == LO_COMPANION || - _lo1_export == LO_CH2_SYNTH; - _lo2_enable[size_t(CH1)] = _lo2_src[size_t(CH1)] == LO_INTERNAL || - _lo2_src[size_t(CH2)] == LO_COMPANION || - _lo2_export == LO_CH1_SYNTH; - - _lo2_enable[size_t(CH2)] = _lo2_src[size_t(CH2)] == LO_INTERNAL || - _lo2_src[size_t(CH1)] == LO_COMPANION || - _lo2_export == LO_CH2_SYNTH; - - _lo1_iface[size_t(CH1)]->set_output_enable(adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH1)].get()); - _lo1_iface[size_t(CH2)]->set_output_enable(adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH2)].get()); - - _lo2_iface[size_t(CH1)]->set_output_enable(adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH1)].get()); - _lo2_iface[size_t(CH2)]->set_output_enable(adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH2)].get()); - - //Commit LO1 frequency - // Commit Channel 1's settings to both channels simultaneously if the frequency is the same. - bool simultaneous_commit_lo1 = _lo1_freq[size_t(CH1)].is_dirty() and - _lo1_freq[size_t(CH2)].is_dirty() and - _lo1_freq[size_t(CH1)].get() == _lo1_freq[size_t(CH2)].get() and - _lo1_enable[size_t(CH1)].get() == _lo1_enable[size_t(CH2)].get(); + _lo1_enable[size_t(CH1)] = _lo1_src[size_t(CH1)] == LO_INTERNAL + || _lo1_src[size_t(CH2)] == LO_COMPANION + || _lo1_export == LO_CH1_SYNTH; + + _lo1_enable[size_t(CH2)] = _lo1_src[size_t(CH2)] == LO_INTERNAL + || _lo1_src[size_t(CH1)] == LO_COMPANION + || _lo1_export == LO_CH2_SYNTH; + _lo2_enable[size_t(CH1)] = _lo2_src[size_t(CH1)] == LO_INTERNAL + || _lo2_src[size_t(CH2)] == LO_COMPANION + || _lo2_export == LO_CH1_SYNTH; + + _lo2_enable[size_t(CH2)] = _lo2_src[size_t(CH2)] == LO_INTERNAL + || _lo2_src[size_t(CH1)] == LO_COMPANION + || _lo2_export == LO_CH2_SYNTH; + + _lo1_iface[size_t(CH1)]->set_output_enable( + adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH1)].get()); + _lo1_iface[size_t(CH2)]->set_output_enable( + adf535x_iface::RF_OUTPUT_A, _lo1_enable[size_t(CH2)].get()); + + _lo2_iface[size_t(CH1)]->set_output_enable( + adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH1)].get()); + _lo2_iface[size_t(CH2)]->set_output_enable( + adf435x_iface::RF_OUTPUT_A, _lo2_enable[size_t(CH2)].get()); + + // Commit LO1 frequency + // Commit Channel 1's settings to both channels simultaneously if the frequency is + // the same. + bool simultaneous_commit_lo1 = + _lo1_freq[size_t(CH1)].is_dirty() and _lo1_freq[size_t(CH2)].is_dirty() + and _lo1_freq[size_t(CH1)].get() == _lo1_freq[size_t(CH2)].get() + and _lo1_enable[size_t(CH1)].get() == _lo1_enable[size_t(CH2)].get(); if (simultaneous_commit_lo1) { _config_lo_route(LO1, BOTH); - //Only commit one of the channels. The route LO_CONFIG_BOTH - //will ensure that the LEs for both channels are enabled + // Only commit one of the channels. The route LO_CONFIG_BOTH + // will ensure that the LEs for both channels are enabled _lo1_iface[size_t(CH1)]->commit(); _lo1_freq[size_t(CH1)].mark_clean(); _lo1_freq[size_t(CH2)].mark_clean(); _lo1_enable[size_t(CH1)].mark_clean(); _lo1_enable[size_t(CH2)].mark_clean(); } else { - if (_lo1_freq[size_t(CH1)].is_dirty() || _lo1_enable[size_t(CH1)].is_dirty()) { + if (_lo1_freq[size_t(CH1)].is_dirty() + || _lo1_enable[size_t(CH1)].is_dirty()) { _config_lo_route(LO1, CH1); _lo1_iface[size_t(CH1)]->commit(); _lo1_freq[size_t(CH1)].mark_clean(); _lo1_enable[size_t(CH1)].mark_clean(); } - if (_lo1_freq[size_t(CH2)].is_dirty() || _lo1_enable[size_t(CH2)].is_dirty()) { + if (_lo1_freq[size_t(CH2)].is_dirty() + || _lo1_enable[size_t(CH2)].is_dirty()) { _config_lo_route(LO1, CH2); _lo1_iface[size_t(CH2)]->commit(); _lo1_freq[size_t(CH2)].mark_clean(); @@ -642,29 +787,31 @@ private: //Functions } } - //Commit LO2 frequency - bool simultaneous_commit_lo2 = _lo2_freq[size_t(CH1)].is_dirty() and - _lo2_freq[size_t(CH2)].is_dirty() and - _lo2_freq[size_t(CH1)].get() == _lo2_freq[size_t(CH2)].get() and - _lo2_enable[size_t(CH1)].get() == _lo2_enable[size_t(CH2)].get(); + // Commit LO2 frequency + bool simultaneous_commit_lo2 = + _lo2_freq[size_t(CH1)].is_dirty() and _lo2_freq[size_t(CH2)].is_dirty() + and _lo2_freq[size_t(CH1)].get() == _lo2_freq[size_t(CH2)].get() + and _lo2_enable[size_t(CH1)].get() == _lo2_enable[size_t(CH2)].get(); if (simultaneous_commit_lo2) { _config_lo_route(LO2, BOTH); - //Only commit one of the channels. The route LO_CONFIG_BOTH - //will ensure that the LEs for both channels are enabled + // Only commit one of the channels. The route LO_CONFIG_BOTH + // will ensure that the LEs for both channels are enabled _lo2_iface[size_t(CH1)]->commit(); _lo2_freq[size_t(CH1)].mark_clean(); _lo2_freq[size_t(CH2)].mark_clean(); _lo2_enable[size_t(CH1)].mark_clean(); _lo2_enable[size_t(CH2)].mark_clean(); } else { - if (_lo2_freq[size_t(CH1)].is_dirty() || _lo2_enable[size_t(CH1)].is_dirty()) { + if (_lo2_freq[size_t(CH1)].is_dirty() + || _lo2_enable[size_t(CH1)].is_dirty()) { _config_lo_route(LO2, CH1); _lo2_iface[size_t(CH1)]->commit(); _lo2_freq[size_t(CH1)].mark_clean(); _lo2_enable[size_t(CH1)].mark_clean(); } - if (_lo2_freq[size_t(CH2)].is_dirty() || _lo2_enable[size_t(CH2)].is_dirty()) { + if (_lo2_freq[size_t(CH2)].is_dirty() + || _lo2_enable[size_t(CH2)].is_dirty()) { _config_lo_route(LO2, CH2); _lo2_iface[size_t(CH2)]->commit(); _lo2_freq[size_t(CH2)].mark_clean(); @@ -673,40 +820,46 @@ private: //Functions } } -private: //Members +private: // Members static const size_t NUM_CHANS = 2; - struct tune_freq_t : public uhd::math::fp_compare::fp_compare_delta<double> { - tune_freq_t() : uhd::math::fp_compare::fp_compare_delta<double>( - 0.0, uhd::math::FREQ_COMPARISON_DELTA_HZ) {} + struct tune_freq_t : public uhd::math::fp_compare::fp_compare_delta<double> + { + tune_freq_t() + : uhd::math::fp_compare::fp_compare_delta<double>( + 0.0, uhd::math::FREQ_COMPARISON_DELTA_HZ) + { + } - tune_freq_t(double freq) : uhd::math::fp_compare::fp_compare_delta<double>( - freq, uhd::math::FREQ_COMPARISON_DELTA_HZ) {} + tune_freq_t(double freq) + : uhd::math::fp_compare::fp_compare_delta<double>( + freq, uhd::math::FREQ_COMPARISON_DELTA_HZ) + { + } }; - boost::mutex _mutex; - dboard_iface::sptr _db_iface; - twinrx_gpio::sptr _gpio_iface; - twinrx_cpld_regmap::sptr _cpld_regs; - spi_config_t _spi_config; - adf535x_iface::sptr _lo1_iface[NUM_CHANS]; - adf435x_iface::sptr _lo2_iface[NUM_CHANS]; - lo_source_t _lo1_src[NUM_CHANS]; - lo_source_t _lo2_src[NUM_CHANS]; - dirty_tracked<tune_freq_t> _lo1_freq[NUM_CHANS]; - dirty_tracked<tune_freq_t> _lo2_freq[NUM_CHANS]; - dirty_tracked<bool> _lo1_enable[NUM_CHANS]; - dirty_tracked<bool> _lo2_enable[NUM_CHANS]; - lo_export_source_t _lo1_export; - lo_export_source_t _lo2_export; - bool _chan_enabled[NUM_CHANS]; + boost::mutex _mutex; + dboard_iface::sptr _db_iface; + twinrx_gpio::sptr _gpio_iface; + twinrx_cpld_regmap::sptr _cpld_regs; + spi_config_t _spi_config; + adf535x_iface::sptr _lo1_iface[NUM_CHANS]; + adf435x_iface::sptr _lo2_iface[NUM_CHANS]; + lo_source_t _lo1_src[NUM_CHANS]; + lo_source_t _lo2_src[NUM_CHANS]; + dirty_tracked<tune_freq_t> _lo1_freq[NUM_CHANS]; + dirty_tracked<tune_freq_t> _lo2_freq[NUM_CHANS]; + dirty_tracked<bool> _lo1_enable[NUM_CHANS]; + dirty_tracked<bool> _lo2_enable[NUM_CHANS]; + lo_export_source_t _lo1_export; + lo_export_source_t _lo2_export; + bool _chan_enabled[NUM_CHANS]; }; -twinrx_ctrl::sptr twinrx_ctrl::make( - dboard_iface::sptr db_iface, +twinrx_ctrl::sptr twinrx_ctrl::make(dboard_iface::sptr db_iface, twinrx_gpio::sptr gpio_iface, twinrx_cpld_regmap::sptr cpld_regmap, - const dboard_id_t rx_id -) { + const dboard_id_t rx_id) +{ return std::make_shared<twinrx_ctrl_impl>(db_iface, gpio_iface, cpld_regmap, rx_id); } diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp index dfdacde11..2f4d84ed5 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.hpp @@ -9,22 +9,21 @@ #define INCLUDED_DBOARD_TWINRX_CTRL_HPP #include "twinrx_io.hpp" +#include <uhd/types/ranges.hpp> #include <uhd/types/wb_iface.hpp> #include <uhd/utils/noncopyable.hpp> -#include <uhd/types/ranges.hpp> namespace uhd { namespace usrp { namespace dboard { namespace twinrx { -class twinrx_ctrl : public uhd::noncopyable { +class twinrx_ctrl : public uhd::noncopyable +{ public: typedef std::shared_ptr<twinrx_ctrl> sptr; - static sptr make( - dboard_iface::sptr db_iface, + static sptr make(dboard_iface::sptr db_iface, twinrx_gpio::sptr gpio_iface, twinrx_cpld_regmap::sptr cpld_regmap, - dboard_id_t rx_id - ); + dboard_id_t rx_id); virtual ~twinrx_ctrl() {} @@ -40,7 +39,13 @@ public: enum lo_export_source_t { LO_CH1_SYNTH, LO_CH2_SYNTH, LO_EXPORT_DISABLED }; - enum antenna_mapping_t { ANTX_NATIVE, ANT1_SHARED, ANT2_SHARED, ANTX_SWAPPED, ANTX_DISABLED }; + enum antenna_mapping_t { + ANTX_NATIVE, + ANT1_SHARED, + ANT2_SHARED, + ANTX_SWAPPED, + ANTX_DISABLED + }; enum cal_mode_t { CAL_DISABLED, CAL_CH1, CAL_CH2 }; @@ -52,13 +57,17 @@ public: virtual void set_preamp2(channel_t ch, bool enabled, bool commit = true) = 0; - virtual void set_lb_preamp_preselector(channel_t ch, bool enabled, bool commit = true) = 0; + virtual void set_lb_preamp_preselector( + channel_t ch, bool enabled, bool commit = true) = 0; - virtual void set_signal_path(channel_t ch, signal_path_t path, bool commit = true) = 0; + virtual void set_signal_path( + channel_t ch, signal_path_t path, bool commit = true) = 0; - virtual void set_lb_preselector(channel_t ch, preselector_path_t path, bool commit = true) = 0; + virtual void set_lb_preselector( + channel_t ch, preselector_path_t path, bool commit = true) = 0; - virtual void set_hb_preselector(channel_t ch, preselector_path_t path, bool commit = true) = 0; + virtual void set_hb_preselector( + channel_t ch, preselector_path_t path, bool commit = true) = 0; virtual void set_input_atten(channel_t ch, uint8_t atten, bool commit = true) = 0; @@ -82,9 +91,11 @@ public: virtual double set_lo2_synth_freq(channel_t ch, double freq, bool commit = true) = 0; - virtual double set_lo1_charge_pump(channel_t ch, double current, bool commit = true) = 0; + virtual double set_lo1_charge_pump( + channel_t ch, double current, bool commit = true) = 0; - virtual double set_lo2_charge_pump(channel_t ch, double current, bool commit = true) = 0; + virtual double set_lo2_charge_pump( + channel_t ch, double current, bool commit = true) = 0; virtual uhd::meta_range_t get_lo1_charge_pump_range() = 0; @@ -95,6 +106,6 @@ public: virtual bool read_lo2_locked(channel_t ch) = 0; }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_CTRL_HPP */ diff --git a/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp b/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp index f98521cc9..36bcc1863 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp @@ -7,12 +7,11 @@ #include "twinrx_experts.hpp" #include "twinrx_gain_tables.hpp" -#include <uhd/utils/math.hpp> -#include <uhd/utils/log.hpp> #include <uhd/exception.hpp> #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> -#include <uhd/types/dict.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> #include <boost/assign/list_of.hpp> #include <boost/math/special_functions/round.hpp> @@ -37,15 +36,15 @@ void twinrx_scheduling_expert::resolve() */ void twinrx_freq_path_expert::resolve() { - //Lowband/highband switch point + // Lowband/highband switch point static const double LB_HB_THRESHOLD_FREQ = 1.8e9; static const double LB_TARGET_IF1_FREQ = 2.345e9; static const double HB_TARGET_IF1_FREQ = 1.25e9; static const double INJ_SIDE_THRESHOLD_FREQ = 5.1e9; - static const double FIXED_LO1_THRESHOLD_FREQ= 50e6; + static const double FIXED_LO1_THRESHOLD_FREQ = 50e6; - //Preselector filter switch point + // Preselector filter switch point static const double LB_FILT1_THRESHOLD_FREQ = 0.5e9; static const double LB_FILT2_THRESHOLD_FREQ = 0.8e9; static const double LB_FILT3_THRESHOLD_FREQ = 1.2e9; @@ -57,7 +56,7 @@ void twinrx_freq_path_expert::resolve() static const double LB_PREAMP_PRESEL_THRESHOLD_FREQ = 0.8e9; - //Misc + // Misc static const double INST_BANDWIDTH = 80e6; static const double MANUAL_LO_HYSTERESIS_PPM = 1.0; @@ -65,8 +64,8 @@ void twinrx_freq_path_expert::resolve() rf_freq_abs_t rf_freq(FREQ_RANGE.clip(_rf_freq_d)); // Choose low-band vs high-band depending on frequency - _signal_path = (rf_freq > LB_HB_THRESHOLD_FREQ) ? - twinrx_ctrl::PATH_HIGHBAND : twinrx_ctrl::PATH_LOWBAND; + _signal_path = (rf_freq > LB_HB_THRESHOLD_FREQ) ? twinrx_ctrl::PATH_HIGHBAND + : twinrx_ctrl::PATH_LOWBAND; if (_signal_path == twinrx_ctrl::PATH_LOWBAND) { // Choose low-band preselector filter if (rf_freq < LB_FILT1_THRESHOLD_FREQ) { @@ -97,41 +96,43 @@ void twinrx_freq_path_expert::resolve() UHD_THROW_INVALID_CODE_PATH(); } - //Choose low-band preamp preselector + // Choose low-band preamp preselector _lb_preamp_presel = (rf_freq > LB_PREAMP_PRESEL_THRESHOLD_FREQ); - //Choose LO frequencies - const double target_if1_freq = (_signal_path == twinrx_ctrl::PATH_HIGHBAND) ? - HB_TARGET_IF1_FREQ : LB_TARGET_IF1_FREQ; + // Choose LO frequencies + const double target_if1_freq = (_signal_path == twinrx_ctrl::PATH_HIGHBAND) + ? HB_TARGET_IF1_FREQ + : LB_TARGET_IF1_FREQ; const double target_if2_freq = _if_freq_d; // LO1 double lo1_freq_ideal = 0.0, lo2_freq_ideal = 0.0; if (rf_freq <= FIXED_LO1_THRESHOLD_FREQ) { - //LO1 Freq static + // LO1 Freq static lo1_freq_ideal = target_if1_freq + FIXED_LO1_THRESHOLD_FREQ; } else if (rf_freq <= INJ_SIDE_THRESHOLD_FREQ) { - //High-side LO1 Injection + // High-side LO1 Injection lo1_freq_ideal = rf_freq.get() + target_if1_freq; } else { - //Low-side LO1 Injection + // Low-side LO1 Injection lo1_freq_ideal = rf_freq.get() - target_if1_freq; } if (_lo1_freq_d.get_author() == experts::AUTHOR_USER) { - if (_lo1_freq_d.is_dirty()) { //Are we here because the LO frequency was set? + if (_lo1_freq_d.is_dirty()) { // Are we here because the LO frequency was set? // The user explicitly requested to set the LO freq so don't touch it! } else { // Something else changed which may cause the LO frequency to update. // Only commit if the frequency is stale. If the user's value is stale // reset the author to expert. - if (rf_freq_ppm_t(lo1_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) != _lo1_freq_d.get()) { - _lo1_freq_d = lo1_freq_ideal; //Reset author + if (rf_freq_ppm_t(lo1_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) + != _lo1_freq_d.get()) { + _lo1_freq_d = lo1_freq_ideal; // Reset author } } } else { // The LO frequency was never set by the user. Let the expert take care of it - _lo1_freq_d = lo1_freq_ideal; //Reset author + _lo1_freq_d = lo1_freq_ideal; // Reset author } // LO2 @@ -144,37 +145,40 @@ void twinrx_freq_path_expert::resolve() } if (_lo2_freq_d.get_author() == experts::AUTHOR_USER) { - if (_lo2_freq_d.is_dirty()) { //Are we here because the LO frequency was set? + if (_lo2_freq_d.is_dirty()) { // Are we here because the LO frequency was set? // The user explicitly requested to set the LO freq so don't touch it! } else { // Something else changed which may cause the LO frequency to update. // Only commit if the frequency is stale. If the user's value is stale // reset the author to expert. - if (rf_freq_ppm_t(lo2_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) != _lo2_freq_d.get()) { - _lo2_freq_d = lo2_freq_ideal; //Reset author + if (rf_freq_ppm_t(lo2_freq_ideal, MANUAL_LO_HYSTERESIS_PPM) + != _lo2_freq_d.get()) { + _lo2_freq_d = lo2_freq_ideal; // Reset author } } } else { // The LO frequency was never set by the user. Let the expert take care of it - _lo2_freq_d = lo2_freq_ideal; //Reset author + _lo2_freq_d = lo2_freq_ideal; // Reset author } // Determine injection side using the final LO frequency - _lo1_inj_side = (_lo1_freq_d > rf_freq.get()) ? INJ_HIGH_SIDE : INJ_LOW_SIDE; + _lo1_inj_side = (_lo1_freq_d > rf_freq.get()) ? INJ_HIGH_SIDE : INJ_LOW_SIDE; _lo2_inj_side = (_lo2_freq_d > target_if1_freq) ? INJ_HIGH_SIDE : INJ_LOW_SIDE; } lo_inj_side_t twinrx_freq_path_expert::_compute_lo2_inj_side( - double lo1_freq, double if1_freq, double if2_freq, double bandwidth -) { + double lo1_freq, double if1_freq, double if2_freq, double bandwidth) +{ static const int MAX_SPUR_ORDER = 5; for (int ord = MAX_SPUR_ORDER; ord >= 1; ord--) { // Check high-side injection first - if (not _has_mixer_spurs(lo1_freq, if1_freq + if2_freq, if2_freq, bandwidth, ord)) { + if (not _has_mixer_spurs( + lo1_freq, if1_freq + if2_freq, if2_freq, bandwidth, ord)) { return INJ_HIGH_SIDE; } // Check low-side injection second - if (not _has_mixer_spurs(lo1_freq, if1_freq - if2_freq, if2_freq, bandwidth, ord)) { + if (not _has_mixer_spurs( + lo1_freq, if1_freq - if2_freq, if2_freq, bandwidth, ord)) { return INJ_LOW_SIDE; } } @@ -183,19 +187,18 @@ lo_inj_side_t twinrx_freq_path_expert::_compute_lo2_inj_side( } bool twinrx_freq_path_expert::_has_mixer_spurs( - double lo1_freq, double lo2_freq, double if2_freq, - double bandwidth, int spur_order -) { + double lo1_freq, double lo2_freq, double if2_freq, double bandwidth, int spur_order) +{ // Iterate through all N-th order harmomic combinations // of LOs... for (int lo1h_i = 1; lo1h_i <= spur_order; lo1h_i++) { double lo1harm_freq = lo1_freq * lo1h_i; for (int lo2h_i = 1; lo2h_i <= spur_order; lo2h_i++) { double lo2harm_freq = lo2_freq * lo2h_i; - double hdelta = lo1harm_freq - lo2harm_freq; + double hdelta = lo1harm_freq - lo2harm_freq; // .. and check if there is a mixer spur in the IF band - if (std::abs(hdelta + if2_freq) < bandwidth/2 or - std::abs(hdelta - if2_freq) < bandwidth/2) { + if (std::abs(hdelta + if2_freq) < bandwidth / 2 + or std::abs(hdelta - if2_freq) < bandwidth / 2) { return true; } } @@ -211,11 +214,12 @@ bool twinrx_freq_path_expert::_has_mixer_spurs( void twinrx_freq_coercion_expert::resolve() { const double actual_if2_freq = _if_freq_d; - const double actual_if1_freq = (_lo2_inj_side == INJ_LOW_SIDE) ? - (_lo2_freq_c + actual_if2_freq) : (_lo2_freq_c - actual_if2_freq); + const double actual_if1_freq = (_lo2_inj_side == INJ_LOW_SIDE) + ? (_lo2_freq_c + actual_if2_freq) + : (_lo2_freq_c - actual_if2_freq); - _rf_freq_c = (_lo1_inj_side == INJ_LOW_SIDE) ? - (_lo1_freq_c + actual_if1_freq) : (_lo1_freq_c - actual_if1_freq); + _rf_freq_c = (_lo1_inj_side == INJ_LOW_SIDE) ? (_lo1_freq_c + actual_if1_freq) + : (_lo1_freq_c - actual_if1_freq); } /*!--------------------------------------------------------- @@ -238,12 +242,14 @@ void twinrx_nyquist_expert::resolve() _cached_cmd_time = _rx_frontend_time; double if_freq_sign = 1.0; - if (_lo1_inj_side == INJ_HIGH_SIDE) if_freq_sign *= -1.0; - if (_lo2_inj_side == INJ_HIGH_SIDE) if_freq_sign *= -1.0; + if (_lo1_inj_side == INJ_HIGH_SIDE) + if_freq_sign *= -1.0; + if (_lo2_inj_side == INJ_HIGH_SIDE) + if_freq_sign *= -1.0; _if_freq_c = _if_freq_d * if_freq_sign; - _db_iface->set_fe_connection(dboard_iface::UNIT_RX, _channel, - usrp::fe_connection_t(_codec_conn, _if_freq_c)); + _db_iface->set_fe_connection( + dboard_iface::UNIT_RX, _channel, usrp::fe_connection_t(_codec_conn, _if_freq_c)); } /*!--------------------------------------------------------- @@ -253,22 +259,22 @@ void twinrx_nyquist_expert::resolve() void twinrx_chan_gain_expert::resolve() { if (_gain_profile != "default") { - //TODO: Implement me! + // TODO: Implement me! throw uhd::not_implemented_error("custom gain strategies not implemeted yet"); } - //Lookup table using settings - const twinrx_gain_table table = twinrx_gain_table::lookup_table( - _signal_path, - (_signal_path==twinrx_ctrl::PATH_HIGHBAND) ? _hb_presel : _lb_presel, + // Lookup table using settings + const twinrx_gain_table table = twinrx_gain_table::lookup_table(_signal_path, + (_signal_path == twinrx_ctrl::PATH_HIGHBAND) ? _hb_presel : _lb_presel, _gain_profile); - //Compute minimum gain. The user-specified gain value will be interpreted as - //the gain applied on top of the minimum gain state. - //If antennas are shared or swapped, the switch has 6dB of loss - size_t gain_index = std::min(static_cast<size_t>(boost::math::round(_gain.get())), table.get_num_entries()-1); + // Compute minimum gain. The user-specified gain value will be interpreted as + // the gain applied on top of the minimum gain state. + // If antennas are shared or swapped, the switch has 6dB of loss + size_t gain_index = std::min(static_cast<size_t>(boost::math::round(_gain.get())), + table.get_num_entries() - 1); - //Translate gain to an index in the gain table + // Translate gain to an index in the gain table const twinrx_gain_config_t& config = table.find_by_index(gain_index); _input_atten = config.atten1; @@ -279,8 +285,10 @@ void twinrx_chan_gain_expert::resolve() } // Preamp 1 should use the Highband amp for frequencies above 3 GHz - if (_signal_path == twinrx_ctrl::PATH_HIGHBAND && _hb_presel != twinrx_ctrl::PRESEL_PATH1) { - _preamp1 = config.amp1 ? twinrx_ctrl::PREAMP_HIGHBAND : twinrx_ctrl::PREAMP_BYPASS; + if (_signal_path == twinrx_ctrl::PATH_HIGHBAND + && _hb_presel != twinrx_ctrl::PRESEL_PATH1) { + _preamp1 = config.amp1 ? twinrx_ctrl::PREAMP_HIGHBAND + : twinrx_ctrl::PREAMP_BYPASS; } else { _preamp1 = config.amp1 ? twinrx_ctrl::PREAMP_LOWBAND : twinrx_ctrl::PREAMP_BYPASS; } @@ -295,22 +303,21 @@ void twinrx_chan_gain_expert::resolve() void twinrx_lo_config_expert::resolve() { static const uhd::dict<std::string, twinrx_ctrl::lo_source_t> src_lookup = - boost::assign::map_list_of - ("internal", twinrx_ctrl::LO_INTERNAL) - ("external", twinrx_ctrl::LO_EXTERNAL) - ("companion", twinrx_ctrl::LO_COMPANION) - ("disabled", twinrx_ctrl::LO_DISABLED) - ("reimport", twinrx_ctrl::LO_REIMPORT); + boost::assign::map_list_of("internal", twinrx_ctrl::LO_INTERNAL)( + "external", twinrx_ctrl::LO_EXTERNAL)("companion", twinrx_ctrl::LO_COMPANION)( + "disabled", twinrx_ctrl::LO_DISABLED)("reimport", twinrx_ctrl::LO_REIMPORT); if (src_lookup.has_key(_lo_source_ch0)) { _lo1_src_ch0 = _lo2_src_ch0 = src_lookup[_lo_source_ch0]; } else { - throw uhd::value_error("Invalid LO source for channel 0.Choose from {internal, external, companion, reimport}"); + throw uhd::value_error("Invalid LO source for channel 0.Choose from {internal, " + "external, companion, reimport}"); } if (src_lookup.has_key(_lo_source_ch1)) { _lo1_src_ch1 = _lo2_src_ch1 = src_lookup[_lo_source_ch1]; } else { - throw uhd::value_error("Invalid LO source for channel 1.Choose from {internal, external, companion, reimport}"); + throw uhd::value_error("Invalid LO source for channel 1.Choose from {internal, " + "external, companion, reimport}"); } twinrx_ctrl::lo_export_source_t export_src = twinrx_ctrl::LO_EXPORT_DISABLED; @@ -325,11 +332,13 @@ void twinrx_lo_config_expert::resolve() if (_lo_export_ch0 and _lo_export_ch1) { throw uhd::value_error("Cannot export LOs for both channels"); } else if (_lo_export_ch0) { - export_src = (_lo1_src_ch0 == twinrx_ctrl::LO_COMPANION) ? - twinrx_ctrl::LO_CH2_SYNTH : twinrx_ctrl::LO_CH1_SYNTH; + export_src = (_lo1_src_ch0 == twinrx_ctrl::LO_COMPANION) + ? twinrx_ctrl::LO_CH2_SYNTH + : twinrx_ctrl::LO_CH1_SYNTH; } else if (_lo_export_ch1) { - export_src = (_lo1_src_ch1 == twinrx_ctrl::LO_COMPANION) ? - twinrx_ctrl::LO_CH1_SYNTH : twinrx_ctrl::LO_CH2_SYNTH; + export_src = (_lo1_src_ch1 == twinrx_ctrl::LO_COMPANION) + ? twinrx_ctrl::LO_CH1_SYNTH + : twinrx_ctrl::LO_CH2_SYNTH; } _lo1_export_src = _lo2_export_src = export_src; } @@ -348,12 +357,14 @@ void twinrx_lo_mapping_expert::resolve() // "internal" or "reimport" -> this channel // "companion" -> other channel size_t synth_map[] = {0, 0}; - if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { + if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { synth_map[0] = synth_map[0] | CH0_MSK; } else if (_lox_src_ch0 == twinrx_ctrl::LO_COMPANION) { synth_map[1] = synth_map[1] | CH0_MSK; } - if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { + if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { synth_map[1] = synth_map[1] | CH1_MSK; } else if (_lox_src_ch1 == twinrx_ctrl::LO_COMPANION) { synth_map[0] = synth_map[0] | CH1_MSK; @@ -365,20 +376,22 @@ void twinrx_lo_mapping_expert::resolve() // to overlap tuning with signal dwell time. bool hopping_enabled = false; if (_lox_src_ch0 == twinrx_ctrl::LO_DISABLED) { - if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { - synth_map[0] = synth_map[0] | CH0_MSK; + if (_lox_src_ch1 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch1 == twinrx_ctrl::LO_REIMPORT) { + synth_map[0] = synth_map[0] | CH0_MSK; hopping_enabled = true; } else if (_lox_src_ch1 == twinrx_ctrl::LO_COMPANION) { - synth_map[1] = synth_map[1] | CH0_MSK; + synth_map[1] = synth_map[1] | CH0_MSK; hopping_enabled = true; } } if (_lox_src_ch1 == twinrx_ctrl::LO_DISABLED) { - if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { - synth_map[1] = synth_map[1] | CH1_MSK; + if (_lox_src_ch0 == twinrx_ctrl::LO_INTERNAL + or _lox_src_ch0 == twinrx_ctrl::LO_REIMPORT) { + synth_map[1] = synth_map[1] | CH1_MSK; hopping_enabled = true; } else if (_lox_src_ch0 == twinrx_ctrl::LO_COMPANION) { - synth_map[0] = synth_map[0] | CH1_MSK; + synth_map[0] = synth_map[0] | CH1_MSK; hopping_enabled = true; } } @@ -387,7 +400,7 @@ void twinrx_lo_mapping_expert::resolve() for (size_t synth = 0; synth < 2; synth++) { experts::data_writer_t<lo_synth_mapping_t>& lox_mapping = (synth == 0) ? _lox_mapping_synth0 : _lox_mapping_synth1; - if (synth_map[synth] == (CH0_MSK|CH1_MSK)) { + if (synth_map[synth] == (CH0_MSK | CH1_MSK)) { lox_mapping = MAPPING_SHARED; } else if (synth_map[synth] == CH0_MSK) { lox_mapping = MAPPING_CH0; @@ -429,18 +442,22 @@ void twinrx_antenna_expert::resolve() } else if (_antenna_ch0 == ANT1 and _antenna_ch1 == ANT0) { _ant_mapping = twinrx_ctrl::ANTX_SWAPPED; } else if (_antenna_ch0 != ANT0 and _antenna_ch0 != ANT1) { - throw uhd::value_error("Invalid antenna selection " + _antenna_ch0.get() + " for channel 0. Must be " + ANT0 + " or " + ANT1); + throw uhd::value_error("Invalid antenna selection " + _antenna_ch0.get() + + " for channel 0. Must be " + ANT0 + " or " + ANT1); } else if (_antenna_ch1 != ANT0 and _antenna_ch1 != ANT1) { - throw uhd::value_error("Invalid antenna selection " + _antenna_ch1.get() + " for channel 1. Must be " + ANT0 + " or " + ANT1); + throw uhd::value_error("Invalid antenna selection " + _antenna_ch1.get() + + " for channel 1. Must be " + ANT0 + " or " + ANT1); } - //TODO: Implement hooks for the calibration switch + // TODO: Implement hooks for the calibration switch _cal_mode = twinrx_ctrl::CAL_DISABLED; if (_cal_mode == twinrx_ctrl::CAL_CH1 and _lo_export_ch1) { - throw uhd::value_error("Cannot calibrate channel 0 and export the LO for channel 1."); + throw uhd::value_error( + "Cannot calibrate channel 0 and export the LO for channel 1."); } else if (_cal_mode == twinrx_ctrl::CAL_CH2 and _lo_export_ch0) { - throw uhd::value_error("Cannot calibrate channel 1 and export the LO for channel 0."); + throw uhd::value_error( + "Cannot calibrate channel 1 and export the LO for channel 0."); } } @@ -451,72 +468,72 @@ void twinrx_antenna_expert::resolve() void twinrx_ant_gain_expert::resolve() { switch (_ant_mapping) { - case twinrx_ctrl::ANTX_NATIVE: - _ant0_input_atten = _ch0_input_atten; - _ant0_preamp1 = _ch0_preamp1; - _ant0_preamp2 = _ch0_preamp2; - _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; - _ant1_input_atten = _ch1_input_atten; - _ant1_preamp1 = _ch1_preamp1; - _ant1_preamp2 = _ch1_preamp2; - _ant1_lb_preamp_presel = _ch1_lb_preamp_presel; - break; - case twinrx_ctrl::ANTX_SWAPPED: - _ant0_input_atten = _ch1_input_atten; - _ant0_preamp1 = _ch1_preamp1; - _ant0_preamp2 = _ch1_preamp2; - _ant0_lb_preamp_presel = _ch1_lb_preamp_presel; - _ant1_input_atten = _ch0_input_atten; - _ant1_preamp1 = _ch0_preamp1; - _ant1_preamp2 = _ch0_preamp2; - _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; - break; - case twinrx_ctrl::ANT1_SHARED: - if ((_ch0_input_atten != _ch1_input_atten) or - (_ch0_preamp1 != _ch1_preamp1) or - (_ch0_preamp2 != _ch1_preamp2) or - (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) - { - UHD_LOGGER_WARNING("TWINRX") << "incompatible gain settings for antenna sharing. temporarily using Ch0 settings for Ch1."; - } - _ant0_input_atten = _ch0_input_atten; - _ant0_preamp1 = _ch0_preamp1; - _ant0_preamp2 = _ch0_preamp2; - _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; - - _ant1_input_atten = 0; - _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant1_preamp2 = false; - _ant1_lb_preamp_presel = false; - break; - case twinrx_ctrl::ANT2_SHARED: - if ((_ch0_input_atten != _ch1_input_atten) or - (_ch0_preamp1 != _ch1_preamp1) or - (_ch0_preamp2 != _ch1_preamp2) or - (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) - { - UHD_LOGGER_WARNING("TWINRX") << "incompatible gain settings for antenna sharing. temporarily using Ch0 settings for Ch1."; - } - _ant1_input_atten = _ch0_input_atten; - _ant1_preamp1 = _ch0_preamp1; - _ant1_preamp2 = _ch0_preamp2; - _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; - - _ant0_input_atten = 0; - _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant0_preamp2 = false; - _ant0_lb_preamp_presel = false; - break; - default: - _ant0_input_atten = 0; - _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant0_preamp2 = false; - _ant0_lb_preamp_presel = false; - _ant1_input_atten = 0; - _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; - _ant1_preamp2 = false; - _ant1_lb_preamp_presel = false; - break; + case twinrx_ctrl::ANTX_NATIVE: + _ant0_input_atten = _ch0_input_atten; + _ant0_preamp1 = _ch0_preamp1; + _ant0_preamp2 = _ch0_preamp2; + _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; + _ant1_input_atten = _ch1_input_atten; + _ant1_preamp1 = _ch1_preamp1; + _ant1_preamp2 = _ch1_preamp2; + _ant1_lb_preamp_presel = _ch1_lb_preamp_presel; + break; + case twinrx_ctrl::ANTX_SWAPPED: + _ant0_input_atten = _ch1_input_atten; + _ant0_preamp1 = _ch1_preamp1; + _ant0_preamp2 = _ch1_preamp2; + _ant0_lb_preamp_presel = _ch1_lb_preamp_presel; + _ant1_input_atten = _ch0_input_atten; + _ant1_preamp1 = _ch0_preamp1; + _ant1_preamp2 = _ch0_preamp2; + _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; + break; + case twinrx_ctrl::ANT1_SHARED: + if ((_ch0_input_atten != _ch1_input_atten) or (_ch0_preamp1 != _ch1_preamp1) + or (_ch0_preamp2 != _ch1_preamp2) + or (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) { + UHD_LOGGER_WARNING("TWINRX") + << "incompatible gain settings for antenna sharing. temporarily " + "using Ch0 settings for Ch1."; + } + _ant0_input_atten = _ch0_input_atten; + _ant0_preamp1 = _ch0_preamp1; + _ant0_preamp2 = _ch0_preamp2; + _ant0_lb_preamp_presel = _ch0_lb_preamp_presel; + + _ant1_input_atten = 0; + _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant1_preamp2 = false; + _ant1_lb_preamp_presel = false; + break; + case twinrx_ctrl::ANT2_SHARED: + if ((_ch0_input_atten != _ch1_input_atten) or (_ch0_preamp1 != _ch1_preamp1) + or (_ch0_preamp2 != _ch1_preamp2) + or (_ch0_lb_preamp_presel != _ch1_lb_preamp_presel)) { + UHD_LOGGER_WARNING("TWINRX") + << "incompatible gain settings for antenna sharing. temporarily " + "using Ch0 settings for Ch1."; + } + _ant1_input_atten = _ch0_input_atten; + _ant1_preamp1 = _ch0_preamp1; + _ant1_preamp2 = _ch0_preamp2; + _ant1_lb_preamp_presel = _ch0_lb_preamp_presel; + + _ant0_input_atten = 0; + _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant0_preamp2 = false; + _ant0_lb_preamp_presel = false; + break; + default: + _ant0_input_atten = 0; + _ant0_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant0_preamp2 = false; + _ant0_lb_preamp_presel = false; + _ant1_input_atten = 0; + _ant1_preamp1 = twinrx_ctrl::PREAMP_BYPASS; + _ant1_preamp2 = false; + _ant1_lb_preamp_presel = false; + break; } } @@ -529,7 +546,7 @@ const bool twinrx_settings_expert::FORCE_COMMIT = false; void twinrx_settings_expert::resolve() { for (size_t i = 0; i < 2; i++) { - ch_settings& ch_set = (i == 1) ? _ch1 : _ch0; + ch_settings& ch_set = (i == 1) ? _ch1 : _ch0; twinrx_ctrl::channel_t ch = (i == 1) ? twinrx_ctrl::CH2 : twinrx_ctrl::CH1; _ctrl->set_chan_enabled(ch, ch_set.chan_enabled, FORCE_COMMIT); _ctrl->set_preamp1(ch, ch_set.preamp1, FORCE_COMMIT); @@ -550,34 +567,45 @@ void twinrx_settings_expert::resolve() } _resolve_lox_freq(STAGE_LO1, - _ch0.lo1_freq_d, _ch1.lo1_freq_d, _ch0.lo1_freq_c, _ch1.lo1_freq_c, - _ch0.lo1_source, _ch1.lo1_source, _lo1_synth0_mapping, _lo1_synth1_mapping, + _ch0.lo1_freq_d, + _ch1.lo1_freq_d, + _ch0.lo1_freq_c, + _ch1.lo1_freq_c, + _ch0.lo1_source, + _ch1.lo1_source, + _lo1_synth0_mapping, + _lo1_synth1_mapping, _lo1_hopping_enabled); _resolve_lox_freq(STAGE_LO2, - _ch0.lo2_freq_d, _ch1.lo2_freq_d, _ch0.lo2_freq_c, _ch1.lo2_freq_c, - _ch0.lo2_source, _ch1.lo2_source, _lo2_synth0_mapping, _lo2_synth1_mapping, + _ch0.lo2_freq_d, + _ch1.lo2_freq_d, + _ch0.lo2_freq_c, + _ch1.lo2_freq_c, + _ch0.lo2_source, + _ch1.lo2_source, + _lo2_synth0_mapping, + _lo2_synth1_mapping, _lo2_hopping_enabled); _ctrl->set_lo1_export_source(_lo1_export_src, FORCE_COMMIT); _ctrl->set_lo2_export_source(_lo2_export_src, FORCE_COMMIT); _ctrl->set_antenna_mapping(_ant_mapping, FORCE_COMMIT); - //TODO: Re-enable this when we support this mode + // TODO: Re-enable this when we support this mode //_ctrl->set_crossover_cal_mode(_cal_mode, FORCE_COMMIT); _ctrl->commit(); } -void twinrx_settings_expert::_resolve_lox_freq( - lo_stage_t lo_stage, +void twinrx_settings_expert::_resolve_lox_freq(lo_stage_t lo_stage, uhd::experts::data_reader_t<double>& ch0_freq_d, uhd::experts::data_reader_t<double>& ch1_freq_d, uhd::experts::data_writer_t<double>& ch0_freq_c, uhd::experts::data_writer_t<double>& ch1_freq_c, - twinrx_ctrl::lo_source_t ch0_lo_source, - twinrx_ctrl::lo_source_t ch1_lo_source, - lo_synth_mapping_t synth0_mapping, - lo_synth_mapping_t synth1_mapping, - bool hopping_enabled) + twinrx_ctrl::lo_source_t ch0_lo_source, + twinrx_ctrl::lo_source_t ch1_lo_source, + lo_synth_mapping_t synth0_mapping, + lo_synth_mapping_t synth1_mapping, + bool hopping_enabled) { if (ch0_lo_source == twinrx_ctrl::LO_EXTERNAL) { // If the LO is external then we don't need to program any synthesizers @@ -594,7 +622,8 @@ void twinrx_settings_expert::_resolve_lox_freq( ch0_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH2, ch0_freq_d); } else if (synth0_mapping == MAPPING_SHARED or synth1_mapping == MAPPING_SHARED) { // If any synthesizer is being shared then we are not in hopping mode - twinrx_ctrl::channel_t ch = (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; + twinrx_ctrl::channel_t ch = + (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; ch0_freq_c = _set_lox_synth_freq(lo_stage, ch, ch0_freq_d); ch1_freq_c = ch0_freq_c; } @@ -609,28 +638,32 @@ void twinrx_settings_expert::_resolve_lox_freq( // hopping, then always write the frequency because other inputs might require // an LO re-commit const bool freq_update_request = (not hopping_enabled) or ch1_freq_d.is_dirty(); - // As an additional layer of protection from unnecessarily committing the LO, check - // if the frequency has actually changed. + // As an additional layer of protection from unnecessarily committing the LO, + // check if the frequency has actually changed. if (synth0_mapping == MAPPING_CH1 and freq_update_request) { ch1_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH1, ch1_freq_d); } else if (synth1_mapping == MAPPING_CH1 and freq_update_request) { ch1_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH2, ch1_freq_d); } else if (synth0_mapping == MAPPING_SHARED or synth1_mapping == MAPPING_SHARED) { // If any synthesizer is being shared then we are not in hopping mode - twinrx_ctrl::channel_t ch = (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; + twinrx_ctrl::channel_t ch = + (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2; ch0_freq_c = _set_lox_synth_freq(lo_stage, ch, ch0_freq_d); ch1_freq_c = ch0_freq_c; } } } -double twinrx_settings_expert::_set_lox_synth_freq(lo_stage_t stage, twinrx_ctrl::channel_t ch, double freq) +double twinrx_settings_expert::_set_lox_synth_freq( + lo_stage_t stage, twinrx_ctrl::channel_t ch, double freq) { lo_freq_cache_t* freq_cache = NULL; if (stage == STAGE_LO1) { - freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo1_synth0_freq : &_cached_lo1_synth1_freq; + freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo1_synth0_freq + : &_cached_lo1_synth1_freq; } else if (stage == STAGE_LO2) { - freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo2_synth0_freq : &_cached_lo2_synth1_freq; + freq_cache = (ch == twinrx_ctrl::CH1) ? &_cached_lo2_synth0_freq + : &_cached_lo2_synth1_freq; } else { throw uhd::assertion_error("Invalid LO stage"); } @@ -650,4 +683,3 @@ double twinrx_settings_expert::_set_lox_synth_freq(lo_stage_t stage, twinrx_ctrl } return coerced_freq; } - diff --git a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp index 16569849c..c7e021a90 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp @@ -9,8 +9,8 @@ #define INCLUDED_DBOARD_TWINRX_EXPERTS_HPP #include "twinrx_ctrl.hpp" -#include <uhdlib/experts/expert_nodes.hpp> #include <uhd/utils/math.hpp> +#include <uhdlib/experts/expert_nodes.hpp> namespace uhd { namespace usrp { namespace dboard { namespace twinrx { @@ -18,26 +18,37 @@ namespace uhd { namespace usrp { namespace dboard { namespace twinrx { // Misc types and definitions //--------------------------------------------------------- -struct rf_freq_abs_t : public uhd::math::fp_compare::fp_compare_delta<double> { - rf_freq_abs_t(double freq = 0.0, double epsilon = 1.0 /* 1Hz epsilon */) : - uhd::math::fp_compare::fp_compare_delta<double>(freq, epsilon) {} - inline double get() const { return _value; } +struct rf_freq_abs_t : public uhd::math::fp_compare::fp_compare_delta<double> +{ + rf_freq_abs_t(double freq = 0.0, double epsilon = 1.0 /* 1Hz epsilon */) + : uhd::math::fp_compare::fp_compare_delta<double>(freq, epsilon) + { + } + inline double get() const + { + return _value; + } }; -struct rf_freq_ppm_t : public rf_freq_abs_t { - rf_freq_ppm_t(double freq = 0.0, double epsilon_ppm = 0.1 /* 1PPM epsilon */) : - rf_freq_abs_t(freq, 1e-6 * freq * epsilon_ppm) {} +struct rf_freq_ppm_t : public rf_freq_abs_t +{ + rf_freq_ppm_t(double freq = 0.0, double epsilon_ppm = 0.1 /* 1PPM epsilon */) + : rf_freq_abs_t(freq, 1e-6 * freq * epsilon_ppm) + { + } }; enum lo_stage_t { STAGE_LO1, STAGE_LO2 }; enum lo_inj_side_t { INJ_LOW_SIDE, INJ_HIGH_SIDE }; enum lo_synth_mapping_t { MAPPING_NONE, MAPPING_CH0, MAPPING_CH1, MAPPING_SHARED }; -static const std::string prepend_ch(std::string name, const std::string& ch) { +static const std::string prepend_ch(std::string name, const std::string& ch) +{ return ch + "/" + name; } -static const std::string lo_stage_str(lo_stage_t stage, bool lower = false) { +static const std::string lo_stage_str(lo_stage_t stage, bool lower = false) +{ std::string prefix = lower ? "lo" : "LO"; return prefix + ((stage == STAGE_LO1) ? "1" : "2"); } @@ -53,12 +64,13 @@ static const std::string lo_stage_str(lo_stage_t stage, bool lower = false) { * * --------------------------------------------------------- */ -class twinrx_scheduling_expert : public experts::worker_node_t { +class twinrx_scheduling_expert : public experts::worker_node_t +{ public: twinrx_scheduling_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_scheduling_expert", ch)), - _command_time (db, prepend_ch("time/cmd", ch)), - _rx_frontend_time (db, prepend_ch("time/rx_frontend", ch)) + : experts::worker_node_t(prepend_ch("twinrx_scheduling_expert", ch)) + , _command_time(db, prepend_ch("time/cmd", ch)) + , _rx_frontend_time(db, prepend_ch("time/rx_frontend", ch)) { bind_accessor(_command_time); bind_accessor(_rx_frontend_time); @@ -67,11 +79,11 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<time_spec_t> _command_time; + // Inputs + experts::data_reader_t<time_spec_t> _command_time; - //Outputs - experts::data_writer_t<time_spec_t> _rx_frontend_time; + // Outputs + experts::data_writer_t<time_spec_t> _rx_frontend_time; }; /*!--------------------------------------------------------- @@ -85,20 +97,21 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_freq_path_expert : public experts::worker_node_t { +class twinrx_freq_path_expert : public experts::worker_node_t +{ public: twinrx_freq_path_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_freq_path_expert", ch)), - _rf_freq_d (db, prepend_ch("freq/desired", ch)), - _if_freq_d (db, prepend_ch("if_freq/desired", ch)), - _signal_path (db, prepend_ch("ch/signal_path", ch)), - _lb_presel (db, prepend_ch("ch/lb_presel", ch)), - _hb_presel (db, prepend_ch("ch/hb_presel", ch)), - _lb_preamp_presel (db, prepend_ch("ch/lb_preamp_presel", ch)), - _lo1_freq_d (db, prepend_ch("los/LO1/freq/desired", ch)), - _lo2_freq_d (db, prepend_ch("los/LO2/freq/desired", ch)), - _lo1_inj_side (db, prepend_ch("ch/LO1/inj_side", ch)), - _lo2_inj_side (db, prepend_ch("ch/LO2/inj_side", ch)) + : experts::worker_node_t(prepend_ch("twinrx_freq_path_expert", ch)) + , _rf_freq_d(db, prepend_ch("freq/desired", ch)) + , _if_freq_d(db, prepend_ch("if_freq/desired", ch)) + , _signal_path(db, prepend_ch("ch/signal_path", ch)) + , _lb_presel(db, prepend_ch("ch/lb_presel", ch)) + , _hb_presel(db, prepend_ch("ch/hb_presel", ch)) + , _lb_preamp_presel(db, prepend_ch("ch/lb_preamp_presel", ch)) + , _lo1_freq_d(db, prepend_ch("los/LO1/freq/desired", ch)) + , _lo2_freq_d(db, prepend_ch("los/LO2/freq/desired", ch)) + , _lo1_inj_side(db, prepend_ch("ch/LO1/inj_side", ch)) + , _lo2_inj_side(db, prepend_ch("ch/LO2/inj_side", ch)) { bind_accessor(_rf_freq_d); bind_accessor(_if_freq_d); @@ -115,23 +128,25 @@ public: private: virtual void resolve(); static lo_inj_side_t _compute_lo2_inj_side( - double lo1_freq, double if1_freq, double if2_freq, double bandwidth); - static bool _has_mixer_spurs( - double lo1_freq, double lo2_freq, double if2_freq, - double bandwidth, int spur_order); - - //Inputs - experts::data_reader_t<double> _rf_freq_d; - experts::data_reader_t<double> _if_freq_d; - //Outputs - experts::data_writer_t<twinrx_ctrl::signal_path_t> _signal_path; + double lo1_freq, double if1_freq, double if2_freq, double bandwidth); + static bool _has_mixer_spurs(double lo1_freq, + double lo2_freq, + double if2_freq, + double bandwidth, + int spur_order); + + // Inputs + experts::data_reader_t<double> _rf_freq_d; + experts::data_reader_t<double> _if_freq_d; + // Outputs + experts::data_writer_t<twinrx_ctrl::signal_path_t> _signal_path; experts::data_writer_t<twinrx_ctrl::preselector_path_t> _lb_presel; experts::data_writer_t<twinrx_ctrl::preselector_path_t> _hb_presel; - experts::data_writer_t<bool> _lb_preamp_presel; - experts::data_writer_t<double> _lo1_freq_d; - experts::data_writer_t<double> _lo2_freq_d; - experts::data_writer_t<lo_inj_side_t> _lo1_inj_side; - experts::data_writer_t<lo_inj_side_t> _lo2_inj_side; + experts::data_writer_t<bool> _lb_preamp_presel; + experts::data_writer_t<double> _lo1_freq_d; + experts::data_writer_t<double> _lo2_freq_d; + experts::data_writer_t<lo_inj_side_t> _lo1_inj_side; + experts::data_writer_t<lo_inj_side_t> _lo2_inj_side; }; /*!--------------------------------------------------------- @@ -145,20 +160,21 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_lo_config_expert : public experts::worker_node_t { +class twinrx_lo_config_expert : public experts::worker_node_t +{ public: twinrx_lo_config_expert(const experts::node_retriever_t& db) - : experts::worker_node_t("twinrx_lo_config_expert"), - _lo_source_ch0 (db, prepend_ch("los/all/source", "0")), - _lo_source_ch1 (db, prepend_ch("los/all/source", "1")), - _lo_export_ch0 (db, prepend_ch("los/all/export", "0")), - _lo_export_ch1 (db, prepend_ch("los/all/export", "1")), - _lo1_src_ch0 (db, prepend_ch("ch/LO1/source", "0")), - _lo1_src_ch1 (db, prepend_ch("ch/LO1/source", "1")), - _lo2_src_ch0 (db, prepend_ch("ch/LO2/source", "0")), - _lo2_src_ch1 (db, prepend_ch("ch/LO2/source", "1")), - _lo1_export_src (db, "com/LO1/export_source"), - _lo2_export_src (db, "com/LO2/export_source") + : experts::worker_node_t("twinrx_lo_config_expert") + , _lo_source_ch0(db, prepend_ch("los/all/source", "0")) + , _lo_source_ch1(db, prepend_ch("los/all/source", "1")) + , _lo_export_ch0(db, prepend_ch("los/all/export", "0")) + , _lo_export_ch1(db, prepend_ch("los/all/export", "1")) + , _lo1_src_ch0(db, prepend_ch("ch/LO1/source", "0")) + , _lo1_src_ch1(db, prepend_ch("ch/LO1/source", "1")) + , _lo2_src_ch0(db, prepend_ch("ch/LO2/source", "0")) + , _lo2_src_ch1(db, prepend_ch("ch/LO2/source", "1")) + , _lo1_export_src(db, "com/LO1/export_source") + , _lo2_export_src(db, "com/LO2/export_source") { bind_accessor(_lo_source_ch0); bind_accessor(_lo_source_ch1); @@ -175,16 +191,16 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<std::string> _lo_source_ch0; - experts::data_reader_t<std::string> _lo_source_ch1; - experts::data_reader_t<bool> _lo_export_ch0; - experts::data_reader_t<bool> _lo_export_ch1; - //Outputs - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch0; - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch1; - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch0; - experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch1; + // Inputs + experts::data_reader_t<std::string> _lo_source_ch0; + experts::data_reader_t<std::string> _lo_source_ch1; + experts::data_reader_t<bool> _lo_export_ch0; + experts::data_reader_t<bool> _lo_export_ch1; + // Outputs + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch0; + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo1_src_ch1; + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch0; + experts::data_writer_t<twinrx_ctrl::lo_source_t> _lo2_src_ch1; experts::data_writer_t<twinrx_ctrl::lo_export_source_t> _lo1_export_src; experts::data_writer_t<twinrx_ctrl::lo_export_source_t> _lo2_export_src; }; @@ -201,15 +217,20 @@ private: * One instance of this expert is required for each LO stage * --------------------------------------------------------- */ -class twinrx_lo_mapping_expert : public experts::worker_node_t { +class twinrx_lo_mapping_expert : public experts::worker_node_t +{ public: twinrx_lo_mapping_expert(const experts::node_retriever_t& db, lo_stage_t stage) - : experts::worker_node_t("twinrx_" + lo_stage_str(stage, true) + "_mapping_expert"), - _lox_src_ch0 (db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "0")), - _lox_src_ch1 (db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "1")), - _lox_mapping_synth0 (db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "0")), - _lox_mapping_synth1 (db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "1")), - _lox_hopping_enabled (db, "com/synth/" + lo_stage_str(stage) + "/hopping_enabled") + : experts::worker_node_t( + "twinrx_" + lo_stage_str(stage, true) + "_mapping_expert") + , _lox_src_ch0(db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "0")) + , _lox_src_ch1(db, prepend_ch("ch/" + lo_stage_str(stage) + "/source", "1")) + , _lox_mapping_synth0( + db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "0")) + , _lox_mapping_synth1( + db, prepend_ch("synth/" + lo_stage_str(stage) + "/mapping", "1")) + , _lox_hopping_enabled( + db, "com/synth/" + lo_stage_str(stage) + "/hopping_enabled") { bind_accessor(_lox_src_ch0); bind_accessor(_lox_src_ch1); @@ -221,13 +242,13 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch0; - experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch1; - //Outputs - experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth0; - experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth1; - experts::data_writer_t<bool> _lox_hopping_enabled; + // Inputs + experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch0; + experts::data_reader_t<twinrx_ctrl::lo_source_t> _lox_src_ch1; + // Outputs + experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth0; + experts::data_writer_t<lo_synth_mapping_t> _lox_mapping_synth1; + experts::data_writer_t<bool> _lox_hopping_enabled; }; /*!--------------------------------------------------------- @@ -240,16 +261,17 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_freq_coercion_expert : public experts::worker_node_t { +class twinrx_freq_coercion_expert : public experts::worker_node_t +{ public: twinrx_freq_coercion_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_freq_coercion_expert", ch)), - _lo1_freq_c (db, prepend_ch("los/LO1/freq/coerced", ch)), - _lo2_freq_c (db, prepend_ch("los/LO2/freq/coerced", ch)), - _if_freq_d (db, prepend_ch("if_freq/desired", ch)), - _lo1_inj_side (db, prepend_ch("ch/LO1/inj_side", ch)), - _lo2_inj_side (db, prepend_ch("ch/LO2/inj_side", ch)), - _rf_freq_c (db, prepend_ch("freq/coerced", ch)) + : experts::worker_node_t(prepend_ch("twinrx_freq_coercion_expert", ch)) + , _lo1_freq_c(db, prepend_ch("los/LO1/freq/coerced", ch)) + , _lo2_freq_c(db, prepend_ch("los/LO2/freq/coerced", ch)) + , _if_freq_d(db, prepend_ch("if_freq/desired", ch)) + , _lo1_inj_side(db, prepend_ch("ch/LO1/inj_side", ch)) + , _lo2_inj_side(db, prepend_ch("ch/LO2/inj_side", ch)) + , _rf_freq_c(db, prepend_ch("freq/coerced", ch)) { bind_accessor(_lo1_freq_c); bind_accessor(_lo2_freq_c); @@ -262,14 +284,14 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<double> _lo1_freq_c; - experts::data_reader_t<double> _lo2_freq_c; - experts::data_reader_t<double> _if_freq_d; - experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; - experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; - //Outputs - experts::data_writer_t<double> _rf_freq_c; + // Inputs + experts::data_reader_t<double> _lo1_freq_c; + experts::data_reader_t<double> _lo2_freq_c; + experts::data_reader_t<double> _if_freq_d; + experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; + experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; + // Outputs + experts::data_writer_t<double> _rf_freq_c; }; /*!--------------------------------------------------------- @@ -281,21 +303,23 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_nyquist_expert : public experts::worker_node_t { +class twinrx_nyquist_expert : public experts::worker_node_t +{ public: - twinrx_nyquist_expert(const experts::node_retriever_t& db, std::string ch, - dboard_iface::sptr db_iface) - : experts::worker_node_t(prepend_ch("twinrx_nyquist_expert", ch)), - _channel (ch), - _codec_conn (ch=="0"?"II":"QQ"), //Ch->ADC Port mapping - _lo1_freq_d (db, prepend_ch("los/LO1/freq/desired", ch)), - _lo2_freq_d (db, prepend_ch("los/LO2/freq/desired", ch)), - _if_freq_d (db, prepend_ch("if_freq/desired", ch)), - _lo1_inj_side (db, prepend_ch("ch/LO1/inj_side", ch)), - _lo2_inj_side (db, prepend_ch("ch/LO2/inj_side", ch)), - _rx_frontend_time (db, prepend_ch("time/rx_frontend", ch)), - _if_freq_c (db, prepend_ch("if_freq/coerced", ch)), - _db_iface (db_iface) + twinrx_nyquist_expert( + const experts::node_retriever_t& db, std::string ch, dboard_iface::sptr db_iface) + : experts::worker_node_t(prepend_ch("twinrx_nyquist_expert", ch)) + , _channel(ch) + , _codec_conn(ch == "0" ? "II" : "QQ") + , // Ch->ADC Port mapping + _lo1_freq_d(db, prepend_ch("los/LO1/freq/desired", ch)) + , _lo2_freq_d(db, prepend_ch("los/LO2/freq/desired", ch)) + , _if_freq_d(db, prepend_ch("if_freq/desired", ch)) + , _lo1_inj_side(db, prepend_ch("ch/LO1/inj_side", ch)) + , _lo2_inj_side(db, prepend_ch("ch/LO2/inj_side", ch)) + , _rx_frontend_time(db, prepend_ch("time/rx_frontend", ch)) + , _if_freq_c(db, prepend_ch("if_freq/coerced", ch)) + , _db_iface(db_iface) { bind_accessor(_lo1_freq_d); bind_accessor(_lo2_freq_d); @@ -309,22 +333,22 @@ public: private: virtual void resolve(); - //Inputs - const std::string _channel; - const std::string _codec_conn; - experts::data_reader_t<double> _lo1_freq_d; - experts::data_reader_t<double> _lo2_freq_d; - experts::data_reader_t<double> _if_freq_d; - experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; - experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; - experts::data_reader_t<time_spec_t> _rx_frontend_time; - - //Outputs - experts::data_writer_t<double> _if_freq_c; - dboard_iface::sptr _db_iface; - - //Misc - time_spec_t _cached_cmd_time; + // Inputs + const std::string _channel; + const std::string _codec_conn; + experts::data_reader_t<double> _lo1_freq_d; + experts::data_reader_t<double> _lo2_freq_d; + experts::data_reader_t<double> _if_freq_d; + experts::data_reader_t<lo_inj_side_t> _lo1_inj_side; + experts::data_reader_t<lo_inj_side_t> _lo2_inj_side; + experts::data_reader_t<time_spec_t> _rx_frontend_time; + + // Outputs + experts::data_writer_t<double> _if_freq_c; + dboard_iface::sptr _db_iface; + + // Misc + time_spec_t _cached_cmd_time; }; /*!--------------------------------------------------------- @@ -337,18 +361,19 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_antenna_expert : public experts::worker_node_t { +class twinrx_antenna_expert : public experts::worker_node_t +{ public: twinrx_antenna_expert(const experts::node_retriever_t& db) - : experts::worker_node_t("twinrx_antenna_expert"), - _antenna_ch0 (db, prepend_ch("antenna", "0")), - _antenna_ch1 (db, prepend_ch("antenna", "1")), - _enabled_ch0 (db, prepend_ch("enabled", "0")), - _enabled_ch1 (db, prepend_ch("enabled", "1")), - _lo_export_ch0 (db, prepend_ch("los/all/export", "0")), - _lo_export_ch1 (db, prepend_ch("los/all/export", "1")), - _ant_mapping (db, "com/ant_mapping"), - _cal_mode (db, "com/cal_mode") + : experts::worker_node_t("twinrx_antenna_expert") + , _antenna_ch0(db, prepend_ch("antenna", "0")) + , _antenna_ch1(db, prepend_ch("antenna", "1")) + , _enabled_ch0(db, prepend_ch("enabled", "0")) + , _enabled_ch1(db, prepend_ch("enabled", "1")) + , _lo_export_ch0(db, prepend_ch("los/all/export", "0")) + , _lo_export_ch1(db, prepend_ch("los/all/export", "1")) + , _ant_mapping(db, "com/ant_mapping") + , _cal_mode(db, "com/cal_mode") { bind_accessor(_antenna_ch0); bind_accessor(_antenna_ch1); @@ -363,16 +388,16 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<std::string> _antenna_ch0; - experts::data_reader_t<std::string> _antenna_ch1; - experts::data_reader_t<bool> _enabled_ch0; - experts::data_reader_t<bool> _enabled_ch1; - experts::data_reader_t<bool> _lo_export_ch0; - experts::data_reader_t<bool> _lo_export_ch1; - //Outputs - experts::data_writer_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - experts::data_writer_t<twinrx_ctrl::cal_mode_t> _cal_mode; + // Inputs + experts::data_reader_t<std::string> _antenna_ch0; + experts::data_reader_t<std::string> _antenna_ch1; + experts::data_reader_t<bool> _enabled_ch0; + experts::data_reader_t<bool> _enabled_ch1; + experts::data_reader_t<bool> _lo_export_ch0; + experts::data_reader_t<bool> _lo_export_ch1; + // Outputs + experts::data_writer_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + experts::data_writer_t<twinrx_ctrl::cal_mode_t> _cal_mode; }; /*!--------------------------------------------------------- @@ -386,21 +411,22 @@ private: * One instance of this expert is required for each channel * --------------------------------------------------------- */ -class twinrx_chan_gain_expert : public experts::worker_node_t { +class twinrx_chan_gain_expert : public experts::worker_node_t +{ public: twinrx_chan_gain_expert(const experts::node_retriever_t& db, std::string ch) - : experts::worker_node_t(prepend_ch("twinrx_chan_gain_expert", ch)), - _gain (db, prepend_ch("gain", ch)), - _gain_profile (db, prepend_ch("gain_profile", ch)), - _signal_path (db, prepend_ch("ch/signal_path", ch)), - _lb_presel (db, prepend_ch("ch/lb_presel", ch)), - _hb_presel (db, prepend_ch("ch/hb_presel", ch)), - _ant_mapping (db, "com/ant_mapping"), - _input_atten (db, prepend_ch("ch/input_atten", ch)), - _lb_atten (db, prepend_ch("ch/lb_atten", ch)), - _hb_atten (db, prepend_ch("ch/hb_atten", ch)), - _preamp1 (db, prepend_ch("ch/preamp1", ch)), - _preamp2 (db, prepend_ch("ch/preamp2", ch)) + : experts::worker_node_t(prepend_ch("twinrx_chan_gain_expert", ch)) + , _gain(db, prepend_ch("gain", ch)) + , _gain_profile(db, prepend_ch("gain_profile", ch)) + , _signal_path(db, prepend_ch("ch/signal_path", ch)) + , _lb_presel(db, prepend_ch("ch/lb_presel", ch)) + , _hb_presel(db, prepend_ch("ch/hb_presel", ch)) + , _ant_mapping(db, "com/ant_mapping") + , _input_atten(db, prepend_ch("ch/input_atten", ch)) + , _lb_atten(db, prepend_ch("ch/lb_atten", ch)) + , _hb_atten(db, prepend_ch("ch/hb_atten", ch)) + , _preamp1(db, prepend_ch("ch/preamp1", ch)) + , _preamp2(db, prepend_ch("ch/preamp2", ch)) { bind_accessor(_gain); bind_accessor(_gain_profile); @@ -418,19 +444,19 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<double> _gain; - experts::data_reader_t<std::string> _gain_profile; - experts::data_reader_t<twinrx_ctrl::signal_path_t> _signal_path; + // Inputs + experts::data_reader_t<double> _gain; + experts::data_reader_t<std::string> _gain_profile; + experts::data_reader_t<twinrx_ctrl::signal_path_t> _signal_path; experts::data_reader_t<twinrx_ctrl::preselector_path_t> _lb_presel; experts::data_reader_t<twinrx_ctrl::preselector_path_t> _hb_presel; - experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - //Outputs - experts::data_writer_t<uint8_t> _input_atten; - experts::data_writer_t<uint8_t> _lb_atten; - experts::data_writer_t<uint8_t> _hb_atten; - experts::data_writer_t<twinrx_ctrl::preamp_state_t> _preamp1; - experts::data_writer_t<bool> _preamp2; + experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + // Outputs + experts::data_writer_t<uint8_t> _input_atten; + experts::data_writer_t<uint8_t> _lb_atten; + experts::data_writer_t<uint8_t> _hb_atten; + experts::data_writer_t<twinrx_ctrl::preamp_state_t> _preamp1; + experts::data_writer_t<bool> _preamp2; }; /*!--------------------------------------------------------- @@ -443,27 +469,28 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_ant_gain_expert : public experts::worker_node_t { +class twinrx_ant_gain_expert : public experts::worker_node_t +{ public: twinrx_ant_gain_expert(const experts::node_retriever_t& db) - : experts::worker_node_t("twinrx_ant_gain_expert"), - _ant_mapping (db, "com/ant_mapping"), - _ch0_input_atten (db, prepend_ch("ch/input_atten", "0")), - _ch0_preamp1 (db, prepend_ch("ch/preamp1", "0")), - _ch0_preamp2 (db, prepend_ch("ch/preamp2", "0")), - _ch0_lb_preamp_presel (db, prepend_ch("ch/lb_preamp_presel", "0")), - _ch1_input_atten (db, prepend_ch("ch/input_atten", "1")), - _ch1_preamp1 (db, prepend_ch("ch/preamp1", "1")), - _ch1_preamp2 (db, prepend_ch("ch/preamp2", "1")), - _ch1_lb_preamp_presel (db, prepend_ch("ch/lb_preamp_presel", "1")), - _ant0_input_atten (db, prepend_ch("ant/input_atten", "0")), - _ant0_preamp1 (db, prepend_ch("ant/preamp1", "0")), - _ant0_preamp2 (db, prepend_ch("ant/preamp2", "0")), - _ant0_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "0")), - _ant1_input_atten (db, prepend_ch("ant/input_atten", "1")), - _ant1_preamp1 (db, prepend_ch("ant/preamp1", "1")), - _ant1_preamp2 (db, prepend_ch("ant/preamp2", "1")), - _ant1_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "1")) + : experts::worker_node_t("twinrx_ant_gain_expert") + , _ant_mapping(db, "com/ant_mapping") + , _ch0_input_atten(db, prepend_ch("ch/input_atten", "0")) + , _ch0_preamp1(db, prepend_ch("ch/preamp1", "0")) + , _ch0_preamp2(db, prepend_ch("ch/preamp2", "0")) + , _ch0_lb_preamp_presel(db, prepend_ch("ch/lb_preamp_presel", "0")) + , _ch1_input_atten(db, prepend_ch("ch/input_atten", "1")) + , _ch1_preamp1(db, prepend_ch("ch/preamp1", "1")) + , _ch1_preamp2(db, prepend_ch("ch/preamp2", "1")) + , _ch1_lb_preamp_presel(db, prepend_ch("ch/lb_preamp_presel", "1")) + , _ant0_input_atten(db, prepend_ch("ant/input_atten", "0")) + , _ant0_preamp1(db, prepend_ch("ant/preamp1", "0")) + , _ant0_preamp2(db, prepend_ch("ant/preamp2", "0")) + , _ant0_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "0")) + , _ant1_input_atten(db, prepend_ch("ant/input_atten", "1")) + , _ant1_preamp1(db, prepend_ch("ant/preamp1", "1")) + , _ant1_preamp2(db, prepend_ch("ant/preamp2", "1")) + , _ant1_lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", "1")) { bind_accessor(_ant_mapping); bind_accessor(_ch0_input_atten); @@ -487,26 +514,26 @@ public: private: virtual void resolve(); - //Inputs - experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - experts::data_reader_t<uint8_t> _ch0_input_atten; - experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch0_preamp1; - experts::data_reader_t<bool> _ch0_preamp2; - experts::data_reader_t<bool> _ch0_lb_preamp_presel; - experts::data_reader_t<uint8_t> _ch1_input_atten; - experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch1_preamp1; - experts::data_reader_t<bool> _ch1_preamp2; - experts::data_reader_t<bool> _ch1_lb_preamp_presel; - - //Outputs - experts::data_writer_t<uint8_t> _ant0_input_atten; - experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant0_preamp1; - experts::data_writer_t<bool> _ant0_preamp2; - experts::data_writer_t<bool> _ant0_lb_preamp_presel; - experts::data_writer_t<uint8_t> _ant1_input_atten; - experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant1_preamp1; - experts::data_writer_t<bool> _ant1_preamp2; - experts::data_writer_t<bool> _ant1_lb_preamp_presel; + // Inputs + experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + experts::data_reader_t<uint8_t> _ch0_input_atten; + experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch0_preamp1; + experts::data_reader_t<bool> _ch0_preamp2; + experts::data_reader_t<bool> _ch0_lb_preamp_presel; + experts::data_reader_t<uint8_t> _ch1_input_atten; + experts::data_reader_t<twinrx_ctrl::preamp_state_t> _ch1_preamp1; + experts::data_reader_t<bool> _ch1_preamp2; + experts::data_reader_t<bool> _ch1_lb_preamp_presel; + + // Outputs + experts::data_writer_t<uint8_t> _ant0_input_atten; + experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant0_preamp1; + experts::data_writer_t<bool> _ant0_preamp2; + experts::data_writer_t<bool> _ant0_lb_preamp_presel; + experts::data_writer_t<uint8_t> _ant1_input_atten; + experts::data_writer_t<twinrx_ctrl::preamp_state_t> _ant1_preamp1; + experts::data_writer_t<bool> _ant1_preamp2; + experts::data_writer_t<bool> _ant1_lb_preamp_presel; }; /*!--------------------------------------------------------- @@ -521,25 +548,27 @@ private: * One instance of this expert is required for all channels * --------------------------------------------------------- */ -class twinrx_settings_expert : public experts::worker_node_t { +class twinrx_settings_expert : public experts::worker_node_t +{ public: twinrx_settings_expert(const experts::node_retriever_t& db, twinrx_ctrl::sptr ctrl) - : experts::worker_node_t("twinrx_settings_expert"), _ctrl(ctrl), - _ch0 (db, "0"), - _ch1 (db, "1"), - _lo1_synth0_mapping(db, "0/synth/LO1/mapping"), - _lo1_synth1_mapping(db, "1/synth/LO1/mapping"), - _lo2_synth0_mapping(db, "0/synth/LO2/mapping"), - _lo2_synth1_mapping(db, "1/synth/LO2/mapping"), - _lo1_hopping_enabled(db, "com/synth/LO1/hopping_enabled"), - _lo2_hopping_enabled(db, "com/synth/LO2/hopping_enabled"), - _lo1_export_src (db, "com/LO1/export_source"), - _lo2_export_src (db, "com/LO2/export_source"), - _ant_mapping (db, "com/ant_mapping"), - _cal_mode (db, "com/cal_mode") + : experts::worker_node_t("twinrx_settings_expert") + , _ctrl(ctrl) + , _ch0(db, "0") + , _ch1(db, "1") + , _lo1_synth0_mapping(db, "0/synth/LO1/mapping") + , _lo1_synth1_mapping(db, "1/synth/LO1/mapping") + , _lo2_synth0_mapping(db, "0/synth/LO2/mapping") + , _lo2_synth1_mapping(db, "1/synth/LO2/mapping") + , _lo1_hopping_enabled(db, "com/synth/LO1/hopping_enabled") + , _lo2_hopping_enabled(db, "com/synth/LO2/hopping_enabled") + , _lo1_export_src(db, "com/LO1/export_source") + , _lo2_export_src(db, "com/LO2/export_source") + , _ant_mapping(db, "com/ant_mapping") + , _cal_mode(db, "com/cal_mode") { for (size_t i = 0; i < 2; i++) { - ch_settings& ch = (i==1) ? _ch1 : _ch0; + ch_settings& ch = (i == 1) ? _ch1 : _ch0; bind_accessor(ch.chan_enabled); bind_accessor(ch.preamp1); bind_accessor(ch.preamp2); @@ -575,103 +604,105 @@ public: private: virtual void resolve(); - void _resolve_lox_freq( - lo_stage_t lo_stage, + void _resolve_lox_freq(lo_stage_t lo_stage, experts::data_reader_t<double>& ch0_freq_d, experts::data_reader_t<double>& ch1_freq_d, experts::data_writer_t<double>& ch0_freq_c, experts::data_writer_t<double>& ch1_freq_c, - twinrx_ctrl::lo_source_t ch0_lo_source, - twinrx_ctrl::lo_source_t ch1_lo_source, - lo_synth_mapping_t synth0_mapping, - lo_synth_mapping_t synth1_mapping, - bool hopping_enabled); + twinrx_ctrl::lo_source_t ch0_lo_source, + twinrx_ctrl::lo_source_t ch1_lo_source, + lo_synth_mapping_t synth0_mapping, + lo_synth_mapping_t synth1_mapping, + bool hopping_enabled); double _set_lox_synth_freq(lo_stage_t stage, twinrx_ctrl::channel_t ch, double freq); - class ch_settings { + class ch_settings + { public: - ch_settings(const experts::node_retriever_t& db, const std::string& ch) : - chan_enabled (db, prepend_ch("enabled", ch)), - preamp1 (db, prepend_ch("ant/preamp1", ch)), - preamp2 (db, prepend_ch("ant/preamp2", ch)), - lb_preamp_presel (db, prepend_ch("ant/lb_preamp_presel", ch)), - signal_path (db, prepend_ch("ch/signal_path", ch)), - lb_presel (db, prepend_ch("ch/lb_presel", ch)), - hb_presel (db, prepend_ch("ch/hb_presel", ch)), - input_atten (db, prepend_ch("ant/input_atten", ch)), - lb_atten (db, prepend_ch("ch/lb_atten", ch)), - hb_atten (db, prepend_ch("ch/hb_atten", ch)), - lo1_source (db, prepend_ch("ch/LO1/source", ch)), - lo2_source (db, prepend_ch("ch/LO2/source", ch)), - lo1_freq_d (db, prepend_ch("los/LO1/freq/desired", ch)), - lo2_freq_d (db, prepend_ch("los/LO2/freq/desired", ch)), - lo1_charge_pump_d (db, prepend_ch("los/LO1/charge_pump/desired", ch)), - lo2_charge_pump_d (db, prepend_ch("los/LO2/charge_pump/desired", ch)), - lo1_freq_c (db, prepend_ch("los/LO1/freq/coerced", ch)), - lo2_freq_c (db, prepend_ch("los/LO2/freq/coerced", ch)), - lo1_charge_pump_c (db, prepend_ch("los/LO1/charge_pump/coerced", ch)), - lo2_charge_pump_c (db, prepend_ch("los/LO2/charge_pump/coerced", ch)) - {} - - //Inputs (channel specific) - experts::data_reader_t<bool> chan_enabled; - experts::data_reader_t<twinrx_ctrl::preamp_state_t> preamp1; - experts::data_reader_t<bool> preamp2; - experts::data_reader_t<bool> lb_preamp_presel; - experts::data_reader_t<twinrx_ctrl::signal_path_t> signal_path; + ch_settings(const experts::node_retriever_t& db, const std::string& ch) + : chan_enabled(db, prepend_ch("enabled", ch)) + , preamp1(db, prepend_ch("ant/preamp1", ch)) + , preamp2(db, prepend_ch("ant/preamp2", ch)) + , lb_preamp_presel(db, prepend_ch("ant/lb_preamp_presel", ch)) + , signal_path(db, prepend_ch("ch/signal_path", ch)) + , lb_presel(db, prepend_ch("ch/lb_presel", ch)) + , hb_presel(db, prepend_ch("ch/hb_presel", ch)) + , input_atten(db, prepend_ch("ant/input_atten", ch)) + , lb_atten(db, prepend_ch("ch/lb_atten", ch)) + , hb_atten(db, prepend_ch("ch/hb_atten", ch)) + , lo1_source(db, prepend_ch("ch/LO1/source", ch)) + , lo2_source(db, prepend_ch("ch/LO2/source", ch)) + , lo1_freq_d(db, prepend_ch("los/LO1/freq/desired", ch)) + , lo2_freq_d(db, prepend_ch("los/LO2/freq/desired", ch)) + , lo1_charge_pump_d(db, prepend_ch("los/LO1/charge_pump/desired", ch)) + , lo2_charge_pump_d(db, prepend_ch("los/LO2/charge_pump/desired", ch)) + , lo1_freq_c(db, prepend_ch("los/LO1/freq/coerced", ch)) + , lo2_freq_c(db, prepend_ch("los/LO2/freq/coerced", ch)) + , lo1_charge_pump_c(db, prepend_ch("los/LO1/charge_pump/coerced", ch)) + , lo2_charge_pump_c(db, prepend_ch("los/LO2/charge_pump/coerced", ch)) + { + } + + // Inputs (channel specific) + experts::data_reader_t<bool> chan_enabled; + experts::data_reader_t<twinrx_ctrl::preamp_state_t> preamp1; + experts::data_reader_t<bool> preamp2; + experts::data_reader_t<bool> lb_preamp_presel; + experts::data_reader_t<twinrx_ctrl::signal_path_t> signal_path; experts::data_reader_t<twinrx_ctrl::preselector_path_t> lb_presel; experts::data_reader_t<twinrx_ctrl::preselector_path_t> hb_presel; - experts::data_reader_t<uint8_t> input_atten; - experts::data_reader_t<uint8_t> lb_atten; - experts::data_reader_t<uint8_t> hb_atten; - experts::data_reader_t<twinrx_ctrl::lo_source_t> lo1_source; - experts::data_reader_t<twinrx_ctrl::lo_source_t> lo2_source; - experts::data_reader_t<double> lo1_freq_d; - experts::data_reader_t<double> lo2_freq_d; - experts::data_reader_t<double> lo1_charge_pump_d; - experts::data_reader_t<double> lo2_charge_pump_d; - - //Output (channel specific) - experts::data_writer_t<double> lo1_freq_c; - experts::data_writer_t<double> lo2_freq_c; - experts::data_writer_t<double> lo1_charge_pump_c; - experts::data_writer_t<double> lo2_charge_pump_c; + experts::data_reader_t<uint8_t> input_atten; + experts::data_reader_t<uint8_t> lb_atten; + experts::data_reader_t<uint8_t> hb_atten; + experts::data_reader_t<twinrx_ctrl::lo_source_t> lo1_source; + experts::data_reader_t<twinrx_ctrl::lo_source_t> lo2_source; + experts::data_reader_t<double> lo1_freq_d; + experts::data_reader_t<double> lo2_freq_d; + experts::data_reader_t<double> lo1_charge_pump_d; + experts::data_reader_t<double> lo2_charge_pump_d; + + // Output (channel specific) + experts::data_writer_t<double> lo1_freq_c; + experts::data_writer_t<double> lo2_freq_c; + experts::data_writer_t<double> lo1_charge_pump_c; + experts::data_writer_t<double> lo2_charge_pump_c; }; - //External interface - twinrx_ctrl::sptr _ctrl; - - //Inputs (channel agnostic) - ch_settings _ch0; - ch_settings _ch1; - experts::data_reader_t<lo_synth_mapping_t> _lo1_synth0_mapping; - experts::data_reader_t<lo_synth_mapping_t> _lo1_synth1_mapping; - experts::data_reader_t<lo_synth_mapping_t> _lo2_synth0_mapping; - experts::data_reader_t<lo_synth_mapping_t> _lo2_synth1_mapping; - experts::data_reader_t<bool> _lo1_hopping_enabled; - experts::data_reader_t<bool> _lo2_hopping_enabled; + // External interface + twinrx_ctrl::sptr _ctrl; + + // Inputs (channel agnostic) + ch_settings _ch0; + ch_settings _ch1; + experts::data_reader_t<lo_synth_mapping_t> _lo1_synth0_mapping; + experts::data_reader_t<lo_synth_mapping_t> _lo1_synth1_mapping; + experts::data_reader_t<lo_synth_mapping_t> _lo2_synth0_mapping; + experts::data_reader_t<lo_synth_mapping_t> _lo2_synth1_mapping; + experts::data_reader_t<bool> _lo1_hopping_enabled; + experts::data_reader_t<bool> _lo2_hopping_enabled; experts::data_reader_t<twinrx_ctrl::lo_export_source_t> _lo1_export_src; experts::data_reader_t<twinrx_ctrl::lo_export_source_t> _lo2_export_src; - experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; - experts::data_reader_t<twinrx_ctrl::cal_mode_t> _cal_mode; + experts::data_reader_t<twinrx_ctrl::antenna_mapping_t> _ant_mapping; + experts::data_reader_t<twinrx_ctrl::cal_mode_t> _cal_mode; - //Outputs (channel agnostic) - //None + // Outputs (channel agnostic) + // None - //Misc - struct lo_freq_cache_t { + // Misc + struct lo_freq_cache_t + { rf_freq_ppm_t desired; - double coerced; + double coerced; }; - lo_freq_cache_t _cached_lo1_synth0_freq; - lo_freq_cache_t _cached_lo2_synth0_freq; - lo_freq_cache_t _cached_lo1_synth1_freq; - lo_freq_cache_t _cached_lo2_synth1_freq; + lo_freq_cache_t _cached_lo1_synth0_freq; + lo_freq_cache_t _cached_lo2_synth0_freq; + lo_freq_cache_t _cached_lo1_synth1_freq; + lo_freq_cache_t _cached_lo2_synth1_freq; static const bool FORCE_COMMIT; }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_EXPERTS_HPP */ diff --git a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp index cc9336f2a..729141b35 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.cpp @@ -796,13 +796,11 @@ static const std::vector<twinrx_gain_config_t> LOWBAND4_TABLE{ }; // clang-format on -const twinrx_gain_table twinrx_gain_table::lookup_table -( +const twinrx_gain_table twinrx_gain_table::lookup_table( twinrx_ctrl::signal_path_t signal_path, twinrx_ctrl::preselector_path_t preselector_path, - std::string -) { - + std::string) +{ if (signal_path == twinrx_ctrl::PATH_HIGHBAND) { switch (preselector_path) { case twinrx_ctrl::PRESEL_PATH1: @@ -829,12 +827,15 @@ const twinrx_gain_table twinrx_gain_table::lookup_table throw runtime_error("NO GAIN TABLE SELECTED"); } -const twinrx_gain_config_t& twinrx_gain_table::find_by_index(size_t index) const { - if (index >= get_num_entries()) throw uhd::value_error("invalid gain table index"); +const twinrx_gain_config_t& twinrx_gain_table::find_by_index(size_t index) const +{ + if (index >= get_num_entries()) + throw uhd::value_error("invalid gain table index"); return _tbl.at(index); } -uhd::gain_range_t twinrx_gain_table::get_gain_range() const { +uhd::gain_range_t twinrx_gain_table::get_gain_range() const +{ double max = std::numeric_limits<double>::min(); double min = std::numeric_limits<double>::max(); for (size_t i = 0; i < get_num_entries(); i++) { diff --git a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp index 94469ab0b..f02241745 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_gain_tables.hpp @@ -8,56 +8,65 @@ #ifndef INCLUDED_DBOARD_TWINRX_GAIN_TABLES_HPP #define INCLUDED_DBOARD_TWINRX_GAIN_TABLES_HPP +#include "twinrx_ctrl.hpp" #include <uhd/config.hpp> -#include <stdint.h> #include <uhd/types/ranges.hpp> -#include "twinrx_ctrl.hpp" +#include <stdint.h> namespace uhd { namespace usrp { namespace dboard { namespace twinrx { -class twinrx_gain_config_t { +class twinrx_gain_config_t +{ public: - twinrx_gain_config_t( - size_t index_, double sys_gain_, - uint8_t atten1_, uint8_t atten2_, - bool amp1_, bool amp2_ - ): index(index_), sys_gain(sys_gain_), atten1(atten1_), atten2(atten2_), - amp1(amp1_), amp2(amp2_) - {} + twinrx_gain_config_t(size_t index_, + double sys_gain_, + uint8_t atten1_, + uint8_t atten2_, + bool amp1_, + bool amp2_) + : index(index_) + , sys_gain(sys_gain_) + , atten1(atten1_) + , atten2(atten2_) + , amp1(amp1_) + , amp2(amp2_) + { + } - twinrx_gain_config_t& operator=(const twinrx_gain_config_t& src) { + twinrx_gain_config_t& operator=(const twinrx_gain_config_t& src) + { if (this != &src) { - this->index = src.index; + this->index = src.index; this->sys_gain = src.sys_gain; - this->atten1 = src.atten1; - this->atten2 = src.atten2; - this->amp1 = src.amp1; - this->amp2 = src.amp2; + this->atten1 = src.atten1; + this->atten2 = src.atten2; + this->amp1 = src.amp1; + this->amp2 = src.amp2; } return *this; } - size_t index; - double sys_gain; + size_t index; + double sys_gain; uint8_t atten1; uint8_t atten2; - bool amp1; - bool amp2; + bool amp1; + bool amp2; }; -class twinrx_gain_table { +class twinrx_gain_table +{ public: - static const twinrx_gain_table lookup_table( - twinrx_ctrl::signal_path_t signal_path, + static const twinrx_gain_table lookup_table(twinrx_ctrl::signal_path_t signal_path, twinrx_ctrl::preselector_path_t presel_path, std::string profile); - twinrx_gain_table(const std::vector<twinrx_gain_config_t>& tbl) - : _tbl(tbl) {} + twinrx_gain_table(const std::vector<twinrx_gain_config_t>& tbl) : _tbl(tbl) {} const twinrx_gain_config_t& find_by_index(size_t index) const; - inline size_t get_num_entries() const { + inline size_t get_num_entries() const + { return _tbl.size(); } @@ -68,6 +77,6 @@ private: }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_GAIN_TABLES_HPP */ diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp b/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp index 599b1d456..118090701 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ids.hpp @@ -8,9 +8,9 @@ using namespace uhd; using namespace usrp; namespace twinrx { - const dboard_id_t TWINRX_REV_A_ID(0x91); - const dboard_id_t TWINRX_REV_B_ID(0x93); - const dboard_id_t TWINRX_REV_C_ID(0x95); -} +const dboard_id_t TWINRX_REV_A_ID(0x91); +const dboard_id_t TWINRX_REV_B_ID(0x93); +const dboard_id_t TWINRX_REV_C_ID(0x95); +} // namespace twinrx #endif diff --git a/host/lib/usrp/dboard/twinrx/twinrx_io.hpp b/host/lib/usrp/dboard/twinrx/twinrx_io.hpp index e3e475148..2949138dd 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_io.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_io.hpp @@ -19,24 +19,35 @@ namespace uhd { namespace usrp { namespace dboard { namespace twinrx { static const uint32_t SET_ALL_BITS = 0xFFFFFFFF; namespace cpld { -static wb_iface::wb_addr_type addr(uint8_t cpld_num, uint8_t cpld_addr) { - //Decode CPLD addressing for the following bitmap: +static wb_iface::wb_addr_type addr(uint8_t cpld_num, uint8_t cpld_addr) +{ + // Decode CPLD addressing for the following bitmap: // {CPLD1_EN, CPLD2_EN, CPLD3_EN, CPLD4_EN, CPLD_ADDR[2:0]} uint8_t addr = 0; switch (cpld_num) { - case 1: addr = 0x8 << 3; break; - case 2: addr = 0x4 << 3; break; - case 3: addr = 0x2 << 3; break; - case 4: addr = 0x1 << 3; break; - default: UHD_THROW_INVALID_CODE_PATH(); + case 1: + addr = 0x8 << 3; + break; + case 2: + addr = 0x4 << 3; + break; + case 3: + addr = 0x2 << 3; + break; + case 4: + addr = 0x1 << 3; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } return static_cast<wb_iface::wb_addr_type>(addr | (cpld_addr & 0x7)); } -static uint32_t get_reg(wb_iface::wb_addr_type addr) { +static uint32_t get_reg(wb_iface::wb_addr_type addr) +{ return static_cast<uint32_t>(addr) & 0x7; } -} +} // namespace cpld class twinrx_gpio : public wb_iface { @@ -44,163 +55,196 @@ public: typedef std::shared_ptr<twinrx_gpio> sptr; //---------------------------------------------- - //Public GPIO fields - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH1, /*width*/ 1, /*shift*/ 0); //GPIO[0] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH2, /*width*/ 1, /*shift*/ 1); //GPIO[1] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_MUXOUT_CH1, /*width*/ 1, /*shift*/ 2); //GPIO[2] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_MUXOUT_CH2, /*width*/ 1, /*shift*/ 3); //GPIO[3] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH1, /*width*/ 1, /*shift*/ 4); //GPIO[4] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH2, /*width*/ 1, /*shift*/ 5); //GPIO[5] IN - // NO CONNECT //GPIO[8:6] - // PRIVATE //GPIO[15:9] - // NO CONNECT //GPIO[16] - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_CE_CH1, /*width*/ 1, /*shift*/ 17); //GPIO[17] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_CE_CH2, /*width*/ 1, /*shift*/ 18); //GPIO[18] OUT - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_MUXOUT_CH1, /*width*/ 1, /*shift*/ 19); //GPIO[19] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO1_MUXOUT_CH2, /*width*/ 1, /*shift*/ 20); //GPIO[20] IN - // NO CONNECT //GPIO[21:23] - UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_CLK, /*width*/ 1, /*shift*/ 24); //GPIO[24] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_PWR_GOOD, /*width*/ 1, /*shift*/ 25); //GPIO[25] IN - UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_EN, /*width*/ 1, /*shift*/ 26); //GPIO[26] OUT - // PRIVATE //GPIO[27:31] + // Public GPIO fields + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH1, /*width*/ 1, /*shift*/ 0); // GPIO[0] OUT + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_CE_CH2, /*width*/ 1, /*shift*/ 1); // GPIO[1] OUT + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO2_MUXOUT_CH1, /*width*/ 1, /*shift*/ 2); // GPIO[2] IN + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO2_MUXOUT_CH2, /*width*/ 1, /*shift*/ 3); // GPIO[3] IN + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH1, /*width*/ 1, /*shift*/ 4); // GPIO[4] IN + UHD_DEFINE_SOFT_REG_FIELD(FIELD_LO2_LD_CH2, /*width*/ 1, /*shift*/ 5); // GPIO[5] IN + // NO CONNECT //GPIO[8:6] PRIVATE //GPIO[15:9] NO CONNECT //GPIO[16] + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_CE_CH1, /*width*/ 1, /*shift*/ 17); // GPIO[17] OUT + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_CE_CH2, /*width*/ 1, /*shift*/ 18); // GPIO[18] OUT + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_MUXOUT_CH1, /*width*/ 1, /*shift*/ 19); // GPIO[19] IN + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_LO1_MUXOUT_CH2, /*width*/ 1, /*shift*/ 20); // GPIO[20] IN + // NO CONNECT //GPIO[21:23] + UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_CLK, /*width*/ 1, /*shift*/ 24); // GPIO[24] IN + UHD_DEFINE_SOFT_REG_FIELD( + FIELD_SWPS_PWR_GOOD, /*width*/ 1, /*shift*/ 25); // GPIO[25] IN + UHD_DEFINE_SOFT_REG_FIELD(FIELD_SWPS_EN, /*width*/ 1, /*shift*/ 26); // GPIO[26] OUT + // PRIVATE //GPIO[27:31] //---------------------------------------------- - twinrx_gpio(dboard_iface::sptr iface) : _db_iface(iface) { + twinrx_gpio(dboard_iface::sptr iface) : _db_iface(iface) + { _db_iface->set_gpio_ddr(dboard_iface::UNIT_BOTH, GPIO_OUTPUT_MASK, SET_ALL_BITS); _db_iface->set_pin_ctrl(dboard_iface::UNIT_BOTH, GPIO_PINCTRL_MASK, SET_ALL_BITS); _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, 0, ~GPIO_PINCTRL_MASK); } - ~twinrx_gpio() { + ~twinrx_gpio() + { _db_iface->set_gpio_ddr(dboard_iface::UNIT_BOTH, ~GPIO_OUTPUT_MASK, SET_ALL_BITS); } - void set_field(const uhd::soft_reg_field_t field, const uint32_t value) { + void set_field(const uhd::soft_reg_field_t field, const uint32_t value) + { boost::lock_guard<boost::mutex> lock(_mutex); using namespace soft_reg_field; - _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, - (value << shift(field)), - mask<uint32_t>(field)); + _db_iface->set_gpio_out( + dboard_iface::UNIT_BOTH, (value << shift(field)), mask<uint32_t>(field)); } - uint32_t get_field(const uhd::soft_reg_field_t field) { + uint32_t get_field(const uhd::soft_reg_field_t field) + { boost::lock_guard<boost::mutex> lock(_mutex); using namespace soft_reg_field; - return (_db_iface->read_gpio(dboard_iface::UNIT_BOTH) & mask<uint32_t>(field)) >> shift(field); + return (_db_iface->read_gpio(dboard_iface::UNIT_BOTH) & mask<uint32_t>(field)) + >> shift(field); } // CPLD register write-only interface - void poke32(const wb_addr_type addr, const uint32_t data) { + void poke32(const wb_addr_type addr, const uint32_t data) + { boost::lock_guard<boost::mutex> lock(_mutex); using namespace soft_reg_field; - //Step 1: Write the reg offset and data to the GPIO bus and de-assert all enables + // Step 1: Write the reg offset and data to the GPIO bus and de-assert all enables _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, (cpld::get_reg(addr) << shift(CPLD_FULL_ADDR)) | (data << shift(CPLD_DATA)), - mask<uint32_t>(CPLD_FULL_ADDR)|mask<uint32_t>(CPLD_DATA)); - //Sleep for 166ns to ensure that we don't toggle the enables too quickly - //The underlying sleep function rounds to microsecond precision. + mask<uint32_t>(CPLD_FULL_ADDR) | mask<uint32_t>(CPLD_DATA)); + // Sleep for 166ns to ensure that we don't toggle the enables too quickly + // The underlying sleep function rounds to microsecond precision. _db_iface->sleep(boost::chrono::nanoseconds(166)); - //Step 2: Write the reg offset and data, and assert the necessary enable + // Step 2: Write the reg offset and data, and assert the necessary enable _db_iface->set_gpio_out(dboard_iface::UNIT_BOTH, - (static_cast<uint32_t>(addr) << shift(CPLD_FULL_ADDR)) | (data << shift(CPLD_DATA)), - mask<uint32_t>(CPLD_FULL_ADDR)|mask<uint32_t>(CPLD_DATA)); + (static_cast<uint32_t>(addr) << shift(CPLD_FULL_ADDR)) + | (data << shift(CPLD_DATA)), + mask<uint32_t>(CPLD_FULL_ADDR) | mask<uint32_t>(CPLD_DATA)); } -private: //Members/definitions - static const uint32_t GPIO_OUTPUT_MASK = 0xFC06FE03; - static const uint32_t GPIO_PINCTRL_MASK = 0x00000000; +private: // Members/definitions + static const uint32_t GPIO_OUTPUT_MASK = 0xFC06FE03; + static const uint32_t GPIO_PINCTRL_MASK = 0x00000000; - //Private GPIO fields - UHD_DEFINE_SOFT_REG_FIELD(CPLD_FULL_ADDR, /*width*/ 7, /*shift*/ 9); //GPIO[15:9] - UHD_DEFINE_SOFT_REG_FIELD(CPLD_DATA, /*width*/ 5, /*shift*/ 27); //GPIO[31:27] + // Private GPIO fields + UHD_DEFINE_SOFT_REG_FIELD(CPLD_FULL_ADDR, /*width*/ 7, /*shift*/ 9); // GPIO[15:9] + UHD_DEFINE_SOFT_REG_FIELD(CPLD_DATA, /*width*/ 5, /*shift*/ 27); // GPIO[31:27] - //Members - dboard_iface::sptr _db_iface; - boost::mutex _mutex; + // Members + dboard_iface::sptr _db_iface; + boost::mutex _mutex; }; -class twinrx_cpld_regmap : public uhd::soft_regmap_t { +class twinrx_cpld_regmap : public uhd::soft_regmap_t +{ public: typedef std::shared_ptr<twinrx_cpld_regmap> sptr; //---------------------------------------------- // IF CCA: CPLD 1 //---------------------------------------------- - class if0_reg0_t : public uhd::soft_reg32_wo_t { + class if0_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH2, /*width*/ 1, /*shift*/ 4); - - if0_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 0), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO2_EN_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH2, /*width*/ 1, /*shift*/ 4); + + if0_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg0; - class if0_reg1_t : public uhd::soft_reg32_wo_t { + class if0_reg1_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW20_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - if0_reg1_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 1), OPTIMIZED_FLUSH) { + if0_reg1_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 1), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg1; - class if0_reg2_t : public uhd::soft_reg32_wo_t { + class if0_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH2, /*width*/ 1, /*shift*/ 4); - - if0_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 2), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_IF1_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(LO2_LE_CH2, /*width*/ 1, /*shift*/ 4); + + if0_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg2; - class if0_reg3_t : public uhd::soft_reg32_wo_t { + class if0_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH1, /*width*/ 1, /*shift*/ 3); - if0_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 3), OPTIMIZED_FLUSH) { + if0_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg3; - class if0_reg4_t : public uhd::soft_reg32_wo_t { + class if0_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW25_CTRL, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - - if0_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 4), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW25_CTRL, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(IF1_IF2_EN_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW19_CTRL_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW21_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + + if0_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg4; - class if0_reg6_t : public uhd::soft_reg32_wo_t { + class if0_reg6_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_IF1_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW13_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - if0_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 6), OPTIMIZED_FLUSH) { + if0_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg6; - class if0_reg7_t : public uhd::soft_reg32_wo_t { + class if0_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW24_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - if0_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 7), OPTIMIZED_FLUSH) { + if0_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 1, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } if0_reg7; @@ -208,90 +252,114 @@ public: //---------------------------------------------- // RF CCA: CPLD 2 //---------------------------------------------- - class rf0_reg0_t : public uhd::soft_reg32_wo_t { + class rf0_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH1, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH1, /*width*/ 5, /*shift*/ 0); - rf0_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 0), OPTIMIZED_FLUSH) { + rf0_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg0; - class rf0_reg1_t : public uhd::soft_reg32_wo_t { + class rf0_reg1_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH2, /*width*/ 1, /*shift*/ 4); - - rf0_reg1_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 1), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH2, /*width*/ 1, /*shift*/ 4); + + rf0_reg1_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 1), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg1; - class rf0_reg2_t : public uhd::soft_reg32_wo_t { + class rf0_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH2, /*width*/ 1, /*shift*/ 4); - - rf0_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 2), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(LO1_LE_CH2, /*width*/ 1, /*shift*/ 4); + + rf0_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg2; - class rf0_reg3_t : public uhd::soft_reg32_wo_t { + class rf0_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH2, /*width*/ 2, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH1, /*width*/ 2, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH2, /*width*/ 2, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH1, /*width*/ 2, /*shift*/ 2); - rf0_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 3), OPTIMIZED_FLUSH) { + rf0_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg3; - class rf0_reg4_t : public uhd::soft_reg32_wo_t { + class rf0_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH2, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_IN_CH2, /*width*/ 5, /*shift*/ 0); - rf0_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 4), OPTIMIZED_FLUSH) { + rf0_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg4; - class rf0_reg5_t : public uhd::soft_reg32_wo_t { + class rf0_reg5_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH1, /*width*/ 2, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + UHD_DEFINE_SOFT_REG_FIELD(SW9_CTRL_CH1, /*width*/ 2, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(HB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - rf0_reg5_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 5), OPTIMIZED_FLUSH) { + rf0_reg5_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 5), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg5; - class rf0_reg6_t : public uhd::soft_reg32_wo_t { + class rf0_reg6_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH2, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH2, /*width*/ 1, /*shift*/ 4); - - rf0_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 6), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW6_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW5_CTRL_CH2, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW4_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH2, /*width*/ 1, /*shift*/ 4); + + rf0_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg6; - class rf0_reg7_t : public uhd::soft_reg32_wo_t { + class rf0_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH2, /*width*/ 2, /*shift*/ 3); - - rf0_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 7), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SWPA1_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SWPA3_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW3_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW7_CTRL_CH2, /*width*/ 2, /*shift*/ 3); + + rf0_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 2, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf0_reg7; @@ -299,91 +367,115 @@ public: //---------------------------------------------- // RF CCA: CPLD 3 //---------------------------------------------- - class rf1_reg0_t : public uhd::soft_reg32_wo_t { + class rf1_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH1, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH1, /*width*/ 5, /*shift*/ 0); - rf1_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 0), OPTIMIZED_FLUSH) { + rf1_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg0; - class rf1_reg1_t : public uhd::soft_reg32_wo_t { + class rf1_reg1_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH1, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - - rf1_reg1_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 1), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH1, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + + rf1_reg1_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 1), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg1; - class rf1_reg2_t : public uhd::soft_reg32_wo_t { + class rf1_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH1, /*width*/ 1, /*shift*/ 1); UHD_DEFINE_SOFT_REG_FIELD(HB_PRESEL_PGA_EN_CH2, /*width*/ 1, /*shift*/ 2); - rf1_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 2), OPTIMIZED_FLUSH) { + rf1_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg2; - class rf1_reg3_t : public uhd::soft_reg32_wo_t { + class rf1_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW23_CTRL, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH1, /*width*/ 2, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW23_CTRL, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH1, /*width*/ 2, /*shift*/ 2); - rf1_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 3), OPTIMIZED_FLUSH) { + rf1_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg3; - class rf1_reg4_t : public uhd::soft_reg32_wo_t { + class rf1_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH2, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_HB_CH2, /*width*/ 5, /*shift*/ 0); - rf1_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 4), OPTIMIZED_FLUSH) { + rf1_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg4; - class rf1_reg5_t : public uhd::soft_reg32_wo_t { + class rf1_reg5_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH2, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH1, /*width*/ 1, /*shift*/ 4); - - rf1_reg5_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 5), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(AMP_LO1_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW15_CTRL_CH2, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW14_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH1, /*width*/ 1, /*shift*/ 4); + + rf1_reg5_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 5), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg5; - class rf1_reg6_t : public uhd::soft_reg32_wo_t { + class rf1_reg6_t : public uhd::soft_reg32_wo_t + { public: UHD_DEFINE_SOFT_REG_FIELD(HB_PRESEL_PGA_EN_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH2, /*width*/ 1, /*shift*/ 2); - UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH2, /*width*/ 1, /*shift*/ 4); + UHD_DEFINE_SOFT_REG_FIELD(SW17_CTRL_CH2, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW16_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH2, /*width*/ 1, /*shift*/ 4); - rf1_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 6), OPTIMIZED_FLUSH) { + rf1_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg6; - class rf1_reg7_t : public uhd::soft_reg32_wo_t { + class rf1_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH2, /*width*/ 2, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH2, /*width*/ 1, /*shift*/ 4); - - rf1_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 7), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SW22_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW10_CTRL_CH2, /*width*/ 2, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW12_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(AMP_HB_EN_CH2, /*width*/ 1, /*shift*/ 4); + + rf1_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 3, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf1_reg7; @@ -391,77 +483,99 @@ public: //---------------------------------------------- // RF CCA: CPLD 4 //---------------------------------------------- - class rf2_reg0_t : public uhd::soft_reg32_wo_t { + class rf2_reg0_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH1, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH1, /*width*/ 5, /*shift*/ 0); - rf2_reg0_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 0), OPTIMIZED_FLUSH) { + rf2_reg0_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 0), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg0; - class rf2_reg2_t : public uhd::soft_reg32_wo_t { + class rf2_reg2_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH1, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH1, /*width*/ 1, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH1, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH1, /*width*/ 1, /*shift*/ 2); - rf2_reg2_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 2), OPTIMIZED_FLUSH) { + rf2_reg2_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 2), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg2; - class rf2_reg3_t : public uhd::soft_reg32_wo_t { + class rf2_reg3_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH2, /*width*/ 1, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH1, /*width*/ 2, /*shift*/ 2); + UHD_DEFINE_SOFT_REG_FIELD(PREAMP2_EN_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW18_CTRL_CH2, /*width*/ 1, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH1, /*width*/ 2, /*shift*/ 2); - rf2_reg3_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 3), OPTIMIZED_FLUSH) { + rf2_reg3_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 3), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg3; - class rf2_reg4_t : public uhd::soft_reg32_wo_t { + class rf2_reg4_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH2, /*width*/ 5, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(ATTEN_LB_CH2, /*width*/ 5, /*shift*/ 0); - rf2_reg4_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 4), OPTIMIZED_FLUSH) { + rf2_reg4_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 4), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg4; - class rf2_reg5_t : public uhd::soft_reg32_wo_t { + class rf2_reg5_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SWPA2_CTRL_CH2, /*width*/ 1, /*shift*/ 0); - rf2_reg5_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 5), OPTIMIZED_FLUSH) { + rf2_reg5_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 5), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg5; - class rf2_reg6_t : public uhd::soft_reg32_wo_t { + class rf2_reg6_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(LB_PREAMP_EN_CH2, /*width*/ 1, /*shift*/ 0); - rf2_reg6_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 6), OPTIMIZED_FLUSH) { + rf2_reg6_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 6), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg6; - class rf2_reg7_t : public uhd::soft_reg32_wo_t { + class rf2_reg7_t : public uhd::soft_reg32_wo_t + { public: - UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH1, /*width*/ 1, /*shift*/ 0); - UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH2, /*width*/ 2, /*shift*/ 1); - UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH2, /*width*/ 1, /*shift*/ 3); - UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH2, /*width*/ 1, /*shift*/ 4); - - rf2_reg7_t(): uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 7), OPTIMIZED_FLUSH) { + UHD_DEFINE_SOFT_REG_FIELD(SWPA4_CTRL_CH1, /*width*/ 1, /*shift*/ 0); + UHD_DEFINE_SOFT_REG_FIELD(SW8_CTRL_CH2, /*width*/ 2, /*shift*/ 1); + UHD_DEFINE_SOFT_REG_FIELD(SW11_CTRL_CH2, /*width*/ 1, /*shift*/ 3); + UHD_DEFINE_SOFT_REG_FIELD(AMP_LB_EN_CH2, /*width*/ 1, /*shift*/ 4); + + rf2_reg7_t() + : uhd::soft_reg32_wo_t(cpld::addr(/*cpld*/ 4, /*reg*/ 7), OPTIMIZED_FLUSH) + { set(REGISTER, 0); } } rf2_reg7; - twinrx_cpld_regmap() : soft_regmap_t("twinrx_cpld") { + twinrx_cpld_regmap() : soft_regmap_t("twinrx_cpld") + { // IF CCA: CPLD 1 add_to_map(if0_reg0, "if0_reg0"); add_to_map(if0_reg1, "if0_reg1"); @@ -499,6 +613,6 @@ public: } }; -}}}} //namespaces +}}}} // namespace uhd::usrp::dboard::twinrx #endif /* INCLUDED_DBOARD_TWINRX_IO_HPP */ |