summaryrefslogtreecommitdiffstats
path: root/host/utils
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils')
-rw-r--r--host/utils/CMakeLists.txt22
-rwxr-xr-xhost/utils/FastSendDatagramThreshold.regbin0 -> 312 bytes
-rw-r--r--host/utils/query_gpsdo_sensors.cpp120
-rw-r--r--host/utils/uhd_images_downloader.py.in94
-rw-r--r--host/utils/uhd_usrp_probe.cpp12
-rw-r--r--host/utils/usrp_cal_utils.hpp18
-rwxr-xr-xhost/utils/usrp_n2xx_net_burner.py16
-rwxr-xr-xhost/utils/usrp_n2xx_net_burner_gui.py9
8 files changed, 275 insertions, 16 deletions
diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt
index 0ecd6b4e7..763bb47bc 100644
--- a/host/utils/CMakeLists.txt
+++ b/host/utils/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2010-2011 Ettus Research LLC
+# Copyright 2010-2012 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
@@ -38,6 +38,7 @@ ENDFOREACH(util_source)
# Utilities that get installed into the share path
########################################################################
SET(util_share_sources
+ query_gpsdo_sensors.cpp
usrp_burn_db_eeprom.cpp
usrp_burn_mb_eeprom.cpp
)
@@ -64,6 +65,17 @@ FOREACH(util_source ${util_share_sources})
INSTALL(TARGETS ${util_name} RUNTIME DESTINATION ${PKG_LIB_DIR}/utils COMPONENT utilities)
ENDFOREACH(util_source)
+#UHD images downloader configuration
+CONFIGURE_FILE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/uhd_images_downloader.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py
+@ONLY)
+INSTALL(PROGRAMS
+ ${CMAKE_CURRENT_BINARY_DIR}/uhd_images_downloader.py
+ DESTINATION ${PKG_LIB_DIR}/utils
+ COMPONENT utilities
+)
+
IF(ENABLE_USRP2)
IF(WIN32 AND UHD_RELEASE_MODE) #include dd.exe
FILE(DOWNLOAD
@@ -76,8 +88,14 @@ IF(ENABLE_USRP2)
COMPONENT utilities
)
ENDIF(WIN32 AND UHD_RELEASE_MODE)
+ IF(LINUX)
+ INSTALL(PROGRAMS
+ usrp2_recovery.py
+ DESTINATION ${PKG_LIB_DIR}/utils
+ COMPONENT utilities
+ )
+ ENDIF(LINUX)
INSTALL(PROGRAMS
- usrp2_recovery.py
usrp2_card_burner.py
usrp2_card_burner_gui.py
usrp_n2xx_net_burner.py
diff --git a/host/utils/FastSendDatagramThreshold.reg b/host/utils/FastSendDatagramThreshold.reg
new file mode 100755
index 000000000..c0665d09e
--- /dev/null
+++ b/host/utils/FastSendDatagramThreshold.reg
Binary files differ
diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp
new file mode 100644
index 000000000..10792db7c
--- /dev/null
+++ b/host/utils/query_gpsdo_sensors.cpp
@@ -0,0 +1,120 @@
+//
+// Copyright 2012 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/paths.hpp>
+#include <uhd/utils/thread_priority.hpp>
+#include <uhd/utils/safe_main.hpp>
+#include <uhd/usrp/multi_usrp.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/program_options.hpp>
+#include <boost/format.hpp>
+#include <iostream>
+#include <complex>
+#include <boost/thread.hpp>
+#include <string>
+#include <cmath>
+
+namespace po = boost::program_options;
+namespace fs = boost::filesystem;
+
+int UHD_SAFE_MAIN(int argc, char *argv[]){
+ uhd::set_thread_priority_safe();
+
+ std::string args;
+
+ //Set up program options
+ po::options_description desc("Allowed options");
+ desc.add_options()
+ ("help", "help message")
+ ("args", po::value<std::string>(&args)->default_value(""), "Specify a single USRP.")
+ ;
+ 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("Query GPSDO Sensors %s") % desc << std::endl;
+ return ~0;
+ }
+
+ //Create a USRP device
+ std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args;
+ uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
+ std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string();
+
+ //Helpful notes
+ std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n");
+ std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n");
+ std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n");
+ std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n");
+ std::cout << boost::format("****************************************************************************************************************\n");
+
+
+ //Verify GPS sensors are present (i.e. EEPROM has been burnt)
+ std::vector<std::string> sensor_names = usrp->get_mboard_sensor_names(0);
+
+ if(std::find(sensor_names.begin(), sensor_names.end(), "gps_locked") == sensor_names.end()){
+ std::cout << boost::format("\ngps_locked sensor not found. This could mean that you have not installed the GPSDO correctly.\n\n");
+ std::cout << boost::format("Visit this page if the problem persists:\n");
+ std::cout << boost::format("http://files.ettus.com/uhd_docs/manual/html/gpsdo.html\n\n");
+ exit(1);
+ }
+
+ //Check for GPS lock
+ uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0);
+ if(gps_locked.to_pp_string().find("unlocked") > 0){
+ std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n");
+ std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n");
+ }
+ else std::cout << boost::format("GPS Locked\n");
+
+ //Check for 10 MHz lock
+ if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()){
+ uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("ref_locked",0);
+ if(gps_locked.to_pp_string().find("unlocked") > 0){
+ std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n");
+ std::cout << boost::format("Double check installation instructions: https://www.ettus.com/content/files/gpsdo-kit_2.pdf\n\n");
+ }
+ else std::cout << boost::format("USRP Locked to GPSDO 10 MHz Reference.\n");
+ }
+ else std::cout << boost::format("ref_locked sensor not present on this board.\n");
+
+ //Check PPS and compare UHD device time to GPS time
+ uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time");
+ const uhd::time_spec_t last_pps_time = usrp->get_time_last_pps();
+ if(int(round(last_pps_time.get_real_secs())) == gps_time.to_int())
+ {
+ std::cout << boost::format("GPS and UHD Device time are aligned.\n");
+ }
+ else
+ {
+ std::cout << boost::format("\nGPS and UHD Device time are NOT aligned. Try re-running the program. Double check 1 PPS connection from GPSDO.\n\n");
+ }
+
+ //print NMEA strings
+ std::cout << boost::format("Printing available NMEA strings:\n");
+ uhd::sensor_value_t gga_string = usrp->get_mboard_sensor("gps_gpgga");
+ uhd::sensor_value_t rmc_string = usrp->get_mboard_sensor("gps_gprmc");
+ std::cout << boost::format("%s\n%s\n%s\n") % gga_string.to_pp_string() % rmc_string.to_pp_string() % gps_time.to_pp_string();
+ std::cout << boost::format("UHD Device time: %.0f seconds\n") % round(last_pps_time.get_real_secs());
+
+ //finished
+ std::cout << boost::format("\nDone!\n\n");
+
+ return 0;
+}
diff --git a/host/utils/uhd_images_downloader.py.in b/host/utils/uhd_images_downloader.py.in
new file mode 100644
index 000000000..6aa619660
--- /dev/null
+++ b/host/utils/uhd_images_downloader.py.in
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 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/>.
+#
+
+from optparse import OptionParser
+import os
+import os.path
+import shutil
+import sys
+import urllib2
+import zipfile
+
+if __name__ == "__main__":
+
+ #Command line options
+ parser = OptionParser()
+ parser.add_option("--download-location", type="string", default="@CMAKE_INSTALL_PREFIX@/share/uhd/images", help="Set custom download location for images, [default=%default]")
+ parser.add_option("--buffer-size", type="int", default=8192, help="Set download buffer size, [default=%default]",)
+ (options, args) = parser.parse_args()
+
+ #Configuring image download info
+ images_src = "@UHD_IMAGES_DOWNLOAD_SRC@"
+ filename = images_src.split("/")[-1]
+
+ #Configuring image destination
+ cmake_install_prefix = "@CMAKE_INSTALL_PREFIX@"
+ if options.download_location != "":
+ images_dir = options.download_location
+ else:
+ images_dir = "@CMAKE_INSTALL_PREFIX@/share/uhd/images"
+
+ u = urllib2.urlopen(images_src)
+ f = open(filename, "wb")
+ meta = u.info()
+ filesize = float(meta.getheaders("Content-Length")[0])
+
+ print "Downloading images from: %s" % images_src
+
+ filesize_dl = 0.0
+
+ #Downloading file
+ while True:
+ buffer = u.read(options.buffer_size)
+ if not buffer:
+ break
+
+ filesize_dl -= len(buffer)
+ f.write(buffer)
+
+ status = r"%2.2f MB/%2.2f MB (%3.2f" % (-filesize_dl/1e6, filesize/1e6, (-filesize_dl*100.)/filesize) + r"%)"
+ status += chr(8)*(len(status)+1)
+ print status,
+
+ f.close()
+
+ #Extracting contents of zip file
+ if os.path.exists("tempdir"):
+ shutil.rmtree("tempdir")
+ os.mkdir("tempdir")
+
+ images_zip = zipfile.ZipFile(filename)
+ images_zip.extractall("tempdir")
+
+ #Removing images currently in images_dir
+ if os.path.exists(images_dir):
+ try:
+ shutil.rmtree(images_dir)
+ except:
+ sys.stderr.write("\nMake sure you have write permissions in the images directory.\n")
+ sys.exit(0)
+
+ #Copying downloaded images into images_dir
+ shutil.copytree("tempdir/%s/share/uhd/images" % filename[:-4],images_dir)
+
+ #Removing tempdir and zip file
+ shutil.rmtree("tempdir")
+ images_zip.close()
+ os.remove(filename)
+
+ print "\nImages successfully installed to: %s" % images_dir
diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp
index 1bd49a5ff..5b3702fb4 100644
--- a/host/utils/uhd_usrp_probe.cpp
+++ b/host/utils/uhd_usrp_probe.cpp
@@ -69,9 +69,9 @@ static std::string prop_names_to_pp_string(const std::vector<std::string> &prop_
return ss.str();
}
-static std::string get_subdev_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){
+static std::string get_frontend_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){
std::stringstream ss;
- ss << boost::format("%s Subdev: %s") % type % path.leaf() << std::endl;
+ ss << boost::format("%s Frontend: %s") % type % path.leaf() << std::endl;
//ss << std::endl;
ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) << std::endl;
@@ -123,7 +123,7 @@ static std::string get_dboard_pp_string(const std::string &type, property_tree::
if (not gdb_eeprom.serial.empty()) ss << boost::format("Serial: %s") % gdb_eeprom.serial << std::endl;
}
BOOST_FOREACH(const std::string &name, tree->list(path / (prefix + "_frontends"))){
- ss << make_border(get_subdev_pp_string(type, tree, path / (prefix + "_frontends") / name));
+ ss << make_border(get_frontend_pp_string(type, tree, path / (prefix + "_frontends") / name));
}
ss << make_border(get_codec_pp_string(type, tree, path.branch_path().branch_path() / (prefix + "_codecs") / path.leaf()));
return ss.str();
@@ -137,6 +137,12 @@ static std::string get_mboard_pp_string(property_tree::sptr tree, const fs_path
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;
}
+ if (tree->exists(path / "fw_version")){
+ ss << "FW Version: " << tree->access<std::string>(path / "fw_version").get() << std::endl;
+ }
+ if (tree->exists(path / "fpga_version")){
+ ss << "FPGA Version: " << tree->access<std::string>(path / "fpga_version").get() << std::endl;
+ }
ss << std::endl;
ss << "Time sources: " << prop_names_to_pp_string(tree->access<std::vector<std::string> >(path / "time_source" / "options").get()) << std::endl;
ss << "Clock sources: " << prop_names_to_pp_string(tree->access<std::vector<std::string> >(path / "clock_source" / "options").get()) << std::endl;
diff --git a/host/utils/usrp_cal_utils.hpp b/host/utils/usrp_cal_utils.hpp
index 825d94d64..364b68bbe 100644
--- a/host/utils/usrp_cal_utils.hpp
+++ b/host/utils/usrp_cal_utils.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2011-2012 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
@@ -68,7 +68,13 @@ static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp){
const uhd::fs_path tx_fe_path = "/mboards/0/dboards/A/tx_frontends/0";
const std::string tx_name = tree->access<std::string>(tx_fe_path / "name").get();
- if (tx_name.find("WBX") != std::string::npos or tx_name.find("SBX") != std::string::npos){
+ if (tx_name.find("WBX") != std::string::npos){
+ usrp->set_tx_gain(0);
+ }
+ else if (tx_name.find("SBX") != std::string::npos){
+ usrp->set_tx_gain(0);
+ }
+ else if (tx_name.find("RFX") != std::string::npos){
usrp->set_tx_gain(0);
}
else{
@@ -77,7 +83,13 @@ static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp){
const uhd::fs_path rx_fe_path = "/mboards/0/dboards/A/tx_frontends/0";
const std::string rx_name = tree->access<std::string>(rx_fe_path / "name").get();
- if (rx_name.find("WBX") != std::string::npos or rx_name.find("SBX") != std::string::npos){
+ if (rx_name.find("WBX") != std::string::npos){
+ usrp->set_rx_gain(25);
+ }
+ else if (rx_name.find("SBX") != std::string::npos){
+ usrp->set_rx_gain(25);
+ }
+ else if (rx_name.find("RFX") != std::string::npos){
usrp->set_rx_gain(25);
}
else{
diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py
index f2cfb8ecf..8f16de501 100755
--- a/host/utils/usrp_n2xx_net_burner.py
+++ b/host/utils/usrp_n2xx_net_burner.py
@@ -222,7 +222,9 @@ def enumerate_devices():
pkt = sock.recv(UDP_MAX_XFER_BYTES)
(proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(pkt)
if(pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG):
- yield socket.inet_ntoa(struct.pack("<L", socket.ntohl(ip_addr)))
+ use_addr = socket.inet_ntoa(struct.pack("<L", socket.ntohl(ip_addr)))
+ burner = burner_socket(use_addr, True)
+ yield "%s (%s)" % (socket.inet_ntoa(struct.pack("<L", socket.ntohl(ip_addr))), n2xx_revs[burner.get_hw_rev()][0])
except socket.timeout:
still_goin = False
@@ -230,12 +232,13 @@ def enumerate_devices():
# Burner class, holds a socket and send/recv routines
########################################################################
class burner_socket(object):
- def __init__(self, addr):
+ def __init__(self, addr, quiet):
self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ self._quiet = quiet
self._sock.settimeout(UDP_TIMEOUT)
self._sock.connect((addr, UDP_FW_UPDATE_PORT))
self.set_callbacks(lambda *a: None, lambda *a: None)
- self.init_update() #check that the device is there
+ self.init_update(quiet) #check that the device is there
self.get_hw_rev()
def set_callbacks(self, progress_cb, status_cb):
@@ -247,13 +250,13 @@ class burner_socket(object):
return self._sock.recv(UDP_MAX_XFER_BYTES)
#just here to validate comms
- def init_update(self):
+ def init_update(self,quiet):
out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0)
try: in_pkt = self.send_and_recv(out_pkt)
except socket.timeout: raise Exception("No response from device")
(proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt)
if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG:
- print("USRP-N2XX found.")
+ if not quiet: print("USRP-N2XX found.")
else:
raise Exception("Invalid reply received from device.")
@@ -488,6 +491,7 @@ if __name__=='__main__':
if options.list:
print('Possible network devices:')
print(' ' + '\n '.join(enumerate_devices()))
+ #enumerate_devices()
exit()
if not options.addr: raise Exception('no address specified')
@@ -500,7 +504,7 @@ if __name__=='__main__':
response = raw_input("""Type "yes" to continue, or anything else to quit: """)
if response != "yes": sys.exit(0)
- burner = burner_socket(addr=options.addr)
+ burner = burner_socket(addr=options.addr,quiet=False)
if options.read:
if options.fw:
diff --git a/host/utils/usrp_n2xx_net_burner_gui.py b/host/utils/usrp_n2xx_net_burner_gui.py
index e2b79e72c..a9150bd88 100755
--- a/host/utils/usrp_n2xx_net_burner_gui.py
+++ b/host/utils/usrp_n2xx_net_burner_gui.py
@@ -96,7 +96,11 @@ class DeviceEntryWidget(tkinter.Frame):
tkinter.Button(self, text="Rescan for Devices", command=self._reload_cb).pack()
self._hints = tkinter.Listbox(self)
+ self._hints_addrs_only = tkinter.Listbox(self)
+
self._hints.bind("<<ListboxSelect>>", self._listbox_cb)
+ self._hints_addrs_only.bind("<<ListboxSelect>>", self._listbox_cb)
+
self._reload_cb()
self._hints.pack(expand=tkinter.YES, fill=tkinter.X)
@@ -112,10 +116,11 @@ class DeviceEntryWidget(tkinter.Frame):
self._hints.delete(0, tkinter.END)
for hint in usrp_n2xx_net_burner.enumerate_devices():
self._hints.insert(tkinter.END, hint)
+ self._hints_addrs_only.insert(tkinter.END, hint.split(" (")[0])
def _listbox_cb(self, event):
try:
- sel = self._hints.get(self._hints.curselection()[0])
+ sel = self._hints_addrs_only.get(self._hints.curselection()[0])
self._entry.delete(0, tkinter.END)
self._entry.insert(0, sel)
except Exception as e: print(e)
@@ -196,7 +201,7 @@ class USRPN2XXNetBurnerApp(tkinter.Frame):
self._disable_input()
try:
#make a new burner object and attempt the burner operation
- burner = usrp_n2xx_net_burner.burner_socket(addr=addr)
+ burner = usrp_n2xx_net_burner.burner_socket(addr=addr,quiet=False)
for (image_type, fw_img, fpga_img) in (('FPGA', '', fpga), ('Firmware', fw, '')):
#setup callbacks that update the gui