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(); + } } |