summaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
Diffstat (limited to 'host')
-rw-r--r--host/docs/CMakeLists.txt1
-rw-r--r--host/docs/identification.rst97
-rw-r--r--host/docs/index.rst1
-rw-r--r--host/docs/usrp1.rst30
-rw-r--r--host/docs/usrp2.rst17
-rw-r--r--host/include/uhd/usrp/CMakeLists.txt1
-rw-r--r--host/include/uhd/usrp/mboard_eeprom.hpp64
-rw-r--r--host/include/uhd/usrp/mboard_props.hpp3
-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
-rw-r--r--host/utils/CMakeLists.txt12
-rw-r--r--host/utils/uhd_usrp_probe.cpp8
-rw-r--r--host/utils/usrp1_serial_burner.cpp75
-rw-r--r--host/utils/usrp2_addr_burner.cpp91
-rw-r--r--host/utils/usrp_burn_db_eeprom.cpp6
-rw-r--r--host/utils/usrp_burn_mb_eeprom.cpp81
30 files changed, 583 insertions, 333 deletions
diff --git a/host/docs/CMakeLists.txt b/host/docs/CMakeLists.txt
index 65db3befc..4d3269543 100644
--- a/host/docs/CMakeLists.txt
+++ b/host/docs/CMakeLists.txt
@@ -20,6 +20,7 @@
########################################################################
SET(manual_sources
index.rst
+ identification.rst
build.rst
coding.rst
dboards.rst
diff --git a/host/docs/identification.rst b/host/docs/identification.rst
new file mode 100644
index 000000000..49d36ec1a
--- /dev/null
+++ b/host/docs/identification.rst
@@ -0,0 +1,97 @@
+========================================================================
+UHD - Device Identification Notes
+========================================================================
+
+.. contents:: Table of Contents
+
+------------------------------------------------------------------------
+Identifying USRPs
+------------------------------------------------------------------------
+Every device has several ways of identifying it on the host system:
+
+* **Serial:** A globally unique identifier.
+* **Address:** A unique identifier on a network.
+* **Name:** An optional user-set identifier.
+
+The address is only applicable for network-based devices.
+See the USRP2 application notes.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Device discovery via command line
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+A "find devices" utility application comes bundled with the UHD.
+The find devices application will search for all devices on the host system and print the results.
+
+::
+
+ uhd_find_devices
+
+Device address arguments can be supplied to narrow the scope of the search.
+
+::
+
+ uhd_find_devices --args="type=usrp1"
+
+ -- OR --
+
+ uhd_find_devices --args="serial=12345678"
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Device discovery through the API
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The device::find() API call searches for devices and returns a list of discovered devices.
+
+::
+
+ uhd::device_addr_t hint; //an empty hint discovers all devices
+ uhd::device_addrs_t dev_addrs = uhd::device::find(hint);
+
+The hint argument can be populated to narrow the scope of the search.
+
+::
+
+ uhd::device_addr_t hint;
+ hint["type"] = "usrp1";
+ uhd::device_addrs_t dev_addrs = uhd::device::find(hint);
+
+ -- OR --
+
+ uhd::device_addr_t hint;
+ hint["serial"] = "12345678";
+ uhd::device_addrs_t dev_addrs = uhd::device::find(hint);
+
+------------------------------------------------------------------------
+Naming a USRP
+------------------------------------------------------------------------
+For convenience purposes, users may assign a custom name to their USRPs.
+The USRP can then be identified via name, rather than a difficult to remember serial or address.
+
+A name has the following properties:
+
+* is composed of ASCII characters
+* is between 0 and 20 characters
+* is not required to be unique
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Set a custom name
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Run the following commands:
+::
+
+ cd <prefix>/share/uhd/utils
+ ./usrp_burn_mb_eeprom --args=<optional device args> --key=name --val=lab1_xcvr
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Discovery via name
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The keyword "name" can be used to narrow the scope of the search.
+Example with the find devices utility:
+::
+
+ uhd_find_devices --args="name=lab1_xcvr"
+
+ -- OR --
+
+ uhd_find_devices --args="type=usrp1, name=lab1_xcvr"
diff --git a/host/docs/index.rst b/host/docs/index.rst
index 7f8129e2d..9d6d14d0f 100644
--- a/host/docs/index.rst
+++ b/host/docs/index.rst
@@ -21,6 +21,7 @@ Building the UHD
Application Notes
^^^^^^^^^^^^^^^^^^^^^
* `General Application Notes <./general.html>`_
+* `Device Identification Notes <./identification.html>`_
* `Firmware and FPGA Image Notes <./images.html>`_
* `USRP1 Application Notes <./usrp1.html>`_
* `USRP2 Application Notes <./usrp2.html>`_
diff --git a/host/docs/usrp1.rst b/host/docs/usrp1.rst
index 3443fd871..be684e20e 100644
--- a/host/docs/usrp1.rst
+++ b/host/docs/usrp1.rst
@@ -4,36 +4,6 @@ UHD - USRP1 Application Notes
.. contents:: Table of Contents
-------------------------------------------------------------------------
-Addressing the device
-------------------------------------------------------------------------
-A USRP1 can be identified though its 8 digit serial number,
-designated by the "serial" key in the device address.
-
-The device address string representation for a USRP1 with serial 12345678:
-
-::
-
- serial=12345678
-
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Change the serial number
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The USRP1 serial number can be changed to any 8 byte string. Examples:
-
-::
-
- cd <prefix>/share/uhd/utils
- ./usrp1_serial_burner --new=87654321
-
- -- OR --
-
- ./usrp1_serial_burner --new=Beatrice
-
- -- OR --
-
- ./usrp1_serial_burner --old=12345678 --new=87654321
-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Specify a non-standard image
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst
index ada98000d..b617fcbf4 100644
--- a/host/docs/usrp2.rst
+++ b/host/docs/usrp2.rst
@@ -11,9 +11,14 @@ Load the images onto the SD card
Use the usrp2_card_burner.py with caution. If you specify the wrong device node,
you could overwrite your hard drive. Make sure that --dev= specifies the SD card.
-Use the *--list* option to get a list of possible raw devices.
-The list result will filter out disk partitions and devices too large to be the sd card.
-The list option has been implemented on Linux, Mac OS X, and Windows.
+**Warning!**
+It is possible to use 3rd party SD cards with the USRP2.
+However, certain types of SD cards will not interface with the CPLD:
+
+* Cards can be SDHC, which is not a supported interface.
+* Cards can have unexpected timing characteristics.
+
+For these reasons, we recommend that you use the SD card that was supplied with the USRP2.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use the card burner tool (unix)
@@ -28,6 +33,10 @@ Use the card burner tool (unix)
sudo ./usrp2_card_burner.py --dev=/dev/sd<XXX> --fpga=<path_to_fpga_image>
sudo ./usrp2_card_burner.py --dev=/dev/sd<XXX> --fw=<path_to_firmware_image>
+Use the *--list* option to get a list of possible raw devices.
+The list result will filter out disk partitions and devices too large to be the sd card.
+The list option has been implemented on Linux, Mac OS X, and Windows.
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use the card burner tool (windows)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -97,7 +106,7 @@ Run the following commands:
::
cd <prefix>/share/uhd/utils
- ./usrp_addr_burner --addr=192.168.10.2 --new-ip=192.168.10.3
+ ./usrp_burn_mb_eeprom --args=<optional device args> --key=ip-addr --val=192.168.10.3
**Method 2 (Linux Only):**
This method assumes that you do not know the IP address of your USRP2.
diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt
index abddf3951..cdf31df87 100644
--- a/host/include/uhd/usrp/CMakeLists.txt
+++ b/host/include/uhd/usrp/CMakeLists.txt
@@ -34,6 +34,7 @@ INSTALL(FILES
### utilities ###
dsp_utils.hpp
+ mboard_eeprom.hpp
misc_utils.hpp
subdev_spec.hpp
tune_helper.hpp
diff --git a/host/include/uhd/usrp/mboard_eeprom.hpp b/host/include/uhd/usrp/mboard_eeprom.hpp
new file mode 100644
index 000000000..f44275aad
--- /dev/null
+++ b/host/include/uhd/usrp/mboard_eeprom.hpp
@@ -0,0 +1,64 @@
+//
+// 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/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_MBOARD_EEPROM_HPP
+#define INCLUDED_UHD_USRP_MBOARD_EEPROM_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/dict.hpp>
+#include <uhd/types/serial.hpp>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+ /*!
+ * The motherboard EEPROM object:
+ * Knows how to read and write the EEPROM for various USRPs.
+ * The class inherits from a string, string dictionary.
+ * Use the dictionary interface to get and set values.
+ * Commit to the EEPROM to save changed settings.
+ */
+ struct UHD_API mboard_eeprom_t : uhd::dict<std::string, std::string>{
+
+ //! Possible EEPROM maps types
+ enum map_type{
+ MAP_NXXX,
+ MAP_B1XX
+ };
+
+ //! Make a new empty mboard eeprom
+ mboard_eeprom_t(void);
+
+ /*!
+ * Make a new mboard EEPROM handler.
+ * \param iface the interface to i2c
+ * \param map the map type enum
+ */
+ mboard_eeprom_t(i2c_iface &iface, map_type map);
+
+ /*!
+ * Write the contents of this object to the EEPROM.
+ * \param iface the interface to i2c
+ * \param map the map type enum
+ */
+ void commit(i2c_iface &iface, map_type map);
+
+ };
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_MBOARD_EEPROM_HPP */
diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp
index 0f250f439..df94d1678 100644
--- a/host/include/uhd/usrp/mboard_props.hpp
+++ b/host/include/uhd/usrp/mboard_props.hpp
@@ -44,7 +44,8 @@ namespace uhd{ namespace usrp{
MBOARD_PROP_CLOCK_CONFIG = 'C', //rw, clock_config_t
MBOARD_PROP_TIME_NOW = 't', //rw, time_spec_t
MBOARD_PROP_TIME_NEXT_PPS = 'T', //wo, time_spec_t
- MBOARD_PROP_STREAM_CMD = 's' //wo, stream_cmd_t
+ MBOARD_PROP_STREAM_CMD = 's', //wo, stream_cmd_t
+ MBOARD_PROP_EEPROM_MAP = 'M' //wr, mboard_eeprom_t::sptr
};
}} //namespace
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;
diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt
index a95864ca7..f0fa806c5 100644
--- a/host/utils/CMakeLists.txt
+++ b/host/utils/CMakeLists.txt
@@ -33,23 +33,19 @@ INSTALL(TARGETS
########################################################################
# Utilities that get installed into the share path
########################################################################
-ADD_EXECUTABLE(usrp2_addr_burner usrp2_addr_burner.cpp)
-TARGET_LINK_LIBRARIES(usrp2_addr_burner uhd)
-
ADD_EXECUTABLE(usrp_burn_db_eeprom usrp_burn_db_eeprom.cpp)
TARGET_LINK_LIBRARIES(usrp_burn_db_eeprom uhd)
+ADD_EXECUTABLE(usrp_burn_mb_eeprom usrp_burn_mb_eeprom.cpp)
+TARGET_LINK_LIBRARIES(usrp_burn_mb_eeprom uhd)
+
ADD_EXECUTABLE(usrp1_init_eeprom usrp1_init_eeprom.cpp)
TARGET_LINK_LIBRARIES(usrp1_init_eeprom uhd)
-ADD_EXECUTABLE(usrp1_serial_burner usrp1_serial_burner.cpp)
-TARGET_LINK_LIBRARIES(usrp1_serial_burner uhd)
-
INSTALL(TARGETS
- usrp2_addr_burner
usrp_burn_db_eeprom
+ usrp_burn_mb_eeprom
usrp1_init_eeprom
- usrp1_serial_burner
RUNTIME DESTINATION ${PKG_DATA_DIR}/utils
)
diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp
index 8947034d7..8cea52fa6 100644
--- a/host/utils/uhd_usrp_probe.cpp
+++ b/host/utils/uhd_usrp_probe.cpp
@@ -26,6 +26,7 @@
#include <uhd/usrp/dsp_props.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/usrp/dboard_id.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
@@ -123,10 +124,9 @@ static std::string get_mboard_pp_string(wax::obj mboard){
std::stringstream ss;
ss << boost::format("Mboard: %s") % mboard[usrp::MBOARD_PROP_NAME].as<std::string>() << std::endl;
//ss << std::endl;
- BOOST_FOREACH(const std::string &other_name, mboard[usrp::MBOARD_PROP_OTHERS].as<prop_names_t>()){
- try{
- ss << boost::format("%s: %s") % other_name % mboard[other_name].as<std::string>() << std::endl;
- } catch(...){}
+ usrp::mboard_eeprom_t mb_eeprom = mboard[usrp::MBOARD_PROP_EEPROM_MAP].as<usrp::mboard_eeprom_t>();
+ BOOST_FOREACH(const std::string &key, mb_eeprom.keys()){
+ if (not mb_eeprom[key].empty()) ss << boost::format("%s: %s") % key % mb_eeprom[key] << std::endl;
}
BOOST_FOREACH(const std::string &dsp_name, mboard[usrp::MBOARD_PROP_RX_DSP_NAMES].as<prop_names_t>()){
ss << make_border(get_dsp_pp_string("RX", mboard[named_prop_t(usrp::MBOARD_PROP_RX_DSP, dsp_name)]));
diff --git a/host/utils/usrp1_serial_burner.cpp b/host/utils/usrp1_serial_burner.cpp
deleted file mode 100644
index bf7d3d3bb..000000000
--- a/host/utils/usrp1_serial_burner.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// 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/utils/safe_main.hpp>
-#include <uhd/device.hpp>
-#include <uhd/usrp/device_props.hpp>
-#include <boost/program_options.hpp>
-#include <boost/format.hpp>
-#include <iostream>
-
-namespace po = boost::program_options;
-
-int UHD_SAFE_MAIN(int argc, char *argv[]){
- po::options_description desc("Allowed options");
- desc.add_options()
- ("help", "help message")
- ("old", po::value<std::string>(), "old USRP serial number (optional)")
- ("new", po::value<std::string>(), "new USRP serial number")
- ;
-
- po::variables_map vm;
- po::store(po::parse_command_line(argc, argv, desc), vm);
- po::notify(vm);
-
- //print the help message
- if (vm.count("help")){
- std::cout << boost::format("USRP serial burner %s") % desc << std::endl;
- return ~0;
- }
-
- if(vm.count("new") == 0) {
- std::cout << "error: must input --new arg" << std::endl;
- return ~0;
- }
-
- //load the options into the address
- uhd::device_addr_t device_addr;
- device_addr["type"] = "usrp1";
- if(vm.count("old")) device_addr["serial"] = vm["old"].as<std::string>();
-
- //find and create a control transport to do the writing.
-
- uhd::device_addrs_t found_addrs = uhd::device::find(device_addr);
-
- if (found_addrs.size() == 0){
- std::cerr << "No USRP devices found" << std::endl;
- return ~0;
- }
-
- for (size_t i = 0; i < found_addrs.size(); i++){
- uhd::device::sptr dev = uhd::device::make(found_addrs[i]);
- wax::obj mb = (*dev)[uhd::usrp::DEVICE_PROP_MBOARD];
- std::cout << "Writing serial number..." << std::endl;
- mb[std::string("serial")] = vm["new"].as<std::string>();
- std::cout << "Reading back serial number: " << mb[std::string("serial")].as<std::string>() << std::endl;
- }
-
-
- std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl;
- return 0;
-}
diff --git a/host/utils/usrp2_addr_burner.cpp b/host/utils/usrp2_addr_burner.cpp
deleted file mode 100644
index f0e3434b7..000000000
--- a/host/utils/usrp2_addr_burner.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//
-// 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/utils/safe_main.hpp>
-#include <uhd/device.hpp>
-#include <uhd/usrp/device_props.hpp>
-#include <boost/program_options.hpp>
-#include <boost/format.hpp>
-#include <iostream>
-
-namespace po = boost::program_options;
-
-int UHD_SAFE_MAIN(int argc, char *argv[]){
- po::options_description desc("Allowed options");
- desc.add_options()
- ("help", "help message")
- ("addr", po::value<std::string>(), "resolvable network address")
- ("new-ip", po::value<std::string>(), "new ip address (optional)")
- ("new-mac", po::value<std::string>(), "new mac address (optional)")
- ;
-
- po::variables_map vm;
- po::store(po::parse_command_line(argc, argv, desc), vm);
- po::notify(vm);
-
- //print the help message
- if (vm.count("help")){
- std::cout << boost::format("USRP2 Address Burner %s") % desc << std::endl;
- return ~0;
- }
-
- //load the options into the address
- uhd::device_addr_t device_addr;
- device_addr["type"] = "usrp2";
- if (vm.count("addr")){
- device_addr["addr"] = vm["addr"].as<std::string>();
- }
- else{
- std::cerr << "Error: missing addr option" << std::endl;
- return ~0;
- }
-
- //create a usrp2 device
- uhd::device::sptr u2_dev = uhd::device::make(device_addr);
- //FIXME usees the default mboard for now (until the mimo link is supported)
- wax::obj u2_mb = (*u2_dev)[uhd::usrp::DEVICE_PROP_MBOARD];
- std::cout << std::endl;
-
- //fetch and print current settings
- std::cout << "Fetching current settings from usrp2 eeprom:" << std::endl;
- std::string curr_ip = u2_mb[std::string("ip-addr")].as<std::string>();
- std::cout << boost::format(" Current IP Address: %s") % curr_ip << std::endl;
- std::string curr_mac = u2_mb[std::string("mac-addr")].as<std::string>();
- std::cout << boost::format(" Current MAC Address: %s") % curr_mac << std::endl;
- std::cout << " Done" << std::endl << std::endl;
-
- //try to set the new ip (if provided)
- if (vm.count("new-ip")){
- std::cout << "Burning a new ip address into the usrp2 eeprom:" << std::endl;
- std::string new_ip = vm["new-ip"].as<std::string>();
- std::cout << boost::format(" New IP Address: %s") % new_ip << std::endl;
- u2_mb[std::string("ip-addr")] = new_ip;
- std::cout << " Done" << std::endl << std::endl;
- }
-
- //try to set the new mac (if provided)
- if (vm.count("new-mac")){
- std::cout << "Burning a new mac address into the usrp2 eeprom:" << std::endl;
- std::string new_mac = vm["new-mac"].as<std::string>();
- std::cout << boost::format(" New MAC Address: %s") % new_mac << std::endl;
- u2_mb[std::string("mac-addr")] = new_mac;
- std::cout << " Done" << std::endl << std::endl;
- }
-
- std::cout << "Power-cycle the usrp2 for the changes to take effect." << std::endl;
- return 0;
-}
diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp
index 64ecf75d6..9afd71a22 100644
--- a/host/utils/usrp_burn_db_eeprom.cpp
+++ b/host/utils/usrp_burn_db_eeprom.cpp
@@ -58,10 +58,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help")){
- std::cout << boost::format("USRP Burn DB EEPROM %s") % desc << std::endl;
+ std::cout << boost::format("USRP Burn Daughterboard EEPROM %s") % desc << std::endl;
std::cout << boost::format(
- "Omit the id argument to perform readback,\n"
- "Or specify a new id to burn into the eeprom.\n"
+ "Omit the ID argument to perform readback,\n"
+ "Or specify a new ID to burn into the EEPROM.\n"
) << std::endl;
return ~0;
}
diff --git a/host/utils/usrp_burn_mb_eeprom.cpp b/host/utils/usrp_burn_mb_eeprom.cpp
new file mode 100644
index 000000000..20e1b58b1
--- /dev/null
+++ b/host/utils/usrp_burn_mb_eeprom.cpp
@@ -0,0 +1,81 @@
+//
+// 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/utils/safe_main.hpp>
+#include <uhd/device.hpp>
+#include <uhd/usrp/device_props.hpp>
+#include <uhd/usrp/mboard_props.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
+#include <boost/program_options.hpp>
+#include <boost/format.hpp>
+#include <iostream>
+
+namespace po = boost::program_options;
+
+int UHD_SAFE_MAIN(int argc, char *argv[]){
+ std::string args, key, val;
+
+ po::options_description desc("Allowed options");
+ desc.add_options()
+ ("help", "help message")
+ ("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
+ ("key", po::value<std::string>(&key), "the indentifier for a value in EEPROM")
+ ("val", po::value<std::string>(&val), "the new value to set, omit for readback")
+ ;
+
+ po::variables_map vm;
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+
+ //print the help message
+ if (vm.count("help") or not vm.count("key")){
+ std::cout << boost::format("USRP Burn Motherboard EEPROM %s") % desc << std::endl;
+ std::cout << boost::format(
+ "Omit the value argument to perform a readback,\n"
+ "Or specify a new value to burn into the EEPROM.\n"
+ ) << std::endl;
+ return ~0;
+ }
+
+ std::cout << "Creating USRP device from address: " + args << std::endl;
+ uhd::device::sptr dev = uhd::device::make(args);
+ //FIXME the default mboard for now (may be others)
+ wax::obj mboard = (*dev)[uhd::usrp::DEVICE_PROP_MBOARD];
+ std::cout << std::endl;
+
+ if (true /*always readback*/){
+ std::cout << "Fetching current settings from EEPROM..." << std::endl;
+ uhd::usrp::mboard_eeprom_t mb_eeprom = \
+ mboard[uhd::usrp::MBOARD_PROP_EEPROM_MAP].as<uhd::usrp::mboard_eeprom_t>();
+ if (not mb_eeprom.has_key(key)){
+ std::cerr << boost::format("Cannot find value for EEPROM[%s]") % key << std::endl;
+ return ~0;
+ }
+ std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % key % mb_eeprom[key] << std::endl;
+ std::cout << std::endl;
+ }
+ if (vm.count("val")){
+ uhd::usrp::mboard_eeprom_t mb_eeprom; mb_eeprom[key] = val;
+ std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") % key % val << std::endl;
+ mboard[uhd::usrp::MBOARD_PROP_EEPROM_MAP] = mb_eeprom;
+ std::cout << "Power-cycle the USRP device for the changes to take effect." << std::endl;
+ std::cout << std::endl;
+ }
+
+ std::cout << "Done" << std::endl;
+ return 0;
+}