diff options
Diffstat (limited to 'host/utils')
-rw-r--r-- | host/utils/b2xx_fx3_utils.cpp | 342 | ||||
-rw-r--r-- | host/utils/converter_benchmark.cpp | 278 | ||||
-rw-r--r-- | host/utils/fx2_init_eeprom.cpp | 136 | ||||
-rw-r--r-- | host/utils/latency/include/Responder.hpp | 538 | ||||
-rw-r--r-- | host/utils/latency/lib/Responder.cpp | 1089 | ||||
-rw-r--r-- | host/utils/latency/responder.cpp | 47 | ||||
-rw-r--r-- | host/utils/octoclock_burn_eeprom.cpp | 63 | ||||
-rw-r--r-- | host/utils/query_gpsdo_sensors.cpp | 459 | ||||
-rw-r--r-- | host/utils/uhd_cal_rx_iq_balance.cpp | 215 | ||||
-rw-r--r-- | host/utils/uhd_cal_tx_dc_offset.cpp | 222 | ||||
-rw-r--r-- | host/utils/uhd_cal_tx_iq_balance.cpp | 222 | ||||
-rw-r--r-- | host/utils/uhd_config_info.cpp | 40 | ||||
-rw-r--r-- | host/utils/uhd_find_devices.cpp | 56 | ||||
-rw-r--r-- | host/utils/uhd_image_loader.cpp | 86 | ||||
-rw-r--r-- | host/utils/uhd_usrp_probe.cpp | 327 | ||||
-rw-r--r-- | host/utils/usrp_burn_db_eeprom.cpp | 60 | ||||
-rw-r--r-- | host/utils/usrp_burn_mb_eeprom.cpp | 60 | ||||
-rw-r--r-- | host/utils/usrp_cal_utils.hpp | 267 | ||||
-rw-r--r-- | host/utils/usrp_e3x0_network_mode.cpp | 31 |
19 files changed, 2351 insertions, 2187 deletions
diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp index 75bb1a5bb..e723b904a 100644 --- a/host/utils/b2xx_fx3_utils.cpp +++ b/host/utils/b2xx_fx3_utils.cpp @@ -5,50 +5,47 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include <uhd/config.hpp> +#include <uhd/exception.hpp> +#include <uhd/transport/usb_control.hpp> +#include <uhd/transport/usb_device_handle.hpp> +#include <uhd/utils/paths.hpp> +#include <b200_iface.hpp> +#include <libusb.h> +#include <stdint.h> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <boost/functional/hash.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/program_options.hpp> +#include <chrono> +#include <cmath> #include <cstdlib> #include <cstring> -#include <iostream> -#include <iomanip> #include <fstream> -#include <libusb.h> +#include <iomanip> +#include <iostream> #include <sstream> #include <string> -#include <cmath> -#include <cstring> -#include <chrono> #include <thread> -#include <stdint.h> -#include <boost/filesystem.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/format.hpp> -#include <boost/program_options.hpp> -#include <boost/functional/hash.hpp> - -#include <b200_iface.hpp> -#include <uhd/config.hpp> -#include <uhd/transport/usb_control.hpp> -#include <uhd/transport/usb_device_handle.hpp> -#include <uhd/exception.hpp> -#include <uhd/utils/paths.hpp> - namespace po = boost::program_options; namespace fs = boost::filesystem; -struct vid_pid_t { +struct vid_pid_t +{ uint16_t vid; uint16_t pid; }; -const static vid_pid_t known_vid_pids[] = { - {FX3_VID, FX3_DEFAULT_PID}, +const static vid_pid_t known_vid_pids[] = {{FX3_VID, FX3_DEFAULT_PID}, {FX3_VID, FX3_REENUM_PID}, {B200_VENDOR_ID, B200_PRODUCT_ID}, {B200_VENDOR_ID, B200MINI_PRODUCT_ID}, {B200_VENDOR_ID, B205MINI_PRODUCT_ID}, {B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID}, - {B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID} -}; -const static std::vector<vid_pid_t> known_vid_pid_vector(known_vid_pids, known_vid_pids + (sizeof(known_vid_pids) / sizeof(known_vid_pids[0]))); + {B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID}}; +const static std::vector<vid_pid_t> known_vid_pid_vector(known_vid_pids, + known_vid_pids + (sizeof(known_vid_pids) / sizeof(known_vid_pids[0]))); static const size_t EEPROM_INIT_VALUE_VECTOR_SIZE = 8; static uhd::byte_vector_t construct_eeprom_init_value_vector(uint16_t vid, uint16_t pid) @@ -65,19 +62,25 @@ static uhd::byte_vector_t construct_eeprom_init_value_vector(uint16_t vid, uint1 return init_values; } -//!used with lexical cast to parse a hex string -template <class T> struct to_hex{ +//! used with lexical cast to parse a hex string +template <class T> struct to_hex +{ T value; - operator T() const {return value;} - friend std::istream& operator>>(std::istream& in, to_hex& out){ + operator T() const + { + return value; + } + friend std::istream& operator>>(std::istream& in, to_hex& out) + { in >> std::hex >> out.value; return in; } }; -//!parse hex-formatted ASCII text into an int -uint16_t atoh(const std::string &string){ - if (string.substr(0, 2) == "0x"){ +//! parse hex-formatted ASCII text into an int +uint16_t atoh(const std::string& string) +{ + if (string.substr(0, 2) == "0x") { std::stringstream interpreter(string); to_hex<uint16_t> hh; interpreter >> hh; @@ -98,42 +101,39 @@ int reset_usb() /* Check each of the possible paths above to find which ones this system * uses. */ - for(std::set<fs::path>::iterator found = path_list.begin(); - found != path_list.end(); ++found) { - - if(fs::exists(*found)) { - + for (std::set<fs::path>::iterator found = path_list.begin(); found != path_list.end(); + ++found) { + if (fs::exists(*found)) { fs::path devpath = *found; std::set<fs::path> globbed; /* Now, glob all of the files in the directory. */ fs::directory_iterator end_itr; - for(fs::directory_iterator itr(devpath); itr != end_itr; ++itr) { + for (fs::directory_iterator itr(devpath); itr != end_itr; ++itr) { globbed.insert((*itr).path()); } /* Check each file path string to see if it is a device file. */ - for(std::set<fs::path>::iterator it = globbed.begin(); - it != globbed.end(); ++it) { - + for (std::set<fs::path>::iterator it = globbed.begin(); it != globbed.end(); + ++it) { std::string file = fs::path((*it).filename()).string(); if (file.length() < 5) continue; - if(file.compare(0, 5, "0000:") == 0) { + if (file.compare(0, 5, "0000:") == 0) { /* Un-bind the device. */ - std::fstream unbind((devpath.string() + "unbind").c_str(), - std::fstream::out); + std::fstream unbind( + (devpath.string() + "unbind").c_str(), std::fstream::out); unbind << file; unbind.close(); /* Re-bind the device. */ - std::cout << "Re-binding: " << file << " in " - << devpath.string() << std::endl; - std::fstream bind((devpath.string() + "bind").c_str(), - std::fstream::out); + std::cout << "Re-binding: " << file << " in " << devpath.string() + << std::endl; + std::fstream bind( + (devpath.string() + "bind").c_str(), std::fstream::out); bind << file; bind.close(); } @@ -144,7 +144,8 @@ int reset_usb() return 0; } -uhd::transport::usb_device_handle::sptr open_device(const uint16_t vid, const uint16_t pid, const bool user_supplied = false) +uhd::transport::usb_device_handle::sptr open_device( + const uint16_t vid, const uint16_t pid, const bool user_supplied = false) { std::vector<uhd::transport::usb_device_handle::sptr> handles; uhd::transport::usb_device_handle::sptr handle; @@ -152,60 +153,70 @@ uhd::transport::usb_device_handle::sptr open_device(const uint16_t vid, const ui try { // try caller's VID/PID first - std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> vid_pid_pair_list(1,uhd::transport::usb_device_handle::vid_pid_pair_t(vid,pid)); + std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> vid_pid_pair_list( + 1, uhd::transport::usb_device_handle::vid_pid_pair_t(vid, pid)); handles = uhd::transport::usb_device_handle::get_device_list(vid_pid_pair_list); - if (handles.size() == 0) - { - if (user_supplied) - { - std::cerr << (boost::format("Failed to open device with VID 0x%04x and PID 0x%04x - trying other known VID/PIDs") % vid % pid).str() << std::endl; + if (handles.size() == 0) { + if (user_supplied) { + std::cerr << (boost::format("Failed to open device with VID 0x%04x and " + "PID 0x%04x - trying other known VID/PIDs") + % vid % pid) + .str() + << std::endl; } // try known VID/PIDs next - for (size_t i = 0; handles.size() == 0 && i < known_vid_pid_vector.size(); i++) - { + for (size_t i = 0; handles.size() == 0 && i < known_vid_pid_vector.size(); + i++) { vp = known_vid_pid_vector[i]; - handles = uhd::transport::usb_device_handle::get_device_list(vp.vid, vp.pid); + handles = + uhd::transport::usb_device_handle::get_device_list(vp.vid, vp.pid); } - } - if (handles.size() > 0) - { + if (handles.size() > 0) { handle = handles[0]; - std::cout << (boost::format("Device opened (VID=0x%04x,PID=0x%04x)") % vp.vid % vp.pid).str() << std::endl; + std::cout << (boost::format("Device opened (VID=0x%04x,PID=0x%04x)") % vp.vid + % vp.pid) + .str() + << std::endl; } if (!handle) std::cerr << "Cannot open device" << std::endl; - } - catch(const std::exception &) { + } catch (const std::exception&) { std::cerr << "Failed to communicate with the device!" << std::endl; - #ifdef UHD_PLATFORM_WIN32 - std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/manual/page_transport.html" << std::endl; - #endif /* UHD_PLATFORM_WIN32 */ +#ifdef UHD_PLATFORM_WIN32 + std::cerr << "The necessary drivers are not installed. Read the UHD Transport " + "Application Notes for " + "details:\nhttp://files.ettus.com/manual/page_transport.html" + << std::endl; +#endif /* UHD_PLATFORM_WIN32 */ handle.reset(); } return handle; } -b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr &handle) +b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr& handle) { b200_iface::sptr b200; try { - uhd::transport::usb_control::sptr usb_ctrl = uhd::transport::usb_control::make(handle, 0); + uhd::transport::usb_control::sptr usb_ctrl = + uhd::transport::usb_control::make(handle, 0); b200 = b200_iface::make(usb_ctrl); if (!b200) std::cerr << "Cannot create device interface" << std::endl; - } - catch(const std::exception &) { + } catch (const std::exception&) { std::cerr << "Failed to communicate with the device!" << std::endl; - #ifdef UHD_PLATFORM_WIN32 - std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/manual/page_transport.html" << std::endl; - #endif /* UHD_PLATFORM_WIN32 */ +#ifdef UHD_PLATFORM_WIN32 + std::cerr << "The necessary drivers are not installed. Read the UHD Transport " + "Application Notes for " + "details:\nhttp://files.ettus.com/manual/page_transport.html" + << std::endl; +#endif /* UHD_PLATFORM_WIN32 */ b200.reset(); } @@ -216,7 +227,7 @@ int read_eeprom(b200_iface::sptr& b200, uhd::byte_vector_t& data) { try { data = b200->read_eeprom(0x0, 0x0, 8); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while reading EEPROM: " << e.what() << std::endl; return -1; } @@ -227,8 +238,8 @@ int read_eeprom(b200_iface::sptr& b200, uhd::byte_vector_t& data) int write_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data) { try { - b200->write_eeprom(0x0, 0x0, data); - } catch (std::exception &e) { + b200->write_eeprom(0x0, 0x0, data); + } catch (std::exception& e) { std::cerr << "Exception while writing EEPROM: " << e.what() << std::endl; return -1; } @@ -243,16 +254,17 @@ int verify_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data) if (read_eeprom(b200, read_bytes)) return -1; - if (data.size() != read_bytes.size()) - { - std::cerr << "ERROR: Only able to verify first " << std::min(data.size(), read_bytes.size()) << " bytes." << std::endl; + if (data.size() != read_bytes.size()) { + std::cerr << "ERROR: Only able to verify first " + << std::min(data.size(), read_bytes.size()) << " bytes." << std::endl; verified = false; } for (size_t i = 0; i < std::min(data.size(), read_bytes.size()); i++) { if (data[i] != read_bytes[i]) { verified = false; - std::cerr << "Byte " << i << " Expected: " << data[i] << ", Got: " << read_bytes[i] << std::endl; + std::cerr << "Byte " << i << " Expected: " << data[i] + << ", Got: " << read_bytes[i] << std::endl; } } @@ -285,39 +297,32 @@ int erase_eeprom(b200_iface::sptr& b200) return 0; } -int32_t main(int32_t argc, char *argv[]) { +int32_t main(int32_t argc, char* argv[]) +{ uint16_t vid, pid; std::string pid_str, vid_str, fw_file, fpga_file, writevid_str, writepid_str; bool user_supplied_vid_pid = false; po::options_description visible("Allowed options"); - visible.add_options() - ("help,h", "help message") - ("vid,v", po::value<std::string>(&vid_str), - "Specify VID of device to use.") - ("pid,p", po::value<std::string>(&pid_str), - "Specify PID of device to use.") - ("speed,S", "Read back the USB mode currently in use.") - ("reset-device,D", "Reset the B2xx Device.") - ("reset-fpga,F", "Reset the FPGA (does not require re-programming.") - ("reset-usb,U", "Reset the USB subsystem on your host computer.") - ("load-fw,W", po::value<std::string>(&fw_file), - "Load a firmware (hex) file into the FX3.") - ("load-fpga,L", po::value<std::string>(&fpga_file), - "Load a FPGA (bin) file into the FPGA.") - ; + visible.add_options()("help,h", "help message")( + "vid,v", po::value<std::string>(&vid_str), "Specify VID of device to use.")( + "pid,p", po::value<std::string>(&pid_str), "Specify PID of device to use.")( + "speed,S", "Read back the USB mode currently in use.")( + "reset-device,D", "Reset the B2xx Device.")( + "reset-fpga,F", "Reset the FPGA (does not require re-programming.")( + "reset-usb,U", "Reset the USB subsystem on your host computer.")("load-fw,W", + po::value<std::string>(&fw_file), + "Load a firmware (hex) file into the FX3.")("load-fpga,L", + po::value<std::string>(&fpga_file), + "Load a FPGA (bin) file into the FPGA."); // Hidden options provided for testing - use at your own risk! po::options_description hidden("Hidden options"); - hidden.add_options() - ("init-device,I", "Initialize a B2xx device.") - ("uninit-device", "Uninitialize a B2xx device.") - ("read-eeprom,R", "Read first 8 bytes of EEPROM") - ("erase-eeprom,E", "Erase first 8 bytes of EEPROM") - ("write-vid", po::value<std::string>(&writevid_str), - "Write VID field of EEPROM") - ("write-pid", po::value<std::string>(&writepid_str), - "Write PID field of EEPROM"); + hidden.add_options()("init-device,I", "Initialize a B2xx device.")("uninit-device", + "Uninitialize a B2xx device.")("read-eeprom,R", "Read first 8 bytes of EEPROM")( + "erase-eeprom,E", "Erase first 8 bytes of EEPROM")( + "write-vid", po::value<std::string>(&writevid_str), "Write VID field of EEPROM")( + "write-pid", po::value<std::string>(&writepid_str), "Write PID field of EEPROM"); po::options_description desc; desc.add(visible); @@ -328,16 +333,17 @@ int32_t main(int32_t argc, char *argv[]) { try { po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while parsing arguments: " << e.what() << std::endl; std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; return ~0; } - if (vm.count("help")){ + if (vm.count("help")) { try { std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; - } catch(...) {} + } catch (...) { + } return ~0; } @@ -348,15 +354,14 @@ int32_t main(int32_t argc, char *argv[]) { uhd::transport::usb_device_handle::sptr handle; b200_iface::sptr b200; - vid = B200_VENDOR_ID; // Default - pid = B200_PRODUCT_ID; // Default - if (vm.count("vid") && vm.count("pid")) - { + vid = B200_VENDOR_ID; // Default + pid = B200_PRODUCT_ID; // Default + if (vm.count("vid") && vm.count("pid")) { try { vid = atoh(vid_str); pid = atoh(pid_str); - } catch (std::exception &e) { - std::cerr << "Exception while parsing VID and PID: " << e.what() << std:: endl; + } catch (std::exception& e) { + std::cerr << "Exception while parsing VID and PID: " << e.what() << std::endl; return ~0; } user_supplied_vid_pid = true; @@ -374,14 +379,13 @@ int32_t main(int32_t argc, char *argv[]) { return -1; std::cout << " Control of B2xx granted..." << std::endl << std::endl; - // if we are supposed to load a new firmware image and one already exists, reset the FX3 so we can load the new one - if (vm.count("load-fw") && handle->firmware_loaded()) - { + // if we are supposed to load a new firmware image and one already exists, reset the + // FX3 so we can load the new one + if (vm.count("load-fw") && handle->firmware_loaded()) { std::cout << "Overwriting existing firmware" << std::endl; // before we reset, make sure we have a good firmware file - if(!(fs::exists(fw_file))) - { + if (!(fs::exists(fw_file))) { std::cerr << "Invalid firmware filepath: " << fw_file << std::endl; return -1; } @@ -389,14 +393,15 @@ int32_t main(int32_t argc, char *argv[]) { // reset the device try { b200->reset_fx3(); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while reseting FX3: " << e.what() << std::endl; } // re-open device b200.reset(); handle.reset(); - std::this_thread::sleep_for(std::chrono::seconds(2)); // wait 2 seconds for FX3 to reset + std::this_thread::sleep_for( + std::chrono::seconds(2)); // wait 2 seconds for FX3 to reset handle = open_device(vid, pid); if (!handle) return -1; @@ -406,19 +411,18 @@ int32_t main(int32_t argc, char *argv[]) { } // Check to make sure firmware is loaded - if (!(handle->firmware_loaded())) - { + if (!(handle->firmware_loaded())) { std::cout << "Loading firmware" << std::endl; if (fw_file.empty()) fw_file = uhd::find_image_path(B200_FW_FILE_NAME); - if(fw_file.empty()) { + if (fw_file.empty()) { std::cerr << "Firmware image not found!" << std::endl; return -1; } - if(!(fs::exists(fw_file))) { + if (!(fs::exists(fw_file))) { std::cerr << "Invalid filepath: " << fw_file << std::endl; return -1; } @@ -426,7 +430,7 @@ int32_t main(int32_t argc, char *argv[]) { // load firmware try { b200->load_firmware(fw_file); - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "Exception while loading firmware: " << e.what() << std::endl; return ~0; } @@ -445,8 +449,7 @@ int32_t main(int32_t argc, char *argv[]) { } // Added for testing purposes - not exposed - if (vm.count("read-eeprom")) - { + if (vm.count("read-eeprom")) { uhd::byte_vector_t data; if (read_eeprom(b200, data)) @@ -459,8 +462,7 @@ int32_t main(int32_t argc, char *argv[]) { } // Added for testing purposes - not exposed - if (vm.count("erase-eeprom")) - { + if (vm.count("erase-eeprom")) { if (erase_eeprom(b200)) return -1; @@ -470,90 +472,90 @@ int32_t main(int32_t argc, char *argv[]) { } // Added for testing purposes - not exposed - if (vm.count("uninit-device")) - { + if (vm.count("uninit-device")) { // erase EEPROM erase_eeprom(b200); - std::cout << "EEPROM uninitialized, resetting device..." - << std::endl << std::endl; + std::cout << "EEPROM uninitialized, resetting device..." << std::endl + << std::endl; // reset the device try { b200->reset_fx3(); - } catch (uhd::exception &e) { + } catch (uhd::exception& e) { std::cerr << "Exception while resetting FX3: " << e.what() << std::endl; return -1; } - std::cout << "Uninitialization Process Complete." - << std::endl << std::endl; + std::cout << "Uninitialization Process Complete." << std::endl << std::endl; return 0; } /* If we are initializing the device, the VID/PID should default to the * Cypress VID/PID for the initial FW load, but we can initialize from any state. */ - if (vm.count("init-device")) - { + if (vm.count("init-device")) { uint16_t writevid = B200_VENDOR_ID; uint16_t writepid = B200_PRODUCT_ID; /* Now, initialize the device. */ - // Added for testing purposes - not exposed - if (vm.count("write-vid") && vm.count("write-pid")) - { + // Added for testing purposes - not exposed + if (vm.count("write-vid") && vm.count("write-pid")) { try { - writevid = atoh(writevid_str); - writepid = atoh(writepid_str); - } catch (std::exception &e) { - std::cerr << "Exception while parsing write VID and PID: " << e.what() << std:: endl; - return ~0; + writevid = atoh(writevid_str); + writepid = atoh(writepid_str); + } catch (std::exception& e) { + std::cerr << "Exception while parsing write VID and PID: " << e.what() + << std::endl; + return ~0; } } std::cout << "Writing VID and PID to EEPROM..." << std::endl << std::endl; - if (write_and_verify_eeprom(b200, construct_eeprom_init_value_vector(writevid, writepid))) return -1; + if (write_and_verify_eeprom( + b200, construct_eeprom_init_value_vector(writevid, writepid))) + return -1; - std::cout << "EEPROM initialized, resetting device..." - << std::endl << std::endl; + std::cout << "EEPROM initialized, resetting device..." << std::endl << std::endl; /* Reset the device! */ try { b200->reset_fx3(); - } catch (const std::exception &e) { + } catch (const std::exception& e) { std::cerr << "Exception while resetting device: " << e.what() << std::endl; return -1; } - std::cout << "Initialization Process Complete." - << std::endl << std::endl; + std::cout << "Initialization Process Complete." << std::endl << std::endl; return 0; } uint8_t data_buffer[16]; memset(data_buffer, 0x0, sizeof(data_buffer)); - if (vm.count("speed")){ + if (vm.count("speed")) { uint8_t speed; - try {speed = b200->get_usb_speed();} - catch (uhd::exception &e) { + try { + speed = b200->get_usb_speed(); + } catch (uhd::exception& e) { std::cerr << "Exception while getting USB speed: " << e.what() << std::endl; return -1; } - std::cout << "Currently operating at USB " << (int) speed << std::endl; + std::cout << "Currently operating at USB " << (int)speed << std::endl; } if (vm.count("reset-device")) { - try {b200->reset_fx3();} - catch (uhd::exception &e) { + try { + b200->reset_fx3(); + } catch (uhd::exception& e) { std::cerr << "Exception while resetting FX3: " << e.what() << std::endl; return -1; } } else if (vm.count("reset-fpga")) { - try {b200->set_fpga_reset_pin(true);} - catch (uhd::exception &e) { + try { + b200->set_fpga_reset_pin(true); + } catch (uhd::exception& e) { std::cerr << "Exception while resetting FPGA: " << e.what() << std::endl; return -1; } @@ -561,24 +563,24 @@ int32_t main(int32_t argc, char *argv[]) { } else if (vm.count("load-fpga")) { std::cout << "Loading FPGA image (" << fpga_file << ")" << std::endl; uint32_t fx3_state; - try {fx3_state = b200->load_fpga(fpga_file);} // returns 0 on success, or FX3 state on error - catch (uhd::exception &e) { + try { + fx3_state = b200->load_fpga(fpga_file); + } // returns 0 on success, or FX3 state on error + catch (uhd::exception& e) { std::cerr << "Exception while loading FPGA: " << e.what() << std::endl; return ~0; } if (fx3_state != 0) { - std::cerr << std::flush << "Error loading FPGA. FX3 state (" - << fx3_state << "): " << b200_iface::fx3_state_string(fx3_state) << std::endl; + std::cerr << std::flush << "Error loading FPGA. FX3 state (" << fx3_state + << "): " << b200_iface::fx3_state_string(fx3_state) << std::endl; return ~0; } - std::cout << "FPGA load complete, releasing USB interface..." - << std::endl; + std::cout << "FPGA load complete, releasing USB interface..." << std::endl; } std::cout << "Operation complete! I did it! I did it!" << std::endl; return 0; } - diff --git a/host/utils/converter_benchmark.cpp b/host/utils/converter_benchmark.cpp index cb8cce519..07aec9170 100644 --- a/host/utils/converter_benchmark.cpp +++ b/host/utils/converter_benchmark.cpp @@ -5,32 +5,30 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> -#include <uhd/types/dict.hpp> #include <uhd/convert.hpp> #include <uhd/exception.hpp> -#include <boost/program_options.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/utils/safe_main.hpp> +#include <stdint.h> +#include <boost/algorithm/string.hpp> #include <boost/format.hpp> -#include <boost/timer.hpp> #include <boost/lexical_cast.hpp> -#include <boost/algorithm/string.hpp> -#include <iostream> +#include <boost/program_options.hpp> +#include <boost/timer.hpp> +#include <complex> #include <iomanip> +#include <iostream> #include <map> -#include <complex> -#include <stdint.h> namespace po = boost::program_options; using namespace uhd::convert; -enum buf_init_t { - RANDOM, INC -}; +enum buf_init_t { RANDOM, INC }; // Convert `sc16_item32_le' -> `sc16' // Finds the first _ in format and returns the string // until then. Returns the entire string if no _ is found. -std::string format_to_type(const std::string &format) +std::string format_to_type(const std::string& format) { std::string ret_val = ""; for (size_t i = 0; i < format.length(); i++) { @@ -44,10 +42,8 @@ std::string format_to_type(const std::string &format) } void configure_conv( - converter::sptr conv, - const std::string &in_type, - const std::string &out_type -) { + converter::sptr conv, const std::string& in_type, const std::string& out_type) +{ if (in_type == "sc16") { if (out_type == "fc32") { std::cout << "Setting scalar to 32767." << std::endl; @@ -68,21 +64,19 @@ void configure_conv( } template <typename T> -void init_random_vector_complex_float(std::vector<char> &buf_ptr, const size_t n_items) +void init_random_vector_complex_float(std::vector<char>& buf_ptr, const size_t n_items) { - std::complex<T> * const buf = reinterpret_cast<std::complex<T> * const>(&buf_ptr[0]); + std::complex<T>* const buf = reinterpret_cast<std::complex<T>* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = std::complex<T>( - T(std::rand()/(RAND_MAX/2.0) - 1), - T(std::rand()/(RAND_MAX/2.0) - 1) - ); + T(std::rand() / (RAND_MAX / 2.0) - 1), T(std::rand() / (RAND_MAX / 2.0) - 1)); } } template <typename T> -void init_random_vector_complex_int(std::vector<char> &buf_ptr, const size_t n_items) +void init_random_vector_complex_int(std::vector<char>& buf_ptr, const size_t n_items) { - std::complex<T> * const buf = reinterpret_cast<std::complex<T> * const>(&buf_ptr[0]); + std::complex<T>* const buf = reinterpret_cast<std::complex<T>* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = std::complex<T>(T(std::rand()), T(std::rand())); } @@ -96,45 +90,45 @@ struct item32_sc12_3x }; template <typename T> -void init_random_vector_complex_sc12(std::vector<char> &buf_ptr, const size_t n_items) +void init_random_vector_complex_sc12(std::vector<char>& buf_ptr, const size_t n_items) { - item32_sc12_3x *const buf = reinterpret_cast<item32_sc12_3x * const>(&buf_ptr[0]); - if (n_items % 4) throw std::invalid_argument(""); + item32_sc12_3x* const buf = reinterpret_cast<item32_sc12_3x* const>(&buf_ptr[0]); + if (n_items % 4) + throw std::invalid_argument(""); for (size_t i = 0; i < n_items / 4; i++) { int16_t iq[8]; - for (auto &k : iq) k = rand() & 0xfff; - buf[i].line0 = iq[0] << 20 | iq[1] << 8 | iq[2] >> 4; + for (auto& k : iq) + k = rand() & 0xfff; + buf[i].line0 = iq[0] << 20 | iq[1] << 8 | iq[2] >> 4; buf[i].line1 = iq[2] << 28 | iq[3] << 16 | iq[4] << 4 | iq[5] >> 8; buf[i].line2 = iq[5] << 24 | iq[6] << 12 | iq[7] << 0; } } template <typename T> -void init_random_vector_real_int(std::vector<char> &buf_ptr, size_t n_items) +void init_random_vector_real_int(std::vector<char>& buf_ptr, size_t n_items) { - T * const buf = reinterpret_cast<T * const>(&buf_ptr[0]); + T* const buf = reinterpret_cast<T* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = T(std::rand()); } } // Fill a buffer with increasing numbers -template <typename T> -void init_inc_vector(std::vector<char> &buf_ptr, size_t n_items) +template <typename T> void init_inc_vector(std::vector<char>& buf_ptr, size_t n_items) { - T * const buf = reinterpret_cast<T * const>(&buf_ptr[0]); + T* const buf = reinterpret_cast<T* const>(&buf_ptr[0]); for (size_t i = 0; i < n_items; i++) { buf[i] = T(i); } } -void init_buffers( - std::vector< std::vector<char> > &buf, - const std::string &type, - size_t bytes_per_item, - buf_init_t buf_seed_mode -) { +void init_buffers(std::vector<std::vector<char>>& buf, + const std::string& type, + size_t bytes_per_item, + buf_init_t buf_seed_mode) +{ if (buf.empty()) { return; } @@ -144,26 +138,25 @@ void init_buffers( if (buf_seed_mode == INC) { for (size_t i = 0; i < buf.size(); i++) { if (type == "sc8") { - init_inc_vector< std::complex<int8_t> >(buf[i], n_items); + init_inc_vector<std::complex<int8_t>>(buf[i], n_items); } else if (type == "sc16") { - init_inc_vector< std::complex<int16_t> >(buf[i], n_items); + init_inc_vector<std::complex<int16_t>>(buf[i], n_items); } else if (type == "sc32") { - init_inc_vector< std::complex<int32_t> >(buf[i], n_items); + init_inc_vector<std::complex<int32_t>>(buf[i], n_items); } else if (type == "fc32") { - init_inc_vector< std::complex<float> >(buf[i], n_items); + init_inc_vector<std::complex<float>>(buf[i], n_items); } else if (type == "fc64") { - init_inc_vector< std::complex<double> >(buf[i], n_items); + init_inc_vector<std::complex<double>>(buf[i], n_items); } else if (type == "s8") { - init_inc_vector< int8_t >(buf[i], n_items); + init_inc_vector<int8_t>(buf[i], n_items); } else if (type == "s16") { - init_inc_vector< int16_t >(buf[i], n_items); + init_inc_vector<int16_t>(buf[i], n_items); } else if (type == "item32") { - init_inc_vector< uint32_t >(buf[i], n_items); + init_inc_vector<uint32_t>(buf[i], n_items); init_random_vector_real_int<uint32_t>(buf[i], n_items); } else { - throw uhd::runtime_error(str( - boost::format("Cannot handle data type: %s") % type - )); + throw uhd::runtime_error( + str(boost::format("Cannot handle data type: %s") % type)); } } @@ -193,21 +186,19 @@ void init_buffers( } else if (type == "item32") { init_random_vector_real_int<uint32_t>(buf[i], n_items); } else { - throw uhd::runtime_error(str( - boost::format("Cannot handle data type: %s") % type - )); + throw uhd::runtime_error( + str(boost::format("Cannot handle data type: %s") % type)); } } } // Returns time elapsed -double run_benchmark( - converter::sptr conv, - const std::vector<const void *> &input_buf_refs, - const std::vector<void *> &output_buf_refs, - size_t n_items, - size_t iterations -) { +double run_benchmark(converter::sptr conv, + const std::vector<const void*>& input_buf_refs, + const std::vector<void*>& output_buf_refs, + size_t n_items, + size_t iterations) +{ boost::timer benchmark_timer; for (size_t i = 0; i < iterations; i++) { conv->conv(input_buf_refs, output_buf_refs, n_items); @@ -215,71 +206,58 @@ double run_benchmark( return benchmark_timer.elapsed(); } -template <typename T> -std::string void_ptr_to_hexstring(const void *v_ptr, size_t index) +template <typename T> std::string void_ptr_to_hexstring(const void* v_ptr, size_t index) { - const T *ptr = reinterpret_cast<const T *>(v_ptr); + const T* ptr = reinterpret_cast<const T*>(v_ptr); return str(boost::format("%X") % ptr[index]); } -std::string item_to_hexstring( - const void *v_ptr, - size_t index, - const std::string &type -) { +std::string item_to_hexstring(const void* v_ptr, size_t index, const std::string& type) +{ if (type == "fc32") { return void_ptr_to_hexstring<uint64_t>(v_ptr, index); - } - else if (type == "sc16" || type == "item32") { + } else if (type == "sc16" || type == "item32") { return void_ptr_to_hexstring<uint32_t>(v_ptr, index); - } - else if (type == "sc8" || type == "s16") { + } else if (type == "sc8" || type == "s16") { return void_ptr_to_hexstring<uint16_t>(v_ptr, index); - } - else if (type == "u8") { + } else if (type == "u8") { return void_ptr_to_hexstring<uint8_t>(v_ptr, index); - } - else { + } else { return str(boost::format("<unhandled data type: %s>") % type); } } std::string item_to_string( - const void *v_ptr, - size_t index, - const std::string &type, - const bool print_hex -) { + const void* v_ptr, size_t index, const std::string& type, const bool print_hex) +{ if (print_hex) { return item_to_hexstring(v_ptr, index, type); } if (type == "sc16") { - const std::complex<int16_t> *ptr = reinterpret_cast<const std::complex<int16_t> *>(v_ptr); + const std::complex<int16_t>* ptr = + reinterpret_cast<const std::complex<int16_t>*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "sc8") { - const std::complex<int8_t> *ptr = reinterpret_cast<const std::complex<int8_t> *>(v_ptr); + } else if (type == "sc8") { + const std::complex<int8_t>* ptr = + reinterpret_cast<const std::complex<int8_t>*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "fc32") { - const std::complex<float> *ptr = reinterpret_cast<const std::complex<float> *>(v_ptr); + } else if (type == "fc32") { + const std::complex<float>* ptr = + reinterpret_cast<const std::complex<float>*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "item32") { - const uint32_t *ptr = reinterpret_cast<const uint32_t *>(v_ptr); + } else if (type == "item32") { + const uint32_t* ptr = reinterpret_cast<const uint32_t*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else if (type == "s16") { - const int16_t *ptr = reinterpret_cast<const int16_t *>(v_ptr); + } else if (type == "s16") { + const int16_t* ptr = reinterpret_cast<const int16_t*>(v_ptr); return boost::lexical_cast<std::string>(ptr[index]); - } - else { + } else { return str(boost::format("<unhandled data type: %s>") % type); } } -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string in_format, out_format; std::string priorities; @@ -311,15 +289,19 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) 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 Converter Benchmark Tool %s") % desc << std::endl << std::endl; - std::cout << " Use this to benchmark or debug converters." << std::endl - << " When using as a benchmark tool, it will output the execution time\n" - " for every conversion run in CSV format to stdout. Every line between\n" - " the output delimiters {{{ }}} is of the format: <PRIO>,<TIME IN MILLISECONDS>\n" - " When using for converter debugging, every line is formatted as\n" - " <INPUT_VALUE>,<OUTPUT_VALUE>\n" << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("UHD Converter Benchmark Tool %s") % desc << std::endl + << std::endl; + std::cout + << " Use this to benchmark or debug converters." << std::endl + << " When using as a benchmark tool, it will output the execution time\n" + " for every conversion run in CSV format to stdout. Every line between\n" + " the output delimiters {{{ }}} is of the format: <PRIO>,<TIME IN " + "MILLISECONDS>\n" + " When using for converter debugging, every line is formatted as\n" + " <INPUT_VALUE>,<OUTPUT_VALUE>\n" + << std::endl; return EXIT_FAILURE; } @@ -329,7 +311,9 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } else if (seed_mode == "random") { buf_seed_mode = RANDOM; } else { - std::cout << "Invalid argument: --seed-mode must be either 'incremental' or 'random'." << std::endl; + std::cout + << "Invalid argument: --seed-mode must be either 'incremental' or 'random'." + << std::endl; } bool debug_mode = vm.count("debug-converter") > 0; @@ -343,13 +327,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) converter_id.output_format = out_format; converter_id.num_inputs = n_inputs; converter_id.num_outputs = n_outputs; - std::cout << "Requested converter format: " << converter_id.to_string() - << std::endl; + std::cout << "Requested converter format: " << converter_id.to_string() << std::endl; uhd::dict<priority_type, converter::sptr> conv_list; if (priorities == "default" or priorities.empty()) { try { - conv_list[prio] = get_converter(converter_id, prio)(); // Can throw a uhd::key_error - } catch(const uhd::key_error &) { + conv_list[prio] = + get_converter(converter_id, prio)(); // Can throw a uhd::key_error + } catch (const uhd::key_error&) { std::cout << "No converters found." << std::endl; return EXIT_FAILURE; } @@ -357,7 +341,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) for (priority_type i = 0; i < max_prio; i++) { try { // get_converter() returns a factory function, execute that immediately: - converter::sptr conv_for_prio = get_converter(converter_id, i)(); // Can throw a uhd::key_error + converter::sptr conv_for_prio = + get_converter(converter_id, i)(); // Can throw a uhd::key_error conv_list[i] = conv_for_prio; } catch (...) { continue; @@ -365,15 +350,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } } else { // Assume that priorities contains a list of prios (e.g. 0,2,3) std::vector<std::string> prios_in_list; - boost::split( - prios_in_list, - priorities, - boost::is_any_of(","), // Split at , - boost::token_compress_on // Avoid empty results + boost::split(prios_in_list, + priorities, + boost::is_any_of(","), // Split at , + boost::token_compress_on // Avoid empty results ); - for(const std::string &this_prio: prios_in_list) { + for (const std::string& this_prio : prios_in_list) { size_t prio_index = boost::lexical_cast<size_t>(this_prio); - converter::sptr conv_for_prio = get_converter(converter_id, prio_index)(); // Can throw a uhd::key_error + converter::sptr conv_for_prio = + get_converter(converter_id, prio_index)(); // Can throw a uhd::key_error conv_list[prio_index] = conv_for_prio; } } @@ -383,25 +368,27 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // First, convert the types to plain types (e.g. sc16_item32_le -> sc16) const std::string in_type = format_to_type(in_format); const std::string out_type = format_to_type(out_format); - const size_t in_size = get_bytes_per_item(in_type); - const size_t out_size = get_bytes_per_item(out_type); + const size_t in_size = get_bytes_per_item(in_type); + const size_t out_size = get_bytes_per_item(out_type); // Create the buffers and fill them with random data & zeros, respectively - std::vector< std::vector<char> > input_buffers(n_inputs, std::vector<char>(in_size * n_samples, 0)); - std::vector< std::vector<char> > output_buffers(n_outputs, std::vector<char>(out_size * n_samples, 0)); + std::vector<std::vector<char>> input_buffers( + n_inputs, std::vector<char>(in_size * n_samples, 0)); + std::vector<std::vector<char>> output_buffers( + n_outputs, std::vector<char>(out_size * n_samples, 0)); init_buffers(input_buffers, in_type, in_size, buf_seed_mode); // Create ref vectors for the converter: - std::vector<const void *> input_buf_refs(n_inputs); - std::vector<void *> output_buf_refs(n_outputs); + std::vector<const void*> input_buf_refs(n_inputs); + std::vector<void*> output_buf_refs(n_outputs); for (size_t i = 0; i < n_inputs; i++) { - input_buf_refs[i] = reinterpret_cast<const void *>(&input_buffers[i][0]); + input_buf_refs[i] = reinterpret_cast<const void*>(&input_buffers[i][0]); } for (size_t i = 0; i < n_outputs; i++) { - output_buf_refs[i] = reinterpret_cast<void *>(&output_buffers[i][0]); + output_buf_refs[i] = reinterpret_cast<void*>(&output_buffers[i][0]); } /// Final configurations to the converter: std::cout << "Configuring converters:" << std::endl; - for(priority_type prio_i: conv_list.keys()) { + for (priority_type prio_i : conv_list.keys()) { std::cout << "* [" << prio_i << "]: "; configure_conv(conv_list[prio_i], in_type, out_type); } @@ -410,38 +397,33 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::cout << "{{{" << std::endl; if (not debug_mode) { std::cout << "prio,duration_ms,avg_duration_ms,n_samples,iterations" << std::endl; - for(priority_type prio_i: conv_list.keys()) { - double duration = run_benchmark( - conv_list[prio_i], - input_buf_refs, - output_buf_refs, - n_samples, - iterations - ); - std::cout << boost::format("%i,%d,%d,%d,%d") - % prio_i - % (duration * 1000) - % (duration * 1000.0 / iterations) - % n_samples - % iterations - << std::endl; + for (priority_type prio_i : conv_list.keys()) { + double duration = run_benchmark(conv_list[prio_i], + input_buf_refs, + output_buf_refs, + n_samples, + iterations); + std::cout << boost::format("%i,%d,%d,%d,%d") % prio_i % (duration * 1000) + % (duration * 1000.0 / iterations) % n_samples % iterations + << std::endl; } } /// Or run debug mode, which runs one conversion and prints the results //// if (debug_mode) { // Only run on the first converter: - run_benchmark( - conv_list[conv_list.keys().at(0)], + run_benchmark(conv_list[conv_list.keys().at(0)], input_buf_refs, output_buf_refs, n_samples, - iterations - ); + iterations); for (size_t i = 0; i < n_samples; i++) { std::cout << item_to_string(input_buf_refs[0], i, in_type, vm.count("hex")) << ";" - << item_to_string(reinterpret_cast< const void * >(output_buf_refs[0]), i, out_type, vm.count("hex")) + << item_to_string(reinterpret_cast<const void*>(output_buf_refs[0]), + i, + out_type, + vm.count("hex")) << std::endl; } } diff --git a/host/utils/fx2_init_eeprom.cpp b/host/utils/fx2_init_eeprom.cpp index 448652faf..e375b27f5 100644 --- a/host/utils/fx2_init_eeprom.cpp +++ b/host/utils/fx2_init_eeprom.cpp @@ -5,31 +5,32 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> +#include "b100_eeprom.h" +#include "usrp1_eeprom.h" #include <uhd/device.hpp> #include <uhd/property_tree.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> -#include <boost/filesystem.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string/predicate.hpp> -#include <iostream> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <fstream> -#include "usrp1_eeprom.h" -#include "b100_eeprom.h" +#include <iostream> #ifdef UHD_PLATFORM_LINUX -#include <unistd.h> // syscall constants -#include <fcntl.h> // O_NONBLOCK -#include <sys/syscall.h> -#include <cerrno> -#include <cstring> // for std::strerror -#endif //UHD_PLATFORM_LINUX +# include <fcntl.h> // O_NONBLOCK +# include <sys/syscall.h> +# include <unistd.h> // syscall constants +# include <cerrno> +# include <cstring> // for std::strerror +#endif // UHD_PLATFORM_LINUX const std::string FX2_VENDOR_ID("0x04b4"); const std::string FX2_PRODUCT_ID("0x8613"); namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ std::string type; std::string image; po::options_description desc("Allowed options"); @@ -47,97 +48,104 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("USRP EEPROM initialization %s") % desc << std::endl; return EXIT_FAILURE; } #ifdef UHD_PLATFORM_LINUX - //can't find an uninitialized usrp with this mystery usbtest in the way... + // can't find an uninitialized usrp with this mystery usbtest in the way... std::string module("usbtest"); std::ifstream modules("/proc/modules"); bool module_found = false; std::string module_line; - while(std::getline(modules, module_line) && (!module_found)) { + while (std::getline(modules, module_line) && (!module_found)) { module_found = boost::starts_with(module_line, module); } - if(module_found) { - std::cout << boost::format("Found the '%s' module. Unloading it.\n" ) % module; + if (module_found) { + std::cout << boost::format("Found the '%s' module. Unloading it.\n") % module; int fail = syscall(__NR_delete_module, module.c_str(), O_NONBLOCK); - if(fail) - std::cerr << ( boost::format("Removing the '%s' module failed with error '%s'.\n") % module % std::strerror(errno) ); + if (fail) + std::cerr << (boost::format( + "Removing the '%s' module failed with error '%s'.\n") + % module % std::strerror(errno)); } -#endif //UHD_PLATFORM_LINUX +#endif // UHD_PLATFORM_LINUX - //load the options into the address + // load the options into the address uhd::device_addr_t device_addr; device_addr["type"] = type; - if(vm.count("vid") or vm.count("pid")) { - if(not (vm.count("vid") and vm.count("pid") and vm.count("type"))) { - std::cerr << "ERROR: Must specify vid, pid, and type if specifying any of the two former args" << std::endl; + if (vm.count("vid") or vm.count("pid")) { + if (not(vm.count("vid") and vm.count("pid") and vm.count("type"))) { + std::cerr << "ERROR: Must specify vid, pid, and type if specifying any of " + "the two former args" + << std::endl; } else { - device_addr["vid"] = vm["vid"].as<std::string>(); - device_addr["pid"] = vm["pid"].as<std::string>(); + device_addr["vid"] = vm["vid"].as<std::string>(); + device_addr["pid"] = vm["pid"].as<std::string>(); device_addr["type"] = vm["type"].as<std::string>(); } } else { device_addr["vid"] = FX2_VENDOR_ID; device_addr["pid"] = FX2_PRODUCT_ID; } - if(vm.count("image")) { - //if specified, use external image file - image = vm["image"].as<std::string>(); + if (vm.count("image")) { + // if specified, use external image file + image = vm["image"].as<std::string>(); } else { - //if not specified, use built-ins; requires user to define type - size_t image_len; - unsigned const char* image_data; + // if not specified, use built-ins; requires user to define type + size_t image_len; + unsigned const char* image_data; + + if (!vm.count("type")) { + std::cerr << boost::format("ERROR: Image file not specified and type of " + "device not given. Cannot use built-in images.\n"); + return EXIT_FAILURE; + } - if(!vm.count("type")) { - std::cerr << boost::format("ERROR: Image file not specified and type of device not given. Cannot use built-in images.\n"); - return EXIT_FAILURE; - } - - std::cout << boost::format("Using built-in image for \"%s\".\n") % type; - - if(vm["type"].as<std::string>() == "usrp1") { - image_len = usrp1_eeprom_bin_len; - image_data = usrp1_eeprom_bin; - } else if(vm["type"].as<std::string>() == "b100") { - image_len = b100_eeprom_bin_len; - image_data = b100_eeprom_bin; - } else { - std::cerr << boost::format("ERROR: Unsupported device type \"%s\" specified and no EEPROM image file given.\n") % type; - return EXIT_FAILURE; - } + std::cout << boost::format("Using built-in image for \"%s\".\n") % type; + + if (vm["type"].as<std::string>() == "usrp1") { + image_len = usrp1_eeprom_bin_len; + image_data = usrp1_eeprom_bin; + } else if (vm["type"].as<std::string>() == "b100") { + image_len = b100_eeprom_bin_len; + image_data = b100_eeprom_bin; + } else { + std::cerr << boost::format("ERROR: Unsupported device type \"%s\" specified " + "and no EEPROM image file given.\n") + % type; + return EXIT_FAILURE; + } - //get temporary file name, and write image to that. - image = boost::filesystem::unique_path().string(); - std::ofstream tmp_image(image, std::ofstream::binary); - tmp_image.write((const char*)image_data, image_len); - tmp_image.close(); + // get temporary file name, and write image to that. + image = boost::filesystem::unique_path().string(); + std::ofstream tmp_image(image, std::ofstream::binary); + tmp_image.write((const char*)image_data, image_len); + tmp_image.close(); } - //find and create a control transport to do the writing. + // find and create a control transport to do the writing. uhd::device_addrs_t found_addrs = uhd::device::find(device_addr, uhd::device::USRP); - if (found_addrs.size() == 0){ + if (found_addrs.size() == 0) { std::cerr << "No USRP devices found" << std::endl; return EXIT_FAILURE; } - for (size_t i = 0; i < found_addrs.size(); i++){ + for (size_t i = 0; i < found_addrs.size(); i++) { std::cout << "Writing EEPROM data..." << std::endl; - //uhd::device_addrs_t devs = uhd::device::find(found_addrs[i]); + // uhd::device_addrs_t devs = uhd::device::find(found_addrs[i]); uhd::device::sptr dev = uhd::device::make(found_addrs[i], uhd::device::USRP); uhd::property_tree::sptr tree = dev->get_tree(); tree->access<std::string>("/mboards/0/load_eeprom").set(image); } - //delete temporary image file if we created one - if(!vm.count("image")) { - boost::filesystem::remove(image); + // delete temporary image file if we created one + if (!vm.count("image")) { + boost::filesystem::remove(image); } std::cout << "Power-cycle the usrp for the changes to take effect." << std::endl; diff --git a/host/utils/latency/include/Responder.hpp b/host/utils/latency/include/Responder.hpp index 0d690bcd6..81b5e84f9 100644 --- a/host/utils/latency/include/Responder.hpp +++ b/host/utils/latency/include/Responder.hpp @@ -8,279 +8,299 @@ #ifndef RESPONDER_H #define RESPONDER_H +#include <uhd/usrp/multi_usrp.hpp> #include <curses.h> -#include <map> -#include <ctime> #include <stdint.h> - -#include <uhd/usrp/multi_usrp.hpp> +#include <ctime> +#include <map> using namespace std; class Responder { - public: - enum ReturnCodes +public: + enum ReturnCodes { + RETCODE_OK = 0, + RETCODE_BAD_ARGS = -1, + RETCODE_RUNTIME_ERROR = -2, + RETCODE_UNKNOWN_EXCEPTION = -3, + RETCODE_RECEIVE_TIMEOUT = -4, + RETCODE_RECEIVE_FAILED = -5, + RETCODE_MANUAL_ABORT = -6, + RETCODE_BAD_PACKET = -7, + RETCODE_OVERFLOW = -8 + }; + + struct Options + { + string device_args; + double delay; + double sample_rate; + double trigger_level; + float output_scale; + double response_duration; + double dc_offset_delay; + double init_delay; + double timeout; + size_t samps_per_buff; + size_t samps_per_packet; + double level_calibration_duration; + std::string test_title; + std::string stats_filename; + std::string stats_filename_prefix; + std::string stats_filename_suffix; + double delay_min; + double delay_max; + double delay_step; + double pulse_detection_threshold; + uint64_t test_iterations; + size_t end_test_after_success_count; + size_t skip_iterations; + double simulate_frequency; + double time_mul; + size_t flush_count; + size_t optimize_padding; + double rt_priority; + bool ignore_simulation_check; + bool test_iterations_is_sample_count; + bool skip_eob; + bool adjust_simulation_rate; + bool optimize_simulation_rate; + bool no_stats_file; + bool log_file; + bool batch_mode; + bool skip_if_results_exist; + bool skip_send; + bool combine_eob; + bool pause; + bool realtime; + float invert; + float output_value; + bool no_delay; + bool allow_late_bursts; + + uint64_t level_calibration_count() const { - RETCODE_OK = 0, - RETCODE_BAD_ARGS = -1, - RETCODE_RUNTIME_ERROR = -2, - RETCODE_UNKNOWN_EXCEPTION = -3, - RETCODE_RECEIVE_TIMEOUT = -4, - RETCODE_RECEIVE_FAILED = -5, - RETCODE_MANUAL_ABORT = -6, - RETCODE_BAD_PACKET = -7, - RETCODE_OVERFLOW = -8 - }; - - struct Options - { - string device_args; - double delay; - double sample_rate; - double trigger_level; - float output_scale; - double response_duration; - double dc_offset_delay; - double init_delay; - double timeout; - size_t samps_per_buff; - size_t samps_per_packet; - double level_calibration_duration; - std::string test_title; - std::string stats_filename; - std::string stats_filename_prefix; - std::string stats_filename_suffix; - double delay_min; - double delay_max; - double delay_step; - double pulse_detection_threshold; - uint64_t test_iterations; - size_t end_test_after_success_count; - size_t skip_iterations; - double simulate_frequency; - double time_mul; - size_t flush_count; - size_t optimize_padding; - double rt_priority; - bool ignore_simulation_check; - bool test_iterations_is_sample_count; - bool skip_eob; - bool adjust_simulation_rate; - bool optimize_simulation_rate; - bool no_stats_file; - bool log_file; - bool batch_mode; - bool skip_if_results_exist; - bool skip_send; - bool combine_eob; - bool pause; - bool realtime; - float invert; - float output_value; - bool no_delay; - bool allow_late_bursts; - - uint64_t level_calibration_count() const - { - return (uint64_t)(sample_rate * level_calibration_duration); - } + return (uint64_t)(sample_rate * level_calibration_duration); + } - uint64_t response_length() const - { - return (uint64_t)(sample_rate * response_duration); - } - - uint64_t highest_delay_samples(const double delay) const - { - return (uint64_t)(delay * (double)sample_rate); - } - - uint64_t simulate_duration(const double simulate_frequency) const - { - if(simulate_frequency > 0.0) { - return (uint64_t)((double)sample_rate / simulate_frequency); - } - return 0; - } - }; - - typedef struct Stats + uint64_t response_length() const { - double delay; - uint64_t detected; - uint64_t missed; - uint64_t skipped; - } STATS; + return (uint64_t)(sample_rate * response_duration); + } - typedef std::map<uint64_t,STATS> StatsMap; + uint64_t highest_delay_samples(const double delay) const + { + return (uint64_t)(delay * (double)sample_rate); + } - struct DebugInfo + uint64_t simulate_duration(const double simulate_frequency) const { - time_t start_time; - time_t end_time; - time_t start_time_test; - time_t end_time_test; - time_t first_send_timeout; - }; - Responder(Options& opt); - virtual ~Responder(); - - // Main entry point after constructor. - int run(); - - int get_return_code(){return _return_code;} - - protected: - private: - // These 2 variables are used for ncurses output. - WINDOW* _window; - std::stringstream _ss; - std::stringstream _ss_cerr; - - // struct which holds all arguments as constants settable from outside the class - const Options _opt; - - string _stats_filename; // Specify name of statistics file - string _stats_log_filename; // Specify name for log file. - double _delay; // may be altered in all modes. - size_t _samps_per_packet; // This is one of the options of interest. Find out how well it performs. - double _delay_step; // may be altered in interactive mode - double _simulate_frequency; // updated during automatic test iterations - - // additional attributes - bool _allow_late_bursts; // may be altered in interactive mode - bool _no_delay; // may be altered in interactive mode - - // dependent variables - uint64_t _response_length; - int64_t _init_delay_count; - int64_t _dc_offset_countdown; - int64_t _level_calibration_countdown; - uint64_t _simulate_duration; - uint64_t _original_simulate_duration; - - // these variables store test conditions - uint64_t _num_total_samps; // printed on exit - size_t _overruns; // printed on exit - StatsMap _mapStats; // store results - uint64_t _max_success; // < 0 --> write results to file - int _return_code; - - // Hold USRP, streams and commands - uhd::usrp::multi_usrp::sptr _usrp; - uhd::tx_streamer::sptr _tx_stream; - uhd::rx_streamer::sptr _rx_stream; - uhd::stream_cmd_t _stream_cmd; - - // Keep track of number of timeouts. - uint64_t _timeout_burst_count; - uint64_t _timeout_eob_count; - - // Transmit attributes - float* _pResponse; - - // Control print parameters. - int _y_delay_pos; - int _x_delay_pos; // Remember the cursor position of delay line - uint64_t _last_overrun_count; - - // Hold debug info during test. Will be included in log file. - DebugInfo _dbginfo; - - /* - * Here are the class's member methods. - */ - // These methods are used for ncurses output - void create_ncurses_window(); - void FLUSH_SCREEN(); - void FLUSH_SCREEN_NL(); - - // Variable calculation helpers - inline uint64_t get_response_length(double sample_rate, double response_duration) - {return (uint64_t)(sample_rate * response_duration);} - int calculate_dependent_values(); - - // make sure existing results are not overwritten accidently - bool set_stats_filename(string test_id); - bool check_for_existing_results(); - - // Functions that may cause Responder to finish - void register_stop_signal_handler(); - bool test_finished(size_t success_count); - int test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_test, STATS statsCurrent, size_t success_count); - - // Check if sent burst could be transmitted. - bool tx_burst_is_late(); - - // Handle receiver errors such as overflows. - bool handle_rx_errors(uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps); - - // In interactive mode, handle Responder control and output. - bool handle_interactive_control(); - void print_interactive_msg(std::string msg); - - // calibration important for interactive mode with 2nd USRP connected. - float calibrate_usrp_for_test_run(); - - // Run actual test - void run_test(float threshold = 0.0f ); - - // Detect falling edge - bool get_new_state(uint64_t total_samps, uint64_t simulate_duration, float val, float threshold); - uint64_t detect_respond_pulse_count(STATS &statsCurrent, std::vector<std::complex<float> > &buff, uint64_t trigger_count, size_t num_rx_samps, float threshold, uhd::time_spec_t rx_time); - - // Hold test results till they are printed to a file - void add_stats_to_results(STATS statsCurrent, double delay); - - // Control USRP and necessary streamers - uhd::usrp::multi_usrp::sptr create_usrp_device(); - void set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena); - void stop_usrp_stream(); - uhd::tx_streamer::sptr create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp); - uhd::rx_streamer::sptr create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp); - - // Send burst and handle results. - bool send_tx_burst(uhd::time_spec_t rx_time, size_t n); - void handle_tx_timeout(int burst, int eob); - float* alloc_response_buffer_with_data(uint64_t response_length); - uhd::tx_metadata_t get_tx_metadata(uhd::time_spec_t rx_time, size_t n); - - // Control test parameters - void update_and_print_parameters(const STATS& statsPrev, const double delay); - double get_simulate_frequency(double delay, uint64_t response_length, uint64_t original_simulate_duration); - double get_max_possible_frequency(uint64_t highest_delay_samples, uint64_t response_length); - - // Helper methods to print status during test. - void print_init_test_status(); - void print_test_title(); - void print_usrp_status(); - void print_create_usrp_msg(); - void print_tx_stream_status(); - void print_rx_stream_status(); - void print_test_parameters(); - void print_formatted_delay_line(const uint64_t simulate_duration, const uint64_t old_simulate_duration, const STATS& statsPrev, const double delay, const double simulate_frequency); - void print_overrun_msg(); - void print_error_msg(std::string msg); - void print_timeout_msg(); - void print_final_statistics(); - void print_msg_and_wait(std::string msg); - void print_msg(std::string msg); - - // Safe results of test to file. - void write_statistics_to_file(StatsMap mapStats); - void safe_write_statistics_to_file(StatsMap mapStats, uint64_t max_success, int return_code); - void write_log_file(); - - // Write debug info to log file if requested. - void write_debug_info(ofstream& logs); - std::string get_gmtime_string(time_t time); - std::string enum2str(int return_code); - std::vector<std::map<std::string,std::string> > read_eth_info(); - uhd::device_addr_t get_usrp_info(); - std::map<std::string, std::string> get_hw_info(); - std::string get_ip_subnet_addr(std::string ip); + if (simulate_frequency > 0.0) { + return (uint64_t)((double)sample_rate / simulate_frequency); + } + return 0; + } + }; + + typedef struct Stats + { + double delay; + uint64_t detected; + uint64_t missed; + uint64_t skipped; + } STATS; + + typedef std::map<uint64_t, STATS> StatsMap; + + struct DebugInfo + { + time_t start_time; + time_t end_time; + time_t start_time_test; + time_t end_time_test; + time_t first_send_timeout; + }; + Responder(Options& opt); + virtual ~Responder(); + + // Main entry point after constructor. + int run(); + + int get_return_code() + { + return _return_code; + } + +protected: +private: + // These 2 variables are used for ncurses output. + WINDOW* _window; + std::stringstream _ss; + std::stringstream _ss_cerr; + + // struct which holds all arguments as constants settable from outside the class + const Options _opt; + + string _stats_filename; // Specify name of statistics file + string _stats_log_filename; // Specify name for log file. + double _delay; // may be altered in all modes. + size_t _samps_per_packet; // This is one of the options of interest. Find out how well + // it performs. + double _delay_step; // may be altered in interactive mode + double _simulate_frequency; // updated during automatic test iterations + + // additional attributes + bool _allow_late_bursts; // may be altered in interactive mode + bool _no_delay; // may be altered in interactive mode + + // dependent variables + uint64_t _response_length; + int64_t _init_delay_count; + int64_t _dc_offset_countdown; + int64_t _level_calibration_countdown; + uint64_t _simulate_duration; + uint64_t _original_simulate_duration; + + // these variables store test conditions + uint64_t _num_total_samps; // printed on exit + size_t _overruns; // printed on exit + StatsMap _mapStats; // store results + uint64_t _max_success; // < 0 --> write results to file + int _return_code; + + // Hold USRP, streams and commands + uhd::usrp::multi_usrp::sptr _usrp; + uhd::tx_streamer::sptr _tx_stream; + uhd::rx_streamer::sptr _rx_stream; + uhd::stream_cmd_t _stream_cmd; + + // Keep track of number of timeouts. + uint64_t _timeout_burst_count; + uint64_t _timeout_eob_count; + + // Transmit attributes + float* _pResponse; + + // Control print parameters. + int _y_delay_pos; + int _x_delay_pos; // Remember the cursor position of delay line + uint64_t _last_overrun_count; + + // Hold debug info during test. Will be included in log file. + DebugInfo _dbginfo; + + /* + * Here are the class's member methods. + */ + // These methods are used for ncurses output + void create_ncurses_window(); + void FLUSH_SCREEN(); + void FLUSH_SCREEN_NL(); + + // Variable calculation helpers + inline uint64_t get_response_length(double sample_rate, double response_duration) + { + return (uint64_t)(sample_rate * response_duration); + } + int calculate_dependent_values(); + + // make sure existing results are not overwritten accidently + bool set_stats_filename(string test_id); + bool check_for_existing_results(); + + // Functions that may cause Responder to finish + void register_stop_signal_handler(); + bool test_finished(size_t success_count); + int test_step_finished(uint64_t trigger_count, + uint64_t num_total_samps_test, + STATS statsCurrent, + size_t success_count); + + // Check if sent burst could be transmitted. + bool tx_burst_is_late(); + + // Handle receiver errors such as overflows. + bool handle_rx_errors(uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps); + + // In interactive mode, handle Responder control and output. + bool handle_interactive_control(); + void print_interactive_msg(std::string msg); + + // calibration important for interactive mode with 2nd USRP connected. + float calibrate_usrp_for_test_run(); + + // Run actual test + void run_test(float threshold = 0.0f); + + // Detect falling edge + bool get_new_state( + uint64_t total_samps, uint64_t simulate_duration, float val, float threshold); + uint64_t detect_respond_pulse_count(STATS& statsCurrent, + std::vector<std::complex<float>>& buff, + uint64_t trigger_count, + size_t num_rx_samps, + float threshold, + uhd::time_spec_t rx_time); + + // Hold test results till they are printed to a file + void add_stats_to_results(STATS statsCurrent, double delay); + + // Control USRP and necessary streamers + uhd::usrp::multi_usrp::sptr create_usrp_device(); + void set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena); + void stop_usrp_stream(); + uhd::tx_streamer::sptr create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp); + uhd::rx_streamer::sptr create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp); + + // Send burst and handle results. + bool send_tx_burst(uhd::time_spec_t rx_time, size_t n); + void handle_tx_timeout(int burst, int eob); + float* alloc_response_buffer_with_data(uint64_t response_length); + uhd::tx_metadata_t get_tx_metadata(uhd::time_spec_t rx_time, size_t n); + + // Control test parameters + void update_and_print_parameters(const STATS& statsPrev, const double delay); + double get_simulate_frequency( + double delay, uint64_t response_length, uint64_t original_simulate_duration); + double get_max_possible_frequency( + uint64_t highest_delay_samples, uint64_t response_length); + + // Helper methods to print status during test. + void print_init_test_status(); + void print_test_title(); + void print_usrp_status(); + void print_create_usrp_msg(); + void print_tx_stream_status(); + void print_rx_stream_status(); + void print_test_parameters(); + void print_formatted_delay_line(const uint64_t simulate_duration, + const uint64_t old_simulate_duration, + const STATS& statsPrev, + const double delay, + const double simulate_frequency); + void print_overrun_msg(); + void print_error_msg(std::string msg); + void print_timeout_msg(); + void print_final_statistics(); + void print_msg_and_wait(std::string msg); + void print_msg(std::string msg); + + // Safe results of test to file. + void write_statistics_to_file(StatsMap mapStats); + void safe_write_statistics_to_file( + StatsMap mapStats, uint64_t max_success, int return_code); + void write_log_file(); + + // Write debug info to log file if requested. + void write_debug_info(ofstream& logs); + std::string get_gmtime_string(time_t time); + std::string enum2str(int return_code); + std::vector<std::map<std::string, std::string>> read_eth_info(); + uhd::device_addr_t get_usrp_info(); + std::map<std::string, std::string> get_hw_info(); + std::string get_ip_subnet_addr(std::string ip); }; #endif // RESPONDER_H diff --git a/host/utils/latency/lib/Responder.cpp b/host/utils/latency/lib/Responder.cpp index 5597c0fcd..0d7a307dd 100644 --- a/host/utils/latency/lib/Responder.cpp +++ b/host/utils/latency/lib/Responder.cpp @@ -6,60 +6,55 @@ // #include "Responder.hpp" - -#include <iostream> -#include <iomanip> -#include <fstream> +#include <uhd/property_tree.hpp> +#include <uhd/utils/thread.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <boost/thread/condition_variable.hpp> +#include <cmath> #include <complex> #include <csignal> -#include <cmath> +#include <fstream> +#include <iomanip> +#include <iostream> #include <sstream> -#include <boost/format.hpp> -#include <boost/algorithm/string.hpp> -#include <boost/thread/condition_variable.hpp> -#include <boost/filesystem.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/property_tree.hpp> - const std::string _eth_file("eths_info.txt"); // Redirect output to stderr -struct cerr_redirect { - cerr_redirect( std::streambuf * new_buffer ) - : old( std::cerr.rdbuf( new_buffer ) ) - { } +struct cerr_redirect +{ + cerr_redirect(std::streambuf* new_buffer) : old(std::cerr.rdbuf(new_buffer)) {} - ~cerr_redirect( ) { - std::cerr.rdbuf( old ); + ~cerr_redirect() + { + std::cerr.rdbuf(old); } private: - std::streambuf * old; + std::streambuf* old; }; - // Catch keyboard interrupts for clean manual abort static bool s_stop_signal_called = false; -static int s_signal = 0; +static int s_signal = 0; static void sig_int_handler(int signal) { s_stop_signal_called = true; - s_signal = signal; + s_signal = signal; } // member of Responder to register sig int handler -void -Responder::register_stop_signal_handler() +void Responder::register_stop_signal_handler() { std::signal(SIGINT, &sig_int_handler); } // For ncurses. Print everything in stream to screen -void -Responder::FLUSH_SCREEN() +void Responder::FLUSH_SCREEN() { printw(_ss.str().c_str()); refresh(); @@ -67,13 +62,12 @@ Responder::FLUSH_SCREEN() } // Like FLUSH_SCREEN but with new line -void -Responder::FLUSH_SCREEN_NL() +void Responder::FLUSH_SCREEN_NL() { do { int y, x; getyx(_window, y, x); - if (x > 0){ + if (x > 0) { printw("\n"); y++; } @@ -82,33 +76,39 @@ Responder::FLUSH_SCREEN_NL() } // Constructor -Responder::Responder( Options& opt) - : _opt(opt), - _stats_filename(opt.stats_filename), - _delay(opt.delay), - _samps_per_packet(opt.samps_per_packet), - _delay_step(opt.delay_step), - _simulate_frequency(opt.simulate_frequency), - _allow_late_bursts(opt.allow_late_bursts), - _no_delay(opt.no_delay), - //Initialize atributes not given by Options - _num_total_samps(0), // printed on exit - _overruns(0), // printed on exit - _max_success(0), // < 0 --> write results to file - _return_code(RETCODE_OK), - _stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS), - _timeout_burst_count(0), - _timeout_eob_count(0), - _y_delay_pos(-1), - _x_delay_pos(-1), // Remember the cursor position of delay line. +Responder::Responder(Options& opt) + : _opt(opt) + , _stats_filename(opt.stats_filename) + , _delay(opt.delay) + , _samps_per_packet(opt.samps_per_packet) + , _delay_step(opt.delay_step) + , _simulate_frequency(opt.simulate_frequency) + , _allow_late_bursts(opt.allow_late_bursts) + , _no_delay(opt.no_delay) + , + // Initialize atributes not given by Options + _num_total_samps(0) + , // printed on exit + _overruns(0) + , // printed on exit + _max_success(0) + , // < 0 --> write results to file + _return_code(RETCODE_OK) + , _stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS) + , _timeout_burst_count(0) + , _timeout_eob_count(0) + , _y_delay_pos(-1) + , _x_delay_pos(-1) + , // Remember the cursor position of delay line. _last_overrun_count(0) { - time( &_dbginfo.start_time ); // for debugging + time(&_dbginfo.start_time); // for debugging // Disable logging to console uhd::log::set_console_level(uhd::log::off); - if (uhd::set_thread_priority_safe(_opt.rt_priority, _opt.realtime) == false) // try to set realtime scheduling + if (uhd::set_thread_priority_safe(_opt.rt_priority, _opt.realtime) + == false) // try to set realtime scheduling { cerr << "Failed to set real-time" << endl; } @@ -120,16 +120,12 @@ Responder::Responder( Options& opt) create_ncurses_window(); print_create_usrp_msg(); - try - { + try { _usrp = create_usrp_device(); - } - catch (const std::runtime_error& e) - { - print_msg(e.what() ); + } catch (const std::runtime_error& e) { + print_msg(e.what()); _return_code = RETCODE_RUNTIME_ERROR; - } - catch(...){ + } catch (...) { print_msg("unhandled ERROR"); _return_code = RETCODE_UNKNOWN_EXCEPTION; print_msg_and_wait("create USRP device failed!\nPress key to abort test..."); @@ -141,12 +137,10 @@ Responder::Responder( Options& opt) // ensure that filename is set string test_id = _usrp->get_mboard_name(); - if (set_stats_filename(test_id) ) - { + if (set_stats_filename(test_id)) { _return_code = RETCODE_BAD_ARGS; // make sure run() does return! FLUSH_SCREEN(); - if (_opt.batch_mode == false) - { + if (_opt.batch_mode == false) { print_msg_and_wait("Press any key to end..."); } return; @@ -156,20 +150,19 @@ Responder::Responder( Options& opt) register_stop_signal_handler(); } -int -Responder::calculate_dependent_values() +int Responder::calculate_dependent_values() { - _response_length = _opt.response_length(); - _init_delay_count = (int64_t)(_opt.sample_rate * _opt.init_delay); - _dc_offset_countdown = (int64_t)(_opt.sample_rate * _opt.dc_offset_delay); + _response_length = _opt.response_length(); + _init_delay_count = (int64_t)(_opt.sample_rate * _opt.init_delay); + _dc_offset_countdown = (int64_t)(_opt.sample_rate * _opt.dc_offset_delay); _level_calibration_countdown = (int64_t)_opt.level_calibration_count(); - _original_simulate_duration = _simulate_duration = _opt.simulate_duration(_simulate_frequency); + _original_simulate_duration = _simulate_duration = + _opt.simulate_duration(_simulate_frequency); - if (_simulate_duration > 0) - { + if (_simulate_duration > 0) { // Skip settling period and calibration - _init_delay_count = 0; - _dc_offset_countdown = 0; + _init_delay_count = 0; + _dc_offset_countdown = 0; _level_calibration_countdown = 0; double highest_delay = 0.0; @@ -179,70 +172,78 @@ Responder::calculate_dependent_values() highest_delay = _delay; uint64_t highest_delay_samples = _opt.highest_delay_samples(highest_delay); - if ((highest_delay_samples + _response_length + _opt.flush_count) > _simulate_duration) - { - if (_opt.adjust_simulation_rate) // This is now done DURING the simulation based on active delay + if ((highest_delay_samples + _response_length + _opt.flush_count) + > _simulate_duration) { + if (_opt.adjust_simulation_rate) // This is now done DURING the simulation + // based on active delay { //_simulate_frequency = max_possible_rate; - //_simulate_duration = (uint64_t)((double)sample_rate / _simulate_frequency); - } - else - { - cerr << boost::format("Highest delay and response duration will exceed the pulse simulation rate (%ld + %ld > %ld samples)") % highest_delay_samples % _response_length % _simulate_duration << endl; - int max_possible_rate = (int) get_max_possible_frequency(highest_delay_samples, _response_length); - double max_possible_delay = (double)(_simulate_duration - (_response_length + _opt.flush_count)) / (double)_opt.sample_rate; - cerr << boost::format("Simulation rate must be less than %i Hz, or maximum delay must be less than %f s") % max_possible_rate % max_possible_delay << endl; + //_simulate_duration = (uint64_t)((double)sample_rate / + //_simulate_frequency); + } else { + cerr << boost::format( + "Highest delay and response duration will exceed the pulse " + "simulation rate (%ld + %ld > %ld samples)") + % highest_delay_samples % _response_length + % _simulate_duration + << endl; + int max_possible_rate = (int)get_max_possible_frequency( + highest_delay_samples, _response_length); + double max_possible_delay = + (double)(_simulate_duration - (_response_length + _opt.flush_count)) + / (double)_opt.sample_rate; + cerr << boost::format("Simulation rate must be less than %i Hz, or " + "maximum delay must be less than %f s") + % max_possible_rate % max_possible_delay + << endl; if (_opt.ignore_simulation_check == 0) return RETCODE_BAD_ARGS; } } - } - else - { - boost::format fmt("Simulation frequency too high (%f Hz with sample_rate %f Msps)"); - fmt % _simulate_frequency % (_opt.sample_rate/1e6); + } else { + boost::format fmt( + "Simulation frequency too high (%f Hz with sample_rate %f Msps)"); + fmt % _simulate_frequency % (_opt.sample_rate / 1e6); cerr << fmt << endl; return RETCODE_BAD_ARGS; } - if (_opt.test_iterations > 0) // Force certain settings during test mode + if (_opt.test_iterations > 0) // Force certain settings during test mode { - _no_delay = false; + _no_delay = false; _allow_late_bursts = false; - _delay = _opt.delay_min; + _delay = _opt.delay_min; } return RETCODE_OK; // default return code } // print test title to ncurses window -void -Responder::print_test_title() +void Responder::print_test_title() { - if (_opt.test_title.empty() == false) - { + if (_opt.test_title.empty() == false) { std::string title(_opt.test_title); boost::replace_all(title, "%", "%%"); print_msg(title + "\n"); } } -void -Responder::print_usrp_status() +void Responder::print_usrp_status() { std::string msg; - msg += (boost::format("Using device:\n%s\n") % _usrp->get_pp_string() ).str(); - msg += (boost::format("Setting RX rate: %f Msps\n") % (_opt.sample_rate/1e6)).str(); - msg += (boost::format("Actual RX rate: %f Msps\n") % (_usrp->get_rx_rate()/1e6) ).str(); - msg += (boost::format("Setting TX rate: %f Msps\n") % (_opt.sample_rate/1e6) ).str(); - msg += (boost::format("Actual TX rate: %f Msps") % (_usrp->get_tx_rate()/1e6) ).str(); + msg += (boost::format("Using device:\n%s\n") % _usrp->get_pp_string()).str(); + msg += (boost::format("Setting RX rate: %f Msps\n") % (_opt.sample_rate / 1e6)).str(); + msg += (boost::format("Actual RX rate: %f Msps\n") % (_usrp->get_rx_rate() / 1e6)) + .str(); + msg += (boost::format("Setting TX rate: %f Msps\n") % (_opt.sample_rate / 1e6)).str(); + msg += + (boost::format("Actual TX rate: %f Msps") % (_usrp->get_tx_rate() / 1e6)).str(); print_msg(msg); print_tx_stream_status(); print_rx_stream_status(); } -void -Responder::print_test_parameters() +void Responder::print_test_parameters() { // Some status output shoud be printed here! size_t rx_max_num_samps = _rx_stream->get_max_num_samps(); @@ -250,52 +251,58 @@ Responder::print_test_parameters() std::string msg; msg += (boost::format("Samples per buffer: %d\n") % _opt.samps_per_buff).str(); - msg += (boost::format("Maximum number of samples: RX = %d, TX = %d\n") % rx_max_num_samps % tx_max_num_samps).str(); - msg += (boost::format("Response length: %ld samples (%f us)") % _response_length % (_opt.response_duration * 1e6) ).str(); + msg += (boost::format("Maximum number of samples: RX = %d, TX = %d\n") + % rx_max_num_samps % tx_max_num_samps) + .str(); + msg += (boost::format("Response length: %ld samples (%f us)") % _response_length + % (_opt.response_duration * 1e6)) + .str(); if (_simulate_duration > 0) - msg += (boost::format("\nSimulating pulses at %f Hz (every %ld samples)") % _simulate_frequency % _simulate_duration ).str(); + msg += (boost::format("\nSimulating pulses at %f Hz (every %ld samples)") + % _simulate_frequency % _simulate_duration) + .str(); - if (_opt.test_iterations > 0) - { - msg += (boost::format("\nTest coverage: %f -> %f (%f steps)") % _opt.delay_min % _opt.delay_max % _opt.delay_step ).str(); + if (_opt.test_iterations > 0) { + msg += (boost::format("\nTest coverage: %f -> %f (%f steps)") % _opt.delay_min + % _opt.delay_max % _opt.delay_step) + .str(); if (_opt.end_test_after_success_count > 0) - msg += (boost::format("\nTesting will end after %d successful delays") % _opt.end_test_after_success_count ).str(); + msg += (boost::format("\nTesting will end after %d successful delays") + % _opt.end_test_after_success_count) + .str(); } - if ((_dc_offset_countdown == 0) && (_simulate_frequency == 0.0)) - { + if ((_dc_offset_countdown == 0) && (_simulate_frequency == 0.0)) { msg += "\nDC offset disabled"; } print_msg(msg); } -// e.g. B200 doesn't support this command. Check if possible and only set rx_dc_offset if available -void -Responder::set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena) +// e.g. B200 doesn't support this command. Check if possible and only set rx_dc_offset if +// available +void Responder::set_usrp_rx_dc_offset(uhd::usrp::multi_usrp::sptr usrp, bool ena) { uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // FIXME: Path needs to be build in a programmatic way. - bool dc_offset_exists = tree->exists( uhd::fs_path("/mboards/0/rx_frontends/A/dc_offset") ); - if(dc_offset_exists) - { + bool dc_offset_exists = + tree->exists(uhd::fs_path("/mboards/0/rx_frontends/A/dc_offset")); + if (dc_offset_exists) { usrp->set_rx_dc_offset(ena); } } -void -Responder::print_create_usrp_msg() +void Responder::print_create_usrp_msg() { std::string msg("Creating the USRP device"); if (_opt.device_args.empty() == false) - msg.append( (boost::format(" with args \"%s\"") % _opt.device_args ).str() ); + msg.append((boost::format(" with args \"%s\"") % _opt.device_args).str()); msg.append("..."); print_msg(msg); } -uhd::usrp::multi_usrp::sptr -Responder::create_usrp_device() +uhd::usrp::multi_usrp::sptr Responder::create_usrp_device() { uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(_opt.device_args); usrp->set_rx_rate(_opt.sample_rate); // set the rx sample rate @@ -307,22 +314,19 @@ Responder::create_usrp_device() return usrp; } -uhd::rx_streamer::sptr -Responder::create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp) +uhd::rx_streamer::sptr Responder::create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp) { - uhd::stream_args_t stream_args("fc32"); //complex floats - if (_samps_per_packet > 0) - { + uhd::stream_args_t stream_args("fc32"); // complex floats + if (_samps_per_packet > 0) { stream_args.args["spp"] = str(boost::format("%d") % _samps_per_packet); } uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - _samps_per_packet = rx_stream->get_max_num_samps(); + _samps_per_packet = rx_stream->get_max_num_samps(); return rx_stream; } -void -Responder::print_rx_stream_status() +void Responder::print_rx_stream_status() { std::string msg; msg += (boost::format("Samples per packet set to: %d\n") % _samps_per_packet).str(); @@ -332,27 +336,22 @@ Responder::print_rx_stream_status() print_msg(msg); } -uhd::tx_streamer::sptr -Responder::create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp) +uhd::tx_streamer::sptr Responder::create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp) { - uhd::stream_args_t tx_stream_args("fc32"); //complex floats - if (_allow_late_bursts == false) - { + uhd::stream_args_t tx_stream_args("fc32"); // complex floats + if (_allow_late_bursts == false) { tx_stream_args.args["underflow_policy"] = "next_burst"; } uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(tx_stream_args); return tx_stream; } -void -Responder::print_tx_stream_status() +void Responder::print_tx_stream_status() { std::string msg; - if (_allow_late_bursts == false) - { + if (_allow_late_bursts == false) { msg += "Underflow policy set to drop late bursts"; - } - else + } else msg += "Underflow policy set to allow late bursts"; if (_opt.skip_send) msg += "\nNOT sending bursts"; @@ -362,35 +361,36 @@ Responder::print_tx_stream_status() } // handle transmit timeouts properly -void -Responder::handle_tx_timeout(int burst, int eob) +void Responder::handle_tx_timeout(int burst, int eob) { - if(_timeout_burst_count == 0 && _timeout_eob_count == 0) - time( &_dbginfo.first_send_timeout ); + if (_timeout_burst_count == 0 && _timeout_eob_count == 0) + time(&_dbginfo.first_send_timeout); _timeout_burst_count += burst; _timeout_eob_count += eob; print_timeout_msg(); } -void -Responder::print_timeout_msg() +void Responder::print_timeout_msg() { - move(_y_delay_pos+3, _x_delay_pos); - print_msg( (boost::format("Send timeout, burst_count = %ld\teob_count = %ld\n") % _timeout_burst_count % _timeout_eob_count ).str() ); + move(_y_delay_pos + 3, _x_delay_pos); + print_msg((boost::format("Send timeout, burst_count = %ld\teob_count = %ld\n") + % _timeout_burst_count % _timeout_eob_count) + .str()); } uhd::tx_metadata_t Responder::get_tx_metadata(uhd::time_spec_t rx_time, size_t n) { uhd::tx_metadata_t tx_md; tx_md.start_of_burst = true; - tx_md.end_of_burst = false; + tx_md.end_of_burst = false; if ((_opt.skip_eob == false) && (_opt.combine_eob)) { tx_md.end_of_burst = true; } if (_no_delay == false) { tx_md.has_time_spec = true; - tx_md.time_spec = rx_time + uhd::time_spec_t(0, n, _opt.sample_rate) + uhd::time_spec_t(_delay); + tx_md.time_spec = + rx_time + uhd::time_spec_t(0, n, _opt.sample_rate) + uhd::time_spec_t(_delay); } else { tx_md.has_time_spec = false; } @@ -402,22 +402,25 @@ bool Responder::send_tx_burst(uhd::time_spec_t rx_time, size_t n) if (_opt.skip_send == true) { return false; } - //send a single packet + // send a single packet uhd::tx_metadata_t tx_md = get_tx_metadata(rx_time, n); - const size_t length_to_send = _response_length + (_opt.flush_count - (tx_md.end_of_burst ? 0 : 1)); + const size_t length_to_send = + _response_length + (_opt.flush_count - (tx_md.end_of_burst ? 0 : 1)); - size_t num_tx_samps = _tx_stream->send(_pResponse, length_to_send, tx_md, _opt.timeout); // send pulse! + size_t num_tx_samps = + _tx_stream->send(_pResponse, length_to_send, tx_md, _opt.timeout); // send pulse! if (num_tx_samps < length_to_send) { handle_tx_timeout(1, 0); } if (_opt.skip_eob == false && _opt.combine_eob == false) { tx_md.start_of_burst = false; - tx_md.end_of_burst = true; - tx_md.has_time_spec = false; + tx_md.end_of_burst = true; + tx_md.has_time_spec = false; const size_t eob_length_to_send = 1; - size_t eob_num_tx_samps = _tx_stream->send(&_pResponse[length_to_send], eob_length_to_send, tx_md); // send EOB + size_t eob_num_tx_samps = _tx_stream->send( + &_pResponse[length_to_send], eob_length_to_send, tx_md); // send EOB if (eob_num_tx_samps < eob_length_to_send) { handle_tx_timeout(0, 1); } @@ -427,61 +430,69 @@ bool Responder::send_tx_burst(uhd::time_spec_t rx_time, size_t n) } // ensure that stats_filename is not empty. -bool -Responder::set_stats_filename(string test_id) +bool Responder::set_stats_filename(string test_id) { - if (_stats_filename.empty()) - { + if (_stats_filename.empty()) { string file_friendly_test_id(test_id); boost::replace_all(file_friendly_test_id, " ", "_"); - boost::format fmt = boost::format("%slatency-stats.id_%s-rate_%i-spb_%i-spp_%i%s") % _opt.stats_filename_prefix % file_friendly_test_id % (int)_opt.sample_rate % _opt.samps_per_buff % _samps_per_packet % _opt.stats_filename_suffix; - _stats_filename = str(fmt) + ".txt"; + boost::format fmt = boost::format("%slatency-stats.id_%s-rate_%i-spb_%i-spp_%i%s") + % _opt.stats_filename_prefix % file_friendly_test_id + % (int)_opt.sample_rate % _opt.samps_per_buff + % _samps_per_packet % _opt.stats_filename_suffix; + _stats_filename = str(fmt) + ".txt"; _stats_log_filename = str(fmt) + ".log"; } return check_for_existing_results(); } // Check if results file can be overwritten -bool -Responder::check_for_existing_results() +bool Responder::check_for_existing_results() { bool ex = false; - if ((_opt.skip_if_results_exist) && (boost::filesystem::exists(_stats_filename))) - { - print_msg( (boost::format("Skipping invocation as results file already exists: %s") % _stats_filename).str() ); + if ((_opt.skip_if_results_exist) && (boost::filesystem::exists(_stats_filename))) { + print_msg((boost::format("Skipping invocation as results file already exists: %s") + % _stats_filename) + .str()); ex = true; } return ex; } // Allocate an array with a burst response -float* -Responder::alloc_response_buffer_with_data(uint64_t response_length) // flush_count, output_value, output_scale are const +float* Responder::alloc_response_buffer_with_data( + uint64_t response_length) // flush_count, output_value, output_scale are const { float* pResponse = new float[(response_length + _opt.flush_count) * 2]; for (unsigned int i = 0; i < (response_length * 2); ++i) pResponse[i] = _opt.output_value * _opt.output_scale; - for (unsigned int i = (response_length * 2); i < ((response_length + _opt.flush_count) * 2); ++i) + for (unsigned int i = (response_length * 2); + i < ((response_length + _opt.flush_count) * 2); + ++i) pResponse[i] = 0.0f; return pResponse; } // print test parameters for current delay time -void -Responder::print_formatted_delay_line(const uint64_t simulate_duration, const uint64_t old_simulate_duration, const STATS& statsPrev, const double delay, const double simulate_frequency) +void Responder::print_formatted_delay_line(const uint64_t simulate_duration, + const uint64_t old_simulate_duration, + const STATS& statsPrev, + const double delay, + const double simulate_frequency) { - if(_y_delay_pos < 0 || _x_delay_pos < 0){ // make sure it gets printed to the same position everytime + if (_y_delay_pos < 0 + || _x_delay_pos < 0) { // make sure it gets printed to the same position everytime getyx(_window, _y_delay_pos, _x_delay_pos); } double score = 0.0; if (statsPrev.detected > 0) - score = 100.0 * (double)(statsPrev.detected - statsPrev.missed) / (double)statsPrev.detected; + score = 100.0 * (double)(statsPrev.detected - statsPrev.missed) + / (double)statsPrev.detected; std::string form; boost::format fmt0("Delay now: %.6f (previous delay %.6f scored %.1f%% [%ld / %ld])"); - fmt0 % delay % statsPrev.delay % score % (statsPrev.detected - statsPrev.missed) % statsPrev.detected; + fmt0 % delay % statsPrev.delay % score % (statsPrev.detected - statsPrev.missed) + % statsPrev.detected; form += fmt0.str(); - if (old_simulate_duration != simulate_duration) - { + if (old_simulate_duration != simulate_duration) { boost::format fmt1(" [Simulation rate now: %.1f Hz (%ld samples)]"); fmt1 % simulate_frequency % simulate_duration; form = form + fmt1.str(); @@ -491,8 +502,7 @@ Responder::print_formatted_delay_line(const uint64_t simulate_duration, const ui } // print message and wait for user interaction -void -Responder::print_msg_and_wait(std::string msg) +void Responder::print_msg_and_wait(std::string msg) { msg = "\n" + msg; print_msg(msg); @@ -502,114 +512,103 @@ Responder::print_msg_and_wait(std::string msg) } // print message to ncurses window -void -Responder::print_msg(std::string msg) +void Responder::print_msg(std::string msg) { _ss << msg << endl; FLUSH_SCREEN(); } // Check if error occured during call to receive -bool -Responder::handle_rx_errors(uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps) +bool Responder::handle_rx_errors( + uhd::rx_metadata_t::error_code_t err, size_t num_rx_samps) { // handle errors - if (err == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) - { - std::string msg = (boost::format("Timeout while streaming (received %ld samples)") % _num_total_samps).str(); + if (err == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { + std::string msg = (boost::format("Timeout while streaming (received %ld samples)") + % _num_total_samps) + .str(); print_error_msg(msg); _return_code = RETCODE_RECEIVE_TIMEOUT; return true; - } - else if (err == uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET) - { - std::string msg = (boost::format("Bad packet (received %ld samples)") % _num_total_samps).str(); + } else if (err == uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET) { + std::string msg = + (boost::format("Bad packet (received %ld samples)") % _num_total_samps).str(); print_error_msg(msg); _return_code = RETCODE_BAD_PACKET; return true; - } - else if ((num_rx_samps == 0) && (err == uhd::rx_metadata_t::ERROR_CODE_NONE)) - { + } else if ((num_rx_samps == 0) && (err == uhd::rx_metadata_t::ERROR_CODE_NONE)) { print_error_msg("Received no samples"); _return_code = RETCODE_RECEIVE_FAILED; return true; - } - else if (err == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) - { + } else if (err == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { ++_overruns; print_overrun_msg(); // update overrun info on console. - } - else if (err != uhd::rx_metadata_t::ERROR_CODE_NONE) - { - throw std::runtime_error(str(boost::format( - "Unexpected error code 0x%x" - ) % err)); + } else if (err != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error(str(boost::format("Unexpected error code 0x%x") % err)); } return false; } // print overrun status message. -void -Responder::print_overrun_msg() +void Responder::print_overrun_msg() { - if (_num_total_samps > (_last_overrun_count + (uint64_t)(_opt.sample_rate * 1.0))) - { + if (_num_total_samps > (_last_overrun_count + (uint64_t)(_opt.sample_rate * 1.0))) { int y, x, y_max, x_max; getyx(_window, y, x); getmaxyx(_window, y_max, x_max); - move(y_max-1, 0); - print_msg( (boost::format("Overruns: %d") % _overruns).str() ); + move(y_max - 1, 0); + print_msg((boost::format("Overruns: %d") % _overruns).str()); move(y, x); _last_overrun_count = _num_total_samps; } } // print error message on last line of ncurses window -void -Responder::print_error_msg(std::string msg) +void Responder::print_error_msg(std::string msg) { int y, x, y_max, x_max; getyx(_window, y, x); getmaxyx(_window, y_max, x_max); - move(y_max-2, 0); + move(y_max - 2, 0); clrtoeol(); print_msg(msg); move(y, x); } // calculate simulate frequency -double -Responder::get_simulate_frequency(double delay, uint64_t response_length, uint64_t original_simulate_duration) +double Responder::get_simulate_frequency( + double delay, uint64_t response_length, uint64_t original_simulate_duration) { - double simulate_frequency = _simulate_frequency; + double simulate_frequency = _simulate_frequency; uint64_t highest_delay_samples = _opt.highest_delay_samples(delay); - if ((_opt.optimize_simulation_rate) || - ((highest_delay_samples + response_length + _opt.flush_count) > original_simulate_duration)) - { - simulate_frequency = get_max_possible_frequency(highest_delay_samples, response_length); + if ((_opt.optimize_simulation_rate) + || ((highest_delay_samples + response_length + _opt.flush_count) + > original_simulate_duration)) { + simulate_frequency = + get_max_possible_frequency(highest_delay_samples, response_length); } return simulate_frequency; } // calculate max possible simulate frequency -double -Responder::get_max_possible_frequency(uint64_t highest_delay_samples, uint64_t response_length) // only 2 args, others are all const! +double Responder::get_max_possible_frequency(uint64_t highest_delay_samples, + uint64_t response_length) // only 2 args, others are all const! { - return std::floor((double)_opt.sample_rate / (double)(highest_delay_samples + response_length + _opt.flush_count + _opt.optimize_padding)); + return std::floor((double)_opt.sample_rate + / (double)(highest_delay_samples + response_length + + _opt.flush_count + _opt.optimize_padding)); } // Check if conditions to finish test are met. -bool -Responder::test_finished(size_t success_count) +bool Responder::test_finished(size_t success_count) { - if (success_count == _opt.end_test_after_success_count) - { - print_msg( (boost::format("\nTest complete after %d successes.") % success_count).str() ); + if (success_count == _opt.end_test_after_success_count) { + print_msg( + (boost::format("\nTest complete after %d successes.") % success_count).str()); return true; } - if (((_opt.delay_min <= _opt.delay_max) && (_delay >= _opt.delay_max)) || - ((_opt.delay_min > _opt.delay_max) && (_delay <= _opt.delay_max))) - { + if (((_opt.delay_min <= _opt.delay_max) && (_delay >= _opt.delay_max)) + || ((_opt.delay_min > _opt.delay_max) && (_delay <= _opt.delay_max))) { print_msg("\nTest complete."); return true; } @@ -617,45 +616,38 @@ Responder::test_finished(size_t success_count) } // handle keyboard input in interactive mode -bool -Responder::handle_interactive_control() +bool Responder::handle_interactive_control() { std::string msg = ""; - int c = wgetch(_window); - if (c > -1) - { + int c = wgetch(_window); + if (c > -1) { // UP/DOWN Keys control delay step width - if ((c == KEY_DOWN) || (c == KEY_UP)) - { + if ((c == KEY_DOWN) || (c == KEY_UP)) { double dMag = log10(_delay_step); - int iMag = (int)floor(dMag); + int iMag = (int)floor(dMag); iMag += ((c == KEY_UP) ? 1 : -1); _delay_step = pow(10.0, iMag); - msg += (boost::format("Step: %f") % _delay_step ).str(); + msg += (boost::format("Step: %f") % _delay_step).str(); } // LEFT/RIGHT Keys control absolute delay length - if ((c == KEY_LEFT) || (c == KEY_RIGHT)) - { + if ((c == KEY_LEFT) || (c == KEY_RIGHT)) { double step = _delay_step * ((c == KEY_RIGHT) ? 1 : -1); if ((_delay + step) >= 0.0) _delay += step; msg += (boost::format("Delay: %f") % _delay).str(); } // Enable/disable fixed delay <--> best effort mode - if (c == 'd') - { + if (c == 'd') { _no_delay = !_no_delay; if (_no_delay) msg += "Delay disabled (best effort)"; else msg += (boost::format("Delay: %f") % _delay).str(); - } - else if (c == 'q') // exit test + } else if (c == 'q') // exit test { return true; // signal test to stop - } - else if (c == 'l') // change late burst policy + } else if (c == 'l') // change late burst policy { _allow_late_bursts = !_allow_late_bursts; @@ -670,16 +662,13 @@ Responder::handle_interactive_control() } // print updated interactive control value -void -Responder::print_interactive_msg(std::string msg) +void Responder::print_interactive_msg(std::string msg) { - if(msg != "") - { + if (msg != "") { // move cursor back to beginning of line int y, x; getyx(_window, y, x); - if (x > 0) - { + if (x > 0) { move(y, 0); clrtoeol(); } @@ -689,36 +678,31 @@ Responder::print_interactive_msg(std::string msg) } // check if transmit burst is late -bool -Responder::tx_burst_is_late() +bool Responder::tx_burst_is_late() { uhd::async_metadata_t async_md; - if (_usrp->get_device()->recv_async_msg(async_md, 0)) - { - if (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_TIME_ERROR) - { + if (_usrp->get_device()->recv_async_msg(async_md, 0)) { + if (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_TIME_ERROR) { return true; } } return false; } -void -Responder::create_ncurses_window() +void Responder::create_ncurses_window() { _window = initscr(); - cbreak(); // Unbuffered key input, except for signals (cf. 'raw') + cbreak(); // Unbuffered key input, except for signals (cf. 'raw') noecho(); nonl(); intrflush(_window, FALSE); - keypad(_window, TRUE); // Enable function keys, arrow keys, ... + keypad(_window, TRUE); // Enable function keys, arrow keys, ... nodelay(_window, 0); timeout(0); } // print all fixed test parameters -void -Responder::print_init_test_status() +void Responder::print_init_test_status() { // Clear the window and write new data. erase(); @@ -740,30 +724,29 @@ Responder::print_init_test_status() } // in interactive mode with second usrp sending bursts. calibrate trigger level -float -Responder::calibrate_usrp_for_test_run() +float Responder::calibrate_usrp_for_test_run() { bool calibration_finished = false; - float threshold = 0.0f; + float threshold = 0.0f; double ave_high = 0, ave_low = 0; int ave_high_count = 0, ave_low_count = 0; - bool level_calibration_stage_2 = false; // 1. stage = rough calibration ; 2. stage = fine calibration + bool level_calibration_stage_2 = + false; // 1. stage = rough calibration ; 2. stage = fine calibration - std::vector<std::complex<float> > buff(_opt.samps_per_buff); - while (not s_stop_signal_called && !calibration_finished && _return_code == RETCODE_OK) - { + std::vector<std::complex<float>> buff(_opt.samps_per_buff); + while ( + not s_stop_signal_called && !calibration_finished && _return_code == RETCODE_OK) { uhd::rx_metadata_t rx_md; - size_t num_rx_samps = _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); + size_t num_rx_samps = + _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); // handle errors - if(handle_rx_errors(rx_md.error_code, num_rx_samps) ) - { + if (handle_rx_errors(rx_md.error_code, num_rx_samps)) { break; } // Wait for USRP for DC offset calibration - if (_dc_offset_countdown > 0) - { + if (_dc_offset_countdown > 0) { _dc_offset_countdown -= (int64_t)num_rx_samps; if (_dc_offset_countdown > 0) continue; @@ -772,8 +755,7 @@ Responder::calibrate_usrp_for_test_run() } // Wait for certain time to minimize POWER UP effects - if (_init_delay_count > 0) - { + if (_init_delay_count > 0) { _init_delay_count -= (int64_t)num_rx_samps; if (_init_delay_count > 0) continue; @@ -782,48 +764,35 @@ Responder::calibrate_usrp_for_test_run() //////////////////////////////////////////////////////////// // detect falling edges and calibrate detection values - if (_level_calibration_countdown > 0) - { - if (level_calibration_stage_2 == false) - { + if (_level_calibration_countdown > 0) { + if (level_calibration_stage_2 == false) { float average = 0.0f; for (size_t n = 0; n < num_rx_samps; n++) average += buff[n].real() * _opt.invert; average /= (float)num_rx_samps; - if (ave_low_count == 0) - { + if (ave_low_count == 0) { ave_low = average; ++ave_low_count; - } - else if (average < ave_low) - { + } else if (average < ave_low) { ave_low = average; ++ave_low_count; } - if (ave_high_count == 0) - { + if (ave_high_count == 0) { ave_high = average; ++ave_high_count; - } - else if (average > ave_high) - { + } else if (average > ave_high) { ave_high = average; ++ave_high_count; } - } - else { - for (size_t n = 0; n < num_rx_samps; n++) - { + } else { + for (size_t n = 0; n < num_rx_samps; n++) { float f = buff[n].real() * _opt.invert; - if (f >= threshold) - { + if (f >= threshold) { ave_high += f; ave_high_count++; - } - else - { + } else { ave_low += f; ave_low_count++; } @@ -832,43 +801,51 @@ Responder::calibrate_usrp_for_test_run() _level_calibration_countdown -= (int64_t)num_rx_samps; - if (_level_calibration_countdown <= 0) - { - if (level_calibration_stage_2 == false) - { - level_calibration_stage_2 = true; + if (_level_calibration_countdown <= 0) { + if (level_calibration_stage_2 == false) { + level_calibration_stage_2 = true; _level_calibration_countdown = _opt.level_calibration_count(); - threshold = ave_low + ((ave_high - ave_low) / 2.0); - print_msg( (boost::format("Phase #1: Ave low: %.3f (#%d), ave high: %.3f (#%d), threshold: %.3f") % ave_low % ave_low_count % ave_high % ave_high_count % threshold).str() ); + threshold = ave_low + ((ave_high - ave_low) / 2.0); + print_msg((boost::format("Phase #1: Ave low: %.3f (#%d), ave high: " + "%.3f (#%d), threshold: %.3f") + % ave_low % ave_low_count % ave_high % ave_high_count + % threshold) + .str()); ave_low_count = ave_high_count = 0; ave_low = ave_high = 0.0f; continue; - } - else - { + } else { ave_low /= (double)ave_low_count; ave_high /= (double)ave_high_count; threshold = ave_low + ((ave_high - ave_low) * _opt.trigger_level); - print_msg( (boost::format("Phase #2: Ave low: %.3f (#%d), ave high: %.3f (#%d), threshold: %.3f\n") % ave_low % ave_low_count % ave_high % ave_high_count % threshold).str() ); - - _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; + print_msg((boost::format("Phase #2: Ave low: %.3f (#%d), ave high: " + "%.3f (#%d), threshold: %.3f\n") + % ave_low % ave_low_count % ave_high % ave_high_count + % threshold) + .str()); + + _stream_cmd.stream_mode = + uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); double diff = std::abs(ave_high - ave_low); - if (diff < _opt.pulse_detection_threshold) - { + if (diff < _opt.pulse_detection_threshold) { _return_code = RETCODE_BAD_ARGS; - print_error_msg( (boost::format("Did not detect any pulses (difference %.6f < detection threshold %.6f)") % diff % _opt.pulse_detection_threshold).str() ); + print_error_msg( + (boost::format("Did not detect any pulses (difference %.6f < " + "detection threshold %.6f)") + % diff % _opt.pulse_detection_threshold) + .str()); break; } - _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + _stream_cmd.stream_mode = + uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); } - } - else + } else continue; } // calibration finished calibration_finished = true; @@ -877,86 +854,82 @@ Responder::calibrate_usrp_for_test_run() } // try to stop USRP properly after tests -void -Responder::stop_usrp_stream() +void Responder::stop_usrp_stream() { - try - { - if (_usrp) - { + try { + if (_usrp) { _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; - _stream_cmd.stream_now = true; + _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); } - } - catch (...) - { + } catch (...) { // } } // after each delay length update test parameters and print them -void -Responder::update_and_print_parameters(const STATS& statsPrev, const double delay) +void Responder::update_and_print_parameters(const STATS& statsPrev, const double delay) { uint64_t old_simulate_duration = _simulate_duration; - _simulate_frequency = get_simulate_frequency(delay, _response_length, _original_simulate_duration); + _simulate_frequency = + get_simulate_frequency(delay, _response_length, _original_simulate_duration); _simulate_duration = _opt.simulate_duration(_simulate_frequency); - print_formatted_delay_line(_simulate_duration, old_simulate_duration, statsPrev, delay, _simulate_frequency); + print_formatted_delay_line( + _simulate_duration, old_simulate_duration, statsPrev, delay, _simulate_frequency); _timeout_burst_count = 0; - _timeout_eob_count = 0; + _timeout_eob_count = 0; } // detect or simulate burst level. -bool -Responder::get_new_state(uint64_t total_samps, uint64_t simulate_duration, float val, float threshold) +bool Responder::get_new_state( + uint64_t total_samps, uint64_t simulate_duration, float val, float threshold) { bool new_state = false; if (simulate_duration > 0) // only simulated input bursts! new_state = (((total_samps) % simulate_duration) == 0); else - new_state = (val >= threshold); // TODO: Just measure difference in fall + new_state = (val >= threshold); // TODO: Just measure difference in fall return new_state; } // detect a pulse, respond to it and count number of pulses. // statsCurrent holds parameters. -uint64_t -Responder::detect_respond_pulse_count(STATS &statsCurrent, std::vector<std::complex<float> > &buff, uint64_t trigger_count, size_t num_rx_samps, float threshold, uhd::time_spec_t rx_time) +uint64_t Responder::detect_respond_pulse_count(STATS& statsCurrent, + std::vector<std::complex<float>>& buff, + uint64_t trigger_count, + size_t num_rx_samps, + float threshold, + uhd::time_spec_t rx_time) { // buff, threshold bool input_state = false; - for (size_t n = 0; n < num_rx_samps; n++) - { + for (size_t n = 0; n < num_rx_samps; n++) { float f = buff[n].real() * _opt.invert; - bool new_state = get_new_state(_num_total_samps + n, _simulate_duration, f, threshold); + bool new_state = + get_new_state(_num_total_samps + n, _simulate_duration, f, threshold); if ((new_state == false) && (input_state)) // == falling_edge { trigger_count++; statsCurrent.detected++; - if ((_opt.test_iterations > 0) - && (_opt.skip_iterations > 0) - && (statsCurrent.skipped == 0) - && (_opt.skip_iterations == statsCurrent.detected)) - { + if ((_opt.test_iterations > 0) && (_opt.skip_iterations > 0) + && (statsCurrent.skipped == 0) + && (_opt.skip_iterations == statsCurrent.detected)) { memset(&statsCurrent, 0x00, sizeof(STATS)); - statsCurrent.delay = _delay; + statsCurrent.delay = _delay; statsCurrent.detected = 1; - statsCurrent.skipped = _opt.skip_iterations; + statsCurrent.skipped = _opt.skip_iterations; trigger_count = 1; } - if( !send_tx_burst(rx_time, n) ) - { + if (!send_tx_burst(rx_time, n)) { statsCurrent.missed++; } - if(tx_burst_is_late() ) - { + if (tx_burst_is_late()) { statsCurrent.missed++; } } @@ -967,34 +940,33 @@ Responder::detect_respond_pulse_count(STATS &statsCurrent, std::vector<std::comp } // this is the actual "work" function. All the fun happens here -void -Responder::run_test(float threshold) +void Responder::run_test(float threshold) { STATS statsCurrent; //, statsPrev; memset(&statsCurrent, 0x00, sizeof(STATS)); - if (_opt.test_iterations > 0) - { + if (_opt.test_iterations > 0) { update_and_print_parameters(statsCurrent, _delay); statsCurrent.delay = _opt.delay_min; } /////////////////////////////////////////////////////////////////////////// - uint64_t trigger_count = 0; - size_t success_count = 0; + uint64_t trigger_count = 0; + size_t success_count = 0; uint64_t num_total_samps_test = 0; - std::vector<std::complex<float> > buff(_opt.samps_per_buff); - while (not s_stop_signal_called && _return_code == RETCODE_OK) - { + std::vector<std::complex<float>> buff(_opt.samps_per_buff); + while (not s_stop_signal_called && _return_code == RETCODE_OK) { // get samples from rx stream. uhd::rx_metadata_t rx_md; - size_t num_rx_samps = _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); + size_t num_rx_samps = + _rx_stream->recv(&buff.front(), buff.size(), rx_md, _opt.timeout); // handle errors - if(handle_rx_errors(rx_md.error_code, num_rx_samps) ) - { + if (handle_rx_errors(rx_md.error_code, num_rx_samps)) { break; } - // detect falling edges, send respond pulse and check if response could be sent in time - trigger_count = detect_respond_pulse_count(statsCurrent, buff, trigger_count, num_rx_samps, threshold, rx_md.time_spec); + // detect falling edges, send respond pulse and check if response could be sent in + // time + trigger_count = detect_respond_pulse_count( + statsCurrent, buff, trigger_count, num_rx_samps, threshold, rx_md.time_spec); // increase counters for single test and overall test samples count. _num_total_samps += num_rx_samps; @@ -1003,40 +975,47 @@ Responder::run_test(float threshold) // control section for interactive mode if (_opt.test_iterations == 0) // == "interactive' { - if(handle_interactive_control() ) + if (handle_interactive_control()) break; } // control section for test mode if (_opt.test_iterations > 0) // == test mode / batch-mode { - int step_return = test_step_finished(trigger_count, num_total_samps_test, statsCurrent, success_count); - if(step_return == -2) // == test is finished with all desired delay steps + int step_return = test_step_finished( + trigger_count, num_total_samps_test, statsCurrent, success_count); + if (step_return == -2) // == test is finished with all desired delay steps break; - else if(step_return == -1) // just continue test + else if (step_return == -1) // just continue test continue; else // test with one delay is finished { - success_count = (size_t) step_return; - trigger_count = 0; + success_count = (size_t)step_return; + trigger_count = 0; num_total_samps_test = 0; - memset(&statsCurrent, 0x00, sizeof(STATS)); // reset current stats for next test iteration + memset(&statsCurrent, + 0x00, + sizeof(STATS)); // reset current stats for next test iteration statsCurrent.delay = _delay; } } // end test mode control section - }// exit outer loop after stop signal is called, test is finished or other break condition is met + } // exit outer loop after stop signal is called, test is finished or other break + // condition is met if (s_stop_signal_called) _return_code = RETCODE_MANUAL_ABORT; } // check if test with one specific delay is finished -int -Responder::test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_test, STATS statsCurrent, size_t success_count) +int Responder::test_step_finished(uint64_t trigger_count, + uint64_t num_total_samps_test, + STATS statsCurrent, + size_t success_count) { - if ( ((_opt.test_iterations_is_sample_count == false) && (trigger_count >= _opt.test_iterations)) || - ((_opt.test_iterations_is_sample_count) && (num_total_samps_test > _opt.test_iterations)) ) - { + if (((_opt.test_iterations_is_sample_count == false) + && (trigger_count >= _opt.test_iterations)) + || ((_opt.test_iterations_is_sample_count) + && (num_total_samps_test > _opt.test_iterations))) { add_stats_to_results(statsCurrent, _delay); if (statsCurrent.missed == 0) // == NO late bursts @@ -1044,7 +1023,7 @@ Responder::test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_t else success_count = 0; - if(test_finished(success_count) ) + if (test_finished(success_count)) return -2; // test is completely finished _delay += _delay_step; // increase delay by one step @@ -1056,58 +1035,50 @@ Responder::test_step_finished(uint64_t trigger_count, uint64_t num_total_samps_t } // save test results -void -Responder::add_stats_to_results(STATS statsCurrent, double delay) +void Responder::add_stats_to_results(STATS statsCurrent, double delay) { - _max_success = max(_max_success, (statsCurrent.detected - statsCurrent.missed)); // > 0 --> save results - uint64_t key = (uint64_t)(delay * 1e6); + _max_success = max(_max_success, + (statsCurrent.detected - statsCurrent.missed)); // > 0 --> save results + uint64_t key = (uint64_t)(delay * 1e6); _mapStats[key] = statsCurrent; } // run tests and handle errors -int -Responder::run() +int Responder::run() { if (_return_code != RETCODE_OK) return _return_code; if (_opt.pause) print_msg_and_wait("Press any key to begin..."); - time( &_dbginfo.start_time_test ); + time(&_dbginfo.start_time_test); // Put some info about the test on the console print_init_test_status(); try { - //setup streaming + // setup streaming _stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - _stream_cmd.stream_now = true; + _stream_cmd.stream_now = true; _usrp->issue_stream_cmd(_stream_cmd); - if( !_opt.batch_mode ){ + if (!_opt.batch_mode) { float threshold = calibrate_usrp_for_test_run(); - if (_return_code != RETCODE_OK) - { + if (_return_code != RETCODE_OK) { return _return_code; } run_test(threshold); - } - else - { + } else { run_test(); } - } - catch (const std::runtime_error& e) - { - print_msg(e.what() ); + } catch (const std::runtime_error& e) { + print_msg(e.what()); _return_code = RETCODE_RUNTIME_ERROR; - } - catch (...) - { + } catch (...) { print_msg("Unhandled exception"); _return_code = RETCODE_UNKNOWN_EXCEPTION; } stop_usrp_stream(); - time( &_dbginfo.end_time_test ); + time(&_dbginfo.end_time_test); return (_return_code < 0 ? _return_code : _overruns); } @@ -1116,8 +1087,7 @@ Responder::run() */ // This method should print statistics after ncurses endwin. -void -Responder::print_final_statistics() +void Responder::print_final_statistics() { cout << boost::format("Received %ld samples during test run") % _num_total_samps; if (_overruns > 0) @@ -1126,29 +1096,30 @@ Responder::print_final_statistics() } // safe test results to a log file if enabled -void -Responder::write_log_file() +void Responder::write_log_file() { - try - { - if(_opt.log_file){ + try { + if (_opt.log_file) { std::map<std::string, std::string> hw_info = get_hw_info(); ofstream logs(_stats_log_filename.c_str()); logs << boost::format("title=%s") % _opt.test_title << endl; - logs << boost::format("device=%s") % _usrp->get_mboard_name() << endl; + logs << boost::format("device=%s") % _usrp->get_mboard_name() << endl; logs << boost::format("device_args=%s") % _opt.device_args << endl; - logs << boost::format("type=%s") % hw_info["type"] << endl; - if (hw_info.size() > 0) - { - logs << boost::format("usrp_addr=%s") % hw_info["usrp_addr"] << endl; - logs << boost::format("usrp_name=%s") % hw_info["name"] << endl; - logs << boost::format("serial=%s") % hw_info["serial"] << endl; - logs << boost::format("host_interface=%s") % hw_info["interface"] << endl; - logs << boost::format("host_addr=%s") % hw_info["host_addr"] << endl; - logs << boost::format("host_mac=%s") % hw_info["mac"] << endl; - logs << boost::format("host_vendor=%s (id=%s)") % hw_info["vendor"] % hw_info["vendor_id"] << endl; - logs << boost::format("host_device=%s (id=%s)") % hw_info["device"] % hw_info["device_id"] << endl; + logs << boost::format("type=%s") % hw_info["type"] << endl; + if (hw_info.size() > 0) { + logs << boost::format("usrp_addr=%s") % hw_info["usrp_addr"] << endl; + logs << boost::format("usrp_name=%s") % hw_info["name"] << endl; + logs << boost::format("serial=%s") % hw_info["serial"] << endl; + logs << boost::format("host_interface=%s") % hw_info["interface"] << endl; + logs << boost::format("host_addr=%s") % hw_info["host_addr"] << endl; + logs << boost::format("host_mac=%s") % hw_info["mac"] << endl; + logs << boost::format("host_vendor=%s (id=%s)") % hw_info["vendor"] + % hw_info["vendor_id"] + << endl; + logs << boost::format("host_device=%s (id=%s)") % hw_info["device"] + % hw_info["device_id"] + << endl; } logs << boost::format("sample_rate=%f") % _opt.sample_rate << endl; logs << boost::format("samps_per_buff=%i") % _opt.samps_per_buff << endl; @@ -1158,97 +1129,113 @@ Responder::write_log_file() logs << boost::format("delay_step=%f") % _delay_step << endl; logs << boost::format("delay=%f") % _delay << endl; logs << boost::format("init_delay=%f") % _opt.init_delay << endl; - logs << boost::format("response_duration=%f") % _opt.response_duration << endl; + logs << boost::format("response_duration=%f") % _opt.response_duration + << endl; logs << boost::format("response_length=%ld") % _response_length << endl; logs << boost::format("timeout=%f") % _opt.timeout << endl; - logs << boost::format("timeout_burst_count=%ld") % _timeout_burst_count << endl; + logs << boost::format("timeout_burst_count=%ld") % _timeout_burst_count + << endl; logs << boost::format("timeout_eob_count=%f") % _timeout_eob_count << endl; - logs << boost::format("allow_late_bursts=%s") % (_allow_late_bursts ? "yes" : "no") << endl; + logs << boost::format("allow_late_bursts=%s") + % (_allow_late_bursts ? "yes" : "no") + << endl; logs << boost::format("skip_eob=%s") % (_opt.skip_eob ? "yes" : "no") << endl; - logs << boost::format("combine_eob=%s") % (_opt.combine_eob ? "yes" : "no") << endl; - logs << boost::format("skip_send=%s") % (_opt.skip_send ? "yes" : "no") << endl; + logs << boost::format("combine_eob=%s") % (_opt.combine_eob ? "yes" : "no") + << endl; + logs << boost::format("skip_send=%s") % (_opt.skip_send ? "yes" : "no") + << endl; logs << boost::format("no_delay=%s") % (_no_delay ? "yes" : "no") << endl; logs << boost::format("simulate_frequency=%f") % _simulate_frequency << endl; logs << boost::format("simulate_duration=%ld") % _simulate_duration << endl; - logs << boost::format("original_simulate_duration=%ld") % _original_simulate_duration << endl; + logs << boost::format("original_simulate_duration=%ld") + % _original_simulate_duration + << endl; logs << boost::format("realtime=%s") % (_opt.realtime ? "yes" : "no") << endl; logs << boost::format("rt_priority=%f") % _opt.rt_priority << endl; logs << boost::format("test_iterations=%ld") % _opt.test_iterations << endl; - logs << boost::format("end_test_after_success_count=%i") % _opt.end_test_after_success_count << endl; + logs << boost::format("end_test_after_success_count=%i") + % _opt.end_test_after_success_count + << endl; logs << boost::format("skip_iterations=%i") % _opt.skip_iterations << endl; logs << boost::format("overruns=%i") % _overruns << endl; logs << boost::format("num_total_samps=%ld") % _num_total_samps << endl; - logs << boost::format("return_code=%i\t(%s)") % _return_code % enum2str(_return_code) << endl; + logs << boost::format("return_code=%i\t(%s)") % _return_code + % enum2str(_return_code) + << endl; logs << endl; write_debug_info(logs); - } - } - catch(...) - { + } catch (...) { cerr << "Failed to write log file to: " << _stats_log_filename << endl; } } // write debug info to log file -void -Responder::write_debug_info(ofstream& logs) +void Responder::write_debug_info(ofstream& logs) { logs << endl << "%% DEBUG INFO %%" << endl; - logs << boost::format("dbg_time_start=%s") % get_gmtime_string(_dbginfo.start_time) << endl; - logs << boost::format("dbg_time_end=%s") % get_gmtime_string(_dbginfo.end_time) << endl; - logs << boost::format("dbg_time_duration=%d") % difftime( _dbginfo.end_time, _dbginfo.start_time ) << endl; - logs << boost::format("dbg_time_start_test=%s") % get_gmtime_string(_dbginfo.start_time_test) << endl; - logs << boost::format("dbg_time_end_test=%s") % get_gmtime_string(_dbginfo.end_time_test) << endl; - logs << boost::format("dbg_time_duration_test=%d") % difftime( _dbginfo.end_time_test, _dbginfo.start_time_test ) << endl; - logs << boost::format("dbg_time_first_send_timeout=%s") % get_gmtime_string(_dbginfo.first_send_timeout) << endl; + logs << boost::format("dbg_time_start=%s") % get_gmtime_string(_dbginfo.start_time) + << endl; + logs << boost::format("dbg_time_end=%s") % get_gmtime_string(_dbginfo.end_time) + << endl; + logs << boost::format("dbg_time_duration=%d") + % difftime(_dbginfo.end_time, _dbginfo.start_time) + << endl; + logs << boost::format("dbg_time_start_test=%s") + % get_gmtime_string(_dbginfo.start_time_test) + << endl; + logs << boost::format("dbg_time_end_test=%s") + % get_gmtime_string(_dbginfo.end_time_test) + << endl; + logs << boost::format("dbg_time_duration_test=%d") + % difftime(_dbginfo.end_time_test, _dbginfo.start_time_test) + << endl; + logs << boost::format("dbg_time_first_send_timeout=%s") + % get_gmtime_string(_dbginfo.first_send_timeout) + << endl; } // convert a time string to desired format -std::string -Responder::get_gmtime_string(time_t time) +std::string Responder::get_gmtime_string(time_t time) { tm* ftm; - ftm = gmtime( &time ); + ftm = gmtime(&time); std::string strtime; - strtime.append( (boost::format("%i") % (ftm->tm_year+1900) ).str() ); - strtime.append( (boost::format("-%02i") % ftm->tm_mon).str() ); - strtime.append( (boost::format("-%02i") % ftm->tm_mday).str() ); - strtime.append( (boost::format("-%02i") % ((ftm->tm_hour)) ).str() ); - strtime.append( (boost::format(":%02i") % ftm->tm_min).str() ); - strtime.append( (boost::format(":%02i") % ftm->tm_sec).str() ); + strtime.append((boost::format("%i") % (ftm->tm_year + 1900)).str()); + strtime.append((boost::format("-%02i") % ftm->tm_mon).str()); + strtime.append((boost::format("-%02i") % ftm->tm_mday).str()); + strtime.append((boost::format("-%02i") % ((ftm->tm_hour))).str()); + strtime.append((boost::format(":%02i") % ftm->tm_min).str()); + strtime.append((boost::format(":%02i") % ftm->tm_sec).str()); return strtime; } // read hardware info from file if available to include it in log file -std::map<std::string, std::string> -Responder::get_hw_info() +std::map<std::string, std::string> Responder::get_hw_info() { std::map<std::string, std::string> result; - std::vector<std::map<std::string,std::string> > eths = read_eth_info(); - if(eths.empty()){ + std::vector<std::map<std::string, std::string>> eths = read_eth_info(); + if (eths.empty()) { return result; } uhd::device_addr_t usrp_info = get_usrp_info(); - std::string uaddr = get_ip_subnet_addr(usrp_info["addr"]); + std::string uaddr = get_ip_subnet_addr(usrp_info["addr"]); - for(unsigned int i = 0 ; i < eths.size() ; i++ ) - { - if(get_ip_subnet_addr(eths[i]["addr"]) == uaddr) - { - result["type"] = usrp_info["type"]; + for (unsigned int i = 0; i < eths.size(); i++) { + if (get_ip_subnet_addr(eths[i]["addr"]) == uaddr) { + result["type"] = usrp_info["type"]; result["usrp_addr"] = usrp_info["addr"]; - result["name"] = usrp_info["name"]; - result["serial"] = usrp_info["serial"]; + result["name"] = usrp_info["name"]; + result["serial"] = usrp_info["serial"]; result["interface"] = eths[i]["interface"]; result["host_addr"] = eths[i]["addr"]; - result["mac"] = eths[i]["mac"]; - result["vendor"] = eths[i]["vendor"]; + result["mac"] = eths[i]["mac"]; + result["vendor"] = eths[i]["vendor"]; result["vendor_id"] = eths[i]["vendor_id"]; - result["device"] = eths[i]["device"]; + result["device"] = eths[i]["device"]; result["device_id"] = eths[i]["device_id"]; break; // Use first item found. Imitate device discovery. } @@ -1258,138 +1245,124 @@ Responder::get_hw_info() } // subnet used to identify used network interface -std::string -Responder::get_ip_subnet_addr(std::string ip) +std::string Responder::get_ip_subnet_addr(std::string ip) { return ip.substr(0, ip.rfind(".") + 1); } // get network interface info from file (should include all available interfaces) -std::vector<std::map<std::string,std::string> > -Responder::read_eth_info() +std::vector<std::map<std::string, std::string>> Responder::read_eth_info() { const std::string eth_file(_eth_file); - std::vector<std::map<std::string,std::string> > eths; - try - { + std::vector<std::map<std::string, std::string>> eths; + try { ifstream eth_info(eth_file.c_str()); - if(!eth_info.is_open()){ + if (!eth_info.is_open()) { return eths; } const int len = 256; char cline[len]; - for(; !eth_info.eof() ;) - { + for (; !eth_info.eof();) { eth_info.getline(cline, len); std::string line(cline); - if(line.find("## ETH Interface") != std::string::npos) - { + if (line.find("## ETH Interface") != std::string::npos) { eth_info.getline(cline, len); std::string eth(cline); -// cout << "interface=" << eth << endl; - std::map<std::string,std::string> iface; + // cout << "interface=" << eth << endl; + std::map<std::string, std::string> iface; iface["interface"] = eth; eths.push_back(iface); } const std::string ipstr("\tip "); - if(line.find(ipstr) != std::string::npos) - { - std::string ip( line.replace(line.begin(), line.begin()+ipstr.length(), "") ); -// cout << "ip=" << ip << endl; + if (line.find(ipstr) != std::string::npos) { + std::string ip( + line.replace(line.begin(), line.begin() + ipstr.length(), "")); + // cout << "ip=" << ip << endl; eths.back()["addr"] = ip; } const std::string macstr("\tmac "); - if(line.find(macstr) != std::string::npos) - { - std::string mac( line.replace(line.begin(), line.begin()+macstr.length(), "") ); -// cout << "mac=" << mac << endl; + if (line.find(macstr) != std::string::npos) { + std::string mac( + line.replace(line.begin(), line.begin() + macstr.length(), "")); + // cout << "mac=" << mac << endl; eths.back()["mac"] = mac; } const std::string vstr("\t\tvendor "); - if(line.find(vstr) != std::string::npos) - { - std::string vendor( line.replace(line.begin(), line.begin()+vstr.length(), "") ); - std::string vid( vendor.substr(0,6) ); + if (line.find(vstr) != std::string::npos) { + std::string vendor( + line.replace(line.begin(), line.begin() + vstr.length(), "")); + std::string vid(vendor.substr(0, 6)); vendor.replace(0, 7, ""); -// cout << "id=" << vid << endl; -// cout << "vendor=" << vendor << endl; - eths.back()["vendor"] = vendor; + // cout << "id=" << vid << endl; + // cout << "vendor=" << vendor << endl; + eths.back()["vendor"] = vendor; eths.back()["vendor_id"] = vid; } const std::string dstr("\t\tdevice "); - if(line.find(dstr) != std::string::npos) - { - std::string device( line.replace(line.begin(), line.begin()+dstr.length(), "") ); - std::string did( device.substr(0,6) ); + if (line.find(dstr) != std::string::npos) { + std::string device( + line.replace(line.begin(), line.begin() + dstr.length(), "")); + std::string did(device.substr(0, 6)); device.replace(0, 7, ""); -// cout << "id=" << did << endl; -// cout << "device=" << device << endl; - eths.back()["device"] = device; + // cout << "id=" << did << endl; + // cout << "device=" << device << endl; + eths.back()["device"] = device; eths.back()["device_id"] = did; } } - } - catch(...) - { + } catch (...) { // nothing in yet } return eths; } // get info on used USRP -uhd::device_addr_t -Responder::get_usrp_info() +uhd::device_addr_t Responder::get_usrp_info() { uhd::device_addrs_t device_addrs = uhd::device::find(_opt.device_args); - uhd::device_addr_t device_addr = device_addrs[0]; + uhd::device_addr_t device_addr = device_addrs[0]; return device_addr; } // write statistics of test run to file -void -Responder::write_statistics_to_file(StatsMap mapStats) +void Responder::write_statistics_to_file(StatsMap mapStats) { - try - { + try { ofstream results(_stats_filename.c_str()); - for (StatsMap::iterator it = mapStats.begin(); it != mapStats.end(); ++it) - { + for (StatsMap::iterator it = mapStats.begin(); it != mapStats.end(); ++it) { STATS& stats = it->second; - double d = 0.0; + double d = 0.0; if (stats.detected > 0) d = 1.0 - ((double)stats.missed / (double)stats.detected); - cout << "\t" << setprecision(6) << stats.delay << "\t\t" << setprecision(6) << d << endl; + cout << "\t" << setprecision(6) << stats.delay << "\t\t" << setprecision(6) + << d << endl; - results << (stats.delay * _opt.time_mul) << " " << setprecision(6) << d << endl; + results << (stats.delay * _opt.time_mul) << " " << setprecision(6) << d + << endl; } cout << "Statistics written to: " << _stats_filename << endl; - } - catch (...) - { + } catch (...) { cout << "Failed to write statistics to: " << _stats_filename << endl; } } // make sure write files is intended -void -Responder::safe_write_statistics_to_file(StatsMap mapStats, uint64_t max_success, int return_code) +void Responder::safe_write_statistics_to_file( + StatsMap mapStats, uint64_t max_success, int return_code) { - if ((_opt.test_iterations > 0) && (_stats_filename.empty() == false) && (_opt.no_stats_file == false)) - { - if (mapStats.empty()) - { + if ((_opt.test_iterations > 0) && (_stats_filename.empty() == false) + && (_opt.no_stats_file == false)) { + if (mapStats.empty()) { cout << "No results to output (not writing statistics file)" << endl; - } - else if ((max_success == 0) && (return_code == RETCODE_MANUAL_ABORT)) - { - cout << "Aborted before a single successful timed burst (not writing statistics file)" << endl; - } - else - { + } else if ((max_success == 0) && (return_code == RETCODE_MANUAL_ABORT)) { + cout << "Aborted before a single successful timed burst (not writing " + "statistics file)" + << endl; + } else { write_statistics_to_file(mapStats); } write_log_file(); @@ -1400,10 +1373,10 @@ Responder::safe_write_statistics_to_file(StatsMap mapStats, uint64_t max_success Responder::~Responder() { endwin(); - if(_pResponse != NULL){ + if (_pResponse != NULL) { delete[] _pResponse; } - time( &_dbginfo.end_time ); + time(&_dbginfo.end_time); // Print final info about test run print_final_statistics(); // check conditions and write statistics to file @@ -1412,21 +1385,27 @@ Responder::~Responder() } // make test output more helpful -std::string -Responder::enum2str(int return_code) +std::string Responder::enum2str(int return_code) { - switch(return_code) - { - case RETCODE_OK: return "OK"; - case RETCODE_BAD_ARGS: return "BAD_ARGS"; - case RETCODE_RUNTIME_ERROR: return "RUNTIME_ERROR"; - case RETCODE_UNKNOWN_EXCEPTION: return "UNKNOWN_EXCEPTION"; - case RETCODE_RECEIVE_TIMEOUT: return "RECEIVE_TIMEOUT"; - case RETCODE_RECEIVE_FAILED: return "RECEIVE_FAILED"; - case RETCODE_MANUAL_ABORT: return "MANUAL_ABORT"; - case RETCODE_BAD_PACKET: return "BAD_PACKET"; - case RETCODE_OVERFLOW: return "OVERFLOW"; + switch (return_code) { + case RETCODE_OK: + return "OK"; + case RETCODE_BAD_ARGS: + return "BAD_ARGS"; + case RETCODE_RUNTIME_ERROR: + return "RUNTIME_ERROR"; + case RETCODE_UNKNOWN_EXCEPTION: + return "UNKNOWN_EXCEPTION"; + case RETCODE_RECEIVE_TIMEOUT: + return "RECEIVE_TIMEOUT"; + case RETCODE_RECEIVE_FAILED: + return "RECEIVE_FAILED"; + case RETCODE_MANUAL_ABORT: + return "MANUAL_ABORT"; + case RETCODE_BAD_PACKET: + return "BAD_PACKET"; + case RETCODE_OVERFLOW: + return "OVERFLOW"; } return "UNKNOWN"; } - diff --git a/host/utils/latency/responder.cpp b/host/utils/latency/responder.cpp index 6216f15e6..fd47ad085 100644 --- a/host/utils/latency/responder.cpp +++ b/host/utils/latency/responder.cpp @@ -5,16 +5,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <boost/program_options.hpp> #include <uhd/utils/safe_main.hpp> #include <Responder.hpp> +#include <boost/program_options.hpp> namespace po = boost::program_options; static Responder::Options prog; -po::options_description -get_program_options_description() +po::options_description get_program_options_description() { po::options_description desc("Allowed options"); // clang-format off @@ -71,41 +70,40 @@ get_program_options_description() return desc; } -void -read_program_options(po::variables_map vm) +void read_program_options(po::variables_map vm) { // read out given options prog.realtime = (vm.count("no-realtime") == 0); prog.delay_step = std::abs(prog.delay_step); - if (prog.delay_min > prog.delay_max) - { + if (prog.delay_min > prog.delay_max) { prog.delay_step *= -1; } - prog.allow_late_bursts = (vm.count("allow-late") > 0); + prog.allow_late_bursts = (vm.count("allow-late") > 0); prog.test_iterations_is_sample_count = (vm.count("test-duration") > 0); - prog.invert = ((vm.count("invert") > 0) ? -1.0f : 1.0f); - prog.output_value = ((vm.count("invert-output") > 0) ? -1.0f : 1.0f); - prog.skip_eob = (vm.count("skip-eob") > 0); - prog.no_delay = (vm.count("no-delay") > 0); - prog.adjust_simulation_rate = (vm.count("adjust-simulation-rate") > 0); + prog.invert = ((vm.count("invert") > 0) ? -1.0f : 1.0f); + prog.output_value = ((vm.count("invert-output") > 0) ? -1.0f : 1.0f); + prog.skip_eob = (vm.count("skip-eob") > 0); + prog.no_delay = (vm.count("no-delay") > 0); + prog.adjust_simulation_rate = (vm.count("adjust-simulation-rate") > 0); prog.optimize_simulation_rate = (vm.count("optimize-simulation-rate") > 0); - prog.no_stats_file = (vm.count("no-stats-file") > 0); - prog.log_file = (vm.count("log-file") > 0); - prog.batch_mode = (vm.count("batch-mode") > 0); - prog.skip_if_results_exist = (vm.count("skip-if-exists") > 0); - prog.skip_send = (vm.count("disable-send") > 0); - prog.combine_eob = (vm.count("combine-eob") > 0); - prog.pause = (vm.count("pause") > 0); - prog.ignore_simulation_check = vm.count("ignore-simulation-check"); + prog.no_stats_file = (vm.count("no-stats-file") > 0); + prog.log_file = (vm.count("log-file") > 0); + prog.batch_mode = (vm.count("batch-mode") > 0); + prog.skip_if_results_exist = (vm.count("skip-if-exists") > 0); + prog.skip_send = (vm.count("disable-send") > 0); + prog.combine_eob = (vm.count("combine-eob") > 0); + prog.pause = (vm.count("pause") > 0); + prog.ignore_simulation_check = vm.count("ignore-simulation-check"); } /* * This is the MAIN function! * UHD_SAFE_MAIN catches all errors and prints them to stderr. */ -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc = get_program_options_description(); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -113,13 +111,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ read_program_options(vm); // Print help message instead of executing Responder. - if (vm.count("help")){ + if (vm.count("help")) { cout << boost::format("UHD Latency Test %s") % desc; return Responder::RETCODE_OK; } - //create a new instance of Responder and run it! + // create a new instance of Responder and run it! boost::shared_ptr<Responder> my_responder(new Responder(prog)); return my_responder->run(); } - diff --git a/host/utils/octoclock_burn_eeprom.cpp b/host/utils/octoclock_burn_eeprom.cpp index f98f526f6..6221c4e83 100644 --- a/host/utils/octoclock_burn_eeprom.cpp +++ b/host/utils/octoclock_burn_eeprom.cpp @@ -6,13 +6,13 @@ // #include <uhd/device.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/usrp_clock/octoclock_eeprom.hpp> #include <uhd/property_tree.hpp> #include <uhd/types/device_addr.hpp> +#include <uhd/usrp_clock/octoclock_eeprom.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string.hpp> -#include <boost/program_options.hpp> #include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> #include <vector> @@ -21,7 +21,8 @@ namespace po = boost::program_options; using namespace uhd; using namespace uhd::usrp_clock; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ std::string args, input_str, key, val; po::options_description desc("Allowed options"); @@ -38,50 +39,60 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))){ + // print the help message + if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))) { std::cout << boost::format("OctoClock Burn EEPROM %s") % desc << std::endl; - std::cout << boost::format( - "Omit the value argument to perform a readback,\n" - "Or specify a new value to burn into the EEPROM.\n" - ) << std::endl; + std::cout << boost::format("Omit the value argument to perform a readback,\n" + "Or specify a new value to burn into the EEPROM.\n") + << std::endl; return EXIT_FAILURE; } std::cout << "Creating OctoClock device from args: " + args << std::endl; - device::sptr oc = device::make(args, device::CLOCK); + device::sptr oc = device::make(args, device::CLOCK); property_tree::sptr tree = oc->get_tree(); - octoclock_eeprom_t oc_eeprom = tree->access<octoclock_eeprom_t>("/mboards/0/eeprom").get(); + octoclock_eeprom_t oc_eeprom = + tree->access<octoclock_eeprom_t>("/mboards/0/eeprom").get(); std::cout << std::endl; std::vector<std::string> keys_vec, vals_vec; - if(vm.count("read-all")) keys_vec = oc_eeprom.keys(); //Leaving vals_vec empty will force utility to only read - else if(vm.count("values")){ - //uhd::device_addr_t properly parses input values + if (vm.count("read-all")) + keys_vec = + oc_eeprom.keys(); // Leaving vals_vec empty will force utility to only read + else if (vm.count("values")) { + // uhd::device_addr_t properly parses input values device_addr_t vals(input_str); keys_vec = vals.keys(); vals_vec = vals.vals(); - } - else throw std::runtime_error("Must specify --values or --read-all option!"); + } else + throw std::runtime_error("Must specify --values or --read-all option!"); std::cout << "Fetching current settings from EEPROM..." << std::endl; - for(size_t i = 0; i < keys_vec.size(); i++){ - if (not oc_eeprom.has_key(keys_vec[i])){ - std::cerr << boost::format("Cannot find value for EEPROM[\"%s\"]") % keys_vec[i] << std::endl; + for (size_t i = 0; i < keys_vec.size(); i++) { + if (not oc_eeprom.has_key(keys_vec[i])) { + std::cerr << boost::format("Cannot find value for EEPROM[\"%s\"]") + % keys_vec[i] + << std::endl; return EXIT_FAILURE; } - std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] % oc_eeprom[keys_vec[i]] << std::endl; + std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] + % oc_eeprom[keys_vec[i]] + << std::endl; } - if(!vm.count("read-all")){ + if (!vm.count("read-all")) { std::cout << std::endl; - for(size_t i = 0; i < vals_vec.size(); i++){ - if(vals_vec[i] != ""){ + for (size_t i = 0; i < vals_vec.size(); i++) { + if (vals_vec[i] != "") { oc_eeprom[keys_vec[i]] = vals_vec[i]; - std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") % keys_vec[i] % vals_vec[i] << std::endl; + std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") + % keys_vec[i] % vals_vec[i] + << std::endl; } } tree->access<octoclock_eeprom_t>("/mboards/0/eeprom").set(oc_eeprom); } - std::cout << std::endl << "Power-cycle your device to allow any changes to take effect." << std::endl; + std::cout << std::endl + << "Power-cycle your device to allow any changes to take effect." + << std::endl; return EXIT_SUCCESS; } diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp index 6a3ecca13..4a8aa24d2 100644 --- a/host/utils/query_gpsdo_sensors.cpp +++ b/host/utils/query_gpsdo_sensors.cpp @@ -5,241 +5,270 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/paths.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhd/usrp/multi_usrp.hpp> #include <uhd/usrp_clock/multi_usrp_clock.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/filesystem.hpp> -#include <boost/program_options.hpp> #include <boost/format.hpp> -#include <iostream> -#include <complex> -#include <string> +#include <boost/program_options.hpp> +#include <chrono> #include <cmath> -#include <ctime> +#include <complex> #include <cstdlib> -#include <chrono> +#include <ctime> +#include <iostream> +#include <string> #include <thread> namespace po = boost::program_options; namespace fs = boost::filesystem; -void print_notes(void) { - // 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("****************************************************************************************************************\n"); +void print_notes(void) +{ + // 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( + "********************************************************************************" + "********************************\n"); } -int query_clock_sensors(const std::string &args) { - std::cout << boost::format("\nCreating the clock device with: %s...\n") % args; - uhd::usrp_clock::multi_usrp_clock::sptr clock = uhd::usrp_clock::multi_usrp_clock::make(args); - - //Verify GPS sensors are present - std::vector<std::string> sensor_names = clock->get_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 this unit does not have a GPSDO.\n\n"); - return EXIT_FAILURE; - } - - // Print NMEA strings - try { - uhd::sensor_value_t gga_string = clock->get_sensor("gps_gpgga"); - uhd::sensor_value_t rmc_string = clock->get_sensor("gps_gprmc"); - uhd::sensor_value_t servo_string = clock->get_sensor("gps_servo"); - std::cout << boost::format("\nPrinting available NMEA strings:\n"); - std::cout << boost::format("%s\n%s\n") % gga_string.to_pp_string() % rmc_string.to_pp_string(); - std::cout << boost::format("\nPrinting GPS servo status:\n"); - std::cout << boost::format("%s\n\n") % servo_string.to_pp_string(); - } catch (const uhd::lookup_error &) { - std::cout << "NMEA strings not implemented for this device." << std::endl; - } - std::cout << boost::format("GPS Epoch time: %.5f seconds\n") % clock->get_sensor("gps_time").to_real(); - std::cout << boost::format("PC Clock time: %.5f seconds\n") % time(NULL); - - //finished - std::cout << boost::format("\nDone!\n\n"); - - return EXIT_SUCCESS; +int query_clock_sensors(const std::string& args) +{ + std::cout << boost::format("\nCreating the clock device with: %s...\n") % args; + uhd::usrp_clock::multi_usrp_clock::sptr clock = + uhd::usrp_clock::multi_usrp_clock::make(args); + + // Verify GPS sensors are present + std::vector<std::string> sensor_names = clock->get_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 " + "this unit does not have a GPSDO.\n\n"); + return EXIT_FAILURE; + } + + // Print NMEA strings + try { + uhd::sensor_value_t gga_string = clock->get_sensor("gps_gpgga"); + uhd::sensor_value_t rmc_string = clock->get_sensor("gps_gprmc"); + uhd::sensor_value_t servo_string = clock->get_sensor("gps_servo"); + std::cout << boost::format("\nPrinting available NMEA strings:\n"); + std::cout << boost::format("%s\n%s\n") % gga_string.to_pp_string() + % rmc_string.to_pp_string(); + std::cout << boost::format("\nPrinting GPS servo status:\n"); + std::cout << boost::format("%s\n\n") % servo_string.to_pp_string(); + } catch (const uhd::lookup_error&) { + std::cout << "NMEA strings not implemented for this device." << std::endl; + } + std::cout << boost::format("GPS Epoch time: %.5f seconds\n") + % clock->get_sensor("gps_time").to_real(); + std::cout << boost::format("PC Clock time: %.5f seconds\n") % time(NULL); + + // finished + std::cout << boost::format("\nDone!\n\n"); + + return EXIT_SUCCESS; } -int UHD_SAFE_MAIN(int argc, char *argv[]){ - uhd::set_thread_priority_safe(); +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ + uhd::set_thread_priority_safe(); - std::string args; + std::string args; - //Set up program options - po::options_description desc("Allowed options"); - // clang-format off + // Set up program options + po::options_description desc("Allowed options"); + // clang-format off desc.add_options() ("help", "help message") ("args", po::value<std::string>(&args)->default_value(""), "Device address arguments specifying a single USRP") ("clock", "query a clock device's sensors") ; - // clang-format on - 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, 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; - } - - //If specified, query a clock device instead - if(vm.count("clock")) { - return query_clock_sensors(args); - } - - //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(); - - //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 one of these pages if the problem persists:\n"); - std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html\n"); - std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); - return EXIT_FAILURE; - } - - bool ref_set_to_gpsdo = false; - - // Set clock source to gpsdo if supported - if (uhd::has(usrp->get_clock_sources(0),"gpsdo")) - { - std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; - usrp->set_clock_source("gpsdo"); - ref_set_to_gpsdo = true; - } - std::cout << "Clock source is now " << usrp->get_clock_source(0) << std::endl; - - // Set time source to gpsdo if supported - if (uhd::has(usrp->get_time_sources(0),"gpsdo")) - { - std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; - usrp->set_time_source("gpsdo"); - ref_set_to_gpsdo = true; - } - std::cout << "Time source is now " << usrp->get_time_source(0) << std::endl; - - if (not ref_set_to_gpsdo) - { - std::cerr << "ERROR: Unable to set clock or time reference to \"gpsdo\"" << std::endl; - return EXIT_FAILURE; - } - - //Check for ref lock - if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { - uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0); - for (size_t i = 0; not ref_locked.to_bool() and i < 300; i++) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ref_locked = usrp->get_mboard_sensor("ref_locked",0); - } - if(not ref_locked.to_bool()) { - std::cout << boost::format("USRP NOT Locked to 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"); - return EXIT_FAILURE; - } else { - std::cout << boost::format("USRP Locked to Reference.\n"); - } - } else { - std::cout << boost::format("ref_locked sensor not present on this board.\n"); - } - - print_notes(); - - // The TCXO has a long warm up time, so wait up to 30 seconds for sensor data - // to show up - std::cout << "Waiting for the GPSDO to warm up..." << std::flush; - auto end = std::chrono::steady_clock::now() + std::chrono::seconds(30); - while (std::chrono::steady_clock::now() < end) { - try { - usrp->get_mboard_sensor("gps_locked", 0); - break; - } catch (std::exception &) {} - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - std::cout << "." << std::flush; - } - std::cout << std::endl; - try { - usrp->get_mboard_sensor("gps_locked", 0); - } catch (std::exception &) { - std::cout << "No response from GPSDO in 30 seconds" << std::endl; - return EXIT_FAILURE; - } - std::cout << "The GPSDO is warmed up and talking." << 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"); - } - - //Check PPS and compare UHD device time to GPS time - uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time"); - 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 << "\nTrying to align the device time to GPS time..." - << std::endl; - - gps_time = usrp->get_mboard_sensor("gps_time"); - - //set the device time to the GPS time - //getting the GPS time returns just after the PPS edge, so just add a - //second and set the device time at the next PPS edge - usrp->set_time_next_pps(uhd::time_spec_t(gps_time.to_int() + 1.0)); - //allow some time to make sure the PPS has come… - std::this_thread::sleep_for(std::chrono::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); - } - - if (pps_seconds == gps_seconds) { - std::cout << boost::format("GPS and UHD Device time are aligned.\n"); - } else { - std::cout << boost::format("Could not align UHD Device time to GPS time. Giving up.\n"); - } - std::cout << boost::format("last_pps: %ld vs gps: %ld.") - % pps_seconds % gps_seconds - << std::endl; - - //print NMEA strings - try { - 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") % gga_string.to_pp_string() % rmc_string.to_pp_string(); - } catch (uhd::lookup_error&) { - std::cout << "NMEA strings not implemented for this device." << std::endl; - } - 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"); - - return EXIT_SUCCESS; + // clang-format on + 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, 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; + } + + // If specified, query a clock device instead + if (vm.count("clock")) { + return query_clock_sensors(args); + } + + // 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(); + + // 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 one of these pages if the problem persists:\n"); + std::cout << boost::format( + " * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html\n"); + std::cout << boost::format( + " * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); + return EXIT_FAILURE; + } + + bool ref_set_to_gpsdo = false; + + // Set clock source to gpsdo if supported + if (uhd::has(usrp->get_clock_sources(0), "gpsdo")) { + std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; + usrp->set_clock_source("gpsdo"); + ref_set_to_gpsdo = true; + } + std::cout << "Clock source is now " << usrp->get_clock_source(0) << std::endl; + + // Set time source to gpsdo if supported + if (uhd::has(usrp->get_time_sources(0), "gpsdo")) { + std::cout << "Setting the reference clock source to \"gpsdo\"..." << std::endl; + usrp->set_time_source("gpsdo"); + ref_set_to_gpsdo = true; + } + std::cout << "Time source is now " << usrp->get_time_source(0) << std::endl; + + if (not ref_set_to_gpsdo) { + std::cerr << "ERROR: Unable to set clock or time reference to \"gpsdo\"" + << std::endl; + return EXIT_FAILURE; + } + + // Check for ref lock + if (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") + != sensor_names.end()) { + uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked", 0); + for (size_t i = 0; not ref_locked.to_bool() and i < 300; i++) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + ref_locked = usrp->get_mboard_sensor("ref_locked", 0); + } + if (not ref_locked.to_bool()) { + std::cout << boost::format("USRP NOT Locked to 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"); + return EXIT_FAILURE; + } else { + std::cout << boost::format("USRP Locked to Reference.\n"); + } + } else { + std::cout << boost::format("ref_locked sensor not present on this board.\n"); + } + + print_notes(); + + // The TCXO has a long warm up time, so wait up to 30 seconds for sensor data + // to show up + std::cout << "Waiting for the GPSDO to warm up..." << std::flush; + auto end = std::chrono::steady_clock::now() + std::chrono::seconds(30); + while (std::chrono::steady_clock::now() < end) { + try { + usrp->get_mboard_sensor("gps_locked", 0); + break; + } catch (std::exception&) { + } + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + std::cout << "." << std::flush; + } + std::cout << std::endl; + try { + usrp->get_mboard_sensor("gps_locked", 0); + } catch (std::exception&) { + std::cout << "No response from GPSDO in 30 seconds" << std::endl; + return EXIT_FAILURE; + } + std::cout << "The GPSDO is warmed up and talking." << 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"); + } + + // Check PPS and compare UHD device time to GPS time + uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time"); + 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 << "\nTrying to align the device time to GPS time..." << std::endl; + + gps_time = usrp->get_mboard_sensor("gps_time"); + + // set the device time to the GPS time + // getting the GPS time returns just after the PPS edge, so just add a + // second and set the device time at the next PPS edge + usrp->set_time_next_pps(uhd::time_spec_t(gps_time.to_int() + 1.0)); + // allow some time to make sure the PPS has come… + std::this_thread::sleep_for(std::chrono::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); + } + + if (pps_seconds == gps_seconds) { + std::cout << boost::format("GPS and UHD Device time are aligned.\n"); + } else { + std::cout << boost::format( + "Could not align UHD Device time to GPS time. Giving up.\n"); + } + std::cout << boost::format("last_pps: %ld vs gps: %ld.") % pps_seconds % gps_seconds + << std::endl; + + // print NMEA strings + try { + 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") % gga_string.to_pp_string() + % rmc_string.to_pp_string(); + } catch (uhd::lookup_error&) { + std::cout << "NMEA strings not implemented for this device." << std::endl; + } + 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"); + + return EXIT_SUCCESS; } diff --git a/host/utils/uhd_cal_rx_iq_balance.cpp b/host/utils/uhd_cal_rx_iq_balance.cpp index d8c6a63da..a90e37651 100644 --- a/host/utils/uhd_cal_rx_iq_balance.cpp +++ b/host/utils/uhd_cal_rx_iq_balance.cpp @@ -6,21 +6,21 @@ // #include "usrp_cal_utils.hpp" -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/paths.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <boost/thread/thread.hpp> #include <boost/math/special_functions/round.hpp> -#include <iostream> -#include <complex> +#include <boost/program_options.hpp> +#include <boost/thread/thread.hpp> +#include <chrono> #include <cmath> -#include <ctime> +#include <complex> #include <cstdlib> -#include <chrono> +#include <ctime> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -32,20 +32,19 @@ static void tx_thread(uhd::tx_streamer::sptr tx_stream, const double tx_wave_amp { uhd::set_thread_priority_safe(); - //setup variables and allocate buffer + // setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; - std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); + std::vector<samp_type> buff(tx_stream->get_max_num_samps() * 10); - //fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) - { + // fill buff and send until interrupted + while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = float(tx_wave_ampl); tx_stream->send(&buff.front(), buff.size(), md); } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); } @@ -53,21 +52,22 @@ static void tx_thread(uhd::tx_streamer::sptr tx_stream, const double tx_wave_amp /*********************************************************************** * Tune RX and TX routine **********************************************************************/ -static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double rx_lo_freq, const double tx_offset) +static double tune_rx_and_tx( + uhd::usrp::multi_usrp::sptr usrp, const double rx_lo_freq, const double tx_offset) { - //tune the receiver with no cordic + // tune the receiver with no cordic uhd::tune_request_t rx_tune_req(rx_lo_freq); rx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.dsp_freq = 0; + rx_tune_req.dsp_freq = 0; usrp->set_rx_freq(rx_tune_req); - //tune the transmitter - double tx_freq = usrp->get_rx_freq() + tx_offset; + // tune the transmitter + double tx_freq = usrp->get_rx_freq() + tx_offset; double min_fe_tx_freq = usrp->get_fe_tx_freq_range().start(); double max_fe_tx_freq = usrp->get_fe_tx_freq_range().stop(); uhd::tune_request_t tx_tune_req(tx_freq); tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - tx_tune_req.dsp_freq = 0; + tx_tune_req.dsp_freq = 0; if (tx_freq < min_fe_tx_freq) tx_tune_req.dsp_freq = tx_freq - min_fe_tx_freq; else if (tx_freq > max_fe_tx_freq) @@ -82,7 +82,7 @@ static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double rx_l /*********************************************************************** * Main **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string args, subdev, serial; double tx_wave_ampl, tx_offset; @@ -111,13 +111,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) 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("USRP Generate RX IQ Balance Calibration Table %s") % desc << std::endl; - std::cout << - "This application measures leakage between RX and TX on a transceiver daughterboard to self-calibrate.\n" - "Note: Not all daughterboards support this feature. Refer to the UHD manual for details.\n" - << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Generate RX IQ Balance Calibration Table %s") + % desc + << std::endl; + std::cout << "This application measures leakage between RX and TX on a " + "transceiver daughterboard to self-calibrate.\n" + "Note: Not all daughterboards support this feature. Refer to the " + "UHD manual for details.\n" + << std::endl; return EXIT_FAILURE; } @@ -127,143 +130,154 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (not vm.count("nsamps")) nsamps = size_t(usrp->get_rx_rate() / default_fft_bin_size); - //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + // create a receive streamer + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //create a transmit streamer + // create a transmit streamer uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //create a transmitter thread + // create a transmitter thread boost::thread_group threads; threads.create_thread(boost::bind(&tx_thread, tx_stream, tx_wave_ampl)); - //re-usable buffer for samples + // re-usable buffer for samples std::vector<samp_type> buff; - //store the results here + // store the results here std::vector<result_t> results; - if (not vm.count("freq_start")) freq_start = usrp->get_fe_rx_freq_range().start(); - if (not vm.count("freq_stop")) freq_stop = usrp->get_fe_tx_freq_range().stop(); + if (not vm.count("freq_start")) + freq_start = usrp->get_fe_rx_freq_range().start(); + if (not vm.count("freq_stop")) + freq_stop = usrp->get_fe_tx_freq_range().stop(); - //check start and stop frequencies - if (freq_start < usrp->get_fe_rx_freq_range().start()) - { - std::cerr << "freq_start must be " << usrp->get_fe_rx_freq_range().start() << " or greater for this daughter board" << std::endl; + // check start and stop frequencies + if (freq_start < usrp->get_fe_rx_freq_range().start()) { + std::cerr << "freq_start must be " << usrp->get_fe_rx_freq_range().start() + << " or greater for this daughter board" << std::endl; return EXIT_FAILURE; } - if (freq_stop > usrp->get_fe_rx_freq_range().stop()) - { - std::cerr << "freq_stop must be " << usrp->get_fe_rx_freq_range().stop() << " or less for this daughter board" << std::endl; + if (freq_stop > usrp->get_fe_rx_freq_range().stop()) { + std::cerr << "freq_stop must be " << usrp->get_fe_rx_freq_range().stop() + << " or less for this daughter board" << std::endl; return EXIT_FAILURE; } - //check tx_offset - double min_tx_offset = usrp->get_tx_freq_range().start() - usrp->get_fe_rx_freq_range().start(); - double max_tx_offset = usrp->get_tx_freq_range().stop() - usrp->get_fe_rx_freq_range().stop(); - if (tx_offset < min_tx_offset or tx_offset > max_tx_offset) - { + // check tx_offset + double min_tx_offset = + usrp->get_tx_freq_range().start() - usrp->get_fe_rx_freq_range().start(); + double max_tx_offset = + usrp->get_tx_freq_range().stop() - usrp->get_fe_rx_freq_range().stop(); + if (tx_offset < min_tx_offset or tx_offset > max_tx_offset) { std::cerr << "tx_offset must be between " << min_tx_offset << " and " - << max_tx_offset << " for this daughter board" << std::endl; + << max_tx_offset << " for this daughter board" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl; + std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") + % (freq_start / 1e6) % (freq_stop / 1e6) + << std::endl; size_t tx_error_count = 0; - for (double rx_lo_i = freq_start; rx_lo_i <= freq_stop; rx_lo_i += freq_step) - { + for (double rx_lo_i = freq_start; rx_lo_i <= freq_stop; rx_lo_i += freq_step) { const double rx_lo = tune_rx_and_tx(usrp, rx_lo_i, tx_offset); - //frequency constants for this tune event + // frequency constants for this tune event const double actual_rx_rate = usrp->get_rx_rate(); const double actual_tx_freq = usrp->get_tx_freq(); const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_tone_freq = actual_tx_freq - actual_rx_freq; - const double bb_imag_freq = -bb_tone_freq; + const double bb_tone_freq = actual_tx_freq - actual_rx_freq; + const double bb_imag_freq = -bb_tone_freq; - //reset RX IQ balance + // reset RX IQ balance usrp->set_rx_iq_balance(0.0); - //set optimal RX gain setting for this frequency + // set optimal RX gain setting for this frequency set_optimal_rx_gain(usrp, rx_stream); - //capture initial uncorrected value + // capture initial uncorrected value capture_samples(usrp, rx_stream, buff, nsamps); - const double initial_suppression = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate) - compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double initial_suppression = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate) + - compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); - //bounds and results from searching + // bounds and results from searching double phase_corr_start = -1.0; - double phase_corr_stop = 1.0; - double phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + double phase_corr_stop = 1.0; + double phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); double ampl_corr_start = -1.0; - double ampl_corr_stop = 1.0; - double ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + double ampl_corr_stop = 1.0; + double ampl_corr_step = + (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); double best_suppression = 0; - double best_phase_corr = 0; - double best_ampl_corr = 0; - while (phase_corr_step >= precision or ampl_corr_step >= precision) - { - for (double phase_corr = phase_corr_start + phase_corr_step; phase_corr <= phase_corr_stop - phase_corr_step; phase_corr += phase_corr_step) - { - for (double ampl_corr = ampl_corr_start + ampl_corr_step; ampl_corr <= ampl_corr_stop - ampl_corr_step; ampl_corr += ampl_corr_step) - { + double best_phase_corr = 0; + double best_ampl_corr = 0; + while (phase_corr_step >= precision or ampl_corr_step >= precision) { + for (double phase_corr = phase_corr_start + phase_corr_step; + phase_corr <= phase_corr_stop - phase_corr_step; + phase_corr += phase_corr_step) { + for (double ampl_corr = ampl_corr_start + ampl_corr_step; + ampl_corr <= ampl_corr_stop - ampl_corr_step; + ampl_corr += ampl_corr_step) { const std::complex<double> correction(ampl_corr, phase_corr); usrp->set_rx_iq_balance(correction); - //receive some samples + // receive some samples capture_samples(usrp, rx_stream, buff, nsamps); - //check for TX errors in the current captured iteration - if (has_tx_error(tx_stream)){ + // check for TX errors in the current captured iteration + if (has_tx_error(tx_stream)) { if (vm.count("verbose")) { - std::cout - << "[WARNING] TX error detected! " - << "Repeating current iteration" - << std::endl; + std::cout << "[WARNING] TX error detected! " + << "Repeating current iteration" << std::endl; } // Undo the correction step: ampl_corr -= ampl_corr_step; tx_error_count++; if (tx_error_count >= MAX_NUM_TX_ERRORS) { throw uhd::runtime_error( - "Too many TX errors. Aborting calibration." - ); + "Too many TX errors. Aborting calibration."); } continue; } - const double tone_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); - const double imag_dbrms = compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double tone_dbrms = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); + const double imag_dbrms = + compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); const double suppression = tone_dbrms - imag_dbrms; - if (suppression > best_suppression) - { + if (suppression > best_suppression) { best_suppression = suppression; - best_phase_corr = phase_corr; - best_ampl_corr = ampl_corr; + best_phase_corr = phase_corr; + best_ampl_corr = ampl_corr; } } } phase_corr_start = best_phase_corr - phase_corr_step; - phase_corr_stop = best_phase_corr + phase_corr_step; - phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + phase_corr_stop = best_phase_corr + phase_corr_step; + phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); ampl_corr_start = best_ampl_corr - ampl_corr_step; - ampl_corr_stop = best_ampl_corr + ampl_corr_step; - ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + ampl_corr_stop = best_ampl_corr + ampl_corr_step; + ampl_corr_step = (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); } - if (best_suppression > initial_suppression) //keep result + if (best_suppression > initial_suppression) // keep result { result_t result; - result.freq = rx_lo; + result.freq = rx_lo; result.real_corr = best_ampl_corr; result.imag_corr = best_phase_corr; - result.best = best_suppression; - result.delta = best_suppression - initial_suppression; + result.best = best_suppression; + result.delta = best_suppression - initial_suppression; results.push_back(result); if (vm.count("verbose")) - std::cout << boost::format("RX IQ: %f MHz: best suppression %f dB, corrected %f dB") % (rx_lo/1e6) % result.best % result.delta << std::endl; + std::cout << boost::format( + "RX IQ: %f MHz: best suppression %f dB, corrected %f dB") + % (rx_lo / 1e6) % result.best % result.delta + << std::endl; else std::cout << "." << std::flush; } @@ -273,9 +287,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } // end for each frequency loop std::cout << std::endl; - //stop the transmitter + // stop the transmitter threads.interrupt_all(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); //wait for threads to finish + std::this_thread::sleep_for( + std::chrono::milliseconds(500)); // wait for threads to finish threads.join_all(); store_results(results, "RX", "rx", "iq", serial); diff --git a/host/utils/uhd_cal_tx_dc_offset.cpp b/host/utils/uhd_cal_tx_dc_offset.cpp index 6519cd9ec..f47b5e913 100644 --- a/host/utils/uhd_cal_tx_dc_offset.cpp +++ b/host/utils/uhd_cal_tx_dc_offset.cpp @@ -6,19 +6,19 @@ // #include "usrp_cal_utils.hpp" -#include <uhd/utils/thread.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/utils/paths.hpp> -#include <uhd/utils/algorithm.hpp> #include <uhd/usrp/multi_usrp.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> #include <boost/format.hpp> -#include <boost/thread/thread.hpp> #include <boost/math/special_functions/round.hpp> -#include <iostream> +#include <boost/program_options.hpp> +#include <boost/thread/thread.hpp> +#include <chrono> #include <complex> #include <ctime> -#include <chrono> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -26,33 +26,35 @@ namespace po = boost::program_options; /*********************************************************************** * Transmit thread **********************************************************************/ -static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, const double tx_wave_freq, const double tx_wave_ampl) +static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, + uhd::tx_streamer::sptr tx_stream, + const double tx_wave_freq, + const double tx_wave_ampl) { uhd::set_thread_priority_safe(); // set max TX gain usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); - //setup variables and allocate buffer + // setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; - std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); + std::vector<samp_type> buff(tx_stream->get_max_num_samps() * 10); - //values for the wave table lookup - size_t index = 0; + // values for the wave table lookup + size_t index = 0; const double tx_rate = usrp->get_tx_rate(); - const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); + const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); wave_table table(tx_wave_ampl); - //fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) - { + // fill buff and send until interrupted + while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = table(index += step); tx_stream->send(&buff.front(), buff.size(), md); } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); } @@ -60,21 +62,22 @@ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr t /*********************************************************************** * Tune RX and TX routine **********************************************************************/ -static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) +static double tune_rx_and_tx( + uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) { - //tune the transmitter with no cordic + // tune the transmitter with no cordic uhd::tune_request_t tx_tune_req(tx_lo_freq); tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - tx_tune_req.dsp_freq = 0; + tx_tune_req.dsp_freq = 0; usrp->set_tx_freq(tx_tune_req); - //tune the receiver - double rx_freq = usrp->get_tx_freq() - rx_offset; + // tune the receiver + double rx_freq = usrp->get_tx_freq() - rx_offset; double min_fe_rx_freq = usrp->get_fe_rx_freq_range().start(); double max_fe_rx_freq = usrp->get_fe_rx_freq_range().stop(); uhd::tune_request_t rx_tune_req(rx_freq); rx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.dsp_freq = 0; + rx_tune_req.dsp_freq = 0; if (rx_freq < min_fe_rx_freq) rx_tune_req.dsp_freq = rx_freq - min_fe_rx_freq; else if (rx_freq > max_fe_rx_freq) @@ -89,7 +92,7 @@ static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_l /*********************************************************************** * Main **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string args, subdev, serial; double tx_wave_freq, tx_wave_ampl, rx_offset; @@ -119,13 +122,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) 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("USRP Generate TX DC Offset Calibration Table %s") % desc << std::endl; - std::cout << - "This application measures leakage between RX and TX on a transceiver daughterboard to self-calibrate.\n" - "Note: Not all daughterboards support this feature. Refer to the UHD manual for details.\n" - << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Generate TX DC Offset Calibration Table %s") + % desc + << std::endl; + std::cout << "This application measures leakage between RX and TX on a " + "transceiver daughterboard to self-calibrate.\n" + "Note: Not all daughterboards support this feature. Refer to the " + "UHD manual for details.\n" + << std::endl; return EXIT_FAILURE; } @@ -135,138 +141,145 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (not vm.count("nsamps")) nsamps = size_t(usrp->get_rx_rate() / default_fft_bin_size); - //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + // create a receive streamer + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //create a transmit streamer + // create a transmit streamer uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //create a transmitter thread + // create a transmitter thread boost::thread_group threads; - threads.create_thread(boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); + threads.create_thread( + boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); - //re-usable buffer for samples + // re-usable buffer for samples std::vector<samp_type> buff; - //store the results here + // store the results here std::vector<result_t> results; - if (not vm.count("freq_start")) freq_start = usrp->get_fe_tx_freq_range().start(); - if (not vm.count("freq_stop")) freq_stop = usrp->get_fe_tx_freq_range().stop(); + if (not vm.count("freq_start")) + freq_start = usrp->get_fe_tx_freq_range().start(); + if (not vm.count("freq_stop")) + freq_stop = usrp->get_fe_tx_freq_range().stop(); - //check start and stop frequencies - if (freq_start < usrp->get_fe_tx_freq_range().start()) - { - std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() << " or greater for this daughter board" << std::endl; + // check start and stop frequencies + if (freq_start < usrp->get_fe_tx_freq_range().start()) { + std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() + << " or greater for this daughter board" << std::endl; return EXIT_FAILURE; } - if (freq_stop > usrp->get_fe_tx_freq_range().stop()) - { - std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() << " or less for this daughter board" << std::endl; + if (freq_stop > usrp->get_fe_tx_freq_range().stop()) { + std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() + << " or less for this daughter board" << std::endl; return EXIT_FAILURE; } - //check rx_offset - double min_rx_offset = usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); - double max_rx_offset = usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); - if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) - { + // check rx_offset + double min_rx_offset = + usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); + double max_rx_offset = + usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); + if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) { std::cerr << "rx_offset must be between " << min_rx_offset << " and " - << max_rx_offset << " for this daughter board" << std::endl; + << max_rx_offset << " for this daughter board" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl; + std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") + % (freq_start / 1e6) % (freq_stop / 1e6) + << std::endl; - //set RX gain + // set RX gain usrp->set_rx_gain(0); size_t tx_error_count = 0; - for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) - { + for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) { const double tx_lo = tune_rx_and_tx(usrp, tx_lo_i, rx_offset); - //frequency constants for this tune event + // frequency constants for this tune event const double actual_rx_rate = usrp->get_rx_rate(); const double actual_tx_freq = usrp->get_tx_freq(); const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_dc_freq = actual_tx_freq - actual_rx_freq; + const double bb_dc_freq = actual_tx_freq - actual_rx_freq; - //reset TX DC offset + // reset TX DC offset usrp->set_tx_dc_offset(std::complex<double>(0, 0)); - //capture initial uncorrected value + // capture initial uncorrected value capture_samples(usrp, rx_stream, buff, nsamps); - const double initial_dc_dbrms = compute_tone_dbrms(buff, bb_dc_freq/actual_rx_rate); - - //bounds and results from searching - double i_corr_start = -1.0; - double i_corr_stop = 1.0; - double i_corr_step = (i_corr_stop - i_corr_start)/(num_search_steps+1); - double q_corr_start = -1.0; - double q_corr_stop = 1.0; - double q_corr_step= (q_corr_stop - q_corr_start)/(num_search_steps+1); + const double initial_dc_dbrms = + compute_tone_dbrms(buff, bb_dc_freq / actual_rx_rate); + + // bounds and results from searching + double i_corr_start = -1.0; + double i_corr_stop = 1.0; + double i_corr_step = (i_corr_stop - i_corr_start) / (num_search_steps + 1); + double q_corr_start = -1.0; + double q_corr_stop = 1.0; + double q_corr_step = (q_corr_stop - q_corr_start) / (num_search_steps + 1); double best_dc_dbrms = initial_dc_dbrms; - double best_i_corr = 0; - double best_q_corr = 0; - while (i_corr_step >= precision or q_corr_step >= precision) - { - for (double i_corr = i_corr_start + i_corr_step; i_corr <= i_corr_stop - i_corr_step; i_corr += i_corr_step) - { - for (double q_corr = q_corr_start + q_corr_step; q_corr <= q_corr_stop - q_corr_step; q_corr += q_corr_step) - { + double best_i_corr = 0; + double best_q_corr = 0; + while (i_corr_step >= precision or q_corr_step >= precision) { + for (double i_corr = i_corr_start + i_corr_step; + i_corr <= i_corr_stop - i_corr_step; + i_corr += i_corr_step) { + for (double q_corr = q_corr_start + q_corr_step; + q_corr <= q_corr_stop - q_corr_step; + q_corr += q_corr_step) { const std::complex<double> correction(i_corr, q_corr); usrp->set_tx_dc_offset(correction); - //receive some samples + // receive some samples capture_samples(usrp, rx_stream, buff, nsamps); - //check for TX errors in the current captured iteration - if (has_tx_error(tx_stream)){ - std::cout - << "[WARNING] TX error detected! " - << "Repeating current iteration" - << std::endl; + // check for TX errors in the current captured iteration + if (has_tx_error(tx_stream)) { + std::cout << "[WARNING] TX error detected! " + << "Repeating current iteration" << std::endl; // Undo the Q correction step q_corr -= q_corr_step; tx_error_count++; if (tx_error_count >= MAX_NUM_TX_ERRORS) { throw uhd::runtime_error( - "Too many TX errors. Aborting calibration." - ); + "Too many TX errors. Aborting calibration."); } continue; } - const double dc_dbrms = compute_tone_dbrms(buff, bb_dc_freq/actual_rx_rate); + const double dc_dbrms = + compute_tone_dbrms(buff, bb_dc_freq / actual_rx_rate); - if (dc_dbrms < best_dc_dbrms) - { + if (dc_dbrms < best_dc_dbrms) { best_dc_dbrms = dc_dbrms; - best_i_corr = i_corr; - best_q_corr = q_corr; + best_i_corr = i_corr; + best_q_corr = q_corr; } } } i_corr_start = best_i_corr - i_corr_step; - i_corr_stop = best_i_corr + i_corr_step; - i_corr_step = (i_corr_stop - i_corr_start)/(num_search_steps+1); + i_corr_stop = best_i_corr + i_corr_step; + i_corr_step = (i_corr_stop - i_corr_start) / (num_search_steps + 1); q_corr_start = best_q_corr - q_corr_step; - q_corr_stop = best_q_corr + q_corr_step; - q_corr_step = (q_corr_stop - q_corr_start)/(num_search_steps+1); + q_corr_stop = best_q_corr + q_corr_step; + q_corr_step = (q_corr_stop - q_corr_start) / (num_search_steps + 1); } - if (best_dc_dbrms < initial_dc_dbrms) //keep result + if (best_dc_dbrms < initial_dc_dbrms) // keep result { result_t result; - result.freq = tx_lo; + result.freq = tx_lo; result.real_corr = best_i_corr; result.imag_corr = best_q_corr; - result.best = best_dc_dbrms; - result.delta = initial_dc_dbrms - best_dc_dbrms; + result.best = best_dc_dbrms; + result.delta = initial_dc_dbrms - best_dc_dbrms; results.push_back(result); if (vm.count("verbose")) - std::cout << boost::format("TX DC: %f MHz: lowest offset %f dB, corrected %f dB") % (tx_lo/1e6) % result.best % result.delta << std::endl; + std::cout << boost::format( + "TX DC: %f MHz: lowest offset %f dB, corrected %f dB") + % (tx_lo / 1e6) % result.best % result.delta + << std::endl; else std::cout << "." << std::flush; } @@ -277,9 +290,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::cout << std::endl; - //stop the transmitter + // stop the transmitter threads.interrupt_all(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); //wait for threads to finish + std::this_thread::sleep_for( + std::chrono::milliseconds(500)); // wait for threads to finish threads.join_all(); store_results(results, "TX", "tx", "dc", serial); diff --git a/host/utils/uhd_cal_tx_iq_balance.cpp b/host/utils/uhd_cal_tx_iq_balance.cpp index 4da5a1f96..2e7229fd3 100644 --- a/host/utils/uhd_cal_tx_iq_balance.cpp +++ b/host/utils/uhd_cal_tx_iq_balance.cpp @@ -6,16 +6,16 @@ // #include "usrp_cal_utils.hpp" -#include <uhd/utils/thread.hpp> #include <uhd/utils/safe_main.hpp> +#include <uhd/utils/thread.hpp> +#include <boost/math/special_functions/round.hpp> #include <boost/program_options.hpp> #include <boost/thread/thread.hpp> -#include <boost/math/special_functions/round.hpp> -#include <iostream> +#include <chrono> #include <complex> -#include <ctime> #include <cstdlib> -#include <chrono> +#include <ctime> +#include <iostream> #include <thread> namespace po = boost::program_options; @@ -23,33 +23,35 @@ namespace po = boost::program_options; /*********************************************************************** * Transmit thread **********************************************************************/ -static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, const double tx_wave_freq, const double tx_wave_ampl) +static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, + uhd::tx_streamer::sptr tx_stream, + const double tx_wave_freq, + const double tx_wave_ampl) { uhd::set_thread_priority_safe(); // set max TX gain usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); - //setup variables and allocate buffer + // setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; - std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); + std::vector<samp_type> buff(tx_stream->get_max_num_samps() * 10); - //values for the wave table lookup - size_t index = 0; + // values for the wave table lookup + size_t index = 0; const double tx_rate = usrp->get_tx_rate(); - const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); + const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); wave_table table(tx_wave_ampl); - //fill buff and send until interrupted - while (not boost::this_thread::interruption_requested()) - { + // fill buff and send until interrupted + while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = table(index += step); tx_stream->send(&buff.front(), buff.size(), md); } - //send a mini EOB packet + // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); } @@ -57,21 +59,22 @@ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr t /*********************************************************************** * Tune RX and TX routine **********************************************************************/ -static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) +static double tune_rx_and_tx( + uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) { - //tune the transmitter with no cordic + // tune the transmitter with no cordic uhd::tune_request_t tx_tune_req(tx_lo_freq); tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - tx_tune_req.dsp_freq = 0; + tx_tune_req.dsp_freq = 0; usrp->set_tx_freq(tx_tune_req); - //tune the receiver - double rx_freq = usrp->get_tx_freq() - rx_offset; + // tune the receiver + double rx_freq = usrp->get_tx_freq() - rx_offset; double min_fe_rx_freq = usrp->get_fe_rx_freq_range().start(); double max_fe_rx_freq = usrp->get_fe_rx_freq_range().stop(); uhd::tune_request_t rx_tune_req(rx_freq); rx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.dsp_freq = 0; + rx_tune_req.dsp_freq = 0; if (rx_freq < min_fe_rx_freq) rx_tune_req.dsp_freq = rx_freq - min_fe_rx_freq; else if (rx_freq > max_fe_rx_freq) @@ -86,7 +89,7 @@ static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_l /*********************************************************************** * Main **********************************************************************/ -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { std::string args, subdev, serial; double tx_wave_freq, tx_wave_ampl, rx_offset; @@ -116,14 +119,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) 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("USRP Generate TX IQ Balance Calibration Table %s") % desc << std::endl; - std::cout << - "This application measures leakage between RX and TX on a transceiver daughterboard to self-calibrate.\n" - "Note: Not all daughterboards support this feature. Refer to the UHD manual for details.\n" - << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Generate TX IQ Balance Calibration Table %s") + % desc + << std::endl; + std::cout << "This application measures leakage between RX and TX on a " + "transceiver daughterboard to self-calibrate.\n" + "Note: Not all daughterboards support this feature. Refer to the " + "UHD manual for details.\n" + << std::endl; return EXIT_FAILURE; } @@ -133,140 +138,151 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (not vm.count("nsamps")) nsamps = size_t(usrp->get_rx_rate() / default_fft_bin_size); - //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + // create a receive streamer + uhd::stream_args_t stream_args("fc32"); // complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); - //create a transmit streamer + // create a transmit streamer uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); - //create a transmitter thread + // create a transmitter thread boost::thread_group threads; - threads.create_thread(boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); + threads.create_thread( + boost::bind(&tx_thread, usrp, tx_stream, tx_wave_freq, tx_wave_ampl)); - //re-usable buffer for samples + // re-usable buffer for samples std::vector<samp_type> buff; - //store the results here + // store the results here std::vector<result_t> results; - if (not vm.count("freq_start")) freq_start = usrp->get_fe_tx_freq_range().start(); - if (not vm.count("freq_stop")) freq_stop = usrp->get_fe_tx_freq_range().stop(); + if (not vm.count("freq_start")) + freq_start = usrp->get_fe_tx_freq_range().start(); + if (not vm.count("freq_stop")) + freq_stop = usrp->get_fe_tx_freq_range().stop(); - //check start and stop frequencies - if (freq_start < usrp->get_fe_tx_freq_range().start()) - { - std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() << " or greater for this daughter board" << std::endl; + // check start and stop frequencies + if (freq_start < usrp->get_fe_tx_freq_range().start()) { + std::cerr << "freq_start must be " << usrp->get_fe_tx_freq_range().start() + << " or greater for this daughter board" << std::endl; return EXIT_FAILURE; } - if (freq_stop > usrp->get_fe_tx_freq_range().stop()) - { - std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() << " or less for this daughter board" << std::endl; + if (freq_stop > usrp->get_fe_tx_freq_range().stop()) { + std::cerr << "freq_stop must be " << usrp->get_fe_tx_freq_range().stop() + << " or less for this daughter board" << std::endl; return EXIT_FAILURE; } - //check rx_offset - double min_rx_offset = usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); - double max_rx_offset = usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); - if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) - { + // check rx_offset + double min_rx_offset = + usrp->get_rx_freq_range().start() - usrp->get_fe_tx_freq_range().start(); + double max_rx_offset = + usrp->get_rx_freq_range().stop() - usrp->get_fe_tx_freq_range().stop(); + if (rx_offset < min_rx_offset or rx_offset > max_rx_offset) { std::cerr << "rx_offset must be between " << min_rx_offset << " and " - << max_rx_offset << " for this daughter board" << std::endl; + << max_rx_offset << " for this daughter board" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl; + std::cout << boost::format("Calibration frequency range: %d MHz -> %d MHz") + % (freq_start / 1e6) % (freq_stop / 1e6) + << std::endl; size_t tx_error_count = 0; - for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) - { - + for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step) { const double tx_lo = tune_rx_and_tx(usrp, tx_lo_i, rx_offset); - //frequency constants for this tune event + // frequency constants for this tune event const double actual_rx_rate = usrp->get_rx_rate(); const double actual_tx_freq = usrp->get_tx_freq(); const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_tone_freq = actual_tx_freq + tx_wave_freq - actual_rx_freq; - const double bb_imag_freq = actual_tx_freq - tx_wave_freq - actual_rx_freq; + const double bb_tone_freq = actual_tx_freq + tx_wave_freq - actual_rx_freq; + const double bb_imag_freq = actual_tx_freq - tx_wave_freq - actual_rx_freq; - //reset TX IQ balance + // reset TX IQ balance usrp->set_tx_iq_balance(0.0); - //set optimal RX gain setting for this frequency + // set optimal RX gain setting for this frequency set_optimal_rx_gain(usrp, rx_stream, tx_wave_freq); - //capture initial uncorrected value + // capture initial uncorrected value capture_samples(usrp, rx_stream, buff, nsamps); - const double initial_suppression = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate) - compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double initial_suppression = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate) + - compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); - //bounds and results from searching + // bounds and results from searching double phase_corr_start = -1.0; - double phase_corr_stop = 1.0; - double phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + double phase_corr_stop = 1.0; + double phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); double ampl_corr_start = -1.0; - double ampl_corr_stop = 1.0; - double ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + double ampl_corr_stop = 1.0; + double ampl_corr_step = + (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); double best_suppression = 0; - double best_phase_corr = 0; - double best_ampl_corr = 0; - while (phase_corr_step >= precision or ampl_corr_step >= precision) - { - for (double phase_corr = phase_corr_start + phase_corr_step; phase_corr <= phase_corr_stop - phase_corr_step; phase_corr += phase_corr_step) - { - for (double ampl_corr = ampl_corr_start + ampl_corr_step; ampl_corr <= ampl_corr_stop - ampl_corr_step; ampl_corr += ampl_corr_step) - { + double best_phase_corr = 0; + double best_ampl_corr = 0; + while (phase_corr_step >= precision or ampl_corr_step >= precision) { + for (double phase_corr = phase_corr_start + phase_corr_step; + phase_corr <= phase_corr_stop - phase_corr_step; + phase_corr += phase_corr_step) { + for (double ampl_corr = ampl_corr_start + ampl_corr_step; + ampl_corr <= ampl_corr_stop - ampl_corr_step; + ampl_corr += ampl_corr_step) { const std::complex<double> correction(ampl_corr, phase_corr); usrp->set_tx_iq_balance(correction); - //receive some samples + // receive some samples capture_samples(usrp, rx_stream, buff, nsamps); - //check for TX errors in the current captured iteration - if (has_tx_error(tx_stream)){ - std::cout - << "[WARNING] TX error detected! " - << "Repeating current iteration" - << std::endl; + // check for TX errors in the current captured iteration + if (has_tx_error(tx_stream)) { + std::cout << "[WARNING] TX error detected! " + << "Repeating current iteration" << std::endl; // Undo ampl corr step ampl_corr -= ampl_corr_step; tx_error_count++; if (tx_error_count >= MAX_NUM_TX_ERRORS) { throw uhd::runtime_error( - "Too many TX errors. Aborting calibration." - ); + "Too many TX errors. Aborting calibration."); } continue; } - const double tone_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); - const double imag_dbrms = compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate); + const double tone_dbrms = + compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); + const double imag_dbrms = + compute_tone_dbrms(buff, bb_imag_freq / actual_rx_rate); const double suppression = tone_dbrms - imag_dbrms; - if (suppression > best_suppression) - { + if (suppression > best_suppression) { best_suppression = suppression; - best_phase_corr = phase_corr; - best_ampl_corr = ampl_corr; + best_phase_corr = phase_corr; + best_ampl_corr = ampl_corr; } } } phase_corr_start = best_phase_corr - phase_corr_step; - phase_corr_stop = best_phase_corr + phase_corr_step; - phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps+1); + phase_corr_stop = best_phase_corr + phase_corr_step; + phase_corr_step = + (phase_corr_stop - phase_corr_start) / (num_search_steps + 1); ampl_corr_start = best_ampl_corr - ampl_corr_step; - ampl_corr_stop = best_ampl_corr + ampl_corr_step; - ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps+1); + ampl_corr_stop = best_ampl_corr + ampl_corr_step; + ampl_corr_step = (ampl_corr_stop - ampl_corr_start) / (num_search_steps + 1); } - if (best_suppression > initial_suppression) //keep result + if (best_suppression > initial_suppression) // keep result { result_t result; - result.freq = tx_lo; + result.freq = tx_lo; result.real_corr = best_ampl_corr; result.imag_corr = best_phase_corr; - result.best = best_suppression; - result.delta = best_suppression - initial_suppression; + result.best = best_suppression; + result.delta = best_suppression - initial_suppression; results.push_back(result); if (vm.count("verbose")) - std::cout << boost::format("TX IQ: %f MHz: best suppression %f dB, corrected %f dB") % (tx_lo/1e6) % result.best % result.delta << std::endl; + std::cout << boost::format( + "TX IQ: %f MHz: best suppression %f dB, corrected %f dB") + % (tx_lo / 1e6) % result.best % result.delta + << std::endl; else std::cout << "." << std::flush; } @@ -276,13 +292,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) } std::cout << std::endl; - //stop the transmitter + // stop the transmitter threads.interrupt_all(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); //wait for threads to finish + std::this_thread::sleep_for( + std::chrono::milliseconds(500)); // wait for threads to finish threads.join_all(); store_results(results, "TX", "tx", "iq", serial); return EXIT_SUCCESS; } - diff --git a/host/utils/uhd_config_info.cpp b/host/utils/uhd_config_info.cpp index 2c29af214..784ca9ff2 100644 --- a/host/utils/uhd_config_info.cpp +++ b/host/utils/uhd_config_info.cpp @@ -5,16 +5,16 @@ // #include <uhd/build_info.hpp> -#include <uhd/version.hpp> #include <uhd/utils/paths.hpp> #include <uhd/utils/safe_main.hpp> - +#include <uhd/version.hpp> #include <boost/format.hpp> #include <boost/program_options.hpp> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char* argv[]) { +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ // Program Options po::options_description desc("Allowed Options"); // clang-format off @@ -42,51 +42,53 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) { po::notify(vm); // Print the help message - if(vm.count("help") > 0) { + if (vm.count("help") > 0) { std::cout << boost::format("UHD Config Info - %s") % desc << std::endl; return EXIT_FAILURE; } bool print_all = (vm.count("print-all") > 0); - if(vm.count("version") > 0 or print_all) { + if (vm.count("version") > 0 or print_all) { std::cout << "UHD " << uhd::get_version_string() << std::endl; } - if(vm.count("build-date") > 0 or print_all) { + if (vm.count("build-date") > 0 or print_all) { std::cout << "Build date: " << uhd::build_info::build_date() << std::endl; } - if(vm.count("c-compiler") > 0 or print_all) { + if (vm.count("c-compiler") > 0 or print_all) { std::cout << "C compiler: " << uhd::build_info::c_compiler() << std::endl; } - if(vm.count("cxx-compiler") > 0 or print_all) { + if (vm.count("cxx-compiler") > 0 or print_all) { std::cout << "C++ compiler: " << uhd::build_info::cxx_compiler() << std::endl; } - if(vm.count("c-flags") > 0 or print_all) { + if (vm.count("c-flags") > 0 or print_all) { std::cout << "C flags: " << uhd::build_info::c_flags() << std::endl; } - if(vm.count("cxx-flags") > 0 or print_all) { + if (vm.count("cxx-flags") > 0 or print_all) { std::cout << "C++ flags: " << uhd::build_info::cxx_flags() << std::endl; } - if(vm.count("enabled-components") > 0 or print_all) { - std::cout << "Enabled components: " << uhd::build_info::enabled_components() << std::endl; + if (vm.count("enabled-components") > 0 or print_all) { + std::cout << "Enabled components: " << uhd::build_info::enabled_components() + << std::endl; } - if(vm.count("install-prefix") > 0 or print_all) { + if (vm.count("install-prefix") > 0 or print_all) { std::cout << "Install prefix: " << uhd::build_info::install_prefix() << std::endl; } - if(vm.count("boost-version") > 0 or print_all) { + if (vm.count("boost-version") > 0 or print_all) { std::cout << "Boost version: " << uhd::build_info::boost_version() << std::endl; } - if(vm.count("libusb-version") > 0 or print_all) { + if (vm.count("libusb-version") > 0 or print_all) { std::string _libusb_version = uhd::build_info::libusb_version(); - std::cout << "Libusb version: " << (_libusb_version.empty() ? "N/A" : _libusb_version) << std::endl; + std::cout << "Libusb version: " + << (_libusb_version.empty() ? "N/A" : _libusb_version) << std::endl; } - if(vm.count("pkg-path") > 0 or print_all) { + if (vm.count("pkg-path") > 0 or print_all) { std::cout << "Package path: " << uhd::get_pkg_path() << std::endl; } - if(vm.count("images-dir") > 0 or print_all) { + if (vm.count("images-dir") > 0 or print_all) { std::cout << "Images directory: " << uhd::get_images_dir("") << std::endl; } - if(vm.count("abi-version") > 0 or print_all) { + if (vm.count("abi-version") > 0 or print_all) { std::cout << "ABI version string: " << uhd::get_abi_string() << std::endl; } diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp index 504fafcf7..ad30b168c 100644 --- a/host/utils/uhd_find_devices.cpp +++ b/host/utils/uhd_find_devices.cpp @@ -5,29 +5,30 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> #include <uhd/device.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/format.hpp> -#include <iostream> +#include <boost/program_options.hpp> #include <cstdlib> +#include <iostream> namespace { - //! Conditionally append find_all=1 if the key isn't there yet - uhd::device_addr_t append_findall(const uhd::device_addr_t& device_args) - { - uhd::device_addr_t new_device_args(device_args); - if (!new_device_args.has_key("find_all")) { - new_device_args["find_all"] = "1"; - } - - return new_device_args; +//! Conditionally append find_all=1 if the key isn't there yet +uhd::device_addr_t append_findall(const uhd::device_addr_t& device_args) +{ + uhd::device_addr_t new_device_args(device_args); + if (!new_device_args.has_key("find_all")) { + new_device_args["find_all"] = "1"; } + + return new_device_args; } +} // namespace namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -40,35 +41,34 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("UHD Find Devices %s") % desc << std::endl; return EXIT_SUCCESS; } - //discover the usrps and print the results + // discover the usrps and print the results const uhd::device_addr_t args(vm["args"].as<std::string>()); - uhd::device_addrs_t device_addrs = - uhd::device::find(append_findall(args)); + uhd::device_addrs_t device_addrs = uhd::device::find(append_findall(args)); if (device_addrs.empty()) { std::cerr << "No UHD Devices Found" << std::endl; return EXIT_FAILURE; } - typedef std::map<std::string, std::set<std::string> > device_multi_addrs_t; + typedef std::map<std::string, std::set<std::string>> device_multi_addrs_t; typedef std::map<std::string, device_multi_addrs_t> device_addrs_filtered_t; device_addrs_filtered_t found_devices; for (auto it = device_addrs.begin(); it != device_addrs.end(); ++it) { - std::string serial = (*it)["serial"]; + std::string serial = (*it)["serial"]; found_devices[serial] = device_multi_addrs_t(); - for(std::string key: it->keys()) { + for (std::string key : it->keys()) { if (key != "serial") { found_devices[serial][key].insert(it->get(key)); } } for (auto sit = it + 1; sit != device_addrs.end();) { if ((*sit)["serial"] == serial) { - for(std::string key: sit->keys()) { + for (std::string key : sit->keys()) { if (key != "serial") { found_devices[serial][key].insert(sit->get(key)); } @@ -82,19 +82,15 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ int i = 0; for (auto dit = found_devices.begin(); dit != found_devices.end(); ++dit) { - std::cout << "--------------------------------------------------" - << std::endl; + std::cout << "--------------------------------------------------" << std::endl; std::cout << "-- UHD Device " << i << std::endl; - std::cout << "--------------------------------------------------" - << std::endl; + std::cout << "--------------------------------------------------" << std::endl; std::stringstream ss; ss << "Device Address:" << std::endl; ss << boost::format(" serial: %s") % dit->first << std::endl; for (auto mit = dit->second.begin(); mit != dit->second.end(); ++mit) { - for (auto vit = mit->second.begin(); vit != mit->second.end(); - ++vit) { - ss << boost::format(" %s: %s") % mit->first % *vit - << std::endl; + for (auto vit = mit->second.begin(); vit != mit->second.end(); ++vit) { + ss << boost::format(" %s: %s") % mit->first % *vit << std::endl; } } std::cout << ss.str() << std::endl << std::endl; diff --git a/host/utils/uhd_image_loader.cpp b/host/utils/uhd_image_loader.cpp index 507a4ac87..57ad57958 100644 --- a/host/utils/uhd_image_loader.cpp +++ b/host/utils/uhd_image_loader.cpp @@ -5,47 +5,49 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <csignal> -#include <cstdlib> -#include <iostream> - -#include <boost/assign.hpp> -#include <boost/filesystem.hpp> -#include <boost/format.hpp> - #include <uhd/config.hpp> #include <uhd/image_loader.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/utils/safe_main.hpp> +#include <boost/assign.hpp> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> #include <boost/program_options.hpp> +#include <csignal> +#include <cstdlib> +#include <iostream> namespace fs = boost::filesystem; namespace po = boost::program_options; static std::string device_type = ""; -static int num_ctrl_c = 0; +static int num_ctrl_c = 0; /* * If the user presses Ctrl+C, warn them that they may corrupt their device. * If they press it again, provide instructions on restoring the device * (if applicable) and exit. */ -void sigint_handler(int){ +void sigint_handler(int) +{ num_ctrl_c++; - if(num_ctrl_c == 1){ + if (num_ctrl_c == 1) { std::cout << std::endl - << "Are you sure you want to abort? If you do, your device will likely" << std::endl + << "Are you sure you want to abort? If you do, your device will likely" + << std::endl << "be in an unstable or unusable state." << std::endl - << "Press Ctrl+C again to abort." << std::endl << std::endl; - } - else{ - std::cout << std::endl << uhd::image_loader::get_recovery_instructions(device_type) << std::endl; + << "Press Ctrl+C again to abort." << std::endl + << std::endl; + } else { + std::cout << std::endl + << uhd::image_loader::get_recovery_instructions(device_type) + << std::endl; exit(EXIT_FAILURE); } } -int UHD_SAFE_MAIN(int argc, char *argv[]){ - +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -65,10 +67,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::notify(vm); // Help message - if (vm.count("help")){ + if (vm.count("help")) { std::cout << "UHD Image Loader" << std::endl << std::endl - << "Load firmware and/or FPGA images onto an Ettus Research device." << std::endl + << "Load firmware and/or FPGA images onto an Ettus Research device." + << std::endl << std::endl << desc << std::endl; return EXIT_FAILURE; @@ -77,49 +80,50 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ // Convert user options uhd::image_loader::image_loader_args_t image_loader_args; image_loader_args.args = vm["args"].as<std::string>(); - image_loader_args.load_firmware = (vm.count("no-fw") == 0); - image_loader_args.load_fpga = (vm.count("no-fpga") == 0); + image_loader_args.load_firmware = (vm.count("no-fw") == 0); + image_loader_args.load_fpga = (vm.count("no-fpga") == 0); image_loader_args.download = (vm.count("download") != 0); image_loader_args.firmware_path = vm["fw-path"].as<std::string>(); image_loader_args.fpga_path = vm["fpga-path"].as<std::string>(); image_loader_args.out_path = vm["out-path"].as<std::string>(); // Force user to specify a device - if(not image_loader_args.args.has_key("type")){ + if (not image_loader_args.args.has_key("type")) { throw uhd::runtime_error("You must specify a device type."); } // Clean up paths, if given - if(image_loader_args.firmware_path != ""){ - #ifndef UHD_PLATFORM_WIN32 - if(image_loader_args.firmware_path.find("~") == 0){ - image_loader_args.firmware_path.replace(0,1,getenv("HOME")); + if (image_loader_args.firmware_path != "") { +#ifndef UHD_PLATFORM_WIN32 + if (image_loader_args.firmware_path.find("~") == 0) { + image_loader_args.firmware_path.replace(0, 1, getenv("HOME")); } - #endif /* UHD_PLATFORM_WIN32 */ - image_loader_args.firmware_path = fs::absolute(image_loader_args.firmware_path).string(); +#endif /* UHD_PLATFORM_WIN32 */ + image_loader_args.firmware_path = + fs::absolute(image_loader_args.firmware_path).string(); } - if(image_loader_args.fpga_path != ""){ - #ifndef UHD_PLATFORM_WIN32 - if(image_loader_args.fpga_path.find("~") == 0){ - image_loader_args.fpga_path.replace(0,1,getenv("HOME")); + if (image_loader_args.fpga_path != "") { +#ifndef UHD_PLATFORM_WIN32 + if (image_loader_args.fpga_path.find("~") == 0) { + image_loader_args.fpga_path.replace(0, 1, getenv("HOME")); } - #endif /* UHD_PLATFORM_WIN32 */ +#endif /* UHD_PLATFORM_WIN32 */ image_loader_args.fpga_path = fs::absolute(image_loader_args.fpga_path).string(); } - if(image_loader_args.out_path != ""){ - #ifndef UHD_PLATFORM_WIN32 - if(image_loader_args.out_path.find("~") == 0){ - image_loader_args.out_path.replace(0,1,getenv("HOME")); + if (image_loader_args.out_path != "") { +#ifndef UHD_PLATFORM_WIN32 + if (image_loader_args.out_path.find("~") == 0) { + image_loader_args.out_path.replace(0, 1, getenv("HOME")); } - #endif /* UHD_PLATFORM_WIN32 */ +#endif /* UHD_PLATFORM_WIN32 */ image_loader_args.out_path = fs::absolute(image_loader_args.out_path).string(); } // Detect which type of device we're working with - device_type = image_loader_args.args.get("type",""); + device_type = image_loader_args.args.get("type", ""); std::signal(SIGINT, &sigint_handler); - if(not uhd::image_loader::load(image_loader_args)){ + if (not uhd::image_loader::load(image_loader_args)) { std::cerr << "No applicable UHD devices found" << std::endl; return EXIT_FAILURE; } diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 3522b4148..8f60b211f 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -5,230 +5,303 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> -#include <uhd/version.hpp> #include <uhd/device.hpp> #include <uhd/device3.hpp> -#include <uhd/types/ranges.hpp> #include <uhd/property_tree.hpp> -#include <boost/algorithm/string.hpp> //for split +#include <uhd/types/ranges.hpp> +#include <uhd/types/sensors.hpp> +#include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/dboard_id.hpp> #include <uhd/usrp/mboard_eeprom.hpp> -#include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/types/sensors.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> +#include <uhd/version.hpp> +#include <boost/algorithm/string.hpp> //for split #include <boost/format.hpp> +#include <boost/program_options.hpp> +#include <cstdlib> #include <iostream> #include <sstream> #include <vector> -#include <cstdlib> namespace po = boost::program_options; using namespace uhd; -static std::string make_border(const std::string &text){ +static std::string make_border(const std::string& text) +{ std::stringstream ss; - ss << boost::format(" _____________________________________________________") << std::endl; + ss << boost::format(" _____________________________________________________") + << std::endl; ss << boost::format(" /") << std::endl; - std::vector<std::string> lines; boost::split(lines, text, boost::is_any_of("\n")); - while (lines.back().empty()) lines.pop_back(); //strip trailing newlines - if (lines.size()) lines[0] = " " + lines[0]; //indent the title line - for(const std::string &line: lines){ + std::vector<std::string> lines; + boost::split(lines, text, boost::is_any_of("\n")); + while (lines.back().empty()) + lines.pop_back(); // strip trailing newlines + if (lines.size()) + lines[0] = " " + lines[0]; // indent the title line + for (const std::string& line : lines) { ss << boost::format("| %s") % line << std::endl; } - //ss << boost::format(" \\_____________________________________________________") << std::endl; + // ss << boost::format(" \\_____________________________________________________") << + // std::endl; return ss.str(); } -static std::string get_dsp_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){ +static std::string get_dsp_pp_string( + const std::string& type, property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; ss << boost::format("%s DSP: %s") % type % path.leaf() << std::endl; ss << std::endl; meta_range_t freq_range = tree->access<meta_range_t>(path / "freq/range").get(); - ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start()/1e6) % (freq_range.stop()/1e6) << std::endl;; + ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start() / 1e6) + % (freq_range.stop() / 1e6) + << std::endl; + ; return ss.str(); } -static std::string prop_names_to_pp_string(const std::vector<std::string> &prop_names){ - std::stringstream ss; size_t count = 0; - for(const std::string &prop_name: prop_names){ - ss << ((count++)? ", " : "") << prop_name; +static std::string prop_names_to_pp_string(const std::vector<std::string>& prop_names) +{ + std::stringstream ss; + size_t count = 0; + for (const std::string& prop_name : prop_names) { + ss << ((count++) ? ", " : "") << prop_name; } return ss.str(); } -static std::string get_frontend_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 Frontend: %s") % type % path.leaf() << std::endl; - //ss << std::endl; + // ss << std::endl; - ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) << std::endl; - ss << boost::format("Antennas: %s") % prop_names_to_pp_string(tree->access<std::vector<std::string> >(path / "antenna/options").get()) << std::endl; - if (tree->exists(path/ "sensors")) { - ss << boost::format("Sensors: %s") % prop_names_to_pp_string(tree->list(path / "sensors")) << std::endl; + ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) + << std::endl; + ss << boost::format("Antennas: %s") + % prop_names_to_pp_string( + tree->access<std::vector<std::string>>(path / "antenna/options") + .get()) + << std::endl; + if (tree->exists(path / "sensors")) { + ss << boost::format("Sensors: %s") + % prop_names_to_pp_string(tree->list(path / "sensors")) + << std::endl; } meta_range_t freq_range = tree->access<meta_range_t>(path / "freq/range").get(); - ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start()/1e6) % (freq_range.stop()/1e6) << std::endl; + ss << boost::format("Freq range: %.3f to %.3f MHz") % (freq_range.start() / 1e6) + % (freq_range.stop() / 1e6) + << std::endl; std::vector<std::string> gain_names = tree->list(path / "gains"); - if (gain_names.size() == 0) ss << "Gain Elements: None" << std::endl; - for(const std::string &name: gain_names){ - meta_range_t gain_range = tree->access<meta_range_t>(path / "gains" / name / "range").get(); - ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; + if (gain_names.size() == 0) + ss << "Gain Elements: None" << std::endl; + for (const std::string& name : gain_names) { + meta_range_t gain_range = + tree->access<meta_range_t>(path / "gains" / name / "range").get(); + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name + % gain_range.start() % gain_range.stop() % gain_range.step() + << std::endl; } - if (tree->exists(path / "bandwidth" / "range")) - { - meta_range_t bw_range = tree->access<meta_range_t>(path / "bandwidth" / "range").get(); - ss << boost::format("Bandwidth range: %.1f to %.1f step %.1f Hz") % bw_range.start() % bw_range.stop() % bw_range.step() << std::endl; + if (tree->exists(path / "bandwidth" / "range")) { + meta_range_t bw_range = + tree->access<meta_range_t>(path / "bandwidth" / "range").get(); + ss << boost::format("Bandwidth range: %.1f to %.1f step %.1f Hz") + % bw_range.start() % bw_range.stop() % bw_range.step() + << std::endl; } - ss << boost::format("Connection Type: %s") % (tree->access<std::string>(path / "connection").get()) << std::endl; + ss << boost::format("Connection Type: %s") + % (tree->access<std::string>(path / "connection").get()) + << std::endl; ss << boost::format("Uses LO offset: %s") - % ((tree->exists(path / "use_lo_offset") and tree->access<bool>(path / "use_lo_offset").get())? "Yes" : "No") + % ((tree->exists(path / "use_lo_offset") + and tree->access<bool>(path / "use_lo_offset").get()) + ? "Yes" + : "No") << std::endl; return ss.str(); } -static std::string get_codec_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){ +static std::string get_codec_pp_string( + const std::string& type, property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; if (tree->exists(path / "name")) { ss << boost::format("%s Codec: %s") % type % path.leaf() << std::endl; - ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) << std::endl; + ss << boost::format("Name: %s") % (tree->access<std::string>(path / "name").get()) + << std::endl; std::vector<std::string> gain_names = tree->list(path / "gains"); - if (gain_names.size() == 0) ss << "Gain Elements: None" << std::endl; - for(const std::string &name: gain_names){ - meta_range_t gain_range = tree->access<meta_range_t>(path / "gains" / name / "range").get(); - ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; + if (gain_names.size() == 0) + ss << "Gain Elements: None" << std::endl; + for (const std::string& name : gain_names) { + meta_range_t gain_range = + tree->access<meta_range_t>(path / "gains" / name / "range").get(); + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % name + % gain_range.start() % gain_range.stop() % gain_range.step() + << std::endl; } } return ss.str(); } -static std::string get_dboard_pp_string(const std::string &type, property_tree::sptr tree, const fs_path &path){ +static std::string get_dboard_pp_string( + const std::string& type, property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; ss << boost::format("%s Dboard: %s") % type % path.leaf() << std::endl; - //ss << std::endl; - const std::string prefix = (type == "RX")? "rx" : "tx"; - if (tree->exists(path / (prefix + "_eeprom"))) - { - usrp::dboard_eeprom_t db_eeprom = tree->access<usrp::dboard_eeprom_t>(path / (prefix + "_eeprom")).get(); - if (db_eeprom.id != usrp::dboard_id_t::none()) ss << boost::format("ID: %s") % db_eeprom.id.to_pp_string() << std::endl; - if (not db_eeprom.serial.empty()) ss << boost::format("Serial: %s") % db_eeprom.serial << std::endl; - if (type == "TX"){ - usrp::dboard_eeprom_t gdb_eeprom = tree->access<usrp::dboard_eeprom_t>(path / "gdb_eeprom").get(); - if (gdb_eeprom.id != usrp::dboard_id_t::none()) ss << boost::format("ID: %s") % gdb_eeprom.id.to_pp_string() << std::endl; - if (not gdb_eeprom.serial.empty()) ss << boost::format("Serial: %s") % gdb_eeprom.serial << std::endl; + // ss << std::endl; + const std::string prefix = (type == "RX") ? "rx" : "tx"; + if (tree->exists(path / (prefix + "_eeprom"))) { + usrp::dboard_eeprom_t db_eeprom = + tree->access<usrp::dboard_eeprom_t>(path / (prefix + "_eeprom")).get(); + if (db_eeprom.id != usrp::dboard_id_t::none()) + ss << boost::format("ID: %s") % db_eeprom.id.to_pp_string() << std::endl; + if (not db_eeprom.serial.empty()) + ss << boost::format("Serial: %s") % db_eeprom.serial << std::endl; + if (type == "TX") { + usrp::dboard_eeprom_t gdb_eeprom = + tree->access<usrp::dboard_eeprom_t>(path / "gdb_eeprom").get(); + if (gdb_eeprom.id != usrp::dboard_id_t::none()) + ss << boost::format("ID: %s") % gdb_eeprom.id.to_pp_string() << std::endl; + if (not gdb_eeprom.serial.empty()) + ss << boost::format("Serial: %s") % gdb_eeprom.serial << std::endl; } } if (tree->exists(path / (prefix + "_frontends"))) { - for(const std::string &name: tree->list(path / (prefix + "_frontends"))){ - ss << make_border(get_frontend_pp_string(type, tree, path / (prefix + "_frontends") / name)); + for (const std::string& name : tree->list(path / (prefix + "_frontends"))) { + 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())); + ss << make_border(get_codec_pp_string(type, + tree, + path.branch_path().branch_path() / (prefix + "_codecs") / path.leaf())); return ss.str(); } -static std::string get_rfnoc_pp_string(property_tree::sptr tree, const fs_path &path){ +static std::string get_rfnoc_pp_string(property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; ss << "RFNoC blocks on this device:" << std::endl << std::endl; - for(const std::string &name: tree->list(path)){ + for (const std::string& name : tree->list(path)) { ss << "* " << name << std::endl; } return ss.str(); } -static std::string get_mboard_pp_string(property_tree::sptr tree, const fs_path &path){ +static std::string get_mboard_pp_string(property_tree::sptr tree, const fs_path& path) +{ std::stringstream ss; - ss << boost::format("Mboard: %s") % (tree->access<std::string>(path / "name").get()) << std::endl; + ss << boost::format("Mboard: %s") % (tree->access<std::string>(path / "name").get()) + << std::endl; - if (tree->exists(path / "eeprom")){ - usrp::mboard_eeprom_t mb_eeprom = tree->access<usrp::mboard_eeprom_t>(path / "eeprom").get(); - for(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 / "eeprom")) { + usrp::mboard_eeprom_t mb_eeprom = + tree->access<usrp::mboard_eeprom_t>(path / "eeprom").get(); + for (const std::string& key : mb_eeprom.keys()) { + if (not mb_eeprom[key].empty()) + ss << boost::format("%s: %s") % key % mb_eeprom[key] << std::endl; } } else { ss << "No mboard EEPROM found." << 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 / "fw_version")) { + ss << "FW Version: " << tree->access<std::string>(path / "fw_version").get() + << std::endl; } - if (tree->exists(path / "mpm_version")){ - ss << "MPM Version: " << tree->access<std::string>(path / "mpm_version").get() << std::endl; + if (tree->exists(path / "mpm_version")) { + ss << "MPM Version: " << tree->access<std::string>(path / "mpm_version").get() + << std::endl; } - if (tree->exists(path / "fpga_version")){ - ss << "FPGA Version: " << tree->access<std::string>(path / "fpga_version").get() << std::endl; + if (tree->exists(path / "fpga_version")) { + ss << "FPGA Version: " << tree->access<std::string>(path / "fpga_version").get() + << std::endl; } - if (tree->exists(path / "fpga_version_hash")){ - ss << "FPGA git hash: " << tree->access<std::string>(path / "fpga_version_hash").get() << std::endl; + if (tree->exists(path / "fpga_version_hash")) { + ss << "FPGA git hash: " + << tree->access<std::string>(path / "fpga_version_hash").get() << std::endl; } - if (tree->exists(path / "xbar")){ + if (tree->exists(path / "xbar")) { ss << "RFNoC capable: Yes" << std::endl; } ss << std::endl; try { - if (tree->exists(path / "time_source" / "options")){ - const std::vector< std::string > time_sources = tree->access<std::vector<std::string> >(path / "time_source" / "options").get(); - ss << "Time sources: " << prop_names_to_pp_string(time_sources) << std::endl; + if (tree->exists(path / "time_source" / "options")) { + const std::vector<std::string> time_sources = + tree->access<std::vector<std::string>>(path / "time_source" / "options") + .get(); + ss << "Time sources: " << prop_names_to_pp_string(time_sources) << std::endl; } - if (tree->exists(path / "clock_source" / "options")){ - const std::vector< std::string > clock_sources = tree->access<std::vector<std::string> >(path / "clock_source" / "options").get(); - ss << "Clock sources: " << prop_names_to_pp_string(clock_sources) << std::endl; + if (tree->exists(path / "clock_source" / "options")) { + const std::vector<std::string> clock_sources = + tree->access<std::vector<std::string>>(path / "clock_source" / "options") + .get(); + ss << "Clock sources: " << prop_names_to_pp_string(clock_sources) + << std::endl; } - if (tree->exists(path / "sensors")){ - ss << "Sensors: " << prop_names_to_pp_string(tree->list(path / "sensors")) << std::endl; + if (tree->exists(path / "sensors")) { + ss << "Sensors: " << prop_names_to_pp_string(tree->list(path / "sensors")) + << std::endl; } - if (tree->exists(path / "rx_dsps")){ - for(const std::string &name: tree->list(path / "rx_dsps")){ + if (tree->exists(path / "rx_dsps")) { + for (const std::string& name : tree->list(path / "rx_dsps")) { ss << make_border(get_dsp_pp_string("RX", tree, path / "rx_dsps" / name)); } } if (tree->exists(path / "dboards")) { - for(const std::string &name: tree->list(path / "dboards")){ - ss << make_border(get_dboard_pp_string("RX", tree, path / "dboards" / name)); + for (const std::string& name : tree->list(path / "dboards")) { + ss << make_border( + get_dboard_pp_string("RX", tree, path / "dboards" / name)); } - if (tree->exists(path / "tx_dsps")){ - for(const std::string &name: tree->list(path / "tx_dsps")){ - ss << make_border(get_dsp_pp_string("TX", tree, path / "tx_dsps" / name)); + if (tree->exists(path / "tx_dsps")) { + for (const std::string& name : tree->list(path / "tx_dsps")) { + ss << make_border( + get_dsp_pp_string("TX", tree, path / "tx_dsps" / name)); } } - for(const std::string &name: tree->list(path / "dboards")){ - ss << make_border(get_dboard_pp_string("TX", tree, path / "dboards" / name)); + for (const std::string& name : tree->list(path / "dboards")) { + ss << make_border( + get_dboard_pp_string("TX", tree, path / "dboards" / name)); } } - if (tree->exists(path / "xbar")){ + if (tree->exists(path / "xbar")) { ss << make_border(get_rfnoc_pp_string(tree, path / "xbar")); } - } - catch (const uhd::lookup_error& ex) { + } catch (const uhd::lookup_error& ex) { std::cout << "Exited device probe on " << ex.what() << std::endl; } return ss.str(); } -static std::string get_device_pp_string(property_tree::sptr tree){ +static std::string get_device_pp_string(property_tree::sptr tree) +{ std::stringstream ss; - ss << boost::format("Device: %s") % (tree->access<std::string>("/name").get()) << std::endl; - //ss << std::endl; - for(const std::string &name: tree->list("/mboards")){ + ss << boost::format("Device: %s") % (tree->access<std::string>("/name").get()) + << std::endl; + // ss << std::endl; + for (const std::string& name : tree->list("/mboards")) { ss << make_border(get_mboard_pp_string(tree, "/mboards/" + name)); } return ss.str(); } -void print_tree(const uhd::fs_path &path, uhd::property_tree::sptr tree){ +void print_tree(const uhd::fs_path& path, uhd::property_tree::sptr tree) +{ std::cout << path << std::endl; - for(const std::string &name: tree->list(path)){ + for (const std::string& name : tree->list(path)) { print_tree(path / name, tree); } } -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ po::options_description desc("Allowed options"); // clang-format off desc.add_options() @@ -250,57 +323,69 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("UHD USRP Probe %s") % desc << std::endl; return EXIT_FAILURE; } - if (vm.count("version")){ + if (vm.count("version")) { std::cout << uhd::get_version_string() << std::endl; return EXIT_SUCCESS; } - device::sptr dev = device::make(vm["args"].as<std::string>()); + device::sptr dev = device::make(vm["args"].as<std::string>()); property_tree::sptr tree = dev->get_tree(); - if (vm.count("string")){ + if (vm.count("string")) { if (vm.count("vector")) { - std::vector<std::string> str_vector = tree->access< std::vector<std::string> >(vm["string"].as<std::string>()).get(); + std::vector<std::string> str_vector = + tree->access<std::vector<std::string>>(vm["string"].as<std::string>()) + .get(); std::cout << "("; - for(const std::string &str: str_vector) { + for (const std::string& str : str_vector) { std::cout << str << ","; } std::cout << ")" << std::endl; } else { - std::cout << tree->access<std::string>(vm["string"].as<std::string>()).get() << std::endl; + std::cout << tree->access<std::string>(vm["string"].as<std::string>()).get() + << std::endl; } return EXIT_SUCCESS; } - if (vm.count("double")){ - std::cout << tree->access<double>(vm["double"].as<std::string>()).get() << std::endl; + if (vm.count("double")) { + std::cout << tree->access<double>(vm["double"].as<std::string>()).get() + << std::endl; return EXIT_SUCCESS; } - if (vm.count("int")){ + if (vm.count("int")) { std::cout << tree->access<int>(vm["int"].as<std::string>()).get() << std::endl; return EXIT_SUCCESS; } - if (vm.count("sensor")){ - std::cout << tree->access<uhd::sensor_value_t>(vm["sensor"].as<std::string>()).get().value << std::endl; + if (vm.count("sensor")) { + std::cout << tree->access<uhd::sensor_value_t>(vm["sensor"].as<std::string>()) + .get() + .value + << std::endl; return EXIT_SUCCESS; } - if (vm.count("range")){ - meta_range_t range = tree->access<meta_range_t>(vm["range"].as<std::string>()).get(); - std::cout << boost::format("%.1f:%.1f:%.1f") % range.start() % range.step() % range.stop() << std::endl; + if (vm.count("range")) { + meta_range_t range = + tree->access<meta_range_t>(vm["range"].as<std::string>()).get(); + std::cout << boost::format("%.1f:%.1f:%.1f") % range.start() % range.step() + % range.stop() + << std::endl; return EXIT_SUCCESS; } - if (vm.count("tree") != 0) print_tree("/", tree); - else if (not vm.count("init-only")) std::cout << make_border(get_device_pp_string(tree)) << std::endl; + if (vm.count("tree") != 0) + print_tree("/", tree); + else if (not vm.count("init-only")) + std::cout << make_border(get_device_pp_string(tree)) << std::endl; return EXIT_SUCCESS; } diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp index 391c35950..cfb80fd42 100644 --- a/host/utils/usrp_burn_db_eeprom.cpp +++ b/host/utils/usrp_burn_db_eeprom.cpp @@ -6,24 +6,25 @@ // -#include <uhd/utils/safe_main.hpp> #include <uhd/device.hpp> -#include <uhd/types/dict.hpp> -#include <uhd/utils/assert_has.hpp> #include <uhd/property_tree.hpp> +#include <uhd/types/dict.hpp> #include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/utils/assert_has.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> #include <boost/assign.hpp> +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> using namespace uhd; using namespace uhd::usrp; namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ - //command line variables +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ + // command line variables std::string args, slot, unit; po::options_description desc("Allowed options"); @@ -43,49 +44,54 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ 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("USRP Burn Daughterboard EEPROM %s") % desc << std::endl; - std::cout << boost::format( - "Omit the ID argument to perform readback,\n" - "Or specify a new ID to burn into the EEPROM.\n" - ) << std::endl; + // print the help message + if (vm.count("help")) { + std::cout << boost::format("USRP Burn Daughterboard EEPROM %s") % desc + << std::endl; + std::cout << boost::format("Omit the ID argument to perform readback,\n" + "Or specify a new ID to burn into the EEPROM.\n") + << std::endl; return EXIT_FAILURE; } - //make the device and extract the dboard w/ property - device::sptr dev = device::make(args, device::USRP); - uhd::property_tree::sptr tree = dev->get_tree(); - const uhd::fs_path db_root = "/mboards/0/dboards"; + // make the device and extract the dboard w/ property + device::sptr dev = device::make(args, device::USRP); + uhd::property_tree::sptr tree = dev->get_tree(); + const uhd::fs_path db_root = "/mboards/0/dboards"; std::vector<std::string> dboard_names = tree->list(db_root); - if (dboard_names.size() == 1 and slot.empty()) slot = dboard_names.front(); + if (dboard_names.size() == 1 and slot.empty()) + slot = dboard_names.front(); uhd::assert_has(dboard_names, slot, "dboard slot name"); - std::cout << boost::format("Reading %s EEPROM on %s dboard...") % unit % slot << std::endl; + std::cout << boost::format("Reading %s EEPROM on %s dboard...") % unit % slot + << std::endl; boost::to_lower(unit); const uhd::fs_path db_path = db_root / slot / (unit + "_eeprom"); - dboard_eeprom_t db_eeprom = tree->access<dboard_eeprom_t>(db_path).get(); + dboard_eeprom_t db_eeprom = tree->access<dboard_eeprom_t>(db_path).get(); //------------- handle the dboard ID -----------------------------// - if (vm.count("id")){ + if (vm.count("id")) { db_eeprom.id = dboard_id_t::from_string(vm["id"].as<std::string>()); tree->access<dboard_eeprom_t>(db_path).set(db_eeprom); } - std::cout << boost::format(" Current ID: %s") % db_eeprom.id.to_pp_string() << std::endl; + std::cout << boost::format(" Current ID: %s") % db_eeprom.id.to_pp_string() + << std::endl; //------------- handle the dboard serial--------------------------// - if (vm.count("ser")){ + if (vm.count("ser")) { db_eeprom.serial = vm["ser"].as<std::string>(); tree->access<dboard_eeprom_t>(db_path).set(db_eeprom); } - std::cout << boost::format(" Current serial: \"%s\"") % db_eeprom.serial << std::endl; + std::cout << boost::format(" Current serial: \"%s\"") % db_eeprom.serial + << std::endl; //------------- handle the dboard revision------------------------// - if (vm.count("rev")){ + if (vm.count("rev")) { db_eeprom.revision = vm["rev"].as<std::string>(); tree->access<dboard_eeprom_t>(db_path).set(db_eeprom); } - std::cout << boost::format(" Current revision: \"%s\"") % db_eeprom.revision << std::endl; + std::cout << boost::format(" Current revision: \"%s\"") % db_eeprom.revision + << std::endl; std::cout << " Done" << std::endl << std::endl; return EXIT_SUCCESS; diff --git a/host/utils/usrp_burn_mb_eeprom.cpp b/host/utils/usrp_burn_mb_eeprom.cpp index e2596d5c4..65b68f379 100644 --- a/host/utils/usrp_burn_mb_eeprom.cpp +++ b/host/utils/usrp_burn_mb_eeprom.cpp @@ -5,20 +5,21 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/safe_main.hpp> #include <uhd/device.hpp> #include <uhd/property_tree.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/types/device_addr.hpp> +#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/algorithm/string.hpp> -#include <boost/program_options.hpp> #include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> #include <vector> namespace po = boost::program_options; -int UHD_SAFE_MAIN(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char* argv[]) +{ std::string args, input_str; po::options_description desc("Allowed options"); @@ -35,28 +36,31 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))){ + // print the help message + if (vm.count("help") or (not vm.count("values") and not vm.count("read-all"))) { std::cout << boost::format("USRP Burn Motherboard EEPROM %s") % desc << std::endl; - std::cout << boost::format( - "Omit the value argument to perform a readback,\n" - "Or specify a new value to burn into the EEPROM.\n" - "Example (write to ip-addr0 and read out ip-addr1):\n" - " usrp_burn_mb_eeprom --args=<device args> --values\"ip-addr0=192.168.10.3,ip-addr1\"" - ) << std::endl; + std::cout << boost::format("Omit the value argument to perform a readback,\n" + "Or specify a new value to burn into the EEPROM.\n" + "Example (write to ip-addr0 and read out ip-addr1):\n" + " usrp_burn_mb_eeprom --args=<device args> " + "--values\"ip-addr0=192.168.10.3,ip-addr1\"") + << std::endl; return EXIT_FAILURE; } std::cout << "Creating USRP device from address: " + args << std::endl; - uhd::device::sptr dev = uhd::device::make(args, uhd::device::USRP); + uhd::device::sptr dev = uhd::device::make(args, uhd::device::USRP); uhd::property_tree::sptr tree = dev->get_tree(); - uhd::usrp::mboard_eeprom_t mb_eeprom = tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").get(); + uhd::usrp::mboard_eeprom_t mb_eeprom = + tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").get(); std::cout << std::endl; std::vector<std::string> keys_vec, vals_vec; - if(vm.count("read-all")) keys_vec = mb_eeprom.keys(); //Leaving vals_vec empty will force utility to only read - else if(vm.count("values")){ - //uhd::device_addr_t properly parses input values + if (vm.count("read-all")) + keys_vec = + mb_eeprom.keys(); // Leaving vals_vec empty will force utility to only read + else if (vm.count("values")) { + // uhd::device_addr_t properly parses input values uhd::device_addr_t vals(input_str); keys_vec = vals.keys(); vals_vec = vals.vals(); @@ -64,25 +68,31 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ // 1. Read out values std::cout << "Fetching current settings from EEPROM..." << std::endl; - for(size_t i = 0; i < keys_vec.size(); i++){ - if (not mb_eeprom.has_key(keys_vec[i])){ - std::cerr << boost::format("Cannot find value for EEPROM[%s]") % keys_vec[i] << std::endl; + for (size_t i = 0; i < keys_vec.size(); i++) { + if (not mb_eeprom.has_key(keys_vec[i])) { + std::cerr << boost::format("Cannot find value for EEPROM[%s]") % keys_vec[i] + << std::endl; return EXIT_FAILURE; } - std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] % mb_eeprom[keys_vec[i]] << std::endl; + std::cout << boost::format(" EEPROM [\"%s\"] is \"%s\"") % keys_vec[i] + % mb_eeprom[keys_vec[i]] + << std::endl; } std::cout << std::endl; // 2. Write new values if given mb_eeprom = uhd::usrp::mboard_eeprom_t(); - for(size_t i = 0; i < vals_vec.size(); i++){ - if(vals_vec[i] != ""){ + for (size_t i = 0; i < vals_vec.size(); i++) { + if (vals_vec[i] != "") { mb_eeprom[keys_vec[i]] = vals_vec[i]; - std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") % keys_vec[i] % vals_vec[i] << std::endl; + std::cout << boost::format("Setting EEPROM [\"%s\"] to \"%s\"...") + % keys_vec[i] % vals_vec[i] + << std::endl; } } tree->access<uhd::usrp::mboard_eeprom_t>("/mboards/0/eeprom").set(mb_eeprom); - std::cout << "Power-cycle the USRP device for the changes to take effect." << std::endl; + std::cout << "Power-cycle the USRP device for the changes to take effect." + << std::endl; std::cout << std::endl; std::cout << "Done" << std::endl; diff --git a/host/utils/usrp_cal_utils.hpp b/host/utils/usrp_cal_utils.hpp index ebd1400b7..fe567c7de 100644 --- a/host/utils/usrp_cal_utils.hpp +++ b/host/utils/usrp_cal_utils.hpp @@ -5,38 +5,40 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include <uhd/utils/paths.hpp> #include <uhd/property_tree.hpp> -#include <uhd/usrp/multi_usrp.hpp> #include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/utils/paths.hpp> +#include <uhd/usrp/multi_usrp.hpp> #include <uhd/utils/algorithm.hpp> +#include <uhd/utils/paths.hpp> #include <boost/filesystem.hpp> #include <boost/format.hpp> -#include <iostream> -#include <vector> -#include <complex> +#include <chrono> #include <cmath> +#include <complex> #include <cstdlib> #include <fstream> -#include <chrono> +#include <iostream> #include <thread> +#include <vector> namespace fs = boost::filesystem; -struct result_t{double freq, real_corr, imag_corr, best, delta;}; +struct result_t +{ + double freq, real_corr, imag_corr, best, delta; +}; typedef std::complex<float> samp_type; /*********************************************************************** * Constants **********************************************************************/ -static const double tau = 6.28318531; -static const size_t wave_table_len = 65536; -static const size_t num_search_steps = 5; -static const double default_precision = 0.0001; -static const double default_freq_step = 7.3e6; -static const size_t default_fft_bin_size = 1000; +static const double tau = 6.28318531; +static const size_t wave_table_len = 65536; +static const size_t num_search_steps = 5; +static const double default_precision = 0.0001; +static const double default_freq_step = 7.3e6; +static const size_t default_fft_bin_size = 1000; static constexpr size_t MAX_NUM_TX_ERRORS = 10; /*********************************************************************** @@ -49,51 +51,44 @@ static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp) uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec(); const uhd::fs_path mb_path = "/mboards/0"; - const std::string mb_name = tree->access<std::string>(mb_path / "name").get(); - if (mb_name.find("USRP2") != std::string::npos or - mb_name.find("N200") != std::string::npos or - mb_name.find("N210") != std::string::npos or - mb_name.find("X300") != std::string::npos or - mb_name.find("X310") != std::string::npos or - mb_name.find("n3xx") != std::string::npos) - { + const std::string mb_name = tree->access<std::string>(mb_path / "name").get(); + if (mb_name.find("USRP2") != std::string::npos + or mb_name.find("N200") != std::string::npos + or mb_name.find("N210") != std::string::npos + or mb_name.find("X300") != std::string::npos + or mb_name.find("X310") != std::string::npos + or mb_name.find("n3xx") != std::string::npos) { usrp->set_tx_rate(12.5e6); usrp->set_rx_rate(12.5e6); - } - else if (mb_name.find("B100") != std::string::npos) - { + } else if (mb_name.find("B100") != std::string::npos) { usrp->set_tx_rate(4e6); usrp->set_rx_rate(4e6); - } - else - { + } else { throw std::runtime_error("self-calibration is not supported for this device"); } - const uhd::fs_path tx_fe_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/tx_frontends/0"; + const uhd::fs_path tx_fe_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/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 and - tx_name.find("SBX") == std::string::npos and - tx_name.find("CBX") == std::string::npos and - tx_name.find("RFX") == std::string::npos and - tx_name.find("UBX") == std::string::npos and - tx_name.find("Rhodium") == std::string::npos - ) - { + if (tx_name.find("WBX") == std::string::npos + and tx_name.find("SBX") == std::string::npos + and tx_name.find("CBX") == std::string::npos + and tx_name.find("RFX") == std::string::npos + and tx_name.find("UBX") == std::string::npos + and tx_name.find("Rhodium") == std::string::npos) { throw std::runtime_error("self-calibration is not supported for this TX dboard"); } usrp->set_tx_gain(0); - const uhd::fs_path rx_fe_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_frontends/0"; + const uhd::fs_path rx_fe_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_frontends/0"; const std::string rx_name = tree->access<std::string>(rx_fe_path / "name").get(); - if (rx_name.find("WBX") == std::string::npos and - rx_name.find("SBX") == std::string::npos and - rx_name.find("CBX") == std::string::npos and - rx_name.find("RFX") == std::string::npos and - rx_name.find("UBX") == std::string::npos and - rx_name.find("Rhodium") == std::string::npos - ) - { + if (rx_name.find("WBX") == std::string::npos + and rx_name.find("SBX") == std::string::npos + and rx_name.find("CBX") == std::string::npos + and rx_name.find("RFX") == std::string::npos + and rx_name.find("UBX") == std::string::npos + and rx_name.find("Rhodium") == std::string::npos) { throw std::runtime_error("self-calibration is not supported for this RX dboard"); } usrp->set_rx_gain(0); @@ -107,13 +102,16 @@ void check_for_empty_serial(uhd::usrp::multi_usrp::sptr usrp) // Will work on 1st subdev, top-level must make sure it's the right one uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec(); - //extract eeprom + // extract eeprom uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // This only works with transceiver boards, so we can always check rx side - const uhd::fs_path db_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_eeprom"; - const uhd::usrp::dboard_eeprom_t db_eeprom = tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); + const uhd::fs_path db_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_eeprom"; + const uhd::usrp::dboard_eeprom_t db_eeprom = + tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); - std::string error_string = "This dboard has no serial!\n\nPlease see the Calibration documentation for details on how to fix this."; + std::string error_string = "This dboard has no serial!\n\nPlease see the Calibration " + "documentation for details on how to fix this."; if (db_eeprom.serial.empty()) throw std::runtime_error(error_string); } @@ -128,7 +126,7 @@ public: { _table.resize(wave_table_len); for (size_t i = 0; i < wave_table_len; i++) - _table[i] = samp_type(std::polar(ampl, (tau*i)/wave_table_len)); + _table[i] = samp_type(std::polar(ampl, (tau * i) / wave_table_len)); } inline samp_type operator()(const size_t index) const @@ -137,33 +135,32 @@ public: } private: - std::vector<samp_type > _table; + std::vector<samp_type> _table; }; /*********************************************************************** * Compute power of a tone **********************************************************************/ -static inline double compute_tone_dbrms( - const std::vector<samp_type> &samples, - const double freq) //freq is fractional +static inline double compute_tone_dbrms(const std::vector<samp_type>& samples, + const double freq) // freq is fractional { - //shift the samples so the tone at freq is down at DC - //and average the samples to measure the DC component + // shift the samples so the tone at freq is down at DC + // and average the samples to measure the DC component samp_type average = 0; for (size_t i = 0; i < samples.size(); i++) - average += samp_type(std::polar(1.0, -freq*tau*i)) * samples[i]; + average += samp_type(std::polar(1.0, -freq * tau * i)) * samples[i]; - return 20*std::log10(std::abs(average/float(samples.size()))); + return 20 * std::log10(std::abs(average / float(samples.size()))); } /*********************************************************************** * Write a dat file **********************************************************************/ static inline void write_samples_to_file( - const std::vector<samp_type > &samples, const std::string &file) + const std::vector<samp_type>& samples, const std::string& file) { std::ofstream outfile(file.c_str(), std::ofstream::binary); - outfile.write((const char*)&samples.front(), samples.size()*sizeof(samp_type)); + outfile.write((const char*)&samples.front(), samples.size() * sizeof(samp_type)); outfile.close(); } @@ -171,38 +168,39 @@ static inline void write_samples_to_file( /*********************************************************************** * Retrieve d'board serial **********************************************************************/ -static std::string get_serial( - uhd::usrp::multi_usrp::sptr usrp, - const std::string &tx_rx) +static std::string get_serial(uhd::usrp::multi_usrp::sptr usrp, const std::string& tx_rx) { uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // Will work on 1st subdev, top-level must make sure it's the right one uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec(); - const uhd::fs_path db_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/" + tx_rx + "_eeprom"; - const uhd::usrp::dboard_eeprom_t db_eeprom = tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); + const uhd::fs_path db_path = + "/mboards/0/dboards/" + subdev_spec[0].db_name + "/" + tx_rx + "_eeprom"; + const uhd::usrp::dboard_eeprom_t db_eeprom = + tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); return db_eeprom.serial; } /*********************************************************************** * Store data to file **********************************************************************/ -static void store_results( - const std::vector<result_t> &results, - const std::string &XX, // "TX" or "RX" - const std::string &xx, // "tx" or "rx" - const std::string &what, // Type of test, e.g. "iq", - const std::string &serial) +static void store_results(const std::vector<result_t>& results, + const std::string& XX, // "TX" or "RX" + const std::string& xx, // "tx" or "rx" + const std::string& what, // Type of test, e.g. "iq", + const std::string& serial) { - //make the calibration file path + // make the calibration file path fs::path cal_data_path = fs::path(uhd::get_app_path()) / ".uhd"; fs::create_directory(cal_data_path); cal_data_path = cal_data_path / "cal"; fs::create_directory(cal_data_path); - cal_data_path = cal_data_path / str(boost::format("%s_%s_cal_v0.2_%s.csv") % xx % what % serial); + cal_data_path = + cal_data_path / str(boost::format("%s_%s_cal_v0.2_%s.csv") % xx % what % serial); if (fs::exists(cal_data_path)) - fs::rename(cal_data_path, cal_data_path.string() + str(boost::format(".%d") % time(NULL))); + fs::rename(cal_data_path, + cal_data_path.string() + str(boost::format(".%d") % time(NULL))); - //fill the calibration file + // fill the calibration file std::ofstream cal_data(cal_data_path.string().c_str()); cal_data << boost::format("name, %s Frontend Calibration\n") % XX; cal_data << boost::format("serial, %s\n") % serial; @@ -211,15 +209,10 @@ static void store_results( cal_data << boost::format("DATA STARTS HERE\n"); cal_data << "lo_frequency, correction_real, correction_imag, measured, delta\n"; - for (size_t i = 0; i < results.size(); i++) - { - cal_data - << results[i].freq << ", " - << results[i].real_corr << ", " - << results[i].imag_corr << ", " - << results[i].best << ", " - << results[i].delta << "\n" - ; + for (size_t i = 0; i < results.size(); i++) { + cal_data << results[i].freq << ", " << results[i].real_corr << ", " + << results[i].imag_corr << ", " << results[i].best << ", " + << results[i].delta << "\n"; } std::cout << "wrote cal data to " << cal_data_path << std::endl; @@ -228,10 +221,9 @@ static void store_results( /*********************************************************************** * Data capture routine **********************************************************************/ -static void capture_samples( - uhd::usrp::multi_usrp::sptr usrp, +static void capture_samples(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, - std::vector<samp_type > &buff, + std::vector<samp_type>& buff, const size_t nsamps_requested) { buff.resize(nsamps_requested); @@ -243,34 +235,29 @@ static void capture_samples( std::vector<samp_type> discard_buff(nsamps_to_discard); uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = buff.size() + nsamps_to_discard; + stream_cmd.num_samps = buff.size() + nsamps_to_discard; stream_cmd.stream_now = true; usrp->issue_stream_cmd(stream_cmd); size_t num_rx_samps = 0; // Discard the transient samples. rx_stream->recv(&discard_buff.front(), discard_buff.size(), md); - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - { - throw std::runtime_error(str(boost::format( - "Receiver error: %s" - ) % md.strerror())); + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error( + str(boost::format("Receiver error: %s") % md.strerror())); } // Now capture the data we want num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md); - //validate the received data - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - { - throw std::runtime_error(str(boost::format( - "Receiver error: %s" - ) % md.strerror())); + // validate the received data + if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { + throw std::runtime_error( + str(boost::format("Receiver error: %s") % md.strerror())); } - //we can live if all the data didnt come in - if (num_rx_samps > buff.size()/2) - { + // we can live if all the data didnt come in + if (num_rx_samps > buff.size() / 2) { buff.resize(num_rx_samps); return; } @@ -281,15 +268,16 @@ static void capture_samples( /*********************************************************************** * Setup function **********************************************************************/ -static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal(std::string &args, std::string &subdev, std::string &serial) +static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal( + std::string& args, std::string& subdev, std::string& serial) { std::cout << std::endl; - std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args + << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); // Configure subdev - if (!subdev.empty()) - { + if (!subdev.empty()) { usrp->set_tx_subdev_spec(subdev); usrp->set_rx_subdev_spec(subdev); } @@ -297,16 +285,18 @@ static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal(std::string &args, std::st serial = get_serial(usrp, "tx"); std::cout << "Daughterboard serial: " << serial; - //set the antennas to cal - if (not uhd::has(usrp->get_rx_antennas(), "CAL") or not uhd::has(usrp->get_tx_antennas(), "CAL")) - throw std::runtime_error("This board does not have the CAL antenna option, cannot self-calibrate."); + // set the antennas to cal + if (not uhd::has(usrp->get_rx_antennas(), "CAL") + or not uhd::has(usrp->get_tx_antennas(), "CAL")) + throw std::runtime_error( + "This board does not have the CAL antenna option, cannot self-calibrate."); usrp->set_rx_antenna("CAL"); usrp->set_tx_antenna("CAL"); - //fail if daughterboard has no serial + // fail if daughterboard has no serial check_for_empty_serial(usrp); - //set optimum defaults + // set optimum defaults set_optimum_defaults(usrp); return usrp; @@ -315,25 +305,24 @@ static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal(std::string &args, std::st /*********************************************************************** * Function to find optimal RX gain setting (for the current frequency) **********************************************************************/ -UHD_INLINE void set_optimal_rx_gain( - uhd::usrp::multi_usrp::sptr usrp, +UHD_INLINE void set_optimal_rx_gain(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, double wave_freq = 0.0) { - const double gain_step = 3.0; + const double gain_step = 3.0; const double gain_compression_threshold = gain_step * 0.5; - const double actual_rx_rate = usrp->get_rx_rate(); - const double actual_tx_freq = usrp->get_tx_freq(); - const double actual_rx_freq = usrp->get_rx_freq(); - const double bb_tone_freq = actual_tx_freq - actual_rx_freq + wave_freq; + const double actual_rx_rate = usrp->get_rx_rate(); + const double actual_tx_freq = usrp->get_tx_freq(); + const double actual_rx_freq = usrp->get_rx_freq(); + const double bb_tone_freq = actual_tx_freq - actual_rx_freq + wave_freq; const size_t nsamps = size_t(actual_rx_rate / default_fft_bin_size); std::vector<samp_type> buff(nsamps); uhd::gain_range_t rx_gain_range = usrp->get_rx_gain_range(); - double rx_gain = rx_gain_range.start() + gain_step; - double curr_dbrms = 0.0; - double prev_dbrms = 0.0; - double delta = 0.0; + double rx_gain = rx_gain_range.start() + gain_step; + double curr_dbrms = 0.0; + double prev_dbrms = 0.0; + double delta = 0.0; // No sense in setting the gain where this is no gain range if (rx_gain_range.stop() - rx_gain_range.start() < gain_step) @@ -349,20 +338,19 @@ UHD_INLINE void set_optimal_rx_gain( // Initialize prev_dbrms value usrp->set_rx_gain(rx_gain); capture_samples(usrp, rx_stream, buff, nsamps); - prev_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); + prev_dbrms = compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); rx_gain += gain_step; // Find RX gain where signal begins to clip - while (rx_gain <= rx_gain_range.stop()) - { + while (rx_gain <= rx_gain_range.stop()) { usrp->set_rx_gain(rx_gain); capture_samples(usrp, rx_stream, buff, nsamps); - curr_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate); - delta = curr_dbrms - prev_dbrms; + curr_dbrms = compute_tone_dbrms(buff, bb_tone_freq / actual_rx_rate); + delta = curr_dbrms - prev_dbrms; // check if the gain is compressed beyone the threshold if (delta < gain_step - gain_compression_threshold) - break; // if so, we are done + break; // if so, we are done prev_dbrms = curr_dbrms; rx_gain += gain_step; @@ -391,14 +379,14 @@ bool has_tx_error(uhd::tx_streamer::sptr tx_stream) return false; } - return async_md.event_code & (0 - // Any of these errors are considered a problematic TX error: - | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW - | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR - | uhd::async_metadata_t::EVENT_CODE_TIME_ERROR - | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET - | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST - ); + return async_md.event_code + & (0 + // Any of these errors are considered a problematic TX error: + | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW + | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR + | uhd::async_metadata_t::EVENT_CODE_TIME_ERROR + | uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET + | uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST); } void wait_for_lo_lock(uhd::usrp::multi_usrp::sptr usrp) @@ -407,10 +395,9 @@ void wait_for_lo_lock(uhd::usrp::multi_usrp::sptr usrp) const auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(100); while (not usrp->get_tx_sensor("lo_locked").to_bool() - or not usrp->get_rx_sensor("lo_locked").to_bool()) { + or not usrp->get_rx_sensor("lo_locked").to_bool()) { if (std::chrono::steady_clock::now() > timeout) { - throw std::runtime_error( - "timed out waiting for TX and/or RX LO to lock"); + throw std::runtime_error("timed out waiting for TX and/or RX LO to lock"); } } } diff --git a/host/utils/usrp_e3x0_network_mode.cpp b/host/utils/usrp_e3x0_network_mode.cpp index ac4f47e4d..fbc8aeb28 100644 --- a/host/utils/usrp_e3x0_network_mode.cpp +++ b/host/utils/usrp_e3x0_network_mode.cpp @@ -8,13 +8,10 @@ #include "../lib/usrp/e300/e300_network.hpp" #include <uhd/device.hpp> #include <uhd/exception.hpp> - #include <uhd/transport/if_addrs.hpp> - -#include <boost/program_options.hpp> -#include <boost/format.hpp> #include <boost/asio.hpp> - +#include <boost/format.hpp> +#include <boost/program_options.hpp> #include <iostream> namespace po = boost::program_options; @@ -25,13 +22,13 @@ static void check_network_ok(void) using namespace boost::asio::ip; std::vector<if_addrs_t> addrs = get_if_addrs(); - if(addrs.size() == 1 and addrs.at(0).inet == address_v4::loopback().to_string()) + if (addrs.size() == 1 and addrs.at(0).inet == address_v4::loopback().to_string()) throw uhd::runtime_error( "No network address except for loopback found.\n" "Make sure your DHCP server is working or configure a static IP"); } -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { po::options_description desc("Allowed options"); // clang-format off @@ -45,25 +42,29 @@ int main(int argc, char *argv[]) po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); - //print the help message - if (vm.count("help")){ + // print the help message + if (vm.count("help")) { std::cout << boost::format("UHD E3x0 Network Mode %s") % desc << std::endl; return EXIT_FAILURE; } uhd::device_addr_t args; - if(vm.count("fpga")) { + if (vm.count("fpga")) { args["fpga"] = vm["fpga"].as<std::string>(); } try { check_network_ok(); - uhd::usrp::e300::network_server::sptr server = uhd::usrp::e300::network_server::make(args); + uhd::usrp::e300::network_server::sptr server = + uhd::usrp::e300::network_server::make(args); server->run(); - } catch (uhd::assertion_error &e) { - std::cout << "This executable is supposed to run on the device, not on the host." << std::endl - << "Please refer to the manual section on operating your e3x0 device in network mode." << std::endl; + } catch (uhd::assertion_error& e) { + std::cout << "This executable is supposed to run on the device, not on the host." + << std::endl + << "Please refer to the manual section on operating your e3x0 device " + "in network mode." + << std::endl; return EXIT_FAILURE; - } catch (uhd::runtime_error &e) { + } catch (uhd::runtime_error& e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; } |