diff options
| -rw-r--r-- | host/lib/usrp/dboard/db_rfx.cpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_sbx_version4.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_version2.cpp | 26 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_version3.cpp | 26 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_version4.cpp | 24 | 
5 files changed, 53 insertions, 39 deletions
| diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 32aa3fe04..6e32b5fe5 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -358,7 +358,7 @@ double rfx_xcvr::set_lo_freq(       * The goal here to to loop though possible R dividers,       * band select clock dividers, and prescaler values.       * Calculate the A and B counters for each set of values. -     * The loop exists when it meets all of the constraints. +     * The loop exits when it meets all of the constraints.       * The resulting loop values are loaded into the registers.       *       * fvco = [P*B + A] * fref/R diff --git a/host/lib/usrp/dboard/db_sbx_version4.cpp b/host/lib/usrp/dboard/db_sbx_version4.cpp index 12bc9b76e..f091caab7 100644 --- a/host/lib/usrp/dboard/db_sbx_version4.cpp +++ b/host/lib/usrp/dboard/db_sbx_version4.cpp @@ -78,7 +78,6 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      if(ref_freq <= 12.5e6) D = adf4351_regs_t::REFERENCE_DOUBLER_ENABLED;      //increase RF divider until acceptable VCO frequency -    //start with target_freq*2 because mixer has divide by 2      double vco_freq = target_freq;      while (vco_freq < 2.2e9) {          vco_freq *= 2; @@ -86,7 +85,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      }      //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) -    adf4351_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5; +    adf4351_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;      /*       * The goal here is to loop though possible R dividers, @@ -94,7 +93,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar       * (frac) dividers.       *       * Calculate the N and F dividers for each set of values. -     * The loop exists when it meets all of the constraints. +     * The loop exits when it meets all of the constraints.       * The resulting loop values are loaded into the registers.       *       * from pg.21 @@ -128,7 +127,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      //Fractional-N calculation      MOD = 4095; //max fractional accuracy -    FRAC = int((vco_freq/pfd_freq - N)*MOD); +    FRAC = int((target_freq/pfd_freq - N)*MOD);      //Reference divide-by-2 for 50% duty cycle      // if R even, move one divide by 2 to to regs.reference_divide_by_2 @@ -138,7 +137,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      }      //actual frequency calculation -    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv); +    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T))));      UHD_LOGV(often)          << boost::format("SBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl @@ -158,6 +157,9 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      regs.frac_12_bit = FRAC;      regs.int_16_bit = N;      regs.mod_12_bit = MOD; +    regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD))); +    regs.feedback_select = adf4351_regs_t::FEEDBACK_SELECT_DIVIDED; +    regs.clock_div_mode = adf4351_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;      regs.prescaler = prescaler;      regs.r_counter_10_bit = R;      regs.reference_divide_by_2 = T; diff --git a/host/lib/usrp/dboard/db_wbx_version2.cpp b/host/lib/usrp/dboard/db_wbx_version2.cpp index ad31339e7..ef91a7553 100644 --- a/host/lib/usrp/dboard/db_wbx_version2.cpp +++ b/host/lib/usrp/dboard/db_wbx_version2.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -166,6 +166,9 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar          "WBX tune: target frequency %f Mhz"      ) % (target_freq/1e6) << std::endl; +    //start with target_freq*2 because mixer has divide by 2 +    target_freq *= 2; +      //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)      static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of          (0,23) //adf4350_regs_t::PRESCALER_4_5 @@ -193,15 +196,14 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar      if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED;      //increase RF divider until acceptable VCO frequency -    //start with target_freq*2 because mixer has divide by 2 -    double vco_freq = target_freq*2; +    double vco_freq = target_freq;      while (vco_freq < 2.2e9) {          vco_freq *= 2;          RFdiv *= 2;      }      //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) -    adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5; +    adf4350_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;      /*       * The goal here is to loop though possible R dividers, @@ -209,7 +211,7 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar       * (frac) dividers.       *       * Calculate the N and F dividers for each set of values. -     * The loop exists when it meets all of the constraints. +     * The loop exits when it meets all of the constraints.       * The resulting loop values are loaded into the registers.       *       * from pg.21 @@ -228,7 +230,7 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar          if (pfd_freq > 25e6) continue;          //ignore fractional part of tuning -        N = int(std::floor(vco_freq/pfd_freq)); +        N = int(std::floor(target_freq/pfd_freq));          //keep N > minimum int divider requirement          if (N < prescaler_to_min_int_div[prescaler]) continue; @@ -243,7 +245,7 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar      //Fractional-N calculation      MOD = 4095; //max fractional accuracy -    FRAC = int((vco_freq/pfd_freq - N)*MOD); +    FRAC = int((target_freq/pfd_freq - N)*MOD);      //Reference divide-by-2 for 50% duty cycle      // if R even, move one divide by 2 to to regs.reference_divide_by_2 @@ -253,14 +255,13 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar      }      //actual frequency calculation -    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv/2); - +    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/2);      UHD_LOGV(often)          << boost::format("WBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl -        << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s" -            ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl +        << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d" +            ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl          << boost::format("WBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"              ) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl; @@ -270,6 +271,9 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar      regs.frac_12_bit = FRAC;      regs.int_16_bit = N;      regs.mod_12_bit = MOD; +    regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD))); +    regs.feedback_select = adf4350_regs_t::FEEDBACK_SELECT_DIVIDED; +    regs.clock_div_mode = adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;      regs.prescaler = prescaler;      regs.r_counter_10_bit = R;      regs.reference_divide_by_2 = T; diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp index 7ef47edd4..95b48d182 100644 --- a/host/lib/usrp/dboard/db_wbx_version3.cpp +++ b/host/lib/usrp/dboard/db_wbx_version3.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -198,6 +198,9 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar          "WBX tune: target frequency %f Mhz"      ) % (target_freq/1e6) << std::endl; +    //start with target_freq*2 because mixer has divide by 2 +    target_freq *= 2; +      //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)      static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of          (0,23) //adf4350_regs_t::PRESCALER_4_5 @@ -225,15 +228,14 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar      if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED;      //increase RF divider until acceptable VCO frequency -    //start with target_freq*2 because mixer has divide by 2 -    double vco_freq = target_freq*2; +    double vco_freq = target_freq;      while (vco_freq < 2.2e9) {          vco_freq *= 2;          RFdiv *= 2;      }      //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) -    adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5; +    adf4350_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;      /*       * The goal here is to loop though possible R dividers, @@ -241,7 +243,7 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar       * (frac) dividers.       *       * Calculate the N and F dividers for each set of values. -     * The loop exists when it meets all of the constraints. +     * The loop exits when it meets all of the constraints.       * The resulting loop values are loaded into the registers.       *       * from pg.21 @@ -260,7 +262,7 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar          if (pfd_freq > 25e6) continue;          //ignore fractional part of tuning -        N = int(std::floor(vco_freq/pfd_freq)); +        N = int(std::floor(target_freq/pfd_freq));          //keep N > minimum int divider requirement          if (N < prescaler_to_min_int_div[prescaler]) continue; @@ -275,7 +277,7 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar      //Fractional-N calculation      MOD = 4095; //max fractional accuracy -    FRAC = int((vco_freq/pfd_freq - N)*MOD); +    FRAC = int((target_freq/pfd_freq - N)*MOD);      //Reference divide-by-2 for 50% duty cycle      // if R even, move one divide by 2 to to regs.reference_divide_by_2 @@ -285,14 +287,13 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar      }      //actual frequency calculation -    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv/2); - +    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/2);      UHD_LOGV(often)          << boost::format("WBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl -        << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s" -            ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl +        << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d" +            ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl          << boost::format("WBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"              ) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl; @@ -302,6 +303,9 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar      regs.frac_12_bit = FRAC;      regs.int_16_bit = N;      regs.mod_12_bit = MOD; +    regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD))); +    regs.feedback_select = adf4350_regs_t::FEEDBACK_SELECT_DIVIDED; +    regs.clock_div_mode = adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;      regs.prescaler = prescaler;      regs.r_counter_10_bit = R;      regs.reference_divide_by_2 = T; diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp index 3a85826cd..384e5790d 100644 --- a/host/lib/usrp/dboard/db_wbx_version4.cpp +++ b/host/lib/usrp/dboard/db_wbx_version4.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -179,6 +179,9 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar          "WBX tune: target frequency %f Mhz"      ) % (target_freq/1e6) << std::endl; +    //start with target_freq*2 because mixer has divide by 2 +    target_freq *= 2; +      //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)      static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of          (0,23) //adf4351_regs_t::PRESCALER_4_5 @@ -208,15 +211,14 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      if(ref_freq <= 12.5e6) D = adf4351_regs_t::REFERENCE_DOUBLER_ENABLED;      //increase RF divider until acceptable VCO frequency -    //start with target_freq*2 because mixer has divide by 2 -    double vco_freq = target_freq*2; +    double vco_freq = target_freq;      while (vco_freq < 2.2e9) {          vco_freq *= 2;          RFdiv *= 2;      }      //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) -    adf4351_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5; +    adf4351_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;      /*       * The goal here is to loop though possible R dividers, @@ -243,7 +245,7 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar          if (pfd_freq > 25e6) continue;          //ignore fractional part of tuning -        N = int(std::floor(vco_freq/pfd_freq)); +        N = int(std::floor(target_freq/pfd_freq));          //keep N > minimum int divider requirement          if (N < prescaler_to_min_int_div[prescaler]) continue; @@ -258,7 +260,7 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      //Fractional-N calculation      MOD = 4095; //max fractional accuracy -    FRAC = int((vco_freq/pfd_freq - N)*MOD); +    FRAC = int((target_freq/pfd_freq - N)*MOD);      //Reference divide-by-2 for 50% duty cycle      // if R even, move one divide by 2 to to regs.reference_divide_by_2 @@ -268,14 +270,13 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      }      //actual frequency calculation -    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv/2); - +    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/2);      UHD_LOGV(often)          << boost::format("WBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl -        << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s" -            ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl +        << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d" +            ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl          << boost::format("WBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"              ) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl; @@ -285,6 +286,9 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar      regs.frac_12_bit = FRAC;      regs.int_16_bit = N;      regs.mod_12_bit = MOD; +    regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD))); +    regs.feedback_select = adf4351_regs_t::FEEDBACK_SELECT_DIVIDED; +    regs.clock_div_mode = adf4351_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;      regs.prescaler = prescaler;      regs.r_counter_10_bit = R;      regs.reference_divide_by_2 = T; | 
