diff options
| -rw-r--r-- | host/lib/usrp/usrp_e/clock_ctrl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e/codec_ctrl.cpp | 48 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e/codec_ctrl.hpp | 19 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e/codec_impl.cpp | 69 | 
4 files changed, 128 insertions, 9 deletions
| diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index 8a5bd1c6b..b53e880a2 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -60,7 +60,6 @@ class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{  public:      usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){          _iface = iface; -        std::cout << "master_clock_rate: " << (master_clock_rate/1e6) << " MHz" << std::endl;          //init the clock gen registers          //Note: out0 should already be clocking the FPGA or this isnt going to work diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp index ac61bc6b4..5322f94bd 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -31,6 +31,9 @@ using namespace uhd;  static const bool codec_debug = false; +const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); +const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); +  /***********************************************************************   * Codec Control Implementation   **********************************************************************/ @@ -44,6 +47,12 @@ public:      float read_aux_adc(aux_adc_t which);      void write_aux_dac(aux_dac_t which, float volts); +    //pga gain control +    void set_tx_pga_gain(float); +    float get_tx_pga_gain(void); +    void set_rx_pga_gain(float, char); +    float get_rx_pga_gain(char); +  private:      usrp_e_iface::sptr _iface;      ad9862_regs_t _ad9862_regs; @@ -120,6 +129,45 @@ usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){  }  /*********************************************************************** + * Codec Control Gain Control Methods + **********************************************************************/ +void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ +    int gain_word = int(63*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); +    _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, 63); +    this->send_reg(16); +} + +float usrp_e_codec_ctrl_impl::get_tx_pga_gain(void){ +    return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/63) + tx_pga_gain_range.min; +} + +void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ +    int gain_word = int(0x14*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); +    gain_word = std::clip(gain_word, 0, 0x14); +    switch(which){ +    case 'A': +        _ad9862_regs.rx_pga_a = gain_word; +        this->send_reg(2); +        return; +    case 'B': +        _ad9862_regs.rx_pga_b = gain_word; +        this->send_reg(3); +        return; +    default: UHD_THROW_INVALID_CODE_PATH(); +    } +} + +float usrp_e_codec_ctrl_impl::get_rx_pga_gain(char which){ +    int gain_word; +    switch(which){ +    case 'A': gain_word = _ad9862_regs.rx_pga_a; break; +    case 'B': gain_word = _ad9862_regs.rx_pga_b; break; +    default: UHD_THROW_INVALID_CODE_PATH(); +    } +    return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/0x14) + rx_pga_gain_range.min; +} + +/***********************************************************************   * Codec Control AUX ADC Methods   **********************************************************************/  static float aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){ diff --git a/host/lib/usrp/usrp_e/codec_ctrl.hpp b/host/lib/usrp/usrp_e/codec_ctrl.hpp index b9005a82d..87b6ff951 100644 --- a/host/lib/usrp/usrp_e/codec_ctrl.hpp +++ b/host/lib/usrp/usrp_e/codec_ctrl.hpp @@ -19,6 +19,7 @@  #define INCLUDED_USRP_E_CODEC_CTRL_HPP  #include "usrp_e_iface.hpp" +#include <uhd/types/ranges.hpp>  #include <boost/shared_ptr.hpp>  #include <boost/utility.hpp> @@ -31,10 +32,13 @@ class usrp_e_codec_ctrl : boost::noncopyable{  public:      typedef boost::shared_ptr<usrp_e_codec_ctrl> sptr; +    static const uhd::gain_range_t tx_pga_gain_range; +    static const uhd::gain_range_t rx_pga_gain_range; +      /*! -     * Make a new clock control object. +     * Make a new codec control object.       * \param iface the usrp_e iface object -     * \return the clock control object +     * \return the codec control object       */      static sptr make(usrp_e_iface::sptr iface); @@ -70,6 +74,17 @@ public:       */      virtual void write_aux_dac(aux_dac_t which, float volts) = 0; +    //! Set the TX PGA gain +    virtual void set_tx_pga_gain(float gain) = 0; + +    //! Get the TX PGA gain +    virtual float get_tx_pga_gain(void) = 0; + +    //! Set the RX PGA gain ('A' or 'B') +    virtual void set_rx_pga_gain(float gain, char which) = 0; + +    //! Get the RX PGA gain ('A' or 'B') +    virtual float get_rx_pga_gain(char which) = 0;  };  #endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e/codec_impl.cpp b/host/lib/usrp/usrp_e/codec_impl.cpp index 51f7b02b8..84f8bd37f 100644 --- a/host/lib/usrp/usrp_e/codec_impl.cpp +++ b/host/lib/usrp/usrp_e/codec_impl.cpp @@ -16,6 +16,7 @@  //  #include "usrp_e_impl.hpp" +#include <uhd/utils/assert.hpp>  #include <uhd/usrp/codec_props.hpp>  #include <boost/bind.hpp> @@ -40,6 +41,8 @@ void usrp_e_impl::codec_init(void){  /***********************************************************************   * RX Codec Properties   **********************************************************************/ +static const std::string ad9862_pga_gain_name = "ad9862 pga"; +  void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){      wax::obj key; std::string name;      boost::tie(key, name) = extract_named_prop(key_); @@ -55,15 +58,46 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){          return;      case CODEC_PROP_GAIN_NAMES: -        val = prop_names_t(); //no gain elements to be controlled +        val = prop_names_t(1, ad9862_pga_gain_name); +        return; + +    case CODEC_PROP_GAIN_RANGE: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        val = usrp_e_codec_ctrl::rx_pga_gain_range; +        return; + +    case CODEC_PROP_GAIN_I: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        val = _codec_ctrl->get_rx_pga_gain('A'); +        return; + +    case CODEC_PROP_GAIN_Q: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        val = _codec_ctrl->get_rx_pga_gain('B');          return;      default: UHD_THROW_PROP_GET_ERROR();      }  } -void usrp_e_impl::rx_codec_set(const wax::obj &, const wax::obj &){ -    UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the set request conditioned on the key +    switch(key.as<codec_prop_t>()){ +    case CODEC_PROP_GAIN_I: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        _codec_ctrl->set_rx_pga_gain(val.as<float>(), 'A'); +        return; + +    case CODEC_PROP_GAIN_Q: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        _codec_ctrl->set_rx_pga_gain(val.as<float>(), 'B'); +        return; + +    default: UHD_THROW_PROP_SET_ERROR(); +    }  }  /*********************************************************************** @@ -84,13 +118,36 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){          return;      case CODEC_PROP_GAIN_NAMES: -        val = prop_names_t(); //no gain elements to be controlled +        val = prop_names_t(1, ad9862_pga_gain_name); +        return; + +    case CODEC_PROP_GAIN_RANGE: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        val = usrp_e_codec_ctrl::tx_pga_gain_range; +        return; + +    case CODEC_PROP_GAIN_I: //only one gain for I and Q +    case CODEC_PROP_GAIN_Q: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        val = _codec_ctrl->get_tx_pga_gain();          return;      default: UHD_THROW_PROP_GET_ERROR();      }  } -void usrp_e_impl::tx_codec_set(const wax::obj &, const wax::obj &){ -    UHD_THROW_PROP_SET_ERROR(); +void usrp_e_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the set request conditioned on the key +    switch(key.as<codec_prop_t>()){ +    case CODEC_PROP_GAIN_I: //only one gain for I and Q +    case CODEC_PROP_GAIN_Q: +        UHD_ASSERT_THROW(name == ad9862_pga_gain_name); +        _codec_ctrl->set_tx_pga_gain(val.as<float>()); +        return; + +    default: UHD_THROW_PROP_SET_ERROR(); +    }  } | 
