summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/docs/dboards.rst4
-rw-r--r--host/docs/usrp2.rst11
-rw-r--r--host/examples/CMakeLists.txt14
-rw-r--r--host/examples/test_async_messages.cpp208
-rw-r--r--host/examples/test_pps_input.cpp (renamed from host/examples/pps_test.cpp)2
-rw-r--r--host/lib/transport/CMakeLists.txt6
-rw-r--r--host/lib/usrp/usrp1/CMakeLists.txt32
-rw-r--r--host/lib/usrp/usrp2/CMakeLists.txt59
-rw-r--r--host/utils/usrp_burn_db_eeprom.cpp15
9 files changed, 307 insertions, 44 deletions
diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst
index 0f6d1cfeb..985fbc12b 100644
--- a/host/docs/dboards.rst
+++ b/host/docs/dboards.rst
@@ -141,7 +141,7 @@ With the daughterboard plugged-in, run the following commands:
::
cd <prefix>/share/uhd/utils
- ./usrp_burn_db_eeprom --id=0x000d --unit=RX --args=<args> --db=<db>
+ ./usrp_burn_db_eeprom --id=0x000d --unit=RX --args=<args> --slot=<slot>
* <args> are device address arguments (optional if only one USRP is on your machine)
-* <db> is the name of the daughterboard slot (optional if the USRP has only one slot)
+* <slot> is the name of the daughterboard slot (optional if the USRP has only one slot)
diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst
index 0d48209be..745361b77 100644
--- a/host/docs/usrp2.rst
+++ b/host/docs/usrp2.rst
@@ -213,10 +213,19 @@ Hardware setup notes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ref Clock - 10MHz
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Using an external 10MHz reference clock requires a signal level between +5dBm and +20dBm at 10MHz applied to the Ref Clock SMA port on the front panel.
+Using an external 10MHz reference clock requires a signal level between
++5dBm and +20dBm at 10MHz applied to the Ref Clock SMA port on the front panel.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PPS - Pulse Per Second
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using a PPS signal for timestamp synchronization requires a 5Vpp square wave signal
+
+Test the PPS input of the USRP2 with the following app:
+::
+
+ cd <prefix>/share/uhd/examples
+ ./test_pps_input --args=<args>
+
+* <args> are device address arguments (optional if only one USRP is on your machine)
diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt
index 7da31a16b..fb7777d42 100644
--- a/host/examples/CMakeLists.txt
+++ b/host/examples/CMakeLists.txt
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-
+########################################################################
ADD_EXECUTABLE(benchmark_rx_rate benchmark_rx_rate.cpp)
TARGET_LINK_LIBRARIES(benchmark_rx_rate uhd)
@@ -25,6 +25,12 @@ TARGET_LINK_LIBRARIES(rx_timed_samples uhd)
ADD_EXECUTABLE(rx_to_file rx_to_file.cpp)
TARGET_LINK_LIBRARIES(rx_to_file uhd)
+ADD_EXECUTABLE(test_async_messages test_async_messages.cpp)
+TARGET_LINK_LIBRARIES(test_async_messages uhd)
+
+ADD_EXECUTABLE(test_pps_input test_pps_input.cpp)
+TARGET_LINK_LIBRARIES(test_pps_input uhd)
+
ADD_EXECUTABLE(tx_timed_samples tx_timed_samples.cpp)
TARGET_LINK_LIBRARIES(tx_timed_samples uhd)
@@ -34,16 +40,14 @@ TARGET_LINK_LIBRARIES(tx_from_file uhd)
ADD_EXECUTABLE(tx_waveforms tx_waveforms.cpp)
TARGET_LINK_LIBRARIES(tx_waveforms uhd)
-ADD_EXECUTABLE(pps_test pps_test.cpp)
-TARGET_LINK_LIBRARIES(pps_test uhd)
-
INSTALL(TARGETS
benchmark_rx_rate
rx_timed_samples
+ test_async_messages
+ test_pps_input
tx_timed_samples
tx_from_file
rx_to_file
tx_waveforms
- pps_test
RUNTIME DESTINATION ${PKG_DATA_DIR}/examples
)
diff --git a/host/examples/test_async_messages.cpp b/host/examples/test_async_messages.cpp
new file mode 100644
index 000000000..e02bc5f40
--- /dev/null
+++ b/host/examples/test_async_messages.cpp
@@ -0,0 +1,208 @@
+//
+// 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/thread_priority.hpp>
+#include <uhd/utils/safe_main.hpp>
+#include <uhd/utils/static.hpp>
+#include <uhd/usrp/simple_usrp.hpp>
+#include <boost/program_options.hpp>
+#include <boost/format.hpp>
+#include <complex>
+#include <iostream>
+
+namespace po = boost::program_options;
+
+static const size_t async_to_ms = 100;
+
+/*!
+ * Test that no messages are received:
+ * Send a burst of many samples that will fragment internally.
+ * We expect to not get any async messages.
+ */
+void test_no_async_message(uhd::usrp::simple_usrp::sptr sdev){
+ uhd::device::sptr dev = sdev->get_device();
+ std::cout << "Test no async message... " << std::flush;
+
+ uhd::tx_metadata_t md;
+ md.start_of_burst = true;
+ md.end_of_burst = true;
+ md.has_time_spec = false;
+
+ //3 times max-sps guarantees a SOB, no burst, and EOB packet
+ std::vector<std::complex<float> > buff(dev->get_max_send_samps_per_packet()*3);
+
+ dev->send(
+ &buff.front(), buff.size(), md,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::SEND_MODE_FULL_BUFF
+ );
+
+ uhd::async_metadata_t async_md;
+ if (dev->recv_async_msg(async_md, async_to_ms)){
+ std::cout << boost::format(
+ "failed:\n"
+ " Got unexpected event code 0x%x.\n"
+ ) % async_md.event_code << std::endl;
+ //clear the async messages
+ while (dev->recv_async_msg(async_md, 0));
+ }
+ else{
+ std::cout << boost::format(
+ "success:\n"
+ " Did not get an async message.\n"
+ ) << std::endl;
+ }
+}
+
+/*!
+ * Test the underflow message:
+ * Send a start of burst packet with no following end of burst.
+ * We expect to get an underflow(within a burst) async message.
+ */
+void test_underflow_message(uhd::usrp::simple_usrp::sptr sdev){
+ uhd::device::sptr dev = sdev->get_device();
+ std::cout << "Test underflow message... " << std::flush;
+
+ uhd::tx_metadata_t md;
+ md.start_of_burst = true;
+ md.end_of_burst = false;
+ md.has_time_spec = false;
+
+ dev->send(NULL, 0, md,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::SEND_MODE_FULL_BUFF
+ );
+
+ uhd::async_metadata_t async_md;
+ if (not dev->recv_async_msg(async_md, async_to_ms)){
+ std::cout << boost::format(
+ "failed:\n"
+ " Async message recv timed out.\n"
+ ) << std::endl;
+ return;
+ }
+
+ switch(async_md.event_code){
+ case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW:
+ std::cout << boost::format(
+ "success:\n"
+ " Got event code underflow message.\n"
+ ) << std::endl;
+ break;
+
+ default:
+ std::cout << boost::format(
+ "failed:\n"
+ " Got unexpected event code 0x%x.\n"
+ ) % async_md.event_code << std::endl;
+ }
+}
+
+/*!
+ * Test the time error message:
+ * Send a burst packet that occurs at a time in the past.
+ * We expect to get a time error async message.
+ */
+void test_time_error_message(uhd::usrp::simple_usrp::sptr sdev){
+ uhd::device::sptr dev = sdev->get_device();
+ std::cout << "Test time error message... " << std::flush;
+
+ uhd::tx_metadata_t md;
+ md.start_of_burst = true;
+ md.end_of_burst = true;
+ md.has_time_spec = true;
+ md.time_spec = uhd::time_spec_t(100.0); //send at 100s
+
+ sdev->set_time_now(uhd::time_spec_t(200.0)); //time at 200s
+
+ dev->send(NULL, 0, md,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::SEND_MODE_FULL_BUFF
+ );
+
+ uhd::async_metadata_t async_md;
+ if (not dev->recv_async_msg(async_md, async_to_ms)){
+ std::cout << boost::format(
+ "failed:\n"
+ " Async message recv timed out.\n"
+ ) << std::endl;
+ return;
+ }
+
+ switch(async_md.event_code){
+ case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR:
+ std::cout << boost::format(
+ "success:\n"
+ " Got event code time error message.\n"
+ ) << std::endl;
+ break;
+
+ default:
+ std::cout << boost::format(
+ "failed:\n"
+ " Got unexpected event code 0x%x.\n"
+ ) % async_md.event_code << std::endl;
+ }
+}
+
+int UHD_SAFE_MAIN(int argc, char *argv[]){
+ uhd::set_thread_priority_safe();
+
+ //variables to be set by po
+ std::string args;
+ double rate;
+
+ //setup the program options
+ po::options_description desc("Allowed options");
+ desc.add_options()
+ ("help", "help message")
+ ("args", po::value<std::string>(&args)->default_value(""), "simple uhd device address args")
+ ("rate", po::value<double>(&rate)->default_value(1.5e6), "rate of outgoing samples")
+ ;
+ 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("UHD Test Async Messages %s") % desc << std::endl;
+ return ~0;
+ }
+
+ //create a usrp device
+ std::cout << std::endl;
+ std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
+ uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args);
+ std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl;
+
+ //set the tx sample rate
+ std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl;
+ sdev->set_tx_rate(rate);
+ std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl << std::endl;
+
+ //------------------------------------------------------------------
+ // begin asyc messages test
+ //------------------------------------------------------------------
+ test_no_async_message(sdev);
+ test_underflow_message(sdev);
+ test_time_error_message(sdev);
+
+ //finished
+ std::cout << std::endl << "Done!" << std::endl << std::endl;
+
+ return 0;
+}
diff --git a/host/examples/pps_test.cpp b/host/examples/test_pps_input.cpp
index c25cbe94f..e01d32910 100644
--- a/host/examples/pps_test.cpp
+++ b/host/examples/test_pps_input.cpp
@@ -45,7 +45,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//print the help message
if (vm.count("help")){
- std::cout << boost::format("UHD PPS Test %s") % desc << std::endl;
+ std::cout << boost::format("UHD Test PPS Input %s") % desc << std::endl;
return ~0;
}
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index 43449d732..96ef8e505 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -35,6 +35,12 @@ IF(LIBUSB_FOUND)
SET(HAVE_USB_SUPPORT TRUE)
ENDIF(LIBUSB_FOUND)
+IF(HAVE_USB_SUPPORT)
+ MESSAGE(STATUS "Has USB support - found")
+ELSE(HAVE_USB_SUPPORT)
+ MESSAGE(STATUS "Has USB support - not found")
+ENDIF(HAVE_USB_SUPPORT)
+
########################################################################
# Check for SIMD headers
########################################################################
diff --git a/host/lib/usrp/usrp1/CMakeLists.txt b/host/lib/usrp/usrp1/CMakeLists.txt
index 229a4ce63..67487f99e 100644
--- a/host/lib/usrp/usrp1/CMakeLists.txt
+++ b/host/lib/usrp/usrp1/CMakeLists.txt
@@ -20,18 +20,26 @@
########################################################################
# Conditionally configure the USRP1 support
########################################################################
-MESSAGE(STATUS "Configuring usrp1 support...")
+MESSAGE(STATUS "Configuring USRP1 support...")
-IF(HAVE_USB_SUPPORT)
- MESSAGE(STATUS "Has USB support - found")
-ELSE(HAVE_USB_SUPPORT)
- MESSAGE(STATUS "Has USB support - not found")
-ENDIF(HAVE_USB_SUPPORT)
+IF(DEFINED ENABLE_USRP1)
+ IF(ENABLE_USRP1)
+ MESSAGE(STATUS "USRP1 support enabled by configure flag")
+ ELSE(ENABLE_USRP1)
+ MESSAGE(STATUS "USRP1 support disabled by configure flag")
+ ENDIF(ENABLE_USRP1)
+ELSE(DEFINED ENABLE_USRP1) #not defined: automatic enabling of component
+ SET(ENABLE_USRP1 ${HAVE_USB_SUPPORT})
+ENDIF(DEFINED ENABLE_USRP1)
+SET(ENABLE_USRP1 ${ENABLE_USRP1} CACHE BOOL "enable USRP1 support")
-#TODO check for usrp1 enable/disable option flag
+#sanity check when USRP1 support enabled
+IF(ENABLE_USRP1 AND NOT HAVE_USB_SUPPORT)
+ MESSAGE(FATAL_ERROR "USRP1 support enabled without USB support")
+ENDIF(ENABLE_USRP1 AND NOT HAVE_USB_SUPPORT)
-IF(HAVE_USB_SUPPORT)
- MESSAGE(STATUS " Building usrp1 support.")
+IF(ENABLE_USRP1)
+ MESSAGE(STATUS " Building USRP1 support.")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../firmware/fx2/include)
LIBUHD_APPEND_SOURCES(
@@ -52,6 +60,6 @@ IF(HAVE_USB_SUPPORT)
${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_ctrl.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_ctrl.hpp
)
-ELSE(HAVE_USB_SUPPORT)
- MESSAGE(STATUS " Skipping usrp1 support.")
-ENDIF(HAVE_USB_SUPPORT)
+ELSE(ENABLE_USRP1)
+ MESSAGE(STATUS " Skipping USRP1 support.")
+ENDIF(ENABLE_USRP1)
diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt
index 796126d07..078485d6a 100644
--- a/host/lib/usrp/usrp2/CMakeLists.txt
+++ b/host/lib/usrp/usrp2/CMakeLists.txt
@@ -17,22 +17,43 @@
#This file will be included by cmake, use absolute paths!
-LIBUHD_APPEND_SOURCES(
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_ctrl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_ctrl.hpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_ctrl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_ctrl.hpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_impl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.hpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.hpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.hpp
- ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.hpp
-)
+########################################################################
+# Conditionally configure the USRP2 support
+########################################################################
+MESSAGE(STATUS "Configuring USRP2 support...")
+
+IF(DEFINED ENABLE_USRP2)
+ IF(ENABLE_USRP2)
+ MESSAGE(STATUS "USRP2 support enabled by configure flag")
+ ELSE(ENABLE_USRP2)
+ MESSAGE(STATUS "USRP2 support disabled by configure flag")
+ ENDIF(ENABLE_USRP2)
+ELSE(DEFINED ENABLE_USRP2) #not defined: automatic enabling of component
+ SET(ENABLE_USRP2 TRUE)
+ENDIF(DEFINED ENABLE_USRP2)
+SET(ENABLE_USRP2 ${ENABLE_USRP2} CACHE BOOL "enable USRP2 support")
+
+IF(ENABLE_USRP2)
+ MESSAGE(STATUS " Building USRP2 support.")
+ LIBUHD_APPEND_SOURCES(
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_ctrl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_ctrl.hpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_ctrl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_ctrl.hpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.hpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.hpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.hpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.hpp
+ )
+ELSE(ENABLE_USRP2)
+ MESSAGE(STATUS " Skipping USRP2 support.")
+ENDIF(ENABLE_USRP2)
diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp
index db2981e87..64ecf75d6 100644
--- a/host/utils/usrp_burn_db_eeprom.cpp
+++ b/host/utils/usrp_burn_db_eeprom.cpp
@@ -19,6 +19,7 @@
#include <uhd/utils/safe_main.hpp>
#include <uhd/device.hpp>
#include <uhd/types/dict.hpp>
+#include <uhd/utils/assert.hpp>
#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/device_props.hpp>
#include <uhd/usrp/mboard_props.hpp>
@@ -34,16 +35,19 @@ namespace po = boost::program_options;
int UHD_SAFE_MAIN(int argc, char *argv[]){
//command line variables
- std::string args, db_name, unit;
+ std::string args, slot, unit;
static const uhd::dict<std::string, mboard_prop_t> unit_to_db_prop = boost::assign::map_list_of
("RX", MBOARD_PROP_RX_DBOARD) ("TX", MBOARD_PROP_TX_DBOARD)
;
+ static const uhd::dict<std::string, mboard_prop_t> unit_to_db_names_prop = boost::assign::map_list_of
+ ("RX", MBOARD_PROP_RX_DBOARD_NAMES) ("TX", MBOARD_PROP_TX_DBOARD_NAMES)
+ ;
po::options_description desc("Allowed options");
desc.add_options()
("help", "help message")
("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
- ("db", po::value<std::string>(&db_name)->default_value(""), "dboard name [default = \"\"]")
+ ("slot", po::value<std::string>(&slot)->default_value(""), "dboard slot name [default is blank for automatic]")
("unit", po::value<std::string>(&unit)->default_value(""), "which unit [RX or TX]")
("id", po::value<std::string>(), "dboard id to burn, omit for readback")
;
@@ -70,8 +74,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
//make the device and extract the dboard w/ property
device::sptr dev = device::make(args);
- wax::obj dboard = (*dev)[DEVICE_PROP_MBOARD][named_prop_t(unit_to_db_prop[unit], db_name)];
- std::string prefix = (db_name == "")? unit : (unit + ":" + db_name);
+ uhd::prop_names_t dboard_names = (*dev)[DEVICE_PROP_MBOARD][unit_to_db_names_prop[unit]].as<uhd::prop_names_t>();
+ if (dboard_names.size() == 1 and slot.empty()) slot = dboard_names.front();
+ uhd::assert_has(dboard_names, slot, "dboard slot name");
+ wax::obj dboard = (*dev)[DEVICE_PROP_MBOARD][named_prop_t(unit_to_db_prop[unit], slot)];
+ std::string prefix = unit + ":" + slot;
//read the current dboard id from eeprom
if (vm.count("id") == 0){