diff options
author | Mark Meserve <mark.meserve@ni.com> | 2018-10-02 14:26:49 -0500 |
---|---|---|
committer | Brent Stapleton <bstapleton@g.hmc.edu> | 2018-11-05 13:43:07 -0800 |
commit | 728d9abfe7fd9adf87ba4f87627829e09ddcc8cf (patch) | |
tree | 757accf69ea77d5f04ce147c0188be20b742a9f0 /host/lib/usrp | |
parent | 44eb4b4b43a58324854ce50ef983331c98125eeb (diff) | |
download | uhd-728d9abfe7fd9adf87ba4f87627829e09ddcc8cf.tar.gz uhd-728d9abfe7fd9adf87ba4f87627829e09ddcc8cf.tar.bz2 uhd-728d9abfe7fd9adf87ba4f87627829e09ddcc8cf.zip |
rh: add lo distribution support
- This is a combination of 5 commits.
- rh: add lo distribution board gpio expander
- rh: add lo distribution mpm functions
- rh: add code to conditionally initialize lo distribution
- rh: change empty i2c device from exception to assertion
- rh: add lo distribution board control
Diffstat (limited to 'host/lib/usrp')
4 files changed, 161 insertions, 0 deletions
diff --git a/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp b/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp index 1d76994d0..dd703a612 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_constants.hpp @@ -7,6 +7,7 @@ #ifndef INCLUDED_LIBUHD_RHODIUM_CONSTANTS_HPP #define INCLUDED_LIBUHD_RHODIUM_CONSTANTS_HPP +#include <array> #include <vector> #include <string> #include <cstddef> @@ -68,6 +69,15 @@ static constexpr char RHODIUM_LO_GAIN[] = "dsa"; //! LO output power static constexpr char RHODIUM_LO_POWER[] = "lo"; +static constexpr int NUM_LO_OUTPUT_PORT_NAMES = 4; + +static constexpr std::array<const char*, NUM_LO_OUTPUT_PORT_NAMES> LO_OUTPUT_PORT_NAMES = { + "LO_OUT_0", + "LO_OUT_1", + "LO_OUT_2", + "LO_OUT_3" +}; + static constexpr size_t RHODIUM_NUM_CHANS = 1; #endif /* INCLUDED_LIBUHD_RHODIUM_CONSTANTS_HPP */ diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_impl.hpp index 4f4dd925c..c070dabea 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_impl.hpp @@ -114,6 +114,12 @@ public: bool get_tx_lo_export_enabled(const std::string& name, const size_t chan); bool get_rx_lo_export_enabled(const std::string& name, const size_t chan); + // LO Distribution Control + void set_tx_lo_output_enabled(const bool enabled, const std::string& port_name, const size_t chan); + void set_rx_lo_output_enabled(const bool enabled, const std::string& port_name, const size_t chan); + bool get_tx_lo_output_enabled(const std::string& port_name, const size_t chan); + bool get_rx_lo_output_enabled(const std::string& port_name, const size_t chan); + // LO Gain Control //! Set the external gain for a TX LO @@ -185,6 +191,25 @@ private: const direction_t dir ); + //! Validate that port_name is valid, and that LO distribution functions + // can be called in this instance + void _validate_output_port( + const std::string& port_name, + const std::string& function_name + ); + + //! Configure LO Distribution board's termination switches + void _set_lo_output_enabled( + const bool enabled, + const std::string& port_name, + const direction_t dir + ); + + bool _get_lo_output_enabled( + const std::string& port_name, + const direction_t dir + ); + //! Configure LO1's output power // Out of range values will be coerced to [0-63] double _set_lo1_power( @@ -336,6 +361,13 @@ private: double _rx_lo_freq = 0.0; double _tx_lo_freq = 0.0; + //! LO Distribution board + bool _lo_dist_present = false; + + //! LO Distribution board output status + bool _lo_dist_rx_out_enabled[4] = { false, false, false, false }; + bool _lo_dist_tx_out_enabled[4] = { false, false, false, false }; + }; /* class radio_ctrl_impl */ }} /* namespace uhd::rfnoc */ diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_init.cpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_init.cpp index 8c2e6f231..6f7e37c26 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_init.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_init.cpp @@ -213,6 +213,10 @@ void rhodium_radio_ctrl_impl::_init_peripherals() _tx_fe_core->set_dc_offset(tx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE); _tx_fe_core->set_iq_balance(tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE); _tx_fe_core->populate_subtree(_tree->subtree(_root_path / "tx_fe_corrections" / 0)); + + UHD_LOG_TRACE(unique_id(), "Checking for existence of LO Distribution board"); + _lo_dist_present = _rpcc->request_with_token<bool>(_rpc_prefix + "is_lo_dist_present"); + UHD_LOG_DEBUG(unique_id(), str(boost::format("LO distribution board is%s present") % (_lo_dist_present ? "" : " NOT"))); } void rhodium_radio_ctrl_impl::_init_frontend_subtree( @@ -661,6 +665,28 @@ void rhodium_radio_ctrl_impl::_init_frontend_subtree( this->set_tx_lo_export_enabled(enabled, RHODIUM_LO2, chan_idx); }) ; + + //LO Distribution Output Ports + if (_lo_dist_present) { + for (const auto& port : LO_OUTPUT_PORT_NAMES) { + subtree->create<bool>(tx_fe_path / "los" / RHODIUM_LO1 / "lo_distribution" / port / "export") + .add_coerced_subscriber([this, chan_idx, port](bool enabled) { + this->set_tx_lo_output_enabled(enabled, port, chan_idx); + }) + .set_publisher([this, chan_idx, port]() { + return this->get_tx_lo_output_enabled(port, chan_idx); + }) + ; + subtree->create<bool>(rx_fe_path / "los" / RHODIUM_LO1 / "lo_distribution" / port / "export") + .add_coerced_subscriber([this, chan_idx, port](bool enabled) { + this->set_tx_lo_output_enabled(enabled, port, chan_idx); + }) + .set_publisher([this, chan_idx, port]() { + return this->get_tx_lo_output_enabled(port, chan_idx); + }) + ; + } + } } void rhodium_radio_ctrl_impl::_init_prop_tree() diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_lo.cpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_lo.cpp index 49eb854d5..a2789bc9a 100644 --- a/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_lo.cpp +++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_ctrl_lo.cpp @@ -307,6 +307,10 @@ void rhodium_radio_ctrl_impl::_set_lo1_export_enabled( ) { auto& _lo_ctrl = (dir == RX_DIRECTION) ? _rx_lo : _tx_lo; _lo_ctrl->set_output_enable(lmx2592_iface::output_t::RF_OUTPUT_B, enabled); + if (_lo_dist_present) { + const auto direction = (dir == RX_DIRECTION) ? "RX" : "TX"; + _rpcc->notify_with_token(_rpc_prefix + "enable_lo_export", direction, enabled); + } } void rhodium_radio_ctrl_impl::set_tx_lo_export_enabled( @@ -372,6 +376,95 @@ bool rhodium_radio_ctrl_impl::get_rx_lo_export_enabled( } /****************************************************************************** + * LO Distribution Control + *****************************************************************************/ + +void rhodium_radio_ctrl_impl::_validate_output_port(const std::string& port_name, const std::string& function_name) +{ + if (!_lo_dist_present) { + throw uhd::runtime_error(str(boost::format( + "%s can only be called if the LO distribution board was detected") % function_name)); + } + + if (!uhd::has(LO_OUTPUT_PORT_NAMES, port_name)) { + throw uhd::value_error(str(boost::format( + "%s was called with an invalid LO output port: %s Valid ports are [LO_OUT_0, LO_OUT_1, LO_OUT_2, LO_OUT_3]") + % function_name % port_name)); + } +} + +void rhodium_radio_ctrl_impl::_set_lo_output_enabled( + const bool enabled, + const std::string& port_name, + const direction_t dir +) { + auto direction = (dir == RX_DIRECTION) ? "RX" : "TX"; + auto name_iter = std::find(LO_OUTPUT_PORT_NAMES.begin(), LO_OUTPUT_PORT_NAMES.end(), port_name); + auto index = std::distance(LO_OUTPUT_PORT_NAMES.begin(), name_iter); + + _rpcc->notify_with_token(_rpc_prefix + "enable_lo_output", direction, index, enabled); + auto out_enabled = (dir == RX_DIRECTION) ? _lo_dist_rx_out_enabled : _lo_dist_tx_out_enabled; + out_enabled[index] = enabled; +} + +void rhodium_radio_ctrl_impl::set_tx_lo_output_enabled( + const bool enabled, + const std::string& port_name, + const size_t chan +) { + UHD_LOG_TRACE(unique_id(), "set_tx_lo_output_enabled(enabled=" << enabled << ", port_name=" << port_name << ", chan=" << chan << ")"); + UHD_ASSERT_THROW(chan == 0); + _validate_output_port(port_name, "set_tx_lo_output_enabled"); + + _set_lo_output_enabled(enabled, port_name, TX_DIRECTION); +} + +void rhodium_radio_ctrl_impl::set_rx_lo_output_enabled( + const bool enabled, + const std::string& port_name, + const size_t chan +) { + UHD_LOG_TRACE(unique_id(), "set_rx_lo_output_enabled(enabled=" << enabled << ", port_name=" << port_name << ", chan=" << chan << ")"); + UHD_ASSERT_THROW(chan == 0); + _validate_output_port(port_name, "set_rx_lo_output_enabled"); + + _set_lo_output_enabled(enabled, port_name, RX_DIRECTION); +} + +bool rhodium_radio_ctrl_impl::_get_lo_output_enabled( + const std::string& port_name, + const direction_t dir +) { + auto name_iter = std::find(LO_OUTPUT_PORT_NAMES.begin(), LO_OUTPUT_PORT_NAMES.end(), port_name); + auto index = std::distance(LO_OUTPUT_PORT_NAMES.begin(), name_iter); + + auto out_enabled = (dir == RX_DIRECTION) ? _lo_dist_rx_out_enabled : _lo_dist_tx_out_enabled; + return out_enabled[index]; +} + +bool rhodium_radio_ctrl_impl::get_tx_lo_output_enabled( + const std::string& port_name, + const size_t chan +) { + UHD_LOG_TRACE(unique_id(), "get_tx_lo_output_enabled(port_name=" << port_name << ", chan=" << chan << ")"); + UHD_ASSERT_THROW(chan == 0); + _validate_output_port(port_name, "get_tx_lo_output_enabled"); + + return _get_lo_output_enabled(port_name, TX_DIRECTION); +} + +bool rhodium_radio_ctrl_impl::get_rx_lo_output_enabled( + const std::string& port_name, + const size_t chan +) { + UHD_LOG_TRACE(unique_id(), "get_rx_lo_output_enabled(port_name=" << port_name << ", chan=" << chan << ")"); + UHD_ASSERT_THROW(chan == 0); + _validate_output_port(port_name, "get_rx_lo_output_enabled"); + + return _get_lo_output_enabled(port_name, RX_DIRECTION); +} + +/****************************************************************************** * Gain Control *****************************************************************************/ |