aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/common/lmx2592.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/common/lmx2592.cpp')
-rw-r--r--host/lib/usrp/common/lmx2592.cpp391
1 files changed, 181 insertions, 210 deletions
diff --git a/host/lib/usrp/common/lmx2592.cpp b/host/lib/usrp/common/lmx2592.cpp
index e6ffdfbfb..e1c85c05f 100644
--- a/host/lib/usrp/common/lmx2592.cpp
+++ b/host/lib/usrp/common/lmx2592.cpp
@@ -80,12 +80,17 @@ enum intermediate_frequency_t {
FRF_IN,
};
-const char* log_intermediate_frequency(intermediate_frequency_t inter) {
+const char* log_intermediate_frequency(intermediate_frequency_t inter)
+{
switch (inter) {
- case FRF_IN: return "FRF_IN";
- case FVCO: return "FVCO";
- case FLO: return "FLO";
- default: return "???";
+ case FRF_IN:
+ return "FRF_IN";
+ case FVCO:
+ return "FVCO";
+ case FLO:
+ return "FLO";
+ default:
+ return "???";
}
}
@@ -98,30 +103,30 @@ inline bool abs_less_than_compare(const double a, const double b)
typedef std::pair<double, intermediate_frequency_t> offset_t;
// comparator that uses absolute value on the first value of an offset_t
-inline bool offset_abs_less_than_compare(
- const offset_t a,
- const offset_t b)
+inline bool offset_abs_less_than_compare(const offset_t a, const offset_t b)
{
return std::abs(a.first) < std::abs(b.first);
}
-}
+} // namespace
-class lmx2592_impl : public lmx2592_iface {
+class lmx2592_impl : public lmx2592_iface
+{
public:
explicit lmx2592_impl(write_spi_t write_fn, read_spi_t read_fn)
: _write_fn([write_fn](const uint8_t addr, const uint16_t data) {
- const uint32_t spi_transaction =
- 0 | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT) | data;
- write_fn(spi_transaction);
- }),
- _read_fn([read_fn](const uint8_t addr) {
- const uint32_t spi_transaction =
- SPI_READ_FLAG | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT);
- return read_fn(spi_transaction);
- }),
- _regs(),
- _rewrite_regs(true) {
+ const uint32_t spi_transaction =
+ 0 | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT) | data;
+ write_fn(spi_transaction);
+ })
+ , _read_fn([read_fn](const uint8_t addr) {
+ const uint32_t spi_transaction = SPI_READ_FLAG
+ | ((addr & SPI_ADDR_MASK) << SPI_ADDR_SHIFT);
+ return read_fn(spi_transaction);
+ })
+ , _regs()
+ , _rewrite_regs(true)
+ {
UHD_LOG_TRACE("LMX2592", "Initializing Synthesizer");
// Soft Reset
@@ -133,16 +138,16 @@ public:
_regs.reset = 0;
// Set register values where driver defaults differ from the datasheet values
- _regs.acal_enable = 0;
- _regs.fcal_enable = 0;
- _regs.cal_clk_div = 0;
- _regs.vco_idac_ovr = 1;
- _regs.cp_idn = 12;
- _regs.cp_iup = 12;
- _regs.vco_idac = 350;
+ _regs.acal_enable = 0;
+ _regs.fcal_enable = 0;
+ _regs.cal_clk_div = 0;
+ _regs.vco_idac_ovr = 1;
+ _regs.cp_idn = 12;
+ _regs.cp_iup = 12;
+ _regs.vco_idac = 350;
_regs.mash_ditherer = 1;
- _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO;
- _regs.fcal_fast = 1;
+ _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO;
+ _regs.fcal_fast = 1;
// Write default register values, ensures register copy is synchronized
_rewrite_regs = true;
@@ -152,13 +157,15 @@ public:
commit();
}
- ~lmx2592_impl() override { UHD_SAFE_CALL(_regs.powerdown = 1; commit();) }
+ ~lmx2592_impl() override
+ {
+ UHD_SAFE_CALL(_regs.powerdown = 1; commit();)
+ }
- double set_frequency(
- const double target_freq,
+ double set_frequency(const double target_freq,
const bool spur_dodging = false,
- const double spur_dodging_threshold = DEFAULT_LMX2592_SPUR_DODGING_THRESHOLD)
- override
+ const double spur_dodging_threshold =
+ DEFAULT_LMX2592_SPUR_DODGING_THRESHOLD) override
{
// Enforce LMX frequency limits
if (target_freq < LMX2592_MIN_OUT_FREQ or target_freq > LMX2592_MAX_OUT_FREQ) {
@@ -187,7 +194,7 @@ public:
const int vco_multiplier = target_freq > LMX2592_MAX_VCO_FREQ ? 2 : 1;
const auto target_vco_freq = target_freq * output_divider;
- const auto core_vco_freq = target_vco_freq / vco_multiplier;
+ const auto core_vco_freq = target_vco_freq / vco_multiplier;
double input_freq = _ref_freq;
@@ -205,18 +212,20 @@ public:
input_freq /= _regs.pll_r_pre;
// Multiplier
- _regs.mult = narrow_cast<uint8_t>(std::floor(LMX2592_MAX_MULT_OUT_FREQ / input_freq));
+ _regs.mult =
+ narrow_cast<uint8_t>(std::floor(LMX2592_MAX_MULT_OUT_FREQ / input_freq));
input_freq *= _regs.mult;
// Post R divider
- _regs.pll_r = narrow_cast<uint8_t>(std::ceil(input_freq / LMX2592_MAX_POSTR_DIV_OUT_FREQ));
+ _regs.pll_r =
+ narrow_cast<uint8_t>(std::ceil(input_freq / LMX2592_MAX_POSTR_DIV_OUT_FREQ));
// Default to divide by 2, will be increased later if N exceeds its limit
- int prescaler = 2;
+ int prescaler = 2;
_regs.pll_n_pre = lmx2592_regs_t::pll_n_pre_t::PLL_N_PRE_DIVIDE_BY_2;
const int min_n_divider = LMX2592_MIN_N_DIV[_regs.mash_order];
- double pfd_freq = input_freq / _regs.pll_r;
+ double pfd_freq = input_freq / _regs.pll_r;
while (pfd_freq * (prescaler * min_n_divider) / vco_multiplier > core_vco_freq) {
_regs.pll_r++;
pfd_freq = input_freq / _regs.pll_r;
@@ -224,7 +233,7 @@ public:
// Calculate N and frac
const auto N_dot_F = target_vco_freq / (pfd_freq * prescaler);
- auto N = static_cast<uint16_t>(std::floor(N_dot_F));
+ auto N = static_cast<uint16_t>(std::floor(N_dot_F));
if (N > MAX_N_DIVIDER) {
_regs.pll_n_pre = lmx2592_regs_t::pll_n_pre_t::PLL_N_PRE_DIVIDE_BY_4;
N /= 2;
@@ -234,30 +243,37 @@ public:
// Increase VCO step size to threshold to avoid primary fractional spurs
const double min_vco_step_size = spur_dodging ? spur_dodging_threshold : 1;
// Calculate Fden
- const auto initial_fden = static_cast<uint32_t>(std::floor(pfd_freq * prescaler / min_vco_step_size));
+ const auto initial_fden =
+ static_cast<uint32_t>(std::floor(pfd_freq * prescaler / min_vco_step_size));
const auto fden = (spur_dodging) ? _find_fden(initial_fden) : initial_fden;
// Calculate Fnum
const auto initial_fnum = static_cast<uint32_t>(std::round(frac * fden));
- const auto fnum = (spur_dodging) ? _find_fnum(N, initial_fnum, fden, prescaler, pfd_freq, output_divider, spur_dodging_threshold) : initial_fnum;
+ const auto fnum = (spur_dodging) ? _find_fnum(N,
+ initial_fnum,
+ fden,
+ prescaler,
+ pfd_freq,
+ output_divider,
+ spur_dodging_threshold)
+ : initial_fnum;
// Calculate mash_seed
// if spur_dodging is true, mash_seed is the first odd value less than fden
// else mash_seed is int(fden / 2);
- const uint32_t mash_seed = (spur_dodging) ?
- _find_mash_seed(fden) :
- static_cast<uint32_t>(fden / 2);
+ const uint32_t mash_seed = (spur_dodging) ? _find_mash_seed(fden)
+ : static_cast<uint32_t>(fden / 2);
// Calculate actual Fcore_vco, Fvco, F_lo frequencies
const auto actual_fvco = pfd_freq * prescaler * (N + double(fnum) / double(fden));
const auto actual_fcore_vco = actual_fvco / vco_multiplier;
- const auto actual_f_lo = actual_fcore_vco * vco_multiplier / output_divider;
+ const auto actual_f_lo = actual_fcore_vco * vco_multiplier / output_divider;
// Write to registers
- _regs.pll_n = N;
- _regs.pll_num_lsb = narrow_cast<uint16_t>(fnum);
- _regs.pll_num_msb = narrow_cast<uint16_t>(fnum >> 16);
- _regs.pll_den_lsb = narrow_cast<uint16_t>(fden);
- _regs.pll_den_msb = narrow_cast<uint16_t>(fden >> 16);
+ _regs.pll_n = N;
+ _regs.pll_num_lsb = narrow_cast<uint16_t>(fnum);
+ _regs.pll_num_msb = narrow_cast<uint16_t>(fnum >> 16);
+ _regs.pll_den_lsb = narrow_cast<uint16_t>(fden);
+ _regs.pll_den_msb = narrow_cast<uint16_t>(fden >> 16);
_regs.mash_seed_lsb = narrow_cast<uint16_t>(mash_seed);
_regs.mash_seed_msb = narrow_cast<uint16_t>(mash_seed >> 16);
@@ -276,7 +292,8 @@ public:
return actual_f_lo;
}
- void set_mash_order(const mash_order_t mash_order) override {
+ void set_mash_order(const mash_order_t mash_order) override
+ {
if (mash_order == mash_order_t::INT_N) {
_regs.mash_order = lmx2592_regs_t::mash_order_t::MASH_ORDER_INT_MODE;
@@ -294,22 +311,26 @@ public:
}
}
- void set_reference_frequency(const double ref_freq) override {
+ void set_reference_frequency(const double ref_freq) override
+ {
if (ref_freq < LMX2592_MIN_REF_FREQ or ref_freq > LMX2592_MAX_REF_FREQ) {
- throw std::runtime_error("Reference frequency is out of bounds for the LMX2592");
+ throw std::runtime_error(
+ "Reference frequency is out of bounds for the LMX2592");
}
_ref_freq = ref_freq;
}
- void set_output_power(const output_t output, const unsigned int power) override {
+ void set_output_power(const output_t output, const unsigned int power) override
+ {
UHD_LOGGER_TRACE("LMX2592")
- << "Set output: " << (output == RF_OUTPUT_A ? "A" : "B") << " to power " << power;
+ << "Set output: " << (output == RF_OUTPUT_A ? "A" : "B") << " to power "
+ << power;
const auto MAX_POWER = 63;
if (power > MAX_POWER) {
- UHD_LOGGER_ERROR("LMX2592")
- << "Requested power level of " << power << " exceeds maximum of " << MAX_POWER;
+ UHD_LOGGER_ERROR("LMX2592") << "Requested power level of " << power
+ << " exceeds maximum of " << MAX_POWER;
return;
}
@@ -322,9 +343,11 @@ public:
commit();
}
- void set_output_enable(const output_t output, const bool enable) override {
- UHD_LOGGER_TRACE("LMX2592") << "Set output " << (output == RF_OUTPUT_A ? "A" : "B")
- << " to " << (enable ? "On" : "Off");
+ void set_output_enable(const output_t output, const bool enable) override
+ {
+ UHD_LOGGER_TRACE("LMX2592")
+ << "Set output " << (output == RF_OUTPUT_A ? "A" : "B") << " to "
+ << (enable ? "On" : "Off");
if (enable) {
_regs.chdiv_dist_pd = 0;
@@ -338,13 +361,13 @@ public:
} else {
if (output == RF_OUTPUT_A) {
- _regs.outa_pd = 1;
- _regs.vco_dista_pd = 1;
+ _regs.outa_pd = 1;
+ _regs.vco_dista_pd = 1;
_regs.chdiv_dista_en = 0;
} else {
- _regs.outb_pd = 1;
- _regs.vco_distb_pd = 1;
+ _regs.outb_pd = 1;
+ _regs.vco_distb_pd = 1;
_regs.chdiv_distb_en = 0;
}
}
@@ -357,40 +380,41 @@ public:
commit();
}
- bool get_lock_status() override {
+ bool get_lock_status() override
+ {
// SPI MISO is being driven by lock detect
// If the PLL is locked we expect to read 0xFFFF from any read, else 0x0000
- const auto value_read = _read_fn(_regs.ADDR_R0);
+ const auto value_read = _read_fn(_regs.ADDR_R0);
const auto lock_status = (value_read == 0xFFFF);
- UHD_LOG_TRACE(
- "LMX2592",
- str(boost::format("Read Lock status: 0x%04X") % static_cast<unsigned int>(value_read)));
+ UHD_LOG_TRACE("LMX2592",
+ str(boost::format("Read Lock status: 0x%04X")
+ % static_cast<unsigned int>(value_read)));
return lock_status;
}
- void commit() override {
+ void commit() override
+ {
UHD_LOGGER_DEBUG("LMX2592")
<< "Storing register cache " << (_rewrite_regs ? "completely" : "selectively")
<< " to LMX via SPI...";
- const auto changed_addrs =
- _rewrite_regs ? _regs.get_all_addrs() : _regs.get_changed_addrs<size_t>();
+ const auto changed_addrs = _rewrite_regs ? _regs.get_all_addrs()
+ : _regs.get_changed_addrs<size_t>();
for (const auto addr : changed_addrs) {
_write_fn(addr, _regs.get_reg(addr));
UHD_LOGGER_TRACE("LMX2592")
- << "Register " << std::setw(2) << static_cast<unsigned int>(addr) << ": 0x"
- << std::hex << std::uppercase << std::setw(4) << std::setfill('0')
- << static_cast<unsigned int>(_regs.get_reg(addr));
+ << "Register " << std::setw(2) << static_cast<unsigned int>(addr)
+ << ": 0x" << std::hex << std::uppercase << std::setw(4)
+ << std::setfill('0') << static_cast<unsigned int>(_regs.get_reg(addr));
}
_regs.save_state();
UHD_LOG_DEBUG("LMX2592",
- "Writing registers complete: "
- "Updated "
- << changed_addrs.size()
- << " registers.");
+ "Writing registers complete: "
+ "Updated "
+ << changed_addrs.size() << " registers.");
_rewrite_regs = false;
}
@@ -407,8 +431,8 @@ private: // Members
bool _rewrite_regs;
double _ref_freq;
- void _set_chdiv_values(const int output_divider_index) {
-
+ void _set_chdiv_values(const int output_divider_index)
+ {
// Configure divide segments and mux
const auto seg1 = LMX2592_CHDIV_SEGS[output_divider_index][0];
const auto seg2 = LMX2592_CHDIV_SEGS[output_divider_index][1];
@@ -417,12 +441,13 @@ private: // Members
_regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_POWERDOWN;
if (seg1 > 1) {
- _regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1;
+ _regs.chdiv_seg_sel =
+ lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1;
_regs.chdiv_seg1_en = 1;
- _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_DIVIDER;
- _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_DIVIDER;
- _regs.vco_dista_pd = 1;
- _regs.vco_distb_pd = 1;
+ _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_DIVIDER;
+ _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_DIVIDER;
+ _regs.vco_dista_pd = 1;
+ _regs.vco_distb_pd = 1;
_regs.chdiv_dist_pd = 0;
if (_regs.outa_pd == 0) {
@@ -434,8 +459,8 @@ private: // Members
} else {
_regs.chdiv_seg1_en = 0;
- _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO;
- _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_VCO;
+ _regs.outa_mux = lmx2592_regs_t::outa_mux_t::OUTA_MUX_VCO;
+ _regs.outb_mux = lmx2592_regs_t::outb_mux_t::OUTB_MUX_VCO;
_regs.chdiv_dist_pd = 1;
if (_regs.outa_pd == 0) {
@@ -454,7 +479,8 @@ private: // Members
if (seg2 > 1) {
_regs.chdiv_seg2_en = 1;
- _regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_AND_2;
+ _regs.chdiv_seg_sel =
+ lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_AND_2;
} else {
_regs.chdiv_seg2_en = 0;
}
@@ -473,7 +499,8 @@ private: // Members
if (seg3 > 1) {
_regs.chdiv_seg3_en = 1;
- _regs.chdiv_seg_sel = lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_2_AND_3;
+ _regs.chdiv_seg_sel =
+ lmx2592_regs_t::chdiv_seg_sel_t::CHDIV_SEG_SEL_DIV_SEG_1_2_AND_3;
} else {
_regs.chdiv_seg3_en = 0;
}
@@ -498,56 +525,33 @@ private: // Members
int _get_k(const uint32_t fden) const
{
const auto mash = _regs.mash_order;
- if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_INT_MODE or
- mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FIRST)
- {
+ if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_INT_MODE
+ or mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FIRST) {
return 1;
- }
- else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_SECOND)
- {
- if (fden % 2 != 0)
- {
+ } else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_SECOND) {
+ if (fden % 2 != 0) {
return 1;
- }
- else {
+ } else {
return 2;
}
- }
- else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_THIRD)
- {
- if (fden % 2 != 0 and fden % 3 != 0)
- {
+ } else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_THIRD) {
+ if (fden % 2 != 0 and fden % 3 != 0) {
return 1;
- }
- else if (fden % 2 == 0 and fden % 3 != 0)
- {
+ } else if (fden % 2 == 0 and fden % 3 != 0) {
return 2;
- }
- else if (fden % 2 != 0 and fden % 3 == 0)
- {
+ } else if (fden % 2 != 0 and fden % 3 == 0) {
return 3;
- }
- else
- {
+ } else {
return 6;
}
- }
- else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FOURTH)
- {
- if (fden % 2 != 0 and fden % 3 != 0)
- {
+ } else if (mash == lmx2592_regs_t::mash_order_t::MASH_ORDER_FOURTH) {
+ if (fden % 2 != 0 and fden % 3 != 0) {
return 1;
- }
- else if (fden % 2 == 0 and fden % 3 != 0)
- {
+ } else if (fden % 2 == 0 and fden % 3 != 0) {
return 3;
- }
- else if (fden % 2 != 0 and fden % 3 == 0)
- {
+ } else if (fden % 2 != 0 and fden % 3 == 0) {
return 4;
- }
- else
- {
+ } else {
return 12;
}
}
@@ -561,47 +565,38 @@ private: // Members
auto fden = initial_fden;
// mathematically, this loop should run a maximum of 4 times
// i.e. initial_fden = 6N + 4 and mash_order is third or fourth order
- for (int i = 0; i < 4; ++i)
- {
- if (_get_k(fden) == 1)
- {
- UHD_LOGGER_TRACE("LMX2592") <<
- "_find_fden(" << initial_fden << ") returned " << fden;
+ for (int i = 0; i < 4; ++i) {
+ if (_get_k(fden) == 1) {
+ UHD_LOGGER_TRACE("LMX2592")
+ << "_find_fden(" << initial_fden << ") returned " << fden;
return fden;
}
// decrement rather than increment, as incrementing fden would decrease
// the step size and violate any minimum step size that has been set
--fden;
}
- UHD_LOGGER_WARNING("LMX2592") <<
- "Unable to find suitable fractional value denominator for spur dodging on LMX2592";
- UHD_LOGGER_ERROR("LMX2592") <<
- "Spur dodging failed";
+ UHD_LOGGER_WARNING("LMX2592") << "Unable to find suitable fractional value "
+ "denominator for spur dodging on LMX2592";
+ UHD_LOGGER_ERROR("LMX2592") << "Spur dodging failed";
return initial_fden;
}
// returns the offset of the closest multiple of
// spur_frequency_base to target_frequency
// A negative offset indicates the closest multiple is at a lower frequency
- double _get_closest_spur_offset(
- double target_frequency,
- double spur_frequency_base)
+ double _get_closest_spur_offset(double target_frequency, double spur_frequency_base)
{
// find closest multiples of spur_frequency_base to target_frequency
const auto first_harmonic_number =
std::floor(target_frequency / spur_frequency_base);
- const auto second_harmonic_number =
- first_harmonic_number + 1;
+ const auto second_harmonic_number = first_harmonic_number + 1;
// calculate offsets
const auto first_spur_offset =
(first_harmonic_number * spur_frequency_base) - target_frequency;
const auto second_spur_offset =
(second_harmonic_number * spur_frequency_base) - target_frequency;
// select offset with smallest absolute value
- return std::min({
- first_spur_offset,
- second_spur_offset },
- abs_less_than_compare);
+ return std::min({first_spur_offset, second_spur_offset}, abs_less_than_compare);
}
// returns the closest spur offset among 4 different spurs
@@ -611,8 +606,7 @@ private: // Members
// 3. Reference to Fvco spur
// 4. Reference to Flo spur
// A negative offset indicates the closest spur is at a lower frequency
- offset_t _get_min_offset_frequency(
- const uint16_t N,
+ offset_t _get_min_offset_frequency(const uint16_t N,
const uint32_t fnum,
const uint32_t fden,
const int prescaler,
@@ -620,10 +614,10 @@ private: // Members
const int output_divider)
{
// Calculate intermediate values
- const auto fref = _ref_freq;
+ const auto fref = _ref_freq;
const auto frf_in = pfd_freq * (N + double(fnum) / double(fden));
- const auto fvco = frf_in * prescaler;
- const auto flo = fvco / output_divider;
+ const auto fvco = frf_in * prescaler;
+ const auto flo = fvco / output_divider;
// the minimum offset is the smallest absolute value of these 4 values
// as calculated by the _get_closest_spur_offset function
@@ -631,23 +625,19 @@ private: // Members
// in order to calculate the necessary frequency shift
// Integer Boundary:
- const offset_t ib_spur = { _get_closest_spur_offset(frf_in, pfd_freq), FRF_IN };
+ const offset_t ib_spur = {_get_closest_spur_offset(frf_in, pfd_freq), FRF_IN};
// PFD Offset Spur:
- const offset_t pfd_offset_spur = { _get_closest_spur_offset(fvco, pfd_freq), FVCO };
+ const offset_t pfd_offset_spur = {_get_closest_spur_offset(fvco, pfd_freq), FVCO};
// Reference to Fvco Spur:
- const offset_t fvco_spur = { _get_closest_spur_offset(fvco, fref), FVCO };
+ const offset_t fvco_spur = {_get_closest_spur_offset(fvco, fref), FVCO};
// Reference to F_lo Spur:
- const offset_t flo_spur = { _get_closest_spur_offset(flo, fref), FLO };
+ const offset_t flo_spur = {_get_closest_spur_offset(flo, fref), FLO};
// use min with special comparator for minimal absolute value
- return std::min({
- ib_spur,
- pfd_offset_spur,
- fvco_spur,
- flo_spur},
+ return std::min({ib_spur, pfd_offset_spur, fvco_spur, flo_spur},
offset_abs_less_than_compare);
}
@@ -659,8 +649,7 @@ private: // Members
// PFD frequency will be at least 10x larger than the step size of
// (fnum / fden). This function only considers at least 50% potential
// values of fnum, and does not consider changes to N.
- uint32_t _find_fnum(
- const uint16_t N,
+ uint32_t _find_fnum(const uint16_t N,
const uint32_t initial_fnum,
const uint32_t fden,
const int prescaler,
@@ -669,40 +658,28 @@ private: // Members
const double spur_dodging_threshold)
{
auto fnum = initial_fnum;
- auto min_offset = _get_min_offset_frequency(
- N,
- fnum,
- fden,
- prescaler,
- pfd_freq,
- output_divider);
-
- UHD_LOGGER_TRACE("LMX2592") <<
- "closest spur is at " << min_offset.first <<
- " to " << log_intermediate_frequency(min_offset.second);
+ auto min_offset =
+ _get_min_offset_frequency(N, fnum, fden, prescaler, pfd_freq, output_divider);
+
+ UHD_LOGGER_TRACE("LMX2592") << "closest spur is at " << min_offset.first << " to "
+ << log_intermediate_frequency(min_offset.second);
// shift away from the closest integer boundary i.e. towards 0.5
const double delta_fnum_sign = ((((double)fnum) / ((double)fden)) < 0.5) ? 1 : -1;
- while (std::abs(min_offset.first) < spur_dodging_threshold)
- {
+ while (std::abs(min_offset.first) < spur_dodging_threshold) {
double shift = spur_dodging_threshold;
// if the spur is in the same direction as the desired shift direction...
- if (std::signbit(min_offset.first) == std::signbit(delta_fnum_sign))
- {
+ if (std::signbit(min_offset.first) == std::signbit(delta_fnum_sign)) {
shift += std::abs(min_offset.first);
- }
- else {
+ } else {
shift -= std::abs(min_offset.first);
}
// convert shift of IF value to shift of Frf_in
- if (min_offset.second == FVCO)
- {
+ if (min_offset.second == FVCO) {
shift /= prescaler;
- }
- else if (min_offset.second == FLO)
- {
+ } else if (min_offset.second == FLO) {
shift /= prescaler;
shift *= output_divider;
}
@@ -710,33 +687,27 @@ private: // Members
double delta_fnum_value = std::ceil((shift / pfd_freq) * fden);
fnum += narrow_cast<int32_t>(delta_fnum_value * delta_fnum_sign);
- UHD_LOGGER_TRACE("LMX2592") <<
- "adjusting fnum by " << (delta_fnum_value * delta_fnum_sign);
+ UHD_LOGGER_TRACE("LMX2592")
+ << "adjusting fnum by " << (delta_fnum_value * delta_fnum_sign);
// fnum is unsigned, so this also checks for underflow
- if (fnum >= fden)
- {
- UHD_LOGGER_WARNING("LMX2592") <<
- "Unable to find suitable fractional value numerator for spur dodging on LMX2592";
- UHD_LOGGER_ERROR("LMX2592") <<
- "Spur dodging failed";
+ if (fnum >= fden) {
+ UHD_LOGGER_WARNING("LMX2592")
+ << "Unable to find suitable fractional value numerator for spur "
+ "dodging on LMX2592";
+ UHD_LOGGER_ERROR("LMX2592") << "Spur dodging failed";
return initial_fnum;
}
min_offset = _get_min_offset_frequency(
- N,
- fnum,
- fden,
- prescaler,
- pfd_freq,
- output_divider);
-
- UHD_LOGGER_TRACE("LMX2592") <<
- "closest spur is at " << min_offset.first <<
- " to " << log_intermediate_frequency(min_offset.second);
+ N, fnum, fden, prescaler, pfd_freq, output_divider);
+
+ UHD_LOGGER_TRACE("LMX2592")
+ << "closest spur is at " << min_offset.first << " to "
+ << log_intermediate_frequency(min_offset.second);
}
- UHD_LOGGER_TRACE("LMX2592") <<
- "_find_fnum(" << initial_fnum << ") returned " << fnum;
+ UHD_LOGGER_TRACE("LMX2592")
+ << "_find_fnum(" << initial_fnum << ") returned " << fnum;
return fnum;
}
@@ -745,13 +716,13 @@ private: // Members
{
if (fden < 2) {
return 1;
- }
- else {
+ } else {
return (fden - 2) | 0x1;
}
};
};
-lmx2592_impl::sptr lmx2592_iface::make(write_spi_t write, read_spi_t read) {
+lmx2592_impl::sptr lmx2592_iface::make(write_spi_t write, read_spi_t read)
+{
return std::make_shared<lmx2592_impl>(write, read);
}