diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp | 267 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp | 26 | 
2 files changed, 234 insertions, 59 deletions
| 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 cc51562aa..53d1f7dab 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp @@ -21,6 +21,7 @@  #include <uhd/rfnoc/node_ctrl_base.hpp>  #include <uhd/transport/chdr.hpp>  #include <uhd/utils/math.hpp> +#include <uhd/types/direction.hpp>  #include <boost/algorithm/string.hpp>  #include <boost/make_shared.hpp>  #include <boost/format.hpp> @@ -31,8 +32,18 @@ using namespace uhd::usrp;  using namespace uhd::rfnoc;  static const size_t IO_MASTER_RADIO = 0; + +// TODO: some of these values are duplicated in ad937x_device.cpp  static const double MAGNESIUM_TICK_RATE = 125e6; // Hz  static const double MAGNESIUM_RADIO_RATE = 125e6; // Hz +static const double MAGNESIUM_MIN_FREQ = 300e6; // Hz +static const double MAGNESIUM_MAX_FREQ = 6e9; // Hz +static const double MAGNESIUM_MIN_RX_GAIN = 0.0; // dB +static const double MAGNESIUM_MAX_RX_GAIN = 30.0; // dB +static const double MAGNESIUM_RX_GAIN_STEP = 0.5; +static const double MAGNESIUM_MIN_TX_GAIN = 0.0; // dB +static const double MAGNESIUM_MAX_TX_GAIN = 41.95; // dB +static const double MAGNESIUM_TX_GAIN_STEP = 0.05;  static const double MAGNESIUM_CENTER_FREQ = 2.5e9; // Hz  static const double MAGNESIUM_DEFAULT_GAIN = 0.0; // dB  static const double MAGNESIUM_DEFAULT_BANDWIDTH = 40e6; // Hz TODO: fix @@ -69,6 +80,19 @@ std::string _get_which(direction_t dir, size_t chan)      return ss.str();  } +fs_path magnesium_radio_ctrl_impl::_get_fe_path(size_t chan, direction_t dir) +{ +    switch (dir) +    { +        case TX_DIRECTION: +            return fs_path("dboards" / _radio_slot / "tx_frontends" / get_dboard_fe_from_chan(chan, TX_DIRECTION)); +        case RX_DIRECTION: +            return fs_path("dboards" / _radio_slot / "rx_frontends" / get_dboard_fe_from_chan(chan, RX_DIRECTION)); +        default: +            UHD_THROW_INVALID_CODE_PATH(); +    } +} +  UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(magnesium_radio_ctrl)  {      UHD_LOG_TRACE("MAGNESIUM", "magnesium_radio_ctrl_impl::ctor() "); @@ -78,9 +102,9 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(magnesium_radio_ctrl)      const size_t num_rx_chans = get_output_ports().size(); -    UHD_ASSERT_THROW(num_rx_chans == MAGNESIUM_NUM_RX_CHANS); +    //UHD_ASSERT_THROW(num_rx_chans == MAGNESIUM_NUM_RX_CHANS);      const size_t num_tx_chans = get_input_ports().size(); -    UHD_ASSERT_THROW(num_tx_chans == MAGNESIUM_NUM_TX_CHANS); +    //UHD_ASSERT_THROW(num_tx_chans == MAGNESIUM_NUM_TX_CHANS);      UHD_LOG_TRACE("MAGNESIUM", "Setting tick rate to " << MAGNESIUM_TICK_RATE / 1e6 << " MHz");      radio_ctrl_impl::set_rate(MAGNESIUM_TICK_RATE); @@ -104,56 +128,104 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(magnesium_radio_ctrl)      // For use with multi_usrp APIs etc.      // For legacy prop tree init:      // TODO: determine DB number -    fs_path fe_base = fs_path("dboards") / _radio_slot; -    std::vector<std::string> fe({ "rx_frontends" , "tx_frontends" }); -    std::vector<std::string> ant({ "RX" , "TX" }); +    const fs_path fe_base = fs_path("dboards") / _radio_slot; +    const std::vector<uhd::direction_t> dir({ RX_DIRECTION, TX_DIRECTION }); +    const std::vector<std::string> fe({ "rx_frontends", "tx_frontends" }); +    const std::vector<std::string> ant({ "RX" , "TX" }); +    const std::vector<size_t> num_chans({ MAGNESIUM_NUM_RX_CHANS , MAGNESIUM_NUM_TX_CHANS }); +    const size_t RX_IDX = 0, TX_IDX = 1; -    UHD_ASSERT_THROW(MAGNESIUM_NUM_RX_CHANS == MAGNESIUM_NUM_TX_CHANS);      for (size_t fe_idx = 0; fe_idx < fe.size(); ++fe_idx)      { -        fs_path fe_direction_path = fe_base / fe[fe_idx]; -        for (size_t chan = 0; chan < MAGNESIUM_NUM_RX_CHANS; ++chan) { -            fs_path fe_path = fe_direction_path / chan; +        const fs_path fe_direction_path = fe_base / fe[fe_idx]; +        for (size_t chan = 0; chan < num_chans[fe_idx]; ++chan) +        { +            const fs_path fe_path = fe_direction_path / chan;              UHD_LOG_TRACE("MAGNESIUM", "Adding FE at " << fe_path); +            // Shared TX/RX attributes              _tree->create<std::string>(fe_path / "name")                  .set(str(boost::format("Magnesium %s %d") % ant[fe_idx] % chan))                  ;              _tree->create<std::string>(fe_path / "connection")                  .set("IQ")                  ; -            // TODO: fix antenna name -            _tree->create<std::string>(fe_path / "antenna" / "value") -                .set(str(boost::format("%s%d") % ant[fe_idx] % (chan+1))) -                .add_coerced_subscriber(boost::bind(&magnesium_radio_ctrl_impl::set_rx_antenna, this, _1, chan)) -                .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_antenna, this, chan)) -                ; -            _tree->create<std::vector<std::string>>(fe_path / "antenna" / "options") -                .set(std::vector<std::string>(1, str(boost::format("%s%d") % ant[fe_idx] % (chan + 1)))) -                ; -            _tree->create<double>(fe_path / "freq" / "value") -                .set(MAGNESIUM_CENTER_FREQ) -                .set_coercer(boost::bind(&magnesium_radio_ctrl_impl::set_rx_frequency, this, _1, chan)) -                .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_frequency, this, chan)) -                ; -            _tree->create<meta_range_t>(fe_path / "freq" / "range") -                .set(meta_range_t(MAGNESIUM_CENTER_FREQ, MAGNESIUM_CENTER_FREQ)) -                ; -            _tree->create<double>(fe_path / "gains" / "null" / "value") -                .set(MAGNESIUM_DEFAULT_GAIN) -                .set_coercer(boost::bind(&magnesium_radio_ctrl_impl::set_rx_gain, this, _1, chan)) -                .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_gain, this, chan)) -                ; -            _tree->create<meta_range_t>(fe_path / "gains" / "null" / "range") -                .set(meta_range_t(MAGNESIUM_DEFAULT_GAIN, MAGNESIUM_DEFAULT_GAIN)) -                ; -            _tree->create<double>(fe_path / "bandwidth" / "value") -                .set(MAGNESIUM_DEFAULT_BANDWIDTH) -                .set_coercer(boost::bind(&magnesium_radio_ctrl_impl::set_rx_bandwidth, this, _1, chan)) -                .set_publisher(boost::bind(&radio_ctrl_impl::get_rx_bandwidth, this, chan)) -                ; +            { +                // TODO: fix antenna name +                // Now witness the firepower of this fully armed and operational lambda +                auto coerced_lambda = [this, chan, dir = dir[fe_idx]](const std::string &ant) +                { +                    return this->_set_antenna(ant, chan, dir); +                }; +                auto publisher_lambda = [this, chan, dir = dir[fe_idx]]() +                { +                    return this->_get_antenna(chan, dir); +                }; +                _tree->create<std::string>(fe_path / "antenna" / "value") +                    .set(str(boost::format("%s%d") % ant[fe_idx] % (chan + 1))) +                    .add_coerced_subscriber(coerced_lambda) +                    .set_publisher(publisher_lambda); +                // TODO: fix options +                _tree->create<std::vector<std::string>>(fe_path / "antenna" / "options") +                    .set(std::vector<std::string>(1, str(boost::format("%s%d") % ant[fe_idx] % (chan + 1)))); +            } +            { +                auto coerced_lambda = [this, chan, dir = dir[fe_idx]](const double freq) +                { +                    return this->_set_frequency(freq, chan, dir); +                }; +                auto publisher_lambda = [this, chan, dir = dir[fe_idx]]() +                { +                    return this->_get_frequency(chan, dir); +                }; +                _tree->create<double>(fe_path / "freq" / "value") +                    .set(MAGNESIUM_CENTER_FREQ) +                    .set_coercer(coerced_lambda) +                    .set_publisher(publisher_lambda); +                _tree->create<meta_range_t>(fe_path / "freq" / "range") +                    .set(meta_range_t(MAGNESIUM_MIN_FREQ, MAGNESIUM_MAX_FREQ)); +            } +            { +                auto coerced_lambda = [this, chan, dir = dir[fe_idx]](const double gain) +                { +                    return this->_set_gain(gain, chan, dir); +                }; +                auto publisher_lambda = [this, chan, dir = dir[fe_idx]]() +                { +                    return this->_get_gain(chan, dir); +                }; +                auto min_gain = (fe_idx == RX_IDX) ? MAGNESIUM_MIN_RX_GAIN : MAGNESIUM_MIN_TX_GAIN; +                auto max_gain = (fe_idx == RX_IDX) ? MAGNESIUM_MAX_RX_GAIN : MAGNESIUM_MAX_TX_GAIN; +                auto gain_step = (fe_idx == RX_IDX) ? MAGNESIUM_RX_GAIN_STEP : MAGNESIUM_TX_GAIN_STEP; +                // TODO: change from null +                _tree->create<double>(fe_path / "gains" / "null" / "value") +                    .set(MAGNESIUM_DEFAULT_GAIN) +                    .set_coercer(coerced_lambda) +                    .set_publisher(publisher_lambda); +                _tree->create<meta_range_t>(fe_path / "gains" / "null" / "range") +                    .set(meta_range_t(min_gain, max_gain, gain_step)); +            } +            // TODO: set up read/write of bandwidth properties correctly +            if (fe_idx == RX_IDX) +            { +                auto coerced_lambda = [this, chan](const double bw) +                { +                    return this->set_rx_bandwidth(bw, chan); +                }; +                auto publisher_lambda = [this, chan]() +                { +                    return this->get_rx_bandwidth(chan); +                }; +                _tree->create<double>(fe_path / "bandwidth" / "value") +                    .set(MAGNESIUM_DEFAULT_BANDWIDTH) +                    .set_coercer(coerced_lambda) +                    .set_publisher(publisher_lambda); +            } +            else { +                _tree->create<double>(fe_path / "bandwidth" / "value") +                    .set(MAGNESIUM_DEFAULT_BANDWIDTH); +            }              _tree->create<meta_range_t>(fe_path / "bandwidth" / "range") -                .set(meta_range_t(MAGNESIUM_DEFAULT_BANDWIDTH, MAGNESIUM_DEFAULT_BANDWIDTH)) -                ; +                .set(meta_range_t(MAGNESIUM_DEFAULT_BANDWIDTH, MAGNESIUM_DEFAULT_BANDWIDTH));          }      } @@ -187,32 +259,27 @@ double magnesium_radio_ctrl_impl::set_rate(double rate)  void magnesium_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan)  { -    // TODO: implement -    UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set Tx antenna"); -    // CPLD control? +    _set_antenna(ant, chan, TX_DIRECTION);  }  void magnesium_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t chan)  { -    // TODO: implement -    UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set Rx antenna"); -    // CPLD control? +    _set_antenna(ant, chan, RX_DIRECTION);  }  double magnesium_radio_ctrl_impl::set_tx_frequency(const double freq, const size_t chan)  { -    return _set_freq(freq, chan, TX_DIRECTION); +    return _set_frequency(freq, chan, TX_DIRECTION);  }  double magnesium_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan)  { -    return _set_freq(freq, chan, RX_DIRECTION); +    return _set_frequency(freq, chan, RX_DIRECTION);  }  double magnesium_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan)  { -    // TODO: implement -    return get_rx_bandwidth(chan); +    return _set_bandwidth(bandwidth, chan, RX_DIRECTION);  }  double magnesium_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan) @@ -225,15 +292,50 @@ double magnesium_radio_ctrl_impl::set_rx_gain(const double gain, const size_t ch      return _set_gain(gain, chan, RX_DIRECTION);  } +std::string magnesium_radio_ctrl_impl::get_tx_antenna(const size_t chan) /* const */ +{ +    return _get_antenna(chan, TX_DIRECTION); +} + +std::string magnesium_radio_ctrl_impl::get_rx_antenna(const size_t chan) /* const */ +{ +    return _get_antenna(chan, RX_DIRECTION); +} + +double magnesium_radio_ctrl_impl::get_tx_frequency(const size_t chan) /* const */ +{ +    return _get_frequency(chan, TX_DIRECTION); +} + +double magnesium_radio_ctrl_impl::get_rx_frequency(const size_t chan) /* const */ +{ +    return _get_frequency(chan, RX_DIRECTION); +} + +double magnesium_radio_ctrl_impl::get_tx_gain(const size_t chan) /* const */ +{ +    return _get_gain(chan, TX_DIRECTION); +} + +double magnesium_radio_ctrl_impl::get_rx_gain(const size_t chan) /* const */ +{ +    return _get_gain(chan, RX_DIRECTION); +} + +double magnesium_radio_ctrl_impl::get_rx_bandwidth(const size_t chan) /* const */ +{ +    return _get_bandwidth(chan, RX_DIRECTION); +} +  size_t magnesium_radio_ctrl_impl::get_chan_from_dboard_fe(const std::string &fe, const direction_t dir)  { -    UHD_LOG_TRACE("MAGNESIUM", "get_chan_from_dboard_fe " << fe << " returns " << boost::lexical_cast<size_t>(fe)); +    // UHD_LOG_TRACE("MAGNESIUM", "get_chan_from_dboard_fe " << fe << " returns " << boost::lexical_cast<size_t>(fe));      return boost::lexical_cast<size_t>(fe);  }  std::string magnesium_radio_ctrl_impl::get_dboard_fe_from_chan(const size_t chan, const direction_t dir)  { -    UHD_LOG_TRACE("MAGNESIUM", "get_dboard_fe_from_chan " << chan << " returns " << std::to_string(chan)); +    // UHD_LOG_TRACE("MAGNESIUM", "get_dboard_fe_from_chan " << chan << " returns " << std::to_string(chan));      return std::to_string(chan);  } @@ -251,18 +353,71 @@ void magnesium_radio_ctrl_impl::set_rpc_client(      _block_args = block_args;  } -double magnesium_radio_ctrl_impl::_set_freq(const double freq, const size_t chan, const direction_t dir) +double magnesium_radio_ctrl_impl::_set_frequency(const double freq, const size_t chan, const direction_t dir)  { +    // TODO: there is only one LO per RX or TX, so changing frequency will affect the adjacent channel in the same direction +    // Update the adjacent channel when this occurs      auto which = _get_which(dir, chan);      UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "set_freq on " << which << " with " << freq); -    return _rpcc->request_with_token<double>(_slot_prefix + "set_freq", which, freq, false); +    auto retval = _rpcc->request_with_token<double>(_slot_prefix + "set_freq", which, freq, false); +    UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "set_freq returned " << retval); +    return retval;  }  double magnesium_radio_ctrl_impl::_set_gain(const double gain, const size_t chan, const direction_t dir)  {      auto which = _get_which(dir, chan);      UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "set_gain on " << which << " with " << gain); -    return _rpcc->request_with_token<double>(_slot_prefix + "set_gain", which, gain); +    auto retval = _rpcc->request_with_token<double>(_slot_prefix + "set_gain", which, gain); +    UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "set_gain returned " << retval); +    return retval; +} + +void magnesium_radio_ctrl_impl::_set_antenna(const std::string &ant, const size_t chan, const direction_t dir) +{ +    // TODO: implement +    UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set antenna"); +    // CPLD control? +} + +double magnesium_radio_ctrl_impl::_set_bandwidth(const double bandwidth, const size_t chan, const direction_t dir) +{ +    // TODO: implement +    UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to set bandwidth"); +    return get_rx_bandwidth(chan); +} + +double magnesium_radio_ctrl_impl::_get_frequency(const size_t chan, const direction_t dir) +{ +    auto which = _get_which(dir, chan); +    UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "get_freq on " << which); +    auto retval = _rpcc->request_with_token<double>(_slot_prefix + "get_freq", which); +    UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "get_freq returned " << retval); +    return retval; +} + +double magnesium_radio_ctrl_impl::_get_gain(const size_t chan, const direction_t dir) +{ +    auto which = _get_which(dir, chan); +    UHD_LOG_TRACE("MAGNESIUM", "calling " << _slot_prefix << "get_gain on " << which); +    auto retval = _rpcc->request_with_token<double>(_slot_prefix + "get_gain", which); +    UHD_LOG_TRACE("MAGNESIUM", _slot_prefix << "get_gain returned " << retval); +    return retval; +} + +std::string magnesium_radio_ctrl_impl::_get_antenna(const size_t chan, const direction_t dir) +{ +    // TODO: implement +    UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to get antenna"); +    return "RX1"; +    // CPLD control? +} + +double magnesium_radio_ctrl_impl::_get_bandwidth(const size_t chan, const direction_t dir) +{ +    // TODO: implement +    UHD_LOG_WARNING("MAGNESIUM", "Ignoring attempt to get bandwidth"); +    return MAGNESIUM_DEFAULT_BANDWIDTH;  }  UHD_RFNOC_BLOCK_REGISTER(magnesium_radio_ctrl, "MagnesiumRadio"); 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 0bb1b26b8..9535be824 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp @@ -54,6 +54,16 @@ public:      double set_tx_gain(const double gain, const size_t chan);      double set_rx_gain(const double gain, const size_t chan); +    std::string get_tx_antenna(const size_t chan); +    std::string get_rx_antenna(const size_t chan); + +    double get_tx_frequency(const size_t chan); +    double get_rx_frequency(const size_t chan); +    double get_rx_bandwidth(const size_t chan); + +    double get_tx_gain(const size_t chan); +    double get_rx_gain(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); @@ -65,11 +75,21 @@ public:      );  private: -    double _set_freq(const double freq, const size_t chan, const direction_t dir); -    double _set_gain(const double gain, const size_t chan, const direction_t dir); -      std::string _radio_slot;      std::string _slot_prefix; + +    fs_path _get_fe_path(size_t chan, direction_t dir); + +    double _set_frequency(const double freq, const size_t chan, const direction_t dir); +    double _set_gain(const double gain, const size_t chan, const direction_t dir); +    void _set_antenna(const std::string &ant, const size_t chan, const direction_t dir); +    double _set_bandwidth(const double bandwidth, const size_t chan, const direction_t dir); + +    double _get_frequency(const size_t chan, const direction_t dir); +    double _get_gain(const size_t chan, const direction_t dir); +    std::string _get_antenna(const size_t chan, const direction_t dir); +    double _get_bandwidth(const size_t chan, const direction_t dir); +      //! Additional block args; gets set during set_rpc_client()      uhd::device_addr_t _block_args; | 
