From 02f5347c71f53f11162796b70f15fe74adcc3aa0 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Tue, 27 Jul 2010 13:56:59 -0700 Subject: Added gain support for USRP2+ ADC. --- host/lib/usrp/usrp2/codec_ctrl.cpp | 27 ++++++++++++---- host/lib/usrp/usrp2/codec_ctrl.hpp | 13 ++++++++ host/lib/usrp/usrp2/codec_impl.cpp | 63 ++++++++++++++++++++++++++++++++++++-- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 ++ 4 files changed, 96 insertions(+), 9 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 107894d2a..b8f1df799 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -22,6 +22,7 @@ #include #include #include +#include static const bool codec_ctrl_debug = false; @@ -79,15 +80,29 @@ public: if(_iface->get_hw_rev() < USRP2P_FIRST_HW_REV) { //if we're on a USRP2 _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_OFF); } else { //we're on a USRP2+ -// _ads62p44_regs.reset = 1; -// this->send_ads62p44_reg(0x00); //issue a reset to the ADC - //everything else should be pretty much default, i think -// _ads62p44_regs.decimation = DECIMATION_DECIMATE_1; - - + //send a global power-down to the ADC here... it will get lifted on reset + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_GLOBAL_PD; + this->send_ads62p44_reg(0x14); } } + void set_rx_digital_gain(float gain) { //combine fine/correction digital gains + if(_iface->get_hw_rev() >= USRP2P_FIRST_HW_REV) { + int fine_gain = int(gain/0.5); + _ads62p44_regs.fine_gain = fine_gain; //hey what about when it calls for 6.5dB? + _ads62p44_regs.gain_correction = (gain - (double(fine_gain) * 0.5)) / 0.05; + this->send_ads62p44_reg(0x17); + this->send_ads62p44_reg(0x1A); + } else UHD_THROW_INVALID_CODE_PATH(); //should never have been called for USRP2 + } + + void set_rx_analog_gain(bool gain) { //turns on/off analog 3.5dB preamp + if(_iface->get_hw_rev() >= USRP2P_FIRST_HW_REV) { + _ads62p44_regs.coarse_gain = gain ? ads62p44_regs_t::COARSE_GAIN_3_5DB : ads62p44_regs_t::COARSE_GAIN_0DB; + this->send_ads62p44_reg(0x14); + } else UHD_THROW_INVALID_CODE_PATH(); + } + private: ad9777_regs_t _ad9777_regs; ads62p44_regs_t _ads62p44_regs; diff --git a/host/lib/usrp/usrp2/codec_ctrl.hpp b/host/lib/usrp/usrp2/codec_ctrl.hpp index ad014e0e1..d485690f6 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.hpp +++ b/host/lib/usrp/usrp2/codec_ctrl.hpp @@ -33,6 +33,19 @@ public: */ static sptr make(usrp2_iface::sptr iface); + /*! + * Set the analog preamplifier on the USRP2+ ADC (ADS62P44). + * \param gain enable or disable the 3.5dB preamp + */ + + virtual void set_rx_analog_gain(bool gain) = 0; + + /*! + * Set the digital gain on the USRP2+ ADC (ADS62P44). + * \param gain from 0-6.5dB + */ + + virtual void set_rx_digital_gain(float gain) = 0; }; #endif /* INCLUDED_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp index b9d51abf5..b246a35f8 100644 --- a/host/lib/usrp/usrp2/codec_impl.cpp +++ b/host/lib/usrp/usrp2/codec_impl.cpp @@ -17,10 +17,22 @@ #include "usrp2_impl.hpp" #include +#include +#include #include +#include +#include +#include using namespace uhd; using namespace uhd::usrp; +using namespace boost::assign; + +//this only applies to USRP2P +static const uhd::dict codec_rx_gain_ranges = map_list_of + ("analog", gain_range_t(0, 3.5, float(3.5))) + ("digital", gain_range_t(0, 6.45, float(0.05))); + /*********************************************************************** * Helper Methods @@ -55,17 +67,62 @@ void usrp2_mboard_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 + if(_iface->get_hw_rev() >= USRP2P_FIRST_HW_REV) { + val = prop_names_t(codec_rx_gain_ranges.keys()); + } else val = prop_names_t(); + return; + + case CODEC_PROP_GAIN_I: + case CODEC_PROP_GAIN_Q: + assert_has(_codec_rx_gains.keys(), name, "codec rx gain name"); + val = _codec_rx_gains[name]; return; default: UHD_THROW_PROP_GET_ERROR(); } } -void usrp2_mboard_impl::rx_codec_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp2_mboard_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_); + + float gain; + + switch(key.as()) { + case CODEC_PROP_GAIN_I: + case CODEC_PROP_GAIN_Q: + if(_iface->get_hw_rev() < USRP2P_FIRST_HW_REV) UHD_THROW_PROP_SET_ERROR();//this capability is only found in USRP2P + + gain = val.as(); + this->rx_codec_set_gain(gain, name); //okay. we can either have ONE gain and let codec_ctrl do the sorting between analog/digital gains, or we can have TWO gains and do the priority somewhere else. + return; + + default: + UHD_THROW_PROP_SET_ERROR(); + } } +/*********************************************************************** + * Helper function to set RX codec gain + ***********************************************************************/ + +void usrp2_mboard_impl::rx_codec_set_gain(float gain, const std::string &name){ + assert_has(codec_rx_gain_ranges.keys(), name, "codec rx gain name"); + + _codec_rx_gains[name] = gain; + + if(name == "analog") { + _codec_ctrl->set_rx_analog_gain(gain > 0); //just turn it on or off + return; + } + if(name == "digital") { + _codec_ctrl->set_rx_digital_gain(gain); + return; + } + UHD_THROW_PROP_SET_ERROR(); +} + + /*********************************************************************** * TX Codec Properties **********************************************************************/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index eb61609c2..70c3705c9 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -169,6 +169,8 @@ private: void tx_codec_set(const wax::obj &, const wax::obj &); wax_obj_proxy::sptr _rx_codec_proxy; wax_obj_proxy::sptr _tx_codec_proxy; + void rx_codec_set_gain(float, const std::string &); + uhd::dict _codec_rx_gains; //properties interface for rx dboard void rx_dboard_get(const wax::obj &, wax::obj &); -- cgit v1.2.3