aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/usrp/b200/b200_iface.hpp45
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp84
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp2
3 files changed, 84 insertions, 47 deletions
diff --git a/host/lib/usrp/b200/b200_iface.hpp b/host/lib/usrp/b200/b200_iface.hpp
index 83adfdd64..1d123439a 100644
--- a/host/lib/usrp/b200/b200_iface.hpp
+++ b/host/lib/usrp/b200/b200_iface.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2012-2013,2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -21,19 +21,48 @@
#include <stdint.h>
#include <uhd/transport/usb_control.hpp>
#include <uhd/types/serial.hpp> //i2c iface
+#include <uhd/types/dict.hpp>
+#include <boost/assign/list_of.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include "ad9361_ctrl.hpp"
-const static boost::uint16_t B200_VENDOR_ID = 0x2500;
-const static boost::uint16_t B200_PRODUCT_ID = 0x0020;
-const static boost::uint16_t FX3_VID = 0x04b4;
-const static boost::uint16_t FX3_DEFAULT_PID = 0x00f3;
-const static boost::uint16_t FX3_REENUM_PID = 0x00f0;
+enum b200_type_t {
+ B200,
+ B210
+};
+
+const static boost::uint16_t B200_VENDOR_ID = 0x2500;
+const static boost::uint16_t B200_VENDOR_NI_ID = 0x3923;
+const static boost::uint16_t B200_PRODUCT_ID = 0x0020;
+const static boost::uint16_t B200_PRODUCT_NI_ID = 0x7813;
+const static boost::uint16_t B210_PRODUCT_NI_ID = 0x7814;
+const static boost::uint16_t FX3_VID = 0x04b4;
+const static boost::uint16_t FX3_DEFAULT_PID = 0x00f3;
+const static boost::uint16_t FX3_REENUM_PID = 0x00f0;
static const std::string B200_FW_FILE_NAME = "usrp_b200_fw.hex";
-static const std::string B200_FPGA_FILE_NAME = "usrp_b200_fpga.bin";
-static const std::string B210_FPGA_FILE_NAME = "usrp_b210_fpga.bin";
+
+//! Map the product ID (in the EEPROM) to a device type
+static const uhd::dict<boost::uint16_t, b200_type_t> B2X0_PRODUCT_ID = boost::assign::map_list_of
+ (0x0001, B200)
+ (0x7737, B200)
+ (B200_PRODUCT_NI_ID, B200)
+ (0x0002, B210)
+ (0x7738, B210)
+ (B210_PRODUCT_NI_ID, B210)
+;
+
+static const uhd::dict<b200_type_t, std::string> B2X0_STR_NAMES = boost::assign::map_list_of
+ (B200, "B200")
+ (B210, "B210")
+;
+
+static const uhd::dict<b200_type_t, std::string> B2X0_FPGA_FILE_NAME = boost::assign::map_list_of
+ (B200, "usrp_b200_fpga.bin")
+ (B210, "usrp_b210_fpga.bin")
+;
+
class UHD_API b200_iface: boost::noncopyable, public virtual uhd::i2c_iface {
public:
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index f55ae2a71..f4a124a32 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -73,6 +73,24 @@ public:
/***********************************************************************
* Discovery
**********************************************************************/
+//! Look up the type of B-Series device we're currently running.
+// If the product ID stored in mb_eeprom is invalid, throws a
+// uhd::runtime_error.
+static b200_type_t get_b200_type(const mboard_eeprom_t &mb_eeprom)
+{
+ if (mb_eeprom["product"].empty()) {
+ throw uhd::runtime_error("B200: Missing product ID on EEPROM.");
+ }
+ boost::uint16_t product_id = boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]);
+ if (not B2X0_PRODUCT_ID.has_key(product_id)) {
+ throw uhd::runtime_error(str(
+ boost::format("B200 unknown product code: 0x%04x")
+ % product_id
+ ));
+ }
+ return B2X0_PRODUCT_ID[product_id];
+}
+
static device_addrs_t b200_find(const device_addr_t &hint)
{
device_addrs_t b200_addrs;
@@ -148,20 +166,14 @@ static device_addrs_t b200_find(const device_addr_t &hint)
new_addr["type"] = "b200";
new_addr["name"] = mb_eeprom["name"];
new_addr["serial"] = handle->get_serial();
- if (not mb_eeprom["product"].empty())
- {
- switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]))
- {
- case 0x0001:
- case 0x7737:
- new_addr["product"] = "B200";
- break;
- case 0x7738:
- case 0x0002:
- new_addr["product"] = "B210";
- break;
- default: UHD_MSG(error) << "B200 unknown product code: " << mb_eeprom["product"] << std::endl;
- }
+ try {
+ // Turn the 16-Bit product ID into a string representation
+ new_addr["product"] = B2X0_STR_NAMES[get_b200_type(mb_eeprom)];
+ } catch (const uhd::runtime_error &e) {
+ // No problem if this fails -- this is just device discovery, after all.
+ UHD_MSG(error) << e.what() << std::endl;
+ // Skip this loop.
+ continue;
}
//this is a found b200 when the hint serial and name match or blank
if (
@@ -234,39 +246,30 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
.subscribe(boost::bind(&b200_impl::set_mb_eeprom, this, _1));
////////////////////////////////////////////////////////////////////
- // Load the FPGA image, then reset GPIF
+ // Identify the device type
////////////////////////////////////////////////////////////////////
std::string default_file_name;
- std::string product_name = "B200?";
- enum {UNKNOWN,B200,B210} product = UNKNOWN;
- if (not mb_eeprom["product"].empty())
- {
- switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]))
- {
- case 0x0001:
- case 0x7737:
- product_name = "B200";
- default_file_name = B200_FPGA_FILE_NAME;
- product = B200;
- break;
- case 0x7738:
- case 0x0002:
- product_name = "B210";
- default_file_name = B210_FPGA_FILE_NAME;
- product = B210;
- break;
- default: UHD_MSG(error) << "B200 unknown product code: " << mb_eeprom["product"] << std::endl;
+ std::string product_name;
+ try {
+ // This will throw if the product ID is invalid:
+ _b200_type = get_b200_type(mb_eeprom);
+ default_file_name = B2X0_FPGA_FILE_NAME.get(_b200_type);
+ product_name = B2X0_STR_NAMES.get(_b200_type);
+ } catch (const uhd::runtime_error &e) {
+ // The only reason we may let this pass is if the user specified
+ // the FPGA file name:
+ if (not device_addr.has_key("fpga")) {
+ throw e;
}
- }
- if (default_file_name.empty())
- {
- UHD_ASSERT_THROW(device_addr.has_key("fpga"));
+ // In this case, we must provide a default product name:
+ product_name = "B200?";
+ _b200_type = B200;
}
//set up frontend mapping
_fe1 = 1;
_fe2 = 0;
- if (product == B200 and
+ if (_b200_type == B200 and
not mb_eeprom["revision"].empty() and
boost::lexical_cast<size_t>(mb_eeprom["revision"]) >= 5)
{
@@ -274,6 +277,9 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
_fe2 = 1;
}
+ ////////////////////////////////////////////////////////////////////
+ // Load the FPGA image, then reset GPIF
+ ////////////////////////////////////////////////////////////////////
//extract the FPGA path for the B200
std::string b200_fpga_image = find_image_path(
device_addr.has_key("fpga")? device_addr["fpga"] : default_file_name
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index fd94d36ab..b580ff260 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -101,6 +101,8 @@ public:
void check_streamer_args(const uhd::stream_args_t &args, double tick_rate, const char* direction = NULL);
private:
+ b200_type_t _b200_type;
+
//controllers
b200_iface::sptr _iface;
radio_ctrl_core_3000::sptr _local_ctrl;