summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/cmake/Modules/UHDPackage.cmake5
-rw-r--r--host/cmake/Modules/UHDUnitTest.cmake110
-rw-r--r--host/examples/benchmark_rate.cpp3
-rw-r--r--host/examples/latency_test.cpp2
-rw-r--r--host/examples/network_relay.cpp5
-rw-r--r--host/examples/rx_ascii_art_dft.cpp9
-rw-r--r--host/examples/rx_multi_samples.cpp2
-rw-r--r--host/examples/rx_samples_to_file.cpp2
-rw-r--r--host/examples/rx_samples_to_udp.cpp2
-rw-r--r--host/examples/rx_timed_samples.cpp2
-rw-r--r--host/examples/test_dboard_coercion.cpp2
-rw-r--r--host/examples/test_messages.cpp2
-rw-r--r--host/examples/test_pps_input.cpp2
-rw-r--r--host/examples/test_timed_commands.cpp2
-rw-r--r--host/examples/transport_hammer.cpp2
-rw-r--r--host/examples/tx_bursts.cpp2
-rw-r--r--host/examples/tx_samples_from_file.cpp2
-rw-r--r--host/examples/tx_timed_samples.cpp2
-rw-r--r--host/examples/tx_waveforms.cpp2
-rw-r--r--host/examples/txrx_loopback_to_file.cpp2
-rw-r--r--host/lib/usrp/gps_ctrl.cpp134
-rw-r--r--host/tests/CMakeLists.txt13
-rw-r--r--host/utils/fx2_init_eeprom.cpp8
-rw-r--r--host/utils/uhd_cal_rx_iq_balance.cpp5
-rw-r--r--host/utils/uhd_cal_tx_dc_offset.cpp4
-rw-r--r--host/utils/uhd_cal_tx_iq_balance.cpp5
-rw-r--r--host/utils/uhd_find_devices.cpp7
-rw-r--r--host/utils/uhd_usrp_probe.cpp9
-rw-r--r--host/utils/usrp_burn_db_eeprom.cpp4
-rw-r--r--host/utils/usrp_burn_mb_eeprom.cpp6
30 files changed, 281 insertions, 76 deletions
diff --git a/host/cmake/Modules/UHDPackage.cmake b/host/cmake/Modules/UHDPackage.cmake
index d2f5d78f2..330a9ecc2 100644
--- a/host/cmake/Modules/UHDPackage.cmake
+++ b/host/cmake/Modules/UHDPackage.cmake
@@ -109,7 +109,6 @@ SET(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
SET(CPACK_COMPONENT_UTILITIES_GROUP "Runtime")
SET(CPACK_COMPONENT_EXAMPLES_GROUP "Runtime")
-SET(CPACK_COMPONENT_TESTS_GROUP "Runtime")
SET(CPACK_COMPONENT_MANUAL_GROUP "Documentation")
SET(CPACK_COMPONENT_DOXYGEN_GROUP "Documentation")
SET(CPACK_COMPONENT_README_GROUP "Documentation")
@@ -118,7 +117,6 @@ SET(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers")
SET(CPACK_COMPONENT_UTILITIES_DISPLAY_NAME "Utilities")
SET(CPACK_COMPONENT_EXAMPLES_DISPLAY_NAME "Examples")
-SET(CPACK_COMPONENT_TESTS_DISPLAY_NAME "Unit Tests")
SET(CPACK_COMPONENT_MANUAL_DISPLAY_NAME "Manual")
SET(CPACK_COMPONENT_DOXYGEN_DISPLAY_NAME "Doxygen")
SET(CPACK_COMPONENT_README_DISPLAY_NAME "Readme")
@@ -128,7 +126,6 @@ SET(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "Dynamic link library")
SET(CPACK_COMPONENT_HEADERS_DESCRIPTION "C++ development headers")
SET(CPACK_COMPONENT_UTILITIES_DESCRIPTION "Utility executables and python scripts")
SET(CPACK_COMPONENT_EXAMPLES_DESCRIPTION "Example executables")
-SET(CPACK_COMPONENT_TESTS_DESCRIPTION "Unit test executables")
SET(CPACK_COMPONENT_MANUAL_DESCRIPTION "Manual/application notes (rst and html)")
SET(CPACK_COMPONENT_DOXYGEN_DESCRIPTION "API documentation (html)")
SET(CPACK_COMPONENT_README_DESCRIPTION "Readme files (txt)")
@@ -140,7 +137,7 @@ SET(CPACK_COMPONENT_UTILITIES_DEPENDS libraries)
SET(CPACK_COMPONENT_EXAMPLES_DEPENDS libraries)
SET(CPACK_COMPONENT_TESTS_DEPENDS libraries)
-SET(CPACK_COMPONENTS_ALL libraries headers utilities examples tests manual doxygen readme images)
+SET(CPACK_COMPONENTS_ALL libraries headers utilities examples manual doxygen readme images)
########################################################################
# Setup CPack Debian
diff --git a/host/cmake/Modules/UHDUnitTest.cmake b/host/cmake/Modules/UHDUnitTest.cmake
new file mode 100644
index 000000000..47cddc521
--- /dev/null
+++ b/host/cmake/Modules/UHDUnitTest.cmake
@@ -0,0 +1,110 @@
+#
+# 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
+# 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/>.
+#
+
+########################################################################
+# Add a unit test and setup the environment for a unit test.
+# Takes the same arguments as the ADD_TEST function.
+#
+# Before calling set the following variables:
+# UHD_TEST_TARGET_DEPS - built targets for the library path
+# UHD_TEST_LIBRARY_DIRS - directories for the library path
+########################################################################
+function(UHD_ADD_TEST test_name)
+
+ #Ensure that the build exe also appears in the PATH.
+ list(APPEND UHD_TEST_TARGET_DEPS ${ARGN})
+
+ #In the land of windows, all libraries must be in the PATH.
+ #Since the dependent libraries are not yet installed,
+ #we must manually set them in the PATH to run tests.
+ #The following appends the path of a target dependency.
+ foreach(target ${UHD_TEST_TARGET_DEPS})
+ get_target_property(location ${target} LOCATION)
+ if(location)
+ get_filename_component(path ${location} PATH)
+ string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path})
+ list(APPEND UHD_TEST_LIBRARY_DIRS ${path})
+ endif(location)
+ endforeach(target)
+
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir)
+ file(TO_NATIVE_PATH "${UHD_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
+
+ #http://www.cmake.org/pipermail/cmake/2009-May/029464.html
+ #Replaced this add test + set environs code with the shell script generation.
+ #Its nicer to be able to manually run the shell script to diagnose problems.
+ #ADD_TEST(${ARGV})
+ #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
+
+ if(UNIX)
+ set(LD_PATH_VAR "LD_LIBRARY_PATH")
+ if(APPLE)
+ set(LD_PATH_VAR "DYLD_LIBRARY_PATH")
+ endif()
+
+ set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
+ list(APPEND libpath "$${LD_PATH_VAR}")
+
+ #replace list separator with the path separator
+ string(REPLACE ";" ":" libpath "${libpath}")
+ list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}")
+
+ #generate a bat file that sets the environment and runs the test
+ find_program(SHELL sh)
+ set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
+ file(WRITE ${sh_file} "#!${SHELL}\n")
+ #each line sets an environment variable
+ foreach(environ ${environs})
+ file(APPEND ${sh_file} "export ${environ}\n")
+ endforeach(environ)
+ #load the command to run with its arguments
+ foreach(arg ${ARGN})
+ file(APPEND ${sh_file} "${arg} ")
+ endforeach(arg)
+ file(APPEND ${sh_file} "\n")
+
+ #make the shell file executable
+ execute_process(COMMAND chmod +x ${sh_file})
+
+ add_test(${test_name} ${SHELL} ${sh_file})
+
+ endif(UNIX)
+
+ if(WIN32)
+ list(APPEND libpath ${DLL_PATHS} "%PATH%")
+
+ #replace list separator with the path separator (escaped)
+ string(REPLACE ";" "\\;" libpath "${libpath}")
+ list(APPEND environs "PATH=${libpath}")
+
+ #generate a bat file that sets the environment and runs the test
+ set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat)
+ file(WRITE ${bat_file} "@echo off\n")
+ #each line sets an environment variable
+ foreach(environ ${environs})
+ file(APPEND ${bat_file} "SET ${environ}\n")
+ endforeach(environ)
+ #load the command to run with its arguments
+ foreach(arg ${ARGN})
+ file(APPEND ${bat_file} "${arg} ")
+ endforeach(arg)
+ file(APPEND ${bat_file} "\n")
+
+ add_test(${test_name} ${bat_file})
+ endif(WIN32)
+
+endfunction(UHD_ADD_TEST)
diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp
index 8a000f6c3..ed3a8580a 100644
--- a/host/examples/benchmark_rate.cpp
+++ b/host/examples/benchmark_rate.cpp
@@ -25,6 +25,7 @@
#include <boost/math/special_functions/round.hpp>
#include <iostream>
#include <complex>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -264,5 +265,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp
index 518d2383a..461ac9bf8 100644
--- a/host/examples/latency_test.cpp
+++ b/host/examples/latency_test.cpp
@@ -164,5 +164,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
**************************************************************/
std::cout << boost::format("\nACK %d, UNDERFLOW %d, TIME_ERR %d, other %d")
% ack % underflow % time_error % other << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp
index e8f9e667f..bb09296b3 100644
--- a/host/examples/network_relay.cpp
+++ b/host/examples/network_relay.cpp
@@ -24,6 +24,7 @@
#include <iostream>
#include <csignal>
#include <vector>
+#include <cstdlib>
namespace po = boost::program_options;
namespace asio = boost::asio;
@@ -202,7 +203,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
<< "Runs a network relay between UHD on one computer and a USRP on the network.\n"
<< "This example is basically for test purposes. Use at your own convenience.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
{
@@ -223,5 +224,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_ascii_art_dft.cpp b/host/examples/rx_ascii_art_dft.cpp
index fe8fb0347..1aede51a4 100644
--- a/host/examples/rx_ascii_art_dft.cpp
+++ b/host/examples/rx_ascii_art_dft.cpp
@@ -25,6 +25,7 @@
#include <curses.h>
#include <iostream>
#include <complex>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -63,7 +64,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help") or not vm.count("rate")){
std::cout << boost::format("UHD RX ASCII Art DFT %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -82,7 +83,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//set the sample rate
if (not vm.count("rate")){
std::cerr << "Please specify the sample rate with --rate" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl;
usrp->set_rx_rate(rate);
@@ -91,7 +92,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//set the center frequency
if (not vm.count("freq")){
std::cerr << "Please specify the center frequency with --freq" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl;
usrp->set_rx_freq(freq);
@@ -194,5 +195,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_multi_samples.cpp b/host/examples/rx_multi_samples.cpp
index 42ef33d70..83d648eb5 100644
--- a/host/examples/rx_multi_samples.cpp
+++ b/host/examples/rx_multi_samples.cpp
@@ -174,5 +174,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp
index 5197bfe69..d0a02a6c1 100644
--- a/host/examples/rx_samples_to_file.cpp
+++ b/host/examples/rx_samples_to_file.cpp
@@ -214,5 +214,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp
index 2acaa5d8b..f637f9313 100644
--- a/host/examples/rx_samples_to_udp.cpp
+++ b/host/examples/rx_samples_to_udp.cpp
@@ -168,5 +168,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp
index 143bceb03..f0d49b4bd 100644
--- a/host/examples/rx_timed_samples.cpp
+++ b/host/examples/rx_timed_samples.cpp
@@ -124,5 +124,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_dboard_coercion.cpp b/host/examples/test_dboard_coercion.cpp
index 5b1e9f0e2..cfc745147 100644
--- a/host/examples/test_dboard_coercion.cpp
+++ b/host/examples/test_dboard_coercion.cpp
@@ -573,5 +573,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if(test_tx and test_rx) std::cout << std::endl;
if(test_rx) std::cout << rx_results << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp
index afb092092..6f2ddfe28 100644
--- a/host/examples/test_messages.cpp
+++ b/host/examples/test_messages.cpp
@@ -350,5 +350,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_pps_input.cpp b/host/examples/test_pps_input.cpp
index 994b7ca87..c07f2fffd 100644
--- a/host/examples/test_pps_input.cpp
+++ b/host/examples/test_pps_input.cpp
@@ -58,5 +58,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << std::endl << "Attempt to detect the PPS and set the time..." << std::endl << std::endl;
usrp->set_time_unknown_pps(uhd::time_spec_t(0.0));
std::cout << std::endl << "Success!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/test_timed_commands.cpp b/host/examples/test_timed_commands.cpp
index 34c83dfd6..cecf1607c 100644
--- a/host/examples/test_timed_commands.cpp
+++ b/host/examples/test_timed_commands.cpp
@@ -125,5 +125,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/transport_hammer.cpp b/host/examples/transport_hammer.cpp
index e32912eaa..ff35ceb21 100644
--- a/host/examples/transport_hammer.cpp
+++ b/host/examples/transport_hammer.cpp
@@ -272,5 +272,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_bursts.cpp b/host/examples/tx_bursts.cpp
index 4cf5f2fd1..8dd4a002c 100644
--- a/host/examples/tx_bursts.cpp
+++ b/host/examples/tx_bursts.cpp
@@ -156,5 +156,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_samples_from_file.cpp b/host/examples/tx_samples_from_file.cpp
index 04a6a63d4..f9447c25d 100644
--- a/host/examples/tx_samples_from_file.cpp
+++ b/host/examples/tx_samples_from_file.cpp
@@ -192,5 +192,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp
index 3b8cc75d4..4cc31a7c0 100644
--- a/host/examples/tx_timed_samples.cpp
+++ b/host/examples/tx_timed_samples.cpp
@@ -124,5 +124,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp
index 3c5eecd65..40326ae93 100644
--- a/host/examples/tx_waveforms.cpp
+++ b/host/examples/tx_waveforms.cpp
@@ -260,5 +260,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/examples/txrx_loopback_to_file.cpp b/host/examples/txrx_loopback_to_file.cpp
index 495c9f7e4..9dc348da8 100644
--- a/host/examples/txrx_loopback_to_file.cpp
+++ b/host/examples/txrx_loopback_to_file.cpp
@@ -443,5 +443,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index f3bdded60..917f115f3 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -26,6 +26,10 @@
#include <boost/thread/thread.hpp>
#include <boost/tokenizer.hpp>
#include <boost/format.hpp>
+#include <boost/regex.hpp>
+
+#include "boost/tuple/tuple.hpp"
+#include "boost/foreach.hpp"
using namespace uhd;
using namespace boost::gregorian;
@@ -38,14 +42,69 @@ using namespace boost::this_thread;
*/
class gps_ctrl_impl : public gps_ctrl{
+private:
+ std::map<std::string, boost::tuple<std::string, boost::system_time, bool> > sensors;
+
+ std::string get_cached_sensor(const std::string sensor, const int freshness, const bool once, const bool touch=true) {
+ boost::system_time time = boost::get_system_time();
+ try {
+ // this is nasty ...
+ //std::cout << boost::format("Requested %s - seen? ") % sensor << sensors[sensor].get<2>() << " once? " << once << std::endl;
+ if(time - sensors[sensor].get<1>() < milliseconds(freshness) && (!once or !sensors[sensor].get<2>())) {
+ sensors[sensor] = boost::make_tuple(sensors[sensor].get<0>(), sensors[sensor].get<1>(), touch);
+ return sensors[sensor].get<0>();
+ } else {
+ return update_cached_sensors(sensor);
+ }
+ } catch(std::exception &e) {
+ UHD_MSG(warning) << "get_cached_sensor: " << e.what();
+ }
+ return std::string();
+ }
+
+ std::string update_cached_sensors(const std::string sensor) {
+ if(not gps_detected() || (gps_type != GPS_TYPE_JACKSON_LABS)) {
+ UHD_MSG(error) << "get_stat(): unsupported GPS or no GPS detected";
+ return std::string();
+ }
+
+ std::string msg = _recv();
+ static const boost::regex status_regex("\\d\\d-\\d\\d-\\d\\d");
+ boost::system_time time = boost::get_system_time();
+ if(msg.size() < 6)
+ return std::string();
+
+ std::string nmea = msg.substr(1,5);
+ const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC");
+ BOOST_FOREACH(std::string key, list) {
+ // beginning matches one of the NMEA keys
+ if(!nmea.compare(key)) {
+ sensors[key] = boost::make_tuple(msg, time, !sensor.compare(key));
+ // if this was what we're looking for return it
+ return (!sensor.compare(key))? msg : std::string();
+ }
+ }
+
+ //We're still here so it's not one of the NMEA strings from above
+ if(boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous)) {
+ trim(msg);
+ sensors["SERVO"] = boost::make_tuple(msg, time, false);
+ if(!sensor.compare("SERVO"))
+ return msg;
+ else
+ return std::string();
+ }
+ return std::string();
+ }
public:
gps_ctrl_impl(uart_iface::sptr uart){
_uart = uart;
+
std::string reply;
bool i_heard_some_nmea = false, i_heard_something_weird = false;
gps_type = GPS_TYPE_NONE;
-
+
//first we look for a Jackson Labs Firefly (since that's what we provide...)
_flush(); //get whatever junk is in the rx buffer right now, and throw it away
_send("HAAAY GUYYYYS\n"); //to elicit a response from the Firefly
@@ -60,7 +119,7 @@ public:
if(reply.find("Command Error") != std::string::npos) {
gps_type = GPS_TYPE_JACKSON_LABS;
break;
- }
+ }
else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response
else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate
sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
@@ -99,7 +158,8 @@ public:
("gps_gpgga")
("gps_gprmc")
("gps_time")
- ("gps_locked");
+ ("gps_locked")
+ ("gps_servo");
return ret;
}
@@ -108,7 +168,7 @@ public:
or key == "gps_gprmc") {
return sensor_value_t(
boost::to_upper_copy(key),
- get_nmea(boost::to_upper_copy(key.substr(4,8))),
+ get_cached_sensor(boost::to_upper_copy(key.substr(4,8)), GPS_NMEA_NORMAL_FRESHNESS, false, false),
"");
}
else if(key == "gps_time") {
@@ -117,6 +177,9 @@ public:
else if(key == "gps_locked") {
return sensor_value_t("GPS lock status", locked(), "locked", "unlocked");
}
+ else if(key == "gps_servo") {
+ return sensor_value_t("GPS servo status", get_servo(), "");
+ }
else {
throw uhd::value_error("gps ctrl get_sensor unknown key: " + key);
}
@@ -138,24 +201,25 @@ private:
sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
_send("GPS:GPRMC 1\n");
sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
+ _send("SERV:TRAC 1\n"); // enable servo trace message
+ sleep(milliseconds(FIREFLY_STUPID_DELAY_MS));
}
-
+
//retrieve a raw NMEA sentence
std::string get_nmea(std::string msgtype) {
- msgtype.insert(0, "$");
std::string reply;
- if(not gps_detected()) {
- UHD_MSG(error) << "get_nmea(): unsupported GPS or no GPS detected";
- return std::string();
- }
-
- _flush(); //flush all input before waiting for a message
const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
while(boost::get_system_time() < comm_timeout) {
- reply = _recv();
- if(reply.substr(0, 6) == msgtype)
- return reply;
+ if(!msgtype.compare("GPRMC")) {
+ reply = get_cached_sensor(msgtype, GPS_NMEA_FRESHNESS, true);
+ }
+ else {
+ reply = get_cached_sensor(msgtype, GPS_NMEA_LOW_FRESHNESS, false);
+ }
+ if(reply.size()) {
+ if(reply.substr(1, 5) == msgtype) return reply;
+ }
boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
}
throw uhd::value_error(str(boost::format("get_nmea(): no %s message found") % msgtype));
@@ -178,7 +242,7 @@ private:
ptime get_time(void) {
int error_cnt = 0;
ptime gps_time;
- while(error_cnt < 3) {
+ while(error_cnt < 2) {
try {
std::string reply = get_nmea("GPRMC");
@@ -188,29 +252,30 @@ private:
if(datestr.size() == 0 or timestr.size() == 0) {
throw uhd::value_error(str(boost::format("Invalid response \"%s\"") % reply));
}
-
+
//just trust me on this one
- gps_time = ptime( date(
+ gps_time = ptime( date(
greg_year(boost::lexical_cast<int>(datestr.substr(4, 2)) + 2000),
- greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))),
- greg_day(boost::lexical_cast<int>(datestr.substr(0, 2)))
+ greg_month(boost::lexical_cast<int>(datestr.substr(2, 2))),
+ greg_day(boost::lexical_cast<int>(datestr.substr(0, 2)))
),
hours( boost::lexical_cast<int>(timestr.substr(0, 2)))
+ minutes(boost::lexical_cast<int>(timestr.substr(2, 2)))
+ seconds(boost::lexical_cast<int>(timestr.substr(4, 2)))
);
return gps_time;
-
+
} catch(std::exception &e) {
UHD_MSG(warning) << "get_time: " << e.what();
+ _flush();
error_cnt++;
}
}
throw uhd::value_error("Timeout after no valid message found");
-
+
return gps_time; //keep gcc from complaining
}
-
+
time_t get_epoch_time(void) {
return (get_time() - from_time_t(0)).total_seconds();
}
@@ -223,7 +288,7 @@ private:
int error_cnt = 0;
while(error_cnt < 3) {
try {
- std::string reply = get_nmea("GPGGA");
+ std::string reply = get_cached_sensor("GPGGA", GPS_LOCK_FRESHNESS, false, false);
if(reply.size() <= 1) return false;
return (get_token(reply, 6) != "0");
@@ -236,6 +301,20 @@ private:
return false;
}
+ std::string get_servo(void) {
+ std::string reply;
+
+ const boost::system_time comm_timeout = boost::get_system_time() + milliseconds(GPS_COMM_TIMEOUT_MS);
+ while(boost::get_system_time() < comm_timeout) {
+ reply = get_cached_sensor("SERVO", GPS_SERVO_FRESHNESS, false);
+ if(reply.size())
+ return reply;
+ boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
+ }
+ throw uhd::value_error("get_stat(): no servo message found");
+ return std::string();
+ }
+
uart_iface::sptr _uart;
void _flush(void){
@@ -258,7 +337,12 @@ private:
GPS_TYPE_NONE
} gps_type;
- static const int GPS_COMM_TIMEOUT_MS = 1500;
+ static const int GPS_COMM_TIMEOUT_MS = 1300;
+ static const int GPS_NMEA_FRESHNESS = 10;
+ static const int GPS_NMEA_LOW_FRESHNESS = 2500;
+ static const int GPS_NMEA_NORMAL_FRESHNESS = 1000;
+ static const int GPS_SERVO_FRESHNESS = 2500;
+ static const int GPS_LOCK_FRESHNESS = 2500;
static const int GPS_TIMEOUT_DELAY_MS = 200;
static const int FIREFLY_STUPID_DELAY_MS = 200;
};
diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt
index 67e99941b..f5cead184 100644
--- a/host/tests/CMakeLists.txt
+++ b/host/tests/CMakeLists.txt
@@ -16,6 +16,11 @@
#
########################################################################
+# unit test support
+########################################################################
+include(UHDUnitTest)
+
+########################################################################
# unit test suite
########################################################################
SET(test_sources
@@ -39,13 +44,15 @@ SET(test_sources
#turn each test cpp file into an executable with an int main() function
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
-#for each source: build an executable, register it as a test, and install
+SET(UHD_TEST_TARGET_DEPS uhd)
+SET(UHD_TEST_LIBRARY_DIRS ${Boost_LIBRARY_DIRS})
+
+#for each source: build an executable, register it as a test
FOREACH(test_source ${test_sources})
GET_FILENAME_COMPONENT(test_name ${test_source} NAME_WE)
ADD_EXECUTABLE(${test_name} ${test_source})
TARGET_LINK_LIBRARIES(${test_name} uhd)
- ADD_TEST(${test_name} ${test_name})
- INSTALL(TARGETS ${test_name} RUNTIME DESTINATION ${PKG_LIB_DIR}/tests COMPONENT tests)
+ UHD_ADD_TEST(${test_name} ${test_name})
ENDFOREACH(test_source)
########################################################################
diff --git a/host/utils/fx2_init_eeprom.cpp b/host/utils/fx2_init_eeprom.cpp
index c210ae575..701092a5d 100644
--- a/host/utils/fx2_init_eeprom.cpp
+++ b/host/utils/fx2_init_eeprom.cpp
@@ -41,12 +41,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
- po::notify(vm);
+ po::notify(vm);
//print the help message
if (vm.count("help")){
std::cout << boost::format("USRP EEPROM initialization %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//cant find a uninitialized usrp with this mystery module in the way...
@@ -76,7 +76,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if (found_addrs.size() == 0){
std::cerr << "No USRP devices found" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
for (size_t i = 0; i < found_addrs.size(); i++){
@@ -89,5 +89,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp
index 68d0443da..5fb494114 100644
--- a/host/utils/uhd_cal_rx_iq_balance.cpp
+++ b/host/utils/uhd_cal_rx_iq_balance.cpp
@@ -29,6 +29,7 @@
#include <complex>
#include <cmath>
#include <ctime>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -120,7 +121,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout <<
"This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -239,5 +240,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
store_results(usrp, results, "RX", "rx", "iq");
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_cal_tx_dc_offset.cpp b/host/utils/uhd_cal_tx_dc_offset.cpp
index 8f69b3ce1..c9cf757f4 100644
--- a/host/utils/uhd_cal_tx_dc_offset.cpp
+++ b/host/utils/uhd_cal_tx_dc_offset.cpp
@@ -123,7 +123,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout <<
"This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -237,5 +237,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
store_results(usrp, results, "TX", "tx", "dc");
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_cal_tx_iq_balance.cpp b/host/utils/uhd_cal_tx_iq_balance.cpp
index 5478b07e3..20d018edf 100644
--- a/host/utils/uhd_cal_tx_iq_balance.cpp
+++ b/host/utils/uhd_cal_tx_iq_balance.cpp
@@ -28,6 +28,7 @@
#include <iostream>
#include <complex>
#include <ctime>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -123,7 +124,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout <<
"This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n"
<< std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//create a usrp device
@@ -242,5 +243,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
store_results(usrp, results, "TX", "tx", "iq");
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp
index b778eeb68..c258c580e 100644
--- a/host/utils/uhd_find_devices.cpp
+++ b/host/utils/uhd_find_devices.cpp
@@ -20,6 +20,7 @@
#include <boost/program_options.hpp>
#include <boost/format.hpp>
#include <iostream>
+#include <cstdlib>
namespace po = boost::program_options;
@@ -37,7 +38,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help")){
std::cout << boost::format("UHD Find Devices %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//discover the usrps and print the results
@@ -45,7 +46,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if (device_addrs.size() == 0){
std::cerr << "No UHD Devices Found" << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
for (size_t i = 0; i < device_addrs.size(); i++){
@@ -56,5 +57,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//uhd::device::make(device_addrs[i]); //test make
}
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp
index 5b3702fb4..736490f19 100644
--- a/host/utils/uhd_usrp_probe.cpp
+++ b/host/utils/uhd_usrp_probe.cpp
@@ -30,6 +30,7 @@
#include <iostream>
#include <sstream>
#include <vector>
+#include <cstdlib>
namespace po = boost::program_options;
using namespace uhd;
@@ -197,12 +198,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help")){
std::cout << boost::format("UHD USRP Probe %s") % desc << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
if (vm.count("version")){
std::cout << uhd::get_version_string() << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
device::sptr dev = device::make(vm["args"].as<std::string>());
@@ -210,11 +211,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if (vm.count("string")){
std::cout << tree->access<std::string>(vm["string"].as<std::string>()).get() << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
if (vm.count("tree") != 0) print_tree("/", tree);
else std::cout << make_border(get_device_pp_string(tree)) << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp
index b6b2dc4d6..3ca953115 100644
--- a/host/utils/usrp_burn_db_eeprom.cpp
+++ b/host/utils/usrp_burn_db_eeprom.cpp
@@ -58,7 +58,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
"Omit the ID argument to perform readback,\n"
"Or specify a new ID to burn into the EEPROM.\n"
) << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
//make the device and extract the dboard w/ property
@@ -96,5 +96,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << boost::format(" Current revision: \"%s\"") % db_eeprom.revision << std::endl;
std::cout << " Done" << std::endl << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/host/utils/usrp_burn_mb_eeprom.cpp b/host/utils/usrp_burn_mb_eeprom.cpp
index ca9a6c8ba..1b13fb615 100644
--- a/host/utils/usrp_burn_mb_eeprom.cpp
+++ b/host/utils/usrp_burn_mb_eeprom.cpp
@@ -47,7 +47,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
"Omit the value argument to perform a readback,\n"
"Or specify a new value to burn into the EEPROM.\n"
) << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << "Creating USRP device from address: " + args << std::endl;
@@ -60,7 +60,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
uhd::usrp::mboard_eeprom_t mb_eeprom = tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").get();
if (not mb_eeprom.has_key(key)){
std::cerr << boost::format("Cannot find value for EEPROM[%s]") % key << std::endl;
- return ~0;
+ return EXIT_FAILURE;
}
std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % key % mb_eeprom[key] << std::endl;
std::cout << std::endl;
@@ -74,5 +74,5 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
}
std::cout << "Done" << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}