diff options
| -rw-r--r-- | host/lib/usrp/dboard/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_common.cpp (renamed from host/lib/usrp/dboard/db_wbx.cpp) | 266 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_common.hpp | 72 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_simple.cpp | 251 | 
4 files changed, 398 insertions, 196 deletions
| diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt index 7bd201294..1687713a9 100644 --- a/host/lib/usrp/dboard/CMakeLists.txt +++ b/host/lib/usrp/dboard/CMakeLists.txt @@ -1,5 +1,5 @@  # -# Copyright 2010 Ettus Research LLC +# Copyright 2010-2011 Ettus Research LLC  #  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU General Public License as published by @@ -23,7 +23,8 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/db_basic_and_lf.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/db_rfx.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/db_xcvr2450.cpp -    ${CMAKE_CURRENT_SOURCE_DIR}/db_wbx.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_common.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_simple.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/db_dbsrx.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/db_unknown.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/db_tvrx.cpp diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx_common.cpp index 2e9a1edc8..3ad2dac6a 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx_common.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2011 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@  //  // Common IO Pins -#define ANTSW_IO        ((1 << 5)|(1 << 15))    // on UNIT_TX, 0 = TX, 1 = RX, on UNIT_RX 0 = main ant, 1 = RX2  #define ADF4350_CE      (1 << 3)  #define ADF4350_PDBRF   (1 << 2)  #define ADF4350_MUXOUT  (1 << 1)                // INPUT!!! @@ -43,38 +42,23 @@  #define RX_MIXER_ENB    (RXBB_PDB|ADF4350_PDBRF)  #define RX_MIXER_DIS    0 -// Pin functions -#define TX_POWER_IO     (TX_PUP_5V|TX_PUP_3V)   // high enables power supply -#define TXIO_MASK       (TX_POWER_IO|ANTSW_IO|ADF4350_CE|ADF4350_PDBRF|TXMOD_EN) - -#define RX_POWER_IO     (RX_PUP_5V|RX_PUP_3V)   // high enables power supply -#define RXIO_MASK       (RX_POWER_IO|ANTSW_IO|ADF4350_CE|ADF4350_PDBRF|RXBB_PDB|RX_ATTN_MASK) -  // Power functions -#define TX_POWER_UP     (TX_POWER_IO|ADF4350_CE) +#define TX_POWER_UP     (TX_PUP_5V|TX_PUP_3V|ADF4350_CE) // high enables power supply  #define TX_POWER_DOWN   0 -#define RX_POWER_UP     (RX_POWER_IO|ADF4350_CE) +#define RX_POWER_UP     (RX_PUP_5V|RX_PUP_3V|ADF4350_CE) // high enables power supply  #define RX_POWER_DOWN   0 -// Antenna constants -#define ANT_TX          0                       //the tx line is transmitting -#define ANT_RX          ANTSW_IO                //the tx line is receiving -#define ANT_TXRX        0                       //the rx line is on txrx -#define ANT_RX2         ANTSW_IO                //the rx line in on rx2 -#define ANT_XX          0                       //dont care how the antenna is set - +#include "db_wbx_common.hpp"  #include "adf4350_regs.hpp"  #include <uhd/types/dict.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/types/ranges.hpp>  #include <uhd/types/sensors.hpp>  #include <uhd/utils/assert_has.hpp> -#include <uhd/utils/static.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/usrp/dboard_base.hpp> -#include <uhd/usrp/dboard_manager.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/format.hpp>  #include <boost/math/special_functions/round.hpp> @@ -84,16 +68,10 @@ using namespace uhd::usrp;  using namespace boost::assign;  /*********************************************************************** - * The WBX dboard constants + * The WBX Common dboard constants   **********************************************************************/  static const bool wbx_debug = false; -static const freq_range_t wbx_freq_range(68.75e6, 2.2e9); - -static const prop_names_t wbx_tx_antennas = list_of("TX/RX"); - -static const prop_names_t wbx_rx_antennas = list_of("TX/RX")("RX2"); -  static const uhd::dict<std::string, gain_range_t> wbx_tx_gain_ranges = map_list_of      ("PGA0", gain_range_t(0, 25, 0.05))  ; @@ -103,105 +81,69 @@ static const uhd::dict<std::string, gain_range_t> wbx_rx_gain_ranges = map_list_  ;  /*********************************************************************** - * The WBX dboard - **********************************************************************/ -class wbx_xcvr : public xcvr_dboard_base{ -public: -    wbx_xcvr(ctor_args_t args); -    ~wbx_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: -    uhd::dict<std::string, double> _tx_gains, _rx_gains; -    double       _rx_lo_freq, _tx_lo_freq; -    std::string  _tx_ant, _rx_ant; - -    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); - -    void update_atr(void); - -    /*! -     * Set the LO frequency for the particular dboard unit. -     * \param unit which unit rx or tx -     * \param target_freq the desired frequency in Hz -     * \return the actual frequency in Hz -     */ -    double set_lo_freq(dboard_iface::unit_t unit, double target_freq); - -    /*! -     * Get the lock detect status of the LO. -     * \param unit which unit rx or tx -     * \return true for locked -     */ -    bool get_locked(dboard_iface::unit_t unit){ -        return (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; -    } -}; - -/*********************************************************************** - * Register the WBX dboard (min freq, max freq, rx div2, tx div2) + * WBX Common Implementation   **********************************************************************/ -static dboard_base::sptr make_wbx(dboard_base::ctor_args_t args){ -    return dboard_base::sptr(new wbx_xcvr(args)); -} - -UHD_STATIC_BLOCK(reg_wbx_dboards){ -    dboard_manager::register_dboard(0x0053, 0x0052, &make_wbx, "WBX"); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -wbx_xcvr::wbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ +wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){      //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); -    //set the gpio directions and atr controls (identically) -    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXIO_MASK); -    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXIO_MASK); -    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TXIO_MASK); -    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RXIO_MASK); -    if (wbx_debug) std::cerr << boost::format( -        "WBX GPIO Direction: RX: 0x%08x, TX: 0x%08x" -    ) % RXIO_MASK % TXIO_MASK << std::endl; +    //set the gpio directions and atr controls +    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXMOD_EN|ADF4350_PDBRF); +    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB|ADF4350_PDBRF); +    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TX_PUP_5V|TX_PUP_3V|ADF4350_CE|TXMOD_EN|ADF4350_PDBRF); +    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF4350_CE|RXBB_PDB|ADF4350_PDBRF|RX_ATTN_MASK); -    //set some default values -    set_rx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); -    set_tx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); -    set_rx_ant("RX2"); +    //setup ATR for the mixer enables +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        TX_MIXER_DIS, TX_MIXER_DIS | TX_MIXER_ENB); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     TX_MIXER_DIS, TX_MIXER_DIS | TX_MIXER_ENB); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     TX_MIXER_ENB, TX_MIXER_DIS | TX_MIXER_ENB); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, TX_MIXER_ENB, TX_MIXER_DIS | TX_MIXER_ENB); + +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE,        RX_MIXER_DIS, RX_MIXER_DIS | RX_MIXER_ENB); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY,     RX_MIXER_DIS, RX_MIXER_DIS | RX_MIXER_ENB); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY,     RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB); +    //set some default values      BOOST_FOREACH(const std::string &name, wbx_tx_gain_ranges.keys()){          set_tx_gain(wbx_tx_gain_ranges[name].start(), name);      }      BOOST_FOREACH(const std::string &name, wbx_rx_gain_ranges.keys()){          set_rx_gain(wbx_rx_gain_ranges[name].start(), name);      } +    set_rx_enabled(false); +    set_tx_enabled(false);  } -wbx_xcvr::~wbx_xcvr(void){ +wbx_base::~wbx_base(void){      /* NOP */  }  /*********************************************************************** + * Enables + **********************************************************************/ +void wbx_base::set_rx_enabled(bool enb){ +    this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, +        (enb)? RX_POWER_UP : RX_POWER_DOWN, RX_POWER_UP | RX_POWER_DOWN +    ); +} + +void wbx_base::set_tx_enabled(bool enb){ +    this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, +        (enb)? TX_POWER_UP : TX_POWER_DOWN, TX_POWER_UP | TX_POWER_DOWN +    ); +} + +/***********************************************************************   * Gain Handling   **********************************************************************/  static int rx_pga0_gain_to_iobits(double &gain){      //clip the input      gain = wbx_rx_gain_ranges["PGA0"].clip(gain); -    //convert to attenuation and update iobits for atr +    //convert to attenuation      double attn = wbx_rx_gain_ranges["PGA0"].stop() - gain;      //calculate the attenuation @@ -239,7 +181,7 @@ static double tx_pga0_gain_to_dac_volts(double &gain){      return dac_volts;  } -void wbx_xcvr::set_tx_gain(double gain, const std::string &name){ +void wbx_base::set_tx_gain(double gain, const std::string &name){      assert_has(wbx_tx_gain_ranges.keys(), name, "wbx tx gain name");      if(name == "PGA0"){          double dac_volts = tx_pga0_gain_to_dac_volts(gain); @@ -251,75 +193,22 @@ void wbx_xcvr::set_tx_gain(double gain, const std::string &name){      else UHD_THROW_INVALID_CODE_PATH();  } -void wbx_xcvr::set_rx_gain(double gain, const std::string &name){ +void wbx_base::set_rx_gain(double gain, const std::string &name){      assert_has(wbx_rx_gain_ranges.keys(), name, "wbx rx gain name");      if(name == "PGA0"){ -        rx_pga0_gain_to_iobits(gain); +        boost::uint16_t io_bits = rx_pga0_gain_to_iobits(gain);          _rx_gains[name] = gain; -        //write the new gain to atr regs -        update_atr(); +        //write the new gain to rx gpio outputs +        this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, io_bits, RX_ATTN_MASK);      }      else UHD_THROW_INVALID_CODE_PATH();  }  /*********************************************************************** - * Antenna Handling - **********************************************************************/ -void wbx_xcvr::update_atr(void){ -    //calculate atr pins -    int pga0_iobits = rx_pga0_gain_to_iobits(_rx_gains["PGA0"]); - -    //setup the tx atr (this does not change with antenna) -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        TX_POWER_UP | ANT_XX | TX_MIXER_DIS); -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     TX_POWER_UP | ANT_RX | TX_MIXER_DIS); -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     TX_POWER_UP | ANT_TX | TX_MIXER_ENB); -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, TX_POWER_UP | ANT_TX | TX_MIXER_ENB); - -    //setup the rx atr (this does not change with antenna) -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, -        pga0_iobits | RX_POWER_UP | ANT_XX | RX_MIXER_DIS); -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, -        pga0_iobits | RX_POWER_UP | ANT_XX | RX_MIXER_DIS); -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, -        pga0_iobits | RX_POWER_UP | ANT_RX2| RX_MIXER_ENB); - -    //set the rx atr regs that change with antenna setting -    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, -        pga0_iobits | RX_POWER_UP | RX_MIXER_ENB | ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2)); -    if (wbx_debug) std::cerr << boost::format( -        "WBX RXONLY ATR REG: 0x%08x" -    ) % (pga0_iobits | RX_POWER_UP | RX_MIXER_ENB | ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2)) << std::endl; -} - -void wbx_xcvr::set_rx_ant(const std::string &ant){ -    //validate input -    assert_has(wbx_rx_antennas, ant, "wbx rx antenna name"); - -    //shadow the setting -    _rx_ant = ant; - -    //write the new antenna setting to atr regs -    update_atr(); -} - -void wbx_xcvr::set_tx_ant(const std::string &ant){ -    assert_has(wbx_tx_antennas, ant, "wbx tx antenna name"); -    //only one antenna option, do nothing -} - -/***********************************************************************   * Tuning   **********************************************************************/ -void wbx_xcvr::set_rx_lo_freq(double freq){ -    _rx_lo_freq = set_lo_freq(dboard_iface::UNIT_RX, freq); -} - -void wbx_xcvr::set_tx_lo_freq(double freq){ -    _tx_lo_freq = set_lo_freq(dboard_iface::UNIT_TX, freq); -} - -double wbx_xcvr::set_lo_freq( +double wbx_base::set_lo_freq(      dboard_iface::unit_t unit,      double target_freq  ){ @@ -327,9 +216,6 @@ double wbx_xcvr::set_lo_freq(          "WBX tune: target frequency %f Mhz"      ) % (target_freq/1e6) << std::endl; -    //clip the input -    target_freq = wbx_freq_range.clip(target_freq); -      //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)      static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of          (0,23) //adf4350_regs_t::PRESCALER_4_5 @@ -464,10 +350,14 @@ double wbx_xcvr::set_lo_freq(      return actual_freq;  } +bool wbx_base::get_locked(dboard_iface::unit_t unit){ +    return (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; +} +  /***********************************************************************   * RX Get and Set   **********************************************************************/ -void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ +void wbx_base::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 @@ -495,19 +385,19 @@ void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){          return;      case SUBDEV_PROP_FREQ: -        val = _rx_lo_freq; +        val = 0.0;          return;      case SUBDEV_PROP_FREQ_RANGE: -        val = wbx_freq_range; +        val = freq_range_t(0.0, 0.0, 0.0);;          return;      case SUBDEV_PROP_ANTENNA: -        val = _rx_ant; +        val = std::string("");          return;      case SUBDEV_PROP_ANTENNA_NAMES: -        val = wbx_rx_antennas; +        val = prop_names_t(1, "");          return;      case SUBDEV_PROP_CONNECTION: @@ -515,7 +405,7 @@ void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){          return;      case SUBDEV_PROP_ENABLED: -        val = true; //always enabled +        val = _rx_enabled;          return;      case SUBDEV_PROP_USE_LO_OFFSET: @@ -539,26 +429,20 @@ void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){      }  } -void wbx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ +void wbx_base::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 +        _rx_enabled = val.as<bool>(); +        this->set_rx_enabled(_rx_enabled); +        return;      case SUBDEV_PROP_BANDWIDTH:          uhd::warning::post( @@ -573,7 +457,7 @@ void wbx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){  /***********************************************************************   * TX Get and Set   **********************************************************************/ -void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ +void wbx_base::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 @@ -601,19 +485,19 @@ void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){          return;      case SUBDEV_PROP_FREQ: -        val = _tx_lo_freq; +        val = 0.0;          return;      case SUBDEV_PROP_FREQ_RANGE: -        val = wbx_freq_range; +        val = freq_range_t(0.0, 0.0, 0.0);          return;      case SUBDEV_PROP_ANTENNA: -        val = std::string("TX/RX"); +        val = std::string("");          return;      case SUBDEV_PROP_ANTENNA_NAMES: -        val = wbx_tx_antennas; +        val = prop_names_t(1, "");          return;      case SUBDEV_PROP_CONNECTION: @@ -621,7 +505,7 @@ void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){          return;      case SUBDEV_PROP_ENABLED: -        val = true; //always enabled +        val = _tx_enabled;          return;      case SUBDEV_PROP_USE_LO_OFFSET: @@ -645,26 +529,20 @@ void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){      }  } -void wbx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ +void wbx_base::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 +        _tx_enabled = val.as<bool>(); +        this->set_tx_enabled(_tx_enabled); +        return;      case SUBDEV_PROP_BANDWIDTH:          uhd::warning::post( diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp new file mode 100644 index 000000000..07e84a565 --- /dev/null +++ b/host/lib/usrp/dboard/db_wbx_common.hpp @@ -0,0 +1,72 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_LIBUHD_USRP_DBOARD_DB_WBX_COMMON_HPP +#define INCLUDED_LIBUHD_USRP_DBOARD_DB_WBX_COMMON_HPP + +#include "adf4350_regs.hpp" +#include <uhd/types/dict.hpp> +#include <uhd/types/ranges.hpp> +#include <uhd/utils/props.hpp> +#include <uhd/usrp/dboard_base.hpp> + +namespace uhd{ namespace usrp{ + +/*********************************************************************** + * The WBX dboard base class + **********************************************************************/ +class wbx_base : public xcvr_dboard_base{ +public: +    wbx_base(ctor_args_t args); +    virtual ~wbx_base(void); + +protected: +    virtual void set_rx_gain(double gain, const std::string &name); +    virtual void set_tx_gain(double gain, const std::string &name); + +    virtual void set_rx_enabled(bool enb); +    virtual void set_tx_enabled(bool enb); + +    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); + +    /*! +     * Set the LO frequency for the particular dboard unit. +     * \param unit which unit rx or tx +     * \param target_freq the desired frequency in Hz +     * \return the actual frequency in Hz +     */ +    virtual double set_lo_freq(dboard_iface::unit_t unit, double target_freq); + +    /*! +     * Get the lock detect status of the LO. +     * \param unit which unit rx or tx +     * \return true for locked +     */ +    virtual bool get_locked(dboard_iface::unit_t unit); + +private: +    uhd::dict<std::string, double> _tx_gains, _rx_gains; +    bool _rx_enabled, _tx_enabled; +}; + +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_DBOARD_DB_WBX_COMMON_HPP */ diff --git a/host/lib/usrp/dboard/db_wbx_simple.cpp b/host/lib/usrp/dboard/db_wbx_simple.cpp new file mode 100644 index 000000000..390b4474b --- /dev/null +++ b/host/lib/usrp/dboard/db_wbx_simple.cpp @@ -0,0 +1,251 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +// Antenna constants +#define ANTSW_IO        ((1 << 5)|(1 << 15))    // on UNIT_TX, 0 = TX, 1 = RX, on UNIT_RX 0 = main ant, 1 = RX2 +#define ANT_TX          0                       //the tx line is transmitting +#define ANT_RX          ANTSW_IO                //the tx line is receiving +#define ANT_TXRX        0                       //the rx line is on txrx +#define ANT_RX2         ANTSW_IO                //the rx line in on rx2 +#define ANT_XX          0                       //dont care how the antenna is set + +#include "db_wbx_common.hpp" +#include <uhd/utils/static.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/usrp/dboard_manager.hpp> +#include <uhd/usrp/subdev_props.hpp> +#include <boost/assign/list_of.hpp> + +using namespace uhd; +using namespace uhd::usrp; +using namespace boost::assign; + +/*********************************************************************** + * The WBX Simple dboard constants + **********************************************************************/ +static const bool wbx_debug = false; + +static const freq_range_t wbx_freq_range(68.75e6, 2.2e9); + +static const prop_names_t wbx_tx_antennas = list_of("TX/RX"); + +static const prop_names_t wbx_rx_antennas = list_of("TX/RX")("RX2"); + +/*********************************************************************** + * The WBX simple implementation + **********************************************************************/ +class wbx_simple : public wbx_base{ +public: +    wbx_simple(ctor_args_t args); +    ~wbx_simple(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: +    void set_rx_lo_freq(double freq); +    void set_tx_lo_freq(double freq); +    double _rx_lo_freq, _tx_lo_freq; + +    void set_rx_ant(const std::string &ant); +    void set_tx_ant(const std::string &ant); +    std::string _rx_ant; +}; + +/*********************************************************************** + * Register the WBX simple implementation + **********************************************************************/ +static dboard_base::sptr make_wbx_simple(dboard_base::ctor_args_t args){ +    return dboard_base::sptr(new wbx_simple(args)); +} + +UHD_STATIC_BLOCK(reg_wbx_simple_dboards){ +    dboard_manager::register_dboard(0x0053, 0x0052, &make_wbx_simple, "WBX"); +    dboard_manager::register_dboard(0x0053, 0x004f, &make_wbx_simple, "WBX + Simple GDB"); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){ + +    //set the gpio directions and atr controls (antenna switches all under ATR) +    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO); +    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO); +    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO); +    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO); + +    //setup ATR for the antenna switches (constant) +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        ANT_XX, ANTSW_IO); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     ANT_RX, ANTSW_IO); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     ANT_TX, ANTSW_IO); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO); + +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE,        ANT_XX, ANTSW_IO); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY,     ANT_XX, ANTSW_IO); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO); + +    //set some default values +    set_rx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); +    set_tx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); +    set_rx_ant("RX2"); +} + +wbx_simple::~wbx_simple(void){ +    /* NOP */ +} + +/*********************************************************************** + * Antennas + **********************************************************************/ +void wbx_simple::set_rx_ant(const std::string &ant){ +    //validate input +    assert_has(wbx_rx_antennas, ant, "wbx rx antenna name"); + +    //shadow the setting +    _rx_ant = ant; + +    //write the new antenna setting to atr regs +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2), ANTSW_IO); +} + +void wbx_simple::set_tx_ant(const std::string &ant){ +    assert_has(wbx_tx_antennas, ant, "wbx tx antenna name"); +    //only one antenna option, do nothing +} + +/*********************************************************************** + * Tuning + **********************************************************************/ +void wbx_simple::set_rx_lo_freq(double freq){ +    _rx_lo_freq = set_lo_freq(dboard_iface::UNIT_RX, wbx_freq_range.clip(freq)); +} + +void wbx_simple::set_tx_lo_freq(double freq){ +    _tx_lo_freq = set_lo_freq(dboard_iface::UNIT_TX, wbx_freq_range.clip(freq)); +} + +/*********************************************************************** + * RX Get and Set + **********************************************************************/ +void wbx_simple::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 = std::string("WBX RX + Simple GDB"); +        return; + +    case SUBDEV_PROP_FREQ: +        val = _rx_lo_freq; +        return; + +    case SUBDEV_PROP_FREQ_RANGE: +        val = wbx_freq_range; +        return; + +    case SUBDEV_PROP_ANTENNA: +        val = _rx_ant; +        return; + +    case SUBDEV_PROP_ANTENNA_NAMES: +        val = wbx_rx_antennas; +        return; + +    default: +        //call into the base class for other properties +        wbx_base::rx_get(key_, val); +    } +} + +void wbx_simple::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_ANTENNA: +        this->set_rx_ant(val.as<std::string>()); +        return; + +    default: +        //call into the base class for other properties +        wbx_base::rx_set(key_, val); +    } +} + +/*********************************************************************** + * TX Get and Set + **********************************************************************/ +void wbx_simple::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 = std::string("WBX TX + Simple GDB"); +        return; + +    case SUBDEV_PROP_FREQ: +        val = _tx_lo_freq; +        return; + +    case SUBDEV_PROP_FREQ_RANGE: +        val = wbx_freq_range; +        return; + +    case SUBDEV_PROP_ANTENNA: +        val = std::string("TX/RX"); +        return; + +    case SUBDEV_PROP_ANTENNA_NAMES: +        val = wbx_tx_antennas; +        return; + +    default: +        //call into the base class for other properties +        wbx_base::tx_get(key_, val); +    } +} + +void wbx_simple::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_ANTENNA: +        this->set_tx_ant(val.as<std::string>()); +        return; + +    default: +        //call into the base class for other properties +        wbx_base::tx_set(key_, val); +    } +} | 
