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(  | 
