aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/lib/include/uhdlib/usrp/common/adf435x.hpp397
1 files changed, 251 insertions, 146 deletions
diff --git a/host/lib/include/uhdlib/usrp/common/adf435x.hpp b/host/lib/include/uhdlib/usrp/common/adf435x.hpp
index 9c573014f..056290451 100644
--- a/host/lib/include/uhdlib/usrp/common/adf435x.hpp
+++ b/host/lib/include/uhdlib/usrp/common/adf435x.hpp
@@ -8,17 +8,17 @@
#ifndef INCLUDED_ADF435X_HPP
#define INCLUDED_ADF435X_HPP
+#include "adf4350_regs.hpp"
+#include "adf4351_regs.hpp"
#include <uhd/exception.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/utils/log.hpp>
#include <uhdlib/utils/math.hpp>
#include <boost/function.hpp>
-#include <boost/thread.hpp>
#include <boost/math/special_functions/round.hpp>
+#include <boost/thread.hpp>
#include <vector>
-#include "adf4350_regs.hpp"
-#include "adf4351_regs.hpp"
class adf435x_iface
{
@@ -37,9 +37,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 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 muxout_t {
+ MUXOUT_3STATE,
+ MUXOUT_DVDD,
+ MUXOUT_DGND,
+ MUXOUT_RDIV,
+ MUXOUT_NDIV,
+ MUXOUT_ALD,
+ MUXOUT_DLD
+ };
enum tuning_mode_t { TUNING_MODE_HIGH_RESOLUTION, TUNING_MODE_LOW_SPUR };
@@ -74,7 +87,8 @@ public:
virtual void set_output_power(output_t output, output_power_t power) = 0;
- void set_output_power(output_power_t power) {
+ void set_output_power(output_power_t power)
+ {
set_output_power(RF_OUTPUT_A, power);
}
@@ -104,7 +118,8 @@ public:
virtual uhd::range_t get_int_range() = 0;
- virtual double set_frequency(double target_freq, bool int_n_mode, bool flush = false) = 0;
+ virtual double set_frequency(
+ double target_freq, bool int_n_mode, bool flush = false) = 0;
virtual void commit(void) = 0;
};
@@ -113,15 +128,16 @@ template <typename adf435x_regs_t>
class adf435x_impl : public adf435x_iface
{
public:
- adf435x_impl(write_fn_t write_fn) :
- _write_fn(write_fn),
- _regs(),
- _fb_after_divider(false),
- _reference_freq(0.0),
- _N_min(-1)
- {}
+ adf435x_impl(write_fn_t write_fn)
+ : _write_fn(write_fn)
+ , _regs()
+ , _fb_after_divider(false)
+ , _reference_freq(0.0)
+ , _N_min(-1)
+ {
+ }
- virtual ~adf435x_impl() {};
+ virtual ~adf435x_impl(){};
void set_reference_freq(double fref)
{
@@ -137,10 +153,10 @@ public:
{
if (prescaler == PRESCALER_8_9) {
_regs.prescaler = adf435x_regs_t::PRESCALER_8_9;
- _N_min = 75;
+ _N_min = 75;
} else {
_regs.prescaler = adf435x_regs_t::PRESCALER_4_5;
- _N_min = 23;
+ _N_min = 23;
}
}
@@ -149,20 +165,38 @@ public:
switch (output) {
case RF_OUTPUT_A:
switch (power) {
- case OUTPUT_POWER_M4DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M4DBM; break;
- case OUTPUT_POWER_M1DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M1DBM; break;
- case OUTPUT_POWER_2DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_2DBM; break;
- case OUTPUT_POWER_5DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_5DBM; break;
- default: UHD_THROW_INVALID_CODE_PATH();
+ case OUTPUT_POWER_M4DBM:
+ _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M4DBM;
+ break;
+ case OUTPUT_POWER_M1DBM:
+ _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M1DBM;
+ break;
+ case OUTPUT_POWER_2DBM:
+ _regs.output_power = adf435x_regs_t::OUTPUT_POWER_2DBM;
+ break;
+ case OUTPUT_POWER_5DBM:
+ _regs.output_power = adf435x_regs_t::OUTPUT_POWER_5DBM;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
}
break;
case RF_OUTPUT_B:
switch (power) {
- case OUTPUT_POWER_M4DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M4DBM; break;
- case OUTPUT_POWER_M1DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M1DBM; break;
- case OUTPUT_POWER_2DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_2DBM; break;
- case OUTPUT_POWER_5DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_5DBM; break;
- default: UHD_THROW_INVALID_CODE_PATH();
+ case OUTPUT_POWER_M4DBM:
+ _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M4DBM;
+ break;
+ case OUTPUT_POWER_M1DBM:
+ _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M1DBM;
+ break;
+ case OUTPUT_POWER_2DBM:
+ _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_2DBM;
+ break;
+ case OUTPUT_POWER_5DBM:
+ _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_5DBM;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
}
break;
default:
@@ -173,26 +207,45 @@ public:
void set_output_enable(output_t output, bool enable)
{
switch (output) {
- case RF_OUTPUT_A: _regs.rf_output_enable = enable ? adf435x_regs_t::RF_OUTPUT_ENABLE_ENABLED:
- adf435x_regs_t::RF_OUTPUT_ENABLE_DISABLED;
- break;
- case RF_OUTPUT_B: _regs.aux_output_enable = enable ? adf435x_regs_t::AUX_OUTPUT_ENABLE_ENABLED:
- adf435x_regs_t::AUX_OUTPUT_ENABLE_DISABLED;
- break;
+ case RF_OUTPUT_A:
+ _regs.rf_output_enable = enable
+ ? adf435x_regs_t::RF_OUTPUT_ENABLE_ENABLED
+ : adf435x_regs_t::RF_OUTPUT_ENABLE_DISABLED;
+ break;
+ case RF_OUTPUT_B:
+ _regs.aux_output_enable =
+ enable ? adf435x_regs_t::AUX_OUTPUT_ENABLE_ENABLED
+ : adf435x_regs_t::AUX_OUTPUT_ENABLE_DISABLED;
+ break;
}
}
void set_muxout_mode(muxout_t mode)
{
switch (mode) {
- case MUXOUT_3STATE: _regs.muxout = adf435x_regs_t::MUXOUT_3STATE; break;
- case MUXOUT_DVDD: _regs.muxout = adf435x_regs_t::MUXOUT_DVDD; break;
- case MUXOUT_DGND: _regs.muxout = adf435x_regs_t::MUXOUT_DGND; break;
- case MUXOUT_RDIV: _regs.muxout = adf435x_regs_t::MUXOUT_RDIV; break;
- case MUXOUT_NDIV: _regs.muxout = adf435x_regs_t::MUXOUT_NDIV; break;
- case MUXOUT_ALD: _regs.muxout = adf435x_regs_t::MUXOUT_ANALOG_LD; break;
- case MUXOUT_DLD: _regs.muxout = adf435x_regs_t::MUXOUT_DLD; break;
- default: UHD_THROW_INVALID_CODE_PATH();
+ case MUXOUT_3STATE:
+ _regs.muxout = adf435x_regs_t::MUXOUT_3STATE;
+ break;
+ case MUXOUT_DVDD:
+ _regs.muxout = adf435x_regs_t::MUXOUT_DVDD;
+ break;
+ case MUXOUT_DGND:
+ _regs.muxout = adf435x_regs_t::MUXOUT_DGND;
+ break;
+ case MUXOUT_RDIV:
+ _regs.muxout = adf435x_regs_t::MUXOUT_RDIV;
+ break;
+ case MUXOUT_NDIV:
+ _regs.muxout = adf435x_regs_t::MUXOUT_NDIV;
+ break;
+ case MUXOUT_ALD:
+ _regs.muxout = adf435x_regs_t::MUXOUT_ANALOG_LD;
+ break;
+ case MUXOUT_DLD:
+ _regs.muxout = adf435x_regs_t::MUXOUT_DLD;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
}
}
@@ -210,23 +263,56 @@ public:
void set_charge_pump_current(charge_pump_current_t cp_current)
{
switch (cp_current) {
- case CHARGE_PUMP_CURRENT_0_31MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_31MA; break;
- case CHARGE_PUMP_CURRENT_0_63MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_63MA; break;
- case CHARGE_PUMP_CURRENT_0_94MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_94MA; break;
- case CHARGE_PUMP_CURRENT_1_25MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_25MA; break;
- case CHARGE_PUMP_CURRENT_1_56MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_56MA; break;
- case CHARGE_PUMP_CURRENT_1_88MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_88MA; break;
- case CHARGE_PUMP_CURRENT_2_19MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_19MA; break;
- case CHARGE_PUMP_CURRENT_2_50MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_50MA; break;
- case CHARGE_PUMP_CURRENT_2_81MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_81MA; break;
- case CHARGE_PUMP_CURRENT_3_13MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_13MA; break;
- case CHARGE_PUMP_CURRENT_3_44MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_44MA; break;
- case CHARGE_PUMP_CURRENT_3_75MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_75MA; break;
- case CHARGE_PUMP_CURRENT_4_07MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_07MA; break;
- case CHARGE_PUMP_CURRENT_4_38MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_38MA; break;
- case CHARGE_PUMP_CURRENT_4_69MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_69MA; break;
- case CHARGE_PUMP_CURRENT_5_00MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_5_00MA; break;
- default: UHD_THROW_INVALID_CODE_PATH();
+ case CHARGE_PUMP_CURRENT_0_31MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_31MA;
+ break;
+ case CHARGE_PUMP_CURRENT_0_63MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_63MA;
+ break;
+ case CHARGE_PUMP_CURRENT_0_94MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_94MA;
+ break;
+ case CHARGE_PUMP_CURRENT_1_25MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_25MA;
+ break;
+ case CHARGE_PUMP_CURRENT_1_56MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_56MA;
+ break;
+ case CHARGE_PUMP_CURRENT_1_88MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_88MA;
+ break;
+ case CHARGE_PUMP_CURRENT_2_19MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_19MA;
+ break;
+ case CHARGE_PUMP_CURRENT_2_50MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_50MA;
+ break;
+ case CHARGE_PUMP_CURRENT_2_81MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_81MA;
+ break;
+ case CHARGE_PUMP_CURRENT_3_13MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_13MA;
+ break;
+ case CHARGE_PUMP_CURRENT_3_44MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_44MA;
+ break;
+ case CHARGE_PUMP_CURRENT_3_75MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_75MA;
+ break;
+ case CHARGE_PUMP_CURRENT_4_07MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_07MA;
+ break;
+ case CHARGE_PUMP_CURRENT_4_38MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_38MA;
+ break;
+ case CHARGE_PUMP_CURRENT_4_69MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_69MA;
+ break;
+ case CHARGE_PUMP_CURRENT_5_00MA:
+ _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_5_00MA;
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
}
}
@@ -262,7 +348,8 @@ public:
uhd::range_t get_int_range()
{
- if (_N_min < 0) throw uhd::runtime_error("set_prescaler must be called before get_int_range");
+ if (_N_min < 0)
+ throw uhd::runtime_error("set_prescaler must be called before get_int_range");
return uhd::range_t(_N_min, 4095);
}
@@ -274,23 +361,24 @@ public:
static const double VCO_FREQ_MIN = 2.2e9;
static const double VCO_FREQ_MAX = 4.4e9;
- //Default invalid value for actual_freq
+ // Default invalid value for actual_freq
double actual_freq = 0;
uhd::range_t rf_divider_range = _get_rfdiv_range();
- uhd::range_t int_range = get_int_range();
+ uhd::range_t int_range = get_int_range();
double pfd_freq = 0;
uint16_t R = 0, BS = 0, N = 0, FRAC = 0, MOD = 0;
uint16_t RFdiv = static_cast<uint16_t>(rf_divider_range.start());
bool D = false, T = false;
- //Reference doubler for 50% duty cycle
+ // Reference doubler for 50% duty cycle
D = (_reference_freq <= REF_DOUBLER_THRESH_FREQ);
- //increase RF divider until acceptable VCO frequency
+ // increase RF divider until acceptable VCO frequency
double vco_freq = target_freq;
- while (vco_freq < VCO_FREQ_MIN && RFdiv < static_cast<uint16_t>(rf_divider_range.stop())) {
+ while (vco_freq < VCO_FREQ_MIN
+ && RFdiv < static_cast<uint16_t>(rf_divider_range.stop())) {
vco_freq *= 2;
RFdiv *= 2;
}
@@ -313,100 +401,102 @@ public:
*/
double feedback_freq = _fb_after_divider ? target_freq : vco_freq;
- for(R = 1; R <= 1023; R+=1){
- //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T)
- pfd_freq = _reference_freq*(D?2:1)/(R*(T?2:1));
+ for (R = 1; R <= 1023; R += 1) {
+ // PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D
+ // & T)
+ pfd_freq = _reference_freq * (D ? 2 : 1) / (R * (T ? 2 : 1));
- //keep the PFD frequency at or below 25MHz (Loop Filter Bandwidth)
- if (pfd_freq > PFD_FREQ_MAX) continue;
+ // keep the PFD frequency at or below 25MHz (Loop Filter Bandwidth)
+ if (pfd_freq > PFD_FREQ_MAX)
+ continue;
- //First, ignore fractional part of tuning
- N = uint16_t(std::floor(feedback_freq/pfd_freq));
+ // First, ignore fractional part of tuning
+ N = uint16_t(std::floor(feedback_freq / pfd_freq));
- //keep N > minimum int divider requirement
- if (N < static_cast<uint16_t>(int_range.start())) continue;
+ // keep N > minimum int divider requirement
+ if (N < static_cast<uint16_t>(int_range.start()))
+ continue;
- for(BS=1; BS <= 255; BS+=1){
- //keep the band select frequency at or below band_sel_freq_max
- //constraint on band select clock
- if (pfd_freq/BS > BAND_SEL_FREQ_MAX) continue;
+ for (BS = 1; BS <= 255; BS += 1) {
+ // keep the band select frequency at or below band_sel_freq_max
+ // constraint on band select clock
+ if (pfd_freq / BS > BAND_SEL_FREQ_MAX)
+ continue;
goto done_loop;
}
- } done_loop:
+ }
+ done_loop:
double frac_part = (feedback_freq / pfd_freq) - N;
if (int_n_mode) {
- if (frac_part >= 0.5) {
+ if (frac_part >= 0.5) {
// Round integer such that actual freq is closest to target
N++;
}
FRAC = 0;
- MOD = 2;
+ MOD = 2;
} else if (_tuning_mode == TUNING_MODE_LOW_SPUR) {
std::tie(FRAC, MOD) =
uhd::math::rational_approximation(frac_part, 4095, 0.0001);
- if (MOD < 2)
- {
+ if (MOD < 2) {
FRAC *= 2;
MOD *= 2;
}
- } else
- {
+ } else {
MOD = 4095; // max fractional accuracy
FRAC = static_cast<uint16_t>(std::round(frac_part * MOD));
}
- //Reference divide-by-2 for 50% duty cycle
+ // Reference divide-by-2 for 50% duty cycle
// if R even, move one divide by 2 to to regs.reference_divide_by_2
- if(R % 2 == 0) {
+ if (R % 2 == 0) {
T = true;
R /= 2;
}
- //Typical phase resync time documented in data sheet pg.24
+ // Typical phase resync time documented in data sheet pg.24
static const double PHASE_RESYNC_TIME = 400e-6;
- //If feedback after divider, then compensation for the divider is pulled into the INT value
+ // If feedback after divider, then compensation for the divider is pulled into the
+ // INT value
int rf_div_compensation = _fb_after_divider ? 1 : RFdiv;
- //Compute the actual frequency in terms of _reference_freq, N, FRAC, MOD, D, R and T.
- actual_freq = (
- double((N + (double(FRAC)/double(MOD))) *
- (_reference_freq*(D?2:1)/(R*(T?2:1))))
- ) / rf_div_compensation;
-
- uint16_t clock_div = std::max<uint16_t>(1, uint16_t(std::ceil(PHASE_RESYNC_TIME * pfd_freq / MOD)));
- if (clock_div > 4095)
- {
- // if clock_div is larger than 12-bits, increase modulus so it
+ // Compute the actual frequency in terms of _reference_freq, N, FRAC, MOD, D, R
+ // and T.
+ actual_freq = (double((N + (double(FRAC) / double(MOD)))
+ * (_reference_freq * (D ? 2 : 1) / (R * (T ? 2 : 1)))))
+ / rf_div_compensation;
+
+ uint16_t clock_div = std::max<uint16_t>(
+ 1, uint16_t(std::ceil(PHASE_RESYNC_TIME * pfd_freq / MOD)));
+ if (clock_div > 4095) {
+ // if clock_div is larger than 12-bits, increase modulus so it
// fits. Asserts later will ensure these values are not too large
FRAC *= (clock_div >> 12) + 1;
MOD *= (clock_div >> 12) + 1;
clock_div = uint16_t(std::ceil(PHASE_RESYNC_TIME * pfd_freq / MOD));
}
- _regs.frac_12_bit = FRAC;
- _regs.int_16_bit = N;
- _regs.mod_12_bit = MOD;
- _regs.clock_divider_12_bit = clock_div;
- _regs.feedback_select = _fb_after_divider ?
- adf435x_regs_t::FEEDBACK_SELECT_DIVIDED :
- adf435x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
- _regs.clock_div_mode = _fb_after_divider ?
- adf435x_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE :
- adf435x_regs_t::CLOCK_DIV_MODE_FAST_LOCK;
- _regs.r_counter_10_bit = R;
- _regs.reference_divide_by_2 = T ?
- adf435x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED :
- adf435x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- _regs.reference_doubler = D ?
- adf435x_regs_t::REFERENCE_DOUBLER_ENABLED :
- adf435x_regs_t::REFERENCE_DOUBLER_DISABLED;
- _regs.band_select_clock_div = uint8_t(BS);
- _regs.rf_divider_select = static_cast<typename adf435x_regs_t::rf_divider_select_t>(_get_rfdiv_setting(RFdiv));
- _regs.ldf = int_n_mode ?
- adf435x_regs_t::LDF_INT_N :
- adf435x_regs_t::LDF_FRAC_N;
+ _regs.frac_12_bit = FRAC;
+ _regs.int_16_bit = N;
+ _regs.mod_12_bit = MOD;
+ _regs.clock_divider_12_bit = clock_div;
+ _regs.feedback_select = _fb_after_divider
+ ? adf435x_regs_t::FEEDBACK_SELECT_DIVIDED
+ : adf435x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
+ _regs.clock_div_mode = _fb_after_divider
+ ? adf435x_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE
+ : adf435x_regs_t::CLOCK_DIV_MODE_FAST_LOCK;
+ _regs.r_counter_10_bit = R;
+ _regs.reference_divide_by_2 = T ? adf435x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED
+ : adf435x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
+ _regs.reference_doubler = D ? adf435x_regs_t::REFERENCE_DOUBLER_ENABLED
+ : adf435x_regs_t::REFERENCE_DOUBLER_DISABLED;
+ _regs.band_select_clock_div = uint8_t(BS);
+ _regs.rf_divider_select =
+ static_cast<typename adf435x_regs_t::rf_divider_select_t>(
+ _get_rfdiv_setting(RFdiv));
+ _regs.ldf = int_n_mode ? adf435x_regs_t::LDF_INT_N : adf435x_regs_t::LDF_FRAC_N;
// clang-format off
UHD_LOG_TRACE("ADF435X", boost::format(
@@ -422,10 +512,10 @@ public:
% R % BS % N % FRAC % MOD % T % D % RFdiv);
// clang-format on
- UHD_ASSERT_THROW((_regs.frac_12_bit & ((uint16_t)~0xFFF)) == 0);
- UHD_ASSERT_THROW((_regs.mod_12_bit & ((uint16_t)~0xFFF)) == 0);
+ UHD_ASSERT_THROW((_regs.frac_12_bit & ((uint16_t)~0xFFF)) == 0);
+ UHD_ASSERT_THROW((_regs.mod_12_bit & ((uint16_t)~0xFFF)) == 0);
UHD_ASSERT_THROW((_regs.clock_divider_12_bit & ((uint16_t)~0xFFF)) == 0);
- UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0);
+ UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0);
UHD_ASSERT_THROW(vco_freq >= VCO_FREQ_MIN and vco_freq <= VCO_FREQ_MAX);
UHD_ASSERT_THROW(RFdiv >= static_cast<uint16_t>(rf_divider_range.start()));
@@ -433,21 +523,22 @@ public:
UHD_ASSERT_THROW(_regs.int_16_bit >= static_cast<uint16_t>(int_range.start()));
UHD_ASSERT_THROW(_regs.int_16_bit <= static_cast<uint16_t>(int_range.stop()));
- if (flush) commit();
+ if (flush)
+ commit();
return actual_freq;
}
void commit()
{
- //reset counters
+ // reset counters
_regs.counter_reset = adf435x_regs_t::COUNTER_RESET_ENABLED;
std::vector<uint32_t> regs;
regs.push_back(_regs.get_reg(uint32_t(2)));
_write_fn(regs);
_regs.counter_reset = adf435x_regs_t::COUNTER_RESET_DISABLED;
- //write the registers
- //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
+ // write the registers
+ // correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
regs.clear();
for (int addr = 5; addr >= 0; addr--) {
regs.push_back(_regs.get_reg(uint32_t(addr)));
@@ -459,11 +550,11 @@ protected:
uhd::range_t _get_rfdiv_range();
int _get_rfdiv_setting(uint16_t div);
- write_fn_t _write_fn;
- adf435x_regs_t _regs;
- double _fb_after_divider;
- double _reference_freq;
- int _N_min;
+ write_fn_t _write_fn;
+ adf435x_regs_t _regs;
+ double _fb_after_divider;
+ double _reference_freq;
+ int _N_min;
tuning_mode_t _tuning_mode;
};
@@ -483,12 +574,18 @@ template <>
inline int adf435x_impl<adf4350_regs_t>::_get_rfdiv_setting(uint16_t div)
{
switch (div) {
- case 1: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV1);
- case 2: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV2);
- case 4: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV4);
- case 8: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV8);
- case 16: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV16);
- default: UHD_THROW_INVALID_CODE_PATH();
+ case 1:
+ return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV1);
+ case 2:
+ return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV2);
+ case 4:
+ return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV4);
+ case 8:
+ return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV8);
+ case 16:
+ return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV16);
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
}
}
@@ -496,14 +593,22 @@ template <>
inline int adf435x_impl<adf4351_regs_t>::_get_rfdiv_setting(uint16_t div)
{
switch (div) {
- case 1: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV1);
- case 2: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV2);
- case 4: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV4);
- case 8: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV8);
- case 16: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV16);
- case 32: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV32);
- case 64: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV64);
- default: UHD_THROW_INVALID_CODE_PATH();
+ case 1:
+ return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV1);
+ case 2:
+ return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV2);
+ case 4:
+ return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV4);
+ case 8:
+ return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV8);
+ case 16:
+ return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV16);
+ case 32:
+ return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV32);
+ case 64:
+ return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV64);
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
}
}