diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/experts/expert_container.cpp | 13 | ||||
| -rw-r--r-- | host/lib/rfnoc/legacy_compat.cpp | 49 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_twinrx.cpp | 6 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_xcvr2450.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/twinrx/twinrx_experts.cpp | 32 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/twinrx/twinrx_experts.hpp | 39 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_radio_ctrl_impl.cpp | 39 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_radio_ctrl_impl.hpp | 2 | 
8 files changed, 158 insertions, 24 deletions
| diff --git a/host/lib/experts/expert_container.cpp b/host/lib/experts/expert_container.cpp index edfc2ebe3..78c783790 100644 --- a/host/lib/experts/expert_container.cpp +++ b/host/lib/experts/expert_container.cpp @@ -92,23 +92,28 @@ public:          boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex);          boost::lock_guard<boost::mutex> lock(_mutex);          EX_LOG(0, str(boost::format("resolve_all(%s)") % (force?"force":""))); +        // Do a full resolve of the graph          _resolve_helper("", "", force);      } -    void resolve_from(const std::string& node_name) +    void resolve_from(const std::string&)      {          boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex);          boost::lock_guard<boost::mutex> lock(_mutex);          EX_LOG(0, str(boost::format("resolve_from(%s)") % node_name)); -        _resolve_helper(node_name, "", false); +        // Do a full resolve of the graph +        // Not optimizing the traversal using node_name to reduce experts complexity +        _resolve_helper("", "", false);      } -    void resolve_to(const std::string& node_name) +    void resolve_to(const std::string&)      {          boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex);          boost::lock_guard<boost::mutex> lock(_mutex);          EX_LOG(0, str(boost::format("resolve_to(%s)") % node_name)); -        _resolve_helper("", node_name, false); +        // Do a full resolve of the graph +        // Not optimizing the traversal using node_name to reduce experts complexity +        _resolve_helper("", "", false);      }      dag_vertex_t& retrieve(const std::string& name) const diff --git a/host/lib/rfnoc/legacy_compat.cpp b/host/lib/rfnoc/legacy_compat.cpp index 2c8e10c4a..20553062f 100644 --- a/host/lib/rfnoc/legacy_compat.cpp +++ b/host/lib/rfnoc/legacy_compat.cpp @@ -16,6 +16,7 @@  //  #include "legacy_compat.hpp" +#include "../usrp/device3/device3_impl.hpp"  #include <uhd/property_tree.hpp>  #include <uhd/rfnoc/radio_ctrl.hpp>  #include <uhd/rfnoc/ddc_block_ctrl.hpp> @@ -171,6 +172,13 @@ public:      /************************************************************************       * API Calls       ***********************************************************************/ +    inline uhd::fs_path rx_dsp_root(const size_t mboard_idx, const size_t dsp_index, const size_t port_index) +    { +        return mb_root(mboard_idx) / "xbar" / +               str(boost::format("%s_%d") % DDC_BLOCK_NAME % dsp_index) / +               "legacy_api" / port_index; +    } +      uhd::fs_path rx_dsp_root(const size_t mboard_idx, const size_t chan)      {          // The DSP index is the same as the radio index @@ -181,8 +189,13 @@ public:              return mb_root(mboard_idx) / "rx_dsps" / dsp_index / port_index;          } +        return rx_dsp_root(mboard_idx, dsp_index, port_index); +    } + +    inline uhd::fs_path tx_dsp_root(const size_t mboard_idx, const size_t dsp_index, const size_t port_index) +    {          return mb_root(mboard_idx) / "xbar" / -               str(boost::format("%s_%d") % DDC_BLOCK_NAME % dsp_index) / +               str(boost::format("%s_%d") % DUC_BLOCK_NAME % dsp_index) /                 "legacy_api" / port_index;      } @@ -196,9 +209,7 @@ public:              return mb_root(mboard_idx) / "tx_dsps" / dsp_index / port_index;          } -        return mb_root(mboard_idx) / "xbar" / -               str(boost::format("%s_%d") % DUC_BLOCK_NAME % dsp_index) / -               "legacy_api" / port_index; +        return tx_dsp_root(mboard_idx, dsp_index, port_index);      }      uhd::fs_path rx_fe_root(const size_t mboard_idx, const size_t chan) @@ -511,6 +522,20 @@ private: // methods                          ;                      }                  } +            } else { +                for (size_t dsp_idx = 0; dsp_idx < _num_radios_per_board; dsp_idx++) { +                    for (size_t chan = 0; chan < _num_rx_chans_per_radio; chan++) { +                        _tree->access<double>(rx_dsp_root(mboard_idx, dsp_idx, chan) / "rate/value") +                            .add_coerced_subscriber( +                                boost::bind( +                                    &uhd::usrp::device3_impl::update_rx_streamers, +                                    boost::dynamic_pointer_cast<uhd::usrp::device3_impl>(_device), +                                    _1 +                                ) +                            ) +                        ; +                    } +                }              }              if (not _has_ducs) {                  for (size_t radio_idx = 0; radio_idx < _num_radios_per_board; radio_idx++) { @@ -544,7 +569,21 @@ private: // methods                          ;                      }                  } -            } +            } else { +                for (size_t dsp_idx = 0; dsp_idx < _num_radios_per_board; dsp_idx++) { +                    for (size_t chan = 0; chan < _num_tx_chans_per_radio; chan++) { +                        _tree->access<double>(tx_dsp_root(mboard_idx, dsp_idx, chan) / "rate/value") +                            .add_coerced_subscriber( +                                boost::bind( +                                    &uhd::usrp::device3_impl::update_tx_streamers, +                                    boost::dynamic_pointer_cast<uhd::usrp::device3_impl>(_device), +                                    _1 +                                ) +                            ) +                        ; +                    } +                } +            } /* if not _has_ducs */          }      } diff --git a/host/lib/usrp/dboard/db_twinrx.cpp b/host/lib/usrp/dboard/db_twinrx.cpp index e960f134f..477412de0 100644 --- a/host/lib/usrp/dboard/db_twinrx.cpp +++ b/host/lib/usrp/dboard/db_twinrx.cpp @@ -75,6 +75,11 @@ public:          get_rx_subtree()->create<meta_range_t>("bandwidth/range")              .set(freq_range_t(BW, BW)); +        // Command Time +        expert_factory::add_data_node<time_spec_t>(_expert, prepend_ch("time/rx_frontend", _ch_name), time_spec_t(0.0)); +        expert_factory::add_prop_node<time_spec_t>(_expert, get_rx_subtree(), +            "time/cmd", prepend_ch("time/cmd", _ch_name), time_spec_t(0.0)); +          //Frequency Specific          get_rx_subtree()->create<meta_range_t>("freq/range")              .set(freq_range_t(10e6, 6.0e9)); @@ -263,6 +268,7 @@ public:              expert_factory::add_worker_node<twinrx_freq_path_expert>(_expert, _expert->node_retriever(), fe);              expert_factory::add_worker_node<twinrx_freq_coercion_expert>(_expert, _expert->node_retriever(), fe);              expert_factory::add_worker_node<twinrx_chan_gain_expert>(_expert, _expert->node_retriever(), fe); +            expert_factory::add_worker_node<twinrx_scheduling_expert>(_expert, _expert->node_retriever(), fe);              expert_factory::add_worker_node<twinrx_nyquist_expert>(_expert, _expert->node_retriever(), fe, _db_iface);          } diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index aa0bae8b8..0f839b03e 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -372,7 +372,7 @@ double xcvr2450::set_lo_freq_core(double target_freq){      //variables used in the calculation below      double scaler = xcvr2450::is_highband(target_freq)? (4.0/5.0) : (4.0/3.0);      double ref_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_TX); -    int R, intdiv, fracdiv; +    int R, intdiv = 131, fracdiv = 0;      //loop through values until we get a match      for(_ad9515div = 2; _ad9515div <= 3; _ad9515div++){ diff --git a/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp b/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp index ddaa4211e..3b41972da 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_experts.cpp @@ -30,6 +30,17 @@ using namespace uhd::math;  using namespace uhd::usrp::dboard::twinrx;  /*!--------------------------------------------------------- + * twinrx_scheduling_expert::resolve + * --------------------------------------------------------- + */ +void twinrx_scheduling_expert::resolve() +{ +    // Currently a straight pass-through. To be expanded as needed +    // when more advanced scheduling is needed +    _rx_frontend_time = _command_time; +} + +/*!---------------------------------------------------------   * twinrx_freq_path_expert::resolve   * ---------------------------------------------------------   */ @@ -222,6 +233,19 @@ void twinrx_freq_coercion_expert::resolve()   */  void twinrx_nyquist_expert::resolve()  { +    // Do not execute when clear_command_time is called. +    // This is a transition of the command time from non-zero to zero. +    if (_rx_frontend_time == time_spec_t(0.0) and _cached_cmd_time != time_spec_t(0.0)) { +        _cached_cmd_time = _rx_frontend_time; +        return; +    } + +    // Do not execute twice for the same command time unless untimed +    if (_rx_frontend_time == _cached_cmd_time and _rx_frontend_time != time_spec_t(0.0)) { +        return; +    } +    _cached_cmd_time = _rx_frontend_time; +      double if_freq_sign = 1.0;      if (_lo1_inj_side == INJ_HIGH_SIDE) if_freq_sign *= -1.0;      if (_lo2_inj_side == INJ_HIGH_SIDE) if_freq_sign *= -1.0; @@ -570,10 +594,6 @@ void twinrx_settings_expert::_resolve_lox_freq(              ch0_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH2, ch0_freq_d);          } else if (synth0_mapping == MAPPING_SHARED or synth1_mapping == MAPPING_SHARED) {              // If any synthesizer is being shared then we are not in hopping mode -            if (rf_freq_ppm_t(ch0_freq_d) != ch1_freq_d) { -                UHD_MSG(warning) << -                    "Incompatible RF/LO frequencies for LO sharing. Using Ch0 settings for both channels."; -            }              twinrx_ctrl::channel_t ch = (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2;              ch0_freq_c = _set_lox_synth_freq(lo_stage, ch, ch0_freq_d);              ch1_freq_c = ch0_freq_c; @@ -597,10 +617,6 @@ void twinrx_settings_expert::_resolve_lox_freq(              ch1_freq_c = _set_lox_synth_freq(lo_stage, twinrx_ctrl::CH2, ch1_freq_d);          } else if (synth0_mapping == MAPPING_SHARED or synth1_mapping == MAPPING_SHARED) {              // If any synthesizer is being shared then we are not in hopping mode -            if (rf_freq_ppm_t(ch0_freq_d) != ch1_freq_d) { -                UHD_MSG(warning) << -                    "Incompatible RF/LO frequencies for LO sharing. Using Ch0 settings for both channels."; -            }              twinrx_ctrl::channel_t ch = (synth0_mapping == MAPPING_SHARED) ? twinrx_ctrl::CH1 : twinrx_ctrl::CH2;              ch0_freq_c = _set_lox_synth_freq(lo_stage, ch, ch0_freq_d);              ch1_freq_c = ch0_freq_c; diff --git a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp index 1617c9c80..9c83dbfa8 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp @@ -52,6 +52,38 @@ static const std::string lo_stage_str(lo_stage_t stage, bool lower = false) {      return prefix + ((stage == STAGE_LO1) ? "1" : "2");  } + +/*!--------------------------------------------------------- + * twinrx_scheduling_expert + * + * This expert is responsible for scheduling time sensitive actions + * in other experts. It responds to changes in the command time and + * selectively causes experts to run in order to ensure a synchronized + * system. + * + * --------------------------------------------------------- + */ +class twinrx_scheduling_expert : public experts::worker_node_t { +public: +    twinrx_scheduling_expert(const experts::node_retriever_t& db, std::string ch) +    : experts::worker_node_t(prepend_ch("twinrx_scheduling_expert", ch)), +      _command_time     (db, prepend_ch("time/cmd", ch)), +      _rx_frontend_time (db, prepend_ch("time/rx_frontend", ch)) +    { +        bind_accessor(_command_time); +        bind_accessor(_rx_frontend_time); +    } + +private: +    virtual void resolve(); + +    //Inputs +    experts::data_reader_t<time_spec_t>    _command_time; + +    //Outputs +    experts::data_writer_t<time_spec_t>    _rx_frontend_time; +}; +  /*!---------------------------------------------------------   * twinrx_freq_path_expert   * @@ -271,6 +303,7 @@ public:        _if_freq_d        (db, prepend_ch("if_freq/desired", ch)),        _lo1_inj_side     (db, prepend_ch("ch/LO1/inj_side", ch)),        _lo2_inj_side     (db, prepend_ch("ch/LO2/inj_side", ch)), +      _rx_frontend_time (db, prepend_ch("time/rx_frontend", ch)),        _if_freq_c        (db, prepend_ch("if_freq/coerced", ch)),        _db_iface         (db_iface)      { @@ -280,6 +313,7 @@ public:          bind_accessor(_lo1_inj_side);          bind_accessor(_lo2_inj_side);          bind_accessor(_if_freq_c); +        bind_accessor(_rx_frontend_time);      }  private: @@ -293,9 +327,14 @@ private:      experts::data_reader_t<double>                          _if_freq_d;      experts::data_reader_t<lo_inj_side_t>                   _lo1_inj_side;      experts::data_reader_t<lo_inj_side_t>                   _lo2_inj_side; +    experts::data_reader_t<time_spec_t>                     _rx_frontend_time; +      //Outputs      experts::data_writer_t<double>                          _if_freq_c;      dboard_iface::sptr                                      _db_iface; + +    //Misc +    time_spec_t  _cached_cmd_time;  };  /*!--------------------------------------------------------- diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp index f14ea3fd9..991b97696 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp @@ -120,6 +120,15 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)          _tx_fe_map[i].core->set_dc_offset(tx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE);          _tx_fe_map[i].core->set_iq_balance(tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE);          _tx_fe_map[i].core->populate_subtree(_tree->subtree(_root_path / "tx_fe_corrections" / i)); + +        //////////////////////////////////////////////////////////////// +        // Bind the daughterboard command time to the motherboard level property +        //////////////////////////////////////////////////////////////// + +        if (_tree->exists(fs_path("time") / "cmd")) { +            _tree->access<time_spec_t>(fs_path("time") / "cmd") +                    .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i)); +        }      }      //////////////////////////////////////////////////////////////// @@ -163,6 +172,13 @@ double x300_radio_ctrl_impl::set_rate(double /* rate */)      return get_rate();  } +time_spec_t x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t &time, const size_t chan) +{ +    return _tree->access<time_spec_t>( +            fs_path("dboards" / _radio_slot /  "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd") +    ).set(time).get(); +} +  void x300_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan)  {      _tree->access<std::string>( @@ -399,14 +415,25 @@ void x300_radio_ctrl_impl::setup_radio(      //bind frontend corrections to the dboard freq props      const fs_path db_tx_fe_path = db_path / "tx_frontends"; -    BOOST_FOREACH(const std::string &name, _tree->list(db_tx_fe_path)) { -        _tree->access<double>(db_tx_fe_path / name / "freq" / "value") -            .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_tx_fe_corrections, this, db_path, _root_path / "tx_fe_corrections" / name, _1)); +    if (not _tx_fe_map.empty()) { +        for (size_t i = 0; i < _get_num_radios(); i++) { +            if (_tree->exists(db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) { +                _tree->access<double>(db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value") +                        .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_tx_fe_corrections, this, db_path, +                                                            _root_path / "tx_fe_corrections" / _tx_fe_map[i].db_fe_name, _1)); +            } +        }      }      const fs_path db_rx_fe_path = db_path / "rx_frontends"; -    BOOST_FOREACH(const std::string &name, _tree->list(db_rx_fe_path)) { -        _tree->access<double>(db_rx_fe_path / name / "freq" / "value") -            .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_rx_fe_corrections, this, db_path, _root_path / "rx_fe_corrections" / name,_1)); +    if (not _rx_fe_map.empty()) { +        for (size_t i = 0; i < _get_num_radios(); i++) { +            if (_tree->exists(db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) { +                _tree->access<double>(db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value") +                        .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_rx_fe_corrections, this, db_path, +                                                            _root_path / "rx_fe_corrections" / _tx_fe_map[i].db_fe_name, +                                                            _1)); +            } +        }      }      //////////////////////////////////////////////////////////////// diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp index 65d4443eb..5b9d47841 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp @@ -161,6 +161,8 @@ private:      void set_rx_fe_corrections(const uhd::fs_path &db_path, const uhd::fs_path &rx_fe_corr_path, const double lo_freq);      void set_tx_fe_corrections(const uhd::fs_path &db_path, const uhd::fs_path &tx_fe_corr_path, const double lo_freq); +    time_spec_t set_fe_cmd_time(const time_spec_t &time, const size_t chan); +  private: // members      enum radio_connection_t { PRIMARY, SECONDARY }; | 
