aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/include
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/include')
-rw-r--r--host/lib/include/uhdlib/usrp/common/adf535x.hpp814
-rw-r--r--host/lib/include/uhdlib/usrp/common/lmx2592.hpp6
2 files changed, 450 insertions, 370 deletions
diff --git a/host/lib/include/uhdlib/usrp/common/adf535x.hpp b/host/lib/include/uhdlib/usrp/common/adf535x.hpp
index 39dfb4b2a..200610d02 100644
--- a/host/lib/include/uhdlib/usrp/common/adf535x.hpp
+++ b/host/lib/include/uhdlib/usrp/common/adf535x.hpp
@@ -9,16 +9,16 @@
#include "adf5355_regs.hpp"
#include "adf5356_regs.hpp"
-#include <uhd/utils/math.hpp>
#include <uhd/utils/log.hpp>
+#include <uhd/utils/math.hpp>
+#include <uhd/utils/safe_call.hpp>
+#include <stdint.h>
+#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/math/common_factor_rt.hpp> //gcd
+#include <algorithm>
#include <utility>
#include <vector>
-#include <algorithm>
-#include <stdint.h>
-#include <boost/format.hpp>
-#include <uhd/utils/safe_call.hpp>
class adf535x_iface
{
@@ -36,9 +36,22 @@ public:
enum feedback_sel_t { FB_SEL_FUNDAMENTAL, FB_SEL_DIVIDED };
- enum output_power_t { OUTPUT_POWER_M4DBM, OUTPUT_POWER_M1DBM, OUTPUT_POWER_2DBM, OUTPUT_POWER_5DBM };
-
- enum muxout_t { MUXOUT_3STATE, MUXOUT_DVDD, MUXOUT_DGND, MUXOUT_RDIV, MUXOUT_NDIV, MUXOUT_ALD, MUXOUT_DLD };
+ enum output_power_t {
+ OUTPUT_POWER_M4DBM,
+ OUTPUT_POWER_M1DBM,
+ OUTPUT_POWER_2DBM,
+ OUTPUT_POWER_5DBM
+ };
+
+ enum muxout_t {
+ MUXOUT_3STATE,
+ MUXOUT_DVDD,
+ MUXOUT_DGND,
+ MUXOUT_RDIV,
+ MUXOUT_NDIV,
+ MUXOUT_ALD,
+ MUXOUT_DLD
+ };
virtual void set_reference_freq(double fref, bool force = false) = 0;
@@ -52,7 +65,8 @@ public:
virtual void set_muxout_mode(muxout_t mode) = 0;
- virtual double set_frequency(double target_freq, double freq_resolution, bool flush = false) = 0;
+ virtual double set_frequency(
+ double target_freq, double freq_resolution, bool flush = false) = 0;
virtual void commit() = 0;
};
@@ -60,405 +74,471 @@ public:
using namespace uhd;
namespace {
- const double ADF535X_DOUBLER_MAX_REF_FREQ = 60e6;
- const double ADF535X_MAX_FREQ_PFD = 125e6;
-//const double ADF535X_PRESCALER_THRESH = 7e9;
-
- const double ADF535X_MIN_VCO_FREQ = 3.4e9;
-//const double ADF535X_MAX_VCO_FREQ = 6.8e9;
- const double ADF535X_MAX_OUT_FREQ = 6.8e9;
- const double ADF535X_MIN_OUT_FREQ = (3.4e9 / 64);
-//const double ADF535X_MAX_OUTB_FREQ = (6.8e9 * 2);
-//const double ADF535X_MIN_OUTB_FREQ = (3.4e9 * 2);
-
- const double ADF535X_PHASE_RESYNC_TIME = 400e-6;
-
- const uint32_t ADF535X_MOD1 = 16777216;
- const uint32_t ADF535X_MAX_MOD2 = 16383;
- const uint32_t ADF535X_MAX_FRAC2 = 16383;
-//const uint16_t ADF535X_MIN_INT_PRESCALER_89 = 75;
-}
-
-template <typename adf535x_regs_t>
-class adf535x_impl : public adf535x_iface
+const double ADF535X_DOUBLER_MAX_REF_FREQ = 60e6;
+const double ADF535X_MAX_FREQ_PFD = 125e6;
+// const double ADF535X_PRESCALER_THRESH = 7e9;
+
+const double ADF535X_MIN_VCO_FREQ = 3.4e9;
+// const double ADF535X_MAX_VCO_FREQ = 6.8e9;
+const double ADF535X_MAX_OUT_FREQ = 6.8e9;
+const double ADF535X_MIN_OUT_FREQ = (3.4e9 / 64);
+// const double ADF535X_MAX_OUTB_FREQ = (6.8e9 * 2);
+// const double ADF535X_MIN_OUTB_FREQ = (3.4e9 * 2);
+
+const double ADF535X_PHASE_RESYNC_TIME = 400e-6;
+
+const uint32_t ADF535X_MOD1 = 16777216;
+const uint32_t ADF535X_MAX_MOD2 = 16383;
+const uint32_t ADF535X_MAX_FRAC2 = 16383;
+// const uint16_t ADF535X_MIN_INT_PRESCALER_89 = 75;
+} // namespace
+
+template <typename adf535x_regs_t> class adf535x_impl : public adf535x_iface
{
public:
- explicit adf535x_impl(write_fn_t write_fn, wait_fn_t wait_fn) :
- _write_fn(std::move(write_fn)),
- _wait_fn(std::move(wait_fn)),
- _regs(),
- _rewrite_regs(true),
- _wait_time_us(0),
- _ref_freq(0.0),
- _pfd_freq(0.0),
- _fb_after_divider(true)
- {
-
- _regs.vco_band_div = 3;
- _regs.timeout = 11;
- _regs.auto_level_timeout = 30;
- _regs.synth_lock_timeout = 12;
-
- _regs.adc_clock_divider = 16;
- _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED;
- _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED;
-
- // Start with phase resync disabled and enable when reference clock is set
- _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED;
-
- set_feedback_select(FB_SEL_DIVIDED);
- }
-
- ~adf535x_impl() override
- {
- UHD_SAFE_CALL(
- _regs.power_down = adf535x_regs_t::POWER_DOWN_ENABLED;
- commit();
- )
- }
-
- void set_feedback_select(const feedback_sel_t fb_sel) override
- {
- _fb_after_divider = (fb_sel == FB_SEL_DIVIDED);
-
- if (_fb_after_divider) {
- _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_DIVIDED;
- } else {
- _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
+ explicit adf535x_impl(write_fn_t write_fn, wait_fn_t wait_fn)
+ : _write_fn(std::move(write_fn))
+ , _wait_fn(std::move(wait_fn))
+ , _regs()
+ , _rewrite_regs(true)
+ , _wait_time_us(0)
+ , _ref_freq(0.0)
+ , _pfd_freq(0.0)
+ , _fb_after_divider(true)
+ {
+ _regs.vco_band_div = 3;
+ _regs.timeout = 11;
+ _regs.auto_level_timeout = 30;
+ _regs.synth_lock_timeout = 12;
+
+ _regs.adc_clock_divider = 16;
+ _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED;
+ _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED;
+
+ // Start with phase resync disabled and enable when reference clock is set
+ _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED;
+
+ set_feedback_select(FB_SEL_DIVIDED);
}
- }
-
- void set_pfd_freq(const double pfd_freq) override
- {
- if (pfd_freq > ADF535X_MAX_FREQ_PFD) {
- UHD_LOGGER_ERROR("ADF535x") << boost::format("%f MHz is above the maximum PFD frequency of %f MHz\n")
- % (pfd_freq/1e6) % (ADF535X_MAX_FREQ_PFD/1e6);
- return;
- }
- _pfd_freq = pfd_freq;
-
- set_reference_freq(_ref_freq);
- }
- void set_reference_freq(const double fref, const bool force = false) override
- {
- //Skip the body if the reference frequency does not change
- if (uhd::math::frequencies_are_equal(fref, _ref_freq) and (not force))
- return;
-
- _ref_freq = fref;
+ ~adf535x_impl() override
+ {
+ UHD_SAFE_CALL(_regs.power_down = adf535x_regs_t::POWER_DOWN_ENABLED; commit();)
+ }
- //-----------------------------------------------------------
- //Set reference settings
- int ref_div_factor = static_cast<int>(std::floor(_ref_freq / _pfd_freq));
+ void set_feedback_select(const feedback_sel_t fb_sel) override
+ {
+ _fb_after_divider = (fb_sel == FB_SEL_DIVIDED);
- //Reference doubler for 50% duty cycle
- const bool doubler_en = (_ref_freq <= ADF535X_DOUBLER_MAX_REF_FREQ);
- if (doubler_en) {
- ref_div_factor *= 2;
+ if (_fb_after_divider) {
+ _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_DIVIDED;
+ } else {
+ _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
+ }
}
- //Reference divide-by-2 for 50% duty cycle
- // if R even, move one divide by 2 to regs.reference_divide_by_2
- const bool div2_en = (ref_div_factor % 2 == 0);
- if (div2_en) {
- ref_div_factor /= 2;
+ void set_pfd_freq(const double pfd_freq) override
+ {
+ if (pfd_freq > ADF535X_MAX_FREQ_PFD) {
+ UHD_LOGGER_ERROR("ADF535x")
+ << boost::format("%f MHz is above the maximum PFD frequency of %f MHz\n")
+ % (pfd_freq / 1e6) % (ADF535X_MAX_FREQ_PFD / 1e6);
+ return;
+ }
+ _pfd_freq = pfd_freq;
+
+ set_reference_freq(_ref_freq);
}
- _regs.reference_divide_by_2 = div2_en ?
- adf535x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED :
- adf535x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- _regs.reference_doubler = doubler_en ?
- adf535x_regs_t::REFERENCE_DOUBLER_ENABLED :
- adf535x_regs_t::REFERENCE_DOUBLER_DISABLED;
- _regs.r_counter_10_bit = ref_div_factor;
- UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0);
-
- //-----------------------------------------------------------
- //Set timeouts (code from ADI driver)
- _regs.timeout = std::max(1, std::min(int(ceil(_pfd_freq / (20e3 * 30))), 1023));
-
- UHD_ASSERT_THROW((_regs.timeout & ((uint16_t)~0x3FF)) == 0);
- _regs.synth_lock_timeout =
+ void set_reference_freq(const double fref, const bool force = false) override
+ {
+ // Skip the body if the reference frequency does not change
+ if (uhd::math::frequencies_are_equal(fref, _ref_freq) and (not force))
+ return;
+
+ _ref_freq = fref;
+
+ //-----------------------------------------------------------
+ // Set reference settings
+ int ref_div_factor = static_cast<int>(std::floor(_ref_freq / _pfd_freq));
+
+ // Reference doubler for 50% duty cycle
+ const bool doubler_en = (_ref_freq <= ADF535X_DOUBLER_MAX_REF_FREQ);
+ if (doubler_en) {
+ ref_div_factor *= 2;
+ }
+
+ // Reference divide-by-2 for 50% duty cycle
+ // if R even, move one divide by 2 to regs.reference_divide_by_2
+ const bool div2_en = (ref_div_factor % 2 == 0);
+ if (div2_en) {
+ ref_div_factor /= 2;
+ }
+
+ _regs.reference_divide_by_2 =
+ div2_en ? adf535x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED
+ : adf535x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
+ _regs.reference_doubler = doubler_en ? adf535x_regs_t::REFERENCE_DOUBLER_ENABLED
+ : adf535x_regs_t::REFERENCE_DOUBLER_DISABLED;
+ _regs.r_counter_10_bit = ref_div_factor;
+ UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0);
+
+ //-----------------------------------------------------------
+ // Set timeouts (code from ADI driver)
+ _regs.timeout = std::max(1, std::min(int(ceil(_pfd_freq / (20e3 * 30))), 1023));
+
+ UHD_ASSERT_THROW((_regs.timeout & ((uint16_t)~0x3FF)) == 0);
+ _regs.synth_lock_timeout =
static_cast<uint8_t>(ceil((_pfd_freq * 2) / (100e3 * _regs.timeout)));
- UHD_ASSERT_THROW((_regs.synth_lock_timeout & ((uint16_t)~0x1F)) == 0);
- _regs.auto_level_timeout =
+ UHD_ASSERT_THROW((_regs.synth_lock_timeout & ((uint16_t)~0x1F)) == 0);
+ _regs.auto_level_timeout =
static_cast<uint8_t>(ceil((_pfd_freq * 5) / (100e3 * _regs.timeout)));
- //-----------------------------------------------------------
- //Set VCO band divider
- _regs.vco_band_div =
- static_cast<uint8_t>(ceil(_pfd_freq / 2.4e6));
+ //-----------------------------------------------------------
+ // Set VCO band divider
+ _regs.vco_band_div = static_cast<uint8_t>(ceil(_pfd_freq / 2.4e6));
- //-----------------------------------------------------------
- //Set ADC delay (code from ADI driver)
- _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED;
- _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED;
- _regs.adc_clock_divider = std::max(1, std::min(int(ceil(((_pfd_freq / 100e3) - 2) / 4)),255));
+ //-----------------------------------------------------------
+ // Set ADC delay (code from ADI driver)
+ _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED;
+ _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED;
+ _regs.adc_clock_divider =
+ std::max(1, std::min(int(ceil(((_pfd_freq / 100e3) - 2) / 4)), 255));
- _wait_time_us = static_cast<uint32_t>(
+ _wait_time_us = static_cast<uint32_t>(
ceil(16e6 / (_pfd_freq / ((4 * _regs.adc_clock_divider) + 2))));
- //-----------------------------------------------------------
- //Phase resync
- _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_ENABLED;
-
- _regs.phase_adjust = adf535x_regs_t::PHASE_ADJUST_DISABLED;
- _regs.sd_load_reset = adf535x_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE;
- _regs.phase_resync_clk_div = static_cast<uint16_t>(
- floor(ADF535X_PHASE_RESYNC_TIME * _pfd_freq));
-
- _rewrite_regs = true;
- }
-
- double set_frequency(const double target_freq, const double freq_resolution, const bool flush = false) override
- {
- return _set_frequency(target_freq, freq_resolution, flush);
- }
-
- void set_output_power(const output_power_t power) override
- {
- typename adf535x_regs_t::output_power_t setting;
- switch (power) {
- case OUTPUT_POWER_M4DBM: setting = adf535x_regs_t::OUTPUT_POWER_M4DBM; break;
- case OUTPUT_POWER_M1DBM: setting = adf535x_regs_t::OUTPUT_POWER_M1DBM; break;
- case OUTPUT_POWER_2DBM: setting = adf535x_regs_t::OUTPUT_POWER_2DBM; break;
- case OUTPUT_POWER_5DBM: setting = adf535x_regs_t::OUTPUT_POWER_5DBM; break;
- default: UHD_THROW_INVALID_CODE_PATH();
+ //-----------------------------------------------------------
+ // Phase resync
+ _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_ENABLED;
+
+ _regs.phase_adjust = adf535x_regs_t::PHASE_ADJUST_DISABLED;
+ _regs.sd_load_reset = adf535x_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE;
+ _regs.phase_resync_clk_div =
+ static_cast<uint16_t>(floor(ADF535X_PHASE_RESYNC_TIME * _pfd_freq));
+
+ _rewrite_regs = true;
+ }
+
+ double set_frequency(const double target_freq,
+ const double freq_resolution,
+ const bool flush = false) override
+ {
+ return _set_frequency(target_freq, freq_resolution, flush);
}
- if (_regs.output_power != setting) _rewrite_regs = true;
- _regs.output_power = setting;
- }
-
- void set_output_enable(const output_t output, const bool enable) override
- {
- switch (output) {
- case RF_OUTPUT_A: _regs.rf_out_a_enabled = enable ? adf535x_regs_t::RF_OUT_A_ENABLED_ENABLED :
- adf535x_regs_t::RF_OUT_A_ENABLED_DISABLED;
- break;
- case RF_OUTPUT_B: _regs.rf_out_b_enabled = enable ? adf535x_regs_t::RF_OUT_B_ENABLED_ENABLED :
- adf535x_regs_t::RF_OUT_B_ENABLED_DISABLED;
- break;
+
+ void set_output_power(const output_power_t power) override
+ {
+ typename adf535x_regs_t::output_power_t setting;
+ switch (power) {
+ case OUTPUT_POWER_M4DBM:
+ setting = adf535x_regs_t::OUTPUT_POWER_M4DBM;
+ break;
+ case OUTPUT_POWER_M1DBM:
+ setting = adf535x_regs_t::OUTPUT_POWER_M1DBM;
+ break;
+ case OUTPUT_POWER_2DBM:
+ setting = adf535x_regs_t::OUTPUT_POWER_2DBM;
+ break;
+ case OUTPUT_POWER_5DBM:
+ setting = adf535x_regs_t::OUTPUT_POWER_5DBM;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+ if (_regs.output_power != setting)
+ _rewrite_regs = true;
+ _regs.output_power = setting;
+ }
+
+ void set_output_enable(const output_t output, const bool enable) override
+ {
+ switch (output) {
+ case RF_OUTPUT_A:
+ _regs.rf_out_a_enabled = enable
+ ? adf535x_regs_t::RF_OUT_A_ENABLED_ENABLED
+ : adf535x_regs_t::RF_OUT_A_ENABLED_DISABLED;
+ break;
+ case RF_OUTPUT_B:
+ _regs.rf_out_b_enabled = enable
+ ? adf535x_regs_t::RF_OUT_B_ENABLED_ENABLED
+ : adf535x_regs_t::RF_OUT_B_ENABLED_DISABLED;
+ break;
+ }
}
- }
-
- void set_muxout_mode(const muxout_t mode) override
- {
- switch (mode) {
- case MUXOUT_3STATE: _regs.muxout = adf535x_regs_t::MUXOUT_3STATE; break;
- case MUXOUT_DVDD: _regs.muxout = adf535x_regs_t::MUXOUT_DVDD; break;
- case MUXOUT_DGND: _regs.muxout = adf535x_regs_t::MUXOUT_DGND; break;
- case MUXOUT_RDIV: _regs.muxout = adf535x_regs_t::MUXOUT_RDIV; break;
- case MUXOUT_NDIV: _regs.muxout = adf535x_regs_t::MUXOUT_NDIV; break;
- case MUXOUT_ALD: _regs.muxout = adf535x_regs_t::MUXOUT_ANALOG_LD; break;
- case MUXOUT_DLD: _regs.muxout = adf535x_regs_t::MUXOUT_DLD; break;
- default: UHD_THROW_INVALID_CODE_PATH();
+
+ void set_muxout_mode(const muxout_t mode) override
+ {
+ switch (mode) {
+ case MUXOUT_3STATE:
+ _regs.muxout = adf535x_regs_t::MUXOUT_3STATE;
+ break;
+ case MUXOUT_DVDD:
+ _regs.muxout = adf535x_regs_t::MUXOUT_DVDD;
+ break;
+ case MUXOUT_DGND:
+ _regs.muxout = adf535x_regs_t::MUXOUT_DGND;
+ break;
+ case MUXOUT_RDIV:
+ _regs.muxout = adf535x_regs_t::MUXOUT_RDIV;
+ break;
+ case MUXOUT_NDIV:
+ _regs.muxout = adf535x_regs_t::MUXOUT_NDIV;
+ break;
+ case MUXOUT_ALD:
+ _regs.muxout = adf535x_regs_t::MUXOUT_ANALOG_LD;
+ break;
+ case MUXOUT_DLD:
+ _regs.muxout = adf535x_regs_t::MUXOUT_DLD;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
}
- }
- void commit() override
- {
- _commit();
- }
+ void commit() override
+ {
+ _commit();
+ }
protected:
- double _set_frequency(double, double, bool);
- void _commit();
-
-private: //Members
- typedef std::vector<uint32_t> addr_vtr_t;
-
- write_fn_t _write_fn;
- wait_fn_t _wait_fn;
- adf535x_regs_t _regs;
- bool _rewrite_regs;
- uint32_t _wait_time_us;
- double _ref_freq;
- double _pfd_freq;
- double _fb_after_divider;
+ double _set_frequency(double, double, bool);
+ void _commit();
+
+private: // Members
+ typedef std::vector<uint32_t> addr_vtr_t;
+
+ write_fn_t _write_fn;
+ wait_fn_t _wait_fn;
+ adf535x_regs_t _regs;
+ bool _rewrite_regs;
+ uint32_t _wait_time_us;
+ double _ref_freq;
+ double _pfd_freq;
+ double _fb_after_divider;
};
// ADF5355 Functions
template <>
-inline double adf535x_impl<adf5355_regs_t>::_set_frequency(double target_freq, double freq_resolution, bool flush)
+inline double adf535x_impl<adf5355_regs_t>::_set_frequency(
+ double target_freq, double freq_resolution, bool flush)
{
- if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) {
- throw uhd::runtime_error("requested frequency out of range.");
- }
- if ((uint32_t) freq_resolution == 0) {
- throw uhd::runtime_error("requested resolution cannot be less than 1.");
- }
-
- /* Calculate target VCOout frequency */
- //Increase RF divider until acceptable VCO frequency
- double target_vco_freq = target_freq;
- uint32_t rf_divider = 1;
- while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) {
- target_vco_freq *= 2;
- rf_divider *= 2;
- }
-
- switch (rf_divider) {
- case 1: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV1; break;
- case 2: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV2; break;
- case 4: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV4; break;
- case 8: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV8; break;
- case 16: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV16; break;
- case 32: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV32; break;
- case 64: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV64; break;
- default: UHD_THROW_INVALID_CODE_PATH();
- }
-
- //Compute fractional PLL params
- double prescaler_input_freq = target_vco_freq;
- if (_fb_after_divider) {
- prescaler_input_freq /= rf_divider;
- }
-
- const double N = prescaler_input_freq / _pfd_freq;
- const auto INT = static_cast<uint16_t>(floor(N));
- const auto FRAC1 = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1));
- const double residue = (N - INT) * ADF535X_MOD1 - FRAC1;
-
- const double gcd = boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution));
- const auto MOD2 = static_cast<uint16_t>(std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2)));
- const auto FRAC2 = static_cast<uint16_t>(std::min(ceil(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2)));
-
- const double coerced_vco_freq = _pfd_freq *
- (_fb_after_divider ? rf_divider : 1) *
- (double(INT) + ((double(FRAC1) + (double(FRAC2) / double(MOD2))) /
- double(ADF535X_MOD1)));
-
- const double coerced_out_freq = coerced_vco_freq / rf_divider;
-
- /* Update registers */
- _regs.int_16_bit = INT;
- _regs.frac1_24_bit = FRAC1;
- _regs.frac2_14_bit = FRAC2;
- _regs.mod2_14_bit = MOD2;
- _regs.phase_24_bit = 0;
-
- if (flush) commit();
- return coerced_out_freq;
+ if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) {
+ throw uhd::runtime_error("requested frequency out of range.");
+ }
+ if ((uint32_t)freq_resolution == 0) {
+ throw uhd::runtime_error("requested resolution cannot be less than 1.");
+ }
+
+ /* Calculate target VCOout frequency */
+ // Increase RF divider until acceptable VCO frequency
+ double target_vco_freq = target_freq;
+ uint32_t rf_divider = 1;
+ while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) {
+ target_vco_freq *= 2;
+ rf_divider *= 2;
+ }
+
+ switch (rf_divider) {
+ case 1:
+ _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV1;
+ break;
+ case 2:
+ _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV2;
+ break;
+ case 4:
+ _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV4;
+ break;
+ case 8:
+ _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV8;
+ break;
+ case 16:
+ _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV16;
+ break;
+ case 32:
+ _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV32;
+ break;
+ case 64:
+ _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV64;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+
+ // Compute fractional PLL params
+ double prescaler_input_freq = target_vco_freq;
+ if (_fb_after_divider) {
+ prescaler_input_freq /= rf_divider;
+ }
+
+ const double N = prescaler_input_freq / _pfd_freq;
+ const auto INT = static_cast<uint16_t>(floor(N));
+ const auto FRAC1 = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1));
+ const double residue = (N - INT) * ADF535X_MOD1 - FRAC1;
+
+ const double gcd =
+ boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution));
+ const auto MOD2 = static_cast<uint16_t>(
+ std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2)));
+ const auto FRAC2 = static_cast<uint16_t>(
+ std::min(ceil(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2)));
+
+ const double coerced_vco_freq =
+ _pfd_freq * (_fb_after_divider ? rf_divider : 1)
+ * (double(INT)
+ + ((double(FRAC1) + (double(FRAC2) / double(MOD2)))
+ / double(ADF535X_MOD1)));
+
+ const double coerced_out_freq = coerced_vco_freq / rf_divider;
+
+ /* Update registers */
+ _regs.int_16_bit = INT;
+ _regs.frac1_24_bit = FRAC1;
+ _regs.frac2_14_bit = FRAC2;
+ _regs.mod2_14_bit = MOD2;
+ _regs.phase_24_bit = 0;
+
+ if (flush)
+ commit();
+ return coerced_out_freq;
}
-template <>
-inline void adf535x_impl<adf5355_regs_t>::_commit()
+template <> inline void adf535x_impl<adf5355_regs_t>::_commit()
{
- const size_t ONE_REG = 1;
-
- if (_rewrite_regs) {
- //For a full state sync write registers in reverse order 12 - 0
- addr_vtr_t regs;
- for (uint8_t addr = 12; addr > 0; addr--) {
- regs.push_back(_regs.get_reg(addr));
+ const size_t ONE_REG = 1;
+
+ if (_rewrite_regs) {
+ // For a full state sync write registers in reverse order 12 - 0
+ addr_vtr_t regs;
+ for (uint8_t addr = 12; addr > 0; addr--) {
+ regs.push_back(_regs.get_reg(addr));
+ }
+ _write_fn(regs);
+ _wait_fn(_wait_time_us);
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
+ _rewrite_regs = false;
+ } else {
+ // Frequency update sequence from data sheet
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6)));
+ _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_ENABLED;
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4)));
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2)));
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1)));
+ _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_DISABLED;
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
+ _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED;
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4)));
+ _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED;
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
}
- _write_fn(regs);
- _wait_fn(_wait_time_us);
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
- _rewrite_regs = false;
- } else {
- //Frequency update sequence from data sheet
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6)));
- _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_ENABLED;
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4)));
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2)));
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1)));
- _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_DISABLED;
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
- _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED;
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4)));
- _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED;
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
- }
}
// ADF5356 Functions
template <>
-inline double adf535x_impl<adf5356_regs_t>::_set_frequency(double target_freq, double freq_resolution, bool flush)
+inline double adf535x_impl<adf5356_regs_t>::_set_frequency(
+ double target_freq, double freq_resolution, bool flush)
{
- if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) {
- throw uhd::runtime_error("requested frequency out of range.");
- }
- if ((uint32_t) freq_resolution == 0) {
- throw uhd::runtime_error("requested resolution cannot be less than 1.");
- }
-
- /* Calculate target VCOout frequency */
- //Increase RF divider until acceptable VCO frequency
- double target_vco_freq = target_freq;
- uint32_t rf_divider = 1;
- while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) {
- target_vco_freq *= 2;
- rf_divider *= 2;
- }
-
- switch (rf_divider) {
- case 1: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV1; break;
- case 2: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV2; break;
- case 4: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV4; break;
- case 8: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV8; break;
- case 16: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV16; break;
- case 32: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV32; break;
- case 64: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV64; break;
- default: UHD_THROW_INVALID_CODE_PATH();
- }
-
- //Compute fractional PLL params
- double prescaler_input_freq = target_vco_freq;
- if (_fb_after_divider) {
- prescaler_input_freq /= rf_divider;
- }
-
- const double N = prescaler_input_freq / _pfd_freq;
- const auto INT = static_cast<uint16_t>(floor(N));
- const auto FRAC1 = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1));
- const double residue = (N - INT) * ADF535X_MOD1 - FRAC1;
-
- const double gcd = boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution));
- const auto MOD2 = static_cast<uint16_t>(std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2)));
- const auto FRAC2 = static_cast<uint16_t>(std::min(round(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2)));
-
- const double coerced_vco_freq = _pfd_freq *
- (_fb_after_divider ? rf_divider : 1) *
- (double(INT) + ((double(FRAC1) + (double(FRAC2) / double(MOD2)))
- / double(ADF535X_MOD1)));
-
- const double coerced_out_freq = coerced_vco_freq / rf_divider;
-
- /* Update registers */
- _regs.int_16_bit = INT;
- _regs.frac1_24_bit = FRAC1;
- _regs.frac2_msb = FRAC2;
- _regs.mod2_msb = MOD2;
- _regs.phase_24_bit = 0;
-
- if (flush) commit();
- return coerced_out_freq;
+ if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) {
+ throw uhd::runtime_error("requested frequency out of range.");
+ }
+ if ((uint32_t)freq_resolution == 0) {
+ throw uhd::runtime_error("requested resolution cannot be less than 1.");
+ }
+
+ /* Calculate target VCOout frequency */
+ // Increase RF divider until acceptable VCO frequency
+ double target_vco_freq = target_freq;
+ uint32_t rf_divider = 1;
+ while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) {
+ target_vco_freq *= 2;
+ rf_divider *= 2;
+ }
+
+ switch (rf_divider) {
+ case 1:
+ _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV1;
+ break;
+ case 2:
+ _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV2;
+ break;
+ case 4:
+ _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV4;
+ break;
+ case 8:
+ _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV8;
+ break;
+ case 16:
+ _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV16;
+ break;
+ case 32:
+ _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV32;
+ break;
+ case 64:
+ _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV64;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+
+ // Compute fractional PLL params
+ double prescaler_input_freq = target_vco_freq;
+ if (_fb_after_divider) {
+ prescaler_input_freq /= rf_divider;
+ }
+
+ const double N = prescaler_input_freq / _pfd_freq;
+ const auto INT = static_cast<uint16_t>(floor(N));
+ const auto FRAC1 = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1));
+ const double residue = (N - INT) * ADF535X_MOD1 - FRAC1;
+
+ const double gcd =
+ boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution));
+ const auto MOD2 = static_cast<uint16_t>(
+ std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2)));
+ const auto FRAC2 = static_cast<uint16_t>(
+ std::min(round(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2)));
+
+ const double coerced_vco_freq =
+ _pfd_freq * (_fb_after_divider ? rf_divider : 1)
+ * (double(INT)
+ + ((double(FRAC1) + (double(FRAC2) / double(MOD2)))
+ / double(ADF535X_MOD1)));
+
+ const double coerced_out_freq = coerced_vco_freq / rf_divider;
+
+ /* Update registers */
+ _regs.int_16_bit = INT;
+ _regs.frac1_24_bit = FRAC1;
+ _regs.frac2_msb = FRAC2;
+ _regs.mod2_msb = MOD2;
+ _regs.phase_24_bit = 0;
+
+ if (flush)
+ commit();
+ return coerced_out_freq;
}
-template <>
-inline void adf535x_impl<adf5356_regs_t>::_commit()
+template <> inline void adf535x_impl<adf5356_regs_t>::_commit()
{
- const size_t ONE_REG = 1;
- if (_rewrite_regs) {
- //For a full state sync write registers in reverse order 12 - 0
- addr_vtr_t regs;
- for (uint8_t addr = 13; addr > 0; addr--) {
- regs.push_back(_regs.get_reg(addr));
+ const size_t ONE_REG = 1;
+ if (_rewrite_regs) {
+ // For a full state sync write registers in reverse order 12 - 0
+ addr_vtr_t regs;
+ for (uint8_t addr = 13; addr > 0; addr--) {
+ regs.push_back(_regs.get_reg(addr));
+ }
+ _write_fn(regs);
+ _wait_fn(_wait_time_us);
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
+ _rewrite_regs = false;
+ } else {
+ // Frequency update sequence from data sheet
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(13)));
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6)));
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2)));
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1)));
+ _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
}
- _write_fn(regs);
- _wait_fn(_wait_time_us);
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
- _rewrite_regs = false;
- } else {
- //Frequency update sequence from data sheet
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(13)));
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6)));
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2)));
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1)));
- _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));
- }
}
#endif // INCLUDED_ADF535X_HPP
diff --git a/host/lib/include/uhdlib/usrp/common/lmx2592.hpp b/host/lib/include/uhdlib/usrp/common/lmx2592.hpp
index 91beb24b7..f71ae0cf5 100644
--- a/host/lib/include/uhdlib/usrp/common/lmx2592.hpp
+++ b/host/lib/include/uhdlib/usrp/common/lmx2592.hpp
@@ -19,7 +19,8 @@
#include <utility>
#include <vector>
-class lmx2592_iface {
+class lmx2592_iface
+{
public:
typedef std::shared_ptr<lmx2592_iface> sptr;
@@ -37,8 +38,7 @@ public:
enum mash_order_t { INT_N, FIRST, SECOND, THIRD, FOURTH };
- virtual double set_frequency(
- double target_freq,
+ virtual double set_frequency(double target_freq,
const bool spur_dodging,
const double spur_dodging_threshold) = 0;