diff options
author | Josh Blum <josh@joshknows.com> | 2011-01-27 13:56:41 +0000 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-01-27 13:56:41 +0000 |
commit | 38185eb6f18e77245d358860872336d9998e1c07 (patch) | |
tree | 2471c9ef09c148c28cdddb3c7d71f4fd0c76c121 | |
parent | c8eed953d74186049ba94432334771724d1a8070 (diff) | |
download | uhd-38185eb6f18e77245d358860872336d9998e1c07.tar.gz uhd-38185eb6f18e77245d358860872336d9998e1c07.tar.bz2 uhd-38185eb6f18e77245d358860872336d9998e1c07.zip |
usrp-e100: tweak for clock control register calculation, works better
-rw-r--r-- | host/lib/usrp/usrp_e100/clock_ctrl.cpp | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp index 36ab1a8be..e29fe18ce 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp @@ -116,43 +116,46 @@ static clock_settings_type get_clock_settings(double rate){ const size_t X = i*ref_rate/gcd; const size_t Y = i*out_rate/gcd; - //determine chan_div, vco_div, and r_div - //and fill in that order of preference - cs.chan_divider = greatest_divisor<size_t>(X, 32); - cs.vco_divider = greatest_divisor<size_t>(X/cs.chan_divider, 6); - cs.r_counter = X/cs.chan_divider/cs.vco_divider; - - //avoid a vco divider of 1 (if possible) - if (cs.vco_divider == 1){ - cs.vco_divider = least_divisor<size_t>(cs.chan_divider, 2); - cs.chan_divider /= cs.vco_divider; - } - //determine A and B (P is fixed) cs.b_counter = Y/cs.prescaler; cs.a_counter = Y - cs.b_counter*cs.prescaler; - if (CLOCK_SETTINGS_DEBUG){ - std::cout << "X " << X << std::endl; - std::cout << "Y " << Y << std::endl; - std::cout << cs.to_pp_string() << std::endl; - } + static const double vco_bound_pad = 100e6; + for ( //calculate an r divider that fits into the bounds of the vco + cs.r_counter = size_t(cs.get_n_counter()*cs.get_ref_rate()/(1800e6 - vco_bound_pad)); + cs.r_counter <= size_t(cs.get_n_counter()*cs.get_ref_rate()/(1400e6 + vco_bound_pad)) + and cs.r_counter > 0; cs.r_counter++ + ){ + + //determine chan_div and vco_div + //and fill in that order of preference + cs.chan_divider = greatest_divisor<size_t>(X/cs.r_counter, 32); + cs.vco_divider = greatest_divisor<size_t>(X/cs.chan_divider/cs.r_counter, 6); + + //avoid a vco divider of 1 (if possible) + if (cs.vco_divider == 1){ + cs.vco_divider = least_divisor<size_t>(cs.chan_divider, 2); + cs.chan_divider /= cs.vco_divider; + } - //filter limits on the counters - if (cs.vco_divider == 1) continue; - if (cs.r_counter >= (1<<14)) continue; - if (cs.b_counter == 2) continue; - if (cs.b_counter == 1 and cs.a_counter != 0) continue; - if (cs.b_counter >= (1<<13)) continue; - if (cs.a_counter >= (1<<6)) continue; + if (CLOCK_SETTINGS_DEBUG){ + std::cout << "gcd " << gcd << std::endl; + std::cout << "X " << X << std::endl; + std::cout << "Y " << Y << std::endl; + std::cout << cs.to_pp_string() << std::endl; + } - //check the bounds on the vco - static const double vco_bound_pad = 100e6; - if (cs.get_vco_rate() > (1800e6 - vco_bound_pad)) continue; - if (cs.get_vco_rate() < (1400e6 + vco_bound_pad)) continue; + //filter limits on the counters + if (cs.vco_divider == 1) continue; + if (cs.r_counter >= (1<<14)) continue; + if (cs.b_counter == 2) continue; + if (cs.b_counter == 1 and cs.a_counter != 0) continue; + if (cs.b_counter >= (1<<13)) continue; + if (cs.a_counter >= (1<<6)) continue; - std::cout << "USRP-E100 clock control:" << std::endl << cs.to_pp_string() << std::endl; - return cs; + std::cout << "USRP-E100 clock control: " << i << std::endl << cs.to_pp_string() << std::endl; + return cs; + } } throw std::runtime_error(str(boost::format( |