diff options
author | Brent Stapleton <brent.stapleton@ettus.com> | 2019-01-14 10:35:25 -0800 |
---|---|---|
committer | Brent Stapleton <brent.stapleton@ettus.com> | 2019-01-16 11:40:23 -0800 |
commit | 967be2a4e82b1a125b26bb72a60318a4fb2b50c4 (patch) | |
tree | 8a24954b54d1546dc8049a17e485adb0a605f74f /host/lib/usrp/x300/x300_clock_ctrl.cpp | |
parent | aafe4e8b742a0e21d3818f21f34e3c8613132530 (diff) | |
download | uhd-967be2a4e82b1a125b26bb72a60318a4fb2b50c4.tar.gz uhd-967be2a4e82b1a125b26bb72a60318a4fb2b50c4.tar.bz2 uhd-967be2a4e82b1a125b26bb72a60318a4fb2b50c4.zip |
uhd: mpm: apply clang-format to all files
Applying formatting changes to all .cpp and .hpp files in the following
directories:
```
find host/examples/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/tests/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/dboard/neon/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/dboard/magnesium/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/device3/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/mpmd/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/lib/usrp/x300/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find host/utils/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
find mpm/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
```
Also formatted host/include/, except Cpp03 was used as a the language
standard instead of Cpp11.
```
sed -i 's/ Cpp11/ Cpp03/g' .clang-format
find host/include/ -iname *.hpp -o -iname *.cpp | \
xargs clang-format -i -style=file
```
Formatting style was designated by the .clang-format file.
Diffstat (limited to 'host/lib/usrp/x300/x300_clock_ctrl.cpp')
-rw-r--r-- | host/lib/usrp/x300/x300_clock_ctrl.cpp | 940 |
1 files changed, 521 insertions, 419 deletions
diff --git a/host/lib/usrp/x300/x300_clock_ctrl.cpp b/host/lib/usrp/x300/x300_clock_ctrl.cpp index 93e02ca7d..a867a9138 100644 --- a/host/lib/usrp/x300/x300_clock_ctrl.cpp +++ b/host/lib/usrp/x300/x300_clock_ctrl.cpp @@ -5,32 +5,43 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "lmk04816_regs.hpp" #include "x300_clock_ctrl.hpp" +#include "lmk04816_regs.hpp" #include "x300_defaults.hpp" -#include <uhd/utils/safe_call.hpp> #include <uhd/utils/math.hpp> +#include <uhd/utils/safe_call.hpp> #include <stdint.h> #include <boost/format.hpp> #include <boost/math/special_functions/round.hpp> -#include <stdexcept> #include <cmath> #include <cstdlib> +#include <stdexcept> -static const double X300_REF_CLK_OUT_RATE = 10e6; +static const double X300_REF_CLK_OUT_RATE = 10e6; static const uint16_t X300_MAX_CLKOUT_DIV = 1045; -constexpr double MIN_VCO_FREQ = 2370e6; -constexpr double MAX_VCO_FREQ = 2600e6; -constexpr double VCXO_FREQ = 96.0e6; // VCXO runs at 96MHz -constexpr int VCXO_PLL2_N = 2; // Assume that the PLL2 N predivider is set to /2. - -struct x300_clk_delays { - x300_clk_delays() : - fpga_dly_ns(0.0),adc_dly_ns(0.0),dac_dly_ns(0.0),db_rx_dly_ns(0.0),db_tx_dly_ns(0.0) - {} - x300_clk_delays(double fpga, double adc, double dac, double db_rx, double db_tx) : - fpga_dly_ns(fpga),adc_dly_ns(adc),dac_dly_ns(dac),db_rx_dly_ns(db_rx),db_tx_dly_ns(db_tx) - {} +constexpr double MIN_VCO_FREQ = 2370e6; +constexpr double MAX_VCO_FREQ = 2600e6; +constexpr double VCXO_FREQ = 96.0e6; // VCXO runs at 96MHz +constexpr int VCXO_PLL2_N = 2; // Assume that the PLL2 N predivider is set to /2. + +struct x300_clk_delays +{ + x300_clk_delays() + : fpga_dly_ns(0.0) + , adc_dly_ns(0.0) + , dac_dly_ns(0.0) + , db_rx_dly_ns(0.0) + , db_tx_dly_ns(0.0) + { + } + x300_clk_delays(double fpga, double adc, double dac, double db_rx, double db_tx) + : fpga_dly_ns(fpga) + , adc_dly_ns(adc) + , dac_dly_ns(dac) + , db_rx_dly_ns(db_rx) + , db_tx_dly_ns(db_tx) + { + } double fpga_dly_ns; double adc_dly_ns; @@ -51,14 +62,14 @@ static const x300_clk_delays X300_REV7_CLK_DELAYS = x300_clk_delays( using namespace uhd; using namespace uhd::math::fp_compare; -x300_clock_ctrl::~x300_clock_ctrl(void){ +x300_clock_ctrl::~x300_clock_ctrl(void) +{ /* NOP */ } -class x300_clock_ctrl_impl : public x300_clock_ctrl { - +class x300_clock_ctrl_impl : public x300_clock_ctrl +{ public: - ~x300_clock_ctrl_impl(void) {} x300_clock_ctrl_impl(uhd::spi_iface::sptr spiface, @@ -66,18 +77,19 @@ public: const size_t hw_rev, const double master_clock_rate, const double dboard_clock_rate, - const double system_ref_rate): - _spiface(spiface), - _slaveno(static_cast<int>(slaveno)), - _hw_rev(hw_rev), - _master_clock_rate(master_clock_rate), - _dboard_clock_rate(dboard_clock_rate), - _system_ref_rate(system_ref_rate) + const double system_ref_rate) + : _spiface(spiface) + , _slaveno(static_cast<int>(slaveno)) + , _hw_rev(hw_rev) + , _master_clock_rate(master_clock_rate) + , _dboard_clock_rate(dboard_clock_rate) + , _system_ref_rate(system_ref_rate) { init(); } - void reset_clocks() { + void reset_clocks() + { _lmk04816_regs.RESET = lmk04816_regs_t::RESET_RESET; this->write_regs(0); _lmk04816_regs.RESET = lmk04816_regs_t::RESET_NO_RESET; @@ -90,52 +102,56 @@ public: sync_clocks(); } - void sync_clocks(void) { - //soft sync: - //put the sync IO into output mode - FPGA must be input - //write low, then write high - this triggers a soft sync + void sync_clocks(void) + { + // soft sync: + // put the sync IO into output mode - FPGA must be input + // write low, then write high - this triggers a soft sync _lmk04816_regs.SYNC_POL_INV = lmk04816_regs_t::SYNC_POL_INV_SYNC_LOW; this->write_regs(11); _lmk04816_regs.SYNC_POL_INV = lmk04816_regs_t::SYNC_POL_INV_SYNC_HIGH; this->write_regs(11); } - double get_master_clock_rate(void) { + double get_master_clock_rate(void) + { return _master_clock_rate; } - double get_sysref_clock_rate(void) { + double get_sysref_clock_rate(void) + { return _system_ref_rate; } - double get_refout_clock_rate(void) { - //We support only one reference output rate + double get_refout_clock_rate(void) + { + // We support only one reference output rate return X300_REF_CLK_OUT_RATE; } - void set_dboard_rate(const x300_clock_which_t which, double rate) { - uint16_t div = uint16_t(_vco_freq / rate); - uint16_t *reg = NULL; - uint8_t addr = 0xFF; + void set_dboard_rate(const x300_clock_which_t which, double rate) + { + uint16_t div = uint16_t(_vco_freq / rate); + uint16_t* reg = NULL; + uint8_t addr = 0xFF; // Make sure requested rate is an even divisor of the VCO frequency if (not math::frequencies_are_equal(_vco_freq / div, rate)) throw uhd::value_error("invalid dboard rate requested"); - switch (which) - { - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - reg = &_lmk04816_regs.CLKout2_3_DIV; - addr = 1; - break; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - reg = &_lmk04816_regs.CLKout4_5_DIV; - addr = 2; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + reg = &_lmk04816_regs.CLKout2_3_DIV; + addr = 1; + break; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + reg = &_lmk04816_regs.CLKout4_5_DIV; + addr = 2; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } if (*reg == div) @@ -143,13 +159,15 @@ public: // Since the clock rate on one daughter board cannot be changed without // affecting the other daughter board, don't allow it. - throw uhd::not_implemented_error("x3xx set dboard clock rate does not support changing the clock rate"); + throw uhd::not_implemented_error( + "x3xx set dboard clock rate does not support changing the clock rate"); // This is open source code and users may need to enable this function // to support other daughterboards. If so, comment out the line above // that throws the error and allow the program to reach the code below. - // The LMK04816 datasheet says the register must be written twice if SYNC is enabled + // The LMK04816 datasheet says the register must be written twice if SYNC is + // enabled *reg = div; write_regs(addr); write_regs(addr); @@ -159,18 +177,17 @@ public: double get_dboard_rate(const x300_clock_which_t which) { double rate = 0.0; - switch (which) - { - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - rate = _vco_freq / _lmk04816_regs.CLKout2_3_DIV; - break; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - rate = _vco_freq / _lmk04816_regs.CLKout4_5_DIV; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + rate = _vco_freq / _lmk04816_regs.CLKout2_3_DIV; + break; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + rate = _vco_freq / _lmk04816_regs.CLKout4_5_DIV; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } return rate; } @@ -178,49 +195,63 @@ public: std::vector<double> get_dboard_rates(const x300_clock_which_t) { std::vector<double> rates; - for (size_t div = size_t(_vco_freq / _master_clock_rate); div <= X300_MAX_CLKOUT_DIV; div++) + for (size_t div = size_t(_vco_freq / _master_clock_rate); + div <= X300_MAX_CLKOUT_DIV; + div++) rates.push_back(_vco_freq / div); return rates; } void enable_dboard_clock(const x300_clock_which_t which, const bool enable) { - switch (which) - { - case X300_CLOCK_WHICH_DB0_RX: - if (enable != (_lmk04816_regs.CLKout2_TYPE == lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout2_TYPE = enable ? lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT2_TYPE_P_DOWN; - write_regs(6); - } - break; - case X300_CLOCK_WHICH_DB1_RX: - if (enable != (_lmk04816_regs.CLKout3_TYPE == lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout3_TYPE = enable ? lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT3_TYPE_P_DOWN; - write_regs(6); - } - break; - case X300_CLOCK_WHICH_DB0_TX: - if (enable != (_lmk04816_regs.CLKout5_TYPE == lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout5_TYPE = enable ? lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT5_TYPE_P_DOWN; - write_regs(7); - } - break; - case X300_CLOCK_WHICH_DB1_TX: - if (enable != (_lmk04816_regs.CLKout4_TYPE == lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP)) - { - _lmk04816_regs.CLKout4_TYPE = enable ? lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP : lmk04816_regs_t::CLKOUT4_TYPE_P_DOWN; - write_regs(7); - } - break; - default: - UHD_THROW_INVALID_CODE_PATH(); + switch (which) { + case X300_CLOCK_WHICH_DB0_RX: + if (enable + != (_lmk04816_regs.CLKout2_TYPE + == lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout2_TYPE = + enable ? lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT2_TYPE_P_DOWN; + write_regs(6); + } + break; + case X300_CLOCK_WHICH_DB1_RX: + if (enable + != (_lmk04816_regs.CLKout3_TYPE + == lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout3_TYPE = + enable ? lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT3_TYPE_P_DOWN; + write_regs(6); + } + break; + case X300_CLOCK_WHICH_DB0_TX: + if (enable + != (_lmk04816_regs.CLKout5_TYPE + == lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout5_TYPE = + enable ? lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT5_TYPE_P_DOWN; + write_regs(7); + } + break; + case X300_CLOCK_WHICH_DB1_TX: + if (enable + != (_lmk04816_regs.CLKout4_TYPE + == lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP)) { + _lmk04816_regs.CLKout4_TYPE = + enable ? lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP + : lmk04816_regs_t::CLKOUT4_TYPE_P_DOWN; + write_regs(7); + } + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } - void set_ref_out(const bool enable) { + void set_ref_out(const bool enable) + { // TODO Implement divider configuration to allow for configurable output // rates if (enable) @@ -230,44 +261,48 @@ public: this->write_regs(8); } - void write_regs(uint8_t addr) { + void write_regs(uint8_t addr) + { uint32_t data = _lmk04816_regs.get_reg(addr); - _spiface->write_spi(_slaveno, spi_config_t::EDGE_RISE, data,32); + _spiface->write_spi(_slaveno, spi_config_t::EDGE_RISE, data, 32); } - double set_clock_delay(const x300_clock_which_t which, const double delay_ns, const bool resync = true) { - //All dividers have are delayed by 5 taps by default. The delay - //set by this function is relative to the 5 tap delay - static const uint16_t DDLY_MIN_TAPS = 5; - static const uint16_t DDLY_MAX_TAPS = 522; //Extended mode + double set_clock_delay( + const x300_clock_which_t which, const double delay_ns, const bool resync = true) + { + // All dividers have are delayed by 5 taps by default. The delay + // set by this function is relative to the 5 tap delay + static const uint16_t DDLY_MIN_TAPS = 5; + static const uint16_t DDLY_MAX_TAPS = 522; // Extended mode - //The resolution and range of the analog delay is fixed + // The resolution and range of the analog delay is fixed static const double ADLY_RES_NS = 0.025; static const double ADLY_MIN_NS = 0.500; static const double ADLY_MAX_NS = 0.975; - //Each digital tap delays the clock by one VCO period - double vco_period_ns = 1.0e9/_vco_freq; - double half_vco_period_ns = vco_period_ns/2.0; + // Each digital tap delays the clock by one VCO period + double vco_period_ns = 1.0e9 / _vco_freq; + double half_vco_period_ns = vco_period_ns / 2.0; - //Implement as much of the requested delay using digital taps. Whatever is leftover - //will be made up using the analog delay element and the half-cycle digital tap. - //A caveat here is that the analog delay starts at ADLY_MIN_NS, so we need to back off - //by that much when coming up with the digital taps so that the difference can be made - //up using the analog delay. + // Implement as much of the requested delay using digital taps. Whatever is + // leftover will be made up using the analog delay element and the half-cycle + // digital tap. A caveat here is that the analog delay starts at ADLY_MIN_NS, so + // we need to back off by that much when coming up with the digital taps so that + // the difference can be made up using the analog delay. uint16_t ddly_taps = 0; if (delay_ns < ADLY_MIN_NS) { - ddly_taps = static_cast<uint16_t>(std::floor((delay_ns)/vco_period_ns)); + ddly_taps = static_cast<uint16_t>(std::floor((delay_ns) / vco_period_ns)); } else { - ddly_taps = static_cast<uint16_t>(std::floor((delay_ns-ADLY_MIN_NS)/vco_period_ns)); + ddly_taps = static_cast<uint16_t>( + std::floor((delay_ns - ADLY_MIN_NS) / vco_period_ns)); } double leftover_delay = delay_ns - (vco_period_ns * ddly_taps); - //Compute settings - uint16_t ddly_value = ddly_taps + DDLY_MIN_TAPS; - bool adly_en = false; - uint8_t adly_value = 0; - uint8_t half_shift_en = 0; + // Compute settings + uint16_t ddly_value = ddly_taps + DDLY_MIN_TAPS; + bool adly_en = false; + uint8_t adly_value = 0; + uint8_t half_shift_en = 0; if (ddly_value > DDLY_MAX_TAPS) { throw uhd::value_error("set_clock_delay: Requested delay is out of range."); @@ -275,172 +310,203 @@ public: double coerced_delay = (vco_period_ns * ddly_taps); if (leftover_delay > ADLY_MAX_NS) { - //The VCO is running too slowly for us to compensate the digital delay difference using - //analog delay. Do the best we can. - adly_en = true; - adly_value = static_cast<uint8_t>(boost::math::round((ADLY_MAX_NS-ADLY_MIN_NS)/ADLY_RES_NS)); + // The VCO is running too slowly for us to compensate the digital delay + // difference using analog delay. Do the best we can. + adly_en = true; + adly_value = static_cast<uint8_t>( + boost::math::round((ADLY_MAX_NS - ADLY_MIN_NS) / ADLY_RES_NS)); coerced_delay += ADLY_MAX_NS; } else if (leftover_delay >= ADLY_MIN_NS && leftover_delay <= ADLY_MAX_NS) { - //The leftover delay can be compensated by the analog delay up to the analog delay resolution - adly_en = true; - adly_value = static_cast<uint8_t>(boost::math::round((leftover_delay-ADLY_MIN_NS)/ADLY_RES_NS)); - coerced_delay += ADLY_MIN_NS+(ADLY_RES_NS*adly_value); - } else if (leftover_delay >= (ADLY_MIN_NS - half_vco_period_ns) && leftover_delay < ADLY_MIN_NS) { - //The leftover delay if less than the minimum supported analog delay but if we move the digital - //delay back by half a VCO cycle then it will be in the range of the analog delay. So do that! - adly_en = true; - adly_value = static_cast<uint8_t>(boost::math::round((leftover_delay+half_vco_period_ns-ADLY_MIN_NS)/ADLY_RES_NS)); + // The leftover delay can be compensated by the analog delay up to the analog + // delay resolution + adly_en = true; + adly_value = static_cast<uint8_t>( + boost::math::round((leftover_delay - ADLY_MIN_NS) / ADLY_RES_NS)); + coerced_delay += ADLY_MIN_NS + (ADLY_RES_NS * adly_value); + } else if (leftover_delay >= (ADLY_MIN_NS - half_vco_period_ns) + && leftover_delay < ADLY_MIN_NS) { + // The leftover delay if less than the minimum supported analog delay but if + // we move the digital delay back by half a VCO cycle then it will be in the + // range of the analog delay. So do that! + adly_en = true; + adly_value = static_cast<uint8_t>(boost::math::round( + (leftover_delay + half_vco_period_ns - ADLY_MIN_NS) / ADLY_RES_NS)); half_shift_en = 1; - coerced_delay += ADLY_MIN_NS+(ADLY_RES_NS*adly_value)-half_vco_period_ns; + coerced_delay += + ADLY_MIN_NS + (ADLY_RES_NS * adly_value) - half_vco_period_ns; } else { - //Even after moving the digital delay back by half a cycle, we cannot make up the difference - //so give up on compensating for the difference from the digital delay tap. - //If control reaches here then the value of leftover_delay is possible very small and will still - //be close to what the client requested. + // Even after moving the digital delay back by half a cycle, we cannot make up + // the difference so give up on compensating for the difference from the + // digital delay tap. If control reaches here then the value of leftover_delay + // is possible very small and will still be close to what the client + // requested. } - UHD_LOG_DEBUG("X300", boost::format("x300_clock_ctrl::set_clock_delay: Which=%d, Requested=%f, Digital Taps=%d, Half Shift=%d, Analog Delay=%d (%s), Coerced Delay=%fns" - ) % which % delay_ns % ddly_value % (half_shift_en?"ON":"OFF") % ((int)adly_value) % (adly_en?"ON":"OFF") % coerced_delay) - - //Apply settings - switch (which) - { - case X300_CLOCK_WHICH_FPGA: - _lmk04816_regs.CLKout0_1_DDLY = ddly_value; - _lmk04816_regs.CLKout0_1_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout0_ADLY_SEL = lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout1_ADLY_SEL = lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout0_1_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout0_ADLY_SEL = lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout1_ADLY_SEL = lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_PD; - } - write_regs(0); - write_regs(6); - _delays.fpga_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - _lmk04816_regs.CLKout2_3_DDLY = ddly_value; - _lmk04816_regs.CLKout2_3_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout2_ADLY_SEL = lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout3_ADLY_SEL = lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout2_3_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout2_ADLY_SEL = lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout3_ADLY_SEL = lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_PD; - } - write_regs(1); - write_regs(6); - _delays.db_rx_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - _lmk04816_regs.CLKout4_5_DDLY = ddly_value; - _lmk04816_regs.CLKout4_5_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout4_ADLY_SEL = lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout5_ADLY_SEL = lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout4_5_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout4_ADLY_SEL = lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout5_ADLY_SEL = lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_PD; - } - write_regs(2); - write_regs(7); - _delays.db_tx_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_DAC0: - case X300_CLOCK_WHICH_DAC1: - _lmk04816_regs.CLKout6_7_DDLY = ddly_value; - _lmk04816_regs.CLKout6_7_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout6_ADLY_SEL = lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout7_ADLY_SEL = lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout6_7_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout6_ADLY_SEL = lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout7_ADLY_SEL = lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_PD; - } - write_regs(3); - write_regs(7); - _delays.dac_dly_ns = coerced_delay; - break; - case X300_CLOCK_WHICH_ADC0: - case X300_CLOCK_WHICH_ADC1: - _lmk04816_regs.CLKout8_9_DDLY = ddly_value; - _lmk04816_regs.CLKout8_9_HS = half_shift_en; - if (adly_en) { - _lmk04816_regs.CLKout8_ADLY_SEL = lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout9_ADLY_SEL = lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_BOTH; - _lmk04816_regs.CLKout8_9_ADLY = adly_value; - } else { - _lmk04816_regs.CLKout8_ADLY_SEL = lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_PD; - _lmk04816_regs.CLKout9_ADLY_SEL = lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_PD; - } - write_regs(4); - write_regs(8); - _delays.adc_dly_ns = coerced_delay; - break; - default: - throw uhd::value_error("set_clock_delay: Requested source is invalid."); + UHD_LOG_DEBUG("X300", + boost::format( + "x300_clock_ctrl::set_clock_delay: Which=%d, Requested=%f, Digital " + "Taps=%d, Half Shift=%d, Analog Delay=%d (%s), Coerced Delay=%fns") + % which % delay_ns % ddly_value % (half_shift_en ? "ON" : "OFF") + % ((int)adly_value) % (adly_en ? "ON" : "OFF") % coerced_delay) + + // Apply settings + switch (which) { + case X300_CLOCK_WHICH_FPGA: + _lmk04816_regs.CLKout0_1_DDLY = ddly_value; + _lmk04816_regs.CLKout0_1_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout0_ADLY_SEL = + lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout1_ADLY_SEL = + lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout0_1_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout0_ADLY_SEL = + lmk04816_regs_t::CLKOUT0_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout1_ADLY_SEL = + lmk04816_regs_t::CLKOUT1_ADLY_SEL_D_PD; + } + write_regs(0); + write_regs(6); + _delays.fpga_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + _lmk04816_regs.CLKout2_3_DDLY = ddly_value; + _lmk04816_regs.CLKout2_3_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout2_ADLY_SEL = + lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout3_ADLY_SEL = + lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout2_3_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout2_ADLY_SEL = + lmk04816_regs_t::CLKOUT2_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout3_ADLY_SEL = + lmk04816_regs_t::CLKOUT3_ADLY_SEL_D_PD; + } + write_regs(1); + write_regs(6); + _delays.db_rx_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + _lmk04816_regs.CLKout4_5_DDLY = ddly_value; + _lmk04816_regs.CLKout4_5_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout4_ADLY_SEL = + lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout5_ADLY_SEL = + lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout4_5_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout4_ADLY_SEL = + lmk04816_regs_t::CLKOUT4_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout5_ADLY_SEL = + lmk04816_regs_t::CLKOUT5_ADLY_SEL_D_PD; + } + write_regs(2); + write_regs(7); + _delays.db_tx_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_DAC0: + case X300_CLOCK_WHICH_DAC1: + _lmk04816_regs.CLKout6_7_DDLY = ddly_value; + _lmk04816_regs.CLKout6_7_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout6_ADLY_SEL = + lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout7_ADLY_SEL = + lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout6_7_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout6_ADLY_SEL = + lmk04816_regs_t::CLKOUT6_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout7_ADLY_SEL = + lmk04816_regs_t::CLKOUT7_ADLY_SEL_D_PD; + } + write_regs(3); + write_regs(7); + _delays.dac_dly_ns = coerced_delay; + break; + case X300_CLOCK_WHICH_ADC0: + case X300_CLOCK_WHICH_ADC1: + _lmk04816_regs.CLKout8_9_DDLY = ddly_value; + _lmk04816_regs.CLKout8_9_HS = half_shift_en; + if (adly_en) { + _lmk04816_regs.CLKout8_ADLY_SEL = + lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout9_ADLY_SEL = + lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_BOTH; + _lmk04816_regs.CLKout8_9_ADLY = adly_value; + } else { + _lmk04816_regs.CLKout8_ADLY_SEL = + lmk04816_regs_t::CLKOUT8_ADLY_SEL_D_PD; + _lmk04816_regs.CLKout9_ADLY_SEL = + lmk04816_regs_t::CLKOUT9_ADLY_SEL_D_PD; + } + write_regs(4); + write_regs(8); + _delays.adc_dly_ns = coerced_delay; + break; + default: + throw uhd::value_error("set_clock_delay: Requested source is invalid."); } - //Delays are applied only on a sync event - if (resync) sync_clocks(); + // Delays are applied only on a sync event + if (resync) + sync_clocks(); return coerced_delay; } - double get_clock_delay(const x300_clock_which_t which) { - switch (which) - { - case X300_CLOCK_WHICH_FPGA: - return _delays.fpga_dly_ns; - case X300_CLOCK_WHICH_DB0_RX: - case X300_CLOCK_WHICH_DB1_RX: - return _delays.db_rx_dly_ns; - case X300_CLOCK_WHICH_DB0_TX: - case X300_CLOCK_WHICH_DB1_TX: - return _delays.db_tx_dly_ns; - case X300_CLOCK_WHICH_DAC0: - case X300_CLOCK_WHICH_DAC1: - return _delays.dac_dly_ns; - case X300_CLOCK_WHICH_ADC0: - case X300_CLOCK_WHICH_ADC1: - return _delays.adc_dly_ns; - default: - throw uhd::value_error("get_clock_delay: Requested source is invalid."); + double get_clock_delay(const x300_clock_which_t which) + { + switch (which) { + case X300_CLOCK_WHICH_FPGA: + return _delays.fpga_dly_ns; + case X300_CLOCK_WHICH_DB0_RX: + case X300_CLOCK_WHICH_DB1_RX: + return _delays.db_rx_dly_ns; + case X300_CLOCK_WHICH_DB0_TX: + case X300_CLOCK_WHICH_DB1_TX: + return _delays.db_tx_dly_ns; + case X300_CLOCK_WHICH_DAC0: + case X300_CLOCK_WHICH_DAC1: + return _delays.dac_dly_ns; + case X300_CLOCK_WHICH_ADC0: + case X300_CLOCK_WHICH_ADC1: + return _delays.adc_dly_ns; + default: + throw uhd::value_error("get_clock_delay: Requested source is invalid."); } } private: - double autoset_pll2_config(const double output_freq) { // VCXO runs at 96MHz, assume PLL2 reference doubler is enabled const double ref = VCXO_FREQ * 2; const int lowest_vcodiv = static_cast<int>(std::ceil(MIN_VCO_FREQ / output_freq)); - const int highest_vcodiv = static_cast<int>(std::floor(MAX_VCO_FREQ / output_freq)); + const int highest_vcodiv = + static_cast<int>(std::floor(MAX_VCO_FREQ / output_freq)); // Find the PLL2 configuration with the lowest frequency error, favoring // higher phase comparison frequencies. - double best_error = 1e10; - double best_mcr = 0.0; + double best_error = 1e10; + double best_mcr = 0.0; double best_vco_freq = _vco_freq; - int best_N = _lmk04816_regs.PLL2_N_30; - int best_R = _lmk04816_regs.PLL2_R_28; + int best_N = _lmk04816_regs.PLL2_N_30; + int best_R = _lmk04816_regs.PLL2_R_28; for (int vcodiv = lowest_vcodiv; vcodiv <= highest_vcodiv; vcodiv++) { const double try_vco_freq = vcodiv * output_freq; // Start at R=2: with a min value of 2 for R, we don't have to worry // about exceeding the maximum phase comparison frequency for PLL2. - for (int r = 2; r <= 50; r++) - { + for (int r = 2; r <= 50; r++) { // Note: We could accomplish somewhat higher resolution if we change // the N predivider to odd values as well, and we may be able to get // better spur performance by balancing the predivider and the @@ -449,56 +515,60 @@ private: boost::math::round((r * try_vco_freq) / (VCXO_PLL2_N * ref))); const double actual_mcr = (ref * VCXO_PLL2_N * n) / (vcodiv * r); - const double error = std::abs(actual_mcr - output_freq); + const double error = std::abs(actual_mcr - output_freq); if (error < best_error) { - best_error = error; - best_mcr = actual_mcr; + best_error = error; + best_mcr = actual_mcr; best_vco_freq = try_vco_freq; - best_N = n; - best_R = r; + best_N = n; + best_R = r; } } } UHD_ASSERT_THROW(best_mcr > 0.0); - _vco_freq = best_vco_freq; + _vco_freq = best_vco_freq; _lmk04816_regs.PLL2_N_30 = best_N; _lmk04816_regs.PLL2_R_28 = best_R; _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; if (fp_compare_epsilon<double>(best_error) > 0.0) { UHD_LOGGER_WARNING("X300") - << boost::format("Attempted master clock rate %0.2f MHz, got %0.2f MHz") - % (output_freq / 1e6) % (best_mcr / 1e6); + << boost::format("Attempted master clock rate %0.2f MHz, got %0.2f MHz") + % (output_freq / 1e6) % (best_mcr / 1e6); } - UHD_LOGGER_TRACE("X300") << boost::format( - "Using automatic LMK04816 PLL2 config: N=%d, R=%d, VCO=%0.2f MHz, MCR=%0.2f MHz") - % _lmk04816_regs.PLL2_N_30 % _lmk04816_regs.PLL2_R_28 - % (_vco_freq / 1e6) % (best_mcr / 1e6); + UHD_LOGGER_TRACE("X300") + << boost::format("Using automatic LMK04816 PLL2 config: N=%d, R=%d, " + "VCO=%0.2f MHz, MCR=%0.2f MHz") + % _lmk04816_regs.PLL2_N_30 % _lmk04816_regs.PLL2_R_28 + % (_vco_freq / 1e6) % (best_mcr / 1e6); return best_mcr; } - void init() { + void init() + { /* The X3xx has two primary rates. The first is the * _system_ref_rate, which is sourced from the "clock_source"/"value" field - * of the property tree, and whose value can be 10e6, 11.52e6, 23.04e6, or 30.72e6. - * The _system_ref_rate is the input to the clocking system, and - * what comes out is a disciplined master clock running at the - * _master_clock_rate. As such, only certain combinations of - * system reference rates and master clock rates are supported. - * Additionally, a subset of these will operate in "zero delay" mode. */ - - enum opmode_t { INVALID, - m10M_200M_NOZDEL, // used for debug purposes only - m10M_200M_ZDEL, // Normal mode - m11_52M_184_32M_ZDEL, // LTE with 11.52 MHz ref - m23_04M_184_32M_ZDEL, // LTE with 23.04 MHz ref - m30_72M_184_32M_ZDEL, // LTE with external ref, aka CPRI Mode - m10M_184_32M_NOZDEL, // LTE with 10 MHz ref - m10M_120M_ZDEL, // NI USRP 120 MHz Clocking - m10M_AUTO_NOZDEL }; // automatic for arbitrary clock from 10MHz ref + * of the property tree, and whose value can be 10e6, 11.52e6, 23.04e6, + * or 30.72e6. The _system_ref_rate is the input to the clocking system, and what + * comes out is a disciplined master clock running at the _master_clock_rate. As + * such, only certain combinations of system reference rates and master clock + * rates are supported. Additionally, a subset of these will operate in "zero + * delay" mode. */ + + enum opmode_t { + INVALID, + m10M_200M_NOZDEL, // used for debug purposes only + m10M_200M_ZDEL, // Normal mode + m11_52M_184_32M_ZDEL, // LTE with 11.52 MHz ref + m23_04M_184_32M_ZDEL, // LTE with 23.04 MHz ref + m30_72M_184_32M_ZDEL, // LTE with external ref, aka CPRI Mode + m10M_184_32M_NOZDEL, // LTE with 10 MHz ref + m10M_120M_ZDEL, // NI USRP 120 MHz Clocking + m10M_AUTO_NOZDEL + }; // automatic for arbitrary clock from 10MHz ref /* The default clocking mode is 10MHz reference generating a 200 MHz master * clock, in zero-delay mode. */ @@ -515,61 +585,61 @@ private: } else if (math::frequencies_are_equal(_master_clock_rate, 120e6)) { /* 10MHz reference, 120 MHz master clock rate, Zero Delay */ clocking_mode = m10M_120M_ZDEL; - } else if ( - fp_compare_epsilon<double>(_master_clock_rate) >= uhd::usrp::x300::MIN_TICK_RATE - && fp_compare_epsilon<double>(_master_clock_rate) <= uhd::usrp::x300::MAX_TICK_RATE - ) { + } else if (fp_compare_epsilon<double>(_master_clock_rate) + >= uhd::usrp::x300::MIN_TICK_RATE + && fp_compare_epsilon<double>(_master_clock_rate) + <= uhd::usrp::x300::MAX_TICK_RATE) { /* 10MHz reference, attempt to automatically configure PLL * for arbitrary master clock rate, Zero Delay */ - UHD_LOGGER_WARNING("X300") - << "Using automatic master clock PLL config. This is an experimental feature."; + UHD_LOGGER_WARNING("X300") << "Using automatic master clock PLL config. " + "This is an experimental feature."; clocking_mode = m10M_AUTO_NOZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rates when using a %f MHz reference clock are:\n" - "120 MHz, 184.32 MHz and 200 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rates when using a %f MHz " + "reference clock are:\n" + "120 MHz, 184.32 MHz and 200 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else if (math::frequencies_are_equal(_system_ref_rate, 11.52e6)) { if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) { /* 11.52MHz reference, 184.32 MHz master clock out, Zero Delay */ clocking_mode = m11_52M_184_32M_ZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rate when using a %.2f MHz reference clock is: 184.32 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rate when using a %.2f MHz " + "reference clock is: 184.32 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else if (math::frequencies_are_equal(_system_ref_rate, 23.04e6)) { if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) { /* 11.52MHz reference, 184.32 MHz master clock out, Zero Delay */ clocking_mode = m23_04M_184_32M_ZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rate when using a %.2f MHz reference clock is: 184.32 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rate when using a %.2f MHz " + "reference clock is: 184.32 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else if (math::frequencies_are_equal(_system_ref_rate, 30.72e6)) { if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) { /* 30.72MHz reference, 184.32 MHz master clock out, Zero Delay */ clocking_mode = m30_72M_184_32M_ZDEL; } else { - throw uhd::runtime_error(str( - boost::format("Invalid master clock rate: %.2f MHz.\n" - "Valid master clock rate when using a %.2f MHz reference clock is: 184.32 MHz.") - % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid master clock rate: %.2f MHz.\n" + "Valid master clock rate when using a %.2f MHz " + "reference clock is: 184.32 MHz.") + % (_master_clock_rate / 1e6) % (_system_ref_rate / 1e6))); } } else { - throw uhd::runtime_error(str( - boost::format("Invalid system reference rate: %.2f MHz.\nValid reference frequencies are: 10 MHz, 30.72 MHz.") - % (_system_ref_rate / 1e6) - )); + throw uhd::runtime_error( + str(boost::format("Invalid system reference rate: %.2f MHz.\nValid " + "reference frequencies are: 10 MHz, 30.72 MHz.") + % (_system_ref_rate / 1e6))); } UHD_ASSERT_THROW(clocking_mode != INVALID); @@ -583,29 +653,29 @@ private: * architecture. Please refer to the datasheet for more information. */ switch (clocking_mode) { case m10M_200M_NOZDEL: - _vco_freq = 2400e6; + _vco_freq = 2400e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 48; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 48; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 48 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 25; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 4; + _lmk04816_regs.PLL2_N_30 = 25; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 4; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; break; case m10M_200M_ZDEL: - _vco_freq = 2400e6; + _vco_freq = 2400e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 5; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 5; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_1600UA; // PLL2 - 96 MHz compare frequency @@ -613,26 +683,28 @@ private: _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_5; _lmk04816_regs.PLL2_R_28 = 2; - if(_hw_rev <= 4) - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; + if (_hw_rev <= 4) + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; else - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; break; case m10M_184_32M_NOZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 48; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 48; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_4KILO_OHM; @@ -644,18 +716,18 @@ private: break; case m11_52M_184_32M_ZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 1.92 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 6; - _lmk04816_regs.PLL1_R_27 = 6; + _lmk04816_regs.PLL1_N_28 = 6; + _lmk04816_regs.PLL1_R_27 = 6; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_1KILO_OHM; @@ -667,18 +739,18 @@ private: break; case m23_04M_184_32M_ZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 1.92 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 12; - _lmk04816_regs.PLL1_R_27 = 12; + _lmk04816_regs.PLL1_N_28 = 12; + _lmk04816_regs.PLL1_R_27 = 12; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_1KILO_OHM; @@ -690,18 +762,18 @@ private: break; case m30_72M_184_32M_ZDEL: - _vco_freq = 2580.48e6; + _vco_freq = 2580.48e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 2.048 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 15; - _lmk04816_regs.PLL1_R_27 = 15; + _lmk04816_regs.PLL1_N_28 = 15; + _lmk04816_regs.PLL1_R_27 = 15; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 7.68 MHz compare frequency - _lmk04816_regs.PLL2_N_30 = 168; - _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; - _lmk04816_regs.PLL2_R_28 = 25; + _lmk04816_regs.PLL2_N_30 = 168; + _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_2A; + _lmk04816_regs.PLL2_R_28 = 25; _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_3200UA; _lmk04816_regs.PLL2_R3_LF = lmk04816_regs_t::PLL2_R3_LF_1KILO_OHM; @@ -713,12 +785,12 @@ private: break; case m10M_120M_ZDEL: - _vco_freq = 2400e6; + _vco_freq = 2400e6; _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT_ZER_DELAY; // PLL1 - 2 MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 5; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 5; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - 96 MHz compare frequency @@ -726,10 +798,12 @@ private: _lmk04816_regs.PLL2_P_30 = lmk04816_regs_t::PLL2_P_30_DIV_5; _lmk04816_regs.PLL2_R_28 = 2; - if(_hw_rev <= 4) - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; + if (_hw_rev <= 4) + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_1600UA; else - _lmk04816_regs.PLL2_CP_GAIN_26 = lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; + _lmk04816_regs.PLL2_CP_GAIN_26 = + lmk04816_regs_t::PLL2_CP_GAIN_26_400UA; break; @@ -737,8 +811,8 @@ private: _lmk04816_regs.MODE = lmk04816_regs_t::MODE_DUAL_INT; // PLL1 - 2MHz compare frequency - _lmk04816_regs.PLL1_N_28 = 48; - _lmk04816_regs.PLL1_R_27 = 5; + _lmk04816_regs.PLL1_N_28 = 48; + _lmk04816_regs.PLL1_R_27 = 5; _lmk04816_regs.PLL1_CP_GAIN_27 = lmk04816_regs_t::PLL1_CP_GAIN_27_100UA; // PLL2 - this call will set _vco_freq and PLL2 P/N/R registers. @@ -751,11 +825,11 @@ private: break; }; - uint16_t master_clock_div = static_cast<uint16_t>( - std::ceil(_vco_freq / _master_clock_rate)); + uint16_t master_clock_div = + static_cast<uint16_t>(std::ceil(_vco_freq / _master_clock_rate)); - uint16_t dboard_div = static_cast<uint16_t>( - std::ceil(_vco_freq / _dboard_clock_rate)); + uint16_t dboard_div = + static_cast<uint16_t>(std::ceil(_vco_freq / _dboard_clock_rate)); /* Reset the LMK clock controller. */ _lmk04816_regs.RESET = lmk04816_regs_t::RESET_RESET; @@ -770,13 +844,13 @@ private: this->write_regs(0); // Register 1 - _lmk04816_regs.CLKout2_3_PD = lmk04816_regs_t::CLKOUT2_3_PD_POWER_UP; + _lmk04816_regs.CLKout2_3_PD = lmk04816_regs_t::CLKOUT2_3_PD_POWER_UP; _lmk04816_regs.CLKout2_3_DIV = dboard_div; // Register 2 - _lmk04816_regs.CLKout4_5_PD = lmk04816_regs_t::CLKOUT4_5_PD_POWER_UP; + _lmk04816_regs.CLKout4_5_PD = lmk04816_regs_t::CLKOUT4_5_PD_POWER_UP; _lmk04816_regs.CLKout4_5_DIV = dboard_div; // Register 3 - _lmk04816_regs.CLKout6_7_DIV = master_clock_div; + _lmk04816_regs.CLKout6_7_DIV = master_clock_div; _lmk04816_regs.CLKout6_7_OSCin_Sel = lmk04816_regs_t::CLKOUT6_7_OSCIN_SEL_VCO; // Register 4 _lmk04816_regs.CLKout8_9_DIV = master_clock_div; @@ -786,39 +860,55 @@ private: static_cast<uint16_t>(std::ceil(_vco_freq / _system_ref_rate)); // Register 6 - _lmk04816_regs.CLKout0_TYPE = lmk04816_regs_t::CLKOUT0_TYPE_LVDS; //FPGA - _lmk04816_regs.CLKout1_TYPE = lmk04816_regs_t::CLKOUT1_TYPE_P_DOWN; //CPRI feedback clock, use LVDS - _lmk04816_regs.CLKout2_TYPE = lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP; //DB_0_RX - _lmk04816_regs.CLKout3_TYPE = lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP; //DB_1_RX + _lmk04816_regs.CLKout0_TYPE = lmk04816_regs_t::CLKOUT0_TYPE_LVDS; // FPGA + _lmk04816_regs.CLKout1_TYPE = + lmk04816_regs_t::CLKOUT1_TYPE_P_DOWN; // CPRI feedback clock, use LVDS + _lmk04816_regs.CLKout2_TYPE = + lmk04816_regs_t::CLKOUT2_TYPE_LVPECL_700MVPP; // DB_0_RX + _lmk04816_regs.CLKout3_TYPE = + lmk04816_regs_t::CLKOUT3_TYPE_LVPECL_700MVPP; // DB_1_RX // Register 7 - _lmk04816_regs.CLKout4_TYPE = lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP; //DB_1_TX - _lmk04816_regs.CLKout5_TYPE = lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP; //DB_0_TX - _lmk04816_regs.CLKout6_TYPE = lmk04816_regs_t::CLKOUT6_TYPE_LVPECL_700MVPP; //DB0_DAC - _lmk04816_regs.CLKout7_TYPE = lmk04816_regs_t::CLKOUT7_TYPE_LVPECL_700MVPP; //DB1_DAC - _lmk04816_regs.CLKout8_TYPE = lmk04816_regs_t::CLKOUT8_TYPE_LVPECL_700MVPP; //DB0_ADC + _lmk04816_regs.CLKout4_TYPE = + lmk04816_regs_t::CLKOUT4_TYPE_LVPECL_700MVPP; // DB_1_TX + _lmk04816_regs.CLKout5_TYPE = + lmk04816_regs_t::CLKOUT5_TYPE_LVPECL_700MVPP; // DB_0_TX + _lmk04816_regs.CLKout6_TYPE = + lmk04816_regs_t::CLKOUT6_TYPE_LVPECL_700MVPP; // DB0_DAC + _lmk04816_regs.CLKout7_TYPE = + lmk04816_regs_t::CLKOUT7_TYPE_LVPECL_700MVPP; // DB1_DAC + _lmk04816_regs.CLKout8_TYPE = + lmk04816_regs_t::CLKOUT8_TYPE_LVPECL_700MVPP; // DB0_ADC // Register 8 - _lmk04816_regs.CLKout9_TYPE = lmk04816_regs_t::CLKOUT9_TYPE_LVPECL_700MVPP; //DB1_ADC - _lmk04816_regs.CLKout10_TYPE = lmk04816_regs_t::CLKOUT10_TYPE_LVDS; //REF_CLKOUT - _lmk04816_regs.CLKout11_TYPE = lmk04816_regs_t::CLKOUT11_TYPE_P_DOWN; //Debug header, use LVPECL + _lmk04816_regs.CLKout9_TYPE = + lmk04816_regs_t::CLKOUT9_TYPE_LVPECL_700MVPP; // DB1_ADC + _lmk04816_regs.CLKout10_TYPE = lmk04816_regs_t::CLKOUT10_TYPE_LVDS; // REF_CLKOUT + _lmk04816_regs.CLKout11_TYPE = + lmk04816_regs_t::CLKOUT11_TYPE_P_DOWN; // Debug header, use LVPECL // Register 10 - _lmk04816_regs.EN_OSCout0 = lmk04816_regs_t::EN_OSCOUT0_DISABLED; //Debug header - _lmk04816_regs.FEEDBACK_MUX = 5; //use output 10 (REF OUT) for feedback + _lmk04816_regs.EN_OSCout0 = lmk04816_regs_t::EN_OSCOUT0_DISABLED; // Debug header + _lmk04816_regs.FEEDBACK_MUX = 5; // use output 10 (REF OUT) for feedback _lmk04816_regs.EN_FEEDBACK_MUX = lmk04816_regs_t::EN_FEEDBACK_MUX_ENABLED; // Register 11 // MODE set in individual cases above _lmk04816_regs.SYNC_QUAL = lmk04816_regs_t::SYNC_QUAL_FB_MUX; - _lmk04816_regs.EN_SYNC = lmk04816_regs_t::EN_SYNC_ENABLE; - _lmk04816_regs.NO_SYNC_CLKout0_1 = lmk04816_regs_t::NO_SYNC_CLKOUT0_1_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout2_3 = lmk04816_regs_t::NO_SYNC_CLKOUT2_3_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout4_5 = lmk04816_regs_t::NO_SYNC_CLKOUT4_5_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout6_7 = lmk04816_regs_t::NO_SYNC_CLKOUT6_7_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout8_9 = lmk04816_regs_t::NO_SYNC_CLKOUT8_9_CLOCK_XY_SYNC; - _lmk04816_regs.NO_SYNC_CLKout10_11 = lmk04816_regs_t::NO_SYNC_CLKOUT10_11_CLOCK_XY_SYNC; + _lmk04816_regs.EN_SYNC = lmk04816_regs_t::EN_SYNC_ENABLE; + _lmk04816_regs.NO_SYNC_CLKout0_1 = + lmk04816_regs_t::NO_SYNC_CLKOUT0_1_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout2_3 = + lmk04816_regs_t::NO_SYNC_CLKOUT2_3_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout4_5 = + lmk04816_regs_t::NO_SYNC_CLKOUT4_5_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout6_7 = + lmk04816_regs_t::NO_SYNC_CLKOUT6_7_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout8_9 = + lmk04816_regs_t::NO_SYNC_CLKOUT8_9_CLOCK_XY_SYNC; + _lmk04816_regs.NO_SYNC_CLKout10_11 = + lmk04816_regs_t::NO_SYNC_CLKOUT10_11_CLOCK_XY_SYNC; _lmk04816_regs.SYNC_TYPE = lmk04816_regs_t::SYNC_TYPE_INPUT; // Register 12 @@ -826,14 +916,18 @@ private: /* Input Clock Configurations */ // Register 13 - _lmk04816_regs.EN_CLKin0 = lmk04816_regs_t::EN_CLKIN0_NO_VALID_USE; // This is not connected - _lmk04816_regs.EN_CLKin2 = lmk04816_regs_t::EN_CLKIN2_NO_VALID_USE; // Used only for CPRI + _lmk04816_regs.EN_CLKin0 = + lmk04816_regs_t::EN_CLKIN0_NO_VALID_USE; // This is not connected + _lmk04816_regs.EN_CLKin2 = + lmk04816_regs_t::EN_CLKIN2_NO_VALID_USE; // Used only for CPRI _lmk04816_regs.Status_CLKin1_MUX = lmk04816_regs_t::STATUS_CLKIN1_MUX_UWIRE_RB; _lmk04816_regs.CLKin_Select_MODE = lmk04816_regs_t::CLKIN_SELECT_MODE_CLKIN1_MAN; - _lmk04816_regs.HOLDOVER_MUX = lmk04816_regs_t::HOLDOVER_MUX_PLL1_R; + _lmk04816_regs.HOLDOVER_MUX = lmk04816_regs_t::HOLDOVER_MUX_PLL1_R; // Register 14 - _lmk04816_regs.Status_CLKin1_TYPE = lmk04816_regs_t::STATUS_CLKIN1_TYPE_OUT_PUSH_PULL; - _lmk04816_regs.Status_CLKin0_TYPE = lmk04816_regs_t::STATUS_CLKIN0_TYPE_OUT_PUSH_PULL; + _lmk04816_regs.Status_CLKin1_TYPE = + lmk04816_regs_t::STATUS_CLKIN1_TYPE_OUT_PUSH_PULL; + _lmk04816_regs.Status_CLKin0_TYPE = + lmk04816_regs_t::STATUS_CLKIN0_TYPE_OUT_PUSH_PULL; // Register 26 // PLL2_CP_GAIN_26 set above in individual cases @@ -848,7 +942,8 @@ private: // PLL1_N_28 and PLL2_R_28 are set in the individual cases above // Register 29 - _lmk04816_regs.PLL2_N_CAL_29 = _lmk04816_regs.PLL2_N_30; // N_CAL should always match N + _lmk04816_regs.PLL2_N_CAL_29 = + _lmk04816_regs.PLL2_N_30; // N_CAL should always match N _lmk04816_regs.OSCin_FREQ_29 = lmk04816_regs_t::OSCIN_FREQ_29_63_TO_127MHZ; // Register 30 @@ -861,12 +956,18 @@ private: _delays = X300_REV0_6_CLK_DELAYS; } - //Apply delay values - set_clock_delay(X300_CLOCK_WHICH_FPGA, _delays.fpga_dly_ns, false); - set_clock_delay(X300_CLOCK_WHICH_DB0_RX, _delays.db_rx_dly_ns, false); //Sets both Ch0 and Ch1 - set_clock_delay(X300_CLOCK_WHICH_DB0_TX, _delays.db_tx_dly_ns, false); //Sets both Ch0 and Ch1 - set_clock_delay(X300_CLOCK_WHICH_ADC0, _delays.adc_dly_ns, false); //Sets both Ch0 and Ch1 - set_clock_delay(X300_CLOCK_WHICH_DAC0, _delays.dac_dly_ns, false); //Sets both Ch0 and Ch1 + // Apply delay values + set_clock_delay(X300_CLOCK_WHICH_FPGA, _delays.fpga_dly_ns, false); + set_clock_delay(X300_CLOCK_WHICH_DB0_RX, + _delays.db_rx_dly_ns, + false); // Sets both Ch0 and Ch1 + set_clock_delay(X300_CLOCK_WHICH_DB0_TX, + _delays.db_tx_dly_ns, + false); // Sets both Ch0 and Ch1 + set_clock_delay( + X300_CLOCK_WHICH_ADC0, _delays.adc_dly_ns, false); // Sets both Ch0 and Ch1 + set_clock_delay( + X300_CLOCK_WHICH_DAC0, _delays.dac_dly_ns, false); // Sets both Ch0 and Ch1 /* Write the configuration values into the LMK */ for (uint8_t i = 1; i <= 16; ++i) { @@ -879,24 +980,25 @@ private: this->sync_clocks(); } - const spi_iface::sptr _spiface; - const int _slaveno; - const size_t _hw_rev; + const spi_iface::sptr _spiface; + const int _slaveno; + const size_t _hw_rev; // This is technically constant, but it can be coerced during initialization - double _master_clock_rate; - const double _dboard_clock_rate; - const double _system_ref_rate; - lmk04816_regs_t _lmk04816_regs; - double _vco_freq; - x300_clk_delays _delays; + double _master_clock_rate; + const double _dboard_clock_rate; + const double _system_ref_rate; + lmk04816_regs_t _lmk04816_regs; + double _vco_freq; + x300_clk_delays _delays; }; x300_clock_ctrl::sptr x300_clock_ctrl::make(uhd::spi_iface::sptr spiface, - const size_t slaveno, - const size_t hw_rev, - const double master_clock_rate, - const double dboard_clock_rate, - const double system_ref_rate) { - return sptr(new x300_clock_ctrl_impl(spiface, slaveno, hw_rev, - master_clock_rate, dboard_clock_rate, system_ref_rate)); + const size_t slaveno, + const size_t hw_rev, + const double master_clock_rate, + const double dboard_clock_rate, + const double system_ref_rate) +{ + return sptr(new x300_clock_ctrl_impl( + spiface, slaveno, hw_rev, master_clock_rate, dboard_clock_rate, system_ref_rate)); } |