From a7c1ee2ec7d6673611851f9c55d716359212b729 Mon Sep 17 00:00:00 2001 From: bstapleton Date: Tue, 27 Jun 2017 17:49:18 -0700 Subject: UBX: Added error handling for setting the dboard clock rate. Setting daughterboard clock rate while using UBX on X300 caused an error. Added handling, now throws a warning that the phase will vary. --- host/lib/usrp/dboard/db_ubx.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp index 3dd0b1c84..d9abef599 100644 --- a/host/lib/usrp/dboard/db_ubx.cpp +++ b/host/lib/usrp/dboard/db_ubx.cpp @@ -295,6 +295,7 @@ public: _tx_target_pfd_freq = pfd_freq_max; if (_rev >= 1) { + bool can_set_clock_rate = true; // set dboard clock rates to as close to the max PFD freq as possible if (_iface->get_clock_rate(dboard_iface::UNIT_RX) > pfd_freq_max) { @@ -305,10 +306,15 @@ public: if (rate <= pfd_freq_max and rate > highest_rate) highest_rate = rate; } - _iface->set_clock_rate(dboard_iface::UNIT_RX, highest_rate); + try { + _iface->set_clock_rate(dboard_iface::UNIT_RX, highest_rate); + } catch (const uhd::not_implemented_error &) { + UHD_MSG(warning) << "Unable to set dboard clock rate - phase will vary" << std::endl; + can_set_clock_rate = false; + } _rx_target_pfd_freq = highest_rate; } - if (_iface->get_clock_rate(dboard_iface::UNIT_TX) > pfd_freq_max) + if (can_set_clock_rate and _iface->get_clock_rate(dboard_iface::UNIT_TX) > pfd_freq_max) { std::vector rates = _iface->get_clock_rates(dboard_iface::UNIT_TX); double highest_rate = 0.0; @@ -317,7 +323,11 @@ public: if (rate <= pfd_freq_max and rate > highest_rate) highest_rate = rate; } - _iface->set_clock_rate(dboard_iface::UNIT_TX, highest_rate); + try { + _iface->set_clock_rate(dboard_iface::UNIT_TX, highest_rate); + } catch (const uhd::not_implemented_error &) { + UHD_MSG(warning) << "Unable to set dboard clock rate - phase will vary" << std::endl; + } _tx_target_pfd_freq = highest_rate; } } -- cgit v1.2.3 From 49d3d20e0c71db8454246f95c45ab47eb06496a0 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Fri, 30 Jun 2017 12:03:35 -0700 Subject: examples: Improved output for latency_test --- host/examples/latency_test.cpp | 79 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/host/examples/latency_test.cpp b/host/examples/latency_test.cpp index da06086f9..8d8ead412 100644 --- a/host/examples/latency_test.cpp +++ b/host/examples/latency_test.cpp @@ -58,8 +58,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ " and tries to send a packet at time t + rtt,\n" " where rtt is the round trip time sample time\n" " from device to host and back to the device.\n" + " This can be used to test latency between UHD and the device.\n" + " If the value rtt is chosen too small, the transmit packet will.\n" + " arrive too late at the device indicate an error.\n" + " The smallest value of rtt that does not indicate an error is an\n" + " approximation for the time it takes for a sample packet to\n" + " go to UHD and back to the device." << std::endl; - return ~0; + return EXIT_SUCCESS; } bool verbose = vm.count("verbose") != 0; @@ -74,11 +80,17 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //set the tx sample rate usrp->set_tx_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl; + std::cout + << boost::format("Actual TX Rate: %f Msps...") + % (usrp->get_tx_rate()/1e6) + << std::endl; //set the rx sample rate usrp->set_rx_rate(rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl; + std::cout + << boost::format("Actual RX Rate: %f Msps...") + % (usrp->get_rx_rate()/1e6) + << std::endl; //allocate a buffer to use std::vector > buffer(nsamps); @@ -113,8 +125,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ &buffer.front(), buffer.size(), rx_md ); - if(verbose) std::cout << boost::format("Got packet: %u samples, %u full secs, %f frac secs") - % num_rx_samps % rx_md.time_spec.get_full_secs() % rx_md.time_spec.get_frac_secs() << std::endl; + if (verbose) { + std::cout << boost::format( + "Run %d: Got packet: %u samples, %u full secs, %f frac secs" + ) + % nrun + % num_rx_samps + % rx_md.time_spec.get_full_secs() + % rx_md.time_spec.get_frac_secs() + << std::endl; + } else { + std::cout << "." << std::flush; + } /*************************************************************** * Transmit a packet with delta time after received packet @@ -127,7 +149,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t num_tx_samps = tx_stream->send( &buffer.front(), buffer.size(), tx_md ); - if(verbose) std::cout << boost::format("Sent %d samples") % num_tx_samps << std::endl; + if (verbose) { + std::cout + << boost::format("Sent %d samples") % num_tx_samps + << std::endl; + } /*************************************************************** * Check the async messages for result @@ -159,10 +185,47 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } } + while (true) { + uhd::async_metadata_t async_md; + if (not tx_stream->recv_async_msg(async_md)) { + break; + } + switch(async_md.event_code){ + case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: + time_error++; + break; + + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: + ack++; + break; + + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: + underflow++; + break; + + default: + std::cerr << boost::format( + "failed:\n Got unexpected event code 0x%x.\n" + ) % async_md.event_code << std::endl; + other++; + break; + } + } + if (!verbose) { + std::cout << std::endl; + } + /*************************************************************** * Print the summary **************************************************************/ - std::cout << boost::format("\nACK %d, UNDERFLOW %d, TIME_ERR %d, other %d") - % ack % underflow % time_error % other << std::endl; + std::cout << "Summary\n" + << "================\n" + << "Number of runs: " << nruns << std::endl + << "RTT value tested: " << (rtt*1e3) << " ms" << std::endl + << "ACKs received: " << ack << "/" << nruns << std::endl + << "Underruns: " << underflow << std::endl + << "Late packets: " << time_error << std::endl + << "Other errors: " << other << std::endl + << std::endl; return EXIT_SUCCESS; } -- cgit v1.2.3 From 533b7ea652ebe5acc2ec2a5434284af608a0f521 Mon Sep 17 00:00:00 2001 From: Mark Meserve Date: Thu, 29 Jun 2017 14:59:18 -0500 Subject: cbx: turn on LO LPF at <2GHz instead of <1.5GHz --- host/lib/usrp/dboard/db_sbx_common.cpp | 27 ++++++++++++--------------- host/lib/usrp/dboard/db_sbx_common.hpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp index efc84d7e6..6b8fd8579 100644 --- a/host/lib/usrp/dboard/db_sbx_common.cpp +++ b/host/lib/usrp/dboard/db_sbx_common.cpp @@ -118,27 +118,24 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ switch(get_rx_id().to_uint16()) { case 0x0054: db_actual = sbx_versionx_sptr(new sbx_version3(this)); - freq_range = sbx_freq_range; + freq_range = sbx_freq_range; + enable_rx_lo_filter = sbx_enable_rx_lo_filter; + enable_tx_lo_filter = sbx_enable_tx_lo_filter; break; case 0x0065: - db_actual = sbx_versionx_sptr(new sbx_version4(this)); - freq_range = sbx_freq_range; - break; - case 0x0067: - db_actual = sbx_versionx_sptr(new cbx(this)); - freq_range = cbx_freq_range; - break; case 0x0069: - db_actual = sbx_versionx_sptr(new sbx_version4(this)); - freq_range = sbx_freq_range; - break; case 0x0083: db_actual = sbx_versionx_sptr(new sbx_version4(this)); - freq_range = sbx_freq_range; + freq_range = sbx_freq_range; + enable_rx_lo_filter = sbx_enable_rx_lo_filter; + enable_tx_lo_filter = sbx_enable_tx_lo_filter; break; + case 0x0067: case 0x0085: db_actual = sbx_versionx_sptr(new cbx(this)); - freq_range = cbx_freq_range; + freq_range = cbx_freq_range; + enable_rx_lo_filter = cbx_enable_rx_lo_filter; + enable_tx_lo_filter = cbx_enable_tx_lo_filter; break; default: /* We didn't recognize the version of the board... */ @@ -256,8 +253,8 @@ void sbx_xcvr::update_atr(void){ //calculate atr pins int rx_pga0_iobits = rx_pga0_gain_to_iobits(_rx_gains["PGA0"]); int tx_pga0_iobits = tx_pga0_gain_to_iobits(_tx_gains["PGA0"]); - int rx_lo_lpf_en = (_rx_lo_freq == sbx_enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN : 0; - int tx_lo_lpf_en = (_tx_lo_freq == sbx_enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN : 0; + int rx_lo_lpf_en = (_rx_lo_freq == enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN : 0; + int tx_lo_lpf_en = (_tx_lo_freq == enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN : 0; int rx_ld_led = _rx_lo_lock_cache ? 0 : RX_LED_LD; int tx_ld_led = _tx_lo_lock_cache ? 0 : TX_LED_LD; int rx_ant_led = _rx_ant == "TX/RX" ? RX_LED_RX1RX2 : 0; diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp index ad64e2267..0c0ad3ca7 100644 --- a/host/lib/usrp/dboard/db_sbx_common.hpp +++ b/host/lib/usrp/dboard/db_sbx_common.hpp @@ -116,6 +116,14 @@ static const freq_range_t sbx_enable_rx_lo_filter = list_of (range_t(0.4e9, 1.5e9)) ; +static const freq_range_t cbx_enable_tx_lo_filter = list_of + (range_t(1.2e9, 2e9)) +; + +static const freq_range_t cbx_enable_rx_lo_filter = list_of + (range_t(1.2e9, 2e9)) +; + static const std::vector sbx_tx_antennas = list_of("TX/RX")("CAL"); static const std::vector sbx_rx_antennas = list_of("TX/RX")("RX2")("CAL"); @@ -226,9 +234,12 @@ protected: /*! * CBX daughterboard * - * The only driver difference between SBX and CBX is the MAX2870 vs. ADF435x. - * There is also no LO filter switching required, but the GPIO is left blank - * so we don't worry about it. + * There are a few differences between SBX and CBX + * - The CBX and SBX use the MAX2870 and ADF435x respectively for LOs + * - There are different frequency ranges + * - There are different LO LPF cutoff frequencies + * There is also no LO filter switching required on CBX, but the GPIO is left + * blank so we don't worry about it. */ class cbx : public sbx_versionx { public: @@ -251,6 +262,18 @@ protected: */ freq_range_t freq_range; + /*! + * Frequency range to use the LO LPF in RX; this is set in the constructor + * to correspond either to SBX or CBX. + */ + freq_range_t enable_rx_lo_filter; + + /*! + * Frequency range to use the LO LPF in TX; this is set in the constructor + * to correspond either to SBX or CBX. + */ + freq_range_t enable_tx_lo_filter; + /*! * Handle to the version-specific implementation of the SBX. * -- cgit v1.2.3 From fc0014a77681c6ab539ea6ed76fa3bccf52933dd Mon Sep 17 00:00:00 2001 From: bstapleton Date: Thu, 29 Jun 2017 13:20:00 -0700 Subject: x300: Changed discovery to return early if we find the serial requested --- host/lib/usrp/x300/x300_impl.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 71cb7f341..8f6e52523 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -333,7 +333,21 @@ device_addrs_t x300_find(const device_addr_t &hint_) //call discover with the new hint and append results device_addrs_t new_addrs = x300_find(new_hint); - addrs.insert(addrs.begin(), new_addrs.begin(), new_addrs.end()); + //if we are looking for a serial, only add the one device with a matching serial + if (hint.has_key("serial")) { + bool found_serial = false; //signal to break out of the interface loop + for (device_addrs_t::iterator new_addr_it=new_addrs.begin(); new_addr_it != new_addrs.end(); new_addr_it++) { + if ((*new_addr_it)["serial"] == hint["serial"]) { + addrs.emplace(addrs.begin(), *new_addr_it); + found_serial = true; + break; + } + } + if (found_serial) break; + } else { + // Otherwise, add all devices we find + addrs.insert(addrs.begin(), new_addrs.begin(), new_addrs.end()); + } } } -- cgit v1.2.3 From 7ac01c7f979aab8fac5e62f596ff0af52cedec40 Mon Sep 17 00:00:00 2001 From: Brent Stapleton Date: Wed, 5 Jul 2017 09:44:48 -0700 Subject: fixup! x300: Changed discovery to return early if we find the serial requested --- host/lib/usrp/x300/x300_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 8f6e52523..84087c6f1 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -338,7 +338,7 @@ device_addrs_t x300_find(const device_addr_t &hint_) bool found_serial = false; //signal to break out of the interface loop for (device_addrs_t::iterator new_addr_it=new_addrs.begin(); new_addr_it != new_addrs.end(); new_addr_it++) { if ((*new_addr_it)["serial"] == hint["serial"]) { - addrs.emplace(addrs.begin(), *new_addr_it); + addrs.insert(addrs.begin(), *new_addr_it); found_serial = true; break; } -- cgit v1.2.3 From 6ff5cd4f8c92b43b2a38d292d1e2dc046696eb1f Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Fri, 7 Jul 2017 10:17:43 -0700 Subject: CHANGELOG: Imported overlap from 3.9.LTS branch --- CHANGELOG | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 69aae6a91..3f573575a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,20 @@ Change Log for Releases ============================== +## 003.010.001.002 +* multi_usrp: Fixed get_normalized_tx_gain. +* E300: Fix for streamer recreation issue +* X300: Fix for network discovery, will now return early when correct serial is + found. +* CBX: Fixed LO LPF behaviour in 1.5-2 GHz range. +* UBX: Fixed dtor SIGABRT issue. +* GPSDO: Improved detection. +* Examples: Added channel param to samps to/from file. sync_to_gps exits instead + of uncaught throw. +* C API: Fixed some missing fields in USRP info. +* Docs: Many minor fixes. +* CMake: Fixed GCC 4.4 compilation issue. Added ability to specify package + names. ## 003.010.001.001 -- cgit v1.2.3 From 38723f62183227068dc3163278cd7d2de8c01218 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Thu, 6 Jul 2017 14:04:17 -0700 Subject: converters: Added some tolerance for floating point-based tests to account for acceptable rounding --- host/tests/convert_test.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index dd04dcafc..cd31a7846 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -551,7 +551,10 @@ static void test_convert_types_fc32( std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end()); + for (size_t i = 0; i < nsamps; i++){ + MY_CHECK_CLOSE(input[i].real(), output[i].real(), float(1./(1 << 16))); + MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), float(1./(1 << 16))); + } } BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_fc32){ @@ -589,7 +592,9 @@ static void test_convert_types_f32( std::swap(out_id.input_format, out_id.output_format); std::swap(out_id.num_inputs, out_id.num_outputs); loopback(nsamps, in_id, out_id, input, output); - BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end()); + for (size_t i = 0; i < nsamps; i++){ + MY_CHECK_CLOSE(input[i], output[i], float(1./(1 << 16))); + } } BOOST_AUTO_TEST_CASE(test_convert_types_f32_and_f32){ -- cgit v1.2.3 From 684fd3a3ffaf31b9fa726ccf2fdea2627f6ea10d Mon Sep 17 00:00:00 2001 From: Derek Kozel Date: Fri, 14 Jul 2017 13:18:10 +0100 Subject: utils: Added warnings and checks to images downloader --- host/utils/uhd_images_downloader.py.in | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/host/utils/uhd_images_downloader.py.in b/host/utils/uhd_images_downloader.py.in index 593f7759f..84be10902 100644 --- a/host/utils/uhd_images_downloader.py.in +++ b/host/utils/uhd_images_downloader.py.in @@ -252,6 +252,8 @@ def main(): help="Do not clear images directory before extracting new files [default=%default]") parser.add_option("-v", "--verbose", action="store_true", default=False, help="Enable verbose output [default=%default]") + parser.add_option("--force-delete", action="store_true", default=False, + help="Delete all files in the target images directory without prompting [default=%default]") (options, args) = parser.parse_args() if options.buffer_size <= 0: print("Invalid buffer size: %s" % (options.buffer_size)) @@ -287,6 +289,18 @@ def main(): else: print("Images destination: %s" % (images_dir)) + ### Check contradictory arguments + if options.force_delete and options.keep: + print("Error: Keep and force delete options contradict.\n") + parser.print_help() + return 1 + + ### Prevent accidental file deletion + if options.install_location != default_images_dir and options.force_delete == False and options.keep != True: + print("Custom install location specified, defaulting to overwriting only image files.\n" + "Use \'--force-delete\' to clean the target directory first.") + options.keep = True + ### Download or copy downloader = uhd_images_downloader() try: -- cgit v1.2.3