diff options
| -rw-r--r-- | host/lib/usrp/dboard/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_rfx.cpp | 320 | 
2 files changed, 65 insertions, 257 deletions
| diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt index b5474ed16..adaaab683 100644 --- a/host/lib/usrp/dboard/CMakeLists.txt +++ b/host/lib/usrp/dboard/CMakeLists.txt @@ -21,7 +21,7 @@  LIBUHD_APPEND_SOURCES(      #${CMAKE_CURRENT_SOURCE_DIR}/db_basic_and_lf.cpp -    #${CMAKE_CURRENT_SOURCE_DIR}/db_rfx.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/db_rfx.cpp      #${CMAKE_CURRENT_SOURCE_DIR}/db_xcvr2450.cpp      #${CMAKE_CURRENT_SOURCE_DIR}/db_sbx.cpp      #${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_common.cpp diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 14129ef72..3e6d89758 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -45,6 +45,7 @@  #include <uhd/usrp/dboard_base.hpp>  #include <uhd/usrp/dboard_manager.hpp>  #include <boost/assign/list_of.hpp> +#include <boost/bind.hpp>  #include <boost/format.hpp>  #include <boost/math/special_functions/round.hpp> @@ -55,11 +56,9 @@ using namespace boost::assign;  /***********************************************************************   * The RFX Series constants   **********************************************************************/ -static const prop_names_t rfx_tx_antennas = list_of("TX/RX"); +static const std::vector<std::string> rfx_tx_antennas = list_of("TX/RX"); -static const prop_names_t rfx_rx_antennas = list_of("TX/RX")("RX2"); - -static const uhd::dict<std::string, gain_range_t> rfx_tx_gain_ranges; //empty +static const std::vector<std::string> rfx_rx_antennas = list_of("TX/RX")("RX2");  static const uhd::dict<std::string, gain_range_t> rfx_rx_gain_ranges = map_list_of      ("PGA0", gain_range_t(0, 70, 0.022)) @@ -81,27 +80,17 @@ public:      );      ~rfx_xcvr(void); -    void rx_get(const wax::obj &key, wax::obj &val); -    void rx_set(const wax::obj &key, const wax::obj &val); - -    void tx_get(const wax::obj &key, wax::obj &val); -    void tx_set(const wax::obj &key, const wax::obj &val); -  private:      const freq_range_t _freq_range;      const uhd::dict<std::string, gain_range_t> _rx_gain_ranges;      const uhd::dict<dboard_iface::unit_t, bool> _div2; -    double       _rx_lo_freq, _tx_lo_freq;      std::string  _rx_ant;      uhd::dict<std::string, double> _rx_gains;      boost::uint16_t _power_up; -    void set_rx_lo_freq(double freq); -    void set_tx_lo_freq(double freq);      void set_rx_ant(const std::string &ant);      void set_tx_ant(const std::string &ant); -    void set_rx_gain(double gain, const std::string &name); -    void set_tx_gain(double gain, const std::string &name); +    double set_rx_gain(double gain, const std::string &name);      /*!       * Set the LO frequency for the particular dboard unit. @@ -114,17 +103,18 @@ private:      /*!       * Get the lock detect status of the LO.       * \param unit which unit rx or tx -     * \return true for locked +     * \return sensor for locked       */ -    bool get_locked(dboard_iface::unit_t unit){ -        return (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; +    sensor_value_t get_locked(dboard_iface::unit_t unit){ +        const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; +        return sensor_value_t("LO", locked, "locked", "unlocked");      }      /*!       * Read the RSSI from the aux adc -     * \return the rssi in dB +     * \return the rssi sensor in dBm       */ -    double get_rssi(void){ +    sensor_value_t get_rssi(void){          //RSSI from VAGC vs RF Power, Fig 34, pg 13          double max_power = -3.0; @@ -133,7 +123,8 @@ private:          static const double rssi_dyn_range = 60;          //calculate the rssi from the voltage          double voltage = this->get_iface()->read_aux_adc(dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B); -        return max_power - rssi_dyn_range*(voltage - min_v)/(max_v - min_v); +        const double rssi = max_power - rssi_dyn_range*(voltage - min_v)/(max_v - min_v); +        return sensor_value_t("RSSI", rssi, "dBm");      }  }; @@ -192,6 +183,55 @@ rfx_xcvr::rfx_xcvr(      ),      _power_up((get_rx_id() == 0x0024 && get_tx_id() == 0x0028) ? POWER_IO : 0)  { +    //////////////////////////////////////////////////////////////////// +    // Register RX properties +    //////////////////////////////////////////////////////////////////// +    this->get_rx_subtree()->create<std::string>("name").set("RFX RX"); +    this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") +        .publish(boost::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_RX)); +    this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi") +        .publish(boost::bind(&rfx_xcvr::get_rssi, this)); +    BOOST_FOREACH(const std::string &name, _rx_gain_ranges.keys()){ +        this->get_rx_subtree()->create<double>("gains/"+name+"/value") +            .coerce(boost::bind(&rfx_xcvr::set_rx_gain, this, _1, name)) +            .set(_rx_gain_ranges[name].start()); +        this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") +            .set(_rx_gain_ranges[name]); +    } +    this->get_rx_subtree()->create<double>("freq/value") +        .coerce(boost::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1)) +        .set((_freq_range.start() + _freq_range.stop())/2.0); +    this->get_rx_subtree()->create<meta_range_t>("freq/range").set(_freq_range); +    this->get_rx_subtree()->create<std::string>("antenna/value") +        .subscribe(boost::bind(&rfx_xcvr::set_rx_ant, this, _1)) +        .set("RX2"); +    this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") +        .set(rfx_rx_antennas); +    this->get_rx_subtree()->create<std::string>("connection").set("QI"); +    this->get_rx_subtree()->create<bool>("enabled").set(true); //always enabled +    this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); +    this->get_rx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided + +    //////////////////////////////////////////////////////////////////// +    // Register TX properties +    //////////////////////////////////////////////////////////////////// +    this->get_tx_subtree()->create<std::string>("name").set("RFX TX"); +    this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") +        .publish(boost::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_TX)); +    this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists +    this->get_tx_subtree()->create<double>("freq/value") +        .coerce(boost::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1)) +        .set((_freq_range.start() + _freq_range.stop())/2.0); +    this->get_tx_subtree()->create<meta_range_t>("freq/range").set(_freq_range); +    this->get_tx_subtree()->create<std::string>("antenna/value") +        .subscribe(boost::bind(&rfx_xcvr::set_tx_ant, this, _1)).set(rfx_tx_antennas.at(0)); +    this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") +        .set(rfx_tx_antennas); +    this->get_tx_subtree()->create<std::string>("connection").set("IQ"); +    this->get_tx_subtree()->create<bool>("enabled").set(true); //always enabled +    this->get_tx_subtree()->create<bool>("use_lo_offset").set(true); +    this->get_tx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided +      //enable the clocks that we need      this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true);      this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); @@ -213,15 +253,6 @@ rfx_xcvr::rfx_xcvr(      this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE,        _power_up | ANT_XX | MIXER_DIS);      this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY,     _power_up | ANT_XX | MIXER_DIS);      this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB); - -    //set some default values -    set_rx_lo_freq((_freq_range.start() + _freq_range.stop())/2.0); -    set_tx_lo_freq((_freq_range.start() + _freq_range.stop())/2.0); -    set_rx_ant("RX2"); - -    BOOST_FOREACH(const std::string &name, _rx_gain_ranges.keys()){ -        set_rx_gain(_rx_gain_ranges[name].start(), name); -    }  }  rfx_xcvr::~rfx_xcvr(void){ @@ -267,20 +298,16 @@ static double rx_pga0_gain_to_dac_volts(double &gain, double range){      return dac_volts;  } -void rfx_xcvr::set_tx_gain(double, const std::string &name){ -    assert_has(rfx_tx_gain_ranges.keys(), name, "rfx tx gain name"); -    UHD_THROW_INVALID_CODE_PATH(); //no gains to set -} - -void rfx_xcvr::set_rx_gain(double gain, const std::string &name){ +double rfx_xcvr::set_rx_gain(double gain, const std::string &name){      assert_has(_rx_gain_ranges.keys(), name, "rfx rx gain name");      if(name == "PGA0"){          double dac_volts = rx_pga0_gain_to_dac_volts(gain,                                 (_rx_gain_ranges["PGA0"].stop() - _rx_gain_ranges["PGA0"].start())); -        _rx_gains[name] = gain;          //write the new voltage to the aux dac          this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, dac_volts); + +        return gain;      }      else UHD_THROW_INVALID_CODE_PATH();  } @@ -288,14 +315,6 @@ void rfx_xcvr::set_rx_gain(double gain, const std::string &name){  /***********************************************************************   * Tuning   **********************************************************************/ -void rfx_xcvr::set_rx_lo_freq(double freq){ -    _rx_lo_freq = set_lo_freq(dboard_iface::UNIT_RX, freq); -} - -void rfx_xcvr::set_tx_lo_freq(double freq){ -    _tx_lo_freq = set_lo_freq(dboard_iface::UNIT_TX, freq); -} -  double rfx_xcvr::set_lo_freq(      dboard_iface::unit_t unit,      double target_freq @@ -408,214 +427,3 @@ double rfx_xcvr::set_lo_freq(      ) % (actual_freq/1e6) << std::endl;      return actual_freq;  } - -/*********************************************************************** - * RX Get and Set - **********************************************************************/ -void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ -    named_prop_t key = named_prop_t::extract(key_); - -    //handle the get request conditioned on the key -    switch(key.as<subdev_prop_t>()){ -    case SUBDEV_PROP_NAME: -        val = get_rx_id().to_pp_string(); -        return; - -    case SUBDEV_PROP_OTHERS: -        val = prop_names_t(); //empty -        return; - -    case SUBDEV_PROP_GAIN: -        assert_has(_rx_gains.keys(), key.name, "rfx rx gain name"); -        val = _rx_gains[key.name]; -        return; - -    case SUBDEV_PROP_GAIN_RANGE: -        assert_has(_rx_gain_ranges.keys(), key.name, "rfx rx gain name"); -        val = _rx_gain_ranges[key.name]; -        return; - -    case SUBDEV_PROP_GAIN_NAMES: -        val = prop_names_t(_rx_gain_ranges.keys()); -        return; - -    case SUBDEV_PROP_FREQ: -        val = _rx_lo_freq; -        return; - -    case SUBDEV_PROP_FREQ_RANGE: -        val = _freq_range; -        return; - -    case SUBDEV_PROP_ANTENNA: -        val = _rx_ant; -        return; - -    case SUBDEV_PROP_ANTENNA_NAMES: -        val = rfx_rx_antennas; -        return; - -    case SUBDEV_PROP_CONNECTION: -        val = SUBDEV_CONN_COMPLEX_QI; -        return; - -    case SUBDEV_PROP_ENABLED: -        val = true; //always enabled -        return; - -    case SUBDEV_PROP_USE_LO_OFFSET: -        val = false; -        return; - -    case SUBDEV_PROP_SENSOR: -        if (key.name == "lo_locked") -            val = sensor_value_t("LO", this->get_locked(dboard_iface::UNIT_RX), "locked", "unlocked"); -        else if ((key.name == "rssi") and (get_rx_id() != 0x0024)) -            val = sensor_value_t("RSSI", this->get_rssi(), "dBm"); -        else -            UHD_THROW_INVALID_CODE_PATH(); -        return; - -    case SUBDEV_PROP_SENSOR_NAMES:{ -            prop_names_t names = list_of("lo_locked"); -            if (get_rx_id() != 0x0024) names.push_back("rssi"); -            val = names; -        } -        return; - -    case SUBDEV_PROP_BANDWIDTH: -        val = 2*20.0e6; //20MHz low-pass, we want complex double-sided -        return; - -    default: UHD_THROW_PROP_GET_ERROR(); -    } -} - -void rfx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ -    named_prop_t key = named_prop_t::extract(key_); - -    //handle the get request conditioned on the key -    switch(key.as<subdev_prop_t>()){ - -    case SUBDEV_PROP_FREQ: -        this->set_rx_lo_freq(val.as<double>()); -        return; - -    case SUBDEV_PROP_GAIN: -        this->set_rx_gain(val.as<double>(), key.name); -        return; - -    case SUBDEV_PROP_ANTENNA: -        this->set_rx_ant(val.as<std::string>()); -        return; - -    case SUBDEV_PROP_ENABLED: -        return; //always enabled - -    case SUBDEV_PROP_BANDWIDTH: -        UHD_MSG(warning) << "RFX: No tunable bandwidth, fixed filtered to 40MHz"; -        return; - -    default: UHD_THROW_PROP_SET_ERROR(); -    } -} - -/*********************************************************************** - * TX Get and Set - **********************************************************************/ -void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ -    named_prop_t key = named_prop_t::extract(key_); - -    //handle the get request conditioned on the key -    switch(key.as<subdev_prop_t>()){ -    case SUBDEV_PROP_NAME: -        val = get_tx_id().to_pp_string(); -        return; - -    case SUBDEV_PROP_OTHERS: -        val = prop_names_t(); //empty -        return; - -    case SUBDEV_PROP_GAIN: -    case SUBDEV_PROP_GAIN_RANGE: -        assert_has(rfx_tx_gain_ranges.keys(), key.name, "rfx tx gain name"); -        //no controllable tx gains, will not get here -        return; - -    case SUBDEV_PROP_GAIN_NAMES: -        val = prop_names_t(rfx_tx_gain_ranges.keys()); -        return; - -    case SUBDEV_PROP_FREQ: -        val = _tx_lo_freq; -        return; - -    case SUBDEV_PROP_FREQ_RANGE: -        val = _freq_range; -        return; - -    case SUBDEV_PROP_ANTENNA: -        val = std::string("TX/RX"); -        return; - -    case SUBDEV_PROP_ANTENNA_NAMES: -        val = rfx_tx_antennas; -        return; - -    case SUBDEV_PROP_CONNECTION: -        val = SUBDEV_CONN_COMPLEX_IQ; -        return; - -    case SUBDEV_PROP_ENABLED: -        val = true; //always enabled -        return; - -    case SUBDEV_PROP_USE_LO_OFFSET: -        val = true; -        return; - -    case SUBDEV_PROP_SENSOR: -        UHD_ASSERT_THROW(key.name == "lo_locked"); -        val = sensor_value_t("LO", this->get_locked(dboard_iface::UNIT_TX), "locked", "unlocked"); -        return; - -    case SUBDEV_PROP_SENSOR_NAMES: -        val = prop_names_t(1, "lo_locked"); -        return; - -    case SUBDEV_PROP_BANDWIDTH: -        val = 2*20.0e6; //20MHz low-pass, we want complex double-sided -        return; - -    default: UHD_THROW_PROP_GET_ERROR(); -    } -} - -void rfx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ -    named_prop_t key = named_prop_t::extract(key_); - -    //handle the get request conditioned on the key -    switch(key.as<subdev_prop_t>()){ - -    case SUBDEV_PROP_FREQ: -        this->set_tx_lo_freq(val.as<double>()); -        return; - -    case SUBDEV_PROP_GAIN: -        this->set_tx_gain(val.as<double>(), key.name); -        return; - -    case SUBDEV_PROP_ANTENNA: -        this->set_tx_ant(val.as<std::string>()); -        return; - -    case SUBDEV_PROP_ENABLED: -        return; //always enabled - -    case SUBDEV_PROP_BANDWIDTH: -        UHD_MSG(warning) << "RFX: No tunable bandwidth, fixed filtered to 40MHz"; -        return; - -    default: UHD_THROW_PROP_SET_ERROR(); -    } -} | 
