aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-08-13 01:09:45 +0000
committerJosh Blum <josh@joshknows.com>2010-08-13 01:09:45 +0000
commitac85d2b38c26fd6d31ba0a997d033b159d51769d (patch)
tree74af8c091a5e9a46955b9a92169e948bd1bfde88 /host/lib
parent8c676eeb973593caecb7270a6106e8592f73a352 (diff)
downloaduhd-ac85d2b38c26fd6d31ba0a997d033b159d51769d.tar.gz
uhd-ac85d2b38c26fd6d31ba0a997d033b159d51769d.tar.bz2
uhd-ac85d2b38c26fd6d31ba0a997d033b159d51769d.zip
usrp-e: codec gain control from properties interface
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/usrp/usrp_e/clock_ctrl.cpp1
-rw-r--r--host/lib/usrp/usrp_e/codec_ctrl.cpp48
-rw-r--r--host/lib/usrp/usrp_e/codec_ctrl.hpp19
-rw-r--r--host/lib/usrp/usrp_e/codec_impl.cpp69
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();
+ }
}