aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/dboard/db_rfx.cpp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-04-19 17:47:36 -0700
committerJosh Blum <josh@joshknows.com>2011-04-19 17:47:36 -0700
commitfdee3ba82b997c709e6822aa000df8adb61c56a5 (patch)
treeed566f55ef024fd2a45d053a719010e1b2c49366 /host/lib/usrp/dboard/db_rfx.cpp
parentee424d797fc37a8c3c2a82a58218bf1e85456226 (diff)
parent290bb75de236cb53c54bb4599cc2dde924f9800e (diff)
downloaduhd-fdee3ba82b997c709e6822aa000df8adb61c56a5.tar.gz
uhd-fdee3ba82b997c709e6822aa000df8adb61c56a5.tar.bz2
uhd-fdee3ba82b997c709e6822aa000df8adb61c56a5.zip
Merge branch 'master' into next
Conflicts: fpga/usrp2/top/u2plus/Makefile.N200
Diffstat (limited to 'host/lib/usrp/dboard/db_rfx.cpp')
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp44
1 files changed, 26 insertions, 18 deletions
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 4d8222a52..f938c749a 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -294,6 +294,9 @@ double rfx_xcvr::set_lo_freq(
target_freq = _freq_range.clip(target_freq);
if (_div2[unit]) target_freq *= 2;
+ //rfx400 rx is a special case with div2 in mixer, so adf4360 must output fundamental
+ bool is_rx_rfx400 = ((get_rx_id() == 0x0024) && unit != dboard_iface::UNIT_TX);
+
//map prescalers to the register enums
static const uhd::dict<int, adf4360_regs_t::prescaler_value_t> prescaler_to_enum = map_list_of
(8, adf4360_regs_t::PRESCALER_VALUE_8_9)
@@ -309,7 +312,8 @@ double rfx_xcvr::set_lo_freq(
(8, adf4360_regs_t::BAND_SELECT_CLOCK_DIV_8)
;
- double actual_freq=0, ref_freq = this->get_iface()->get_clock_rate(unit);
+ std::vector<double> clock_rates = this->get_iface()->get_clock_rates(unit);
+ double actual_freq = 0, ref_freq = 0;
int R=0, BS=0, P=0, B=0, A=0;
/*
@@ -322,27 +326,31 @@ double rfx_xcvr::set_lo_freq(
* fvco = [P*B + A] * fref/R
* fvco*R/fref = P*B + A = N
*/
- for(R = 2; R <= 32; R+=2){
- BOOST_FOREACH(BS, bandsel_to_enum.keys()){
- if (ref_freq/R/BS > 1e6) continue; //constraint on band select clock
- BOOST_FOREACH(P, prescaler_to_enum.keys()){
- //calculate B and A from N
- double N = target_freq*R/ref_freq;
- B = int(std::floor(N/P));
- A = boost::math::iround(N - P*B);
- if (B < A or B > 8191 or B < 3 or A > 31) continue; //constraints on A, B
- //calculate the actual frequency
- actual_freq = double(P*B + A)*ref_freq/R;
- if (actual_freq/P > 300e6) continue; //constraint on prescaler output
- //constraints met: exit loop
- goto done_loop;
+ for(R = 1; R <= 32; R+=((R==1)?1:2)){
+ BOOST_FOREACH(ref_freq, uhd::reversed(uhd::sorted(clock_rates))){
+ BOOST_FOREACH(BS, bandsel_to_enum.keys()){
+ if (ref_freq/R/BS > 1e6) continue; //constraint on band select clock
+ BOOST_FOREACH(P, prescaler_to_enum.keys()){
+ //calculate B and A from N
+ double N = target_freq*R/ref_freq;
+ B = int(std::floor(N/P));
+ A = boost::math::iround(N - P*B);
+ if (B < A or B > 8191 or B < 3 or A > 31) continue; //constraints on A, B
+ //calculate the actual frequency
+ actual_freq = double(P*B + A)*ref_freq/R;
+ if (actual_freq/P > 300e6) continue; //constraint on prescaler output
+ //constraints met: exit loop
+ goto done_loop;
+ }
}
}
} done_loop:
if (rfx_debug) std::cerr << boost::format(
- "RFX tune: R=%d, BS=%d, P=%d, B=%d, A=%d"
- ) % R % BS % P % B % A << std::endl;
+ "RFX tune: R=%d, BS=%d, P=%d, B=%d, A=%d, DIV2=%d, ref=%fMHz"
+ ) % R % BS % P % B % A % int(_div2[unit] && (!is_rx_rfx400)) % (ref_freq/1e6) << std::endl;
+
+ this->get_iface()->set_clock_rate(unit, ref_freq);
//load the register values
adf4360_regs_t regs;
@@ -361,7 +369,7 @@ double rfx_xcvr::set_lo_freq(
regs.a_counter = A;
regs.b_counter = B;
regs.cp_gain_1 = adf4360_regs_t::CP_GAIN_1_SET1;
- regs.divide_by_2_output = (_div2[unit] && (get_rx_id() != 0x0024)) ? // Special case RFX400 RX Mixer divides by two
+ regs.divide_by_2_output = (_div2[unit] && (!is_rx_rfx400)) ? // Special case RFX400 RX Mixer divides by two
adf4360_regs_t::DIVIDE_BY_2_OUTPUT_DIV2 :
adf4360_regs_t::DIVIDE_BY_2_OUTPUT_FUND ;
regs.divide_by_2_prescaler = adf4360_regs_t::DIVIDE_BY_2_PRESCALER_FUND;