diff options
Diffstat (limited to 'host/lib/usrp/dboard')
5 files changed, 348 insertions, 12 deletions
| diff --git a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp index 72a708165..0d914636e 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp @@ -31,6 +31,9 @@ static const double AD9371_RX_GAIN_STEP = 0.5;  static const double DSA_MIN_GAIN = 0; // dB  static const double DSA_MAX_GAIN = 31.5; // dB  static const double DSA_GAIN_STEP = 0.5; // db +static const double AMP_MIN_GAIN = 0; // dB +static const double AMP_MAX_GAIN = 10; // dB +static const double AMP_GAIN_STEP = 10;// dB  static const double AD9371_MIN_TX_GAIN = 0.0; // dB  static const double AD9371_MAX_TX_GAIN = 41.95; // dB  static const double AD9371_TX_GAIN_STEP = 0.05; @@ -40,14 +43,27 @@ static const double ALL_RX_GAIN_STEP = 0.5;  static const double ALL_TX_MIN_GAIN = 0.0;  static const double ALL_TX_MAX_GAIN = 65.0;  static const double ALL_TX_GAIN_STEP = 0.5; +  static const double MAGNESIUM_CENTER_FREQ = 2.5e9; // Hz  static const std::vector<std::string> MAGNESIUM_RX_ANTENNAS = {      "TX/RX", "RX2", "CAL", "LOCAL"  }; +  //! AD9371 LO (for direct conversion)  static const char* MAGNESIUM_LO1 = "rfic";  //! Low-band LO (for IF conversion)  static const char* MAGNESIUM_LO2 = "lowband"; +//! Magnesium gain profile options +static const std::vector<std::string> MAGNESIUM_GP_OPTIONS = { +    "manual", +    "default" +}; +//! AD9371 attenuation +static const char* MAGNESIUM_GAIN1 = "rfic"; +//! DSA attenuation +static const char* MAGNESIUM_GAIN2 = "dsa"; +//! Amplifier gain +static const char* MAGNESIUM_AMP = "amp";  static const double MAGNESIUM_DEFAULT_BANDWIDTH = 40e6; // Hz TODO: fix  // Note: MAGNESIUM_NUM_CHANS is independent of the number of chans per diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp index 449b772b3..f934e5794 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp @@ -28,9 +28,21 @@ double magnesium_radio_ctrl_impl::_set_all_gain(      const size_t ad9371_chan = _master ? 0 : 1; ;// FIXME: use chan when 2 radios      const magnesium_cpld_ctrl::chan_sel_t chan_sel  =          _master ? magnesium_cpld_ctrl::CHAN1 : magnesium_cpld_ctrl::CHAN2; -    const auto gain_tuple = (dir == RX_DIRECTION) ? -        get_rx_gain_tuple(gain, _map_freq_to_rx_band(freq)) : -        get_tx_gain_tuple(gain, _map_freq_to_tx_band(freq)); +    gain_tuple_t gain_tuple = (dir == RX_DIRECTION) ? +            get_rx_gain_tuple(gain, _map_freq_to_rx_band(freq)): +            get_tx_gain_tuple(gain, _map_freq_to_tx_band(freq)); + +    if (_gain_profile[dir] == "manual"){ +        UHD_LOG_TRACE(unique_id(), "Manual gain mode. Getting gain from property tree."); +        gain_tuple = { +            DSA_MAX_GAIN - _dsa_att[dir], +            ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) - _ad9371_att[dir], +            _amp_bypass[dir]}; +    }else if (_gain_profile[dir] == "default"){ +        UHD_LOG_TRACE(unique_id(), "Getting gain from gain table."); +    }else { +     UHD_LOG_ERROR(unique_id(), "Unsupported gain mode: " << _gain_profile[dir]) +    }      const double ad9371_gain =          ((dir == RX_DIRECTION) ?  AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN)          - gain_tuple.ad9371_att; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp index 2c7121c5c..eb4894e19 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp @@ -412,6 +412,50 @@ double magnesium_radio_ctrl_impl::set_tx_gain(      return coerced_gain;  } +double magnesium_radio_ctrl_impl::_set_tx_gain( +        const std::string &name, +        const double gain, +        const size_t chan +) { +    std::lock_guard<std::mutex> l(_set_lock); +    UHD_LOG_TRACE(unique_id(), +        "_set_tx_gain(name=" << name << ", gain=" << gain << ", chan=" << chan << ")"); +    if (name == MAGNESIUM_GAIN1){ +        _ad9371_att[TX_DIRECTION] = gain; +    }else if (name == MAGNESIUM_GAIN2){ +        _dsa_att[TX_DIRECTION] = gain; +    }else if (name == MAGNESIUM_AMP){ +        _amp_bypass[TX_DIRECTION] =  gain == 0.0; +    }else { +        throw uhd::value_error("Could not find gain element " + name); +    } +    UHD_LOG_TRACE(unique_id(), +        "_set_tx_gain calling update gain"); +    this->_set_all_gain( +        this->_get_all_gain(chan, TX_DIRECTION), +        this->get_tx_frequency(chan), +        chan, +        TX_DIRECTION +    ); +    return gain; // not really any coreced here for individual gain +} + +double magnesium_radio_ctrl_impl::_get_tx_gain( +        const std::string &name, +        const size_t chan +) { +    std::lock_guard<std::mutex> l(_set_lock); +    if (name == MAGNESIUM_GAIN1){ +        return _ad9371_att[TX_DIRECTION]; +    }else if (name == MAGNESIUM_GAIN2){ +        return _dsa_att[TX_DIRECTION]; +    }else if (name == MAGNESIUM_AMP){ +        return _amp_bypass[TX_DIRECTION]? AMP_MIN_GAIN : AMP_MAX_GAIN; +    }else { +        throw uhd::value_error("Could not find gain element " + name); +    } +} +  double magnesium_radio_ctrl_impl::set_rx_gain(          const double gain,          const size_t chan @@ -429,6 +473,51 @@ double magnesium_radio_ctrl_impl::set_rx_gain(      return coerced_gain;  } +double magnesium_radio_ctrl_impl::_set_rx_gain( +        const std::string &name, +        const double gain, +        const size_t chan +) { +    std::lock_guard<std::mutex> l(_set_lock); +    UHD_LOG_TRACE(unique_id(), +        "_set_rx_gain(name=" << name << ", gain=" << gain << ", chan=" << chan << ")"); +    if (name == MAGNESIUM_GAIN1){ +        _ad9371_att[RX_DIRECTION] = gain; +    }else if (name == MAGNESIUM_GAIN2){ +        _dsa_att[RX_DIRECTION] = gain; +    }else if (name == MAGNESIUM_AMP){ +        _amp_bypass[RX_DIRECTION] = gain == 0.0; +    }else { +        throw uhd::value_error("Could not find gain element " + name); +    } +    UHD_LOG_TRACE(unique_id(), +        "_set_rx_gain calling update gain"); +    this->_set_all_gain( +        this->_get_all_gain(chan, RX_DIRECTION), +        this->get_rx_frequency(chan), +        chan, +        RX_DIRECTION +    ); +    return gain; // not really any coreced here for individual gain +} + +double magnesium_radio_ctrl_impl::_get_rx_gain( +        const std::string &name, +        const size_t chan +) { +    std::lock_guard<std::mutex> l(_set_lock); + +    if (name == MAGNESIUM_GAIN1){ +        return _ad9371_att[RX_DIRECTION]; +    }else if (name == MAGNESIUM_GAIN2){ +        return _dsa_att[RX_DIRECTION]; +    }else if (name == MAGNESIUM_AMP){ +        return _amp_bypass[RX_DIRECTION]? AMP_MIN_GAIN : AMP_MAX_GAIN; +    }else{ +        throw uhd::value_error("Could not find gain element " + name); +    } +} +  std::vector<std::string> magnesium_radio_ctrl_impl::get_rx_lo_names(          const size_t /*chan*/  ) { diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp index 49affaa6f..d12666ce7 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp @@ -134,6 +134,10 @@ public:      // gain      double set_tx_gain(const double gain, const size_t chan);      double set_rx_gain(const double gain, const size_t chan); +    void set_tx_gain_source(const std::string& src, const std::string& name, const size_t chan); +    std::string get_tx_gain_source(const std::string& name, const size_t chan); +    void set_rx_gain_source(const std::string& src, const std::string& name, const size_t chan); +    std::string get_rx_gain_source(const std::string& name, const size_t chan);      size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t dir);      std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir); @@ -147,6 +151,18 @@ private:      /**************************************************************************       * Helpers       *************************************************************************/ +    //! Set tx gain on each gain element +    double _set_tx_gain(const std::string &name, const double gain, const size_t chan); + +    //! Set rx gain on each gain element +    double _set_rx_gain(const std::string &name, const double gain, const size_t chan); + +    //! Get tx gain on each gain element +    double _get_tx_gain(const std::string &name, const size_t chan); + +    //! Get rx gain on each gain element +    double _get_rx_gain(const std::string &name, const size_t chan); +      //! Initialize all the peripherals connected to this block      void _init_peripherals(); @@ -328,14 +344,18 @@ private:      //! AD9371 gain      double _ad9371_rx_gain = 0.0;      double _ad9371_tx_gain = 0.0; - +    std::map<direction_t,double> _ad9371_att = { {RX_DIRECTION, 0.0}, {TX_DIRECTION, 0.0} };      //! DSA attenuation      double _dsa_rx_att = 0.0;      double _dsa_tx_att = 0.0; - +    std::map<direction_t,double> _dsa_att = { {RX_DIRECTION, 0.0}, {TX_DIRECTION, 0.0} }; +    //! amp gain +    std::map<direction_t,bool> _amp_bypass = { {RX_DIRECTION, true}, {TX_DIRECTION, true} };      //! All gain      double _all_rx_gain = 0.0;      double _all_tx_gain = 0.0; +    //! Gain profile +    std::map<direction_t,std::string> _gain_profile = { {RX_DIRECTION, "default"}, {TX_DIRECTION, "default"} };      bool _rx_bypass_lnas = true;      bool _tx_bypass_amp  = true; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp index 5858995b0..5eb3cacd0 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp @@ -315,33 +315,232 @@ void magnesium_radio_ctrl_impl::_init_frontend_subtree(              return this->set_tx_gain(gain, chan_idx);          })          .set_publisher([this, chan_idx](){ -            return this->get_tx_gain(chan_idx); +            return radio_ctrl_impl::get_tx_gain(chan_idx);          })      ;      subtree->create<meta_range_t>(tx_fe_path / "gains" / "all" / "range") -        .set(meta_range_t(ALL_TX_MIN_GAIN, ALL_TX_MAX_GAIN, ALL_TX_GAIN_STEP))          .add_coerced_subscriber([](const meta_range_t &){              throw uhd::runtime_error( -                "Attempting to update bandwidth range!"); +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[TX_DIRECTION] == "manual") { +                return meta_range_t(0.0, 0.0, 0.0); +            }else{ +                return meta_range_t(ALL_TX_MIN_GAIN, ALL_TX_MAX_GAIN, ALL_TX_GAIN_STEP); +            }          })      ; + +    subtree->create<std::vector<std::string> >(tx_fe_path / "gains/all/profile/options") +            .set(boost::assign::list_of("manual")("default")); + +    subtree->create<std::string>(tx_fe_path / "gains/all/profile/value") +        .set_coercer([this, chan_idx](const std::string& profile){ +            std::string return_profile = profile; +            if (std::find(MAGNESIUM_GP_OPTIONS.begin(), +                         MAGNESIUM_GP_OPTIONS.end(), +                         profile +                         ) == MAGNESIUM_GP_OPTIONS.end()) +            { +                return_profile = "default"; +            } +            _gain_profile[TX_DIRECTION] = return_profile; +            return return_profile; +        }) +        .set_publisher([this, chan_idx](){ +            return _gain_profile[TX_DIRECTION]; +        }) +    ; +      // RX gains      subtree->create<double>(rx_fe_path / "gains" / "all" / "value")          .set_coercer([this, chan_idx](const double gain){              return this->set_rx_gain(gain, chan_idx);          })          .set_publisher([this, chan_idx](){ -            return this->get_rx_gain(chan_idx); +            return radio_ctrl_impl::get_rx_gain(chan_idx);          })      ; +      subtree->create<meta_range_t>(rx_fe_path / "gains" / "all" / "range") -        .set(meta_range_t(ALL_RX_MIN_GAIN, ALL_RX_MAX_GAIN, ALL_RX_GAIN_STEP))          .add_coerced_subscriber([](const meta_range_t &){              throw uhd::runtime_error( -                "Attempting to update bandwidth range!"); +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[RX_DIRECTION] == "manual") { +                return meta_range_t(0.0, 0.0, 0.0); +            }else{ +                return meta_range_t(ALL_RX_MIN_GAIN, ALL_RX_MAX_GAIN, ALL_RX_GAIN_STEP); +            } +        }) +    ; + +    subtree->create<std::vector<std::string> >(rx_fe_path / "gains/all/profile/options") +            .set(MAGNESIUM_GP_OPTIONS); + +    subtree->create<std::string>(rx_fe_path / "gains/all/profile/value") +        .set_coercer([this, chan_idx](const std::string& profile){ +            std::string return_profile = profile; +            if (std::find(MAGNESIUM_GP_OPTIONS.begin(), +                         MAGNESIUM_GP_OPTIONS.end(), +                         profile +                         ) == MAGNESIUM_GP_OPTIONS.end()) +            { +                return_profile = "default"; +            } +            _gain_profile[RX_DIRECTION] = return_profile; +            return return_profile; +        }) +        .set_publisher([this, chan_idx](){ +            return _gain_profile[RX_DIRECTION];          })      ; -    // FIXME separate DSA and Myk gains + +    // TX mykonos attenuation +    subtree->create<double>(tx_fe_path / "gains" / MAGNESIUM_GAIN1 / "value") +        .set_coercer([this, chan_idx](const double gain){ +            return _set_tx_gain(MAGNESIUM_GAIN1, gain, chan_idx); +        }) +        .set_publisher([this, chan_idx](){ +            return this->_get_tx_gain(MAGNESIUM_GAIN1, chan_idx); +        }) +    ; + +    subtree->create<meta_range_t>(tx_fe_path / "gains" / MAGNESIUM_GAIN1 / "range") +        .add_coerced_subscriber([](const meta_range_t &){ +            throw uhd::runtime_error( +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[TX_DIRECTION] == "manual") { +                return meta_range_t(AD9371_MIN_TX_GAIN, AD9371_MAX_TX_GAIN, AD9371_TX_GAIN_STEP); +            }else{ +                return meta_range_t(0.0, 0.0, 0.0); +            } +        }) +    ; +     // TX DSA +    subtree->create<double>(tx_fe_path / "gains" / MAGNESIUM_GAIN2 / "value") +        .set_coercer([this, chan_idx](const double gain){ +            return this->_set_tx_gain(MAGNESIUM_GAIN2, gain, chan_idx); +        }) +        .set_publisher([this, chan_idx](){ +            return this->_get_tx_gain(MAGNESIUM_GAIN2, chan_idx); +        }) +    ; + +    subtree->create<meta_range_t>(tx_fe_path / "gains" / MAGNESIUM_GAIN2 / "range") +        .add_coerced_subscriber([](const meta_range_t &){ +            throw uhd::runtime_error( +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[TX_DIRECTION] == "manual") { +                return meta_range_t(DSA_MIN_GAIN, DSA_MAX_GAIN, DSA_GAIN_STEP); +            }else{ +                return meta_range_t(0.0, 0.0, 0.0); +            } +        }) +    ; +     //TX amp +    subtree->create<double>(tx_fe_path / "gains" / MAGNESIUM_AMP / "value") +        .set_coercer([this, chan_idx](const double gain) { +            return this->_set_tx_gain(MAGNESIUM_AMP, gain, chan_idx); +        }) +        .set_publisher([this, chan_idx]() { +            return this->_get_tx_gain(MAGNESIUM_AMP, chan_idx); +        }) +    ; + +    subtree->create<meta_range_t>(tx_fe_path / "gains" / MAGNESIUM_AMP / "range") +        .add_coerced_subscriber([](const meta_range_t &) { +            throw uhd::runtime_error( +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[TX_DIRECTION] == "manual") { +                return meta_range_t(AMP_MIN_GAIN, AMP_MAX_GAIN, AMP_GAIN_STEP); +            }else{ +                return meta_range_t(0.0, 0.0, 0.0); +            } +        }) +    ; + +    // RX mykonos attenuation +    subtree->create<double>(rx_fe_path / "gains" / MAGNESIUM_GAIN1 / "value") +        .set_coercer([this, chan_idx](const double gain){ +                UHD_VAR(gain); +            return this->_set_rx_gain(MAGNESIUM_GAIN1, gain, chan_idx); +        }) +        .set_publisher([this, chan_idx](){ +            return this->_get_rx_gain(MAGNESIUM_GAIN1, chan_idx); +        }) +    ; + +    subtree->create<meta_range_t>(rx_fe_path / "gains" / MAGNESIUM_GAIN1 / "range") +        .add_coerced_subscriber([](const meta_range_t &) { +            throw uhd::runtime_error( +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[RX_DIRECTION] == "manual") { +                return meta_range_t(AD9371_MIN_RX_GAIN, AD9371_MAX_RX_GAIN, AD9371_RX_GAIN_STEP); +            }else{ +                return meta_range_t(0.0, 0.0, 0.0); +            } +        }) +    ; +    //RX DSA +    subtree->create<double>(rx_fe_path / "gains" / MAGNESIUM_GAIN2 / "value") +        .set_coercer([this, chan_idx](const double gain) { +            UHD_VAR(gain); +            return this->_set_rx_gain(MAGNESIUM_GAIN2, gain, chan_idx); +        }) +        .set_publisher([this, chan_idx]() { +            return this->_get_rx_gain(MAGNESIUM_GAIN2, chan_idx); +        }) +    ; + +    subtree->create<meta_range_t>(rx_fe_path / "gains" / MAGNESIUM_GAIN2 / "range") +        .add_coerced_subscriber([](const meta_range_t &){ +            throw uhd::runtime_error( +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[RX_DIRECTION] == "manual") { +                return meta_range_t(DSA_MIN_GAIN, DSA_MAX_GAIN, DSA_MAX_GAIN); +            }else{ +                return meta_range_t(0.0, 0.0, 0.0); +            } +        }) +    ; + +    //RX amp +    subtree->create<double>(rx_fe_path / "gains" / MAGNESIUM_AMP / "value") +        .set_coercer([this, chan_idx](const double gain) { +            return this->_set_rx_gain(MAGNESIUM_AMP, gain, chan_idx); +        }) +        .set_publisher([this, chan_idx]() { +            return this->_get_rx_gain(MAGNESIUM_AMP, chan_idx); +        }) +    ; + +    subtree->create<meta_range_t>(rx_fe_path / "gains" / MAGNESIUM_AMP / "range") +        .add_coerced_subscriber([](const meta_range_t &) { +            throw uhd::runtime_error( +                "Attempting to update gain range!"); +        }) +        .set_publisher([this, chan_idx](){ +            if (_gain_profile[RX_DIRECTION] == "manual") { +                return meta_range_t(AMP_MIN_GAIN, AMP_MAX_GAIN, AMP_GAIN_STEP); +            }else{ +                return meta_range_t(0.0, 0.0, 0.0); +            } +        }) +    ; +      // TX LO lock sensor //////////////////////////////////////////////////////      // Note: The lowband and AD9371 LO lock sensors are generated      // programmatically in set_rpc_client(). The actual lo_locked publisher is | 
