diff options
-rw-r--r-- | host/README | 2 | ||||
-rw-r--r-- | host/lib/usrp/README | 12 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/clock_ctrl.cpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/codec_ctrl.cpp | 85 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/codec_impl.cpp | 26 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 19 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_clk_regs.hpp | 31 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.cpp | 42 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_iface.hpp | 22 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.cpp | 12 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.hpp | 8 |
11 files changed, 175 insertions, 86 deletions
diff --git a/host/README b/host/README index cab1e0b10..c4a72cd83 100644 --- a/host/README +++ b/host/README @@ -8,6 +8,7 @@ The hardware driver for Ettus Research products. ######################################################################## USRP1 USRP2 +USRP-N2XX ######################################################################## # Supported USRP Daughterboards @@ -20,6 +21,7 @@ RFX Series XCVR 2450 WBX Series DBSRX +DBSRX2 TVRX ######################################################################## diff --git a/host/lib/usrp/README b/host/lib/usrp/README new file mode 100644 index 000000000..c125d1dad --- /dev/null +++ b/host/lib/usrp/README @@ -0,0 +1,12 @@ +######################################################################## +# lib USRP directories: +######################################################################## + +dboard: + Daughterboard implementation code for all USRP daughterboards + +usrp1: + Implementation code for the USB-based USRP Classic motherboard. + +usrp2: + Implementation code for USRP2 and USRP-N2XX. diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index 1f8e65ce6..428d5539b 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -33,7 +33,7 @@ class usrp2_clock_ctrl_impl : public usrp2_clock_ctrl{ public: usrp2_clock_ctrl_impl(usrp2_iface::sptr iface){ _iface = iface; - clk_regs = usrp2_clk_regs_t(_iface->get_hw_rev()); + clk_regs = usrp2_clk_regs_t(_iface->get_rev()); _ad9510_regs.cp_current_setting = ad9510_regs_t::CP_CURRENT_SETTING_3_0MA; this->write_reg(clk_regs.pll_3); diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 8680c285a..ad1ae1acb 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -59,15 +59,23 @@ public: } //power-up adc - if(!_iface->is_usrp2p()) { //if we're on a USRP2 - _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_ON); - } 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; - _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_NORMAL; - this->send_ads62p44_reg(0x14); + switch(_iface->get_rev()){ + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_ON); + break; + + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _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; + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_NORMAL; + this->send_ads62p44_reg(0x14); + break; + + case usrp2_iface::USRP_NXXX: break; } } @@ -77,34 +85,57 @@ public: this->send_ad9777_reg(0); //power-down adc - if(!_iface->is_usrp2p()) { //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+ - //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); + switch(_iface->get_rev()){ + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_OFF); + break; + + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + //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); + break; + + case usrp2_iface::USRP_NXXX: break; } } void set_rx_digital_gain(float gain) { //fine digital gain - if(_iface->is_usrp2p()) { - _ads62p44_regs.fine_gain = int(gain/0.5); - this->send_ads62p44_reg(0x17); - } else UHD_THROW_INVALID_CODE_PATH(); //should never have been called for USRP2 + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.fine_gain = int(gain/0.5); + this->send_ads62p44_reg(0x17); + break; + + default: UHD_THROW_INVALID_CODE_PATH(); + } } void set_rx_digital_fine_gain(float gain) { //gain correction - if(_iface->is_usrp2p()) { - _ads62p44_regs.gain_correction = int(gain / 0.05); - this->send_ads62p44_reg(0x1A); - } else UHD_THROW_INVALID_CODE_PATH(); //should never have been called for USRP2 + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.gain_correction = int(gain / 0.05); + this->send_ads62p44_reg(0x1A); + break; + + default: UHD_THROW_INVALID_CODE_PATH(); + } } void set_rx_analog_gain(bool gain) { //turns on/off analog 3.5dB preamp - if(_iface->is_usrp2p()) { - _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(); + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.coarse_gain = gain ? ads62p44_regs_t::COARSE_GAIN_3_5DB : ads62p44_regs_t::COARSE_GAIN_0DB; + this->send_ads62p44_reg(0x14); + break; + + default: UHD_THROW_INVALID_CODE_PATH(); + } } private: diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp index 1c1f60765..5f4937643 100644 --- a/host/lib/usrp/usrp2/codec_impl.cpp +++ b/host/lib/usrp/usrp2/codec_impl.cpp @@ -32,7 +32,7 @@ using namespace boost::assign; static const uhd::dict<std::string, gain_range_t> codec_rx_gain_ranges = map_list_of ("analog", gain_range_t(0, 3.5, 3.5)) ("digital", gain_range_t(0, 6.0, 0.5)) - ("digital-fine", gain_range_t(0, 0.5, 0.05)); + ("digital-fine", gain_range_t(0, 0.5, 0.05)); /*********************************************************************** @@ -67,9 +67,14 @@ void usrp2_mboard_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ return; case CODEC_PROP_GAIN_NAMES: - if(_iface->is_usrp2p()) { - val = prop_names_t(codec_rx_gain_ranges.keys()); - } else val = prop_names_t(); + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + val = prop_names_t(codec_rx_gain_ranges.keys()); + return; + + default: val = prop_names_t(); + } return; case CODEC_PROP_GAIN_I: @@ -89,19 +94,14 @@ void usrp2_mboard_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ void usrp2_mboard_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); - float gain; - switch(key.as<codec_prop_t>()) { + switch(key.as<codec_prop_t>()) { case CODEC_PROP_GAIN_I: case CODEC_PROP_GAIN_Q: - if(!_iface->is_usrp2p()) UHD_THROW_PROP_SET_ERROR();//this capability is only found in USRP2P - - gain = val.as<float>(); - this->rx_codec_set_gain(gain, key.name); - return; + this->rx_codec_set_gain(val.as<float>(), key.name); + return; - default: - UHD_THROW_PROP_SET_ERROR(); + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 5b9dd1fa3..5b47045e2 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -147,26 +147,31 @@ void usrp2_mboard_impl::update_clock_config(void){ _iface->poke32(_iface->regs.time64_flags, pps_flags); //clock source ref 10mhz - if(_iface->is_usrp2p()) { + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: switch(_clock_config.ref_source){ case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break; case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; default: throw std::runtime_error("usrp2: unhandled clock configuration reference source"); } - } else { + _clock_ctrl->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO + break; + + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: switch(_clock_config.ref_source){ case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break; case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; default: throw std::runtime_error("usrp2: unhandled clock configuration reference source"); } - } + _clock_ctrl->enable_external_ref(_clock_config.ref_source != clock_config_t::REF_INT); + break; - //clock source ref 10mhz - bool use_external = (_clock_config.ref_source != clock_config_t::REF_INT) - || (_iface->is_usrp2p()); //USRP2P has an internal 10MHz TCXO - _clock_ctrl->enable_external_ref(use_external); + case usrp2_iface::USRP_NXXX: break; + } } void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){ diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp index d5f80a919..6c46d0a35 100644 --- a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp @@ -18,31 +18,38 @@ #ifndef INCLUDED_USRP2_CLK_REGS_HPP #define INCLUDED_USRP2_CLK_REGS_HPP -#include "usrp2_regs.hpp" +#include "usrp2_iface.hpp" class usrp2_clk_regs_t { public: usrp2_clk_regs_t(void) { ; } - usrp2_clk_regs_t(boost::uint16_t hw_rev) { + usrp2_clk_regs_t(usrp2_iface::rev_type rev) { test = 0; fpga = 1; - adc = (hw_rev >= usrp2_rev_nums(N2XX)) ? 2 : 4; dac = 3; - serdes = (hw_rev >= usrp2_rev_nums(N2XX)) ? 4 : 2; //only used by usrp2+ - tx_db = (hw_rev >= usrp2_rev_nums(N2XX)) ? 5 : 6; - - switch(hw_rev) { - case usrp2_rev_nums(USRP2_REV3): + + switch(rev) { + case usrp2_iface::USRP2_REV3: exp = 2; + adc = 4; + serdes = 2; + tx_db = 6; break; - case usrp2_rev_nums(USRP2_REV4): + case usrp2_iface::USRP2_REV4: exp = 5; + adc = 4; + serdes = 2; + tx_db = 6; break; - case usrp2_rev_nums(N2XX): + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: exp = 6; + adc = 2; + serdes = 4; + tx_db = 5; break; - default: - throw std::runtime_error("Unknown hardware revision"); + case usrp2_iface::USRP_NXXX: + //dont throw, it may be unitialized break; } diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 10cb86962..01df68010 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -17,6 +17,7 @@ #include "usrp2_regs.hpp" #include "usrp2_iface.hpp" +#include <uhd/utils/exception.hpp> #include <uhd/utils/assert.hpp> #include <uhd/types/dict.hpp> #include <boost/thread.hpp> @@ -51,11 +52,22 @@ public: **********************************************************************/ usrp2_iface_impl(udp_simple::sptr ctrl_transport){ _ctrl_transport = ctrl_transport; - + mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_N100); - regs = usrp2_get_regs(get_hw_rev()); + switch(this->get_rev()){ + case USRP2_REV3: + case USRP2_REV4: + regs = usrp2_get_regs(false); + break; + + case USRP_NXXX: + case USRP_N200: + case USRP_N210: + regs = usrp2_get_regs(true); + break; + } - //check the fpga compatibility number + //check the fpga compatibility number const boost::uint32_t fpga_compat_num = this->peek32(this->regs.compat_num_rb); if (fpga_compat_num != USRP2_FPGA_COMPAT_NUM){ throw std::runtime_error(str(boost::format( @@ -259,15 +271,27 @@ public: } throw std::runtime_error("usrp2 no control response"); } - - bool is_usrp2p(void) { - return (get_hw_rev() >= usrp2_rev_nums(N2XX)); - } - boost::uint16_t get_hw_rev(void) { - return boost::lexical_cast<boost::uint16_t>(mb_eeprom["rev"]); + rev_type get_rev(void){ + switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["rev"])){ + case 0x0003: return USRP2_REV3; + case 0x0004: return USRP2_REV4; + case 0x0A00: return USRP_N200; + case 0x0A01: return USRP_N210; + } + return USRP_NXXX; //unknown type } + const std::string get_cname(void){ + switch(this->get_rev()){ + case USRP2_REV3: return "USRP2-REV3"; + case USRP2_REV4: return "USRP2-REV4"; + case USRP_N200: return "USRP-N200"; + case USRP_N210: return "USRP-N210"; + case USRP_NXXX: return "USRP-N???"; + } + UHD_THROW_INVALID_CODE_PATH(); + } private: //this lovely lady makes it all possible diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index d7e5df9f5..af3ed6c9f 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -25,6 +25,7 @@ #include <boost/utility.hpp> #include <boost/cstdint.hpp> #include <utility> +#include <string> #include "fw_common.h" #include "usrp2_regs.hpp" @@ -108,16 +109,27 @@ public: virtual void write_uart(boost::uint8_t dev, const std::string &buf) = 0; virtual std::string read_uart(boost::uint8_t dev) = 0; - - virtual boost::uint16_t get_hw_rev(void) = 0; - - virtual bool is_usrp2p(void) = 0; + + //! The list of possible revision types + enum rev_type { + USRP2_REV3 = 3, + USRP2_REV4 = 4, + USRP_N200 = 200, + USRP_N210 = 210, + USRP_NXXX = 0 + }; + + //! Get the revision type for this device + virtual rev_type get_rev(void) = 0; + + //! Get the canonical name for this device + virtual const std::string get_cname(void) = 0; /*! * Register map selected from USRP2/USRP2+. */ usrp2_regs_t regs; - + //motherboard eeprom map structure uhd::usrp::mboard_eeprom_t mb_eeprom; }; diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp index 5853e91e5..b24082edb 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.cpp +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -16,17 +16,19 @@ // #include "usrp2_regs.hpp" +#include "usrp2_iface.hpp" int sr_addr(int misc_output_base, int sr) { return misc_output_base + 4 * sr; } -usrp2_regs_t usrp2_get_regs(boost::uint16_t hw_rev) { +usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) { + //how about you just make this dependent on hw_rev instead of doing the init before main, and give up the const globals, since the application won't ever need both. - const int misc_output_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_MISC_OUTPUT_BASE : USRP2_MISC_OUTPUT_BASE, - gpio_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_GPIO_BASE : USRP2_GPIO_BASE, - atr_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_ATR_BASE : USRP2_ATR_BASE, - bp_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_BP_STATUS_BASE : USRP2_BP_STATUS_BASE; + const int misc_output_base = (use_n2xx_map) ? USRP2P_MISC_OUTPUT_BASE : USRP2_MISC_OUTPUT_BASE, + gpio_base = (use_n2xx_map) ? USRP2P_GPIO_BASE : USRP2_GPIO_BASE, + atr_base = (use_n2xx_map) ? USRP2P_ATR_BASE : USRP2_ATR_BASE, + bp_base = (use_n2xx_map) ? USRP2P_BP_STATUS_BASE : USRP2_BP_STATUS_BASE; usrp2_regs_t x; x.sr_misc = 0; diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index d84106f36..1081ff159 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -20,12 +20,6 @@ #include <boost/cstdint.hpp> -enum usrp2_rev_nums { - USRP2_REV3 = 0x0003, - USRP2_REV4 = 0x0004, - N2XX = 0x0A00 -}; - #define USRP2_MISC_OUTPUT_BASE 0xD400 #define USRP2_GPIO_BASE 0xC800 #define USRP2_ATR_BASE 0xE400 @@ -107,7 +101,7 @@ typedef struct { extern const usrp2_regs_t usrp2_regs; //the register definitions, set in usrp2_regs.cpp and usrp2p_regs.cpp -usrp2_regs_t usrp2_get_regs(boost::uint16_t hw_rev); +usrp2_regs_t usrp2_get_regs(bool); //////////////////////////////////////////////////// // Settings Bus, Slave #7, Not Byte Addressable! |