From 63f4049a101d66c01f7e89098b03f3f780647cbd Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Mon, 20 Nov 2017 13:16:34 -0800 Subject: mg: Enable variable master clock rates The master_clock_rate argument is passed to init() during initialization; this change allows to query the correct MCR at initialization time. It does not allow changing the MCR while a session is active. The MCR also affects the LO settings; it is the reference clock for the lowband LOs. --- .../usrp/dboard/magnesium/magnesium_constants.hpp | 1 - .../dboard/magnesium/magnesium_radio_ctrl_impl.cpp | 46 ++++++++++++++++++++-- .../dboard/magnesium/magnesium_radio_ctrl_impl.hpp | 3 ++ .../dboard/magnesium/magnesium_radio_ctrl_init.cpp | 9 +++-- 4 files changed, 50 insertions(+), 9 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp index 933866d92..581b1cc97 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp @@ -13,7 +13,6 @@ static const size_t FPGPIO_MASTER_RADIO = 0; -static const double MAGNESIUM_TICK_RATE = 125e6; // Hz static const double MAGNESIUM_RADIO_RATE = 125e6; // Hz static const double MAGNESIUM_MIN_FREQ = 1e6; // Hz static const double MAGNESIUM_MAX_FREQ = 6e9; // Hz diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp index 8b722e725..3efe61676 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp @@ -27,6 +27,13 @@ namespace { /************************************************************************** * ADF4351 Controls *************************************************************************/ + /*! + * \param lo_iface Reference to the LO object + * \param freq Frequency (in Hz) of the tone to be generated from the LO + * \param ref_clock_freq Frequency (in Hz) of the reference clock at the + * PLL input of the LO + * \param int_n_mode Integer-N mode on or off + */ double _lo_set_frequency( adf435x_iface::sptr lo_iface, const double freq, @@ -53,6 +60,17 @@ namespace { return actual_freq; } + /*! Configure and enable LO + * + * Will tune it to requested frequency and enable outputs. + * + * \param lo_iface Reference to the LO object + * \param lo_freq Frequency (in Hz) of the tone to be generated from the LO + * \param ref_clock_freq Frequency (in Hz) of the reference clock at the + * PLL input of the LO + * \param int_n_mode Integer-N mode on or off + * \returns the actual frequency the LO is running at + */ double _lo_enable( adf435x_iface::sptr lo_iface, const double lo_freq, @@ -67,6 +85,8 @@ namespace { return actual_lo_freq; } + /*! Disable LO + */ void _lo_disable(adf435x_iface::sptr lo_iface) { lo_iface->set_output_enable(adf435x_iface::RF_OUTPUT_A, false); @@ -192,9 +212,8 @@ double magnesium_radio_ctrl_impl::set_tx_frequency( if_freq = MAGNESIUM_TX_IF_FREQ ; const double lo_freq = if_freq - freq; const bool int_n_mode = false; // FIXME no hardcode - const double ref_clk_freq = 100e6; // FIXME no hardcode //const double actual_lo_freq = - _lo_enable(lo_iface, lo_freq, ref_clk_freq, int_n_mode); + _lo_enable(lo_iface, lo_freq, _master_clock_rate, int_n_mode); //ad9371_freq = actual_lo_freq - freq; } else { _lo_disable(lo_iface); @@ -233,9 +252,8 @@ double magnesium_radio_ctrl_impl::set_rx_frequency( if_freq = MAGNESIUM_RX_IF_FREQ ; const double lo_freq = if_freq - freq; const bool int_n_mode = false; // FIXME no hardcode - const double ref_clk_freq = 100e6; // FIXME no hardcode //const double actual_lo_freq = - _lo_enable(lo_iface, lo_freq, ref_clk_freq, int_n_mode); + _lo_enable(lo_iface, lo_freq, _master_clock_rate, int_n_mode); //ad9371_freq = actual_lo_freq - freq; } else { _lo_disable(lo_iface); @@ -401,6 +419,26 @@ void magnesium_radio_ctrl_impl::set_rpc_client( ) ); + // Note: MCR gets set during the init() call (prior to this), which takes + // in arguments from the device args. So if block_args contains a + // master_clock_rate key, then it should better be whatever the device is + // configured to do. + _master_clock_rate = _rpcc->request_with_token( + _rpc_prefix + "get_master_clock_rate"); + if (block_args.cast("master_clock_rate", _master_clock_rate) + != _master_clock_rate) { + throw uhd::runtime_error(str( + boost::format("Master clock rate mismatch. Device returns %f MHz, " + "but should have been %f MHz.") + % (_master_clock_rate / 1e6) + % (block_args.cast( + "master_clock_rate", _master_clock_rate) / 1e6) + )); + } + UHD_LOG_DEBUG(unique_id(), + "Master Clock Rate is: " << (_master_clock_rate / 1e6) << " MHz."); + radio_ctrl_impl::set_rate(_master_clock_rate); + // EEPROM paths subject to change FIXME const size_t db_idx = get_block_id().get_block_count(); _tree->access(_root_path / "eeprom") diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp index e32c2d5c9..f1543077c 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp @@ -235,6 +235,9 @@ private: // module can be the FP-GPIO master. usrp::gpio_atr::gpio_atr_3000::sptr _fp_gpio; + //! Sampling rate, and also ref clock frequency for the lowband LOs. + double _master_clock_rate = 1.0; + //! AD9371 gain double _ad9371_rx_gain = 0.0; double _ad9371_tx_gain = 0.0; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp index 27cf926a2..191218133 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp @@ -37,9 +37,8 @@ void magnesium_radio_ctrl_impl::_init_defaults() UHD_LOG_TRACE(unique_id(), "Num TX chans: " << num_tx_chans << " Num RX chans: " << num_rx_chans); - UHD_LOG_TRACE(unique_id(), - "Setting tick rate to " << MAGNESIUM_TICK_RATE / 1e6 << " MHz"); - radio_ctrl_impl::set_rate(MAGNESIUM_TICK_RATE); + // get_rate() is useless until we can ask MPM for the actual rate + radio_ctrl_impl::set_rate(1.0); for (size_t chan = 0; chan < num_rx_chans; chan++) { radio_ctrl_impl::set_rx_frequency(MAGNESIUM_CENTER_FREQ, chan); @@ -397,7 +396,9 @@ void magnesium_radio_ctrl_impl::_init_prop_tree() // TODO remove this dirty hack if (not _tree->exists("tick_rate")) { - _tree->create("tick_rate").set(MAGNESIUM_TICK_RATE); + _tree->create("tick_rate") + .set_publisher([this](){ return this->get_rate(); }) + ; } } -- cgit v1.2.3