summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/README2
-rw-r--r--host/lib/usrp/README12
-rw-r--r--host/lib/usrp/usrp2/clock_ctrl.cpp2
-rw-r--r--host/lib/usrp/usrp2/codec_ctrl.cpp85
-rw-r--r--host/lib/usrp/usrp2/codec_impl.cpp26
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp19
-rw-r--r--host/lib/usrp/usrp2/usrp2_clk_regs.hpp31
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp42
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.hpp22
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.cpp12
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.hpp8
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!