From 1a51d7e050d70fae1c4b750892102a5540a0587e Mon Sep 17 00:00:00 2001 From: Nicholas Corgan Date: Tue, 22 Mar 2016 09:16:20 -0700 Subject: Added missing stdint.h include --- host/lib/usrp/common/max287x.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/host/lib/usrp/common/max287x.hpp b/host/lib/usrp/common/max287x.hpp index 644ec726e..596d992e0 100644 --- a/host/lib/usrp/common/max287x.hpp +++ b/host/lib/usrp/common/max287x.hpp @@ -1,5 +1,5 @@ // -// Copyright 2015 Ettus Research LLC +// Copyright 2015-2016 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 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "max2870_regs.hpp" #include "max2871_regs.hpp" -- cgit v1.2.3 From 47aa63a871ab37f3a4c475ed905de178d1a55639 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 28 Jan 2016 17:00:03 +0100 Subject: Unroll the loops in the NEON float to/from integer converters. Unrolling the RX loop showed marked improvement with perf. The TX path was only slightly better. Checked signal correctness with shinysdr to verify received signal and tx_waveforms into a spectrum analyzer for TX. Signed-off-by: Philip Balister --- host/lib/convert/convert_with_neon.cpp | 48 ++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/host/lib/convert/convert_with_neon.cpp b/host/lib/convert/convert_with_neon.cpp index f1c7773ec..a172afb54 100644 --- a/host/lib/convert/convert_with_neon.cpp +++ b/host/lib/convert/convert_with_neon.cpp @@ -34,13 +34,35 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){ size_t i; float32x4_t Q0 = vdupq_n_f32(float(scale_factor)); - for (i=0; i < (nsamps & ~0x03); i+=2) { + for (i=0; i < (nsamps & ~0x0f); i+=8) { float32x4_t Q1 = vld1q_f32(reinterpret_cast(&input[i])); + float32x4_t Q4 = vld1q_f32(reinterpret_cast(&input[i+2])); + float32x4_t Q7 = vld1q_f32(reinterpret_cast(&input[i+4])); + float32x4_t Q10 = vld1q_f32(reinterpret_cast(&input[i+6])); + float32x4_t Q2 = vmulq_f32(Q1, Q0); int32x4_t Q3 = vcvtq_s32_f32(Q2); int16x4_t D8 = vmovn_s32(Q3); int16x4_t D9 = vrev32_s16(D8); vst1_s16((reinterpret_cast(&output[i])), D9); + + float32x4_t Q5 = vmulq_f32(Q4, Q0); + int32x4_t Q6 = vcvtq_s32_f32(Q5); + int16x4_t D10 = vmovn_s32(Q6); + int16x4_t D11 = vrev32_s16(D10); + vst1_s16((reinterpret_cast(&output[i+2])), D11); + + float32x4_t Q8 = vmulq_f32(Q7, Q0); + int32x4_t Q9 = vcvtq_s32_f32(Q8); + int16x4_t D12 = vmovn_s32(Q9); + int16x4_t D13 = vrev32_s16(D12); + vst1_s16((reinterpret_cast(&output[i+4])), D13); + + float32x4_t Q11 = vmulq_f32(Q10, Q0); + int32x4_t Q13 = vcvtq_s32_f32(Q11); + int16x4_t D14 = vmovn_s32(Q13); + int16x4_t D15 = vrev32_s16(D14); + vst1_s16((reinterpret_cast(&output[i+6])), D15); } xx_to_item32_sc16(input+i, output+i, nsamps-i, scale_factor); @@ -53,13 +75,35 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){ size_t i; float32x4_t Q1 = vdupq_n_f32(float(scale_factor)); - for (i=0; i < (nsamps & ~0x03); i+=2) { + for (i=0; i < (nsamps & ~0xf); i+=8) { int16x4_t D0 = vld1_s16(reinterpret_cast(&input[i])); + int16x4_t D2 = vld1_s16(reinterpret_cast(&input[i+2])); + int16x4_t D4 = vld1_s16(reinterpret_cast(&input[i+4])); + int16x4_t D6 = vld1_s16(reinterpret_cast(&input[i+6])); + int16x4_t D1 = vrev32_s16(D0); int32x4_t Q2 = vmovl_s16(D1); float32x4_t Q3 = vcvtq_f32_s32(Q2); float32x4_t Q4 = vmulq_f32(Q3, Q1); vst1q_f32((reinterpret_cast(&output[i])), Q4); + + int16x4_t D3 = vrev32_s16(D2); + int32x4_t Q5 = vmovl_s16(D3); + float32x4_t Q6 = vcvtq_f32_s32(Q5); + float32x4_t Q7 = vmulq_f32(Q6, Q1); + vst1q_f32((reinterpret_cast(&output[i+2])), Q7); + + int16x4_t D5 = vrev32_s16(D4); + int32x4_t Q8 = vmovl_s16(D5); + float32x4_t Q9 = vcvtq_f32_s32(Q8); + float32x4_t Q10 = vmulq_f32(Q9, Q1); + vst1q_f32((reinterpret_cast(&output[i+4])), Q10); + + int16x4_t D7 = vrev32_s16(D6); + int32x4_t Q11 = vmovl_s16(D7); + float32x4_t Q12 = vcvtq_f32_s32(Q11); + float32x4_t Q13 = vmulq_f32(Q12, Q1); + vst1q_f32((reinterpret_cast(&output[i+6])), Q13); } item32_sc16_to_xx(input+i, output+i, nsamps-i, scale_factor); -- cgit v1.2.3 From f2eb8839223a9c3be487846b9597f9ef8c9a9d28 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Thu, 24 Mar 2016 11:45:18 -0700 Subject: cmake: Added installation of .reg file --- host/utils/CMakeLists.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 28fecc895..9f0a6afef 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -173,4 +173,18 @@ IF(ENABLE_USRP2) ENDIF(ENABLE_USRP2) +######################################################################## +# Other files that are not utilities or executables +######################################################################## +IF(WIN32) + SET(windows_extra_files + FastSendDatagramThreshold.reg + ) + UHD_INSTALL( + FILES ${windows_extra_files} + DESTINATION ${PKG_DATA_DIR} + COMPONENT utilities + ) +ENDIF(WIN32) + ADD_SUBDIRECTORY(latency) -- cgit v1.2.3 From 7b54874264c8b9371c9ca88b0f420e9da5087075 Mon Sep 17 00:00:00 2001 From: Marcus Müller Date: Tue, 10 Nov 2015 16:54:17 -0800 Subject: utils: Updated query_gpsdo_sensors * Beautified the tool: * better help messages, argument description * removed device-specific warning about external clock source being unavailable * if instant LO lock cannot be achieved, wait a few seconds * try/catches don't swallow unrelated errors * copyright year * Since time is no longer auto-set on GPSDO, fix that --- host/utils/query_gpsdo_sensors.cpp | 121 +++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 31 deletions(-) diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp index 3b98a634c..4c17c6044 100644 --- a/host/utils/query_gpsdo_sensors.cpp +++ b/host/utils/query_gpsdo_sensors.cpp @@ -1,5 +1,5 @@ // -// Copyright 2012,2014 Ettus Research LLC +// Copyright 2012,2014,2015 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,7 +38,6 @@ void print_notes(void) { 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"); } @@ -51,7 +50,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") - ("args", po::value(&args)->default_value(""), "Specify a single USRP.") + ("args", po::value(&args)->default_value(""), "Device address arguments specifying a single USRP") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -59,8 +58,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //Print the help message if (vm.count("help")) { - std::cout << boost::format("Query GPSDO Sensors %s") % desc << std::endl; - return EXIT_FAILURE; + std::cout << boost::format("Query GPSDO Sensors, try to lock the reference oscillator to the GPS disciplined clock, and set the device time to GPS time") + << std::endl + << std::endl + << desc; + return EXIT_FAILURE; } //Create a USRP device @@ -68,9 +70,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); - print_notes(); - - //Verify GPS sensors are present (i.e. EEPROM has been burnt) std::vector sensor_names = usrp->get_mboard_sensor_names(0); @@ -82,38 +81,96 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ exit(EXIT_FAILURE); } + // Explicitly set time source to gpsdo + boost::this_thread::sleep(boost::posix_time::seconds(1)); + try { + usrp->set_time_source("gpsdo"); + } catch (uhd::value_error &e) { + std::cout << "could not set the time source to \"gpsdo\"; error was:" <set_time_source("external"); + } catch (uhd::value_error &e) { + std::cout << "\"external\" failed, too." << std::endl; + } + } + std::cout<< std::endl << "Time source is now " << usrp->get_time_source(0) << std::endl; + //Check for GPS lock uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0); if(not gps_locked.to_bool()) { - 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"); + 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"); + } + + std::cout << "\nSetting the reference clock source to \"gpsdo\"...\n"; + try { + usrp->set_clock_source("gpsdo"); + } catch (uhd::value_error &e) { + std::cout << "could not set the clock source to \"gpsdo\"; error was:" <set_clock_source("external"); + } catch (uhd::value_error &e) { + std::cout << "\"external\" failed, too." << std::endl; + } + } + std::cout<< std::endl << "Clock source is now " << usrp->get_clock_source(0) << std::endl; + + print_notes(); + //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(not gps_locked.to_bool()) { - std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n"); - std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.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"); - - // Explicitly set time source to gpsdo - usrp->set_time_source("gpsdo"); + uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("ref_locked",0); + if(not gps_locked.to_bool()) { + std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n"); + std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n"); + std::cout << boost::format("Locking the internal reference to the GPSDO might take a second to reach stability. Retrying in 10 s...\n\n"); + boost::this_thread::sleep(boost::posix_time::seconds(10)); + } + if(usrp->get_mboard_sensor("ref_locked",0).to_bool()) { + 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 boost::this_thread::sleep(boost::posix_time::seconds(1)); uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time"); - const time_t pc_clock_time = time(NULL); - const uhd::time_spec_t last_pps_time = usrp->get_time_last_pps(); + uhd::time_spec_t last_pps_time = usrp->get_time_last_pps(); + + //we only care about the full seconds + signed gps_seconds = gps_time.to_int(); + long long pps_seconds = last_pps_time.to_ticks(1.0); + + if(pps_seconds != gps_seconds) { + std::cout << boost::format("\nGPS and UHD Device time are NOT aligned;\nlast_pps: %ld vs gps: %ld. Trying to set the device time to GPS time...") + % pps_seconds % gps_seconds + << std::endl; + //full next after next second + uhd::time_spec_t next_pps_time(gps_seconds + 2.0); + //instruct the USRP to wait for the next PPS edge, then set the new time on the following PPS + usrp->set_time_unknown_pps(next_pps_time); + //allow some time to make sure the PPS has come… + boost::this_thread::sleep(boost::posix_time::seconds(1.1)); + //…then ask + gps_seconds = usrp->get_mboard_sensor("gps_time").to_int(); + pps_seconds = usrp->get_time_last_pps().to_ticks(1.0); + } - if (last_pps_time.to_ticks(1.0) == gps_time.to_int()) { + std::cout << boost::format("last_pps: %ld vs gps: %ld.") + % pps_seconds % gps_seconds + << std::endl; + if (pps_seconds == gps_seconds) { 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 last_pps: %ld vs gps: %ld. Try re-running the program. Double check 1 PPS connection from GPSDO.\n\n") % last_pps_time.to_ticks(1.0) % gps_time.to_int() << std::endl; + std::cout << boost::format("Could not align UHD Device time to GPS time. Giving up.\n"); } //print NMEA strings @@ -121,12 +178,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ 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("Printing available NMEA strings:\n"); - 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(); - } catch (std::exception &) { + std::cout << boost::format("%s\n%s\n") % gga_string.to_pp_string() % rmc_string.to_pp_string(); + } catch (uhd::lookup_error &e) { std::cout << "NMEA strings not implemented for this device." << std::endl; } - std::cout << boost::format("UHD Device time: %.0f seconds\n") % (last_pps_time.get_real_secs()); - std::cout << boost::format("PC Clock time: %.0f seconds\n") % pc_clock_time; + std::cout << boost::format("GPS Epoch time at last PPS: %.5f seconds\n") % usrp->get_mboard_sensor("gps_time").to_real(); + std::cout << boost::format("UHD Device time last PPS: %.5f seconds\n") % (usrp->get_time_last_pps().get_real_secs()); + std::cout << boost::format("UHD Device time right now: %.5f seconds\n") % (usrp->get_time_now().get_real_secs()); + std::cout << boost::format("PC Clock time: %.5f seconds\n") % time(NULL); //finished std::cout << boost::format("\nDone!\n\n"); -- cgit v1.2.3 From 8bfc4f541c083a60d27113897b0e7bacbc395717 Mon Sep 17 00:00:00 2001 From: Nicholas Corgan Date: Fri, 15 Jan 2016 12:36:06 -0800 Subject: query_gpsdo_sensors: fixed sleep time --- host/utils/query_gpsdo_sensors.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp index 4c17c6044..21d26e81e 100644 --- a/host/utils/query_gpsdo_sensors.cpp +++ b/host/utils/query_gpsdo_sensors.cpp @@ -1,5 +1,5 @@ // -// Copyright 2012,2014,2015 Ettus Research LLC +// Copyright 2012,2014-2016 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 @@ -158,7 +158,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //instruct the USRP to wait for the next PPS edge, then set the new time on the following PPS usrp->set_time_unknown_pps(next_pps_time); //allow some time to make sure the PPS has come… - boost::this_thread::sleep(boost::posix_time::seconds(1.1)); + boost::this_thread::sleep(boost::posix_time::milliseconds(1100)); //…then ask gps_seconds = usrp->get_mboard_sensor("gps_time").to_int(); pps_seconds = usrp->get_time_last_pps().to_ticks(1.0); -- cgit v1.2.3