diff options
| -rw-r--r-- | host/lib/include/uhdlib/usrp/common/adf535x.hpp | 814 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/usrp/common/lmx2592.hpp | 6 | ||||
| -rw-r--r-- | host/lib/usrp/b100/clock_ctrl.cpp | 506 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_io_impl.cpp | 527 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad936x_manager.cpp | 247 | 
5 files changed, 1129 insertions, 971 deletions
diff --git a/host/lib/include/uhdlib/usrp/common/adf535x.hpp b/host/lib/include/uhdlib/usrp/common/adf535x.hpp index 39dfb4b2a..200610d02 100644 --- a/host/lib/include/uhdlib/usrp/common/adf535x.hpp +++ b/host/lib/include/uhdlib/usrp/common/adf535x.hpp @@ -9,16 +9,16 @@  #include "adf5355_regs.hpp"  #include "adf5356_regs.hpp" -#include <uhd/utils/math.hpp>  #include <uhd/utils/log.hpp> +#include <uhd/utils/math.hpp> +#include <uhd/utils/safe_call.hpp> +#include <stdint.h> +#include <boost/format.hpp>  #include <boost/function.hpp>  #include <boost/math/common_factor_rt.hpp> //gcd +#include <algorithm>  #include <utility>  #include <vector> -#include <algorithm> -#include <stdint.h> -#include <boost/format.hpp> -#include <uhd/utils/safe_call.hpp>  class adf535x_iface  { @@ -36,9 +36,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 muxout_t { MUXOUT_3STATE, MUXOUT_DVDD, MUXOUT_DGND, MUXOUT_RDIV, MUXOUT_NDIV, MUXOUT_ALD, MUXOUT_DLD }; +    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 +    };      virtual void set_reference_freq(double fref, bool force = false) = 0; @@ -52,7 +65,8 @@ public:      virtual void set_muxout_mode(muxout_t mode) = 0; -    virtual double set_frequency(double target_freq, double freq_resolution, bool flush = false) = 0; +    virtual double set_frequency( +        double target_freq, double freq_resolution, bool flush = false) = 0;      virtual void commit() = 0;  }; @@ -60,405 +74,471 @@ public:  using namespace uhd;  namespace { -  const double ADF535X_DOUBLER_MAX_REF_FREQ    = 60e6; -  const double ADF535X_MAX_FREQ_PFD            = 125e6; -//const double ADF535X_PRESCALER_THRESH        = 7e9; - -  const double ADF535X_MIN_VCO_FREQ            = 3.4e9; -//const double ADF535X_MAX_VCO_FREQ            = 6.8e9; -  const double ADF535X_MAX_OUT_FREQ            = 6.8e9; -  const double ADF535X_MIN_OUT_FREQ            = (3.4e9 / 64); -//const double ADF535X_MAX_OUTB_FREQ           = (6.8e9 * 2); -//const double ADF535X_MIN_OUTB_FREQ           = (3.4e9 * 2); - -  const double ADF535X_PHASE_RESYNC_TIME       = 400e-6; - -  const uint32_t ADF535X_MOD1           = 16777216; -  const uint32_t ADF535X_MAX_MOD2       = 16383; -  const uint32_t ADF535X_MAX_FRAC2      = 16383; -//const uint16_t ADF535X_MIN_INT_PRESCALER_89 = 75; -} - -template <typename adf535x_regs_t> -class adf535x_impl : public adf535x_iface +const double ADF535X_DOUBLER_MAX_REF_FREQ = 60e6; +const double ADF535X_MAX_FREQ_PFD         = 125e6; +// const double ADF535X_PRESCALER_THRESH        = 7e9; + +const double ADF535X_MIN_VCO_FREQ = 3.4e9; +// const double ADF535X_MAX_VCO_FREQ            = 6.8e9; +const double ADF535X_MAX_OUT_FREQ = 6.8e9; +const double ADF535X_MIN_OUT_FREQ = (3.4e9 / 64); +// const double ADF535X_MAX_OUTB_FREQ           = (6.8e9 * 2); +// const double ADF535X_MIN_OUTB_FREQ           = (3.4e9 * 2); + +const double ADF535X_PHASE_RESYNC_TIME = 400e-6; + +const uint32_t ADF535X_MOD1      = 16777216; +const uint32_t ADF535X_MAX_MOD2  = 16383; +const uint32_t ADF535X_MAX_FRAC2 = 16383; +// const uint16_t ADF535X_MIN_INT_PRESCALER_89 = 75; +} // namespace + +template <typename adf535x_regs_t> class adf535x_impl : public adf535x_iface  {  public: -  explicit adf535x_impl(write_fn_t write_fn, wait_fn_t wait_fn) : -          _write_fn(std::move(write_fn)), -          _wait_fn(std::move(wait_fn)), -          _regs(), -          _rewrite_regs(true), -          _wait_time_us(0), -          _ref_freq(0.0), -          _pfd_freq(0.0), -          _fb_after_divider(true) -  { - -    _regs.vco_band_div = 3; -    _regs.timeout = 11; -    _regs.auto_level_timeout = 30; -    _regs.synth_lock_timeout = 12; - -    _regs.adc_clock_divider = 16; -    _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED; -    _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED; - -    // Start with phase resync disabled and enable when reference clock is set -    _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED; - -    set_feedback_select(FB_SEL_DIVIDED); -  } - -  ~adf535x_impl() override -  { -    UHD_SAFE_CALL( -      _regs.power_down = adf535x_regs_t::POWER_DOWN_ENABLED; -      commit(); -    ) -  } - -  void set_feedback_select(const feedback_sel_t fb_sel) override -  { -    _fb_after_divider = (fb_sel == FB_SEL_DIVIDED); - -    if (_fb_after_divider) { -      _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_DIVIDED; -    } else { -      _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; +    explicit adf535x_impl(write_fn_t write_fn, wait_fn_t wait_fn) +        : _write_fn(std::move(write_fn)) +        , _wait_fn(std::move(wait_fn)) +        , _regs() +        , _rewrite_regs(true) +        , _wait_time_us(0) +        , _ref_freq(0.0) +        , _pfd_freq(0.0) +        , _fb_after_divider(true) +    { +        _regs.vco_band_div       = 3; +        _regs.timeout            = 11; +        _regs.auto_level_timeout = 30; +        _regs.synth_lock_timeout = 12; + +        _regs.adc_clock_divider = 16; +        _regs.adc_conversion    = adf535x_regs_t::ADC_CONVERSION_ENABLED; +        _regs.adc_enable        = adf535x_regs_t::ADC_ENABLE_ENABLED; + +        // Start with phase resync disabled and enable when reference clock is set +        _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED; + +        set_feedback_select(FB_SEL_DIVIDED);      } -  } - -  void set_pfd_freq(const double pfd_freq) override -  { -    if (pfd_freq > ADF535X_MAX_FREQ_PFD) { -        UHD_LOGGER_ERROR("ADF535x") << boost::format("%f MHz is above the maximum PFD frequency of %f MHz\n") -                % (pfd_freq/1e6) % (ADF535X_MAX_FREQ_PFD/1e6); -      return; -    } -    _pfd_freq = pfd_freq; - -    set_reference_freq(_ref_freq); -  } -  void set_reference_freq(const double fref, const bool force = false) override -  { -    //Skip the body if the reference frequency does not change -    if (uhd::math::frequencies_are_equal(fref, _ref_freq) and (not force)) -      return; - -    _ref_freq = fref; +    ~adf535x_impl() override +    { +        UHD_SAFE_CALL(_regs.power_down = adf535x_regs_t::POWER_DOWN_ENABLED; commit();) +    } -    //----------------------------------------------------------- -    //Set reference settings -    int ref_div_factor = static_cast<int>(std::floor(_ref_freq / _pfd_freq)); +    void set_feedback_select(const feedback_sel_t fb_sel) override +    { +        _fb_after_divider = (fb_sel == FB_SEL_DIVIDED); -    //Reference doubler for 50% duty cycle -    const bool doubler_en = (_ref_freq <= ADF535X_DOUBLER_MAX_REF_FREQ); -    if (doubler_en) { -      ref_div_factor *= 2; +        if (_fb_after_divider) { +            _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_DIVIDED; +        } else { +            _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; +        }      } -    //Reference divide-by-2 for 50% duty cycle -    // if R even, move one divide by 2 to regs.reference_divide_by_2 -    const bool div2_en = (ref_div_factor % 2 == 0); -    if (div2_en) { -      ref_div_factor /= 2; +    void set_pfd_freq(const double pfd_freq) override +    { +        if (pfd_freq > ADF535X_MAX_FREQ_PFD) { +            UHD_LOGGER_ERROR("ADF535x") +                << boost::format("%f MHz is above the maximum PFD frequency of %f MHz\n") +                       % (pfd_freq / 1e6) % (ADF535X_MAX_FREQ_PFD / 1e6); +            return; +        } +        _pfd_freq = pfd_freq; + +        set_reference_freq(_ref_freq);      } -    _regs.reference_divide_by_2 = div2_en ? -                                  adf535x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : -                                  adf535x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; -    _regs.reference_doubler = doubler_en ? -                              adf535x_regs_t::REFERENCE_DOUBLER_ENABLED : -                              adf535x_regs_t::REFERENCE_DOUBLER_DISABLED; -    _regs.r_counter_10_bit = ref_div_factor; -    UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0); - -    //----------------------------------------------------------- -    //Set timeouts (code from ADI driver) -    _regs.timeout = std::max(1, std::min(int(ceil(_pfd_freq / (20e3 * 30))), 1023)); - -    UHD_ASSERT_THROW((_regs.timeout & ((uint16_t)~0x3FF)) == 0); -    _regs.synth_lock_timeout = +    void set_reference_freq(const double fref, const bool force = false) override +    { +        // Skip the body if the reference frequency does not change +        if (uhd::math::frequencies_are_equal(fref, _ref_freq) and (not force)) +            return; + +        _ref_freq = fref; + +        //----------------------------------------------------------- +        // Set reference settings +        int ref_div_factor = static_cast<int>(std::floor(_ref_freq / _pfd_freq)); + +        // Reference doubler for 50% duty cycle +        const bool doubler_en = (_ref_freq <= ADF535X_DOUBLER_MAX_REF_FREQ); +        if (doubler_en) { +            ref_div_factor *= 2; +        } + +        // Reference divide-by-2 for 50% duty cycle +        // if R even, move one divide by 2 to regs.reference_divide_by_2 +        const bool div2_en = (ref_div_factor % 2 == 0); +        if (div2_en) { +            ref_div_factor /= 2; +        } + +        _regs.reference_divide_by_2 = +            div2_en ? adf535x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED +                    : adf535x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; +        _regs.reference_doubler = doubler_en ? adf535x_regs_t::REFERENCE_DOUBLER_ENABLED +                                             : adf535x_regs_t::REFERENCE_DOUBLER_DISABLED; +        _regs.r_counter_10_bit = ref_div_factor; +        UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0); + +        //----------------------------------------------------------- +        // Set timeouts (code from ADI driver) +        _regs.timeout = std::max(1, std::min(int(ceil(_pfd_freq / (20e3 * 30))), 1023)); + +        UHD_ASSERT_THROW((_regs.timeout & ((uint16_t)~0x3FF)) == 0); +        _regs.synth_lock_timeout =              static_cast<uint8_t>(ceil((_pfd_freq * 2) / (100e3 * _regs.timeout))); -    UHD_ASSERT_THROW((_regs.synth_lock_timeout & ((uint16_t)~0x1F)) == 0); -    _regs.auto_level_timeout = +        UHD_ASSERT_THROW((_regs.synth_lock_timeout & ((uint16_t)~0x1F)) == 0); +        _regs.auto_level_timeout =              static_cast<uint8_t>(ceil((_pfd_freq * 5) / (100e3 * _regs.timeout))); -    //----------------------------------------------------------- -    //Set VCO band divider -    _regs.vco_band_div = -            static_cast<uint8_t>(ceil(_pfd_freq / 2.4e6)); +        //----------------------------------------------------------- +        // Set VCO band divider +        _regs.vco_band_div = static_cast<uint8_t>(ceil(_pfd_freq / 2.4e6)); -    //----------------------------------------------------------- -    //Set ADC delay (code from ADI driver) -    _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED; -    _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED; -    _regs.adc_clock_divider = std::max(1, std::min(int(ceil(((_pfd_freq / 100e3) - 2) / 4)),255)); +        //----------------------------------------------------------- +        // Set ADC delay (code from ADI driver) +        _regs.adc_enable     = adf535x_regs_t::ADC_ENABLE_ENABLED; +        _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED; +        _regs.adc_clock_divider = +            std::max(1, std::min(int(ceil(((_pfd_freq / 100e3) - 2) / 4)), 255)); -    _wait_time_us = static_cast<uint32_t>( +        _wait_time_us = static_cast<uint32_t>(              ceil(16e6 / (_pfd_freq / ((4 * _regs.adc_clock_divider) + 2)))); -    //----------------------------------------------------------- -    //Phase resync -    _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_ENABLED; - -    _regs.phase_adjust = adf535x_regs_t::PHASE_ADJUST_DISABLED; -    _regs.sd_load_reset = adf535x_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE; -    _regs.phase_resync_clk_div = static_cast<uint16_t>( -            floor(ADF535X_PHASE_RESYNC_TIME * _pfd_freq)); - -    _rewrite_regs = true; -  } - -  double set_frequency(const double target_freq, const double freq_resolution, const bool flush = false) override -  { -    return _set_frequency(target_freq, freq_resolution, flush); -  } - -  void set_output_power(const output_power_t power) override -  { -    typename adf535x_regs_t::output_power_t setting; -    switch (power) { -      case OUTPUT_POWER_M4DBM: setting = adf535x_regs_t::OUTPUT_POWER_M4DBM; break; -      case OUTPUT_POWER_M1DBM: setting = adf535x_regs_t::OUTPUT_POWER_M1DBM; break; -      case OUTPUT_POWER_2DBM:  setting = adf535x_regs_t::OUTPUT_POWER_2DBM; break; -      case OUTPUT_POWER_5DBM:  setting = adf535x_regs_t::OUTPUT_POWER_5DBM; break; -      default: UHD_THROW_INVALID_CODE_PATH(); +        //----------------------------------------------------------- +        // Phase resync +        _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_ENABLED; + +        _regs.phase_adjust  = adf535x_regs_t::PHASE_ADJUST_DISABLED; +        _regs.sd_load_reset = adf535x_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE; +        _regs.phase_resync_clk_div = +            static_cast<uint16_t>(floor(ADF535X_PHASE_RESYNC_TIME * _pfd_freq)); + +        _rewrite_regs = true; +    } + +    double set_frequency(const double target_freq, +        const double freq_resolution, +        const bool flush = false) override +    { +        return _set_frequency(target_freq, freq_resolution, flush);      } -    if (_regs.output_power != setting) _rewrite_regs = true; -    _regs.output_power = setting; -  } - -  void set_output_enable(const output_t output, const bool enable) override -  { -    switch (output) { -      case RF_OUTPUT_A: _regs.rf_out_a_enabled = enable ? adf535x_regs_t::RF_OUT_A_ENABLED_ENABLED : -                                                 adf535x_regs_t::RF_OUT_A_ENABLED_DISABLED; -        break; -      case RF_OUTPUT_B: _regs.rf_out_b_enabled = enable ? adf535x_regs_t::RF_OUT_B_ENABLED_ENABLED : -                                                 adf535x_regs_t::RF_OUT_B_ENABLED_DISABLED; -        break; + +    void set_output_power(const output_power_t power) override +    { +        typename adf535x_regs_t::output_power_t setting; +        switch (power) { +            case OUTPUT_POWER_M4DBM: +                setting = adf535x_regs_t::OUTPUT_POWER_M4DBM; +                break; +            case OUTPUT_POWER_M1DBM: +                setting = adf535x_regs_t::OUTPUT_POWER_M1DBM; +                break; +            case OUTPUT_POWER_2DBM: +                setting = adf535x_regs_t::OUTPUT_POWER_2DBM; +                break; +            case OUTPUT_POWER_5DBM: +                setting = adf535x_regs_t::OUTPUT_POWER_5DBM; +                break; +            default: +                UHD_THROW_INVALID_CODE_PATH(); +        } +        if (_regs.output_power != setting) +            _rewrite_regs = true; +        _regs.output_power = setting; +    } + +    void set_output_enable(const output_t output, const bool enable) override +    { +        switch (output) { +            case RF_OUTPUT_A: +                _regs.rf_out_a_enabled = enable +                                             ? adf535x_regs_t::RF_OUT_A_ENABLED_ENABLED +                                             : adf535x_regs_t::RF_OUT_A_ENABLED_DISABLED; +                break; +            case RF_OUTPUT_B: +                _regs.rf_out_b_enabled = enable +                                             ? adf535x_regs_t::RF_OUT_B_ENABLED_ENABLED +                                             : adf535x_regs_t::RF_OUT_B_ENABLED_DISABLED; +                break; +        }      } -  } - -  void set_muxout_mode(const muxout_t mode) override -  { -    switch (mode) { -      case MUXOUT_3STATE: _regs.muxout = adf535x_regs_t::MUXOUT_3STATE; break; -      case MUXOUT_DVDD:   _regs.muxout = adf535x_regs_t::MUXOUT_DVDD; break; -      case MUXOUT_DGND:   _regs.muxout = adf535x_regs_t::MUXOUT_DGND; break; -      case MUXOUT_RDIV:   _regs.muxout = adf535x_regs_t::MUXOUT_RDIV; break; -      case MUXOUT_NDIV:   _regs.muxout = adf535x_regs_t::MUXOUT_NDIV; break; -      case MUXOUT_ALD:    _regs.muxout = adf535x_regs_t::MUXOUT_ANALOG_LD; break; -      case MUXOUT_DLD:    _regs.muxout = adf535x_regs_t::MUXOUT_DLD; break; -      default: UHD_THROW_INVALID_CODE_PATH(); + +    void set_muxout_mode(const muxout_t mode) override +    { +        switch (mode) { +            case MUXOUT_3STATE: +                _regs.muxout = adf535x_regs_t::MUXOUT_3STATE; +                break; +            case MUXOUT_DVDD: +                _regs.muxout = adf535x_regs_t::MUXOUT_DVDD; +                break; +            case MUXOUT_DGND: +                _regs.muxout = adf535x_regs_t::MUXOUT_DGND; +                break; +            case MUXOUT_RDIV: +                _regs.muxout = adf535x_regs_t::MUXOUT_RDIV; +                break; +            case MUXOUT_NDIV: +                _regs.muxout = adf535x_regs_t::MUXOUT_NDIV; +                break; +            case MUXOUT_ALD: +                _regs.muxout = adf535x_regs_t::MUXOUT_ANALOG_LD; +                break; +            case MUXOUT_DLD: +                _regs.muxout = adf535x_regs_t::MUXOUT_DLD; +                break; +            default: +                UHD_THROW_INVALID_CODE_PATH(); +        }      } -  } -  void commit() override -  { -    _commit(); -  } +    void commit() override +    { +        _commit(); +    }  protected: -  double _set_frequency(double, double, bool); -  void _commit(); - -private: //Members -  typedef std::vector<uint32_t> addr_vtr_t; - -  write_fn_t      _write_fn; -  wait_fn_t       _wait_fn; -  adf535x_regs_t  _regs; -  bool            _rewrite_regs; -  uint32_t        _wait_time_us; -  double          _ref_freq; -  double          _pfd_freq; -  double          _fb_after_divider; +    double _set_frequency(double, double, bool); +    void _commit(); + +private: // Members +    typedef std::vector<uint32_t> addr_vtr_t; + +    write_fn_t _write_fn; +    wait_fn_t _wait_fn; +    adf535x_regs_t _regs; +    bool _rewrite_regs; +    uint32_t _wait_time_us; +    double _ref_freq; +    double _pfd_freq; +    double _fb_after_divider;  };  // ADF5355 Functions  template <> -inline double adf535x_impl<adf5355_regs_t>::_set_frequency(double target_freq, double freq_resolution, bool flush) +inline double adf535x_impl<adf5355_regs_t>::_set_frequency( +    double target_freq, double freq_resolution, bool flush)  { -  if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { -    throw uhd::runtime_error("requested frequency out of range."); -  } -  if ((uint32_t) freq_resolution == 0) { -    throw uhd::runtime_error("requested resolution cannot be less than 1."); -  } - -  /* Calculate target VCOout frequency */ -  //Increase RF divider until acceptable VCO frequency -  double target_vco_freq = target_freq; -  uint32_t rf_divider = 1; -  while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { -    target_vco_freq *= 2; -    rf_divider *= 2; -  } - -  switch (rf_divider) { -    case 1:  _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV1;  break; -    case 2:  _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV2;  break; -    case 4:  _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV4;  break; -    case 8:  _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV8;  break; -    case 16: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV16; break; -    case 32: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV32; break; -    case 64: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV64; break; -    default: UHD_THROW_INVALID_CODE_PATH(); -  } - -  //Compute fractional PLL params -  double prescaler_input_freq = target_vco_freq; -  if (_fb_after_divider) { -    prescaler_input_freq /= rf_divider; -  } - -  const double N = prescaler_input_freq / _pfd_freq; -  const auto INT = static_cast<uint16_t>(floor(N)); -  const auto FRAC1 = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1)); -  const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; - -  const double gcd = boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution)); -  const auto MOD2 = static_cast<uint16_t>(std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2))); -  const auto FRAC2 = static_cast<uint16_t>(std::min(ceil(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2))); - -  const double coerced_vco_freq = _pfd_freq * -    (_fb_after_divider ? rf_divider : 1) * -    (double(INT) + ((double(FRAC1) + (double(FRAC2) / double(MOD2))) / -    double(ADF535X_MOD1))); - -  const double coerced_out_freq = coerced_vco_freq / rf_divider; - -  /* Update registers */ -  _regs.int_16_bit = INT; -  _regs.frac1_24_bit = FRAC1; -  _regs.frac2_14_bit = FRAC2; -  _regs.mod2_14_bit = MOD2; -  _regs.phase_24_bit = 0; - -  if (flush) commit(); -  return coerced_out_freq; +    if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { +        throw uhd::runtime_error("requested frequency out of range."); +    } +    if ((uint32_t)freq_resolution == 0) { +        throw uhd::runtime_error("requested resolution cannot be less than 1."); +    } + +    /* Calculate target VCOout frequency */ +    // Increase RF divider until acceptable VCO frequency +    double target_vco_freq = target_freq; +    uint32_t rf_divider    = 1; +    while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { +        target_vco_freq *= 2; +        rf_divider *= 2; +    } + +    switch (rf_divider) { +        case 1: +            _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV1; +            break; +        case 2: +            _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV2; +            break; +        case 4: +            _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV4; +            break; +        case 8: +            _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV8; +            break; +        case 16: +            _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV16; +            break; +        case 32: +            _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV32; +            break; +        case 64: +            _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV64; +            break; +        default: +            UHD_THROW_INVALID_CODE_PATH(); +    } + +    // Compute fractional PLL params +    double prescaler_input_freq = target_vco_freq; +    if (_fb_after_divider) { +        prescaler_input_freq /= rf_divider; +    } + +    const double N       = prescaler_input_freq / _pfd_freq; +    const auto INT       = static_cast<uint16_t>(floor(N)); +    const auto FRAC1     = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1)); +    const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; + +    const double gcd = +        boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution)); +    const auto MOD2 = static_cast<uint16_t>( +        std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2))); +    const auto FRAC2 = static_cast<uint16_t>( +        std::min(ceil(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2))); + +    const double coerced_vco_freq = +        _pfd_freq * (_fb_after_divider ? rf_divider : 1) +        * (double(INT) +              + ((double(FRAC1) + (double(FRAC2) / double(MOD2))) +                    / double(ADF535X_MOD1))); + +    const double coerced_out_freq = coerced_vco_freq / rf_divider; + +    /* Update registers */ +    _regs.int_16_bit   = INT; +    _regs.frac1_24_bit = FRAC1; +    _regs.frac2_14_bit = FRAC2; +    _regs.mod2_14_bit  = MOD2; +    _regs.phase_24_bit = 0; + +    if (flush) +        commit(); +    return coerced_out_freq;  } -template <> -inline void adf535x_impl<adf5355_regs_t>::_commit() +template <> inline void adf535x_impl<adf5355_regs_t>::_commit()  { -  const size_t ONE_REG = 1; - -  if (_rewrite_regs) { -    //For a full state sync write registers in reverse order 12 - 0 -    addr_vtr_t regs; -    for (uint8_t addr = 12; addr > 0; addr--) { -      regs.push_back(_regs.get_reg(addr)); +    const size_t ONE_REG = 1; + +    if (_rewrite_regs) { +        // For a full state sync write registers in reverse order 12 - 0 +        addr_vtr_t regs; +        for (uint8_t addr = 12; addr > 0; addr--) { +            regs.push_back(_regs.get_reg(addr)); +        } +        _write_fn(regs); +        _wait_fn(_wait_time_us); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); +        _rewrite_regs = false; +    } else { +        // Frequency update sequence from data sheet +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); +        _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_ENABLED; +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); +        _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_DISABLED; +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); +        _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED; +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); +        _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED; +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));      } -    _write_fn(regs); -    _wait_fn(_wait_time_us); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); -    _rewrite_regs = false; -  } else { -    //Frequency update sequence from data sheet -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); -    _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_ENABLED; -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); -    _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_DISABLED; -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); -    _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED; -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); -    _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED; -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); -  }  }  // ADF5356 Functions  template <> -inline double adf535x_impl<adf5356_regs_t>::_set_frequency(double target_freq, double freq_resolution, bool flush) +inline double adf535x_impl<adf5356_regs_t>::_set_frequency( +    double target_freq, double freq_resolution, bool flush)  { -  if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { -    throw uhd::runtime_error("requested frequency out of range."); -  } -  if ((uint32_t) freq_resolution == 0) { -    throw uhd::runtime_error("requested resolution cannot be less than 1."); -  } - -  /* Calculate target VCOout frequency */ -  //Increase RF divider until acceptable VCO frequency -  double target_vco_freq = target_freq; -  uint32_t rf_divider = 1; -  while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { -    target_vco_freq *= 2; -    rf_divider *= 2; -  } - -  switch (rf_divider) { -    case 1:  _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV1;  break; -    case 2:  _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV2;  break; -    case 4:  _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV4;  break; -    case 8:  _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV8;  break; -    case 16: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV16; break; -    case 32: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV32; break; -    case 64: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV64; break; -    default: UHD_THROW_INVALID_CODE_PATH(); -  } - -  //Compute fractional PLL params -  double prescaler_input_freq = target_vco_freq; -  if (_fb_after_divider) { -    prescaler_input_freq /= rf_divider; -  } - -  const double N = prescaler_input_freq / _pfd_freq; -  const auto INT = static_cast<uint16_t>(floor(N)); -  const auto FRAC1 = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1)); -  const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; - -  const double gcd = boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution)); -  const auto MOD2 = static_cast<uint16_t>(std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2))); -  const auto FRAC2 = static_cast<uint16_t>(std::min(round(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2))); - -  const double coerced_vco_freq = _pfd_freq * -    (_fb_after_divider ? rf_divider : 1) * -    (double(INT) + ((double(FRAC1) + (double(FRAC2) / double(MOD2))) -    / double(ADF535X_MOD1))); - -  const double coerced_out_freq = coerced_vco_freq / rf_divider; - -  /* Update registers */ -  _regs.int_16_bit = INT; -  _regs.frac1_24_bit = FRAC1; -  _regs.frac2_msb = FRAC2; -  _regs.mod2_msb = MOD2; -  _regs.phase_24_bit = 0; - -  if (flush) commit(); -  return coerced_out_freq; +    if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { +        throw uhd::runtime_error("requested frequency out of range."); +    } +    if ((uint32_t)freq_resolution == 0) { +        throw uhd::runtime_error("requested resolution cannot be less than 1."); +    } + +    /* Calculate target VCOout frequency */ +    // Increase RF divider until acceptable VCO frequency +    double target_vco_freq = target_freq; +    uint32_t rf_divider    = 1; +    while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { +        target_vco_freq *= 2; +        rf_divider *= 2; +    } + +    switch (rf_divider) { +        case 1: +            _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV1; +            break; +        case 2: +            _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV2; +            break; +        case 4: +            _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV4; +            break; +        case 8: +            _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV8; +            break; +        case 16: +            _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV16; +            break; +        case 32: +            _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV32; +            break; +        case 64: +            _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV64; +            break; +        default: +            UHD_THROW_INVALID_CODE_PATH(); +    } + +    // Compute fractional PLL params +    double prescaler_input_freq = target_vco_freq; +    if (_fb_after_divider) { +        prescaler_input_freq /= rf_divider; +    } + +    const double N       = prescaler_input_freq / _pfd_freq; +    const auto INT       = static_cast<uint16_t>(floor(N)); +    const auto FRAC1     = static_cast<uint32_t>(floor((N - INT) * ADF535X_MOD1)); +    const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; + +    const double gcd = +        boost::math::gcd(static_cast<int>(_pfd_freq), static_cast<int>(freq_resolution)); +    const auto MOD2 = static_cast<uint16_t>( +        std::min(floor(_pfd_freq / gcd), static_cast<double>(ADF535X_MAX_MOD2))); +    const auto FRAC2 = static_cast<uint16_t>( +        std::min(round(residue * MOD2), static_cast<double>(ADF535X_MAX_FRAC2))); + +    const double coerced_vco_freq = +        _pfd_freq * (_fb_after_divider ? rf_divider : 1) +        * (double(INT) +              + ((double(FRAC1) + (double(FRAC2) / double(MOD2))) +                    / double(ADF535X_MOD1))); + +    const double coerced_out_freq = coerced_vco_freq / rf_divider; + +    /* Update registers */ +    _regs.int_16_bit   = INT; +    _regs.frac1_24_bit = FRAC1; +    _regs.frac2_msb    = FRAC2; +    _regs.mod2_msb     = MOD2; +    _regs.phase_24_bit = 0; + +    if (flush) +        commit(); +    return coerced_out_freq;  } -template <> -inline void adf535x_impl<adf5356_regs_t>::_commit() +template <> inline void adf535x_impl<adf5356_regs_t>::_commit()  { -  const size_t ONE_REG = 1; -  if (_rewrite_regs) { -    //For a full state sync write registers in reverse order 12 - 0 -    addr_vtr_t regs; -    for (uint8_t addr = 13; addr > 0; addr--) { -      regs.push_back(_regs.get_reg(addr)); +    const size_t ONE_REG = 1; +    if (_rewrite_regs) { +        // For a full state sync write registers in reverse order 12 - 0 +        addr_vtr_t regs; +        for (uint8_t addr = 13; addr > 0; addr--) { +            regs.push_back(_regs.get_reg(addr)); +        } +        _write_fn(regs); +        _wait_fn(_wait_time_us); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); +        _rewrite_regs = false; +    } else { +        // Frequency update sequence from data sheet +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(13))); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); +        _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0)));      } -    _write_fn(regs); -    _wait_fn(_wait_time_us); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); -    _rewrite_regs = false; -  } else { -    //Frequency update sequence from data sheet -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(13))); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); -    _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); -  }  }  #endif // INCLUDED_ADF535X_HPP diff --git a/host/lib/include/uhdlib/usrp/common/lmx2592.hpp b/host/lib/include/uhdlib/usrp/common/lmx2592.hpp index 91beb24b7..f71ae0cf5 100644 --- a/host/lib/include/uhdlib/usrp/common/lmx2592.hpp +++ b/host/lib/include/uhdlib/usrp/common/lmx2592.hpp @@ -19,7 +19,8 @@  #include <utility>  #include <vector> -class lmx2592_iface { +class lmx2592_iface +{  public:      typedef std::shared_ptr<lmx2592_iface> sptr; @@ -37,8 +38,7 @@ public:      enum mash_order_t { INT_N, FIRST, SECOND, THIRD, FOURTH }; -    virtual double set_frequency( -        double target_freq, +    virtual double set_frequency(double target_freq,          const bool spur_dodging,          const double spur_dodging_threshold) = 0; diff --git a/host/lib/usrp/b100/clock_ctrl.cpp b/host/lib/usrp/b100/clock_ctrl.cpp index 7a089e293..e30ca120f 100644 --- a/host/lib/usrp/b100/clock_ctrl.cpp +++ b/host/lib/usrp/b100/clock_ctrl.cpp @@ -7,79 +7,89 @@  #include "clock_ctrl.hpp"  #include "ad9522_regs.hpp" -#include <uhd/utils/log.hpp> - +#include "b100_regs.hpp" //spi slave constants  #include <uhd/exception.hpp>  #include <uhd/utils/assert_has.hpp> +#include <uhd/utils/log.hpp>  #include <uhd/utils/safe_call.hpp>  #include <stdint.h> -#include "b100_regs.hpp" //spi slave constants  #include <boost/format.hpp>  #include <boost/math/common_factor_rt.hpp> //gcd  #include <algorithm> -#include <utility>  #include <chrono>  #include <thread> +#include <utility>  using namespace uhd;  /***********************************************************************   * Constants   **********************************************************************/ -static const bool ENABLE_THE_TEST_OUT = true; +static const bool ENABLE_THE_TEST_OUT    = true;  static const double REFERENCE_INPUT_RATE = 10e6;  /***********************************************************************   * Helpers   **********************************************************************/ -template <typename div_type, typename bypass_type> static void set_clock_divider( -    size_t divider, div_type &low, div_type &high, bypass_type &bypass -){ -    high = divider/2 - 1; -    low = divider - high - 2; -    bypass = (divider == 1)? 1 : 0; +template <typename div_type, typename bypass_type> +static void set_clock_divider( +    size_t divider, div_type& low, div_type& high, bypass_type& bypass) +{ +    high   = divider / 2 - 1; +    low    = divider - high - 2; +    bypass = (divider == 1) ? 1 : 0;  }  /***********************************************************************   * Clock rate calculation stuff:   *   Using the internal VCO between 1400 and 1800 MHz   **********************************************************************/ -struct clock_settings_type{ -    size_t ref_clock_doubler, r_counter, a_counter, b_counter, prescaler, vco_divider, chan_divider; -    size_t get_n_counter(void) const{return prescaler * b_counter + a_counter;} -    double get_ref_rate(void) const{return REFERENCE_INPUT_RATE * ref_clock_doubler;} -    double get_vco_rate(void) const{return get_ref_rate()/r_counter * get_n_counter();} -    double get_chan_rate(void) const{return get_vco_rate()/vco_divider;} -    double get_out_rate(void) const{return get_chan_rate()/chan_divider;} -    std::string to_pp_string(void) const{ -        return str(boost::format( -            "  r_counter: %d\n" -            "  a_counter: %d\n" -            "  b_counter: %d\n" -            "  prescaler: %d\n" -            "  vco_divider: %d\n" -            "  chan_divider: %d\n" -            "  vco_rate: %fMHz\n" -            "  chan_rate: %fMHz\n" -            "  out_rate: %fMHz\n" -            ) -            % r_counter -            % a_counter -            % b_counter -            % prescaler -            % vco_divider -            % chan_divider -            % (get_vco_rate()/1e6) -            % (get_chan_rate()/1e6) -            % (get_out_rate()/1e6) -        ); +struct clock_settings_type +{ +    size_t ref_clock_doubler, r_counter, a_counter, b_counter, prescaler, vco_divider, +        chan_divider; +    size_t get_n_counter(void) const +    { +        return prescaler * b_counter + a_counter; +    } +    double get_ref_rate(void) const +    { +        return REFERENCE_INPUT_RATE * ref_clock_doubler; +    } +    double get_vco_rate(void) const +    { +        return get_ref_rate() / r_counter * get_n_counter(); +    } +    double get_chan_rate(void) const +    { +        return get_vco_rate() / vco_divider; +    } +    double get_out_rate(void) const +    { +        return get_chan_rate() / chan_divider; +    } +    std::string to_pp_string(void) const +    { +        return str(boost::format("  r_counter: %d\n" +                                 "  a_counter: %d\n" +                                 "  b_counter: %d\n" +                                 "  prescaler: %d\n" +                                 "  vco_divider: %d\n" +                                 "  chan_divider: %d\n" +                                 "  vco_rate: %fMHz\n" +                                 "  chan_rate: %fMHz\n" +                                 "  out_rate: %fMHz\n") +                   % r_counter % a_counter % b_counter % prescaler % vco_divider +                   % chan_divider % (get_vco_rate() / 1e6) % (get_chan_rate() / 1e6) +                   % (get_out_rate() / 1e6));      }  };  //! gives the greatest divisor of num between 1 and max inclusive -template<typename T> static inline T greatest_divisor(T num, T max){ -    for (T i = max; i > 1; i--){ -        if (num%i == 0){ +template <typename T> static inline T greatest_divisor(T num, T max) +{ +    for (T i = max; i > 1; i--) { +        if (num % i == 0) {              return i;          }      } @@ -87,116 +97,130 @@ template<typename T> static inline T greatest_divisor(T num, T max){  }  //! gives the least divisor of num between min and num exclusive -template<typename T> static inline T least_divisor(T num, T min){ -    for (T i = min; i < num; i++){ -        if (num%i == 0){ +template <typename T> static inline T least_divisor(T num, T min) +{ +    for (T i = min; i < num; i++) { +        if (num % i == 0) {              return i;          }      }      return 1;  } -static clock_settings_type get_clock_settings(double rate){ +static clock_settings_type get_clock_settings(double rate) +{      clock_settings_type cs; -    cs.ref_clock_doubler = 2; //always doubling -    cs.prescaler = 8; //set to 8 when input is under 2400 MHz +    cs.ref_clock_doubler = 2; // always doubling +    cs.prescaler         = 8; // set to 8 when input is under 2400 MHz -    //basic formulas used below: -    //out_rate*X = ref_rate*Y -    //X = i*ref_rate/gcd -    //Y = i*out_rate/gcd -    //X = chan_div * vco_div * R -    //Y = P*B + A +    // basic formulas used below: +    // out_rate*X = ref_rate*Y +    // X = i*ref_rate/gcd +    // Y = i*out_rate/gcd +    // X = chan_div * vco_div * R +    // Y = P*B + A      const uint64_t out_rate = uint64_t(rate);      const uint64_t ref_rate = uint64_t(cs.get_ref_rate()); -    const size_t gcd = size_t(boost::math::gcd(ref_rate, out_rate)); +    const size_t gcd        = size_t(boost::math::gcd(ref_rate, out_rate)); -    for (size_t i = 1; i <= 100; i++){ -        const size_t X = size_t(i*ref_rate/gcd); -        const size_t Y = size_t(i*out_rate/gcd); +    for (size_t i = 1; i <= 100; i++) { +        const size_t X = size_t(i * ref_rate / gcd); +        const size_t Y = size_t(i * out_rate / gcd); -        //determine A and B (P is fixed) -        cs.b_counter = Y/cs.prescaler; -        cs.a_counter = Y - cs.b_counter*cs.prescaler; +        // determine A and B (P is fixed) +        cs.b_counter = Y / cs.prescaler; +        cs.a_counter = Y - cs.b_counter * cs.prescaler;          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){ +        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;              }              UHD_LOGGER_TRACE("B100") -                << "gcd: " << gcd -                << " X: " << X -                << " Y: " << Y -                << cs.to_pp_string() -            ; - -            //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 (cs.get_vco_rate() > 1800e6 - vco_bound_pad) continue; -            if (cs.get_vco_rate() < 1400e6 + vco_bound_pad) continue; -            if (cs.get_out_rate() != rate) continue; - -            UHD_LOGGER_TRACE("B100") << "USRP-B100 clock control: " << i  << cs.to_pp_string() ; +                << "gcd: " << gcd << " X: " << X << " Y: " << Y << cs.to_pp_string(); + +            // 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 (cs.get_vco_rate() > 1800e6 - vco_bound_pad) +                continue; +            if (cs.get_vco_rate() < 1400e6 + vco_bound_pad) +                continue; +            if (cs.get_out_rate() != rate) +                continue; + +            UHD_LOGGER_TRACE("B100") +                << "USRP-B100 clock control: " << i << cs.to_pp_string();              return cs;          }      } -    throw uhd::value_error(str(boost::format( -        "USRP-B100 clock control: could not calculate settings for clock rate %fMHz" -    ) % (rate/1e6))); +    throw uhd::value_error(str( +        boost::format( +            "USRP-B100 clock control: could not calculate settings for clock rate %fMHz") +        % (rate / 1e6)));  } -b100_clock_ctrl::~b100_clock_ctrl(void) { +b100_clock_ctrl::~b100_clock_ctrl(void) +{      /* NOP */  }  /***********************************************************************   * Clock Control Implementation   **********************************************************************/ -class b100_clock_ctrl_impl : public b100_clock_ctrl{ +class b100_clock_ctrl_impl : public b100_clock_ctrl +{  public: -    b100_clock_ctrl_impl(i2c_iface::sptr iface, double master_clock_rate){ -        _iface = iface; +    b100_clock_ctrl_impl(i2c_iface::sptr iface, double master_clock_rate) +    { +        _iface     = iface;          _chan_rate = 0.0; -        _out_rate = 0.0; +        _out_rate  = 0.0; -        //perform soft-reset +        // perform soft-reset          _ad9522_regs.soft_reset = 1;          this->send_reg(0x000);          this->latch_regs();          _ad9522_regs.soft_reset = 0; -        //init the clock gen registers -        _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; -        _ad9522_regs.enb_stat_eeprom_at_stat_pin = 0; //use status pin -        _ad9522_regs.status_pin_control = 0x1; //n divider -        _ad9522_regs.ld_pin_control = 0x00; //dld -        _ad9522_regs.refmon_pin_control = 0x12; //show ref2 +        // init the clock gen registers +        _ad9522_regs.sdo_active                  = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO; +        _ad9522_regs.enb_stat_eeprom_at_stat_pin = 0; // use status pin +        _ad9522_regs.status_pin_control          = 0x1; // n divider +        _ad9522_regs.ld_pin_control              = 0x00; // dld +        _ad9522_regs.refmon_pin_control          = 0x12; // show ref2          _ad9522_regs.lock_detect_counter = ad9522_regs_t::LOCK_DETECT_COUNTER_16CYC;          this->use_internal_ref(); -        this->set_fpga_clock_rate(master_clock_rate); //initialize to something +        this->set_fpga_clock_rate(master_clock_rate); // initialize to something          this->enable_fpga_clock(true);          this->enable_test_clock(ENABLE_THE_TEST_OUT); @@ -204,12 +228,12 @@ public:          this->enable_tx_dboard_clock(false);      } -    ~b100_clock_ctrl_impl(void){ -        UHD_SAFE_CALL( -            this->enable_test_clock(ENABLE_THE_TEST_OUT); -            this->enable_rx_dboard_clock(false); -            this->enable_tx_dboard_clock(false); -            //this->enable_fpga_clock(false); //FIXME +    ~b100_clock_ctrl_impl(void) +    { +        UHD_SAFE_CALL(this->enable_test_clock(ENABLE_THE_TEST_OUT); +                      this->enable_rx_dboard_clock(false); +                      this->enable_tx_dboard_clock(false); +            // this->enable_fpga_clock(false); //FIXME          )      } @@ -218,105 +242,123 @@ public:       *  - set clock rate w/ internal VCO       *  - set clock rate w/ external VCXO       **********************************************************************/ -    void set_clock_settings_with_internal_vco(double rate){ +    void set_clock_settings_with_internal_vco(double rate) +    {          const clock_settings_type cs = get_clock_settings(rate); -        //set the rates to private variables so the implementation knows! +        // set the rates to private variables so the implementation knows!          _chan_rate = cs.get_chan_rate(); -        _out_rate = cs.get_out_rate(); +        _out_rate  = cs.get_out_rate(); -        _ad9522_regs.enable_clock_doubler = (cs.ref_clock_doubler == 2)? 1 : 0; +        _ad9522_regs.enable_clock_doubler = (cs.ref_clock_doubler == 2) ? 1 : 0;          _ad9522_regs.set_r_counter(cs.r_counter);          _ad9522_regs.a_counter = cs.a_counter;          _ad9522_regs.set_b_counter(cs.b_counter); -        UHD_ASSERT_THROW(cs.prescaler == 8); //assumes this below: +        UHD_ASSERT_THROW(cs.prescaler == 8); // assumes this below:          _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9;          _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; -        _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA; +        _ad9522_regs.cp_current     = ad9522_regs_t::CP_CURRENT_1_2MA;          _ad9522_regs.bypass_vco_divider = 0; -        switch(cs.vco_divider){ -        case 1: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV1; break; -        case 2: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV2; break; -        case 3: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV3; break; -        case 4: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV4; break; -        case 5: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; break; -        case 6: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV6; break; +        switch (cs.vco_divider) { +            case 1: +                _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV1; +                break; +            case 2: +                _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV2; +                break; +            case 3: +                _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV3; +                break; +            case 4: +                _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV4; +                break; +            case 5: +                _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; +                break; +            case 6: +                _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV6; +                break;          }          _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; -        //setup fpga master clock +        // setup fpga master clock          _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS;          set_clock_divider(cs.chan_divider,              _ad9522_regs.divider0_low_cycles,              _ad9522_regs.divider0_high_cycles, -            _ad9522_regs.divider0_bypass -        ); +            _ad9522_regs.divider0_bypass); -        //setup codec clock +        // setup codec clock          _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS;          set_clock_divider(cs.chan_divider,              _ad9522_regs.divider1_low_cycles,              _ad9522_regs.divider1_high_cycles, -            _ad9522_regs.divider1_bypass -        ); +            _ad9522_regs.divider1_bypass);          this->send_all_regs();          calibrate_now();      } -    void set_clock_settings_with_external_vcxo(double rate){ -        //set the rates to private variables so the implementation knows! +    void set_clock_settings_with_external_vcxo(double rate) +    { +        // set the rates to private variables so the implementation knows!          _chan_rate = rate; -        _out_rate = rate; +        _out_rate  = rate; -        _ad9522_regs.enable_clock_doubler = 1; //doubler always on -        const double ref_rate = REFERENCE_INPUT_RATE*2; +        _ad9522_regs.enable_clock_doubler = 1; // doubler always on +        const double ref_rate             = REFERENCE_INPUT_RATE * 2; -        //bypass prescaler such that N = B +        // bypass prescaler such that N = B          long gcd = boost::math::gcd(long(ref_rate), long(rate)); -        _ad9522_regs.set_r_counter(int(ref_rate/gcd)); +        _ad9522_regs.set_r_counter(int(ref_rate / gcd));          _ad9522_regs.a_counter = 0; -        _ad9522_regs.set_b_counter(int(rate/gcd)); +        _ad9522_regs.set_b_counter(int(rate / gcd));          _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV1; -        //setup external vcxo -        _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; -        _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA; -        _ad9522_regs.bypass_vco_divider = 1; +        // setup external vcxo +        _ad9522_regs.pll_power_down      = ad9522_regs_t::PLL_POWER_DOWN_NORMAL; +        _ad9522_regs.cp_current          = ad9522_regs_t::CP_CURRENT_1_2MA; +        _ad9522_regs.bypass_vco_divider  = 1;          _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_EXTERNAL; -        //setup fpga master clock -        _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; +        // setup fpga master clock +        _ad9522_regs.out0_format     = ad9522_regs_t::OUT0_FORMAT_LVDS;          _ad9522_regs.divider0_bypass = 1; -        //setup codec clock -        _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; +        // setup codec clock +        _ad9522_regs.out3_format     = ad9522_regs_t::OUT3_FORMAT_LVDS;          _ad9522_regs.divider1_bypass = 1;          this->send_all_regs();      } -    void set_fpga_clock_rate(double rate){ -        if (_out_rate == rate) return; -        if (rate == 61.44e6) set_clock_settings_with_external_vcxo(rate); -        else                 set_clock_settings_with_internal_vco(rate); -        //clock rate changed! update dboard clocks and FPGA ticks per second +    void set_fpga_clock_rate(double rate) +    { +        if (_out_rate == rate) +            return; +        if (rate == 61.44e6) +            set_clock_settings_with_external_vcxo(rate); +        else +            set_clock_settings_with_internal_vco(rate); +        // clock rate changed! update dboard clocks and FPGA ticks per second          set_rx_dboard_clock_rate(rate);          set_tx_dboard_clock_rate(rate);      } -    double get_fpga_clock_rate(void){ +    double get_fpga_clock_rate(void) +    {          return this->_out_rate;      }      /***********************************************************************       * FPGA clock enable       **********************************************************************/ -    void enable_fpga_clock(bool enb){ -        _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; +    void enable_fpga_clock(bool enb) +    { +        _ad9522_regs.out0_format          = ad9522_regs_t::OUT0_FORMAT_LVDS;          _ad9522_regs.out0_lvds_power_down = !enb;          this->send_reg(0x0F0);          this->latch_regs(); @@ -325,12 +367,13 @@ public:      /***********************************************************************       * Special test clock output       **********************************************************************/ -    void enable_test_clock(bool enb){ -        //setup test clock (same divider as codec clock) +    void enable_test_clock(bool enb) +    { +        // setup test clock (same divider as codec clock)          _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; -        _ad9522_regs.out4_cmos_configuration = (enb)? -            ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : -            ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; +        _ad9522_regs.out4_cmos_configuration = +            (enb) ? ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON +                  : ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF;          this->send_reg(0x0F4);          this->latch_regs();      } @@ -338,105 +381,118 @@ public:      /***********************************************************************       * RX Dboard Clock Control (output 9, divider 3)       **********************************************************************/ -    void enable_rx_dboard_clock(bool enb){ -        _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_LVDS; +    void enable_rx_dboard_clock(bool enb) +    { +        _ad9522_regs.out9_format          = ad9522_regs_t::OUT9_FORMAT_LVDS;          _ad9522_regs.out9_lvds_power_down = !enb;          this->send_reg(0x0F9);          this->latch_regs();      } -    std::vector<double> get_rx_dboard_clock_rates(void){ +    std::vector<double> get_rx_dboard_clock_rates(void) +    {          std::vector<double> rates; -        for(size_t div = 1; div <= 16+16; div++) -            rates.push_back(this->_chan_rate/div); +        for (size_t div = 1; div <= 16 + 16; div++) +            rates.push_back(this->_chan_rate / div);          return rates;      } -    void set_rx_dboard_clock_rate(double rate){ +    void set_rx_dboard_clock_rate(double rate) +    {          assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate");          _rx_clock_rate = rate; -        size_t divider = size_t(this->_chan_rate/rate); -        //set the divider registers +        size_t divider = size_t(this->_chan_rate / rate); +        // set the divider registers          set_clock_divider(divider,              _ad9522_regs.divider3_low_cycles,              _ad9522_regs.divider3_high_cycles, -            _ad9522_regs.divider3_bypass -        ); +            _ad9522_regs.divider3_bypass);          this->send_reg(0x199);          this->send_reg(0x19a);          this->soft_sync();      } -    double get_rx_clock_rate(void){ +    double get_rx_clock_rate(void) +    {          return _rx_clock_rate;      }      /***********************************************************************       * TX Dboard Clock Control (output 6, divider 2)       **********************************************************************/ -    void enable_tx_dboard_clock(bool enb){ -        _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_LVDS; +    void enable_tx_dboard_clock(bool enb) +    { +        _ad9522_regs.out6_format          = ad9522_regs_t::OUT6_FORMAT_LVDS;          _ad9522_regs.out6_lvds_power_down = !enb;          this->send_reg(0x0F6);          this->latch_regs();      } -    std::vector<double> get_tx_dboard_clock_rates(void){ -        return get_rx_dboard_clock_rates(); //same master clock, same dividers... +    std::vector<double> get_tx_dboard_clock_rates(void) +    { +        return get_rx_dboard_clock_rates(); // same master clock, same dividers...      } -    void set_tx_dboard_clock_rate(double rate){ +    void set_tx_dboard_clock_rate(double rate) +    {          assert_has(get_tx_dboard_clock_rates(), rate, "tx dboard clock rate");          _tx_clock_rate = rate; -        size_t divider = size_t(this->_chan_rate/rate); -        //set the divider registers +        size_t divider = size_t(this->_chan_rate / rate); +        // set the divider registers          set_clock_divider(divider,              _ad9522_regs.divider2_low_cycles,              _ad9522_regs.divider2_high_cycles, -            _ad9522_regs.divider2_bypass -        ); +            _ad9522_regs.divider2_bypass);          this->send_reg(0x196);          this->send_reg(0x197);          this->soft_sync();      } -    double get_tx_clock_rate(void){ +    double get_tx_clock_rate(void) +    {          return _tx_clock_rate;      }      /***********************************************************************       * Clock reference control       **********************************************************************/ -    void use_internal_ref(void) { +    void use_internal_ref(void) +    {          _ad9522_regs.enable_ref2 = 1;          _ad9522_regs.enable_ref1 = 0; -        _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2; -        _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL; +        _ad9522_regs.select_ref  = ad9522_regs_t::SELECT_REF_REF2; +        _ad9522_regs.enb_auto_ref_switchover = +            ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL;          this->send_reg(0x01C);          this->latch_regs();      } -    void use_external_ref(void) { +    void use_external_ref(void) +    {          _ad9522_regs.enable_ref2 = 0;          _ad9522_regs.enable_ref1 = 1; -        _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF1; -        _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL; +        _ad9522_regs.select_ref  = ad9522_regs_t::SELECT_REF_REF1; +        _ad9522_regs.enb_auto_ref_switchover = +            ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL;          this->send_reg(0x01C);          this->latch_regs();      } -    void use_auto_ref(void) { +    void use_auto_ref(void) +    {          _ad9522_regs.enable_ref2 = 1;          _ad9522_regs.enable_ref1 = 1; -        _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF1; -        _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_AUTO; +        _ad9522_regs.select_ref  = ad9522_regs_t::SELECT_REF_REF1; +        _ad9522_regs.enb_auto_ref_switchover = +            ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_AUTO;          this->send_reg(0x01C);          this->latch_regs();      } -    bool get_locked(void){ +    bool get_locked(void) +    {          static const uint8_t addr = 0x01F; -        uint32_t reg = this->read_reg(addr); +        uint32_t reg              = this->read_reg(addr);          _ad9522_regs.set_reg(addr, reg);          return _ad9522_regs.digital_lock_detect != 0;      } @@ -444,18 +500,20 @@ public:  private:      i2c_iface::sptr _iface;      ad9522_regs_t _ad9522_regs; -    double _out_rate; //rate at the fpga and codec -    double _chan_rate; //rate before final dividers +    double _out_rate; // rate at the fpga and codec +    double _chan_rate; // rate before final dividers      double _rx_clock_rate, _tx_clock_rate; -    void latch_regs(void){ +    void latch_regs(void) +    {          _ad9522_regs.io_update = 1;          this->send_reg(0x232);      } -    void send_reg(uint16_t addr){ +    void send_reg(uint16_t addr) +    {          uint32_t reg = _ad9522_regs.get_write_reg(addr); -        UHD_LOGGER_TRACE("B100") << "clock control write reg: " << std::hex << reg ; +        UHD_LOGGER_TRACE("B100") << "clock control write reg: " << std::hex << reg;          byte_vector_t buf;          buf.push_back(uint8_t(reg >> 16));          buf.push_back(uint8_t(reg >> 8)); @@ -464,7 +522,8 @@ private:          _iface->write_i2c(0x5C, buf);      } -    uint8_t read_reg(uint16_t addr){ +    uint8_t read_reg(uint16_t addr) +    {          byte_vector_t buf;          buf.push_back(uint8_t(addr >> 8));          buf.push_back(uint8_t(addr & 0xff)); @@ -475,35 +534,39 @@ private:          return uint32_t(buf[0] & 0xFF);      } -    void calibrate_now(void){ -        //vco calibration routine: +    void calibrate_now(void) +    { +        // vco calibration routine:          _ad9522_regs.vco_calibration_now = 0;          this->send_reg(0x18);          this->latch_regs();          _ad9522_regs.vco_calibration_now = 1;          this->send_reg(0x18);          this->latch_regs(); -        //wait for calibration done: +        // wait for calibration done:          static const uint8_t addr = 0x01F; -        for (size_t ms10 = 0; ms10 < 100; ms10++){ +        for (size_t ms10 = 0; ms10 < 100; ms10++) {              std::this_thread::sleep_for(std::chrono::milliseconds(10));              uint32_t reg = read_reg(addr);              _ad9522_regs.set_reg(addr, reg); -            if (_ad9522_regs.vco_calibration_finished) goto wait_for_ld; +            if (_ad9522_regs.vco_calibration_finished) +                goto wait_for_ld;          }          UHD_LOGGER_ERROR("B100") << "USRP-B100 clock control: VCO calibration timeout"; -        wait_for_ld: -        //wait for digital lock detect: -        for (size_t ms10 = 0; ms10 < 100; ms10++){ +    wait_for_ld: +        // wait for digital lock detect: +        for (size_t ms10 = 0; ms10 < 100; ms10++) {              std::this_thread::sleep_for(std::chrono::milliseconds(10));              uint32_t reg = read_reg(addr);              _ad9522_regs.set_reg(addr, reg); -            if (_ad9522_regs.digital_lock_detect) return; +            if (_ad9522_regs.digital_lock_detect) +                return;          }          UHD_LOGGER_ERROR("B100") << "USRP-B100 clock control: lock detection timeout";      } -    void soft_sync(void){ +    void soft_sync(void) +    {          _ad9522_regs.soft_sync = 1;          this->send_reg(0x230);          this->latch_regs(); @@ -512,21 +575,20 @@ private:          this->latch_regs();      } -    void send_all_regs(void){ -        //setup a list of register ranges to write +    void send_all_regs(void) +    { +        // setup a list of register ranges to write          typedef std::pair<uint16_t, uint16_t> range_t; -        static const std::vector<range_t> ranges{ -            range_t(0x000, 0x000), +        static const std::vector<range_t> ranges{range_t(0x000, 0x000),              range_t(0x010, 0x01F),              range_t(0x0F0, 0x0FD),              range_t(0x190, 0x19B),              range_t(0x1E0, 0x1E1), -            range_t(0x230, 0x230) -        }; +            range_t(0x230, 0x230)}; -        //write initial register values and latch/update -        for(const range_t &range:  ranges){ -            for(uint16_t addr = range.first; addr <= range.second; addr++){ +        // write initial register values and latch/update +        for (const range_t& range : ranges) { +            for (uint16_t addr = range.first; addr <= range.second; addr++) {                  this->send_reg(addr);              }          } @@ -537,6 +599,8 @@ private:  /***********************************************************************   * Clock Control Make   **********************************************************************/ -b100_clock_ctrl::sptr b100_clock_ctrl::make(i2c_iface::sptr iface, double master_clock_rate){ +b100_clock_ctrl::sptr b100_clock_ctrl::make( +    i2c_iface::sptr iface, double master_clock_rate) +{      return sptr(new b100_clock_ctrl_impl(iface, master_clock_rate));  } diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp index b40ea5d82..4f4eba052 100644 --- a/host/lib/usrp/b200/b200_io_impl.cpp +++ b/host/lib/usrp/b200/b200_io_impl.cpp @@ -5,13 +5,13 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include "b200_regs.hpp" -#include "b200_impl.hpp" -#include <uhdlib/usrp/common/validate_subdev_spec.hpp> -#include <uhdlib/usrp/common/async_packet_handler.hpp>  #include "../../transport/super_recv_packet_handler.hpp"  #include "../../transport/super_send_packet_handler.hpp" +#include "b200_impl.hpp" +#include "b200_regs.hpp"  #include <uhd/utils/math.hpp> +#include <uhdlib/usrp/common/async_packet_handler.hpp> +#include <uhdlib/usrp/common/validate_subdev_spec.hpp>  #include <boost/bind.hpp>  #include <boost/make_shared.hpp>  #include <boost/math/common_factor.hpp> @@ -32,53 +32,56 @@ void b200_impl::check_tick_rate_with_current_streamers(double rate)  }  // direction can either be "TX", "RX", or empty (default) -size_t b200_impl::max_chan_count(const std::string &direction /* = "" */) +size_t b200_impl::max_chan_count(const std::string& direction /* = "" */)  {      size_t max_count = 0; -    for(radio_perifs_t &perif:  _radio_perifs) -    { -        if ((direction == "RX" or direction.empty()) and not perif.rx_streamer.expired()) { +    for (radio_perifs_t& perif : _radio_perifs) { +        if ((direction == "RX" or direction.empty()) +            and not perif.rx_streamer.expired()) {              boost::shared_ptr<sph::recv_packet_streamer> rx_streamer = -                boost::dynamic_pointer_cast<sph::recv_packet_streamer>(perif.rx_streamer.lock()); +                boost::dynamic_pointer_cast<sph::recv_packet_streamer>( +                    perif.rx_streamer.lock());              max_count = std::max(max_count, rx_streamer->get_num_channels());          } -        if ((direction == "TX" or direction.empty()) and not perif.tx_streamer.expired()) { +        if ((direction == "TX" or direction.empty()) +            and not perif.tx_streamer.expired()) {              boost::shared_ptr<sph::send_packet_streamer> tx_streamer = -                boost::dynamic_pointer_cast<sph::send_packet_streamer>(perif.tx_streamer.lock()); +                boost::dynamic_pointer_cast<sph::send_packet_streamer>( +                    perif.tx_streamer.lock());              max_count = std::max(max_count, tx_streamer->get_num_channels());          }      }      return max_count;  } -void b200_impl::check_streamer_args(const uhd::stream_args_t &args, double tick_rate, const std::string &direction /*= ""*/) +void b200_impl::check_streamer_args(const uhd::stream_args_t& args, +    double tick_rate, +    const std::string& direction /*= ""*/)  {      std::set<size_t> chans_set; -    for (size_t stream_i = 0; stream_i < args.channels.size(); stream_i++) -    { +    for (size_t stream_i = 0; stream_i < args.channels.size(); stream_i++) {          const size_t chan = args.channels[stream_i];          chans_set.insert(chan);      } -    enforce_tick_rate_limits(chans_set.size(), tick_rate, direction);   // Defined in b200_impl.cpp +    enforce_tick_rate_limits( +        chans_set.size(), tick_rate, direction); // Defined in b200_impl.cpp  }  void b200_impl::set_auto_tick_rate( -        const double rate, -        const fs_path &tree_dsp_path, -        size_t num_chans -) { +    const double rate, const fs_path& tree_dsp_path, size_t num_chans) +{      if (num_chans == 0) { // Divine them          num_chans = std::max(size_t(1), max_chan_count());      } -    const double max_tick_rate = ad9361_device_t::AD9361_MAX_CLOCK_RATE/num_chans; +    const double max_tick_rate = ad9361_device_t::AD9361_MAX_CLOCK_RATE / num_chans;      using namespace uhd::math; -    if (rate != 0.0 and -        (fp_compare::fp_compare_delta<double>(rate, FREQ_COMPARISON_DELTA_HZ) > max_tick_rate)) { -        throw uhd::value_error(str( -                boost::format("Requested sampling rate (%.2f Msps) exceeds maximum tick rate of %.2f MHz.") -                % (rate / 1e6) % (max_tick_rate / 1e6) -        )); +    if (rate != 0.0 +        and (fp_compare::fp_compare_delta<double>(rate, FREQ_COMPARISON_DELTA_HZ) +                > max_tick_rate)) { +        throw uhd::value_error(str(boost::format("Requested sampling rate (%.2f Msps) " +                                                 "exceeds maximum tick rate of %.2f MHz.") +                                   % (rate / 1e6) % (max_tick_rate / 1e6)));      }      // See also the doxygen documentation for these steps in b200_impl.hpp @@ -87,7 +90,8 @@ void b200_impl::set_auto_tick_rate(      for (int i = 0; i < 2; i++) { // Loop through rx and tx          std::string dir = (i == 0) ? "tx" : "rx";          // We assume all 'set' DSPs are being used. -        for(const std::string &dsp_no:  _tree->list(str(boost::format("/mboards/0/%s_dsps") % dir))) { +        for (const std::string& dsp_no : +            _tree->list(str(boost::format("/mboards/0/%s_dsps") % dir))) {              fs_path dsp_path = str(boost::format("/mboards/0/%s_dsps/%s") % dir % dsp_no);              if (dsp_path == tree_dsp_path) {                  continue; @@ -97,18 +101,18 @@ void b200_impl::set_auto_tick_rate(              }              double this_dsp_rate = _tree->access<double>(dsp_path / "rate/value").get();              // Check if the user selected something completely unreasonable: -            if (fp_compare::fp_compare_delta<double>(this_dsp_rate, FREQ_COMPARISON_DELTA_HZ) > max_tick_rate) { -                throw uhd::value_error(str( -                        boost::format("Requested sampling rate (%.2f Msps) exceeds maximum tick rate of %.2f MHz.") -                        % (this_dsp_rate / 1e6) % (max_tick_rate / 1e6) -                )); +            if (fp_compare::fp_compare_delta<double>( +                    this_dsp_rate, FREQ_COMPARISON_DELTA_HZ) +                > max_tick_rate) { +                throw uhd::value_error( +                    str(boost::format("Requested sampling rate (%.2f Msps) exceeds " +                                      "maximum tick rate of %.2f MHz.") +                        % (this_dsp_rate / 1e6) % (max_tick_rate / 1e6)));              }              // Clean up floating point rounding errors if they crept in              this_dsp_rate = std::min(max_tick_rate, this_dsp_rate); -            lcm_rate = boost::math::lcm<uint32_t>( -                    lcm_rate, -                    static_cast<uint32_t>(floor(this_dsp_rate + 0.5)) -            ); +            lcm_rate      = boost::math::lcm<uint32_t>( +                lcm_rate, static_cast<uint32_t>(floor(this_dsp_rate + 0.5)));          }      }      if (lcm_rate == 1) { @@ -121,13 +125,15 @@ void b200_impl::set_auto_tick_rate(          // Step 2: Get a good tick rate value          const double new_rate = _codec_mgr->get_auto_tick_rate(base_rate, num_chans);          // Step 3: Set the new tick rate value (if any change) -        if (!uhd::math::frequencies_are_equal(_tree->access<double>("/mboards/0/tick_rate").get(), new_rate)) { +        if (!uhd::math::frequencies_are_equal( +                _tree->access<double>("/mboards/0/tick_rate").get(), new_rate)) {              _tree->access<double>("/mboards/0/tick_rate").set(new_rate);          } -    } catch (const uhd::value_error &) { -        UHD_LOGGER_WARNING("B200") -            << "Cannot automatically determine an appropriate tick rate for these sampling rates."  -            << "Consider using different sampling rates, or manually specify a suitable master clock rate." ; +    } catch (const uhd::value_error&) { +        UHD_LOGGER_WARNING("B200") << "Cannot automatically determine an appropriate " +                                      "tick rate for these sampling rates." +                                   << "Consider using different sampling rates, or " +                                      "manually specify a suitable master clock rate.";          return; // Let the others handle this      }  } @@ -136,22 +142,25 @@ void b200_impl::update_tick_rate(const double new_tick_rate)  {      check_tick_rate_with_current_streamers(new_tick_rate); -    for(radio_perifs_t &perif:  _radio_perifs) -    { +    for (radio_perifs_t& perif : _radio_perifs) {          boost::shared_ptr<sph::recv_packet_streamer> my_streamer = -            boost::dynamic_pointer_cast<sph::recv_packet_streamer>(perif.rx_streamer.lock()); -        if (my_streamer) my_streamer->set_tick_rate(new_tick_rate); +            boost::dynamic_pointer_cast<sph::recv_packet_streamer>( +                perif.rx_streamer.lock()); +        if (my_streamer) +            my_streamer->set_tick_rate(new_tick_rate);          perif.framer->set_tick_rate(new_tick_rate);      } -    for(radio_perifs_t &perif:  _radio_perifs) -    { +    for (radio_perifs_t& perif : _radio_perifs) {          boost::shared_ptr<sph::send_packet_streamer> my_streamer = -            boost::dynamic_pointer_cast<sph::send_packet_streamer>(perif.tx_streamer.lock()); -        if (my_streamer) my_streamer->set_tick_rate(new_tick_rate); +            boost::dynamic_pointer_cast<sph::send_packet_streamer>( +                perif.tx_streamer.lock()); +        if (my_streamer) +            my_streamer->set_tick_rate(new_tick_rate);      }  } -void b200_impl::update_rx_dsp_tick_rate(const double tick_rate, rx_dsp_core_3000::sptr ddc, uhd::fs_path rx_dsp_path) +void b200_impl::update_rx_dsp_tick_rate( +    const double tick_rate, rx_dsp_core_3000::sptr ddc, uhd::fs_path rx_dsp_path)  {      ddc->set_tick_rate(tick_rate);      if (_tree->access<bool>(rx_dsp_path / "rate" / "set").get()) { @@ -159,7 +168,8 @@ void b200_impl::update_rx_dsp_tick_rate(const double tick_rate, rx_dsp_core_3000      }  } -void b200_impl::update_tx_dsp_tick_rate(const double tick_rate, tx_dsp_core_3000::sptr duc, uhd::fs_path tx_dsp_path) +void b200_impl::update_tx_dsp_tick_rate( +    const double tick_rate, tx_dsp_core_3000::sptr duc, uhd::fs_path tx_dsp_path)  {      duc->set_tick_rate(tick_rate);      if (_tree->access<bool>(tx_dsp_path / "rate" / "set").get()) { @@ -167,21 +177,27 @@ void b200_impl::update_tx_dsp_tick_rate(const double tick_rate, tx_dsp_core_3000      }  } -#define CHECK_RATE_AND_THROW(rate)  \ -        if (uhd::math::fp_compare::fp_compare_delta<double>(rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) > \ -            uhd::math::fp_compare::fp_compare_delta<double>(ad9361_device_t::AD9361_MAX_CLOCK_RATE, uhd::math::FREQ_COMPARISON_DELTA_HZ)) { \ -            throw uhd::value_error(str( \ -                    boost::format("Requested sampling rate (%.2f Msps) exceeds maximum tick rate.") \ -                    % (rate / 1e6) \ -            )); \ -        } +#define CHECK_RATE_AND_THROW(rate)                                                    \ +    if (uhd::math::fp_compare::fp_compare_delta<double>(                              \ +            rate, uhd::math::FREQ_COMPARISON_DELTA_HZ)                                \ +        > uhd::math::fp_compare::fp_compare_delta<double>(                            \ +              ad9361_device_t::AD9361_MAX_CLOCK_RATE,                                 \ +              uhd::math::FREQ_COMPARISON_DELTA_HZ)) {                                 \ +        throw uhd::value_error(                                                       \ +            str(boost::format(                                                        \ +                    "Requested sampling rate (%.2f Msps) exceeds maximum tick rate.") \ +                % (rate / 1e6)));                                                     \ +    } -double b200_impl::coerce_rx_samp_rate(rx_dsp_core_3000::sptr ddc, size_t dspno, const double rx_rate) +double b200_impl::coerce_rx_samp_rate( +    rx_dsp_core_3000::sptr ddc, size_t dspno, const double rx_rate)  { -    // Have to set tick rate first, or the ddc will change the requested rate based on default tick rate +    // Have to set tick rate first, or the ddc will change the requested rate based on +    // default tick rate      if (_tree->access<bool>("/mboards/0/auto_tick_rate").get()) {          CHECK_RATE_AND_THROW(rx_rate); -        const std::string dsp_path = (boost::format("/mboards/0/rx_dsps/%s") % dspno).str(); +        const std::string dsp_path = +            (boost::format("/mboards/0/rx_dsps/%s") % dspno).str();          set_auto_tick_rate(rx_rate, dsp_path);      }      return ddc->set_host_rate(rx_rate); @@ -190,20 +206,25 @@ double b200_impl::coerce_rx_samp_rate(rx_dsp_core_3000::sptr ddc, size_t dspno,  void b200_impl::update_rx_samp_rate(const size_t dspno, const double rate)  {      boost::shared_ptr<sph::recv_packet_streamer> my_streamer = -        boost::dynamic_pointer_cast<sph::recv_packet_streamer>(_radio_perifs[dspno].rx_streamer.lock()); -    if (not my_streamer) return; +        boost::dynamic_pointer_cast<sph::recv_packet_streamer>( +            _radio_perifs[dspno].rx_streamer.lock()); +    if (not my_streamer) +        return;      my_streamer->set_samp_rate(rate);      const double adj = _radio_perifs[dspno].ddc->get_scaling_adjustment();      my_streamer->set_scale_factor(adj);      _codec_mgr->check_bandwidth(rate, "Rx");  } -double b200_impl::coerce_tx_samp_rate(tx_dsp_core_3000::sptr duc, size_t dspno, const double tx_rate) +double b200_impl::coerce_tx_samp_rate( +    tx_dsp_core_3000::sptr duc, size_t dspno, const double tx_rate)  { -    // Have to set tick rate first, or the duc will change the requested rate based on default tick rate +    // Have to set tick rate first, or the duc will change the requested rate based on +    // default tick rate      if (_tree->access<bool>("/mboards/0/auto_tick_rate").get()) {          CHECK_RATE_AND_THROW(tx_rate); -        const std::string dsp_path = (boost::format("/mboards/0/tx_dsps/%s") % dspno).str(); +        const std::string dsp_path = +            (boost::format("/mboards/0/tx_dsps/%s") % dspno).str();          set_auto_tick_rate(tx_rate, dsp_path);      }      return duc->set_host_rate(tx_rate); @@ -212,8 +233,10 @@ double b200_impl::coerce_tx_samp_rate(tx_dsp_core_3000::sptr duc, size_t dspno,  void b200_impl::update_tx_samp_rate(const size_t dspno, const double rate)  {      boost::shared_ptr<sph::send_packet_streamer> my_streamer = -        boost::dynamic_pointer_cast<sph::send_packet_streamer>(_radio_perifs[dspno].tx_streamer.lock()); -    if (not my_streamer) return; +        boost::dynamic_pointer_cast<sph::send_packet_streamer>( +            _radio_perifs[dspno].tx_streamer.lock()); +    if (not my_streamer) +        return;      my_streamer->set_samp_rate(rate);      const double adj = _radio_perifs[dspno].duc->get_scaling_adjustment();      my_streamer->set_scale_factor(adj); @@ -223,7 +246,8 @@ void b200_impl::update_tx_samp_rate(const size_t dspno, const double rate)  /***********************************************************************   * frontend selection   **********************************************************************/ -uhd::usrp::subdev_spec_t b200_impl::coerce_subdev_spec(const uhd::usrp::subdev_spec_t &spec_) +uhd::usrp::subdev_spec_t b200_impl::coerce_subdev_spec( +    const uhd::usrp::subdev_spec_t& spec_)  {      uhd::usrp::subdev_spec_t spec = spec_;      // Because of the confusing nature of the subdevs on B200 @@ -232,16 +256,17 @@ uhd::usrp::subdev_spec_t b200_impl::coerce_subdev_spec(const uhd::usrp::subdev_s      //      // Any other spec is probably illegal and will be caught by      // validate_subdev_spec(). -    if (spec.size() and (_product == B200 or _product == B200MINI or _product == B205MINI) and spec[0].sd_name == "B") -    { +    if (spec.size() and (_product == B200 or _product == B200MINI or _product == B205MINI) +        and spec[0].sd_name == "B") {          spec[0].sd_name = "A";      }      return spec;  } -void b200_impl::update_subdev_spec(const std::string &tx_rx, const uhd::usrp::subdev_spec_t &spec) +void b200_impl::update_subdev_spec( +    const std::string& tx_rx, const uhd::usrp::subdev_spec_t& spec)  { -    //sanity checking +    // sanity checking      if (spec.size()) {          validate_subdev_spec(_tree, spec, tx_rx);      } @@ -250,23 +275,22 @@ void b200_impl::update_subdev_spec(const std::string &tx_rx, const uhd::usrp::su      for (size_t i = 0; i < spec.size(); i++) {          chan_to_dsp_map[i] = (spec[i].sd_name == "A") ? 0 : 1;      } -    _tree->access<std::vector<size_t> >("/mboards/0" / (tx_rx + "_chan_dsp_mapping")).set(chan_to_dsp_map); +    _tree->access<std::vector<size_t>>("/mboards/0" / (tx_rx + "_chan_dsp_mapping")) +        .set(chan_to_dsp_map);      this->update_enables();  }  static void b200_if_hdr_unpack_le( -    const uint32_t *packet_buff, -    vrt::if_packet_info_t &if_packet_info -){ +    const uint32_t* packet_buff, vrt::if_packet_info_t& if_packet_info) +{      if_packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR;      return vrt::if_hdr_unpack_le(packet_buff, if_packet_info);  }  static void b200_if_hdr_pack_le( -    uint32_t *packet_buff, -    vrt::if_packet_info_t &if_packet_info -){ +    uint32_t* packet_buff, vrt::if_packet_info_t& if_packet_info) +{      if_packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR;      return vrt::if_hdr_pack_le(packet_buff, if_packet_info);  } @@ -274,93 +298,91 @@ static void b200_if_hdr_pack_le(  /***********************************************************************   * Async Data   **********************************************************************/ -bool b200_impl::recv_async_msg( -    async_metadata_t &async_metadata, double timeout -){ +bool b200_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout) +{      return _async_task_data->async_md->pop_with_timed_wait(async_metadata, timeout);  }  /*   * This method is constantly called in a msg_task loop.   * Incoming messages are dispatched in to the hosts radio_ctrl_cores. - * The radio_ctrl_core queues are accessed via a weak_ptr to them, stored in AsyncTaskData. - * During shutdown the radio_ctrl_core dtor's are called. - * An empty peek32(0) is sent out to flush pending async messages. - * The response to those messages can't be delivered to the ctrl_core queues anymore - * because the shared pointer corresponding to the weak_ptrs is no longer valid. - * Those stranded messages are put into a dump_queue implemented in msg_task. - * A radio_ctrl_core can search for missing messages there. + * The radio_ctrl_core queues are accessed via a weak_ptr to them, stored in + * AsyncTaskData. During shutdown the radio_ctrl_core dtor's are called. An empty + * peek32(0) is sent out to flush pending async messages. The response to those messages + * can't be delivered to the ctrl_core queues anymore because the shared pointer + * corresponding to the weak_ptrs is no longer valid. Those stranded messages are put into + * a dump_queue implemented in msg_task. A radio_ctrl_core can search for missing messages + * there.   */  boost::optional<uhd::msg_task::msg_type_t> b200_impl::handle_async_task( -    uhd::transport::zero_copy_if::sptr xport, -    boost::shared_ptr<AsyncTaskData> data -) +    uhd::transport::zero_copy_if::sptr xport, boost::shared_ptr<AsyncTaskData> data)  {      managed_recv_buffer::sptr buff = xport->get_recv_buff();      if (not buff or buff->size() < 8)          return boost::none; -    const uint32_t sid = uhd::wtohx(buff->cast<const uint32_t *>()[1]); +    const uint32_t sid = uhd::wtohx(buff->cast<const uint32_t*>()[1]);      switch (sid) { - -    //if the packet is a control response -    case B200_RESP0_MSG_SID: -    case B200_RESP1_MSG_SID: -    case B200_LOCAL_RESP_SID: -    { -    	radio_ctrl_core_3000::sptr ctrl; -        if (sid == B200_RESP0_MSG_SID) ctrl = data->radio_ctrl[0].lock(); -        if (sid == B200_RESP1_MSG_SID) ctrl = data->radio_ctrl[1].lock(); -        if (sid == B200_LOCAL_RESP_SID) ctrl = data->local_ctrl.lock(); -        if (ctrl){ -        	ctrl->push_response(buff->cast<const uint32_t *>()); -        } -        else{ -            return std::make_pair(sid, uhd::msg_task::buff_to_vector(buff->cast<uint8_t *>(), buff->size() ) ); +        // if the packet is a control response +        case B200_RESP0_MSG_SID: +        case B200_RESP1_MSG_SID: +        case B200_LOCAL_RESP_SID: { +            radio_ctrl_core_3000::sptr ctrl; +            if (sid == B200_RESP0_MSG_SID) +                ctrl = data->radio_ctrl[0].lock(); +            if (sid == B200_RESP1_MSG_SID) +                ctrl = data->radio_ctrl[1].lock(); +            if (sid == B200_LOCAL_RESP_SID) +                ctrl = data->local_ctrl.lock(); +            if (ctrl) { +                ctrl->push_response(buff->cast<const uint32_t*>()); +            } else { +                return std::make_pair(sid, +                    uhd::msg_task::buff_to_vector(buff->cast<uint8_t*>(), buff->size())); +            } +            break;          } -        break; -    } -    //if the packet is a uart message -    case B200_RX_GPS_UART_SID: -    { -        data->gpsdo_uart->handle_uart_packet(buff); -        break; -    } - -    //or maybe the packet is a TX async message -    case B200_TX_MSG0_SID: -    case B200_TX_MSG1_SID: -    { -        const size_t i = (sid == B200_TX_MSG0_SID)? 0 : 1; +        // if the packet is a uart message +        case B200_RX_GPS_UART_SID: { +            data->gpsdo_uart->handle_uart_packet(buff); +            break; +        } -        //extract packet info -        vrt::if_packet_info_t if_packet_info; -        if_packet_info.num_packet_words32 = buff->size()/sizeof(uint32_t); -        const uint32_t *packet_buff = buff->cast<const uint32_t *>(); +        // or maybe the packet is a TX async message +        case B200_TX_MSG0_SID: +        case B200_TX_MSG1_SID: { +            const size_t i = (sid == B200_TX_MSG0_SID) ? 0 : 1; + +            // extract packet info +            vrt::if_packet_info_t if_packet_info; +            if_packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t); +            const uint32_t* packet_buff       = buff->cast<const uint32_t*>(); + +            // unpacking can fail +            try { +                b200_if_hdr_unpack_le(packet_buff, if_packet_info); +            } catch (const std::exception& ex) { +                UHD_LOGGER_ERROR("B200") << "Error parsing ctrl packet: " << ex.what(); +                break; +            } -        //unpacking can fail -        try -        { -            b200_if_hdr_unpack_le(packet_buff, if_packet_info); -        } -        catch(const std::exception &ex) -        { -            UHD_LOGGER_ERROR("B200") << "Error parsing ctrl packet: " << ex.what(); +            // fill in the async metadata +            async_metadata_t metadata; +            load_metadata_from_buff(uhd::wtohx<uint32_t>, +                metadata, +                if_packet_info, +                packet_buff, +                _tick_rate, +                i); +            data->async_md->push_with_pop_on_full(metadata); +            standard_async_msg_prints(metadata);              break;          } -        //fill in the async metadata -        async_metadata_t metadata; -        load_metadata_from_buff(uhd::wtohx<uint32_t>, metadata, if_packet_info, packet_buff, _tick_rate, i); -        data->async_md->push_with_pop_on_full(metadata); -        standard_async_msg_prints(metadata); -        break; -    } - -    //doh! -    default: -        UHD_LOGGER_ERROR("B200") << "Got a ctrl packet with unknown SID " << sid; +        // doh! +        default: +            UHD_LOGGER_ERROR("B200") << "Got a ctrl packet with unknown SID " << sid;      }      return boost::none;  } @@ -368,15 +390,16 @@ boost::optional<uhd::msg_task::msg_type_t> b200_impl::handle_async_task(  /***********************************************************************   * Receive streamer   **********************************************************************/ -rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_) +rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t& args_)  {      boost::mutex::scoped_lock lock(_transport_setup_mutex);      stream_args_t args = args_; -    //setup defaults for unspecified values -    if (args.otw_format.empty()) args.otw_format = "sc16"; -    args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; +    // setup defaults for unspecified values +    if (args.otw_format.empty()) +        args.otw_format = "sc16"; +    args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels;      if (_tree->access<bool>("/mboards/0/auto_tick_rate").get()) {          set_auto_tick_rate(0, "", args.channels.size()); @@ -384,42 +407,49 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_)      check_streamer_args(args, this->get_tick_rate(), "RX");      boost::shared_ptr<sph::recv_packet_streamer> my_streamer; -    for (size_t stream_i = 0; stream_i < args.channels.size(); stream_i++) -    { -        const size_t radio_index = _tree->access<std::vector<size_t> >("/mboards/0/rx_chan_dsp_mapping") -                                        .get().at(args.channels[stream_i]); -        radio_perifs_t &perif = _radio_perifs[radio_index]; -        if (args.otw_format == "sc16") perif.ctrl->poke32(TOREG(SR_RX_FMT), 0); -        if (args.otw_format == "sc12") perif.ctrl->poke32(TOREG(SR_RX_FMT), 1); -        if (args.otw_format == "fc32") perif.ctrl->poke32(TOREG(SR_RX_FMT), 2); -        if (args.otw_format == "sc8") perif.ctrl->poke32(TOREG(SR_RX_FMT), 3); +    for (size_t stream_i = 0; stream_i < args.channels.size(); stream_i++) { +        const size_t radio_index = +            _tree->access<std::vector<size_t>>("/mboards/0/rx_chan_dsp_mapping") +                .get() +                .at(args.channels[stream_i]); +        radio_perifs_t& perif = _radio_perifs[radio_index]; +        if (args.otw_format == "sc16") +            perif.ctrl->poke32(TOREG(SR_RX_FMT), 0); +        if (args.otw_format == "sc12") +            perif.ctrl->poke32(TOREG(SR_RX_FMT), 1); +        if (args.otw_format == "fc32") +            perif.ctrl->poke32(TOREG(SR_RX_FMT), 2); +        if (args.otw_format == "sc8") +            perif.ctrl->poke32(TOREG(SR_RX_FMT), 3);          const uint32_t sid = radio_index ? B200_RX_DATA1_SID : B200_RX_DATA0_SID; -        //calculate packet size -        static const size_t hdr_size = 0 -            + vrt::max_if_hdr_words32*sizeof(uint32_t) +        // calculate packet size +        static const size_t hdr_size = +            0 +            + vrt::max_if_hdr_words32 * sizeof(uint32_t)              //+ sizeof(vrt::if_packet_info_t().tlr) //no longer using trailer -            - sizeof(vrt::if_packet_info_t().cid) //no class id ever used -            - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used -        ; +            - sizeof(vrt::if_packet_info_t().cid) // no class id ever used +            - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used +            ;          const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size;          const size_t bpi = convert::get_bytes_per_item(args.otw_format); -        size_t spp = unsigned(args.args.cast<double>("spp", bpp/bpi)); -        spp = std::min<size_t>(4092, spp); //FPGA FIFO maximum for framing at full rate +        size_t spp       = unsigned(args.args.cast<double>("spp", bpp / bpi)); +        spp = std::min<size_t>(4092, spp); // FPGA FIFO maximum for framing at full rate -        //make the new streamer given the samples per packet -        if (not my_streamer) my_streamer = boost::make_shared<sph::recv_packet_streamer>(spp); +        // make the new streamer given the samples per packet +        if (not my_streamer) +            my_streamer = boost::make_shared<sph::recv_packet_streamer>(spp);          my_streamer->resize(args.channels.size()); -        //init some streamer stuff +        // init some streamer stuff          my_streamer->set_vrt_unpacker(&b200_if_hdr_unpack_le); -        //set the converter +        // set the converter          uhd::convert::id_type id; -        id.input_format = args.otw_format + "_item32_le"; -        id.num_inputs = 1; +        id.input_format  = args.otw_format + "_item32_le"; +        id.num_inputs    = 1;          id.output_format = args.cpu_format; -        id.num_outputs = 1; +        id.num_outputs   = 1;          my_streamer->set_converter(id);          perif.framer->clear(); @@ -428,20 +458,21 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_)          perif.framer->setup(args);          perif.ddc->setup(args);          _demux->realloc_sid(sid); -        my_streamer->set_xport_chan_get_buff(stream_i, boost::bind( -            &recv_packet_demuxer_3000::get_recv_buff, _demux, sid, _1 -        ), true /*flush*/); -        my_streamer->set_overflow_handler(stream_i, boost::bind( -            &b200_impl::handle_overflow, this, radio_index -        )); -        my_streamer->set_issue_stream_cmd(stream_i, boost::bind( -            &rx_vita_core_3000::issue_stream_command, perif.framer, _1 -        )); -        perif.rx_streamer = my_streamer; //store weak pointer - -        //sets all tick and samp rates on this streamer +        my_streamer->set_xport_chan_get_buff(stream_i, +            boost::bind(&recv_packet_demuxer_3000::get_recv_buff, _demux, sid, _1), +            true /*flush*/); +        my_streamer->set_overflow_handler( +            stream_i, boost::bind(&b200_impl::handle_overflow, this, radio_index)); +        my_streamer->set_issue_stream_cmd(stream_i, +            boost::bind(&rx_vita_core_3000::issue_stream_command, perif.framer, _1)); +        perif.rx_streamer = my_streamer; // store weak pointer + +        // sets all tick and samp rates on this streamer          this->update_tick_rate(this->get_tick_rate()); -        _tree->access<double>(str(boost::format("/mboards/0/rx_dsps/%u/rate/value") % radio_index)).update(); +        _tree +            ->access<double>( +                str(boost::format("/mboards/0/rx_dsps/%u/rate/value") % radio_index)) +            .update();      }      this->update_enables(); @@ -451,42 +482,46 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_)  void b200_impl::handle_overflow(const size_t radio_index)  {      boost::shared_ptr<sph::recv_packet_streamer> my_streamer = -            boost::dynamic_pointer_cast<sph::recv_packet_streamer>(_radio_perifs[radio_index].rx_streamer.lock()); -    if (my_streamer->get_num_channels() == 2) //MIMO time +        boost::dynamic_pointer_cast<sph::recv_packet_streamer>( +            _radio_perifs[radio_index].rx_streamer.lock()); +    if (my_streamer->get_num_channels() == 2) // MIMO time      { -        //find out if we were in continuous mode before stopping -        const bool in_continuous_streaming_mode = _radio_perifs[radio_index].framer->in_continuous_streaming_mode(); -        //stop streaming +        // find out if we were in continuous mode before stopping +        const bool in_continuous_streaming_mode = +            _radio_perifs[radio_index].framer->in_continuous_streaming_mode(); +        // stop streaming          my_streamer->issue_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); -        //flush demux +        // flush demux          _demux->realloc_sid(B200_RX_DATA0_SID);          _demux->realloc_sid(B200_RX_DATA1_SID); -        //flush actual transport -        while (_data_transport->get_recv_buff(0.001)){} -        //restart streaming -        if (in_continuous_streaming_mode) -        { +        // flush actual transport +        while (_data_transport->get_recv_buff(0.001)) { +        } +        // restart streaming +        if (in_continuous_streaming_mode) {              stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);              stream_cmd.stream_now = false; -            stream_cmd.time_spec = _radio_perifs[radio_index].time64->get_time_now() + time_spec_t(0.01); +            stream_cmd.time_spec = +                _radio_perifs[radio_index].time64->get_time_now() + time_spec_t(0.01);              my_streamer->issue_stream_cmd(stream_cmd);          } -    } -    else _radio_perifs[radio_index].framer->handle_overflow(); +    } else +        _radio_perifs[radio_index].framer->handle_overflow();  }  /***********************************************************************   * Transmit streamer   **********************************************************************/ -tx_streamer::sptr b200_impl::get_tx_stream(const uhd::stream_args_t &args_) +tx_streamer::sptr b200_impl::get_tx_stream(const uhd::stream_args_t& args_)  {      boost::mutex::scoped_lock lock(_transport_setup_mutex);      stream_args_t args = args_; -    //setup defaults for unspecified values -    if (args.otw_format.empty()) args.otw_format = "sc16"; -    args.channels = args.channels.empty()? std::vector<size_t>(1, 0) : args.channels; +    // setup defaults for unspecified values +    if (args.otw_format.empty()) +        args.otw_format = "sc16"; +    args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels;      if (_tree->access<bool>("/mboards/0/auto_tick_rate").get()) {          set_auto_tick_rate(0, "", args.channels.size()); @@ -494,58 +529,68 @@ tx_streamer::sptr b200_impl::get_tx_stream(const uhd::stream_args_t &args_)      check_streamer_args(args, this->get_tick_rate(), "TX");      boost::shared_ptr<sph::send_packet_streamer> my_streamer; -    for (size_t stream_i = 0; stream_i < args.channels.size(); stream_i++) -    { -        const size_t radio_index = _tree->access<std::vector<size_t> >("/mboards/0/tx_chan_dsp_mapping") -                                        .get().at(args.channels[stream_i]); -        radio_perifs_t &perif = _radio_perifs[radio_index]; -        if (args.otw_format == "sc16") perif.ctrl->poke32(TOREG(SR_TX_FMT), 0); -        if (args.otw_format == "sc12") perif.ctrl->poke32(TOREG(SR_TX_FMT), 1); -        if (args.otw_format == "fc32") perif.ctrl->poke32(TOREG(SR_TX_FMT), 2); -        if (args.otw_format == "sc8") perif.ctrl->poke32(TOREG(SR_TX_FMT), 3); - -        //calculate packet size -        static const size_t hdr_size = 0 -            + vrt::max_if_hdr_words32*sizeof(uint32_t) +    for (size_t stream_i = 0; stream_i < args.channels.size(); stream_i++) { +        const size_t radio_index = +            _tree->access<std::vector<size_t>>("/mboards/0/tx_chan_dsp_mapping") +                .get() +                .at(args.channels[stream_i]); +        radio_perifs_t& perif = _radio_perifs[radio_index]; +        if (args.otw_format == "sc16") +            perif.ctrl->poke32(TOREG(SR_TX_FMT), 0); +        if (args.otw_format == "sc12") +            perif.ctrl->poke32(TOREG(SR_TX_FMT), 1); +        if (args.otw_format == "fc32") +            perif.ctrl->poke32(TOREG(SR_TX_FMT), 2); +        if (args.otw_format == "sc8") +            perif.ctrl->poke32(TOREG(SR_TX_FMT), 3); + +        // calculate packet size +        static const size_t hdr_size = +            0 +            + vrt::max_if_hdr_words32 * sizeof(uint32_t)              //+ sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer -            - sizeof(vrt::if_packet_info_t().cid) //no class id ever used -            - sizeof(vrt::if_packet_info_t().tsi) //no int time ever used -        ; +            - sizeof(vrt::if_packet_info_t().cid) // no class id ever used +            - sizeof(vrt::if_packet_info_t().tsi) // no int time ever used +            ;          static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size; -        const size_t spp = bpp/convert::get_bytes_per_item(args.otw_format); +        const size_t spp        = bpp / convert::get_bytes_per_item(args.otw_format); -        //make the new streamer given the samples per packet -        if (not my_streamer) my_streamer = boost::make_shared<sph::send_packet_streamer>(spp); +        // make the new streamer given the samples per packet +        if (not my_streamer) +            my_streamer = boost::make_shared<sph::send_packet_streamer>(spp);          my_streamer->resize(args.channels.size()); -        //init some streamer stuff +        // init some streamer stuff          my_streamer->set_vrt_packer(&b200_if_hdr_pack_le); -        //set the converter +        // set the converter          uhd::convert::id_type id; -        id.input_format = args.cpu_format; -        id.num_inputs = 1; +        id.input_format  = args.cpu_format; +        id.num_inputs    = 1;          id.output_format = args.otw_format + "_item32_le"; -        id.num_outputs = 1; +        id.num_outputs   = 1;          my_streamer->set_converter(id);          perif.deframer->clear();          perif.deframer->setup(args);          perif.duc->setup(args); -        my_streamer->set_xport_chan_get_buff(stream_i, boost::bind( -            &zero_copy_if::get_send_buff, _data_transport, _1 -        )); +        my_streamer->set_xport_chan_get_buff( +            stream_i, boost::bind(&zero_copy_if::get_send_buff, _data_transport, _1));          my_streamer->set_async_receiver(boost::bind( -            &async_md_type::pop_with_timed_wait, _async_task_data->async_md, _1, _2 -        )); -        my_streamer->set_xport_chan_sid(stream_i, true, radio_index ? B200_TX_DATA1_SID : B200_TX_DATA0_SID); -        my_streamer->set_enable_trailer(false); //TODO not implemented trailer support yet -        perif.tx_streamer = my_streamer; //store weak pointer - -        //sets all tick and samp rates on this streamer +            &async_md_type::pop_with_timed_wait, _async_task_data->async_md, _1, _2)); +        my_streamer->set_xport_chan_sid( +            stream_i, true, radio_index ? B200_TX_DATA1_SID : B200_TX_DATA0_SID); +        my_streamer->set_enable_trailer(false); // TODO not implemented trailer support +                                                // yet +        perif.tx_streamer = my_streamer; // store weak pointer + +        // sets all tick and samp rates on this streamer          this->update_tick_rate(this->get_tick_rate()); -        _tree->access<double>(str(boost::format("/mboards/0/tx_dsps/%u/rate/value") % radio_index)).update(); +        _tree +            ->access<double>( +                str(boost::format("/mboards/0/tx_dsps/%u/rate/value") % radio_index)) +            .update();      }      this->update_enables(); diff --git a/host/lib/usrp/common/ad936x_manager.cpp b/host/lib/usrp/common/ad936x_manager.cpp index 8fd2a919d..87521e834 100644 --- a/host/lib/usrp/common/ad936x_manager.cpp +++ b/host/lib/usrp/common/ad936x_manager.cpp @@ -5,8 +5,8 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include <uhdlib/usrp/common/ad936x_manager.hpp>  #include <uhd/utils/log.hpp> +#include <uhdlib/usrp/common/ad936x_manager.hpp>  #include <boost/functional/hash.hpp>  #include <boost/make_shared.hpp>  #include <chrono> @@ -18,15 +18,15 @@ using namespace uhd::usrp;  /****************************************************************************   * Default values   ***************************************************************************/ -const double   ad936x_manager::DEFAULT_GAIN = 0; -const double   ad936x_manager::DEFAULT_BANDWIDTH = ad9361_device_t::AD9361_MAX_BW; -const double   ad936x_manager::DEFAULT_TICK_RATE = 16e6; -const double   ad936x_manager::DEFAULT_FREQ = 100e6; // Hz -const uint32_t ad936x_manager::DEFAULT_DECIM  = 128; -const uint32_t ad936x_manager::DEFAULT_INTERP = 128; -const bool     ad936x_manager::DEFAULT_AUTO_DC_OFFSET = true; -const bool     ad936x_manager::DEFAULT_AUTO_IQ_BALANCE = true; -const bool     ad936x_manager::DEFAULT_AGC_ENABLE = false; +const double ad936x_manager::DEFAULT_GAIN          = 0; +const double ad936x_manager::DEFAULT_BANDWIDTH     = ad9361_device_t::AD9361_MAX_BW; +const double ad936x_manager::DEFAULT_TICK_RATE     = 16e6; +const double ad936x_manager::DEFAULT_FREQ          = 100e6; // Hz +const uint32_t ad936x_manager::DEFAULT_DECIM       = 128; +const uint32_t ad936x_manager::DEFAULT_INTERP      = 128; +const bool ad936x_manager::DEFAULT_AUTO_DC_OFFSET  = true; +const bool ad936x_manager::DEFAULT_AUTO_IQ_BALANCE = true; +const bool ad936x_manager::DEFAULT_AGC_ENABLE      = false;  class ad936x_manager_impl : public ad936x_manager  { @@ -34,17 +34,14 @@ public:      /************************************************************************       * Structor       ***********************************************************************/ -    ad936x_manager_impl( -            const ad9361_ctrl::sptr &codec_ctrl, -            const size_t n_frontends -    ) : _codec_ctrl(codec_ctrl), -        _n_frontends(n_frontends) +    ad936x_manager_impl(const ad9361_ctrl::sptr& codec_ctrl, const size_t n_frontends) +        : _codec_ctrl(codec_ctrl), _n_frontends(n_frontends)      {          if (_n_frontends < 1 or _n_frontends > 2) { -            throw uhd::runtime_error(str( -                boost::format("AD936x device can only have either 1 or 2 frontends, not %d.") -                % _n_frontends -            )); +            throw uhd::runtime_error( +                str(boost::format( +                        "AD936x device can only have either 1 or 2 frontends, not %d.") +                    % _n_frontends));          }          for (size_t i = 1; i <= _n_frontends; i++) {              const std::string rx_fe_str = str(boost::format("RX%d") % i); @@ -61,7 +58,7 @@ public:       ***********************************************************************/      void init_codec()      { -        for (const std::string &rx_fe : _rx_frontends) { +        for (const std::string& rx_fe : _rx_frontends) {              _codec_ctrl->set_gain(rx_fe, DEFAULT_GAIN);              _codec_ctrl->set_bw_filter(rx_fe, DEFAULT_BANDWIDTH);              _codec_ctrl->tune(rx_fe, DEFAULT_FREQ); @@ -69,7 +66,7 @@ public:              _codec_ctrl->set_iq_balance_auto(rx_fe, DEFAULT_AUTO_IQ_BALANCE);              _codec_ctrl->set_agc(rx_fe, DEFAULT_AGC_ENABLE);          } -        for (const std::string &tx_fe : _tx_frontends) { +        for (const std::string& tx_fe : _tx_frontends) {              _codec_ctrl->set_gain(tx_fe, DEFAULT_GAIN);              _codec_ctrl->set_bw_filter(tx_fe, DEFAULT_BANDWIDTH);              _codec_ctrl->tune(tx_fe, DEFAULT_FREQ); @@ -87,10 +84,9 @@ public:      // whatever timing is configured at the time the test is called rather than select      // worst case conditions to stress the interface.      // -    void loopback_self_test( -          std::function<void(uint32_t)> poker_functor, -          std::function<uint64_t()> peeker_functor -    ) { +    void loopback_self_test(std::function<void(uint32_t)> poker_functor, +        std::function<uint64_t()> peeker_functor) +    {          // Put AD936x in loopback mode          _codec_ctrl->data_port_loopback(true);          UHD_LOGGER_DEBUG("AD936X") << "Performing CODEC loopback test... "; @@ -115,16 +111,16 @@ public:              // Read back values              const uint64_t rb_word64 = peeker_functor(); -            const uint32_t rb_tx = uint32_t(rb_word64 >> 32); -            const uint32_t rb_rx = uint32_t(rb_word64 & 0xffffffff); +            const uint32_t rb_tx     = uint32_t(rb_word64 >> 32); +            const uint32_t rb_rx     = uint32_t(rb_word64 & 0xffffffff);              // Compare TX and RX values to test word              const bool test_fail = word32 != rb_tx or word32 != rb_rx;              if (test_fail) {                  UHD_LOGGER_ERROR("AD936X") -                  << "CODEC loopback test failed! " -                  << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") -                      % word32 % rb_tx % rb_rx; +                    << "CODEC loopback test failed! " +                    << boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X") +                           % word32 % rb_tx % rb_rx;                  throw uhd::runtime_error("CODEC loopback test failed.");              }          } @@ -138,22 +134,22 @@ public:      } -    double get_auto_tick_rate( -            const double lcm_rate, -            size_t num_chans -    ) { +    double get_auto_tick_rate(const double lcm_rate, size_t num_chans) +    {          UHD_ASSERT_THROW(num_chans >= 1 and num_chans <= _n_frontends);          const uhd::meta_range_t rate_range = _codec_ctrl->get_clock_rate_range(); -        const double min_tick_rate = rate_range.start(); -        const double max_tick_rate = rate_range.stop() / num_chans; +        const double min_tick_rate         = rate_range.start(); +        const double max_tick_rate         = rate_range.stop() / num_chans;          // Check if the requested rate is within available limits: -        if (uhd::math::fp_compare::fp_compare_delta<double>(lcm_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) > -            uhd::math::fp_compare::fp_compare_delta<double>(max_tick_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ)) { -            throw uhd::value_error(str( -                    boost::format("[ad936x_manager] Cannot get determine a tick rate if sampling rate exceeds maximum tick rate (%f > %f)") -                    % lcm_rate % max_tick_rate -            )); +        if (uhd::math::fp_compare::fp_compare_delta<double>( +                lcm_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) +            > uhd::math::fp_compare::fp_compare_delta<double>( +                  max_tick_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ)) { +            throw uhd::value_error( +                str(boost::format("[ad936x_manager] Cannot get determine a tick rate if " +                                  "sampling rate exceeds maximum tick rate (%f > %f)") +                    % lcm_rate % max_tick_rate));          }          // **** Choose the new rate **** @@ -168,22 +164,23 @@ public:          //          // where r is the base rate and f_max is the maximum tick rate. The case          // where floor() yields 1 must be caught. -        // We use shifts here instead of 2^x because exp2() is not available in all compilers, -        // also this guarantees no rounding issues. The type cast to int32_t serves as floor(): +        // We use shifts here instead of 2^x because exp2() is not available in all +        // compilers, also this guarantees no rounding issues. The type cast to int32_t +        // serves as floor():          int32_t multiplier = (1 << int32_t(uhd::math::log2(max_tick_rate / lcm_rate)));          if (multiplier == 2 and lcm_rate >= min_tick_rate) {              // Don't bother (see above)              multiplier = 1;          }          const double new_rate = lcm_rate * multiplier; -        UHD_ASSERT_THROW( -            uhd::math::fp_compare::fp_compare_delta<double>(new_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) >= -            uhd::math::fp_compare::fp_compare_delta<double>(min_tick_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) -        ); -        UHD_ASSERT_THROW( -            uhd::math::fp_compare::fp_compare_delta<double>(new_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) <= -            uhd::math::fp_compare::fp_compare_delta<double>(max_tick_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) -        ); +        UHD_ASSERT_THROW(uhd::math::fp_compare::fp_compare_delta<double>( +                             new_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) +                         >= uhd::math::fp_compare::fp_compare_delta<double>( +                                min_tick_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ)); +        UHD_ASSERT_THROW(uhd::math::fp_compare::fp_compare_delta<double>( +                             new_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ) +                         <= uhd::math::fp_compare::fp_compare_delta<double>( +                                max_tick_rate, uhd::math::FREQ_COMPARISON_DELTA_HZ));          return new_rate;      } @@ -191,59 +188,49 @@ public:      bool check_bandwidth(double rate, const std::string dir)      {          double bw = _bw[dir == "Rx" ? "RX1" : "TX1"]; -        if (bw == 0.) //0 indicates bandwidth is default value. +        if (bw == 0.) // 0 indicates bandwidth is default value.          {              double max_bw = ad9361_device_t::AD9361_MAX_BW;              double min_bw = ad9361_device_t::AD9361_MIN_BW; -            if (rate > max_bw) -            { -            UHD_LOGGER_WARNING("AD936X") -                << "Selected " << dir << " sample rate (" << (rate/1e6) << " MHz) is greater than\n" -                << "analog frontend filter bandwidth (" << (max_bw/1e6) << " MHz)." -                ; -            } -            else if (rate < min_bw) -            { -            UHD_LOGGER_WARNING("AD936X") -                << "Selected " << dir << " sample rate (" << (rate/1e6) << " MHz) is less than\n" -                << "analog frontend filter bandwidth (" << (min_bw/1e6) << " MHz)." -                ; +            if (rate > max_bw) { +                UHD_LOGGER_WARNING("AD936X") +                    << "Selected " << dir << " sample rate (" << (rate / 1e6) +                    << " MHz) is greater than\n" +                    << "analog frontend filter bandwidth (" << (max_bw / 1e6) << " MHz)."; +            } else if (rate < min_bw) { +                UHD_LOGGER_WARNING("AD936X") +                    << "Selected " << dir << " sample rate (" << (rate / 1e6) +                    << " MHz) is less than\n" +                    << "analog frontend filter bandwidth (" << (min_bw / 1e6) << " MHz).";              }          }          return (rate <= bw);      }      void populate_frontend_subtree( -        uhd::property_tree::sptr subtree, -        const std::string &key, -        uhd::direction_t dir -    ) { -        subtree->create<std::string>("name").set("FE-"+key); +        uhd::property_tree::sptr subtree, const std::string& key, uhd::direction_t dir) +    { +        subtree->create<std::string>("name").set("FE-" + key);          // Sensors -        subtree->create<sensor_value_t>("sensors/temp") -            .set_publisher([this](){ -                return this->_codec_ctrl->get_temperature(); -            }) -        ; +        subtree->create<sensor_value_t>("sensors/temp").set_publisher([this]() { +            return this->_codec_ctrl->get_temperature(); +        });          if (dir == RX_DIRECTION) { -            subtree->create<sensor_value_t>("sensors/rssi") -                .set_publisher([this, key](){ -                    return this->_codec_ctrl->get_rssi(key); -                }) -            ; +            subtree->create<sensor_value_t>("sensors/rssi").set_publisher([this, key]() { +                return this->_codec_ctrl->get_rssi(key); +            });          }          // Gains -        for (const std::string &name : ad9361_ctrl::get_gain_names(key)) { +        for (const std::string& name : ad9361_ctrl::get_gain_names(key)) {              subtree->create<meta_range_t>(uhd::fs_path("gains") / name / "range")                  .set(ad9361_ctrl::get_gain_range(key));              subtree->create<double>(uhd::fs_path("gains") / name / "value")                  .set(ad936x_manager::DEFAULT_GAIN) -                .set_coercer([this, key](const double gain){ +                .set_coercer([this, key](const double gain) {                      return this->_codec_ctrl->set_gain(key, gain); -                }) -            ; +                });          }          // FE Settings @@ -254,78 +241,62 @@ public:          // Analog Bandwidths          subtree->create<double>("bandwidth/value")              .set(DEFAULT_BANDWIDTH) -            .set_coercer([this,key](double bw) { -                    return set_bw_filter(key, bw); -                } -            ) -        ; -        subtree->create<meta_range_t>("bandwidth/range") -            .set_publisher([key]() { -                    return ad9361_ctrl::get_bw_filter_range(); -                } -            ) -        ; +            .set_coercer([this, key](double bw) { return set_bw_filter(key, bw); }); +        subtree->create<meta_range_t>("bandwidth/range").set_publisher([key]() { +            return ad9361_ctrl::get_bw_filter_range(); +        });          // LO Tuning -        subtree->create<meta_range_t>("freq/range") -            .set_publisher([](){ -                return ad9361_ctrl::get_rf_freq_range(); -            }) -        ; +        subtree->create<meta_range_t>("freq/range").set_publisher([]() { +            return ad9361_ctrl::get_rf_freq_range(); +        });          subtree->create<double>("freq/value") -            .set_publisher([this, key](){ -                return this->_codec_ctrl->get_freq(key); -            }) -            .set_coercer([this, key](const double freq){ +            .set_publisher([this, key]() { return this->_codec_ctrl->get_freq(key); }) +            .set_coercer([this, key](const double freq) {                  return this->_codec_ctrl->tune(key, freq); -            }) -        ; +            });          // Frontend corrections -        if(dir == RX_DIRECTION) -        { -            subtree->create<bool>("dc_offset/enable" ) +        if (dir == RX_DIRECTION) { +            subtree->create<bool>("dc_offset/enable")                  .set(ad936x_manager::DEFAULT_AUTO_DC_OFFSET) -                .add_coerced_subscriber([this, key](const bool enable){ +                .add_coerced_subscriber([this, key](const bool enable) {                      this->_codec_ctrl->set_dc_offset_auto(key, enable); -                }) -            ; -            subtree->create<bool>("iq_balance/enable" ) +                }); +            subtree->create<bool>("iq_balance/enable")                  .set(ad936x_manager::DEFAULT_AUTO_IQ_BALANCE) -                .add_coerced_subscriber([this, key](const bool enable){ -                   this->_codec_ctrl->set_iq_balance_auto(key, enable); -                }) -            ; +                .add_coerced_subscriber([this, key](const bool enable) { +                    this->_codec_ctrl->set_iq_balance_auto(key, enable); +                });              // AGC setup              const std::list<std::string> mode_strings{"slow", "fast"};              subtree->create<bool>("gain/agc/enable")                  .set(DEFAULT_AGC_ENABLE) -                .add_coerced_subscriber([this, key](const bool enable){ +                .add_coerced_subscriber([this, key](const bool enable) {                      this->_codec_ctrl->set_agc(key, enable); -                }) -            ; +                });              subtree->create<std::string>("gain/agc/mode/value") -                .add_coerced_subscriber([this, key](const std::string& value){ +                .add_coerced_subscriber([this, key](const std::string& value) {                      this->_codec_ctrl->set_agc_mode(key, value);                  }) -                .set(mode_strings.front()) -            ; +                .set(mode_strings.front());              subtree->create<std::list<std::string>>("gain/agc/mode/options") -                .set(mode_strings) -            ; +                .set(mode_strings);          }          // Frontend filters -        for (const auto &filter_name : _codec_ctrl->get_filter_names(key)) { -            subtree->create<filter_info_base::sptr>(uhd::fs_path("filters") / filter_name / "value") -                .set_publisher([this, key, filter_name](){ +        for (const auto& filter_name : _codec_ctrl->get_filter_names(key)) { +            subtree +                ->create<filter_info_base::sptr>( +                    uhd::fs_path("filters") / filter_name / "value") +                .set_publisher([this, key, filter_name]() {                      return this->_codec_ctrl->get_filter(key, filter_name);                  }) -                .add_coerced_subscriber([this, key, filter_name](filter_info_base::sptr filter_info){ -                    this->_codec_ctrl->set_filter(key, filter_name, filter_info); -                }) -            ; +                .add_coerced_subscriber( +                    [this, key, filter_name](filter_info_base::sptr filter_info) { +                        this->_codec_ctrl->set_filter(key, filter_name, filter_info); +                    });          }      } @@ -342,22 +313,20 @@ private:      std::vector<std::string> _tx_frontends;      //! Current bandwidths -    std::map<std::string,double> _bw; +    std::map<std::string, double> _bw;      //! Function to set bandwidth so it is tracked here      double set_bw_filter(const std::string& which, const double bw)      {          double actual_bw = _codec_ctrl->set_bw_filter(which, bw); -        _bw[which] = actual_bw; +        _bw[which]       = actual_bw;          return actual_bw;      }  }; /* class ad936x_manager_impl */  ad936x_manager::sptr ad936x_manager::make( -        const ad9361_ctrl::sptr &codec_ctrl, -        const size_t n_frontends -) { +    const ad9361_ctrl::sptr& codec_ctrl, const size_t n_frontends) +{      return boost::make_shared<ad936x_manager_impl>(codec_ctrl, n_frontends);  } -  | 
