summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-11-05 19:55:19 -0700
committerJosh Blum <josh@joshknows.com>2010-11-05 19:55:19 -0700
commit13d735c65e40af23f978f96b5b418712976ab5f2 (patch)
tree020be6fd66df9a9d8ed9f328fa7c50713b6daa71 /host/lib
parent9d50dea1c2f884835b606ccaa1444e5de96926cb (diff)
parentf740a51cc0737b07fd4906f8ca80683ec6e87faa (diff)
downloaduhd-13d735c65e40af23f978f96b5b418712976ab5f2.tar.gz
uhd-13d735c65e40af23f978f96b5b418712976ab5f2.tar.bz2
uhd-13d735c65e40af23f978f96b5b418712976ab5f2.zip
Merge branch 'mb_eeprom'
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/types.cpp13
-rw-r--r--host/lib/usrp/CMakeLists.txt1
-rw-r--r--host/lib/usrp/mboard_eeprom.cpp194
-rw-r--r--host/lib/usrp/usrp1/CMakeLists.txt2
-rw-r--r--host/lib/usrp/usrp1/mboard_impl.cpp35
-rw-r--r--host/lib/usrp/usrp1/usrp1_iface.cpp4
-rw-r--r--host/lib/usrp/usrp1/usrp1_iface.hpp3
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp13
-rw-r--r--host/lib/usrp/usrp2/clock_ctrl.cpp5
-rw-r--r--host/lib/usrp/usrp2/fw_common.h8
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp75
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp3
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.hpp4
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp45
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp16
16 files changed, 312 insertions, 117 deletions
diff --git a/host/lib/types.cpp b/host/lib/types.cpp
index 4188568aa..e5e6a2512 100644
--- a/host/lib/types.cpp
+++ b/host/lib/types.cpp
@@ -250,22 +250,19 @@ mac_addr_t mac_addr_t::from_bytes(const byte_vector_t &bytes){
mac_addr_t mac_addr_t::from_string(const std::string &mac_addr_str){
- byte_vector_t bytes = boost::assign::list_of
- (0x00)(0x50)(0xC2)(0x85)(0x30)(0x00); // Matt's IAB
+ byte_vector_t bytes;
try{
- //only allow patterns of xx:xx or xx:xx:xx:xx:xx:xx
- //the IAB above will fill in for the shorter pattern
- if (mac_addr_str.size() != 5 and mac_addr_str.size() != 17)
- throw std::runtime_error("expected exactly 5 or 17 characters");
+ if (mac_addr_str.size() != 17){
+ throw std::runtime_error("expected exactly 17 characters");
+ }
//split the mac addr hex string at the colons
- size_t i = 0;
BOOST_FOREACH(const std::string &hex_str, std::split_string(mac_addr_str, ":")){
int hex_num;
std::istringstream iss(hex_str);
iss >> std::hex >> hex_num;
- bytes[i++] = boost::uint8_t(hex_num);
+ bytes.push_back(boost::uint8_t(hex_num));
}
}
diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt
index eeb181e0b..3d832c356 100644
--- a/host/lib/usrp/CMakeLists.txt
+++ b/host/lib/usrp/CMakeLists.txt
@@ -23,6 +23,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_SOURCE_DIR}/lib/usrp/dboard_id.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/dboard_manager.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/dsp_utils.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/mboard_eeprom.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/misc_utils.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/multi_usrp.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/single_usrp.cpp
diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp
new file mode 100644
index 000000000..076d0b279
--- /dev/null
+++ b/host/lib/usrp/mboard_eeprom.cpp
@@ -0,0 +1,194 @@
+//
+// Copyright 2010 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
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/usrp/mboard_eeprom.hpp>
+#include <uhd/types/mac_addr.hpp>
+#include <uhd/utils/algorithm.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+/***********************************************************************
+ * Constants
+ **********************************************************************/
+static const size_t SERIAL_LEN = 9;
+static const size_t NAME_MAX_LEN = 32 - SERIAL_LEN;
+
+/***********************************************************************
+ * Utility functions
+ **********************************************************************/
+
+//! create a string from a byte vector, return empty if invalid ascii
+static const std::string bytes_to_string(const byte_vector_t &bytes){
+ std::string out;
+ BOOST_FOREACH(boost::uint8_t byte, bytes){
+ if (byte < 32 or byte > 127) return out;
+ out += byte;
+ }
+ return out;
+}
+
+//! create a byte vector from a string, null terminate unless max length
+static const byte_vector_t string_to_bytes(const std::string &string, size_t max_length){
+ byte_vector_t bytes;
+ for (size_t i = 0; i < std::min(string.size(), max_length); i++){
+ bytes.push_back(string[i]);
+ }
+ if (bytes.size() < max_length - 1) bytes.push_back('\0');
+ return bytes;
+}
+
+/***********************************************************************
+ * Implementation of NXXX load/store
+ **********************************************************************/
+static const boost::uint8_t NXXX_EEPROM_ADDR = 0x50;
+
+static const uhd::dict<std::string, boost::uint8_t> USRP_NXXX_OFFSETS = boost::assign::map_list_of
+ ("rev-lsb-msb", 0x00)
+ ("mac-addr", 0x02)
+ ("ip-addr", 0x08)
+ //leave space here for other addresses (perhaps)
+ ("serial", 0x18)
+ ("name", 0x18 + SERIAL_LEN)
+;
+
+static void load_nxxx(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
+ //extract the revision number
+ byte_vector_t rev_lsb_msb = iface.read_eeprom(NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["rev-lsb-msb"], 2);
+ boost::uint16_t rev = (boost::uint16_t(rev_lsb_msb.at(0)) << 0) | (boost::uint16_t(rev_lsb_msb.at(1)) << 8);
+ mb_eeprom["rev"] = boost::lexical_cast<std::string>(rev);
+
+ //extract the addresses
+ mb_eeprom["mac-addr"] = mac_addr_t::from_bytes(iface.read_eeprom(
+ NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["mac-addr"], 6
+ )).to_string();
+
+ boost::asio::ip::address_v4::bytes_type ip_addr_bytes;
+ std::copy(iface.read_eeprom(NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["ip-addr"], 4), ip_addr_bytes);
+ mb_eeprom["ip-addr"] = boost::asio::ip::address_v4(ip_addr_bytes).to_string();
+
+ //extract the serial
+ mb_eeprom["serial"] = bytes_to_string(iface.read_eeprom(
+ NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["serial"], SERIAL_LEN
+ ));
+
+ //extract the name
+ mb_eeprom["name"] = bytes_to_string(iface.read_eeprom(
+ NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["name"], NAME_MAX_LEN
+ ));
+
+ //empty serial correction: use the mac address
+ if (mb_eeprom["serial"].empty()) mb_eeprom["serial"] = mb_eeprom["mac-addr"];
+}
+
+static void store_nxxx(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
+ //parse the revision number
+ if (mb_eeprom.has_key("rev")){
+ boost::uint16_t rev = boost::lexical_cast<boost::uint16_t>(mb_eeprom["rev"]);
+ byte_vector_t rev_lsb_msb = boost::assign::list_of
+ (boost::uint8_t(rev >> 0))
+ (boost::uint8_t(rev >> 8))
+ ;
+ iface.write_eeprom(NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["rev-lsb-msb"], rev_lsb_msb);
+ }
+
+ //store the addresses
+ if (mb_eeprom.has_key("mac-addr")) iface.write_eeprom(
+ NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["mac-addr"],
+ mac_addr_t::from_string(mb_eeprom["mac-addr"]).to_bytes()
+ );
+
+ if (mb_eeprom.has_key("ip-addr")){
+ byte_vector_t ip_addr_bytes(4);
+ std::copy(boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr"]).to_bytes(), ip_addr_bytes);
+ iface.write_eeprom(NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["ip-addr"], ip_addr_bytes);
+ }
+
+ //store the serial
+ if (mb_eeprom.has_key("serial")) iface.write_eeprom(
+ NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["serial"],
+ string_to_bytes(mb_eeprom["serial"], SERIAL_LEN)
+ );
+
+ //store the name
+ if (mb_eeprom.has_key("name")) iface.write_eeprom(
+ NXXX_EEPROM_ADDR, USRP_NXXX_OFFSETS["name"],
+ string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)
+ );
+}
+
+/***********************************************************************
+ * Implementation of B1XX load/store
+ **********************************************************************/
+static const boost::uint8_t B1XX_EEPROM_ADDR = 0x50;
+static const size_t B1XXX_SERIAL_LEN = 8;
+
+static const uhd::dict<std::string, boost::uint8_t> USRP_B1XX_OFFSETS = boost::assign::map_list_of
+ ("serial", 0xf8)
+ ("name", 0xf8 - NAME_MAX_LEN)
+;
+
+static void load_b1xx(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
+ //extract the serial
+ mb_eeprom["serial"] = bytes_to_string(iface.read_eeprom(
+ B1XX_EEPROM_ADDR, USRP_B1XX_OFFSETS["serial"], B1XXX_SERIAL_LEN
+ ));
+
+ //extract the name
+ mb_eeprom["name"] = bytes_to_string(iface.read_eeprom(
+ B1XX_EEPROM_ADDR, USRP_B1XX_OFFSETS["name"], NAME_MAX_LEN
+ ));
+}
+
+static void store_b1xx(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
+ //store the serial
+ if (mb_eeprom.has_key("serial")) iface.write_eeprom(
+ B1XX_EEPROM_ADDR, USRP_B1XX_OFFSETS["serial"],
+ string_to_bytes(mb_eeprom["serial"], B1XXX_SERIAL_LEN)
+ );
+
+ //store the name
+ if (mb_eeprom.has_key("name")) iface.write_eeprom(
+ B1XX_EEPROM_ADDR, USRP_B1XX_OFFSETS["name"],
+ string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)
+ );
+}
+
+/***********************************************************************
+ * Implementation of mboard eeprom
+ **********************************************************************/
+mboard_eeprom_t::mboard_eeprom_t(void){
+ /* NOP */
+}
+
+mboard_eeprom_t::mboard_eeprom_t(i2c_iface &iface, map_type map){
+ switch(map){
+ case MAP_NXXX: load_nxxx(*this, iface); break;
+ case MAP_B1XX: load_b1xx(*this, iface); break;
+ }
+}
+
+void mboard_eeprom_t::commit(i2c_iface &iface, map_type map){
+ switch(map){
+ case MAP_NXXX: store_nxxx(*this, iface); break;
+ case MAP_B1XX: store_b1xx(*this, iface); break;
+ }
+}
diff --git a/host/lib/usrp/usrp1/CMakeLists.txt b/host/lib/usrp/usrp1/CMakeLists.txt
index 67487f99e..022015231 100644
--- a/host/lib/usrp/usrp1/CMakeLists.txt
+++ b/host/lib/usrp/usrp1/CMakeLists.txt
@@ -40,7 +40,7 @@ ENDIF(ENABLE_USRP1 AND NOT HAVE_USB_SUPPORT)
IF(ENABLE_USRP1)
MESSAGE(STATUS " Building USRP1 support.")
- INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../firmware/fx2/include)
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../firmware/fx2/common)
LIBUHD_APPEND_SOURCES(
${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/clock_ctrl.cpp
diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp
index 669b20efa..c1f0f1d38 100644
--- a/host/lib/usrp/usrp1/mboard_impl.cpp
+++ b/host/lib/usrp/usrp1/mboard_impl.cpp
@@ -262,24 +262,10 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val)
{
named_prop_t key = named_prop_t::extract(key_);
- if(key_.type() == typeid(std::string)) {
- if(key.as<std::string>() == "serial") {
- uhd::byte_vector_t buf;
- buf.insert(buf.begin(), 248);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
- _iface->write_i2c(I2C_DEV_EEPROM, buf);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
- buf = _iface->read_i2c(I2C_DEV_EEPROM, 8);
- val = std::string(buf.begin(), buf.end());
- }
-
- return;
- }
-
//handle the get request conditioned on the key
switch(key.as<mboard_prop_t>()){
case MBOARD_PROP_NAME:
- val = std::string("usrp1 mboard - " + (*_mboard_proxy)[std::string("serial")].as<std::string>());
+ val = std::string("usrp1 mboard - " + _iface->mb_eeprom["serial"]);
return;
case MBOARD_PROP_OTHERS:
@@ -336,6 +322,10 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val)
val = _tx_subdev_spec;
return;
+ case MBOARD_PROP_EEPROM_MAP:
+ val = _iface->mb_eeprom;
+ return;
+
default: UHD_THROW_PROP_GET_ERROR();
}
}
@@ -351,14 +341,6 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
std::cout << "USRP1 EEPROM image: " << usrp1_eeprom_image << std::endl;
_ctrl_transport->usrp_load_eeprom(val.as<std::string>());
}
-
- if(key.as<std::string>() == "serial") {
- std::string sernum = val.as<std::string>();
- uhd::byte_vector_t buf(sernum.begin(), sernum.end());
- buf.insert(buf.begin(), 248);
- _iface->write_i2c(I2C_DEV_EEPROM, buf);
- }
-
return;
}
@@ -395,6 +377,13 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
_iface->poke32(FR_TX_MUX, calc_tx_mux(_tx_subdev_spec, _mboard_proxy->get_link()));
return;
+ case MBOARD_PROP_EEPROM_MAP:
+ // Step1: commit the map, writing only those values set.
+ // Step2: readback the entire eeprom map into the iface.
+ val.as<mboard_eeprom_t>().commit(*_iface, mboard_eeprom_t::MAP_B1XX);
+ _iface->mb_eeprom = mboard_eeprom_t(*_iface, mboard_eeprom_t::MAP_B1XX);
+ return;
+
default: UHD_THROW_PROP_SET_ERROR();
}
}
diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp
index 64ced2905..691c51fe8 100644
--- a/host/lib/usrp/usrp1/usrp1_iface.cpp
+++ b/host/lib/usrp/usrp1/usrp1_iface.cpp
@@ -25,6 +25,7 @@
#include <iomanip>
using namespace uhd;
+using namespace uhd::usrp;
using namespace uhd::transport;
static const bool iface_debug = false;
@@ -36,7 +37,8 @@ public:
******************************************************************/
usrp1_iface_impl(usrp_ctrl::sptr ctrl_transport)
{
- _ctrl_transport = ctrl_transport;
+ _ctrl_transport = ctrl_transport;
+ mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_B1XX);
}
~usrp1_iface_impl(void)
diff --git a/host/lib/usrp/usrp1/usrp1_iface.hpp b/host/lib/usrp/usrp1/usrp1_iface.hpp
index 3f608584a..34a2330b5 100644
--- a/host/lib/usrp/usrp1/usrp1_iface.hpp
+++ b/host/lib/usrp/usrp1/usrp1_iface.hpp
@@ -18,6 +18,7 @@
#ifndef INCLUDED_USRP1_IFACE_HPP
#define INCLUDED_USRP1_IFACE_HPP
+#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/types/serial.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
@@ -81,6 +82,8 @@ public:
boost::uint16_t index,
unsigned char* buff,
boost::uint16_t length) = 0;
+
+ uhd::usrp::mboard_eeprom_t mb_eeprom;
};
#endif /* INCLUDED_USRP1_IFACE_HPP */
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index bc478c7fb..6016b0979 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -56,6 +56,10 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
//return an empty list of addresses when type is set to non-usrp1
if (hint.has_key("type") and hint["type"] != "usrp1") return usrp1_addrs;
+ //Return an empty list of addresses when an address is specified,
+ //since an address is intended for a different, non-USB, device.
+ if (hint.has_key("addr")) return usrp1_addrs;
+
//extract the firmware path for the USRP1
std::string usrp1_fw_image;
try{
@@ -89,11 +93,16 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
pid = USRP1_PRODUCT_ID;
BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
+ usrp1_iface::sptr iface = usrp1_iface::make(usrp_ctrl::make(usb_control::make(handle)));
device_addr_t new_addr;
new_addr["type"] = "usrp1";
+ new_addr["name"] = iface->mb_eeprom["name"];
new_addr["serial"] = handle->get_serial();
- //this is a found usrp1 when a hint serial is not specified or it matches
- if (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]){
+ //this is a found usrp1 when the hint serial and name match or blank
+ if (
+ (not hint.has_key("name") or hint["name"] == new_addr["name"]) and
+ (not hint.has_key("serial") or hint["serial"] == new_addr["serial"])
+ ){
usrp1_addrs.push_back(new_addr);
}
}
diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp
index 1e1c9b7b8..232f3b32a 100644
--- a/host/lib/usrp/usrp2/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp2/clock_ctrl.cpp
@@ -20,6 +20,7 @@
#include "usrp2_regs.hpp" //spi slave constants
#include <uhd/utils/assert.hpp>
#include <boost/cstdint.hpp>
+#include <boost/lexical_cast.hpp>
#include <iostream>
using namespace uhd;
@@ -83,8 +84,8 @@ public:
}
void enable_mimo_clock_out(bool enb){
- //FIXME TODO put this revision read in a common place
- boost::uint8_t rev_hi = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV_MSB, 1).at(0);
+ boost::uint16_t rev = boost::lexical_cast<boost::uint16_t>(_iface->mb_eeprom["rev"]);
+ boost::uint8_t rev_hi = boost::uint8_t(rev >> 8);
//calculate the low and high dividers
size_t divider = size_t(this->get_master_clock_rate()/10e6);
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index e812e1221..4ff31ddfd 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -52,14 +52,6 @@ extern "C" {
#define USRP2_I2C_ADDR_TX_DB (USRP2_I2C_DEV_EEPROM | 0x4)
#define USRP2_I2C_ADDR_RX_DB (USRP2_I2C_DEV_EEPROM | 0x5)
-////////////////////////////////////////////////////////////////////////
-// EEPROM Layout
-////////////////////////////////////////////////////////////////////////
-#define USRP2_EE_MBOARD_REV_LSB 0x00 //1 byte
-#define USRP2_EE_MBOARD_REV_MSB 0x01 //1 byte
-#define USRP2_EE_MBOARD_MAC_ADDR 0x02 //6 bytes
-#define USRP2_EE_MBOARD_IP_ADDR 0x0C //uint32, big-endian
-
typedef enum{
USRP2_CTRL_ID_HUH_WHAT = ' ',
//USRP2_CTRL_ID_FOR_SURE, //TODO error condition enums
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index bbe9c273f..83b70bddc 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -236,6 +236,11 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{
return bpp/_rx_otw_type.get_sample_size();
}
+static void handle_overflow(std::vector<usrp2_mboard_impl::sptr> &mboards, size_t chan){
+ std::cerr << "O" << std::flush;
+ mboards.at(chan/mboards.size())->handle_overflow();
+}
+
size_t usrp2_impl::recv(
const std::vector<void *> &buffs, size_t num_samps,
rx_metadata_t &metadata, const io_type_t &io_type,
@@ -248,6 +253,7 @@ size_t usrp2_impl::recv(
io_type, _rx_otw_type, //input and output types to convert
_mboards.front()->get_master_clock_freq(), //master clock tick rate
uhd::transport::vrt::if_hdr_unpack_be,
- boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout)
+ boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout),
+ boost::bind(&handle_overflow, _mboards, _1)
);
}
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index a0e6adfad..df98ba275 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -22,11 +22,7 @@
#include <uhd/usrp/mboard_props.hpp>
#include <uhd/utils/assert.hpp>
#include <uhd/utils/algorithm.hpp>
-#include <uhd/types/mac_addr.hpp>
-#include <uhd/types/dict.hpp>
#include <boost/bind.hpp>
-#include <boost/assign/list_of.hpp>
-#include <boost/asio/ip/address_v4.hpp>
#include <iostream>
using namespace uhd;
@@ -41,15 +37,9 @@ usrp2_mboard_impl::usrp2_mboard_impl(
size_t recv_frame_size
):
_index(index),
- _recv_frame_size(recv_frame_size)
+ _recv_frame_size(recv_frame_size),
+ _iface(usrp2_iface::make(ctrl_transport))
{
- //make a new interface for usrp2 stuff
- _iface = usrp2_iface::make(ctrl_transport);
-
- //extract the mboard rev numbers
- _rev_lo = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV_LSB, 1).at(0);
- _rev_hi = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV_MSB, 1).at(0);
-
//contruct the interfaces to mboard perifs
_clock_ctrl = usrp2_clock_ctrl::make(_iface);
_codec_ctrl = usrp2_codec_ctrl::make(_iface);
@@ -176,7 +166,15 @@ void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){
_iface->poke32(U2_REG_TIME64_SECS, boost::uint32_t(time_spec.get_full_secs()));
}
+void usrp2_mboard_impl::handle_overflow(void){
+ _iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1);
+ if (_continuous_streaming){ //re-issue the stream command if already continuous
+ this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
+ }
+}
+
void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
+ _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS;
_iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, dsp_type1::calc_stream_cmd_word(
stream_cmd, _recv_frame_size
));
@@ -192,35 +190,14 @@ static const std::string dboard_name = "0";
void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
named_prop_t key = named_prop_t::extract(key_);
- //handle the other props
- if (key_.type() == typeid(std::string)){
- if (key.as<std::string>() == "mac-addr"){
- byte_vector_t bytes = _iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, 6);
- val = mac_addr_t::from_bytes(bytes).to_string();
- return;
- }
-
- if (key.as<std::string>() == "ip-addr"){
- boost::asio::ip::address_v4::bytes_type bytes;
- std::copy(_iface->read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, 4), bytes);
- val = boost::asio::ip::address_v4(bytes).to_string();
- return;
- }
- }
-
//handle the get request conditioned on the key
switch(key.as<mboard_prop_t>()){
case MBOARD_PROP_NAME:
- val = str(boost::format("usrp2 mboard%d - rev %d:%d") % _index % _rev_hi % _rev_lo);
+ val = str(boost::format("usrp2 mboard%d - rev %s") % _index % _iface->mb_eeprom["rev"]);
return;
- case MBOARD_PROP_OTHERS:{
- prop_names_t others = boost::assign::list_of
- ("mac-addr")
- ("ip-addr")
- ;
- val = others;
- }
+ case MBOARD_PROP_OTHERS:
+ val = prop_names_t();
return;
case MBOARD_PROP_RX_DBOARD:
@@ -281,6 +258,10 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
val = _tx_subdev_spec;
return;
+ case MBOARD_PROP_EEPROM_MAP:
+ val = _iface->mb_eeprom;
+ return;
+
default: UHD_THROW_PROP_GET_ERROR();
}
}
@@ -289,21 +270,6 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
* MBoard Set Properties
**********************************************************************/
void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){
- //handle the other props
- if (key.type() == typeid(std::string)){
- if (key.as<std::string>() == "mac-addr"){
- byte_vector_t bytes = mac_addr_t::from_string(val.as<std::string>()).to_bytes();
- _iface->write_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, bytes);
- return;
- }
-
- if (key.as<std::string>() == "ip-addr"){
- byte_vector_t bytes(4);
- std::copy(boost::asio::ip::address_v4::from_string(val.as<std::string>()).to_bytes(), bytes);
- _iface->write_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, bytes);
- return;
- }
- }
//handle the get request conditioned on the key
switch(key.as<mboard_prop_t>()){
@@ -347,6 +313,13 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){
));
return;
+ case MBOARD_PROP_EEPROM_MAP:
+ // Step1: commit the map, writing only those values set.
+ // Step2: readback the entire eeprom map into the iface.
+ val.as<mboard_eeprom_t>().commit(*_iface, mboard_eeprom_t::MAP_NXXX);
+ _iface->mb_eeprom = mboard_eeprom_t(*_iface, mboard_eeprom_t::MAP_NXXX);
+ return;
+
default: UHD_THROW_PROP_SET_ERROR();
}
}
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index 2d450bfc6..eb2685efa 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -28,6 +28,7 @@
#include <algorithm>
using namespace uhd;
+using namespace uhd::usrp;
using namespace uhd::transport;
/*!
@@ -58,6 +59,8 @@ public:
"The fpga build is not compatible with the host code build."
) % int(USRP2_FPGA_COMPAT_NUM) % fpga_compat_num));
}
+
+ mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_NXXX);
}
~usrp2_iface_impl(void){
diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp
index 12fd4730a..bf36cbf6e 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.hpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.hpp
@@ -20,6 +20,7 @@
#include <uhd/transport/udp_simple.hpp>
#include <uhd/types/serial.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/cstdint.hpp>
@@ -102,6 +103,9 @@ public:
size_t num_bits,
bool readback
) = 0;
+
+ //motherboard eeprom map structure
+ uhd::usrp::mboard_eeprom_t mb_eeprom;
};
#endif /* INCLUDED_USRP2_IFACE_HPP */
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index a680708ad..5f549c4fd 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -21,6 +21,7 @@
#include <uhd/usrp/device_props.hpp>
#include <uhd/utils/assert.hpp>
#include <uhd/utils/static.hpp>
+#include <uhd/utils/warning.hpp>
#include <uhd/utils/algorithm.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
@@ -61,7 +62,7 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){
if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue;
//create a new hint with this broadcast address
- device_addr_t new_hint;
+ device_addr_t new_hint = hint;
new_hint["addr"] = if_addrs.bcast;
//call discover with the new hint and append results
@@ -101,19 +102,37 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){
while(true){
size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem), DISCOVERY_TIMEOUT_MS);
//std::cout << len << "\n";
- if (len > offsetof(usrp2_ctrl_data_t, data)){
- //handle the received data
- switch(ntohl(ctrl_data_in->id)){
- case USRP2_CTRL_ID_WAZZUP_DUDE:
- //make a boost asio ipv4 with the raw addr in host byte order
- boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in->data.ip_addr));
- device_addr_t new_addr;
- new_addr["type"] = "usrp2";
- new_addr["addr"] = ip_addr.to_string();
- usrp2_addrs.push_back(new_addr);
- //dont break here, it will exit the while loop
- //just continue on to the next loop iteration
+ if (len > offsetof(usrp2_ctrl_data_t, data) and ntohl(ctrl_data_in->id) == USRP2_CTRL_ID_WAZZUP_DUDE){
+ //make a boost asio ipv4 with the raw addr in host byte order
+ boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in->data.ip_addr));
+ device_addr_t new_addr;
+ new_addr["type"] = "usrp2";
+ new_addr["addr"] = ip_addr.to_string();
+ //Attempt to read the name from the EEPROM and perform filtering.
+ //This operation can throw due to COMPAT mismatch. That is OK.
+ //We will allow the device to be found and the COMPAT mismatch
+ //will be thrown as an exception in the factory function.
+ try{
+ mboard_eeprom_t mb_eeprom = usrp2_iface::make(
+ udp_simple::make_connected(new_addr["addr"], num2str(USRP2_UDP_CTRL_PORT))
+ )->mb_eeprom;
+ new_addr["name"] = mb_eeprom["name"];
+ new_addr["serial"] = mb_eeprom["serial"];
+ if (
+ (not hint.has_key("name") or hint["name"] == new_addr["name"]) and
+ (not hint.has_key("serial") or hint["serial"] == new_addr["serial"])
+ ){
+ usrp2_addrs.push_back(new_addr);
+ }
}
+ catch(const std::exception &e){
+ uhd::warning::post(
+ std::string("Ignoring discovered device\n")
+ + e.what()
+ );
+ }
+ //dont break here, it will exit the while loop
+ //just continue on to the next loop iteration
}
if (len == 0) break; //timeout
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 558726a2b..71f52878c 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -32,7 +32,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <uhd/transport/vrt_if_packet.hpp>
-#include <uhd/transport/udp_simple.hpp> //mtu
+#include <uhd/transport/udp_simple.hpp>
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/usrp/subdev_spec.hpp>
@@ -92,15 +92,12 @@ public:
return _clock_ctrl->get_master_clock_rate();
}
+ void handle_overflow(void);
+
private:
size_t _index;
- int _rev_hi, _rev_lo;
const size_t _recv_frame_size;
-
- //properties for this mboard
- void get(const wax::obj &, wax::obj &);
- void set(const wax::obj &, const wax::obj &);
- uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec;
+ bool _continuous_streaming;
//interfaces
usrp2_iface::sptr _iface;
@@ -108,6 +105,11 @@ private:
usrp2_codec_ctrl::sptr _codec_ctrl;
usrp2_serdes_ctrl::sptr _serdes_ctrl;
+ //properties for this mboard
+ void get(const wax::obj &, wax::obj &);
+ void set(const wax::obj &, const wax::obj &);
+ uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec;
+
//rx and tx dboard methods and objects
uhd::usrp::dboard_manager::sptr _dboard_manager;
uhd::usrp::dboard_iface::sptr _dboard_iface;